I'm trying to compile a simple hello world module following this guide and I'm confused about what the Makefile
is actually doing.
Here it is:
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
I understand that when I type the make
command it will run the all
recipe which runs make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
. So now it runs the Makefile found at the path given after the -C
flag, but what does the M=$(PWD) modules
do?
Here is a breakdown:
obj-m
: specifies object files which are built as loadable kernel modules.
all
and clean
: If you run make
by default it will run the first target, which is all
. But we can use make all
and make clean
too: it will run only those specific targets.
For example:
make all
# Will run: make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
make clean
# Will run: make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
uname -r
: get version information about the current kernel.
Example: for me, the output is 4.6.0-rc1
.
Option -C dir
: change to directory dir
before reading the makefiles in there.
Example:
make -C /lib/modules/$(shell uname -r)/build
# Will translate to: make -C /lib/modules/4.6.0-rc1/build
# And execute the Makefile at /lib/modules/4.6.0-rc1/build/Makefile
$(PWD)
: get the path of your current directory.
Now you want to create your loadable module by using:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
Your source code needs a specific environment to be compiled. That's why we have to use the -C
option to change build directory. Which have all needed definitions, header file, macros etc. Now after changing to the build directory you tell the kernel Makefile where your module is located using M=$(PWD)
.