A modern piece of software usually involves a number of parts that you did not write yourself. This could be libraries or tools for example. Many of those are available under so-called Open Source Licenses, like MIT, BSD or the GPL. But even if you are usually allowed to use software under these licenses for free, as without financial compensation, it does not mean that you are free to do whatever you want. Especially once you are distributing your resulting software product, a number of obligations apply.
This tutorial will guide you through the mechanisms that the Yocto Project® offers in order to understand the licenses that are involved in your build, and outline some considerations and means that you can apply in order to archieve license compliance.
To follow this tutorial, it is helpful to have a finished Yocto Project® build that you can inspect. As an example for the Raspberry Pi 3, you can follow the tutorial at Preparing the Yocto Project environment from scratch. In that case the
MACHINE variable is
raspberrypi3. If you use a build for another board, the
MACHINE variable differs accordingly.
The most basic step in understanding your licensing situation is to see which licenses actually do apply to your build. This is something that the Yocto Project® already gives you without additional effort.
In your build directory, look at the
tmp/deploy/licenses subdirectory. Here you will find an exhaustive list of all artifacts generated in this build context and their licensing information. The license of most artifacts will not vary across different
MACHINE selections, so the content of this directory is not split up by
MACHINE, build date or other determinants. Images are a special case then, as they are
MACHINE-specific and also often vary over build iterations, so they follow the additional naming convention
$IMAGE_NAME-$MACHINE-$DATE. As we are mostly interested in the licenses involved in one specific image, we can inspect such like for example:
$ tree tmp/deploy/licenses/core-image-minimal-raspberrypi3-20220408092057/ tmp/deploy/licenses/core-image-minimal-raspberrypi3-20220408092057/ ├── image_license.manifest ├── license.manifest └── package.manifest
There are two files with the term
license in the name. Looking at those shows the following information:
image_license.manifest: the licenses for all deployed packages. These are mostly things that are needed to boot the device, but live outside the root filesystem. In the case of the Raspberry Pi 3, these are
linux-raspberrypi(the Linux kernel),
u-boot(the bootloader). The file includes an exhaustive mapping of file to license, recipe and version. Example extract for the
RECIPE NAME: u-boot VERSION: 2020.01 LICENSE: GPLv2+ FILES: u-boot-initial-env-raspberrypi3-2020.01-r0 fw_env.config-raspberrypi3-2020.01-r0 fw_env.config.default u-boot-raspberrypi3-2020.01-r0.bin uboot.env
licenses.manifest: the licenses of all packages included in the image. Those are not broken down on a file level, but also include a mapping of package to license, recipe and version. Example extract for the
PACKAGE NAME: bash PACKAGE VERSION: 5.0 RECIPE NAME: bash LICENSE: GPLv3+
package.manifest file is not relevant in the context of this tutorial.
So by inspecting those files we can get reliable information on the licenses involved in the software artifact that we are deploying.
You might want to restrict your build from using specific licenses, and allow some others. By default, a Yocto Project® build does include software under commercial licenses.
As you will want to apply licensing-related setting to all of your build, they must be put into a
.conf (e.g. “configuration”) file, such as your products
local.conf. Usually the
DISTRO is a good place is it makes sure this setting is under version control and therefore reproducible, but under some circumstances a more transient setting in
local.conf can be appropriate too.
This does not work when put into the recipe of the image that you are building. The reason is that it is only locally visible in the context of the recipe then and can not affect any other recipe.
In a product that you are shipping, you will maybe want to allow certain commercial things to be added to your build, such as the Mender Monitor add-on. This can be done by adding
LICENSE_FLAGS_WHITELIST += "commercial_mender-monitor"
to the configuration file.
On the opposite end, there are cases where you want to avoid software under specific open source licenses being added to your build. As an example, you can exclude any
AGPL-3.0-licensed package by adding
INCOMPATIBLE_LICENSE = "AGPL-3.0"
to the configuration file. This affects the whole build dependencies and not only the packages that you actively added.
Note: removing software can break dependencies, especially when core recipes are involved.
As an example, you can try and remove the
GPL-3.0-license. This will not work without supplying replacements for a number of packages in the most cases.
In order for the tracking mechanism to function properly, all recipes are required to provide license information. This information consists of two parts.
naming the applicable license. This is done by setting the
LICENSEvariable in the recipe, for example like
LICENSE = "MIT"
The standard licenses are included in
meta/files/common-licensesdirectory. The file names should be used as license strings. More information also relating to SPDX is provided in the variable reference
tracking the license of your sources. The tracking in itself does not convey any information about the actual license, but makes sure that it does not change unnoticed between builds. This is archieved by supplying at least one, but often multiple locations and checksums of license statements in the sources to the
LIC_FILES_CHECKSUMvariable. An example taken from the Yocto Project® documentation demonstrates various mechanims:
LIC_FILES_CHKSUM = "file://COPYING;md5=xxxx \ file://licfile1.txt;beginline=5;endline=29;md5=yyyy \ file://licfile2.txt;endline=50;md5=zzzz \ ..."
Checksumming the license notes in the sources has the desired effect of mismatching and therefore stopping the build whenever a change in those notes happens. Then the note and license can be inspected to verify that the assumed license information is still correct.
For more information on this, please see the Yoctp Project® Dev Manual
CLOSED is not commercial/proprietary!
A common misconception is that setting
LICENSE = "CLOSED" means the recipe in question is closed source, respectively proprietary. This is not the actual case: the license value
CLOSED has the meaning “do not care about the license of this recipe”. This effectively disables all license tracking for this recipe and should be avoided.
The correct way to set a proprietary, nonstandard license is
LICENSE = "Proprietary"
This often correlates with being commercial, which is expressed by the flag
LICENSE_FLAGS = "commercial"
commercial flag is automatically expanded with the recipe name, and can then be matched, therefore allowed for the build, as outlined in the first paragraph.
In this tutorial we went through the basics for understanding and adjusting the licenses involved in a image build using the Yocto Project®, as well as properly declaring license information for your own recipes.
For further reading please visit
- Yocto Project® documentation on license compliance in the product lifecycle
- Yocto Project®s own licensing
- Free Software Foundation on licensing
If this tutorial was useful to you, please press like, or leave a thank you note to the contributor who put valuable time into this and made it available to you. It will be much appreciated!