2013-06-12 892 views
8

在学习Linux内核模块时,我可以看到(迄今为止有两种来源)编写Makefile的两种方式。首先是这样的: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的行。一旦找到内核源代码树,生成文件 将调用缺省目标,该目标会运行第二个make命令(参数为 ,makefile为$(MAKE))以调用内核生成系统,如前所述。 在第二次阅读时,makefile设置obj-m,内核makefiles负责实际构建模块的 。

如果makefile被读取两次,那么第二种方法应该导致递归,不是吗?

+5

递归(在此上下文中)被定义为Make调用Make的另一个实例的一个实例。所以第二种方法涉及递归。如果您问第二种方法是否导致无限循环,答案是否定的,因为Make的第二个实例具有“模块”作为目标,而不是“全部”。这是否回答你的问题? – Beta

+1

测试版,您应该将其作为回答发布,而不是评论。我会喜欢你的。我会补充一点,这两种方法都使用递归来工作,但第一个结果使得稍微更加明显的是,第二遍中不会调用“默认”或“全部”规则。 –

+0

@Beta,你能更详细地解释一下这不是导致内部递归吗?可能发布你的答案,我会upvote你^^。 (看着kbuild的Makefile的源代码不能让我知道内部的问题) – mesmerizingr

回答

3

当您通过在控制台上键入#make第一次调用Makefile时,您没有传递任何目标。 因此,默认情况下,它会在makefile中调用目标名称all:

all:目标内部,您将目标作为模块传递。因此,这次它将构建模块而不是去all:目标。

SO它不会无限递归。