I have a kernel module (often compiled using CONFIG_MYMODULE=m) which is set-up like the following:
mymodule/Makefile
../foo/Makefile
../foo/component1/Makefile
../foo/component2/Makefile
Currently what's being used is:
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
and inside each component folder I have:
../foo/component1/Makefile
FOO_FILES += foo1file.o foo2file.o foo3file.o #etc
This definitely doesn't appear to be the proper way of going about this, as everything is included directly into the mymodule/Makefile and thus can't set folder-specific gcc flags.
What is the proper way of organizing this while still building everything into a single kernel module ? I've read the kbuild/modules.txt documentation, but I haven't seen anything which relates directly, and I can't quite figure out how to go about this or if it's indeed possible.
Thanks
I've tried the following, but I get the following error:
"ld: cannot find foo: File format not recognized"
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
If I change this to instead use obj-y += ../foo rather than mymodule-y += ../foo it at least enters the folder, but doesn't seem to attempt to complile, and I want this to be all a part of a single kernel module.
This doesn't seem too difficult.
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
Is that sufficient for your purposes?
You can get parent directories working using subdir-
and extra-y
but is just an overhead and still ccflags per directory wouldn't work. Perhaps the proper way would be to have components as sub-modules, with dependency to mymodule.
I would keep the module build in the top directory mymodule/Makefile
, is easy to build multiple modules from one directory but I found nothing about one module from multiple objects in subdirectories (maybe a keep a clean design policy, or just was easier this way).
obj-m
define the list of kernel modules to build (only one in the example below: hello.ko
, is named hello.o
but will output hello.ko
)
hello-objs
define the list of compiled objects to link to get hello.ko
, by using the same name : hello
.
Being a Makefile is easy to link objects conditionally (see CONFIG_HELLO_COMPONENT1
)
Eventually if there are many objects per component and we want to keep the top Makefile clean we can still use include
but just to conditionally add objects to hello-objs
and flags to ccflags-y
(or whatever variable needed, just not obj-*
).
CFLAGS_$*.o
(see below) can be used to set per object cflags, but it doesn't honour the path, so objects with the same name in different directories will have the same flags.
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
For completeness below all the files, should build and work, with make
or 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");
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.