Skip to content

Yocto Builds with CROPS Containers

In a recent post Using Docker Containers for Yocto Builds, I suffered an episode of NIHS (not-invented-here syndrome). I wrote a Dockerfile for Yocto builds. Stefan Agner pointed out in his comment that the CROPS project provides ready-made containers for Linux distributions like Ubuntu, Fedora and others. The crops/poky-container enables us to start our first Yocto build within minutes.

If not done yet, we must install Docker. The section Installing Docker of my previous post covers this.

We create a working directory that will hold all the source files going into the Yocto build and all the files generated by the Yocto build.

$ mkdir work-cuteradio
$ cd work-cuteradio

We use my standard project cuteradio as an example. It builds a complete Linux system and a very simple Qt-based Internet radio application for a Raspberry Pi 3. We clone the Yocto layers into the working directory.

$ git clone --recurse-submodules https://github.com/bstubert/cuteradio.git

We are now ready to run the crops/poky container from the current working directory.

$ docker run --rm -it -v ${PWD}:/work-cuteradio crops/poky:ubuntu-16.04 --workdir=/work-cuteradio
Unable to find image 'crops/poky:ubuntu-16.04' locally
ubuntu-16.04: Pulling from crops/poky
7e6591854262: Pull complete
...
64da849d3519: Pull complete
Digest: sha256:e13dafef3d5e3b37a04fe9200cbdbc5974483690024b5d7ad6413e73b5d01dfa
Status: Downloaded newer image for crops/poky:ubuntu-16.04

As we run the crops/poky container for the first time, Docker builds the image locally. Subsequently, Docker simply runs the container without building it. By default, crops/poky uses ubuntu-14.04. We told it to use the newer version ubuntu-16.04.

Option -v maps the current working directory (e.g. /public/Projects/work-cuteradio) on the host computer to the directory /work-cuteradio inside the container. This option makes the tree rooted at the working directory visible both in the container and on the host computer.

We must ensure that the directory paths for BBLAYERS in cuteradio/sources/meta-cuteradio/custom/bblayers.conf.sample point to the working directory inside the container: /work-cuteradio.

BBLAYERS ?= " \
/work-cuteradio/cuteradio/sources/poky/meta \
/work-cuteradio/cuteradio/sources/poky/meta-poky \
...

The very first Yocto build copies bblayers.conf.sample to /work-cuteradio/build/conf/bblayers.conf. If we forget to adapt the BBLAYERS paths, we’ll see the following error message.

ERROR: Layer directory '/home/cuteradio/yocto/input/cuteradio/sources/poky/meta' does not exist! 
Please check BBLAYERS in /work-cuteradio/build/conf/bblayers.conf

The crops/poky container creates a user with the the ID of the user who owns the working directory on the host computer. Using the same Linux user ID on the host and in the container allows the host user access to both worlds. Option –workdir helps the container to figure out the Linux user ID. This makes it easy for different users to run the same container. This is not possible with the solution I presented previously, where all users must have the same user ID.

When Docker finishes the build of the crops/poky image, it starts a bash shell in the container. We enter the command for the Yocto build at the shell prompt.

pokyuser@56871110db67:/work-cuteradio$ export TEMPLATECONF=${PWD}/cuteradio/sources/meta-cuteradio/custom && \
source ${PWD}/cuteradio/sources/poky/oe-init-build-env build && \
bitbake cuteradio-image

The Yocto build takes a couple of hours depending on the performance of our host computers. We deploy and run the Linux image on the Raspberry Pi 3 as described in my previous post.

We don’t want to type the lengthy docker command in the host shell and the even lengthier commands in the container shell. Instead, we only want to type the actual Yocto command like bitbake cuteradio-image. We come close with the helper script ycr, which is an acronym for yocto cuteradio.

#!/bin/bash
cmd="export TEMPLATECONF=/work-cuteradio/cuteradio/sources/meta-cuteradio/custom
&& source /work-cuteradio/cuteradio/sources/poky/oe-init-build-env build
&& $@"
docker run --rm -it -v ${PWD}:/work-cuteradio crops/poky:ubuntu-16.04 \
--workdir=/work-cuteradio --cmd "${cmd}"

We copy the script in one of the directories of $PATHS~/bin, for example – and make it executable.

On the host computer, we execute the command

$ ycr bitbake cuteradio-image

to build the Linux image for the CuteRadio project. This one-liner does the same as the lengthy commands before.

We start a bash shell in the Yocto build environment with the command

$ ycr bash

In general, we can pass to ycr any command (with arguments) that we can enter and run in a Yocto build environment.

Every member of a project team can perform Yocto builds in the same development environment – thanks to the crops/poky Docker container. Team members don’t have to spend time on installing the correct development environment and on figuring out why their development environment is slightly different than that of others.


Leave a Reply

Your email address will not be published. Required fields are marked *