资讯详情

PHP 7.4编译报错libzip缺失?深入解析pkg-config与依赖管理

📅 2026/10/17 1:11:28 | 华诺云谱 👁 阅读
PHP 7.4编译报错libzip缺失?深入解析pkg-config与依赖管理
1. 这个报错到底卡在哪一步编译安装 PHP 7.4 的时候终端突然甩出一行红字configure: error: Package requirements (libzip 0.11) were not met: No package libzip很多人第一反应是我明明装了 libzip 啊然后rpm -qa | grep libzip或者dpkg -l | grep libzip一查确实装了。但 configure 就是不认。这个现象背后其实有两层原因搞清楚这两层问题基本就解决了一大半。第一层是开发包和运行库的区别。绝大多数 Linux 发行版把同一个库拆成两个包一个是运行时用的动态库比如libzip5、libzip.so.5另一个是编译时需要的头文件和 pkg-config 描述文件比如libzip-devel、libzip-dev。你yum install libzip装的是前者configure 阶段需要的是后者。pkg-config 找不到.pc文件就会报 No package libzip。第二层是版本门槛。PHP 7.4 对 libzip 的最低要求是 0.11这个版本号在 2017 年左右发布。如果你用的是 CentOS 7 这类老系统默认源里的 libzip 可能只有 0.10.x即使装了 devel 包版本也不够。这时候光装 devel 没用得想办法搞到 0.11 以上的版本。提示报错信息里的 No package libzip 和 libzip 0.11 were not met 是两种不同的失败。前者是压根找不到后者是找到了但版本低。看仔细你遇到的是哪一种处理路径完全不同。我见过不少人在这卡了一整天反复yum install libzip、yum install libzip-devel装完还是报错最后发现是系统源里的版本太老。所以第一步不是急着装包而是先确认三件事系统发行版和版本、当前 libzip 的实际版本、pkg-config 能不能找到它。# 确认系统版本 cat /etc/os-release # 查已安装的 libzip 相关包 rpm -qa | grep -i libzip # RedHat 系 dpkg -l | grep -i libzip # Debian 系 # 查 pkg-config 能否找到 libzip pkg-config --exists libzip echo found || echo not found pkg-config --modversion libzip这几条命令跑完问题的轮廓就清楚了。如果pkg-config --modversion libzip直接报错说找不到包那就是 devel 包没装或者.pc文件路径不对。如果输出了一个低于 0.11 的版本号那就是版本不够需要升级。2. 不同发行版的依赖安装差异PHP 编译这件事最让人头疼的就是不同发行版的包名和源策略完全不一样。同一个 libzip在 CentOS、Ubuntu、Alpine 上的处理方式差得很远。下面这张表是我这些年反复踩坑总结出来的对照建议直接收藏。发行版运行时包名开发包名默认源版本情况备注CentOS 7libziplibzip-devel0.10.x低于要求需要额外源或手动编译CentOS 8 / Rocky 8libziplibzip-devel1.x满足要求直接装即可Ubuntu 18.04libzip5libzip-dev1.1.x满足要求直接装即可Ubuntu 20.04libzip5libzip-dev1.5满足要求直接装即可Debian 10libzip5libzip-dev1.5满足要求直接装即可Alpinelibziplibzip-dev1.x满足要求用 apk 安装从表里能看出来真正麻烦的其实就一个 CentOS 7。它的生命周期长、装机量大但默认源里的软件版本普遍偏老。如果你正好在 CentOS 7 上编译 PHP 7.4那大概率要面对 libzip 版本不够的问题。对于 Ubuntu 和 Debian 用户事情简单很多sudo apt update sudo apt install -y libzip-dev装完之后再跑pkg-config --modversion libzip正常应该输出 1.x 的版本号。如果还是找不到检查一下是不是pkg-config本身没装sudo apt install -y pkg-configAlpine 用户用 apkapk add --no-cache libzip-devCentOS 8 及以上sudo dnf install -y libzip-devel这些操作看起来简单但有个细节容易被忽略装完 devel 包之后最好重新开一个终端或者执行hash -r因为 shell 可能缓存了旧的命令路径和 pkg-config 的搜索路径。我遇到过装完包在当前终端里死活找不到新开一个终端就正常的情况排查半天才发现是缓存问题。注意如果你是在 Docker 容器里编译记得把apt install和./configure放在同一个 RUN 指令里或者至少确保 devel 包在 configure 之前装好。分层的镜像构建有时候会让人产生我明明装了的错觉。3. CentOS 7 上的版本困局与破局思路CentOS 7 是这个问题的高发区值得单独拿出来讲。它的默认 yum 源里libzip 停留在 0.10.1而 PHP 7.4 要求 0.11 以上。你yum install libzip-devel装完pkg-config --modversion libzip输出 0.10.1configure 照样报错。这时候有几条路可以走我按推荐程度从高到低排一下。第一条路换用 Remi 源。Remi 是一个专门提供新版 PHP 及相关依赖的第三方源在 CentOS 生态里用得很多。装上 Remi 源之后可以直接yum install libzip-devel拿到较新的版本。具体操作是先装 epel-release 和 remi-release然后用yum --enablereporemi install libzip-devel。这条路的优点是干净、可维护缺点是引入了第三方源有些对源管控严格的环境可能不允许。第二条路手动编译 libzip。这是最通用、最不依赖外部源的办法。从 libzip 的官方发布页下载 1.x 的源码包自己编译安装到/usr/local下。步骤大概是# 下载源码版本号按需替换 wget https://libzip.org/download/libzip-1.7.3.tar.gz tar -xzf libzip-1.7.3.tar.gz cd libzip-1.7.3 mkdir build cd build cmake .. make -j$(nproc) sudo make install # 让系统能找到新装的库 sudo sh -c echo /usr/local/lib64 /etc/ld.so.conf.d/libzip.conf sudo ldconfig # 让 pkg-config 能找到 .pc 文件 export PKG_CONFIG_PATH/usr/local/lib64/pkgconfig:$PKG_CONFIG_PATH这里有几个坑要特别注意。第一libzip 1.x 用 CMake 构建不是传统的./configure所以系统里得有 cmake没有的话先yum install cmake。第二安装路径默认是/usr/local库文件可能在/usr/local/lib或/usr/local/lib64取决于系统架构ld.so.conf里要写对。第三PKG_CONFIG_PATH这个环境变量必须设置否则 pkg-config 还是只会在默认路径里找看不到你新装的版本。第三条路用 SCL 或容器。如果只是想要一个能跑的 PHP 7.4不想在系统层面折腾依赖可以考虑用 Software Collections 提供的 PHP或者干脆用官方 Docker 镜像。这条路绕开了编译但如果你就是要自己编译那前两条路更合适。我个人的经验是如果这台机器以后还要长期维护优先走 Remi 源如果是一次性编译或者环境隔离要求高手动编译 libzip 更可控。手动编译虽然多几步但版本、路径都捏在自己手里出了问题也好排查。4. 手动编译 libzip 的完整链路与验证手动编译 libzip 这条路我想把每个环节都拆开讲清楚因为很多人卡在编译完了但 PHP 还是找不到这个状态。先说依赖。libzip 本身依赖 zlib编译前确认 zlib 的开发包在sudo yum install -y zlib-devel如果 cmake 版本太老CentOS 7 默认的 cmake 是 2.8.xlibzip 1.7 以上可能要求 cmake 3.x这时候要么升级 cmake要么选一个对 cmake 要求低的 libzip 版本比如 1.5.x。我一般建议直接升级 cmake因为后面编译其他东西也可能用到# 从源码装新版 cmake 的通用套路 wget https://github.com/Kitware/CMake/releases/download/v3.20.0/cmake-3.20.0-linux-x86_64.tar.gz tar -xzf cmake-3.20.0-linux-x86_64.tar.gz sudo mv cmake-3.20.0-linux-x86_64 /opt/cmake sudo ln -sf /opt/cmake/bin/cmake /usr/local/bin/cmake cmake --version编译 libzip 的时候我习惯指定安装前缀方便后面管理cd libzip-1.7.3 mkdir build cd build cmake -DCMAKE_INSTALL_PREFIX/usr/local .. make -j$(nproc) sudo make install装完之后验证分三步走。第一步确认库文件在ls -l /usr/local/lib64/libzip*第二步确认 pkg-config 能找到export PKG_CONFIG_PATH/usr/local/lib64/pkgconfig:$PKG_CONFIG_PATH pkg-config --modversion libzip第三步确认动态链接器能加载ldconfig -p | grep libzip这三步都过了再回到 PHP 源码目录重新跑 configure。这里有个关键点configure 会缓存上一次的检测结果。如果你之前 configure 失败过直接重跑可能还是用旧结果。稳妥的做法是先清理make clean rm -f config.cache ./configure --with-zip ...--with-zip这个参数在 PHP 7.4 里是启用 zip 扩展的关键。PHP 7.4 把 zip 扩展的依赖从原来的 libzip 0.10 升级到了 0.11所以这个报错才会在 7.4 上集中出现。如果你不需要 zip 扩展其实可以在 configure 时加--without-zip绕过去但大多数场景下 zip 扩展还是要的比如 Composer 处理压缩包、PhpSpreadsheet 读写 xlsx 都依赖它。提示PKG_CONFIG_PATH这个变量只在当前 shell 有效。如果你是在脚本里编译记得在脚本开头 export或者写进/etc/profile.d/下的一个 sh 文件里让所有会话都能看到。5. 那些让人白忙半天的隐蔽陷阱讲完主流程再说几个我实际踩过、也见过别人踩的坑。这些坑的共同特点是报错信息看起来和 libzip 无关但根因就在这。坑一pkg-config 的搜索路径被覆盖。有些环境里PKG_CONFIG_PATH被其他软件设置成了别的值你 export 的时候如果用了而不是:或者追加就会把原有路径冲掉。正确写法是export PKG_CONFIG_PATH/usr/local/lib64/pkgconfig:$PKG_CONFIG_PATH保留原有的。我见过一个案例某台机器上装了多个版本的库pkg-config 找到的是旧版本就是因为路径顺序不对。坑二多版本 libzip 共存导致的混乱。如果你先用 yum 装了 0.10又手动编译了 1.7 到/usr/local系统里就有两份。ldconfig -p可能显示两个pkg-config 找到哪个取决于路径顺序。这种情况下要么把旧的卸掉要么确保/usr/local的路径在 pkg-config 搜索顺序里靠前。排查的时候用pkg-config --variablelibdir libzip看看它到底指向哪个目录。坑三configure 参数写错。PHP 7.4 里 zip 扩展的参数是--with-zip不是老版本的--enable-zip。如果你照着旧教程写--enable-zipconfigure 可能不报错但也不启用或者报一个让人摸不着头脑的错。另外如果你要指定 libzip 的路径可以用--with-zip/usr/local但前提是那个路径下有正确的目录结构。坑四编译 PHP 时的链接顺序。极少数情况下libzip 装好了、pkg-config 也找到了但链接阶段报 undefined reference。这通常是链接顺序或者-lzip没带上导致的。检查config.log里关于 zip 的部分看看 configure 到底检测到了什么。config.log是排查 configure 问题的第一手资料比终端输出的那几行红字信息量大得多。坑五Docker 多阶段构建的路径问题。如果你在 builder 阶段编译了 libzip 到/usr/local但最终镜像里没有把/usr/local/lib64拷过去运行时会报找不到libzip.so。多阶段构建的时候库文件、头文件、pkg-config 文件都要考虑清楚哪些需要保留。下面这张表把常见现象和对应根因列一下方便对照排查现象可能根因排查命令No package libzipdevel 包未装或 .pc 不在搜索路径pkg-config --exists libziplibzip 0.11 were not met版本过低pkg-config --modversion libzip装完 devel 仍报错shell 缓存或 configure 缓存hash -r、rm config.cache链接阶段 undefined reference链接顺序或库路径问题查config.log运行时找不到 libzip.soldconfig 未更新或路径未配置ldconfig -p | grep libzip6. 从根上理解 pkg-config 的工作方式要彻底搞明白这个报错绕不开 pkg-config 这个工具。它本质上是个库信息查询器编译系统通过它来获取某个库的头文件路径、库文件路径、版本号、编译参数等信息。libzip 安装的时候会往某个目录放一个libzip.pc文件pkg-config 就是靠读这个文件来回答查询的。libzip.pc的内容大概长这样prefix/usr/local exec_prefix${prefix} libdir${exec_prefix}/lib64 includedir${prefix}/include Name: libzip Description: library for handling zip archives Version: 1.7.3 Libs: -L${libdir} -lzip Cflags: -I${includedir}pkg-config 默认会在/usr/lib/pkgconfig、/usr/share/pkgconfig、/usr/lib64/pkgconfig这些路径下找.pc文件。如果你把 libzip 装到了/usr/local它的.pc文件在/usr/local/lib64/pkgconfig这个路径不在默认搜索范围里所以必须通过PKG_CONFIG_PATH告诉 pkg-config。理解了这个机制很多问题就顺了。比如为什么装了 devel 包还是找不到因为 devel 包可能装到了非默认路径为什么版本显示不对因为 pkg-config 找到了另一个路径下的旧.pc文件。排查的时候pkg-config --variablepcfiledir libzip可以直接告诉你它读的是哪个文件非常有用。还有一个细节PHP 的 configure 脚本在检测 libzip 时会调用pkg-config --exists libzip和pkg-config --atleast-version0.11 libzip。前者判断存在性后者判断版本。两个都通过才会继续。所以你的目标就是让这两条命令都返回成功。# 模拟 configure 的检测逻辑 pkg-config --exists libzip echo exists ok pkg-config --atleast-version0.11 libzip echo version ok这两条都输出 okconfigure 就不会再报这个错了。如果第一条失败查路径和 devel 包如果第一条成功第二条失败查版本该升级升级。7. 一套可复用的排查动作清单最后把我自己常用的一套排查动作整理出来遇到类似某个库找不到或版本不够的问题基本都能套用。这套动作的核心思路是先定位再修复最后验证每一步都有明确的命令和预期输出。第一步读报错。区分是找不到还是版本不够。找不到就查 devel 包和 pkg-config 路径版本不够就查升级方案。第二步查现状。用pkg-config --modversion、pkg-config --variablepcfiledir、ldconfig -p三条命令把库的版本、配置文件位置、动态库加载情况摸清楚。第三步装依赖。根据发行版选对应的 devel 包装完hash -r清缓存重新验证 pkg-config。第四步版本不够就升级。优先用发行版的新源其次手动编译到/usr/local记得配PKG_CONFIG_PATH和ld.so.conf。第五步清理 PHP 的 configure 缓存重新 configure。失败就看config.log里面会有详细的检测过程。第六步编译安装后验证扩展。php -m | grep zip确认 zip 扩展加载了再写个简单脚本测试ZipArchive类能不能用。?php $zip new ZipArchive(); if ($zip-open(/tmp/test.zip, ZipArchive::CREATE) true) { $zip-addFromString(hello.txt, test content); $zip-close(); echo zip extension works\n; } else { echo zip extension failed\n; }这套流程走下来绝大多数 libzip 相关的问题都能解决。真正花时间的往往不是操作本身而是搞清楚为什么。一旦理解了 pkg-config 的机制和发行版包管理的差异这类报错就从玄学变成了按图索骥。我在实际使用中发现把PKG_CONFIG_PATH和ld.so.conf的配置写进一个初始化脚本里每次编译新软件前 source 一下能省掉大量重复排查的时间。尤其是那种需要频繁编译不同版本 PHP 的场景环境变量的一致性比什么都重要。踩过几次坑之后我现在养成了一个习惯任何手动编译安装的库装完立刻验证 pkg-config 和 ldconfig确认无误再往下走绝不带着不确定性进入下一步。
📝

华诺云谱内容团队

资深建站顾问 · 行业研究员

10年+企业数字化服务经验,专注智能建站、SEO优化与品牌营销,持续输出建站技巧、行业洞察与营销干货,已帮助5000+企业实现数字化增长。

你可能需要的服务

订阅华诺云谱资讯周报

每周一封,精选建站技巧、SEO与营销干货,直达邮箱。已有 8,000+ 企业主订阅,助你少走弯路。

↑