我有一个先决条件,我需要声明一个目标,在我尝试构建目标之前需要始终运行。它实际上并不生成文件。问题是,如果我将它声明为目标本身的第一个依赖关系,那么虚假依赖关系会在$ ^中结束并混淆后续的链接步骤。
以下是一个例子:
.PHONY: start
sample-prog-1 : start sample-prog-1.o
在其他地方,我有一个从目标文件构建可执行文件的规则:
%: %.o
echo "Building executable $@";$(CC) $(LDFLAGS) $^ $(LOADLIBES) $(LDLIBS) -o $@ $(LDFLAGS_$@)
问题是,“start”是一个虚假的目标,所以它不存在,但链接阶段被称为“start”作为目标文件之一,所以构建过程呱呱叫!
我找到了解决办法,只是从目标文件列表中删除“开始”:
%: %.o
echo "Building executable $@";$(CC) $(LDFLAGS) $(shell echo "$^" | sed s/start//g) $(LOADLIBES) $(LDLIBS) -o $@ $(LDFLAGS_$@)
但除了看起来非常hacky和丑陋之外,它还意味着我不能拥有任何“开始”的源文件。我也总是重新建立样本编程-1,因为“开始”总是被重新制作。
这似乎是错误的解决方案,但我不知道这样做的“正确”方法是什么。我想我应该做一些事情,我用这样的东西来分解可执行文件:
sample-prog-1 : sample-prog-1.o
do_sample-prog-1 : start sample-prog-1
但这是不直观的,因为现在如果我想构建一个给定的目标,我必须记住在该目标名前加上或附加一些其他字符串,以便在构建可执行文件之前运行起始代码。
答案 0 :(得分:3)
答案 1 :(得分:1)
您可以将假目标放在.o目标之后,然后使用$<
代替$^
:
sample-prog-1 : sample-prog-1.o start
%: %.o
echo "Building executable $@";$(CC) $(LDFLAGS) $< $(LOADLIBES) $(LDLIBS) -o $@ $(LDFLAGS_$@)
或者,如果您正在使用gnu-make,请使用内置filter
来获取目标文件:
$(CC) $(LDFLAGS) $(filter %.o $^) $(LOADLIBES) $(LDLIBS) -o $@