You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
383 lines
11 KiB
383 lines
11 KiB
#!/bin/bash
|
|
#
|
|
# Copyright (C) 2017 The Android Open Source Project
|
|
#
|
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
# you may not use this file except in compliance with the License.
|
|
# You may obtain a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
# See the License for the specific language governing permissions and
|
|
# limitations under the License.
|
|
|
|
if [[ ! -d art ]]; then
|
|
echo "Script needs to be run at the root of the android tree"
|
|
exit 1
|
|
fi
|
|
|
|
ALL_CONFIGS=(linux-ia32 linux-x64 linux-armv8 linux-armv7 android-armv8 android-armv7)
|
|
|
|
usage() {
|
|
local config
|
|
local golem_target
|
|
|
|
(cat << EOF
|
|
Usage: $(basename "${BASH_SOURCE[0]}") [--golem=<target>] --machine-type=MACHINE_TYPE
|
|
[--tarball[=<target>.tar.gz]]
|
|
|
|
Build minimal art binaries required to run golem benchmarks either
|
|
locally or on the golem servers.
|
|
|
|
Creates the \$MACHINE_TYPE binaries in your \$OUT_DIR, and if --tarball was specified,
|
|
it also tars the results of the build together into your <target.tar.gz> file.
|
|
--------------------------------------------------------
|
|
Required Flags:
|
|
--machine-type=MT Specify the machine type that will be built.
|
|
|
|
Optional Flags":
|
|
--golem=<target> Builds with identical commands that Golem servers use.
|
|
--tarball[=o.tgz] Tar/gz the results. File name defaults to <machine_type>.tar.gz
|
|
-j<num> Specify how many jobs to use for parallelism.
|
|
--help Print this help listing.
|
|
--showcommands Show commands as they are being executed.
|
|
--simulate Print commands only, don't execute commands.
|
|
EOF
|
|
) | sed -e 's/^[[:space:]][[:space:]]//g' >&2 # Strip leading whitespace from heredoc.
|
|
|
|
echo >&2 "Available machine types:"
|
|
for config in "${ALL_CONFIGS[@]}"; do
|
|
echo >&2 " $config"
|
|
done
|
|
|
|
echo >&2
|
|
echo >&2 "Available Golem targets:"
|
|
while IFS='' read -r golem_target; do
|
|
echo >&2 " $golem_target"
|
|
done < <("$(thisdir)/env" --list-targets)
|
|
}
|
|
|
|
# Check if $1 element is in array $2
|
|
contains_element() {
|
|
local e
|
|
for e in "${@:2}"; do [[ "$e" == "$1" ]] && return 0; done
|
|
return 1
|
|
}
|
|
|
|
# Display a command, but don't execute it, if --showcommands was set.
|
|
show_command() {
|
|
if [[ $showcommands == "showcommands" ]]; then
|
|
echo "$@"
|
|
fi
|
|
}
|
|
|
|
# Execute a command, displaying it if --showcommands was set.
|
|
# If --simulate is used, command is not executed.
|
|
execute() {
|
|
show_command "$@"
|
|
execute_noshow "$@"
|
|
}
|
|
|
|
# Execute a command unless --simulate was used.
|
|
execute_noshow() {
|
|
if [[ $simulate == "simulate" ]]; then
|
|
return 0
|
|
fi
|
|
|
|
local prog="$1"
|
|
shift
|
|
"$prog" "$@"
|
|
}
|
|
|
|
# Export environment variable, echoing it to screen.
|
|
setenv() {
|
|
local name="$1"
|
|
local value="$2"
|
|
|
|
export $name="$value"
|
|
echo export $name="$value"
|
|
}
|
|
|
|
# Export environment variable, echoing $3 to screen ($3 is meant to be unevaluated).
|
|
setenv_escape() {
|
|
local name="$1"
|
|
local value="$2"
|
|
local escaped_value="$3"
|
|
|
|
export $name="$value"
|
|
echo export $name="$escaped_value"
|
|
}
|
|
|
|
log_usage_error() {
|
|
echo >&2 "ERROR: " "$@"
|
|
echo >&2 " See --help for the correct usage information."
|
|
exit 1
|
|
}
|
|
|
|
log_fatal() {
|
|
echo >&2 "FATAL: " "$@"
|
|
exit 2
|
|
}
|
|
|
|
# Get the directory of this script.
|
|
thisdir() {
|
|
(\cd "$(dirname "${BASH_SOURCE[0]}")" && pwd )
|
|
}
|
|
|
|
# Get the path to the top of the Android source tree.
|
|
gettop() {
|
|
if [[ "x$ANDROID_BUILD_TOP" != "x" ]]; then
|
|
echo "$ANDROID_BUILD_TOP";
|
|
else
|
|
echo "$(thisdir)/../../.."
|
|
fi
|
|
}
|
|
|
|
# Get a build variable from the Android build system.
|
|
get_build_var() {
|
|
local varname="$1"
|
|
|
|
# include the desired target product/build-variant
|
|
# which won't be set in our env if neither we nor the user first executed
|
|
# source build/envsetup.sh (e.g. if simulating from a fresh shell).
|
|
local extras
|
|
[[ -n $target_product ]] && extras+=" TARGET_PRODUCT=$target_product"
|
|
[[ -n $target_build_variant ]] && extras+=" TARGET_BUILD_VARIANT=$target_build_variant"
|
|
|
|
# call dumpvar from the build system.
|
|
(\cd "$(gettop)"; env $extras build/soong/soong_ui.bash --dumpvar-mode $varname)
|
|
}
|
|
|
|
# Defaults from command-line.
|
|
|
|
mode="" # blank or 'golem' if --golem was specified.
|
|
golem_target="" # --golem=$golem_target
|
|
config="" # --machine-type=$config
|
|
j_arg=""
|
|
showcommands=""
|
|
simulate=""
|
|
make_tarball=""
|
|
tarball=""
|
|
|
|
# Parse command line arguments
|
|
|
|
while [[ "$1" != "" ]]; do
|
|
case "$1" in
|
|
--help)
|
|
usage
|
|
exit 1
|
|
;;
|
|
--golem=*)
|
|
mode="golem"
|
|
golem_target="${1##--golem=}"
|
|
|
|
if [[ "x$golem_target" == x ]]; then
|
|
log_usage_error "Missing --golem target type."
|
|
fi
|
|
|
|
shift
|
|
;;
|
|
--machine-type=*)
|
|
config="${1##--machine-type=}"
|
|
if ! contains_element "$config" "${ALL_CONFIGS[@]}"; then
|
|
log_usage_error "Invalid --machine-type value '$config'"
|
|
fi
|
|
shift
|
|
;;
|
|
--tarball)
|
|
tarball="" # reuse the machine type name.
|
|
make_tarball="make_tarball"
|
|
shift
|
|
;;
|
|
--tarball=*)
|
|
tarball="${1##--tarball=}"
|
|
make_tarball="make_tarball"
|
|
shift
|
|
;;
|
|
-j*)
|
|
j_arg="$1"
|
|
shift
|
|
;;
|
|
--showcommands)
|
|
showcommands="showcommands"
|
|
shift
|
|
;;
|
|
--simulate)
|
|
simulate="simulate"
|
|
shift
|
|
;;
|
|
*)
|
|
log_usage_error "Unknown options $1"
|
|
;;
|
|
esac
|
|
done
|
|
|
|
###################################
|
|
###################################
|
|
###################################
|
|
|
|
if [[ -z $config ]]; then
|
|
log_usage_error "--machine-type option is required."
|
|
fi
|
|
|
|
# --tarball defaults to the --machine-type value with .tar.gz.
|
|
tarball="${tarball:-$config.tar.gz}"
|
|
|
|
target_product="$TARGET_PRODUCT"
|
|
target_build_variant="$TARGET_BUILD_VARIANT"
|
|
|
|
# If not using --golem, use whatever the user had lunch'd prior to this script.
|
|
if [[ $mode == "golem" ]]; then
|
|
# This section is intended solely to be executed by a golem build server.
|
|
|
|
target_build_variant=eng
|
|
case "$config" in
|
|
*-armv7)
|
|
target_product="arm_krait"
|
|
;;
|
|
*-armv8)
|
|
target_product="armv8"
|
|
;;
|
|
*)
|
|
target_product="sdk"
|
|
;;
|
|
esac
|
|
|
|
if [[ $target_product = arm* ]]; then
|
|
# If using the regular manifest, e.g. 'master'
|
|
# The lunch command for arm will assuredly fail because we don't have device/generic/art.
|
|
#
|
|
# Print a human-readable error message instead of trying to lunch and failing there.
|
|
if ! [[ -d "$(gettop)/device/generic/art" ]]; then
|
|
log_fatal "Missing device/generic/art directory. Perhaps try master-art repo manifest?\n" \
|
|
" Cannot build ARM targets (arm_krait, armv8) for Golem." >&2
|
|
fi
|
|
# We could try to keep on simulating but it seems brittle because we won't have the proper
|
|
# build variables to output the right strings.
|
|
fi
|
|
|
|
# Get this particular target's environment variables (e.g. ART read barrier on/off).
|
|
source "$(thisdir)"/env "$golem_target" || exit 1
|
|
|
|
lunch_target="$target_product-$target_build_variant"
|
|
|
|
execute 'source' build/envsetup.sh
|
|
# Build generic targets (as opposed to something specific like aosp_angler-eng).
|
|
execute lunch "$lunch_target"
|
|
# Golem uses master-art repository which is missing a lot of other libraries.
|
|
setenv SOONG_ALLOW_MISSING_DEPENDENCIES true
|
|
# Let the build system know we're not aiming to do a full platform build.
|
|
if [ ! -d frameworks/base ]; then
|
|
setenv TARGET_BUILD_UNBUNDLED true
|
|
fi
|
|
# Golem may be missing tools such as javac from its path.
|
|
setenv_escape PATH "/usr/lib/jvm/java-8-openjdk-amd64/bin/:$PATH" '/usr/lib/jvm/java-8-openjdk-amd64/bin/:$PATH'
|
|
else
|
|
# Look up the default variables from the build system if they weren't set already.
|
|
[[ -z $target_product ]] && target_product="$(get_build_var TARGET_PRODUCT)"
|
|
[[ -z $target_build_variant ]] && target_build_variant="$(get_build_var TARGET_BUILD_VARIANT)"
|
|
fi
|
|
|
|
# Defaults for all machine types.
|
|
make_target="build-art-target-golem"
|
|
out_dir="out/x86_64"
|
|
root_dir_var="PRODUCT_OUT"
|
|
strip_symbols=false
|
|
bit64_suffix=""
|
|
tar_directories=(system data/art-test)
|
|
|
|
# Per-machine type overrides
|
|
if [[ $config == linux-arm* ]]; then
|
|
setenv ART_TARGET_LINUX true
|
|
fi
|
|
|
|
case "$config" in
|
|
linux-ia32|linux-x64)
|
|
root_dir_var="HOST_OUT"
|
|
# Android strips target builds automatically, but not host builds.
|
|
strip_symbols=true
|
|
make_target="build-art-host-golem"
|
|
|
|
if [[ $config == linux-ia32 ]]; then
|
|
out_dir="out/x86"
|
|
setenv HOST_PREFER_32_BIT true
|
|
else
|
|
bit64_suffix="64"
|
|
fi
|
|
|
|
tar_directories=(bin framework usr lib${bit64_suffix})
|
|
;;
|
|
*-armv8)
|
|
bit64_suffix="64"
|
|
;;
|
|
*-armv7)
|
|
;;
|
|
*)
|
|
log_fatal "Unsupported machine-type '$config'"
|
|
esac
|
|
|
|
# Golem benchmark run commands expect a certain $OUT_DIR to be set,
|
|
# so specify it here.
|
|
#
|
|
# Note: It is questionable if we want to customize this since users
|
|
# could alternatively probably use their own build directly (and forgo this script).
|
|
setenv OUT_DIR "$out_dir"
|
|
root_dir="$(get_build_var "$root_dir_var")"
|
|
|
|
if [[ $mode == "golem" ]]; then
|
|
# For golem-style running only.
|
|
# Sets the DT_INTERP to this path in every .so we can run the
|
|
# non-system version of dalvikvm with our own copies of the dependencies (e.g. our own libc++).
|
|
if [[ $config == android-* ]]; then
|
|
# TODO: the linker can be relative to the binaries
|
|
# (which is what we do for linux-armv8 and linux-armv7)
|
|
golem_run_path="/data/local/tmp/runner/"
|
|
else
|
|
golem_run_path=""
|
|
fi
|
|
|
|
# Only do this for target builds. Host doesn't need this.
|
|
if [[ $config == *-arm* ]]; then
|
|
setenv CUSTOM_TARGET_LINKER "${golem_run_path}${root_dir}/system/bin/linker${bit64_suffix}"
|
|
fi
|
|
fi
|
|
|
|
#
|
|
# Main command execution below here.
|
|
# (everything prior to this just sets up environment variables,
|
|
# and maybe calls lunch).
|
|
#
|
|
|
|
execute build/soong/soong_ui.bash --make-mode "${j_arg}" "${make_target}"
|
|
|
|
if $strip_symbols; then
|
|
# Further reduce size by stripping symbols.
|
|
execute_noshow strip $root_dir/bin/* || true
|
|
show_command strip $root_dir/bin/'*' '|| true'
|
|
execute_noshow strip $root_dir/lib${bit64_suffix}/'*'
|
|
show_command strip $root_dir/lib${bit64_suffix}/'*'
|
|
fi
|
|
|
|
if [[ "$make_tarball" == "make_tarball" ]]; then
|
|
# Create a tarball which is required for the golem build resource.
|
|
# (In particular, each golem benchmark's run commands depend on a list of resource files
|
|
# in order to have all the files it needs to actually execute,
|
|
# and this tarball would satisfy that particular target+machine-type's requirements).
|
|
dirs_rooted=()
|
|
for tar_dir in "${tar_directories[@]}"; do
|
|
dirs_rooted+=("$root_dir/$tar_dir")
|
|
done
|
|
|
|
execute tar -czf "${tarball}" --exclude ".git" --exclude ".gitignore" "${dirs_rooted[@]}"
|
|
tar_result=$?
|
|
if [[ $tar_result -ne 0 ]]; then
|
|
[[ -f $tarball ]] && rm $tarball
|
|
fi
|
|
|
|
show_command '[[ $? -ne 0 ]] && rm' "$tarball"
|
|
fi
|
|
|