I have a package (openssl) that must be built for the host and the target. It creates some .so and .a libraries that some other packages need for runtime and compilation time respectively.
When I compile this package for the target everything works fine and every file ends up in the place I tell it to go, but when I compile for the host (${PN}-native target) it just doesn't put the libraries in the host sysroot directory (./build/tmp/sysroot/x86_64-linux).
This is the recipe:
SUMMARY = "Secure Socket Layer"
SECTION = "libs/network"
LICENSE = "openssl"
LIC_FILES_CHKSUM = "file://LICENSE;md5=4004583eb8fb7f89"
branch = "yocto"
SRC_URI = "git://www.myserver.com/openssl.git;protocol=ssh;branch=${branch}"
SRCREV = "${AUTOREV}"
S = "${WORKDIR}/git"
BBCLASSEXTEND += "native nativesdk"
# This is because I am porting this package from other project and I can't modify it.
FILES_${PN} += "${libdir}/libssl.so ${base_libdir}/libcrypto.so"
FILES_SOLIBSDEV = ""
do_compile() {
${MAKE}
}
do_install() {
DESTDIR=${D} ${MAKE} install
}
Could anyone let me know what I am doing wrong? Thanks in advance
First, why are you writing your own recipe for openssl instead of using the one in oe-core?
Anyway the problem is that at no point do you tell the recipe what prefix to use. In native builds the prefix is what relocates the package correctly into the native sysroot.
Ok, I know what the problem is:
It seems like for native recipes, you have to install it using the full path to your host sysroot inside the image folder. This means that when compiling for the target, the image folder looks like this:
$ tree -d
/openssl/1.0.0-r0/image
├── lib
└── usr
├── include
│ └── openssl
└── lib
but for the host, it looks like this in my case:
$ tree -d
openssl-native/1.0.0-r0/image
└── home
└── xnor
└── yocto
└── build
└── tmp
└── sysroots
└── x86_64-linux
├── lib
└── usr
├── include
│ └── openssl
└── lib
EDIT
The right solution is to modify the Makefile to take ${prefix}, ${bindir}, ${libdir}, etc. from the environment instead of hardcoding those paths in the Makefile. In my case this is not possible because of the project requirements, so I have to do this:
SUMMARY = "Secure Socket Layer"
SECTION = "libs/network"
LICENSE = "openssl"
LIC_FILES_CHKSUM = "file://LICENSE;md5=4004583eb8fb7f89"
branch = "yocto"
SRC_URI = "git://www.myserver.com/openssl.git;protocol=ssh;branch=${branch}"
SRCREV = "${AUTOREV}"
S = "${WORKDIR}/git"
BBCLASSEXTEND += "native nativesdk"
# This is because I am porting this package from other project and I can't modify it.
FILES_${PN} += "${libdir}/libssl.so ${base_libdir}/libcrypto.so"
FILES_SOLIBSDEV = ""
do_compile() {
${MAKE}
}
do_install() {
# The change is here!
DESTDIR=${D}${base_prefix} ${MAKE} install
}
and as you can imagine, ${base_prefix} expands to "/home/xnor/yocto/build/tmp/sysroots/x86_64-linux/" for the host (openssl-native) recipe and to "" for the target (openssl).
Related
I'm a neophyte with Yocto, though I have been able to glean enough from tutorials to create an image that meets some of the requirements for my current project. I'm able to create my own layer and recipe so I can generate it with bitbake, e.g. bitbake mycustomimage.
I'm working with a beaglebone and the tutorials I've followed state you need the following layers:
meta-arm
meta-ti
poky (of course)
Just following the beagelbone tutorials will allow you to create a variety of prepackaged images from default recipes. However, tutorials and Yocto documentation do not explain how to access features and applications contained in the existing layers but are not utilized by the default recipes. I'm aware that you can use the IMAGE_FEATURE and EXTRA_IMAGE_FEATURE variables to add some (prepackaged) support.
I've come up with a way to add features from other layers by copying them into my custom layer directory structure and adding them to my customimage.bb file. This technique feels hacky and potentially error prone, also it duplicates files and directories found in other layers. My question is:
How are you supposed to add features from existing layers added to your project? For example I'll be needing PRU support for my beaglebone project, I know where those features are in the meta-ti layer (found in the recipes-bsp/ directory). How can I access that support and those features without a stupid hack? There must be a way.
Here's an example. I needed xorg-minimal-fonts installed, the recipe is contained in the poky/meta/recipes-graphics directory. I copied the contents into my custom layer which looks something like this:
mycustomimage
├── conf
│ └── layer.conf
└── recipes-core
├── images
│ └── core-image-mycustomimage.bb
└── xorg-font
├── encodings
│ └── nocompiler.patch
├── encodings_1.0.5.bb
├── font-alias-1.0.3
│ └── nocompiler.patch
├── font-alias_1.0.3.bb
├── font-util_1.3.2.bb
├── xorg-font-common.inc
├── xorg-minimal-fonts
│ └── misc
│ ├── 6x13B-ISO8859-10.pcf.gz
...(a bunch of zipped fonts)
│ ├── cursor.pcf.gz
│ └── fonts.dir
└── xorg-minimal-fonts.bb
My custom layer .bb file looks like this:
IMAGE_FEATURES_append = " x11-base ssh-server-dropbear hwcodecs"
IMAGE_FEATURES_remove = "allow-empty-password"
IMAGE_FEATURES_remove = "empty-root-password"
require recipes-core/xorg-font/xorg-minimal-fonts.bb
IMAGE_INSTALL = "\
packagegroup-core-boot \
packagegroup-core-full-cmdline \
${CORE_IMAGE_EXTRA_INSTALL} \
xorg-minimal-fonts \
"
inherit core-image extrausers
I know this is not how you're supposed do this, but it did work.
If you have a custom layer with a custom image, you can add any recipe that is in other layer.
If you copied xorg-font folder for that reason, it means that you need to copy all folders also of what you set in IMAGE_INSTALL.
You do not need to require the xorg-minimal-fonts recipe in the image recipe.
Also, IMAGE_INSTALL = .. will override the IMAGE_INSTALL of core-image class, so here is your custom image after some fixes:
# Inherit core-image because it already has:
#
# CORE_IMAGE_BASE_INSTALL = '\
# packagegroup-core-boot \
# packagegroup-base-extended \
# \
# ${CORE_IMAGE_EXTRA_INSTALL} \
# '
# ...
# IMAGE_INSTALL ?= "${CORE_IMAGE_BASE_INSTALL}"
inherit core-image extrausers
# Activate features
#
# Activate x11-base only if x11 is in DISTRO_FEATURES
IMAGE_FEATURES_append = " ${#bb.utils.contains('DISTRO_FEATURES', 'x11', 'x11-base', '', d)}"
IMAGE_FEATURES_append = " ssh-server-dropbear hwcodecs"
IMAGE_FEATURES_remove = "allow-empty-password"
IMAGE_FEATURES_remove = "empty-root-password"
# Add custom recipes
IMAGE_INSTALL_append = " xorg-minimal-fonts"
I'm trying to unpack .tar.gz file to my root during the building system, but it doesn't work because of an unclear reason for me. I did it in the same way as other recipes in my meta (which works fine), but in this case, I have an empty directory in the target system root. The recipe has the same name as tar.gz.
Based on Yocto Project Documentation and my other experience it should work fine. I tried to remove manually tmp, sstate-cache directories and rebuild system, but it doesn't change anything. The recipe is building, but the /my-app is empty. Can I force extract my archive?
Tree file:
├── meta-my
│ └── recipe-my-app-files
│ └── my-app
| └── my-app.bb
│ └── files
│ ├── my-app.tar.gz
....
my-app.bb
DESCRIPTION = "My Application package preinstall"
FILESEXTRAPATHS_prepend := "${THISDIR}/files:"
LICENSE = "MIT"
LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MIT;md5=0835ade698e0bcf8506ecda2f7b4f302"
RDEPENDS_my-app="bash qtdeclarative qtbase"
DEPENDS = "bash"
FILES_${PN} += "/my-app"
SRC_URI = "file://my-app.tar.gz"
BB_STRICT_CHECKSUM = "0"
S = "${WORKDIR}"
do_install() {
# Create directories
install -d ${D}/my-app
}
As mentionned in the link you provided that:
The unpack call automatically decompresses and extracts files with
".Z", ".z", ".gz", ".xz", ".zip", ".jar", ".ipk", ".rpm". ".srpm",
".deb" and ".bz2" extensions as well as various combinations of
tarball extensions.
it extracts .gz automatically into ${WORKDIR}.
The issue with your recipe is that you are creating /my-app but not filling it with any content.
Keep in mind that the compressed file is unpacked under ${WORKDIR}, so install it into ${D}/my-app:
do_install(){
# Create directories
install -d ${D}/my-app
# Install unpacked application
# install -m 0755 app ${D}/my-app
# ...
}
I do not know the content of your application, so change that according to it.
I wrote a basic hello world recipe
DESCRIPTION = "Simple helloworld C application"
LICENSE = "MIT"
LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MIT;md5=0835ade698e0bcf8506ecda2f7b4f302"
SRC_URI = "file://userprog.c file://ReadMe.txt"
S = "${WORKDIR}"
do_compile() {
${CC} -DUSE_SYSCALL userprog.c ${LDFLAGS} -o userprog
}
do_install() {
install -d ${D}${bindir}
install -m 0755 userprog ${D}${bindir}
install -d ${D}${docdir}
install -m 0644 ReadMe.txt ${D}${docdir}
}
After, looking at the WORKDIR, the contents of 'package' and 'image' folder are same.
$ tree image/
image/
└── usr
├── bin
│ └── userprog
└── share
└── doc
└── ReadMe.txt
$ tree package
package
└── usr
├── bin
│ └── userprog
└── share
└── doc
└── ReadMe.txt
What is the difference between both folders, I know image folder is controlled in do_install task, what about in package folder?
images/ is for staging install dir, something like make install DESTDIR=<..>
package is for do_package task which is then further split into individual output packages in packages-split,
even though the content looks similar context is different, since it operates on PACKAGES and FILES variables, and if the files are not mentioned in these variables it won't copy those from image/ into package/ it is described in detail in Yocto project manual
I have created a new recipe is helloworld example in manual.
I'm using imx6sx processor, so created it in meta-freescale-3rdparty folder as recipes-helloword and checked this layer whether has been added to bblayer.conf. It can be compiled with bitbake helloworld there was no error and it exists in rpm folder. After that, the image compiled again with bitbake fsl-image-qt5-validation-imx and generated a new rootfs and sdcard file.
However, I can't find the application in rootfs. Where is the application in rootfs? (the recipe has been inserted in local.conf : IMAGE_INSTALL_append = " helloworld")
.
./recipes-helloworld/
└── helloworld
├── helloworld
│ ├── COPYING
│ └── helloworld.c
└── helloworld_0.0.bb
2 directories, 3 files
helloworld_0.0.bb
SUMMARY = "Hello World Cpp App Sources"
LICENSE = "MIT"
LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MIT;md5=0835ade698e0bcf8506ecda2f7b4f302"
PV = "1.5"
TARGET_CC_ARCH += "${LDFLAGS}"
SRC_URI = "file://helloworld.c"
S= "${WORKDIR}"
do_compile() {
${CC} helloworld.c -o helloworld
}
do_install() {
install -d ${D}${bindir}
install -m 0755 helloworld ${D}${bindir}
}
Can you check the build manifest of the image to see if helloworld is in there:
{build_folder}/tmp/deploy/licenses/{image_name + last_timestamp}/package.manifest
If it's there you should find helloworld in /usr/bin/helloworld
If it's not, helloworld package is not being included in the image.
Can you check 'helloword' application is available in 'helloword' package. Means it is built and put in /usr/bin. If it's available in image directory it means this binary is being installed into rootfs as part of the helloword package.
(build_dir)/tmp/work/***/hello word/***/image/usr/bin
If it is available it indicates the helloword package is being built and create the binary and it's installed in to /usr/bin and plan to put into rootfs.
Since you have already added the package in local.conf as IMAGE_INSTALL_append, it should built as part of target.
If it is not available still, can you please add the following line in recipe
FILES_${PN} += "${bindir}/helloword"
Then try to rebuild 'helloword' and final traget and check the binary is available in rootfs.
Hi this is my layer tree
├── conf
│ └── layer.conf
├── COPYING.MIT
├── README
└── recipes-hello
├── helloworld
│ ├── helloworld-0.1
│ │ ├── helloworld.c
│ │ ├── helloworld.patch
│ │ └── newhelloworld.c
│ └── helloworld_0.1.bb
├── message
│ ├── message-0.1
│ │ └── message.txt
│ └── message_0.1.bb
└── service
├── service-0.1
│ ├── test_systemd.service
│ └── test_systemd.sh
└── service_0.1.bb
Here test_systemd.service is the service file which have to invoke test_systemd.sh, which I am trying to achieve using service_0.1.bb
# This recipe performs the following tasks
# 1) Install .sh file in /home/root/ and .sh script creates a random text file
# 2) Install the .service file in systemd directory
# 3) Invoke the .sh script via .service file
inherit systemd
SUMMARY = "Install and start a systemd service"
SECTION = "examples"
LICENSE = "MIT"
LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MIT;md5=0835ade698e0bcf8506ecda2f7b4f302"
#here we specify the source we want to build
SRC_URI = "file://test_systemd.sh"
SRC_URI += "file://test_systemd.service"
#here we specify the source directory, where we can do all the building and expect sources to be placed
S = "${WORKDIR}"
SYSTEMD_SERVICE_${PN} = "test_systemd.service"
#bitbake task
#created a directory /home/root for target install the script
do_install() {
install -d ${D}/home/root
install -m 0755 ${WORKDIR}/test_systemd.sh ${D}/home/root
install -d ${D}{systemd_system_unitdir}
install -m 0644 ${WORKDIR}/test_systemd.service ${D}{systemd_system_unitdir}
}
#Pack the path
FILES_${PN} += "/home/root"
FILES_${PN} += "/lib/systemd/system"
REQUIRED_DISTRO_FEATURES= "systemd"
The problem is when I try to bitbake system recipe, bitbake throws an error saying test_systemd.service not found.
I managed to install both the files in RFS with a previous attempt but when I include the systemd concept. I get the no such file error. What could be the reason ?
Error message
NOTE: Executing SetScene Tasks
NOTE: Executing RunQueue Tasks
ERROR: service-0.1-r0 do_package: SYSTEMD_SERVICE_service value test_systemd.service does not exist
ERROR: service-0.1-r0 do_package: Function failed: systemd_populate_packages
ERROR: Logfile of failure stored in: /home/guest/yocto_practice/poky/build-beaglebone/tmp/work/cortexa8hf-neon-poky-linux-gnueabi/service/0.1-r0/temp/log.do_package.2860
ERROR: Task (/home/guest/yocto_practice/meta-testlayer/recipes-hello/service/service_0.1.bb:do_package) failed with exit code '1'
NOTE: Tasks Summary: Attempted 514 tasks of which 506 didn't need to be rerun and 1 failed.
Summary: 1 task failed:
/home/guest/yocto_practice/meta-testlayer/recipes-hello/service/service_0.1.bb:do_package
Summary: There were 2 ERROR messages shown, returning a non-zero exit code.
Also is this the correct way to write bb recipe for systemd and what is the significance of writing this
#Pack the path
FILES_${PN} += "/home/root"
FILES_${PN} += "/lib/systemd/system"
without this bitbake throws error.
SYSTEMD_SERVICE_${PN} += "file://test_systemd.service"
This should be:
SYSTEMD_SERVICE_${PN} = "test_systemd.service"
Other notes (unrelated to the error):
Installing things into /home is probably not a great idea (you could use e.g. ${libexecdir} for scripts that other scripts need.
there's no reason for having a do_install_append() in a bb file: you can just put everything in do_install()
If your Yocto is recent, using ${systemd_system_unitdir} instead of /lib/systemd/system is a good idea (in older releases ${systemd_unitdir}/system/ works)
In order to resolve this packaging error, I used the following install step
do_install() {
install -d ${D}${bindir}
install -m 0755 ${WORKDIR}/test_systemd.sh ${D}${bindir}
install -d ${D}${systemd_unitdir}/system
install -m 0644 ${WORKDIR}/test_systemd.service ${D}${systemd_unitdir}/system
}