xref: /aosp_15_r20/build/bazel/bin/bazel (revision 7594170e27e0732bc44b93d1440d87a54b6ffe7c)
1#!/bin/bash
2
3# Copyright (C) 2022 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 -eo pipefail
18
19source $(cd $(dirname $BASH_SOURCE) &> /dev/null && pwd)/../../make/shell_utils.sh
20require_top
21
22
23ABSOLUTE_OUT_DIR="$(getoutdir)"
24# Store all bazel-related metadata files in this subdir of OUT_DIR.
25BAZEL_METADATA_OUT="${ABSOLUTE_OUT_DIR}/bazel"
26mkdir -p "${BAZEL_METADATA_OUT}"
27
28case $(uname -s) in
29    Darwin)
30        ANDROID_BAZEL_PATH="${TOP}/prebuilts/bazel/darwin-x86_64/bazel"
31        ANDROID_BAZELRC_NAME="darwin.bazelrc"
32        ANDROID_BAZEL_JDK_PATH="${TOP}/prebuilts/jdk/jdk21/darwin-x86"
33
34        # Lock down PATH in action execution environment, thereby removing
35        # Bazel's default /bin, /usr/bin, /usr/local/bin and ensuring
36        # hermeticity from the system.
37        #
38        # The new PATH components are:
39        #
40        # - prebuilts/build-tools/path: contains checked-in tools that can be
41        #   used as executables in actions.
42        #
43        # - out/.path: a special directory created by path_interposer with
44        #   config from ui/build/paths/config.go for allowlisting specific
45        #   binaries not in prebuilts/build-tools/path, but on the host system.
46        #   If one runs Bazel without soong_ui, then this  directory wouldn't
47        #   exist, making standalone Bazel execution's PATH variable stricter than
48        #   Bazel execution within soong_ui.
49        RESTRICTED_PATH="${TOP}/prebuilts/build-tools/path/darwin-x86:${ABSOLUTE_OUT_DIR}/.path"
50        ;;
51    Linux)
52        ANDROID_BAZEL_PATH="${TOP}/prebuilts/bazel/linux-x86_64/bazel"
53        ANDROID_BAZELISK_PATH="${TOP}/prebuilts/bazel/linux-x86_64/dev_tools/bazelisk/bazelisk"
54        ANDROID_BAZELRC_NAME="linux.bazelrc"
55        ANDROID_BAZEL_JDK_PATH="${TOP}/prebuilts/jdk/jdk21/linux-x86"
56        RESTRICTED_PATH="${TOP}/prebuilts/build-tools/path/linux-x86:${ABSOLUTE_OUT_DIR}/.path"
57        ;;
58    *)
59        >&2 echo "Bazel is supported on Linux and Darwin only. Your OS is not supported for Bazel usage, based on 'uname -s': $(uname -s)"
60        exit 1
61        ;;
62esac
63
64function verify_soong_outputs_exist() {
65    local to_check="${ABSOLUTE_OUT_DIR}/.path"
66    local no_soong=0
67    if [[ ! -d "${to_check}" ]]; then
68      no_soong=1
69    fi
70
71    local bazel_configs=(
72        "bp2build"
73        "queryview"
74    )
75    local valid_bazel_config=0
76    for c in "${bazel_configs[@]}"
77    do
78        if [[ -d "${ABSOLUTE_OUT_DIR}/soong/""${c}" ]]; then
79          valid_bazel_config=1
80        fi
81    done
82
83    if [[ "${no_soong}" -eq "1" || "${valid_bazel_config}" -eq "0" ]]; then
84        >&2 echo "Error: missing generated Bazel files. Have you run bp2build or queryview?"
85        >&2 echo "Run bp2build with the command: m bp2build"
86        >&2 echo "Run queryview with the command: m queryview"
87        >&2 echo "Alternatively, for non-queryview applications, invoke Bazel using 'b' with the command: source envsetup.sh; b query/build/test <targets>"
88        exit 1
89    fi
90}
91
92function create_bazelrc() {
93    cat > "${BAZEL_METADATA_OUT}/generated.bazelrc" <<EOF
94# This file is generated by build/bazel/bin/bazel. Do not edit manually.
95build --action_env=PATH=${RESTRICTED_PATH}
96
97# The --package_path option needs to be added to several different
98# bazel subcommands, because they don't inherit from each other, and
99# if we put it on "common", then it would break other commands like
100# shutdown that don't support --package_path. In addition, we have
101# to set at least one option on the "common" target so that bazel
102# won't complain that bp2build doesn't exist when using
103# --config=bp2build. We'll use --noannounce_rc for that, because
104# --noannounce_rc is the default.
105
106
107# Run bazel query from the workspace, without cd'ing into \$OUT_DIR/soong/queryview
108common:queryview --noannounce_rc
109build:queryview --package_path=${ABSOLUTE_OUT_DIR}/soong/queryview
110fetch:queryview --package_path=${ABSOLUTE_OUT_DIR}/soong/queryview
111mod:queryview --package_path=${ABSOLUTE_OUT_DIR}/soong/queryview
112query:queryview --package_path=${ABSOLUTE_OUT_DIR}/soong/queryview
113sync:queryview --package_path=${ABSOLUTE_OUT_DIR}/soong/queryview
114
115# Run bazel build from the workspace, without cd'ing into \$OUT_DIR/soong/workspace
116common:bp2build --noannounce_rc
117build:bp2build --package_path=${ABSOLUTE_OUT_DIR}/soong/workspace
118fetch:bp2build --package_path=${ABSOLUTE_OUT_DIR}/soong/workspace
119mod:bp2build --package_path=${ABSOLUTE_OUT_DIR}/soong/workspace
120query:bp2build --package_path=${ABSOLUTE_OUT_DIR}/soong/workspace
121sync:bp2build --package_path=${ABSOLUTE_OUT_DIR}/soong/workspace
122
123EOF
124}
125
126# Return 1 if STANDALONE_BAZEL is truthy
127function is_standalone_bazel() {
128    [[ ${STANDALONE_BAZEL} =~ ^(true|TRUE|1)$ ]]
129}
130
131case "x${ANDROID_BAZELRC_PATH}" in
132    x)
133      # Path not provided, use default.
134      if is_standalone_bazel; then
135        # Standalone bazel uses the empty /dev/null bazelrc
136        # This is necessary since some configs in common.bazelrc depend on soong_injection
137        ANDROID_BAZELRC_PATH=/dev/null
138      else
139        ANDROID_BAZELRC_PATH="${TOP}/build/bazel"
140      fi
141        ;;
142    x/*)
143        # Absolute path, take it as-is.
144        ANDROID_BAZELRC_PATH="${ANDROID_BAZELRC_PATH}"
145        ;;
146    x*)
147        # Relative path, consider it relative to TOP.
148        ANDROID_BAZELRC_PATH="${TOP}/${ANDROID_BAZELRC_PATH}"
149        ;;
150esac
151
152if [ -d "${ANDROID_BAZELRC_PATH}" ]; then
153    # If we're given a directory, find the correct bazelrc file there.
154    ANDROID_BAZELRC_PATH="${ANDROID_BAZELRC_PATH}/${ANDROID_BAZELRC_NAME}"
155fi
156
157ADDITIONAL_FLAGS=()
158
159if [[ -z ${USE_BAZEL_VERSION+x} ]]; then
160  if [ -n "$ANDROID_BAZEL_PATH" -a -f "$ANDROID_BAZEL_PATH" ]; then
161      export ANDROID_BAZEL_PATH
162  else
163      >&2 echo "Couldn't locate Bazel binary"
164      exit 1
165  fi
166else
167  echo -e "\033[1m\033[33mUSING BAZELISK:\033[0m Using Bazelisk because of env var: USE_BAZEL_VERSION=${USE_BAZEL_VERSION}" >&2
168  ANDROID_BAZEL_PATH=$ANDROID_BAZELISK_PATH
169  export ANDROID_BAZEL_PATH
170  # TODO(b/283971340): Pass BAZELISK_NOJDK=1 when this works with bazelisk.
171fi
172
173if [ "$ANDROID_BAZELRC_PATH" == "/dev/null" ] || [ -n "$ANDROID_BAZELRC_PATH" -a -f "$ANDROID_BAZELRC_PATH" ]; then
174    export ANDROID_BAZELRC_PATH
175else
176    >&2 echo "Couldn't locate bazelrc file for Bazel"
177    exit 1
178fi
179
180if [ -n "$ANDROID_BAZEL_JDK_PATH" -a -d "$ANDROID_BAZEL_JDK_PATH" ]; then
181    export ANDROID_BAZEL_JDK_PATH
182else
183    >&2 echo "Couldn't locate JDK to use for Bazel"
184    exit 1
185fi
186
187# In order to be able to load JNI libraries, this directory needs to exist
188mkdir -p "${BAZEL_METADATA_OUT}/javatmp"
189
190# Output a deps file. Soong will read these as dependencies for mixed builds
191MIXED_BUILDS_DOTD="${BAZEL_METADATA_OUT}/bazel.list"
192touch "${MIXED_BUILDS_DOTD}"
193echo $ANDROID_BAZEL_PATH > "${MIXED_BUILDS_DOTD}"
194echo $ANDROID_BAZELRC_PATH >> "${MIXED_BUILDS_DOTD}"
195echo $ANDROID_BAZEL_JDK_PATH >> "${MIXED_BUILDS_DOTD}"
196
197
198if  is_standalone_bazel; then
199    # STANDALONE_BAZEL is set.
200    >&2 echo "WARNING: Using Bazel in standalone mode. This mode is not integrated with Soong and Make, and is not supported"
201    >&2 echo "for Android Platform builds. Use this mode at your own risk."
202    >&2 echo
203else
204    # Generate a bazelrc with dynamic content, like the absolute path to PATH variable values.
205    create_bazelrc
206    # Check that the Bazel synthetic workspace and other required inputs exist before handing over control to Bazel.
207    verify_soong_outputs_exist
208    ADDITIONAL_FLAGS+=("--bazelrc=${BAZEL_METADATA_OUT}/generated.bazelrc")
209
210    # These bazelrc files are only available when bp2build has been run.
211    # Standalone bazel and queryview don't run bp2build.
212    if [[ -f "${ABSOLUTE_OUT_DIR}/soong/soong_injection/product_config_platforms/common.bazelrc" ]]; then
213        ADDITIONAL_FLAGS+=("--bazelrc=${ABSOLUTE_OUT_DIR}/soong/soong_injection/product_config_platforms/common.bazelrc")
214        case $(uname -s) in
215            Darwin)
216                ADDITIONAL_FLAGS+=("--bazelrc=${ABSOLUTE_OUT_DIR}/soong/soong_injection/product_config_platforms/darwin.bazelrc")
217                ;;
218            Linux)
219                ADDITIONAL_FLAGS+=("--bazelrc=${ABSOLUTE_OUT_DIR}/soong/soong_injection/product_config_platforms/linux.bazelrc")
220                ;;
221            *)
222                >&2 echo "Bazel is supported on Linux and Darwin only. Your OS is not supported for Bazel usage, based on 'uname -s': $(uname -s)"
223                exit 1
224                ;;
225        esac
226    fi
227fi
228
229# Change the PATH variable for the bazel invocation to include RESTRICTED_PATH.
230# This only affects the workspace_status_marker script environment and
231# the bazel run environment, and works around a bug for Bazelisk where Bazelisk
232# behaves differently if no PATH is present.
233BAZEL_PATH=$PATH:${RESTRICTED_PATH}
234
235# TODO(b/240354506): Re-enable hsperfdata file creation without causing SIGBUS errors
236PATH="${BAZEL_PATH}" JAVA_HOME="${ANDROID_BAZEL_JDK_PATH}" \
237  "${ANDROID_BAZEL_PATH}" \
238  --server_javabase="${ANDROID_BAZEL_JDK_PATH}" \
239  --output_user_root="${BAZEL_METADATA_OUT}/output_user_root" \
240  --host_jvm_args=-Djava.io.tmpdir="${BAZEL_METADATA_OUT}/javatmp" \
241  --nohome_rc --nosystem_rc \
242  --bazelrc="${ANDROID_BAZELRC_PATH}" \
243  "${ADDITIONAL_FLAGS[@]}" \
244  "$@"
245