The Linux kernel makefiles use the Kbuild framework. Although these are interpreted by GNU make, Kbuild consists of a large set of macros with peculiar usage conventions, so typical makefile guidelines do not apply. The nice thing about Kbuild is that you need very little boilerplate considering the complexity of the task.
Kbuild is documented in the kernel source, in Documentation/kbuild
. As a module writer, you should especially read modules.txt
(and at least skim through the others).
What you're doing now isn't working because $(shell pwd)
is expanded when the EXTRA_CFLAGS
variable is used. Since the makefile runs from the kernel source tree rather than from your module's directory (this is one of Kbuild's many nonobvious aspects), it's picking up the wrong directory.
The official idiom for specifying include directories in an out-of-tree module is in §5.3 of modules.txt
. The src
variable is set to your module's toplevel directory. Therefore:
EXTRA_CFLAGS := -I$(src)/src/inc
Note that this declaration should be in a file called Kbuild
at the root of your module tree. (You may want to consider the src
directory to be the root of your module tree; if so, put Kbuild
there and replace the value above by -I$(src)/inc
). It's also possible to put them in a Makefile
, but mind that this definition (as long as anything else that applies only when building a kernel module) should be within a conditional directive ifeq ($(KERNELRELEASE),)
. See §4.1 of modules.txt
.
If you don't have a Kbuild
file already and want to switch to having one, read §4.1 of modules.txt
. Having a separate Kbuild
file is slightly clearer. Don't put anything that applies to the kernel in your main makefile, other than a rule to call make -C $(KERNELDIR) M=$(pwd)
. In Kbuild
, the minimum you need is the list of modules you're building (often just the one) and a list of files to include in your module, plus a dependency declaration:
EXTRA_CFLAGS := -I$(src)/inc
obj-m := mymod.o
mymod-y := $(src)/mod/mymod.o
$(src)/mod/mymod.o: $(src)/inc/mymod.h