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?