2012-03-09 55 views
1

我有一个先决条件,我需要声明的需要始终运行之前,我尝试建立目标对象一个虚假的前提条件。它实际上并不生成文件。问题是,如果我宣布它作为目标本身的第一依赖,那么假依赖于$ ^卷起和混淆连接的后续步骤。

下面是一个例子:

.PHONY: start 
    sample-prog-1 : start sample-prog-1.o 

在其他地方我有一个从目标文件建立一个可执行的规则:

%: %.o 
     echo "Building executable [email protected]";$(CC) $(LDFLAGS) $^ $(LOADLIBES) $(LDLIBS) -o [email protected] $([email protected]) 

问题是,“开始”是假目标,所以它不存在,但链接阶段被称为“开始”作为其中一个目标文件,所以构建过程呱呱叫!

我发现了一个变通办法,这简直是从对象的文件列表中去掉“开始”:

%: %.o 
    echo "Building executable [email protected]";$(CC) $(LDFLAGS) $(shell echo "$^" | sed s/start//g) $(LOADLIBES) $(LDLIBS) -o [email protected] $([email protected]) 

但除了似乎很哈克和丑陋,这也意味着我可以”没有任何有“开始”的源文件。我总是重新构建sample-prog-1,因为“开始”总是被重新制作。

这似乎只是错误的解决方案,但我在一个无所适从的“正确”的方式做到这一点。我想我应该做的事情,我分析出的可执行文件是这样的:

sample-prog-1 : sample-prog-1.o 
    do_sample-prog-1 : start sample-prog-1 

但是,这是直观的,因为现在如果我想建立一个给定的目标,我必须记住前面或后面附加一些其他字符串指向该目标名称,以便在构建可执行文件之前运行开始代码。

回答

3

你可能会考虑一个order-only prerequisite

sample-prog-1 : sample-prog-1.o | start 

除其他事项外,订单只有先决条件不会出现在$^

+0

正是我在找什么,谢谢! – Michael 2012-03-09 22:42:08

+0

奇怪的是,使没有运行我的命令,唯一的前提首先,虽然我不知道它是如何知道它可以摆脱这一点。但它确实搞乱了输出,因为现在我看到编译的东西之前我回应了开始编译的细节,这是开始的一件事情。 – Michael 2012-03-09 23:14:16

+0

如果你想有一个前提条件,以某事的构建运行之前,它需要的是东西前提条件。在这个例子中,'start'不是.o文件将的前提条件,所以(如果使用-j或同时)的.o文件将可能会先建。目前唯一隐含的顺序是'start'在链接步骤之前运行。 – 2012-03-09 23:42:29

1

你可以把假目标的.o目标之后再使用$<代替$^

sample-prog-1 : sample-prog-1.o start 

%: %.o 
     echo "Building executable [email protected]";$(CC) $(LDFLAGS) $< $(LOADLIBES) $(LDLIBS) -o [email protected] $([email protected]) 

或者,如果你正在使用的GNU-make,使用内建filter得到公正的对象文件:

$(CC) $(LDFLAGS) $(filter %.o $^) $(LOADLIBES) $(LDLIBS) -o [email protected] 
+0

只要目标不需要多个目标文件,第一种方法就没有问题。第二个是有效的,只有轻微kludgey。 +1 – Beta 2012-03-09 22:43:24

+0

在某些情况下,我有多个对象文件,因此必须使用第二种方法。这只是我尝试的一个较短版本,我认为它的问题仍然是它仍然会尝试重新构建可执行文件,即使它不需要,因为它认为开始改变了。 – Michael 2012-03-09 23:45:53