#!/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="v21.02.2" PACKAGEREV="b0ccc356900f6e1e1dc613d0ea980d5572f553dd" ROUTINGREV="10d3ffd8b30186b49538167bac1fa1bf9c88f860" # Gluon packages: master from 2020-02-04 GLUONREV="12e41d0ff07ec54bbd67a31ab50d12ca04f2238c" OPENWRT_PKGS="gpioctl-sysfs libugpio fastd haserl micrond mtr bmon" ROUTING_PKGS="kmod-batman-adv batctl alfred babeld" 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 [ -d "$DIRECTORY" ]; then if $MYGIT remote -v | grep -q "$REPO_URL" ; then echo "Right remote detected" # Remove untracked files $MYGIT clean -f -d # Select desired commit and remove local changes (-f) if ! $MYGIT checkout -f "$COMMITID" ; then echo "commitid not found trying to fetch new commits" $MYGIT fetch --all && $MYGIT checkout "$COMMITID" fi else echo "wrong remote or not an git repo at all -> deleting whole directory" /bin/rm -rf "$DIRECTORY" #needs to be without -C!!! git clone "$REPO_URL" "$DIRECTORY" $MYGIT checkout "$COMMITID" fi else echo "We need to do a fresh checkout" #needs to be without -C!!! git clone "$REPO_URL" "$DIRECTORY" $MYGIT checkout "$COMMITID" fi } 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 # apply variant to ensure the included file "variant.mk" # exists in builddir. apply_variant update_feeds } apply_variant() { # set the variant for this build export FFF_VARIANT=$(cat selected_variant) # force the reevaluation of this Makefile to make note of the new variant touch ./src/packages/fff/fff/Makefile } 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() { apply_variant #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 { 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") make V=99 ;; "fast") ionice -c 2 -- nice -n 1 -- make -j $((cpus*2)) ;; *) ionice -c 3 -- nice -n 10 -- make -j $((cpus+1)) ;; 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-/} filename_build=${filename_build//${chipset}-/} filename_build=${filename_build//${subtarget}-/} 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 *.tar; do md5sum "$binary" > ./"$binary".md5 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 echo "don't run buildscript as root" exit 1 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 " 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 " 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 "Normaly 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]" echo else build "$2" 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 " echo " selectvariant " 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 help" echo ;; esac