【问题标题】:How to define rules in the Makefile to compile only that *.cpp files which was modified (and their dependencies), not all *.cpp files如何在 Makefile 中定义规则以仅编译已修改的 *.cpp 文件(及其依赖项),而不是所有 *.cpp 文件
【发布时间】:2011-03-06 11:20:49
【问题描述】:

假设我有文件:

库:

  • one.cpp, one.h
  • 两个.cpp,两个.h
  • 三个.cpp,三个.h

程序:

  • program.cpp

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

目前我有类似的东西:

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 的已修改代码,则应重新编译这两个文件)。

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

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

但是如果 one.cpp 使用了 two.cpp 中的修改过的代码,那就做吧:

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

【问题讨论】:

  • (我想你的意思是one.cpp,而不是first.cpp。)

标签: makefile gnu-make


【解决方案1】:

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

例子:

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

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

【讨论】:

  • 这不就是$(OBJS)的用途吗?
  • 你告诉我,这是你的代码。我从来没有在依赖字段中使用过变量,但逻辑上没有什么可以阻止它的工作。
  • 变量可以是先决条件,但是除了$(OBJS)之外,OP的makefile中还有其他一些东西应该是先决条件。
【解决方案2】:

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

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

【讨论】:

  • 这并不能解决依赖头文件或目标文件的问题。
  • ^^^ 这对我不起作用。您的解决方案没有针对 %.h 目标的规则。不知道为什么这被接受了。
【解决方案3】:

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

all: program

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

然后我们将头文件制作成对象的先决条件,这样如果我们改变three.h,Make就会重建three.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),但这对于今天来说已经足够了。

【讨论】:

    猜你喜欢
    • 2012-04-04
    • 2012-10-18
    • 2015-01-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多