Jia*_*Cai 1 c++ makefile gnu-make
我不知道为什么Make每次都会重新编译所有文件,包括未更改的文件,这会花费很长时间。我搜索了堆栈溢出并找到了一些解决方案,但仍然无法解决我的问题。
我应该如何更改此makefile,以便它不会编译所有文件,包括未更改的文件?
这是我的make文件:
CXX = g++
CXXFLAGS = -g -Wall -O2 -std=c++11
BIN = bin
SRC = src
OBJ = obj
COMPILER = $(BIN)/compiler
LEX_CPP = $(SRC)/lex.cpp
UTIL_CPP = $(SRC)/util.cpp
TOKEN_CPP = $(SRC)/token.cpp
MAIN_CPP = $(SRC)/main.cpp
TEST_CPP = $(SRC)/test.cpp
PARSER_CPP = $(SRC)/parser.cpp
COMPILER_CPP = $(SRC)/compiler.cpp
COMPILER_OBJS = parser.o compiler.o test.o token.o lex.o util.o main.o
dir_guard=@mkdir -p $(OBJ)
compiler: $(COMPILER_OBJS)
$(CXX) $(CXXFLAGS) -o $(COMPILER) $(OBJ)/lex.o $(OBJ)/compiler.o $(OBJ)/parser.o $(OBJ)/test.o $(OBJ)/token.o $(OBJ)/util.o $(OBJ)/main.o
main.o:
$(dir_guard)
$(CXX) $(CXXFLAGS) -o $(OBJ)/main.o -c $(MAIN_CPP)
lex.o:
$(dir_guard)
$(CXX) $(CXXFLAGS) -o $(OBJ)/lex.o -c $(LEX_CPP)
util.o:
$(dir_guard)
$(CXX) $(CXXFLAGS) -o $(OBJ)/util.o -c $(UTIL_CPP)
token.o:
$(dir_guard)
$(CXX) $(CXXFLAGS) -o $(OBJ)/token.o -c $(TOKEN_CPP)
test.o:
$(dir_guard)
$(CXX) $(CXXFLAGS) -o $(OBJ)/test.o -c $(TEST_CPP)
compiler.o:
$(dir_guard)
$(CXX) $(CXXFLAGS) -o $(OBJ)/compiler.o -c $(COMPILER_CPP)
parser.o:
$(dir_guard)
$(CXX) $(CXXFLAGS) -o $(OBJ)/parser.o -c $(PARSER_CPP)
clean:
rm $(OBJ)/*.o
Run Code Online (Sandbox Code Playgroud)
我想将所有.o文件放入文件obj夹,并将exe文件放入文件bin夹。
我的操作系统是Ubuntu 15.04,使用GNU Make 4.0。
任何帮助表示赞赏,在此先感谢您!
只需非常清楚:djgandy和Norman Gray已正确诊断出各种方式来破坏您的makefile。但是,对于为什么文件不断被重建的特定问题的具体答案是:
token.o:
$(dir_guard)
$(CXX) $(CXXFLAGS) -o $(OBJ)/token.o -c $(TOKEN_CPP)
Run Code Online (Sandbox Code Playgroud)
撇开所有其他问题,在这里告诉make:“如果要构建文件token.o,则可以使用此配方来完成”。但是配方不能建立token.o,它可以建立$(OBJ)/token.o。这是错误的,因为在运行配方后目标(token.o)仍然不存在。因此,下一次您运行make时,它说:“哦,我需要构建token.o... gee,它不存在,所以我想我必须构建它...哦,这是可以构建它的规则... `仍未真正构建它。
您的makefile违反了Makefiles的第二条规则:每个非.PHONY规则都必须使用目标文件的确切名称来更新文件。
您的规则应始终建立,$@因为规则始终具有使目标相信您应该构建的路径。