#!/bin/bash # SPDX-License-Identifier: GPL-2.0-only # Script to build all possible BSP branches in a git yocto kernel tree. # Copyright 2012 Wind River. Licensed under the GPLv2 included herein # by reference. # Requirements: # Toolchain for each arch. # $PATH which includes the above. # Proper CROSS_COMPILE (per arch) settings; see defaults below. # # Stick all your customizations, local $PATH additions in the below. # if [ -f $HOME/.buildallrc ]; then echo Sourcing custom settings in $HOME/.buildallrc source $HOME/.buildallrc fi if [ -z "$JOBS" ]; then JOBS=20 fi if [ -z "$NICE" ]; then NICE=15 fi # The (bare) git tree that you want build tested. # TREE=~/workdir/foo.git # or # TREE=git://some.site.com/linux.git # both absolute paths and git repos are valid inputs if [ -z "$TREE" ]; then TREE=git://git.yoctoproject.org/linux-yocto-3.17 fi # Name of dir created for containing checked out src to build from if [ -z "$LINUX_SRC" ]; then LINUX_SRC=linux fi # Name of dir created for bare clone used as base tree. if [ -z "$DEFKERN" ]; then DEFKERN=default_kernel fi # Where all the radioactive fallout is contained if [ -z "$BUILDALL" ]; then BUILDALL=kernel_builds fi # If non fatal warnings are issued by this script, they are here if [ -z "$WARN_LOG" ]; then WARN_LOG=warnings.txt fi # to save on clones, check std location. if [ -z "$REFERENCE" ]; then REFERENCE=~/git/linux fi # Sane defaults if [ -z "$PPC_CROSS_COMPILE" ]; then PPC_CROSS_COMPILE=powerpc-poky-linux- fi if [ -z "$MIPS_CROSS_COMPILE" ]; then MIPS_CROSS_COMPILE=mips-poky-linux- fi if [ -z "$ARM_CROSS_COMPILE" ]; then ARM_CROSS_COMPILE=arm-poky-linux-gnueabi- fi if [ -z "$X86_CROSS_COMPILE" ]; then X86_CROSS_COMPILE=i586-poky-linux- fi if [ -z "$X86_64_CROSS_COMPILE" ]; then X86_64_CROSS_COMPILE=x86_64-poky-linux- fi MYPATH=`dirname $0` MYPATH=`readlink -f $MYPATH` CONFIGME=`readlink -f $MYPATH/configme` UPDATEME=`readlink -f $MYPATH/updateme` PATH=$PATH:$MYPATH export PATH if [ -d $TREE ]; then TREE=`readlink -f $TREE` fi if [ ! -x $CONFIGME ];then echo Error: Cant locate configuration script \"configme\" echo Was looking for $CONFIGME exit 1 fi if [ ! -x $UPDATEME ];then echo Error: Cant locate meta series refresh script \"updateme\" echo Was looking for $UPDATEME exit 1 fi if [ -z "$META_DIR" ]; then META_DIR=.meta fi if [ -z "$META_BRANCH" ]; then META_BRANCH=meta fi ######## build one branch; assumes it is checked out and config'd ###### build_branch() { if [ -z "$ARCH" ]; then echo ARCH not set, cant build $BUILD_DIR return 1 fi if [ "$ARCH" == "powerpc" ];then CROSS_COMPILE=$PPC_CROSS_COMPILE elif [ "$ARCH" == "i386" ];then CROSS_COMPILE=$X86_CROSS_COMPILE elif [ "$ARCH" == "x86" ];then CROSS_COMPILE=$X86_CROSS_COMPILE elif [ "$ARCH" == "x86_64" ];then CROSS_COMPILE=$X86_64_CROSS_COMPILE elif [ "$ARCH" == "mips" ];then CROSS_COMPILE=$MIPS_CROSS_COMPILE elif [ "$ARCH" == "arm" ];then CROSS_COMPILE=$ARM_CROSS_COMPILE elif [ "$ARCH" == "arm64" ];then CROSS_COMPILE=$ARM_CROSS_COMPILE else echo Unknown architecture: $ARCH -- Giving up. return 1 fi # Find the arch specific gcc for the toolchain which $CROSS_COMPILE\gcc > /dev/null 2>&1 if [ $? != 0 ]; then echo Error: cant find a $CROSS_COMPILE\gcc in PATH echo PATH is: $PATH return 1 fi export ARCH export CROSS_COMPILE command time --quiet -f '%E' -o time.log nice -n $NICE \ make -j$JOBS O=$BUILD_DIR > $BUILD_DIR/build.log 2>&1 return $? } debare() { mkdir .git if [ $? != 0 ]; then echo debare: you already have a .git in $PWD echo fix your shit exit 1 fi mv * .git git config core.bare false } # We could omit this step, but it makes the remainder of things # indifferent to where things came from. clone_local() { git clone --bare --shared $TREE $DEFKERN > /dev/null 2>&1 if [ $? != 0 ]; then echo clone of $TREE failed echo I tried to run: \"git clone --bare --shared $TREE $DEFKERN\" exit 1 fi } clone_ref() { if [ -d $REFERENCE ]; then REF="--reference $REFERENCE" fi git clone --bare $REF $TREE $DEFKERN > /dev/null 2>&1 if [ $? != 0 ]; then echo clone of $TREE failed echo I tried to run: \"git clone --bare $REF $TREE $DEFKERN\" exit 1 fi } stage_src() { git clone --bare --shared --no-checkout $DEFKERN $LINUX_SRC>/dev/null 2>&1 if [ $? != 0 ]; then echo shared clone of default_kernel failed echo I tried to run: \"git clone --bare --shared --no-checkout $DEFKERN $LINUX_SRC\" exit 1 fi # De-bare the clone. There should be a command for this... cd $LINUX_SRC debare git checkout -f $META_BRANCH > /dev/null 2>&1 if [ $? != 0 ];then echo checkout of meta branch \"$META_BRANCH\" failed exit 1 fi } get_branch() { if [ ! -f "$1" ]; then echo get_branch: $1: file does not exist >&2 return fi for i in `cat $1 |grep _branch_begin| awk '{print $3}'` ; do echo -n $i/ done | sed 's,/$,,' } fail_mail() { local META=$1 local FAILLOG=$2 local DIR=`dirname $FAILLOG` local FAILMAIL=`mktemp -p /var/tmp` if [ $? != 0 ]; then FAILMAIL=`mktemp -p /tmp` fi echo From: $MAILTO > $FAILMAIL echo Date: `date '+%c %z'` >> $FAILMAIL echo Subject: Build of $META failed. >> $FAILMAIL echo >> $FAILMAIL echo The build of $META has failed. >> $FAILMAIL echo -------- error --------------- >> $FAILMAIL grep error: $FAILLOG >> $FAILMAIL echo -------- tail ---------------- >> $FAILMAIL tail -n 30 $FAILLOG >> $FAILMAIL echo ------------------------------ >> $FAILMAIL echo >> $FAILMAIL echo Sincerely, >> $FAILMAIL echo buildall @ `hostname` >> $FAILMAIL git send-email --from $MAILTO --quiet --confirm=never --to $MAILTO \ --smtp-server=$SMTPSERVER $FAILMAIL >> $DIR/mail.log 2>&1 if [ $? != 0 ]; then echo tried to notify $MAILTO about something, but failed. echo See $DIR/mail.log for details. fi cp $FAILMAIL $DIR rm -f $FAILMAIL } ######################### start ##################### PASS_CFG=0 FAIL_CFG=0 PASS_BUILD=0 FAIL_BUILD=0 which mkimage > /dev/null 2>&1 if [ $? != 0 ]; then echo Error -- you dont have a mkimage in your path, needed for echo powerpc builds. Go get one from the u-boot tree. exit 1 fi if [ -n "$MAILTO" ]; then SMTPSERVER=`git config --get sendemail.smtpserver` if [ -z "$SMTPSERVER" ]; then echo Error: you need a smptserver setting in \$HOME/.gitconfig or a SMTPSERVER echo setting in your \".buildallrc\" file if you want to have build failures sent to you. exit 1 fi which git | grep -q sysroot if [ $? = 0 ]; then echo Error: git send-email in the poky sysroot is non functional. echo Please ensure the sysroot PATH for toolchain is _after_ normal PATH. exit 1 fi fi if [ -d $BUILDALL ]; then echo Destination dir \"$BUILDALL\" already exists. echo Assuming you are resuming an interrupted/failed run. RESUME=1 sleep 1 fi echo Using $TREE as upstream source echo You can use \"export TREE=git://myhost.com/mypath\" to change. echo Doing initial setup.... mkdir -p $BUILDALL cd $BUILDALL echo "Infrastructural warnings from this run:" > $WARN_LOG if [ -d $DEFKERN ]; then echo Dir $DEFKERN already exists - assuming resuming prev. run. echo Assuming you are resuming an interrupted/failed run. RESUME=1 else if [ -d $TREE ]; then TREE=`readlink -f $TREE` clone_local else clone_ref fi fi # Set us up a linux dir and checkout meta if [ ! -d $LINUX_SRC ]; then stage_src else echo $LINUX_SRC exists, skipping staging of source code. cd $LINUX_SRC fi if [ ! -d $META_DIR/cfg/kernel-cache ]; then echo \"$META_DIR/cfg/kernel-cache\" does not exist in $PWD. echo Cant proceed without it. exit 1 fi # Create a mapping between scc and meta series and arch META_LIST=`mktemp` for i in `grep -Rl '^define KMACHINE' $META_DIR/cfg/kernel-cache` ; do SCC=`basename $i .scc` KMACHINE=`grep '^define KMACHINE' $i | head -n1 | awk '{print $3}'` KTYPE=`grep '^define KTYPE' $i | head -n1 | awk '{print $3}'` KARCH=`grep '^define KARCH' $i | head -n1 | awk '{print $3}'` META=$KMACHINE-$KTYPE-meta # 1 2 3 4 5 echo $KMACHINE $KTYPE $KARCH $META $SCC >> $META_LIST done if [ ! -z "$RANDOMIZE" ]; then mv $META_LIST $META_LIST~ sort -R < $META_LIST~ > $META_LIST rm $META_LIST~ fi # Move off meta branch before making meta content become untracked git checkout -f standard/base 2>/dev/null if [ $? != 0 ]; then echo fatal: checkout of standard/base failed exit 1 fi $MYPATH/kgit-checkpoint -r > /dev/null 2>&1 if [ $? != 0 ]; then echo fatal: checkpoint restore failed exit 1 fi for i in `cat $META_LIST| awk '{print $4}'` ; do KMACHINE=`grep $i $META_LIST | awk '{print $1}'` ARCH=`grep $i $META_LIST | awk '{print $3}'` KTYPE=`grep $i $META_LIST | awk '{print $2}'` META=`grep $i $META_LIST | awk '{print $4}'` SCC=`grep $i $META_LIST | awk '{print $5}'` METAPATH=$META_DIR/cfg/scratch/$META # echo KMACH:$KMACHINE ARCH:$ARCH KTYPE:$KTYPE META:$META SCC:$SCC if [ ! -z "$MAX_BUILDS" ]; then TOTAL_BUILD=`expr $PASS_BUILD + $FAIL_BUILD` if [ $TOTAL_BUILD -eq $MAX_BUILDS ]; then echo MAX_BUILDS value of $MAX_BUILDS reached, exiting. break fi fi if [ ! -z "$BLACKLIST" ]; then echo $BLACKLIST | grep -q "$i" if [ $? = 0 ]; then echo Skipping $i, since blacklisted continue fi fi if [ ! -z "$BLACKREGEX" ]; then echo $i | grep -q "$BLACKREGEX" if [ $? = 0 ]; then echo Skipping $i, matches blacklisted regex \"$BLACKREGEX\" continue fi fi if [ ! -z "$WHITELIST" ]; then echo $WHITELIST | grep -q "$i" if [ $? != 0 ]; then echo Skipping $i, since not explicitly whitelisted continue fi fi if [ ! -z "$WHITEREGEX" ]; then echo $i | grep -q "$WHITEREGEX" if [ $? != 0 ]; then echo Skipping $i - does not match whitelisted regex \"$WHITEREGEX\" continue fi fi $UPDATEME -DKDESC=$KMACHINE:$KTYPE $ARCH $KMACHINE > updateme.log 2>&1 if [ $? != 0 ]; then echo Generation of meta series from scc failed for $SCC echo See updateme.log for details exit 1 fi if [ ! -f $METAPATH ]; then echo Cant find meta series for $i echo I expected to find $METAPATH exit 1 fi rm -f updateme.log BRANCH=`get_branch $METAPATH` if [ -z "$BRANCH" ]; then echo Cant find branch for $META echo Skipping it continue fi git rev-parse $BRANCH > /dev/null 2>&1 if [ $? != 0 ]; then BRANCH=$BRANCH/base git rev-parse $BRANCH > /dev/null 2>&1 if [ $? != 0 ]; then echo Cant find base branch \($BRANCH\) for $META echo Skipping it continue fi fi git checkout -f $BRANCH 2>/dev/null if [ $? != 0 ]; then echo fatal: checkout of $BRANCH \(for $i\) failed exit 1 fi BUILD_DIR=../$i if [ ! -z "$RESUME" ]; then if [ -f $BUILD_DIR/00-PASS ]; then echo Skipping $i build since dir already passed. echo Remove it if you want a rebuild of it from scratch continue else if [ -d $BUILD_DIR ]; then echo Doing nuke-n-pave on old $i build since it did not pass rm -rf $BUILD_DIR fi fi else if [ -d "$BUILD_DIR" ]; then echo `basename $0`: Error: Dir \"$BUILD_DIR\" should not already exist echo We dont appear to be resuming a build sequence, so giving up. exit 1 fi fi # configme looks for the meta series in play in $META_DIR cat $METAPATH > $META_DIR/meta-series $CONFIGME -o ../$i $KTYPE $KMACHINE > cfg.log 2>&1 if [ $? != 0 ]; then echo Configuration of $i failed mv cfg.log $BUILD_DIR touch $BUILD_DIR/00-FAIL FAIL_CFG=$[$FAIL_CFG + 1] continue fi PASS_CFG=$[$PASS_CFG + 1] mv cfg.log $BUILD_DIR echo -n "Building $BRANCH for $i, status: " build_branch > error.log 2>&1 if [ $? != 0 ]; then echo -n FAILED. touch $BUILD_DIR/00-FAIL FAIL_BUILD=$[$FAIL_BUILD + 1] if [ ! -f $BUILD_DIR/build.log ]; then mv error.log $BUILD_DIR/build.log fi if [ ! -z "$MAILTO" ]; then fail_mail $i $BUILD_DIR/build.log fi else echo -n passed. touch $BUILD_DIR/00-PASS PASS_BUILD=$[$PASS_BUILD + 1] fi if [ -f time.log ]; then echo " (`cat time.log`)" rm -f time.log else echo fi if [ -s error.log ] ; then echo On branch $BRANCH for $i: >> ../$WARN_LOG cat error.log >> ../$WARN_LOG fi rm -f error.log done rm $META_LIST cd .. TOTAL_CFG=`expr $PASS_CFG + $FAIL_CFG` TOTAL_BUILD=`expr $PASS_BUILD + $FAIL_BUILD` echo ========================= Build Summary ============================ echo Kernel config: Total: $TOTAL_CFG, Pass: $PASS_CFG, Fail: $FAIL_CFG echo Kernel build: Total: $TOTAL_BUILD, Pass: $PASS_BUILD, Fail: $FAIL_BUILD echo ==================================================================== RET=`expr $FAIL_CFG + $FAIL_BUILD` if [ $RET != "0" ];then echo Do a \"ls \*\/\*FAIL\*\" for more details. fi exit $RET ######################################################## # Local variables: # enable-local-eval: t # hack-local-variables-hook: save-buffers-kill-emacs # end: