如何检查 libc 版本?

3
这个问题与为什么pclose会提前返回有关。我想找出交叉编译可执行文件所使用的libc版本。下面介绍的限制使得检查特定gcc编译器的glibc版本的答案不适用。
  • 一个提议的方法是使用在gnu/libc-version.h中声明的gnu_get_libc_version()函数来检查libc版本。我的交叉工具链没有包含libc-version.h

  • 另一个解决方案是使用-print-file-namegcc选项。链接问题中的答案对我根本没有用:

$ /path/to/toolchains/ARM-cortex-m3-4.4/bin/arm-uclinuxeabi-gcc -print-file-name=libc.so
libc.so
$
$ /path/to/toolchains/ARM-cortex-m3-4.4/bin/arm-uclinuxeabi-gcc -print-file-name=foo.bar
foo.bar
$ # I really do not have a foo.bar file in existence

另一个提出的解决方案是只执行ldd --version。我的目标平台没有ldd
$ ldd
sh: can't execute 'ldd': No such file or directory

另一个提议的解决方案是查看__GLIBC____GLIBC_MINOR__ -- 但这些似乎也来自于libc-version.h,而在我的交叉工具链中并不存在,正如上面所述。
我的交叉工具链似乎只提供libc.a,而不是libc.so
我尝试通过/path/to/toolchains/ARM-cortex-m3-4.4/bin/arm-uclinuxeabi-nmstringslibc.a进行搜索(忽略大小写)以查找“version”和“libc”,但没有发现任何看起来像是标识版本的内容。
我最后尝试的方法是strings /path/to/toolchains/ARM-cortex-m3-4.4/bin/arm-uclinuxeabi-gcc | grep GLIBC,它给了我:
GLIBC_2.3
GLIBC_2.2
GLIBC_2.1
GLIBC_2.0
EGLIBC configuration specifier, serves multilib purposes.

但是那个解决方案并没有得到高票支持,它还有一条评论表明它并不能真正给你版本号。我不太理解这个答案或者它的回应评论,所以我不知道它的有效性。

问题:考虑到所有上述情况,是否有确定交叉编译使用的libc版本的明确方法?


strings这个东西很可能只是告诉你编译器可执行文件本身与(主机)glibc进行了链接。这并不能告诉你它所生成的可执行文件的作用。 - Nate Eldredge
2
听起来你的目标平台可能根本不使用glibc,而是使用一些完全无关的C库,所以glibc的东西可能没有任何用处。每个C库的实现都可以自行决定如何报告其版本号(如果有的话);据我所知,没有标准的接口。因此,你需要找出你安装的C库是什么,并阅读它的文档。 - Nate Eldredge
1
哇,感谢你为研究这个问题所付出的努力。对另一个问题的评论表明你可能正在处理uclibc。你可以尝试一下这个答案,看看它是否给出了正确的版本? - Nick ODell
@KamilCuk - 我找到了各种版权参考,所以很难说哪一个是“正确”的。一个例子是/path/to/toolchains/ARM-cortex-m3-4.4/sysroot/include/stdlib.h,上面写着版权为“1991-2007, 2009”。听起来这种方法 - 即浏览头文件 - 在这种情况下是最好的途径,谢谢你。 - StoneThrow
@NateEldredge - 我需要与负责这个工具链的工程师核实一下;我认为你是对的 - 他们应该有记录,说明构成这个工具链的软件和版本。 - StoneThrow
显示剩余12条评论
1个回答

4
你可能正在处理除glibc之外的libc变体。 libc有多个不同的实现,例如musl或uclibc。
这是一个Bash脚本,可以检测您的编译器是否使用glibc或uclibc,并在检测到任何一个时告诉您版本。
GCC_FEATURES=$(gcc -dM -E - <<< "#include <features.h>")

if grep -q __UCLIBC__ <<< "${GCC_FEATURES}"; then
    echo "uClibc"
    grep "#define __UCLIBC_MAJOR__" <<< "${GCC_FEATURES}"
    grep "#define __UCLIBC_MINOR__" <<< "${GCC_FEATURES}"
    grep "#define __UCLIBC_SUBLEVEL__" <<< "${GCC_FEATURES}"
elif grep -q __GLIBC__ <<< "${GCC_FEATURES}"; then
    echo "glibc"
    grep "#define __GLIBC__" <<< "${GCC_FEATURES}"
    grep "#define __GLIBC_MINOR__" <<< "${GCC_FEATURES}"
else
    echo "something else"
fi

(Source.)

如果您正在使用musl,不幸的是,此脚本将报告“something else”。无法使用预处理器宏检测musl,这是故意的


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