☰
OpenEuler源码编译liblz4报错解决:lz4-devel开发包是关键
2026/10/7 3:10:19 网站建设 项目流程

OpenEuler 上做源码编译,最烦的往往不是机器卡顿,而是 configure 阶段突然被人当头一棒。解压好源码包、信心满满敲下./configure,结果没跑几行就报出checking for liblz4... no,然后紧跟一行configure: error: Package requirements (liblz4) were not met,整个构建直接中止。这种问题在 OpenEuler 服务器上非常典型,尤其在编译 QEMU、libvirt、kmod 这类跟虚拟化、存储相关的组件时,几乎是绕不开的一道小坎。

这个报错看着吓人,根子却很简单:系统里缺了 liblz4 的开发包。注意,是“开发包”,不是 lz4 命令本身。很多人第一反应是dnf install lz4,装完发现还是同样的报错,那是因为装错了包。这篇文章按我自己的实战顺序,把这个问题的“为什么”“怎么查”“怎么解”全部拆开讲,顺便把 ARM 架构 OpenEuler、虚拟化场景相关的坑也一起说清楚,适合正在 OpenEuler 上做源码编译的运维、开发,以及被 Package requirements 类报错卡住的新手参考。

1. 第一次遇到这个报错:configure 在半路上“撂挑子”

1.1 先还原一下现场

绝大多数见到这个报错的场景都是这样的,你从源码构建某个软件,进入源码目录后执行:

./configure

屏幕滚动一会儿,然后卡住,输出大概长这样:

checking for liblz4... no configure: error: Package requirements (liblz4) were not met: No package 'liblz4' found Consider adjusting the PKG_CONFIG_PATH environment variable if you installed software in a non-standard prefix. Alternatively, you may set the environment variables LIBLZ4_CFLAGS and LIBLZ4_LIBS to avoid the need to call pkg-config.

这一屏信息透露了两点:第一,configure 在探测名为liblz4的库时没有找到;第二,它提示你可以调PKG_CONFIG_PATH,也可以强行设LIBLZ4_CFLAGS和LIBLZ4_LIBS绕过检测。可很多新手看到后面两行反而更懵:这两个环境变量从哪来?设成什么值?别急,后面逐条说。

这个报错本质上不是编译器坏了,也不是源码包坏了,而是 configure 的依赖探测机制用了 pkg-config,而 pkg-config 在系统里找不到liblz4的元数据文件。这时候 configure 宁可停下,也不敢带着残缺依赖继续编译。这种“宁可报错也不硬编”的风格,是 autotools 生态的默认策略,保的是构建过程的稳定和后续运行期的安全。

1.2 liblz4 到底是什么“拦路虎”

liblz4 是 lz4 压缩算法的 C 语言库接口。lz4 是一个以极快压缩解压速度著称的压缩算法,很多底层项目会在可选项里默认带上它。说几个常见场景:

  • QEMU 的某些块设备格式、压缩相关特性会依赖 liblz4;
  • libvirt 的日志、快照、内存转储功能经常需要 liblz4;
  • systemd 的 journal 日志压缩,在较新版本里默认倾向用 lz4;
  • 部分存储中间件、数据库、分布式文件系统客户端,也会把 lz4 列为编译依赖。

所以你在 OpenEuler 上源码编译这些项目时,configure 阶段就多了一道类似开关的检查:如果 liblz4 存在,就开启相关支持;如果不存在,还没到“降级编译”这一步,很多项目干脆直接报错中止。尤其当你是在构建虚拟化相关组件时,这个依赖几乎是必经之路。

2. 先搞清楚包的关系:lz4 和 lz4-devel 不是一回事

2.1 运行库与开发库的分工

在 RPM 系 Linux 发行版里,一个开源库通常被拆成多个包:

  • lz4:命令行工具(lz4 命令)和运行时动态库liblz4.so.1。日常跑程序、用命令压缩文件,有这个就够了。
  • lz4-devel:编译期需要的头文件,例如/usr/include/lz4.h、/usr/include/lz4frame.h,以及最关键的文件/usr/lib64/pkgconfig/liblz4.pc。
  • lz4-static:静态库liblz4.a,一般只有在需要静态链接时才用。

