如何使用旧的 stdlib 和 libc 在旧的 linux 发行版中构建 C++17 应用程序?

How to build C++17 application in old linux distro with old stdlib and libc?

我需要使用具有 libstdc++ 6.0.22 (GLIBCXX 3.4.22) 和 libc 2.24 的发行版构建一个 C++17 应用程序。这些版本的库不允许我构建现代 C++,我也无法更新系统版本。事实上,我需要一个正确的工作应用程序(可能从源代码中携带已编译的 stdlib),我可以将其提供给我的客户,他们将使用它。该发行版的存储库中包含 llvm-9,它提供了一个我可以使用的标准库

我尝试了两件事:

  1. 针对 libc++ 构建应用程序,但这将迫使我也重新编译系统依赖项并将它们与我的包一起分发(但我什至不知道如何去做)
  2. 从源构建 libstdc++ 并将其与我的包一起分发

(1) 方法编译时间太长,我需要知道如何重新编译系统依赖项并分发它们。它不是一个小的 hello world 应用程序,它使用了很多系统 deps
我刚刚尝试的 (2) 方法由于很多错误(未知类型、意外标识符等)而失败。

libstdc++ 是 C++ 编译器(gcc 或 llvm)的一部分。您不仅需要当前的 libstdc++,还需要它附带的编译器。每个编译器的当前版本(支持 C++17 需要)需要当前版本的 libstdc++ 才能编译程序。我没有仔细检查 binutils 依赖项,但较新的编译器可能需要较新版本的 binutils(特别是 ld linker)。新 C++ 标准的高级功能可能需要在系统 linker 中实现新功能。更不用说新的编译器功能(例如,当前版本的 gcc 中的 link 时间优化需要 linker、ldgold,这实际上会在 link 阶段再次调用编译器。

您唯一现实的解决方案是 bootstrap 辅助工具链,从 binutils 开始,最后是当前版本的编译器。您不必更新或替换系统安装的 libstdc++、编译器或 ld。通过 运行 它们各自的配置脚本,可以将整个工具链安装在单独的目录层次结构中,这样它们就不会干扰系统安装的 binutils 和编译器。

就其他系统依赖项而言,您可能只需要重建 C++ 依赖项。作为 C 库的系统依赖项不太可能需要重建。尽管如此,如果你有一些,你将不得不重建它们,就是这样,没有其他捷径。

差不多就这些了。没有其他选择。正如您可以推测的那样,bootstrapping 整个工具链以便以不干扰它的方式将其“旁加载”到具有现有编译器工具链的系统上,这并非易事。即使对于技术娴熟、经验丰富的开发人员或系统管理员来说,这也是一个挑战。但这当然是可行的,几年前我在以前的工作中就这样做过。这样做是可能的,所以我看不出为什么现在不能这样做;这几乎是能够在带有旧编译器工具链(不支持当前 C++ 标准)的发行版上支持现代版本 C++ 的唯一可行方法。