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 调用默认值:target,它运行第二个 make 命令(在 makefile 中参数化为 $(MAKE))来调用内核构建系统,如前所述。在二读时,makefile 设置了 obj-m,

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

4

1 回答 1

4

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

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

所以它不会是无限递归。

于 2013-06-15T12:39:54.567 回答