blob: 9f0813ee17f34d636786efbdf0c2828611e3fabf [file] [log] [blame]
# Copyright 2014 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 routines - do not execute directly.
# Sanitize environment
set -e
export LANG=C
export LC_ALL=C
_SHU_PROGDIR=$(dirname "$0")
_SHU_PROGNAME=$(basename "$0")
# Print an error message to stderr then exit the current process.
panic () {
echo "ERROR: $@" >&2
exit 1
}
# Internal verbosity level. Note that this value is inherited from
# the VERBOSE environment variable.
_SHU_VERBOSE=${VERBOSE:-1}
# Increment internal verbosity level.
increment_verbosity () {
_SHU_VERBOSE=$(( $_SHU_VERBOSE + 1 ))
}
# Decrement internal verbosity level.
decrement_verbosity () {
_SHU_VERBOSE=$(( $_SHU_VERBOSE - 1 ))
}
# Return internal verbosity level, clamped to 0 as a minimum bound.
get_verbosity () {
local RET=$_SHU_VERBOSE
if [ "$RET" -lt 0 ]; then
RET=0
fi
echo "$RET"
}
# Used internally to conditionally print a message.
# $1: message's verbosity level. If greater or equal than $_SHU_VERBOSE then
# the message will be ignored.
# $2+: message to print to stdout.
dump_n () {
local LEVEL=$1
shift
if [ "$LEVEL" -lt "$_SHU_VERBOSE" ]; then
printf "%s\n" "$@"
fi
}
# Dump a message to standard output.
dump () {
dump_n 0 "$@"
}
# Dump a message to standard output if --verbose was used.
log () {
dump_n 1 "$@"
}
# Dump a message to standard output if --verbose --verbose is used.
log2 () {
dump_n 2 "$@"
}
# Run a command, output depends on verbosity level
run () {
local VERBOSE=$_SHU_VERBOSE
if [ "$VERBOSE" -lt 0 ]; then
VERBOSE=0
fi
if [ "$VERBOSE" -gt 1 ]; then
echo "COMMAND: $@"
fi
case $VERBOSE in
0|1)
"$@" >/dev/null 2>&1
;;
2)
"$@" >/dev/null
;;
*)
"$@"
;;
esac
}
# Return the current script's directory.
program_directory () {
printf "%s" "$_SHU_PROGDIR"
}
# Return the current script's filename.
program_name () {
printf "%s" "$_SHU_PROGNAME"
}
# Return the value of a given named variable.
# $1: variable name
#
# example:
# FOO=BAR
# BAR=ZOO
# echo `var_value $FOO`
# will print 'ZOO'
#
var_value () {
eval printf %s \"\$$1\"
}
# Return success if variable $1 is set and non-empty, failure otherwise.
# $1: Variable name.
# Usage example:
# if var_is_set FOO; then
# .. Do something the handle FOO condition.
# fi
var_is_set () {
test -n "$(var_value $1)"
}
# Set the value of a given name variables.
# $1: Variable name.
# $2+: Variable value.
# example:
# FOO=BAR
# var_assign $FOO bar
# is equivalent to
# BAR=bar
var_assign () {
local _var_assign_varname
_var_assign_varname=$1
shift
eval $_var_assign_varname=\'"$*"\'
}
# Append a space-separated list of items to a given variable.
# $1: Variable name.
# $2+: Variable value.
# Example:
# FOO=
# var_append FOO foo (FOO is now 'foo')
# var_append FOO bar (FOO is now 'foo bar')
# var_append FOO zoo (FOO is now 'foo bar zoo')
var_append () {
local _var_append_varname
_var_append_varname=$1
shift
if test $(var_value $_var_append_varname); then
eval $_var_append_varname=\$$_var_append_varname\'\ "$*"\'
else
eval $_var_append_varname=\'"$*"\'
fi
}
# Import shell script $1. Similar to sourcing the script except
# that each script will only be sourced once, even with multiple
# dependencies.
shell_import () {
local SCRIPT="$_SHU_PROGDIR/$1"
if [ ! -f "$SCRIPT" ]; then
panic "Missing script: $SCRIPT"
fi
local SCRIPT_TAG=_SHU_SHELL_SCRIPT_TAG__${1%%.shi}
SCRIPT_TAG=$(echo "$SCRIPT_TAG" | tr '-' '_')
case $(var_value $SCRIPT_TAG) in
imported)
# Script is already imported.
return 0
;;
importing)
# Script is already being imported, this is
# a circular dependency.
panic "Circular dependency when trying to import $1"
;;
*)
# Import the script.
var_assign $SCRIPT_TAG importing
. "$SCRIPT"
var_assign $SCRIPT_TAG imported
;;
esac
}
# Unpack a given archive into a given destination directory.
# $1: Archive path
# $2: Destination directory
unpack_archive () {
local PKG_PATH="$1"
local DEST_DIR="$2"
case $PKG_PATH in
*.tar.gz|*.tar.bz2|*.tar.xz)
run tar xf "$PKG_PATH" -C "$DEST_DIR"
;;
*.zip)
run unzip -q -o -d "$DEST_DIR" "$PKG_PATH"
;;
*)
panic "Unsupported package format: $PKG_PATH"
;;
esac
}
# Return the build machine's operating system tag.
# Valid return values are:
# linux
# darwin
# freebsd
# windows (really MSys)
# cygwin
get_build_os () {
if [ -z "$_SHU_BUILD_OS" ]; then
_SHU_BUILD_OS=$(uname -s)
case $_SHU_BUILD_OS in
Darwin)
_SHU_BUILD_OS=darwin
;;
FreeBSD) # note: this is not tested
_SHU_BUILD_OS=freebsd
;;
Linux)
# note that building 32-bit binaries on x86_64 is handled later
_SHU_BUILD_OS=linux
;;
CYGWIN*|*_NT-*)
_SHU_BUILD_OS=windows
if [ "x$OSTYPE" = xcygwin ] ; then
_SHU_BUILD_OS=cygwin
fi
;;
esac
fi
echo "$_SHU_BUILD_OS"
}
# Return the build machine's CPU architecture.
# Valid return values are:
# x86
# x86_64
get_build_arch () {
local TEST
if [ -z "$_SHU_BUILD_ARCH" ]; then
case $(get_build_os) in
linux|darwin)
_SHU_BUILD_ARCH=$(uname -m)
# Kernel bitness might not match user space, so test
# the bitness of our shell to know what the user is
# really running.
TEST=$(/usr/bin/file -L $SHELL 2>/dev/null | grep 'x86[_-]64')
if [ "$TEST" ]; then
_SHU_BUILD_ARCH=x86_64
fi
;;
windows|cygwin)
case $PROCESSOR_ARCHITECTURE in
ADM64)
_SHU_BUILD_ARCH=x86_64
;;
*)
_SHU_BUILD_ARCH=x86
;;
esac
;;
*)
_SHU_BUILD_ARCH=$(uname -p)
;;
esac
fi
echo "$_SHU_BUILD_ARCH"
}
# Return the executable extension for a given operating system tag.
# $1: operating system tag.
_shu_get_exe_extension_for () {
case $1 in
windows|cygwin)
echo ".exe"
;;
*)
echo ""
esac
}
# Return the dynamic library extension for a given operating system tag.
# $1: operating system tag.
_shu_get_dll_extension_for () {
case $1 in
darwin)
echo ".dylib"
;;
windows|cygwin)
echo ".dll"
;;
*)
echo ".so"
;;
esac
}
# Return the extension of executables on the build machine.
get_build_exe_extension () {
if [ -z "$_SHU_BUILD_EXE_EXTENSION_DEFINED" ]; then
_SHU_BUILD_EXE_EXTENSION=$(_shu_get_exe_extension_for $(get_build_os))
_SHU_BUILD_EXE_EXTENSION_DEFINED=true
fi
echo "$_SHU_BUILD_EXE_EXTENSION"
}
# Return the extension of dynamic libraries on the build machine.
get_build_dll_extension () {
if [ -z "$_SHU_BUILD_DLL_EXTENSION_DEFINED" ]; then
_SHU_BUILD_DLL_EXTENSION=$(_shu_get_dll_extension_for $(get_build_os))
_SHU_BUILD_DLL_EXTENSION_DEFINED=true
fi
echo "$_SHU_BUILD_DLL_EXTENSION"
}
# Return the number of CPU cores on the build machine.
get_build_num_cores () {
case $(get_build_os) in
linux)
grep -c -e processor /proc/cpuinfo 2>/dev/null || echo 1
;;
darwin|freebsd)
sysctl -n hw.ncpu 2>/dev/null || echo 1
;;
windows|cygwin)
echo "${NUMBER_OF_PROCESSORS:-1}"
;;
*)
echo "1"
;;
esac
}
# Convert commas into spaces.
# $1: input string
# Out: input string, with each comma replaced by a space.
commas_to_spaces () {
printf "%s" "$1" | tr ',' ' '
}
# Convert spaces into commas
# $1: input string
# Out: input string, with contiguous spaces replaced by a comma.
# NOTE: This also strips leading/trailing space.
spaces_to_commas () {
local ITEM RET
for ITEM in $1; do
if [ -z "$RET" ]; then
RET=$ITEM
else
RET="$RET,$ITEM"
fi
done
printf "%s" "$RET"
}
# Return success iff item |$2| is in list |$1|.
# $1: input list
# $2: item to find in list.
list_contains () {
local ITEM
for ITEM in $(commas_to_spaces "$1"); do
if [ "$ITEM" = "$2" ]; then
return 0
fi
done
return 1
}