Leamas's notes
Handling private libs
Guidelines basically says that private libs should be kept out of ld.so's linker path. They should also be filtered from package provides. See Filtering Private Libs
You may also end up here because of rpmlint warnings such as no-soname, private-shared-object-provides, or invalid-soname. See Common Rpmlint Issues
Lets look at the different aspects:
Soname
To display a package's soname::
objdump -p filaname | grep SONAME
To change it, use '-Wl,-soname,<SONAME>' linker flags to gcc.
Filtering
Filtering doc is at time of writing in a sad state. Unless this ticket is resolved stay away from current filtering guidelines. Instead use upstream documentation
The provides part required by the guidelines is usually straightforward: use the %__provides_exclude_from macro to filter all libraries in the private dir:
%global __provides_exclude_from %{_libdir}/private-lib/.*\\.so
After filtering the Provides: the package often becomes in a state where it Requires: the internal libs without providing them and thus becomes non-installable. The solution is to filter the Requires:, but this is trickier.. If you filter all deps in the private dir using __requires_exclude_from you will also filter all dependencies by the private libs. This is most likely not what you want.
Alternative is to just list all libs which should be excluded. This must be done "by hand" since at the early stage when these filters are evaluated, there are no unpacked directories to scan. OTOH, we can later verify that the manual list is OK.
To filter individual object files from Requires: use something like:
%global __requires_exclude liblearning.so %global __requires_exclude %{__requires_exclude}|libnetworking.so %global __requires_exclude %{__requires_exclude}|libraceengine.sp
To check that you really filtered all files in private lib, in %install:
cd private-lib excluded=$( echo '%{__requires_exclude}' | tr '|' ':' ) for lib in *.so; do if [ "${excluded/${lib}/}" = "$excluded" ]; then echo "ERROR: $lib not filtered in __requires_exclude" >&2 exit 2 fi done
If simply excluding isn't enough you can roll your own find-requires e. g.,
Source8: my-find-requires.sh %define __find_requires %{SOURCE8}
my-find-requires.sh:
#!/bin/sh FINDREQ=$( rpm --eval %__find_requires ) $FINDREQ $@ | sed -e '/libssl.so.0.9.8/d' -e '/libcef.so/d' -e 's/.0d\|.1d//g'
One can redefine __find_provides the same way.
Rpath
The preferred method to find the libs in the private dir is using a rpath.
To display and and change rpath use chrpath -l and chrpath -r. To replace an existing rpath with the private libs is the safest way, not depending on whatever rpath upstream sets. Note that chrpath can't add a rpath, there must already be one to work. cmake and gcc has usable options to create a rpath. Cookbook:
cd private-lib for lib in *.so; do chrpath --replace %{_libdir}/private-lib $lib done
NOTE! chrpath must be built for the architecture of the binary it copes with - chrpath.i386 doesn't work on a x86_64 binary.