多种方式解决交叉编译中glibc版本不兼容导致的编译问题(libc.so.6: version `GLIBC_xxx‘ not found问题)
一个常见的问题就是:拿到客户的开发板后需要验证自己本地搭建的交叉编译环境是否正确,这影响到后续的开发.glibc就是指libc.so.6这个动态库,libc.so.6软链接到实际的动态库. 文章共1,877字 · 阅读需要大约7分钟 一键AI生成摘要,助你高效阅读 7391人浏览 · 2023-11-20 18:22:07
目录
一个常见的问题就是:
拿到客户的开发板后需要验证自己本地搭建的交叉编译环境是否正确,这影响到后续的开发.
glibc 就是指libc.so.6这个动态库,libc.so.6软链接到实际的动态库.
开始动手!
在开发板上,如果有例子比如说可执行程序.那么可以通过
nm sample_adc | grep GLIBC_ : sample_adc(作为可执行程序) 查看那些调用是用到glibc 库的
strings /lib/x86_64-linux-gnu/libc.so.6 |grep GLIBC_ 查看glibc 的所有版本,如果是开发板注意库的路径.
查看开发板和本地linux所支持的最高版本,目前 我的工作证明 链接 低版本的glibc的bin可以在高版本上运行 , 高版本编译的bin不能在低版本的glib的环境 中运行。
网上看了很多种方式,总结下来有这么几种:
个人推荐用第三种,既不影响本地的glibc,又能完成目标.
linux安装指定版本glibc,适配降级_redhat6.9降级glibc-CSDN博客
1.更新linux系统的glibc的版本,使得可以和开发板上适配.一般都是开发板上的glibc的版本过低.需要降低本地的glibc的版本.
这种方式我破天荒在第一次安装好低版本的glibc库后,通过在/etc/profile中 加入
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/opt/glibc-2.25/lib
再执行 ‘source /etc/profile’
使得再本地终端中生效,第一次编译刚好没有问题,make 命令竟然没有报错,而且 编译出的bin在开发板上能运行 .因为那天是星期五快下班了没怎么关注make是如何链接到glibc的.就没有关注,直到星期一,发现make不了了,因为make是在/usr/bin 中 它链接的是export 之前的 glibc 库 , 而export 修改了 LD_LIBRARY_PATH 的值,导致找不到之前 链接的动态库了.这一点怎么在之前却没有出现! ls 等其他命令都出现了问题,因为它们这些可执行命令都链接的是之前的glibc .除非用 sudo ls 才会生效.
后面未找到解决方法.本身这种方式也不灵活且会导致很多问题.
这种方式是在搜索途中找到的.通过指定动态库路径和库名的方式去编译. 但是对于非本人开发的SDK(以Makefile构建)的项目来看,肯定是不希望改动Makefile文件的.按照开发者的规则来进行能降低奇奇怪怪的错误.
参考 高版本gcc编译出的程序在低版本glibc机器上运行 - 简书 (jianshu.com)
这种方法如果是自己比较熟悉的工程通过指定路径的方式未尝不是一种比较好的选择.
通过patchelf的方式,这种方式是修改二进制的方式.把编译出来的二进制程序所链接的glibc动态库进行修改, 这种方式形象的比喻就是 无论过程如何,但是编译的产物bin所链接的bin 通过 pathcelf 修改 . 这种方式,我使用起来效果甚好,所以 详细描述 .
查看二进制程序依赖的glibc库及其库版本
nm sample_adc | grep GLIBC_
file xxx(bin二进制可执行程序)
查看链接的库.
发现链接的是系统的 /lib下的库.(这里看不出glibc,但patchelf修改后会有变化,通过这点来验证patchelf是否成功).
使用patchelf需要准备一下几件事:
- 确定开发板上的glibc的版本,比如开发板上最高是2.25,那么我们要确定自己本地要装2.25的glibc的库.
- 在 本地的linux系统 下(我这里的ubuntu) 下载glibc的库然后编译.这一点有些问题。参考 linux安装指定版本glibc,适配降级_redhat6.9降级glibc-CSDN博客
../configure --prefix=/opt/glibc-2.17 --disable-werror
使得 make & make install 能够通过
还有一种方式. 通过 glibc-all-in-one 这个工具来管理glibc,支持下载和编译具体的glibc库.这一种也是我推荐的.能用工具来管理当然就用工具来管理了.
做完以上的两件事,则能够得到编译后的glibc库了,接下来就是按照patchelf.
-
//新建目录 git clone https://github.com/NixOS/patchelf.git //进行仓库 ./bootstrap.sh (.bootstrap.sh执行报 autoreconf: not found 执行sudo apt-get install autoconf automake libtool) ./configure make check sudo make install
安装完后.通过输入patchelf 查看是否安装成功.
以编译后的可执行程序来指定与开发板适配的glibc:以2.25为例:
patchelf --set-interpreter xxx( 第一步编译的glibc的文件路经 也就是libc.so.6) --set-rpath xxx( 第一步编译 的glibc的搜索路径) xxx(可执行程序)
patchelf --set-interpreter /opt/glibc-2.25/lib/libc.so.6(glibc的文件路经) --set-rpath /opt/glibc-2.25/lib(glibc的搜索路径) spi_master(可执行程序)
没有输出则成功:
file xxxx
此时此刻拷贝到开发板中运行,正确运行.
# linux
所有评论(0)