2016-08-15 74 views
0

我有涉及yacclex一個make爲基礎的項目,但make正在執行我不期望,不能從我的makefile說明操作:生成文件的YACC和Flex

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中沒有這樣的命令,並且導致構建失敗。

+1

1.找到再現問題的最小代碼量 - 自己隔離問題(這樣做會經常導致您找到解決方案)2.然後在這裏以適當的格式發佈最簡單的示例。 –

+0

Hi Sayan - 我已經爲你的代碼和輸出應用了一些標記,所以現在閱讀更清晰;但你的問題仍然需要一些工作。如果你可以先自己做一些調查來確定問題的真相(這就是Mark Galeck說的最簡單的例子),這可以幫助人們回答這個問題。 –

+0

這看起來不像一個makefile。格式混亂,也許它看起來更像你的意思。如果這是關於你的makefile,爲什麼添加其他標籤? – Olaf

回答

3

您有:

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.cass3_14CS101.c。所以,這就是你看到它做的。

您可能會注意到make在您注意到的mv之前再次運行yacc命令;並且該調用與第一個不同。

您需要使用更多的宏。 YACC包含Yacc程序的名稱,並且YFLAGS通常包含它的參數(它看起來像您更喜歡-dtv -W作爲Yacc標誌)。類似地,對於C編譯器(CCCFLAGS)和連接經常增加LDFLAGSLDLIBS - 所以你最終像的命令行:

${CC} -o [email protected] ${CFLAGS} ${OBJECTFILES} ${LDFLAGS} ${LDLIBS} 

作爲連接命令行。我指定爲${OBJECTFILES}的宏是應該鏈接的對象文件的列表。請注意,包含${CFLAGS};它通常包含用於調試信息的-g選項,並且您需要在鏈接命令行以及對象文件命令行中使用該選項。

使用宏的一個主要好處是,如果需要,您可以從make命令行調整編譯 - 無需編輯makefile

+0

在同一個目錄中已經存在文件名ass_14CS101.c。那麼爲什麼'make'會從.y文件創建另一個.c文件? –

+0

我認爲這是因爲'make'是通過'.SUFFIXES'規則中的後綴列表設置的,以便從'.y'文件建立到現有的'.c'文件。 –