In Yocto, how to include header files from another recipes - yocto

My program depends on the poco recipes, which provides both the header files and shared libraries. However, I cannot make use of the header files from poco in my recipe, which leads to the error Poco/Delegate.h: No such file for directory.
How do I make the header available at build time for my software package?
Here is an example recipe:
SUMMARY = ""
DESCRIPTION = ""
AUTHOR = ""
LICENSE = "CLOSED"
LIC_FILES_CHKSUM = ""
HOMEPAGE = ""
BUGTRACKER = ""
S = "${WORKDIR}"
SRC_URI = " file://foo.cpp \
file://CMakeLists.txt \
"
inherit pkgconfig cmake
DEPENDS_foo = "poco"
RDEPENDS_foo = "poco"
do_install() {
install -d ${D}/${bindir}
install -m 755 ${S}/foo ${D}/${bindir}
}
FILES_${PN} = "${bindir}/foo"

We can use provider and user to illustrate this case, the package (recipe) provides a header file to be used by another package (recipe) is the provider, the package (recipe) use a header file from another package (recipe) is the user.
First we change the provider's recipe (myprovider.bb) to export the header file -- myapi.h,
...
do_install() {
install -d ${D}/${bindir}
install -m 755 ${B}/hello_provider ${D}/${bindir}
install -d ${D}${libdir}/lib_myprovider/
install -m 0755 ${WORKDIR}/myapi.h ${STAGING_DIR_TARGET}${libdir}/lib_myprovider/
}
...
Secondly we change the user's recipe (myuser.bb) to refer the header file -- myapi.h
...
do_compile () {
${CC} ${WORKDIR}/main.c -o hello_user ${CFLAGS} ${LDFLAGS} -I${STAGING_DIR_TARGET}/${libdir}/lib_myprovider/
}
# file dependency declaration
FILES_${PN} = "${libdir}/lib_myprovider"
# package dependency declaration
DEPENDS += "myprovider"
...
At last, rebuild myprovider.bb and myuser.bb recipes, it should work.

Manual recommends:
Recipes should never populate the sysroot directly:
Recommended way is (poco recipe should do something similar):
Files should be installed into standard locations:
...
do_install() {
...
install -d ${D}${includedir}
install -m 0755 ${S}/myapi.h ${D}${includedir}/
...
}
...
Than, include poco recipe as a build dependency of foo.bb :
DEPENDS += "poco"
And compile normally.

You could use DEPENDS to have dependency with "poco" recipe and it would build and populate "poco" recipe's headers and libs into your recipe's sysroot.
Similar way you have to mention the export paths in the provider's recipe with FILES_*( * - package type)

Related

No bb files found in layer

I am new to Yocto and doing some starter projects. I have added my own layer called meta-tutorial .
I have the following recipe file inside my layer at meta-tutorial/recipe-example/hello/hello_1.0.bb
DESCRIPTION = "Simple helloworld application"
LICENSE = "MIT"
LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MIT;md5=0835ade698e0bcf8506ecda2f7b4f302"
SRC_URI = "file://hello.c"
S = "${WORKDIR}"
do_compile() {
${CC} hello.c ${LDFLAGS} -o hello
}
do_install() {
install -d ${D}${bindir}
install -m 0755 hello ${D}${bindir}
}
The hello.c source file is located at meta-tutorial/recipe-example/hello/files/hello.c
When I source the oe-init-build-env script , and try to build my recipe as follows bitbake hello_1.0.bb, I encounter the following issues :
WARNING: No bb files in default matched BBFILE_PATTERN_meta-tutorial '^/home/Yocto-test/poky/meta-tutorial/'
ERROR: Nothing PROVIDES 'hello_1.0.bb'
What is the problem here exactly, it's not clear?
A Yocto layer have a configuration file that describes where to look for recipes .bb and recipes append files .bbappend:
meta-tutorial/conf/layer.conf:
...
BBFILES += "${LAYERDIR}/recipes-*/*/*.bb ${LAYERDIR}/recipes-*/*/*.bbappend"
^
|
(Look closely)-----------------
...
so, your mistake is that you put your recipe under the path:
meta-tutorial/recipe-example/hello
^
|
(The mistake)-------
So, your recipe should be under:
meta-tutorial/recipes-example/hello
^
|
(Correction)---------

Yocto: Create a New Directory in etcdir

