不能在内核模块makefile中使用通配符

时间:2013-08-04 10:03:18

标签: linux makefile linux-kernel gnu-make kernel-module

我对Makefile和内核模块非常熟悉,但是最近我的Makefile中出现了一个问题 - 使用通配符时没有任何意义。 为了证明这一点,我正在从头开始编译一个hello world内核模块。 目录结构如下:

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

这是实际的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

问题在于,即使注释的$(CFILES)和未注释的$(CFILES)完全相同,构建也会因使用第一个$(CFILES)而失败,并出现以下错误:

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

如果使用了注释的$(CFILES),它可以很好地工作。

如果有人想对此进行测试,我将包含hello.c的hello world源代码:

#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);

有谁知道为什么会这样?我需要在makefile中使用通配符。任何帮助将不胜感激。

2 个答案:

答案 0 :(得分:2)

这里发生了两件事。第一个真正只依赖于KSRC变量和递归make调用。第二个make仅需要CFILESOBJSobj-mhello_world-y变量,并且不使用all:目标。所以你的调试显示CFILES正确设置为第一个Make,它没有被使用,并且没有在第二个make中显示它,它在哪里。

您是从另一个目录扩展的通配符,而不是选择正确的文件。试试这个CFILES:

CFILES := $(notdir $(wildcard $M/hello.c*))

答案 1 :(得分:0)

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

应该是(请参阅foreach example in documentation

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

(无需$(strip),....或者

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

使用remake(可能是remake -x)来调试此类问题。