configure 检查liblz4时,依赖的正是那个.pc文件。它相当于图书馆里的索引卡片:记录了这个库的头文件路径、库文件路径、链接参数、版本号。pkg-config 通过读这张卡片,才知道编译命令该怎么写。你只装lz4,就好比书在书架上,但检索目录里没有登记,编译器自然认为“没有这本书”。这就是为什么dnf install lz4不能解决问题。

2.2 用 dnf 反向定位开发包

在 OpenEuler 上,正确做法是装lz4-devel。但为了让你以后遇到其他类似报错也能举一反三,我建议先学会“反向查包”。先搜一下仓库里有哪些 lz4 相关包:

dnf search lz4

通常输出会包括:

  • lz4.x86_64
  • lz4-devel.x86_64
  • lz4-static.x86_64

如果你不确定哪个包包含了liblz4.pc,可以用 dnf 的provides功能按文件反查:

dnf provides "*/liblz4.pc"

这个命令会搜索仓库所有已收录包的文件清单,凡是包含该文件名的包都会列出来。在 OpenEuler 20.03、22.03 这类版本上,返回结果基本就是lz4-devel。这个方法价值很大,*/通配符会忽略路径前缀,不管.pc文件是在/usr/lib64/pkgconfig还是/usr/share/pkgconfig,都能一把抓出来。

2.3 安装并验证

确认包名后直接安装:

dnf install -y lz4-devel

安装完成后,先验证一下 pkg-config 是否已经能识别这个库:

pkg-config --modversion liblz4

如果输出类似1.9.3,说明 pkg-config 已经找到了这张“索引卡片”。此时再回头看/usr/lib64/pkgconfig/liblz4.pc,这个文件就是关键,它存在且内容正确,configure 就不会再报no。

提示:pkg-config --modversion liblz4输出的版本号可以帮你判断当前能用的 lz4 版本。如果项目对版本有硬性要求(比如需要 1.9 以上),这一步就能提前发现矛盾。

3. 实操演示:从报错到完整编译通过

3.1 环境准备与安装命令

我这里以一台 OpenEuler 20.03 x86_64 服务器为例,现场模拟一遍完整过程。假设你要构建的是某个依赖 liblz4 的组件,最开始系统状态是“缺 lz4-devel”。执行顺序如下:

dnf update -y dnf install -y gcc gcc-c++ make pkg-config autoconf automake

第一组命令是常规编译环境,必须有 pkg-config,否则任何基于 pkg-config 检测的软件都会直接报错。然后安装 lz4-devel:

dnf install -y lz4-devel

装完以后不用急着重跑 configure,先做三件小事:

pkg-config --exists liblz4 && echo "exists" pkg-config --cflags liblz4 pkg-config --libs liblz4

正常情况下,--cflags输出-I/usr/include或空值,--libs输出类似-llz4。这说明编译参数已经被正确解析出来,configure 再调用同一个接口时就不会迷路了。

3.2 清理残留缓存再重跑 configure

这里有一个很容易踩的坑:如果 configure 之前已经失败过,有些项目会在源码目录里生成config.cache或config.log,并把失败结果记进去。第二次重跑时,configure 可能直接读缓存,跳过部分检测,这会导致明明装好了包,日志里仍显示旧的状态。

稳妥做法是执行:

make distclean 2>/dev/null || true rm -f config.cache rm -rf autom4te.cache

然后重新执行:

./configure --prefix=/usr/local

这次观察输出,你会发现:

checking for liblz4... yes

看到yes那一刻,悬着的心基本可以放下了。后续就是常规操作:

make -j$(nproc) make install

3.3 一个临时绕过方案:LIBLZ4_CFLAGS 和 LIBLZ4_LIBS

还有一个场景需要提一下。如果你所在的网络环境短时间内装不了 lz4-devel,但又急着把 configure 跑完,可以利用报错信息里给出的第二个引导方式,手动指定库位置。假设你已经从别的机器拷入了liblz4.so和lz4.h,放在/opt/lz4下,可以这样临时设置:

