CentOS 7交叉编译调用libsamplerate库程序ARM64(aarch64)版的libm wrong format问题

还是先说下环境,系统是CentOS 7.9(怕玩坏了,用的docker,官方镜像centos:centos7.9.2009),配合ARM官方的linux工具链gcc-arm-8.3-2019.03-x86_64-aarch64_be-linux-gnu.tar.xz(这里: https://developer.arm.com/downloads/-/gnu-a),解压到了 /usr/local/ARM-toolchain/gcc-arm-8.3-2019.03-x86_64-aarch64-linux-gnu,使用环境变量:

export AR="/usr/local/ARM-toolchain/gcc-arm-8.3-2019.03-x86_64-aarch64-linux-gnu/bin/aarch64-linux-gnu-ar"
export AS="/usr/local/ARM-toolchain/gcc-arm-8.3-2019.03-x86_64-aarch64-linux-gnu/bin/aarch64-linux-gnu-as"
export CC="/usr/local/ARM-toolchain/gcc-arm-8.3-2019.03-x86_64-aarch64-linux-gnu/bin/aarch64-linux-gnu-gcc"
export CXX="/usr/local/ARM-toolchain/gcc-arm-8.3-2019.03-x86_64-aarch64-linux-gnu/bin/aarch64-linux-gnu-g++"
export RANLIB="/usr/local/ARM-toolchain/gcc-arm-8.3-2019.03-x86_64-aarch64-linux-gnu/bin/aarch64-linux-gnu-ranlib"
export STRIP="/usr/local/ARM-toolchain/gcc-arm-8.3-2019.03-x86_64-aarch64-linux-gnu/bin/aarch64-linux-gnu-strip"
export PATH="/usr/local/ARM-toolchain/gcc-arm-8.3-2019.03-x86_64-aarch64-linux-gnu/bin:$PATH"

来指定交叉编译工具链,依赖的libsamplerate库版本是:0.2.2,报错信息如下:

/usr/local/ARM-toolchain/gcc-arm-8.3-2019.03-x86_64-aarch64-linux-gnu/bin/../lib/gcc/aarch64-linux-gnu/8.3.0/../../../../aarch64-linux-gnu/bin/ld: /usr/lib64/libm.so: error adding symbols: file in wrong format

其实这个程序在交叉编译环境刚部署好的时候编译构建时没有问题的,出现这个报错情况是在构建另一个库时需要用到libtool这个工具程序,而在yum安装libtool时又依赖安装了CentOS 7自带的gcc 4.8,于是就造成了一个系统同时存在两个libm.so的问题,一个是本机x64环境的so,位于:/usr/lib64/libm.so,而另一个显而易见就是我们的交叉编译工具链带的arm64版的so,位于:/usr/local/ARM-toolchain/gcc-arm-8.3-2019.03-x86_64-aarch64-linux-gnu/aarch64-linux-gnu/libc/usr/lib64/libm.so。

这就导致在链接程序的时候,错误的使用了x64版的libm,造成了报错wrong format!

排查了下发现libsamplerate的CMakeLists.txt中有这样一段脚本:

if(NOT (WIN32 OR APPLE OR CYGWIN OR HAIKU OR BEOS))
  find_library(MATH_LIBRARY m)
  if(MATH_LIBRARY)
    set(LIBM_REQUIRED 1)
    if(LIBM_REQUIRED)
      list(APPEND CMAKE_REQUIRED_LIBRARIES m)
      if(LIBM_REQUIRED)
        link_libraries(${MATH_LIBRARY})
      endif()
    endif()
  endif()
endif()

同时,调用cmake后生成的CMakeCache.txt文件中可以看到:“MATH_LIBRARY:FILEPATH=/usr/lib64/libm.so”,也就是定位到了错误指令集的so,那么解决的办法,我是在调用cmake时强制指定了arm64 toolchain中的版本:

cmake -DMATH_LIBRARY:FILEPATH=/usr/local/ARM-toolchain/gcc-arm-8.3-2019.03-x86_64-aarch64-linux-gnu/aarch64-linux-gnu/libc/usr/lib64/libm.so ..

这样,再次make就不会再报错了,当然,也许研究下find_library的策略,可能有更“干净”的处理方法。

博主友情提示:

如您在评论中需要提及如QQ号、电子邮件地址或其他隐私敏感信息,欢迎使用>>博主专用加密工具v3<<处理后发布,原文只有博主可以看到。