Makefile for Linux kernel module?
obj-m += chardev.o
Linux Kernel Module ignores main module file when an additional source file is added
The line
obj-m += mymodule.o
tells KBuild system just to build a module named mymodule
.
The sources compiled into that module depend from variable mymodule-y
:
- If the variable is set (like in your code), then source list it taken only from this variable. There is no "automatic" addition of
mymodule.c
source. - If the variable is not set, then, by default, the module is compiled from the source which has the same name.
Note, that one cannot build a module mymodule
from several sources, one of which is mymodule.c
, that is has the same name as the module itself.
Either module or the source file should be renamed. That situation is described in that question.
Single makefile that compiles kernel driver and .c file
Create 2 makefiles
- one for hello.c and the other for hello_driver.c
Create a third makefile - this master makefile will call the above 2.
$(MAKE) -f <path/to/makefile1>
$(MAKE) -f <path/to/makefile2>
Linux kernel module Makefile can't include relative paths
The Linux kernel uses Kbuild to make modules. This framework differs from normal makefile conventions, so while they are both interpreted by GNU make, one needs to be aware of the differences. Documentation for Makefiles using Kbuild can be found here and documentation for building external kernel modules can be found here.
A few important points, relevant to your problem, from the documentation are quoted below.
From makefiles.txt
:
--- 3.10 Special Rules
Special rules are used when the kbuild infrastructure does not provide the required support. A typical example is header files
generated during the build process. Another example are the
architecture-specific Makefiles which need special rules to prepare
boot images etc. Special rules are written as normal Make rules. Kbuild is not executing in the directory where the Makefile is located, so all
special rules shall provide a relative path to prerequisite files
and target files. Two variables are used when defining special rules:~
$(src)
~
$(src)
is a relative path which points to the directory where the Makefile is located. Always use$(src)
when referring to files located in thesrc
tree.~
$(obj)
~
$(obj)
is a relative path which points to the directory where the target is saved. Always use$(obj)
when referring to generated files.
From modules.txt
:
--- 4.3 Several Subdirectories
kbuild can handle files that are spread over several directories.
Consider the following example:.
|__ src
| |__ complex_main.c
| |__ hal
| |__ hardwareif.c
| |__ include
| |__ hardwareif.h
|__ include
|__ complex.h
To build the module complex.ko, we then need the following kbuild
file:--> filename: Kbuild
obj-m := complex.o
complex-y := src/complex_main.o
complex-y += src/hal/hardwareif.o
ccflags-y := -I$(src)/include
ccflags-y += -I$(src)/src/hal/include
As you can see, kbuild knows how to handle object files located in
other directories. The trick is to specify the directory relative to
the kbuild file's location. That being said, this is NOT recommended
practice.For the header files, kbuild must be explicitly told where to look.
When kbuild executes, the current directory is always the root of the
kernel tree (the argument to "-C") and therefore an absolute path is
needed.$(src)
provides the absolute path by pointing to the
directory where the currently executing kbuild file is located.
Thus, your Makefile should look like the following:
KBUILD_EXTRA_SYMBOLS := $(src)/../../Module.symvers
KBUILD_EXTRA_SYMBOLS := $(src)/../../dir0/Module.symvers
KDIR = $(src)/../../../../kernel/linux-4.9
INCLUDES = \
-I$(src)/../dir1/dir2/dir3 \
-I$(src)/../dir1/dir2 \
-I$(src)/../dir1
EXTRA_CFLAGS += $(INCLUDES)
PWD = $(shell pwd)
TARGET = some_module
obj-m := $(TARGET).o
all: default clean
default:
make $(INCLUDES) -C $(KDIR) M=$(PWD) modules
clean:
@rm -f *.o .*.cmd .*.flags *.mod.c *.order
@rm -f .*.*.cmd *.symvers *~ *.*~ TODO.*
@rm -fR .tmp*
@rm -rf .tmp_versions
disclean: clean
@rm -f *.ko
Build Linux Kernel Module using Makefile with different pathname
Move all Kbuild-related logic into the file Kbuild
. Kernel's build system checks file with this name first, so it won't look into Makefile
, created by CMake. This feature is documented in Documentation/kbuild/makefiles.txt.
I use exactly this approach in my CMake projects, related with Linux kernel.
Related Topics
How to Read Config Files with Section in Bash Shell
Libpcap - Capture Packets from All Interfaces
Certificate with Extended Key Usage Only Works in Firefox
Process Stuck in Exit, Shows as Zombie But Cannot Be Reaped
How to Add Boost Library to Code::Blocks in Linux
Sending Keycode to Xorg + Wine with Bash Script
How to Add an User and Re Set the Root User in Yocto
How Uevents Get Triggered in Kernel
How to Capitalize First Letter of Each Line in Bash
Sending Sigint from Keyboard to Piped Commands in Bash
.Zshrc Config File Syntax Error
How to Grep While Avoiding 'Too Many Arguments'
Access Bash Positional Parameter Through Variable
Storing Pid File for a Daemon Run as User
Cmake Set Environment Variable