Linux内核模块编程:makefile

9

在学习Linux内核模块时,我发现(迄今为止来自两个来源)有两种编写Makefile的方法。第一种方法大致如下:

ifneq ($(KERNELRELEASE),)
        obj-m := module.o
else
default:
        $(MAKE) -C /lib/modules/$(shell uname -r)/build M=$(shell pwd) modules
endif

后者较为简单:
obj-m := module.o
all:
        $(MAKE) -C /lib/modules/$(shell uname -r)/build M=$(shell pwd) modules

无论是makefile编译还是成功编译的模块,在我的学习中都与LDD3书籍相伴。目前我所阅读的内容如下:
当从命令行调用makefile时,该makefile通常会被读取两次。它注意到KERNELRELEASE变量未设置,并利用已安装模块目录中构建的符号链接指回内核构建树,以定位内核源目录。如果您实际上没有运行正在构建的内核,则可以在命令行上提供KERNELDIR =选项、设置KERNELDIR环境变量或重写在makefile中设置KERNELDIR的那行。一旦找到内核源树,makefile将调用默认目标,运行第二个make命令(在makefile中参数化为$(MAKE)),如上述描述,调用内核构建系统。在第二次阅读中,makefile设置obj-m,内核makefile负责实际构建模块。
如果makefile被读取两次,第二种方法是否应导致递归呢?

5
递归(在本文中)被定义为一个Make实例调用另一个Make实例。因此,第二种方法涉及递归。如果您想知道第二种方法是否会导致无限循环,答案是否定的,因为第二个Make实例的目标是“modules”,而不是“all”。这回答了你的问题吗? - Beta
1
Beta,你应该将其发布为答案而不是评论。我会给你点赞。我想补充一下,两种方法都使用递归来工作,但第一个结果使得“默认”或“全部”规则在第二次通过时稍微更加明显。 - Benjamin Leinweber
@Beta,你能详细解释一下这个问题是如何导致make内部递归的吗?也许你可以发表你的答案,我会点赞的^^。(观察kbuild的Makefile源代码并不能让我理解其内部原理) - mesmerizingr
1个回答

4
当您在控制台上键入#make进行第一次调用Makefile时,您没有传递任何目标。因此,默认情况下,它将调用Makefile中的目标名称all:
all:目标内,您将目标作为模块传递。所以,这一次它将构建模块而不是转到all:目标。
所以它不会是无限递归。

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