public inbox for docs@lists.yoctoproject.org
 help / color / mirror / Atom feed
* Best practices documentation for multiconfigs
@ 2025-01-07 23:07 Mark Hatle
  2025-01-07 23:37 ` [docs] " Joshua Watt
  2025-01-08 15:31 ` Antonin Godard
  0 siblings, 2 replies; 9+ messages in thread
From: Mark Hatle @ 2025-01-07 23:07 UTC (permalink / raw)
  To: docs; +Cc: antonin.godard, Richard Purdie

I was talking to Richard on IRC and we think that we need to start collecting 
and documenting examples and/or best practices for multiconfig usage.  Below is 
my question attempt at starting this.  Hopefully we can expand this to something 
generally useful.  What follows is a bit rough, and will likely need editing...


A common use for multiconfig is to use the default configuration as the regular 
Linux build, while one or more multiconfigs can be used to build special 
components (often baremetal firmware.)  Enabling this workflow requires us to do 
three primary actions:

   1) Configure the multiconfig builds
   2) Use multiconfig dependencies to trigger builds of necessary components
   3) Pick up the output of the multiconfig build and bring it into a different 
config

In order to successfully do the above, the following could be considered to be 
best practices.

Configuration:

All of the (user) configuration starts with the local.conf file.  A default 
value of:

TMPDIR ?= "${TOPDIR}/tmp"

is used to control the location for temporary build items, where components are 
stored and built components are deployed.  For the deployed items the settings are:

DEPLOY_DIR ?= "${TMPDIR}/deploy"
DEPLOY_DIR_IMAGE ?= "${DEPLOY_DIR}/images/${MACHINE}"


Each multiconfig requires a separate multiconfig configuration file.

See: 
https://docs.yoctoproject.org/dev-manual/building.html#building-images-for-multiple-targets-using-multiple-configurations


At a minimum a different TMPDIR is required for each multiconfig.  As a best 
practice, instead of defining each TMPDIR separately, if they are defined as an 
append (.= operation) with an expected format, later steps can use this 
information to find the output of the build.  For example:

TMPDIR .= "-${BB_CURRENT_MC}"


This also has the side effect that if the user changes the default TMPDIR 
location in local.conf, all of the multiconfigs will follow with the same change 
automatically.


For example:

conf/multiconfig/baremetal-firmware.conf:

TMPDIR .= "-${BB_CURRENT_MC}"
TCLIBC = "newlib"


and a custom recipe called 'my-firmware.bb' that uses newlib to build baremetal 
firmware for the device.  my-firmware.bb should define a do_deploy function that 
deploys the baremetal firmware to ${DEPLOYDIR} with a specific name, such as 
"my-firmware.elf".


Building:

Using an 'mcdepend' a recipe in one multiconfig can trigger the build in another 
multiconfig, such as:


my-special-firmware.bb:

do_compile[mcdepends] = "mc::baremetal-firmware:my-firmware:do_deploy"


The above will ensure when do_compile is triggered, it further triggers the 
multiconfig build which will deploy the built firmware.



Using the output of the build:

However, just because we've built the item using mcdepends, we need to use the 
output in some way.   We can make a series of assumptions, based on the default 
Yocto Project variables in order to get the binary for packaging.

Adding a do_install task to the example above:

my-special-firmware.bb:

do_install() {
    install -Dm 0644 ${TMPDIR}-baremetal-firmware/deploy/my-firmware.elf 
${D}/lib/firmware/my-firmware.elf
}


Doing the above will allow the firmware binary to be transfered and packaged 
into the Linux context and rootfs.  However, this only works if we are careful 
to not affect TMPDIR outside of specific places, and we use the default 
DEPLOY_DIR (or other) deployment variables.


Suggested best practices:

TMPDIR (other then the default set in bitbake.conf) is only set in local.conf by 
the user.  This means that we should NOT manipulate TMPDIR in any way within the 
machine or distro .conf files.

A multiconfig must specify a TMPDIR, and should specify it by appending the 
multiconfig name via "-${BB_CURRENT_MC}".

All recipes should following the best practices for do_install and do_deploy.

Recipes that are used to transfer the output from a multiconfig target should 
use task[mcdepends] to trigger the build of the component, and then transfer the 
item to the current configuration in do_install or do_deploy, assuming the value 
of the deployed item based on the TMPDIR.

Suggested that the dependency and path are specific in a variable to make it 
easier to adjust as assumptions change, or the user has specific environment needs.


(we should have some proper examples for this.... i.e.)

conf/multiconfig/baremetal-firmware.conf:

TMPDIR .= "-${BB_CURRENT_MC}"
TCLIBC = "newlib"

recipes-firmware/firmware/my-firmware.bb:

