当前位置:网站首页>多个gcc/glibc版本的共存及指定gcc版本的编译
多个gcc/glibc版本的共存及指定gcc版本的编译
2022-08-04 05:25:00 【mo4776】
文章目录
这篇文章描述解决的方法,是针对这样的场景, 怎么使多个gcc/glib版本共存,在多个gcc/glib版本共存的情况,怎么样指定一个版本进行编译,怎么在一个与编译环境不同(gcc/glibc版本不同)的机器上运行服务
需求
服务原本的编译环境 Ubuntu + gcc 5.5.0(libstdc++) + libc.so.2.17
需要在目标编译环境 centos 6.8 + gcc 4.8(libstdc++) + libc.so.2.14
需要在环境 centos 6.8 + libc.so.2.14 运行
- 限制:
- 源码必须使用gcc 5.5.0编译,所以得在
目标编译环境安装对应版本的gcc和glibc 目标编译环境账号没有root权限
还有一点要注意,目标编译环境与原编译环境上的连接器的版本也需要一致(或高于),连接器是隶属于 binutils包的。
这个需求中囊括了这样三个需求:怎么使多个gcc/glib版本共存,在多个gcc/glib版本共存的情况,怎么样指定一个版本进行编译,怎么在一个与编译环境不同(gcc/glibc版本不同)的机器上运行服务
背景知识
什么是glibc,libc,glib
glibc是linux的GUN C函数库,是linux系统中最底层的API,几乎其它任何运行时库都依赖于glibc。glibc除了封装linux操作系统所提供的系统服务,它本身也提供了许多其它必要功能服务的实现,例如:动态加载模块libdl、实时扩展接口librt。对应的动态库的名字
libc.solibc是Linux下的ANSI C函数库,被glibc包含
libc是Linux下原来的标准C库,也就是当初写hello world时包含的头文件#include < stdio.h> 定义的地方。
后来逐渐被glibc取代,也就是传说中的GNU C Library,在此之前除了有libc,还有klibc,uclibc。现在只要知道用的最多的是glibc就行了,主流的一些linux操作系统如 Debian, Ubuntu,Redhat等用的都是glibc(或者其变种,下面会说到).
- glib是Linux下C的一些工具库,和glibc没有关系
依赖关系
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zzFJvF6H-1629517049109)(https://note.youdao.com/yws/api/personal/file/WEB1525e2b8f59e6aba4d5212f778140ddf?method=download&shareKey=69bafa9f7495f1a0f9ff03ffe6242795)]
构建程序,只要链接的libstdc++,glibc(libc.so,libpthread,动态连接器等系列库)版本正确,就不会出问题。在低版本的os上,安装高版本的gcc,glibc,只要可以顺利编译通过,则意味这高版本库是支持低版本OS的。
方法
查看glibc版本
- 通过ldd
ldd --version
ldd是隶属于glibc,它的版本就是glibc的版本
- 通过
getconf GNU_LIBC_VERSION
pthread也是一个非常重要的库,它被包含在glibc中,可以通过
getconf GNU_LIBPTHREAD_VERSION查看它的版本,是与glibc的版本是一致的
查找glibc库的位置
- 通过
ldd
linux 上几乎所有的程序都依赖于glibc,所以可以直接通过 ldd 某个程序 | grep "libc.so"的方式查看
- 通过gcc
gcc -print-file-name=libc.so可以获得libc.so的位置,这也是该gcc依赖的libc.so的位置
查看glibc API的版本
strings /lib64/libc.so.6 | grep GLIBC
libstdc++
libstdc++是 gcc的标准C++库(libc++是clang的标准C++库)
查找libstdc++.so的位置
/sbin/ldconfig -p | grep stdc++locate libstdc++.so
查看libstdc++的版本
libstdc++是被包含在gcc中的,对应为gcc的版本
gcc --version
查看系统libstdc++API的版本
strings /usr/lib/libstdc++.so.6 | grep LIBCXX
libstdc++,glibc的关系
libstdc++与gcc是捆绑在一起的,也就是说安装gcc的时候会把libstdc++装上。 那为什么glibc和gcc没有捆绑在一起呢?因为程序可以不依赖libstdc++,但是必须依赖glibc
确定程序需要的glibc/libstdc++的版本
readelf -s qt_cef_poc | grep -oP "GLIBC_[\d\.]*" | sort | uniq
解决步骤
编译安装
必须安装如下程序:
- gcc(这里需求的是版本 5.5.0) 包含了 gcc/g++ ,libstdc++
- binutils(这里需求的是版本2.27) 包含了 链接器(ld)
- glibc(这里需求的是版本2.17) 包含了 libc.so , ld(动态链接器,用于在程序运行时链接动态库),libpthread
多个gcc/glibc版本共存
多个gcc/glibc共存,新安装的gcc/glibc版本需要指定安装目录。特别是glibc作为基础库,如果直接替换了系统中原有的glibc,很可能造成任何命令/程序都无法运行的情况。切记,一定要指定安装目录。
指定gcc/g++,glibc的版本进行编译
在编译时需要指定gcc及库的依赖路径,包括以下几点:
- 指定gcc/g++的版本
export CC=gcc的路径
export CXX=g++的路径
- 指定连接器的版本
将连接器的路径,放在LD_LIBRARY_PATH的最前面
- 指定glibc的版本
通过gcc 的-L参数指定glibc库(libc.so)的路径
在gcc的编译参数中指定 -Wl,–dynamic-linker=glibc中动态链接器的路径,如下:
-Wl,--dynamic-linker=/动态连接器的路径/ld-linux-x86-64.so.2
在gcc中链接libc.so(-lc)
将
glibc的路径,引入LD_LIBRARY_PATH中
程序运行机器上的依赖
如果编译环境与运行环境不同,则需要将gcc,glibc的一些库打包到程序安装包中,并且指定库的路径
- 依赖的库
libstdc++.so,libc.so库及它们的依赖库,动态连接器都需要放入程序的依赖库的目录中,基本是包含如下几个库
librt.so.1
libdl.so.2
libpthread.so.0
libstdc++.so.6
libm.so.6
libc.so.6 -> glibc库
libgcc_s.so.1
libresolv.so.2
libcrypt.so.1
ld-linux-x86-64.so.2 ->其实是个执行程序,为动态连接器
- 指定依赖库的路径
在编译是通过gcc的编译参数-Wl,-rpath=程序的依赖库路径
这些库最好都放在指定的,固定的目录中,在编译时通过这个编译选项指定该路径
3.将动态连接器ld-linux-x86-64.so.2的路径配置到PATH中
总结
基本原理,就是千方百计的,将程序链接/运行时的依赖路径指向期望的版本,手段包括:
-Wl,-rpath=编译参数-Wl,--dynamic-linker编译参数- 设置
LD_LIBRARY_PATH - 设置
PATH
吐个槽,C++的库管理太麻烦了。
边栏推荐
猜你喜欢

败给“MySQL”的第60天,我重振旗鼓,四面拿下蚂蚁金服offer

TSF微服务治理实战系列(一)——治理蓝图

MySQL log articles, binlog log of MySQL log, detailed explanation of binlog log

Web Basics and Exercises for C1 Certification - My Study Notes

npm安装依赖报错npm ERR! code ENOTFOUNDnpm ERR! syscall getaddrinfonpm ERR! errno ENOTFOUND

入坑软件测试的经验与建议

Swoole学习(一)

MySQL数据库面试题总结(2022最新版)

Summary of MySQL database interview questions (2022 latest version)

OpenSSF 安全计划:SBOM 将驱动软件供应链安全
随机推荐
力扣:63. 不同路径 II
CentOS7 - yum install mysql
FLV格式详解
利用Jenkins实现Unity自动化构建
4.1 声明式事务之JdbcTemplate
Embedded system driver primary [3] - _IO model in character device driver foundation
8大软件供应链攻击事件概述
The cost of automated testing is high and the effect is poor, so what is the significance of automated testing?
7.16 Day22---MYSQL (Dao mode encapsulates JDBC)
7.15 Day21---MySQL----Index
Unity行为树AI分享
C Expert Programming Chapter 4 The Shocking Fact: Arrays and pointers are not the same 4.1 Arrays are not pointers
7.18 Day23----标记语言
【问题解决】同一机器上Flask部署TensorRT报错记录
TensorRTx-YOLOv5工程解读(一)
Handling List
MySQL日志篇,MySQL日志之binlog日志,binlog日志详解
The idea setting recognizes the .sql file type and other file types
一个对象引用的思考
动态规划总括