每次都会编译所有文件,包括未更改的文件 [英] Make compiles all the files every time including the unchanged files

查看:153
本文介绍了每次都会编译所有文件,包括未更改的文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我不知道为什么Make每次都会重新编译所有文件,包括未更改的文件,这会花费很长时间.我搜索了堆栈溢出并找到了一些解决方案,但仍然无法解决我的问题.

I don't know why the Make recompiles all the files every time including the unchanged files, it takes a long time. I searched the Stack Overflow and found some solutions, but I still couldn't resolve my problem.

我应该如何更改此Makefile,以使其不会编译包括未更改文件在内的所有文件?

这是我的制作文件:

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

我想将所有.o文件放入obj文件夹,并将exe文件放入bin文件夹.

I want to put all the .o files to the obj folder, and put the exe file to the bin folder.

我的操作系统是Ubuntu 15.04,并使用GNU Make 4.0.

My OS is Ubuntu 15.04 and using GNU Make 4.0.

感谢您的帮助,在此先感谢您!

Any help is appreciated, thank you in advance!

推荐答案

您正在该Makefile中重复很多次–这就是make应该避免的事情.

You're repeating yourself a lot in that Makefile – that's what make is supposed to avoid.

请考虑以下内容

MODULES=parser compiler test token lex util main
COMPILER_OBJS=$(MODULES:%=$(OBJ)/%.o)

$(OBJ)/%.o: %.c
    @test -d $(OBJ) || mkdir $(OBJ)
    $(CXX) $(CXXFLAGS) -c -o $@ $<

compiler: $(COMPILER_OBJS)
    $(CXX) $(CXXFLAGS) -o $(COMPILER) $(COMPILER_OBJS)

也就是说,您正在使用模式规则"来告诉Make如何从.c文件制作目标文件,并且稍微不规范但合理地将其放置在另一个目录中.

That is, you're using a ‘pattern rule’ to tell Make how to make an object file from a .c file and, slightly non-standardly but reasonably, having that file placed in another directory.

使用基于模式的变量引用来设置COMPILER_OBJS意味着您只需要在一个地方指定模块列表即可.

Using the pattern-based variable reference to set COMPILER_OBJS means that you only have to specify the list of modules in one place.

最终结果应该是(我尚未测试过)make compiler(或者实际上只是make,只要compiler仍然是文件中的第一个目标)将构建compiler二进制文件,重建当时已过期的任何.o文件.

The end result should be (I haven't tested this) that make compiler (or indeed just make, as long as compiler remains the first target in the file) will build the compiler binary, rebuilding whichever .o files are out of date at that point.

经常会出现使Makefile过于复杂的趋势,但是使用模式规则和基于模式的变量引用是有用的核心功能,因此应确保您了解这些行的工作方式(尽管请注意,这两个功能都是特定的到GNU Make).

There's a constant tendency to make Makefiles over-complicated, but using pattern rules and pattern-based variable references are useful core functionality, so you should make sure you understand how those lines work (though note that both of these features are specific to GNU Make).

这篇关于每次都会编译所有文件,包括未更改的文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