firmware/buildscript

527 lines
13 KiB
Bash
Executable File

#!/bin/bash
# SPDX-License-Identifier: GPL-3.0-or-later
set -e
set -o pipefail
builddir=./build
# OpenWrt: package hashes correspond to core repo version
OPENWRTREV="2f2eceab1307d9f9c33f151d442ab97c95bd0400"
PACKAGEREV="b1b33235b221b36458942c2cb8f51d0e1d0d8f89"
ROUTINGREV="648753932d5a7deff7f2bdb33c000018a709ad84"
# Gluon packages: master from 2020-02-04
GLUONREV="12e41d0ff07ec54bbd67a31ab50d12ca04f2238c"
OPENWRT_PKGS="gpioctl-sysfs libugpio fastd haserl micrond mtr bmon htop sysstat procps-ng procps-ng-vmstat"
ROUTING_PKGS="kmod-batman-adv batctl alfred babeld bird2"
GLUON_PKGS="simple-tc uradvd"
FFF_VARIANTS="node layer3"
OPENWRTURL="https://git.freifunk-franken.de/mirror/openwrt.git"
## Feed definition [0]: name aka directory, [1]: url, [2]: revision
#official openwrt packages
OPENWRT=(openwrt
https://git.freifunk-franken.de/mirror/openwrt-packages.git
$PACKAGEREV)
#gluon packages
GLUON=(gluon
https://github.com/freifunk-gluon/packages.git
$GLUONREV)
#official openwrt routing packages
ROUTING=(routing
https://git.freifunk-franken.de/mirror/openwrt-routing.git
$ROUTINGREV)
FFF=(fff)
FFF_PKGS="-a"
FEEDS=(OPENWRT ROUTING GLUON FFF)
# Disable dnsmasq and other useless stuff
export DEVICE_TYPE=
checkout_git(){
local DIRECTORY=$1
local REPO_URL=$2
local COMMITID=$3
local MYGIT="git -C $DIRECTORY"
echo "checking out $REPO_URL to $DIRECTORY in version $COMMITID"
if ! $MYGIT remote -v | grep -q "$REPO_URL"; then
echo "we need to do a fresh clone"
/bin/rm -rf -- "$DIRECTORY"
mkdir "$DIRECTORY"
$MYGIT clone --progress --no-checkout --filter=blob:none "$REPO_URL" .
$MYGIT config gc.auto 0
$MYGIT config advice.detachedHead 0
fi
echo
# Remove untracked files
$MYGIT clean -f -d
# Select desired commit and remove local changes (-f)
if ! $MYGIT checkout --progress --force "$COMMITID" ; then
echo "commitid not found trying to fetch new commits"
$MYGIT fetch --all && $MYGIT checkout "$COMMITID"
fi
echo
}
get_source() {
#Get the OpenWrt main repo
checkout_git $builddir $OPENWRTURL $OPENWRTREV
test -d src/packages || mkdir -p src/packages
cd src/packages
#checkout needed package feeds
for FEEDVAR in "${FEEDS[@]}" ; do
FEED="${FEEDVAR}[@]"
FEED=("${!FEED}")
local NAME=${FEED[0]}
local URL=${FEED[1]}
local REV=${FEED[2]}
if [ -n "$URL" ] && [ -n "$REV" ]; then
checkout_git "$NAME" "$URL" "$REV"
# Patches for feeds are stored in known directories like feed_patches/$NAME/
for PATCH in $(ls ../../feed_patches/${NAME}/*.patch 2>/dev/null); do
if [ -s "$PATCH" ] ; then
echo "Applying $PATCH"
git -C "$NAME" am --whitespace=nowarn "../$PATCH"
else
echo "Empty patch $PATCH ignored."
fi
done
fi
done
cd .. # packages
cd .. # src
}
patch_target() {
for patch in $(ls "$PWD"/build_patches/openwrt/*.patch 2>/dev/null); do
echo "Applying $patch:"
patch --no-backup-if-mismatch -p1 -d "$builddir" -i "$patch"
done
}
prepare() {
get_source
patch_target
update_feeds
}
update_feeds() {
## generate own feeds.conf
#this local variable should be globally configure variable used in get_source and here
local PACKAGEBASE=${PWD}/src/packages
rm -f "$builddir"/feeds.conf
for FEEDVAR in "${FEEDS[@]}" ; do
FEED="${FEEDVAR}[@]"
FEED=("${!FEED}")
local NAME=${FEED[0]}
echo "adding $NAME to package feeds"
echo src-link "$NAME" "$PACKAGEBASE"/"$NAME" >> "$builddir"/feeds.conf
done
echo "cleaning feeds"
"$builddir"/scripts/feeds clean
"$builddir"/scripts/feeds update
for FEEDVAR in "${FEEDS[@]}" ; do
FEED="${FEEDVAR}[@]"
FEED=("${!FEED}")
local NAME=${FEED[0]}
local PACKAGESVAR="${FEEDVAR}_PKGS"
PACKAGESVAR="${PACKAGESVAR}[@]"
PACKAGESVAR=(${!PACKAGESVAR})
if [[ -n "${PACKAGESVAR[@]}" ]] ; then
echo "adding ${PACKAGESVAR[*]} from feed $NAME to available packages"
"$builddir"/scripts/feeds install -p "$NAME" "${PACKAGESVAR[@]}"
fi
done
}
prebuild() {
#create filesdir for our config
/bin/rm -rf "$builddir"/files
mkdir "$builddir"/files
cp -r ./bsp/default/root_file_system/* "$builddir"/files/
cp ./bsp/"$machine"/.config "$builddir"/.config
#insert actual firware version informations into release file
variant=$(cat selected_variant)
version=$(git describe --tags --dirty)
if [ 0 -ne $? ]; then
version=$(git log -1 --pretty=format:%h)
fi
if [ -n "$variant" ]; then
version="$variant-$version"
fi
# select variant packages
echo "CONFIG_PACKAGE_fff-${variant}=y" >> "$builddir"/.config
{
echo "FIRMWARE_VERSION=\"$version\""
echo "VARIANT=\"$variant\""
echo "BUILD_DATE=\"build date: $(date)\""
echo "OPENWRT_CORE_REVISION=\"${OPENWRTREV}\""
echo "OPENWRT_FEEDS_PACKAGES_REVISION=\"${PACKAGEREV}\""
} > "$builddir"/files/etc/firmware_release
opath=$(pwd)
cd "$builddir"
make defconfig
cd "$opath"
}
build() {
prebuild
rm_firmware
opath=$(pwd)
cd "$builddir"
cpus=$(nproc)
case "$1" in
"debug")
if [ -n "$2" ]; then
make V=99 -j $2
else
make V=99
fi
;;
"fast")
[ -n "$2" ] && threads=$2 || threads=$((cpus*2))
ionice -c 2 -- nice -n 1 -- make -j $threads
;;
*)
[ -n "$2" ] && threads=$2 || threads=$((cpus+1))
ionice -c 3 -- nice -n 10 -- make -j $threads
;;
esac
cd "$opath"
cp_firmware
}
config() {
prebuild
opath=$(pwd)
cd "$builddir"
case "$1" in
"openwrt")
make menuconfig
;;
esac
save=""
until [ "$save" = "y" -o "$save" = "n" ]; do
echo "Do you want to save the generated config? (y/n)"
read save
done
if [ "$save" = "y" ]; then
case "$1" in
"openwrt")
echo "# Generated using \"./buildscript config openwrt\"." > "$opath"/bsp/"$machine"/.config
echo "# Do no edit manually" >> "$opath"/bsp/"$machine"/.config
echo "#" >> "$opath"/bsp/"$machine"/.config
./scripts/diffconfig.sh >> "$opath"/bsp/"$machine"/.config
;;
esac
fi
cd "$opath"
}
rm_firmware() {
[ -n "$subtarget" ] || subtarget="generic"
rm -rf $builddir/bin/targets/${chipset}/${subtarget}
}
cp_firmware() {
[ -n "$subtarget" ] || subtarget="generic"
mkdir -p "bin/$variant"
imagesrcpath="$builddir/bin/targets/${chipset}/${subtarget}"
imagedestpath="./bin/$variant"
for image in ${images[@]}; do
# This assumes the set of images names is given with a wildcard
fullsrcpattern=$imagesrcpath/$image
if ! ls $fullsrcpattern >/dev/null 2>/dev/null; then
echo "Warning: $image not found."
continue
fi
for f in $fullsrcpattern; do
filename_build=${f##*/}
filename_build=${filename_build//openwrt/fff-${version}}
filename_build=${filename_build//squashfs-/}
# The x86 OpenWrt target does not have a device name,
# so keep the target and subtarget for identification.
if [ "$chipset" != "x86" ]; then
filename_build=${filename_build//${chipset}-/}
filename_build=${filename_build//${subtarget}-/}
fi
cp "$f" "$imagedestpath/$filename_build"
done
done
}
buildrelease() {
if [ "$1" = "all" ];then
all=true
elif [ "$1" = "fast" ];then
fast=fast
fi
if [ "$2" = "all" ];then
all=true
elif [ "$2" = "fast" ];then
fast=fast
fi
if [ $all ]; then
buildall $fast
else
build $fast
fi
cd bin/$variant
for binary in *.bin *.img *.img.gz *.tar; do
sha256sum "$binary" > ./"$binary".sha256
done
echo -e "VERSION:$version" > release.nfo
cd ../..
}
clean() {
/bin/rm -rf bin $builddir
# remove downloaded package feeds
for FEEDVAR in "${FEEDS[@]}" ; do
FEED="${FEEDVAR}[@]"
FEED=("${!FEED}")
local NAME=${FEED[0]}
local URL=${FEED[1]}
local REV=${FEED[2]}
if [ -n "$URL" ] && [ -n "$REV" ]; then
/bin/rm -rf src/packages/"$NAME"
fi
done
}
loadBSP()
{
localbsppath=$(/bin/ls -l selected_bsp | awk '{ print $11 }')
if ! [ -s selected_bsp ]; then
echo "Error: $localbsppath does not exist. Aborting ..."
exit 1
fi
echo "Working with $localbsppath"
. selected_bsp
machine=$(basename $(realpath selected_bsp) .bsp)
}
loadVariant()
{
echo "Working with build variant \"$(cat selected_variant)\""
}
setVariant()
{
echo "$1" > selected_variant
}
setBSP()
{
/bin/rm -rf selected_bsp
/bin/ln -s "$1" selected_bsp
loadBSP
}
buildall() {
for bsp in $(/bin/ls bsp/*.bsp); do
setBSP "$bsp"
build "$1"
done
}
if [ "$(/usr/bin/id -u)" -eq 0 ]; then
TPUT=$(command -v tput || echo ":")
textWarn="$($TPUT bold setaf 1)" # bold + red
textReset="$($TPUT sgr0)" # be a good citizen
printf "${textWarn}WARNING: buildscript is running as root${textReset}\n"
printf "${textWarn}WARNING: build may fail at a later stage${textReset}\n"
fi
if [ "$1" != "selectbsp" -a "$1" != "selectvariant" ]; then
if [ ! -h selected_bsp ]; then
echo "Please select a Board-Support-Package using:"
echo "$0 selectbsp"
exit
fi
if [ ! -f selected_variant ]; then
echo "Please select a build variant using:"
echo "$0 selectvariant"
exit
fi
loadBSP
loadVariant
echo
fi
case "$1" in
"selectbsp")
if [ "$2" = "help" ] || [ "$2" = "" ]; then
echo "Select a Board-Support-Package:"
echo
echo "Usage: $0 $1 <bsp-file>"
echo "available packages:"
/bin/ls bsp/*.bsp
echo
else
if [ ! -f "$2" ]; then
echo "Could not find $2"
else
setBSP "$2"
fi
fi
;;
"selectvariant")
if [ "$2" = "help" ] || [ "$2" = "" ]; then
echo "Select a build variant:"
echo
echo "Usage: $0 $1 <name of variant>"
echo "available variants: $FFF_VARIANTS"
echo
else
if ! echo "$FFF_VARIANTS" | grep -q "\b$2\b"; then
echo "Could not find variant $2"
else
setVariant $2
fi
fi
;;
"prepare")
if [ "$2" = "help" ] || [ "$2" = "x" ]; then
echo "This option fetches the sources for the images and configurates the build so that it can be compiled"
echo
echo "Usage: $0 $1"
echo
else
prepare
fi
;;
"updatefeeds")
update_feeds
;;
"build")
if [ "$2" = "help" ] || [ "$2" = "x" ]; then
echo "This option compiles the firmware"
echo "Normally the build uses lower IO and System priorities, "
echo "you can append \"fast\" option, to use normal user priorities"
echo
echo "Usage: $0 $1 [fast|debug] [numthreads]"
echo
else
build "$2" "$3"
fi
;;
"config")
case "$2" in
openwrt)
config openwrt
;;
*)
echo "This open the OpenWrt menuconfig dialog"
echo
echo "Usage: $0 $1 openwrt"
echo
;;
esac
;;
"clean")
if [ "$2" = "help" ] || [ "$2" = "x" ]; then
echo "This option cleans all build files."
echo
echo "Usage: $0 $1"
echo
else
clean
fi
;;
"buildall")
if [ "$2" = "help" ]; then
echo "This option builds the firmware for all routers."
echo
echo "Usage: $0 $1 [fast]"
echo
else
buildall "$2"
fi
;;
"release")
if [ "$2" = help ]; then
echo "This option builds the firmware for a given board. It also creates hash sums and a the file release.nfo"
echo
echo "Usage: $0 $1 [all] [fast]"
echo
else
buildrelease "$2" "$3"
fi
;;
*)
echo "This is the Build Environment Script of the Freifunk Community Franken."
echo
echo "Usage: $0 command"
echo "command:"
echo " selectbsp <bsp-file>"
echo " selectvariant <name of variant>"
echo " prepare"
echo " updatefeeds"
echo " config openwrt"
echo " build [fast|debug]"
echo " buildall [fast]"
echo " release [all] [fast]"
echo " clean"
echo ""
echo "If you need help to one of these options just type: $0 <command> help"
echo
;;
esac