4

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

mymodule/Makefile
../foo/Makefile
../foo/component1/Makefile
../foo/component2/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-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 它至少进入文件夹,但似乎没有尝试编译,我希望这是所有单个内核模块的一部分。

4

2 回答 2

1

这似乎并不太难。

我的模块/生成文件:

...
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

这足以满足您的目的吗?

于 2016-10-17T15:32:04.820 回答
0

subdir-您可以使用and让父目录正常工作,extra-y但这只是开销,并且每个目录的 ccflags 仍然不起作用。也许正确的方法是将组件作为子模块,依赖于 mymodule。

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

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

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

作为 Makefile 很容易有条件地链接对象(请参阅 参考资料CONFIG_HELLO_COMPONENT1

最终,如果每个组件有很多对象,并且我们希望保持顶部 Makefile 干净,我们仍然可以使用include,但只是有条件地将对象添加到hello-objs并标记到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

为了下面所有文件的完整性,应该使用makeor构建和工作make 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");
}
于 2016-10-22T00:20:27.347 回答