在Makefile中,如何防止虚假先决条件包含在$^
我有一个先决条件,我需要为一个目标声明,在我尝试构建目标之前,该目标需要始终运行。它实际上并不生成文件。问题是,如果我将其声明为目标本身的第一个依赖项,那么虚假的依赖项将在$^中结束,并混淆后续的链接步骤 以下是一个例子:在Makefile中,如何防止虚假先决条件包含在$^,makefile,Makefile,我有一个先决条件,我需要为一个目标声明,在我尝试构建目标之前,该目标需要始终运行。它实际上并不生成文件。问题是,如果我将其声明为目标本身的第一个依赖项,那么虚假的依赖项将在$^中结束,并混淆后续的链接步骤 以下是一个例子: .PHONY: start sample-prog-1 : start sample-prog-1.o 在其他地方,我有一个从对象文件构建可执行文件的规则: %: %.o echo "Building executable $@";$(CC)
.PHONY: start
sample-prog-1 : start sample-prog-1.o
在其他地方,我有一个从对象文件构建可执行文件的规则:
%: %.o
echo "Building executable $@";$(CC) $(LDFLAGS) $^ $(LOADLIBES) $(LDLIBS) -o $@ $(LDFLAGS_$@)
问题是,“开始”是一个虚假的目标,所以它不存在,但链接阶段被称为“开始”作为一个对象文件,所以构建过程嘎嘎作响
我找到了一个解决方法,就是从对象文件列表中删除“开始”:
%: %.o
echo "Building executable $@";$(CC) $(LDFLAGS) $(shell echo "$^" | sed s/start//g) $(LOADLIBES) $(LDLIBS) -o $@ $(LDFLAGS_$@)
$(CC) $(LDFLAGS) $(filter %.o $^) $(LOADLIBES) $(LDLIBS) -o $@
但是除了看起来非常粗糙和丑陋之外,这也意味着我不能有任何包含“开始”的源文件。我也总是重新构建sample-prog-1,因为“begin”总是被重新制作
这似乎是一个错误的解决方案,但我不知道什么是“正确”的方法。我想我应该做一些事情,用这样的东西来分解可执行文件:
sample-prog-1 : sample-prog-1.o
do_sample-prog-1 : start sample-prog-1
但是这是不直观的,因为现在如果我想建立一个给定的目标,我必须记住,在目标代码的前面加上或附加一些其他字符串,以便在可执行文件建立之前运行起始代码。
除其他事项外,仅订购的先决条件不会出现在
$^
中。您可以将虚假目标放在.o目标之后,然后使用$第一种方法很好,只要目标不需要多个对象文件。第二种是有效的,只是有点笨拙+1在某些情况下,我有多个对象文件,因此必须使用第二种方法。这只是我尝试过的东西的一个较短版本,我认为它的问题仍然是,它仍将尝试重新构建可执行文件,即使它不需要,因为它认为开始已更改。奇怪的是,make并没有首先运行我的订单,尽管我不确定它如何知道它可以摆脱这个问题。但它确实会弄乱输出,因为现在我看到一些东西在我回显正在启动的编译的细节之前编译,这是start所做的一件事。如果你想在构建某个东西之前运行一个prereq,它需要是该东西的一个prereq。在本例中,start
不是.o文件的预请求,因此可以首先生成.o文件(如果使用-j,则可以同时生成)。当前暗示的唯一顺序是start
在链接步骤之前运行。
sample-prog-1 : sample-prog-1.o start
%: %.o
echo "Building executable $@";$(CC) $(LDFLAGS) $< $(LOADLIBES) $(LDLIBS) -o $@ $(LDFLAGS_$@)
$(CC) $(LDFLAGS) $(filter %.o $^) $(LOADLIBES) $(LDLIBS) -o $@