Makefile obj-m变量如何导出到sub make?

Makefile obj-m变量如何导出到sub make?,makefile,gnu-make,kbuild,Makefile,Gnu Make,Kbuild,我试图通过阅读GNU make手册来学习linux内核模块构建和kbuild 以下是Linux内核模块编程指南中第一个示例Hello-1的Makefile: obj-m += hello-1.o all: make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules clean: make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean 好的,obj-

我试图通过阅读GNU make手册来学习linux内核模块构建和kbuild

以下是Linux内核模块编程指南中第一个示例Hello-1的Makefile:

obj-m += hello-1.o

all:
    make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules

clean:
    make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
好的,
obj-m
应该由kbuild读取。然而,根据GNU Make手册,我知道不应该导出
obj-m

除非通过显式请求,否则仅当变量为 最初在环境中定义或在命令上设置 行,如果其名称仅由字母、数字和 强调。有些shell无法处理环境变量名 由字母、数字和下划线以外的字符组成


obj-m
最初既不在环境中定义,也不在命令行中设置。所以我希望它不应该导出到target
all
的配方中。kbuild如何访问obj-m?

您的makefile调用子make并将指向当前目录的make变量
m
传递给它。使用
-C
选项调用submake,使其运行时如同从指定目录(即内核源目录)调用一样。因此,使用的是具有自己的makefile的内核构建系统。由于
M
变量,内核makefile知道在哪里可以找到makefile,并将其包含在
obj-M
定义中

注意:您显示的makefile可能需要修改一些条件,以便在Linux构建系统中只能看到
obj-m
变量定义。否则,makefile的
all
clean
目标与内核makefile中具有相同名称的目标之间存在冲突的风险。而且,正如疯狂科学家所指出的,使用
make
不是一个好主意<代码>$(MAKE)更好。您可能应该使用以下内容:

ifeq ($(KERNELRELEASE),)
all:
    $(MAKE) -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules

clean:
    $(MAKE) -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
else
obj-m += hello-1.o
endif

包含Makefile是有意义的。现在我明白了为什么LDD3的作者一直说Makefile会被读取两次。您对if语句的改进与LDD3推荐的方式非常相似,我现在理解了。也许,如果我也用$(make)切换make会更好。谢谢。@Alper绝对是,
$(MAKE)
必须是首选。注意:如果您很好奇,想知道内核构建系统的哪个makefile包含您的makefile,只需更改makefile的名称,并在调用make时使用
-f
选项。您应该会得到一个关于
Makefile not found
的错误,错误消息应该会告诉您哪个内核Makefile遇到了问题以及在哪一行。哇!微妙的调试方式。我检查并看到scripts/Makefile.build:44给出了一个错误,对应于消息第一次修订时编写的Makefile.bulid代码段。这是一个糟糕的示例。您应该始终使用变量
$(make)
调用递归make,而决不能使用如上所示的硬编码
make
命令。@madscietist是的,您是对的。我们还讨论了这个问题的答案后。这是Linux内核模块编程指南中给出的Makefile示例我知道,这就是我想说的:该指南中给出的示例是一个糟糕的示例。