public inbox for docs@lists.yoctoproject.org
 help / color / mirror / Atom feed
From: Mark Hatle <mark.hatle@kernel.crashing.org>
To: docs@lists.yoctoproject.org
Subject: Re: [docs] Best practices documentation for multiconfigs
Date: Wed, 8 Jan 2025 09:34:44 -0600	[thread overview]
Message-ID: <39d815da-1f48-4822-a1c2-1d8762ab7989@kernel.crashing.org> (raw)
In-Reply-To: <CAJdd5GZY6-QwiJQM1KjQN1=GpSL_po4ay_hahvx4+Miz59vJVg@mail.gmail.com>



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]
>> -=-=-=-=-=-=-=-=-=-=-=-
>>


  reply	other threads:[~2025-01-08 15:34 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 [this message]
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

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=39d815da-1f48-4822-a1c2-1d8762ab7989@kernel.crashing.org \
    --to=mark.hatle@kernel.crashing.org \
    --cc=docs@lists.yoctoproject.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