我正在尝试构建 Linux 内核模块:
KBUILD_EXTRA_SYMBOLS := ../../Module.symvers
KBUILD_EXTRA_SYMBOLS := ../../dir0/Module.symvers
KDIR = ../../../../kernel/linux-4.9
INCLUDES = \
-I../dir1/dir2/dir3 \
-I../dir1/dir2 \
-I../dir1
EXTRA_CFLAGS += $(INCLUDES)
PWD = $(shell pwd)
TARGET = some_module
obj-m := $(TARGET).o
all: default clean
default:
make $(INCLUDES) -C $(KDIR) M=$(PWD) modules
clean:
@rm -f *.o .*.cmd .*.flags *.mod.c *.order
@rm -f .*.*.cmd *.symvers *~ *.*~ TODO.*
@rm -fR .tmp*
@rm -rf .tmp_versions
disclean: clean
@rm -f *.ko
但它无法在相对路径中找到文件,例如喜欢fatal error: some_header.h: No such file or directory
。当我使用绝对路径时,它工作得很好,但我需要从该项目中的当前目录进行相对寻址。怎么了?
抱歉,如果很明显的话。
Linux内核使用Kbuild来制作模块。该框架与普通的 makefile 约定不同,因此虽然它们都由 GNU make 解释,但需要注意其中的差异。使用 Kbuild 的 Makefile 文档可以在这里找到 https://www.mjmwired.net/kernel/Documentation/kbuild/makefiles.txt and 构建外部内核模块的文档可以在这里找到 https://www.kernel.org/doc/Documentation/kbuild/modules.txt.
下面引用了文档中与您的问题相关的一些要点。
From makefiles.txt
:
--- 3.10 特别规则
当 kbuild 基础设施不提供所需的支持时,将使用特殊规则。一个典型的例子是头文件
在构建过程中生成。另一个例子是
需要特殊规则来准备的特定于体系结构的 Makefile
启动映像等。特殊规则按照正常的 Make 规则编写。 Kbuild 并不是在 Makefile 所在的目录中执行,所以所有
特殊规则应提供先决条件文件的相对路径
和目标文件。定义特殊规则时使用两个变量:
~$(src)
~
$(src)
是指向Makefile所在目录的相对路径。总是使用$(src)
当引用位于src
tree.
~$(obj)
~
$(obj)
是一个相对路径,指向保存目标的目录。总是使用$(obj)
当引用生成的文件时。
From modules.txt
:
--- 4.3 几个子目录
kbuild 可以处理分布在多个目录中的文件。
考虑以下示例:
.
|__ src
| |__ complex_main.c
| |__ hal
| |__ hardwareif.c
| |__ include
| |__ hardwareif.h
|__ include
|__ complex.h
为了构建模块complex.ko,我们需要以下kbuild
文件:
--> filename: Kbuild
obj-m := complex.o
complex-y := src/complex_main.o
complex-y += src/hal/hardwareif.o
ccflags-y := -I$(src)/include
ccflags-y += -I$(src)/src/hal/include
正如你所看到的,kbuild 知道如何处理位于
其他目录。技巧是指定相对于的目录
kbuild 文件的位置。话虽如此,不推荐这样做
实践。
对于头文件,必须明确告诉 kbuild 在哪里查找。
当kbuild执行时,当前目录始终是根目录
内核树(“-C”的参数),因此绝对路径是
需要。$(src)
通过指向提供绝对路径
当前正在执行的kbuild文件所在的目录。
因此,您的 Makefile 应如下所示:
KBUILD_EXTRA_SYMBOLS := $(src)/../../Module.symvers
KBUILD_EXTRA_SYMBOLS := $(src)/../../dir0/Module.symvers
KDIR = $(src)/../../../../kernel/linux-4.9
INCLUDES = \
-I$(src)/../dir1/dir2/dir3 \
-I$(src)/../dir1/dir2 \
-I$(src)/../dir1
EXTRA_CFLAGS += $(INCLUDES)
PWD = $(shell pwd)
TARGET = some_module
obj-m := $(TARGET).o
all: default clean
default:
make $(INCLUDES) -C $(KDIR) M=$(PWD) modules
clean:
@rm -f *.o .*.cmd .*.flags *.mod.c *.order
@rm -f .*.*.cmd *.symvers *~ *.*~ TODO.*
@rm -fR .tmp*
@rm -rf .tmp_versions
disclean: clean
@rm -f *.ko
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)