do_compile() {
    echo "testing" > ${B}/my-firmware.bin

do_install() {
    install -mD 0644 ${B}/my-firmware.bin ${D}/lib/firmware/my-firmware.bin
}

do_deploy() {
    install -mD 0644 ${B}/my-firmware.bin ${DEPLOYDIR}/my-firmware.bin
}

recipes-firmware/firmware/my-special-firmware.bb:

INHIBIT_DEFAULT_DEPS = "1"

FIRMWARE_DEPENDS   ??= ""
FIRMWARE_MCDEPENDS ??= "mc::baremetal-firmware:my-firmware:do_deploy"
FIRMWARE_FILE      ??= "${TMPDIR}-baremetal-firmware/deploy/my-firmware.elf"
FIRMWARE_FILE[vardepsexclude] += "TMPDIR"

do_install() {
     if [ ! -e ${FIRMWARE_FILE} ]; then
         echo "Unable to find FIRMWARE_FILE (${FIRMWARE_FILE})"
         exit 1
     fi

     install -Dm 0644 ${FIRMWARE_FILE} ${D}/lib/firmware/${FIRMWARE_FILE}
}

do_deploy() {
     if [ ! -e ${FIRMWARE_FILE} ]; then
         echo "Unable to find FIRMWARE_FILE (${FIRMWARE_FILE})"
         exit 1
     fi

     install -Dm 0644 ${FIRMWARE_FILE} ${DEPLOYDIR}/${FIRMWARE_FILE}
}


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [docs] Best practices documentation for multiconfigs
  2025-01-07 23:07 Best practices documentation for multiconfigs Mark Hatle
@ 2025-01-07 23:37 ` Joshua Watt
  2025-01-08 15:34   ` Mark Hatle
  2025-01-08 15:31 ` Antonin Godard
  1 sibling, 1 reply; 9+ messages in thread
From: Joshua Watt @ 2025-01-07 23:37 UTC (permalink / raw)
  To: mark.hatle; +Cc: docs, antonin.godard, Richard Purdie

This seems good to me and is inline with how we use multiconfig

FWIW, we also use "inter-multiconfig" dependencies also (where one
multiconfig pulls in deployed files from another), but I don't think
anything in the proposal prevents that from working.

On Tue, Jan 7, 2025 at 4:09 PM Mark Hatle via lists.yoctoproject.org
<mark.hatle=kernel.crashing.org@lists.yoctoproject.org> wrote:
>
> I was talking to Richard on IRC and we think that we need to start collecting
> and documenting examples and/or best practices for multiconfig usage.  Below is
> my question attempt at starting this.  Hopefully we can expand this to something
> generally useful.  What follows is a bit rough, and will likely need editing...
>
>
> A common use for multiconfig is to use the default configuration as the regular
> Linux build, while one or more multiconfigs can be used to build special
> components (often baremetal firmware.)  Enabling this workflow requires us to do
> three primary actions:
>
>    1) Configure the multiconfig builds
>    2) Use multiconfig dependencies to trigger builds of necessary components
>    3) Pick up the output of the multiconfig build and bring it into a different
> config
>
> In order to successfully do the above, the following could be considered to be
> best practices.
>
> Configuration:
>
> All of the (user) configuration starts with the local.conf file.  A default
> value of:
>
> TMPDIR ?= "${TOPDIR}/tmp"
>
> is used to control the location for temporary build items, where components are
> stored and built components are deployed.  For the deployed items the settings are:
>
> DEPLOY_DIR ?= "${TMPDIR}/deploy"
> DEPLOY_DIR_IMAGE ?= "${DEPLOY_DIR}/images/${MACHINE}"
>
>
> Each multiconfig requires a separate multiconfig configuration file.
>
> See:
> https://docs.yoctoproject.org/dev-manual/building.html#building-images-for-multiple-targets-using-multiple-configurations
>
>
> At a minimum a different TMPDIR is required for each multiconfig.  As a best
> practice, instead of defining each TMPDIR separately, if they are defined as an
> append (.= operation) with an expected format, later steps can use this
> information to find the output of the build.  For example:
>
> TMPDIR .= "-${BB_CURRENT_MC}"
>
>
> This also has the side effect that if the user changes the default TMPDIR
> location in local.conf, all of the multiconfigs will follow with the same change
> automatically.
>
>
> For example:
>
> conf/multiconfig/baremetal-firmware.conf:
>
> TMPDIR .= "-${BB_CURRENT_MC}"
> TCLIBC = "newlib"
>
>
> and a custom recipe called 'my-firmware.bb' that uses newlib to build baremetal
> firmware for the device.  my-firmware.bb should define a do_deploy function that
> deploys the baremetal firmware to ${DEPLOYDIR} with a specific name, such as
> "my-firmware.elf".
>
>
> Building:
>
> Using an 'mcdepend' a recipe in one multiconfig can trigger the build in another
> multiconfig, such as:
>
>
> my-special-firmware.bb:
>
> do_compile[mcdepends] = "mc::baremetal-firmware:my-firmware:do_deploy"
>
>
> The above will ensure when do_compile is triggered, it further triggers the
> multiconfig build which will deploy the built firmware.
>
>
>
> Using the output of the build:
>
> However, just because we've built the item using mcdepends, we need to use the
> output in some way.   We can make a series of assumptions, based on the default
> Yocto Project variables in order to get the binary for packaging.
>
> Adding a do_install task to the example above:
>
> my-special-firmware.bb:
>
> do_install() {
>     install -Dm 0644 ${TMPDIR}-baremetal-firmware/deploy/my-firmware.elf
> ${D}/lib/firmware/my-firmware.elf
> }
>
>
> Doing the above will allow the firmware binary to be transfered and packaged
> into the Linux context and rootfs.  However, this only works if we are careful
> to not affect TMPDIR outside of specific places, and we use the default
> DEPLOY_DIR (or other) deployment variables.
>
>
> Suggested best practices:
>
> TMPDIR (other then the default set in bitbake.conf) is only set in local.conf by
> the user.  This means that we should NOT manipulate TMPDIR in any way within the
> machine or distro .conf files.
>
> A multiconfig must specify a TMPDIR, and should specify it by appending the
> multiconfig name via "-${BB_CURRENT_MC}".
>
> All recipes should following the best practices for do_install and do_deploy.
>
> Recipes that are used to transfer the output from a multiconfig target should
> use task[mcdepends] to trigger the build of the component, and then transfer the
> item to the current configuration in do_install or do_deploy, assuming the value
> of the deployed item based on the TMPDIR.
>
> Suggested that the dependency and path are specific in a variable to make it
> easier to adjust as assumptions change, or the user has specific environment needs.
>
>
> (we should have some proper examples for this.... i.e.)
>
> conf/multiconfig/baremetal-firmware.conf:
>
> TMPDIR .= "-${BB_CURRENT_MC}"
> TCLIBC = "newlib"
>
> recipes-firmware/firmware/my-firmware.bb:
>
> do_compile() {
>     echo "testing" > ${B}/my-firmware.bin
>
> do_install() {
>     install -mD 0644 ${B}/my-firmware.bin ${D}/lib/firmware/my-firmware.bin
> }
>
> do_deploy() {
>     install -mD 0644 ${B}/my-firmware.bin ${DEPLOYDIR}/my-firmware.bin
> }
>
> recipes-firmware/firmware/my-special-firmware.bb:
>
> INHIBIT_DEFAULT_DEPS = "1"
>
> FIRMWARE_DEPENDS   ??= ""
> FIRMWARE_MCDEPENDS ??= "mc::baremetal-firmware:my-firmware:do_deploy"
> FIRMWARE_FILE      ??= "${TMPDIR}-baremetal-firmware/deploy/my-firmware.elf"
> FIRMWARE_FILE[vardepsexclude] += "TMPDIR"
>
> do_install() {
>      if [ ! -e ${FIRMWARE_FILE} ]; then
>          echo "Unable to find FIRMWARE_FILE (${FIRMWARE_FILE})"
>          exit 1
>      fi
>
>      install -Dm 0644 ${FIRMWARE_FILE} ${D}/lib/firmware/${FIRMWARE_FILE}
> }
>
> do_deploy() {
>      if [ ! -e ${FIRMWARE_FILE} ]; then
>          echo "Unable to find FIRMWARE_FILE (${FIRMWARE_FILE})"
>          exit 1
>      fi
>
>      install -Dm 0644 ${FIRMWARE_FILE} ${DEPLOYDIR}/${FIRMWARE_FILE}
> }
>
> -=-=-=-=-=-=-=-=-=-=-=-
> Links: You receive all messages sent to this group.
> View/Reply Online (#6062): https://lists.yoctoproject.org/g/docs/message/6062
> Mute This Topic: https://lists.yoctoproject.org/mt/110487932/3616693
> Group Owner: docs+owner@lists.yoctoproject.org
> Unsubscribe: https://lists.yoctoproject.org/g/docs/unsub [JPEWhacker@gmail.com]
> -=-=-=-=-=-=-=-=-=-=-=-
>


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: Best practices documentation for multiconfigs
  2025-01-07 23:07 Best practices documentation for multiconfigs Mark Hatle
  2025-01-07 23:37 ` [docs] " Joshua Watt
@ 2025-01-08 15:31 ` Antonin Godard
  2025-01-08 15:38   ` Mark Hatle
  2025-01-14  9:52   ` [docs] " Quentin Schulz
  1 sibling, 2 replies; 9+ messages in thread
From: Antonin Godard @ 2025-01-08 15:31 UTC (permalink / raw)
  To: Mark Hatle, docs; +Cc: Richard Purdie

Hi Mark,

Thanks for this. I can help with formatting as well as where to put this bit of
documentation.

I already created a bug for this, you can add yourself to CC if you want to
track it: https://bugzilla.yoctoproject.org/show_bug.cgi?id=15709.

First thought: compared to what we currently have [1], your doc seems to bring
better details on multiconfigs. I'm thinking we could merge both to have a
complete document on multiconfigs (and also make it its own document instead of
a "Building" subsection).

Other comments below.

[1]: https://docs.yoctoproject.org/dev-manual/building.html#building-images-for-multiple-targets-using-multiple-configurations

On Wed Jan 8, 2025 at 12:07 AM CET, Mark Hatle wrote:
> I was talking to Richard on IRC and we think that we need to start collecting 
> and documenting examples and/or best practices for multiconfig usage.  Below is 
> my question attempt at starting this.  Hopefully we can expand this to something 
> generally useful.  What follows is a bit rough, and will likely need editing...
>
>
> A common use for multiconfig is to use the default configuration as the regular 
> Linux build, while one or more multiconfigs can be used to build special 
> components (often baremetal firmware.)  Enabling this workflow requires us to do 
> three primary actions:
>
>    1) Configure the multiconfig builds
>    2) Use multiconfig dependencies to trigger builds of necessary components
>    3) Pick up the output of the multiconfig build and bring it into a different 
> config
>
> In order to successfully do the above, the following could be considered to be 
> best practices.
>
> Configuration:
>
> All of the (user) configuration starts with the local.conf file.  A default 
> value of:
>
> TMPDIR ?= "${TOPDIR}/tmp"
>
> is used to control the location for temporary build items, where components are 
> stored and built components are deployed.  For the deployed items the settings are:
>
> DEPLOY_DIR ?= "${TMPDIR}/deploy"
> DEPLOY_DIR_IMAGE ?= "${DEPLOY_DIR}/images/${MACHINE}"
>
>
> Each multiconfig requires a separate multiconfig configuration file.
>
> See: 
> https://docs.yoctoproject.org/dev-manual/building.html#building-images-for-multiple-targets-using-multiple-configurations
>
>
> At a minimum a different TMPDIR is required for each multiconfig.  As a best 
> practice, instead of defining each TMPDIR separately, if they are defined as an 
> append (.= operation) with an expected format, later steps can use this 
> information to find the output of the build.  For example:
>
> TMPDIR .= "-${BB_CURRENT_MC}"
>
>
> This also has the side effect that if the user changes the default TMPDIR 
> location in local.conf, all of the multiconfigs will follow with the same change 
> automatically.
>
>
> For example:
>
> conf/multiconfig/baremetal-firmware.conf:
>
> TMPDIR .= "-${BB_CURRENT_MC}"

I assumed the `:append` override to be better practice in configuration files.

> TCLIBC = "newlib"
>
>
> and a custom recipe called 'my-firmware.bb' that uses newlib to build baremetal 
> firmware for the device.  my-firmware.bb should define a do_deploy function that 
> deploys the baremetal firmware to ${DEPLOYDIR} with a specific name, such as 
> "my-firmware.elf".
>
>
> Building:
>
> Using an 'mcdepend' a recipe in one multiconfig can trigger the build in another 
> multiconfig, such as:
>
>
> my-special-firmware.bb:
>
> do_compile[mcdepends] = "mc::baremetal-firmware:my-firmware:do_deploy"
>
>
> The above will ensure when do_compile is triggered, it further triggers the 
> multiconfig build which will deploy the built firmware.

Yes and actually this is lacking in the current documentation: this is the
way to add a dependency on a multiconfig from the default ("" empty string)
config, which is a common use-case of multiconfigs I believe.

>
>
>
> Using the output of the build:
>
> However, just because we've built the item using mcdepends, we need to use the 
> output in some way.   We can make a series of assumptions, based on the default 
> Yocto Project variables in order to get the binary for packaging.
>
> Adding a do_install task to the example above:
>
> my-special-firmware.bb:
>
> do_install() {
>     install -Dm 0644 ${TMPDIR}-baremetal-firmware/deploy/my-firmware.elf 
> ${D}/lib/firmware/my-firmware.elf
> }

In my-firmware.bb, is deploying to DEPLOYDIR (defined as "${WORKDIR}/deploy-my-firmware"
for the recipe) enough for my-special-firmware to pick up the firmware in
baremetal-firmware's DEPLOY_DIR ("${TMPDIR}-baremetal-firmware/deploy") here?
Shouldn't it pick it up in baremetal-firmware's DEPLOY_DIR_IMAGE instead?

>
>
> Doing the above will allow the firmware binary to be transfered and packaged 
> into the Linux context and rootfs.  However, this only works if we are careful 
> to not affect TMPDIR outside of specific places, and we use the default 
> DEPLOY_DIR (or other) deployment variables.
>
>
> Suggested best practices:
>
> TMPDIR (other then the default set in bitbake.conf) is only set in local.conf by 
> the user.  This means that we should NOT manipulate TMPDIR in any way within the 
> machine or distro .conf files.
>
> A multiconfig must specify a TMPDIR, and should specify it by appending the 
> multiconfig name via "-${BB_CURRENT_MC}".
>
> All recipes should following the best practices for do_install and do_deploy.
>
> Recipes that are used to transfer the output from a multiconfig target should 
> use task[mcdepends] to trigger the build of the component, and then transfer the 
> item to the current configuration in do_install or do_deploy, assuming the value 
> of the deployed item based on the TMPDIR.
>
> Suggested that the dependency and path are specific in a variable to make it 
> easier to adjust as assumptions change, or the user has specific environment needs.

Not sure I got this sentence, could you explain what you meant here?

>
> (we should have some proper examples for this.... i.e.)
>
> conf/multiconfig/baremetal-firmware.conf:
>
> TMPDIR .= "-${BB_CURRENT_MC}"
> TCLIBC = "newlib"
>
> recipes-firmware/firmware/my-firmware.bb:
>
> do_compile() {
>     echo "testing" > ${B}/my-firmware.bin
>
> do_install() {
>     install -mD 0644 ${B}/my-firmware.bin ${D}/lib/firmware/my-firmware.bin
> }
>
> do_deploy() {
>     install -mD 0644 ${B}/my-firmware.bin ${DEPLOYDIR}/my-firmware.bin
> }
>
> recipes-firmware/firmware/my-special-firmware.bb:
>
> INHIBIT_DEFAULT_DEPS = "1"
>
> FIRMWARE_DEPENDS   ??= ""
> FIRMWARE_MCDEPENDS ??= "mc::baremetal-firmware:my-firmware:do_deploy"
> FIRMWARE_FILE      ??= "${TMPDIR}-baremetal-firmware/deploy/my-firmware.elf"
> FIRMWARE_FILE[vardepsexclude] += "TMPDIR"
>
> do_install() {
>      if [ ! -e ${FIRMWARE_FILE} ]; then
>          echo "Unable to find FIRMWARE_FILE (${FIRMWARE_FILE})"

Suggestion: "bberror" for visibility?

>          exit 1
>      fi
>
>      install -Dm 0644 ${FIRMWARE_FILE} ${D}/lib/firmware/${FIRMWARE_FILE}
> }
>
> do_deploy() {
>      if [ ! -e ${FIRMWARE_FILE} ]; then
>          echo "Unable to find FIRMWARE_FILE (${FIRMWARE_FILE})"
>          exit 1
>      fi
>
>      install -Dm 0644 ${FIRMWARE_FILE} ${DEPLOYDIR}/${FIRMWARE_FILE}
> }


Antonin

-- 
Antonin Godard, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [docs] Best practices documentation for multiconfigs
  2025-01-07 23:37 ` [docs] " Joshua Watt
@ 2025-01-08 15:34   ` Mark Hatle
  2025-01-09  8:14     ` Christian Eggers
  0 siblings, 1 reply; 9+ messages in thread
From: Mark Hatle @ 2025-01-08 15:34 UTC (permalink / raw)
  To: docs



On 1/7/25 5:37 PM, Joshua Watt via lists.yoctoproject.org wrote:
> This seems good to me and is inline with how we use multiconfig
> 
> FWIW, we also use "inter-multiconfig" dependencies also (where one
> multiconfig pulls in deployed files from another), but I don't think
> anything in the proposal prevents that from working.

I think the key with this, we need to document a _good_ way to use files from 
one multiconfig build in another.  That was really the problem I was trying to 
lay out below, the key being that if TMPDIR is not stable (i.e. not modified by 
machine.conf or distro.conf) it becomes nearly impossible to automate this for a 
general/shared layer type case.

So explaining to people how to configure this, how to deploy the files, and then 
how to use them is really vital for people to be able to use multiconfigs.

As an aside, I've also moved to putting the BBMULTICONFIG into my machine.conf 
files, because ultimately to build the machine I need the multiconfig to build 
my firmware.  So we end up with something like:

(using the example below)

my-machine.conf:

BBMULTICONFIG += "baremetal-firmware"

FIRMWARE_DEPENDS   = ""
FIRMWARE_MCDEPENDS = "mc::baremetal-firmware:my-firmware:do_deploy"
FIRMWARE_FILE      = "${TMPDIR}-baremetal-firmware/deploy/my-firmware.elf"

...

(this points out a bug in the example below, I've added it inline)

This way the user can just do MACHINE=my-machine bitbake core-image-minimal and 
they get all of the multiconfig, and other settings automatically.

I'm not sure we want to suggest this behavior generically, but it might be a 
reasonable follow on to this.


(Note I specify both DEPENDS on MCDEPENDS in these examples because there are 
cases where the user might want to provide the binary itself via a recipe in the 
current context, and this allows a common packaging recipe to handle this 
behavior.  Maybe that should be removed from the example as I don't really 
explain it.)


> On Tue, Jan 7, 2025 at 4:09 PM Mark Hatle via lists.yoctoproject.org
> <mark.hatle=kernel.crashing.org@lists.yoctoproject.org> wrote:
>>
>> I was talking to Richard on IRC and we think that we need to start collecting
>> and documenting examples and/or best practices for multiconfig usage.  Below is
>> my question attempt at starting this.  Hopefully we can expand this to something
>> generally useful.  What follows is a bit rough, and will likely need editing...
>>
>>
>> A common use for multiconfig is to use the default configuration as the regular
>> Linux build, while one or more multiconfigs can be used to build special
>> components (often baremetal firmware.)  Enabling this workflow requires us to do
>> three primary actions:
>>
>>     1) Configure the multiconfig builds
>>     2) Use multiconfig dependencies to trigger builds of necessary components
>>     3) Pick up the output of the multiconfig build and bring it into a different
>> config
>>
>> In order to successfully do the above, the following could be considered to be
>> best practices.
>>
>> Configuration:
>>
>> All of the (user) configuration starts with the local.conf file.  A default
>> value of:
>>
>> TMPDIR ?= "${TOPDIR}/tmp"
>>
>> is used to control the location for temporary build items, where components are
>> stored and built components are deployed.  For the deployed items the settings are:
>>
>> DEPLOY_DIR ?= "${TMPDIR}/deploy"
>> DEPLOY_DIR_IMAGE ?= "${DEPLOY_DIR}/images/${MACHINE}"
>>
>>
>> Each multiconfig requires a separate multiconfig configuration file.
>>
>> See:
>> https://docs.yoctoproject.org/dev-manual/building.html#building-images-for-multiple-targets-using-multiple-configurations
>>
>>
>> At a minimum a different TMPDIR is required for each multiconfig.  As a best
>> practice, instead of defining each TMPDIR separately, if they are defined as an
>> append (.= operation) with an expected format, later steps can use this
>> information to find the output of the build.  For example:
>>
>> TMPDIR .= "-${BB_CURRENT_MC}"
>>
>>
>> This also has the side effect that if the user changes the default TMPDIR
>> location in local.conf, all of the multiconfigs will follow with the same change
>> automatically.
>>
>>
>> For example:
>>
>> conf/multiconfig/baremetal-firmware.conf:
>>
>> TMPDIR .= "-${BB_CURRENT_MC}"
>> TCLIBC = "newlib"
>>
>>
>> and a custom recipe called 'my-firmware.bb' that uses newlib to build baremetal
>> firmware for the device.  my-firmware.bb should define a do_deploy function that
>> deploys the baremetal firmware to ${DEPLOYDIR} with a specific name, such as
>> "my-firmware.elf".
>>
>>
>> Building:
>>
>> Using an 'mcdepend' a recipe in one multiconfig can trigger the build in another
>> multiconfig, such as:
>>
>>
>> my-special-firmware.bb:
>>
>> do_compile[mcdepends] = "mc::baremetal-firmware:my-firmware:do_deploy"
>>
>>
>> The above will ensure when do_compile is triggered, it further triggers the
>> multiconfig build which will deploy the built firmware.
>>
>>
>>
>> Using the output of the build:
>>
>> However, just because we've built the item using mcdepends, we need to use the
>> output in some way.   We can make a series of assumptions, based on the default
>> Yocto Project variables in order to get the binary for packaging.
>>
>> Adding a do_install task to the example above:
>>
>> my-special-firmware.bb:
>>
>> do_install() {
>>      install -Dm 0644 ${TMPDIR}-baremetal-firmware/deploy/my-firmware.elf
>> ${D}/lib/firmware/my-firmware.elf
>> }
>>
>>
>> Doing the above will allow the firmware binary to be transfered and packaged
>> into the Linux context and rootfs.  However, this only works if we are careful
>> to not affect TMPDIR outside of specific places, and we use the default
>> DEPLOY_DIR (or other) deployment variables.
>>
>>
>> Suggested best practices:
>>
>> TMPDIR (other then the default set in bitbake.conf) is only set in local.conf by
>> the user.  This means that we should NOT manipulate TMPDIR in any way within the
>> machine or distro .conf files.
>>
>> A multiconfig must specify a TMPDIR, and should specify it by appending the
>> multiconfig name via "-${BB_CURRENT_MC}".
>>
>> All recipes should following the best practices for do_install and do_deploy.
>>
>> Recipes that are used to transfer the output from a multiconfig target should
>> use task[mcdepends] to trigger the build of the component, and then transfer the
>> item to the current configuration in do_install or do_deploy, assuming the value
>> of the deployed item based on the TMPDIR.
>>
>> Suggested that the dependency and path are specific in a variable to make it
>> easier to adjust as assumptions change, or the user has specific environment needs.
>>
>>
>> (we should have some proper examples for this.... i.e.)
>>
>> conf/multiconfig/baremetal-firmware.conf:
>>
>> TMPDIR .= "-${BB_CURRENT_MC}"
>> TCLIBC = "newlib"
>>
>> recipes-firmware/firmware/my-firmware.bb:
>>
>> do_compile() {
>>      echo "testing" > ${B}/my-firmware.bin
>>
>> do_install() {
>>      install -mD 0644 ${B}/my-firmware.bin ${D}/lib/firmware/my-firmware.bin
>> }
>>
>> do_deploy() {
>>      install -mD 0644 ${B}/my-firmware.bin ${DEPLOYDIR}/my-firmware.bin
>> }
>>
>> recipes-firmware/firmware/my-special-firmware.bb:
>>
>> INHIBIT_DEFAULT_DEPS = "1"
>>
>> FIRMWARE_DEPENDS   ??= ""
>> FIRMWARE_MCDEPENDS ??= "mc::baremetal-firmware:my-firmware:do_deploy"
>> FIRMWARE_FILE      ??= "${TMPDIR}-baremetal-firmware/deploy/my-firmware.elf"
>> FIRMWARE_FILE[vardepsexclude] += "TMPDIR"
>>

(forgot the dependency stuff)

do_compile[depends] += "${FIRMWARE_DEPENDS}"
do_compile[mcdepends] += "${FIRMWARE_MCDEPENDS}"
do_compile() {
     :
}

>> do_install() {
>>       if [ ! -e ${FIRMWARE_FILE} ]; then
>>           echo "Unable to find FIRMWARE_FILE (${FIRMWARE_FILE})"
>>           exit 1
>>       fi
>>
>>       install -Dm 0644 ${FIRMWARE_FILE} ${D}/lib/firmware/${FIRMWARE_FILE}
>> }
>>
>> do_deploy() {
>>       if [ ! -e ${FIRMWARE_FILE} ]; then
>>           echo "Unable to find FIRMWARE_FILE (${FIRMWARE_FILE})"
>>           exit 1
>>       fi
>>
>>       install -Dm 0644 ${FIRMWARE_FILE} ${DEPLOYDIR}/${FIRMWARE_FILE}
>> }
>>
>>
>>
>>
>>
>> -=-=-=-=-=-=-=-=-=-=-=-
>> Links: You receive all messages sent to this group.
>> View/Reply Online (#6063): https://lists.yoctoproject.org/g/docs/message/6063
>> Mute This Topic: https://lists.yoctoproject.org/mt/110487932/3616948
>> Group Owner: docs+owner@lists.yoctoproject.org
>> Unsubscribe: https://lists.yoctoproject.org/g/docs/unsub [mark.hatle@kernel.crashing.org]
>> -=-=-=-=-=-=-=-=-=-=-=-
>>


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: Best practices documentation for multiconfigs
  2025-01-08 15:31 ` Antonin Godard
@ 2025-01-08 15:38   ` Mark Hatle
  2025-01-14  9:52   ` [docs] " Quentin Schulz
  1 sibling, 0 replies; 9+ messages in thread
From: Mark Hatle @ 2025-01-08 15:38 UTC (permalink / raw)
  To: Antonin Godard, docs; +Cc: Richard Purdie



On 1/8/25 9:31 AM, Antonin Godard wrote:
> Hi Mark,
> 
> Thanks for this. I can help with formatting as well as where to put this bit of
> documentation.
> 
> I already created a bug for this, you can add yourself to CC if you want to
> track it: https://bugzilla.yoctoproject.org/show_bug.cgi?id=15709.
> 
> First thought: compared to what we currently have [1], your doc seems to bring
> better details on multiconfigs. I'm thinking we could merge both to have a
> complete document on multiconfigs (and also make it its own document instead of
> a "Building" subsection).

Ultimately I think multiconfigs and how to use them is a large enough long-term 
topic that we will need to expand on this and figure out how to tie it into the 
(normal) single configuration.

I've struggled to explain this to people in my organization in a way that isn't 
horribly confusing.  My go to is:

Each configuration is effectively it's own, just as if you have multiple build 
directories each with their own configuration.  The complications [these best 
practices] come into play when we need to build something in one configuration 
and use it in another, which pretty much is always a requirement for a few 
select components [firmwares].

I then usually introduce this topic by walking through configuring individual 
build directories, building the components manually... and then "convert" it to 
a multiconfig.

Long term, we may want to do something similar in our own YP manuals, but I'll 
leave that to others to decide if that is really a good idea or not.

--Mark

> Other comments below.
> 
> [1]: https://docs.yoctoproject.org/dev-manual/building.html#building-images-for-multiple-targets-using-multiple-configurations
> 
> On Wed Jan 8, 2025 at 12:07 AM CET, Mark Hatle wrote:
>> I was talking to Richard on IRC and we think that we need to start collecting
>> and documenting examples and/or best practices for multiconfig usage.  Below is
>> my question attempt at starting this.  Hopefully we can expand this to something
>> generally useful.  What follows is a bit rough, and will likely need editing...
>>
>>
>> A common use for multiconfig is to use the default configuration as the regular
>> Linux build, while one or more multiconfigs can be used to build special
>> components (often baremetal firmware.)  Enabling this workflow requires us to do
>> three primary actions:
>>
>>     1) Configure the multiconfig builds
>>     2) Use multiconfig dependencies to trigger builds of necessary components
>>     3) Pick up the output of the multiconfig build and bring it into a different
>> config
>>
>> In order to successfully do the above, the following could be considered to be
>> best practices.
>>
>> Configuration:
>>
>> All of the (user) configuration starts with the local.conf file.  A default
>> value of:
>>
>> TMPDIR ?= "${TOPDIR}/tmp"
>>
>> is used to control the location for temporary build items, where components are
>> stored and built components are deployed.  For the deployed items the settings are:
>>
>> DEPLOY_DIR ?= "${TMPDIR}/deploy"
>> DEPLOY_DIR_IMAGE ?= "${DEPLOY_DIR}/images/${MACHINE}"
>>
>>
>> Each multiconfig requires a separate multiconfig configuration file.
>>
>> See:
>> https://docs.yoctoproject.org/dev-manual/building.html#building-images-for-multiple-targets-using-multiple-configurations
>>
>>
>> At a minimum a different TMPDIR is required for each multiconfig.  As a best
>> practice, instead of defining each TMPDIR separately, if they are defined as an
>> append (.= operation) with an expected format, later steps can use this
>> information to find the output of the build.  For example:
>>
>> TMPDIR .= "-${BB_CURRENT_MC}"
>>
>>
>> This also has the side effect that if the user changes the default TMPDIR
>> location in local.conf, all of the multiconfigs will follow with the same change
>> automatically.
>>
>>
>> For example:
>>
>> conf/multiconfig/baremetal-firmware.conf:
>>
>> TMPDIR .= "-${BB_CURRENT_MC}"
> 
> I assumed the `:append` override to be better practice in configuration files.
> 
>> TCLIBC = "newlib"
>>
>>
>> and a custom recipe called 'my-firmware.bb' that uses newlib to build baremetal
>> firmware for the device.  my-firmware.bb should define a do_deploy function that
>> deploys the baremetal firmware to ${DEPLOYDIR} with a specific name, such as
>> "my-firmware.elf".
>>
>>
>> Building:
>>
>> Using an 'mcdepend' a recipe in one multiconfig can trigger the build in another
>> multiconfig, such as:
>>
>>
>> my-special-firmware.bb:
>>
>> do_compile[mcdepends] = "mc::baremetal-firmware:my-firmware:do_deploy"
>>
>>
>> The above will ensure when do_compile is triggered, it further triggers the
>> multiconfig build which will deploy the built firmware.
> 
> Yes and actually this is lacking in the current documentation: this is the
> way to add a dependency on a multiconfig from the default ("" empty string)
> config, which is a common use-case of multiconfigs I believe.
> 
>>
>>
>>
>> Using the output of the build:
>>
>> However, just because we've built the item using mcdepends, we need to use the
>> output in some way.   We can make a series of assumptions, based on the default
>> Yocto Project variables in order to get the binary for packaging.
>>
>> Adding a do_install task to the example above:
>>
>> my-special-firmware.bb:
>>
>> do_install() {
>>      install -Dm 0644 ${TMPDIR}-baremetal-firmware/deploy/my-firmware.elf
>> ${D}/lib/firmware/my-firmware.elf
>> }
> 
> In my-firmware.bb, is deploying to DEPLOYDIR (defined as "${WORKDIR}/deploy-my-firmware"
> for the recipe) enough for my-special-firmware to pick up the firmware in
> baremetal-firmware's DEPLOY_DIR ("${TMPDIR}-baremetal-firmware/deploy") here?
> Shouldn't it pick it up in baremetal-firmware's DEPLOY_DIR_IMAGE instead?
> 
>>
>>
>> Doing the above will allow the firmware binary to be transfered and packaged
>> into the Linux context and rootfs.  However, this only works if we are careful
>> to not affect TMPDIR outside of specific places, and we use the default
>> DEPLOY_DIR (or other) deployment variables.
>>
>>
>> Suggested best practices:
>>
>> TMPDIR (other then the default set in bitbake.conf) is only set in local.conf by
>> the user.  This means that we should NOT manipulate TMPDIR in any way within the
>> machine or distro .conf files.
>>
>> A multiconfig must specify a TMPDIR, and should specify it by appending the
>> multiconfig name via "-${BB_CURRENT_MC}".
>>
>> All recipes should following the best practices for do_install and do_deploy.
>>
>> Recipes that are used to transfer the output from a multiconfig target should
>> use task[mcdepends] to trigger the build of the component, and then transfer the
>> item to the current configuration in do_install or do_deploy, assuming the value
>> of the deployed item based on the TMPDIR.
>>
>> Suggested that the dependency and path are specific in a variable to make it
>> easier to adjust as assumptions change, or the user has specific environment needs.
> 
> Not sure I got this sentence, could you explain what you meant here?
> 
>>
>> (we should have some proper examples for this.... i.e.)
>>
>> conf/multiconfig/baremetal-firmware.conf:
>>
>> TMPDIR .= "-${BB_CURRENT_MC}"
>> TCLIBC = "newlib"
>>
>> recipes-firmware/firmware/my-firmware.bb:
>>
>> do_compile() {
>>      echo "testing" > ${B}/my-firmware.bin
>>
>> do_install() {
>>      install -mD 0644 ${B}/my-firmware.bin ${D}/lib/firmware/my-firmware.bin
>> }
>>
>> do_deploy() {
>>      install -mD 0644 ${B}/my-firmware.bin ${DEPLOYDIR}/my-firmware.bin
>> }
>>
>> recipes-firmware/firmware/my-special-firmware.bb:
>>
>> INHIBIT_DEFAULT_DEPS = "1"
>>
>> FIRMWARE_DEPENDS   ??= ""
>> FIRMWARE_MCDEPENDS ??= "mc::baremetal-firmware:my-firmware:do_deploy"
>> FIRMWARE_FILE      ??= "${TMPDIR}-baremetal-firmware/deploy/my-firmware.elf"
>> FIRMWARE_FILE[vardepsexclude] += "TMPDIR"
>>
>> do_install() {
>>       if [ ! -e ${FIRMWARE_FILE} ]; then
>>           echo "Unable to find FIRMWARE_FILE (${FIRMWARE_FILE})"
> 
> Suggestion: "bberror" for visibility?
> 
>>           exit 1
>>       fi
>>
>>       install -Dm 0644 ${FIRMWARE_FILE} ${D}/lib/firmware/${FIRMWARE_FILE}
>> }
>>
>> do_deploy() {
>>       if [ ! -e ${FIRMWARE_FILE} ]; then
>>           echo "Unable to find FIRMWARE_FILE (${FIRMWARE_FILE})"
>>           exit 1
>>       fi
>>
>>       install -Dm 0644 ${FIRMWARE_FILE} ${DEPLOYDIR}/${FIRMWARE_FILE}
>> }
> 
> 
> Antonin
> 


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [docs] Best practices documentation for multiconfigs
  2025-01-08 15:34   ` Mark Hatle
@ 2025-01-09  8:14     ` Christian Eggers
  2025-01-09 15:35       ` Mark Hatle
  0 siblings, 1 reply; 9+ messages in thread
From: Christian Eggers @ 2025-01-09  8:14 UTC (permalink / raw)
  To: docs; +Cc: Mark Hatle

Hi,

due to this thread I got noticed about the "multiconfig" feature for
the first time. I have two additional questions related to this topic:

1. Toolchain
For baremetal targets we currently use the "GNUARM" toolchain. Would it
make sense to build the "secondary" toolchain with Yocto instead? Other
users may prefer staying at an external toolchain. Is there already
documentation about building a secondary toolchain (or using an existing one)?

2. SDK
How can the additional components of a multiconfig (e.g. toolchain, libraries)
be added to the SDK?

regards,
Christian





^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [docs] Best practices documentation for multiconfigs
  2025-01-09  8:14     ` Christian Eggers
@ 2025-01-09 15:35       ` Mark Hatle
  0 siblings, 0 replies; 9+ messages in thread
From: Mark Hatle @ 2025-01-09 15:35 UTC (permalink / raw)
  To: Christian Eggers, docs



On 1/9/25 2:14 AM, Christian Eggers wrote:
> Hi,
> 
> due to this thread I got noticed about the "multiconfig" feature for
> the first time. I have two additional questions related to this topic:
> 
> 1. Toolchain
> For baremetal targets we currently use the "GNUARM" toolchain. Would it
> make sense to build the "secondary" toolchain with Yocto instead? Other
> users may prefer staying at an external toolchain. Is there already
> documentation about building a secondary toolchain (or using an existing one)?

In _MY_ base, I don't want to use any binary toolchains, so I build from source. 
  Otherwise I don't consider the code to be properly reproducible.

> 2. SDK
> How can the additional components of a multiconfig (e.g. toolchain, libraries)
> be added to the SDK?

SDKs are single configuration.  You need multiple SDKs, one for each configuration.

--Mark

> regards,
> Christian
> 
> 
> 
> _______________________________________________________​​​​
> 
> Christian
> 
> 	
> 
> 
> 	
> 
> Eggers
> 
> Software Engineer
> 
> ​
> 
> ARRI
> 
> Arnold & Richter Cine Technik GmbH & Co. Betriebs KG
> 
> Arriweg 17
> 
> 	
> 
> ,
> 
> 	
> 
> 83071
> 
> 	
> 
> 
> 	
> 
> Stephanskirchen
> 
> www.arri.com
> 
> <http://www.arri.com/>
> 
> 	
> 
> +49 8036 3009-3118 <tel:+49%208036%203009-3118>
> 
> 	
> 	
> 
> 	
> 
> CEggers@arri.de <mailto:CEggers@arri.de>
> 
> 
> ​
> 
> SkyPanel Pro <https://www.arri.com/en/lighting/led-panel-lights/skypanel-pro>
> 
> 
> Arnold & Richter Cine Technik GmbH & Co. Betriebs KG
> Sitz: München ‑ Registergericht: Amtsgericht München ‑ Handelsregisternummer: HRA 57918
> Persönlich haftender Gesellschafter: Arnold & Richter Cine Technik GmbH
> Sitz: München ‑ Registergericht: Amtsgericht München ‑ Handelsregisternummer: HRB 54477
> Geschäftsführer: Stefan Mairiedl; Walter Trauninger
> 
> 
> ​
> 


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [docs] Best practices documentation for multiconfigs
  2025-01-08 15:31 ` Antonin Godard
  2025-01-08 15:38   ` Mark Hatle
@ 2025-01-14  9:52   ` Quentin Schulz
  2025-01-16  3:32     ` Mark Hatle
  1 sibling, 1 reply; 9+ messages in thread
From: Quentin Schulz @ 2025-01-14  9:52 UTC (permalink / raw)
  To: antonin.godard, Mark Hatle, docs; +Cc: Richard Purdie

Hi Antonin, Mark,

On 1/8/25 4:31 PM, Antonin Godard via lists.yoctoproject.org wrote:
> Hi Mark,
> 
> Thanks for this. I can help with formatting as well as where to put this bit of
> documentation.
> 
> I already created a bug for this, you can add yourself to CC if you want to
> track it: https://bugzilla.yoctoproject.org/show_bug.cgi?id=15709.
> 
> First thought: compared to what we currently have [1], your doc seems to bring
> better details on multiconfigs. I'm thinking we could merge both to have a
> complete document on multiconfigs (and also make it its own document instead of
> a "Building" subsection).
> 
> Other comments below.
> 
> [1]: https://docs.yoctoproject.org/dev-manual/building.html#building-images-for-multiple-targets-using-multiple-configurations
> 
> On Wed Jan 8, 2025 at 12:07 AM CET, Mark Hatle wrote:
>> I was talking to Richard on IRC and we think that we need to start collecting
>> and documenting examples and/or best practices for multiconfig usage.  Below is
>> my question attempt at starting this.  Hopefully we can expand this to something
>> generally useful.  What follows is a bit rough, and will likely need editing...
>>
>>
>> A common use for multiconfig is to use the default configuration as the regular
>> Linux build, while one or more multiconfigs can be used to build special
>> components (often baremetal firmware.)  Enabling this workflow requires us to do
>> three primary actions:
>>
>>     1) Configure the multiconfig builds
>>     2) Use multiconfig dependencies to trigger builds of necessary components
>>     3) Pick up the output of the multiconfig build and bring it into a different
>> config
>>
>> In order to successfully do the above, the following could be considered to be
>> best practices.
>>
>> Configuration:
>>
>> All of the (user) configuration starts with the local.conf file.  A default
>> value of:
>>
>> TMPDIR ?= "${TOPDIR}/tmp"
>>
>> is used to control the location for temporary build items, where components are
>> stored and built components are deployed.  For the deployed items the settings are:
>>
>> DEPLOY_DIR ?= "${TMPDIR}/deploy"
>> DEPLOY_DIR_IMAGE ?= "${DEPLOY_DIR}/images/${MACHINE}"
>>
>>
>> Each multiconfig requires a separate multiconfig configuration file.
>>
>> See:
>> https://docs.yoctoproject.org/dev-manual/building.html#building-images-for-multiple-targets-using-multiple-configurations
>>
>>
>> At a minimum a different TMPDIR is required for each multiconfig.  As a best
>> practice, instead of defining each TMPDIR separately, if they are defined as an
>> append (.= operation) with an expected format, later steps can use this
>> information to find the output of the build.  For example:
>>
>> TMPDIR .= "-${BB_CURRENT_MC}"
>>
>>
>> This also has the side effect that if the user changes the default TMPDIR
>> location in local.conf, all of the multiconfigs will follow with the same change
>> automatically.
>>
>>
>> For example:
>>
>> conf/multiconfig/baremetal-firmware.conf:
>>
>> TMPDIR .= "-${BB_CURRENT_MC}"
> 
> I assumed the `:append` override to be better practice in configuration files.
> 
>> TCLIBC = "newlib"
>>
>>
>> and a custom recipe called 'my-firmware.bb' that uses newlib to build baremetal
>> firmware for the device.  my-firmware.bb should define a do_deploy function that
>> deploys the baremetal firmware to ${DEPLOYDIR} with a specific name, such as
>> "my-firmware.elf".
>>
>>
>> Building:
>>
>> Using an 'mcdepend' a recipe in one multiconfig can trigger the build in another
>> multiconfig, such as:
>>
>>
>> my-special-firmware.bb:
>>
>> do_compile[mcdepends] = "mc::baremetal-firmware:my-firmware:do_deploy"
>>
>>
>> The above will ensure when do_compile is triggered, it further triggers the
>> multiconfig build which will deploy the built firmware.
> 
> Yes and actually this is lacking in the current documentation: this is the
> way to add a dependency on a multiconfig from the default ("" empty string)
> config, which is a common use-case of multiconfigs I believe.
> 
>>
>>
>>
>> Using the output of the build:
>>
>> However, just because we've built the item using mcdepends, we need to use the
>> output in some way.   We can make a series of assumptions, based on the default
>> Yocto Project variables in order to get the binary for packaging.
>>
>> Adding a do_install task to the example above:
>>
>> my-special-firmware.bb:
>>
>> do_install() {
>>      install -Dm 0644 ${TMPDIR}-baremetal-firmware/deploy/my-firmware.elf
>> ${D}/lib/firmware/my-firmware.elf
>> }
> 
> In my-firmware.bb, is deploying to DEPLOYDIR (defined as "${WORKDIR}/deploy-my-firmware"
> for the recipe) enough for my-special-firmware to pick up the firmware in
> baremetal-firmware's DEPLOY_DIR ("${TMPDIR}-baremetal-firmware/deploy") here?
> Shouldn't it pick it up in baremetal-firmware's DEPLOY_DIR_IMAGE instead?
> 

