rpm: Filtering dependencies differently for different subpackages
Recently I was trying to work out how to filter rpm Requires/Provides dependencies differently for different subpackages. I was trying to produce a subpackage that was the same as another subpackage, but stripping out some library dependencies. Call the one subpackage foo
and the other foo-nodeps
. (Don’t ask why I was trying to do this.)
rpm has a way of hooking the dependency generation, as described in FilteringAutomaticDependencies at the Fedora wiki. This is pretty magical. You disable rpm’s internal dependency generation. You can then override the default external dependency generation scripts (if you want). Normally rpm uses find-requires
and find-provides
in /usr/lib/rpm
, or /usr/lib/rpm/redhat
on some Red Hat or Red Hat-derived systems. If you do override the scripts, it’s likely you’ll want to call them and filter their output.
When you define your own dependency generation scripts, they are applied to all subpackages. There is no information passed to the script to indicate which package/subpackage it is being call for. You can pass arbitrary parameters to your custom find-requires/find-provides scripts. But there are no macros that you can use to pass that in as a parameter (%name
is always the main package’s name – there’s no %subpackage
macro AFACIS).
A solution was to pass that information in via the filesystem. In the %install
script I’d create a file per package. Something like this:
mkdir -p %{buildroot}/NOTINSTALLED
touch %{buildroot}/NOTINSTALLED/foo.ghost
touch %{buildroot}/NOTINSTALLED/foo-nodeps.ghost
Then in each package’s file list I’d put the appropriate file:
%files
...
%ghost /NOTINSTALLED/foo.ghost
%files nodeps
...
%ghost /NOTINSTALLED/foo-nodeps.ghost
The %ghost
ensures that the file isn’t installed, but is still passed to the find-requires/find-provides scripts. A custom find-requires script can then find out which subpackage it’s being called for. Something like this:
cat > .files
if (grep -q -E '^/NOTINSTALLED/foo-nodeps.ghost$' 2>/dev/null); then
# Filter out dependencies on libfoo
/usr/lib/rpm/find-requires | grep -v -E '^libfoo.so'
else
/usr/lib/rpm/find-requires
fi