I have a do_install
task in a BitBake recipe which I've written for a driver where I execute a custom install
script. The task fails because the installation script cannot find kernel source header files within <the image rootfs>/usr/src/kernel
. This script runs fine on the generated OS.
Here's the relevant part of my recipe:
SRC_URI += "file://${TOPDIR}/example"
DEPENDS += " virtual/kernel linux-libc-headers "
do_install () {
( cd ${TOPDIR}/example/Install ; ./install )
}
Here's a relevant portion of the install
script:
if [ ! -d "/usr/src/kernel/include" ]; then
echo ERROR: Linux kernel source include directory not found.
exit 1
fi
cd /usr/src/kernel
make scripts
...
./install_drv pci ${DRV_ARGS}
I checked changing to if [ ! -d "/usr/src/kernel" ]
, which also failed. install
passes different options to install_drv
, which I have a relevant portion of below:
cd ${DRV_PATH}/pci
make NO_SYSFS=${ARG_NO_SYSFS} NO_INSTALL=${ARG_NO_INSTALL} ${ARGS_HWINT}
if [ ${ARG_NO_INSTALL} == 0 ]; then
if [ `/sbin/lsmod | grep -ci "uceipci"` -eq 1 ]; then
./unload_pci
fi
./load_pci DEBUG=${ARG_DEBUG}
fi
The make
target build:
within ${DRV_PATH}/pci
is essentially this:
make -C /usr/src/kernel SUBDIRS=${PWD} modules
I found these comments within linux-libc-headers.inc
relevant:
# You're probably looking here thinking you need to create some new copy
# of linux-libc-headers since you have your own custom kernel. To put
# this simply, you DO NOT.
#
# Why? These headers are used to build the libc. If you customise the
# headers you are customising the libc and the libc becomes machine
# specific. Most people do not add custom libc extensions to the kernel
# and have a machine specific libc.
#
# But you have some kernel headers you need for some driver? That is fine
# but get them from STAGING_KERNEL_DIR where the kernel installs itself.
# This will make the package using them machine specific but this is much
# better than having a machine specific C library. This does mean your
# recipe needs a DEPENDS += "virtual/kernel" but again, that is fine and
# makes total sense.
#
# There can also be a case where your kernel extremely old and you want
# an older libc ABI for that old kernel. The headers installed by this
# recipe should still be a standard mainline kernel, not your own custom
# one.
I'm a bit unclear if I can 'get' the headers from the STAGING_KERNEL_DIR
properly since I'm not using make.
Within kernel.bbclass
provided in the meta/classes
directory, there is this variable assigment:
# Define where the kernel headers are installed on the target as well as where
# they are staged.
KERNEL_SRC_PATH = "/usr/src/kernel"
This path is then packaged later within that .bbclass
file here:
PACKAGES = "kernel kernel-base kernel-vmlinux kernel-image kernel-dev kernel-modules"
...
FILES_kernel-dev = "/boot/System.map* /boot/Module.symvers* /boot/config* ${KERNEL_SRC_PATH} /lib/modules/${KERNEL_VERSION}/build"
A suggestion on the yocto IRC channel was to use the following line:
do_configure[depends] += "virtual/kernel:do_shared_workdir"
which is corroborated by the Yocto Project Reference Manual, which states that in version 1.8, there was the following change:
The kernel build process was changed to place the source in a common shared work area and to place build artifacts separately in the source code tree. In theory, migration paths have been provided for most common usages in kernel recipes but this might not work in all cases. In particular, users need to ensure that
${S}
(source files) and${B}
(build artifacts) are used correctly in functions such asdo_configure
anddo_install
. For kernel recipes that do not inherit fromkernel-yocto
or includelinux-yocto.inc
, you might wish to refer to thelinux.inc
file in themeta-oe
layer for the kinds of changes you need to make. For reference, here is the commit where thelinux.inc
file inmeta-oe
was updated.Recipes that rely on the kernel source code and do not inherit the module classes might need to add explicit dependencies on the
do_shared_workdir
kernel task, for example:do_configure[depends] += "virtual/kernel:do_shared_workdir"
But I'm having difficulties applying this to my recipe. From what I understand, I should be able to change the above line to:
do_install[depends] += "virtual/kernel:do_shared_workdir"
Which would mean that the do_install
task now must be run after do_shared_workdir
task of the virtual/kernel
recipe, which means that I should be able to work with the shared workdir (see Question 3 below), but I still have the same missing kernel header issue.
I'm using a custom linux kernel (v3.14) from git.kernel.org. which inherits the kernel
class. Here are some of my questions:
kernel-dev
be a part of any recipe which inherits the kernel
class? (this section of the variables glossary)virtual/kernel
to the DEPENDS
variable, wouldn't that mean that the kernel-dev
would be brought in?kernel-dev
is part of the dependencies of my recipe, wouldn't I be able to point to the /usr/src/kernel
directory from my recipe? According to this reply on the Yocto mailing list, I think I should.Remember that there are different environments within the the build time environment, consisting of:
kernel-dev
is a target package, which you'd install into the rootfs of the target system for certain things like kernel symbol maps which are needed by profiling tools like perf/oprofile. It is not present at build time although some of its contents are available in the sysroots or shared workdir.
Your do_install
runs at build time so this is within the build directory structures of the build system, not the target one. In particular, /usr/src/
won't be correct, it would need to be some path within your build directory. The virtual/kernel
do_shared_workdir
task populates ${STAGING_KERNEL_DIR}
so you would want to change to that directory in your script.
The:
do_install[depends] += "virtual/kernel:do_shared_workdir
dependency like looks correct for your use case, assuming nothing in do_configure
or do_compile
accesses the data there.
module
BitBake classThe other answers are correct in the recommendation to look at module.bbclass
, since this illustrates how common kernel modules can be built. If you want to use custom functions or make commands, this is fine, you can just override them. If you really don't want to use that class, I would suggest taking inspiration from it though.
Adding virtual/kernel
to DEPENDS
means virtual/kernel:do_populate_sysroot
must run before our do_configure
task. Since you need a dependency for do_shared_workdir
here, a DEPENDS
on virtual/kernel
is not enough.
The kernel-dev
package would be built, however it would then need to be installed into your target image and used at runtime on a real target. You need this at build time so kernel-dev
is not appropriate.
You'd likely want the kernel-devsrc
package for what you're doing, not the kernel-dev
package.