我对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中使用通配符。任何帮助将不胜感激。
答案 0 :(得分:2)
这里发生了两件事。第一个真正只依赖于KSRC变量和递归make调用。第二个make仅需要CFILES
,OBJS
,obj-m
和hello_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
)来调试此类问题。