How specify optimization level of compilation for kernel module [duplicate] - c

Eg: a common device module's Makefile
obj-m:=jc.o
default:
$(MAKE) -C /lib/modules/$(shell uname -r)/build M=$(shell pwd) modules
clean:
$(MAKE) -C /lib/modules/$(shell uname -r)/build M=$(shell pwd) modules clean
I consider if I can set CFLAGS to the file. When I change default section to
$(MAKE) -O2 -C /lib/modules/$(shell uname -r)/build M=$(shell pwd) modules
But it didn't work.
Any help? Thanks a lot.

-O2 would be an option to make (or $(MAKE), as you're using it) in what you tried. Obviously, the compiler (probably gcc) needs this flag, not make.
Kbuild understands a make variable named CFLAGS_modulename.o to add specific C flags when compiling this unit. In your case, your module object will be jc.o, so you can specify:
CFLAGS_jc.o := -O2
and it should work. Add V=1 to your $(MAKE) lines to get a verbose output and you should see -O2 when jc.c is being compiled.
You can find more about compiling modules in the official documentation.

You can also use
ccflags-y := -O2
This will be applied to all of the source files compiled for your module with the Makefile. This is indirectly documented in the link provided by eepp in Section 4.2

Related

kernel module doesn't search for include library when -I is used

I want to build a basic main.c, that is actually a kernel module written in C. I have include header files that are in include/. I want to use GCC -I to make GCC search for the include headers in -Iinclude. However, GCC doesn't seem to understand that, and I have no clue how to debug it.
Tree:
main.c
include
file.h
main.c
#include "file.h"
...
Makefile:
EXTRA_CFLAGS += -Iinclude -Werror -Wall \
-Wno-missing-braces -Wno-error=unused-function
all:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
clean:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
The error:
main.c: fatal error: file.h: No such file or directory
That's because make is not actually running in your directory, when it compiles things.
The -C option in this command:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
tells make to change it's current working directory to that path. Thus, include is no longer the include directory in your current directory.
You should write it like this:
EXTRA_CFLAGS += -I'$M/include' -Werror -Wall \
-Wno-missing-braces -Wno-error=unused-function
all:
$(MAKE) -C "/lib/modules/$$(uname -r)/build" M='$(CURDIR)' modules
clean:
$(MAKE) -C "/lib/modules/$$(uname -r)/build" M='$(CURDIR)' clean
You should always use $(MAKE), and never make, when running a sub-make. And using make's shell function is not really needed since a recipe is already running in a shell. And, PWD is just inherited from the calling shell and might be inaccurate.

Linux Kernel generate compile-commands.json for module

The problem: Most of macro definition and even header files are not looked up by an IDE because include path is not specified in the IDE configuration. It inhibits autocompletion and navigation.
Here is my Makefile:
#-Wno-declaration-after-statement
ccflags-y := -std=gnu11 -Wno-declaration-after-statement -Werror
obj-m += pfsw.o
pfsw-objs := src/init.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
I ran make V=1 and noticed that the compile command along with include path is actually pretty cumbersome (counting Linux Specific -include for parameters):
gcc -Wp,-MD,/home/memyself/lkm/procfs_write/src/.init.o.d -nostdinc
-isystem /usr/lib/gcc/x86_64-linux-gnu/7/include
-I./arch/x86/include -I./arch/x86/include/generated -I./include -I./arch/x86/include/uapi
-I./arch/x86/include/generated/uapi -I./include/uapi -I./include/generated/uapi
-include ./include/linux/kconfig.h -Iubuntu/include -include ./include/linux/compiler_types.h
-D__KERNEL__
//tons of options ommitted...
-c -o /home/memyself/lkm/procfs_write/src/init.o
/home/memyself/lkm/procfs_write/src/init.c
Question: Is there a way to generate compile-command.json to inform IDE about include paths? Or the only solution is to manually pass the include path to the IDE one by one?
Due to CLang has a lot of different tools, including some to analyze the code, the compile-command.json is required. That's why Tom Roeder from Google provided a
scripts/clang-tools/gen_compile_commands.py in the commit b30204640192 ("scripts: add a tool to produce a compile_commands.json file") for this.
Note, kernel must be compiled at list once to make this script work.
P.S. I suppose you are trying MS Visual Studio Code?
Kudos to colleague of mine, Alex, who is user of it and told me about existence of such script.

Why does my Makefile build an non-existent source file?

I have the following makefile which is supposed to build procdriver.c and thus output a .ko file. The issue is that even when I delete procdriver.c my makefile seems to be able to build a procdriver.ko file. I would like to try to find out from where it gets the source file it is building every time.
TARGET = procdriver
obj-m := procdriver.o
procdriver-objs+= gpioLib.o
KDIR:= /home/pi/myRpi/linux
PWD := $(shell pwd)
all: gpioLib.o procdriver.c
echo<<"in all"
$(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules
rm -r -f .tmp_versions *.mod.c .*.cmd *.o *.symvers
gpioLib.o: gpioLib.c gpioLib.h
gcc -c gpioLib.c -o gpioLib.o
clean:
make -C $(KDIR) SUBDIRS=$(PWD) clean
This is the output from the Makefile: http://paste.ubuntu.com/23575533/
EDIT
the entire output of the remake command: http://paste.ubuntu.com/23577274
I think this is the most important bit of output: http://pastebin.com/0vj9aNMg
obj-m := procdriver.o
procdriver-objs+= gpioLib.o
is wrong. It says that the sole object file for the module will be procdriver.o
and that the build system is to generate that one from procdriver-objs
procdriver-objs is initally empty and so becomes = gpioLib.o. So gpioLib.o
is the only object prerequisite of procdriver.o; hence gpioLib.c and gpioLib.h
are the only source prerequisites of procdriver.o. procdriver.c is redundant.
You want (I believe) to make a module from a pair of object files procdriver.o and gpioLib.o,
compiled respectively from the corresponding .c files. The way you need to express that is:
obj-m += my-module-name.o
my-module-name-objs := procdriver.o gpioLib.o
You will have to rethink your filenames to avoid a collision between my-module-name.o
and procdriver.o. Consult the documentation The Linux Kernel Module Programming Guide: 2.7. Modules Spanning Multiple Files.
Much of the content of your makefile is redundant. As far as I can see all it
needs is:
obj-m += my-module-name.o
my-module-name-objs := procdriver.o gpioLib.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
gpioLib.o: gpioLib.h

Propagate V=s Flage to all sub makefiles

When ever I build kernel modules using make, I get this kind of logs
CC[M] module1
CC[M] module2
CC[M] module3
CC[M] module4
i.e just compilation or linking info about any module currently being processed.
I need to know complete information that which commands actually compiles the modules source code, what are the flags used in those command etc. e.g
gcc -Wall abcd.c
I even checked it by setting V=s , V=1, -n and -d but couldn't get what I want.
Kindly tell me how to make V=s propagate through each and every subsequent makefiles. It could be done by exporting, by how?
Thanks
There are two kinds of methods:
You can build modules with "make V=1" to print verbose messages.
You can also do this by putting "export KBUILD_VERBOSE=1" line into your Makefile.
Here is an example of makefile:
TARGET :=sysfs-sample
export KBUILD_VERBOSE=1
obj-m += $(TARGET).o
$(TARGET)-objs := main.o
MODULE_DIR := "$(PWD)"
all:
CROSS_COMPILE= ARCH=x86 make -C /lib/modules/$(shell uname -r)/build M=$(MODULE_DIR) modules
clean:
make -C /lib/modules/$(shell uname -r)/build M=$(MODULE_DIR) clean

Empty Module.symvers file when compiling a module

I'm writing a custom kernel module (let's call it mod1) that I would like to export functions for use in other modules (let's call those mod2, etc...). When compiling the other modules, I get warning messages about undefined symbols (functions in mod1). Though everything should work fine after loading, I like to compile without warnings. I read that I should add the path to mod1's Module.symvers to KBUILD_EXTRA_SYMBOLS However, I noticed that my Module.symvers file is empty. What am I doing wrong?
Here's a MWE of a module:
#include <linux/module.h>
MODULE_INFO(version, "0.1");
MODULE_AUTHOR("Me");
MODULE_LICENSE("GPL");
int foo(int x) {
return x;
}
EXPORT_SYMBOL_GPL(foo)
And a Makefile:
all:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
clean:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
And me running make showing that Module.symvers is empty:
user#host:~/mwe$ make; [[ -s ./Module.symvers ]] || echo "File size is zero!"
make -C /lib/modules/3.13.0-30-generic/build M=/home/user/mwe modules
make[1]: Entering directory `/usr/src/linux-headers-3.13.0-30-generic'
Building modules, stage 2.
MODPOST 0 modules
make[1]: Leaving directory `/usr/src/linux-headers-3.13.0-30-generic'
File size is zero!
I'm not sure what I'm doing wrong and my search for answers has been fruitless thusfar.
Looks like the Makefile is incorrect. Where is the name of the file you want to compile ? Change test.o to whatever your filename.
Makefile:
obj-m += test.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

Resources