ci: Rework SDK build steps
Significantly rework how we're doing the SDK step for our CI scripts:
* Reduce the number of packages to speed up SDK build step. The only
reusable piece of an SDK is the toolchain and it's own dependent
pieces (i.e., sysroot dir), so don't waste time by building packages
that will be rebuilt when the SDK is used.
* Instead of always building the SDK based on witherspoon_defconfig,
take into account the platform for which the SDK is being built for,
but try to canonize it and consider it's primary characteristics to
make it unique, such as buildroot version, architecture, OS, Kernel
Headers and GCC version used.
Without this, at the time of this commit, the complete zz_defconfig
build is using GCC 7.4.0, the sdk build is using GCC 6.5.0 from
witherspoon_defconfig - an inconsistency in the result from a
complete versus an sdk-based build.
Signed-off-by: Klaus Heinrich Kiwi <klaus@linux.vnet.ibm.com>
diff --git a/ci/build-all-defconfigs.sh b/ci/build-all-defconfigs.sh
index 0ad613e..30703f2 100755
--- a/ci/build-all-defconfigs.sh
+++ b/ci/build-all-defconfigs.sh
@@ -4,14 +4,14 @@
set -eo pipefail
BUILD_INFO=0
+SDK_ONLY=0
CONFIGTAG="_defconfig"
-
DEFCONFIGS=();
-
+CCACHE_DIR=""
SDK_DIR=""
-opt=$(getopt -o 'o:s:p:r' -- "$@")
-if [ $? != 0 ] ; then
+opt=$(getopt -o 'o:Ss:p:r' -- "$@")
+if [ $? -ne 0 ] ; then
echo "Invalid arguments"
exit 1
fi
@@ -26,10 +26,14 @@
echo "Output directory: $1"
OUTDIR="$1"
;;
+ '-S')
+ echo "Build SDK Only"
+ SDK_ONLY=1
+ ;;
'-s')
shift
- echo "SDK is in: $1"
- SDK_DIR=$1
+ echo "SDK cache dir is in: $1"
+ SDK_CACHE=$1
;;
'-p')
shift
@@ -52,12 +56,142 @@
shift
done
-function get_kernel_release
+function get_major_minor_release
{
IFS=. read major minor macro <<<"$1"
echo -n "${major}_${minor}"
}
+function get_major_release
+{
+ IFS=. read major minor macro <<<"$1"
+ echo -n "${major}"
+}
+
+function build_sdk
+{
+# $1 is the defconfig
+# $2 is the SDK output directory
+# writes the output SDK pathname in global $SDK_DIR
+# also considers global var $CCACHE_DIR
+ SDK_BUILD_DIR=`mktemp -d`
+ op-build O=$SDK_BUILD_DIR $1
+
+ # Accumulate the SDK properties we want to hash to make it unique, but
+ # just so. Start with the buildroot version and machine/OS
+ HASH_PROPERTIES="$(git submodule) $(uname -mo)"
+
+ # Even if they should be interchangeable, we want to force the sdk
+ # build on every supported OS variations
+ HASH_PROPERTIES="$(HASH PROPERTIES) $(lsb_release -as | tr -d '/n[:space:]')"
+
+ # Disable things not necessary for the sdk
+ # (Buildroot manual section 6.1.3 plus a few more things)
+ buildroot/utils/config --file $SDK_BUILD_DIR/.config --disable INIT_BUSYBOX \
+ --enable INIT_NONE \
+ --disable SYSTEM_BIN_SH_BUSYBOX \
+ --disable TARGET_ROOTFS_TAR \
+ --disable SYSTEM_BIN_SH_DASH \
+ --enable SYSTEM_BIN_SH_NONE
+
+ # We don't need the Linux Kernel or eudev (they'll be rebuilt anyway), but we need
+ # to preserve the custom kernel version (if defined) for headers consistency, and
+ # since we're at it, enabling CPP won't hurt and will make the SDK more general
+ buildroot/utils/config --file $SDK_BUILD_DIR/.config --disable LINUX_KERNEL \
+ --disable ROOTFS_DEVICE_CREATION_DYNAMIC_EUDEV \
+ --enable INSTALL_LIBSTDCPP
+
+ # As we are disabling BR2_LINUX_KERNEL, capture Kernel version if any
+ # to prevent it from defaulting to the last on olddefconfig
+ KERNEL_VER=$(buildroot/utils/config --file $SDK_BUILD_DIR/.config --state LINUX_KERNEL_CUSTOM_VERSION_VALUE)
+ if [ "$KERNEL_VER" != "undef" ]; then
+ KERNEL="KERNEL_HEADERS_$(get_major_minor_release $KERNEL_VER)"
+ buildroot/utils/config --file $SDK_BUILD_DIR/.config --enable "$KERNEL"
+ fi
+
+ # Disable packages we won't pull into the SDK to speed it's build
+ buildroot/utils/config --file $SDK_BUILD_DIR/.config --package \
+ --disable BUSYBOX \
+ --disable KEXEC_LITE \
+ --disable LINUX_FIRMWARE \
+ --disable CRYPTSETUP \
+ --disable IPMITOOL \
+ --disable LVM2 \
+ --disable MDADM \
+ --disable NVME \
+ --disable PCIUTILS \
+ --disable ZLIB \
+ --disable LIBZLIB \
+ --disable DTC \
+ --disable LIBAIO \
+ --disable JSON_C \
+ --disable ELFUTILS \
+ --disable NCURSES \
+ --disable POPT \
+ --disable DROPBEAR --disable DROPBEAR_CLIENT \
+ --disable ETHTOOL \
+ --disable IFUPDOWN_SCRIPTS \
+ --disable LRZSZ \
+ --disable NETCAT \
+ --disable RSYNC \
+ --disable SUDO \
+ --disable KMOD \
+ --disable POWERPC_UTILS \
+ --disable UTIL_LINUX \
+ --disable IPRUTILS
+
+ # Additionally, disable ROOTFS stuff that we won't need
+ # Including the OpenPower Packages
+ buildroot/utils/config --file $SDK_BUILD_DIR/.config --undefine ROOTFS_USERS_TABLES \
+ --undefine ROOTFS_OVERLAY \
+ --undefine ROOTFS_POST_BUILD_SCRIPT \
+ --undefine ROOTFS_POST_FAKEROOT_SCRIPT \
+ --undefine ROOTFS_POST_IMAGE_SCRIPT \
+ --undefine ROOTFS_POST_SCRIPT_ARGS \
+ --undefine OPENPOWER_PLATFORM \
+ --undefine BR2_OPENPOWER_POWER8 \
+ --undefine BR2_OPENPOWER_POWER9
+
+ # Enable CCACHE
+ buildroot/utils/config --file $SDK_BUILD_DIR/.config --enable CCACHE \
+ --set-str CCACHE_DIR $CCACHE_DIR
+
+ op-build O=$SDK_BUILD_DIR olddefconfig
+
+ # Ideally this woulnd't matter, but to be safe, include Kernel
+ # Headers and GCC version as part of the SDK Hash, so that we
+ # don't have Full builds and SDK builds potentially diverging
+ # on the headers/compiler versions each uses
+ KERNEL_VER=$(buildroot/utils/config --file $SDK_BUILD_DIR/.config --state DEFAULT_KERNEL_HEADERS)
+ HASH_PROPERTIES="$HASH_PROPERTIES $KERNEL_VER"
+ echo "SDK KERNEL Version: $KERNEL_VER"
+ GCC_VER=$(buildroot/utils/config --file $SDK_BUILD_DIR/.config --state GCC_VERSION)
+ echo "SDK GCC Version: $GCC_VER"
+ HASH_PROPERTIES="$HASH_PROPERTIES $GCC_VER"
+
+ # sha1sum our properties and check if a matching sdk exists
+ # A potential caveat he is if op-build is patching any of the
+ # HASH_PROPERTIES content at build time
+ HASH_VAL=$(echo -n "$HASH_PROPERTIES" | sha1sum | sed -e 's/ .*//')
+
+ SDK_DIR="$2/toolchain-${HASH_VAL}"
+
+ if [ -e "$SDK_DIR" ]; then
+ echo "Acceptable SDK for $i exists in $SDK_DIR - skipping build"
+ else
+ op-build O=$SDK_BUILD_DIR sdk
+ if [ $? -ne 0 ]; then
+ rm -rf $SDK_DIR
+ return 1
+ fi
+
+ # Move sdk to resting location and adjust paths
+ mv $SDK_BUILD_DIR $SDK_DIR
+ $SDK_DIR/host/relocate-sdk.sh
+ fi
+ export SDK_DIR
+}
+
if [ -z "${PLATFORM_LIST}" ]; then
echo "Using all the defconfigs for all the platforms"
DEFCONFIGS=`(cd openpower/configs; ls -1 *_defconfig)`
@@ -90,26 +224,50 @@
for i in ${DEFCONFIGS[@]}; do
export O=${OUTDIR}/$i
rm -rf $O
- op-build O=$O $i
- ./buildroot/utils/config --file $O/.config --enable CCACHE \
- --set-str CCACHE_DIR $CCACHE_DIR
- if [ -d "$SDK_DIR" ]; then
- ./buildroot/utils/config --file $O/.config --enable TOOLCHAIN_EXTERNAL \
- --set-str TOOLCHAIN_EXTERNAL_PATH $SDK_DIR \
- --enable TOOLCHAIN_EXTERNAL_CUSTOM_GLIBC \
- --enable TOOLCHAIN_EXTERNAL_CXX
- # FIXME: How do we work this out programatically?
- ./buildroot/utils/config --file $O/.config --enable BR2_TOOLCHAIN_EXTERNAL_GCC_6
- KERNEL_VER=$(./buildroot/utils/config --file $O/.config --state BR2_LINUX_KERNEL_CUSTOM_VERSION_VALUE)
- echo "KERNEL_VER " $KERNEL_VER
- HEADERS=BR2_TOOLCHAIN_EXTERNAL_HEADERS_$(get_kernel_release $KERNEL_VER)
- ./buildroot/utils/config --file $O/.config --set-val $HEADERS y
+ SDK_DIR=""
+ build_sdk $i $SDK_CACHE
+ if [ $? -ne 0 ]; then
+ echo "Error building SDK"
+ exit 1
fi
+
+ if [ $SDK_ONLY -ne 0 ]; then
+ continue
+ fi
+
+ op-build O=$O $i
+ buildroot/utils/config --file $O/.config --enable CCACHE \
+ --set-str CCACHE_DIR $CCACHE_DIR
+ buildroot/utils/config --file $O/.config --enable TOOLCHAIN_EXTERNAL \
+ --set-str TOOLCHAIN_EXTERNAL_PATH $SDK_DIR/host \
+ --enable TOOLCHAIN_EXTERNAL_CUSTOM_GLIBC
+
+ # Our SDK will always have CPP enabled, but avoid potentially
+ # diverging with the Full build by only enabling it
+ # conditionally
+ CPP_REQUIRED=$(buildroot/utils/config --file $O/.config --state INSTALL_LIBSTDCPP)
+ if [ "$CPP_REQUIRED" = "y" ]; then
+ buildroot/utils/config --file $O/.config --enable TOOLCHAIN_EXTERNAL_CXX
+ fi
+
+ # The Kernel Headers requested MUST be the same as the one
+ # provided by the SDK (i.e., it's part of the hash)
+ HEADERS_VER=$(buildroot/utils/config --file $O/.config --state TOOLCHAIN_HEADERS_AT_LEAST)
+ echo "Toolchain Headers Version Requested: $HEADERS_VER"
+ HEADERS="TOOLCHAIN_EXTERNAL_HEADERS_$(get_major_minor_release $HEADERS_VER)"
+ buildroot/utils/config --file $O/.config --enable "$HEADERS"
+
+ # Same for the GCC version
+ EXTERNAL_GCC_VER=$(buildroot/utils/config --file $O/.config --state GCC_VERSION)
+ echo "GCC Version Requested: $EXTERNAL_GCC_VER"
+ EXTERNAL_GCC="TOOLCHAIN_EXTERNAL_GCC_$(get_major_release $EXTERNAL_GCC_VER)"
+ buildroot/utils/config --file $O/.config --enable "$EXTERNAL_GCC"
+
op-build O=$O olddefconfig
op-build O=$O
r=$?
- if [ ${BUILD_INFO} = 1 ] && [ $r = 0 ]; then
+ if [ ${BUILD_INFO} -eq 1 ] && [ $r -eq 0 ]; then
op-build O=$O legal-info
op-build O=$O graph-build
op-build O=$O graph-size
diff --git a/ci/build-sdk.sh b/ci/build-sdk.sh
deleted file mode 100755
index f2a312a..0000000
--- a/ci/build-sdk.sh
+++ /dev/null
@@ -1,58 +0,0 @@
-#!/bin/bash
-
-set -ex
-set -eo pipefail
-
-if [ -z "$1" ]; then
- echo "No build distro specified"
- exit 1;
-fi
-
-if [ -z "$2" ]; then
- echo "No defconfig to build SDK from specified"
- exit 1;
-fi
-
-if [ -z "$CCACHE_DIR" ]; then
- CCACHE_DIR=`pwd`/.op-build_ccache
-fi
-
-shopt -s expand_aliases
-source op-build-env
-
-if [ -n "$DL_DIR" ]; then
- unset BR2_DL_DIR
- export BR2_DL_DIR=${DL_DIR}
-fi
-
-export O=`pwd`/output-$1-$2/
-op-build O=$O $2
-./buildroot/utils/config --file $O/.config --enable CCACHE
-./buildroot/utils/config --file $O/.config --set-str CCACHE_DIR $CCACHE_DIR
-
-# Disable things not necessary for the sdk
-# (Buildroot manual section 6.1.3)
-./buildroot/utils/config --file $O/.config --disable INIT_BUSYBOX \
- --enable INIT_NONE \
- --disable SYSTEM_BIN_SH_BUSYBOX \
- --disable TARGET_ROOTFS_TAR
-
-# Additionally, disable OpenPower packages and
-# ROOTFS stuff that we won't need
-./buildroot/utils/config --file $O/.config --disable OPENPOWER_PLATFORM \
- --undefine ROOTFS_USERS_TABLES \
- --undefine ROOTFS_OVERLAY \
- --undefine ROOTFS_POST_BUILD_SCRIPT \
- --undefine ROOTFS_POST_FAKEROOT_SCRIPT \
- --undefine ROOTFS_POST_IMAGE_SCRIPT \
- --undefine ROOTFS_POST_SCRIPT_ARGS
-
-op-build O=$O olddefconfig
-
-if [ -f "$(ldconfig -p | grep libeatmydata.so | tr ' ' '\n' | grep /|head -n1)" ]; then
- export LD_PRELOAD=${LD_PRELOAD:+"$LD_PRELOAD "}libeatmydata.so
-elif [ -f "/usr/lib64/nosync/nosync.so" ]; then
- export LD_PRELOAD=${LD_PRELOAD:+"$LD_PRELOAD "}/usr/lib64/nosync/nosync.so
-fi
-
-op-build O=$O sdk
diff --git a/ci/build.sh b/ci/build.sh
index a0430df..e0acc1a 100755
--- a/ci/build.sh
+++ b/ci/build.sh
@@ -7,7 +7,7 @@
SDK_ONLY=0
opt=$(getopt -o 's:Sab:p:c:hr' -- "$@")
-if [ $? != 0 ] ; then
+if [ $? -ne 0 ] ; then
echo "Invalid arguments"
exit 1
fi
@@ -96,10 +96,6 @@
-t $1 $2
}
-function toolchain_hash
-{
- echo -n 'toolchain-'$((git submodule ; cd openpower/configs/; cat `ls -1 |grep '_defconfig$'|sort`)|sha1sum |sed -e 's/ .*//')
-}
env
@@ -144,15 +140,6 @@
EOF
)
$DOCKER_PREFIX docker build --network=host -t openpower/op-build-$distro - <<< "${Dockerfile}"
- SDK_DIR=$SDK_CACHE/$(toolchain_hash)-$distro
- if [ ! -d "$SDK_DIR" ]; then
- chmod +x ci/build-sdk.sh
- run_docker openpower/op-build-$distro "./ci/build-sdk.sh $distro witherspoon_defconfig"
- mv output-$distro-witherspoon_defconfig $SDK_DIR
- $SDK_DIR/host/relocate-sdk.sh
- fi
-
- sdk_args="-s $SDK_DIR/host"
if [ -n "$PLATFORMS" ]; then
platform_args="-p $PLATFORMS"
@@ -160,11 +147,15 @@
platform_args=""
fi
- if [ $SDK_ONLY == 0 ]; then
- run_docker openpower/op-build-$distro "./ci/build-all-defconfigs.sh -o `pwd`/output-$distro ${platform_args} ${release_args} ${sdk_args}"
+ if [ $SDK_ONLY -ne 0 ]; then
+ sdk_args="-S"
+ else
+ sdk_args=""
fi
- if [ $? != 0 ]; then
+ run_docker openpower/op-build-$distro "./ci/build-all-defconfigs.sh -o `pwd`/output-$distro ${platform_args} ${release_args} ${sdk_args} -s $SDK_CACHE"
+
+ if [ $? -ne 0 ]; then
exit $?;
fi
done;