Michael
Michael

Reputation: 523

Yocto Systemd Configuration

I am trying to start a service on boot, however I am having issues building. This is my tree structure in my custom layer

michael@michael-VirtualBox:~/Documents/simple_daemon/sources/meta-simpledaemon$ tree
.
├── conf
│   └── layer.conf
├── COPYING.MIT
├── README
└── recipes-example
    ├── example
    │   └── example_0.1.bb
    └── simpledaemon
        ├── files
        │   └── simpledaemon.service
        └── simpledaemon_git.bb

In my local.conf I have added the following to the end:

IMAGE_INSTALL_append = " bbexample "
IMAGE_INSTALL_append = " simpledaemon "
IMAGE_INSTALL_append = " packagegroup-core-ssh-openssh "
IMAGE_INSTALL_append = " openssh-sftp-server "


DISTRO_FEATURES_append = " systemd"
VIRTUAL-RUNTIME_init_manager = " systemd"
DISTRO_FEATURES_BACKFILL_CONSIDERED = "sysvinit"
VIRTUAL-RUNTIME_initscripts = ""

My .bb file is as follows:

# Recipe created by recipetool
# This is the basis of a recipe and may need further editing in order to be fully functional.
# (Feel free to remove these comments when editing.)

# WARNING: the following LICENSE and LIC_FILES_CHKSUM values are best guesses - it is
# your responsibility to verify that the values are complete and correct.
LICENSE = "MIT"
LIC_FILES_CHKSUM = "file://LICENSE;md5=ca119cf6dcda0f0883a416a3e7f94cc2"

SRC_URI = "git://github.com/MichaelBMiner/simpledaemon;protocol=https"

# Modify these as desired
PV = "1.0+git${SRCPV}"
SRCREV = "a37a89df4d53bca97c12c8908cbe8552032417b4"

inherit systemd

S = "${WORKDIR}/git"

SYSTEMD_SERVICE_${PN} = "simpledaemon.service"
do_compile () {
    ${CC} ${LDFLAGS} simpledaemon.c -o simpledaemon
}
do_install () {
    install -d ${D}${bindir}
    install -m 0755 ${WORKDIR}/simpledaemon ${D}${bindir}
    install -d ${D}${systemd_unitdir}/system
    install -m 0644 ${WORKDIR}/simpledaemon.service ${D}${systemd_unitdir}/system sed -i -e     's,@BINDIR@,${bindir},g' ${D}${systemd_unitdir}/system/simpledaemon.service
}

# NOTE: if this software is not capable of being built in a separate build directory
# from the source, you should replace autotools with autotools-brokensep in the
# inherit line
inherit autotools

# Specify any options you want to pass to the configure script using EXTRA_OECONF:
EXTRA_OECONF = ""

My simpledaemon.service is as follows:

[Unit]
Description=Example service
[Service]
Type=forking
ExecStart=@BINDIR@/simple-service
[Install]
WantedBy=multi-user.target

I got all of this information from the book Embedded Linux Development Using Yocto Project Cookbook Second Edition.

All of my builds have been successful until I attempt to add this new service. This book makes no mention of an init shell script for systemd services. I am also pulling code from GitHub rather than code in my build directory (you can look at the repo).

When I run bitbake I am given the error Didn't find service unit 'simpledaemon.service', specified in SYSTEMD_SERVICE_simpledaemon.. This tells me it is a path error that I can only assume arises from my GitHub structure. Can anyone shine some light on this?

Upvotes: 0

Views: 4841

Answers (2)

justinsg
justinsg

Reputation: 848

There are a few issues with your recipe that lead to your error:

1. Use correct SRCREV:

SRCREV = "a37a89df4d53bca97c12c8908cbe8552032417b4"

The SRCREV above refers to a commit in your repository before the .service file was added. Change this to the latest commit, 2140a0646b3ffc6595c50ac549dc6f1220f66c28

2. Remove steps already described by autotools:

Since your source code uses autotools and your Yocto recipe inherits the autotools class, Yocto will automatically run the equivalent of ./configure, make, make install to configure/compile/install this package.

Therefore, you can remove your entire do_compile task and the first few lines of do_install where you manually install the binary:

do_compile () {
    ${CC} ${LDFLAGS} simpledaemon.c -o simpledaemon
}

do_install () {
    install -d ${D}${bindir}
    install -m 0755 ${WORKDIR}/simpledaemon ${D}${bindir}

3. Use do_install_append to install the systemd service

The inherit autotools at the end of your recipe file causes your do_install task to be overridden as the autotools class sets it to an autotools-style method.

Since you need the autotools do_install to run, and also some of your own code (to install the systemd service), you can move the inherit upward and combine it with the systemd one:

inherit autotools systemd

and, then define a do_install_append function to append on the extra steps required to install your systemd service:

do_install_append () {
    install -d ${D}${systemd_system_unitdir}
    install -m 0644 ${S}/simpledaemon.service ${D}${systemd_system_unitdir}
    sed -i -e 's,@BINDIR@,${bindir},g' ${D}${systemd_system_unitdir}/simpledaemon.service
}

There were a number of errors in your original do_install too:

  1. The simpledaemon.service file is installed from ${S} which is the source directory (i.e the git directory), not ${WORKDIR}
  2. The sed command should be on a new line
  3. (optimisation) You can use ${systemd_system_unitdir} in place of ${systemd_unitdir}/system

4. Remove unused EXTRA_OECONF = ""

Setting EXTRA_OECONF to empty will override any default value it had, which often is defined by the Yocto distro. If you do need extra arguments to ./configure consider using PACKAGECONFIG or at last resort EXTRA_OECONF += "--foo-bar".


Complete recipe:

LICENSE = "MIT"
LIC_FILES_CHKSUM = "file://LICENSE;md5=ca119cf6dcda0f0883a416a3e7f94cc2"

SRC_URI = "git://github.com/MichaelBMiner/simpledaemon;protocol=https"

PV = "1.0+git${SRCPV}"
SRCREV = "2140a0646b3ffc6595c50ac549dc6f1220f66c28"

inherit systemd autotools

S = "${WORKDIR}/git"

SYSTEMD_SERVICE_${PN} = "simpledaemon.service"

do_install_append () {
    install -d ${D}${systemd_system_unitdir}
    install -m 0644 ${S}/simpledaemon.service ${D}${systemd_system_unitdir}
    sed -i -e 's,@BINDIR@,${bindir},g' ${D}${systemd_system_unitdir}/simpledaemon.service
}

Debugging tip

A useful way to debug recipes is to dump the output of the following command to a file and inspect it:

bitbake -e your-recipe-or-image-name

If you inspect the output of bitbake -e simpledaemon for your original recipe, and look for the final definition of do_install (search for a line beginning with do_install). It was clear that after parsing, the function did not contain your steps to install the service code.

You can read more about this technique in the manual, under Viewing Variable Values.

Upvotes: 8

John b
John b

Reputation: 1398

can you move simpledaemon dir inside the example dir?

You can use obmc-op-control-host_git.bb as a reference.

Upvotes: 0

Related Questions