Propagate V=s Flage to all sub makefiles - c

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

Related

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.

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

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

GCC Kernel Module Compilation Errors

I'm working on a netfilter and compiling it on a virtual machine.
matt#ubuntu:~$ make
gcc -c -O2 -W -isystem /lib/modules/4.4.0-87-generic/build/include -D__KERNEL__ -DMODULE test10.c -I.
In file included from /usr/src/linux-headers-4.4.0-87/include/linux/kernel.h:6:0,
from structs1.h:2,
from test10.c:1:
/usr/src/linux-headers-4.4.0-87/include/linux/linkage.h:7:25: fatal error: asm/linkage.h: No such file or directory
compilation terminated.
makefile:2: recipe for target 'test' failed
make: *** [test] Error 1
Above is my GCC command used to attempt to build my kernel module and the subsequent error that it throws.
In researching this, I have found one possible solution that involves specifiying the kernel version as such:
KERNEL_VER=/usr/src/linux-headers-4.4.0-87/arch/x86/
But two problems:
I'm not sure how to actually use this in my make file which can be seen below, outside of just making a symbolic link, and
I looked in this folder (/usr/src/linux-headers-4.4.0-87/arch/x86/) and sub folders and it doesn't have any of the same kernel.h files -- which is what I need.
Makefile:
test:
gcc -c -O2 -W -isystem /lib/modules/4.4.0-87-generic/build/include -D__KERNEL__ -DMODULE test10.c -I.
Any help on this would be greatly appreciated.
The standard Makefile used to build a loadable kernel module is as follows.
obj-m += test10.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
Refer Compiling a loadable kernel module this for more information.

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

'make' equivalent of -D flag as in gcc

My C code has various files having statements that I want to execute only if a macro is defined. I have two files each having the following code:
#ifdef SOME_MACRO
printf("macro defined\n");
#else
printf("macro undefined");
#endif
My Makefile contains:
make -C /lib/modules/$(shell uname -r )/build M=$(PWD) modules $(CFLAGS)
and I am calling make as:
make all CFLAGS=SOME_MACRO=10
When I execute the resulting program, I get 'macro undefined' indicating the macro is not being defined.
I have also tried calling it as:
make all CFLAGS=SOME_MACRO
which gives me:
make[1]: *** No rule to make target `SOME_MACRO'. Stop.
make[1]: Leaving directory `/X/Y/Z'
make: *** [default] Error 2
And also calling it as:
make all CFLAGS=-DSOME_MACRO=10
as given here and here but this is not working either.
How do I make this work?
The third form is correct (make all CFLAGS=-DSOME_MACRO=10 or just make all CFLAGS=-DSOME_MACRO). But the make file that you are calling has to actually use that CFLAGS macro.
Make's implicit rules for compiling an executable or object c file will use CFLAGS, but we can't tell whether it is being invoked or overridden without seeing either the content of that makefile or the output from make.
The output from make should show the build commands. The implicit rule for making a .o from a .c file is $(CC) $(CPPFLAGS) $(CFLAGS) -c so you should see something like cc -DSOME_MACRO=2 -DFOO=99 -c -o x.o x.c given you compiling an object file, and similar if you compiling a executable.
Also make sure your cleaning you project properly make clean. And make sure the clean is actually recursive (i.e. cleans you "modules" project too)...
Edit: Oh yeah ... as #nneonneo's answer points out you also have an error in recursive the make call which is definitely an issue (I figured you were running the 2nd make command directly to debug the problem..). The above may still apply.
Your Makefile contains
make -C /lib/modules/$(shell uname -r )/build M=$(PWD) modules $(CFLAGS)
which will pass the value of the variable CFLAGS as make arguments. This is not what you want. Use CFLAGS=$(CFLAGS) instead:
make -C /lib/modules/$(shell uname -r )/build M=$(PWD) modules CFLAGS=$(CFLAGS)
to pass the CFLAGS along to the sub-make, then simply use make CFLAGS=-DSOME_MACRO=10 to build.

Resources