前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >如何知道程序需要什么版本的libc/libstdc++

如何知道程序需要什么版本的libc/libstdc++

作者头像
mingjie
发布2023-10-13 10:28:09
1.5K0
发布2023-10-13 10:28:09
举报
文章被收录于专栏:Postgresql源码分析

总结

  • 一套系统折腾多套gcc、libc、libstdc++没必要,浪费时间。用对应版本的系统编译对应版本的二进制即可。一般软件对libc、libstdc++的要求都不会太高,系统别太老一般都能跑。
  • 如果系统太老,自带的libc太旧,新软件可能会编译失败(比如用了新的libc的函数),这种情况下如果是因为libc太久,可以直接升级系统,实在可下载libc给程序特供。
  • 如果因为libstdc++太旧(比如用了新的c++库函数),因为libstdc++是跟着gcc的,系统的gcc也比较旧了,可以更新gcc的版本,编译时需要执行用新的gcc,但很可能编译时还回去去找老的gcc和老的stdlibc++库,这就需要看程序的怎么编译的了,改下编译器、引用库路径等。

C++的版本管理简单粗暴,像libc这种基础库如果需要多版本,用起来非常不方便,但c/c++基础库都是向下兼容的,最好的方式就是用一套比较新的系统,带着新的libc,再安装一套和系统版本同年代的新一点的gcc编译器即可,可满足大部分的使用场景,避免一套环境上折腾多套libc、libstdc++,经验之谈:非常麻烦性价比很低!

libc.so

系统一定会自带libc.so,因为这是C的基础库,内核和所有程序都会依赖系统自带libc.so。

随便一个程序看下依赖库,都能看到Libc的影子:

代码语言:javascript
复制
# ldd /usr/bin/echo
	...
	...
	libc.so.6 => /lib64/libc.so.6 (0x00007fa004df6000)
	libdl.so.2 => /lib64/libdl.so.2 (0x00007fa004bf2000)
	/lib64/ld-linux-x86-64.so.2 (0x00007fa0053c5000)

注意:程序用的时候都会用/lib64/libc.so.6的名字,而libc.so.6会指向哭啼某个版本的libc。

查看所依赖的libc版本,可以看出当前Libc的版本是2.28。而Libc是向下兼容的,从库中定义的一些字符串常量可以知道兼容哪些版本:

  • 当前是2.28
  • 向下兼容到2.3
代码语言:javascript
复制
$ ll /lib64/libc.so.6
lrwxrwxrwx 1 root root 12 Nov 24  2022 /lib64/libc.so.6 -> libc-2.28.so

$ strings /lib64/libc.so.6 | grep -E '^GLIBC' | sort
GLIBC_2.10
GLIBC_2.11
GLIBC_2.11
GLIBC_2.12
GLIBC_2.13
GLIBC_2.13
GLIBC_2.14
GLIBC_2.15
GLIBC_2.16
GLIBC_2.16
GLIBC_2.17
GLIBC_2.18
GLIBC_2.18
GLIBC_2.22
GLIBC_2.23
GLIBC_2.23
GLIBC_2.24
GLIBC_2.2.5
GLIBC_2.25
GLIBC_2.25
GLIBC_2.2.6
GLIBC_2.2.6
GLIBC_2.26
GLIBC_2.26
GLIBC_2.27
GLIBC_2.28
GLIBC_2.28
GLIBC_2.3
GLIBC_2.3.2
GLIBC_2.3.3
GLIBC_2.3.4
GLIBC_2.4
GLIBC_2.5
GLIBC_2.5
GLIBC_2.6
GLIBC_2.6
GLIBC_2.7
GLIBC_2.7
GLIBC_2.8
GLIBC_2.8
GLIBC_2.9
GLIBC_2.9
GLIBC_PRIVATE

/lib64/目录是短连接,实际位置:

代码语言:javascript
复制
$ ll /lib64
lrwxrwxrwx 1 root root 9 Dec 21  2021 /lib64 -> usr/lib64

$ ll /usr/lib64/ | grep libc.so
-rw-r--r--  1 root root      253 Nov 24  2022 libc.so
lrwxrwxrwx  1 root root       12 Nov 24  2022 libc.so.6 -> libc-2.28.so

ldd的版本和libc是配套的:

代码语言:javascript
复制
$ ldd --version
ldd (GNU libc) 2.28
Copyright (C) 2018 Free Software Foundation, Inc.

编译器用的Libc版本:

代码语言:javascript
复制
$ gcc -print-file-name=libc.so
/usr/lib/gcc/x86_64-redhat-linux/8/../../../../lib64/libc.so

libstdc++与gcc

  • libstdc++是c++的标准库文件,注意libstdc++是和gcc一起编译安装的。
  • 自己编译安装的gcc是不会安装libc的,libc可以单独下载升级。
  • linux系统内核、自带工具会依赖libc,所以libc是必须存在的;但不依赖libstdc++,所以libstdc++可以不安装。

使用g++编译的c++程序会依赖c++标准库libstdc++.so.6

代码语言:javascript
复制
$ ldd llvm-as
	...
	libstdc++.so.6 => /lib64/libstdc++.so.6 (0x00007f4cf5ae0000)
	libm.so.6 => /lib64/libm.so.6 (0x00007f4cf575e000)
	libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00007f4cf5546000)
	libc.so.6 => /lib64/libc.so.6 (0x00007f4cf5180000)
	/lib64/ld-linux-x86-64.so.2 (0x00007f4cf68bc000)

