Kernel compilation in Yocto, what to define? - linux-kernel

I am currently trying to compile a kernel with yocto (jethro). Kernel one can fetch from here (commit 4561d2504e8ea562674070350d27c19357f0d7f0)
git clone --depth 1 --branch pine64-hacks-1.2 --single-branch https://github.com/longsleep/linux-pine64.git linux-pine64
I tried to compile it, and it is a success but integrating it in yocto system gives compilation errors. Looking at the logs, one can think some modules don't work but they can be compiled if not integrated in Yocto. A parameter has not been set, for sure, I just don't know how to proceed to have a similar behaviour in yocto.
Some parts of the log that can help to understand.
+ oe_runmake Image CC=aarch64-poky-linux-gcc -fuse-ld=bfd --sysroot=/home/dbensoussan/new_poky/poky/build/tmp/sysroots/pine64 LD=aarch64-poky-linux-ld.bfd --sysroot=/home/dbensoussan/new_poky/poky/build/tmp/sysroots/pine64
+ bbnote make -j 8 Image CC=aarch64-poky-linux-gcc -fuse-ld=bfd --sysroot=/home/dbensoussan/new_poky/poky/build/tmp/sysroots/pine64 LD=aarch64-poky-linux-ld.bfd --sysroot=/home/dbensoussan/new_poky/poky/build/tmp/sysroots/pine64
+ printf %b\0 bbnote make -j 8 Image CC=aarch64-poky-linux-gcc -fuse-ld=bfd --sysroot=/home/dbensoussan/new_poky/poky/build/tmp/sysroots/pine64 LD=aarch64-poky-linux-ld.bfd --sysroot=/home/dbensoussan/new_poky/poky/build/tmp/sysroots/pine64
+ make -j 8 Image CC=aarch64-poky-linux-gcc -fuse-ld=bfd --sysroot=/home/dbensoussan/new_poky/poky/build/tmp/sysroots/pine64 LD=aarch64-poky-linux-ld.bfd --sysroot=/home/dbensoussan/new_poky/poky/build/tmp/sysroots/pine64
GEN /home/dbensoussan/new_poky/poky/build/tmp/work/pine64-poky-linux/linux-pine64/3.10-r0/linux-pine64-standard-build/Makefile
scripts/kconfig/conf --silentoldconfig Kconfig
Here are warnings :
drivers/net/wireless/bcmdhd/Kconfig:50:warning: defaults for choice values not supported
warning: (COMPAT) selects COMPAT_BINFMT_ELF which has unmet direct dependencies (COMPAT && BINFMT_ELF)
GEN /home/dbensoussan/new_poky/poky/build/tmp/work/pine64-poky-linux/linux-pine64/3.10-r0/linux-pine64-standard-build/Makefile
/home/dbensoussan/new_poky/poky/build/tmp/work-shared/pine64/kernel-source/scripts/dtc/updatetree.c: In function 'sunxi_dt_init_pinconf_prop':
/home/dbensoussan/new_poky/poky/build/tmp/work-shared/pine64/kernel-source/scripts/dtc/updatetree.c: In function 'sunxi_dt_init_pinconf_prop':
/home/dbensoussan/new_poky/poky/build/tmp/work-shared/pine64/kernel-source/scripts/dtc/updatetree.c:149:8: warning: variable 'propend' set but not used [-Wunused-but-set-variable]
void *propend;
/home/dbensoussan/new_poky/poky/build/tmp/work-shared/pine64/kernel-source/scripts/dtc/updatetree.c:306:9: warning: variable 'ret' set but not used [-Wunused-but-set-variable]
int i, ret, len, gpio_value[4], phandle, phandle_count;
GEN usr/initramfs_data.cpio
In file included from /home/dbensoussan/new_poky/poky/build/tmp/work-shared/pine64/kernel-source/include/linux/memcontrol.h:22:0,
from /home/dbensoussan/new_poky/poky/build/tmp/work-shared/pine64/kernel-source/include/linux/swap.h:8,
from /home/dbensoussan/new_poky/poky/build/tmp/work-shared/pine64/kernel-source/include/linux/suspend.h:4,
from /home/dbensoussan/new_poky/poky/build/tmp/work-shared/pine64/kernel-source/init/do_mounts.c:16:
/home/dbensoussan/new_poky/poky/build/tmp/work-shared/pine64/kernel-source/include/linux/cgroup.h:907:18: warning: 'struct cgroup_taskset' declared inside parameter list
struct cgroup_taskset *tset)
A lot of cgroup warnings follow and ends with an error and ends the compilation:
/home/dbensoussan/new_poky/poky/build/tmp/work-shared/pine64/kernel-source/security/apparmor/lsm.c:1293:29: error: 'CONFIG_SECURITY_APPARMOR_UNCONFINED_INIT' undeclared here (not in a function)
bool aa_g_unconfined_init = CONFIG_SECURITY_APPARMOR_UNCONFINED_INIT;
My kernel recipe is:
require recipes-kernel/linux/linux-yocto.inc
DESCRIPTION = "Linux kernel for Allwinner a64 processors"
COMPATIBLE_MACHINE = "pine64"
LINUX_VERSION ?= "3.10"
PV = "${LINUX_VERSION}"
SRCREV_pn-${PN} = "6c0b852b9ab4688534c8e978d2d55cf8a26cbd05"
KERNEL_DEVICETREE ?= " \
allwinner/sun50i-a64-pine64.dtb \
allwinner/sun50i-a64-pine64-plus.dtb \
"
KERNEL_IMAGETYPE="Image"
KERNEL_DEFCONFIG_pine64 ?= "defconfig"
DEPENDS_aarch64 += "libgcc"
SRC_URI += "git://github.com/apritzel/linux.git;protocol=git;branch=a64-v4 \
file://defconfig \
"
S = "${WORKDIR}/git"
do_kernel_configme_prepend() {
echo "new custom config install"
install -m 0644 ${S}/arch/${ARCH}/configs/${KERNEL_DEFCONFIG} ${WORKDIR}/defconfig || die "No default configuration for ${MACHINE} / ${KERNEL_DEFCONFIG} available."
}

