![](/img/trans.png)
[英]Building an out-of-tree linux kernel module with separate output directory
[英]Building an out-of-tree Linux kernel module in a separate object directory
我正在面對 Linux 內核構建系統(Kbuild,內核 ≥2.6.28)以及更大項目的目錄結構和構建系統。 我們的項目包含一個 out-of-tree Linux 內核模塊,我們的目錄結構如下所示(顯然是簡化的):
checkout/src/common/*.c source files (common to Linux and other platforms)
checkout/src/linux-driver/*.c source files (for the Linux kernel driver)
checkout/build/linux/Kbuild Kbuild
tmp/linux-2.6.xx/ where the Linux kernel is unpacked and configured
output/linux-arm-debug/ where object files must end up
構建過程不得修改checkout
下的任何內容,構建模塊不得修改tmp/linux-2.6.xx
下的任何tmp/linux-2.6.xx
。 所有輸出文件都必須在output/linux-arm-debug
(或在構建時選擇的任何架構和調試變體)。
我已經閱讀了kbuild/modules.txt
,並開始編寫我的Kbuild
文件:
MOD_OUTPUT_DIR = ../../../output/linux-$(ARCH)-$(DEBUG)
obj-m += $(MOD_OUTPUT_DIR)/foo_mod.o
$(MOD_OUTPUT_DIR)/our_module-objs := $(MOD_OUTPUT_DIR)/foo_common.o $(MOD_OUTPUT_DIR)/foo_linux.o
這處理將目標文件存儲在與Kbuild
所在目錄不同的目錄中。 現在我如何指定foo_common.o
需要從…/checkout/src/common/foo_common.c
和foo_linux.o
從…/checkout/src/linux-driver/foo_linux.c
?
這是一個 Makefile,它為內核樹模塊之外的源樹構建(改編自 @Mark 的評論)...
KDIR ?= /lib/modules/$(shell uname -r)/build
BUILD_DIR ?= $(PWD)/build
BUILD_DIR_MAKEFILE ?= $(PWD)/build/Makefile
default: $(BUILD_DIR_MAKEFILE)
make -C $(KDIR) M=$(BUILD_DIR) src=$(PWD) modules
$(BUILD_DIR):
mkdir -p "$@"
$(BUILD_DIR_MAKEFILE): $(BUILD_DIR)
touch "$@"
clean:
make -C $(KDIR) M=$(BUILD_DIR) src=$(PWD) clean
注意:您仍然需要一個 Kbuild 文件...
obj-m += my_driver.o
我有一個類似的問題。 我修改了linux_2_6_34/scripts/Makefile.build
如下。
ifdef SRCDIR
src := $(SRCDIR)
else
src := $(obj)
endif
SRCDIR
是目錄源。
要編譯模塊,請運行
make -c $(KDIR) M=$(Your_output_dir) SRCDIR=$(your source directory)`
我不雅但有效的解決方案是將源文件復制到輸出樹中。
FOO_SOURCES_DIR = $(src)/../../../checkout/src
FOO_MOD_OUTPUT_DIR = ../../../output/linux-$(ARCH)-$(DEBUG)
# Specify the object files
obj-m += $(FOO_MOD_OUTPUT_DIR)/foo_mod.o
FOO_MODULE_OBJS := $(FOO_MOD_OUTPUT_DIR)/foo_common.o $(FOO_MOD_OUTPUT_DIR)/foo_linux.o
$(FOO_MOD_OUTPUT_DIR)/foo_mod-objs := $(FOO_MODULE_OBJS)
# Where to find the sources
$(src)/$(FOO_MOD_OUTPUT_DIR)/foo_common.c: $(FOO_SOURCES_DIR)/common/foo_common.c
$(src)/$(FOO_MOD_OUTPUT_DIR)/foo_linux.c: $(FOO_SOURCES_DIR)/linux-driver/foo_linux.c
# Rules to copy the sources
FOO_COPIED_SOURCES = $(patsubst %.o,$(src)/%.c,$(FOO_MODULE_OBJS))
$(FOO_COPIED_SOURCES):
$(Q)mkdir -p $(@D)
cp -f $< $@
clean-files += $(FOO_COPIED_SOURCES)
clean-dirs += $(FOO_MOD_OUTPUT_DIR)
雖然到目前為止您還沒有提到您嘗試過的內容(或者您是否已經找到了解決方案),但看起來您只需要進一步深入modules.txt文件 - 到第 4.3 節:
--- 4.3 Several Subdirectories
kbuild can handle files that are spread over several directories.
Consider the following example:
.
|__ src
| |__ complex_main.c
| |__ hal
| |__ hardwareif.c
| |__ include
| |__ hardwareif.h
|__ include
|__ complex.h
To build the module complex.ko, we then need the following
kbuild file:
--> 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
As you can see, kbuild knows how to handle object files located
in other directories. The trick is to specify the directory
relative to the kbuild file's location. That being said, this
is NOT recommended practice.
For the header files, kbuild must be explicitly told where to
look. When kbuild executes, the current directory is always the
root of the kernel tree (the argument to "-C") and therefore an
absolute path is needed. $(src) provides the absolute path by
pointing to the directory where the currently executing kbuild
file is located.
有點晚了,但看起來O= 標志是您所需要的。
您可以設置環境變量KBUILD_OUTPUT
。 此功能類似於O=
選項; 但是,由於它是一個環境變量,因此它可以跨越多個 makefile,其中O=
無法傳遞或需要構建目錄外模塊。 我在嘗試構建一組兼容無線模塊時遇到了同樣的問題,我需要使用O=
來構建實際的內核映像。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.