使用GNU Make构建分层Makefile

时间:2011-04-05 10:44:50

标签: makefile gnu-make

我有一个分为模块的项目,每个模块都托管在一个目录中,比如说:

root
|_module_A
 |_module.cpp
 |_Makefile
|_module_B
 |_Makefile
|_main.c
|_Makefile

main.c取决于与module_Amodule_B相关的Makefile中定义的目标。

我想针对两个模块的Makefile中定义的目标编写root/Makefile

现在,我知道我可以使用include指令,但问题是module_Amodule_B中的目标和文件名不会在其目录前面添加,所以我得到这样的东西:

make: *** No rule to make target `module.o', needed by `main.c'.  Stop.

有一个好方法可以解决这个问题吗?

感谢。

2 个答案:

答案 0 :(得分:2)

有几种方法可以做到这一点,但没有一种方法是完美的。基本问题是Make善于使用那里来制作 here ,而不是相反。

您还没有说明module_B中的目标是什么;我会感到悲观,并认为module_Amodule_B都有名为module的目标(不同的源文件,不同的食谱),所以你真的不能使用include

您必须做出的最大选择是使用递归Make:

如果您不这样做,那么root/Makefile必须知道如何构建module_A/modulemodule_B/module,因此您只需要将这些规则放入。然后您必须离开subdir makefile中的冗余规则(并冒着与master makefile脱离协议的风险),或者消除它们,或让它们递归调用master makefile(你不必经常这样做,但是肯定会看起来很傻。)

如果你这样做,那么root/Makefile将会是这样的:

main: main.o module_A/module.o Module_B/module.o
    ...

main.o: main.c
    ...

%/module.o:
    $(MAKE) -C $(@D) $(@F)

这将运行良好,但它对子目录中的依赖项一无所知,因此有时无法重建过时的对象。你可以事先make clean(递归地),只是为了安全起见,粗暴但有效。或者强制执行%/module.o规则,这样可以减少浪费但更复杂一点。或者复制root/Makefile中的依赖关系信息,这是乏味且不整洁的。

这只是你的优先事项的问题。

答案 1 :(得分:1)

你不能以非递归的方式编写makefile吗?

Recursive Make Considered Harmful