I am trying to learn linux kernel module building and kbuild by following https://www.tldp.org/LDP/lkmpg/2.6/lkmpg.pdf and reading GNU make manual.
Here is the Makefile of the first example, Hello-1, on The Linux Kernel Module Programming Guide:
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
should be read by kbuild. However according to GNU Make manual, I understand that obj-m
shouldn't be exported.
Except by explicit request, make exports a variable only if it is either defined in the environment initially or set on the command line, and if its name consists only of letters, numbers, and underscores. Some shells cannot cope with environment variable names consisting of characters other than letters, numbers, and underscores.
https://www.gnu.org/software/make/manual/html_node/Variables_002fRecursion.html
obj-m
is neither defined in the environment initially nor set on command line. So I expect that it shouldn't exported to recipe of target all
. How does kbuild access obj-m
?
Your makefile calls a submake and passes it the make variable M
that points to the current directory. The submake is invoked with the -C
option such that it is run as if it was invoked from the specified directory, that is the kernel source directory. It is thus the kernel build system with its own makefiles that is used. Thanks to the M
variable the kernel makefiles know where they can find your makefile and include it with its obj-m
definition.
Note: the makefile you show should probably be modified a bit with conditionals such that only the obj-m
variable definition is visible from the Linux build system. Else, there is a risk of collision between the all
and clean
targets of your makefile and targets with the same names in the kernel makefiles. And, as noted by MadScientist, using make
is not a good idea; $(MAKE)
is preferable. You should probably use something like:
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