将内核模块构建到特定目录中
Posted
技术标签:
【中文标题】将内核模块构建到特定目录中【英文标题】:Build kernel module into a specific directory 【发布时间】:2012-08-28 00:30:01 【问题描述】:有没有办法在我的 makefile 中设置一个输出目录来制作内核模块?
我想从构建文件中保持我的源目录干净。
【问题讨论】:
Building an out-of-tree Linux kernel module in a separate object directory的可能重复 【参考方案1】:KBUILD_OUTPUT
和 O=
对我不起作用,并且在外部构建时无法找到内核头文件。
我的解决方案是将源文件符号链接到 bin 目录中,并在 bin 目录中动态生成一个新的 MakeFile。这样可以轻松清理所有构建文件,因为动态 Makefile 始终可以重新创建。
INCLUDE=include
SOURCE=src
TARGET=mymodule
OUTPUT=bin
EXPORT=package
SOURCES=$(wildcard $(SOURCE)/*.c)
# Depends on bin/include bin/*.c and bin/Makefile
all: $(OUTPUT)/$(INCLUDE) $(subst $(SOURCE),$(OUTPUT),$(SOURCES)) $(OUTPUT)/Makefile
make -C /lib/modules/$(shell uname -r)/build M=$(PWD)/$(OUTPUT) modules
# Create a symlink from src to bin
$(OUTPUT)/%: $(SOURCE)/%
ln -s ../$< $@
# Generate a Makefile with the needed obj-m and mymodule-objs set
$(OUTPUT)/Makefile:
echo "obj-m += $(TARGET).o\n$(TARGET)-objs := $(subst $(TARGET).o,, $(subst .c,.o,$(subst $(SOURCE)/,,$(SOURCES))))" > $@
clean:
rm -rf $(OUTPUT)
mkdir $(OUTPUT)
【讨论】:
这是 linux 内核开发的一个非常可悲的证明。在构成 linux 内核的成千上万个问题中,难道没有一个对一个干净的源目录很感兴趣吗?【参考方案2】:如果您在内核树中构建,您可以使用O
变量:
make O=/path/to/mydir
如果您在内核树(模块或任何其他类型的程序)之外进行编译,则需要将 Makefile
更改为在不同的目录中输出。这里是一个在MY_DIR
目录中输出的 Makefile 规则的小例子:
$(MY_DIR)/test: test.c
gcc -o $@ $<
然后写:
$ make MY_DIR=/path/to/build/directory
【讨论】:
不幸的是,它在构建外部(树外)内核模块时似乎没有帮助。在我的系统(OpenSUSE 12.1 x86)上,我有一个目录(~/sample
),其中包含一个简单内核模块的源代码以及它的 Kbuild 和 Makefile。我将其设为只读并创建了一个构建目录~/sample_build
。从后者,我执行了make -C ~/sample O=$(pwd)
。构建失败是因为构建系统仍然试图创建~/sample/.tmp_versions
目录以及~/sample
中的.tmp*.o
文件。或许,还需要其他的东西才能让它发挥作用?
另一方面,make ... O=<build_dir>
似乎适用于 in-tree 内核模块。
感谢您的回答,但您的解决方案不适用于内核模块。因为在您的 kernel-module-makefile 中,您必须使用 /lib/modules/O
标志不能完成这项工作。内核 v5.x 及更高版本是否有更好的解决方案?【参考方案3】:
这里也一样,但我使用了一种对我有用的解决方法:
-
为每个架构名称(例如“debug_64”)创建一个子目录。
在“debug_64”下:创建所有 .c 和 .h 文件的符号链接。保持相同的结构。
将 makefile 复制到“debug_64”并为 64 Debug 构建设置正确的标志,例如
ccflags-y := -DCRONO_DEBUG_ENABLED
ccflags-y += -I$(src)/../../../lib/include
KBUILD_AFLAGS += -march=x86_64
-
记得将相对目录路径设置为下一层,例如
../inc
将是 ../../inc
。
对每个拱门/轮廓重复相同的操作。
现在我们有了一个源代码、不同的文件夹和不同的 make 文件。
顺便说一句,在内核模块构建的 make 文件中创建配置文件并不是一件容易的工作,因此,我更喜欢为每个架构创建一个 makefile 的副本。
【讨论】:
以上是关于将内核模块构建到特定目录中的主要内容,如果未能解决你的问题,请参考以下文章