export LIBLZ4_CFLAGS="-I/opt/lz4/include" export LIBLZ4_LIBS="-L/opt/lz4/lib -llz4" ./configure

configure 会跳过 pkg-config 检测,直接采用你给的两个变量。这属于“手动绕行”方案,能解一时燃眉之急,但长期维护不推荐,因为它绕过了 pkg-config 的版本检验,如果版本不对,问题会延迟到链接期甚至运行期才暴露。

4. ARM 架构 OpenEuler 上的编译故事

4.1 ARM 架构下的库路径差异

最近几年 ARM 架构的 OpenEuler 服务器越来越多,有些朋友在鲲鹏这类机器上做虚拟化部署,自己从源码编译 libvirt-daemon-kvm 相关组件,结果同样被liblz4卡住。ARM 架构下有个和 x86 不太一样的细节:系统的库目录同样是/usr/lib64,但软件仓库的包名会标注aarch64。

在 ARM 机器上执行:

uname -m

输出是aarch64。此时用 dnf 安装 lz4-devel 时,dnf 会自动选择架构正确的包。但如果你是从源码自行编译 lz4,再让目标项目去依赖它,就需要特别留意 pkg-config 的搜索路径。自行编译安装到/usr/local时,.pc文件通常落在/usr/local/lib64/pkgconfig,而这个路径不一定在默认搜索范围内。

验证当前搜索范围可以这样看:

pkg-config --variable pc_path pkg-config

如果输出里没有/usr/local/lib64/pkgconfig,就要手动把路径追加到环境变量:

export PKG_CONFIG_PATH=/usr/local/lib64/pkgconfig:$PKG_CONFIG_PATH

这个知识点在 ARM 交叉编译时尤为重要。如果你在 x86 主机上交叉编译 ARM 版本软件,必须把交叉工具链里那份 pkg-config 路径配好,否则即便宿主机的 liblz4 装得再全,目标 ARM 环境依然会被判定为“找不到”。

4.2 虚拟化场景中的连环依赖

很多人在 ARM 架构 OpenEuler 上源码构建 libvirt-daemon-kvm 栈时会发现,liblz4 只是第一关,后面还连着yajl、libpciaccess、numactl等一系列依赖。这种“连环依赖”在编译虚拟化组件时特别常见,我习惯的做法是提前一次性把基础依赖装齐:

dnf install -y lz4-devel yajl-devel libpciaccess-devel numactl-devel \ libattr-devel libcap-ng-devel device-mapper-devel

虽然每个项目报错时都可以单独反查,但虚拟化组件之间共享依赖很多,先装齐一批,后面配置会顺畅得多。

注意:源码树里如果有多个组件,比如 libvirt 和 QEMU 分开构建,每个组件都建议单独跑一遍pkg-config --exists liblz4做验证,避免前一个组件编译通过就默认所有依赖都到位。

5. 疑难杂症避坑手册:为什么装了包仍然报 no

5.1 自定义安装路径导致 PKG_CONFIG_PATH 失效

最常见的“装了包还报 no”,发生在从源码自行编译 lz4 的场景。默认包管理器安装的 lz4-devel,.pc文件放在标准路径,pkg-config 一定能找到;但如果你为了给某个老项目适配特定版本,手动编译安装了一份 lz4,.pc文件大概率落在/usr/local/lib/pkgconfig或/opt/lz4/lib/pkgconfig这类非标准路径里。此时 pkg-config 不认识这个地方,自然报 no。

解决办法很简单,把路径加进环境变量:

export PKG_CONFIG_PATH=/opt/lz4/lib/pkgconfig:$PKG_CONFIG_PATH ./configure

经验是优先使用--define或直接把.pc文件软链到标准目录,实在图省事再用环境变量。但环境变量的缺点很明显:换一个终端窗口就丢了,所以写进~/.bashrc前要想清楚,避免影响后续其他项目。

5.2 多版本 lz4 与 configure 缓存残留

另一种“灵异事件”是:明明 pkg-config 能查到 liblz4,configure 里还是报 no。原因往往出在 configure 的缓存上。某些源码包即使不加config.cache参数,也会在autom4te.cache或config.log里记录探测结果。切换分支、更换依赖版本后,旧记录还在,configure 比较“懒”,直接用了旧结论。

