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时,会注意到KERNELRELEASEvariables没有被设置。 它通过利用已安装模块目录中的符号链接构build指向内核构build树的事实来定位内核源代码目录。 如果你实际上没有运行正在构build的内核,你可以在命令行提供一个KERNELDIR =选项,设置KERNELDIR环境variables,或者重写在makefile中设置KERNELDIR的行。 一旦find内核源代码树,makefile会调用默认:target,它将运行第二个make命令(在makefile中参数化为$(MAKE))来调用内核构build系统,如前所述。 在第二次阅读时,makefile设置obj-m,内核makefiles负责实际构build模块。

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

当你通过在控制台上键入#make首次调用Makefile时,你没有传递任何目标。 所以,它会默认调用目标名all:在makefile中。

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

所以它不会是无限的递归。