如何链接其他目录中的文件?

时间:2017-06-01 18:58:45

标签: kernel-module kbuild

我有一个足够大的项目,可以通过目录对文件进行分类。我试图在所有内核模块中构建一个内核模块。

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的一部分,而不是它自己的模块?

1 个答案:

答案 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,但仍然会受到劝阻。

在此期间我会坚持这个解决方案,但由于它们都不理想,我想我会暂时搁置这个问题。