我有一个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
之后运行。我坐在这个剧本上看起来无助,不知道这里有什么问题(一定是傻事)。你能想到什么吗?
答案 0 :(得分:3)
你真的不应该在规则中使用$(wildcard ...)
,而是做一些像
MYSRC:=$(wildcard *.c)
MYOBJ:=$(patsubst %.c, %.o, $(MYSRC))
%.o: %.c
$(CC) -c $< -o $@
my_binary: $(MYOBJ)
$(CC) $^ -o $@
这样您就知道MYSRC
和MYOBJ
匹配。另请注意,使用$<
表示当前目标的依赖关系,$@
表示当前目标的目标文件名。
编辑:在链接步骤中将$<
更改为$^
,以包含所有目标文件,而不仅仅是最后一个。
编辑:如果您不想从child.makefile
中提取源文件名,您应该可以执行以下操作:
.PHONY: all
all:
$(MAKE) --file=child.makefile
$(MAKE) my_binary OBJS="$(wildcard *.o)"
my_binary: $(OBJS)
$(CC) $< -o my_binary
重要的是,构建OBJS
时my_binary
的值是一致的。这样,您可以清楚地将构建拆分为两个步骤,并在执行第二个make之前读取目标文件列表。