Introduction
The Yocto Project consists of recipes, dependencies and metadata to instruct the build system how to build software packages for installation into a target Embedded operating system.
This tutorial will guide you through generating a basic recipe to add your application to an existing Yocto project build, including the configuration needed to launch a systemd service. Specifically we will launch our new application as a simple service which runs one time at boot.
Prerequisites
-
A configured Yocto environment . We will use the QEMU setup for easy testing of the new recipe without requiring physical hardware.
-
Please review the following for more background on this:
Step 1: Generate the initial build and verify that it boots
This is a summary of the steps outlined here.
export BRANCH="warrior"
mkdir mender-qemu && cd mender-qemu
repo init -u https://github.com/mendersoftware/meta-mender-community \
-m meta-mender-qemu/scripts/manifest-qemu.xml \
-b ${BRANCH}
repo sync
source setup-environment qemu
MACHINE=qemux86-64 bitbake core-image-base
../sources/meta-mender/meta-mender-qemu/scripts/mender-qemu core-image-base
Step 2: Create a custom layer
We will create a custom layer to hold our new recipe. See this tutorial for more details on custom layers.
Please note that the tutorials on this site will re-use this layer and if you have already created this structure by following another tutorial you can skip this step.
Create a new layer called meta-stargazer
using the bitbake-layers
helper application:
bitbake-layers create-layer ../sources/meta-stargazer
This will create a basic structure in meta-stargazer
directory:
../sources/meta-stargazer/
├── conf
│ └── layer.conf
├── COPYING.MIT
├── README
└── recipes-example
└── example
└── example_0.1.bb
3 directories, 4 files
Include the layer in our Yocto Project environment:
bitbake-layers add-layer ../sources/meta-stargazer
Step 3: Create a new recipe
We will use the recipetool
utility provided by Yocto to generate a new recipe for the GNU Hello program. This package is setup for building properly with autoconf and automake, and Yocto can automatically generate recipes that use these tools.
mkdir ../sources/meta-stargazer/recipes-example/gnuhello
recipetool create https://ftp.gnu.org/gnu/hello/hello-2.10.tar.gz \
-o ../sources/meta-stargazer/recipes-example/gnuhello/
Now verify that it builds.
bitbake hello
Note that the recipe is setup to automatically download the sources from the GNU URL. The recipetool
utility can also use URIs from source code management systems such as Git. Additionally, the source code for your recipe can be stored directly in the custom layer but it is considered Yocto best practice to keep it separate and have the recipe download it from the appropriate location.
See the Yocto Project Development Tasks Manual for more details on the recipetool
utility.
Now let’s add this to our image, boot and verify that the /usr/bin/hello executable exists.
cat >> conf/local.conf <<EOF
IMAGE_INSTALL_append = " hello "
EOF
MACHINE=qemux86-64 bitbake core-image-base
../sources/meta-mender/meta-mender-qemu/scripts/mender-qemu core-image-base
Login as root with no password and execute the new binary:
qemux86-64 login: root
root@qemux86-64:~# ls -l /usr/bin/hello
-rwxr-xr-x 1 root root 34976 Oct 27 12:44 /usr/bin/hello
root@qemux86-64:~# /usr/bin/hello
Hello, world!
root@qemux86-64:~#
Step 4: Modify recipe to add systemd service file.
For this hello-world
application, we don’t necessarily need a service file as this application does not provide services to other parts of this operating system. However, for example purposes, we will create an autostart script to run hello at boot time. The output from this invocation will be available in the systemd logs using the journalctl
command. This service file can also be manually invoked at runtime.
First, we will create the service file itself which is read and processed by systemd:
mkdir -p ../sources/meta-stargazer/recipes-example/gnuhello/files/
cat > ../sources/meta-stargazer/recipes-example/gnuhello/files/hello.service <<EOF
[Unit]
Description=GNU Hello World startup script
[Service]
ExecStart=/usr/bin/hello
[Install]
WantedBy=multi-user.target
EOF
Now let’s add the recipe settings to integrate this into the systemd configuration for our build:
cat >> ../sources/meta-stargazer/recipes-example/gnuhello/hello_2.10.bb <<EOF
inherit systemd
SYSTEMD_AUTO_ENABLE = "enable"
SYSTEMD_SERVICE_\${PN} = "hello.service"
SRC_URI_append = " file://hello.service "
FILES_\${PN} += "\${systemd_unitdir}/system/hello.service"
do_install_append() {
install -d \${D}/\${systemd_unitdir}/system
install -m 0644 \${WORKDIR}/hello.service \${D}/\${systemd_unitdir}/system
}
EOF
Note: Dollar symbols require to be escaped with a backslash ( \$
) to work with cat
. If you copy-paste these examples remove the backslashes.
Now, rebuild, boot and verify that the service started and the output is visible in the systemd logs.
MACHINE=qemux86-64 bitbake core-image-base
../sources/meta-mender/meta-mender-qemu/scripts/mender-qemu core-image-base
root@qemux86-64:~# systemctl --no-pager status hello
● hello.service - GNU Hello World startup script
Loaded: loaded (/lib/systemd/system/hello.service; enabled; vendor preset: enabled)
Active: inactive (dead) since Sun 2019-10-27 13:56:09 UTC; 52s ago
Process: 178 ExecStart=/usr/bin/hello (code=exited, status=0/SUCCESS)
Main PID: 178 (code=exited, status=0/SUCCESS)
Oct 27 13:56:03 qemux86-64 systemd[1]: Started GNU Hello World startup script.
Oct 27 13:56:04 qemux86-64 hello[178]: Hello, world!
Oct 27 13:56:09 qemux86-64 systemd[1]: hello.service: Succeeded.
root@qemux86-64:~# journalctl -u hello --no-pager
-- Logs begin at Sun 2019-10-27 13:55:32 UTC, end at Sun 2019-10-27 13:57:43 UTC. --
Oct 27 13:56:03 qemux86-64 systemd[1]: Started GNU Hello World startup script.
Oct 27 13:56:04 qemux86-64 hello[178]: Hello, world!
Oct 27 13:56:09 qemux86-64 systemd[1]: hello.service: Succeeded.
Conclusion
In this tutorial we covered adding new recipes to Yocto project builds and enabling autostart services with systemd.
For further reading please visit
- Welcome to the Yocto Project Documentation — The Yocto Project ® 4.2.999 documentation
- systemd
- systemd.service
If this tutorial was useful to you, please press like, or leave a thank you note to the contributor who put valuable time into this and made it available to you. It will be much appreciated!