Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

bblayers order #36

Closed
HerrMuellerluedenscheid opened this issue Dec 4, 2020 · 13 comments
Closed

bblayers order #36

HerrMuellerluedenscheid opened this issue Dec 4, 2020 · 13 comments

Comments

@HerrMuellerluedenscheid
Copy link

Hey,
the order of layers in BBLAYERS in the generated build directory deviates from the order in my yml configuration.

After removing bblayers.conf (just to see that I'm not mistaken) I run kas build mconfig.yml. This is BBLAYERS:

BBLAYERS ?= " \
    /home/pyrocko/yocto/qs-kas/meta-mender/meta-mender-core \
    /home/pyrocko/yocto/qs-kas/meta-mender/meta-mender-raspberrypi \
    /home/pyrocko/yocto/qs-kas/meta-openembedded/meta-networking \
    /home/pyrocko/yocto/qs-kas/meta-openembedded/meta-oe \
    /home/pyrocko/yocto/qs-kas/meta-openembedded/meta-python \
    /home/pyrocko/yocto/qs-kas/meta-openembedded/meta-webserver \
    /home/pyrocko/yocto/qs-kas/meta-quakesaver/. \
    /home/pyrocko/yocto/qs-kas/meta-quakesaver/meta-qs-raspberrypi \
    /home/pyrocko/yocto/qs-kas/meta-scipy \
    /home/pyrocko/yocto/qs-kas/poky/meta \
    /home/pyrocko/yocto/qs-kas/poky/meta-poky \
    /home/pyrocko/yocto/qs-kas/poky/meta-yocto-bsp"
 

And this is the order of my yml file:

  meta-quakesaver:
    layers:
      .:
      meta-qs-raspberrypi:

  meta-scipy:

  meta-mender:
    layers:
      meta-mender-core:
      meta-mender-raspberrypi:
      meta-mender-core:

  meta-openembedded:
    layers:
      meta-oe:
      meta-python:
      meta-networking:
      meta-webserver:

  poky:
    layers:
       meta:
       meta-poky:
       meta-yocto-bsp:

As you can see it's not reversed but just different. The actual config includes another config.yml but that one doesn't define any layers or repos. Any idea why that happens?

@HerrMuellerluedenscheid
Copy link
Author

BTW: I removed url and refspec to make the example a little more lightweight.

@jan-kiszka
Copy link
Collaborator

kas processes repos in parallel, plus repos and layers can come different include files. This made generated config files undeterministic, see c9326cc. I'm open for a more user-controllable ordering algorithm, provided it's deterministic. But it's not a simple thing to solve I'm afraid.

Weren't layer prior invented for sorting out such ordering issues?

@HerrMuellerluedenscheid
Copy link
Author

I'm not entirely sure and probably lack deeper understanding of how things are put together under the hood. I always thought that layer order actually matters. Given that two layers have identical priorities wouldn't assignments with e.g. ?= result in different settings dependent on the ordering of layers?

I asked in the yocto irc if order matters and basically got two replies:

Hey there: just to confirm: the order of the layers defined in BBLAYERS matters, right?
mckoan: Yes
mckoan: 1st priority, 2nd order
qschulz: it's more complex than that, so if you have a precise question we can answer
qschulz: bbclass and conf files are not handled the same way as bb or bbappends

If order matters, c9326cc would be rather counterproductive.

@jan-kiszka
Copy link
Collaborator

jan-kiszka commented Dec 6, 2020

That commit was needed as we were otherwise producing even random orders. But things seem to have changed since then, including dict becoming ordered by default. I think we can try reverting this. Can you check how far this gets us?

diff --git a/kas/config.py b/kas/config.py
index 0119f68..9b827fb 100644
--- a/kas/config.py
+++ b/kas/config.py
@@ -24,6 +24,7 @@
 """
 
 import os
+from collections import OrderedDict
 from .repos import Repo
 from .includehandler import IncludeHandler, IncludeException
 
@@ -87,7 +88,7 @@ class Config:
         """
         repo_config_dict = self._config.get('repos', {})
         repo_defaults = self._config.get('defaults', {}).get('repos', {})
-        repo_dict = {}
+        repo_dict = OrderedDict()
         repo_fallback_path = os.path.dirname(self.filenames[0])
         for repo in repo_config_dict:
             repo_config_dict[repo] = repo_config_dict[repo] or {}
@@ -128,7 +129,7 @@ class Config:
             Returns the local.conf header
         """
         header = ''
-        for key, value in sorted(self._config.get(header_name, {}).items()):
+        for key, value in self._config.get(header_name, {}).items():
             header += '# {}\n{}\n'.format(key, value)
         return header
 
diff --git a/kas/libcmds.py b/kas/libcmds.py
index d65048d..750c973 100644
--- a/kas/libcmds.py
+++ b/kas/libcmds.py
@@ -245,8 +245,8 @@ class WriteBBConfig(Command):
                 fds.write(ctx.config.get_bblayers_conf_header())
                 fds.write('BBLAYERS ?= " \\\n    ')
                 fds.write(' \\\n    '.join(
-                    sorted(layer for repo in ctx.config.get_repos()
-                           for layer in repo.layers)))
+                    layer for repo in ctx.config.get_repos()
+                    for layer in repo.layers))
                 fds.write('"\n')
 
         def _write_local_conf(ctx):

We may still have an undesired order of things across includes, simply because ordering was so far not checked. If that's the case, I suppose we can sort that out before the next release if folks with such workload provide feedback (our layering does not rely on ordering, thus cannot help).

@jan-kiszka
Copy link
Collaborator

Ping @HerrMuellerluedenscheid

jan-kiszka added a commit that referenced this issue Dec 14, 2020
According to c9326cc, we had issues with producing a deterministic
order for those config elements. As sorting is a rather blunt method of
resolving it and as ordering plays a role in bitbake's processing of the
configs, we should try harder to provide more user control over that.

A key role in this play ordered dictionaries that report their content
the same order it was added. We already use OrderedDict for merging the
config dict across includes, see _internal_dict_merge. Includes are
merged recursively, depths-first, thus are expected to be deterministic
and predictable. We just need to convert building the repo_dict to
OrderedDict, and them sorted() can be removed.

Closes: #36

Reported-by: Marius Kriegerowski <marius.kriegerowski@gfz-potsdam.de>
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
@HerrMuellerluedenscheid
Copy link
Author

Hey, sorry for the late reply. I did a quick test and can confirm that that patch preserves the layer order!

@HerrMuellerluedenscheid
Copy link
Author

Let me know if I can help with anything else on that end.
Feel free to close the issue.

jan-kiszka added a commit that referenced this issue Dec 15, 2020
According to c9326cc, we had issues with producing a deterministic
order for those config elements. As sorting is a rather blunt method of
resolving it and as ordering plays a role in bitbake's processing of the
configs, we should try harder to provide more user control over that.

A key role in this play ordered dictionaries that report their content
the same order it was added. With Python 3.6 now the minimal supported
version, this is the default behavior. So it's safe to remove sorted().

Closes: #36

Reported-by: Marius Kriegerowski <marius.kriegerowski@gfz-potsdam.de>
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
@jan-kiszka
Copy link
Collaborator

Sorting by list order was discussed in https://groups.google.com/g/kas-devel/c/kbX_NAtQEMk, and we concluded to stick with ordering by name.

@paweljonskim
Copy link

paweljonskim commented Mar 19, 2021

@jan-kiszka
Hello,
unfortunately ordering layers by name makes kas unusable in our environment. We cannot really change that because of external yocto environment delivered from another company, but we still would like to use with kas. Is it closed matter or maybe we could find a way to maintain the yml layer order somehow?

@jan-kiszka
Copy link
Collaborator

Ordering is by layer key, as defined in the kas files. Is that external delivery providing you kas files as well? But even then: There is always a way to move a string before or after an existing set of stings.

@paweljonskim
Copy link

paweljonskim commented Mar 19, 2021

Can you please explain what do you mean by layer key?
No, the provided repo does not contain kas config file.
I will elaborate my case. Part of kas config yml file:

repos:
  repo_name:
    url: "git@github.com:org/repo_name.git"
    refspec: master
    layers:
      meta-c:
      meta-b:
      meta-a:

ends up creating bblayers.conf:

BBLAYERS ?= " \
    /home/pjonski/workspace/kasproject/repo_name/meta-a \
    /home/pjonski/workspace/kasproject/repo_name/meta-b \
    /home/pjonski/workspace/kasproject/repo_name/meta-c \

So repo names get sorted, which is not what I would expect. What do you mean by layer key?

@jan-kiszka
Copy link
Collaborator

Please read the email thread referenced in this issue, specifically https://groups.google.com/g/kas-devel/c/kbX_NAtQEMk/m/jYQzuz5VAgAJ.

@90degs2infty
Copy link

Sorry for resurrecting the dead. I've just stumbled upon a similar problem and wanted to add some thoughts on this.

From how I read this issue, kas relies on the layer ordering being specified by means of priorities (i.e. out of control of kas, as the layers themselves should set BBFILE_PRIORITY_... as needed). Consequently, the way kas orders the layers when writing BBLAYERS to conf/bblayers.conf should not matter. However, from how I understand Yocto's docs, the ordering in fact does matter:

Priority values control which layer takes precedence if there are recipe files with the same name in multiple layers.
For these cases, the recipe file from the layer with a higher priority number takes precedence.
Priority values also affect the order in which multiple .bbappend files for the same recipe are applied.

-- docs.yoctoproject.org

Note in the above, that the docs explicitly refer to recipes and append files.
Quoting the docs some more:

Also, the layer priority does not currently affect the precedence order of .conf or .bbclass files.
Future versions of BitBake might address this.

-- docs.yoctoproject.org

and

BitBake parses each conf/layer.conf file from the top down as specified in the BBLAYERS variable within the conf/bblayers.conf file.
During the processing of each conf/layer.conf file, BitBake adds the recipes, classes and configurations contained within the particular layer to the source directory.

-- docs.yoctoproject.org

So to my understanding, bitbake respects priorities only in some context, while in others it falls back to the order in BBLAYERS.

In my specific use case, it was enough to employ the workaround referenced above. But I feel like this only works if there is a one-to-one mapping between git-repositories and layers. As soon as one maintains several layers within the same git repository,1 there is no way for the user to fully control the layers' ordering in BBLAYERS, right? So as long as bitbake in parts relies on the ordering in BBLAYERS, it might be beneficial to provide a fully user-controlled way to order layers from within kas?

Footnotes

  1. as is the case e.g. for meta-openembedded

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants