【问题标题】:How to set up a C++ toolchain for cross-compilation?如何为交叉编译设置 C++ 工具链?
【发布时间】:2021-08-30 03:51:41
【问题描述】:

我有一个目标系统 Astra Linux Smolensk,它可以访问非常过时的软件包,其中包括 GCC 6。它不支持 C++17,这是一些非常有用的 3rd 方库和语言特性所必需的。在某些时候,我正在考虑使用 20 标准中的概念的可能性。但是没有简单的方法可以实现。
基本上,我看到了两种方式:

  1. 自己编译所需版本的 GCC,并使用自定义版本的 Astra Linux 来构建附加软件包(这不是一个好的选择,因为我们对系统修改有限制)。我即将尝试这个选项,但这不是这个问题的主题。
  2. 使用工具链在 Ubuntu 上与最新的 GCC 交叉编译。

那么,我需要什么才能为自定义版本的 Linux 创建工具链?我唯一确定的是 Linux Core 版本。我可以使用现有的 Linux 工具链,还是必须导出系统库并创建自定义工具链?


Here我发现了一些似乎有用的工具。例如:

构建根
Buildroot 是一个基于 Linux 内核配置系统的完整构建系统,支持广泛的目标架构。它生成准备写入闪存的根文件系统映像。除了拥有大量可以编译到镜像中的包之外,它还生成一个交叉工具链来从源代码构建这些包。即使您不想为根文件系统使用 buildroot,它也是生成工具链的有用工具。 Buildroot 支持 uClibc-ng、glibc 和 musl。

我想知道它是否能满足我的需要,我是否可以将最新的 GCC 编译器与这些生成的工具链一起使用。


我发现了类似的问题:
How to build C++17 application in old linux distro with old stdlib and libc?
https://askubuntu.com/questions/162465/are-gcc-versions-tied-to-kernel-versions
How can I link to a specific glibc version?


需要澄清一下: 该项目严重依赖于来自目标 linux 的包存储库的许多第 3 方依赖项。此外,我使用动态的.so 模块,可以隐式和显式加载。

【问题讨论】:

  • 在目标系统上编译 gcc 会简单得多,因为在这种情况下您只需要设置编译器。交叉编译时,您不仅需要设置编译器,还需要设置所有要链接的依赖项,如 glibc、openssl、libxml 等。
  • @dewaffled 我已经链接了一个问题,其中提到了为较旧的核心和 glibc 版本构建 C++17。我也有类似的情况。我无法在目标系统上使用新版本的 glibc,因为它不可用。
  • 我不明白。您可以下载编译器源并在目标系统上构建它,因此它会选择系统 glibc 和其他依赖项。还有实现 C++ 标准库功能的 libstdc++,您需要将它与应用程序一起分发,并且无论构建方法如何,您都需要。
  • 我认为您参考的是内核版本,根据文档:musl is built on the Linux syscall layer. Linux kernel >=2.6.39 is necessary for POSIX conformant behaviour, older kernels will work with varying degrees of non-conformance, 2.4 kernels will only work for simple single-threaded applications.
  • @prehistoricpenguin 我有4.15.3 内核版本。我想您可以将其发布为答案。

标签: c++ linux cross-compiling toolchain


【解决方案1】:

如今有了 docker 和基于容器的现代 CI/CD 管道,我们不再像过去那样经常依赖流程编译。

借助 musl,我们甚至可以创建具有静态链接的通用 Linux 二进制文件:我们使用所有静态库而不是动态库。然后我们发送一个可执行文件。

根据musl的doc,需要

Linux 内核 >=2.6.39

这是 2011 年左右发布的一个非常旧的版本,因此即使是旧的 Linux 发行版也可以运行我们的二进制文件。

Musl 被广泛用于许多项目,尤其是在 Rust 项目中,我们为用户提供 Musl 构建以方便用户。

请注意,我们在使用 Musl 时可能需要修复我们的代码库,与 GNU libc 有非常细微的差异,我们应该注意这一点。

【讨论】:

  • 如果我链接到一个不是用musl 编译的.so 怎么办?或者我有一个使用其他.so 文件进行动态链接的应用程序?
  • @SergeyKolesnik 将动态与musl 混合似乎很危险或不起作用。有依赖库的源码吗?
  • 不,我依赖目标 linux 软件包存储库中的许多 3rdparty 库。我还使用我自己的独立 .so 库来实现模块化。这不是一个可以改变的主题。
  • @SergeyKolesnik 那么我的回答可能不适合你。但从源头构建3rdparty,静态联动是未来的趋势。我们可以使用多个静态库来实现模块化并将它们链接在一起。
  • 虽然您的答案可能不太适合,但它通常很有用。使用动态库提供了通过动态加载的插件扩展行为的可能性。隐式加载的动态库也有助于模块化更新。
猜你喜欢
  • 2019-08-17
  • 1970-01-01
  • 2021-01-23
  • 2015-05-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-17
  • 1970-01-01
相关资源
最近更新 更多