Restrict a library from going into final image - yocto

I am building a Yocto image. There are some GPLv3 libraries which are required only at build time. I have put GPLv3 as INCOMPATIBLE_LICENSE and whitelisted the libraries which are required at build time. But these libraries are getting into the final image. How can I restrict them into the final image and only use them at the build time?

If we think about the Yocto basics, we know that everything goes into the final image is a collection of recipes providing packages that are collected together in a single root file system.
So, what makes a recipe goes into the final rootfs ?
Added via IMAGE_INSTALL.
Be set as RDEPENDS of another recipe.
You need to analyse that deeply to find out what goes into your final rootfs.
Also, you may not find it obvious in the content of IMAGE_INSTALL by running:
bitbake -e <your_image_recipe> | grep ^IMAGE_INSTALL=
but, you may see some packagegroups that are shipped. A packagegroup is a group that RDEPENDS on a list of other recipes.
So, you need to carefully analyse them (if found) to see what provides the lib you want to inhibit from rootfs.
packagegroups usually gets shipped dynamically via IMAGE_FEATURES variable.
So, those are the most important points that are responsible of shipping a recipe to the rootfs. So, Analyse your wanted recipe.
Is it an RDEPENDS of another recipe ?
Find out where exactly it gets called to be shipped.

Removing the installation of lib from do_install task by adding something like this in recipe e.g gdb as you said
do_install:append()
{
#remove the lib which you don't want to ship into image
}
And make sure the same lib is not added to FILES var in recipe
e.g FILES:${PN} += "< lib >"

PACKAGE_EXCLUDE worked for me. If packages listed under PACKAGE_EXCLUDE is getting into the final image, then this will raise an error.
Also if any other package has a runtime dependency on a package listed under PACKAGE_EXCLUDE, then this will raise an error too.
References:
https://docs.yoctoproject.org/ref-manual/variables.html#term-PACKAGE_EXCLUDE
https://git.yoctoproject.org/poky/tree/meta/conf/documentation.conf#n313

Related

Avoid a library from going to final image in Yocto

I am working on building an Yocto image in which I use some Open Source libraries whiich are required only during the build time. Currently they are not part of the final image. Is there a way to make sure that they do not make it to the final image in the future also?
Thanks in advance.
If any recipe is found in the final image that means the recipe is specified into one of the install variables (IMAGE_INSTALL, IMAGE_FEATURES, ...) or it is specified as a run time dependency of another recipe (RDEPENDS).
I could be one of these cases:
If the libraries are provided by a separate recipe and that recipe is specified as DEPENDS of your main recipe. Make sure that the recipe of the libraries is not present in IMAGE_INSTALL or any image installation variable. And make sure that it is not present in any RDEPENDS variable.
If the main recipe is generating libraries and using them to compile the final result, it is easy, just make sure that they are not installed or mentioned in do_install task.
I found PACKAGE_EXCLUDE to be more helpful which throws an error when the packages of the OSS libraries are being installed on the image by anyone.
Refer the doc - https://docs.yoctoproject.org/2.5.1/ref-manual/ref-manual.html#var-PACKAGE_EXCLUDE

How do I figure out what is causing a recipe to be included?

I am working on a yocto project and in my custom layer, I have dozens of recipes. A couple recipes are still under development and were not listed in the my image's recipe. However one broken recipe is still being pulled into the build. I have deleted by build/tmp directory as well as my state cache and rebuilt. But the bad recipe is still being pulled in. How do I figure out what is pulling in this bad recipe? bitbake -e doesn't show my recipe at all.
I was able to figure it out by shear luck, so I'm really asking for debug skills on doing this in the future. In my case, the bad recipe had a dozen or so PROVIDES, and another recipe was DEPENDing on one of those. Is there a way to get bitbake to indicate why a recipe is being baked? something like "Compling lib_bad.bb because lib_good.bb depends on it"
You can generate dependacy graph:
bitbake -g <packagename>
vim task-depends.dot
or graphical version (graphviz):
bitbake -g <packagename> -u taskexp
So to answer my own question, there are a few things to offer: https://docs.yoctoproject.org/what-i-wish-id-known.html My question is basically the crux of item #8 on that list. So here is what I could have done to expedite solving the mystery.
When you run bitbake -g core-image-minimal you get two files in the build directory: task-depends.dot and pn-buildlist.
Then look in the task-depends.dot file and search for the package. grep <package> task-depends.dot The first search results are going to show several entries for the culprit package that is pulling in the bad package.
~/poky/build$ grep lib_bad task-depends.dot
"lib_good.do_build" -> "lib_bad.do_package_write_deb"
"lib_good.do_package" -> "lib_bad.do_packagedata"
"lib_good.do_prepare_recipe_sysroot" -> "lib_bad.do_populate_sysroot"
"lib_bad.do_build" -> "autoconf.do_package_write_deb"
etc...
So after search the dependency graph, we can see that lib_good is somehow pulling lib_bad into the build. The next step will be to look in that recipe for its DEPENDS or RDEPENDS variables, and compare them with what lib_bad has in its PROVIDES variable.

How to add a missing library (or executable or other file) to Yocto/bitbake