I'm not sure about the failure, but judging by the error it is unlikely to be related to the build system. There are quite a few things that jump out as being odd in the recipe though:
Use SRC_URI = instead of SRC_URI += - you appear to have all the items listed that you'd want to fetch, so you should be setting the value not appending to it
SRCREV_pn-${PN} = is ugly - we're already in the context of the recipe so a pn- override should not be necessary. Use SRCREV = instead.
You should generally use = instead of ?= unless you genuinely expect the value to be overridden via the configuration, otherwise your recipe's desired values may never be used if there is a default.
The DEPENDS_aarch64 += line isn't going to do what you probably think it does. It won't add libgcc to the DEPENDS, it'll set that value outright as DEPENDS because the += happens immediately and not at the same time as the override, leaving you with DEPENDS_aarch64 = " libgcc". Assuming this line is even necessary at all, you should just use DEPENDS += since this is a machine-specific recipe - you should always be building for aarch64, right?
Supplying a defconfig in SRC_URI and also copying the defconfig from the kernel is horrific. Drop all of that and instead set KBUILD_DEFCONFIG = "defconfig" instead (if that is genuinely the name of the defconfig file within the source tree under arch/${ARCH}/configs).

Related

Buildroot build error: `ERROR: Dependency "nlohmann_json" not found, tried pkgconfig and cmake`

