C++ 构建系统 - 使用什么?

2021-12-28 00:00:00 build c++

我正在考虑用 C++ 开始一个新项目――最初只是在我自己的时间――我正在研究可用的构建系统.答案似乎是很多,而且都很糟糕".

I'm looking at starting a new project in C++ - just in my own time initially - and I'm investigating the build systems that are available. It would appear that the answer is "Many, and they're all awful".

我特别需要的功能是:

  1. C++11 支持
  2. 跨平台(Linux 作为主要目标,但至少也可以在 Windows 上构建)
  3. 体面的单元测试支持
  4. 支持多个模块分离代码
  5. 支持代码生成(使用 asn1c 或 protobuf - 还不是 100% 确定)
  6. 易于维护

现在,我知道我可以很容易地使用 CMake 和 Autotools 完成其中的 1-4 个.可能还有 SCons 和 Waf 以及其他几个人.问题是我从来没有想过如何使用它们正确地生成代码 - 即在首次运行构建过程之前不存在的源文件,因此构建系统必须能够将源文件转换为可执行代码但在构建开始之前实际上并不知道......(特别是 ASN1C 会生成几十个必须能够协同工作的头文件和源文件,实际生成的文件集取决于您的 asn 文件的内容)还有一个事实是,这些都不是特别容易维护 - CMake 和 Autotools 有自己的大量脚本,你需要管理它们才能工作,Waf 和 Scons 要求任何与它们一起工作的人都对 Python 有一定的了解(我不要)与他们一起工作......

Now, I know I can do 1-4 of those using CMake and Autotools easily enough. Probably also with SCons and Waf and the couple of others too. The problem is that I've never worked out how to correctly do code generation using them - that is source files that do not exist until the build process is first run, so source files that the build system must be able to convert into executable code but doesn't actually know about until the build starts... (ASN1C in particular generates dozens of header and source files that must be able to work together, and the actual set of files generates depends on the contents of your asn file) There's also the fact that none of these are especially easy to maintain - CMake and Autotools have their own huge set of scripts that you need to manage for them to work, and Waf and Scons require that anybody working with them has decent knowledge of python (I don't) to work with them...

那么 - 对于这样的事情,推荐什么构建系统?或者我现在会被 make 文件和 shell 脚本困住吗?

So - what build systems are recommended for something like this? Or will I be stuck with make files and shell scripts for now?

推荐答案

+1 表示很多,而且很糟糕."

+1 for, "Many, and they're awful."

但是,最丰富的"和最可扩展的"可能是 CMake,它是一个 Makefile-生成器(也生成本机 MSVC++ *.proj/*.sln).奇怪的语法,但是一旦你学会了它,它可以让你很好地为不同的平台生成构建.如果我重新开始",我可能会使用 CMake.它应该处理您的列表,尽管您的代码生成"可能会在构建系统之外进行自己的生活",具体取决于您想要做什么.(见下文.)

But, the "richest" and "most-scalable" is probably CMake, which is a Makefile-generator (also generates native MSVC++ *.proj/*.sln). Weird syntax, but once you learn it, it can allow you to nicely generate builds for different platforms. If I "started-fresh", I'd probably use CMake. It should handle your list, although your "code-generation" could take on "a-life-of-its-own" beyond the build system depending on what you want to do. (See below.)

对于简单的项目,QMake 生成器是可以的(你不需要使用使用 QMake 的 Qt 库).但是,您不是在描述简单"――代码生成和额外阶段"意味着您可能需要 CMake 或具有丰富 API 的东西,例如 Scons(或Waf).

For simple projects, the QMake generator is ok (you don't need to use the Qt libraries to use QMake). But, you're not describing "simple" -- code generation and "extra-phases" means you probably want CMake or something with a rich API for your own extensions, like Scons (or Waf).

我们在工作中使用 Scons.它产生防弹构建",但它真的很慢.没有其他系统能像 Scons 那样防弹.但是,它很慢.它是用 Python 编写的,我们扩展了工作区组织"的接口(我们仅指定模块依赖项),这是 Scons 设计意图的一部分(这种类型的扩展通过Python).方便,但构建速度慢.您获得了防弹构建(任何开发人员盒子都可以发布最终版本),但速度很慢.而且,速度很慢.不要忘记,如果你使用 Scons,它会很慢.而且,它很慢.

We use Scons at work. It produces "bullet-proof-builds", but it's really slow. No other system will be as bullet-proof as Scons. But, it's slow. It is written in Python and we've extended the interface for our "workspace-organization" (where we merely specify module dependencies), and that is part of the Scons design intent (this type of extension through Python). Convenient, but builds are slow. You get bullet-proof builds (any developer box can make the final release), but it's slow. And, it's slow. Don't forget that if you use Scons, though, that it's slow. And, it's slow.

想到 2000 年后的十年,我们仍然没有飞行汽车,这让我感到不适.我们可能还得再等一百年或什么的才能得到它们.而且,我们可能都将乘坐我们的飞行汽车飞来飞去,这些汽车仍然使用蹩脚的构建系统.

It makes me ill to think that a decade after the Year 2000, we still don't have flying cars. We'll probably have to wait another hundred years or something to get them. And, we will then all probably be flying around in our flying cars that are still being constructed with crappy build systems.

是的,他们都很糟糕.

[关于代码生成]

Scons 作用于阶段",它们有点静态".它可以构建作为构建的一部分生成的代码(人们以几种不同的方式执行此操作),但这被描述为非常不像 Scons 的东西".

Scons works on "phases", and they are "somewhat-static". It can build code that is generated as part of the build (people are doing this in a couple of different ways), but this has been described as, "something very un-Scons-like".

如果是简单的预处理一些文件并生成源文件",那么没什么大不了的(你有很多选择,这就是编写 qmake 的原因――为了 moc *.hpp/*.cpp 文件的预处理).

If it's simple "preprocess some files and generate source files", then no biggie (you have lots of options, and this is why qmake was written -- for the moc preprocessing of *.hpp/*.cpp files).

但是,如果您以繁重的方式"执行此操作,则需要编写自己的脚本.例如,我们有 as-a-part-of-the-build 脚本,用于查询数据库并生成 C++ 类以在层"之间进行接口(在传统的 3 层应用程序开发中).同样,我们通过 IDL 生成服务器/客户端源代码,并嵌入版本信息以允许多个客户端/服务器同时运行不同版本(对于相同的客户端"或服务器").大量生成的源代码.我们可以假装"那是构建系统",但实际上,它是配置管理"的重要基础设施,其中一部分是构建系统".例如,该系统必须将拆除"和启动"服务器作为该过程的一部分.类似地,回归测试是作为这个过程的一部分执行的,版本之间有大量的报告"和差异测试"――所有这些都是我们构建脚本"的一部分.

However, if you are doing this in a "heavy-manner", you're going to need to script your own. For example, we had as-a-part-of-the-build scripts that queried the databases and generated C++ classes to interface between the "layers" (in traditional 3-tier application development). Similarly, we generated server/client source code through IDLs, and embedded version information to permit multiple clients/servers to run simultaneously with different versions (for the same "client" or "server"). Lots of generated source code. We could "pretend" that is "the-build-system", but really, it's a non-trivial-infrastructure for "configuration management", of which part of it is the "build-system". For example, this system had to, "take-down" and "start-up" servers as a part of this process. Similarly, the regression-tests were executed as a part of this process, with heavy "reporting" and "difference-testing" between versions -- all as a part of our "build-scripts".

相关文章