• 多种方式解决交叉编译中glibc版本不兼容导致的编译问题(libc.so.6: version `GLIBC_xxx‘ not found问题)


    目录

    背景

    开始动手!

    第一种

    第二种

             第三种


    背景

    一个常见的问题就是:

    拿到客户的开发板后需要验证自己本地搭建的交叉编译环境是否正确,这影响到后续的开发.

    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需要准备一下几件事:

    1. 确定开发板上的glibc的版本,比如开发板上最高是2.25,那么我们要确定自己本地要装2.25的glibc的库.
    2. 本地的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.

    1.  
      1. //新建目录
      2. git clone https://github.com/NixOS/patchelf.git
      3. //进行仓库
      4. ./bootstrap.sh
      5. (.bootstrap.sh执行报 autoreconf: not found
      6. 执行sudo apt-get install autoconf automake libtool)
      7. ./configure
      8. make
      9. make check
      10. 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

     查看

     此时此刻拷贝到开发板中运行,正确运行.

  • 相关阅读:
    1. 数据结构
    有监督学习神经网络的回归拟合——基于红外光谱的汽油辛烷值预测(Matlab代码实现)
    Qt项目实战 杂谈一二:中文乱码事情小,处理不好头发少
    如何运营好技术相关的自媒体?
    刷题笔记之十 (小易的升级之路+找出字符串中第一个只出现一次的字符+洗牌+MP3光标位置)
    多元时间序列特征工程的指南
    垃圾分类资讯易语言代码
    初识Redis与桌面客户端
    免费开箱即用微鳄OA办公系统
    还在为sql注入眼花缭乱的过滤而烦恼?一文教您快速找出所有过滤内容
  • 原文地址:https://blog.csdn.net/PHILICS7/article/details/134512178