libstdc++.so.6的名字也是用短连接指向真正的库文件:

代码语言:javascript
复制
$ ll /lib64/libstdc++.so.6
lrwxrwxrwx 1 root root 19 May 24 22:05 /lib64/libstdc++.so.6 -> libstdc++.so.6.0.25

$ strings /usr/lib64/libstdc++.so.6 | grep LIBCXX
GLIBCXX_3.4
GLIBCXX_3.4.1
GLIBCXX_3.4.2
GLIBCXX_3.4.3
GLIBCXX_3.4.4
GLIBCXX_3.4.5
GLIBCXX_3.4.6
GLIBCXX_3.4.7
GLIBCXX_3.4.8
GLIBCXX_3.4.9
GLIBCXX_3.4.10
GLIBCXX_3.4.11
GLIBCXX_3.4.12
GLIBCXX_3.4.13
GLIBCXX_3.4.14
GLIBCXX_3.4.15
GLIBCXX_3.4.16
GLIBCXX_3.4.17
GLIBCXX_3.4.18
GLIBCXX_3.4.19
GLIBCXX_3.4.20
GLIBCXX_3.4.21
GLIBCXX_3.4.22
GLIBCXX_3.4.23
GLIBCXX_3.4.24
GLIBCXX_3.4.25
GLIBCXX_DEBUG_MESSAGE_LENGTH
GA+GLIBCXX_ASSERTIONS

程序需要什么版本的libc和libstdc++

以llvm为例

代码语言:javascript
复制
$ readelf -s llvm-ar | grep -oE "GLIBCXX_.*|GLIBC_.*" | sort | uniq
GLIBCXX_3.4
GLIBCXX_3.4 (6)
GLIBCXX_3.4.11 (14)
GLIBCXX_3.4.14 (26)
GLIBCXX_3.4.15 (11)
GLIBCXX_3.4.18 (22)
GLIBCXX_3.4.19 (21)
GLIBCXX_3.4.20 (5)
GLIBCXX_3.4.21 (8)
GLIBCXX_3.4.9 (13)
GLIBC_2.14
GLIBC_2.14 (7)
GLIBC_2.15 (23)
GLIBC_2.2.5
GLIBC_2.2.5 (15)
GLIBC_2.2.5 (18)
GLIBC_2.2.5 (3)
GLIBC_2.2.5 (4)
GLIBC_2.3
GLIBC_2.3 (17)
GLIBC_2.3 (9)
GLIBC_2.6
GLIBC_2.6 (10)

可以看出llvm-ar需要:

  • libc的版本为:2.15
  • libcxx的版本为:3.4.21

而当前系统提供:

  • libc的最新版本:2.28
  • libcxx的版本:3.4.25
代码语言:javascript
复制
strings /usr/lib64/libstdc++.so.6 | grep GLIBCXX
GLIBCXX_3.4
GLIBCXX_3.4.1
GLIBCXX_3.4.2
GLIBCXX_3.4.3
GLIBCXX_3.4.4
GLIBCXX_3.4.5
GLIBCXX_3.4.6
GLIBCXX_3.4.7
GLIBCXX_3.4.8
GLIBCXX_3.4.9
GLIBCXX_3.4.10
GLIBCXX_3.4.11
GLIBCXX_3.4.12
GLIBCXX_3.4.13
GLIBCXX_3.4.14
GLIBCXX_3.4.15
GLIBCXX_3.4.16
GLIBCXX_3.4.17
GLIBCXX_3.4.18
GLIBCXX_3.4.19
GLIBCXX_3.4.20
GLIBCXX_3.4.21
GLIBCXX_3.4.22
GLIBCXX_3.4.23
GLIBCXX_3.4.24
GLIBCXX_3.4.25

strings /lib64/libc.so.6 | grep -E '^GLIBC' | sort
GLIBC_2.10
GLIBC_2.11
GLIBC_2.11
GLIBC_2.12
GLIBC_2.13
GLIBC_2.13
GLIBC_2.14
GLIBC_2.15
GLIBC_2.16
GLIBC_2.16
GLIBC_2.17
GLIBC_2.18
GLIBC_2.18
GLIBC_2.2.5
GLIBC_2.2.6
GLIBC_2.2.6
GLIBC_2.22
GLIBC_2.23
GLIBC_2.23
GLIBC_2.24
GLIBC_2.25
GLIBC_2.25
GLIBC_2.26
GLIBC_2.26
GLIBC_2.27
GLIBC_2.28
GLIBC_2.28
GLIBC_2.3
GLIBC_2.3.2
GLIBC_2.3.3
GLIBC_2.3.4
GLIBC_2.4
GLIBC_2.5
GLIBC_2.5
GLIBC_2.6
GLIBC_2.6
GLIBC_2.7
GLIBC_2.7
GLIBC_2.8
GLIBC_2.8
GLIBC_2.9
GLIBC_2.9

可以满足要求。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2023-07-22,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 总结
  • libc.so
  • libstdc++与gcc
  • 程序需要什么版本的libc和libstdc++
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档