8
votes

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?

2
You can name your makefile anything you want. make will only look for certain filenames by default though. For any other names you need to use the -f argument.Etan Reisner
If you give make a specific rule for your object file with a prerequisite of the relevant source file and rules to build the target make will use that instead of the default rule you mentioned. So module1_code.o: code.c ; <command to build>.Etan Reisner

2 Answers

5
votes

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.

3
votes

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.