1#!/bin/bash -e 2# 3# Copyright (C) 2023 The Android Open Source Project 4# 5# Licensed under the Apache License, Version 2.0 (the "License"); 6# you may not use this file except in compliance with the License. 7# You may obtain a copy of the License at 8# 9# http://www.apache.org/licenses/LICENSE-2.0 10# 11# Unless required by applicable law or agreed to in writing, software 12# distributed under the License is distributed on an "AS IS" BASIS, 13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14# See the License for the specific language governing permissions and 15# limitations under the License. 16 17usage() { 18 echo "usage: ${0} -t TARGET -v VARIANT [-d DIST_OUT] [[-a ALTER_TARGET] ...] [-c] [-o] [-r] [GOALS ...]" 19 echo " -t TARGET : Primay target to build" 20 echo " -v VARIANT : Build variant (ex. user, userdebug)" 21 echo " -d DIST_OUT : Path for dist out" 22 echo " -a ALTER_TARGET: Alternative targets that share the build artifacts with the primary target" 23 echo " -c : Run the target build again after installclean for reference" 24 echo ' -o : Write build time ("build_time_results.txt") and disk usage results (disk_size_results.txt") to "${OUT_DIR}" or "${DIST_OUT}/logs" if -d defined' 25 echo " -r : Dryrun to see the commands without actually building the targets" 26} 27 28while getopts ha:cd:ort:v: opt; do 29 case "${opt}" in 30 h) 31 usage 32 ;; 33 a) 34 alter_targets+=("${OPTARG}") 35 ;; 36 c) 37 installclean="true" 38 ;; 39 d) 40 dist_dir="${OPTARG}" 41 ;; 42 o) 43 result_out="build_time_results.txt" 44 result_out_size="disk_size_results.txt" 45 ;; 46 r) 47 dry_run="true" 48 ;; 49 t) 50 target="${OPTARG}" 51 ;; 52 v) 53 variant="${OPTARG}" 54 ;; 55 *) 56 usage 57 ;; 58 esac 59done 60 61if [[ -z "${target}" ]]; then 62 echo "-t must set for the primary target" 63 usage 64 exit 1 65fi 66if [[ -z "${variant}" ]]; then 67 echo "-v must set for build variant" 68 usage 69 exit 1 70fi 71if [ "${#alter_targets[@]}" -eq 1 ]; then 72 # test for a-b-a builds 73 alter_targets+=("${target}") 74fi 75 76goals="${@:OPTIND}" 77 78readonly ANDROID_TOP="$(cd $(dirname $0)/../..; pwd)" 79cd "${ANDROID_TOP}" 80 81out_dir="${OUT_DIR:-out}" 82if [[ -n "${dist_dir}" ]]; then 83 out_dir="${dist_dir}/logs" 84fi 85 86base_command="build/soong/soong_ui.bash --make-mode TARGET_RELEASE=trunk_staging" 87if [[ -n "${dist_dir}" ]]; then 88 base_command="${base_command} DIST_DIR=${dist_dir} dist" 89fi 90 91run_command() { 92 echo "**Running: ${1}" 93 if [[ -z "${dry_run}" ]]; then 94 eval "${1}" 95 fi 96} 97 98read_df() { 99 # read the available disk size 100 df -k . | awk '{print $4}' | sed -n '2p' 101} 102 103write_output() { 104 if [[ -z "$2" || -n "${dry_run}" ]]; then 105 echo "Output: $1" 106 else 107 echo "$1" >> "${out_dir}/$2" 108 fi 109} 110 111get_build_trace() { 112 run_command "cp -f ${out_dir}/build.trace.gz ${out_dir}/${1}" 113 if [[ -n "${result_out}" ]]; then 114 write_output "$(python3 development/treble/read_build_trace_gz.py ${out_dir}/${1})" "${result_out}" 115 fi 116} 117 118if [[ -n "${result_out}" ]]; then 119 run_command "rm -f ${out_dir}/${result_out}" 120 write_output "target, soong, kati, ninja, total" "${result_out}" 121fi 122 123if [[ -n "${result_out_size}" ]]; then 124 run_command "rm -f ${out_dir}/${result_out_size}" 125 write_output "target, size, size_after_clean" "${result_out_size}" 126fi 127 128# Build the target first. 129disk_space_source=$(read_df) 130echo; echo "Initial build..." 131run_command "${base_command} TARGET_PRODUCT=${target} TARGET_BUILD_VARIANT=${variant} ${goals}" 132size_primary=$((${disk_space_source}-$(read_df))) 133 134if [[ -n "${installclean}" ]]; then 135 # Run the same build after installclean 136 echo; echo "Installclean for incremental build..." 137 run_command "${base_command} TARGET_PRODUCT=${target} TARGET_BUILD_VARIANT=${variant} installclean" 138 size_primary_clean=$((${disk_space_source}-$(read_df))) 139 write_output "${target}, ${size_primary}, ${size_primary_clean}" "${result_out_size}" 140 141 echo "Build the same initial build..." 142 run_command "${base_command} TARGET_PRODUCT=${target} TARGET_BUILD_VARIANT=${variant} NINJA_ARGS=\"-d explain\" ${goals}" 143 get_build_trace "build_${target}_installclean.trace.gz" 144 echo "Installclean to prepare for the next build..." 145 run_command "${base_command} TARGET_PRODUCT=${target} TARGET_BUILD_VARIANT=${variant} installclean" 146fi 147 148count=0 149# Building the next targets in sequence 150for alter_target in "${alter_targets[@]}"; do 151 count=$((${count}+1)) 152 echo; echo "Build ${alter_target}...(${count})" 153 run_command "${base_command} TARGET_PRODUCT=${alter_target} TARGET_BUILD_VARIANT=${variant} NINJA_ARGS=\"-d explain\" ${goals}" 154 size_alter=$((${disk_space_source}-$(read_df))) 155 get_build_trace "build_${alter_target}_ab${count}.trace.gz" 156 157 echo "Installclean for ${alter_target}..." 158 run_command "${base_command} TARGET_PRODUCT=${alter_target} TARGET_BUILD_VARIANT=${variant} installclean" 159 size_alter_clean=$((${disk_space_source}-$(read_df))) 160 write_output "${alter_target}, ${size_alter}, ${size_alter_clean}" "${result_out_size}" 161 162 if [[ -n "${dist_dir}" ]]; then 163 # Remove target-specific dist artifacts 164 run_command "rm -f ${dist_dir}/${alter_target}*" 165 fi 166done 167 168if [[ -n "${dist_dir}" ]]; then 169 # Remove some dist artifacts to save disk space 170 run_command "rm -f ${dist_dir}/${target}*" 171 run_command "rm -f ${dist_dir}/device-tests*" 172 run_command "rm -f ${dist_dir}/cvd-host_package.tar.gz" 173 run_command "rm -f ${dist_dir}/dexpreopt_tools.zip" 174 run_command "rm -f ${dist_dir}/otatools.zip" 175fi 176