如何为不同的调试和发行版构建目录设置make目标?

问题描述 投票:5回答:3

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

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

我们目前的makefile使用了一个COMPILETYPE变量,这个变量被设置为Debug(默认)或Release("release "目标),它可以正确地进行构建,但是clean up和make all只能在默认的Debug树上工作。传递下来的COMPILETYPE变量变得很笨拙,因为是否和如何这样做取决于实际目标的值。

makefile gnu-make
3个回答
0
投票

一种选择是在子目录中为每种构建类型设置特定的目标。 因此,如果你在顶层做了一个 "make all",它就会查看COMPILETYPE,然后根据情况调用 "make all-debug "或 "make all-release"。

或者,你可以在顶层设置一个 COMPILETYPE 环境变量,然后让每个子 makeefile 处理它。

真正的解决方案是不做递归的make,而是在顶层文件的子目录中包含makefile。 这将让你很容易地在一个与源代码不同的目录中进行构建,所以你可以让 构建_debug构建发布 目录。 它还允许并行的make工作(make -j)。参见 递进式使被认为是有害的 来获得完整的解释。


0
投票

如果你在Makefiles中严格地使用$(COMPILETYPE)变量来引用所有规则中适当的构建目录,从生成对象文件的规则,到cleandistetc的规则,你应该可以做到。

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

只要你使用$(MAKE)来调用子制造(并且使用GNU make),你就可以自动将COMPILETYPE变量导出到所有的子制造,而不需要做任何特殊的操作。更多信息,请参见 GNU make手册的相关章节.

其他一些选项。

  • 当编译器标志发生变化时,通过在元文件上为所有对象添加一个依赖关系,跟踪最后使用的编译器标志集,来强制重新编译。 例如,请看 Git管理对象文件.
  • 如果你使用的是autoconfautomake,你可以很容易的为你的不同构建类型使用一个单独的构建目录,比如, cd /scratch/build/$COMPILETYPE && $srcdir/configure --mode=$COMPILETYPE && make 这将把编译类型从Makefiles中移出,并进入configure (在这里,你必须添加一些支持,以基于 --mode 在你 configure.ac)

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

© www.soinside.com 2019 - 2024. All rights reserved.