Collect all RPMs that are needed by a package to m

2019-12-16 19:36发布

问题:

I need to copy all of the RPMs from a CentOS repo that are needed to build a custom version of CentOS for a DVD.

Essentially I need a complete list of the packages needed by my custom RPM so that I can copy them to the ISO image I am building.

I have a custom RPM(s) here that is not in the repo so I can't use yum deplist.

When I do rpm -qpR it is close but it lists things that are not files with pathnames or packages.

Files are easy because I can loop with repoquery --qf='%{name}' -f file-name

Packages are easy too because they are what I need.

But I get dependencies from rpm -qpR like config(alsa-lib) and rtld(GNU_HASH) which are neither packages nor files nor libraries.

I am considering just saying any dependency with a "(" in it, except empty '()' can be skipped. Will this work?

The empty '()' ones I would use repoquery to get the package since it would be a library.

Also I get dependencies like: libc.so.6()(64bit) libc.so.6(GLIBC_2.14)(64bit) libc.so.6(GLIBC_2.16)(64bit) libc.so.6(GLIBC_2.2.5)(64bit) . . .

Lots of different versions of GLIBC. I am thinking about just installing the newest one from my repo since glibc shows up as a package. Is this safe?

回答1:

There are several questions asked (you might consider refactoring your question). Here are some answers:

  • repoquery might be useful for deploying your application, but not much use for analyzing the set of needed RPMs. For the use you are making of it, a plain "rpm -qf" for the given files will identify the package name, and do it more rapidly.
  • the manpage for rpm is a good place to start. It has the -R option: List capabilities on which this package depends.
  • rpm also has --whatprovides: Query all packages that provide the CAPABILITY capability..

Largely, your question seems to have overlooked capabilities. Those may be specific files, or they may be names for other ways to refer to packages and/or their contents. For instance, this:

$ rpm -qR `rpm -qf vi`
config(vim-minimal) = 2:7.4.629-5.el6
libacl.so.1()(64bit)  
libacl.so.1(ACL_1.0)(64bit)  
libc.so.6()(64bit)  
libc.so.6(GLIBC_2.11)(64bit)  
libc.so.6(GLIBC_2.2.5)(64bit)  
libc.so.6(GLIBC_2.3)(64bit)  
libc.so.6(GLIBC_2.3.4)(64bit)  
libc.so.6(GLIBC_2.4)(64bit)  
libselinux.so.1()(64bit)  
libtinfo.so.5()(64bit)  
rpmlib(CompressedFileNames) <= 3.0.4-1
rpmlib(FileDigests) <= 4.6.0-1
rpmlib(PayloadFilesHavePrefix) <= 4.0-1
rpmlib(VersionedDependencies) <= 3.0.3-1
rtld(GNU_HASH)  
rpmlib(PayloadIsXz) <= 5.2-1

Those lines are capabilities, e.g.,

$ rpm -q --whatprovides 'libtinfo.so.5()(64bit)'
ncurses-libs-5.7-4.20090207.el6.x86_64

To accomplish your task, you should follow those capabilities recursively, until you reach (and presumably disregard) packages in the base system. Some packages provide multiple capabilities:

