1#!/bin/bash
2#
3# This script must be run in the location of the script!
4#
5# This script generates Android.bp files for this and all subdirs of this
6#
7DIR="${ANDROID_BUILD_TOP}/device/google/cuttlefish_vmm"
8
9function remove_trailing_slash {
10  if [[ $1 == "/" ]]; then
11    echo $i
12  else
13    echo ${1%/}
14  fi
15}
16
17set -o errexit
18
19function check_location() {
20  local my_loc="$(realpath ${DIR})"
21  my_loc=$(remove_trailing_slash ${my_loc})
22
23  local my_pwd="$(realpath $PWD)"
24  my_pwd="$(remove_trailing_slash ${my_pwd})"
25  if [[ "${my_loc}" != "${my_pwd}" ]]; then
26    echo ${my_loc}
27    echo ${my_pwd}
28    >&2 echo "the script location must be run where the script is located"
29    exit 10
30  fi
31}
32
33my_name=`basename $0`
34seccomp_archs=("x86_64" "aarch64")
35# under get_arch_dir() in cuttlefish_vmm, where is seccomp?
36subdir="etc/seccomp"
37
38# define arch dir pattern: e.g. ${ARCH}-linux-gnu
39function get_arch_dir() {
40  local suffix="-linux-gnu"
41  local arch=$1
42  echo ${arch}${suffix}
43}
44
45# take arch, return the path of the output Android.bp file
46function get_output_file() {
47  local blueprint_dir=$1
48  blueprint_dir="$(remove_trailing_slash ${blueprint_dir})"
49  echo "${blueprint_dir}/Android.bp"
50}
51
52# utility function to enumerate policy files
53#
54# 1: seccomp dir to scan
55function scan_policy_name() {
56  local seccomp_dir=$1
57  (
58    # pushd but no output to stdout/stderr
59    # the output is taken and used by the caller
60    pushd $seccomp_dir > /dev/null 2>&1
61    ls -1
62    popd > /dev/null 2>&1
63  )
64}
65
66# starting from old Android.bp
67function gen_license() {
68  local year=${1:-"2019"}
69cat <<EOF
70// Autogenerated via ${my_name}
71//
72// Copyright (C) ${year} The Android Open Source Project
73//
74// Licensed under the Apache License, Version 2.0 (the "License");
75// you may not use this file except in compliance with the License.
76// You may obtain a copy of the License at
77//
78//      http://www.apache.org/licenses/LICENSE-2.0
79//
80// Unless required by applicable law or agreed to in writing, software
81// distributed under the License is distributed on an "AS IS" BASIS,
82// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
83// See the License for the specific language governing permissions and
84// limitations under the License.
85
86EOF
87}
88
89#
90# first two args are module type (e.g. prebuilt_usr_share_host)
91# and the whitespaces for indentation
92#
93# the rest must be in this form:
94#  --name=value
95#
96# then, it simply generates this line repeatedly:
97# <indent>name: value,
98#
99# e.g. --name="\"foo\"" will generate
100#   name: "foo",
101#
102function gen_module() {
103  local mod_name=$1  # e.g. prebuilt_usr_share_host
104  local indent="$2"
105  shift 2
106  local long_options=()
107  local long_opt=""
108  local OPTIND=1
109  while getopts ":-:" op; do
110    # a long opt like --srcs="some" is actually:
111    # - + - + "srcs=some"
112    # that's a short option '-' just like h, and
113    # the OPTARGS of the option '-' is srcs=some
114    if [[ "$op" != "-" ]]; then
115      >&2 echo "gen_module does take long options with = only"
116      exit 8
117    fi
118    long_op="${OPTARG%%=*}"
119    OPTARG="${OPTARG#$long_op}"
120    OPTARG="${OPTARG#=}"
121    long_options+=( "$long_op" )
122    declare local ${long_op}="${OPTARG}"
123  done
124
125  echo "$mod_name {"
126  for field in "${long_options[@]}"; do
127    eval local value=\$$field
128    echo "${indent}${field}: ${value},"
129  done
130  echo "}"
131}
132
133function gen_android_bp4seccomp() {
134  local arch="$1"
135  local arch_dir="$(get_arch_dir ${arch})"
136  local seccomp_dir="${arch_dir}/${subdir}"
137  local where_in_etc_on_user_machine="cuttlefish/${arch_dir}/seccomp"
138  gen_license 2019
139  for i in $(scan_policy_name $seccomp_dir); do
140    # first two are: e.g. prebuilt_usr_share_host and whitespace for intentation
141    local base_name="$(basename $i)"
142    gen_module "prebuilt_usr_share_host" '  ' \
143      --name="\"${base_name}_at_${arch}\"" \
144      --src="\"${subdir}/${base_name}\"" \
145      --filename="\"${base_name}\"" \
146      --sub_dir="\"${where_in_etc_on_user_machine}\""
147  done
148}
149
150function gen_main_android_bp() {
151  gen_license 2019
152
153  gen_module "cc_prebuilt_binary" '  ' \
154    --name="\"common_crosvm\"" \
155    --stem="\"crosvm"\" \
156    --srcs="[\"scripts/crosvm\"]" \
157    --defaults="[\"cuttlefish_host_only\"]"
158
159  cat <<EOF
160// NOTE: Using cc_prebuilt_binary because cc_prebuilt_library can't handle stem on pie
161
162EOF
163
164for i in */bin/*; do
165  if [[ ! -L "$i" ]]; then
166    name="${i//\//_}"
167    name="${name//-/_}"
168    name="${name/_bin_/_}"
169    path="$(dirname $(dirname "$i"))"
170    stem="$(basename "$i")"
171
172    if [[ "crosvm" != "${stem}" ]]; then
173      name="${name}_for_crosvm"
174    fi
175
176    gen_module "cc_prebuilt_binary" '  ' \
177    --name="\"${name}\"" \
178    --srcs="[\"$i\"]" \
179    --stem="\"$stem"\" \
180    --relative_install_path="\"${path}\"" \
181    --defaults="[\"cuttlefish_host_only\"]"
182  fi
183done
184}
185
186# main
187check_location
188gen_main_android_bp > $(get_output_file ${DIR})
189for arch in ${seccomp_archs[@]}; do
190  arch_dir=$(get_arch_dir ${arch})
191  outfile="$(get_output_file ${arch_dir})"
192  gen_android_bp4seccomp $arch > $outfile
193done
194