簡體   English   中英

Linux kernel 模塊 Makefile 不能包含相對路徑

[英]Linux kernel module Makefile can't include relative paths

我正在嘗試構建 Linux kernel 模塊:

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 kernel使用Kbuild制作模塊。 該框架不同於普通的 makefile 約定,因此雖然它們都由 GNU make 解釋,但需要注意差異。 可以在此處找到使用 Kbuild 的 Makefile 的文檔,並且可以在此處找到用於構建外部 kernel 模塊的文檔

下面引用了文檔中與您的問題相關的一些要點。

makefiles.txt

--- 3.10 特殊規則

當 kbuild 基礎架構不提供所需的支持時,使用特殊規則。 一個典型的例子是在構建過程中生成的 header 文件。 另一個例子是特定於體系結構的 Makefiles,它需要特殊的規則來准備啟動映像等。特殊規則被編寫為普通的 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 知道如何處理位於其他目錄中的 object 文件。 訣竅是指定相對於 kbuild 文件位置的目錄。 話雖如此,這不是推薦的做法。

對於 header 文件,必須明確告知 kbuild 在哪里查找。 當 kbuild 執行時,當前目錄始終是 kernel 樹的根目錄(“-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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM