Dependency Handling
RPM has multiple types of metadata to describe dependency relationships between packages.
The two basic types are Requires
and Provides
.
Requires
denote that a package needs something to be present at runtime to work correctly and the package manager is supposed to ensure that requires are met.
A single Requires
item can specify a package or a virtual provide.
RPM Provides
are a way to express that a package provides certain capability that other packages might need.
In case of Maven packages, the Provides
are used to denote that a package contains certain Maven artifact.
They add more flexibility to the dependency management as single package can have any number of provides, and they can be moved across different packages without breaking other packages' requires.
Provides
are usually generated by automatic tools based on the information from the built binaries or package source.
The Java packaging tooling on Fedora provides automatic Requires
and Provides
generation for packages built using XMvn.
The Provides
are based on Maven artifact coordinates of artifacts that were installed by the currently being built.
They are generated for each subpackage separately.
They follow a general format mvn(groupId:artifactId:extension:classifier:version)
, where the extension is omitted if its jar
and classifier is omitted if empty.
Version
is present only for compat artifacts, but the trailing colon has to be present unless it is a Jar artifact with no classifier.
# Example provide for Jar artifact
mvn(org.eclipse.jetty:jetty-server)
# Example provide for POM artifact
mvn(org.eclipse.jetty:jetty-parent:pom:)
# Example provide for Jar artifact with classifier
mvn(org.sonatype.sisu:sisu-guice::no_aop:)
The generated Requires are based on dependencies specified in Maven POMs in the project.
Only dependencies with scope
set to either compile
, runtime
or not set at all are used for Requires generation.
Requires do not rely on package names and instead always use virtual provides that were described above, in exactly the same format, in order to be satisfiable by the already existing provides.
For packages consisting of multiple subpackages, Requires
are generated separately for each subpackage.
Additionally, Requires
that point to an artifact in a different subpackage of the same source package are generated with exact versions to prevent version mismatches between artifacts belonging to the same project.
The requires generator also always generates Requires
on java-headless
and javapackages-tools
.
If the package is built built using different tool than Apache Maven, but still ships Maven POM(s), the you will still get automatic provides generation if you install the POM using %mvn_artifact
and %mvn_install
.
The requires generation will also be executed but the outcome largely depends on whether the POM contains accurate dependency insformation.
If it contains dependency information, you should double-check that it is correct and up-to-date.
Otherwise you need to add Requires
tags manually as described in the next section.
For packages without POMs it is necessary to specify Requires
tags manually.
In order to build the package you needed to specify BuildRequires
tags.
Your Requires
tags will therefore likely be a subset of your BuildRequires
, excluding build tools and test only dependencies.
The generated Requires and Provides of built packages can be queried using rpm
:
rpm -qp --provides path/to/example-1.0.noarch.rpm
rpm -qp --requires path/to/example-1.0.noarch.rpm
See also Querying Fedora repositories |
While Requires
and Provides
generation is automated for Maven projects, BuildRequires
still remains a manual task.
However, there are tools to simplify it to some extent.
XMvn ships a script xmvn-builddep
that takes a build.log
output from mock and prints Maven-style BuildRequires
on artifacts that were actually used during the build.
It does not help you to figure out what the BuildRequires
are before you actually build it, but it may help you to have a minimal set of BuildRequires
that are less likely to break, as they do not rely on transitive dependencies.
Want to help? Learn how to contribute to Fedora Docs ›