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.
Related
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.
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.
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
I am learning Linux kernel module programming. I am using Beaglebone black for that. I have made simple 'Hello World' application and makefile. I have checked my makefile it's proper. But when I command 'make', it gives me following error:
root#beaglebone:/home/sonu# make
make: Warning: File `Makefile' has modification time 2.2e+02 s in the future
make -C /lib/modules/3.8.13-bone70/build M=/home/sonu modules
make: *** /lib/modules/3.8.13-bone70/build: No such file or directory. Stop.
make: *** [all] Error 2
Though I referred some websites. But, all they are asking me to install packages. As I am a newbie. I don't even know how to configure and start internet connection on Beaglebone using ethernet. Please help me I am stuck. Thanks in advance.
Code is:
#include<linux/module.h>
#include<linux/kernel.h>
#include<linux/init.h>
static int __init hello(void)
{
printk(KERN_INFO "Hello World!");
return 0;
}
static void __exit hello_cleanup(void)
{
printk(KERN_INFO "Bye");
}
module_init(hello);
module_exit(hello_cleanup);
Makefile is:
obj-m+=Hello.o
all:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
$(CC) Hello.c -o test
clean:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
rm test
It appears that you're trying to build your module for a kernel version that you haven't installed the headers for.
Instead of calling uname directly in your rules, it's helpful to put that into a variable you can override:
obj-m+=Hello.o
KSRC := /lib/modules/$(shell uname -r)/build
all:
make -C $(KSRC) M=$(PWD) modules
$(CC) Hello.c -o test
clean:
make -C $(KSRC) M=$(PWD) clean
rm test
Now, you can override with the actual location of your kernel headers:
make KSRC=/usr/src/linux-headers-4.9.2 all
You can simplify the Makefile further with a catch-all rule:
obj-m+=Hello.o
KSRC := /lib/modules/$(shell uname -r)/build
all: modules
$(CC) Hello.c -o test
%:
make -C $(KSRC) M=$(PWD) $#
clean::
make -C $(KSRC) M=$(PWD) clean
$(RM) test
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