在Makefile中,如何防止虚假的先决条件被包含在$ ^中

时间:2012-03-09 22:17:27

标签: makefile

我有一个先决条件,我需要声明一个目标,在我尝试构建目标之前需要始终运行。它实际上并不生成文件。问题是,如果我将它声明为目标本身的第一个依赖关系,那么虚假依赖关系会在$ ^中结束并混淆后续的链接步骤。

以下是一个例子:

    .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_$@)

但除了看起来非常h​​acky和丑陋之外,它还意味着我不能拥有任何“开始”的源文件。我也总是重新建立样本编程-1,因为“开始”总是被重新制作。

这似乎是错误的解决方案,但我不知道这样做的“正确”方法是什么。我想我应该做一些事情,我用这样的东西来分解可执行文件:

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

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

2 个答案:

答案 0 :(得分:3)

您可以考虑order-only prerequisite

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

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

答案 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 $@