我正在寻找一些建议,以便在一个递归的makefile系统中正确地处理单独的调试和发布构建子目录,该系统使用gnumake手册中记载的$(SUBDIRS)目标来应用make目标到(源代码)子目录。
具体来说,我对实现'all'、'clean'、'realclean'等目标的可能策略很感兴趣,这些目标要么假设其中一棵树,要么应该在两棵树上都工作,都会造成问题。
我们目前的makefile使用了一个COMPILETYPE变量,这个变量被设置为Debug(默认)或Release("release "目标),它可以正确地进行构建,但是clean up和make all只能在默认的Debug树上工作。传递下来的COMPILETYPE变量变得很笨拙,因为是否和如何这样做取决于实际目标的值。
一种选择是在子目录中为每种构建类型设置特定的目标。 因此,如果你在顶层做了一个 "make all",它就会查看COMPILETYPE,然后根据情况调用 "make all-debug "或 "make all-release"。
或者,你可以在顶层设置一个 COMPILETYPE 环境变量,然后让每个子 makeefile 处理它。
真正的解决方案是不做递归的make,而是在顶层文件的子目录中包含makefile。 这将让你很容易地在一个与源代码不同的目录中进行构建,所以你可以让 构建_debug 和 构建发布 目录。 它还允许并行的make工作(make -j)。参见 递进式使被认为是有害的 来获得完整的解释。
如果你在Makefiles中严格地使用$(COMPILETYPE)变量来引用所有规则中适当的构建目录,从生成对象文件的规则,到cleandistetc的规则,你应该可以做到。
在我参与的一个项目中,我们有一个$(BUILD)变量,它被设置为(相当于)build-(COMPILETYPE),这使得规则变得更容易,因为所有的规则都可以引用$(BUILD),例如,clean将rm -rf $(BUILD)。
只要你使用$(MAKE)来调用子制造(并且使用GNU make),你就可以自动将COMPILETYPE变量导出到所有的子制造,而不需要做任何特殊的操作。更多信息,请参见 GNU make手册的相关章节.
其他一些选项。
cd /scratch/build/$COMPILETYPE && $srcdir/configure --mode=$COMPILETYPE && make
这将把编译类型从Makefiles中移出,并进入configure (在这里,你必须添加一些支持,以基于 --mode
在你 configure.ac
)如果你再举一些具体的例子来说明你的实际规则,也许你会得到一些更具体的建议。