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

时间:2018-06-07 13:40:54

标签: makefile gnu-make kbuild

我正在尝试通过关注https://www.tldp.org/LDP/lkmpg/2.6/lkmpg.pdf和阅读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

AFAIK,obj-m应由kbuild阅读。但是根据GNU Make手册,我了解不应导出obj-m

  

除了显式请求之外,仅在导出时才导出变量   最初在环境中定义或在命令上设置   如果它的名称只包含字母,数字和   下划线。有些shell无法处理环境变量名称   由字母,数字和下划线以外的字符组成。

https://www.gnu.org/software/make/manual/html_node/Variables_002fRecursion.html

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

1 个答案:

答案 0 :(得分:1)

你的makefile调用一个submake并传递指向当前目录的make变量M。使用-C选项调用子制表,使其像从指定目录(即内核源目录)调用一样运行。因此,内核构建系统具有自己的makefile。感谢M变量,内核makefile知道他们在哪里可以找到你的makefile并将其包含在obj-m定义中。

注意:您显示的makefile可能应该使用条件进行一些修改,以便只能从Linux构建系统中看到obj-m变量定义。否则,makefile的allclean目标与内核makefile中具有相同名称的目标之间可能会发生冲突。而且,正如MadScientist所指出的,使用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