spec依赖检查机制
rpm包通过spec脚本来控制rpm包的安装过程,如果有依赖不满足,将通过yum/dnf工具提示到用户。那么spec文件的依赖是怎么检查的?
编译阶段:通过BuildRequires;运行阶段:通过Requires
1 | BuildRequires: python |
具体检查方式:
查看rpmbuild源码:Ftp - /releases/rpm-4.15.x/ :: Oregon State University Open Source Lab
BuildRequires被解释为使用宏__spec_buildrequires_template:
该宏具体内容可以通过rpm –eval展开:
1 | rpm --eval %{__spec_buildrequires_template} |
这里涉及到一个环境变量PKG_CONFIG_PATH,使用了pkg-config工具,关于该工具介绍查看:Guide to pkg-config (people.freedesktop.org)
该工具的作用:
- 避免硬编码lib库路径:
1 | gcc test.c `pkg-config --libs --cflags glib-2.0` |
- 依赖版本检查
1 | $ pkg-config --libs "bar >= 2.7" |
如果bar依赖foo,则使用以下命令将连带出完整的依赖链:
1 | [root@openEuler2003SP1 test]# pkg-config --libs --static foo |
我们常见的configure输出的package not found错误,其实就是来自pkg-config的判断:
1 | [root@openEuler2003SP1 test]# pkg-config --exists --print-errors xoxo |
我们再看下平时build阶段经常依赖的devel包,里面都有什么:
可以看到有三部分,header、so、pc
header对应到头文件函数声明,so对应的函数具体实现,pc就是pkg-config的元数据文件了,这三元组最终组合形成完整的依赖编译命令:
1 | gcc test.c -I/usr/include/foo -L/usr/lib -lbar -L/usr/lib -lfoo |
现在回到spec,BuildRequires不满足打印示例:
1 | [root@openEuler2003SP1 SPECS]# rpmbuild -ba daos.spec |
这些error依赖检查来自:
ts变量:transaction set,在rpmts.h中定义了一系列关于该变量的使用方法:
所以rpm检查依赖的底层逻辑是通过查询数据库,数据库路径可以通过宏查看:
1 | [root@openEuler2003SP1 SPECS]# rpm --eval "%{_db_backend}" |
它是一个bdb数据库(旧的也有使用sqlite:rpm.org - RPM Database Recovery)
devel包如何构建:linux - Building both devel and normal version of a RPM package - Stack Overflow
一般不会单独写一个devel的spec,而是和binary rpm的spec共用,通过在各个章节后面带devel标记区分:
1 | %package devel |