Yocto - Why do runtime variables (RDEPENDS, RPROVIDES, etc), require package name overrides? - yocto

essentially I don't understand why variables like RDEPENDS require a package name conditional override such as "RDEPENDS_${PN}" while other variables, including DEPENDS, do not require this. Isn't putting the package name as a conditional after the variable pointless? I feel like my confusion may stem from some fundamental misunderstanding of the way bitbake works.

When a recipe is built, that single recipe can generate multiple packages. For example, debugging information is in ${PN}-dbg, docs in ${PN}-doc and development headers/files in ${PN}-dev. The "main" files for a recipe would go to ${PN} but many recipes split other pieces into other separate packages by adding entries to PACKAGES (which defaults to the above values).
Since there are multiple output "runtime" packages, runtime variables such as RDEPENDS have to be applied to a specific output package, hence the RDEPENDS:${PN} or for older releases RDEPENDS_${PN} variable name format, otherwise it would be unclear which package they applied to.

Related

How does the key "file" of the structure "provides" work with "META.*" for "CPAN::Meta::Spec"?

I'm trying to better understand what I could use CPAN::Meta::Spec for and came across the following sentence in the spec for the key file:
[...]to a file that contains or generates the package. It may be given as META.yml or META.json to claim a package for indexing without needing a *.pm.
This sentence reads to me like one was able to directly specify some META.* within the config using a path to a file instead of a *.pm. Hence using the wording it, that clearly associates to the formerly mentioned path. Pretty much like in the following example:
provides => {
'Foo::Bar' => {
file => 'lib/Foo/Bar.pm',
version => '0.27_02'
},
'Foo::Bar2' => {
file => 'lib/Foo/Bar2.yml', <-- META.yml?
},
'Foo::Bar3' => {
file => 'lib/Foo/Bar3.json', <-- META.json?
version => '0.3'
}
So, while Foo/Bar2.pm and Foo/Bar3.pm might exist in the distribution, they are not defined explicitly, but implicitly using the META.* files.
How does such a META.* look like, what does it contain? Only things like name and version, which is what a native Perl package might provide as well? Or additional things like license and keyword, maybe everything except dependencies?
How do CPAN-clients handle such cases? META.* obviously isn't the Perl package itself and I don't see how it's used to generate it. So what gets actually installed in a system in the end? Is there some additional mechanism generating the package somehow?
How is providing META.* instead of *.pm compatible with the key version and the following restriction:
[...]If the package does not have a $VERSION, this field must be omitted.
Does META.* count as a package containing $VERSION in this case? Or is it expected that somehow the package gets generated in the end and that simply must have $VERSION as well and as long as the package isn't generated, the version of META.* can simply be used?
Thanks for your clarification!
The provides metadata is a list of the packages provided by the distribution primarily for use by the PAUSE indexer, but also may be used by analysis tools. If it is present, PAUSE will not inspect your files for packages and their versions but will trust provides. For each package in the distribution it must list the file in which the package resides, and the version of the package if it has one. Since this is an "override", it is not required to match reality, but unless you're doing something very strange it should. The ability to set the file to META.yml or META.json is simply a fallback if you have a package which has no associated file; it is extremely uncommon that you will need to do this, and it places no additional requirement on the META.json or META.yml except they should exist. As always, in implementation this metadata is always set in META.json and META.yml included in the distribution.

Yocto: how to remove/blacklist some dependency from RDEPENDS of a package?

I have a custom machine layer based on https://github.com/jumpnow/meta-wandboard.
I've upgraded the kernel to 4.8.6 and want to add X11 to the image.
I'm modifying to image recipe (console-image.bb).
Since wandboard is based on i.MX6, I want to include the xf86-video-imxfb-vivante package from meta-fsl-arm.
However, it fails complaining about inability to build kernel-module-imx-gpu-viv. I believe that happens because xf86-video-imxfb-vivante DEPENDS on imx-gpu-viv which in turn RDEPENDS on kernel-module-imx-gpu-viv.
I realize that those dependencies have been created with meta-fsl-arm BSP and vanilla Poky distribution. But those things are way outdated for wandboard, hence I am using the custom machine layer with modern kernel.
The kernel is configured to include the Vivante DRM module and I really don't want the kernel-module-imx-gpu-viv package to be built.
Is there a way to exclude it from RDEPENDS? Can I somehow swear my health to the build system that I will take care of this specific run-time dependency myself?
I have tried blacklisting 'kernel-module-imx-gpu-viv' setting PNBLACKLIST[kernel-module-imx-gpu-viv] in my local.conf, but that's just a part of a solution. It helps avoid build failures, but the packaging process still fails.
IIUC you problem comes from these lines in img-gpu-viv recipe:
FILES_libgal-mx6 = "${libdir}/libGAL${SOLIBS} ${libdir}/libGAL_egl${SOLIBS}"
FILES_libgal-mx6-dev = "${libdir}/libGAL${SOLIBSDEV} ${includedir}/HAL"
RDEPENDS_libgal-mx6 += "kernel-module-imx-gpu-viv"
INSANE_SKIP_libgal-mx6 += "build-deps"
I would actually qualify this RDEPENDS as a bug, usually kernel module dependencies are specified as RRECOMMENDS because most modules can be compiled into the kernel thus making no separate package at all while still providing the functionality. But that's another issue.
There are several ways to fix this problem, the first general route is to tweak RDEPENDS for the package. It's just a bitbake variable, so you can either assign it some other value or remove some portion of it. In the first case it's going to look somewhat like this:
RDEPENDS_libgal-mx6 = ""
In the second one:
RDEPENDS_libgal-mx6_remove = "kernel-module-imx-gpu-viv"
Obviously, these two options have different implications for your present and future work. In general I would opt for the softer one which is the second, because it has less potential for breakage when you're to update meta-fsl-arm layer, which can change imx-gpu-viv recipe in any kind of way. But when you're overriding some more complex recipe with big lists in variables and you're modifying it heavily (not just removing a thing or two) it might be easier to maintain it with full hard assignment of variables.
Now there is also a question of where to do this variable mangling. The main option is .bbappend in your layer, that's what appends are made for, but you can also do this from your distro configuration (if you're maintaining your own distro it might be easier to have all these tweaks in one place, rather than sprayed into numerous appends) or from your local.conf (which is a nice place to quickly try it out, but probably not something to use in longer term). I usually use .bbappend.
But there is also a completely different approach to this problem, rather than fixing package dependencies you can also fix what some other package provides. If for example you have a kernel configured to have imx-gpu-viv module built right into the main zimage you can do
RPROVIDES_kernel-image += "kernel-module-imx-gpu-viv"
(also in .bbappend, distro configuration or local.conf) and that's it.
In any case your approach to fixing this problem should reflect the difference between your setup and recipe assumptions. If you do have the module, but in a different package, then go for RPROVIDES, if you have some other module providing the same functionality to libgal-mx6 package then fix libgal-mx6 dependencies (and it's better to fix them, meaning not only drop something you don't need, but also add things that are relevant for your setup).

