1#!/bin/bash 2 3set -eo pipefail 4 5# TODO: Refactor build/make/envsetup.sh to make gettop() available elsewhere 6function gettop 7{ 8 local TOPFILE=build/bazel/bazel.sh 9 if [ -n "$TOP" -a -f "$TOP/$TOPFILE" ] ; then 10 # The following circumlocution ensures we remove symlinks from TOP. 11 (cd "$TOP"; PWD= /bin/pwd) 12 else 13 if [ -f $TOPFILE ] ; then 14 # The following circumlocution (repeated below as well) ensures 15 # that we record the true directory name and not one that is 16 # faked up with symlink names. 17 PWD= /bin/pwd 18 else 19 local HERE=$PWD 20 local T= 21 while [ \( ! \( -f $TOPFILE \) \) -a \( "$PWD" != "/" \) ]; do 22 \cd .. 23 T=`PWD= /bin/pwd -P` 24 done 25 \cd "$HERE" 26 if [ -f "$T/$TOPFILE" ]; then 27 echo "$T" 28 fi 29 fi 30 fi 31} 32 33# TODO: Refactor build/soong/scripts/microfactory.bash to make getoutdir() available elsewhere 34function getoutdir 35{ 36 local out_dir="${OUT_DIR-}" 37 if [ -z "${out_dir}" ]; then 38 if [ "${OUT_DIR_COMMON_BASE-}" ]; then 39 out_dir="${OUT_DIR_COMMON_BASE}/$(basename ${TOP})" 40 else 41 out_dir="out" 42 fi 43 fi 44 if [[ "${out_dir}" != /* ]]; then 45 out_dir="${TOP}/${out_dir}" 46 fi 47 echo "${out_dir}" 48} 49 50TOP="$(gettop)" 51if [ ! "$TOP" ]; then 52 >&2 echo "Couldn't locate the top of the tree. Try setting TOP." 53 exit 1 54fi 55 56case $(uname -s) in 57 Darwin) 58 ANDROID_BAZEL_PATH="${TOP}/prebuilts/bazel/darwin-x86_64/bazel" 59 ANDROID_BAZELRC_NAME="darwin.bazelrc" 60 ANDROID_BAZEL_JDK_PATH="${TOP}/prebuilts/jdk/jdk11/darwin-x86" 61 62 # Lock down PATH in action execution environment, thereby removing 63 # Bazel's default /bin, /usr/bin, /usr/local/bin and ensuring 64 # hermeticity from the system. 65 # 66 # The new PATH components are: 67 # 68 # - prebuilts/build-tools/path: contains checked-in tools that can be 69 # used as executables in actions. 70 # 71 # - out/.path: a special directory created by path_interposer with 72 # config from ui/build/paths/config.go for allowlisting specific 73 # binaries not in prebuilts/build-tools/path, but on the host system. 74 # If one runs Bazel without soong_ui, then this directory wouldn't 75 # exist, making standalone Bazel execution's PATH variable stricter than 76 # Bazel execution within soong_ui. 77 RESTRICTED_PATH="${TOP}/prebuilts/build-tools/path/darwin-x86:${TOP}/out/.path" 78 ;; 79 Linux) 80 ANDROID_BAZEL_PATH="${TOP}/prebuilts/bazel/linux-x86_64/bazel" 81 ANDROID_BAZELRC_NAME="linux.bazelrc" 82 ANDROID_BAZEL_JDK_PATH="${TOP}/prebuilts/jdk/jdk11/linux-x86" 83 RESTRICTED_PATH="${TOP}/prebuilts/build-tools/path/linux-x86:${TOP}/out/.path" 84 ;; 85 *) 86 >&2 echo "Bazel is supported on Linux and Darwin only. Your OS is not supported for Bazel usage, based on 'uname -s': $(uname -s)" 87 exit 1 88 ;; 89esac 90 91function verify_soong_outputs_exist() { 92 local to_check="${ABSOLUTE_OUT_DIR}/.path" 93 local no_soong=0 94 if [[ ! -d "${to_check}" ]]; then 95 no_soong=1 96 fi 97 98 local bazel_configs=( 99 "bp2build" 100 "queryview" 101 ) 102 local valid_bazel_config=0 103 for c in "${bazel_configs[@]}" 104 do 105 if [[ -d "${ABSOLUTE_OUT_DIR}/soong/""${c}" ]]; then 106 valid_bazel_config=1 107 fi 108 done 109 110 if [[ "${no_soong}" -eq "1" || "${valid_bazel_config}" -eq "0" ]]; then 111 >&2 echo "Error: missing generated Bazel files. Have you run bp2build or queryview?" 112 >&2 echo "Run bp2build with the command: m bp2build" 113 >&2 echo "Run queryview with the command: m queryview" 114 >&2 echo "Alternatively, for non-queryview applications, invoke Bazel using 'b' with the command: source envsetup.sh; b query/build/test <targets>" 115 exit 1 116 fi 117} 118 119function create_bazelrc() { 120 cat > "${ABSOLUTE_OUT_DIR}/bazel/path.bazelrc" <<EOF 121 # This file is generated by tools/bazel. Do not edit manually. 122build --action_env=PATH=${RESTRICTED_PATH} 123EOF 124} 125 126case "x${ANDROID_BAZELRC_PATH}" in 127 x) 128 # Path not provided, use default. 129 ANDROID_BAZELRC_PATH="${TOP}/build/bazel" 130 ;; 131 x/*) 132 # Absolute path, take it as-is. 133 ANDROID_BAZELRC_PATH="${ANDROID_BAZELRC_PATH}" 134 ;; 135 x*) 136 # Relative path, consider it relative to TOP. 137 ANDROID_BAZELRC_PATH="${TOP}/${ANDROID_BAZELRC_PATH}" 138 ;; 139esac 140 141if [ -d "${ANDROID_BAZELRC_PATH}" ]; then 142 # If we're given a directory, find the correct bazelrc file there. 143 ANDROID_BAZELRC_PATH="${ANDROID_BAZELRC_PATH}/${ANDROID_BAZELRC_NAME}" 144fi 145 146 147if [ -n "$ANDROID_BAZEL_PATH" -a -f "$ANDROID_BAZEL_PATH" ]; then 148 export ANDROID_BAZEL_PATH 149else 150 >&2 echo "Couldn't locate Bazel binary" 151 exit 1 152fi 153 154if [ -n "$ANDROID_BAZELRC_PATH" -a -f "$ANDROID_BAZELRC_PATH" ]; then 155 export ANDROID_BAZELRC_PATH 156else 157 >&2 echo "Couldn't locate bazelrc file for Bazel" 158 exit 1 159fi 160 161if [ -n "$ANDROID_BAZEL_JDK_PATH" -a -d "$ANDROID_BAZEL_JDK_PATH" ]; then 162 export ANDROID_BAZEL_JDK_PATH 163else 164 >&2 echo "Couldn't locate JDK to use for Bazel" 165 exit 1 166fi 167 168ABSOLUTE_OUT_DIR="$(getoutdir)" 169 170# In order to be able to load JNI libraries, this directory needs to exist 171mkdir -p "${ABSOLUTE_OUT_DIR}/bazel/javatmp" 172 173ADDITIONAL_FLAGS=() 174if [[ "${STANDALONE_BAZEL}" =~ ^(true|TRUE|1)$ ]]; then 175 # STANDALONE_BAZEL is set. 176 >&2 echo "WARNING: Using Bazel in standalone mode. This mode is not integrated with Soong and Make, and is not supported" 177 >&2 echo "for Android Platform builds. Use this mode at your own risk." 178 >&2 echo 179else 180 # STANDALONE_BAZEL is not set. 181 >&2 echo "WARNING: Bazel support for the Android Platform is experimental and is undergoing development." 182 >&2 echo "WARNING: Currently, build stability is not guaranteed. Thank you." 183 >&2 echo 184 185 # Generate a bazelrc with dynamic content, like the absolute path to PATH variable values. 186 create_bazelrc 187 # Check that the Bazel synthetic workspace and other required inputs exist before handing over control to Bazel. 188 verify_soong_outputs_exist 189 ADDITIONAL_FLAGS+=("--bazelrc=${ABSOLUTE_OUT_DIR}/bazel/path.bazelrc") 190fi 191 192JAVA_HOME="${ANDROID_BAZEL_JDK_PATH}" "${ANDROID_BAZEL_PATH}" \ 193 --server_javabase="${ANDROID_BAZEL_JDK_PATH}" \ 194 --output_user_root="${ABSOLUTE_OUT_DIR}/bazel/output_user_root" \ 195 --host_jvm_args=-Djava.io.tmpdir="${ABSOLUTE_OUT_DIR}/bazel/javatmp" \ 196 --bazelrc="${ANDROID_BAZELRC_PATH}" \ 197 "${ADDITIONAL_FLAGS[@]}" \ 198 "$@" 199