Linux内核模块Makefile不能包含相对路径

时间:2020-06-04 13:48:59

标签: c linux makefile linux-kernel gnu-make

我正在尝试构建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。当我使用绝对路径时,它可以很好地工作,但是我需要从该项目中的当前目录进行相对寻址。怎么了?
抱歉,很明显。

1 个答案:

答案 0 :(得分:2)

Linux内核使用Kbuild来制作模块。该框架不同于常规的makefile约定,因此尽管它们都由GNU make解释,但需要注意它们之间的差异。 Documentation for Makefiles using Kbuild can be found heredocumentation for building external kernel modules can be found here

以下引用了文档中与您的问题相关的一些重要要点。

来自makefiles.txt

--- 3.10特殊规则

当kbuild基础结构未提供所需支持时,将使用特殊规则。一个典型的例子是头文件 在构建过程中生成。另一个例子是 需要特定规则准备的特定于体系结构的Makefile 引导映像等。特殊规则写为正常的Make规则。 Kbuild未在Makefile所在的目录中执行,因此所有 特殊规则应提供前提文件的相对路径 和目标文件。定义特殊规则时使用两个变量:

〜{$(src)

$(src)是指向Makefile所在目录的相对路径。引用位于$(src)树中的文件时,请始终使用src

〜{$(obj)

$(obj)是一个相对路径,指向目标保存目录。引用生成的文件时,请始终使用$(obj)

来自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