I believe the hardcoded path is missing the intermediate 
images/<machine>/ directories as the deploy.bbclass installs in 
DEPLOY_DIR_IMAGE, which is where the deploy bbclass stores the sstate 
output of the deploy task. This is the default according to bitbake.conf.

>>
>>
>> Doing the above will allow the firmware binary to be transfered and packaged
>> into the Linux context and rootfs.  However, this only works if we are careful
>> to not affect TMPDIR outside of specific places, and we use the default
>> DEPLOY_DIR (or other) deployment variables.
>>
>>
>> Suggested best practices:
>>
>> TMPDIR (other then the default set in bitbake.conf) is only set in local.conf by
>> the user.  This means that we should NOT manipulate TMPDIR in any way within the
>> machine or distro .conf files.
>>
>> A multiconfig must specify a TMPDIR, and should specify it by appending the
>> multiconfig name via "-${BB_CURRENT_MC}".
>>
>> All recipes should following the best practices for do_install and do_deploy.
>>
>> Recipes that are used to transfer the output from a multiconfig target should
>> use task[mcdepends] to trigger the build of the component, and then transfer the
>> item to the current configuration in do_install or do_deploy, assuming the value
>> of the deployed item based on the TMPDIR.
>>
>> Suggested that the dependency and path are specific in a variable to make it
>> easier to adjust as assumptions change, or the user has specific environment needs.
> 
> Not sure I got this sentence, could you explain what you meant here?
> 
>>
>> (we should have some proper examples for this.... i.e.)
>>
>> conf/multiconfig/baremetal-firmware.conf:
>>
>> TMPDIR .= "-${BB_CURRENT_MC}"
>> TCLIBC = "newlib"
>>
>> recipes-firmware/firmware/my-firmware.bb:
>>
>> do_compile() {
>>      echo "testing" > ${B}/my-firmware.bin
>>
>> do_install() {
>>      install -mD 0644 ${B}/my-firmware.bin ${D}/lib/firmware/my-firmware.bin
>> }
>>
>> do_deploy() {
>>      install -mD 0644 ${B}/my-firmware.bin ${DEPLOYDIR}/my-firmware.bin
>> }
>>
>> recipes-firmware/firmware/my-special-firmware.bb:
>>
>> INHIBIT_DEFAULT_DEPS = "1"
>>
>> FIRMWARE_DEPENDS   ??= ""

Considering it's empty and the example does nothing in compile task, I 
suggest to remove it to not confuse people on whether this is necessary. 
Or provide an actual valid example that requires the recipe using the 
built firmware to do something with it in compile task.

>> FIRMWARE_MCDEPENDS ??= "mc::baremetal-firmware:my-firmware:do_deploy"
>> FIRMWARE_FILE      ??= "${TMPDIR}-baremetal-firmware/deploy/my-firmware.elf"
>> FIRMWARE_FILE[vardepsexclude] += "TMPDIR"
>>

This vardepsexclude varflags would need to be explained.

I would suggest (if we haven't already done it) to have a minimal 
multiconfig example in poky that we build regularly and whose content 
could be duplicated (explicitly) in the docs like we have for baremetal 
hello, kernel modules, etc... so we avoid having the docs have outdated 
examples in the future.

Otherwise sounds like a good plan!

Cheers,
Quentin


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [docs] Best practices documentation for multiconfigs
  2025-01-14  9:52   ` [docs] " Quentin Schulz
@ 2025-01-16  3:32     ` Mark Hatle
  0 siblings, 0 replies; 9+ messages in thread
From: Mark Hatle @ 2025-01-16  3:32 UTC (permalink / raw)
  To: Quentin Schulz, antonin.godard, docs; +Cc: Richard Purdie



On 1/14/25 3:52 AM, Quentin Schulz wrote:
> Hi Antonin, Mark,
> 
> On 1/8/25 4:31 PM, Antonin Godard via lists.yoctoproject.org wrote:
>> Hi Mark,
>>
>> Thanks for this. I can help with formatting as well as where to put this bit of
>> documentation.
>>
>> I already created a bug for this, you can add yourself to CC if you want to
>> track it: https://bugzilla.yoctoproject.org/show_bug.cgi?id=15709.
>>
>> First thought: compared to what we currently have [1], your doc seems to bring
>> better details on multiconfigs. I'm thinking we could merge both to have a
>> complete document on multiconfigs (and also make it its own document instead of
>> a "Building" subsection).
>>
>> Other comments below.
>>
>> [1]: https://docs.yoctoproject.org/dev-manual/building.html#building-images-for-multiple-targets-using-multiple-configurations
>>
>> On Wed Jan 8, 2025 at 12:07 AM CET, Mark Hatle wrote:
>>> I was talking to Richard on IRC and we think that we need to start collecting
>>> and documenting examples and/or best practices for multiconfig usage.  Below is
>>> my question attempt at starting this.  Hopefully we can expand this to something
>>> generally useful.  What follows is a bit rough, and will likely need editing...
>>>
>>>
>>> A common use for multiconfig is to use the default configuration as the regular
>>> Linux build, while one or more multiconfigs can be used to build special
>>> components (often baremetal firmware.)  Enabling this workflow requires us to do
>>> three primary actions:
>>>
>>>      1) Configure the multiconfig builds
>>>      2) Use multiconfig dependencies to trigger builds of necessary components
>>>      3) Pick up the output of the multiconfig build and bring it into a different
>>> config
>>>
>>> In order to successfully do the above, the following could be considered to be
>>> best practices.
>>>
>>> Configuration:
>>>
>>> All of the (user) configuration starts with the local.conf file.  A default
>>> value of:
>>>
>>> TMPDIR ?= "${TOPDIR}/tmp"
>>>
>>> is used to control the location for temporary build items, where components are
>>> stored and built components are deployed.  For the deployed items the settings are:
>>>
>>> DEPLOY_DIR ?= "${TMPDIR}/deploy"
>>> DEPLOY_DIR_IMAGE ?= "${DEPLOY_DIR}/images/${MACHINE}"
>>>
>>>
>>> Each multiconfig requires a separate multiconfig configuration file.
>>>
>>> See:
>>> https://docs.yoctoproject.org/dev-manual/building.html#building-images-for-multiple-targets-using-multiple-configurations
>>>
>>>
>>> At a minimum a different TMPDIR is required for each multiconfig.  As a best
>>> practice, instead of defining each TMPDIR separately, if they are defined as an
>>> append (.= operation) with an expected format, later steps can use this
>>> information to find the output of the build.  For example:
>>>
>>> TMPDIR .= "-${BB_CURRENT_MC}"
>>>
>>>
>>> This also has the side effect that if the user changes the default TMPDIR
>>> location in local.conf, all of the multiconfigs will follow with the same change
>>> automatically.
>>>
>>>
>>> For example:
>>>
>>> conf/multiconfig/baremetal-firmware.conf:
>>>
>>> TMPDIR .= "-${BB_CURRENT_MC}"
>>
>> I assumed the `:append` override to be better practice in configuration files.
>>
>>> TCLIBC = "newlib"
>>>
>>>
>>> and a custom recipe called 'my-firmware.bb' that uses newlib to build baremetal
>>> firmware for the device.  my-firmware.bb should define a do_deploy function that
>>> deploys the baremetal firmware to ${DEPLOYDIR} with a specific name, such as
>>> "my-firmware.elf".
>>>
>>>
>>> Building:
>>>
>>> Using an 'mcdepend' a recipe in one multiconfig can trigger the build in another
>>> multiconfig, such as:
>>>
>>>
>>> my-special-firmware.bb:
>>>
>>> do_compile[mcdepends] = "mc::baremetal-firmware:my-firmware:do_deploy"
>>>
>>>
>>> The above will ensure when do_compile is triggered, it further triggers the
>>> multiconfig build which will deploy the built firmware.
>>
>> Yes and actually this is lacking in the current documentation: this is the
>> way to add a dependency on a multiconfig from the default ("" empty string)
>> config, which is a common use-case of multiconfigs I believe.
>>
>>>
>>>
>>>
>>> Using the output of the build:
>>>
>>> However, just because we've built the item using mcdepends, we need to use the
>>> output in some way.   We can make a series of assumptions, based on the default
>>> Yocto Project variables in order to get the binary for packaging.
>>>
>>> Adding a do_install task to the example above:
>>>
>>> my-special-firmware.bb:
>>>
>>> do_install() {
>>>       install -Dm 0644 ${TMPDIR}-baremetal-firmware/deploy/my-firmware.elf
>>> ${D}/lib/firmware/my-firmware.elf
>>> }
>>
>> In my-firmware.bb, is deploying to DEPLOYDIR (defined as "${WORKDIR}/deploy-my-firmware"
>> for the recipe) enough for my-special-firmware to pick up the firmware in
>> baremetal-firmware's DEPLOY_DIR ("${TMPDIR}-baremetal-firmware/deploy") here?
>> Shouldn't it pick it up in baremetal-firmware's DEPLOY_DIR_IMAGE instead?
>>
> 
> I believe the hardcoded path is missing the intermediate
> images/<machine>/ directories as the deploy.bbclass installs in
> DEPLOY_DIR_IMAGE, which is where the deploy bbclass stores the sstate
> output of the deploy task. This is the default according to bitbake.conf.
> 
>>>
>>>
>>> Doing the above will allow the firmware binary to be transfered and packaged
>>> into the Linux context and rootfs.  However, this only works if we are careful
>>> to not affect TMPDIR outside of specific places, and we use the default
>>> DEPLOY_DIR (or other) deployment variables.
>>>
>>>
>>> Suggested best practices:
>>>
>>> TMPDIR (other then the default set in bitbake.conf) is only set in local.conf by
>>> the user.  This means that we should NOT manipulate TMPDIR in any way within the
>>> machine or distro .conf files.
>>>
>>> A multiconfig must specify a TMPDIR, and should specify it by appending the
>>> multiconfig name via "-${BB_CURRENT_MC}".
>>>
>>> All recipes should following the best practices for do_install and do_deploy.
>>>
>>> Recipes that are used to transfer the output from a multiconfig target should
>>> use task[mcdepends] to trigger the build of the component, and then transfer the
>>> item to the current configuration in do_install or do_deploy, assuming the value
>>> of the deployed item based on the TMPDIR.
>>>
>>> Suggested that the dependency and path are specific in a variable to make it
>>> easier to adjust as assumptions change, or the user has specific environment needs.
>>
>> Not sure I got this sentence, could you explain what you meant here?
>>
>>>
>>> (we should have some proper examples for this.... i.e.)
>>>
>>> conf/multiconfig/baremetal-firmware.conf:
>>>
>>> TMPDIR .= "-${BB_CURRENT_MC}"
>>> TCLIBC = "newlib"
>>>
>>> recipes-firmware/firmware/my-firmware.bb:
>>>
>>> do_compile() {
>>>       echo "testing" > ${B}/my-firmware.bin
>>>
>>> do_install() {
>>>       install -mD 0644 ${B}/my-firmware.bin ${D}/lib/firmware/my-firmware.bin
>>> }
>>>
>>> do_deploy() {
>>>       install -mD 0644 ${B}/my-firmware.bin ${DEPLOYDIR}/my-firmware.bin
>>> }
>>>
>>> recipes-firmware/firmware/my-special-firmware.bb:
>>>
>>> INHIBIT_DEFAULT_DEPS = "1"
>>>
>>> FIRMWARE_DEPENDS   ??= ""
> 
> Considering it's empty and the example does nothing in compile task, I
> suggest to remove it to not confuse people on whether this is necessary.
> Or provide an actual valid example that requires the recipe using the
> built firmware to do something with it in compile task.
> 
>>> FIRMWARE_MCDEPENDS ??= "mc::baremetal-firmware:my-firmware:do_deploy"
>>> FIRMWARE_FILE      ??= "${TMPDIR}-baremetal-firmware/deploy/my-firmware.elf"
>>> FIRMWARE_FILE[vardepsexclude] += "TMPDIR"
>>>
> 
> This vardepsexclude varflags would need to be explained.

If the path changes, the recipe is invalidated.  We want the invalidation to 
happen based on the dependencies, not the magic directory that TMPDIR is.  (By 
default TOPDIR is excluded, which is a component of TMPDIR.  However, if the 
user changes TMPDIR to something else then it's no longer excluded and the full 
path in FIRMWARE_FILE is hashed and triggers a 'rebuild'.

> I would suggest (if we haven't already done it) to have a minimal
> multiconfig example in poky that we build regularly and whose content
> could be duplicated (explicitly) in the docs like we have for baremetal
> hello, kernel modules, etc... so we avoid having the docs have outdated
> examples in the future.
> 
> Otherwise sounds like a good plan!
> 
> Cheers,
> Quentin


^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2025-01-16  3:34 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-01-07 23:07 Best practices documentation for multiconfigs Mark Hatle
2025-01-07 23:37 ` [docs] " Joshua Watt
2025-01-08 15:34   ` Mark Hatle
2025-01-09  8:14     ` Christian Eggers
2025-01-09 15:35       ` Mark Hatle
2025-01-08 15:31 ` Antonin Godard
2025-01-08 15:38   ` Mark Hatle
2025-01-14  9:52   ` [docs] " Quentin Schulz
2025-01-16  3:32     ` Mark Hatle

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox