• Uncategorized

About linux : Cannot-use-wildcard-in-kernel-module-makefile

Question Detail

I am pretty familiar with Makefiles and kernel modules, but recently I got a problem in my Makefile that doesn’t make any sense — on using wildcards.
To demonstrate this, I am compiling a hello world kernel module from scratch.
The directory structure is like this:

hello_mod/
   | 
   --- hello.c
   |
   --- Makefile

Here is the actual makefile :

CFILES := $(wildcard hello.c*)
#CFILES := hello.c
OBJS := $(CFILES:.c=.o)

KSRC := /lib/modules/$(shell uname -r)/build

obj-m += hello_world.o
hello_world-y := $(OBJS)

all:    
        @echo $(CFILES)
        $(MAKE) -C $(KSRC) M=$$PWD modules

clean:
        $(MAKE) -C $(KSRC) M=$$PWD clean

.PHONY: clean

The problem is that even though the commented $(CFILES) and the uncommented $(CFILES) are exactly the same, the build fails on using the first $(CFILES) with the following error:

*** No rule to make target `/home/test/hello_mod/hello_world.c', needed by
/home/test/hello_mod/hello_world.o'.  Stop.

If the commented $(CFILES) is used, it works perfectly.

If someone wants to test this out, I’m including the source for the hello world source which is hello.c :

#include <linux/kernel.h>
#include <linux/module.h>

static int mod_init()
{
        printk("Hello\n");
        return 0;
}

static void mod_exit()
{
        printk("Bye world\n");    
}

module_init(mod_init);
module_exit(mod_exit);

Does anyone know why it is behaving as such? And I need to use wildcards in the makefile. Any help will be appreciated.

Question Answer

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*))

 SRCDIRS := subdir1 subdir2
 CFILES := $(strip $(foreach dir,$(SRCDIRS),$(wildcard $(dir)/*.c)))

should probably be (see foreach example in documentation)

 SRCDIRS := subdir1 subdir2
 CFILES := $(foreach dir,$(SRCDIRS),$(wildcard $(dir)/*.c))

(no need to $(strip), …. or perhaps

 CFILES := $(wildcard  {subdir1,subdir2}/*.c)

Use remake, probably as remake -x, to debug such issues.

You may also like...

Leave a Reply

Your email address will not be published.

This site uses Akismet to reduce spam. Learn how your comment data is processed.