如何查看gcc版本,gcc各版本的区别详解?

营销圈公众号引导关注

前言

这次在排查 gcc 编译时遇到的问题时,对 gcc 编译的理解又加深了一点,现分享给大家。在这之前,请先阅读下我之前写的两篇文章:详解三大编译器:gcc、llvm 和 clang 详解 gcc 编译、链接原理—揭开应用程序运行背后的奥秘

什么是 gcc

[gcc 官方网站](https://gcc.gnu.org/)

GCC(GNU Compiler Collection,GNU编译器套件),是由 GNU 开发的编程语言编译器。它是以 GPL(General Public License)许可证所发行的自由软件,也是 GNU 计划的关键部分(GPU 是一个软件工程项目,是 GNU’s Not Unix 的缩写)。

GCC 原本作为 GNU 操作系统的官方编译器,现已被大多数类 Unix 操作系统(如Linux、BSD、Mac OS X等)采纳为标准的编译器,GCC 同样适用于微软的Windows。GCC 是自由软件过程发展中的著名例子,由自由软件基金会以 GPL 协议发布。

什么是 glibc

[glibc 官方网站](
https://www.gnu.org/software/libc/)

glibc 是 gnu 发布的 libc 库,即 c 运行库。glibc 是 linux 系统中最底层的 api,几乎其他任何的运行库都会依赖 glibc. glibc 除了封装 linux 操作系统所提供的系统服务外,它本身提供了许多其它一些必要服务的实现,主要有:

  • string:字符串处理
  • signal:信号处理
  • dlfcn:管理共享库的动态加载
  • direct:文件目录操作
  • elf:共享库的动态加载器,即 interpreter
  • iconv:不同字符集的编码转换
  • inet:socket 接口的实现
  • intl:gettext 的实现
  • io
  • linuxthreads
  • locale:本地化
  • login:虚拟终端设备的管理,及系统的安全访问
  • malloc:动态内存管理的分配与管理
  • nis
  • stdlib
  • math

gcc 和 glibc 的关系

首先,gcc 是编译器,基本上 linux 下所有程序(包括内核)都是 gcc 编译的,libc 也是。但 gcc 和 libc 又是相互依赖的,什么意思呢?就是在编译 c/cpp 代码时,既需要 gcc,也需要 libc.

gcc 发行版本

截止2021年8月,最新版本已经到 gcc11.2 了。

glibc 发行版本

截止2021年8月,最新版本已经到 glibc2.34 了,历史版本有 glibc2.29、2.30、2.31、2.32、2.33 等。

查看命令

1、查看当前系统的 glibc 版本

  • 方法1:
/lib/x86_64-linux-gnu/libc.so.6

为什么这个库可以直接运行呢?原来是在 libc 的代码中有一点小手脚:

void
__libc_main (void) 
{ 
    __libc_print_version (); 
    _exit (0); 
}
  • 方法2:

ldd 命令也是 glibc 提供的,所以也能查看 glibc 版本:

ldd --version

2、查看 glibc 的 api 版本

strings /lib/x86_64-linux-gnu/libc.so.6 | grep GLIBC

3、查看 so 信息

`objdump -p test_gcc.so`,其他类似命令还有 `nm` 和 `readelf`

4、查看当前so依赖哪些so

  • 方法1:
`ldd test_gcc.so`
  • 方法2:
`objdump -x test_gcc.so | grep NEEDED`

5、获取 gcc 依赖的某个 so 文件位置

`gcc --print-file-name=libz.so.1`

6、查看当前使用的 gcc 版本和引用的头文件路径

`echo | gcc -v -x c -E -`

7、查看当前so使用了GLIBC_2.23中哪些函数

`objdump -T test_gcc.so | grep GLIBC_2.23`

8、查看当前so使用的memcpy版本

`nm test_gcc.so | grep memcpy -w`

`objdump -T /lib/x86_64-linux-gnu/libc.so.6 | grep memcpy`

9、设置 c、c++ 头文件路径

`export CPLUS_INCLUDE_PATH=/opt/compiler/gcc-8.2/x86_64-custom-linux-gnu/include/c++/8.2.0:/usr/include/x86_64-linux-gnu/`

`export C_INCLUDE_PATH=......`

10、编译时如何设置链接器版本

指定正确的 ldd 路径,也就是对应具体的 glibc 版本(非常重要)。

11、设置链接库路径

  • 方法1:

先查看:`echo $LD_LIBRARY_PATH`,可通过该环境变量直接设置。

或者,`gcc –print-search-dirs`

  • 方法2:使用动态库管理命令 ldconfig

`ldconfig -v`: 查看所有动态链接库

`vim /etc/ld.so.conf`,显示 `include /etc/ld.so.conf.d/*.conf`,然后`cd /etc/ld.so.conf.d`

修改完之后,要重新运行下 `ldconfig`

解释

linux 下的共享库机制采用了类似于高速缓存的机制,将库信息保存在`/etc/ld.so.cache`里边。

程序连接的时候首先从这个文件里边查找,然后再到`ld.so.conf`的路径里边去详细找。

这就是为什么修改了`ld.so.conf`要重新运行一下`ldconfig`的原因

12、c++ 标准库: stdlibc++ 和 libc 的版本号是不一样的

`objdump -T /usr/lib/gcc/x86_64-linux-gnu/5/libstdc++.so | grep GLIBCXX`

13、gcc 头文件的搜索路径顺序

1. 优先搜索`-I`指定的路径

2. 查找GCC的环境变量`C_INCLUDE_PATH`/`CPLUS_INCLUDE_PATH`/`OBJC_INCLUDE_PATH`指定的路径

3. 查找默认的搜索路径`/usr/include`、`/usr/local/include`

14、gcc搜索链接库(编译期 + 运行期)的顺序

gcc在编译时按照如下顺序寻找所需要的库文件:

1. gcc会去找`-L`指定的目录

2. 再找gcc的环境变量`LIBRARY_PATH`

3. 再找内定目录

  • /lib和/lib64
  • /usr/lib 和/usr/lib64
  • /usr/local/lib和/usr/local/lib64

这是当初 compile gcc 时写在程序内的。

这里有两个问题:

  • 默认情况下,gcc编译时只会查找相应的头文件,而不会连接具体的lib。也就是说只要include设置完全,就可以编译通过。它没有进一步检查include中的类和函数有没有实现,而是在运行时才开始查找。所以就会经常发生编译可以通过,但运行时却无法运行,因为在运行时它找不到相关类或者函数的实现。

这时,使用`-Wl`,`–no-undefined`参数,如果使用了 include 文件,链接器却找不到相应的实现,就会产生错误提示。

  • 编译时默认不查找当前目录,需要使用`-L ./`指定,例如

运行时动态库的搜索路径的先后顺序是:

1. 编译目标代码时指定的动态库搜索路径;这是通过gcc的参数`-Wl,-rpath=`指定。当指定多个动态库搜索路径时,路径之间用冒号 :分隔

2. 环境变量`LD_LIBRARY_PATH`指定的动态库搜索路径

3. 配置文件`/etc/ld.so.conf`中指定的动态库搜索路径

4. 默认的动态库搜索路径,如:`/lib`, `/usr/lib`

注意:

1. 动态库搜寻路径并不包括当前目录,所以当即使可执行文件和其所需的so文件在同一文件夹,也会出现找不到问题

2. 一般不推荐直接修改环境变量,而是修改`/etc/ld.so.conf`,将相应的路径添加上,然后`ldconfig`一下就好

3. ldconfig做的这些东西都与运行程序时有关,跟编译时一点关系都没有,编译的时候还是该加`-L`就得加,不要混淆了

4. 往`/lib`和`/usr/lib`里面加 `lib`,是不用修改`/etc/ld.so.conf`的,但是完了之后要调一下`ldconfig`(很重要),不然这个`lib`会找不到。而往其他目录加`lib`,需要修改`/etc/ld.so.conf`,并且要`ldconfig`一下。

15、如何安装指定版本glibc

  • 从官网下载,解压,如 ./glibc-2.21
  • cd glibc-2.21
  • mkdir build
  • mkdir /opt/glibc-2.21
  • cd build
  • ../configure –prefix=/opt/glibc-2.21
  • apt-get install gawk
  • make
  • 需要解决一些编译告警或错误问题
  • 报错(解决):./stdlib/setenv.c +270
  • 报错(未解决):

../sysdeps/x86_64/multiarch/strstr.c:47:30

  • 未完待续。。。

好了,这篇文章的内容营销圈就和大家分享到这里,如果大家对网络推广引流和网络创业项目感兴趣,可以添加微信:Sum8338 备注:营销圈引流学习,我拉你进直播课程学习群,每周135晚上都是有实战的推广引流技术和网络创业项目课程分享,当然是免费学!

版权声明:本站部分文章来源互联网用户自发投稿,主要目的在于分享信息,版权归原作者所有,不承担相关法律责任。如有侵权请联系我们反馈邮箱yingxiaoo@foxmail.com,我们将在7个工作日内进行处理,如若转载,请注明本文地址:https://www.yingxiaoo.com/148898.html