如何编写真正的跨平台 C++ 库以进行分发

Posted

技术标签:

【中文标题】如何编写真正的跨平台 C++ 库以进行分发【英文标题】:How to write truly cross-platform C++ libraries for distribution 【发布时间】:2019-01-08 01:51:48 【问题描述】:

问题:

我正在编写一个主要是 C++ 的 SDK。源代码将授权给为其付费的开发人员,输出库和包含头文件将免费供公众使用。该 SDK 将面向众多平台,包括 Windows、Xbox、Playstation、androidios、Mac OS X 和 Linux。我是那种最喜欢 Visual Studio 并且通常使用 Windows 机器开发软件的人。在过去的几年里,Visual Studio 使这比以前容易多了,我有一个非常清晰的路径来定位所有前面提到的平台,使用 Visual Studio 项目文件集作为带来所有我的源代码文件放在一起......不幸的是,Mac OS X 除外。 Visual Studio 能够通过分别与 Mac 或 Linux 机器进行远程接口进行编译和调试来为 iOS 和 Linux 构建可执行代码,这确实很酷,但出于某种原因,此处省略了作为目标的 Mac OS X。此外,我很清楚有很多其他专业开发人员不在 Windows 机器上编写代码,他们也没有兴趣购买 Visual Studio 的商业许可证。

问题: 由于 C++ 仍然没有构建系统标准,而且可能永远都没有,我如何维护一个单一的事实来源来维护针对这么多不同平台的所有源文件的构建配置,同时最大限度地减少支持的进入障碍需要构建、运行和调试我的源代码的软件开发者客户?

我知道的可能答案:

A) Visual Studio 项目仍然是任何其他 C++ 项目类型(如 Android Studio、XCode 和 .make 文件)派生的真实来源。我知道可以将 VS 转换为 .make 等的工具,但实际上还没有尝试过(我的源代码库已经开始变得有点大了)。或者我可以硬着头皮手写它们,并尽量保持它们同步。

B) CMake。叹。令人沮丧的是它非常受欢迎,并且似乎完全解决了我的问题,但它有自己的一系列问题,似乎是交易破坏者。对于初学者来说,一旦你开始使用 CMake,你几乎就再也回不来了。使用 Visual Studio 和属性表,我已经能够调整我的构建配置,这些属性大多是继承的,很少在项目和配置之间重复。据我所知,CMake 并不关心尊重这些东西,对于公共属性,它只是在所有 vcxproj 文件上复制它们。更糟糕的是,它在输出项目中生成的所有文件路径都是绝对的,而不是相对的,而且最重要的是,它会强制构建代码的任何其他人使用 CMake,不允许分发它创建的项目构建文件没有它.另外,这甚至适用于游戏机吗?最后我检查了一下,如果不破解源代码,我找不到支持它们的合理方法。

C) 滚动我自己的脚本,它类似于 CMake,但允许重新分发其输出项目,并支持我需要的所有平台。不用说,这会消耗大量的开发时间。

我在这里缺少任何其他选项吗?非常感谢您的意见。

【问题讨论】:

总有谦虚而强大的MakefileGNU Make 运行在所有东西上。 ***.com/questions/14427547/…的可能重复 当我开始使用 CMake 时(几年前),我也有类似的担忧。之前,我和你做的类似 - 主要在 Notepad++ 中调整了我的 VS 2008 项目文件。迁移到 VS2010 是不可能的——项目被破坏了。 (可能迁移工具很垃圾。)一位同事说服我改用 CMake。现在,项目设置非常简单 - 通过一些帮助程序,CMakeLists.txt 非常简短、清晰且易于维护。从现在开始,我不再关心 VS 项目的内容(有时只是查看它们以检查内容)。而且,实际上,我必须承认我并没有那么想念它。 试试 CMake,真的。 github.com/chronoxor/CppTemplate - 这是我的跨平台 C++ 模板项目,其中包括 C++ 库、示例、单元测试、性能基准,支持 Linux、OSX、Windows、Cygwin、MinGW 编译和 Travis/Appveyor CI 【参考方案1】:

我同意@Scheff 和@arrowd 的cmets。使用 CMake。我已经在多个平台上构建和部署了软件,CMake 是我发现的用于构建 C++ 代码的最佳解决方案,虽然并不完美。

我无需破解 cmake 代码即可使其在各种平台上运行。 不用担心 vcxproj 文件中的属性会重复。使用 CMake,构建语言位于 CMakeLists.txt 文件中。 vcxproj 文件是生成的 代码。只要您没有多余的 cmake 逻辑,您就不必关心 生成的 vcxproj 文件中的复制属性。同样,您不应该关心 生成的 vcxproj 文件是否具有绝对路径;您不重用 vcxproj 文件 您重用 CMakeLists.txt 文件并为每个新平台或构建重新生成 vcxproj 文件。 使用*** CMakeLists.txt 定义所有目标共有的属性。然后在单个目标中,CMakeLists.txt 文件使用目标属性来调整特定目标的构建。以我的经验,在 生成的 文件中复制属性会有所帮助,因为它们使构建更加一致;我能够最大限度地减少源 CMake 逻辑中的复制。 各种 IDE(VS 2017、CLion、QtCreator)可以直接使用基于 cmake 的项目。 没有 cmake 特定于生成的工件。我们 SDK 的标头、库(和 dll)和可执行文件是独立的工件。是的,cmake 可以让您的 SDK 用户更轻松,但在您的 SDK 中使用 CMake 不会强迫您的客户使用 CMake。

您是否尝试过 CMake 却无法使用?还是您在寻找更好的东西?肯定有多个 C++ 构建系统,但尽管有缺点,我相信 CMake 是目前最好的。

【讨论】:

我不喜欢 CMake 只是一条单行道。我不喜欢这样的事实,即如果我的源代码是分布式的,那么其他开发人员将被要求使用它来构建我的代码。如果 CMake 可以生成在没有 CMake 的情况下仍然可以使用的项目,其中使用了相对路径,并在适当的情况下使用了属性表,以至于修改在 CMake 中生成的大型解决方案仍然可行,我会全力以赴,相信我.另外,对游戏机平台的 CMake 有什么想法吗? 另外,为了回答您的其他问题,我之前在两个不同的组织中使用过 CMake。一个只是针对 Windows 和 Linux,代码完全是内部的,不能分发,所以没问题。在另一个组织,我不得不花几天时间从头开始为 Xbox 和 Playstation 平台手动重建 Visual Studio 项目,随后必须与 CMake 文件并行维护,因为 CMake 不知道这些平台。顺便说一句,这是大约 2015 年。它在我的嘴里留下了一点不好的味道。 我明白你的意思。如果您使用 CMake 构建,那么,是的,其他人也将需要使用 CMake。我还没有这样做,但是您应该能够通过用相对路径替换绝对路径来自动将 CMake 生成的 vcxproj 和 sln 文件转换为可重新分发的文件(因为 vcxproj 文件是 xml,这应该不会太难- -著名遗言)。另外,如果你使用的是 VS 2017,你应该可以直接使用 CMake 构建。

以上是关于如何编写真正的跨平台 C++ 库以进行分发的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Windows 上分发 Gtkmm 应用程序?

OTA AdHoc 分发 - 如何从命令行构建 IPA?

如何在 C++ 中编写 shell 扩展?

如何在 C++ 中编写独立于平台的包装函数 [重复]

如何在 C++ 中编写文本编辑器 [关闭]

如何开始使用 Visual C++ 编写 DLL?