【问题标题】:Compile a shared object (.so) with static glibc使用静态 glibc 编译共享对象 (.so)
【发布时间】:2017-08-03 12:50:18
【问题描述】:

我正在构建一些需要成为共享对象 (.so) 的代码。

我的构建机器上的 libc 可能比已发布的机器更新的问题,所以我想静态链接它以避免兼容性问题。 (我的程序使用 memcpy,它显然是 GLIBC_2.14 的东西,它可以低至 2.5)。

同时使用 -shared 和 -static 编译不起作用,因为 crtbeginT.o 不是使用 -fPIC 编译的。

编辑:可能不是 GCC linking libc static and some other library dynamically, revisited? 的重复,因为那个问题是关于静态链接 libc 的主精灵,这是关于静态链接 libc 的共享对象。

【问题讨论】:

  • 请您发布您的 gcc 选项。
  • 按照你的描述去做是没有意义的,因为你最终会得到任何使用你的库的应用程序同时使用两个不同版本的 glibc——一个通过你的库,一个不同的是它自己的直接 glibc 依赖项。这正是您希望避免的那种问题(我想),所以按照您的建议去做不会有任何收获。
  • 根据经验,通过设置例如具有所需旧发行版/版本的 VirtualBox VM,具有与您的“发布”机器匹配的旧 glibc 并在该 VM 上构建您的版本(您仍然可以在较新的开发发行版上开发/测试),而不是您将尝试与 glibc 兼容性作斗争问题。如果您正在创建一个共享库,其中包含将加载到链接到旧 glibc 的进程中的较新 glibc 片段,则更是如此。只是不要那样做。
  • memcpy 是自第一个版本以来的标准功能。每个 C 库都必须提供它。 C++ 的情况可能有所不同,这是一种不同的语言。
  • 你甚至不需要虚拟机,你可以在 chrooted 环境中完成(不过我自己从来没有设置过,只使用了预配置的,所以不确定会做多少工作) .也应该能够使用 Docker 进行设置。

标签: c++ c gcc glibc static-compilation


【解决方案1】:

您想在共享库中静态链接 glibc。

你不应该这样做。

如果您尝试,最终会违反 C++ 单一定义规则 (ODR)。这是因为 glibc 的某些部分来自目标机器的“旧”版本,而某些部分来自库的“新”版本。结果是未定义的行为。

正确的解决方案很简单:使用较旧的 glibc 构建(与您最旧的部署目标一样旧)。或者构建多次,为您需要的每个版本的 glibc 构建一次(如果您确实需要新的 glibc 功能)。即使您认为需要一个新的 glibc 功能,也可以考虑将该功能以不同的名称复制粘贴到您的库中以避免冲突。

特别是关于 memcpy,请参阅:https://stackoverflow.com/a/8823419/4323 - 手动修复:https://stackoverflow.com/a/5977518/4323

【讨论】:

  • 好吧,那么追逐不可能的事情就没有意义了。我会设置一个虚拟机,谢谢。
  • 静态链接 glibc 也有运行与底层运行时内核的系统调用接口不匹配的 glibc 版本的风险。
猜你喜欢
  • 2011-12-09
  • 1970-01-01
  • 1970-01-01
  • 2023-03-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-04-16
  • 1970-01-01
相关资源
最近更新 更多