• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# 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
43# Asserts that the root of the tree can be found.
44if [ -z "${IMPORTING_ENVSETUP:-}" ] ; then
45function require_top
46{
47    TOP=$(gettop)
48    if [[ ! $TOP ]] ; then
49        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
50        exit 1
51    fi
52}
53fi
54
55# 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
66# This function sets up the build environment to be appropriate for Cog.
67function setup_cog_env_if_needed() {
68  local top=$(gettop)
69
70  # return early if not in a cog workspace
71  if [[ ! "$top" =~ ^/google/cog ]]; then
72    return 0
73  fi
74
75  setup_cog_symlink
76
77  export ANDROID_BUILD_ENVIRONMENT_CONFIG="googler-cog"
78
79  # Running repo command within Cog workspaces is not supported, so override
80  # it with this function. If the user is running repo within a Cog workspace,
81  # we'll fail with an error, otherwise, we run the original repo command with
82  # the given args.
83  if ! ORIG_REPO_PATH=`which repo`; then
84    return 0
85  fi
86  function repo {
87    if [[ "${PWD}" == /google/cog/* ]]; then
88      echo -e "\e[01;31mERROR:\e[0mrepo command is disallowed within Cog workspaces."
89      kill -INT $$ # exits the script without exiting the user's shell
90    fi
91    ${ORIG_REPO_PATH} "$@"
92  }
93}
94
95# creates a symlink for the out/ dir when inside a cog workspace.
96function setup_cog_symlink() {
97  local out_dir=$(getoutdir)
98  local top=$(gettop)
99
100  # return early if out dir is already a symlink.
101  if [[ -L "$out_dir" ]]; then
102    destination=$(readlink "$out_dir")
103    # ensure the destination exists.
104    mkdir -p "$destination"
105    return 0
106  fi
107
108  # return early if out dir is not in the workspace
109  if [[ ! "$out_dir" =~ ^$top/ ]]; then
110    return 0
111  fi
112
113  local link_destination="${HOME}/.cog/android-build-out"
114
115  # remove existing out/ dir if it exists
116  if [[ -d "$out_dir" ]]; then
117    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"
118    if ! rm -rf "$out_dir"; then
119      echo "Failed to remove existing out/ directory: $out_dir" >&2
120      kill -INT $$ # exits the script without exiting the user's shell
121    fi
122  fi
123
124  # create symlink
125  echo "Creating symlink: $out_dir -> $link_destination"
126  mkdir -p ${link_destination}
127  if ! ln -s "$link_destination" "$out_dir"; then
128    echo "Failed to create cog symlink: $out_dir -> $link_destination" >&2
129    kill -INT $$ # exits the script without exiting the user's shell
130  fi
131}
132
133function getoutdir
134{
135    local top=$(gettop)
136    local out_dir="${OUT_DIR:-}"
137    if [[ -z "${out_dir}" ]]; then
138        if [[ -n "${OUT_DIR_COMMON_BASE:-}" && -n "${top}" ]]; then
139            out_dir="${OUT_DIR_COMMON_BASE}/$(basename ${top})"
140        else
141            out_dir="out"
142        fi
143    fi
144    if [[ "${out_dir}" != /* ]]; then
145        out_dir="${top}/${out_dir}"
146    fi
147    echo "${out_dir}"
148}
149
150# Pretty print the build status and duration
151function _wrap_build()
152{
153    if [[ "${ANDROID_QUIET_BUILD:-}" == true ]]; then
154      "$@"
155      return $?
156    fi
157    local start_time=$(date +"%s")
158    "$@"
159    local ret=$?
160    local end_time=$(date +"%s")
161    local tdiff=$(($end_time-$start_time))
162    local hours=$(($tdiff / 3600 ))
163    local mins=$((($tdiff % 3600) / 60))
164    local secs=$(($tdiff % 60))
165    local ncolors=$(tput colors 2>/dev/null)
166    if [ -n "$ncolors" ] && [ $ncolors -ge 8 ]; then
167        color_failed=$'\E'"[0;31m"
168        color_success=$'\E'"[0;32m"
169        color_warning=$'\E'"[0;33m"
170        color_reset=$'\E'"[00m"
171    else
172        color_failed=""
173        color_success=""
174        color_reset=""
175    fi
176
177    echo
178    if [ $ret -eq 0 ] ; then
179        echo -n "${color_success}#### build completed successfully "
180    else
181        echo -n "${color_failed}#### failed to build some targets "
182    fi
183    if [ $hours -gt 0 ] ; then
184        printf "(%02d:%02d:%02d (hh:mm:ss))" $hours $mins $secs
185    elif [ $mins -gt 0 ] ; then
186        printf "(%02d:%02d (mm:ss))" $mins $secs
187    elif [ $secs -gt 0 ] ; then
188        printf "(%d seconds)" $secs
189    fi
190    echo " ####${color_reset}"
191    echo
192    return $ret
193}
194
195
196function log_tool_invocation()
197{
198    if [[ -z $ANDROID_TOOL_LOGGER ]]; then
199        return
200    fi
201
202    LOG_TOOL_TAG=$1
203    LOG_START_TIME=$(date +%s.%N)
204    trap '
205        exit_code=$?;
206        # Remove the trap to prevent duplicate log.
207        trap - EXIT;
208        $ANDROID_TOOL_LOGGER \
209                --tool_tag="${LOG_TOOL_TAG}" \
210                --start_timestamp="${LOG_START_TIME}" \
211                --end_timestamp="$(date +%s.%N)" \
212                --tool_args="$*" \
213                --exit_code="${exit_code}" \
214                ${ANDROID_TOOL_LOGGER_EXTRA_ARGS} \
215           > /dev/null 2>&1 &
216        exit ${exit_code}
217    ' SIGINT SIGTERM SIGQUIT EXIT
218}
219
220# Import the build variables supplied as arguments into this shell's environment.
221# For absolute variables, prefix the variable name with a '/'. For example:
222#    import_build_vars OUT_DIR DIST_DIR /HOST_OUT_EXECUTABLES
223# Returns nonzero if the build command failed. Stderr is passed through.
224function import_build_vars()
225{
226    require_top
227    local script
228    script=$(cd $TOP && build/soong/bin/get_build_vars "$@")
229    local ret=$?
230    if [ $ret -ne 0 ] ; then
231        return $ret
232    fi
233    eval "$script"
234    return $?
235}
236