In bitbake, are inheritances transferable between include files when they are added with require keyword? Or do we need to reuse inherit keyword over and over again in each of the include files? I'm using bitbake to built images with Yocto.
exampleA.inc file
inherit exampleC
exampleB.inc file
require exampleA.inc
In that case, if I want exampleB.inc to be inherited from exampleC as well, do I need to specify it in this file?
Assume that the exampleC is a bbclass file.
TLDR: one inherit statement is enough.
require and include just insert the content of the specified file at the current position in the recipe. This results in the same outcome, as if you had written the whole content of your .inc file into the recipe. Multiple layers of include / require should not change that. This means, that not the .inc file inherits from exanpleC, but rather the recipe, which requires said .inc file.
I also ran some quick tests to confirm the theory, and it all seems to work.
Do not be deterred by the BitBake documentation stating:
[...] you can use the inherit directive to inherit the functionality of a class (.bbclass). BitBake only supports this directive when used within recipe and class files (i.e. .bb and .bbclass).
This does not mean, that it does not work in .inc files, but rather that it will not work for configuration files.
Related
I'm trying to understand mapping of URIs to files. Let's take this URI:
modelica://foo.bar/file.png
Is it correct that there are two possible locations for file.png?
It could be either
$MODELICAPATH/foo/file.png if file $MODELICAPATH/foo/bar.mo exists.
Or
$MODELICAPATH/foo/bar/file.png if file $MODELICAPATH/foo/bar/package.mo exists.
Likely Section "13.2.3 External resources" of the Modelica Language Specification helps.
A little modification of your example should help to understand how it works. Using modelica://foo/bar/file.png refers to foo as top-level package/library. The library the path is resolved when it is loaded in the simulation environment. In case you store the library hierarchically (i.e. every package is represented as folder, each model is a file) bar would be a subfolder within the libraries root directory. file.png would be the file name within bar.
This is different if the package is stored as a single file, but as this has several disadvantages I would recommend to go with the hierarchical option.
No need to edit $ModelicaPath$ if the library is loaded.
Usually pictures etc. are put into a Resources folder within the library. This folder can contain additional folders like data, Images, Scripts...
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.
I opened an XCode project produced as a tutorial by Apple ("Auto Layout Cookbook"), when I found two files with a strange naming:
Recipe+Loading.swift
Recipe+Storyboards.swift
Both contain an extension called Recipe. I was not able to find any docs about this kind of naming.
Is there any reason why they named the files this way?
The naming comes from Objective-C where every extension for a class needed a name. For example, a class Recipe could have extension:
#interface Recipe (Loading)
#end
which contained methods related to "Loading".
Such extensions were commonly put into files named Recipe+Loading.h (that is, class Recipe extended with Loading methods).
In Swift extensions don't have a name but old habits die hard. They used the same naming for files.
This is a common naming convention from Objective-C. As you surmised it basically contains extensions to Recipe that pertain to loading and storyboards respectively. It's primarily a way to break up large source files or label extensions to system classes (String, Array, etc.)
I have a third-party Yocto layer which provides a recipe (let's call it recipe.bb) which references a local include file using require recipe.inc).
I have then created a custom layer and I would like to "replace" the included file recipe.inc with a custom version of it, provided by me. Is it possible? I've already tried to put my own recipe.inc in my folder and then using FILESEXTRAPATHS_prepend := "${THISDIR}:" in my recipe_%.bbappend but it does not work and the original recipe.inc is still included...
Is there a way for doing that?
No, it's not possible to override an .inc-file like that.
If you really need to do that, you could just as well copy recipe.bb into your own layer as well. Normally, the .inc file has all the logics, and the .bb-file only has the version specific stuff. Thus, replacing the .inc file would basically be equal to writing a new recipe.
What are you trying to do, that would require changing all the logics?
Are you sure that it's not enough to add a .bbappend file in your own layer, and override a smaller selection of tasks / variables from the .inc-file?
I have created a small Modelica library of my own. The way I have created it is in a single file. But I would like to make it a proper Modelica Library, as in the one with multiple directories for each subpackages.
So this is what i followed. File > New Modelica Class > Specialization - Package > Unchecked Save contents in one file. I copied the entire package code from the single file library, pasted it here and saved it. while doing so, I've noticed that the library lost most of its extends clauses, few models went missing.
Have I followed the correct procedure to create the library or did I do something wrong?
Can anyone point me towards the right direction?
#MSK, I cannot help you with OpenModelica as I work with Dymola. I did however recently split a single-file library (called package in Modelica) into several files manually. I did this so that the library hierarchy is represented in the file system hierarchy (i.e. several subfolders and .mo files in a library folder). For 35,000 lines of code this took roughly 10 hours. Just follow these steps:
create folder with same name as library
in this folder, create a text file "package.mo"
"package.mo" has to start with the statement
within ;
package [name of your package, i.e. the folder name...without the brackets];
now you want to create a subclass within this package. To do this create another folder containing a text file called "package.mo"
start this "package.mo" with
within [name of your package];
and declare the model as usual.
continue all the way down your library hierarchy
at the lowest hierarchy level you no longer need to create folders. You can simply create a .mo with the name of the lowest level class. As usual, start this file with
within [name of your package].[subclass1].[subclass2];
For an example of implementation please refer to the Physiolibrary found at https://www.modelica.org/libraries or the Modelica Standard Library which also uses this structure.