各种glibc和Linux内核版本的兼容性

10

在构建编译器时,必须指定Linux头文件版本和最小支持内核版本,以及glibc版本。目标机器上实际的内核版本和glibc版本(带有自己的内核头文件版本和最小支持内核版本)。我很困惑试图理解这些版本是如何配合工作的。

示例1:假设我有一个使用内核头文件 3.14 构建的 glibc 2.13 系统。这有意义吗? glibc 2.13(于2011年发布)如何使用来自 3.14(于2014年发布) 的新内核特性?

示例2:假设我有一个具有比 2.13 新的 glibc 版本的编译器。编译后的程序能在具有 glibc 2.13 的系统上运行吗?如果编译器的 glibc 版本比 2.13 老呢?

示例3:从 https://sourceware.org/glibc/wiki/FAQ#What_version_of_the_Linux_kernel_headers_should_be_used.3F 我了解到,如果使用旧的内核满足编译glibc时使用的“最小内核版本”,那么可以使用旧的内核。但是我不理解这段话: 另一方面(使用旧的内核头文件编译GNU C库并在最近的内核上运行)不一定按预期工作。例如,如果您使用旧的内核头文件来编译 GNU C库,则无法使用新内核特性。 这是唯一可能发生的事情吗?如果内核在编译时比较新,是否会破坏glibc中的某些内容?

示例4:glibc设置中更微妙的差异是否会产生影响(例如,将可执行文件与使用内核头文件3.Y编译的glibc版本2.X链接,并在最小支持内核版本为2.6.A的系统上执行,但在编译时针对使用内核头文件3.Z和最小支持内核版本为2.6.B的同一glibc版本2.X)?我怀疑它们不会产生影响,但想确保。

问题很多 :) 谢谢!


1
与内核版本不兼容的GLIBC库新版本是否能够使用? - Ciro Santilli OurBigBook.com
1个回答

9
  1. 您不能轻易地(无论如何定义这个词)在旧版本的glibc中使用较新的内核功能。如果您确实需要,可以直接调用系统调用(使用syscall()库函数),并从用户空间内核头文件中获取所需的任何常量值和数据结构(在较新的内核中保存在include/uapi下)。另一方面,内核开发人员通常承诺不会在较新的内核中破坏传统功能,因此较旧的glibc版本仍然按预期工作(好吧,几乎是这样)。

  2. 旧程序仍可与较新版本的glibc一起使用,因为glibc支持符号版本控制(有关一些详细信息,请参见此处:https://www.kernel.org/pub/software/libs/glibc/hjl/compat/)。如果您的程序动态链接了较新版本的glibc而没有特殊规定(如上述链接中所述),则无法使用较旧版本的glibc库运行它(动态链接器将抱怨未解决的符号,因为适当的符号版本将不可用)。


我明白了。因此,目标平台上的glibc不应该比我们链接的glibc旧。但是内核呢?哪一个被认为包含“新内核特性”,例如针对内核3.14编译的glibc 2.13?自glibc 2.13发布后发布的内核2.6.38,还是更新的内核3.15,因为它比我们编译的内核更新? - Alexandr Zarubkin
你需要检查你正在使用的特定API。例如,在epoll_ctl中有一个众所周知的不兼容性,其中2.6.9之前的内核以不同的方式处理其参数,并且这一事实反映在手册页中。对于大多数程序来说,没有什么可担心的,因为在过去的10年中,大多数Linux API都相当稳定(除了udev和与图形相关的东西)。 - oakad
谢谢,再澄清一下:使用glibc 2.13我可以使用哪些内核特性?这是否取决于我构建glibc时使用的内核头版本? - Alexandr Zarubkin
它不是那样工作的。回到epoll的例子:man页面说“在2.3.2版本中添加了对glibc的支持”。因此,如果您有一个旧的glibc,这意味着您将无法获得必要的包含文件和库包装器。所有其他非平凡的东西也是如此。 - oakad
谢谢。所以,使用新的内核头文件编译旧的glibc实际上没有意义(但也没有伤害),对吗? - Alexandr Zarubkin
如果版本不匹配太大(例如旧版glibc与最新内核),编译可能会失败,因为某些标头被移动并重新排列,这不会有任何影响。 - oakad

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接