Over the years I’ve come to respect distro builders. They can do things that blow the minds of traditional software engineers. Occasionally I find myself needing to try and patch a piece of software in Yocto. This blog explains a cool hack I call the "RM WORK" trick that was taught to me by legendary hacker, Ricardo Salveti.
The best engineers have quick ways to get into a compile/test loop. There are always multiple ways to do this. The "RM WORK” trick isn’t always the best, but it's usually a pretty good way to start on something you don't know well. For this article, I'll cover debugging a problem in Aktualizr-lite.
I'm a novice at Yocto and have found it hard to debug effectively. Yocto/Bitbake tooling is expansive and more than I can remember. Ricardo taught me the "RM WORK" trick to give me a consistent way to work on different types of projects. Bitbake builds components in isolated directories. These directories include scripts and the component's code with all the correct paths and environment variables needed to cross-compile. These directories are called "work", and Bitbake cleans them up after building a component to help save space.
The beauty of Yocto is that if you type enough things in CAPITAL_LETTERS
, you'll eventually unlock something magical. In this case the secret is called RM_WORK_EXCLUDE
. This directive tells Yocto to keep all these "work" files around after it builds a component.
Sharing my local environment, I have a setup like: /home/doanac/code/lmp
. Underneath that, I have a build directory for qemu, ./build-intel
. I can tell Yocto to keep around for work some components by appending to my local build configuration, build-intel/conf/local.conf
:
RM_WORK_EXCLUDE += "aktualizr fioconfig lmp-device-register"
As you can see here, I keep the work around for a few components so that it's easy for me to build binaries for the components I work on most.
To continue from this example, after I've done my Yocto build say bitbake aktualizr-lite
(aktualizr "RPROVIDES" aktualizr-lite - it’s all about CAPITAL_LETTERS
), I will have this directory:
./tmp-lmp/work/corei7-64-lmp-linux/aktualizr/1.0+gitAUTOINC+95ecfb878f-7/
This is where the magic is. From this directory I can:
- Edit source under the
git
directory, e.g.git/source/main.cc
- Run
./temp/run.do_compile
to produce a new binary that's cross-compiled for your specific version of Yocto:./build/src/aktualizr-lite
. - Copy this binary to my device
- Rinse and repeat until I’ve fixed my bug.
I get clever and do mv git git-oe; git clone https://github.com/foundriesio/aktualizr-lite git
to let me work from Git and track my changes. This also works from something in Golang like Fioconfig. In this case, Yocto puts my source files under: fioconfig-git/src/github.com/foundriesio/fioconfig
. /tmp/run.do.compile
still builds the binary and it will be located at ./build/bin/fioconfig
.
In closing, this isn't a perfect trick but it's helped me pay the mortgage over the years.