Search code examples
configyoctobitbakeopenembeddedyocto-recipe

Yocto: what is the best practice for having a recipe install config files for another application, but only if said application is to be installed?


What is the recommended way to include config files depending on the presence of another package or recipe in an image?

For example, if the python3-supervisor recipe is included in a target image, what is the best way to write a custom recipe so that, in this case, the recipe installs a foo.conf file into /etc/supervisor/conf.d/ directory, and if the python3-supervisor recipe is not installed, then it does not do that?

I was looking at DISTRO_FEATURES as that is sometimes used for installing systemd unit files, but there's also IMAGE_FEATURES which might work too if the .conf files are put in their own packages - e.g. foo-conf installs /etc/supervisor/conf.d/foo.conf but only if, say, IMAGE_FEATURES_append = " supervisor-conf".

I wasn't able to find any recommendations in the bitbake manual on how to do this properly. Is there a good example in any of the OpenEmbedded layers?

In my case I'm writing my own recipes for my own applications, that would install their own .conf files into /etc/supervisor/conf.d/ if the python3-supervisor recipe is installed, and fall back to something else (or nothing) if it isn't, but the problem can be thought of as a more general "how do I gate the installation of certain files based on what's going into the image?"


Solution

  • Since there's no reliable way for one package to know what other packages from other recipes are installed in a particular image (each package is built independently of the packages from other recipes, and may or may not be included in the final image), it seems a good way to do this is with a custom DISTRO_FEATURES string.

    For example, in local.conf one can specify an arbitrary custom feature, let's call it supervisord:

    DISTRO_FEATURES_append = " supervisord"
    

    Then in individual recipes, the following can be used to selectively install supervisord .conf files, if this feature is selected:

    # myrecipe.bb
    
    SRC_URI = " \
              ${@bb.utils.contains('DISTRO_FEATURES', 'supervisord', 'file://myrecipe.conf', '', d)} \
              "
    
    # ...
    
    do_install() {
        if ${@bb.utils.contains('DISTRO_FEATURES', 'supervisord', 'true', 'false', d)}; then
            install -d ${D}${sysconfdir}/supervisor/conf.d
            install -m 0644 ${WORKDIR}/myrecipe.conf ${D}${sysconfdir}/supervisor/conf.d/myrecipe.conf
        fi
    }
    

    Unlike IMAGE_FEATURES, this does not require the features to be pre-defined in a .bbclass or somesuch. Instead, DISTRO_FEATURES is just treated as space-delimited list of strings, and the check for a particular string in this list is trivial.