[已解决]spec文件中需要写Requires么

写 spec 文件时参考了苏姐在 wiki 里的翻译:

这么说写 spec 不需要写 Requires,我拿 bcloud 百度云客户端来做了测试(是个纯 python package),删掉 Requires 后能正常 build 出包,但是装上就不能正常运行,缺各种依赖(比如 python3-lxml 等等)。

那么

  1. 写 spec 到底需要 Requires 么
  2. 如果需要写 Requires, 除了从软件开发者上游得知需要哪些 Requires 外,只能在软件运行的时候试错得知 Requires 哪些包么

希望大家指点一下 :joy:

不懂 rpm 打包,只是说说我的想法。
或许 rpm 自动寻找依赖用的是 ldd 之类的东西,找出这个二进制文件依赖的 so 库然后自动添加这个库所在的包。
而 bcloud 应该是 python 写的吧,没法用上面这种方法分析出依赖来。

对,python 相关的模块没有分析出来,应该是你说的那样

  1. RPM 既然设计了那个 Tag 就是需要的。但是人是会懒的,所以不写就表示有自动化流程能够找到。

RPM 自动化 Provides/Requires 查找流程的原理是这样的:

RPM 在编译完之后,会把编译出来的文件列表(也就是你的 %{buildroot} 下的全部内容)传给脚本,脚本根据一些规则来在编译出来的文件中查找 Provides/Requires。

比如对于共享库 Requires 的自动查找就是先 filter 一下,找到 .so 结尾的文件,然后用 ldd 去读它 Require 的 symbols,然后通过 symbols 就知道需要哪个包了,同时也能读出它提供的 symbols,就可以 Provides 一下给别的包用。

4.9.1 版以后的 RPM 还提供了 fileattr,也就是你可以提前定义 filter,这样 RPM 就只会把满足 filter 的内容传给脚本。

参考 rpm.org/wiki/PackagerDocs/DependencyGenerator

RPM 本身带了一些上游的脚本(/usr/lib/rpm/fileattrs),openSUSE 又自己写了一些。比如我写的:

github.com/margueirte/golang-packaging
github.com/marguerite/nodejs-packaging

上游没有提供 Python 对应的脚本,openSUSE 的 Python 维护者又没写这样的脚本,就是你那种情况:必须手写。

  1. 你可以自己写 shell script 滤出来啊。

比如 python 导入模块的关键字是 import,那你用

grep -r “import” bcloud-xxx

就能得到不少东西。明显是一句自然语言的话的那可能是注释。它自己提供又被 import 的跟 import 系统包不太一样,python 主程序提供的也跟别的不一样,你大概就可以知道它 import 了哪些外部模块。通过外部模块名就能猜出来 openSUSE 的包名。

查了下 rpm.org 的文档,确实对于共享库 Requires 不需要写,对于 rpm 不能自动 generate 的 requires 需要打包者自己写。

自己的 rpmlint 结果也验证了这一点:

 Requires:       gtk3-data >= 3.4.0
Requires:       python3
Requires:       python3-base
Requires:       python3-gobject
Requires:       python3-kde4
Requires:       python3-pycrypto
Requires:       python3-cssselect
Requires:       python3-lxml
Requires:       python3-keyring >= 3.7
#Requires:       libwebkitgtk3
Requires:       sqlite3
Requires:       girepository-1_0
#Requires:       libnotify4
Requires:       dbus-1-python3
#Requires:       gnome-icon-theme-symbolic

  250s] RPMLINT report:
  250s] ===============
  252s] bcloud.noarch: W: explicit-lib-dependency libnotify4
  252s] bcloud.noarch: W: explicit-lib-dependency libwebkitgtk3
  252s] You must let rpm find the library dependencies by itself. Do not put unneeded explicit Requires: tags.

plus:膜拜苏姐的 nodejs 打包工具 :1:(居然是 ruby)

grep 来找 python 依赖的模块确实比较实用,我把这个想得复杂了。

关于 rpm 自动解决依赖的描述:
rpm.org/max-rpm/s1-rpm-depend-auto-depend.html
关于 packager 手动解决依赖:
rpm.org/max-rpm/s1-rpm-depend-manual-dependencies.html