How to include local header files in linux kernel module
Solution 1
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
Solution 2
Traditionally the way to #include
files with paths relative to the current source code's directory is to use quotation marks rather than angle brackets:
#include <stdio.h>
#include "mygreatfunctions.h"
In this case, the first #include
will reference the compiler's include search path (which, in the case of gcc, is controlled by the -I
command line switch), whereas the second will look in the directory that contains the source file with the #include
.
Such paths can be relative, too. So in src/mod/mymod.c, you can say:
#include "../inc/mymod.h"
and it should "just work".
I don't know if this is common practice in the Linux kernel tree, but surely it's better than mucking around with the include path, which could have any number of unintended side effects.
Related videos on Youtube
Om Narasimhan
Updated on September 18, 2022Comments
-
Om Narasimhan over 1 year
Say I have a module
mymod
with source files as follows:src/mod/mymod.c
src/inc/mymod.hI try to include mymod.h as follows
#include <mymod.h>
My makefile contains
EXTRA_CFLAGS= -I$(shell pwd)/../inc/
but when the kernel is made, I get an error stating:mymod.h not found
The reason seems to be that when kernel modules are made this command gets run from the makefile: (using
make
V1):make -C <path/to/linux/src> M=<path/to/mymod> modules
In other works my
$(shell pwd)
got expanded to<path/to/linux>
. This is not what I want. How can I specify the-I
parameter to point tosrc/inc
of mymymod
source tree? -
Om Narasimhan almost 13 yearsI could not update the post because I did not have enough reputation.
-
user almost 13 years@Om Narasimhan: If this helped you figure out the solution, you should mark the answer as accepted.
-
vonbrand over 11 yearsSure enough, but the C compiler behaviour of looking for <foo> in some configured set of directories, and for "bar" looking first at the current directory and then falling back to the path mentioned before won't change by what bizarre means called the compiler in the first place.