云服务器运维实战系列 · 第 5 篇(共 7 篇)
ARM 服务器编译 PHP 报 file in wrong format:是依赖库的架构错了
在 ARM 服务器上用宝塔编译 PHP 8.2,前面编译都正常,到最后链接阶段突然失败:
/bin/ld: /usr/local/curl_2/lib/libcurl.so: error adding symbols: file in wrong format collect2: error: ld returned 1 exit status make: *** [Makefile:308: sapi/cli/php] Error 1 ======================================================== ERROR: php-8.2.33 install failed.
file in wrong format 这个报错看着吓人,其实意思很直接:链接器拿到的某个库,架构跟当前机器对不上。这篇讲怎么定位是哪个库、为什么会这样。
报错在说什么
PHP 编译分两步:先把一个个源文件编译成 .o 目标文件,再由链接器 ld 把这些目标文件和各种依赖库(curl、openssl、ICU 等)拼到一起,生成最终的 php 可执行文件。
报错发生在链接阶段,点名了 /usr/local/curl_2/lib/libcurl.so。error adding symbols: file in wrong format 表示这个库的二进制格式不对——在 aarch64 机器上,大概率是这个库其实是 x86_64 的,链接器没法把 x86 的代码拼进 ARM 的程序。

第一步:确认库的架构
用 file 直接看这个库:

file /usr/local/curl_2/lib/libcurl.so
如果输出里写 x86-64,而机器是 aarch64,问题就坐实了:
uname -m # aarch64
一个 x86 的库出现在 ARM 机器上,通常是这么来的:
以前某次安装,下载/解压了错误架构的预编译包(和面板在 ARM 上拿不到正确包、回退逻辑混乱有关);
手动装依赖时,从 x86 的来源拷了一份;
旧系统残留的目录没清干净,编译脚本按路径找到了它。
我这台机器上 /usr/local/curl_2/ 就是一份架构不对的 curl,PHP 配置时把它的 lib 路径加进了链接搜索路径,于是链接到了错误的库。
第二步:看程序到底链接了哪些库
ldd 能列出一个可执行文件(或库)依赖的所有动态库及路径:
# 看已经编出的 php(如果有)依赖了什么 ldd /www/server/php/82/bin/php # 只看 curl / icu / sodium 相关 ldd /www/server/php/82/bin/php | grep -E 'curl|icu|sodium' # 看有没有找不到的库 ldd /www/server/php/82/bin/php | grep 'not found'
编译中途失败、还没有最终 php 时,可以直接对那个出问题的库做检查,并全盘搜一下有没有多个同名库:
# 全盘找 libcurl,看各自路径
find / -name "libcurl.so*" 2>/dev/null
# 逐个 file 看架构
find / -name "libcurl.so*" 2>/dev/null -exec file {} \;这样能把"正确的 ARM 库在哪、错误的 x86 库在哪"都列出来。
第三步:清掉错误的库,让它用正确的
思路是让链接器找到 aarch64 的库,而不是那份 x86 的。
1. 删除或移走错误架构的目录(确认没用后):
# 例:这份 curl 架构不对、也没被其他服务需要 sudo rm -rf /usr/local/curl_2
2. 用 apt 装 ARM 原生的依赖,Ubuntu 源里的包一定匹配 aarch64:

sudo apt update sudo apt install -y libcurl4-openssl-dev libssl-dev \ libicu-dev libsodium-dev pkg-config
3. 清掉残留的半成品编译目录,重新编译。宝塔编译会在 PHP 版本目录留下缓存和 .o,不清可能继续引用旧路径:
sudo rm -rf /www/server/php/82
然后回到面板重新点"安装 PHP 8.2",这次配置阶段通过 pkg-config 找到的是 apt 装的 ARM 库,链接就不会再报格式错误。
第四步:装好后验证
/www/server/php/82/bin/php -v /www/server/php/82/bin/php -m | grep -E 'curl|intl|sodium' # 确认链接的都是正常库、没有 not found ldd /www/server/php/82/bin/php | grep 'not found'
最后一条没有输出,就说明所有依赖都正常解析了。
通用的判断方法
file in wrong format 这类问题不限于 PHP,任何在 ARM 上编译/运行的程序都可能遇到,判断套路相同:
uname -m确认当前架构;file <报错点名的库>看它是什么架构;ldd/find把依赖和同名库都列出来对比;删掉错误架构的库,用系统包管理器(apt/yum)装对应架构的原生库;
清编译缓存后重新编译。
核心就一句:编译器和链接器不会骗人,wrong format 九成是库的架构拿错了,顺着路径把那份错误架构的库揪出来即可。