Reputation: 1138
I have a project that is big enough to benefit from having its files classified by directory. I'm trying to build one kernel module out of all of them.
The documentation states the following:
--- 3.6 Descending down in directories
A Makefile is only responsible for building objects in its own
directory. Files in subdirectories should be taken care of by
Makefiles in these subdirs. The build system will automatically
invoke make recursively in subdirectories, provided you let it know of
them.
To do so, obj-y and obj-m are used.
ext2 lives in a separate directory, and the Makefile present in fs/
tells kbuild to descend down using the following assignment.
Example:
#fs/Makefile
obj-$(CONFIG_EXT2_FS) += ext2/
If CONFIG_EXT2_FS is set to either 'y' (built-in) or 'm' (modular)
the corresponding obj- variable will be set, and kbuild will descend
down in the ext2 directory.
However, this seems to be different from what I need. What comes out of this is two independent .ko
files; one in each directory, each an amalgamation of the object files in its own directory.
This is my project (simplified):
root directory
|
+--- Makefile
|
+--- foo.c
|
+--- subdir
|
+--- Makefile
|
+--- bar.c
I would think that ending up with something like this would be reasonable:
root directory
|
+--- Makefile
|
+--- foo.c
|
+--- foo.o (containing foo.c's stuff)
|
+--- subdir
| |
| +--- Makefile
| |
| +--- bar.c
| |
| +--- bar.o (containing bar.c's stuff)
|
+--- kernel-module.ko (containing foo.o and subdir/bar.o)
What I really end up with is this:
root directory
|
+--- Makefile
|
+--- foo.c
|
+--- foo.o (containing foo.c's stuff)
|
+--- subdir
| |
| +--- Makefile
| |
| +--- bar.c
| |
| +--- bar.o (containing bar.c's stuff)
| |
| +--- bar.ko (containing bar.o)
|
+--- kernel-module.ko (containing only foo.o)
I'm hoping that building one module per directory is not a fundamental assumption of Kbuild's design. Shipping several modules sounds like a lot of mess for no gain.
This is my root Makefile
:
KERNEL_DIR ?= /lib/modules/$(shell uname -r)/build
obj-m += kernel-module.o
obj-m += subdir/
kernel-module-objs += foo.o
all:
make -C ${KERNEL_DIR} M=$$PWD
modules:
make -C ${KERNEL_DIR} M=$$PWD $@
clean:
make -C ${KERNEL_DIR} M=$$PWD $@
This is subdir/Makefile
:
obj-m += bar.o
This is foo.c
:
int external_function(void);
int test(void)
{
return external_function();
}
And this is subdir/bar.c
:
int external_function(void)
{
return 4;
}
make
(in the root directory) spits the following warning:
WARNING: "external_function" [(...)/kernel-module.ko] undefined!
And my attempts to insert kernel-module.ko
are refused:
$ sudo insmod kernel-module.ko
insmod: ERROR: could not insert module kernel-module.ko: Unknown symbol in module
$ dmesg | tail -1
[11688.540153] kernel_module: Unknown symbol external_function (err 0)
How do I tell Kbuild that subdir/bar.o
is supposed to be part of kernel-module.ko
and not its own module?
Upvotes: 2
Views: 1750
Reputation: 1138
One solution is to append bar's object file to the kernel module's object listing. The problem with this code:
obj-m += kernel-module.o
obj-m += subdir/
kernel-module-objs += foo.o
Is that it's telling Kbuild to descend to subdir/
, but it's not telling it to include the results of that in kernel-module
.
This would fix that:
obj-m += kernel-module.o
obj-m += subdir/
kernel-module-objs += foo.o subdir/bar.o
However, I don't like this solution at all because it breaks the DRY principle: It means bar.o
has to be named twice; one in /Makefile
and the other one in /subdir/Makefile
.
Also, this solution doesn't prevent Kbuild from creating the redundant subdir/bar.ko
module.
Finally, certain documentation states that it is "NOT recommended practice" for some completely unstated reason.
So this solution is pretty bad. I don't think I will stick to it.
Another solution (which branches from the previous one) is to just delete subdir/Makefile
and, within the root Makefile, instead of this:
obj-m += kernel-module.o
obj-m += subdir/
kernel-module-objs += foo.o
do this:
obj-m += kernel-module.o
kernel-module-objs += foo.o subdir/bar.o
This fixes the DRY issue and prevents subdir/bar.ko
from being generated but still suffers from discouraged practice.
I will stick to this solution in the meantime, but since neither of them is ideal, I guess I'll leave the question open for a while.
Upvotes: 1