我有一个足够大的项目,可以通过目录对文件进行分类。我试图在所有内核模块中构建一个内核模块。
documentation声明如下:
contentType
但是,这似乎与我的需求不同。这是由两个独立的--- 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.
文件组成的;每个目录中有一个,每个目录文件都在其自己的目录中合并。
这是我的项目(简化):
.ko
我认为最终会有这样的结论是合理的:
root directory
|
+--- Makefile
|
+--- foo.c
|
+--- subdir
|
+--- Makefile
|
+--- bar.c
我最终得到的是:
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)
我希望每个目录构建一个模块不是Kbuild设计的基本假设。运送几个模块听起来很乱,但没有收获。
这是我的根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)
:
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 $@
:
subdir/Makefile
这是obj-m += bar.o
:
foo.c
这是int external_function(void);
int test(void)
{
return external_function();
}
:
subdir/bar.c
int external_function(void)
{
return 4;
}
(在根目录中)会发出以下警告:
make
我拒绝插入WARNING: "external_function" [(...)/kernel-module.ko] undefined!
的尝试:
kernel-module.ko
如何告诉Kbuild $ 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)
应该是subdir/bar.o
的一部分,而不是它自己的模块?
答案 0 :(得分:1)
一种解决方案是将bar的目标文件附加到内核模块的对象列表中。这段代码存在问题:
obj-m += kernel-module.o
obj-m += subdir/
kernel-module-objs += foo.o
它是否告诉Kbuild下降到subdir/
,但它没有告诉它在kernel-module
中包含该结果。
这可以解决这个问题:
obj-m += kernel-module.o
obj-m += subdir/
kernel-module-objs += foo.o subdir/bar.o
但是,我根本不喜欢这个解决方案,因为它违反了DRY原则:这意味着bar.o
必须被命名两次;一个位于/Makefile
,另一个位于/subdir/Makefile
。
此外,此解决方案并不能阻止Kbuild创建冗余的subdir/bar.ko
模块。
最后,某些documentation表示它是"不建议练习"一些完全没有说明理由。
所以这个解决方案非常糟糕。我不认为我会坚持下去。
另一个解决方案(从前一个解析)只是删除subdir/Makefile
,并在根Makefile中删除,而不是:
obj-m += kernel-module.o
obj-m += subdir/
kernel-module-objs += foo.o
这样做:
obj-m += kernel-module.o
kernel-module-objs += foo.o subdir/bar.o
这可以修复DRY问题并阻止生成subdir/bar.ko
,但仍然会受到劝阻。
在此期间我会坚持这个解决方案,但由于它们都不理想,我想我会暂时搁置这个问题。