繁体   English   中英

如何正确链接KBuild Makefiles以在内核模块中构建子文件夹

[英]How to chain KBuild Makefiles properly to build subfolders inside kernel module

我有一个内核模块(通常使用CONFIG_MYMODULE = m编译),其设置如下:

mymodule/Makefile
../foo/Makefile
../foo/component1/Makefile
../foo/component2/Makefile

目前正在使用的是:

MyModule的/ Makefile文件:

mymodule-y += mod1file.o mod2file.o mod3file.o #etc
include ../foo/Makefile
mymodule-y += $(FOO_FILES)
obj-$(CONFIG_MYMODULE) += mymodule.o

../foo/Makefile:

include component1/Makefile
include component2/Makefile

在我拥有的每个组件文件夹中:

../foo/component1/Makefile

FOO_FILES += foo1file.o foo2file.o foo3file.o #etc

这绝对不是正确的解决方法,因为所有内容都直接包含在mymodule / Makefile中,因此无法设置特定于文件夹的gcc标志。

在将所有内容构建到单个内核模块中的同时组织这个的正确方法是什么? 我已经阅读了kbuild / modules.txt文档,但我没有看到任何直接相关的内容,而且我无法弄清楚如何解决这个问题,或者它确实可行。

谢谢


我尝试了以下内容,但是我收到以下错误:

“ld:找不到foo:文件格式无法识别”

MyModule的/ Makefile文件:

mymodule-y += mod1file.o mod2file.o mod3file.o #etc
mymodule-y += ../foo/
obj-$(CONFIG_MYMODULE) += mymodule.o

../foo/Makefile

ccflags-y := -I$(src)/component1/ -I$(src)/component2/
foo-y := foo1file.o foo2file.o foo3file.o
foo-y += component1
foo-y += component2

../foo/component1/Makefile

component1-y := component1file.o component1file.o

../foo/component2/Makefile

component2-y := component2file.o component2file.o

如果我改为使用obj-y + = ../foo而不是mymodule-y + = ../foo它至少进入文件夹,但似乎没有尝试编译,我希望这是单个内核模块的所有部分。

这似乎并不太难。

MyModule的/ Makefile文件:

...
include ../foo/Makefile
...
# whatever rules use the folder-specific flags:
foo:
    gcc blah blah $(FOLDERFLAGS) blah

../foo/component1/Makefile:

FOLDER_FILES := foo1file.o foo2file.o foo3file.o #etc
$(FOLDER_FILES): FOLDER_FLAGS=folder_1_flag
FOO_FILES += FOLDER_FILES

../foo/component2/Makefile:

FOLDER_FILES := foo20file.o foo21file.o foo22file.o #etc
$(FOLDER_FILES): FOLDER_FLAGS=folder_2_flag
FOO_FILES += FOLDER_FILES

这足以满足您的目的吗?

您可以使用subdir-extra-y来获取父目录,但这只是一个开销,每个目录仍然无法使用ccflags。 也许正确的方法是将组件作为子模块,依赖于mymodule。

我会将模块构建在顶层目录mymodule/Makefile ,很容易从一个目录构建多个模块但我没有发现子目录中多个对象的一个​​模块(也许保持一个干净的设计策略,或者这样更简单)。

obj-m定义要构建的内核模块列表(在下面的示例中只有一个: hello.ko ,名为hello.o但会输出hello.ko

hello-objs hello.ko使用相同的名称定义要链接的编译对象列表以获取hello.kohello

作为Makefile很容易有条件地链接对象(参见CONFIG_HELLO_COMPONENT1

最终,如果每个组件有很多对象,并且我们希望保持顶级Makefile清洁,我们仍然可以使用include但只是有条件地将对象添加到hello-objs ccflags-y并将标志添加到ccflags-y (或者任何需要的变量,只是不是obj-* ) 。

CFLAGS_$*.o (见下文)可用于设置每个对象的cflags,但它不支持路径,因此不同目录中具有相同名称的对象将具有相同的标志。

mymodule/Makefile

ifeq ($(CONFIG_HELLO_COMPONENT1), y)
 ccflags-y += -I$(src)/foo/component1 -DCONFIG_HELLO_COMPONENT1
endif
ccflags-y += -I$(src)/foo/component2

obj-m += hello.o

CFLAGS_component2.o += -DTEST_CFLAGS

hello-objs = hello-1.o
ifeq ($(CONFIG_HELLO_COMPONENT1), y)
 hello-objs += foo/component1/component1.o
endif
hello-objs += foo/component2/component2.o

all:
    make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules

clean:
    make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean

为了在所有文件下面的完整性,应该使用makemake CONFIG_HELLO_COMPONENT1=y来构建和工作。

mymodule/hello-1.c

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#ifdef CONFIG_HELLO_COMPONENT1
#include <component1.h>
#endif
#include <component2.h>
static int __init init_hello(void) {
#ifdef CONFIG_HELLO_COMPONENT1
    component1();
#endif
    component2();
    printk(KERN_INFO "Hello world 1.\n");
    return 0;
}
static void __exit cleanup_hello(void) {
    printk(KERN_INFO "Goodbye world 1.\n");
}
module_init(init_hello);
module_exit(cleanup_hello);

mymodule/foo/component2/component2.h

#ifndef COMPONENT2_H
#define COMPONENT2_H
void component2(void);
#endif

mymodule/foo/component2/component2.c

#include <linux/kernel.h>
void component2(void) {
    printk(KERN_INFO "component2\n");
}

mymodule/foo/component1/component1.h

#ifndef COMPONENT1_H
#define COMPONENT1_H
void component1(void);
#endif

mymodule/foo/component1/component1.c

#include <linux/kernel.h>
void component1(void) {
    printk(KERN_INFO "component1\n");
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM