如何为单独的调试和发布构建目录制作目标?

时间:2009-02-13 12:46:09

标签: makefile gnu-make

我正在寻找正确处理单独调试和发布构建子目录的建议,在递归makefile系统中使用gnumake手册中记录的$(SUBDIRS)目标将make目标应用于(源代码)子目录。

具体来说,我对实现诸如'all','clean','realclean'等目标的可能策略感兴趣,这些目标要么假定其中一棵树,要么应该在两棵树上工作都会导致问题。

我们当前的makefile使用一个COMPILETYPE变量,该变量被设置为Debug(默认)或Release('release'目标),它可以正确地进行构建,但是清理并使所有只能在默认的Debug树上工作。传递COMPILETYPE变量变得笨拙,因为是否以及如何执行此操作取决于实际目标的值。

2 个答案:

答案 0 :(得分:0)

一种选择是在每个构建类型的子目录中具有特定目标。因此,如果您在顶层执行“make all”,它会查看COMPILETYPE并根据需要调用“make all-debug”或“make all-release”。

或者,您可以在顶层设置COMPILETYPE环境变量,并让每个子Makefile处理它。

真正的解决方案是不进行递归make,而是将makefile包含在顶级文件的子目录中。这将使您可以轻松地构建一个与源不同的目录,因此您可以拥有 build_debug build_release 目录。它还允许并行make工作(make -j)。有关完整说明,请参阅Recursive Make Considered Harmful

答案 1 :(得分:0)

如果您在Makefile中遵守使用$(COMPILETYPE)变量来引用所有规则中相应构建目录的规定,从生成目标文件的规则,到clean / dist / etc的规则,您应该是细

在我参与的一个项目中,我们有一个$(BUILD)变量设置为(相当于)build-(COMPILETYPE),这使得规则更容易一些,因为所有规则都可以引用$( BUILD),例如,清洁将rm -rf $(BUILD)。

只要您使用$(MAKE)来调用子制作(并使用GNU make),您就可以自动将COMPILETYPE变量导出到所有子制作,而无需执行任何特殊操作。有关详细信息,请参阅relevant section of the GNU make manual

其他一些选择:

  • 通过在跟踪最后使用的编译器标志集的元文件上添加所有对象的依赖项,强制在编译器标志更改时重新构建。例如,请参阅Git manages object files
  • 的方式
  • 如果您使用的是autoconf / automake,则可以轻松地为不同的构建类型使用单独的构建外部构建目录。例如,cd /scratch/build/$COMPILETYPE && $srcdir/configure --mode=$COMPILETYPE && make将构建类型从Makefile中移出并进入configure(您必须根据--modeconfigure.ac的值添加一些支持以指定所需的构建标记。 {1}})

如果你提供一些更实际的规则的具体例子,也许你会得到一些更具体的建议。