Some notes about dependency managementMany people who are new to packaging think that dependency management is
only about the
Provides: and
Requires: tags in the spec file. These are only part of the story because rpm does
automatic dependency generation as part of the rpmbuild process for programs which are
compiled (C, C++ etc.). Therefore in general it is not necessary to add any Provides: or Requires: tags for these types of package. In fact, adding unnecessary Requires: tags can cause problems if a library package name changes or on 64 bit (where library packages can be named differently anyway). The general rule is to only add Requires: tags for packages consisting of script languages (python, perl, bash etc.) or where the required package is desirable (to add functionality) rather than necessary (to install the package).
This automatic dependency generation is handled by 2 scripts
find-provides and
find-requires which you will see run towards the end of the build.
find-providesThis script examines all the files in the
%files list and if any shared libraries are found the
soname of the lib is added to the list of capabilities/facilities
provided by the rpm. This means that if another package depends on that shared lib your package can be selected by apt/synaptic to satisfy that dependency.
Be very careful when packaging apps where the SOURCES contain pre-built libraries as they
will be added and you could find your package being selected as a dependency of a seemingly totally unrelated application (Calibre springs to mind). Worse still, this can lead to instability if those libraries are used with another application (because they were not built on PCLinuxOS). To avoid this you can add:
Autoprov: Noto the summary section of the spec file (that is where the Provides/BuildRequires/Requires/Obsoletes tags go) for these types of package (and
only these types of package!). Documentation for these tags is
here.
find-requiresThis script examines all the files in the
%files list and effectively runs an
ldd on any executable to see what shared-libraries are needed by the executable. The
sonames for these libraries are added to the list of capabilities
required by the rpm and will need to be resolved when the rpm is installed. Once again pre-built binaries in the SOURCE can cause issues as they may reference sonames which cannot be resolved by existing packages in the repo. An example would be because the SOURCE contains binaries for multiple architectures (see
example here)
Devel dependencies (added Jul 5)
There is a further twist with shared objects
which are to be used as system shared libraries (there are other uses for .so files). The build will produce 3 "copies" of the lib (actually only 1 is a real file the others are links but that doesn't matter for the purposes here) :
/usr/lib/libxyz.so.1.2.3
/usr/lib/libxyz.so.1
/usr/lib/libxyz.so
The first 2 (the versioned files) are required at runtime and should be in the main package. The 3rd one (libxyz.so) is only required by the linker when building apps against the shared lib and should therefore be in the -devel package (along with header files).
RPM is clever enough to know this and generates "devel" provides/requires for that file. Therefore if you put the unversioned .so in the main package the automatic dependency management will generate a "devel" provides:
[terry@localhost ~]$ rpm -q --provides kde-workspace-core | grep devel
devel(libkwinglesutils)
devel(libkwinglutils)
devel(liboxygenstyleconfig)
devel(libpowerdevilconfigcommonprivate)
devel(libpowerdevilui)and therefore devel dependencies:
[terry@localhost ~]$ rpm -qR kde-workspace-core | grep devel
devel(libdl)
devel(libEGL)
devel(libgcc_s)
devel(libGL)
devel(libGLESv2)
devel(libICE)
devel(libkdecore)
devel(libkdeui)
devel(libkephal)
devel(libkwineffects)
devel(libm)
devel(libpowerdevilcore)
devel(libpowerdevilui)
devel(libQtCore)
devel(libQtDBus)
devel(libQtGui)
devel(libQtSvg)
devel(libSM)
devel(libstdc++)
devel(libX11)
devel(libXau)
devel(libXdmcp)
devel(libXext)
devel(libXft)
devel(libXpmand these devel dependencies will have their own dependencies etc. etc. This could result in a large amount of unnecessary -devel packages and other "build" packages being installed on systems which are not used for software building. This can consume a lot of space and make things like remastering more difficult.
If you are
sure that nothing will ever want to link/build against such a library you could avoid creating a -devel subpackage by either deleting the .so at the end of the %install section
rm -f %buildroot/%{_libdir}/libxyz.soor using a %exclude for the file in the %files list.
%files
...
%exclude %{_libdir}/libxyz.so
but if there is any doubt it is safer to provide a -devel package.
To summarize, great care must be taken with dependency management when dealing with system shared libraries. It is complicated, tedious and certainly not glamorous but it IS necessary to avoid the repo descending into bloat and chaos.
Terry.