diff mbox series

[bitbake-devel,v2] doc: bitbake-user-manual: document inherit_defer

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

Commit Message

Antonin Godard Nov. 20, 2024, 9:30 a.m. UTC
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,

Comments

Quentin Schulz Nov. 25, 2024, 4:34 p.m. UTC | #1
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 mbox series

Patch

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