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

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.

Related

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

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.

Upgrading (overriding) an entire recipe in a custom layer

I have a custom layer in project. This gets shared with colleagues.
My distro (poky) it uses a older version of alsa. This gets downloaded on initial setup of the build area. I would like to 'replace' that version of alsa with a later version and do this within my custom layer, so that they don't have to edit/replace recipes in poky.
What's the best way to do this? If I just download the newer recipe and include it in my layer (matching the file system names) will it automatically use the later version or is there something else I need to do?
The way you proceeded is the right way, you should add new recipes/bbappend files on your own layer(s), you shouldn't modify Yocto's base layers nor third-party layers by default. Nevertheless, since you want to add a newer version of an existing recipe, you should keep in mind that:
You have to check the priority of your own layer and the priority of the layer that contains the original recipe. Yocto will pick the recipe of the higher priority layer, no matter if it is a newer version or not (ignoring PV). For further information, search for BBFILE_PRIORITY in the Yocto Project Reference Manual. (You can also see a list of all configured layers along with their priorities with the command bitbake-layers show-layers)
In the case of both layers having the same priority, Yocto will build the recipe with the highest PV (you can check/set this value inside your recipe or in its filename recipename_pv.bb). Alternatively, if you wish to select another version rather than the one that is being currently built, you can just set the variable PREFERRED_VERSION_recipename = desiredPV in your distro.conf or local.conf file.

Yocto - exclude files from -dev package

I have a great problem moving some header files from FILES_${PN}-dev to a custom dev-internal package.
In OpenEmbedded documentation there is explicitly stated that there is "no actual support for explicitly excluding files from packaging".
I tried this:
FILES_${PN}-dev = ""
PACKAGES += "${PN}-dev-internal"
FILES_${PN}-dev-internal = "${includedir}/<my-pattern>.h"
FILES_${PN}-dev = "<original-content>"
but it seems that the first defined package captures first anyway.
Is there any known workaround for this? Except of naming everything explicitly in both packages content which is highly, really undesirable.
but it seems that the first defined package captures first anyway.
Yes. So put PN-dev-internal before PN-dev in PACKAGES. This might work:
PACKAGES =+ "${PN}-dev-internal"
If not, PACKAGE_BEFORE_PN is useful.
You can probably change the component installation config to better separate the headers (e.g. place them in different directories).

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.

Adding additional libraries to MODELICAPATH in JModelica

In JModelica I want to create models using components from multiple existing libraries.
This means that it would be very useful to add the multiple libraries to the MODELICAPATH so components can be referenced without changing their existing paths. Something similar seems possible in Dymola.
In JModelica 1.13 it seems that this was once possible using:
c_opts =
{'extra_lib_dirs':['c:\MyLibs1','c:\MyLibs2']}
compile_fmu(class_path, compiler_options=c_opts)
I have read through the JModelica 2.1 document and there seems to be no mention of this argument. I have also tried running the script above and the compiler is not able to locate the path of the model contained within a library listed in the options.
Adding libraries to the Third Party MSL Folder inside the JModelica installation is not an option, as the multiple libraries I'll be working with are GitHub repos.
Is it possible to add these multiple libraries to the MODELICAPATH via startup script or IPython code?
The option "extra_lib_dirs" has been removed in favour of the simpler interface:
from pymodelica import compile_fmu
name = compile_fmu("MyModel", ["MyModelicaFile.mo", "C:\My\Modelica\Lib", ...])
The list after the model is specificed can take any number of Modelica files or directories to where Modelica libraries are located.
Yes, JModelica.org looks at the environment variable MODELICAPATH for additional locations of Modelica libraries (as per the Modelica language specification, section 13.2.4).
Either you modify the variable in batch before starting JModelica.org, or you modify the environment inside Python:
import os
os.environ['MODELICAPATH'] = "C:/somePath/;" + os.environ['JMODELICA_HOME'] + "/ThirdParty/MSL"
from pymodelica import compile_fmu
compile_fmu("SomeLibrary.SomeModel")
Note, if you're going to compile models from MSL or models using parts of MSL, then you have to add the MSL folder from the JModelica.org installation to the MODELICAPATH as well. The reason for this is that we are overriding the default MODELICAPATH and JModelica.org uses MODELICAPATH to find MSL.
I might add that it is more efficient to add the library folders to MODELICAPATH than listing them in the compile_fmu command. The reason for this is that if you list them to the compile_fmu command, then all the libraries will be parsed, while, if you add them (or rather the parent folder) to MODELICAPATH, then they are loaded as needed.