• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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