Hurdle 3: Scoping OpenWRT's Build System Down (Continued)
Previously:
./scripts/feeds
feedsis the main script for OpenWRT's package feed management written in Perl, abstracting all the repository operations and package install/uninstall logic in a uniform manner, so users don't have to worry themselves with details of where packages come from or how they are versioned....
(About understanding their build system:) I've just realized that another way to approach this is to look at their GH Actions. Upon inspection, it appears that they do have a build flow used to test LuCI, and we even have some example runs to look at
Task 1: Digesting ./scripts/feeds and ./scripts/feeds.conf.default
Previously, I failed to mention why we are going over feeds and feeds.conf.default. When using the SDK (or the full buildroot), you will often be instructed to use feeds quite rigorously mainly for healing your SDK, buildroot, or if you are building using the OS itself, your OpenWRT installation. It can also be used to install dependencies for your project as well.
Some, but not all instances of it being referenced in OpenWRT/LuCI documentation:
- https://openwrt.org/docs/guide-developer/toolchain/using_the_sdk
- https://github.com/openwrt/luci/wiki/Installation
LuCI instructs that you run:
./scripts/feeds update
./scripts/feeds install -a -p luci
make menuconfig
...but as we have discovered previously, it may be better for us to use feeds the way their GH Actions do
Task 2: Reviewing SDK Usage in GH Actions:
LuCI's interaction with the SDK at the workflow level is quite minimal:
- name: Build
uses: openwrt/gh-action-sdk@v7
env:
ARCH: ${{ matrix.arch }}-${{ env.BRANCH }}
FEEDNAME: packages_ci
V: s
# nothing actually happens between invoking the SDK and moving the packages around:
- name: Move created packages to project dir
run: cp bin/packages/${{ matrix.arch }}/packages_ci/* . || true
It seems that most of the building is done automatically by the SDK action:
- https://github.com/openwrt/gh-action-sdk/blob/b8cc97d1072dedff455e2945a73fc43f5c7e1749/entrypoint.sh
The available environment variables are documented here:
ARCHdetermines the used OpenWRT SDK Docker container. E.g.x86_64orx86_64-22.03.2ARTIFACTS_DIRdetermines where the built packages and build logs are saved. Defaults to the default working directory (GITHUB_WORKSPACE).BUILD_LOGstores the build logs in./logs.CONTAINERcan set other SDK containers thanopenwrt/sdkEXTRA_FEEDSare added to thefeeds.conf, where|are replaced by white spaces.FEED_DIRused in the createdfeeds.conffor the current repo. Defaults to the default working directory (GITHUB_WORKSPACE).FEEDNAMEis used in the createdfeeds.conffor the current repo. Defaults toaction.IGNORE_ERRORScan ignore failing package builds.INDEXmakes the action build the package index. Default is 0. Set to 1 to enable.KEY_BUILDcan be a private Signify/usignkey to sign the packages (ipk) feed.PRIVATE_KEYcan be a private key to sign the packages (apk) feed.NO_DEFAULT_FEEDSdisable adding the default SDK feedsNO_REFRESH_CHECKdisable check if patches need a refreshNO_SHFMT_CHECKdisable check if init files are formattedPACKAGES(Optional) specify the list of packages (space separated) to be builtVchanges the build verbosity level.
setup.sh Breakdown:
First, it calls setup.sh from ghcr.io/openwrt/sdk
group "bash setup.sh"
# snapshot containers don't ship with the SDK to save bandwidth
# run setup.sh to download and extract the SDK
[ ! -f setup.sh ] || bash setup.sh
endgroup
Then, it sets up the feed configuration:
FEEDNAME="${FEEDNAME:-action}"
...
echo "src-link $FEEDNAME /feed/" >> feeds.conf
Which we know from before is packages_ci:
It appears they use openwrt/gh-action-sdk with a few env vars:
ARCH-<arch>-<branch>FEEDNAME-packages_ci
Noteworthy (but unused by LuCI) is the fact that you can optionally disable the default feeds:
if [ -z "$NO_DEFAULT_FEEDS" ]; then
sed \
-e 's,https://git.openwrt.org/feed/,https://github.com/openwrt/,' \
-e 's,https://git.openwrt.org/openwrt/,https://github.com/openwrt/,' \
-e 's,https://git.openwrt.org/project/,https://github.com/openwrt/,' \
feeds.conf.default > feeds.conf
fi
Then the script starts adding in the extra feeds:
ALL_CUSTOM_FEEDS="$FEEDNAME "
#shellcheck disable=SC2153
for EXTRA_FEED in $EXTRA_FEEDS; do
echo "$EXTRA_FEED" | tr '|' ' ' >> feeds.conf
ALL_CUSTOM_FEEDS+="$(echo "$EXTRA_FEED" | cut -d'|' -f2) "
done
Finally, it updates the feeds:
group "feeds.conf"
cat feeds.conf
endgroup
group "feeds update -a"
./scripts/feeds update -a
endgroup
Then it builds defconfig:
group "make defconfig"
make defconfig
endgroup
We're not gonna go over defconfig, unless I later determine we need it, but more on it can be found here:
- https://gitlab.com/openwrt/openwrt/openwrt/-/blob/master/include/toplevel.mk#L120-124
- It is a makefile target that generates a
.configfile used in kconfig build systems. - It is used in place of
make menuconfigto generate a default configuration file for the build system.
The majority of the rest of the script is determined by whether $PACKAGES is set or not. LuCI does not set it, so it uses the default behavior:
if [ -z "$PACKAGES" ]; then
# compile all packages in feed
for FEED in $ALL_CUSTOM_FEEDS; do
group "feeds install -p $FEED -f -a"
./scripts/feeds install -p "$FEED" -f -a
endgroup
done
RET=0
make \
BUILD_LOG="$BUILD_LOG" \
CONFIG_SIGNED_PACKAGES="$CONFIG_SIGNED_PACKAGES" \
IGNORE_ERRORS="$IGNORE_ERRORS" \
CONFIG_AUTOREMOVE=y \
V="$V" \
-j "$(nproc)" || RET=$?
else
...
fi
Then it wraps up the build:
if [ "$INDEX" = '1' ];then
group "make package/index"
make package/index
endgroup
fi
if [ -d bin/ ]; then
mv bin/ /artifacts/
fi
if [ -d logs/ ]; then
mv logs/ /artifacts/
fi
exit "$RET"
Now that we understand how they build the packages automatically, we can now use this knowledge for building our own way. For now, we will use the recommended make menuconfig as described in Task 1, but we will likely switch to using the GH Actions way of building in the future.
I think the next 2 steps is to finish digesting feeds, then play around with make menuconfig to get a better understanding of the available options.
Top comments (0)