1

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

hello_mod/
   | 
   --- hello.c
   |
   --- 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 world 源代码的源代码 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);

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

4

2 回答 2

2

这里发生了两种情况。第一个实际上只依赖于 KSRC 变量和递归调用。第二个 make 只需要CFILES, OBJS,obj-mhello_world-y变量,并且不使用all:目标。因此,您的调试显示 CFILES 为第一个 Make 设置正确,它没有被使用,并且没有在第二个 Make 中显示它,它在哪里。

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

CFILES := $(notdir $(wildcard $M/hello.c*))
于 2013-08-05T15:50:32.780 回答
0
 SRCDIRS := subdir1 subdir2
 CFILES := $(strip $(foreach dir,$(SRCDIRS),$(wildcard $(dir)/*.c)))

应该是(参见foreach 文档中的示例

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

(不需要$(strip),....或者也许

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

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

于 2013-08-04T11:06:59.703 回答