Cannot Use Wildcard in Kernel Module Makefile

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:

  1. When you type make from your module's directory.
  2. 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



Leave a reply



Submit