| #!/bin/bash |
| |
| # |
| # edk2-build.sh: evolution of uefi-build.sh for edk2-platforms |
| # |
| |
| unset MAKEFLAGS # BaseTools not safe to build parallel, prevent env overrides |
| |
| TOOLS_DIR="`dirname $0`" |
| TOOLS_DIR="`readlink -f \"$TOOLS_DIR\"`" |
| export TOOLS_DIR |
| . "$TOOLS_DIR"/common-functions |
| PLATFORM_CONFIG="-c $TOOLS_DIR/edk2-platforms.config" |
| ARCH= |
| VERBOSE=0 # Override with -v |
| ATF_DIR= |
| TOS_DIR= |
| TOOLCHAIN="gcc" # Override with -T |
| WORKSPACE= |
| EDK2_DIR= |
| PLATFORMS_DIR= |
| NON_OSI_DIR= |
| IMPORT_OPENSSL=TRUE |
| OPENSSL_CONFIGURED=FALSE |
| |
| # Number of threads to use for build |
| export NUM_THREADS=$((`getconf _NPROCESSORS_ONLN` + `getconf _NPROCESSORS_ONLN`)) |
| |
| function do_build |
| { |
| PLATFORM_ARCH=`echo $board | cut -s -d: -f2` |
| if [ -n "$PLATFORM_ARCH" ]; then |
| board=`echo $board | cut -d: -f1` |
| else |
| PLATFORM_ARCH="`$TOOLS_DIR/parse-platforms.py $PLATFORM_CONFIG -p $board get -o arch`" |
| fi |
| PLATFORM_NAME="`$TOOLS_DIR/parse-platforms.py $PLATFORM_CONFIG -p $board get -o longname` ($PLATFORM_ARCH)" |
| if [ -z "$PLATFORM_ARCH" ]; then |
| echo "Unknown target architecture - aborting!" >&2 |
| return 1 |
| fi |
| PLATFORM_PREBUILD_CMDS="`$TOOLS_DIR/parse-platforms.py $PLATFORM_CONFIG -p $board get -o prebuild_cmds`" |
| PLATFORM_BUILDFLAGS="`$TOOLS_DIR/parse-platforms.py $PLATFORM_CONFIG -p $board get -o buildflags`" |
| PLATFORM_BUILDFLAGS="$PLATFORM_BUILDFLAGS ${EXTRA_OPTIONS[@]}" |
| PLATFORM_BUILDCMD="`$TOOLS_DIR/parse-platforms.py $PLATFORM_CONFIG -p $board get -o buildcmd`" |
| PLATFORM_DSC="`$TOOLS_DIR/parse-platforms.py $PLATFORM_CONFIG -p $board get -o dsc`" |
| PLATFORM_PACKAGES_PATH="" |
| COMPONENT_INF="`$TOOLS_DIR/parse-platforms.py $PLATFORM_CONFIG -p $board get -o inf`" |
| |
| TEMP_PACKAGES_PATH="$GLOBAL_PACKAGES_PATH:`$TOOLS_DIR/parse-platforms.py $PLATFORM_CONFIG -p $board get -o packages_path`" |
| IFS=: |
| for path in "$TEMP_PACKAGES_PATH"; do |
| case "$path" in |
| /*) |
| PLATFORM_PACKAGES_PATH="$PLATFORM_PACKAGES_PATH:$path" |
| ;; |
| *) |
| PLATFORM_PACKAGES_PATH="$PLATFORM_PACKAGES_PATH:$PWD/$path" |
| ;; |
| esac |
| done |
| unset IFS |
| |
| if [ $VERBOSE -eq 1 ]; then |
| echo "Setting build parallellism to $NUM_THREADS processes" |
| echo "PLATFORM_NAME=$PLATFORM_NAME" |
| echo "PLATFORM_PREBUILD_CMDS=$PLATFORM_PREBUILD_CMDS" |
| echo "PLATFORM_BUILDFLAGS=$PLATFORM_BUILDFLAGS" |
| echo "PLATFORM_BUILDCMD=$PLATFORM_BUILDCMD" |
| echo "PLATFORM_DSC=$PLATFORM_DSC" |
| echo "PLATFORM_ARCH=$PLATFORM_ARCH" |
| echo "PLATFORM_PACKAGES_PATH=$PLATFORM_PACKAGES_PATH" |
| fi |
| |
| set_cross_compile |
| CROSS_COMPILE="$TEMP_CROSS_COMPILE" |
| |
| echo "Building $PLATFORM_NAME - $PLATFORM_ARCH" |
| echo "CROSS_COMPILE=\"$TEMP_CROSS_COMPILE\"" |
| echo "$board"_BUILDFLAGS="'$PLATFORM_BUILDFLAGS'" |
| |
| if [ "$TARGETS" == "" ]; then |
| TARGETS=( RELEASE ) |
| fi |
| |
| case $TOOLCHAIN in |
| "gcc") |
| PLATFORM_TOOLCHAIN=`get_gcc_version "$CROSS_COMPILE"gcc` |
| ;; |
| "clang") |
| PLATFORM_TOOLCHAIN=`get_clang_version clang` |
| ;; |
| *) |
| # Use command-line specified profile directly |
| PLATFORM_TOOLCHAIN=$TOOLCHAIN |
| ;; |
| esac |
| echo "PLATFORM_TOOLCHAIN is ${PLATFORM_TOOLCHAIN}" |
| |
| export ${PLATFORM_TOOLCHAIN}_${PLATFORM_ARCH}_PREFIX=$CROSS_COMPILE |
| echo "Toolchain prefix: ${PLATFORM_TOOLCHAIN}_${PLATFORM_ARCH}_PREFIX=$CROSS_COMPILE" |
| |
| export PACKAGES_PATH="$PLATFORM_PACKAGES_PATH" |
| for target in "${TARGETS[@]}" ; do |
| if [ X"$PLATFORM_PREBUILD_CMDS" != X"" ]; then |
| echo "Run pre-build commands:" |
| if [ $VERBOSE -eq 1 ]; then |
| echo " ${PLATFORM_PREBUILD_CMDS}" |
| fi |
| eval ${PLATFORM_PREBUILD_CMDS} |
| fi |
| |
| if [ -n "$COMPONENT_INF" ]; then |
| # Build a standalone component |
| if [ $VERBOSE -eq 1 ]; then |
| echo "build -n $NUM_THREADS -a \"$PLATFORM_ARCH\" -t ${PLATFORM_TOOLCHAIN} -p \"$PLATFORM_DSC\"" \ |
| "-m \"$COMPONENT_INF\" -b "$target" ${PLATFORM_BUILDFLAGS}" |
| fi |
| build -n $NUM_THREADS -a "$PLATFORM_ARCH" -t ${PLATFORM_TOOLCHAIN} -p "$PLATFORM_DSC" \ |
| -m "$COMPONENT_INF" -b "$target" ${PLATFORM_BUILDFLAGS} |
| else |
| # Build a platform |
| if [ $VERBOSE -eq 1 ]; then |
| echo "build -n $NUM_THREADS -a \"$PLATFORM_ARCH\" -t ${PLATFORM_TOOLCHAIN} -p \"$PLATFORM_DSC\"" \ |
| "-b "$target" ${PLATFORM_BUILDFLAGS}" |
| fi |
| build -n $NUM_THREADS -a "$PLATFORM_ARCH" -t ${PLATFORM_TOOLCHAIN} -p "$PLATFORM_DSC" \ |
| -b "$target" ${PLATFORM_BUILDFLAGS} |
| fi |
| |
| RESULT=$? |
| if [ $RESULT -eq 0 ]; then |
| if [ X"$TOS_DIR" != X"" ]; then |
| pushd $TOS_DIR >/dev/null |
| if [ $VERBOSE -eq 1 ]; then |
| echo "$TOOLS_DIR/tos-build.sh -e "$EDK2_DIR" -t "$target"_${PLATFORM_TOOLCHAIN} $board" |
| fi |
| $TOOLS_DIR/tos-build.sh -e "$EDK2_DIR" -t "$target"_${PLATFORM_TOOLCHAIN} $board |
| RESULT=$? |
| popd >/dev/null |
| fi |
| fi |
| if [ $RESULT -eq 0 ]; then |
| if [ X"$ATF_DIR" != X"" ]; then |
| pushd $ATF_DIR >/dev/null |
| if [ $VERBOSE -eq 1 ]; then |
| echo "$TOOLS_DIR/atf-build.sh -e "$EDK2_DIR" -t "$target"_${PLATFORM_TOOLCHAIN} $board" |
| fi |
| $TOOLS_DIR/atf-build.sh -e "$EDK2_DIR" -t "$target"_${PLATFORM_TOOLCHAIN} $board |
| RESULT=$? |
| popd >/dev/null |
| fi |
| fi |
| result_log $RESULT "$PLATFORM_NAME $target" |
| done |
| unset PACKAGES_PATH |
| } |
| |
| |
| function configure_paths |
| { |
| WORKSPACE="$PWD" |
| |
| # Check to see if we are in a UEFI repository |
| # refuse to continue if we aren't |
| if [ ! -d "$EDK2_DIR"/BaseTools ] |
| then |
| if [ -d "$PWD"/edk2/BaseTools ]; then |
| EDK2_DIR="$PWD"/edk2 |
| else |
| echo "ERROR: can't locate the edk2 directory" >&2 |
| echo " please specify -e/--edk2-dir" >&2 |
| exit 1 |
| fi |
| fi |
| |
| GLOBAL_PACKAGES_PATH="$EDK2_DIR" |
| |
| # locate edk2-platforms |
| if [ -z "$PLATFORMS_DIR" -a -d "$PWD"/edk2-platforms ]; then |
| PLATFORMS_DIR="$PWD"/edk2-platforms |
| fi |
| if [ -n "$PLATFORMS_DIR" ]; then |
| GLOBAL_PACKAGES_PATH="$GLOBAL_PACKAGES_PATH:$PLATFORMS_DIR" |
| fi |
| |
| # locate edk2-non-osi |
| if [ -z "$NON_OSI_DIR" -a -d "$PWD"/edk2-non-osi ]; then |
| NON_OSI_DIR="$PWD"/edk2-non-osi |
| fi |
| if [ -n "$NON_OSI_DIR" ]; then |
| GLOBAL_PACKAGES_PATH="$GLOBAL_PACKAGES_PATH:$NON_OSI_DIR" |
| fi |
| |
| # locate arm-trusted-firmware |
| if [ -z "$ATF_DIR" -a -d "$PWD"/arm-trusted-firmware ]; then |
| ATF_DIR="$PWD"/arm-trusted-firmware |
| fi |
| |
| export WORKSPACE |
| } |
| |
| |
| function prepare_build |
| { |
| get_build_arch |
| export ARCH=$BUILD_ARCH |
| |
| export ARCH |
| cd $EDK2_DIR |
| PACKAGES_PATH=$GLOBAL_PACKAGES_PATH . edksetup.sh --reconfig |
| if [ $? -ne 0 ]; then |
| echo "Sourcing edksetup.sh failed!" >&2 |
| exit 1 |
| fi |
| if [ $VERBOSE -eq 1 ]; then |
| echo "Building BaseTools" |
| fi |
| make -C BaseTools |
| RET=$? |
| cd - |
| if [ $RET -ne 0 ]; then |
| echo " !!! BaseTools failed to build !!! " >&2 |
| exit 1 |
| fi |
| |
| if [ "$IMPORT_OPENSSL" = "TRUE" ]; then |
| cd $EDK2_DIR |
| import_openssl |
| if [ $? -ne 0 ]; then |
| echo "Importing OpenSSL failed - aborting!" >&2 |
| echo " specify --no-openssl to attempt build anyway." >&2 |
| exit 1 |
| fi |
| cd $WORKSPACE |
| fi |
| } |
| |
| |
| function usage |
| { |
| echo "usage:" |
| echo -n "uefi-build.sh [-b DEBUG | RELEASE] [ all " |
| for board in "${boards[@]}" ; do |
| echo -n "| $board " |
| done |
| echo "]" |
| printf "%8s\tbuild %s\n" "all" "all supported platforms" |
| for board in "${boards[@]}" ; do |
| PLATFORM_NAME="`$TOOLS_DIR/parse-platforms.py $PLATFORM_CONFIG -p $board get -o longname`" |
| printf "%8s\tbuild %s\n" "$board" "${PLATFORM_NAME}" |
| done |
| } |
| |
| # |
| # Since we do a command line validation on whether specified platforms exist or |
| # not, do a first pass of command line to see if there is an explicit config |
| # file there to read valid platforms from. |
| # |
| commandline=( "$@" ) |
| i=0 |
| for arg; |
| do |
| if [ $arg == "-c" ]; then |
| FILE_ARG=${commandline[i + 1]} |
| if [ ! -f "$FILE_ARG" ]; then |
| echo "ERROR: configuration file '$FILE_ARG' not found" >&2 |
| exit 1 |
| fi |
| case "$FILE_ARG" in |
| /*) |
| PLATFORM_CONFIG="-c $FILE_ARG" |
| ;; |
| *) |
| PLATFORM_CONFIG="-c `readlink -f \"$FILE_ARG\"`" |
| ;; |
| esac |
| echo "Platform config file: '$FILE_ARG'" |
| fi |
| i=$(($i + 1)) |
| done |
| |
| export PLATFORM_CONFIG |
| |
| builds=() |
| boards=() |
| boardlist="`$TOOLS_DIR/parse-platforms.py $PLATFORM_CONFIG shortlist`" |
| for board in $boardlist; do |
| boards=(${boards[@]} $board) |
| done |
| |
| NUM_TARGETS=0 |
| |
| while [ "$1" != "" ]; do |
| case $1 in |
| -1) # Disable build parallellism |
| NUM_THREADS=1 |
| ;; |
| -a | --arm-tf-dir) |
| shift |
| ATF_DIR="`readlink -f $1`" |
| ;; |
| -c) # Already parsed above - skip this + option |
| shift |
| ;; |
| -b | --build-target) |
| shift |
| echo "Adding Build target: $1" |
| TARGETS=(${TARGETS[@]} $1) |
| ;; |
| -D) # Pass through as -D option to 'build' |
| shift |
| echo "Adding Macro: -D $1" |
| EXTRA_OPTIONS=(${EXTRA_OPTIONS[@]} "-D" $1) |
| ;; |
| -e | --edk2-dir) |
| shift |
| export EDK2_DIR="`readlink -f $1`" |
| ;; |
| -h | --help) |
| usage |
| exit |
| ;; |
| --no-openssl) |
| IMPORT_OPENSSL=FALSE |
| ;; |
| -n | --non-osi-dir) |
| shift |
| NON_OSI_DIR="`readlink -f $1`" |
| ;; |
| -p | --platforms-dir) |
| shift |
| PLATFORMS_DIR="`readlink -f $1`" |
| ;; |
| -s | --tos-dir) |
| shift |
| export TOS_DIR="`readlink -f $1`" |
| ;; |
| -T) # Set specific toolchain tag, or clang/gcc for autoselection |
| shift |
| echo "Setting toolchain tag to '$1'" |
| TOOLCHAIN="$1" |
| ;; |
| -v) |
| VERBOSE=1 |
| ;; |
| all) # Add all targets in configuration file to list |
| builds=(${boards[@]}) |
| NUM_TARGETS=$(($NUM_TARGETS + 1)) |
| ;; |
| *) # Try to match target in configuration file, add to list |
| MATCH=0 |
| for board in "${boards[@]}" ; do |
| if [ "`echo $1 | cut -d: -f1`" == $board ]; then |
| MATCH=1 |
| builds=(${builds[@]} "$1") |
| break |
| fi |
| done |
| |
| if [ $MATCH -eq 0 ]; then |
| echo "unknown arg $1" |
| usage |
| exit 1 |
| fi |
| NUM_TARGETS=$(($NUM_TARGETS + 1)) |
| ;; |
| esac |
| shift |
| done |
| |
| if [ $NUM_TARGETS -le 0 ]; then |
| echo "No targets specified - exiting!" >&2 |
| exit 0 |
| fi |
| |
| export VERBOSE |
| |
| configure_paths |
| |
| prepare_build |
| |
| if [[ "${EXTRA_OPTIONS[@]}" != *"FIRMWARE_VER"* ]]; then |
| if test -d .git && head=`git rev-parse --verify --short HEAD 2>/dev/null`; then |
| FIRMWARE_VER=`git rev-parse --short HEAD` |
| if ! git diff-index --quiet HEAD --; then |
| FIRMWARE_VER="${FIRMWARE_VER}-dirty" |
| fi |
| EXTRA_OPTIONS=( ${EXTRA_OPTIONS[@]} "-D" FIRMWARE_VER=$FIRMWARE_VER ) |
| if [ $VERBOSE -eq 1 ]; then |
| echo "FIRMWARE_VER=$FIRMWARE_VER" |
| echo "EXTRA_OPTIONS=$EXTRA_OPTIONS" |
| fi |
| fi |
| fi |
| |
| for board in "${builds[@]}" ; do |
| do_build |
| done |
| |
| result_print |