Message ID | 20241120-inherit-defer-v2-1-e9291b7cf59b@bootlin.com |
---|---|
State | New |
Headers | show |
Series | [bitbake-devel,v2] doc: bitbake-user-manual: document inherit_defer | expand |
Hi Antonin, On 11/20/24 10:30 AM, Antonin Godard wrote: > This was added in 2.7.2. Since using inherit_defer is safer that inherit > when inheriting conditionally, move the instructions about that in > inherit_defer. > > Fixes [YOCTO #15640]. > > Reported-by: Yoann Congal <yoann.congal@smile.fr> > Signed-off-by: Antonin Godard <antonin.godard@bootlin.com> > --- > Changes in v2: > - Move the instructions on conditional inherits in the inherit_defer > section, since it is a safer call > - Link to v1: https://lore.kernel.org/r/20241118-inherit-defer-v1-1-26866a60ab1b@bootlin.com > --- > .../bitbake-user-manual-metadata.rst | 43 ++++++++++++++++++---- > 1 file changed, 36 insertions(+), 7 deletions(-) > > diff --git a/doc/bitbake-user-manual/bitbake-user-manual-metadata.rst b/doc/bitbake-user-manual/bitbake-user-manual-metadata.rst > index 58975f4c88ce549a2fd27136c0cb37b636bafcdb..40a0c6f02d9c35297dbb51da465efda83d832917 100644 > --- a/doc/bitbake-user-manual/bitbake-user-manual-metadata.rst > +++ b/doc/bitbake-user-manual/bitbake-user-manual-metadata.rst > @@ -771,6 +771,8 @@ In order for include and class files to be found by BitBake, they need > to be located in a "classes" subdirectory that can be found in > :term:`BBPATH`. > > +.. _ref-bitbake-user-manual-metadata-inherit: > + > ``inherit`` Directive > --------------------- > > @@ -809,19 +811,43 @@ An advantage with the inherit directive as compared to both the > :ref:`include <bitbake-user-manual/bitbake-user-manual-metadata:\`\`include\`\` directive>` and :ref:`require <bitbake-user-manual/bitbake-user-manual-metadata:\`\`require\`\` directive>` > directives is that you can inherit class files conditionally. You can > accomplish this by using a variable expression after the ``inherit`` > -statement. Here is an example:: > +statement. > + > +For inheriting classes conditionally, using the :ref:`inherit_defer > +<ref-bitbake-user-manual-metadata-inherit-defer>` directive is advised as > +:ref:`inherit_defer <ref-bitbake-user-manual-metadata-inherit-defer>` is > +evaluated at the end of parsing. > + > +.. _ref-bitbake-user-manual-metadata-inherit-defer: > + > +``inherit_defer`` Directive > +~~~~~~~~~~~~~~~~~~~~~~~~~~~ > + > +The :ref:`inherit_defer <ref-bitbake-user-manual-metadata-inherit-defer>` > +directive works like the :ref:`inherit > +<ref-bitbake-user-manual-metadata-inherit>` directive, except that it is only > +evaluated at the end of parsing. Its usage is recommended when a conditional > +expression is used. > > - inherit ${VARNAME} > +This allows conditional expressions to be evaluated "late", meaning changes to > +the variable after the line is parsed will take effect. With the :ref:`inherit > +<ref-bitbake-user-manual-metadata-inherit>` directive this is not the case. > + > +Here is an example:: > + > + inherit_defer ${VARNAME} > > If ``VARNAME`` is > -going to be set, it needs to be set before the ``inherit`` statement is > +going to be set, it needs to be set before the ``inherit_defer`` statement is > parsed. One way to achieve a conditional inherit in this case is to use > overrides:: I don't think this is correct. It is the case for the inherit statement but that's the raison-d'ĂȘtre of inherit_defer, so that this actually doesn't matter anymore? We could however provide an example of using inherit that doesn't work (redefine the variable after the inherit) and show it doesn't work. Then use inherit_defer and now it works even with the variable later overridden. We can provide a typical usecase for that, which is to be able to modify this through bbappend for example. I believe this was born out of people parsing PACKAGECONFIG to figure out which class to inherit (e.g. python) but this wasn't working with bbappend modifying PACKAGECONFIG, because it happened too late in the parsing. Otherwise, looking good to me! Cheers, Quentin
diff --git a/doc/bitbake-user-manual/bitbake-user-manual-metadata.rst b/doc/bitbake-user-manual/bitbake-user-manual-metadata.rst index 58975f4c88ce549a2fd27136c0cb37b636bafcdb..40a0c6f02d9c35297dbb51da465efda83d832917 100644 --- a/doc/bitbake-user-manual/bitbake-user-manual-metadata.rst +++ b/doc/bitbake-user-manual/bitbake-user-manual-metadata.rst @@ -771,6 +771,8 @@ In order for include and class files to be found by BitBake, they need to be located in a "classes" subdirectory that can be found in :term:`BBPATH`. +.. _ref-bitbake-user-manual-metadata-inherit: + ``inherit`` Directive --------------------- @@ -809,19 +811,43 @@ An advantage with the inherit directive as compared to both the :ref:`include <bitbake-user-manual/bitbake-user-manual-metadata:\`\`include\`\` directive>` and :ref:`require <bitbake-user-manual/bitbake-user-manual-metadata:\`\`require\`\` directive>` directives is that you can inherit class files conditionally. You can accomplish this by using a variable expression after the ``inherit`` -statement. Here is an example:: +statement. + +For inheriting classes conditionally, using the :ref:`inherit_defer +<ref-bitbake-user-manual-metadata-inherit-defer>` directive is advised as +:ref:`inherit_defer <ref-bitbake-user-manual-metadata-inherit-defer>` is +evaluated at the end of parsing. + +.. _ref-bitbake-user-manual-metadata-inherit-defer: + +``inherit_defer`` Directive +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The :ref:`inherit_defer <ref-bitbake-user-manual-metadata-inherit-defer>` +directive works like the :ref:`inherit +<ref-bitbake-user-manual-metadata-inherit>` directive, except that it is only +evaluated at the end of parsing. Its usage is recommended when a conditional +expression is used. - inherit ${VARNAME} +This allows conditional expressions to be evaluated "late", meaning changes to +the variable after the line is parsed will take effect. With the :ref:`inherit +<ref-bitbake-user-manual-metadata-inherit>` directive this is not the case. + +Here is an example:: + + inherit_defer ${VARNAME} If ``VARNAME`` is -going to be set, it needs to be set before the ``inherit`` statement is +going to be set, it needs to be set before the ``inherit_defer`` statement is parsed. One way to achieve a conditional inherit in this case is to use overrides:: VARIABLE = "" VARIABLE:someoverride = "myclass" -Another method is by using anonymous Python. Here is an example:: +Another method is by using :ref:`anonymous Python +<bitbake-user-manual/bitbake-user-manual-metadata:Anonymous Python Functions>`. +Here is an example:: python () { if condition == value: @@ -830,11 +856,14 @@ Another method is by using anonymous Python. Here is an example:: d.setVar('VARIABLE', '') } -Alternatively, you could use an in-line Python expression in the +Alternatively, you could use an inline Python expression in the following form:: - inherit ${@'classname' if condition else ''} - inherit ${@functionname(params)} + inherit_defer ${@'classname' if condition else ''} + +Or:: + + inherit_defer ${@bb.utils.contains('VARIABLE', 'something', 'classname', '', d)} In all cases, if the expression evaluates to an empty string, the statement does not trigger a syntax error because it
This was added in 2.7.2. Since using inherit_defer is safer that inherit when inheriting conditionally, move the instructions about that in inherit_defer. Fixes [YOCTO #15640]. Reported-by: Yoann Congal <yoann.congal@smile.fr> Signed-off-by: Antonin Godard <antonin.godard@bootlin.com> --- Changes in v2: - Move the instructions on conditional inherits in the inherit_defer section, since it is a safer call - Link to v1: https://lore.kernel.org/r/20241118-inherit-defer-v1-1-26866a60ab1b@bootlin.com --- .../bitbake-user-manual-metadata.rst | 43 ++++++++++++++++++---- 1 file changed, 36 insertions(+), 7 deletions(-) --- base-commit: e41c70372ee83320a224d04f46768dc21e6ddd3e change-id: 20241118-inherit-defer-48d3c8e0c087 Best regards,