Search code examples
embedded-linuxyocto

How can I save local changes that have been done in Yocto repository?


I'm working on some Linux embedded system at the moment and using Yocto to build Linux distribution for a board.

I've followed Yocto build flow:

  • download layers sources
  • build image
  • flash image into the board or generate SDK.

Everything works great. However I was required to add some changes to local.conf, probably add some *.bbapend files, systemd services and so forth. So, I'm wondering how can I save those local changes in case if I'll want to setup a new build machine or current one will be corrupted.

Should I create a custom image or layer that will inherit everything from a board manufacturer one and add changes and functionalities that are needed to me? Or something else?


Solution

  • Generally when working on a custom project with Yocto, here is what possibly you will need:

    First of all, you need to create your custom layer

    bitbake-layers create-layer meta-custom
    

    and add it:

    bitbake-layers add-layer <path/to/meta-custom>
    

    After that, here are some ideas:

    Official recipes modification:

    When you have to modify some official recipe that exist in other official layer, you need to create a .bbappend file into your custom layer and make your changes there.

    meta-official/recipes-example/example/example_1.0.bb
    

    your modifications must be made under:

    meta-custom/recipes-example/example/example_1.0.bbappend
    

    or to match all versions of that recipe:

    meta-custom/recipes-example/example/example_%.bbappend
    

    Distro modification:

    If you changed DISTRO_FEATURES in local.conf you may need to create a new distro in your new custom layer:

    meta-custom/conf/distro/custom-distro.conf
    

    in custom-distro.conf:

    • include or require your current used distro
    • Add your custom configuration DISTRO_FEATURES

    Then, when creating new build, set (in local.conf):

    DISTRO = "custom-distro"
    

    Examples for distro changes:

    • Select the init manager: INIT_MANAGER = "systemd" for example.
    • Add some distro features
    • Set some preferred recipes versions PREFERRED_VERSION_recipe = "x"
    • Set some preferred providers PREFERRED_PROVIDER_virtual/xx = "x"

    Machine modification:

    If your board presents a permanent hardware components that, by default, are not activated in Yocto, then I suggest to create a new custom machine as well:

    meta-custom/conf/machine/custom-machine.conf
    

    In that, include or require your current machine configuration file and you may:

    • Select your preferred virtual/kernel provider
    • Select your preferred virtual/bootloader provider
    • Select your custom kernel and bootloader device tree files
    • etc.

    and then, set it (in local.conf):

    MACHINE = "custom-machine"
    

    Image modification:

    This is the most probable modification one may have, which is adding some packages to the image with IMAGE_INSTALL, so you may need to create a custom image:

    meta-custom/recipes-core/images/custom-image.bb
    

    in that require or include other image and:

    • Add packages with IMAGE_INSTALL

    NOTES

    • If you have bbappend that append to an official bbappend then you consider making your layer more priority to the official one in meta-custom/conf/layer.conf

    • If your new custom layer depends on your manufacturer layer than you may consider making it depends on it in the layer conf file:

    LAYERDEPENDS_meta-custom = "meta-official"
    
    • I recommend using kas which you can setup an automatic layers configuration with your custom layer and create the build automatically, this is also useful for DevOps pipelines automation.

    This is what I can think of right now :))

    EDIT

    You can then create a custom repository for your custom layer.

    If you are using repo for your manufacturer provided initialization, then you can use this idea:

    You can customize the manufacturer's manifest file to add your new custom repository, like the following:

    Add remote block for your custom git server

    <remote name="custom-git" fetch="ssh://git@gitlab.xxx/<group>/"/>
    

    If your custom layer is under the git server directly remove group or set it if it is the case.

    Then, add your custom layer as a project:

    <project path="<where/to/unpack>" name="<name/under/remote>" remote="custom-git" revision="<commit>" />
    

    You can check for more repo details here.

    Finally, you just use repo with your custom repository/manifest:

    repo init -u <custom-git/manifest-project> -b <branch> -m custom-project.xml
    repo sync