While learning Linux kernel modules I can see (so far from two sources) two ways for writing Makefile. The first is something like:
ifneq ($(KERNELRELEASE),)
obj-m := module.o
else
default:
$(MAKE) -C /lib/modules/$(shell uname -r)/build M=$(shell pwd) modules
endif
The latter is less complex:
obj-m := module.o
all:
$(MAKE) -C /lib/modules/$(shell uname -r)/build M=$(shell pwd) modules
Either makefile compilation leads to successfully compiled module. My learning is accompanied with the LDD3 book and what I have read so far from it is the next one:
This makefile is read twice on a typical build. When the makefile is invoked from the command line, it notices that the KERNELRELEASE variable has not been set. It locates the kernel source directory by taking advantage of the fact that the symbolic link build in the installed modules directory points back at the kernel build tree. If you are not actually running the kernel that you are building for, you can supply a KERNELDIR= option on the command line, set the KERNELDIR environment variable, or rewrite the line that sets KERNELDIR in the makefile. Once the kernel source tree has been found, the makefile invokes the default: target, which runs a second make command (parameterized in the makefile as $(MAKE))to invoke the kernel build system as described previously. On the second reading, the makefile sets obj-m, and the kernel makefiles take care of actually building the module.
If the makefile is read twice then the second approach should lead to recursion, isn't it?
The top Makefile is responsible for building two major products: vmlinux (the resident kernel image) and modules (any module files). It builds these goals by recursively descending into the subdirectories of the kernel source tree. The list of subdirectories which are visited depends upon the kernel configuration.
$(obj-m) specifies object files which are built as loadable kernel modules. A module may be built from one source file or several source files. In the case of one source file, the kbuild makefile simply adds the file to $(obj-m).
When you call the Makefile for the first time by typing #make
on the console you are not passing any target.
So, It will call the target name all:
in the makefile by default.
Inside the all:
target you are passing the target as modules.So, this time it will build the modules instead of going to all:
targets.
SO its not going to be infinite Recursion.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With