$ rpm -q --whatprovides 'config(vim-minimal) = 2:7.4.629-5.el6'
no package provides config(vim-minimal) = 2:7.4.629-5.el6
$ rpm -q --whatprovides 'libacl.so.1()(64bit)'
libacl-2.2.49-6.el6.x86_64
$ rpm -q --whatprovides 'libacl.so.1(ACL_1.0)(64bit)'
libacl-2.2.49-6.el6.x86_64
$ rpm -q --whatprovides 'libc.so.6()(64bit)'
glibc-2.12-1.166.el6_7.3.x86_64
$ rpm -q --whatprovides 'libc.so.6(GLIBC_2.11)(64bit)'
glibc-2.12-1.166.el6_7.3.x86_64 
$ rpm -q --whatprovides 'libc.so.6(GLIBC_2.2.5)(64bit)'
glibc-2.12-1.166.el6_7.3.x86_64
$ rpm -q --whatprovides 'libc.so.6(GLIBC_2.3)(64bit)'
glibc-2.12-1.166.el6_7.3.x86_64       
$ rpm -q --whatprovides 'libc.so.6(GLIBC_2.3.4)(64bit)'
glibc-2.12-1.166.el6_7.3.x86_64
$ rpm -q --whatprovides 'libc.so.6(GLIBC_2.4)(64bit)'
glibc-2.12-1.166.el6_7.3.x86_64
$ rpm -q --whatprovides 'libselinux.so.1()(64bit)'
libselinux-2.0.94-5.8.el6.x86_64
$ rpm -q --whatprovides 'libtinfo.so.5()(64bit)'
ncurses-libs-5.7-4.20090207.el6.x86_64
$ rpm -q --whatprovides 'rpmlib(CompressedFileNames) <= 3.0.4-1'
no package provides rpmlib(CompressedFileNames) <= 3.0.4-1                      
$ rpm -q --whatprovides 'rpmlib(FileDigests) <= 4.6.0-1'
no package provides rpmlib(FileDigests) <= 4.6.0-1
$ rpm -q --whatprovides 'rpmlib(PayloadFilesHavePrefix) <= 4.0-1'
no package provides rpmlib(PayloadFilesHavePrefix) <= 4.0-1
$ rpm -q --whatprovides 'rpmlib(VersionedDependencies) <= 3.0.3-1'
no package provides rpmlib(VersionedDependencies) <= 3.0.3-1
$ rpm -q --whatprovides 'rtld(GNU_HASH)'
glibc-2.12-1.166.el6_7.3.x86_64
$ rpm -q --whatprovides 'rpmlib(PayloadIsXz) <= 5.2-1'
no package provides rpmlib(PayloadIsXz) <= 5.2-1

The "no package provides" hint at special cases which this option does not address. See for instance the situation with rpmlib discussed in Re: rpmlib(VersionedDependencies) <= 3.0.3-1, which says that rpm --showrc provides the information. (The vim-minimal warning is another special case -- you will handle it and others as they come up).

It is not necessary to install an RPM to find what capabilities it provides. You can do that using the --provides option, e.g.,

rpm -qp --provides your-package-name.rpm

and (as you noted before) use the -R option to see what a given package requires:

rpm -qpR your-package-name.rpm

Looking at a package I built for ncurses-examples, those two commands give me

$ rpm -qp  --provides ncurses-examples-6.0-20151107.x86_64.rpm 
ncurses-examples = 6.0-20151107
ncurses-examples(x86-64) = 6.0-20151107

$ rpm -qpR ncurses-examples-6.0-20151107.x86_64.rpm
libc.so.6()(64bit)
libc.so.6(GLIBC_2.2.5)(64bit)
libc.so.6(GLIBC_2.3)(64bit)
libformw6.so.6()(64bit)
libformw6.so.6(NCURSESW6_5.1.20000708)(64bit)
libformw6.so.6(NCURSESW6_5.9.20150530)(64bit)
libm.so.6()(64bit)
libm.so.6(GLIBC_2.2.5)(64bit)
libmenuw6.so.6()(64bit)
libmenuw6.so.6(NCURSESW6_5.1.20000708)(64bit)
libncursesw6.so.6()(64bit)
libncursesw6.so.6(NCURSESW6_5.1.20000708)(64bit)
libncursesw6.so.6(NCURSESW6_5.3.20021019)(64bit)
libncursesw6.so.6(NCURSESW6_5.4.20040208)(64bit)
libncursesw6.so.6(NCURSESW6_5.7.20081102)(64bit)
libpanelw6.so.6()(64bit)
libpanelw6.so.6(NCURSESW6_5.1.20000708)(64bit)
libtinfow6.so.6()(64bit)
libtinfow6.so.6(NCURSES6_TINFO_5.0.19991023)(64bit)
libtinfow6.so.6(NCURSES6_TINFO_5.1.20000708)(64bit)
libtinfow6.so.6(NCURSES6_TINFO_5.4.20040208)(64bit)
libtinfow6.so.6(NCURSES6_TINFO_5.7.20081102)(64bit)
libtinfow6.so.6(NCURSES6_TINFO_5.9.20150530)(64bit)
libutil.so.1()(64bit)
libutil.so.1(GLIBC_2.2.5)(64bit)
rpmlib(CompressedFileNames) <= 3.0.4-1
rpmlib(FileDigests) <= 4.6.0-1
rpmlib(PayloadFilesHavePrefix) <= 4.0-1
rpmlib(PayloadIsXz) <= 5.2-1
rtld(GNU_HASH)

Like libc6, the ncurses6 ABI has versions to account for, and just matching () alone will not necessarily get the right version of a library.