如何优雅的处理依赖

rpm 的自动依赖是非常有用的特性,但在打包某些软件时,常常会扫描出错误的依赖(如,保存在非标准目录的私有库)。如果你希望精确控制依赖,可以使用 rpm 4.9 加入的 filter 特性。

此功能仅在以下情况使用

  • rpm 为 noarch 包;
  • rpm 为指定架构的包,但二进制文件不在 $PATH 或 libexecdir,共享库不在 libdir 目录。

Old ways

旧方法使用外部宏提供 filter

  • %filter_requires_in [-P]:防止扫描文件/目录的 Requires (pre-scan filtering)
  • %filter_provides_in [-P]:防止扫描文件/目录的 Provides (pre-scan filtering)
  • %filter_from_requires:从 Requires 流中删除匹配项 (post-scan filtering)
  • %filter_from_provides:从 Provides 流中删除匹配项 (post-scan filtering)

注意

  • 宏建议定义在 %description 之前,任何其他定义之后;
  • 有些 RPM 版本会传递 buildroot 前缀,建议正则式不使用 ^ 符号;

示例
不提供 perl 架构相关的扩展库

1
%filter_provides_in -P %{perl_archlib}/(?!CORE/libperl).*\.so$

不添加 mono 和 perl 依赖至 RPM

1
%filter_from_requires /mono/d; /perl/d;

最后,调用 %filter_setup 执行过滤动作。注意,旧方法会在之后的版本删除。

New ways

新方法使用内部接口提供的宏实现 filter

  • %__requires_exclude_from:防止扫描文件/目录的 Requires (pre-scan filtering)
  • %__provides_exclude_from:防止扫描文件/目录的 Provides (pre-scan filtering)
  • %__requires_exclude:从 Requires 流中删除匹配项 (post-scan filtering)
  • %__provides_exclude:从 Provides 流中删除匹配项 (post-scan filtering)

注意

  • 宏建议定义在 %description 之前,任何其他定义之后;
  • 使用 POSIX.2 标准正则表达式,文字字符 ^.[$()|*+?{ 需反斜杠转义。由于 rpm 将 \ 解析为 spec 文件的一部分,因此需要 2 个 \ 进行转义。

示例

1
2
%global __requires_exclude_from ^%{_docdir}/.*$
%global __requires_exclude ^/usr/bin/(python|perl)$

两种方法的对比

旧宏(多次调用) 旧宏参数值(单引号内的值) 解释 新宏参数值 新宏(仅一次调用)
%filter_provides_in(P) grep -v [-P] 'RE' Pre-scan, 不匹配该位置的 provides 正则式 %__provides_exclude_from
%filter_requires_in(P) grep -v -P '(A|B)' Pre-scan, 不匹配该位置的 requires ^(A|B)$ %__requires_exclude_from
%filter_from_provides sed '表达式' Post-scan, 删除匹配的 provides 正则式 %__provides_exclude
%filter_from_requires sed '/A/d; /B/d;' Post-scan, 删除匹配的 requires ^(A|B)$ %__requires_exclude


参考

– EOF –