I am new to Yocto,
I want to create a directory in /etc and copy my server certificates into that directory. I tried doing below, But it it not creating any directory in /etc, however i am not getting any compilation error:
DESCRIPTION = "OC sample service"
SUMMARY = "Install and start a systemd service and copy server certificates"
LICENSE = "MIT"
SRC_URI = "file://service.tar.gz"
inherit systemd
S = "${WORKDIR}/service"
SYSTEMD_PACKAGES = "${PN}"
SYSTEMD_SERVICE_${PN} = "sample.service"
SYSTEMD_AUTO_ENABLE = "enable"
INSANE_SKIP_${PN} += "installed-vs-shipped"
do_configure() {
:
}
do_compile() {
:
}
do_install() {
install -d ${D}${systemd_unitdir}/system
install -m 0755 ${S}/sample.service ${D}${systemd_unitdir}/system
mkdir -p ${D}${etcdir}/oc_certs
install -m 0755 ${S}/certs/* ${D}${etcdir}/oc_certs
}
FILES_${PN} = "${systemd_unitdir}/system
"
Now the problem is, sample.service is successfully being placed to the location but /etc/oc_certs is not being created.
In addition to LetoThe2nd's answer: the ${etcdir} variable is usually empty. If you want a variable for /etc, it is ${sysconfdir}. So your files are probably installed to root directory.
Check output of bitbake -e <your_recipe> and try to find etcdir to verify.
Also drop INSANE_SKIP_${PN} += "installed-vs-shipped" which hides the error your are trying to find (you will see what is installed where but not shipped).
BTW LetoThe2nd's answer is also needed, because you are overwriting (instead of appending FILES_${PN}, otherwise it wouldn't be needed. The ${sysconfdir} is already part of FILES_${PN}.
"Not working" is a rather bad error description, but the most probable issue is that it does not get included in the image. This is because bitbakes packaging mechanisms do not know about that directory, so add it with:
FILES_${PN} += "${etcdir}/oc_certs"
If you need further assistance, please extend your question with a precise error description, respectively the corresponding log.
You are missing a / after ${D}. To create a directory say mydir in your /etc folder, just add the following code in the do_install() of your recipe.
do_install() {
install -d ${D}/etc/mydir
}

systemd yocto recipe for an existing executable

I'm looking for a template recipe for enabling a systemd recipe in yocto. The executable is already installed by a recipe provided by yocto. The goal of this recipe is to provide make /usr/bin/btattach be run at startup.
As a start I created the following structure in my layer in the appropriate recipe directory:
btattach-systemd/
|-- files
| `-- btattach.service
`-- btattach-systemd.bb
The content of the recipe
SUMMARY = "Writes patterns to the fb device"
LICENSE = "MIT"
LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MIT;md5=0835ade698e0bcf8506ecda2f7b4f302"
inherit systemd
REQUIRED_DISTRO_FEATURES= "systemd"
SRC_URI = "file://btattach.service"
S = "${WORKDIR}"
do_install () {
install -m 0644 ${WORKDIR}/btattach.service.service ${D}${sysconfdir}/systemd/system
}
SYSTEMD_SERVICE_${PN} = "btattach.service"
Besides that, the IMAGE_INSTALL in the image recipe has been correctly extended with btattach-systemd.
bitbake btattach-systemd runns ok but when trying to build the complete image the at do_rootfs step for the whole image. with the error:
* opkg_solver_install: Cannot install package btattach-systemd.
Ideas on where the bug is?
I think the recipe should look like this (leaving out summary, license, license checksum, and assuming that the binary package is called "btattach"):
SRC_URI = "file://btattach.service"
SYSTEMD_SERVICE_${PN} = "btattach.service"
inherit systemd
do_install_append() {
install -d ${D}${systemd_unitdir}/system
for service in ${SYSTEMD_SERVICE_${PN}}; do
install -m 0644 ${WORKDIR}/${service} ${D}${systemd_unitdir}/system/
sed -i -e 's,#BINDIR#,${bindir},g' ${D}${systemd_unitdir}/system/${service}
done
}
RDEPENDS_${PN} = "btattach"
I am sorry for not commenting your question as I have no reputation for that. Also, LetoThe2nd answer is more complete than mine, but here follows a possible quick fix:
It seems to me you are installing 'btattach.service.service' instead of 'btattach.service'.
Assuming that the .service file is correct, my take on the Yocto recipe and why it might be failing is because that the btattach.service file isn't included with the installation which is what the final line does below.
Have you ensured that you do a bitbake btattach.systemd -c cleanall and bitbake btattach.systemd -c cleanstate beforehand as well, as I noticed you had a typo in the Yocto recipe as btattach.service.service.
SUMMARY = "Writes patterns to the fb device"
LICENSE = "MIT"
LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MIT;md5=0835ade698e0bcf8506ecda2f7b4f302"
inherit systemd
REQUIRED_DISTRO_FEATURES= "systemd"
SRC_URI = "file://btattach.service"
S = "${WORKDIR}"
do_install () {
install -m 0644 ${WORKDIR}/btattach.service ${D}${sysconfdir}/systemd/system
}
SYSTEMD_SERVICE_${PN} = "btattach.service"
FILES_${PN} += "/lib/systemd/system/btattach.service"

Simple installation of native script for use in other recipe

I need to install a native script, call it foo, in one recipe (foo-native) and then use it in the do_compile step of another (target) recipe - call it bar.
My (minimal) native recipe
SRC_URI = "file://foo"
LICENSE = "CLOSED"
inherit native
BBCLASSEXTEND = "native"
S = "${WORKDIR}"
do_compile() {
:
}
do_install() {
install -d ${D}/usr/bin
install ${WORKDIR}/foo ${D}/usr/bin
}
The script, foo, exists in a directory called files which resides next to the recipe. i.e.
foo/
├── files
│   └── foo
└── foo.bb
My target recipe for bar
SRC_URI = ""
LICENSE = "CLOSED"
DEPENDS = "foo-native"
do_fetch[noexec] = "1"
do_configure[noexec] = "1"
do_compile() {
foo >myfile.json
}
do_install() {
install -d ${D}/etc
install ${WORKDIR}/myfile.json ${D}/etc
}
The error I get is in the do_compile task of bar, and it simply says that foo can not be found (i.e. has not been installed into a directory on the path).
First, you don't need the line
inherit native
in foo.bb. It's taken care of for you by BBCLASSEXTEND = "native".
Secondly, change your do_install to:
do_install() {
install -d ${D}${bindir}
install ${WORKDIR}/foo ${D}${bindir}
}
Note: use ${bindir} instead of /usr/bin. ${bindir} is determined using ${prefix}, which in turn is changed e.g. when building a -native version of a recipe.

How do I add script files to a Raspberry Pi filesystem using a custom Yocto recipe?

I have a working Yocto image for a RaspberryPi3. I want to add 3 script files /etc/ppp/peers/. I would have thought that adding non-compiled files to the root file-system was a fairly generic thing to do but the only examples I can find are using compiled files and inheriting the autotools recipe.
Is there an example of how to add text files or script files to a Yocto root filesystem this somewhere?
Either a How To write up or an existing recipe that takes a set of text files and places them onto the target's rootfs.
I must be missing something because I cannot get the file files onto the system.
I tried using do_deploy, but that puts files into my ../tmp/deploy/images/raspberrypi3/etc/ppp/ which would be helpful for scripts to aid in image deployment. It is not what I want though as the scripts need to be on the target.
Running a do_install() with or without a blank do_compile() has not resulted in things getting onto the target either. Unless there is something about using ${sysconfdir} or ${IMAGE_ROOTFS} or ${S} or ${D} or ${DEPLOYDIR} or ${WORKDIR} which is particular to the Pi. I'd provide an example of my script but having changed it so many times in the last two days there is not much worth of sharing just one iteration.
Anything that resembles the following with;
${IMAGE_ROOTFS} possibly substituted for ${D} or missing
do_install replaced with do_deploy.
There are probably other permutations that I have tried.
#
# Copy the ppp script files for <vendor> chips to the target filesystem
# These files are based on the details provided in
#
SUMMARY = "PPP Scripts for ..."
SECTION = "net"
LICENSE = "MIT"
LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MIT;md5=0835ade698e0bcf8506ecda2f7b4f302"
DESCRIPTION = "A set of Linux PPP scripts blar blar"
RDEPENDS_${PN} = "ppp"
SRC_URI += "file://<provider>-ppp"
SRC_URI += "file://<provider>-chat-connect"
SRC_URI += "file://<provider>-chat-disconnect"
S = "${WORKDIR}"
#PACKAGES =+ "${PN} ${PN}-staticdev"
#DEPLOYDIR = "${WORKDIR}/deploy-${PN}"
#D = "${DEPLOYDIR}"
inherit allarch
# Install script on target's root file-system
do_install () {
# Install init script and default settings
install -d ${IMAGE_ROOTFS}${sysconfdir}
install -d ${IMAGE_ROOTFS}${sysconfdir}/ppp/
install -d ${IMAGE_ROOTFS}${sysconfdir}/ppp/peers/
install -m 0755 ${S}/<provider>-ppp ${IMAGE_ROOTFS}${sysconfdir}/ppp/peers/
install -m 0755 ${S}/<provider>-chat-connect ${IMAGE_ROOTFS}${sysconfdir}/ppp/peers/
install -m 0755 ${S}/<provider>-chat-disconnect ${IMAGE_ROOTFS}${sysconfdir}/ppp/peers/
}
# Mark the files which are part of this package
FILES_${PN} += "${sysconfdir}/ppp/"
FILES_${PN} += "${sysconfdir}/ppp/peers/"
FILES_${PN} += "${sysconfdir}/ppp/peers/<provider>-ppp"
FILES_${PN} += "${sysconfdir}/ppp/peers/<provider>-chat-connect"
FILES_${PN} += "${sysconfdir}/ppp/peers/<provider>-chat-disconnect"
I can find a lot of helloworld.c and automate examples. There must be some basic ones for adding scripts somewhere? My googlefu is very weak, I blame a lingering cold.
You should be using install -m 0755 ${WORKDIR}/<provider>-ppp ${D}${sysconfdir}/ppp/peer in your recipe. Have you added the resulting package to your image recipe? You could look at ${WORKDIR}/packages-split/${PN} to confirm that your files have been properly packaged.