3
votes

I'm trying to add a simple line in fstab within the final rootfs that Yocto builds.

My first approach was to add my own fstab in my layer meta-mylayer/recipes-core/base-files/base-files/fstab and the proper meta-mylayer/recipes-core/base-files/base-files/base-files_%.bbappend which only have the following line:

FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:"

And it works, but as the title of my question says, i want to modify fstab based on the recipe-image i want to build i.e. dev-image & prod-image.

After some investigation i think i have 2 options

  1. Modify fstab within the recipe image, extending the do_install task...
dev-image.bb
--------------

DESCRIPTION = "Development Image"
[...]
inherit core-image

do_install_append () {
    echo "=======  Modifying fstab ========"
    cat >> ${D}${sysconfdir}/fstab <<EOF

# The line i want to Add

EOF
}
[...]

--------------

Problem is that i'm actually not seeing my modified line in my final /etc/fstab and bitbake is not showing any build error or warning about this, actually, i'm not even able to see the echo-trace i put.

  1. My second attempt was to handle these modifications with packages and depending on the recipe-image i will be able to add the package for *-dev or *-prod. This idea was taken from Oleksandr Poznyak in this answer in summary he suggest the following:

1) Create *.bbappend recipe base-files_%s.bbappend in your layer. It appends to poky "base-files" recipe.

2) Create your own "python do_package_prepend" function where you should make your recipe produce two different packages

3) Add them to DEPENDS in your image recipe

And based on his example i made my own recipe:

base-files_%.bbappend
-------------------------
FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:"

SRC_URI += "file://fstab-dev \                                                   
file://fstab-prod \
"

PACKAGES += " ${PN}-dev ${PN}-prod"
CONFFILES_${PN}-dev = "${CONFFILES_${PN}}"
CONFFILES_${PN}-prod = "${CONFFILES_${PN}}"

pkg_preinst_${PN}-dev = "${pkg_preinst_${PN}}"
pkg_preinst_${PN}-prod = "${pkg_preinst_${PN}}"

RREPLACES_${PN}-dev = "${PN}"
RPROVIDES_${PN}-dev = "${PN}"
RCONFLICTS_${PN}-dev = "${PN}"

RREPLACES_${PN}-prod = "${PN}"
RPROVIDES_${PN}-prod = "${PN}"
RCONFLICTS_${PN}-prod = "${PN}"

python populate_packages_prepend() {
    import shutil

    packages = ("${PN}-dev", "${PN}-prod")
    for package in packages:
    # copy ${PN} content to packages
        shutil.copytree("${PKGD}", "${PKGDEST}/%s" % package, symlinks=True)
    # replace fstab
    if package == "${PN}-dev":
        shutil.copy("${WORKDIR}/fstab-dev", "${PKGDEST}/${PN}-dev/etc/fstab")
    else:
        shutil.copy("${WORKDIR}/fstab-prod", "${PKGDEST}/${PN}-prod/etc/fstab")
}
-------------------------

And in my recipe-image(dev-image.bb) i added base-files-dev packet

dev-image.bb
--------------

DESCRIPTION = "Development Image"
[...]
inherit core-image

IMAGE_INSTALL = " \
 ${MY_PACKETS} \
 base-files-dev \
"

[...]

--------------

Problem with this, is that i'm not familiarized with phyton indentation so probably i'm messing things up, the error log shows as follows.

DEBUG: Executing python function populate_packages
ERROR: Error executing a python function in exec_python_func() autogenerated:

The stack trace of python calls that resulted in this exception/failure was:
File: 'exec_python_func() autogenerated', lineno: 2, function: <module>
     0001:
 *** 0002:populate_packages(d)
     0003:
File: '/home/build/share/build_2/../sources/poky/meta/classes/package.bbclass', lineno: 1138, function: populate_packages
     1134:
     1135:    workdir = d.getVar('WORKDIR')
     1136:    outdir = d.getVar('DEPLOY_DIR')
     1137:    dvar = d.getVar('PKGD')
 *** 1138:    packages = d.getVar('PACKAGES').split()
     1139:    pn = d.getVar('PN')
     1140:
     1141:    bb.utils.mkdirhier(outdir)
     1142:    os.chdir(dvar)
File: '/usr/lib/python3.6/shutil.py', lineno: 315, function: copytree
     0311:    destination path as arguments. By default, copy2() is used, but any
     0312:    function that supports the same signature (like copy()) can be used.
     0313:
     0314:    """
 *** 0315:    names = os.listdir(src)
     0316:    if ignore is not None:
     0317:        ignored_names = ignore(src, names)
     0318:    else:
     0319:        ignored_names = set()
Exception: FileNotFoundError: [Errno 2] No such file or directory: '${PKGD}'

DEBUG: Python function populate_packages finished
DEBUG: Python function do_package finished

I will really appreciate any clue or sort of direction, i'm not an Yocto expert so maybe the options that i suggest are not the most elegant and probably there is a better way to do it, so be free to give me any recommendation.

Thank you very much.

UPDATE:

As always, i was not the only one trying this, the way that i make it work was thanks this answer the only inconvenience with this is that you need to rm what you want to install through a .bbappend but for now is fine for me.

I also tried to do the same with bbclasses, which for me, it is a more elegant wayto do it, but i failed... i got the following error

ERROR: base-files-dev-3.0.14-r89 do_packagedata: The recipe base-files-dev is trying to install files into a shared area when those files already exist. Those files and their manifest location are:

I tried to rm fstab within the .bbappend but the same error is showed

Maybe somebody will share what i'm doing wrong...

If you don't find this post valuable please remove...

1

1 Answers

0
votes

Your recipe which base on Oleksandr doesn't work due to dropped support for variables expansion in newer Poky.

https://www.yoctoproject.org/docs/latest/mega-manual/mega-manual.html#migration-2.1-variable-expansion-in-python-functions

Error explicit says: Exception: FileNotFoundError: [Errno 2] No such file or directory: '${PKGD}' It didn't expand the variable.

P.S.

This is not a proper answer to Your question but SO blocks comments.