太早计算通配符?

时间:2010-02-02 13:22:44

标签: makefile linker compilation

我有一个make文件,或多或少,以下编译C ++源代码的结构:

.PHONY: all
all: compile_obj_files my_binary

# This rule generates the object files. It works fine afaik.
.PHONY: compile_obj_files
compile_obj_files:
    $(MAKE) --file=child.makefile

# my_binary is a real binary file that I wish to build.
my_binary: $(wildcard *.o)
    $(CC) $(wildcard *.o) -o my_binary

在第一次运行时,此make文件生成了所有目标文件,但$(wildcard *.o)返回了一个空列表。在第二次运行时,它没有按预期编译任何内容,$(wildcard *.o)确实返回了所有目标文件。看起来$(wildcard *.o)在创建所有目标文件之前执行,尽管my_binary规则始终在compile_obj_files之后运行。我坐在这个剧本上看起来无助,不知道这里有什么问题(一定是傻事)。你能想到什么吗?

1 个答案:

答案 0 :(得分:3)

你真的不应该在规则中使用$(wildcard ...),而是做一些像

这样的事情
MYSRC:=$(wildcard *.c)
MYOBJ:=$(patsubst %.c, %.o, $(MYSRC))

%.o: %.c
        $(CC) -c $< -o $@

my_binary: $(MYOBJ)
        $(CC) $^ -o $@

这样您就知道MYSRCMYOBJ匹配。另请注意,使用$<表示当前目标的依赖关系,$@表示当前目标的目标文件名。

编辑:在链接步骤中将$<更改为$^,以包含所有目标文件,而不仅仅是最后一个。

编辑:如果您不想从child.makefile中提取源文件名,您应该可以执行以下操作:

.PHONY: all
all: 
    $(MAKE) --file=child.makefile
    $(MAKE) my_binary OBJS="$(wildcard *.o)"

my_binary: $(OBJS)
    $(CC) $< -o my_binary

重要的是,构建OBJSmy_binary的值是一致的。这样,您可以清楚地将构建拆分为两个步骤,并在执行第二个make之前读取目标文件列表。