处理方式:

rm -rf autom4te.cache config.cache config.log ./configure

另外还有一种情况是 pkg-config 查到的版本和项目要求的版本不一致。比如项目需要liblz4 >= 1.9.0,系统里是 1.8.2,configure 会把失败信息写得更详细,一般会带上版本冲突的提示。此时要么升级系统包仓库,要么从更高版本源码自编译 lz4 并放到自定义路径。

5.3 32 位与 64 位架构混装

在多架构支持场景下,如果你在 64 位 OpenEuler 上编译 32 位程序,会遇到一个非常隐蔽的问题:系统里装的是lz4-devel.x86_64,它提供/usr/lib64/pkgconfig/liblz4.pc;而 32 位编译需要的是/usr/lib/pkgconfig/liblz4.pc,或至少库文件是 32 位版本。此时 pkg-config 仍然能查到 liblz4,但链接时会对不上位。

排查方式:

file /usr/lib64/liblz4.so file /usr/lib/liblz4.so

如果目标是 32 位,安装对应架构的开发包:

dnf install -y lz4-devel.i686

这个“位数不匹配”的问题在容器镜像里更容易被掩盖,因为镜像里可能同时存在多个架构的 pkg-config 路径,环境变量一叠加,搜索顺序就可能出错。建议在 configure 之前用pkg-config --variable=libdir liblz4确认实际库路径,再判断是否符合当前构建目标。

5.4 常见问题速查表

现象直接原因快速排查命令解决办法
configure 报 liblz4 no缺少 lz4-develpkg-config --modversion liblz4dnf install -y lz4-devel
pkg-config 找不到 .pc.pc 在非标准路径pkg-config --variable pc_path pkg-config设置 PKG_CONFIG_PATH
装了包仍报 noconfigure 缓存残留ls config.cache删除缓存重新 configure
链接时找不到 liblz4.so只装了 dev 头文件ldconfig -p | grep lz4安装 lz4 运行时库
32/64 位数不匹配架构混装file /usr/lib64/liblz4.so安装对应架构的 devel 包
版本过低仓库版本旧dnf list lz4-devel更新仓库或自编译新版本

这张表可以打印出来贴在工位旁边,遇到类似问题先对照一遍,多半不用看日志就能定位。

6. 事后复盘:给新手的速查清单和个人体会

6.1 一条通用排查套路

liblz4 这个 case 解决之后,其实你掌握的是一个更通用的技能。以后再遇到任何Package requirements (xxx) were not met报错,都可以按下面这三步走:

  1. 用dnf provides "*/xxx.pc"反查提供该.pc文件的 RPM 包名;
  2. 安装对应的-devel包,验证pkg-config --modversion xxx能输出版本号;
  3. 删除config.cache和autom4te.cache,再重跑./configure。

这三步能覆盖九成以上的类似问题。剩下那一成,基本是自定义安装路径和架构混装,用前面表格里的方法也能快速定位。

6.2 我踩过几次坑之后的一些体会

说实在的,liblz4 这个报错在编译依赖里算是最温和的一类,因为你只要反查包名、装上-devel就能解决。真正恶心的是“包装对了但路径没找对”的隐性问题,比如你自己编译了一份 lz4 到自定义目录,后面所有依赖它的项目都要求你配置 PKG_CONFIG_PATH,一旦忘了,报错又会回到最初那行checking for liblz4... no。

我个人现在编译任何依赖较多的项目时,都会先刻意做两件事:第一,把dnf provides反查结果归档到项目 README 里,防止同事或未来的自己重新踩坑;第二,在 configure 之前先看一眼pkg-config --modversion和pkg-config --libs的输出,确认依赖版本符合预期再继续。这样看似多花半分钟,省下的却是链接阶段排查问题的几小时。

如果你正在被这个报错困扰,按上面第 2 节和第 3 节的操作顺序走一遍,基本十分钟内能解决。以后再遇到类似的Package requirements报错,别忘了你已经掌握了一套通用排查方法,别再被这些“刚刚好差一个开发包”的报错唬住了。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询