public inbox for docs@lists.yoctoproject.org
 help / color / mirror / Atom feed
From: "Antonin Godard" <antonin.godard@bootlin.com>
To: "Mark Hatle" <mark.hatle@kernel.crashing.org>,
	<docs@lists.yoctoproject.org>
Cc: "Richard Purdie" <richard.purdie@linuxfoundation.org>
Subject: Re: Best practices documentation for multiconfigs
Date: Wed, 08 Jan 2025 16:31:09 +0100	[thread overview]
Message-ID: <D6WSSTWDW44E.3VZKMQHM8HZLN@bootlin.com> (raw)
In-Reply-To: <cb8cda4b-4b71-4896-b355-d628336b11a4@kernel.crashing.org>

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


  parent reply	other threads:[~2025-01-08 15:31 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
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 [this message]
2025-01-08 15:38   ` Mark Hatle
2025-01-14  9:52   ` [docs] " Quentin Schulz
2025-01-16  3:32     ` Mark Hatle

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=D6WSSTWDW44E.3VZKMQHM8HZLN@bootlin.com \
    --to=antonin.godard@bootlin.com \
    --cc=docs@lists.yoctoproject.org \
    --cc=mark.hatle@kernel.crashing.org \
    --cc=richard.purdie@linuxfoundation.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox