blob: 2430d000f2e448ee13e95196967823adb75c44bf [file] [log] [blame]
# Copyright 2015 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.
# Common functions used to help build source packages for the Android emulator.
shell_import utils/aosp_dir.shi
shell_import utils/option_parser.shi
shell_import utils/package_list_parser.shi
# List of valid host systems.
_SHU_VALID_HOST_SYSTEMS="linux-x86,linux-x86_64,windows-x86,windows-x86_64,darwin-x86,darwin-x86_64"
# Call this function before 'option_parse' to register options related to
# building packages. This registers the following options:
#
# --build-dir=<dir>
# --jobs=<count>
# -j<count>
#
package_builder_register_options () {
OPT_BUILD_DIR=
option_register_var "--build-dir=<dir>" OPT_BUILD_DIR "Specify build directory"
OPT_NUM_JOBS=
option_register_var "-j<count>" OPT_NUM_JOBS "Run <count> parallel build jobs [$(get_build_num_cores)]"
option_register_var "--jobs=<count>" OPT_NUM_JOBS "Same as -j<count>."
OPT_CCACHE=
option_register_var "--ccache=<program>" OPT_CCACHE "Use specific ccache program [autodetect]"
OPT_NO_CCACHE=
option_register_var "--no-ccache" OPT_NO_CCACHE "Disable ccache usage."
if [ -z "$DEFAULT_HOST_SYSTEMS" ]; then
case $(get_build_os) in
linux)
DEFAULT_HOST_SYSTEMS="linux-x86_64,windows-x86_64,windows-x86"
;;
darwin)
DEFAULT_HOST_SYSTEMS="darwin-x86_64"
;;
*)
panic "Don't know how to build binaries on this system [$(get_build_os)]"
esac
fi
OPT_DARWIN_SSH=
option_register_var "--darwin-ssh=<host>" OPT_DARWIN_SSH "Perform remote build through SSH."
OPT_SSH_WRAPPER=
option_register_var "--ssh-wrapper=<command>" OPT_SSH_WRAPPER "Prefix <command> to all SSH commands."
OPT_FORCE=
option_register_var "--force" OPT_FORCE "Always rebuild all."
OPT_HOST=
option_register_var "--host=<host>" OPT_HOST "Specify host system of generated binaries [$DEFAULT_HOST_SYSTEMS]"
}
_shu_builder_cleanup_temp_dir () {
rm -rf "$TEMP_DIR"
exit $1
}
# Setup DARWIN_SYSTEMS and LOCAL_HOST_SYSTEMS
# $1: List of host sytems.
_shu_builder_setup_local_systems () {
local HOST_SYSTEMS="$(commas_to_spaces "$1")"
local SYSTEM
# Compute the list of darwin host systems.
DARWIN_SYSTEMS=
for SYSTEM in $HOST_SYSTEMS; do
case $SYSTEM in
darwin*)
var_append DARWIN_SYSTEMS "$SYSTEM"
;;
esac
done
# Compute the list of local host systems, i.e. the ones that will be built
# on the machine running this script, as opposed to remotely with SSH.
LOCAL_HOST_SYSTEMS=$HOST_SYSTEMS
if [ "$DARWIN_SYSTEMS" -a "$(get_build_os)" != "darwin" ]; then
if [ -z "$DARWIN_SSH" ]; then
panic "Cannot build Darwin binaries on this machine, please use --darwin-ssh=<host>."
fi
LOCAL_HOST_SYSTEMS=
for SYSTEM in $HOST_SYSTEMS; do
case $SYSTEM in
darwin*)
;;
*)
var_append LOCAL_HOST_SYSTEMS "$SYSTEM"
;;
esac
done
fi
}
# Call this after 'option_parse' to process the build-related options.
# This also defines the following global variables:
# - TEMP_DIR: Temporary build directory.
# - HOST_SYSTEMS: List of host systems to build binaries for.
# - NUM_JOBS: Number of concurrent build jobs to perform.
# - CCACHE: Path to 'ccache' program is usable.
# - OLD_PATH: Value of $PATH before calling this function.
#
# This also ensures that if --build-dir=<dir> was not used, the temporary
# directory is properly removed when the script exits.
#
# $1: suffix for temporary build directories (e.g. 'android-emulator')
package_builder_process_options () {
if [ "$OPT_BUILD_DIR" ]; then
TEMP_DIR=$OPT_BUILD_DIR
else
TEMP_DIR=/tmp/$USER-build-${1:-temp}-$$
log "Auto-config: --build-dir=$TEMP_DIR"
fi
run mkdir -p "$TEMP_DIR" ||
panic "Could not create build directory: $TEMP_DIR"
if [ -z "$OPT_BUILD_DIR" ]; then
# Ensure temporary directory is deleted on script exit, unless
# --build-dir=<path> was used.
trap "_shu_builder_cleanup_temp_dir 0" EXIT
trap "_shu_builder_cleanup_temp_dir \$?" QUIT INT HUP
fi
if [ "$OPT_FORCE" ]; then
log "Cleaning up build directory."
run rm -rf "$TEMP_DIR"/build-*
fi
if [ "$OPT_NUM_JOBS" ]; then
NUM_JOBS=$OPT_NUM_JOBS
log "Parallel jobs count: $NUM_JOBS"
else
NUM_JOBS=$(get_build_num_cores)
log "Auto-config: --jobs=$NUM_JOBS"
fi
if [ "$OPT_NO_CCACHE" ]; then
if [ "$OPT_CCACHE" ]; then
panic "You can't use both --cache=<program> and --no-ccache at the same time!"
fi
CCACHE=
elif [ -z "$OPT_CCACHE" ]; then
CCACHE=$(find_program ccache)
if [ "$CCACHE" ]; then
log "Auto-config: --ccache=$CCACHE"
else
log "Auto-config: --no-ccache"
fi
else
log "Using ccache: $OPT_CCACHE"
fi
# Check host system(s).
if [ "$OPT_HOST" ]; then
HOST_SYSTEMS=$(commas_to_spaces "$OPT_HOST")
else
HOST_SYSTEMS=$DEFAULT_HOST_SYSTEMS
log "Auto-config: --host=$(spaces_to_commas "$HOST_SYSTEMS") [default]"
fi
HOST_SYSTEMS=$(commas_to_spaces "$HOST_SYSTEMS")
# An SSH wrapper is used
if [ "$OPT_SSH_WRAPPER" ]; then
ANDROID_EMULATOR_SSH_WRAPPER=$OPT_SSH_WRAPPER
elif [ "$ANDROID_EMULATOR_SSH_WRAPPER" ]; then
log "Auto-config: --ssh-wrapper=$ANDROID_EMULATOR_SSH_WRAPPER [ANDROID_EMULATOR_SSH_WRAPPER]"
fi
# Special handling for Darwin target systems.
## Handle remote darwin build
DARWIN_SSH=
if [ "$OPT_DARWIN_SSH" ]; then
DARWIN_SSH=$OPT_DARWIN_SSH
elif [ "$ANDROID_EMULATOR_DARWIN_SSH" ]; then
DARWIN_SSH=$ANDROID_EMULATOR_DARWIN_SSH
log "Auto-config: --darwin-ssh=$DARWIN_SSH [ANDROID_EMULATOR_DARWIN_SSH]"
fi
if [ "$DARWIN_SSH" ]; then
HAS_DARWIN=
for SYSTEM in $(commas_to_spaces "$HOST_SYSTEMS"); do
case $SYSTEM in
darwin-*)
HAS_DARWIN=true
;;
esac
done
if [ -z "$HAS_DARWIN" ]; then
var_append HOST_SYSTEMS "darwin-x86_64"
log "Auto-config: --host=$(spaces_to_commas "$HOST_SYSTEMS")' [darwin-ssh!]"
fi
fi
# Detect bad host system names, and list the good ones in case of error.
local BAD_SYSTEMS SYSTEM
for SYSTEM in $HOST_SYSTEMS; do
if ! list_contains "$_SHU_VALID_HOST_SYSTEMS" "$SYSTEM"; then
BAD_SYSTEMS="$BAD_SYSTEMS $SYSTEM"
fi
done
if [ "$BAD_SYSTEMS" ]; then
panic "Invalid host system name(s): [$BAD_SYSTEMS], use one of: $_SHU_VALID_HOST_SYSTEMS"
fi
# Compute the list of darwin host systems.
_shu_builder_setup_local_systems "$HOST_SYSTEMS"
# Save original path.
ORIGINAL_PATH=$PATH
}
# Find the packages list file in the prebuilts directory and parse it.
package_builder_parse_package_list () {
local ARCHIVE_DIR PACKAGE_LIST
if [ -z "$PREBUILTS_DIR" ]; then
panic "Missing PREBUILTS_DIR definition, did you call \
package_builder_process_options?"
fi
ARCHIVE_DIR=$PREBUILTS_DIR/archive
if [ ! -d "$ARCHIVE_DIR" ]; then
panic "Missing archive directory, please run download-sources.sh: $ARCHIVE_DIR"
fi
_SHU_BUILDER_ARCHIVE_DIR=$ARCHIVE_DIR
PACKAGE_LIST=$ARCHIVE_DIR/PACKAGES.TXT
if [ ! -f "$PACKAGE_LIST" ]; then
panic "Missing package list file: $PACKAGE_LIST"
fi
package_list_parse_file "$PACKAGE_LIST"
}
# Return the current prebuilts archive directory.
# One needs to call package_builder_parse_package_list () before
# Out: prebuilts archive directory path.
builder_archive_dir () {
printf %s "$_SHU_BUILDER_ARCHIVE_DIR"
}
# Check all timestamps and adjust HOST_SYSTEMS / DARWIN_SYSTEMS /
# LOCAL_HOST_SYSTEMS accordingly for all the things.
# $1: top-level install directory
# $2: timestamp label
builder_check_all_timestamps () {
local NEW_HOST_SYSTEMS
local SYSTEM
for SYSTEM in $(commas_to_spaces "$HOST_SYSTEMS"); do
if timestamp_check "$1"/$SYSTEM "$2"; then
log "[$SYSTEM] Already built."
else
var_append NEW_HOST_SYSTEMS "$SYSTEM"
fi
done
HOST_SYSTEMS=$NEW_HOST_SYSTEMS
_shu_builder_setup_local_systems "$HOST_SYSTEMS"
}
# Call this function to enable C++11 features. Must happen before
# any build_prepare_xxxxx function call.
builder_enable_cxx11 () {
_SHU_BUILDER_NO_CXX11=
}
# Call this function to disable C++11 features. Must happen before
# any build_prepare_xxxx function call.
build_disable_cxx11 () {
_SHU_BUILDER_NO_CXX11=true
}
# Run a command on the remote Darwin host when --darwin-ssh is used.
builder_remote_darwin_run () {
run $ANDROID_EMULATOR_SSH_WRAPPER ssh "$DARWIN_SSH" "$@"
}
# Run a 'scp' command from/to the rmote Darwin host when --darwin-ssh is used.
builder_remote_darwin_scp () {
run $ANDROID_EMULATOR_SSH_WRAPPER scp "$@"
}
# Run a 'rsync -hax --delete' command to retrieve files from the remote
# Darwin machine and copy them back to the local one. This uses the
# '-hax --delete' rsync parameters by default,
# $1+: parameters to 'rsync' command.
builder_remote_darwin_rsync () {
run $ANDROID_EMULATOR_SSH_WRAPPER rsync "$@"
}
# $1: darwin host system name (e.g. $SYSTEM)
# $2: local installation directory (e.g. $INSTALL_DIR)
builder_remote_darwin_retrieve_install_dir () {
dump "[$1] Retrieving remote darwin binaries"
mkdir -p "$2" || panic "Could not create final directory: $2"
run $ANDROID_EMULATOR_SSH_WRAPPER rsync -haz --delete \
$DARWIN_SSH:$DARWIN_REMOTE_DIR/install-prefix/$1 "$2"
}
# Prepare for a remote darwin build. This takes as a parameter the
# name of a temporary directory, e..g '/tmp/foo/bar/'.
# This function populates the directory with some scripts and
# prebuilt toolchain binaries if necessary, then defines the
# following variables:
# DARWIN_PKG_DIR: temporary package directory (e.g. '/tmp/foo/bar')
# DARWIN_PKG_NAME: temporary package name (e.g. 'bar')
# DARWIN_REMOTE_DIR: remote build directory to use.
# DARWIN_BUILD_FLAGS: common build flags to use with build.sh
#
# The caller should then add any appropriate sources or binaries, then
# call the function builder_run_remote_build declared below to actually
# perform the remote build through SSH
#
# NOTE: Only call this when --darwin-ssh or equivalent is used.
#
# $1: Package directory (e.g. '/tmp/foo/bar')
# $2: Optional archive directory.
#
builder_prepare_remote_darwin_build () {
local PKG_DIR=${1%%/}
local PKG_NAME=$(basename "$PKG_DIR")
local ARCHIVE_DIR="${2:-$(builder_archive_dir)}"
DARWIN_PKG_NAME=$PKG_NAME
DARWIN_PKG_DIR="$PKG_DIR"
DARWIN_REMOTE_DIR=/tmp/$PKG_NAME
local TOOLCHAIN_SUBDIR=$(aosp_prebuilt_toolchain_subdir_for darwin)
if [ -z "$DARWIN_SSH" ]; then
# Sanity check
panic "builder_prepare_remote_darwin_build: No DARWIN_SSH defined!"
fi
DARWIN_SYSTEMS=$(commas_to_spaces "$DARWIN_SYSTEMS")
log "Preparing remote darwin build."
run mkdir -p "$PKG_DIR" && run rm -rf "$PKG_DIR"/*
run mkdir -p "$PKG_DIR/aosp/prebuilts/gcc"
copy_directory "$AOSP_DIR"/$TOOLCHAIN_SUBDIR \
"$PKG_DIR"/aosp/$TOOLCHAIN_SUBDIR
copy_directory "$(program_directory)" "$PKG_DIR/scripts"
local BREAKPAD_SUBDIR
for DARWIN_SYSTEM in $DARWIN_SYSTEMS; do
BREAKPAD_SUBDIR=$(aosp_prebuilt_breakpad_subdir_for $DARWIN_SYSTEM)
run mkdir -p "$PKG_DIR/aosp/$BREAKPAD_SUBDIR"
copy_directory "$AOSP_DIR"/$BREAKPAD_SUBDIR \
"$PKG_DIR"/aosp/$BREAKPAD_SUBDIR
done
DARWIN_BUILD_FLAGS="--verbosity=$(get_verbosity)"
if [ "$OPT_NUM_JOBS" ]; then
var_append DARWIN_BUILD_FLAGS "-j$OPT_NUM_JOBS"
fi
if [ "$OPT_NO_CCACHE" ]; then
var_append DARWIN_BUILD_FLAGS "--no-ccache"
fi
if [ "$ARCHIVE_DIR" ]; then
copy_directory "$ARCHIVE_DIR" "$DARWIN_PKG_DIR"/archive
fi
DARWIN_REMOTE_DIR=/tmp/$DARWIN_PKG_NAME
}
# Call this after builder_prepare_remote_darwin_build and populating
# $DARWIN_PKG_DIR with build.sh and any other required files to run
# a remote darwin build through SSH.
#
# $1: Optional build script path. If empty, a 'standard' build.sh script
# is generated by this function. Otherwise, it is copied under
# $DARWIN_PKG_DIR/ if it's not already there.
builder_run_remote_darwin_build () {
local BUILD_SH="$1"
if [ -z "$BUILD_SH" ]; then
BUILD_SH="$DARWIN_PKG_DIR"/build.sh
# Generate a script to rebuild all binaries from sources.
# Note that the use of the '-l' flag is important to ensure
# that this is run under a login shell. This ensures that
# ~/.bash_profile is sourced before running the script, which
# puts MacPorts' /opt/local/bin in the PATH properly.
#
# If not, the build is likely to fail with a cryptic error message
# like "readlink: illegal option -- f"
cat > $BUILD_SH <<EOF
#!/bin/bash -l
PROGDIR=\$(dirname \$0)
\$PROGDIR/scripts/$(program_name) \\
--build-dir=$DARWIN_REMOTE_DIR/build \\
--host=$(spaces_to_commas "$DARWIN_SYSTEMS") \\
--install-dir=$DARWIN_REMOTE_DIR/install-prefix \\
--prebuilts-dir=$DARWIN_REMOTE_DIR \\
--aosp-dir=$DARWIN_REMOTE_DIR/aosp \\
$DARWIN_BUILD_FLAGS
EOF
else # BUILD_SH not empty.
if [ "${BUILD_SH#$DARWIN_PKG_DIR}" = "$BUILD_SH" ]; then
# The script is not under $DARWIN_PKG_DIR so copy it there.
run cp "$BUILD_SH" "$DARWIN_PKG_DIR"/build.sh ||
panic "Could not copy build script to $DARWIN_PKG_DIR/: $BUILD_SH"
BUILD_SH=$DARWIN_PKG_DIR/build.sh
fi
fi
chmod a+x "$BUILD_SH"
log "Erasing previours remote build directory."
builder_remote_darwin_run rm -rf $DARWIN_REMOTE_DIR
log "Copying files to remote darwin host."
(tar cf - -C "$DARWIN_PKG_DIR"/.. "$DARWIN_PKG_NAME") |
(builder_remote_darwin_run tar xf - -C /tmp) ||
panic "Could not send files to remote darwin host"
rm -rf "$DARWIN_PKG_DIR"
log "Performing remote darwin build."
builder_remote_darwin_run $DARWIN_REMOTE_DIR/build.sh
}
# Generate a small shell script that can be sourced to prepare the
# build for a given host system.
# $1: Host system name (e.g. linux-x86_64)
# $2: AOSP source directory.
# $3: Optional list of prefix directories (space-separated)
builder_prepare_for_host () {
_shu_builder_prepare_for_host "$1" "$2" "auto" "$3"
}
# Same as builder_prepare_for_host, but ensures that the toolchain wrapper
# doesn't use a host-specific binprefix, i.e. it will be named 'gcc' instead
# of 'x86_64-linux-gcc'. This is required to build certain modules.
# $1: Host system name
# $2: AOSP source directory.
# $3: Optional list of prefix directories (space-separated)
builder_prepare_for_host_no_binprefix () {
_shu_builder_prepare_for_host "$1" "$2" "none" "$3"
}
# Generate a small shell script that can be sourced to prepare the
# build for a given host system.
# $1: Host system name (e.g. linux-x86_64)
# $2: AOSP source directory.
# $3: Binprefix, special values 'auto' and 'none' are recognized.
# 'auto' means the binprefix will depend on $1, and 'none' that no
# binprefix should be used.
# $4: Optional list of prefix directories (space-separated)
_shu_builder_prepare_for_host () {
_SHU_BUILDER_CURRENT_HOST=$1
_SHU_BUILDER_CURRENT_TEXT="[$_SHU_BUILDER_CURRENT_HOST]"
_SHU_BUILDER_CONFIGURE_FLAGS=
_SHU_BUILDER_HOST_EXE_EXTENSION=
case $_SHU_BUILDER_CURRENT_HOST in
windows-*)
_SHU_BUILDER_HOST_EXE_EXTENSION=.exe
;;
*)
;;
esac
case $_SHU_BUILDER_CURRENT_HOST in
linux-x86_64)
_SHU_BUILDER_GNU_CONFIG_HOST=x86_64-linux
;;
linux-x86)
_SHU_BUILDER_GNU_CONFIG_HOST=i686-linux
;;
windows-x86)
_SHU_BUILDER_GNU_CONFIG_HOST=i686-w64-mingw32
;;
windows-x86_64)
_SHU_BUILDER_GNU_CONFIG_HOST=x86_64-w64-mingw32
;;
darwin-*)
# Use host compiler.
_SHU_BUILDER_GNU_CONFIG_HOST=
;;
*)
panic "Host system '$CURRENT_HOST' is not supported by this script!"
;;
esac
if [ "$_SHU_BUILDER_GNU_CONFIG_HOST" ]; then
_SHU_BUILDER_GNU_CONFIG_HOST_FLAG="--host=$_SHU_BUILDER_GNU_CONFIG_HOST"
_SHU_BUILDER_GNU_CONFIG_HOST_PREFIX=${_SHU_BUILDER_GNU_CONFIG_HOST}-
else
_SHU_BUILDER_GNU_CONFIG_HOST_FLAG=
_SHU_BUILDER_GNU_CONFIG_HOST_PREFIX=
fi
case $3 in
auto) # Nothing to do.
;;
none)
_SHU_BUILDER_GNU_CONFIG_HOST_PREFIX=
;;
*)
_SHU_BUILDER_GNU_CONFIG_HOST_PREFIX=$3
;;
esac
log "$_SHU_BUILDER_CURRENT_TEXT Using binprefix [$_SHU_BUILDER_GNU_CONFIG_HOST_PREFIX]"
PATH=$ORIGINAL_PATH
_SHU_BUILDER_BUILD_DIR=$TEMP_DIR/build-$_SHU_BUILDER_CURRENT_HOST
log "$_SHU_BUILDER_CURRENT_TEXT Creating build directory: $_SHU_BUILDER_BUILD_DIR"
run mkdir -p "$_SHU_BUILDER_BUILD_DIR"
_SHU_BUILDER_SRC_DIR=$TEMP_DIR/src
_SHU_BUILDER_ENV_SH=$_SHU_BUILDER_BUILD_DIR/env.sh
_SHU_BUILDER_PREFIX=$TEMP_DIR/install-$_SHU_BUILDER_CURRENT_HOST
_SHU_BUILDER_TOOLCHAIN_PREFIX=$_SHU_BUILDER_PREFIX
local _PREFIX
for _PREFIX in $4; do
var_append _SHU_BUILDER_TOOLCHAIN_PREFIX "$_PREFIX"
done
log "$_SHU_BUILDER_CURRENT_TEXT Using toolchain build prefix: $_SHU_BUILDER_TOOLCHAIN_PREFIX"
_SHU_BUILDER_PKG_CONFIG_PATH=$_SHU_BUILDER_PREFIX/share/pkgconfig:$PKG_CONFIG_PATH
TOOLCHAIN_WRAPPER_DIR=$_SHU_BUILDER_BUILD_DIR/toolchain-wrapper
case $_SHU_BUILDER_CURRENT_HOST in
linux-*)
_SHU_BUILDER_PKG_CONFIG_PATH=$TOOLCHAIN_WRAPPER_DIR/pkgconfig:$_SHU_BUILDER_PKG_CONFIG_PATH
;;
esac
cat > "$_SHU_BUILDER_ENV_SH" <<EOF
# Auto-generated - DO NOT EDIT!
# Source this shell script to prepare the build for $CURRENT_HOST systems.
_SHU_BUILDER_CURRENT_HOST="$_SHU_BUILDER_CURRENT_HOST"
_SHU_BUILDER_CURRENT_TEXT="$_SHU_BUILDER_CURRENT_TEXT"
_SHU_BUILDER_GNU_CONFIG_HOST=$_SHU_BUILDER_GNU_CONFIG_HOST
_SHU_BUILDER_GNU_CONFIG_HOST_PREFIX=$_SHU_BUILDER_GNU_CONFIG_HOST_PREFIX
_SHU_BUILDER_GNU_CONFIG_HOST_FLAG=$_SHU_BUILDER_GNU_CONFIG_HOST_FLAG
_SHU_BUILDER_BUILD_DIR="$_SHU_BUILDER_BUILD_DIR"
_SHU_BUILDER_PREFIX="$_SHU_BUILDER_PREFIX"
_SHU_BUILDER_PKG_CONFIG_PATH="$_SHU_BUILDER_PKG_CONFIG_PATH"
_SHU_BUILDER_CONFIGURE_FLAGS="$_SHU_BUILDER_CONFIGURE_FLAGS"
PATH="$PATH"
export PATH \
_SHU_BUILDER_CURRENT_HOST \
_SHU_BUILDER_CURRENT_TEXT \
_SHU_BUILDER_GNU_CONFIG_HOST \
_SHU_BUILDER_GNU_CONFIG_HOST_PREFIX \
_SHU_BUILDER_GNU_CONFIG_HOST_FLAG \
_SHU_BUILDER_BUILD_DIR \
_SHU_BUILDER_SRC_DIR \
_SHU_BUILDER_PREFIX \
_SHU_BUILDER_PKG_CONFIG_PATH \
_SHU_BUILDER_CONFIGURE_FLAGS
EOF
TOOLCHAIN_WRAPPER_DIR=$_SHU_BUILDER_BUILD_DIR/toolchain-wrapper
log "$_SHU_BUILDER_CURRENT_TEXT Generating $_SHU_BUILDER_GNU_CONFIG_HOST wrapper toolchain in $TOOLCHAIN_WRAPPER_DIR"
local EXTRA_FLAGS
if [ "$CCACHE" ]; then
var_append EXTRA_FLAGS "--ccache=$CCACHE"
else
var_append EXTRA_FLAGS "--no-ccache"
fi
for _PREFIX in $_SHU_BUILDER_TOOLCHAIN_PREFIX; do
var_append EXTRA_FLAGS "--prefix=$_PREFIX"
done
if [ ! "$_SHU_BUILDER_NO_CXX11" ]; then
var_append EXTRA_FLAGS "--cxx11"
fi
run $(program_directory)/gen-android-sdk-toolchain.sh \
--aosp-dir="$2" \
--host=$_SHU_BUILDER_CURRENT_HOST \
--binprefix=${_SHU_BUILDER_GNU_CONFIG_HOST_PREFIX:--} \
$EXTRA_FLAGS \
$TOOLCHAIN_WRAPPER_DIR ||
panic "Cannot generate toolchain wrapper!"
cat >> "$_SHU_BUILDER_ENV_SH" <<EOF
PATH=$TOOLCHAIN_WRAPPER_DIR:\$PATH
export PATH
EOF
PATH=$TOOLCHAIN_WRAPPER_DIR:$PATH
log "$_SHU_BUILDER_CURRENT_TEXT Path: $(echo \"$PATH\" | tr ' ' '\n')"
# Read the source script.
. "$_SHU_BUILDER_ENV_SH"
}
builder_text () {
printf %s "$_SHU_BUILDER_CURRENT_TEXT"
}
builder_host () {
printf %s "$_SHU_BUILDER_CURRENT_HOST"
}
builder_host_exe_extension () {
printf %s "$_SHU_BUILDER_HOST_EXE_EXTENSION"
}
builder_build_dir () {
printf %s "$_SHU_BUILDER_BUILD_DIR"
}
builder_src_dir () {
printf %s "$_SHU_BUILDER_SRC_DIR"
}
builder_install_prefix () {
printf %s "$_SHU_BUILDER_PREFIX"
}
builder_gnu_config () {
printf %s "$_SHU_BUILDER_GNU_CONFIG"
}
builder_gnu_config_host_prefix () {
printf %s "$_SHU_BUILDER_GNU_CONFIG_HOST_PREFIX"
}
builder_gnu_config_host_flag () {
printf %s "$_SHU_BUILDER_GNU_CONFIG_HOST_FLAG"
}
builder_host_ext () {
printf %s "$_SHU_BUILDER_HOST_EXE_EXTENSION"
}
builder_reset_configure_flags () {
_SHU_BUILDER_CONFIGURE_FLAGS="$*"
}
builder_add_configure_flags () {
var_append _SHU_BUILDER_CONFIGURE_FLAGS "$*"
}
# Call this function to disable verbose output during the 'make install' pass
# of builder_build_autotools_package(). This is necessary for certain packages
# with broken Makefiles (e.g. e2fsprogs when built on Darwin).
_SHU_BUILDER_DISABLE_VERBOSE_INSTALL=
builder_disable_verbose_install () {
_SHU_BUILDER_DISABLE_VERBOSE_INSTALL=true
}
# Call this function to disable parallel jobs during the 'make install' pass
# of builder_build_autotools_package(). This is necessary for certain packages
# with broken Makefiles.
_SHU_BUILDER_DISABLE_PARALLEL_INSTALL=
builder_disable_parallel_install () {
_SHU_BUILDER_DISABLE_PARALLEL_INSTALL=true
}
# Unpack package sources if needed into $(builder_src_dir).
# $1: Package basename.
# $2: Optional archive source directory.
builder_unpack_package_source () {
local PKG_NAME ARCHIVE_DIR TIMESTAMP SRC_DIR
PKG_NAME=$(package_list_get_unpack_src_dir $1)
ARCHIVE_DIR=${2:-$(builder_archive_dir)}
SRC_DIR=$(builder_src_dir)
TIMESTAMP=$SRC_DIR/timestamp-$PKG_NAME
if [ ! -f "$TIMESTAMP" -o "$OPT_FORCE" ]; then
package_list_unpack_and_patch "$1" "$ARCHIVE_DIR" "$SRC_DIR"
touch $TIMESTAMP
fi
}
# Build a given autotools based package and run customized install commands
#
# $1: Package basename
# $2: Make commands, e.g. install
# $3+: Additional configure options.
builder_build_autotools_package_full_install () {
local PKG_NAME=$(package_list_get_src_dir $1)
local INSTALL_COMMANDS="$2"
local PKG_SRC_DIR=$(builder_src_dir)/$PKG_NAME
local PKG_BUILD_DIR=$(builder_build_dir)/$PKG_NAME
local PKG_TIMESTAMP=${PKG_BUILD_DIR}-timestamp
shift; shift;
if [ -f "$PKG_TIMESTAMP" -a -z "$OPT_FORCE" ]; then
# Return early if the package was already built.
return 0
fi
case $_SHU_BUILDER_CURRENT_HOST in
darwin*)
# Required for proper Autotools builds on Darwin
builder_disable_verbose_install
;;
esac
local PKG_FULLNAME="$(basename $PKG_NAME)"
dump "$(builder_text) Building $PKG_FULLNAME"
local INSTALL_FLAGS
if [ -z "$_SHU_BUILDER_DISABLE_PARALLEL_INSTALL" ]; then
var_append INSTALL_FLAGS "-j$NUM_JOBS"
fi
if [ -z "$_SHU_BUILDER_DISABLE_VERBOSE_INSTALL" ]; then
var_append INSTALL_FLAGS "V=1";
fi
(
run mkdir -p "$PKG_BUILD_DIR" &&
run cd "$PKG_BUILD_DIR" &&
export LDFLAGS="-L$_SHU_BUILDER_PREFIX/lib" &&
export CPPFLAGS="-I$_SHU_BUILDER_PREFIX/include" &&
export PKG_CONFIG_LIBDIR="$_SHU_BUILDER_PREFIX/lib/pkgconfig" &&
export PKG_CONFIG_PATH="$PKG_CONFIG_LIBDIR:$_SHU_BUILDER_PKG_CONFIG_PATH" &&
run "$PKG_SRC_DIR"/configure \
--prefix=$_SHU_BUILDER_PREFIX \
$_SHU_BUILDER_GNU_CONFIG_HOST_FLAG \
$_SHU_BUILDER_CONFIGURE_FLAGS \
"$@" &&
run make -j$NUM_JOBS V=1 &&
run make $INSTALL_COMMANDS $INSTALL_FLAGS
) ||
panic "Could not build and install $PKG_FULLNAME"
touch "$PKG_TIMESTAMP"
}
# Build with the default 'make install' command in the end
#
# $1: Package basename
# $2+: Additional configure options.
builder_build_autotools_package() {
local FIRST="$1"
shift;
builder_build_autotools_package_full_install "$FIRST" install "$@"
}