Makefile和具有复杂相互依赖性的大型项目

时间:2016-04-21 08:23:46

标签: build makefile dependencies gnu-make

我正在尝试为具有如下结构的大型项目提供构建系统:

├── deploy
├── docs
├── libs
│   ├── lib1
│   └── lib2
├── scripts
└── tools
    ├── prog1
    └── prog2

我的问题是,libs和程序可能会以可能经常变化的顺序相互依赖。我在互联网上查找了信息,我得到了混合信息。有人说我应该使用makefile,而另一些人则认为递归makefile是邪恶的。

除此之外,我不知道如何使用makefile管理依赖项(如果lib2需要lib1来构建,如何告诉make先构建lib1)。有人告诉我,使用变量VPATH很容易实现,但我已阅读文档,我认为它与此无关。

所以我的问题是:

  • 在这种情况下,我真的应该避免使用makefile吗?如果是这样,有哪些替代方案?
  • 如果我应该使用makefile,我该如何自动有效地管理依赖项呢?

2 个答案:

答案 0 :(得分:3)

我在不要撒谎阵营。 这里, 细粒度的依赖是你的朋友。 远离以为您需要表达 prog1 取决于 lib2 。您真正要对 make 说些什么是:

“要链接 prog1 ,您需要所有.o个文件以及所有相应的.a个文件。”

如果你能表达这个, 它将为您的构建改进许多非常重要的参数:

  1. 并行构建正常运行
    • .o的{​​{1}}文件可以与。{1}}同时编译 prog1
    • 如果您将测试作为构建的一部分运行,则更为重要 (你这样做,不是吗?)
  2. 无所事事的时间非常接近于零
    • 没有什么比发布版本差, 几分钟后你就得到了 build已经是最新的(WinCE,我在看着你)
  3. 工作得到妥善剔除
    • 换句话说,你可以依赖你的依赖, 并且永远不必做 make clean ,因为你不信任他们
  4. 毕竟, 这些目标实际上是使用 make 的重点。 弄错了,你也可以使用批处理文件。 (在递归制作系统BTW中使它们正确非常棘手。)

    当然, 在 make 中干净地表达这一点需要花费一些力气, 但你确实说过你有一个大型项目。

答案 1 :(得分:1)

我不是在递归的makefile中是邪恶的阵营 - 虽然递归的makefile没有那么高效(它们不会最大化并发性等),但它是真的。通常可以忽略不计。另一方面,使用递归makefile可以使您的项目更具可扩展性 - 将模块移入和移出,与其他组共享等更简单。

在你的情况下,如果lib2依赖于lib1,你可以这样做:

 lib2: lib1
    make -C libs/lib2

现在make将在lib2之前构建lib1(即使你指定了-j)。

现在,如果你有交叉依赖(lib1中的某些东西依赖于lib2中的东西,而lib2中的东西又取决于lib1中的其他内容),那么你可能想要考虑重构目录以避免交叉依赖,或者使用一个makefile(如果在这种情况下尝试使用递归makefile,那么会暴露很多尖锐的棒)。