具有多个子目录的Linux内核模块的Makefile

3
我需要关于内核模块的Makefile的帮助。即使有例子也将是很大的帮助。
目前我的模块代码在多个目录下。假设
<MAIN-DIR> --- l2.c 
    <SUB-DIR1> --- hello.c
    <SUB-DIR2> --- bye.c

针对上述情况,我应该如何编写Makefile呢?因为我需要构建L2模块,而构建L2模块需要使用到l2.o、hello.o和bye.o这三个目标文件,但它们目前位于多个不同的目录中。
1个回答

6

如果你正在从内核树中构建一个模块,一个简单的Makefile应该像下面这样:

MODULE_NAME = mymodule

SRC     := foo.c src/bar.c

# Path to target Linux Kernel
KDIR        := $(shell pwd) # <--- Fill in with path to kernel you're compiling against

$(MODULE_NAME)-objs = $(SRC:.c=.o)

obj-m       := $(MODULE_NAME).o
PWD     := $(shell pwd)

EXTRA_CFLAGS := -I$(PWD)/src -I$(PWD)/include

all:
    $(MAKE) -C $(KDIR) M=$(PWD) modules

如在SRC :=行中所示,您只需指定所有源文件的路径,包括子目录中的文件。位于KDIR中的顶层内核Makefile将负责编译。

有关内核构建系统和树外构建的更多信息,请参阅内核源代码文档中的Documentation/kbuild/modules.txt


谢谢回复,但似乎对我没有用。问题是<SUB_DIR1>中的.c文件包含了<SUB_DIR2>中的头文件。因此,当我运行makefile时,它会说无法访问使用“”包含的头文件。 - codingfreak
1
我已经更新了示例。您可以使用EXTRA_CFLAGS向编译器传递其他标志,例如额外的包含目录。在没有指定目录的情况下,让<SUB_DIR2>中的某些内容包含来自<SUB_DIR1>的头文件似乎有点奇怪。通常将这些包含分组到一个目录中,并从那里引用它们,可能在Makefile中使用EXTRA_CFLAGS:= -I$(PWD)/include子句。 - Austin Phillips
谢谢。还有一个小问题。我已经修改了内核以包含一个新函数,并在EXPORT_SYMBOL中声明了它。现在我正在从我的.c文件中调用该函数。当我编译时,我会收到错误消息,说隐式声明..理想情况下,这应该在链接时间而不是.o创建时间处理,对吧? - codingfreak
如果您已经导出了一个符号,您还应该在Linux内核头文件中的一个extern中包含它的声明。随后,您的.c模块源代码应该#included这个头文件。您不应该依赖于隐式声明。 - Austin Phillips
那么,对于从同一模块的其他.c文件中包含的函数怎么办?实际上,我有一个在l2.h中声明并在l2.c中定义的函数。现在我正在hello.c和bye.c中使用该函数,甚至包括头文件l2.h。但是当生成.ko文件时,它会将该函数标记为未定义。 - codingfreak
1
在上述设置中,编译hello.c和bye.c时不应该出现任何编译器警告,因为已经包含了l2.h,所以不会有隐式声明警告。如果您遇到函数未定义的情况,那么这听起来像是链接器错误,即最终对象中没有包含l2.o(其中包含您的函数定义)。运行make时,请使用“make V = 1”打开详细输出以显示错误位置。 - Austin Phillips

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接