【问题标题】:Building hierarchical Makefile with GNU Make使用 GNU Make 构建分层 Makefile
【发布时间】:2011-04-05 10:44:49
【问题描述】:

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

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.

有解决这个问题的好方法吗?

谢谢。

【问题讨论】:

  • 你想把目标文件放在哪里(例如module.o)?
  • 在相关源文件的同一(子)目录中。

标签: makefile gnu-make


【解决方案1】:

有几种方法可以做到这一点,但没有一个是完美的。基本问题是 Make 擅长使用 there 的东西来制作 here 的东西,但反之则不行。

你还没有说module_B中的目标是什么;我会很悲观,假设module_Amodule_B 都有名为module 的目标(不同的源文件,不同的配方),所以你真的不能使用include

你要做的最大选择是是否使用递归Make:

如果您不知道,那么root/Makefile 必须知道如何构建module_A/modulemodule_B/module,因此您只需将这些规则放入其中。然后您必须将冗余规则留在子目录makefile 中(并且冒着与主 makefile 不一致的风险),或者消除它们,或者让他们递归调用主 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中的依赖信息,既繁琐又不整洁。

这只是你的优先级问题。

【讨论】:

  • 如果你必须使用递归 make,那么好的、彻底的答案,虽然我会说这在一般情况下是个坏主意。
【解决方案2】:

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

Recursive Make Considered Harmful

【讨论】:

  • 我可以,但是我已经用他们的 Makefile 继承了所有这些模块,而且由于我很懒,我想尽可能地重用它们。Makepp 有一个很棒的工具 (load_makefile)加载放置在给定子目录中的 Makefile 中的所有定义,将子目录添加到那里定义的目标。我想知道是否有办法在 Makefile 中做类似的事情,而不是复制粘贴各种 Makefile 中的所有目标并手动添加子目录。
  • @akappa,简短的回答:是的,但它不可靠。一个简短的sed 脚本可以将目录名称添加到目标中,但如果生成文件在任何地方使用相对路径(并且生成文件有很多方法可以做到这一点),脚本将无法纠正他们。
  • @Beta:谢谢,我想我会写一个 Makefile,毕竟它更容易(而且更简洁)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-05-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多