Package ordering
Rpm orders transactions solely based on package dependency information: dependencies are installed before the dependent, and erased after it. If the install/erase order is not right, then either the dependency information is incomplete, incorrect or there are unresolvable dependency loops.
The order is calculated by matching dependencies on Provides
from the
packages in the transaction. If package A Requires
B, then a provider
of B will be installed before A, and erased after it.
In case of multiple providers, heuristics are used to pick the best match.
Weak dependencies (Recommends
, Suggests
, Supplements
, Enhances
)
and ordering hints (OrderWithRequires
) are similarly considered, if the
provider is present in the transaction.
Note that Supplements
and Enhances
are reverse dependencies and are
ordered thus.Obsoletes
and Conflicts
dependencies are not used for
ordering.
A dependency loop is generally a packaging bug as no correct ordering is possible to achieve in that situation. They are best solved at the source, by splitting packages to sub-packages to eliminate the loop. Sometimes this is not practical though, and also some dependencies are not relevant for ordering at all. Rpm supports various dependency qualifiers to supply context that rpm uses for loop resolution.
Qualifiers work in two ways, depending on the context and the qualifier: they can either resolve the loop, or favor loop cutting.
Normally, Requires: A
and Requires(pre): A
result in exactly the same
install order but when a loop is detected, the latter is favored during
installation. During erasure, the latter is ignored.
In simple cases this is sufficient to nudge the loop resolution in the
desired direction, but there is no guarantee. Also note that favoring
is only used on hard Requires
dependencies.
Requires(preun): A
declares the dependency is only needed during erasure,
so it can resolve an install-time loop. Unordering qualifiers cause the
dependency to be ignored entirely during ordering, so they resolve loops.
Install-order qualifiers:
pre
post
Erase-order qualifiers:
preun
postun
Unordering qualifiers:
pretrans
posttrans
meta
verify
Packages belonging to a dependency loop are installed as a consecutive group, using the qualifier hints to try and cut the loop with least minimal disruption, but one should remember that there is no such thing as a correct order for a loop.
Ordering issues and dependency loops can be difficult to analyze.
To aid with this, rpm can print out transaction ordering diagnostics.
These diagnostics can be enabled with the --deploops
switch from the cli
or the RPMTRANS_FLAG_DEPLOOPS
transaction flag from the API. Installing
to (and erasing from) an empty chroot is an effective way of discovering
missing dependencies.