Makefile 在生成文件中同时运行所有目标

Makefile 在生成文件中同时运行所有目标,makefile,gnu-make,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时,它只运行targetall 我已尝试加入 .

我有一个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时,它只运行target
all

我已尝试加入
.PHONY:all clean
.PHONY:clean
即使它只运行
all
。 我应该在Makefile中做哪些更改以使其运行所有目标

系统配置:
Ubuntu 14.10

GNU Make 4.0

您想在键入
Make
时运行
all
clean
?这通常是没有用的,因为这会清理您刚刚构建的内容(尽管在您的例子中,我看到您的
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,并且没有利用
make
为您提供的任何好处(比如只有在先决条件发生变化时才能智能地重建东西)

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

.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.c
parser.tab.c
文件


还要注意,先决条件是链接的,
clean
现在也会清理二进制文件。您不需要运行
make clean
来以这种方式正确地重建事物。

如果您真的想
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
之前清除所有文件(而且您也不想这样做),实际上您可以改变
所有目标的先决条件:

.PHONY: all_targets
all_targets: clean all

.PHONY: all
all:
    # ...
.PHONY: clean
clean:
    # ...
同样,这并不是您想要使用的
make
,因为它旨在跳过构建过程中所有不必要的工作(即,不重新编译那些不需要重新编译的文件等)

还请记住,您可以调用
make
,以生成多个目标。因此,在您的示例中,您还可以通过执行

make all clean
请注意,目标将按照传递到命令行的顺序构建,因此这里要构建的第一个目标是
all
,后面是
clean
(这同样是胡说八道)

如果你想了解更多关于如何正确使用makefile的知识,我建议你去读这本书。它的特点是对几乎所有(GNU)Make特性进行了相当全面的解释


编辑:如上所述,上述示例中的
所有目标
当然应该是虚假目标。

谢谢
parser.output parser.tab.h parser.tab.c
这些文件是由
flex-d-v parser.y
flex parser.lex
生成的
lex.yy.c
所有_目标
也应该声明
.PHONY