如何在Linux内核模块中包括本地头文件


17

说我有一个mymod包含源文件的模块,如下所示:

src / mod / mymod.c
src / inc / mymod.h

我尝试包括mymod.h如下

#include <mymod.h>

我的makefile包含EXTRA_CFLAGS= -I$(shell pwd)/../inc/但在制作内核时,出现错误提示:

找不到mymod.h

原因似乎是在制作内核模块时,此命令从makefile:运行(使用makeV1):

make -C <path/to/linux/src> M=<path/to/mymod> modules

在其他作品中我$(shell pwd)扩展到了<path/to/linux>。这不是我想要的。我如何指定-I参数设置为指向src/inc我的mymod源代码树?

Answers:


19

Linux内核makefile使用Kbuild框架。尽管这些是由GNU make解释的,但Kbuild由大量具有特殊用法约定的宏组成,因此典型的makefile准则不适用。关于Kbuild的好处是,考虑到任务的复杂性,您几乎不需要样板。

Kbuild记录在内核源代码的Documentation/kbuild。作为模块编写者,您应该特别阅读modules.txt(并至少略读其他内容)。

您现在正在执行的操作无法正常工作,因为使用$(shell pwd)EXTRA_CFLAGS变量时会扩展该功能。由于makefile是从内核源代码树而不是模块目录运行的(这是Kbuild的许多不明显的方面之一),因此它选择了错误的目录。

在树外模块中指定包含目录的官方惯用语在的第5.3节中modules.txt。该src变量设置为模块的顶级目录。因此:

EXTRA_CFLAGS := -I$(src)/src/inc

请注意,此声明应位于Kbuild模块树根目录中的文件中。(您可能希望将src目录视为模块树的根;如果是这样,请放在该目录中,Kbuild并用替换上面的值-I$(src)/inc)。也可以将它们放在中Makefile,但是请注意,此定义(只要在构建内核模块时适用的任何其他条件)应在条件指令内ifeq ($(KERNELRELEASE),)。参见的第4.1节modules.txt

如果您还没有Kbuild文件,并且想要切换到一个文件,请阅读的§4.1 modules.txt。拥有一个单独的Kbuild文件会更清晰一些。除了要调用的规则外,不要在主makefile中放入任何适用于内核的内容make -C $(KERNELDIR) M=$(pwd)。在中Kbuild,您最少需要的是正在构建的模块列表(通常只是一个模块)和要包含在模块中的文件列表,以及一个依赖项声明:

EXTRA_CFLAGS := -I$(src)/inc
obj-m := mymod.o
mymod-y := $(src)/mod/mymod.o
$(src)/mod/mymod.o: $(src)/inc/mymod.h

我没有足够的声誉,因此无法更新该帖子。
Om Narasimhan,时间

1
@Om Narasimhan:如果这可以帮助您找到解决方案,则应将答案标记为已接受。
的CVn

1

传统上,#include使用相对于当前源代码目录的路径进行文件存储的方法是使用引号而不是尖括号:

#include <stdio.h>
#include "mygreatfunctions.h"

在这种情况下,第一个#include将引用编译器的include搜索路径(对于gcc,它是由-I命令行开关控制的),而第二个将在包含源文件的目录中使用#include

这样的路径也可以是相对的。因此,在src / mod / mymod.c中,您可以说:

#include "../inc/mymod.h"

它应该“正常工作”。

我不知道这在Linux内核树中是否很常见,但是肯定比混入include路径更好,因为include路径可能会产生许多意外的副作用。


1
一般而言,这是一个很好的建议,但是Linux内核makefile非常特殊。他们调用了一个相当复杂的宏集,称为Kbuild。通常最好将Kbuild视为与make几乎(但不是完全)完全不同的一种语言。
吉尔(Gilles)'所以

1
确实可以,但是C编译器的行为是在某些已配置的目录集中查找<foo>,然后先在当前目录中查找“ bar”,然后返回先前提到的路径,“ bar”不会因为奇怪的意思而改变首先是编译器。
vonbrand 2013年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.