Request for clarification on Yocto inheritance

I've recently made a foray into building Linux-based embedded systems, a far cry from my usual embedded stuff where I have total control over everything.
As part of that, I'm looking into the Yocto/bitbake/OpenEmbedded build system.
There's one thing I'm grappling with and that's the layering concept, so I'm trying to both figure out the way in which layers use/affect other layers.
From my understanding to date, a .bb recipe file uses require to simply include another file, similar to C's #include "myheader.h" which generally looks locally.
A .bbappend file in an "upper" layer will auto-magically include the base file then make changes to it, sort of an inherent require.
In contrast, the inherit keyword looks for a .bbclass class file in much the same way as it locates the .bb files, and inherits all the detials from them (sort of like #include <stdio.h> which, again generally, looks in the system area(a)).
So the first part of my question is: is my understanding correct? Or am I being too simplistic?
The second part of my question then involves the use of BBEXTENDS in the light of my current understanding. If we already have the ability to extend a recipe by using require, what is the purpose of listing said recipes in a BBEXTENDS variable?
(a) Yes, I'm aware they're both totally implementation dependent in terms of where the headers come from, I'm simply talking about their common use.
The learning curve for Yocto is different than other building systems, that's why I understand your confusion. But trust me, this is worth it. Your questions are related to BitBake so I recommend the BitBake User Manual. Just ensure that you're reading the same version as your poky revision.
require and include.
require is similar to include and can be compared to #include from C and C++ just like you have written.
Although generally both of them should be used to add some extensions to a recipe (*.bb) which are common to some amount of recipes (simply - can be reused).
For instance: definitions of paths, custom tasks used by couple recipes. The common purpose is to make recipe cleaner and separate some constants for re-usage.
The very important thing -> difference between include and require (from BitBake manual):
The include directive does not produce an error when the file cannot be found. Consequently, it is recommended that if the file you are including is expected to exist, you should use require instead of include. Doing so makes sure that an error is produced if the file cannot be found.
As a result: when you include a file to *.bb and it hasn't been found, the BitBake will not raise an error during parsing this recipe.
If you would use require, the error will be raised. You should use require when the pointed file must exist because it contains important variables/tasks that are mandatory to process.
*.bbappend mechanism.
In the case of *.bbappend - it's very powerful. The typical usage is whey you are adding some custom modifications to the recipe from other layer (located above layer where original recipe is) by *.bbappend because (e.g): you are not the maintainer of original recipe or the modifications are only used in your project (then it should be located in your meta-layer). But you can also bbappend the recipe on the same layer. BitBake parses all layers and then 'creates' an output and executes it. More in chapter Execution from BitBake man.
inherit.
The inherit mechanism can be used to inherit *.bbclass where common tasks for some specific purpose are defined so you don't need to write them on your own, e.g: you use inherit cmake or inherit autotools to your recipe when it needs to provide output for sources that are built correspondingly by CMake (and you have CMakeLists.txt defined) or autotools (Makefile.am etc.).
The definitions of classes provided by OpenEmbedded are located under /meta/classes/ if you are using Yocto release with poky.
You can check them and you will see that for example autotools.bbclass has defined (among others) task: autotools_do_configure() so you don't need to write it from the scratch.
However, you can redefine it in your recipe (by just providing your own definition of this function). If the recipe can't be changed, then you can simply create a *.bbappend file and write your own function do_configure() which will override the function from *.bbclass. Just like in OO languages such as C++ or Java.

How to specify package versions in a Bitbake recipe with multiple packages?

I have a single Bitbake recipe that creates several packages, declared by using the PACKAGES variable and specifying the contents of each package using FILE_package1, FILE_package2, etc.
I would like to specify a different version string for each package, but they all share the version string stored in ${PV}. How can I provide a different version for each package?
Although I could be wrong, I don't think it's possible to do what you want. The ${PV} variable is typically specified in the title of the recipe (e.g. busybox_1.22.1.bb) and Bitbake sets the ${PV} variable based on that.
In order to specify different versions for each package I think you're going to have to split the recipe into multiple recipes, each one with its own version.

Can gwt analyze dependency like maven does?

How can I get GWT to provide the same dependency insights as mvn dependency:analyze?
Maven can report about dependencies (Used undeclared dependencies and Unused declared dependencies). I'd like to get GWT to do the same because determining missing inherits in my gwt.xml proves difficult.
Is there a good way for the system to analyze dependency state?
Thanks
Peter
I'm not aware of any such tool, and while I think a utility to analyze and report on GWT dependencies could be interesting, I also think it would be difficult to define well.
Used, undeclared dependencies
Before trying to solve this, what is the problem? In maven, this category means that a Class is loaded from a dependency that isn't directly depended on, but instead is transitively loaded. This starts to get into the whole issue of transitive dependencies (which exist in GWT) and scopes (which don't). If A uses a class in C, but only depends on B, which depends on C, this will be listed in the 'used, undeclared dependencies' list.
In GWT however, we very rarely list every single dependency we use directly. Instead, we assume that transitive dependencies will stay transitive - we dont bother to inherit com.google.gwt.user.RemoteService for RPC as long as we already have com.google.gwt.user.User listed.
So how could we tell if we are using an undeclared dependency, the kind that warns when we do a gwt:compile? Perhaps such a tool could find every .gwt.xml file on the classpath, and read through its <source> and <super-source> rules to look for somewhere that a class we are using is declared? Or in the case of invoking GWT.create on something and getting back a non-concrete type, it could look for <replace-with> and <generate-with> rules. As long as your code already compiles in Java, the classes are on the classpath, but you still run the risk that while the class is there, the .java or .gwt.xml files might not be.
Unused, declared dependencies
This seems like an easier problem - analyze the modules we are inheriting, and look through them for any module that could be pruned out. Unfortunately, as the above discussion notes, we can't just look for the classes and which package they are in, which <source> and <super-source> elements are unused - we also would need to look for <replace-with> and <generate-with> rules - consider something like com.google.gwt.user.RemoteService, which only adds a rule and some configuration details, or even com.google.gwt.user.RemoteServiceObfuscateTypeNames, which modifies only a single setting of the RemoteService module. If RemoteServiceObfuscateTypeNames were removed, everything would still compile, but now there might be information about your RPC classes compiled into your app that you don't expect to be there.
With these in mind, perhaps such a tool could watch all possible rebind rules in the current build, and all configuration settings, properties, etc, and see if any of those rules were not using during a gwt:compile process. Then, indicate which modules had unused parts, and if any module (and all of its inherited modules) were unused, it could shown to the user as able to be removed.
One more important piece: order matters, when defining <inherits> statements. If I add a inherits for com.google.gwt.logging.Logging, then follow it with com.google.gwt.logging.LoggingDisabled, logging classes will be on the source path and will compile, but will have no effect. But if those are ordered the other way around, then they will not only be on the source path, but will all be functional. So any analysis of modules used and unused would need to also include transitive inherits statements, and their orders.