c - yacc 和 flex 的 makefile

标签 c makefile flex-lexer yacc

<分区>

我有一个基于 make 的项目,涉及 yacclex,但是 make 正在执行我的操作不要期望也无法从我的 makefile 中解释:

a.out: lex.yy.o y.tab.o ass3_14CS101.o
    gcc lex.yy.o y.tab.o ass3_14CS101.o -lfl
ass3_14CS101.o: ass3_14CS101.c
    gcc -c ass3_14CS101.c
lex.yy.o: lex.yy.c
    gcc -c lex.yy.c
y.tab.o: y.tab.c
    gcc -c y.tab.c
lex.yy.c: ass3_14CS101.l y.tab.h
    flex ass3_14CS101.l
y.tab.c: ass3_14CS101.y
    yacc -dtv ass3_14CS101.y -W
y.tab.h: ass3_14CS101.y
    yacc -dtv ass3_14CS101.y -W
clean:
    rm lex.yy.c y.tab.c y.tab.h lex.yy.o y.tab.o ass3_14CS101.o y.output a.out
test: 
    ./a.out < ass3_14CS101_test.c

这是一个 make 运行的输出:

yacc -dtv ass3_14CS10061.y -W
ass3_14CS10061.y:48.10: warning: empty rule without %empty [-Wempty-rule]
statement : ;
^
flex ass3_14CS10061.l
ass3_14CS10061.l:77: warning, rule cannot be matched
gcc -c lex.yy.c
gcc -c y.tab.c
yacc ass3_14CS10061.y
mv -f y.tab.c ass3_14CS10061.c
gcc -c ass3_14CS10061.c
gcc lex.yy.o y.tab.o ass3_14CS10061.o -lfl
ass3_14CS10061.o: In function `yyparse':
ass3_14CS10061.c:(.text+0x20): multiple definition of `yyparse'
y.tab.o:y.tab.c:(.text+0x289): first defined here
ass3_14CS10061.o: In function `yyerror':
ass3_14CS10061.c:(.text+0x7f6): multiple definition of `yyerror'
y.tab.o:y.tab.c:(.text+0xd61): first defined here
collect2: error: ld returned 1 exit status
make: *** [a.out] Error 1

mv -f 命令(上面的粗体 行)来自哪里? Makefile 中没有这样的命令,导致构建失败。

最佳答案

你有:

a.out: lex.yy.o y.tab.o ass3_14CS101.o
    gcc lex.yy.o y.tab.o ass3_14CS101.o -lfl
ass3_14CS101.o: ass3_14CS101.c
    gcc -c ass3_14CS101.c

第一条规则说编译需要确保 ass3_14CS101.o 是最新的。第二条规则是通过编译 ass3_14CS101.c 创建 ass3_14CS101.o。其他指定的规则都没有说明如何创建 ass3_14CS101.c,但是 make 很聪明。

鉴于有一个文件 ass3_14CS101.ymake 知道如何从中创建 ass3_14CS101.c:它运行 yacc 并将 yy.tab.c 移动到 ass3_14CS101.c。所以,这就是您所看到的。

您可能会注意到 make 在您注意到的 mv 之前再次运行 yacc 命令;并且该调用与第一个不同。

你需要使用更多的宏。 YACC 包含类 Yacc 程序的名称,YFLAGS 通常包含它的参数(看起来您更喜欢 -dtv -W作为 Yacc 标志)。与 C 编译器(CCCFLAGS)类似,链接通常会添加 LDFLAGSLDLIBS - 所以你最终使用如下命令行:

${CC} -o $@ ${CFLAGS} ${OBJECTFILES} ${LDFLAGS} ${LDLIBS}

作为链接命令行。我指定为 ${OBJECTFILES} 的宏是应该链接的目标文件的列表。请注意,包含了 ${CFLAGS};它通常包含用于调试信息的 -g 选项,您需要在链接命令行和目标文件命令行中使用它。

使用宏的一个主要好处是,如果需要,您可以从 make 命令行调整编译 — 而无需编辑 makefile

关于c - yacc 和 flex 的 makefile,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38962279/

相关文章:

parsing - 词法分析器/解析器工具

C字符串与字符的输入、比较

c - 有没有办法从一个队列出队并入队到另一个队列?

c - 在c中根据另一个数组按升序对一个数组进行排序

g++ - 对`boost::this_thread的 undefined reference :

c++ - 构建基于状态的游戏引擎和 Makefile 结构有帮助吗?

c++ - 制作 vtkOBJWriter 时遇到问题

c - 我收到一条错误,指出 "warning: assignment makes integer from pointer wit hout a cast [enabled by default]"

flex-lexer - Flex 中的单线或多线字符串检测

bison - flex 究竟是如何支持 Bison 定位的?