reduce OpenWrt build times
paidforby opened this issue · 6 comments
Currently building only the firmware for the N600 takes upwards of an hour (see full build report below), to reduce the build time we should figure out how to stop rebuilding the OpenWrt toolchain every time we run a build. I'm guessing the solution is to be found somewhere in the OpenWrt config file, created by the build script here
On my personal computer (a five year old laptop with an i5-3210M CPU @ 2.50GHz and 12GBs of DDR3 RAM)
+ echo 'Building [ar71xx] done.'
Building [ar71xx] done.
+ echo 'Building firmware for [ar71xx] done.'
Building firmware for [ar71xx] done.
real 83m12.340s
user 61m5.468s
sys 10m7.264s
While sitting and waiting for test builds to finish for #116 I had this idea. If we could figure out how to run a rebuilds correctly, then we could run an entire initial build in a docker container, upload that to docker hub, and just perform rebuilds on it? It should be noted that the extender-node firmware takes about half as long as the initial home node firmware build. I think this is because it is a partial rebuild, so a lot of the toolchain has already been set up. I'm going to test this theory by doing a targeted rebuild of the firmware. one for the N600 and then one for the N750. I suspect the second build will take substantially less time than the first.
After talking to @jkilpatr at Our Networks and taking at a stab at building a VM of our firmware (related to sudomesh/peoplesopen-dash#5 ). I've significantly reduced build times. It still takes forty some minutes to build the first time, by logging directly into the docker container with
docker run -it --entrypoint=/bin/bash sudomesh/sudowrt-firmware:0.3.0 -i
I can trigger a rebuild, like so
root@a408fdd34ad2:/usr/local/sudowrt-firmware/built_firmware/builder.ar71xx# time make
make[1] world
make[2] target/compile
make[3] -C target/linux compile
make[2] package/cleanup
make[2] package/compile
make[3] -C package/libs/toolchain compile
make[3] -C package/libs/libnl-tiny compile
make[3] -C package/libs/libjson-c compile
make[3] -C package/utils/lua compile
make[3] -C package/libs/libubox compile
make[3] -C package/system/ubus compile
make[3] -C package/system/uci compile
make[3] -C package/network/config/netifd compile
make[3] -C package/system/opkg host-compile
make[3] -C package/system/ubox compile
make[3] -C package/libs/lzo compile
make[3] -C package/libs/zlib compile
make[3] -C package/libs/ncurses host-compile
make[3] -C package/libs/ncurses compile
make[3] -C package/utils/util-linux compile
make[3] -C package/utils/ubi-utils compile
make[3] -C package/system/procd compile
make[3] -C package/system/usign host-compile
make[3] -C package/utils/jsonfilter compile
make[3] -C package/system/usign compile
make[3] -C package/base-files compile
make[3] -C package/boot/grub2 host-compile
make[3] -C package/boot/grub2 compile
make[3] -C package/firmware/linux-firmware compile
make[3] -C package/kernel/linux compile
make[3] -C package/network/utils/iptables compile
make[3] -C package/network/config/firewall compile
make[3] -C package/network/ipv6/odhcp6c compile
make[3] -C package/network/services/dnsmasq compile
make[3] -C package/network/services/dropbear compile
make[3] -C package/network/services/odhcpd compile
make[3] -C package/libs/libpcap compile
make[3] -C package/network/utils/linux-atm compile
make[3] -C package/network/utils/resolveip compile
make[3] -C package/network/services/ppp compile
make[3] -C package/system/fstools compile
make[3] -C package/system/mtd compile
make[3] -C package/libs/ocf-crypto-headers compile
make[3] -C package/libs/openssl compile
make[3] -C package/system/opkg compile
make[3] -C package/utils/busybox compile
make[3] -C package/utils/mkelfimage compile
make[2] package/install
make[3] package/preconfig
make[2] target/install
make[3] -C target/linux install
make[2] package/index
real 1m0.072s
user 0m26.752s
sys 0m5.680s
As can be seen, it takes 1 min! I confirmed that this rebuild successfully included a new test file. Next, I plan on taking a look at our docker setup and build scripts to figure out how to trigger this type of rebuild from outside the container.
Holy crapsauce. That's incredible.
@bennlich holy crapsauce is right. After this revelation, I went about reworking the build process.
Initially, I thought to reapproach #116 and try running the entire build inside of travis. After a few attempts (ending with 503c1f9 ), I found out that it is impossible to run the full build in travis since it will always timeout after 50mins on a public repo.
But with the incentive of 1min long build times, I came up with a new plan.
So here was my thinking:
- Run full build (i.e.
build_pre
andbuild_only
) once on a local machine in a docker container (as though I was trying build the firmware). - Commit the changes made to that docker container in a new docker image, which I temporarily backed up here, https://hub.docker.com/r/sudomesh/sudowrt-builder/
- Push this new "builder" image to docker hub, in place of the old image, in which only
build_pre
had run, see the difference in size here https://hub.docker.com/r/sudomesh/sudowrt-firmware/tags/ - Modify travis script to pull the new image, copy in latest changes to repo, and rebuild the firmware, so now it looks like this, https://github.com/sudomesh/sudowrt-firmware/blob/master/.travis.yml
- Add
openwrt_rebuilder
andremove_images
functions tobuild_lib
to handle changes to the local copy of repo, modifcations toopenwrt_config
, and the "re-making" of the binaries. See those additions here, https://github.com/sudomesh/sudowrt-firmware/blob/master/build_lib#L310 - Push new travis and build scripts to master to trigger a rebuild that piggybacks off the initial local build that I pushed in step 3.
And guess what, it works!!! https://travis-ci.org/sudomesh/sudowrt-firmware/builds/411983666
Unfortunately, Travis CI takes ~25 mins to complete the pull, update, rebuild process, but the important thing is that it actually finishes!!! Also, I swear, it takes less than one minute to rebuild on my local machine!
Rebuilding [ar71xx] done.
Building firmware for [ar71xx] done.
+ echo 'Building firmware for [ar71xx] done.'
real 0m48.218s
user 0m20.808s
sys 0m4.428s
One thing left to figure out is to see if we can deploy the binaries somewhere. Does anyone (maybe @jhpoelen ?) know how to push files from travis to zenodo? I'm not sure how to access the SudoMesh zenodo account?
Issue has served its purpose, opened new issue for discussion regarding deployment of builds.
This is good reading.