Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Out of tree kernel modules: Multiple module, single Makefile, same source file, different build options

I am building a set of Linux kernel modules using shared source code. From what I understand, the Makefile has to be named "Makefile" so I have to use the same Makefile to build two different modules. How can I build two different modules, within the same Makefile, with the same source code, but with two different build options?

For example, my modules are called module1 and module2. So I have the following line to define them:

obj-m := module1.o module2.o

Among other files, both module1 and module2 need to use the same source file code.c, but built with different build options. So say for example, the Makefile contains the following lines:

module1-objs = module1_code.o other_code.o
module2-objs = module2_code.o other_code.o

I want module1_code.o and module2_code.o to be built from code.c, but with different options. Specifically, I want one module1_code.o with a macro defined -DPREPROCEFFOR_FLAG=1, and module2_code.o built without the macro.

From what I understand, the system of Makefiles used in Linux implicitly infers that for an object file called "code.o", the source file is called "code.c", so how would I achieve this? Is is possible? Is there a better way to do this?

like image 904
Safayet Ahmed Avatar asked Aug 22 '13 16:08

Safayet Ahmed


People also ask

What are out of tree modules?

An out-of-tree module is a GNU Radio component that does not live within the GNU Radio source tree.

What is Insmod and Modprobe?

modprobe is the intelligent version of insmod . insmod simply adds a module where modprobe looks for any dependency (if that particular module is dependent on any other module) and loads them.

What does Objs mean in makefile?

It is standard practice for every makefile to have a variable named objects , OBJECTS , objs , OBJS , obj , or OBJ which is a list of all object file names. We would define such a variable objects with a line like this in the makefile: objects = main.o kbd.o command.o display.o \ insert.o search.o files.o utils.o.

What is Modinfo?

modinfo command in Linux system is used to display the information about a Linux Kernel module. This command extracts the information from the Linux kernel modules given on the command line. If the module name is not a file name, then the /lib/modules/kernel-version directory is searched by default.


2 Answers

You have a problem here, because you obviously have code.c being compiled differently when -DPREPROCEFFOR_FLAG=1 is defined, but once it's compiled into code.o, make won't care about preprocessor flags or whatever because code.o will be already up to date.

You need a way to build code.c to different object files with different C flags. There's probably a clean way to do this (had no chance with O= for out of tree modules), but here's my innelegant yet effective solution for the moment:

my_modules:
    cp code.c code_noflags.c
    cp code.c code_withflags.c
    make -C $$KDIR M=$$PWD modules
    rm code_noflags.c code_withflags.c

# module objects
obj-m := module1.o module2.o

# module1 specifics
module1-y := code_withflags.o
CFLAGS_code_withflags.o := -DPREPROCEFFOR_FLAG=1

# module2 specifics
module2-y := code_noflags.o

Just call:

$ make KDIR=/path/to/kernel

You can verify the preprocessor flag is passed to the source file for the right object with:

$ make KDIR=/path/to/kernel V=1 | grep PREPRO

You could also have two separate directories for each module, if this is possible, and have a symbolic link code.c in each one pointing to the common real code.c. However, this is still hackish and doesn't feel right.

like image 53
eepp Avatar answered Oct 06 '22 00:10

eepp


One simple solution is, continuing from your Makefile

obj-m := module1.o module2.o

module1-objs = module1_code.o other_code.o
module2-objs = module2_code.o other_code.o

to add two more source files, module1_code.c and module2_code.c.

Then module1_code.c just looks like:

#define PREPROCEFFOR_FLAG 1
#include "code.c"

and module2_code.c is:

#include "code.c"

Or if you like, change the names in the Makefile and source files so that the second include without a define isn't necessary. Also you could make the two source files nothing but an include and use the CFLAGS_module1_code.o variable to add the -D... option to the compiler if you prefer.

This is similar to what happens in the upstream kernel with arch/x86/boot/video-vesa.c and arch/x86/realmode/rm/video-vesa.c etc., where the realmode file just contains:

#include "../../boot/video-vesa.c"

and the video-vesa.c code ends up getting compiled twice with different compiler flags.

This seems preferable to copying the source files, since you end up with a mess there if you want to use the O=... option to the kernel build to keep a clean source tree and build in a separate object tree.

like image 41
Roland Avatar answered Oct 05 '22 23:10

Roland