From Fedora Project Wiki

Line 39: Line 39:
     #!/bin/sh
     #!/bin/sh
     FINDREQ=$( rpm --eval %__find_requires )
     FINDREQ=$( rpm --eval %__find_requires )
     $FINDREQ $@ | sed -e '/libssl.so.0.9.8\|libcef.so/d' -e 's/.0d\|.1d//g'
     $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.
One can redefine  __find_provides the same way.

Revision as of 08:42, 14 November 2012

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

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.so

To filter all files in a private dir from Provides:

  %global __provides_exclude_from %{_libdir}/private-lib/.*\\.so

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.,

   %define         __find_requires %{SOURCE8}

SOURCE8:

   #!/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

chrpath must be built for the architecture of the building host - chrpath.i386 doesn't work on x86_64.