I want to create a small application image. That image installed at a separate partition shall be mounted to /usr/local. I created a recipe like this:
inherit image
IMAGE_BASENAME = "appfs"
IMAGE_NAME_SUFFIX = ".appfs"
IMAGE_INSTALL_append = " app_lib "
IMAGE_INSTALL_append = " app_prog1 "
IMAGE_INSTALL_append = " app_prog2 "
IMAGE_INSTALL_append = " app_prog3 "
The result looks not bad, I can control the installation of the files by the prefix-Variable in the recipes of the application programms. So the will be installed in /bin, which means /usr/local/bin in the device.
But the image contains the whole directory structure of a root filesystem. Is there any comfortable way to generate the reduced directory structure of the /usr/local directory? Or do I need to clean it up by myself in a IMAGE_POSTPROCESS_COMMAND?
Kind regards
It sounds like what you want is a package or package group and not an image.
An image is a full distribution installation, usually using the poky distro.
This is built-in to yocto and unavoidable, as all dependencies of your app will need to be in the image. (runtimes, supporting libs, basic linux env, etc.)
In your tmp/deploy/rpm or tmp/deploy/deb directory you should have packages related to your apps.
Something that may help organize is to create a package group to aggregate your applications.
If you look at your tmp/deploy/images/<machine>/<imagename>.manifest file you will notice that in addition to the packages you specified, some additional ones such as libc6 and base-files are included.
You can remove them by naming the packages in ROOTFS_RO_UNNEEDED. This variable is used to remove recipes such as shadow and run-postinsts which are processed when creating a read-only image. You can add the other undesirable recipes to this list until your manifest matches exactly the packages you want included.
For example:
# tested with Yocto 2.6
IMAGE_FSTYPES = "ext4"
IMAGE_INSTALL = "my-go-app"
inherit image
# Don't run ldconfig on the rootfs
LDCONFIGDEPEND = ""
# If not building an RO filesystem, you can force use of ROOTFS_RO_UNNEEDED
# but be aware of the other packages included in the variable by image.bbclass
FORCE_RO_REMOVE = "1"
# Use _append because image.bbclass includes other packages
ROOTFS_RO_UNNEEDED_append = "base-files base-files-lic \
bash bash-lic \
libc6 libc6-lic \
ncurses-libtinfo libtinfo5 \
opkg-utils-lic \
ncurses-terminfo-base ncurses-lic \
run-postinsts-lic \
"
The resulting filesystem I get looks like this:
tmp
├── etc
│ ├── shells.rpmsave
│ ├── timestamp
│ └── version
├── lost+found [error opening dir]
├── usr
│ ├── bin
│ │ └── my-go-app
│ ├── lib
│ │ └── go
│ │ └── pkg
│ │ └── linux_arm64_dynlink
│ │ └── libstd.so
│ └── share
│ ├── common-licenses
│ │ └── license.manifest
│ └── licenses
│ ├── go-runtime
│ │ ├── generic_BSD-3-Clause
│ │ └── LICENSE
│ └── my-go-app
└── var
├── cache
└── lib
There may still be a few files left to clean up using a postprocess function:
postprocess_partial_image() {
rm -f ${IMAGE_ROOTFS}/etc/shells.rpmsave
rm -rf ${IMAGE_ROOTFS}/var
}
ROOTFS_POSTPROCESS_COMMAND += "postprocess_partial_image; "
Related
I need to add debug mode (enable/disable a few kernel config) to a kernel recipe. The recipe resides under recipes-kernel.
We have this inside recipe linux-yocto-onl_5.10.bb:
...
SRC_URI += "\
git://git.yoctoproject.org/yocto-kernel-cache;type=kmeta;name=meta;branch=yocto-5.10;destsuffix=kernel-meta \
file://my-kmeta;type=kmeta;name=my-kmeta;destsuffix=my-kmeta
"
We have this directory structure inside recipe folder:
.
└── my-kmeta
├── bsp
│ ├── armel-iproc
│ │ ├── armel-iproc.cfg
│ │ ├── armel-iproc.scc
│ │ ├── ... (some patches)
│ │ ├── extraconfigs.cfg
│ │ └── extraconfigs_debug.cfg
└── ...
This is content of armel-iproc.scc:
define KMACHINE armel-iproc
define KTYPE standard
define KARCH arm
patch ...
kconf hardware armel-iproc.cfg
kconf non-hardware extraconfigs.cfg
I tried two solution without success:
First I've added another .scc file and appended it to SRC_URI of the recipe. Inside that scc file just added kconf extraconfigs_debug.cfg. after baking the recipe, the config file seems copied to the build directory, but inside the .config file in build directory the changes aren't applied.
The second approach is defining two recipes, one for release and another for debug, for this I need to have two .scc files: one armel-iproc.scc and the other is armel-iproc_debug.scc, the second included the first plus kconfing extraconfigs_debug.cfg. After baking the debug recipe (by including armel-iproc_debug.scc to SRC_URI), I got errors indicating that bsp/armel-iproc is not found.
I want to build two images with every Yocto bitbake command. One for development purposes, one for production releases. I currently control this by commenting the following lines from my application bb file.
# Extra image features required for debugging
IMAGE_INSTALL_append = " systemd-analyze"
IMAGE_INSTALL_append = " packagegroup-core-eclipse-debug"
EXTRA_IMAGE_FEATURES ?= "debug-tweaks"
If my image file is image.bb and I create an development image image-dev.bb how can I build both?
In my bblayers.conf I have included image.bb do I need to include image-dev.bb?
In image-dev.bb I do not want to copy and paste everything from image.bb, can I simply make this file contain:
SUMMARY = "image application dev"
LICENSE = "MIT"
IMAGE_LINGUAS = " "
require image.bb
# Extra image features required for debugging
IMAGE_INSTALL_append = " systemd-analyze"
IMAGE_INSTALL_append = " packagegroup-core-eclipse-debug"
EXTRA_IMAGE_FEATURES ?= "debug-tweaks"
My end goal is to place this into a Jenkins pipeline and archive the two SD card images.
Edited to add my tree output
.
├── busybox
│ ├── busybox
│ │ └── evcc_kernel_features.cfg
│ └── busybox_1.33.1.bbappend
├── helloworld
│ ├── files
│ │ ├── services
│ │ │ └── helloworld.service
│ │ └── src
│ │ └── app
│ │ ├── helloworld.c
│ │ └── helloworld.h
│ └── helloworld_0.1.bb
└── images
├── image.bb
├── image-dev.bb
└── image.inc
Edit 2
Reading the BitBake User Manual I need to move all common functionality to an image.inc file. Then include this in my image.bb and image-dev.bb files. I have done this. Now my image.inc file has my entire setup.
My image.bb is as follows:
SUMMARY = "application"
require evccapplicaion.inc
My image-dev.bb is as follows:
SUMMARY = "image application dev"
require evccapplicaion.inc
# Extra image features required for debugging
IMAGE_INSTALL_append = " systemd-analyze"
IMAGE_INSTALL_append = " packagegroup-core-eclipse-debug"
EXTRA_IMAGE_FEATURES ?= "debug-tweaks"
This gives me the error
image-dev.bb:3: Could not include required file image.inc
This confuses me as the bitbake user manual states that the .inc file should be in the same folder as your .bb files. Looking at my tree output above you can see that I have ensured this to be true.
Edit 3:
My issue was a typo! My official code base name is not image.bb and image-dev.bb but a slightly longer more complicated name. A name which I typed incorrectly. Pro Tip. Spell check!
I am using MV BlueFox3 camera on a RaspberryPi4 and I am trying to write a .bb recipe which is going to install the necessary software for the camera. A quick setup guide is on the manufacturer website, but I can not get the first part to work. So far, this is how my recipe looks:
SUMMARY = "Installs mvIMPACT Acquire base libraries"
DESCRIPTION = "This recipe installs mvIMPACT Acquire base libraries for all MATRIX VISION devices."
HOMEPAGE = "http://www.matrix-vision.de"
LICENSE_FLAGS = "EULA"
LICENSE_FLAGS_WHITELIST = "EULA"
LICENSE = "EULA"
LIC_FILES_CHKSUM = "file://${WORKDIR}/mvIMPACT_Acquire-ARM64-2.45.0/doc/EULA.txt;md5=f6f99507036166a5604b38e6df10f004"
PACKAGE_ARCH = "${MACHINE_ARCH}"
S = "${WORKDIR}"
SRC_URI = "file://mvGenTL_Acquire-ARM64_gnu-2.45.0.tgz"
TARGET = "arm64"
MVIA_SUBDIR = "opt/mvIMPACT_Acquire"
MVIA_LIB_SUBDIR = "lib"
TOOLKITS_LIB_SUBDIR = "Toolkits"
MV_DATA_DIR = "opt/mvIMPACT_Acquire/data"
do_install() {
# install mvIMPACT Acquire runtime binaries
install -m 0755 -d ${D}${base_prefix}/${MVIA_SUBDIR}/${MVIA_LIB_SUBDIR}
install -m 0755 -d ${D}${base_prefix}/${MVIA_SUBDIR}/${TOOLKITS_LIB_SUBDIR}
install -m 0755 -d ${D}${base_prefix}/${MVIA_SUBDIR}/${TOOLKITS_LIB_SUBDIR}/FreeImage3160/bin/Release/FreeImage/${TARGET}
oe_soinstall ${S}/mvIMPACT_Acquire-ARM64-${PV}/lib/${TARGET}/libmvDeviceManager.so.${PV} ${D}${base_prefix}/${MVIA_SUBDIR}/${MVIA_LIB_SUBDIR}
oe_soinstall ${S}/mvIMPACT_Acquire-ARM64-${PV}/lib/${TARGET}/libmvPropHandling.so.${PV} ${D}${base_prefix}/${MVIA_SUBDIR}/${MVIA_LIB_SUBDIR}
oe_soinstall ${S}/mvIMPACT_Acquire-ARM64-${PV}/Toolkits/expat/bin/${TARGET}/lib/*.so.* ${D}${base_prefix}/${MVIA_SUBDIR}/${TOOLKITS_LIB_SUBDIR}
install -m 0755 ${S}/mvIMPACT_Acquire-ARM64-${PV}/Toolkits/FreeImage3160/bin/Release/FreeImage/${TARGET}/*.so ${D}${base_prefix}/${MVIA_SUBDIR}/${TOOLKITS_LIB_SUBDIR}/FreeImage3160/bin/Release/FreeImage/${TARGET}
# set environment variables for mvIMPACT Acquire
install -m 0755 -d ${D}${sysconfdir}/profile.d
echo 'export MVIMPACT_ACQUIRE_DIR=/opt/mvIMPACT_Acquire' >> ${D}${sysconfdir}/profile.d/acquire.sh
echo 'export MVIMPACT_ACQUIRE_DATA_DIR=/opt/mvIMPACT_Acquire/data' >> ${D}${sysconfdir}/profile.d/acquire.sh
# set library search paths for the dynamic linker
install -m 0755 -d ${D}${sysconfdir}/ld.so.conf.d
echo '/opt/mvIMPACT_Acquire/lib' >> ${D}${sysconfdir}/ld.so.conf.d/acquire.conf
echo '/opt/mvIMPACT_Acquire/Toolkits' >> ${D}${sysconfdir}/ld.so.conf.d/acquire.conf
# set up logfiles
install -m 0755 -d ${D}${base_prefix}/${MV_DATA_DIR}/logs
install -m 0755 ${S}/mvIMPACT_Acquire-ARM64-${PV}/apps/mvDebugFlags.mvd ${D}${base_prefix}/${MV_DATA_DIR}/logs/
}
INHIBIT_PACKAGE_STRIP = "1"
INSANE_SKIP_${PN} += "dev-so \
already-stripped \
ldflags"
PACKAGES = "${PN} ${PN}-dev ${PN}-doc"
FILES_${PN} += "${base_prefix}/${MVIA_SUBDIR}/${MVIA_LIB_SUBDIR}/lib*.so.* \
${base_prefix}/${MVIA_SUBDIR}/${TOOLKITS_LIB_SUBDIR}/lib*.so.* \
${base_prefix}/${MVIA_SUBDIR}/${TOOLKITS_LIB_SUBDIR}/FreeImage3160/bin/Release/FreeImage/${TARGET}/lib*.so \
${sysconfdir}/profile.d/*.sh \
${sysconfdir}/ld.so.conf.d/*.conf"
FILES_${PN}-dev += "${base_prefix}/${MVIA_SUBDIR}/${MVIA_LIB_SUBDIR}/lib*.so \
${base_prefix}/${MVIA_SUBDIR}/${TOOLKITS_LIB_SUBDIR}/lib*.so"
FILES_${PN}-doc += "${base_prefix}/${MV_DATA_DIR}/logs"
but I am getting the following error:
NOTE: Executing Tasks
ERROR: mvimpact-acquire-base-2.45.0-r0 do_package: QA Issue: File '/opt/mvIMPACT_Acquire/Toolkits/FreeImage3160/bin/Release/FreeImage/arm64/libfreeimage-3.16.0.so' from mvimpact-acquire-base was already stripped, this will prevent future debugging! [already-stripped]
ERROR: mvimpact-acquire-base-2.45.0-r0 do_package: QA Issue: File '/opt/mvIMPACT_Acquire/Toolkits/libexpat.so.1.6.0' from mvimpact-acquire-base was already stripped, this will prevent future debugging! [already-stripped]
ERROR: mvimpact-acquire-base-2.45.0-r0 do_package: QA Issue: File '/opt/mvIMPACT_Acquire/lib/libmvDeviceManager.so.2.45.0' from mvimpact-acquire-base was already stripped, this will prevent future debugging! [already-stripped]
ERROR: mvimpact-acquire-base-2.45.0-r0 do_package: QA Issue: File '/opt/mvIMPACT_Acquire/lib/libmvPropHandling.so.2.45.0' from mvimpact-acquire-base was already stripped, this will prevent future debugging! [already-stripped]
ERROR: mvimpact-acquire-base-2.45.0-r0 do_package: QA Issue: mvimpact-acquire-base: Files/directories were installed but not shipped in any package:
/opt
/opt/mvIMPACT_Acquire
/opt/mvIMPACT_Acquire/Toolkits
/opt/mvIMPACT_Acquire/lib
/opt/mvIMPACT_Acquire/data
/opt/mvIMPACT_Acquire/Toolkits/libexpat.so
/opt/mvIMPACT_Acquire/Toolkits/libexpat.so.1.6.0
/opt/mvIMPACT_Acquire/Toolkits/libexpat.so.1
/opt/mvIMPACT_Acquire/Toolkits/FreeImage3160
/opt/mvIMPACT_Acquire/Toolkits/FreeImage3160/bin
/opt/mvIMPACT_Acquire/Toolkits/FreeImage3160/bin/Release
/opt/mvIMPACT_Acquire/Toolkits/FreeImage3160/bin/Release/FreeImage
/opt/mvIMPACT_Acquire/Toolkits/FreeImage3160/bin/Release/FreeImage/arm64
/opt/mvIMPACT_Acquire/Toolkits/FreeImage3160/bin/Release/FreeImage/arm64/libfreeimage-3.16.0.so
/opt/mvIMPACT_Acquire/lib/libmvPropHandling.so
/opt/mvIMPACT_Acquire/lib/libmvDeviceManager.so.2.45.0
/opt/mvIMPACT_Acquire/lib/libmvDeviceManager.so.2
/opt/mvIMPACT_Acquire/lib/libmvDeviceManager.so
/opt/mvIMPACT_Acquire/lib/libmvPropHandling.so.2.45.0
/opt/mvIMPACT_Acquire/lib/libmvPropHandling.so.2
/opt/mvIMPACT_Acquire/data/logs
/opt/mvIMPACT_Acquire/data/logs/mvDebugFlags.mvd
Please set FILES such that these items are packaged. Alternatively if they are unneeded, avoid installing them or delete them within do_install.
mvimpact-acquire-base: 22 installed and not shipped files. [installed-vs-shipped]
ERROR: mvimpact-acquire-base-2.45.0-r0 do_package: Fatal QA errors found, failing task.
ERROR: Logfile of failure stored in: /home/stefan/Projects/raspberrypiOS/build/tmp/work/raspberrypi4_64-poky-linux/mvimpact-acquire-base/2.45.0-r0/temp/log.do_package.2280592
ERROR: Task (/home/stefan/Projects/raspberrypiOS/meta-mvimpact-acquire/recipes-mvimpactacquire/mvimpact-acquire/mvimpact-acquire-base_2.45.0.bb:do_package) failed with exit code '1'
I am guessing that I should change the FILES variable to ensure proper package splitting but I do not know how. I have tried adding the directories and files from the error message, but no matter what I do, the error message seems to be the same (22 packages).
In the workdir, the image and package folders seem to be identical, and the package-split folder contains mvimpact-acquire-base (with only the /etc folder inside, but no /opt), while the mvimpact-acquire-base-dev, mvimpact-acquire-base-doc, mvimpact-acquire-base-src folders are all empty.
Can anyone help me understand this problem better or suggest a potential solution regarding the FILES variable and the error message.
I think the other error messages about stripping are not at issue here, but if you can share additional info it would be great.
Below are the contents of some WORKDIR(/work/raspberrypi4_64-poky-linux/mvimpact-acquire-base/2.45.0-r0) subdirectories.
image/
├── etc
│ ├── ld.so.conf.d
│ │ └── acquire.conf
│ └── profile.d
│ └── acquire.sh
└── opt
└── mvIMPACT_Acquire
├── data
│ └── logs
│ └── mvDebugFlags.mvd
├── lib
│ ├── libmvDeviceManager.so -> libmvDeviceManager.so.2.45.0
│ ├── libmvDeviceManager.so.2 -> libmvDeviceManager.so.2.45.0
│ ├── libmvDeviceManager.so.2.45.0
│ ├── libmvPropHandling.so -> libmvPropHandling.so.2.45.0
│ ├── libmvPropHandling.so.2 -> libmvPropHandling.so.2.45.0
│ └── libmvPropHandling.so.2.45.0
└── Toolkits
├── FreeImage3160
│ └── bin
│ └── Release
│ └── FreeImage
│ └── arm64
│ └── libfreeimage-3.16.0.so
├── libexpat.so -> libexpat.so.1.6.0
├── libexpat.so.1 -> libexpat.so.1.6.0
└── libexpat.so.1.6.0
14 directories, 13 files
package/
├── etc
│ ├── ld.so.conf.d
│ │ └── acquire.conf
│ └── profile.d
│ └── acquire.sh
└── opt
└── mvIMPACT_Acquire
├── data
│ └── logs
│ └── mvDebugFlags.mvd
├── lib
│ ├── libmvDeviceManager.so -> libmvDeviceManager.so.2.45.0
│ ├── libmvDeviceManager.so.2 -> libmvDeviceManager.so.2.45.0
│ ├── libmvDeviceManager.so.2.45.0
│ ├── libmvPropHandling.so -> libmvPropHandling.so.2.45.0
│ ├── libmvPropHandling.so.2 -> libmvPropHandling.so.2.45.0
│ └── libmvPropHandling.so.2.45.0
└── Toolkits
├── FreeImage3160
│ └── bin
│ └── Release
│ └── FreeImage
│ └── arm64
│ └── libfreeimage-3.16.0.so
├── libexpat.so -> libexpat.so.1.6.0
├── libexpat.so.1 -> libexpat.so.1.6.0
└── libexpat.so.1.6.0
14 directories, 13 files
packages-split/
├── mvimpact-acquire-base
│ └── etc
│ ├── ld.so.conf.d
│ │ └── acquire.conf
│ └── profile.d
│ └── acquire.sh
├── mvimpact-acquire-base-dev
├── mvimpact-acquire-base-doc
└── mvimpact-acquire-base-src
7 directories, 2 files
The issue was new BitBake syntax. I changed the following lines:
INSANE_SKIP_${PN} += "dev-so
FILES_${PN} += "${base_prefix}/${MVIA_SUBDIR}/${MVIA_LIB_SUBDIR}/lib*.so.* \
${base_prefix}/${MVIA_SUBDIR}/${TOOLKITS_LIB_SUBDIR}/lib*.so.* \
${base_prefix}/${MVIA_SUBDIR}/${TOOLKITS_LIB_SUBDIR}/FreeImage3160/bin/Release/FreeImage/${TARGET}/lib*.so \
${sysconfdir}/profile.d/*.sh \
${sysconfdir}/ld.so.conf.d/*.conf"
to
INSANE_SKIP:${PN} += "dev-so
FILES:${PN} += "${base_prefix}/${MVIA_SUBDIR}/${MVIA_LIB_SUBDIR}/lib*.so.* \
${base_prefix}/${MVIA_SUBDIR}/${TOOLKITS_LIB_SUBDIR}/lib*.so.* \
${base_prefix}/${MVIA_SUBDIR}/${TOOLKITS_LIB_SUBDIR}/FreeImage3160/bin/Release/FreeImage/${TARGET}/lib*.so \
${sysconfdir}/profile.d/*.sh \
${sysconfdir}/ld.so.conf.d/*.conf"
So basically, instead of underscores it now uses colons.
During experiments with Yocto's Advanced Kernel Metadata I got into a situation where I would like to have the .scc, .patch and .cfg files organized into a directory structure as mentioned in the syntax section, and to keep that structure in all the layers (consider 2 layers here - meta-main_layer and meta-bsp_layer):
meta-main_layer
└── recipes-kernel
└── linux
└── linux-yocto.bb
└── linux-yocto
├── cfg
│ ├── main_frag_1.cfg
│ └── main_frag_1.scc
├── features
│ ├── main_feature_1.cfg
│ ├── main_feature_1.patch
│ └── main_feature_1.scc
└── patches
├── main_patch_1.patch
└── main_patch_1.scc
meta-bsp_layer
└── recipes-kernel
└── linux
└── linux-yocto.bbappend
└── linux-yocto
├── bsp
│ └── bsp_definition.scc
├── cfg
│ ├── bsp_frag_1.cfg
│ └── bsp_frag_1.scc
├── features
│ ├── bsp_feature_1.cfg
│ ├── bsp_feature_1.patch
│ └── bsp_feature_1.scc
└── patches
├── bsp_patch_1.patch
└── bsp_patch_1.scc
meta-main_layer/recipes-kernel/linux/linux-yocto.bb contains:
FILESEXTRAPATHS_prepend := "${THISDIR}:"
...
SRC_URI = "file://linux-yocto;type=kmeta \
"
Edit:
And meta-bsp_layer/recipes-kernel/linux/linux-yocto.bbappend:
FILESEXTRAPATHS_prepend := "${THISDIR}:"
...
SRC_URI += " file://linux-yocto;type=kmeta \
"
... end of edit
This means that after parsing the recipes, the SRC_URI will contain file://linux-yocto;type=kmeta twice, and FILESEXTRAPATHS=meta-bsp_layer/recipes-kernel/linux:meta-main_layer/recipes-kernel/linux:. The way I understand it, the do_unpack() task goes through the files in SRC_URI and for each of them, it searches FILESEXTRAPATHS for that file, and it takes the first one it finds. That means that in my case, only the files from meta-bsp_layer are taken, as its path is the first in FILESEXTRAPATHS, and the files from the meta-main_layer are ignored.
What I would like to achieve is that instead of taking the files from only the first path found in FILESEXTRAPATHS, do_unpack() would go through all of the paths in FILESEXTRAPATHS and merge the directories of the same name (cfg, features and patches) from both layers. Without that, I don't see any big benefits of using the Advanced Kernel Metadata mechanism. Could anyone advise how to get this done?
PS: I'm using Yocto Zeus.
I have downloaded a rpm in my ansible-playbook:
(djangoenv)~/P/c/apache-installer ❯❯❯ tree .
.
├── defaults
│ └── main.yml
├── files
│ ├── apache2latest.tar
│ ├── httpd_final.conf
│ ├── httpd_temp.conf
│ └── sshpass-1.05-9.1.i686.rpm
├── handlers
│ └── main.yml
├── hosts
├── meta
│ └── main.yml
├── README.md
├── tasks
│ └── main.yml
├── templates
├── tests
│ ├── inventory
│ └── test.yml
└── vars
└── main.yml
My question is why can't I just install it using:
- yum: name=files/sshpass-1.05-9.1.i686.rpm
? It complains that files/sshpass-1.05-9.1.i686.rpm is not found in the system. Now I am doing it in two steps:
- copy: src=files/sshpass-1.05-9.1.i686.rpm dest=/tmp/sshpass-1.05-9.1.i686.rpm force=no
- yum: name=/tmp/sshpass-1.05-9.1.i686.rpm state=present
No, there is no simple way around coping the package to the remote host before installing. Ansible yum module expects a local file when you define a file in the name parameter.
IMHO it is not a good idea to keep packages inside the Ansible code base. Because they are binary and not exactly part of the actual Ansible code. It would be cleaner to setup a private repository and store those files there. That is the only way around coping a package in this situation I'm aware of.