开源库移植
ARM 架构下 libjpeg 库交叉编译问题解决文档
一、问题背景
在 Ubuntu 18.04 系统中,使用 ARM 交叉编译器(arm-openwrt-linux-muslgnueabi-gcc-6.4.1)编译依赖 libjpeg 库的项目时,出现以下错误:
./lib//libjpeg.so: file not recognized: File format not recognized
collect2: error: ld returned 1 exit status
collect2 是 GCC 编译器调用链接器(ld)的中间程序
编译器尝试链接 ./lib/libjpeg.so 文件时,发现该文件的格式(架构)无法被当前使用的编译器识别,导致链接器执行失败并返回错误状态码 1。
进行检查lib里面的文件,看看是不是ARM的
file /libjpeg.so.9.5.0
核心原因是项目中使用的libjpeg.so.9.5.0为 x86/x86_64 架构,与 ARM 目标平台不兼容,需要为 ARM 架构交叉编译 libjpeg 库。
二、关键问题分析
| 问题现象 | 根本原因 |
|---|---|
| 文件格式不识别 | libjpeg 库为 x86 架构,ARM 交叉编译器无法处理非目标架构的库文件 |
| STAGING_DIR 未定义警告 | OpenWRT 交叉编译工具链的提示性警告,非必需变量,不影响编译结果 |
| 交叉编译后仍为 x86 库 | configure 阶段未正确绑定 ARM 编译器,或缓存残留导致调用系统默认 x86 编译器 |
三、完整解决步骤
3.1 准备工作:定位 ARM 交叉编译器路径
-
查找编译器绝对路径(以实际路径为准):
which arm-openwrt-linux-muslgnueabi-gcc-6.4.1 # 示例输出:/home/ubuntu/tina-d1-h/out/t113-100ask/staging_dir/toolchain/bin/arm-openwrt-linux-muslgnueabi-gcc-6.4.1 -
验证编译器可用性:
/home/ubuntu/tina-d1-h/out/t113-100ask/staging_dir/toolchain/bin/arm-openwrt-linux-muslgnueabi-gcc-6.4.1 -v # 输出包含Target: arm-openwrt-linux-muslgnueabi即为正常 -
配置环境变量(临时生效):
export TOOLCHAIN_BIN=/home/ubuntu/tina-d1-h/out/t113-100ask/staging_dir/toolchain/bin export PATH=$TOOLCHAIN_BIN:$PATH -
永久生效
打开用户的环境变量配置文件
nano ~/.bashrc# 配置ARM交叉编译工具链路径 export TOOLCHAIN_BIN=/home/ubuntu/tina-d1-h/out/t113-100ask/staging_dir/toolchain/bin export PATH=$TOOLCHAIN_BIN:$PATH配置立即生效
source ~/.bashrc
3.2 交叉编译 ARM 架构 libjpeg 库(以 libjpeg-9e 为例)
-
下载并解压源码:
mkdir -p ~/gk/libjpeg_dir && cd ~/gk/libjpeg_dir wget http://www.ijg.org/files/jpegsrc.v9e.tar.gz tar -zxvf jpegsrc.v9e.tar.gz && cd jpeg-9e -
清理旧编译产物(避免缓存干扰):
make distclean -
绑定 ARM 交叉编译工具链:重点
export CC=$TOOLCHAIN_BIN/arm-openwrt-linux-muslgnueabi-gcc-6.4.1 export CXX=$TOOLCHAIN_BIN/arm-openwrt-linux-muslgnueabi-g++-6.4.1 export AR=$TOOLCHAIN_BIN/arm-openwrt-linux-muslgnueabi-ar export RANLIB=$TOOLCHAIN_BIN/arm-openwrt-linux-muslgnueabi-ranlib # 消除STAGING_DIR警告(可选) export STAGING_DIR=/tmp/openwrt_staging -
配置编译参数:
./configure \ --prefix=/home/ubuntu/gk/libjpeg_dir/libjpeg \ # 编译后安装目录 --host=arm-openwrt-linux-muslgnueabi \ # 目标ARM架构 --build=x86_64-linux-gnu \ # 当前主机架构关键检查:configure 输出需包含
checking host system type... arm-openwrt-linux-muslgnueabi。 -
编译并安装:
make -j$(nproc) # -j后接CPU核心数,如-j4 make install -
验证库架构(核心步骤):
file /home/ubuntu/gk/libjpeg_dir/install/lib/libjpeg.so.9.0.0 # 输出包含"ELF 32-bit LSB shared object, ARM"即为成功
3.3 替换项目中的 x86 库并编译项目
-
替换项目 lib 目录下的旧库
-
重新编译项目
-
验证可执行文件架构:
file ./main # 输出包含"ARM"即为适配目标平台
四、常见问题与避坑点
- 编译后仍为 x86 库
- 原因:configure 阶段未正确绑定 ARM 编译器,或未执行
make distclean清理缓存。 - 解决:用绝对路径指定编译器,重新执行
configure。
- 原因:configure 阶段未正确绑定 ARM 编译器,或未执行
- STAGING_DIR 警告
- 性质:仅提示,不影响编译结果,可通过
export STAGING_DIR=/tmp/xxx消除。
- 性质:仅提示,不影响编译结果,可通过
五、核心总结
- 交叉编译的核心是通过
--host指定目标架构、--build指定主机架构,并显式绑定 ARM 编译器; - 必须通过
file命令验证库 / 可执行文件的架构,确保包含ARM标识; - 编译前清理旧产物(
make distclean)是避免缓存干扰的关键步骤; STAGING_DIR警告无需处理,不影响功能,仅为工具链提示。
六、最终验证标准
libjpeg.so.9.5.0/libjpeg.so.9.0.0的file输出包含ARM;- 项目编译无 “文件格式不识别” 错误,生成
main可执行文件; main的file输出包含ARM,可在目标 ARM 开发板正常运行。

浙公网安备 33010602011771号