C++ 编译系统

最近尝试了几款 C++ 编译系统。

  • CMake 对于一个编译系统来说,个人觉得过于复杂了。项目依赖不好解决,可能我姿势不对,用不好 ExternalProject 。

  • CPM 基于 CMake ,对项目结构以及名字空间有额外要求。我写我的代码,导出我的接口,你还想管我怎么写?

  • biicode 自动生成了很多隐式配置,用的时候很大可能要修改这些配置,作者脑洞有点大。不推荐。

  • meson 很轻量的一个编译系统,配置语言很好用。依赖可以在系统软件包和源码之间切换。对现有项目提供的 patch 支持很不错,不需要对上游做破坏性更新。文档还是比较少的,有些东西估计得读下代码才知道怎么用。值得一试。

  • bazel Google 出品,离 1.0 还很远,不过已经可以用了。很合适 Google 那种集中式的代码库,根目录一个 WORKSPACE ,其他的项目都只是一个 BUILD ,项目间的依赖也很好指定。和系统软件包的配合不好,连 make install 都没有。patch 支持,一个 BUILD 文件就可以搞定,复杂的话,可能比较麻烦。文档很不错。推荐。

这几款编译系统都没能解决一个问题:编译时第三方依赖的源码和软件包之间的一致性。举例来说:

如果 packageA 的头文件 header.hpp 通过 make install 或其他的包管理工具安装在 packageA/header.hpp ,那么 packageB 一定可以通过 #include <packageA/header.hpp> 引用到这个文件,不论 packageB 依赖的是 packageA 的源码还是系统软件包。header.hpp 可以在 packageA 的任意位置,甚至可能是编译时生成的头文件。

要做到这一点,我的想法是:在编译 packageB 时,如果依赖的是 packageA 的源码,则先编译 packageA,将其安装在私有的目录,之后通过修改编译参数指定头文件包含目录和链接目录。如果依赖的是 packageA 的软件包,则直接用系统的头文件包含目录和链接目录。这样的话,就可以通过配置语言 packageA 的源码和软件包之间切换。

meson 可以在依赖的源码和软件包之间切换,但是需要根据源码结构和包结构之间的差异做特别的定制。bazel 就是一集中化的代码仓库,包含路径只能相对根目录和当前目录。

也许得自己撸一个?Damnit!