Direkt zum Hauptbereich

Using bbclass based on conditions

When you are working with YOCTO build system, you might be aware of the construct .bbclass.

For those who are not: these are code snippets which will be injected into the recipe itself. Mostly they add new tasks or provide some generalization for things you often. A good example might be pypi.bbclass. In your recipe you write usually something likes this

SRC_URI = "https://www.foo.org/foo.tar.gz"

When it comes to python packages a way more elegant way is to use pypi.org.
And here does the pypi.bbclass provide some magic - you recipe will just look like this

inherit pypi 
PYPI_PACKAGE = "foo"

the bbclass pypi will automatically translate the variable name PYPI_PACKAGE into a valid URL to fetch the package. Also it will set some internal variables such as HOMEPAGE or S to the correct settings. You see life can be convenient when you know how to do it.

If you want to apply a bbclass you can either insert

inherit foo.bbclass

into each recipe or you can put it into your conf/local.conf. E.g. like this

#   - 'buildstats' collect build statistics#   - 'image-mklibs' to reduce shared library files size for an image#   - 'image-prelink' in order to prelink the filesystem image# NOTE: if listing mklibs & prelink both, then make sure mklibs is before prelink# NOTE: mklibs also needs to be explicitly enabled for a given image, see local.conf.extendedUSER_CLASSES ?= "buildstats image-mklibs image-prelink"INHERIT += "rm_work"

Now imagine you're having a layer construction like this (cat conf/bblayers.conf)

# POKY_BBLAYERS_CONF_VERSION is increased each time build/conf/bblayers.conf# changes incompatiblyPOKY_BBLAYERS_CONF_VERSION = "2"
BBPATH = "${TOPDIR}"BBFILES ?= ""
BBLAYERS ?= " \  /media/disk/meta-sca \  /media/disk/meta-buildutils \  /media/disk/meta-clang \  /media/disk/poky/meta \  /media/disk/poky/meta-poky \  /media/disk/poky/meta-yocto-bsp \  /media/disk/poky/build/workspace \  "

which means hundreds of recipes, but most of these are written and maintained by somebody else.
So what can you do if you want a bbclass
  • applied only to your layer?
  • only applied to recipes of a certain license?
  • only applied if the recipe is depending on a certain packages?
When I got into this problem I started digging through the bitbake-code itself and found a nice little function called "inherit" to be found at

from bb.parse.parse_py import BBHandler

this combined with

python __anonymous() {
}

you can create magic. The function is executed on parsing the recipe by bitbake, so it would be obviously a good place to check if another class should be inherited here or not.

I wrote a small class here which simplifies this even further.

Now you can decide by global rules were to include some extra bbclass-magic.
E.g. (from conf/local.conf)

# NOTE: if listing mklibs & prelink both, then make sure mklibs is before prelink# NOTE: mklibs also needs to be explicitly enabled for a given image, see local.conf.extendedUSER_CLASSES ?= "buildstats image-mklibs image-prelink"INHERIT += "rm_work auto-inherit"AUTO_INHERIT_CONF = "BBClass=foo;props=[auto_inherit_is_at_path(d,'meta-foo/recipes-foo/',False)]"

do include a bbclass named "foo.bbclass" into every recipe which is located under "meta-foo/recipes-foo" relative to your project root.

Another example

# NOTE: if listing mklibs & prelink both, then make sure mklibs is before prelink# NOTE: mklibs also needs to be explicitly enabled for a given image, see local.conf.extendedUSER_CLASSES ?= "buildstats image-mklibs image-prelink"INHERIT += "rm_work auto-inherit"AUTO_INHERIT_CONF = "BBClass=bar;props=[auto_inherit_license(d,'GPL.*')]"

would inherit the bbclass "bar.bblass" into each recipe which is licensed under GPL.

Last example

# NOTE: if listing mklibs & prelink both, then make sure mklibs is before prelink# NOTE: mklibs also needs to be explicitly enabled for a given image, see local.conf.extendedUSER_CLASSES ?= "buildstats image-mklibs image-prelink"INHERIT += "rm_work auto-inherit"AUTO_INHERIT_CONF = "BBClass=bar;props=[auto_inherit_contains_package(d,'python3')]"

this would inherit bar.bbclass into each recipe which requires python3.

Also you can combine these rules to make even more complex scenarios.

So I hope this will help you using more of the power from bbclasses.

Kommentare

Beliebte Posts aus diesem Blog

Sharing is caring... about task hashes

The YOCTO-project can do amazing things, but requires a very decent build machine, as by nature when you build everything from scratch it does require a lot of compilation. So the ultimate goal has to be to perform only the necessary steps in each run. Understanding task hashing The thing is that bitbake uses a task hashing to determine, which tasks (such as compilation, packaging, a.s.o.) are actually required to be performed. As tasks depend on each other, this information is also embedded into a hash, so the last task for a recipe is ultimately depending on the variable that are used for this specific task and every task before. You could visualize this by using a utility called bitbake-dumpsig , which produces output like this basewhitelist: {'SOURCE_DATE_EPOCH', 'FILESEXTRAPATHS', 'PRSERV_HOST', 'THISDIR', 'TMPDIR', 'WORKDIR', 'EXTERNAL_TOOLCHAIN', 'FILE', 'BB_TASKHASH', 'USER', 'BBSERVER&

Making go not a no-go

Anyone that dealt with container engines came across go - a wonderful language, that was built to provide a right way of what C++ intended to do. The language itself is pretty straight forward and upstream poky support is given since ages... In the go world one would just run 1 2 go get github.com/foo/bar go build github.com/foo/bar and magically the go ecosystem would pull all the needed sources and build them into an executable. This is where the issues start... In the Openembedded world, one would have  one provider (aka recipe) for each dependency each recipe comes with a (remote) artifact (e.g. tarball, git repo, a.s.o.) which can be archived (so one can build the same software at a later point in time without any online connectivity) dedicated license information all this information is pretty useful when working is an environment (aka company) that has restrictions, such as reproducible builds license compliance security compliance (for instance no unpatched CVE) but when us

Speedup python on embedded systems

Have you ever considered to use python as a scripting language in an embedded system? I've been using this on recent projects although it wasn't my first choice. If I had to choose a scripting language to be used in embedded I always had a strong preference for shell/bash or lua, because they are either builtin or designed to have a significant lower footprint compared to others. Nevertheless the choice was python3 (was out of my hands to decide). When putting together the first builds using YOCTO I realized that there are two sides to python. the starting phase, where the app is initializing the execution phase, where the app just processes new data In the 2nd phase python3 has good tradeoffs between maintainability of code vs. execution speed, so there is nothing to moan about. Startup is the worst But the 1st phase where the python3-interpreter is starting is really bad. So I did some research where is might be coming from. Just to give a comparison of