blob: e55b75f716ad5d4f2d8e98b578b5592ef26e20fb [file] [log] [blame]
Joe Onorato344e4042022-12-05 15:15:36 -08001# Copyright (C) 2022 The Android Open Source Project
2#
3# Licensed under the Apache License, Version 2.0 (the "License");
4# you may not use this file except in compliance with the License.
5# You may obtain a copy of the License at
6#
7# http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS,
11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12# See the License for the specific language governing permissions and
13# limitations under the License.
14
15function gettop
16{
17 local TOPFILE=build/make/core/envsetup.mk
18 # The ${TOP-} expansion allows this to work even with set -u
19 if [ -n "${TOP:-}" -a -f "${TOP:-}/$TOPFILE" ] ; then
20 # The following circumlocution ensures we remove symlinks from TOP.
21 (cd "$TOP"; PWD= /bin/pwd)
22 else
23 if [ -f $TOPFILE ] ; then
24 # The following circumlocution (repeated below as well) ensures
25 # that we record the true directory name and not one that is
26 # faked up with symlink names.
27 PWD= /bin/pwd
28 else
29 local HERE=$PWD
30 local T=
31 while [ \( ! \( -f $TOPFILE \) \) -a \( "$PWD" != "/" \) ]; do
32 \cd ..
33 T=`PWD= /bin/pwd -P`
34 done
35 \cd "$HERE"
36 if [ -f "$T/$TOPFILE" ]; then
37 echo "$T"
38 fi
39 fi
40 fi
41}
42
Joe Onorato23124752024-05-14 15:06:48 -070043# Asserts that the root of the tree can be found.
Joe Onorato344e4042022-12-05 15:15:36 -080044if [ -z "${IMPORTING_ENVSETUP:-}" ] ; then
45function require_top
46{
47 TOP=$(gettop)
48 if [[ ! $TOP ]] ; then
Joe Onorato1b9ab292024-05-17 12:16:43 -070049 echo "Can not locate root of source tree. $(basename $0) must be run from within the Android source tree or TOP must be set." >&2
Joe Onorato344e4042022-12-05 15:15:36 -080050 exit 1
51 fi
52}
53fi
54
Joe Onorato23124752024-05-14 15:06:48 -070055# Asserts that the lunch variables have been set
56if [ -z "${IMPORTING_ENVSETUP:-}" ] ; then
57function require_lunch
58{
59 if [[ ! $TARGET_PRODUCT || ! $TARGET_RELEASE || ! $TARGET_BUILD_VARIANT ]] ; then
60 echo "Please run lunch and try again." >&2
61 exit 1
62 fi
63}
64fi
65
Sam Lewis51193302025-08-22 11:37:33 -070066function set_network_file_system_type_env_var() {
67 local top=$(gettop)
68 local out_dir=$(getoutdir)
69 local cartfs_mount_point=$(cartfs_mount_point)
70
71 local nfs_type=local
72
73 if [[ "$top" =~ ^/google/cog ]]; then
74 nfs_type=cog-symlink
75 fi
76
77 # If CartFS is mounted and the 'out' directory is a symlink pointing to a
78 # CartFS path.
79 if [[ -n "$cartfs_mount_point" && -L "$out_dir" && "$(readlink "$out_dir")" =~ ^/google/cartfs/mount ]]; then
80 nfs_type=cog-cartfs-symlink
81 fi
82
83 export NETWORK_FILE_SYSTEM_TYPE=$nfs_type
84}
85
Sam Lewis2404c4a2024-09-23 20:06:02 +000086# This function sets up the build environment to be appropriate for Cog.
87function setup_cog_env_if_needed() {
88 local top=$(gettop)
89
90 # return early if not in a cog workspace
91 if [[ ! "$top" =~ ^/google/cog ]]; then
92 return 0
93 fi
94
Martin Simard49706bf2025-07-07 10:27:00 -070095 clean_deleted_workspaces_in_cartfs
96
Sam Lewis2404c4a2024-09-23 20:06:02 +000097 setup_cog_symlink
98
99 export ANDROID_BUILD_ENVIRONMENT_CONFIG="googler-cog"
100
101 # Running repo command within Cog workspaces is not supported, so override
102 # it with this function. If the user is running repo within a Cog workspace,
103 # we'll fail with an error, otherwise, we run the original repo command with
104 # the given args.
105 if ! ORIG_REPO_PATH=`which repo`; then
106 return 0
107 fi
108 function repo {
109 if [[ "${PWD}" == /google/cog/* ]]; then
110 echo -e "\e[01;31mERROR:\e[0mrepo command is disallowed within Cog workspaces."
111 kill -INT $$ # exits the script without exiting the user's shell
112 fi
113 ${ORIG_REPO_PATH} "$@"
114 }
115}
116
117# creates a symlink for the out/ dir when inside a cog workspace.
118function setup_cog_symlink() {
119 local out_dir=$(getoutdir)
120 local top=$(gettop)
121
Sam Lewisa7939b22025-03-10 12:00:35 -0700122 # return early if out dir is already a symlink.
Sam Lewis2404c4a2024-09-23 20:06:02 +0000123 if [[ -L "$out_dir" ]]; then
Sam Lewisa7939b22025-03-10 12:00:35 -0700124 destination=$(readlink "$out_dir")
125 # ensure the destination exists.
126 mkdir -p "$destination"
Sam Lewis2404c4a2024-09-23 20:06:02 +0000127 return 0
128 fi
129
130 # return early if out dir is not in the workspace
131 if [[ ! "$out_dir" =~ ^$top/ ]]; then
132 return 0
133 fi
134
135 local link_destination="${HOME}/.cog/android-build-out"
136
Martin Simard49706bf2025-07-07 10:27:00 -0700137 # When cartfs is mounted, use it as the destination for output directory.
138 local cartfs_mount_point=$(cartfs_mount_point)
139 if [[ -n "$cartfs_mount_point" ]]; then
140 local cog_workspace_name="$(basename "$(dirname "${top}")")"
141 link_destination="${cartfs_mount_point}/${cog_workspace_name}/out"
142 fi
143
Sam Lewis1513eab2024-09-24 19:47:08 +0000144 # remove existing out/ dir if it exists
Sam Lewis2404c4a2024-09-23 20:06:02 +0000145 if [[ -d "$out_dir" ]]; then
Sam Lewis1513eab2024-09-24 19:47:08 +0000146 echo "Detected existing out/ directory in the Cog workspace which is not supported. Repairing workspace by removing it and creating the symlink to ~/.cog/android-build-out"
147 if ! rm -rf "$out_dir"; then
148 echo "Failed to remove existing out/ directory: $out_dir" >&2
Sam Lewis2404c4a2024-09-23 20:06:02 +0000149 kill -INT $$ # exits the script without exiting the user's shell
150 fi
151 fi
152
153 # create symlink
154 echo "Creating symlink: $out_dir -> $link_destination"
155 mkdir -p ${link_destination}
156 if ! ln -s "$link_destination" "$out_dir"; then
157 echo "Failed to create cog symlink: $out_dir -> $link_destination" >&2
158 kill -INT $$ # exits the script without exiting the user's shell
159 fi
160}
161
Joe Onorato344e4042022-12-05 15:15:36 -0800162function getoutdir
163{
164 local top=$(gettop)
165 local out_dir="${OUT_DIR:-}"
166 if [[ -z "${out_dir}" ]]; then
167 if [[ -n "${OUT_DIR_COMMON_BASE:-}" && -n "${top}" ]]; then
168 out_dir="${OUT_DIR_COMMON_BASE}/$(basename ${top})"
169 else
170 out_dir="out"
171 fi
172 fi
173 if [[ "${out_dir}" != /* ]]; then
174 out_dir="${top}/${out_dir}"
175 fi
176 echo "${out_dir}"
177}
178
Joe Onorato1b9ab292024-05-17 12:16:43 -0700179# Pretty print the build status and duration
180function _wrap_build()
181{
182 if [[ "${ANDROID_QUIET_BUILD:-}" == true ]]; then
183 "$@"
184 return $?
185 fi
186 local start_time=$(date +"%s")
187 "$@"
188 local ret=$?
189 local end_time=$(date +"%s")
190 local tdiff=$(($end_time-$start_time))
191 local hours=$(($tdiff / 3600 ))
192 local mins=$((($tdiff % 3600) / 60))
193 local secs=$(($tdiff % 60))
194 local ncolors=$(tput colors 2>/dev/null)
195 if [ -n "$ncolors" ] && [ $ncolors -ge 8 ]; then
196 color_failed=$'\E'"[0;31m"
197 color_success=$'\E'"[0;32m"
198 color_warning=$'\E'"[0;33m"
199 color_reset=$'\E'"[00m"
200 else
201 color_failed=""
202 color_success=""
203 color_reset=""
204 fi
205
206 echo
207 if [ $ret -eq 0 ] ; then
208 echo -n "${color_success}#### build completed successfully "
209 else
210 echo -n "${color_failed}#### failed to build some targets "
211 fi
212 if [ $hours -gt 0 ] ; then
Alexander Koskovicha20a7fb2024-10-13 21:33:23 -0400213 printf "(%02d:%02d:%02d (hh:mm:ss))" $hours $mins $secs
Joe Onorato1b9ab292024-05-17 12:16:43 -0700214 elif [ $mins -gt 0 ] ; then
Alexander Koskovicha20a7fb2024-10-13 21:33:23 -0400215 printf "(%02d:%02d (mm:ss))" $mins $secs
Joe Onorato1b9ab292024-05-17 12:16:43 -0700216 elif [ $secs -gt 0 ] ; then
Alexander Koskovicha20a7fb2024-10-13 21:33:23 -0400217 printf "(%d seconds)" $secs
Joe Onorato1b9ab292024-05-17 12:16:43 -0700218 fi
219 echo " ####${color_reset}"
220 echo
221 return $ret
222}
223
224
Joe Onorato1f6eddb2024-05-31 15:04:44 -0700225function log_tool_invocation()
226{
227 if [[ -z $ANDROID_TOOL_LOGGER ]]; then
228 return
229 fi
230
231 LOG_TOOL_TAG=$1
232 LOG_START_TIME=$(date +%s.%N)
233 trap '
234 exit_code=$?;
235 # Remove the trap to prevent duplicate log.
236 trap - EXIT;
237 $ANDROID_TOOL_LOGGER \
238 --tool_tag="${LOG_TOOL_TAG}" \
239 --start_timestamp="${LOG_START_TIME}" \
240 --end_timestamp="$(date +%s.%N)" \
241 --tool_args="$*" \
242 --exit_code="${exit_code}" \
243 ${ANDROID_TOOL_LOGGER_EXTRA_ARGS} \
244 > /dev/null 2>&1 &
245 exit ${exit_code}
246 ' SIGINT SIGTERM SIGQUIT EXIT
247}
Joe Onorato344e4042022-12-05 15:15:36 -0800248
Joe Onorato029c50a2024-12-09 09:38:01 -0800249# Import the build variables supplied as arguments into this shell's environment.
250# For absolute variables, prefix the variable name with a '/'. For example:
251# import_build_vars OUT_DIR DIST_DIR /HOST_OUT_EXECUTABLES
252# Returns nonzero if the build command failed. Stderr is passed through.
253function import_build_vars()
254{
255 require_top
256 local script
257 script=$(cd $TOP && build/soong/bin/get_build_vars "$@")
258 local ret=$?
259 if [ $ret -ne 0 ] ; then
260 return $ret
261 fi
262 eval "$script"
263 return $?
264}
Martin Simard49706bf2025-07-07 10:27:00 -0700265
266function cartfs_mount_point() {
Martin Simard96c7e3e2025-07-08 09:06:20 -0700267 local cartfs_user_id="$(id -u cartfs 2>/dev/null)"
268 local cartfs_mount_point="$(findmnt -t fuse -O "user_id=${cartfs_user_id}" | tail -n +2 | awk '{print $1}')"
269 # Making sure $cartfs_user_id is not empty since findmnt will return mounts
270 # started by root when it is.
271 if [[ -n "$cartfs_user_id" ]] && [[ -n "$cartfs_mount_point" ]] && findmnt "$cartfs_mount_point" >/dev/null 2>&1; then
Martin Simard49706bf2025-07-07 10:27:00 -0700272 echo "$cartfs_mount_point"
Martin Simard49706bf2025-07-07 10:27:00 -0700273 fi
274}
275
276# Deletes cartfs folders that are mapped to deleted workspaces.
277function clean_deleted_workspaces_in_cartfs() {
278 local cartfs_mount_point=$(cartfs_mount_point)
279 if [[ -n "$cartfs_mount_point" ]]; then
280 local folders_list
281 folders_list=$(find "$cartfs_mount_point" -maxdepth 1 -type d)
282 if [[ -n "$folders_list" ]]; then
Martin Simard96c7e3e2025-07-08 09:06:20 -0700283 local log_file="${HOME}/.cartfs/cartfs_workspace_deletion.log"
284 mkdir -p "$(dirname "${log_file}")"
Martin Simard49706bf2025-07-07 10:27:00 -0700285 while read -r folder; do
286 if [[ "$folder" != "$cartfs_mount_point" ]]; then
287 local workspace_name="$(basename "${folder}")"
288 local workspaces_path="$(dirname "$(dirname "${top}")")"
289 local full_path="${workspaces_path}/${workspace_name}"
290 if [[ ! -d "${full_path}" ]]; then
Martin Simard96c7e3e2025-07-08 09:06:20 -0700291 local log_timestamp=$(date +"%Y-%m-%d %H:%M:%S")
292 echo "${log_timestamp}: The workspace ${workspace_name} does not exist, deleting ${folder} from cartfs" >> "${log_file}"
Martin Simard49706bf2025-07-07 10:27:00 -0700293 rm -Rf "${folder}"
294 fi
295 fi
296 done <<< "$folders_list"
297 fi
298 fi
299}