在Makefile中一次运行所有目标

时间:2015-03-20 18:10:39

标签: makefile gnu-make

我有一个Makefile,如下所示

all:
    bison -d -v parser.y
    flex  -o parser.lex.c parser.lex
    gcc  -o cparser parser.lex.c parser.tab.c -lfl -lm 
clean:
    rm parser.tab.h parser.tab.c parser.output parser.lex.c     

当我在终端中运行make时,它只运行目标all

我试过加入  .PHONY:all clean.PHONY:clean,即使它只运行all。 我应该在Makefile中进行哪些更改,以便它运行所有目标?

系统配置:
Ubuntu 14.10
GNU Make 4.0

2 个答案:

答案 0 :(得分:5)

您只想在输入all时运行cleanmake?这通常没有用,因为那会清理你刚刚构建的内容(虽然在你的情况下我看到你的clean目标实际上并没有这样做。)

要做到这一点,你需要类似的东西。

all: cparser clean

cparser:
    bison -d -v parser.y
    flex  -o parser.lex.c parser.lex
    gcc  -o cparser parser.lex.c parser.tab.c -lfl -lm

clean:
    rm parser.tab.h parser.tab.c parser.output parser.lex.c

虽然这仍然是一个相当差的makefile,并且没有利用{em>任何 make给你的好处(比如只有在他们的先决条件发生变化时智能地重建事物)。 / p>

我建议你可能想要更像这样的东西。

.PHONY: all
all: cparser

parser.lex: parser.y
    bison -d -v parser.y

parser.lex.% parser.tab.%: parser.lex
    flex  -o parser.lex.c parser.lex

cparser: parser.lex.c parser.tab.c
    gcc  -o cparser parser.lex.c parser.tab.c -lfl -lm

.PHONY: clean    
clean:
    rm parser.tab.h parser.tab.c parser.output parser.lex.c cparser

假设我没记错,flex会同时生成parser.lex.cparser.tab.c个文件。

另请注意,先决条件是链接的,clean现在也清除了二进制文件。您无需运行make clean即可以正确的方式重建内容。

答案 1 :(得分:1)

如果你真的想要make Makefile中的所有目标(你真的不想要,这通常不是你使用makefile的方式),你可以添加一个具有Makefile的所有其他目标的目标是它的先决条件:

.PHONY: all_targets
all_targets: all clean

.PHONY: all
all:
    # ... command script
.PHONY: clean
clean:
    # ... command script

在此特定示例中,将all后跟clean完全无意义,因为all将构建所有文件,而clean会删除它们。如果您想在构建all之前清除所有文件(并且您也不想这样做),实际上您可以转变all_targets的先决条件:

.PHONY: all_targets
all_targets: clean all

.PHONY: all
all:
    # ...
.PHONY: clean
clean:
    # ...

同样,这不是你想要使用make的方式,因为它旨在跳过构建过程中的所有不必要的工作(也就是说,不重新编译那些不需要重新编译的文件,等)。

另外请记住,您可以使用多个目标来构建make。因此,在您的示例中,您还可以通过执行

来构建所有目标
make all clean

请注意,目标将按照传递给命令行的顺序构建,因此在此构建的第一个目标是all,后跟clean(这也是废话)。

如果您想了解更多有关如何正确使用makefile的信息,建议您抓一本书Managing Projects with GNU Make。它对几乎所有(GNU)Make功能进行了非常全面的解释。

修改:正如tripleee所指出的,上述示例中的all_targets目标当然应该是虚假目标。