仅在需要时编译文件

时间:2012-10-12 19:54:24

标签: c++ build makefile

我在目录./src中有几个cpp和hpp文件。我在一个二进制文件中编译所有cpp文件,比如./bin/run。我想重新编译,只要我需要它,或者其中一个标题被更改。

我可能会创建Makefile,当且仅当文件被更改时才会重新编译文件,但是由于我的代码的大部分都在标题中,所以它非常不舒服。 (它不会被改变,因为产品是标题本身,cpp文件是测试)。

我想在.o

中存储临时./build个文件

我知道g++ -MM功能,但我不确定如何使用它。

我很高兴看到使用不必要make的解决方案,但如果它们足够容易,可以使用任何其他系统。

UPD 我会试着澄清一下,问题是什么:

可能会创建新的cpp,包括可能添加或删除等。我不想每次都编辑我的makefile。

4 个答案:

答案 0 :(得分:2)

为了解决我提到的问题(-include不是一个好的解决方案),我使用这样的东西:

build/%.o: %.cpp
    @$(CC) -MD -c -Wall -o $@ $<
    @cp build/$*.d build/$*.P
    @sed -e 's/#.*//' -e 's/^[^:]*: *//' -e 's/ *\\$$//' \
         -e '/^$$/ d' -e 's/$$/ :/' < build/$*.P >> build/$*.d
    @rm build/$*.P

-include build/*.d

不需要`%.d规则。

修改

@JackKelly有[ * cough *,* choke * ]向我展示了一种更有效的方法来获得相同的依赖文件:

build/%.o: %.cpp
    @$(CC) -MD -c -Wall -o $@ $<
    @$(CC) -MM -MP -Wall -o $*.d $<

-include build/*.d

你可以为同一个目标设置多个规则,只要其中只有一个有命令;先决条件累积。想法是获得这样的文件:

file.o: file.cpp headerfile.h
headerfile.h:

第二行(headerfile.h:)是headerfile.h的规则,没有先决条件或命令。它什么都不做,但这是一个规则,所以如果缺少headerfile.h,Make就会满意。

答案 1 :(得分:1)

解决方案的概要如下:

  • 为每个源文件使用辅助依赖项文件(即为foo.dep创建foo.c,为bar.dep创建bar.c等等。
  • 使用gcc -MM创建依赖项文件
  • 为了强制make自动执行此操作,请使用foo.c作为foo.depfoo.o的先决条件;这需要在sed
  • 的输出上有一些小的gcc -MM魔法
  • 在主makefile中包含所有依赖项文件;这是使这种方法成为可能的关键步骤。

最后一步写成如下:

-include $(dependency_files)

这很棘手但可能;有关详细信息,请参阅GNU make manual

答案 2 :(得分:1)

你提到g++ -MM,它可以做你想做的事情:

include $(ALLOBJ:%.o=%.d)

%.d: %.cxx
    @echo making dependencies for $<
    @g++ -MM -MP $(CXXFLAGS) $< -o $@
    @sed -i 's,$*\.o,& $@ ,g' $@

基本上,这定义了一个从.d文件创建.cxx个文件的规则。反过来,.d语句需要include个文件,.o中的每个ALLOBJ文件都需要一个{{1}}。

依赖关系规则中的最后一行是'sed magic',它使依赖项文件自行重新生成。如果你认为正则表达式充其量只是邪恶,而且经常是邪恶,你可以use the -MT flag

答案 3 :(得分:0)

您可以使用Make执行此操作,只需在规则的敏感度列表中指定标题即可。例如

myfile.o: myfile.cpp
    gcc -c myfile.o myfile.cpp ${LDFLAGS}    # This is optional. make can infer this line.

变成

myfile.o: myfile.cpp myfile.h
    gcc -c myfile.o myfile.cpp ${LDFLAGS}    # Again, optional.

现在,只要myfile.h发生更改,myfile.cpp就会重建。可以以类似的方式链接更多标题。