1#! /bin/bash 2# 3# Copyright (C) 2015 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 17set -e 18 19. "$(dirname $0)/buildbot-utils.sh" 20 21shopt -s failglob 22 23if [ ! -d art ]; then 24 msgerror "Script needs to be run at the root of the Android tree" 25 exit 1 26fi 27 28# Logic for setting out_dir from build/make/core/envsetup.mk: 29if [[ -z $OUT_DIR ]]; then 30 if [[ -z $OUT_DIR_COMMON_BASE ]]; then 31 out_dir=out 32 else 33 out_dir=${OUT_DIR_COMMON_BASE}/${PWD##*/} 34 fi 35else 36 out_dir=${OUT_DIR} 37fi 38 39java_libraries_dir=${out_dir}/target/common/obj/JAVA_LIBRARIES 40common_targets="vogar core-tests core-ojtests apache-harmony-jdwp-tests-hostdex jsr166-tests libartpalette-system mockito-target" 41# These build targets have different names on device and host. 42specific_targets="libjavacoretests libwrapagentproperties libwrapagentpropertiesd" 43build_host="no" 44build_target="no" 45installclean="no" 46skip_run_tests_build="no" 47j_arg="-j$(nproc)" 48showcommands= 49make_command= 50 51while true; do 52 if [[ "$1" == "--host" ]]; then 53 build_host="yes" 54 shift 55 elif [[ "$1" == "--target" ]]; then 56 build_target="yes" 57 shift 58 elif [[ "$1" == "--installclean" ]]; then 59 installclean="yes" 60 shift 61 elif [[ "$1" == "--skip-run-tests-build" ]]; then 62 skip_run_tests_build="yes" 63 shift 64 elif [[ "$1" == -j* ]]; then 65 j_arg=$1 66 shift 67 elif [[ "$1" == "--showcommands" ]]; then 68 showcommands="showcommands" 69 shift 70 elif [[ "$1" == "--dist" ]]; then 71 common_targets="$common_targets dist" 72 shift 73 elif [[ "$1" == "" ]]; then 74 break 75 else 76 msgerror "Unknown options: $@" 77 exit 1 78 fi 79done 80 81# If neither was selected, build both by default. 82if [[ $build_host == "no" ]] && [[ $build_target == "no" ]]; then 83 build_host="yes" 84 build_target="yes" 85fi 86 87implementation_libs=( 88 "heapprofd_client_api" 89 "libandroid_runtime_lazy" 90 "libartpalette-system" 91 "libbinder" 92 "libbinder_ndk" 93 "libcutils" 94 "libutils" 95 "libvndksupport" 96) 97 98if [ -d frameworks/base ]; then 99 # In full manifest branches, build the implementation libraries from source 100 # instead of using prebuilts. 101 common_targets="$common_targets ${implementation_libs[*]}" 102else 103 # Allow to build successfully in master-art. 104 extra_args="SOONG_ALLOW_MISSING_DEPENDENCIES=true BUILD_BROKEN_DISABLE_BAZEL=true" 105 # Switch the build system to unbundled mode in the reduced manifest branch. 106 extra_args="$extra_args TARGET_BUILD_UNBUNDLED=true" 107fi 108 109apexes=( 110 "com.android.art.testing" 111 "com.android.conscrypt" 112 "com.android.i18n" 113 "com.android.runtime" 114 "com.android.tzdata" 115 "com.android.os.statsd" 116) 117 118make_command="build/soong/soong_ui.bash --make-mode $j_arg $extra_args $showcommands $common_targets" 119if [[ $build_host == "yes" ]]; then 120 make_command+=" build-art-host-gtests" 121 test $skip_run_tests_build == "yes" || make_command+=" build-art-host-run-tests" 122 make_command+=" dx-tests junit-host libjdwp-host" 123 for LIB in ${specific_targets} ; do 124 make_command+=" $LIB-host" 125 done 126fi 127if [[ $build_target == "yes" ]]; then 128 if [[ -z "${ANDROID_PRODUCT_OUT}" ]]; then 129 msgerror 'ANDROID_PRODUCT_OUT environment variable is empty; did you forget to run `lunch`?' 130 exit 1 131 fi 132 make_command+=" build-art-target-gtests" 133 test $skip_run_tests_build == "yes" || make_command+=" build-art-target-run-tests" 134 make_command+=" debuggerd sh su toybox" 135 # Indirect dependencies in the platform, e.g. through heapprofd_client_api. 136 # These are built to go into system/lib(64) to be part of the system linker 137 # namespace. 138 make_command+=" libnetd_client-target libprocinfo libtombstoned_client libunwindstack" 139 # Stubs for other APEX SDKs, for use by vogar. Referenced from DEVICE_JARS in 140 # external/vogar/src/vogar/ModeId.java. 141 # Note these go into out/target/common/obj/JAVA_LIBRARIES which isn't removed 142 # by "m installclean". 143 make_command+=" i18n.module.public.api.stubs conscrypt.module.public.api.stubs" 144 # Targets required to generate a linker configuration for device within the 145 # chroot environment. The *.libraries.txt targets are required by 146 # the source linkerconfig but not included in the prebuilt one. 147 make_command+=" linkerconfig conv_linker_config sanitizer.libraries.txt vndkcorevariant.libraries.txt" 148 # Additional targets needed for the chroot environment. 149 make_command+=" event-log-tags" 150 # Needed to extract prebuilt APEXes. 151 make_command+=" deapexer" 152 # Needed to generate the primary boot image for testing. 153 make_command+=" generate-boot-image" 154 # Build/install the required APEXes. 155 make_command+=" ${apexes[*]}" 156 make_command+=" ${specific_targets}" 157fi 158 159if [[ $installclean == "yes" ]]; then 160 msginfo "Perform installclean" 161 ANDROID_QUIET_BUILD=true build/soong/soong_ui.bash --make-mode $extra_args installclean 162 # The common java library directory is not cleaned up by installclean. Do that 163 # explicitly to not overcache them in incremental builds. 164 rm -rf $java_libraries_dir 165else 166 msgwarning "Missing --installclean argument to buildbot-build.sh" 167 msgwarning "This is usually ok, but may cause rare odd failures." 168 echo "" 169fi 170 171msginfo "Executing" "$make_command" 172# Disable path restrictions to enable luci builds using vpython. 173eval "$make_command" 174 175if [[ $build_target == "yes" ]]; then 176 if [[ -z "${ANDROID_HOST_OUT}" ]]; then 177 msgwarning "ANDROID_HOST_OUT environment variable is empty; using $out_dir/host/linux-x86" 178 ANDROID_HOST_OUT=$out_dir/host/linux-x86 179 fi 180 181 # Extract prebuilt APEXes. 182 debugfs=$ANDROID_HOST_OUT/bin/debugfs_static 183 fsckerofs=$ANDROID_HOST_OUT/bin/fsck.erofs 184 blkid=$ANDROID_HOST_OUT/bin/blkid_static 185 for apex in ${apexes[@]}; do 186 dir="$ANDROID_PRODUCT_OUT/system/apex/${apex}" 187 apexbase="$ANDROID_PRODUCT_OUT/system/apex/${apex}" 188 unset file 189 if [ -f "${apexbase}.apex" ]; then 190 file="${apexbase}.apex" 191 elif [ -f "${apexbase}.capex" ]; then 192 file="${apexbase}.capex" 193 fi 194 if [ -n "${file}" ]; then 195 msginfo "Extracting APEX file:" "${file}" 196 rm -rf $dir 197 mkdir -p $dir 198 $ANDROID_HOST_OUT/bin/deapexer --debugfs_path $debugfs --fsckerofs_path $fsckerofs \ 199 --blkid_path $blkid extract $file $dir 200 fi 201 done 202 203 # Replace stub libraries with implementation libraries: because we do chroot 204 # testing, we need to install an implementation of the libraries (and cannot 205 # rely on the one already installed on the device, if the device is post R and 206 # has it). 207 if [ -d prebuilts/runtime/mainline/platform/impl -a ! -d frameworks/base ]; then 208 if [[ $TARGET_ARCH = arm* ]]; then 209 arch32=arm 210 arch64=arm64 211 else 212 arch32=x86 213 arch64=x86_64 214 fi 215 if [ "$TARGET_ARCH" = riscv64 ]; then 216 true # no 32-bit arch for RISC-V 217 else 218 for so in ${implementation_libs[@]}; do 219 if [ -d "$ANDROID_PRODUCT_OUT/system/lib" ]; then 220 cmd="cp -p prebuilts/runtime/mainline/platform/impl/$arch32/${so}.so $ANDROID_PRODUCT_OUT/system/lib/${so}.so" 221 msginfo "Executing" "$cmd" 222 eval "$cmd" 223 fi 224 if [ -d "$ANDROID_PRODUCT_OUT/system/lib64" ]; then 225 cmd="cp -p prebuilts/runtime/mainline/platform/impl/$arch64/${so}.so $ANDROID_PRODUCT_OUT/system/lib64/${so}.so" 226 msginfo "Executing" "$cmd" 227 eval "$cmd" 228 fi 229 done 230 fi 231 fi 232 233 # Create canonical name -> file name symlink in the symbol directory for the 234 # Testing ART APEX. 235 # 236 # This mimics the logic from `art/Android.mk`. We made the choice not to 237 # implement this in `art/Android.mk`, as the Testing ART APEX is a test artifact 238 # that should never ship with an actual product, and we try to keep it out of 239 # standard build recipes 240 # 241 # TODO(b/141004137, b/129534335): Remove this, expose the Testing ART APEX in 242 # the `art/Android.mk` build logic, and add absence checks (e.g. in 243 # `build/make/core/main.mk`) to prevent the Testing ART APEX from ending up in a 244 # system image. 245 target_out_unstripped="$ANDROID_PRODUCT_OUT/symbols" 246 link_name="$target_out_unstripped/apex/com.android.art" 247 link_command="mkdir -p $(dirname "$link_name") && ln -sf com.android.art.testing \"$link_name\"" 248 msginfo "Executing" "$link_command" 249 eval "$link_command" 250 251 # Temporary fix for libjavacrypto.so dependencies in libcore and jvmti tests (b/147124225). 252 conscrypt_dir="$ANDROID_PRODUCT_OUT/system/apex/com.android.conscrypt" 253 conscrypt_libs="libjavacrypto.so libcrypto.so libssl.so" 254 if [ ! -d "${conscrypt_dir}" ]; then 255 msgerror "Missing conscrypt APEX in build output: ${conscrypt_dir}" 256 exit 1 257 fi 258 if [ ! -f "${conscrypt_dir}/javalib/conscrypt.jar" ]; then 259 msgerror "Missing conscrypt jar in build output: ${conscrypt_dir}" 260 exit 1 261 fi 262 for l in lib lib64; do 263 if [ ! -d "$ANDROID_PRODUCT_OUT/system/$l" ]; then 264 continue 265 fi 266 for so in $conscrypt_libs; do 267 src="${conscrypt_dir}/${l}/${so}" 268 dst="$ANDROID_PRODUCT_OUT/system/${l}/${so}" 269 if [ "${src}" -nt "${dst}" ]; then 270 cmd="cp -p \"${src}\" \"${dst}\"" 271 msginfo "Executing" "$cmd" 272 eval "$cmd" 273 fi 274 done 275 done 276 277 # TODO(b/159355595): Ensure there is a tzdata in system to avoid warnings on 278 # stderr from Bionic. 279 if [ ! -f $ANDROID_PRODUCT_OUT/system/usr/share/zoneinfo/tzdata ]; then 280 mkdir -p $ANDROID_PRODUCT_OUT/system/usr/share/zoneinfo 281 cp $ANDROID_PRODUCT_OUT/system/apex/com.android.tzdata/etc/tz/tzdata \ 282 $ANDROID_PRODUCT_OUT/system/usr/share/zoneinfo/tzdata 283 fi 284 285 # Create system symlinks for the Runtime APEX. Normally handled by 286 # installSymlinkToRuntimeApex in soong/cc/binary.go, but we have to replicate 287 # it here since we don't run the install rules for the Runtime APEX. 288 for b in linker{,_asan}{,64}; do 289 msginfo "Symlinking" "/apex/com.android.runtime/bin/$b to /system/bin" 290 ln -sf /apex/com.android.runtime/bin/$b $ANDROID_PRODUCT_OUT/system/bin/$b 291 done 292 for d in $ANDROID_PRODUCT_OUT/system/apex/com.android.runtime/lib{,64}/bionic; do 293 if [ -d $d ]; then 294 for p in $d/*; do 295 lib_dir=$(expr $p : '.*/\(lib[0-9]*\)/.*') 296 lib_file=$(basename $p) 297 src=/apex/com.android.runtime/${lib_dir}/bionic/${lib_file} 298 dst=$ANDROID_PRODUCT_OUT/system/${lib_dir}/${lib_file} 299 msginfo "Symlinking" "$src into /system/${lib_dir}" 300 mkdir -p $(dirname $dst) 301 ln -sf $src $dst 302 done 303 fi 304 done 305 306 # Create linker config files. We run linkerconfig on host to avoid problems 307 # building it statically for device in an unbundled tree. 308 309 # temporary root for linkerconfig 310 linkerconfig_root=$ANDROID_PRODUCT_OUT/art_linkerconfig_root 311 312 rm -rf $linkerconfig_root 313 314 # Linkerconfig reads files from /system/etc 315 mkdir -p $linkerconfig_root/system 316 cp -r $ANDROID_PRODUCT_OUT/system/etc $linkerconfig_root/system 317 318 # Use our smaller public.libraries.txt that contains only the public libraries 319 # pushed to the chroot directory. 320 cp $ANDROID_BUILD_TOP/art/tools/public.libraries.buildbot.txt \ 321 $linkerconfig_root/system/etc/public.libraries.txt 322 323 # For linkerconfig to pick up the APEXes correctly we need to make them 324 # available in $linkerconfig_root/apex. 325 mkdir -p $linkerconfig_root/apex 326 for apex in ${apexes[@]}; do 327 src="$ANDROID_PRODUCT_OUT/system/apex/${apex}" 328 if [[ $apex == com.android.art.* ]]; then 329 dst="$linkerconfig_root/apex/com.android.art" 330 else 331 dst="$linkerconfig_root/apex/${apex}" 332 fi 333 msginfo "Copying APEX directory" "from $src to $dst" 334 rm -rf $dst 335 cp -r $src $dst 336 done 337 338 # Linkerconfig also looks at /apex/apex-info-list.xml to check for system APEXes. 339 apex_xml_file=$linkerconfig_root/apex/apex-info-list.xml 340 msginfo "Creating" "$apex_xml_file" 341 cat <<EOF > $apex_xml_file 342<?xml version="1.0" encoding="utf-8"?> 343<apex-info-list> 344EOF 345 for apex in ${apexes[@]}; do 346 [[ $apex == com.android.art.* ]] && apex=com.android.art 347 cat <<EOF >> $apex_xml_file 348 <apex-info moduleName="${apex}" modulePath="/system/apex/${apex}.apex" preinstalledModulePath="/system/apex/${apex}.apex" versionCode="1" versionName="" isFactory="true" isActive="true"> 349 </apex-info> 350EOF 351 done 352 cat <<EOF >> $apex_xml_file 353</apex-info-list> 354EOF 355 356 system_linker_config_pb=$linkerconfig_root/system/etc/linker.config.pb 357 # This list needs to be synced with provideLibs in system/etc/linker.config.pb 358 # in the targeted platform image. 359 # TODO(b/186649223): Create a prebuilt for it in platform-mainline-sdk. 360 system_provide_libs=( 361 heapprofd_client_api.so 362 libEGL.so 363 libGLESv1_CM.so 364 libGLESv2.so 365 libGLESv3.so 366 libOpenMAXAL.so 367 libOpenSLES.so 368 libRS.so 369 libaaudio.so 370 libadbd_auth.so 371 libadbd_fs.so 372 libamidi.so 373 libandroid.so 374 libandroid_net.so 375 libartpalette-system.so 376 libbinder_ndk.so 377 libc.so 378 libcamera2ndk.so 379 libcgrouprc.so 380 libclang_rt.asan-i686-android.so 381 libclang_rt.asan-x86_64-android.so 382 libdl.so 383 libdl_android.so 384 libft2.so 385 libincident.so 386 libjnigraphics.so 387 liblog.so 388 libm.so 389 libmediametrics.so 390 libmediandk.so 391 libnativewindow.so 392 libneuralnetworks_packageinfo.so 393 libselinux.so 394 libstdc++.so 395 libsync.so 396 libvndksupport.so 397 libvulkan.so 398 libz.so 399 ) 400 401 msginfo "Encoding linker.config.json" "to $system_linker_config_pb" 402 $ANDROID_HOST_OUT/bin/conv_linker_config proto -s $ANDROID_BUILD_TOP/system/core/rootdir/etc/linker.config.json -o $system_linker_config_pb 403 $ANDROID_HOST_OUT/bin/conv_linker_config append -s $system_linker_config_pb -o $system_linker_config_pb --key "provideLibs" --value "${system_provide_libs[*]}" 404 405 # To avoid warnings from linkerconfig when it checks following two partitions 406 mkdir -p $linkerconfig_root/product 407 mkdir -p $linkerconfig_root/system_ext 408 409 platform_version=$(build/soong/soong_ui.bash --dumpvar-mode PLATFORM_VERSION) 410 linkerconfig_out=$ANDROID_PRODUCT_OUT/linkerconfig 411 msginfo "Generating linkerconfig" "in $linkerconfig_out" 412 rm -rf $linkerconfig_out 413 mkdir -p $linkerconfig_out 414 $ANDROID_HOST_OUT/bin/linkerconfig --target $linkerconfig_out --root $linkerconfig_root --vndk $platform_version 415 msgnote "Don't be scared by \"Unable to access VNDK APEX\" message, it's not fatal" 416fi 417