8

我正在使用共享源代码构建一组 Linux 内核模块。据我了解,Makefile 必须命名为“Makefile”,因此我必须使用相同的 Makefile 来构建两个不同的模块。如何在同一个 Makefile 中使用相同的源代码构建两个不同的模块,但使用两个不同的构建选项?

例如,我的模块被称为 module1 和 module2。所以我有以下行来定义它们:

obj-m := module1.o module2.o

在其他文件中,module1 和 module2 都需要使用相同的源文件code.c,但使用不同的构建选项构建。例如,Makefile 包含以下几行:

module1-objs = module1_code.o other_code.o
module2-objs = module2_code.o other_code.o

我想要module1_code.omodule2_code.o从 code.c 构建,但有不同的选项。具体来说,我想要一个module1_code.o定义了宏-DPREPROCEFFOR_FLAG=1,并module2_code.o在没有宏的情况下构建的。

据我了解,Linux 中使用的 Makefile 系统隐含地推断,对于名为“code.o”的目标文件,源文件名为“code.c”,那么我将如何实现呢?有可能吗?有一个更好的方法吗?

4

2 回答 2

5

你在这里有一个问题,因为你显然在定义code.c时被编译了不同-DPREPROCEFFOR_FLAG=1的,但是一旦它被编译成code.o,make就不会关心预处理器标志或任何东西,因为code.o它已经是最新的了。

您需要一种方法来构建code.c具有不同 C 标志的不同目标文件。可能有一种干净的方法可以做到这一点(没有机会使用O=树外模块),但这是我目前不雅但有效的解决方案:

my_modules:
    cp code.c code_noflags.c
    cp code.c code_withflags.c
    make -C $$KDIR M=$$PWD modules
    rm code_noflags.c code_withflags.c

# module objects
obj-m := module1.o module2.o

# module1 specifics
module1-y := code_withflags.o
CFLAGS_code_withflags.o := -DPREPROCEFFOR_FLAG=1

# module2 specifics
module2-y := code_noflags.o

只需致电:

$ make KDIR=/path/to/kernel

您可以使用以下方法验证预处理器标志是否已传递给正确对象的源文件:

$ make KDIR=/path/to/kernel V=1 | grep PREPRO

如果可能的话,您还可以为每个模块设置两个单独的目录,并code.c在每个目录中都有一个指向共同实数的符号链接code.c。但是,这仍然是hackish,感觉不对。

于 2013-08-22T17:29:55.440 回答
3

一个简单的解决方案是,从您的 Makefile 继续

obj-m := module1.o module2.o

module1-objs = module1_code.o other_code.o
module2-objs = module2_code.o other_code.o

添加另外两个源文件,module1_code.c 和 module2_code.c。

然后 module1_code.c 看起来像:

#define PREPROCEFFOR_FLAG 1
#include "code.c"

和 module2_code.c 是:

#include "code.c"

或者,如果您愿意,可以更改 Makefile 和源文件中的名称,以便不需要没有定义的第二个包含。如果您愿意,您也可以使这两个源文件只包含一个包含并使用该CFLAGS_module1_code.o变量将-D...选项添加到编译器。

这类似于在上游内核中发生的事情arch/x86/boot/video-vesa.c等等arch/x86/realmode/rm/video-vesa.c,其中实模式文件只包含:

#include "../../boot/video-vesa.c"

并且 video-vesa.c 代码最终会使用不同的编译器标志编译两次。

这似乎比复制源文件更可取,因为如果您想使用O=...内核构建的选项来保持干净的源树并在单独的对象树中构建,那么最终会出现混乱。

于 2013-08-23T08:57:46.320 回答