blob: 1e7fc4ac60ad2097ddf2476926a7ca561acdd0a3 [file] [log] [blame]
#!/bin/bash -e
set -o pipefail
ROOT_DIR=$(cd $(dirname $0); pwd)
CUR_DIR=$(pwd)
if [ -n "${MAKE_JOBS}" ]; then
CPUS=${MAKE_JOBS}
else
CPUS=$(nproc)
#CPUS=$(($(nproc)/2))
fi
#### TODO LIST ###########################
# 1. support for OUT_DIR specification
# 2. support for repo sync multiple configs
# into one workspace
##########################################
### variables could be changed via parameters
build_config=""
build_config_url=""
MIRROR=""
DEFAULT_MANIFEST_URL="https://android.googlesource.com/platform/manifest"
skip_init=false
skip_sync=false
PINNED_MANIFEST=""
NO_BUILD=false
INSTALL_PACKAGE=false
REPO_GROUPS="default,-notdefault"
DEFAULT_MANIFEST_BRANCH="master"
########### workarounds ##################
# workaround for boot_fat.uefi.img for error:
# AssertionError: Can only handle FAT with 1 reserved sector
# git clone https://github.com/dosfstools/dosfstools -b v3.0.28
# cd dosfstools && make
export PATH=${ROOT_DIR}/dosfstools:${PATH}
# workaround to use openjdk-8 for oreo builds
export JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64/
export PATH=${JAVA_HOME}/bin:$PATH
########### contants #####################
REPO_URL=""
BASE_MANIFEST="default.xml"
default_build_config_url_prefix="https://android-git.linaro.org/android-build-configs.git/plain"
######## functions define ################
function export_config(){
local f_config=$1
while read line; do
if echo "${line}"|tr -d '[:blank:]'|grep -q '^$'; then
continue
fi
if ! echo $line |grep -q '^#'; then
eval "export $line"
fi
done < ${f_config}
}
function repo_sync_patch(){
build_config_tmp=""
if [ -n "${build_config}" ]; then
# case when -c|--config specified
if [ -n "${PINNED_MANIFEST}" ]; then
# need to get the exact same build config file in the pinned manifest
abc_line=$(grep android-build-configs ${PINNED_MANIFEST}|tr -d '"')
abc_commit=''
for field in ${abc_line}; do
if echo ${field}|grep 'revision=' ; then
abc_commit=$(echo ${field}|sed 's/revision=//')
fi
done
if [ -z "${abc_commit}" ]; then
echo "Failed to find the commit information for android-build-configs repository in ${PINNED_MANIFEST}"
echo "Please check first, and try it again"
exit 1
fi
pinned_config_url=https://android-git.linaro.org/android-build-configs.git/plain/${build_config}?id=${abc_commit}
f_tmp=$(mktemp -u lcr-pinned-XXX)
wget ${pinned_config_url} -O ${f_tmp}
export_config ${f_tmp}
#rm -fr ${f_tmp}
elif [ -n "${build_config_url}" ]; then
build_config_tmp=$(mktemp -u lcr-XXX)
build_config_remote_url=${build_config_url}
if echo "${build_config_remote_url}"|grep -q '^/'; then
cp -vf "${build_config_remote_url}" ${build_config_tmp}
else
wget ${build_config_remote_url} -O ${build_config_tmp}
fi
export_config ${build_config_tmp}
rm -f android-build-configs/${build_config}
elif [ ! -f android-build-configs/${build_config} ]; then
f_tmp=$(mktemp -u lcr-XXX)
build_config_remote_url="${default_build_config_url_prefix}/${build_config}"
wget ${build_config_remote_url} -O ${f_tmp}
export_config ${f_tmp}
else
export_config android-build-configs/${build_config}
fi
#else
# case when -tp|--target-product specified
fi
if ! ${skip_init}; then
opt_group=${opt_repo_groups:-${REPO_GROUPS}}
if [ -n "${MIRROR}" ]; then
url_manifest="${MIRROR}"
elif [ -n "${MANIFEST_URL}" ]; then
url_manifest="${MANIFEST_URL}"
else
url_manifest="${DEFAULT_MANIFEST_URL}"
fi
if [ -n "${REPO_URL}" ]; then
opt_repo_url="--repo-url=${REPO_URL}"
else
opt_repo_url=""
fi
while ! repo init \
-u "${url_manifest}" \
-m "${BASE_MANIFEST}" \
-g "${opt_group}" \
${opt_repo_url} \
-b "${MANIFEST_BRANCH:-${DEFAULT_MANIFEST_BRANCH}}"; do
sleep 30
done
fi
# only clone or update local_manifests when pinned manifest file not exist
if [ -z "${PINNED_MANIFEST}" ]; then
if [ -z "${LOCAL_MANIFEST}" ]; then
# remove local_manifests when LOCAL_MANIFEST not specified
${skip_init} || rm -fr .repo/local_manifests
elif [ -d .repo/local_manifests ]; then
cd .repo/local_manifests
git pull
cd -
else
git clone "${LOCAL_MANIFEST}" -b "${LOCAL_MANIFEST_BRANCH}" .repo/local_manifests
fi
elif [ -d .repo/local_manifests ]; then
echo "Please remove the .repo/local_manifests directory first"
echo "Otherwise duplicate of projects error might be reported"
exit 1
fi
if [ -n "${PINNED_MANIFEST}" ]; then
PINNED_MANIFEST_name=$(basename ${PINNED_MANIFEST})
PINNED_MANIFEST_dir=$(cd $(dirname ${PINNED_MANIFEST}); pwd)
PINNED_MANIFEST_ABS="${PINNED_MANIFEST_dir}/${PINNED_MANIFEST_name}"
repo_sync_cmd="repo sync -c --force-sync -j${CPUS} -m ${PINNED_MANIFEST_ABS}"
else
repo_sync_cmd="repo sync -c --force-sync -j${CPUS}"
fi
while ! ${repo_sync_cmd}; do
echo "Try again for repo sync in one minute"
sleep 60
done
mkdir -p out/pinned-manifest
repo manifest -r -o out/pinned-manifest/$(date +%Y-%m-%d-%H-%M)-pinned-manifest.xml
for patch in ${PATCHSETS}; do
./android-patchsets/${patch}
done
if [ -n "${build_config_tmp}" ] && [ ! -f android-build-configs/${build_config} ]; then
mkdir -p android-build-configs
cp -vf "${build_config_tmp}" "android-build-configs/${build_config}"
fi
}
function build_with_config(){
local f_config="android-build-configs/${build_config}"
if [ -f "${f_config}" ]; then
export_config "${f_config}"
fi
if [ -n "${HOOK_PRE_ANDROID_BUILD}" ]; then
./android-build-configs/hooks/${HOOK_PRE_ANDROID_BUILD}
fi
set +x
echo "source build/envsetup.sh"
source build/envsetup.sh
set -x
local lunch_str=""
if [ -n "${LUNCH}" ]; then
lunch_str="${LUNCH}"
elif [ -n "${TARGET_PRODUCT}" ]; then
if [ -n "${OPT_TARGET_BUILD_VARIANT}" ]; then
lunch_str="${TARGET_PRODUCT}-${OPT_TARGET_BUILD_VARIANT}"
elif [ -n "${TARGET_BUILD_VARIANT}" ]; then
lunch_str="${TARGET_PRODUCT}-${TARGET_BUILD_VARIANT}"
else
lunch_str="${TARGET_PRODUCT}-userdebug"
fi
elif [ -n "${OPT_TARGET_PRODUCT}" ]; then
if [ -n "${OPT_TARGET_BUILD_VARIANT}" ]; then
lunch_str="${OPT_TARGET_PRODUCT}-${OPT_TARGET_BUILD_VARIANT}"
elif [ -n "${TARGET_BUILD_VARIANT}" ]; then
lunch_str="${OPT_TARGET_PRODUCT}-${TARGET_BUILD_VARIANT}"
else
lunch_str="${OPT_TARGET_PRODUCT}-userdebug"
fi
else
echo "Please specify at least one of LUNCH or TARGET_PRODUCT"
exit 1
fi
set +x
echo "lunch ${lunch_str}"
lunch ${lunch_str}
MAKE_TARGETS=${MAKE_TARGETS:-droidcore}
set -x
echo "Start to build: make ${MAKE_TARGETS} -j${CPUS}" |tee -a time.log
date +%Y-%m-%d-%H-%M >>time.log
(time LANG=C make ${MAKE_TARGETS} -j${CPUS} ) 2>&1 |tee build-${TARGET_PRODUCT}.log
date +%Y-%m-%d-%H-%M >>time.log
if [ -n "${HOOK_POST_ANDROID_BUILD}" ]; then
./android-build-configs/hooks/${HOOK_POST_ANDROID_BUILD}
fi
}
function print_usage(){
echo "$(basename $0) [-si|--skip_init] [-c|--config <config file name>] [-m|--mirror mirror_url] [-pm|--pinned-manifest]"
echo "$(basename $0) [-si|--skip_init] [-tp|--target-product target-product-name] [-tv|--target-variant target-build-variant] [-m|--mirror mirror_url] [-pm|--pinned-manifest]"
echo -e "\t -ss|--skip-sync: skip to run repo sync and apply patchsets, for cases like only build"
echo -e "\t -si|--skip-init: skip to run repo init, for cases like run on hackbox"
echo -e "\t -c|--config branch: build config file name under:"
echo -e "\t\t\thttps://android-git.linaro.org/android-build-configs.git/tree"
echo -e "\t -cu|--config-url branch: url for the build config file name under, must be absolute path when use local files"
echo -e "\t -m|--mirror mirror_url: specify the url where you want to sync from"
echo -e "\t -g|--groups groups: repo groups used when run repo init"
echo -e "\t -pm|--pinned-manifest file_path: specify the path where you put the pinned manifest file"
echo -e "\t -nb|--no-build: only repo sync all the projects and apply patches, but do not do any build operations"
echo -e "\t -ip|--install-packages: install host packages required for android building"
echo -e "\t -tp|--target-product: specify the TARGET_PRODUCT to be built"
echo -e "\t -tv|--target-variant: specify the TARGET_BUILD_VARIANT to be built"
echo "$(basename $0) [-h|--help]"
echo -e "\t -h|--help: print this usage"
}
function parseArgs(){
while [ -n "$1" ]; do
case "X$1" in
X-ss|X--skip-sync)
skip_sync=true
shift
;;
X-si|X--skip-init)
skip_init=true
shift
;;
X-c|X--config)
if [ -z "$2" ]; then
echo "Please specify the build config file name for the -c|--config option"
exit 1
fi
build_config="$2"
shift 2
;;
X-cu|X--config-url)
if [ -z "$2" ]; then
echo "Please specify the url of the build config file name for the -cu|--config-url option"
exit 1
fi
build_config_url="$2"
shift 2
;;
X-m|X--mirror)
if [ -z "$2" ]; then
echo "Please specify the repo sync mirror url with the -c|--config option"
exit 1
fi
MIRROR="$2"
shift 2
;;
X-b|X--branch)
if [ -z "$2" ]; then
echo "Please specify the manifest branch for the -b|--branch option"
exit 1
fi
MANIFEST_BRANCH="$2"
shift 2
;;
X-ru|X--repo-url)
if [ -z "$2" ]; then
echo "Please specify the manifest branch for the -ru|--repo-url option"
exit 1
fi
REPO_URL="$2"
shift 2
;;
X-g|X--groups)
if [ -z "$2" ]; then
echo "Please specify the repo groups for the -g|--groups option"
exit 1
fi
opt_repo_groups="$2"
shift 2
;;
X-pm|X--pinned-manifest)
if [ -z "$2" ]; then
echo "Please specify the path for the pinned manifest file with the -pm|--pinned-manifest option"
exit 1
fi
PINNED_MANIFEST="$2"
shift 2
;;
X-tp|X--target-product)
if [ -z "$2" ]; then
echo "Please specify the product name for the -tp|--target-product option"
exit 1
fi
OPT_TARGET_PRODUCT="$2"
shift 2
;;
X-tv|X--target-variant)
if [ -z "$2" ]; then
echo "Please specify the build variant value for the -tv|--target-variant option"
exit 1
fi
OPT_TARGET_BUILD_VARIANT="$2"
shift 2
;;
X-nb|X--no-build)
NO_BUILD=true
shift 1
;;
X-ip|X--install-package)
INSTALL_PACKAGE=true
shift 1
;;
X-h|X--help)
print_usage
exit 1
;;
X-*)
echo "Unknown option: $1"
print_usage
exit 1
;;
X*)
echo "Unknown option: $1"
print_usage
exit 1
;;
esac
done
if [ -z "${OPT_TARGET_PRODUCT}" ] && [ -z "${build_config}" ]; then
echo "Please specify the value for either -tp|--target-product option or -c|--config option"
print_usage
exit 1
fi
}
function install_packages(){
# Some of the packges might be not necessary anymore for
# android build, but not going to figure them out here.
sudo apt-get update
packages="acpica-tools bc bison build-essential ccache curl flex genisoimage"
packages="${packages} git git-core g++-multilib gnupg gperf lib32ncurses5-dev lib32z-dev"
packages="${packages} libc6-dev-i386 libdrm-intel1 libgl1-mesa-dev liblz4-tool libssl-dev"
packages="${packages} libx11-dev libxml2-utils linaro-image-tools lzop mtools openjdk-8-jdk"
packages="${packages} patch python-crypto python-mako python-parted python-pip python-requests"
packages="${packages} python-wand python-yaml rsync time u-boot-tools unzip uuid-dev"
packages="${packages} vim-common wget x11proto-core-dev xsltproc zip zlib1g-dev"
## packages needed by OP-TEE
packages="${packages} python-pyelftools"
sudo apt-get install -y ${packages}
}
function main(){
parseArgs "$@"
if ! ${skip_sync}; then
repo_sync_patch
elif [ ! -f android-build-configs/${build_config} ] && [ -z "${OPT_TARGET_PRODUCT}" ]; then
if [ -z "${build_config_url}" ]; then
build_config_remote_url="${default_build_config_url_prefix}/${build_config}"
else
build_config_remote_url=${build_config_url}
fi
if echo "${build_config_remote_url}"|grep -q '^/'; then
cp -vf "${build_config_remote_url}" android-build-configs/${build_config}
else
wget ${build_config_remote_url} -O android-build-configs/${build_config}
fi
export_config android-build-configs/${build_config}
fi
if ${INSTALL_PACKAGE}; then
install_packages
fi
if ! ${NO_BUILD}; then
build_with_config
fi
}
main "$@"