【问题标题】:how to have make targets for separate debug and release build directories?如何为单独的调试和发布构建目录创建目标?
【发布时间】:2010-10-07 10:38:06
【问题描述】:

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

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

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

【问题讨论】:

    标签: makefile gnu-make


    【解决方案1】:

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

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

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

    【讨论】:

      【解决方案2】:

      如果您在 Makefile 中对使用 $(COMPILETYPE) 变量在所有规则中引用适当的构建目录(从生成目标文件的规则到 clean/dist/etc 的规则)进行了规范,那么您应该很好。

      在我参与的一个项目中,我们有一个 $(BUILD) 变量,它被设置为(相当于)build-(COMPILETYPE),这使得规则变得更容易一些,因为所有规则都可以引用 $( BUILD),例如 clean 将 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 中取出并放入配置中(您必须添加一些支持,以根据您的 --mode 中的 --mode 的值指定所需的构建标志@)

      如果你给出一些更具体的例子来说明你的实际规则,也许你会得到一些更具体的建议。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-05-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-18
        • 2020-11-20
        • 1970-01-01
        相关资源
        最近更新 更多