Module 将内核模块构建到特定目录中

Module 将内核模块构建到特定目录中,module,makefile,kernel,Module,Makefile,Kernel,有没有办法设置一个输出目录,以便在我的makefile中生成内核模块 我想保持我的源目录与生成文件的一致性。如果在内核树中生成,可以使用O变量: make O=/path/to/mydir 如果您在内核树(模块或任何其他类型的程序)之外进行编译,则需要将Makefile更改为在不同的目录中输出。下面是一个Makefile规则的小示例,它在MY_DIR目录中输出: $(MY_DIR)/test: test.c gcc -o $@ $< KBUILD\u输出和O=对我不起作用,在外

有没有办法设置一个输出目录,以便在我的makefile中生成内核模块


我想保持我的源目录与生成文件的一致性。

如果在内核树中生成,可以使用
O
变量:

make O=/path/to/mydir
如果您在内核树(模块或任何其他类型的程序)之外进行编译,则需要将
Makefile
更改为在不同的目录中输出。下面是一个Makefile规则的小示例,它在
MY_DIR
目录中输出:

$(MY_DIR)/test: test.c
    gcc -o $@ $<

KBUILD\u输出
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)
INCLUDE=INCLUDE
SOURCE=src
TARGET=mymodule
输出=箱
导出=包
SOURCES=$(通配符$(SOURCE)/*.c)
#取决于bin/include bin/*.c和bin/Makefile
全部:$(输出)/$(包括)$(子对象$(源),$(输出),$(源))$(输出)/Makefile
make-C/lib/modules/$(shell uname-r)/buildm=$(PWD)/$(输出)模块
#创建从src到bin的符号链接
$(输出)/%:$(源)/%
ln-s../$<$@
#使用所需的obj-m和mymodule objs集生成生成文件
$(输出)/生成文件:
echo“obj-m+=$(目标).o\n$(目标)-objs:=$(子脚本$(目标).o,,$(子脚本c,.o,$(子脚本$(源代码)/,$(源代码))”>$@
清洁:
rm-rf$(输出)
mkdir$(输出)

不幸的是,在构建外部(树外)内核模块时,它似乎没有帮助。在我的系统(OpenSUSE 12.1 x86)上,我有一个目录(
~/sample
),其中包含一个简单内核模块的源代码以及它的Kbuild和Makefile。我将其设置为只读,并创建了一个构建目录,
~/sample\u build
。从后者开始,我执行了
make-C~/sample O=$(pwd)
。生成失败,因为生成系统仍试图创建
~/sample/.tmp\u版本
目录以及
~/sample
中的
.tmp*.o
文件。也许,还需要一些别的东西来让它工作?另一方面,
make。。。O=
对于树内内核模块似乎很好。感谢您的回答,但是您的解决方案不适用于内核模块。因为在内核模块makefile中,必须使用/lib/modules//build中的makefile调用make。所以你没有任何gcc呼叫。到目前为止,我目前的解决方案是在编译后移动bin dir中的所有构建文件。当做Tom@Tom,在我们的项目中,我们求助于将内核模块的源代码复制到构建树中,然后以通常的方式在那里构建它们。这是可行的,但也许还有更好的方法,我还不知道。@Eugene我还面临着从源代码构建模块的问题,
O
标志不起作用。在内核v5.x和更高版本上有更好的解决方案吗?这可能是对linux内核开发的一个非常悲哀的证明。在构成linux内核的数千个渴望中,难道没有一个渴望一个干净的源目录吗?
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)