1*9e94795aSAndroid Build Coastguard Worker# Copyright (C) 2022 The Android Open Source Project 2*9e94795aSAndroid Build Coastguard Worker# 3*9e94795aSAndroid Build Coastguard Worker# Licensed under the Apache License, Version 2.0 (the "License"); 4*9e94795aSAndroid Build Coastguard Worker# you may not use this file except in compliance with the License. 5*9e94795aSAndroid Build Coastguard Worker# You may obtain a copy of the License at 6*9e94795aSAndroid Build Coastguard Worker# 7*9e94795aSAndroid Build Coastguard Worker# http://www.apache.org/licenses/LICENSE-2.0 8*9e94795aSAndroid Build Coastguard Worker# 9*9e94795aSAndroid Build Coastguard Worker# Unless required by applicable law or agreed to in writing, software 10*9e94795aSAndroid Build Coastguard Worker# distributed under the License is distributed on an "AS IS" BASIS, 11*9e94795aSAndroid Build Coastguard Worker# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12*9e94795aSAndroid Build Coastguard Worker# See the License for the specific language governing permissions and 13*9e94795aSAndroid Build Coastguard Worker# limitations under the License. 14*9e94795aSAndroid Build Coastguard Worker 15*9e94795aSAndroid Build Coastguard Workerfunction gettop 16*9e94795aSAndroid Build Coastguard Worker{ 17*9e94795aSAndroid Build Coastguard Worker local TOPFILE=build/make/core/envsetup.mk 18*9e94795aSAndroid Build Coastguard Worker # The ${TOP-} expansion allows this to work even with set -u 19*9e94795aSAndroid Build Coastguard Worker if [ -n "${TOP:-}" -a -f "${TOP:-}/$TOPFILE" ] ; then 20*9e94795aSAndroid Build Coastguard Worker # The following circumlocution ensures we remove symlinks from TOP. 21*9e94795aSAndroid Build Coastguard Worker (cd "$TOP"; PWD= /bin/pwd) 22*9e94795aSAndroid Build Coastguard Worker else 23*9e94795aSAndroid Build Coastguard Worker if [ -f $TOPFILE ] ; then 24*9e94795aSAndroid Build Coastguard Worker # The following circumlocution (repeated below as well) ensures 25*9e94795aSAndroid Build Coastguard Worker # that we record the true directory name and not one that is 26*9e94795aSAndroid Build Coastguard Worker # faked up with symlink names. 27*9e94795aSAndroid Build Coastguard Worker PWD= /bin/pwd 28*9e94795aSAndroid Build Coastguard Worker else 29*9e94795aSAndroid Build Coastguard Worker local HERE=$PWD 30*9e94795aSAndroid Build Coastguard Worker local T= 31*9e94795aSAndroid Build Coastguard Worker while [ \( ! \( -f $TOPFILE \) \) -a \( "$PWD" != "/" \) ]; do 32*9e94795aSAndroid Build Coastguard Worker \cd .. 33*9e94795aSAndroid Build Coastguard Worker T=`PWD= /bin/pwd -P` 34*9e94795aSAndroid Build Coastguard Worker done 35*9e94795aSAndroid Build Coastguard Worker \cd "$HERE" 36*9e94795aSAndroid Build Coastguard Worker if [ -f "$T/$TOPFILE" ]; then 37*9e94795aSAndroid Build Coastguard Worker echo "$T" 38*9e94795aSAndroid Build Coastguard Worker fi 39*9e94795aSAndroid Build Coastguard Worker fi 40*9e94795aSAndroid Build Coastguard Worker fi 41*9e94795aSAndroid Build Coastguard Worker} 42*9e94795aSAndroid Build Coastguard Worker 43*9e94795aSAndroid Build Coastguard Worker# Asserts that the root of the tree can be found. 44*9e94795aSAndroid Build Coastguard Workerif [ -z "${IMPORTING_ENVSETUP:-}" ] ; then 45*9e94795aSAndroid Build Coastguard Workerfunction require_top 46*9e94795aSAndroid Build Coastguard Worker{ 47*9e94795aSAndroid Build Coastguard Worker TOP=$(gettop) 48*9e94795aSAndroid Build Coastguard Worker if [[ ! $TOP ]] ; then 49*9e94795aSAndroid Build Coastguard Worker 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*9e94795aSAndroid Build Coastguard Worker exit 1 51*9e94795aSAndroid Build Coastguard Worker fi 52*9e94795aSAndroid Build Coastguard Worker} 53*9e94795aSAndroid Build Coastguard Workerfi 54*9e94795aSAndroid Build Coastguard Worker 55*9e94795aSAndroid Build Coastguard Worker# Asserts that the lunch variables have been set 56*9e94795aSAndroid Build Coastguard Workerif [ -z "${IMPORTING_ENVSETUP:-}" ] ; then 57*9e94795aSAndroid Build Coastguard Workerfunction require_lunch 58*9e94795aSAndroid Build Coastguard Worker{ 59*9e94795aSAndroid Build Coastguard Worker if [[ ! $TARGET_PRODUCT || ! $TARGET_RELEASE || ! $TARGET_BUILD_VARIANT ]] ; then 60*9e94795aSAndroid Build Coastguard Worker echo "Please run lunch and try again." >&2 61*9e94795aSAndroid Build Coastguard Worker exit 1 62*9e94795aSAndroid Build Coastguard Worker fi 63*9e94795aSAndroid Build Coastguard Worker} 64*9e94795aSAndroid Build Coastguard Workerfi 65*9e94795aSAndroid Build Coastguard Worker 66*9e94795aSAndroid Build Coastguard Worker# This function sets up the build environment to be appropriate for Cog. 67*9e94795aSAndroid Build Coastguard Workerfunction setup_cog_env_if_needed() { 68*9e94795aSAndroid Build Coastguard Worker local top=$(gettop) 69*9e94795aSAndroid Build Coastguard Worker 70*9e94795aSAndroid Build Coastguard Worker # return early if not in a cog workspace 71*9e94795aSAndroid Build Coastguard Worker if [[ ! "$top" =~ ^/google/cog ]]; then 72*9e94795aSAndroid Build Coastguard Worker return 0 73*9e94795aSAndroid Build Coastguard Worker fi 74*9e94795aSAndroid Build Coastguard Worker 75*9e94795aSAndroid Build Coastguard Worker setup_cog_symlink 76*9e94795aSAndroid Build Coastguard Worker 77*9e94795aSAndroid Build Coastguard Worker export ANDROID_BUILD_ENVIRONMENT_CONFIG="googler-cog" 78*9e94795aSAndroid Build Coastguard Worker 79*9e94795aSAndroid Build Coastguard Worker # Running repo command within Cog workspaces is not supported, so override 80*9e94795aSAndroid Build Coastguard Worker # it with this function. If the user is running repo within a Cog workspace, 81*9e94795aSAndroid Build Coastguard Worker # we'll fail with an error, otherwise, we run the original repo command with 82*9e94795aSAndroid Build Coastguard Worker # the given args. 83*9e94795aSAndroid Build Coastguard Worker if ! ORIG_REPO_PATH=`which repo`; then 84*9e94795aSAndroid Build Coastguard Worker return 0 85*9e94795aSAndroid Build Coastguard Worker fi 86*9e94795aSAndroid Build Coastguard Worker function repo { 87*9e94795aSAndroid Build Coastguard Worker if [[ "${PWD}" == /google/cog/* ]]; then 88*9e94795aSAndroid Build Coastguard Worker echo -e "\e[01;31mERROR:\e[0mrepo command is disallowed within Cog workspaces." 89*9e94795aSAndroid Build Coastguard Worker kill -INT $$ # exits the script without exiting the user's shell 90*9e94795aSAndroid Build Coastguard Worker fi 91*9e94795aSAndroid Build Coastguard Worker ${ORIG_REPO_PATH} "$@" 92*9e94795aSAndroid Build Coastguard Worker } 93*9e94795aSAndroid Build Coastguard Worker} 94*9e94795aSAndroid Build Coastguard Worker 95*9e94795aSAndroid Build Coastguard Worker# creates a symlink for the out/ dir when inside a cog workspace. 96*9e94795aSAndroid Build Coastguard Workerfunction setup_cog_symlink() { 97*9e94795aSAndroid Build Coastguard Worker local out_dir=$(getoutdir) 98*9e94795aSAndroid Build Coastguard Worker local top=$(gettop) 99*9e94795aSAndroid Build Coastguard Worker 100*9e94795aSAndroid Build Coastguard Worker # return early if out dir is already a symlink 101*9e94795aSAndroid Build Coastguard Worker if [[ -L "$out_dir" ]]; then 102*9e94795aSAndroid Build Coastguard Worker return 0 103*9e94795aSAndroid Build Coastguard Worker fi 104*9e94795aSAndroid Build Coastguard Worker 105*9e94795aSAndroid Build Coastguard Worker # return early if out dir is not in the workspace 106*9e94795aSAndroid Build Coastguard Worker if [[ ! "$out_dir" =~ ^$top/ ]]; then 107*9e94795aSAndroid Build Coastguard Worker return 0 108*9e94795aSAndroid Build Coastguard Worker fi 109*9e94795aSAndroid Build Coastguard Worker 110*9e94795aSAndroid Build Coastguard Worker local link_destination="${HOME}/.cog/android-build-out" 111*9e94795aSAndroid Build Coastguard Worker 112*9e94795aSAndroid Build Coastguard Worker # remove existing out/ dir if it exists 113*9e94795aSAndroid Build Coastguard Worker if [[ -d "$out_dir" ]]; then 114*9e94795aSAndroid Build Coastguard Worker 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" 115*9e94795aSAndroid Build Coastguard Worker if ! rm -rf "$out_dir"; then 116*9e94795aSAndroid Build Coastguard Worker echo "Failed to remove existing out/ directory: $out_dir" >&2 117*9e94795aSAndroid Build Coastguard Worker kill -INT $$ # exits the script without exiting the user's shell 118*9e94795aSAndroid Build Coastguard Worker fi 119*9e94795aSAndroid Build Coastguard Worker fi 120*9e94795aSAndroid Build Coastguard Worker 121*9e94795aSAndroid Build Coastguard Worker # create symlink 122*9e94795aSAndroid Build Coastguard Worker echo "Creating symlink: $out_dir -> $link_destination" 123*9e94795aSAndroid Build Coastguard Worker mkdir -p ${link_destination} 124*9e94795aSAndroid Build Coastguard Worker if ! ln -s "$link_destination" "$out_dir"; then 125*9e94795aSAndroid Build Coastguard Worker echo "Failed to create cog symlink: $out_dir -> $link_destination" >&2 126*9e94795aSAndroid Build Coastguard Worker kill -INT $$ # exits the script without exiting the user's shell 127*9e94795aSAndroid Build Coastguard Worker fi 128*9e94795aSAndroid Build Coastguard Worker} 129*9e94795aSAndroid Build Coastguard Worker 130*9e94795aSAndroid Build Coastguard Workerfunction getoutdir 131*9e94795aSAndroid Build Coastguard Worker{ 132*9e94795aSAndroid Build Coastguard Worker local top=$(gettop) 133*9e94795aSAndroid Build Coastguard Worker local out_dir="${OUT_DIR:-}" 134*9e94795aSAndroid Build Coastguard Worker if [[ -z "${out_dir}" ]]; then 135*9e94795aSAndroid Build Coastguard Worker if [[ -n "${OUT_DIR_COMMON_BASE:-}" && -n "${top}" ]]; then 136*9e94795aSAndroid Build Coastguard Worker out_dir="${OUT_DIR_COMMON_BASE}/$(basename ${top})" 137*9e94795aSAndroid Build Coastguard Worker else 138*9e94795aSAndroid Build Coastguard Worker out_dir="out" 139*9e94795aSAndroid Build Coastguard Worker fi 140*9e94795aSAndroid Build Coastguard Worker fi 141*9e94795aSAndroid Build Coastguard Worker if [[ "${out_dir}" != /* ]]; then 142*9e94795aSAndroid Build Coastguard Worker out_dir="${top}/${out_dir}" 143*9e94795aSAndroid Build Coastguard Worker fi 144*9e94795aSAndroid Build Coastguard Worker echo "${out_dir}" 145*9e94795aSAndroid Build Coastguard Worker} 146*9e94795aSAndroid Build Coastguard Worker 147*9e94795aSAndroid Build Coastguard Worker# Pretty print the build status and duration 148*9e94795aSAndroid Build Coastguard Workerfunction _wrap_build() 149*9e94795aSAndroid Build Coastguard Worker{ 150*9e94795aSAndroid Build Coastguard Worker if [[ "${ANDROID_QUIET_BUILD:-}" == true ]]; then 151*9e94795aSAndroid Build Coastguard Worker "$@" 152*9e94795aSAndroid Build Coastguard Worker return $? 153*9e94795aSAndroid Build Coastguard Worker fi 154*9e94795aSAndroid Build Coastguard Worker local start_time=$(date +"%s") 155*9e94795aSAndroid Build Coastguard Worker "$@" 156*9e94795aSAndroid Build Coastguard Worker local ret=$? 157*9e94795aSAndroid Build Coastguard Worker local end_time=$(date +"%s") 158*9e94795aSAndroid Build Coastguard Worker local tdiff=$(($end_time-$start_time)) 159*9e94795aSAndroid Build Coastguard Worker local hours=$(($tdiff / 3600 )) 160*9e94795aSAndroid Build Coastguard Worker local mins=$((($tdiff % 3600) / 60)) 161*9e94795aSAndroid Build Coastguard Worker local secs=$(($tdiff % 60)) 162*9e94795aSAndroid Build Coastguard Worker local ncolors=$(tput colors 2>/dev/null) 163*9e94795aSAndroid Build Coastguard Worker if [ -n "$ncolors" ] && [ $ncolors -ge 8 ]; then 164*9e94795aSAndroid Build Coastguard Worker color_failed=$'\E'"[0;31m" 165*9e94795aSAndroid Build Coastguard Worker color_success=$'\E'"[0;32m" 166*9e94795aSAndroid Build Coastguard Worker color_warning=$'\E'"[0;33m" 167*9e94795aSAndroid Build Coastguard Worker color_reset=$'\E'"[00m" 168*9e94795aSAndroid Build Coastguard Worker else 169*9e94795aSAndroid Build Coastguard Worker color_failed="" 170*9e94795aSAndroid Build Coastguard Worker color_success="" 171*9e94795aSAndroid Build Coastguard Worker color_reset="" 172*9e94795aSAndroid Build Coastguard Worker fi 173*9e94795aSAndroid Build Coastguard Worker 174*9e94795aSAndroid Build Coastguard Worker echo 175*9e94795aSAndroid Build Coastguard Worker if [ $ret -eq 0 ] ; then 176*9e94795aSAndroid Build Coastguard Worker echo -n "${color_success}#### build completed successfully " 177*9e94795aSAndroid Build Coastguard Worker else 178*9e94795aSAndroid Build Coastguard Worker echo -n "${color_failed}#### failed to build some targets " 179*9e94795aSAndroid Build Coastguard Worker fi 180*9e94795aSAndroid Build Coastguard Worker if [ $hours -gt 0 ] ; then 181*9e94795aSAndroid Build Coastguard Worker printf "(%02d:%02d:%02d (hh:mm:ss))" $hours $mins $secs 182*9e94795aSAndroid Build Coastguard Worker elif [ $mins -gt 0 ] ; then 183*9e94795aSAndroid Build Coastguard Worker printf "(%02d:%02d (mm:ss))" $mins $secs 184*9e94795aSAndroid Build Coastguard Worker elif [ $secs -gt 0 ] ; then 185*9e94795aSAndroid Build Coastguard Worker printf "(%d seconds)" $secs 186*9e94795aSAndroid Build Coastguard Worker fi 187*9e94795aSAndroid Build Coastguard Worker echo " ####${color_reset}" 188*9e94795aSAndroid Build Coastguard Worker echo 189*9e94795aSAndroid Build Coastguard Worker return $ret 190*9e94795aSAndroid Build Coastguard Worker} 191*9e94795aSAndroid Build Coastguard Worker 192*9e94795aSAndroid Build Coastguard Worker 193*9e94795aSAndroid Build Coastguard Workerfunction log_tool_invocation() 194*9e94795aSAndroid Build Coastguard Worker{ 195*9e94795aSAndroid Build Coastguard Worker if [[ -z $ANDROID_TOOL_LOGGER ]]; then 196*9e94795aSAndroid Build Coastguard Worker return 197*9e94795aSAndroid Build Coastguard Worker fi 198*9e94795aSAndroid Build Coastguard Worker 199*9e94795aSAndroid Build Coastguard Worker LOG_TOOL_TAG=$1 200*9e94795aSAndroid Build Coastguard Worker LOG_START_TIME=$(date +%s.%N) 201*9e94795aSAndroid Build Coastguard Worker trap ' 202*9e94795aSAndroid Build Coastguard Worker exit_code=$?; 203*9e94795aSAndroid Build Coastguard Worker # Remove the trap to prevent duplicate log. 204*9e94795aSAndroid Build Coastguard Worker trap - EXIT; 205*9e94795aSAndroid Build Coastguard Worker $ANDROID_TOOL_LOGGER \ 206*9e94795aSAndroid Build Coastguard Worker --tool_tag="${LOG_TOOL_TAG}" \ 207*9e94795aSAndroid Build Coastguard Worker --start_timestamp="${LOG_START_TIME}" \ 208*9e94795aSAndroid Build Coastguard Worker --end_timestamp="$(date +%s.%N)" \ 209*9e94795aSAndroid Build Coastguard Worker --tool_args="$*" \ 210*9e94795aSAndroid Build Coastguard Worker --exit_code="${exit_code}" \ 211*9e94795aSAndroid Build Coastguard Worker ${ANDROID_TOOL_LOGGER_EXTRA_ARGS} \ 212*9e94795aSAndroid Build Coastguard Worker > /dev/null 2>&1 & 213*9e94795aSAndroid Build Coastguard Worker exit ${exit_code} 214*9e94795aSAndroid Build Coastguard Worker ' SIGINT SIGTERM SIGQUIT EXIT 215*9e94795aSAndroid Build Coastguard Worker} 216*9e94795aSAndroid Build Coastguard Worker 217