gpt4 book ai didi

c++ - 如何处理具有完全不同构建系统的第三方库?

转载 作者:IT老高 更新时间:2023-10-28 21:36:50 27 4
gpt4 key购买 nike

C++(和 C,尽管在那儿不太重要)标准规定程序中的所有翻译单元都需要具有相同的定义;这包括编译器开关之类的东西。例如,在 MSVC++ 上,必须链接到正确版本的 C 运行时库(/MT vs /MD vs /MTd vs /MDd) 在所有翻译单元中。

但是,我们想使用几个第三方依赖项,其中有几件事:

  • 他们都使用不同的构建系统(有一个 autoconf,有一个 cmake,还有一个似乎有它自己的手工制作的东西..)
  • 构建系统并非都在其配置中公开这些类型的开关,而且硬编码的开关在不同系统中的设置也不同。 (例如,一个库强制 /MD/MDd,而另一个库强制 /MT/MTd)<

我们不确定处理这类事情的最佳方法是什么。我们讨论了以下选项:

  • 围绕任何第三方依赖项构建我们自己的构建系统。
    • 专业人士:我们知道一切都会匹配
    • 专业人士:我们知道我们可以以正确的方式提供跨平台支持
    • 缺点:我们不知道每个第三方构建系统的具体工作原理
    • CON:工作量很大
    • CON:如果第三方依赖发生变化则中断
  • 尝试使用第三方构建系统,并尝试修改它们来满足我们的需要。
    • 专业人士:似乎工作量更少
    • CON:我们可能会破坏第三方系统
    • CON:如果第三方依赖发生变化则中断
    • CON:迫使我们自己的构建变得非常复杂

我们不知道该怎么做;我们无法相信只有我们一个人遇到这些问题。我们应该选择上述选项之一,还是我没有想到的第三种选择?

最佳答案

严格来说,您并不需要所有库都链接到同一个运行时。假设它们是 DLL,那么只有当它们通过 DLL 边界传递 CRT 数据结构时才会出现问题。使用一个运行时在 DLL 中创建 FILE* 并从链接到另一个运行时的 DLL 中使用它会导致灾难。使用一个运行时从 DLL 调用 mallocnew,从另一个运行时调用 free/delete 会带来很多乐趣问题。

但只要所有与 CRT 相关的内容都保存在 DLL 内部,您就可以安全地链接到使用另一个 CRT 的 DLL。这也意味着您的调试版本可以使用与发布 CRT 链接的库。同样,只要您不尝试跨库混合 CRT 数据结构。

还要注意,大多数编译器标志不会影响 ABI,因此它们可以安全地在库(或文件)之间有所不同。改变 ABI 的通常是显而易见的,例如强制打包或堆栈对齐。

所以我们所做的基本上是这样的:

  • 我们尽可能自行构建库。在大多数情况下,这意味着我们可以通过相当简单的方式控制它应该链接到哪个运行时。这可能需要对构建系统进行少量调整,但通常只需指定是构建调试版本还是发布版本,大多数构建系统都有选择。 (如果库使用 Visual Studio 作为其构建系统,我们会尽可能将其升级到 2010)
  • 我们使用图书馆自己的构建系统。其他任何事情都只是痛苦的秘诀。您希望能够相信构建系统实际上与库源代码保持同步,而确保这一点的最简单方法是使用源代码附带的构建系统。
  • 如果构建库不可行,我们就按原样使用它,然后我们只需分发它所链接的任何运行时。我们会尽量避免这种情况,但在没有其他选择的情况下这样做是足够安全的。
  • 当我们构建一个库时,我们准确地在我们的内部 wiki 上记录它是如何完成的。如果我们必须升级到更新版本的库或重建它,这将是一个巨大的帮助。

我们目前依赖于三种不同的 VS 运行时(2005、2008 和 2010),处理起来很麻烦,但它工作。对于其中一两个,我们总是使用发布版本,即使在我们自己的代码的调试版本中也是如此。

维护起来有点麻烦,但它工作。而且我真的找不到更好的方法。

当然,你应该尽量减少你有多少第三方依赖,当你选择第三方库时,它的构建系统绝对应该是一个考虑因素。有些人比其他人更痛苦

但最终,您可能最终不得不使用一些没有良好构建系统的库,或者构建起来非常痛苦以至于不值得努力,或者在哪里您无法创建库的调试版本。然后拿走你能得到的。让它使用它喜欢使用的任何运行时。

关于c++ - 如何处理具有完全不同构建系统的第三方库?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10854544/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com