I am trying to compile a kernel module that has two .c files. My Makefile is the following
module-y: dummy.o library.o
obj-m += module.o
default:
make -C /lib/modules/`uname -r`/build M=$(PWD) modules
When I run this I get
cc -c -o dummy.o dummy.c
dummy.c:3:24: fatal error: linux/init.h: No such file or directory
It seems the Makefile doesn't know where to find the headers now.
I have tried using CFLAGS to add include directories, but there are so many of them that it becomes tedious and hard to do (haven't managed to make it work).
I would like to generate these two .o files using the include directories that are (magically) used when using a single .c file. Everything works fine in that case.
How to fix the include directories when using two source files?
I wrote the Makefile like the following, and it worked:
ifneq ($(KERNELRELEASE),)
# kbuild part of makefile
obj-m := module.o
module-y := library.o dummy.o
else
# normal makefile
KDIR ?= /lib/modules/`uname -r`/build
default:
$(MAKE) -C $(KDIR) M=$$PWD modules
endif
Related
To start building a block-drive (it is called "out of tree"?) module, I'm trying to compile just some headers from Linux.
Edit: Deleted .c file and renamed .h file to .c, but the same 1 error persists.
BlockVRAM.c:
#include <linux/module.h>
Makefile:
BINARY := BlockVRAM
KERNEL := /lib/modules/$(shell uname -r)/build
ARCH := x86
C_FLAGS := -D__KERNEL__ -Wall -I/usr/src/linux-headers-5.4.0-66-generic/include/ -I/usr/src/linux-headers-5.4.0-66-generic/arch/x86/include
KMOD_DIR := $(shell pwd)
TARGET_PATH := /lib/modules/$(shell uname -r)/kernel/drivers/char
OBJECTS := BlockVRAM.o
CC += $(C_FLAGS)
obj-m := $(BINARY).o
$(BINARY)-y := $(OBJECTS)
$(BINARY).ko:
make ARCH=x86 -C $(KERNEL) M=$(KMOD_DIR) modules
install:
cp $(BINARY).ko $(TARGET_PATH)
depmod -a
clean:
rm -f *.ko
rm -f *.o
There is only 1 error it is returning:
In file included from /usr/src/linux-headers-5.4.0-66-generic/include/linux/time64.h:10:0,
from /usr/src/linux-headers-5.4.0-66-generic/include/linux/restart_block.h:10,
from /usr/src/linux-headers-5.4.0-66-generic/include/linux/thread_info.h:13,
from /usr/src/linux-headers-5.4.0-66-generic/arch/x86/include/asm/preempt.h:7,
from /usr/src/linux-headers-5.4.0-66-generic/include/linux/preempt.h:78,
from /usr/src/linux-headers-5.4.0-66-generic/include/linux/spinlock.h:51,
from /usr/src/linux-headers-5.4.0-66-generic/include/linux/seqlock.h:36,
from /usr/src/linux-headers-5.4.0-66-generic/include/linux/time.h:6,
from /usr/src/linux-headers-5.4.0-66-generic/include/linux/stat.h:19,
from /usr/src/linux-headers-5.4.0-66-generic/include/linux/module.h:10,
from BlockVRAM.h:12,
from BlockVRAM.c:11:
/usr/src/linux-headers-5.4.0-66-generic/include/uapi/linux/time.h:6:10: fatal error: linux/time_types.h: No such file or directory
#include <linux/time_types.h>
^~~~~~~~~~~~~~~~~~~~
compilation terminated.
<builtin>: recipe for target 'BlockVRAM' failed
make: *** [BlockVRAM] Error 1
I tried to include that folder as an include flag but it only caused re-definition errors. I don't know what I'm doing wrong. OS is Ubuntu 18.04 LTS.
Using Makefile as this:
sudo make BlockVRAM
in same folder of source file.
I started from here but there were a lot of errors until I added those two include directory flags in Makefile.
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.
I want to make multiple kernel modules by executing one Makefile.
I have following directories and files:
top level directory:
subdir0:
module0.c
Makefile
subdir1:
module1.c
Makefile
subdir2:
module2.c
Makefile
Makefile (I want to execute this)
I want to execute only the Makefile in the top level directory and all subdir Makefiles should be executed. I want to get one kernel module for each subdirectory.
This is my current setting but it does not work. If I execute make inside of a subdir, it builds the correct *.ko files. But if I execute the top level Makefile it just generates Module.symvers and modules.order and the output looks like every Makefile would be executed, but nothing is created inside of the subdirectories.
My top level Makefile has the following contents:
TARGETS := all clean
SUBDIRS := subdir0 subdir1 subdir2
.PHONY: $(TARGETS) $(SUBDIRS)
$(TARGETS): $(SUBDIRS)
$(SUBDIRS):
$(MAKE) -C $# $(MAKECMDGOALS)
My subdirectory Makefiles have the following code:
obj-m += module0.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 would be glad if someone could help me.
Thanks,
micha
As #0andriy said, I had to use a Makefile similar to the subdirectory Makefiles. But instead of adding obj-m entries, I added all subdirectories to obj-y.
Is it possible to build a kernel module from several source files which one of them has the same name as the module?
For example:
I want to build "mymodule.ko" with the following source files:
mymodule.c
mymodule_func.c
This makefile doesn't work:
#Makefile
obj-m += mymodule.o
mymodule-objs := mymodule.o mymodule_func.o
thanks
I found a solution, I placed my source file in a sub folder:
Makefile
src/mymodule.c
src/mymodule_func.c
#Makefile
obj-m += mymodule.o
mymodule-objs := ./src/mymodule.o ./src/mymodule_func.o
all:
make -C $(KERNEL_PATH) M=$(PWD) modules
clean:
make -C $(KERNEL_PATH) M=$(PWD) clean
Proper way to fix in kernel make file would be as:
#
obj-m+= my_module.o
#append other source files except my_module.c which would be include by default
my_module-objs+= src1.o src2.o
As per my understanding it is not possible to have the module name and the source name to be the same. It would be better to provide module name as module.o and use the Makefile for compiling loadable kernel module as shown below,
Makefile
# If KERNELRELEASE is defined, we've been invoked from the
# kernel build system and can use its language.
ifneq ($(KERNELRELEASE),)
**obj-m := module.o
module-objs := mymodule.o mymodule_func.o**
# Otherwise we were called directly from the command
# line; invoke the kernel build system.
EXTRA_CFLAGS += -DDEBUG
else
KERNELDIR := /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)
default:
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules
endif
clean:
$(MAKE) -C $(KERNELDIR) SUBDIRS=$(PWD) clean
You can use TARGET to name your .ko file as I did in this example:
TARGET = can
KDIR = /lib/modules/3.1.10-1.16-desktop/build
PWD := $(shell pwd)
obj-m += $(TARGET).o
can-objs := can_core.o can_open.o can_select.o can_sysctl.o can_write.o \
can_close.o can_ioctl.o can_read.o can_util.o \
can_debug.o can_error.o \
can_async.o can_sim.o
default:
make -C $(KDIR) M=$(PWD) modules
So after the build I ended with a bunch of object files and can.ko
Another solution is create symlink to the file, say:
mymodule.c: ln -sf mymodule.c _mymodule.c
Now, use _mymodule.o as the object name:
mymodule-objs := _mymodule.o
If anyone has stumbled upon this issue while working with Xilinx SoCs and petalinux, note the generated .bb (bitbake) file. Apart from specifying object files in the Makefile:
modulename-objs+= src1.o src2.o
all files (including headers) must be listed in the modulename.bb file's SRC_URI variable.
I am compiling a Kernel Module in Linux 3.2.6.
I have module.h in /usr/src/linux/include/linux, except when I go to compile it with my makefile, it tells me module.h can not be found.
In my makefile, I also have KDIR set to the location of the modules.
How can I fix this?
My make file is:
MODCFLAGS := -Wall -DMODULE -D__KERNEL__ -DLINUX
obj-m := hello.o
KDIR := /usr/src/linux/include/
PWD := `pwd`
default:
make -C $(KDIR) M=$(PWD) modules