Introduction
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.
Prerequisites
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.
Inspecting the used licenses
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 arebootfiles
,linux-raspberrypi
(the Linux kernel),rpi-config
,rpi-u-boot-scr
andu-boot
(the bootloader). The file includes an exhaustive mapping of file to license, recipe and version. Example extract for theu-boot
recipe: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 thebash
package:PACKAGE NAME: bash PACKAGE VERSION: 5.0 RECIPE NAME: bash LICENSE: GPLv3+
The 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.
Adjusting the allowed licenses for your build
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 DISTRO.conf
or 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.
Correctly specifying LICENSE
for your own recipes
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
LICENSE
variable in the recipe, for example likeLICENSE = "MIT"
The standard licenses are included in
poky
in themeta/files/common-licenses
directory. 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_CHECKSUM
variable. 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"
The 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.
Conclusion
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!