Cannot use wildcard in kernel module makefile
There are two makes happening here. The first really only relies on the KSRC variable and the recursive make call. The second make only needs the CFILES
, OBJS
, obj-m
, and hello_world-y
variables, and doesn't make use of the all:
target. So your debug is showing that CFILES is set correctly for the first Make, where it's not being used, and is not showing it in the second make, where it is.
You're wildcard expanding from a different directory, and not picking up the right files. Try this for CFILES:
CFILES := $(notdir $(wildcard $M/hello.c*))
Issues with using wildcard in Makefile while build .ko from objects across directory
When build the kernel module your Makefile
is processed twice:
- When you type
make
from your module's directory. - Inside Kbuild process, because you pass
M=$(PWD)
option to it.
First time the Makefile is processed with current directory equal to the module's directory. So wildcard works as expected, which is confirmed by printing from all
receipt.
But the second time the Makefile is processed with current directory equal to kernel's build directory (/lib/modules/4.4.23-PT-ProbeOn-AuditOn+/build
in your case). In that mode
$(wildcard src/*.c)
attempts to find a file in kernel's build directory, which obviously fails.
At the time of second processing one may refer to module's build directory with $(src)
.
Such way one may use wildcard()
for collect module's sources. But note, that Kernel build system expects path to source file (more precisely, to object file) to be relative to module's build directory. So, one need to strip $(src)
component of every file obtained with wildcard()
.
For kernel module makefile: Use another name for the makefile and using command line parameter
Just faced this issue, and this is what I did:
For each moduleX
you want to build, write a Kbuild_moduleX
with the targets. Example:
obj-$(MODULE) += MODULE.o
MODULE-y := source.o
Then, in your Makefile_moduleX
, do:
all:
cp Kbuild_moduleX Kbuild
make -C /lib/modules/$(shell uname -r)/build M=$(shell pwd) modules
rm Kbuild
This works because the kernel scripts will give Kbuild priority over reading Makefile.
To compile, do make -f Makefile_moduleX
Is it pretty? No. Does it work? Yes.
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>
Makefiles and wildcards
Short answer: that syntax does not work the way you want it to. The correct way to do what you want in GNU make syntax is to use pattern rules:
public%.o: public%.c hashtable.h
$(CC) $(CFLAGS) -c $<
public%: public%.o
$(CC) -o $@ $<
Long answer: This:
public*.o: public*.c hashtable.h
does not mean what you want it to mean. Assuming you have several file public01.c
, etc., and no files public01.o
, etc., at the start of your build, that syntax is equivalent to this:
public*.o: public01.c public02.c public03.c ... hashtable.h
That is, if public01.o
, etc., do not exist, then make will use the literal string public*.o
as the filename. If some of the .o
files do exist, then that syntax is equivalent to this:
public01.o public02.o ...: public01.c public02.c ... hashtable.h
Seems like what you want right? But that's a common misunderstanding with make, because in fact that line is exactly the same as this:
public01.o: public01.c public02.c ... hashtable.h
public02.o: public01.c public02.c ... hashtable.h
That is -- every .o
file has a dependency on every .c
file! The correct way to do what you want is to use a pattern rule, as shown above.
How to set preprocessor directives in makefile for kernel module build target?
You should be able to use your original version that used EXTRA_CFLAGS
, but just replace EXTRA_CFLAGS
with ccflags-y
:
debug:
$(MAKE) -C $(KDIR) M=$(PWD) ccflags-y="-DDEBUG" modules
or replace it with CFLAGS_main.o
to apply the CFLAGS to a single object:
debug:
$(MAKE) -C $(KDIR) M=$(PWD) CFLAGS_main.o="-DDEBUG" modules
EDIT
As mentioned by the OP Roger Dueck, setting variables on the make
command line has a global effect. It overrides any setting of the same variables within the makefiles which may be undesirable, especially for a globally used variable such as ccflags-y
. To avoid this, use your own makefile variable. In the "normal" part of the Makefile that invokes $(MAKE)
on the "KBuild" part, change the debug:
target to the following, using a custom variable of your choice (I used FOO_CFLAGS
here):
debug:
$(MAKE) -C $(KDIR) M=$(PWD) FOO_CFLAGS="-DDEBUG" modules
In the "KBuild" part of the Makefile invoked by the above rule, use the following to append the custom CFLAGS from FOO_CFLAGS
to ccflags-y
:
ccflags-y += $(FOO_CFLAGS)
Makefile for a Linux kernel module with multiple sub-directories
If you're building a module out of the kernel tree, a simple makefile like the following should work:
MODULE_NAME = mymodule
SRC := foo.c src/bar.c
# Path to target Linux Kernel
KDIR := $(shell pwd) # <--- Fill in with path to kernel you're compiling against
$(MODULE_NAME)-objs = $(SRC:.c=.o)
obj-m := $(MODULE_NAME).o
PWD := $(shell pwd)
EXTRA_CFLAGS := -I$(PWD)/src -I$(PWD)/include
all:
$(MAKE) -C $(KDIR) M=$(PWD) modules
As can be seen in the SRC :=
line, you simple specify the paths to all of your source files, including those in subdirectories. The top level kernel makefile in KDIR
will take care of the compilation.
Further information about the kernel build system and out of tree builds can be found in the kernel source documentation in Documentation/kbuild/modules.txt
.
Related Topics
Where Does Pp (Par) Unpack Add (-A) Files
Perl Fails to Set Locale Even Though It Is Installed
Cannot Use Wildcard in Kernel Module Makefile
Quick Unix Command to Display Specific Lines in the Middle of a File
How to Map a Hostname *And* a Port with /Etc/Hosts
Permanently Change Disassembly Flavor in Gdb
How to Pass a File Argument to My Bash Script Using a Terminal Command in Linux
Use Bash to Read a File and Then Execute a Command from the Words Extracted
Get the Last 4 Characters of Output from Standard Out
How to Get Cmake to Use the Default Compiler on System Path
Chrome Certificate Selection Appears Multiple Times
Extending a Script to Loop Over Multiple Files and Generate Output Names
Find the Files Existing in One Directory But Not in the Other
Linux Command to Translate Domain Name to Ip
Execute a Shell Script Everyday at Specific Time