For an application I am running, there is a run time error as it cannot find libwayland-client.so.0 shared object. How do I know which package provides it and where do I add it. I tried as shown below but it gave me a Nothing PROVIDES error.
CORE_IMAGE_EXTRA_INSTALL += "libwayland-client"
You don't typically work with single files when building Yocto images
In reverse order
You install packages to the image
You build packages by using a recipe
You find (or as a last resort write) recipes as part of layers.
Generally when something is missing you take the following steps:
Check the layerindex https://layers.openembedded.org/layerindex/branch/master/recipes/?q=wayland It tells you that there is a recipe called wayland in layer openembedded-core
Add the layer in question. openembedded-core is already contained in Yocto's poky (directly under the name meta, just to confuse the newcomer...), so nothing to add in this example
Create the environment listing of the recipe in question, bitbake -e wayland >wayland.env
Check what packages the recipe in question creates grep ^PACKAGES= wayland.env. In this case it is easy because there is really only one package wayland (-debug, -dev etc. are special purpose that would not contain the library)
Add a package to the image by its package name. How to do that exactly depends on the image type you create. The variable name given in the question works for some images, but not all. Search for IMAGE_INSTALL in the manual https://www.yoctoproject.org/docs/2.6.1/mega-manual/mega-manual.html for other options.
Once you have built the recipe in question you can also check what files are contained in a package (In this case recipe name and package name are identical, but that is not always the case. Some recipes build more than one package suitable for installation, so obviously they need to use different names)
$ oe-pkgdata-util list-pkg-files wayland
wayland:
/usr/lib/libwayland-client.so.0
/usr/lib/libwayland-client.so.0.3.0
/usr/lib/libwayland-cursor.so.0
/usr/lib/libwayland-cursor.so.0.0.0
/usr/lib/libwayland-server.so.0
/usr/lib/libwayland-server.so.0.1.0

how to remove specific packages from the final rootfs image built by bitbake

I am trying to remove some open source packages that have GPLv3 licensing attached to them that we cannot distribute as part of the final production image . While these packages can be removed using "INCOMPATIBLE_LICENSE=GPLv3" in local.conf but it removes every package that's tagged GPLv3.
I have used
PREFERRED_VERSION_recipename=(GPLv2 recipe_version)
and downgraded all the GPLv3 packages to GPLv2 that we want to push into the final image. But there are several GPLv3 packages that we want to keep as part of the debug image for example M4, make, gdb, bison. There is no need for these packages to be in the final production image but these cannot be removed from the build completely as they are needed during the build/debug.
SO, How do i remove these packages/recipe from the final rootfs image while letting them being as part of the build process and letting them build. In other words I want to let the bitbake build them from the GPLv3 source but keep them out the of the final rootfs image.
I did look at the poky/lib/oe/manifest.py and rootfs.py create function ==> where the final rootfs manifest is being created but couldn't figure out what exactly needs to be set from the bitbake. Does the do_rootfs need to be overwritten. if so what variables need to be set for overriding the final manifest.
There's no single way of doing what you want. One way is to have your production image consists of what you need to deliver, and then let your dev-image require production-image.bb. In that way you can easily extend the dev image with your extra packages.
I've got a similar issue, as I want gdbserver in my dev-image. (Sofar, nothing else that's GPLv3 is necessary / wanted in my dev image). What I've done, is to set
INCOMPATIBLE_LICENSE = "GPL-3.0 LGPL-3.0 AGPL-3.0"
INCOMPATIBLE_LICENSE_pn-gdb = ""
That basically allows gdb to be built, but nothing else that's GPLv3 licensed. Then, my images inherit a company-image.bbclass instead of directly inheriting image.bbclass. In company-image.bbclass, I've got a function like:
python () {
for p in d.getVar('IMAGE_INSTALL', True).split():
if p in ['gdb', 'gdbserver'] and not d.getVar('IMAGE_BASENAME', True) == 'company-dev-image':
bb.fatal("gdb/gdbserver is not allowed in this image!")
}
That will ensure that gdb and gdbserver can only be installed in company-dev-image; thus, there's no risk of having them distributed in the production image.
I would like to provide an example that is , if we would like to remove the "openssh" package from build, needs to be updated "local.conf" file as mentioned below.
Please the add the following line into BUILDFOLDER/conf/local.conf file
PACKAGECONFIG_remove = "openssh"

need help in using bitbake INCOMPATIBLE_LICENSE flag

I am new to bitbake. and I have multiple questions all related to each other.
I am trying to remove all the packages that are GPLv3 from my package. i see that there are .bb files for both versions (gplv2 and gplv3 or other license types as applicable), of packages in meta/recipes-*/ folders. If I use INCOMPATIBLE_LICENSE=GPLv3 it removes all the packages that are GPLv3. But I want to include some packages that are GPLv3. where do i specify this.
I do see a BBFILES flag in the bblayers.conf in poky/build/conf dir. is this this place to add the specific recipes?
Another question i have is, If i want to use a specific .bb file out of the multiple .bb files in the recipes-/ folder how do i do that. for example
/recipes-extended/tar/tar_1.17.bb
/tar_1.27.1.bb
In this case, how do i pick tar_1.17.bb and ignore 1.27.bb. This is just one example. There is a "bitbake -b" command that takes .bb file as input but that will build only that .bb file and ignore dependencies according to the documentation. I want to build the complete package and be able to pick and ignore a specific .bb file.
So, how does bitbake pick and more pricisely which .bb file does bitbake pick when there are multiple .bb files in the recipe folder.
1 There's no way to do that. What would the purpose be? Normally, if you want to avoid GPLv3, you want a completely GPLv3 free image
There's one way to circumvent the system. You can set
INCOMPATIBLE_LICENSE_pn-<package/recipe name> = ""
That will allow you to build the package. However, don't use this for production, unless you really know what you're doing.
2/3: Normally the highest version will be built. You can use
PREFERRED_VERSION_<package name>
in local.conf or in your distro, to select another version. Another way is to add
DEFAULT_PREFERENCE = "-1"
to the recipe you don't want to build.
You should be able to set
WHITELIST_<spdx_license> += "<name of the package which you want to white list>"
Not very well documented but the code is in poky/meta/base.bbclass