RPM 打包冲突的库

RPM 打包冲突的库

对于提供名称上遮盖系统库的库的 RPM 打包来说,最佳实践是什么?

背景: 对于 RPM 支持的 Linux 系统,我正在打包一个“自包含”的应用程序foo,该应用程序希望位于 /opt 下并提供尽可能多的自己的依赖项,以免依赖主系统上安装的版本。(foo使用 LD_LIBRARY_PATH 来避免系统库。)

不幸的是,其中一个foo依赖项是库,其版本与主系统所需的grunk版本完全相同。RPM 的自动libgrunk.so提供:然后,generation 会将两个 RPM 标识为提供此库。(事实并非如此 — 只有系统包才会让任何程序都可以使用该库,而 包foo只会让 可以使用该库foo。)

这有时会使自动依赖性解析变得混乱。例如,yum可能会安装错误的包,或者在需要两个包时只安装一个包。

例子:

grunk-libs-1.2-3.$arch.rpm              # System Library
  Files:
    %{_libdir}/libgrunk.so.1
    %{_libdir}/libgrunk.so.1.2
  Provides:
    libgrunk.so.1()(%{_arch})

foo-x.y.z-r.$arch.rpm                   # App
   Files:
     /opt/foo
     /opt/foo/bin/...
   Requires:
     libgrunk.so.1()(%{_arch})          # foo needs grunk, but wants its own instance

foo-grunklibs-1.2-1.$arch.rpm           # App Dependency
  Files:
    /opt/foo/libs/libgrunk.so.1
    /opt/foo/libs/libgrunk.so.1.2
  Provides:
    libgrunk.so.1()(%{_arch})           # <-- same as from system "grunk-libs"

我暂时禁用了 AutoReqProv,但我希望能够利用 RPM 的自动功能和依赖项生成。我希望 RPM 知道确实foo.rpm需要foo-grunklibs.rpm后者的libgrunk.so.1,但也知道主系统 rpm 中的相同库是不够的。

我认为我已经达到常规使用的极限了。有没有一种打包技术可以解决这个问题?

答案1

经过一段时间的考虑,我认为更正确的方法是使用 RPM 虚拟资源“命名空间”。例如:

Provides:  resource               # 'resource' is available to the whole system
Provides:  namespace(resource)    # 'resource' is specifically available only to "namespace"

RPM 最终看起来像这样:

grunk-libs.rpm
  Provides:  libgrunk.so.1()(%{_arch})       # System library.  unchanged

foo.rpm
  Requires:  /bin/sh
  Requires:  libc.so.6()(%{_arch})
  Requires:  foo(libgrunk.so.1()(%{_arch}))  # Note special foo(...) namespace

foo-grunklibs.rpm
  Provides:  foo(libgrunk.so.1()(%{_arch}))  # Note special foo(...) namespace

这样,foo对特殊构建的依赖性libgrunk就无法通过普通的 RPM 来满足grunk-libs,而必须由该库的 foo 特定构建来满足。

我的概念证明如下:

Name:     foo
...
Source99: find-namespaced-requires     # Here's the magic

%define    _use_internal_dependency_generator 0
%define    __find_requires %{SOURCE99} foo /bin/sh glibc

脚本查找命名空间需要包装标准 RPM%{_rpmconfigdir}/find-requires并过滤其输出。它的第一个参数是"foo(...)"要使用的命名空间 (),后续参数是依赖项或提供依赖项的 RPM,这些依赖项应该不是被命名空间化。在这个例子中,我想要foo需要主系统的 /bin/sh 以及来自 的普通 libc、libdl、libm 等glibc,但其他所有依赖项都应假定为特定于foo

通过将上述大部分内容包装在构建时 RPM 中并说类似的话,可以使其更清晰、更通用:

Name:          foo
BuildRequires: special-deps-macros

%define _namespace            foo      # defaults to %{name} ?
%define _generic_dependencies ...      # defaults to /bin/sh glibc libselinux ?

相关内容