2

这是我的生成文件:

all: lex yacc compile

lex: sql.l
    lex -i sql.l

yacc: sql.y
    yacc -d -v sql.y

compile: y.tab.c lex.yy.c
    $(CC) -o sql_parser y.tab.c lex.yy.c -ly -ll

test: all
    @./parsesql.sh selecttest.sql
    @./parsesql.sh insertintotest.sql
    @./parsesql.sh deletefromtest.sql
    @./parsesql.sh createtest.sql

cleanup:
    rm test.tab.cacc
    rm y.output

运行make将始终触发完全重新编译,即使没有任何改变:

parsesql>  make
lex -i sql.l
yacc -d -v sql.y
cc -o sql_parser y.tab.c lex.yy.c -ly -ll
parsesql>  make
lex -i sql.l
yacc -d -v sql.y
cc -o sql_parser y.tab.c lex.yy.c -ly -ll
parsesql>  make
lex -i sql.l
yacc -d -v sql.y
cc -o sql_parser y.tab.c lex.yy.c -ly -ll

所有文件都没有更改,那么为什么要这样做呢?lexandyacc命令应该仅在或分别发生更改时触发,sql.l不是sql.y吗?

4

1 回答 1

2

您的目标都不是真实文件。使它们成为您正在生成的实际文件的名称,以便make可以找到它们并检查时间戳。

例子:

all: sql_parser

lex.yy.c: sql.l
    lex -i sql.l

y.tab.c: sql.y
    yacc -d -v sql.y

sql_parser: y.tab.c lex.yy.c
    $(CC) -o sql_parser y.tab.c lex.yy.c -ly -ll

test: all
    @./parsesql.sh selecttest.sql
    @./parsesql.sh insertintotest.sql
    @./parsesql.sh deletefromtest.sql
    @./parsesql.sh createtest.sql

cleanup:
    rm test.tab.cacc
    rm y.output

您可以添加.PHONY: all test cleanup以指示make这些目标不是真实文件。

于 2013-06-27T22:58:19.003 回答