如何在Makefile中定义规则,只编译被修改的* .cpp文件(及其依赖项),而不是所有* .cpp文件

时间:2010-06-21 18:42:05

标签: makefile gnu-make

假设我有文件:

利布斯:

  • one.cpp,one.h
  • two.cpp,two.h
  • three.cpp,three.h

程序:

  • program.cpp

有没有办法,创建Makefile,它只会编译从上次编译中修改过的* .cpp?

目前我有类似的东西:

SRCS = one.cpp two.cpp three.cpp
OBJS = $(SRCS:.cpp=.o)

all: $(OBJS) program

.cpp.o:
    g++ -Wall -c $<

program:
    g++ -Wall $(OBJS) program.cpp -o program

clean:
    rm -f $(OBJS) program

我工作正常,但是当我编译我的程序然后更改two.cpp或two.h时我需要先运行“make clean”,因为当我第二次运行“make”时,我得到:

Nothing to be done for 'all'.

我想以这种方式更改我的Makefile,它会识别我的更改并重新编译该文件及其依赖项(如果one.cpp使用来自two.cpp的代码,该代码已被修改,两个文件都应该重新编译)。

所以如果我修改了two.cpp,make应该这样做:

g++ -Wall -c two.cpp
g++ -Wall $(OBJS) program.cpp -o program

但是如果one.cpp使用了被修改的two.cpp中的代码,请执行shold:

g++ -Wall -c one.cpp
g++ -Wall -c two.cpp
g++ -Wall $(OBJS) program.cpp -o program

3 个答案:

答案 0 :(得分:12)

首先,我们制作可执行文件的目标文件先决条件。完成此操作后,只要其中一个SRCS发生更改,Make就会重建program,因此我们不需要OBJS作为明确的目标:

all: program

program: $(OBJS)
  g++ -Wall $(OBJS) program.cpp -o program

然后我们将头文件作为对象的先决条件,这样如果我们改变three.h,Make将重建三个.o:

$(OBJS): %.o : %.h

最后因为one.cpp通过two.h使用来自two.cpp的代码(我希望),所以我们将two.h作为one.o的先决条件:

one.o: two.h

为了使事情更清洁,更容易维护,我们使用自动变量:

program: $(OBJS)
  g++ -Wall $^ program.cpp -o $@

全部放在一起,我们得到:

SRCS = one.cpp two.cpp three.cpp
OBJS = $(SRCS:.cpp=.o)

all: program

$(OBJS): %.o : %.h

one.o: two.h

.cpp.o:
  g++ -Wall -c $<

program: $(OBJS)
  g++ -Wall $^ program.cpp -o $@

clean:
  rm -f $(OBJS) program

还有一些我们可以做的事情(比如将program.o添加到OBJS),但今天就足够了。

答案 1 :(得分:1)

添加命令所依赖的文件以运行到目标名称的右侧。

示例:

default: hello.c
   gcc -o hello.bin hello.c

install: hello.bin
   cp hello.bin ../

答案 2 :(得分:0)

您需要做的就是告诉make .o文件取决于.cpp文件:

%.cpp.o: %.cpp
    g++ -Wall -c -o $@ $<