1#! /bin/bash
2#
3# Sets the current directory as Android build output directory for a
4# given target by writing the "prefix script" to it. Commands prefixed
5# by this script are executed in the Android build environment. E.g.,
6# running
7#   ./run <command>
8# runs <command> as if we issued
9#   cd <source>
10#   mount --bind <build dir> out
11#   . build/envsetup.sh
12#   lunch <config>
13#   <command>
14#   exit
15#
16# This arrangement eliminates the need to issue envsetup/lunch commands
17# manually, and allows to run multiple builds from the same shell.
18# Thus, if your source tree is in ~/aosp and you are building for
19# 'blueline' and 'cuttlefish', issuing
20#   cd /sdx/blueline && \
21#      ~/aosp/build/soong/scripts/setup-android-build.sh aosp_blueline-userdebug
22#   cd /sdx/cuttlefish && \
23#      ~/aosp/build/soong/scripts/setup-android-build.sh aosp_cf_arm64_phone-userdebug
24# sets up build directories in /sdx/blueline and /sdx/cuttlefish respectively.
25# After that, issue
26#   /sdx/blueline/run m
27# to build blueline image, and issue
28#   /sdx/cuttlefish atest CtsSecurityBulletinHostTestCases
29# to run CTS tests. Notice there is no need to change to a specific directory for that.
30#
31# Argument:
32# * configuration (one of those shown by `lunch` command).
33#
34set -e
35function die() { printf "$@"; exit 1; }
36
37# Find out where the source tree using the fact that we are in its
38# build/ subdirectory.
39[[ "$(uname)" == Linux ]] || die "This setup runs only on Linux\n"
40declare -r mydir="${0%/*}"
41declare -r source="${mydir%/build/soong/scripts}"
42[[ "/${mydir}/" =~ '/build/soong/scripts/' ]] || \
43  die "$0 should be in build/soong/scripts/ subdirectory of the source tree\n"
44[[ ! -e .repo && ! -e .git ]] || \
45  die "Current directory looks like source. You should be in the _target_ directory.\n"
46# Do not override old run script.
47if [[ -x ./run ]]; then
48  # Set variables from config=xxx and source=xxx comments in the existing script.
49  . <(sed -nr 's/^# *source=(.*)/oldsource=\1/p;s/^# *config=(.*)/oldconfig=\1/p' run)
50  die "This directory has been already set up to build Android for %s from %s.\n\
51Remove 'run' file if you want to set it up afresh\n" "$oldconfig" "$oldsource"
52fi
53
54(($#<2)) || die "usage: %s [<config>]\n" $0
55
56if (($#==1)); then
57  # Configuration is provided, emit run script.
58  declare -r config="$1"
59  declare -r target="$PWD"
60  cat >./run <<EOF
61#! /bin/bash
62# source=$source
63# config=$config
64declare -r cmd=\$(printf ' %q' "\$@")
65"$source/prebuilts/build-tools/linux-x86/bin/nsjail"\
66 -Mo -q -e -t 0\
67 -EANDROID_QUIET_BUILD=true \
68 -B / -B "$target:$source/out"\
69 --cwd "$source"\
70 --skip_setsid \
71 --keep_caps\
72 --disable_clone_newcgroup\
73 --disable_clone_newnet\
74 --rlimit_as soft\
75 --rlimit_core soft\
76 --rlimit_cpu soft\
77 --rlimit_fsize soft\
78 --rlimit_nofile soft\
79 --proc_rw\
80 --hostname $(hostname) \
81 --\
82 /bin/bash -i -c ". build/envsetup.sh && lunch "$config" &&\$cmd"
83EOF
84  chmod +x ./run
85else
86  # No configuration, show available ones.
87  printf "Please specify build target. Common values:\n"
88  (cd "$source"
89   . build/envsetup.sh
90   get_build_var COMMON_LUNCH_CHOICES | tr ' ' '\n' | pr -c4 -tT -W"$(tput cols)"
91  )
92  exit 1
93fi
94