1. 这个报错到底卡在哪从一次编译翻车说起如果你正在一台干净的 Linux 机器上编译 PHP 7.4敲完./configure之后终端突然甩出这么一行红字configure: error: Package requirements (libzip 0.11) were not met: No package libzip先别急着怀疑人生。这个报错的意思非常直白PHP 在配置阶段想启用 zip 扩展也就是--with-zip它通过pkg-config去系统里找libzip这个库结果没找到或者找到的版本低于 0.11于是 configure 直接罢工。很多人第一次遇到会懵因为明明记得以前编译 PHP 7.3 的时候没这回事。原因在于 PHP 7.4 做了一个重要改动内置的 zip 扩展从原来绑定的libzip旧接口迁移到了libzip的新 API并且强制要求libzip 0.11。在 PHP 7.3 及更早版本zip 扩展用的是自己打包的一份老代码对系统库依赖没那么挑到了 7.4官方把这块重写了直接依赖系统里的libzip开发包。所以只要你的系统里没装libzip-devel或者装了但版本太老configure 就会在检查依赖这一步挂掉。这篇文章就是围绕这个报错展开的。我会把它的来龙去脉、不同发行版下的解决路径、版本不够时的源码编译方案、以及一堆踩过的坑全部摊开讲清楚。适合正在自己编译 PHP 7.4 的后端开发、运维也适合任何被pkg-config依赖检查折磨过的朋友。看完你应该能做到看到类似Package requirements (xxx yyy) were not met的报错心里有一套固定的排查套路而不是到处复制粘贴碰运气。2. 先搞懂原理configure 是怎么检查依赖的2.1 pkg-config 在编译流程里扮演什么角色要彻底解决这个问题得先明白 configure 脚本是怎么判断“库在不在”的。绝大多数现代 C 项目包括 PHP在 configure 阶段会调用一个叫pkg-config的工具。这个工具的作用是帮编译系统回答三个问题这个库装在哪、头文件路径是什么、链接时需要加哪些参数。每个库在安装时通常会在系统的某个目录比如/usr/lib/pkgconfig或/usr/lib64/pkgconfig放一个.pc后缀的文本文件里面记录了版本号、Cflags、Libs等信息。pkg-config --exists libzip就是去这些目录里找libzip.pc找到就返回成功找不到就返回失败。PHP 的 configure 脚本里有一段类似这样的检查逻辑PKG_CHECK_MODULES([LIBZIP], [libzip 0.11], [...], [AC_MSG_ERROR([Package requirements (libzip 0.11) were not met])])PKG_CHECK_MODULES这个宏会先调pkg-config --exists libzip 0.11如果返回非零就执行后面的错误分支把那段你看到的报错打印出来。所以报错信息里No package libzip是pkg-config的原话它压根没找到libzip.pc这个文件。2.2 为什么“装了库”还是报找不到这是最经典的困惑点。很多人说“我明明yum install libzip装过了啊”。问题在于运行时的库和开发用的库是两码事。运行时包如libzip、libzip4只提供.so动态库文件供已经编译好的程序运行使用。开发包如libzip-devel、libzip-dev才提供头文件.h和pkg-config的.pc文件。configure 需要的是后者。你只装了运行时包pkg-config自然找不到.pc文件于是报No package libzip。这个区分在 Debian/Ubuntu 和 RHEL/CentOS 系里都存在只是包名不同。2.3 版本号 0.11 这个门槛是怎么来的libzip在 0.11 版本做了一次比较大的 API 重构引入了zip_open系列的新接口废弃了一批老函数。PHP 7.4 的 zip 扩展正是基于这套新接口写的所以硬性要求 0.11 以上。如果你系统自带的libzip是 0.10 甚至更老一些老发行版就是这样即使装了 devel 包pkg-config --exists libzip 0.11依然会失败报错可能变成Requested libzip 0.11 but version of libzip is 0.10.x。这时候光装包没用得升级或者自己编译。3. 按发行版对症下药三条主流解决路径3.1 Debian / Ubuntu 系一条 apt 命令搞定如果你用的是 Debian、Ubuntu 或者它们的衍生版解决起来最省事。直接装开发包sudo apt-get update sudo apt-get install -y libzip-dev装完之后验证一下pkg-config --modversion libzip正常会输出类似1.7.3的版本号。只要大于等于 0.11重新跑./configure就能过。这里有个小细节Ubuntu 18.04 自带的libzip-dev版本是 1.1.2满足要求但如果你用的是更老的 16.04可能只有 1.0.x那就得走源码编译路线了。提示装完libzip-dev后如果pkg-config还是找不到先确认pkg-config本身装了没有apt-get install pkg-config有些精简系统默认不带。3.2 RHEL / CentOS / 同类系统注意包名和仓库在 RHEL 7、CentOS 7 这类系统上包名是libzip-develsudo yum install -y libzip-devel但这里有个大坑CentOS 7 默认仓库里的libzip版本是 0.10.1低于 0.11。也就是说你装完libzip-develpkg-config --modversion libzip会告诉你 0.10.1configure 依然会失败报错变成版本不满足。这是很多人卡住的地方明明装了却还是不行。解决办法有两个方向。一是启用 EPEL 或者第三方仓库看有没有更高版本二是直接源码编译libzip下一节详细讲。CentOS 8 / RHEL 8 及更新的版本自带libzip通常在 1.x装libzip-devel即可满足。3.3 源码编译 libzip版本不够时的终极方案当系统仓库版本太低或者你没有 root 权限装系统包时源码编译是最可靠的路子。整个流程分下载、编译、安装、让 pkg-config 找到它四步。先确认编译工具链齐全sudo yum install -y gcc gcc-c make cmake zlib-devellibzip依赖zlib所以zlib-devel必须装。然后下载源码包以 1.7.3 为例你可以选更新的稳定版wget https://libzip.org/download/libzip-1.7.3.tar.gz tar -xzf libzip-1.7.3.tar.gz cd libzip-1.7.3用 cmake 构建指定安装到/usr/localmkdir build cd build cmake .. -DCMAKE_INSTALL_PREFIX/usr/local make -j$(nproc) sudo make install装完之后关键一步是让pkg-config能找到它。/usr/local/lib/pkgconfig默认可能不在搜索路径里需要设置环境变量export PKG_CONFIG_PATH/usr/local/lib/pkgconfig:$PKG_CONFIG_PATH验证pkg-config --modversion libzip输出 1.7.3 就对了。这时候再回去编译 PHPconfigure 就能顺利通过。注意这个PKG_CONFIG_PATH是当前 shell 的临时变量如果你开新终端或者用脚本编译记得重新 export或者写进~/.bashrc。4. 完整实操从报错到编译通过的每一步4.1 复现问题与初步诊断假设你在一台 CentOS 7 上编译 PHP 7.4先跑 configure./configure --prefix/usr/local/php74 --with-zip --with-zlib报错出现后别急着重跑先做诊断。第一步确认pkg-config在不在which pkg-config第二步直接问它 libzip 的情况pkg-config --exists libzip echo found || echo not found pkg-config --modversion libzip如果第一条输出 not found说明.pc文件不存在要么没装 devel 包要么路径不对。如果输出了版本号但低于 0.11那就是版本问题。这个诊断顺序很重要能帮你快速定位到底是“没装”还是“版本低”避免盲目操作。4.2 安装依赖并处理版本冲突诊断出是版本低之后先尝试装系统包sudo yum install -y libzip-devel pkg-config --modversion libzip如果输出 0.10.1确认系统仓库版本不够。这时候不要试图用yum强行升级容易把系统依赖搞乱。直接走源码编译。编译前建议先看看系统里是不是已经有一个老版本的libzip.so避免链接时混用ldconfig -p | grep libzip如果显示/usr/lib64/libzip.so.2之类的老版本而你新装的是/usr/local/lib/libzip.so链接器可能优先用老的。稳妥做法是在 configure PHP 时显式指定路径或者确保/usr/local/lib在链接搜索路径靠前的位置。4.3 重新配置 PHP 并验证 zip 扩展依赖搞定后回到 PHP 源码目录。建议先清理上次失败的配置缓存make clean rm -f config.cache然后重新 configure。如果你把 libzip 装在了/usr/local可以显式告诉 PHP./configure --prefix/usr/local/php74 \ --with-zip \ --with-zlib \ PKG_CONFIG_PATH/usr/local/lib/pkgconfigconfigure 通过后编译安装make -j$(nproc) sudo make install装完验证 zip 扩展是否真的生效/usr/local/php74/bin/php -m | grep zip输出zip就说明成功了。再进一步确认版本信息/usr/local/php74/bin/php -i | grep -i zip support应该能看到Zip support enabled以及libzip version的具体版本号。这一步很关键因为 configure 通过不代表运行时一定能加载动态库路径不对的话php -m会报找不到.so。4.4 动态库路径的收尾处理如果php -m报error while loading shared libraries: libzip.so.x: cannot open shared object file说明运行时链接器找不到新装的 libzip。解决办法是把它加进系统库搜索路径echo /usr/local/lib | sudo tee /etc/ld.so.conf.d/libzip.conf sudo ldconfigldconfig会刷新动态库缓存之后 PHP 就能正常加载了。这个步骤在源码编译第三方库时几乎每次都要做属于肌肉记忆级别的操作。5. 常见问题速查与避坑经验5.1 报错信息对照表不同阶段、不同原因会给出不一样的报错下面这张表帮你快速对号入座。报错信息根本原因解决方向No package libzip没装 devel 包.pc文件不存在装libzip-devel或libzip-devRequested libzip 0.11 but version of libzip is 0.10.x装了但版本太低源码编译新版 libzipPackage libzip, required by virtual:world, not foundpkg-config 搜索路径不含安装目录设置PKG_CONFIG_PATHerror while loading shared libraries: libzip.so运行时找不到动态库配置ld.so.conf并ldconfigconfigure 通过但php -m无 zip编译时没真正启用或链接失败检查 configure 参数和 config.log5.2 几个容易踩的坑坑一只装运行时包。前面反复强调过libzip和libzip-devel是两回事。很多人yum install libzip之后以为万事大吉结果 configure 照样报错。记住编译期要的是 devel 包。坑二PKG_CONFIG_PATH 没生效。源码编译 libzip 到/usr/local后pkg-config默认不搜这个目录。你 export 了变量但如果是在一个脚本里编译 PHP脚本可能没继承这个变量。稳妥做法是在 configure 命令后面直接带上PKG_CONFIG_PATH...或者写进/etc/profile.d/。坑三多版本 libzip 混用。系统里同时存在/usr/lib64/libzip.so老版本和/usr/local/lib/libzip.so新版本时链接器可能挑错。用ldconfig -p | grep libzip看清楚有几个版本必要时调整搜索顺序。坑四忘了make clean。configure 失败后源码目录里可能残留了半截配置。直接重跑 configure 有时会用上旧的缓存结果导致行为诡异。养成失败后make clean rm -f config.cache的习惯。坑五zlib 没装。libzip 本身依赖 zlib编译 libzip 时如果报zlib.h not found说明zlib-devel没装。这个依赖链要提前理清。5.3 一个通用的排查思路遇到任何Package requirements (xxx yyy) were not met的报错都可以套用这套流程pkg-config --exists xxx判断库在不在。pkg-config --modversion xxx看版本够不够。不在就装 devel 包版本低就升级或源码编译。源码编译后设置PKG_CONFIG_PATH。运行时再报错就配ld.so.conf加ldconfig。这套思路不只适用于 libzip编译其他依赖 pkg-config 的库比如 libxml2、openssl、curl时同样管用。掌握了它以后遇到类似报错基本能自己搞定不用再满世界搜。6. 关于编译环境隔离的一点个人做法我在实际编译 PHP 这类对依赖版本敏感的项目时越来越倾向于把依赖装到一个独立前缀下而不是直接怼进/usr/local。比如给 libzip 单独指定-DCMAKE_INSTALL_PREFIX/opt/deps/libzip然后在编译 PHP 时把PKG_CONFIG_PATH和LDFLAGS都指向这个目录。这样做的好处是不同项目对同一个库的版本要求可能冲突隔离之后互不干扰卸载也干净直接删目录就行。具体操作上configure PHP 时这样写./configure --prefix/usr/local/php74 \ --with-zip \ PKG_CONFIG_PATH/opt/deps/libzip/lib/pkgconfig \ LDFLAGS-L/opt/deps/libzip/lib -Wl,-rpath,/opt/deps/libzip/lib注意那个-Wl,-rpath它把运行时库搜索路径直接编进可执行文件里这样连ldconfig都不用配PHP 启动时自己就知道去哪找 libzip。这个技巧在部署到多台机器、又不想每台都改系统库配置时特别省心。踩过几次“本地编译好好的换台机器就报找不到库”的坑之后我现在基本都会带上 rpath。另外提醒一句源码编译 libzip 时如果机器上 cmake 版本太老CentOS 7 自带的是 2.8可能构建失败。这时候要么升级 cmake要么用 libzip 提供的 autotools 方式构建老版本支持./configure新版本主推 cmake。确认 cmake 版本用cmake --version低于 3.0 的话建议先升级否则后面构建各种报错会让你怀疑人生。