I'm trying to add the header-only library https://github.com/nlohmann/json "JSON for Modern C++" to my Buildroot package for use both on the target embedded Linux board, as well as on my host build machine in unit tests.
However, I keep getting a variety of errors no matter what I do, including ERROR: Dependency "nlohmann_json" not found, tried pkgconfig and cmake.
What's the proper way to add this library package to be used by my package?
Details about my setup:
That JSON library is known as json-for-modern-cpp in the Buildroot source code, and is located here: https://github.com/buildroot/buildroot/tree/master/package/json-for-modern-cpp
My buildroot/package/json-for-modern-cpp/json-for-modern-cpp.mk file straight from Buildroot looks like this:
################################################################################
#
# json-for-modern-cpp
#
################################################################################
JSON_FOR_MODERN_CPP_VERSION = 3.10.5
JSON_FOR_MODERN_CPP_SOURCE = json-$(JSON_FOR_MODERN_CPP_VERSION).tar.gz
JSON_FOR_MODERN_CPP_SITE = $(call github,nlohmann,json,v$(JSON_FOR_MODERN_CPP_VERSION))
JSON_FOR_MODERN_CPP_LICENSE = MIT
JSON_FOR_MODERN_CPP_LICENSE_FILES = LICENSE.MIT
JSON_FOR_MODERN_CPP_CPE_ID_VENDOR = json-for-modern-cpp_project
JSON_FOR_MODERN_CPP_INSTALL_STAGING = YES
# header only library
JSON_FOR_MODERN_CPP_INSTALL_TARGET = NO
JSON_FOR_MODERN_CPP_CONF_OPTS = -DJSON_BuildTests=OFF -DJSON_MultipleHeaders=ON
$(eval $(cmake-package))
My package's br2-external/package/my-module-name/my-module-name.mk makefile has these dependencies in it (notice I added json-for-modern-cpp to both the MY_MODULE_NAME_DEPENDENCIES target board dependencies, as well as to the HOST_MY_MODULE_NAME_DEPENDENCIES host build system dependencies:
MY_MODULE_NAME_DEPENDENCIES += \
some-other-lib1 \
some-other-lib2 \
json-for-modern-cpp
HOST_MY_MODULE_NAME_DEPENDENCIES += \
host-some-other-lib1 \
host-some-other-lib2 \
json-for-modern-cpp
How to add a Buildroot package to your package, and to your meson.build file
I figured it out. I've documented what I learned in my eRCaGuy_dotfiles/git & Linux cmds, help, tips & tricks - Gabriel.txt notes file. Search that document for "Adding dependencies from other meson.build files" and for "nlohmann" for details and notes.
Here's the solution:
If you need to add a dependency on a 3rd-party library or something, such as JSON for Modern C++ (https://github.com/nlohmann/json), simply do this:
Find that project's meson.build file. Ex: https://github.com/nlohmann/json/blob/develop/meson.build
Notice the 'nlohmann_json' project name at the top. Use that in your module's meson.build file:
all_deps = [
# NB: this `nlohmann_json` meson.build name can be identified from its public repo's
# meson.build file here: https://github.com/nlohmann/json/blob/develop/meson.build#L1
dependency('nlohmann_json')
dependency('some_other_lib2'),
dependency('some_other_lib3'),
dependency('some_other_lib4'),
]
all_deps will then be used in your meson.build file to build your executable and specify your library dependencies--something like this, for example:
my_lib = static_library(
'my_module_name',
include_directories : [include_dirs],
sources: [library_sources],
dependencies: all_deps,
cpp_args: compiler_options,
install: true,
)
Add $(eval $(host-cmake-package)) to the bottom of the json-for-modern-cpp.mk file in Buildroot here: https://github.com/buildroot/buildroot/blob/master/package/json-for-modern-cpp/json-for-modern-cpp.mk. This requires adding your own commit to your own custom fork of that repo.
That changes that file from this:
################################################################################
#
# json-for-modern-cpp
#
################################################################################
JSON_FOR_MODERN_CPP_VERSION = 3.10.5
JSON_FOR_MODERN_CPP_SOURCE = json-$(JSON_FOR_MODERN_CPP_VERSION).tar.gz
JSON_FOR_MODERN_CPP_SITE = $(call github,nlohmann,json,v$(JSON_FOR_MODERN_CPP_VERSION))
JSON_FOR_MODERN_CPP_LICENSE = MIT
JSON_FOR_MODERN_CPP_LICENSE_FILES = LICENSE.MIT
JSON_FOR_MODERN_CPP_CPE_ID_VENDOR = json-for-modern-cpp_project
JSON_FOR_MODERN_CPP_INSTALL_STAGING = YES
# header only library
JSON_FOR_MODERN_CPP_INSTALL_TARGET = NO
JSON_FOR_MODERN_CPP_CONF_OPTS = -DJSON_BuildTests=OFF -DJSON_MultipleHeaders=ON
$(eval $(cmake-package))
to this:
################################################################################
#
# json-for-modern-cpp
#
################################################################################
JSON_FOR_MODERN_CPP_VERSION = 3.10.5
JSON_FOR_MODERN_CPP_SOURCE = json-$(JSON_FOR_MODERN_CPP_VERSION).tar.gz
JSON_FOR_MODERN_CPP_SITE = $(call github,nlohmann,json,v$(JSON_FOR_MODERN_CPP_VERSION))
JSON_FOR_MODERN_CPP_LICENSE = MIT
JSON_FOR_MODERN_CPP_LICENSE_FILES = LICENSE.MIT
JSON_FOR_MODERN_CPP_CPE_ID_VENDOR = json-for-modern-cpp_project
JSON_FOR_MODERN_CPP_INSTALL_STAGING = YES
# header only library
JSON_FOR_MODERN_CPP_INSTALL_TARGET = NO
JSON_FOR_MODERN_CPP_CONF_OPTS = -DJSON_BuildTests=OFF -DJSON_MultipleHeaders=ON
$(eval $(cmake-package))
$(eval $(host-cmake-package))
Again, the only line added was the last one above. That causes cmake to bring in the necessary dependencies for the host build computer too, for your unit tests, and not just for the target embedded Linux board, which is what the $(eval $(cmake-package)) line does.
Use the proper dependencies in your module's Buildroot br2-external/package/my-module-name/my-module-name.mk makefile. For the host it should be host-json-for-modern-cpp, not json-for-modern-cpp, since the latter is for the target board only. Note that the json-for-modern-cpp name seems to be defined in the config file here, by the way: https://github.com/buildroot/buildroot/blob/master/package/json-for-modern-cpp/Config.in#L2.
MY_MODULE_NAME_DEPENDENCIES += \
some-other-lib1 \
some-other-lib2 \
json-for-modern-cpp
HOST_MY_MODULE_NAME_DEPENDENCIES += \
host-some-other-lib1 \
host-some-other-lib2 \
host-json-for-modern-cpp
# This last line just above is now **fixed**!
That's it! It works now.
I'm not sure why I had to add $(eval $(host-cmake-package)) to the buildroot file, as it seems like that should be something in the json-for-modern-cpp.mk file in the Buildroot repo by default, no?

Automake fails when trying to run platform-specific build

I am using autotools to build a project that I want to cross-compile for both Linus and Mac OSX. I am building two libraries, libevent.la and libaffinity.la. libevent should be build when automake is run on both platform. However, libaffinity.la should be build only if the platform is MACOSX. To this end, I have the following in my configure.ac file:
#Detect the target system
case "$host_os" in
darwin*)
build_darwin=yes
;;
esac
AM_CONDITIONAL([DARWIN], [test "$build_darwin" = "yes"])
The variableDARWIN will be set if the proejct is being build on Mac OS. And in the Makefile.am I have following:
extlibdir = $(libdir)/guile/$(GUILE_EFFECTIVE_VERSION)/extensions
extlib_LTLIBRARIES = libevent.la
AM_CFLAGS = -I$(srcdir) $(WARN_CFLAGS) $(DEBUG_CFLAGS)
libevent_la_SOURCES = libevent.c
libevent_la_CFLAGS = $(AM_CFLAGS) $(GUILE_CFLAGS) -Wno-error -Wno-nullability-completeness -Wno-expansion-to-defined
libevent_la_LIBADD = $(GUILE_LIBS)
libevent_la_LDFLAGS = -export-dynamic -module
$(GOBJECTS): libevent.la
if DARWIN
extlib_LTLIBRARIES += libaffinity.la
affinity_la_SOURCES = affinity.c
affinity_la_CFLAGS = $(AM_CFLAGS) $(GUILE_CFLAGS) -Wno-error -Wno-nullability-completeness -Wno-expansion-to-defined
affinity_la_LIBADD = $(GUILE_LIBS)
affinity_la_LDFLAGS = -export-dynamic -module
$(GOBJECTS) += libaffinity.la
endif
When I run make, it fails with the following error:
extlib_LTLIBRARIES += affinity.la
make[1]: extlib_LTLIBRARIES: No such file or directory
make: *** [all] Error 2
However, as you can see, extlib_LTLIBRARIES is defined above the if statement.
How can I fix this? Or is there a better way to do this so that I can selectively build libaffinity.la based on the platform?
The main problem turns out to have been that the lines in the conditional section were indented with tabs. These are not particularly significant to Automake, but they will have been carried through to its generated Makefile.in, and, from there, to the Makefile generated by configure. Tabs are significant to make: a leading tab is how make recognizes the lines of a rule's recipe. (Only a tab will do; spaces do not have the same significance.)
The effect, then, was that make interpreted extlib_LTLIBRARIES += libaffinity.la as one of the commands in the recipe for some rule, so that when it tried to apply the rule, it wanted to execute a system command named extlib_LTLIBRARIES. There being no such executable command found in the path, the shell failed and reported "No such file or directory", which message make forwarded on to its own output.
The fix is to avoid indenting with tabs in your Makefile.am (spaces are ok), except where you actually intend to write a recipe for a make rule (for which an initial tab is obligatory).

