2013-06-18 98 views
2

我正在使用Bison和Flex構建解析器。編譯一切我使用一個簡單的makefile。但是,我不是創建makefile的專家。生成文件正在工作,但幾件事情除外:Makefile:無法完成

更改源文件file.cpp中未檢測到生成文件。 沒有事可做。 A make clean解決了這個問題,但是這當然不是必須的。我發現了很多makefile教程,但沒有討論這類問題。

CC=g++ 
CFLAGS=-Wall -std=c++11 -ll 
EXECUTABLE=parser 
OBJS=parser.tab.cpp lex.yy.c 

FILES= file.cpp 

all: parser 

parser.tab.cpp parser.tab.hpp: parser.ypp 
    bison -d parser.ypp 

lex.yy.c: parser.l parser.tab.hpp 
    flex parser.l 

parser: $(OBJS) $(FILES) 
    $(CC) $(CFLAGS) $(OBJS) $(FILES) -o $(EXECUTABLE) 

clean: 
    rm -rf *o $(EXECUTABLE) $(OBJS) 

當然,我可以用make -B all,然後我還發現一些奇怪的事情:

bison -d parser.ypp 
bison -d parser.ypp 
flex parser.l 
g++ -Wall -std=c++11 -ll parser.tab.cpp lex.yy.c file.cpp -o parser 

爲什麼bison -d parser.ypp做兩次?

[解決]

我們現在下面的Makefile使用:

CC = g++ 
CFLAGS = --std=c++0x -O2 

SOURCES = $(wildcard */*.cpp *.cpp) parser/parser.cpp 
OBJECTS = $(SOURCES:.cpp=.o) scanner/scanner.o parser/parser.o 

EXECUTABLE = calculator 

all: parser/parser.cpp scanner/scanner.cpp $(EXECUTABLE) 

parser/parser.cpp: 
    cd parser && bison -d -o parser.cpp grammar.ypp && cd .. 

scanner/scanner.cpp: parser/parser.hpp 
    cd scanner && flex -o scanner.cpp lexer.l && cd .. 

$(EXECUTABLE): $(OBJECTS) 
    $(CC) $^ -o "[email protected]" 

%.o: %.cpp 
    $(CC) $(CFLAGS) -c "$<" -o "[email protected]" 

clean: 
    rm -rf $(OBJECTS) $(EXECUTABLE) parser/parser.cpp parser/parser.hpp scanner/scanner.cpp 

回答

2

file.cpp作爲cpp文件建立依賴關係。這將使makefile編譯這兩個文件當u改變file.cpp

CC=g++ 
CFLAGS=-Wall -std=c++11 -ll 
EXECUTABLE=parser 
OBJS=parser.tab.cpp lex.yy.c 

FILES= file.cpp 

all: parser 

parser.tab.cpp : parser.ypp $(FILES) 
    bison -d parser.ypp 

lex.yy.c: parser.l parser.tab.hpp $(FILES) 
    flex parser.l 

parser: $(OBJS) $(FILES) 
    $(CC) $(CFLAGS) $(OBJS) $(FILES) -o $(EXECUTABLE) 

clean: 
    rm -rf *o $(EXECUTABLE) $(OBJS) 
+0

爲什麼你想讓lex.yy.c作爲改變file.cpp的結果被重建? –

2

你的一個問題是,這

a b: c 
    do something 
makefile

說:

  • a依賴在c;建立它,運行do something
  • b取決於c;建造它,運行do something

沒有,你可能希望,ab都建成的do something結果。因爲您同時具有parser.tab.cppparser.tab.hpp作爲顯式依賴關係(分別爲parserlex.yy.c),make將構建它們兩個,並且兩次運行相同的命令(如果嘗試並行構建,這會很有趣)。

如果你可以負擔得起改變你的構建系統,你可能想看看Scons這更直觀一些。

我也傾向於打破你賺了一點,使每個的.o是獨立製作的,所以你有這樣的事情:

file.o: file.cpp 
lex.yy.o: lex.yy.c parser.tab.hpp 

parser: lex.yy.o parser.tab.o file.o 

因爲這意味着它不太可能重建的事情你不不需要,而且更有可能重建你想要的東西 - 如果你改變了.hpp,你並不想重建lex.yy.c。但是你確實想重建.o文件

+0

謝謝你的回答!現在很清楚makefile是如何工作的。我正在'重建'我的makefile,因此每個.o都是獨立構建的。你說得對,爲什麼重建lex.yy.c的每個.cpp文件?不是很需要! – Safaci

+0

隨時upvote任何有用的答案 –