ccflag option in Makefile

I want to compile my c code (in kernel) which needs to include some header files from another directory.
Instead of specifying the complete path to header files in c file, I would like to specify the include path in Makefile.
My c file gets complied when the config option CONFIG_FEATURE_X is enabled.
I have written the following in Makefile:
obj-$(CONFIG_FEATURE_X) += my_file.o
ccflags-$(CONFIG_FEATURE_X) += -I$(obj)/../../path
When the CONFIG_FEATURE_X is enabled (Y) in .config using make menuconfig, it works fine.
But when the CONFIG_FEATURE_X is enabled as module (m) in .config, this does not include the header files from the path specified and gives the file not found error.
How can I do this?
When the CONFIG_FEATURE_X is enabled (Y) in .config using make menuconfig, it works fine.
That's because
ccflags-$(CONFIG_FEATURE_X) += -I$(obj)/../../path
would evaluate to
ccflags-y += -I$(obj)/../../path
According to Documentation/kbuild/makefiles.txt:
--- 3.7 Compilation flags
ccflags-y, asflags-y and ldflags-y
These three flags apply only to the kbuild makefile in which they
are assigned. They are used for all the normal cc, as and ld
invocations happening during a recursive build.
Note: Flags with the same behaviour were previously named:
EXTRA_CFLAGS, EXTRA_AFLAGS and EXTRA_LDFLAGS.
They are still supported but their usage is deprecated.
ccflags-y specifies options for compiling with $(CC).
So you have defined a valid compilation flag for the built-in case.
But when the CONFIG_FEATURE_X is enabled as module (m) in .config, this does not include the header files from the path specified and gives the file not found error.
That's because
ccflags-$(CONFIG_FEATURE_X) += -I$(obj)/../../path
would evaluate to
ccflags-m += -I$(obj)/../../path
According to the current version of Documentation/kbuild/makefiles.txt, there is no such compilation flag as "ccflags-m".
So the path specification is never used for the loadable module.
How can I do this?
Instead of the ccflags-$() flag, you could try to use CFLAGS_$#, a per-file options for $(CC).
CFLAGS_$#, AFLAGS_$#
CFLAGS_$# and AFLAGS_$# only apply to commands in current
kbuild makefile.
$(CFLAGS_$#) specifies per-file options for $(CC). The $#
part has a literal value which specifies the file that it is for.
Example:
# drivers/scsi/Makefile
CFLAGS_aha152x.o = -DAHA152X_STAT -DAUTOCONF
CFLAGS_gdth.o = # -DDEBUG_GDTH=2 -D__SERIAL__ -D__COM2__ \
-DGDTH_STATISTICS
These two lines specify compilation flags for aha152x.o and gdth.o.
$(AFLAGS_$#) is a similar feature for source files in assembly
languages.
Example:
# arch/arm/kernel/Makefile
AFLAGS_head.o := -DTEXT_OFFSET=$(TEXT_OFFSET)
AFLAGS_crunch-bits.o := -Wa,-mcpu=ep9312
AFLAGS_iwmmxt.o := -Wa,-mcpu=iwmmxt
So in your Makefile:
CFLAGS_my_file.o = -I$(obj)/../../path
As noted by the #sawdust answer, it seems (according to documentation) that only ccflags-y variable is supported, not a ccflags-m one.
However, for make things work you may use a "trick":
ccflags-y += ${ccflags-m}
Complete code:
obj-$(CONFIG_FEATURE_X) += my_file.o
ccflags-$(CONFIG_FEATURE_X) += -I$(obj)/../../path
# After all, add content of 'ccflags-m' variable to 'ccflags-y' one.
ccflags-y += ${ccflags-m}

KBUILD_DEFCONFIG_KMACHINE ?= defconfig_file does not work as expected

KBUILD_DEFCONFIG_KMACHINE ?= defconfig_file does not work as I expected.
First lesson I learned: defconfig != .config
Bare-Kernel-Build (without yocto): A new defconfig file below arch/arm/config/xy_defconfig created by make savedefconfig is not equal to the .config file. I assume the linux kernel expand some symbols and create the final .config.
Yocto-Build: Here comes the issue: Yocto can not correctly handle the defconfig file below arch/arm/config/xy_defconfig. When building the linux-kernel with yocto.. the kernel is half size and not bootable. This results, because yocto does not expand the missing symbols in .config, which a make defconfig would do.
How do you handle the issue?
Update:
Figured out an additional make xy_defconfig do the trick and creates the correct .config file. It is a ugly hack, any better ideas are very welcome.
Added this to my custom linux-xy.bb file.
KBUILD_DEFCONFIG ?= xy_defconfig
do_makedefconfig() {
oe_runmake -C ${B} ARCH=${ARCH} $KBUILD_DEFCONFIG
}
addtask do_makedefconfig after do_configme before do_compile
First copy your defconfig to sources/meta-mylayer/recipes-kernel/linux
and write a .bbappend file for linux recipe
linux-ti_%.bbappend
FILESEXTRAPATHS_prepend : "${THISDIR}:"
SRC_URI += "file://your-defconfig"
2. open sources/meta-mylayer/conf/machine/your-machine.conf add below line,
search the macro if already present or nor using grep -inr "INTREE_DEFCONFIG"
INTREE_DEFCONFIG_pn-linux-ti = "am335x_phytec_defconfig"
if the macro already present in the same file replace defconfig name.
kernel-yocto approach
The KBUILD_DEFCONFIG variable is handled by kernel-yocto class, so you need to inherit it. It is usually done indirectly through include file linux-yocto.inc, so you should have this line you linux recipe:
require recipes-kernel/linux/linux-yocto.inc
Please note that KBUILD_DEFCONFIG_KMACHINE consists of two parts. The first one is variable name (KBUILD_DEFCONFIG) and the second one is kernel machine override (KMACHINE). So you need to change the override to fit your machine. That's why the KMACHINE part is written in italics in the documentation [1]. There is an example for RPi from the documentation:
KBUILD_DEFCONFIG_raspberrypi2 = "bcm2709_defconfig"
The KMACHINE is set in linux-yocto.inc to the MACHINE variable by default.
handle in-tree defconfig by hand
We are using in-tree defconfig without the kernel-yocto class. linux.inc from meta-oe layer is used. I don't know if this is a best practice. Here is our linux recipe (it is reduced to a bare minimum):
require recipes-kernel/linux/linux.inc
PV = "your_version"
SRC_URI = "your_sources"
do_configure_prepend() {
bbnote "Copying defconfig"
cp ${S}/arch/${ARCH}/configs/YOUR_defconfig ${WORKDIR}/defconfig
}
[1] https://www.yoctoproject.org/docs/2.4/mega-manual/mega-manual.html#var-KBUILD_DEFCONFIG

How to statically build kernel module with buildroot?

Is there an example package somewhere on how you might go about statically compiling in a device driver?
I know that obj-y is used for static compilation vs obj-m. I have a dynamically loadable module being built in my buildroot package right now. That dynamic module works exactly as I would expect. I even figured out that I could change the module makefile to use obj-y, and add a buildroot option where, if I clicked it it would append a line in the drivers/Makefile. The output appeared to show that my module got built. But it didn't at all seem to me that my driver's init function was being executed at startup, because I don't see my device file in /dev.
Supposing you have a driver in driver.c, and a buildroot package called STATICDRVR, you can use the following Config.in and STATICDRVR.mk files to add a static module to be built when the kernel is built:
Config.in
config BR2_PACKAGE_STATICDRVR
bool "Build & link static driver?"
help
This is a driver that blah blah greatness whatever
STATICDRVR.mk
STATICDRVR_VERSION = master
STATICDRVR_SITE = /location/to/STATICDRVR_containing_src
STATICDRVR_SITE_METHOD = local
STATICDRVR_MODULE_SUBDIRS = src
STATICDRVR_INSTALL_TARGET = YES
STATICDRVR_LICENSE = GPLv2
STATICDRVR_LICENSE_FILES = COPYING
STATICDRVR_NAME = STATICDRVR
STATICDRVR_DEPENDENCIES = linux
define STATICDRVR_BUILD_CMDS
#make sure that obj-y += STATICDRVR/ is only in the build makefile once
sed -i '/obj-y += STATICDRVR/d' $(BUILD_DIR)/linux-$(LINUX_VERSION)/drivers/Makefile
echo "obj-y += STATICDRVR/" >> $(BUILD_DIR)/linux-$(LINUX_VERSION)/drivers/Makefile
rm -rf $(BUILD_DIR)/linux-$(LINUX_VERSION)/drivers/STATICDRVR
cp -r $(#D)/src $(BUILD_DIR)/linux-$(LINUX_VERSION)/drivers/STATICDRVR
echo "obj-y += driver.o" > $(BUILD_DIR)/linux-$(LINUX_VERSION)/drivers/STATICDRVR/Makefile
endef
define STATICDRVR_INSTALL_STAGING_CMDS
endef
define STATICDRVR_INSTALL_TARGET_CMDS
endef
endif
define STATICDRVR_DEVICES
endef
define STATICDRVR_PERMISSIONS
endef
define STATICDRVR_USERS
endef
$(eval $(kernel-module))
$(eval $(generic-package))
It is not possible to statically link an external module with the kernel. To do that, you have to patch the kernel itself and add your module there.

Resources