"Missing" lib for rpm install when it is present in rpm file

8k views Asked by At

I'm generating an rpm file for centos but when I try to install it on a clean machine it fails with:

 --> Running transaction check
 ---> Package grass.x86_64 0:6.4.4-1.el6 will be installed
 --> Processing Dependency: libgrass_rli.so()(64bit) for package: grass-6.4.4-1.el6.x86_64
 --> Finished Dependency Resolution Error: Package: grass-6.4.4-1.el6.x86_64 (/grass-6.4.4-1.el6.x86_64)
            Requires: libgrass_rli.so()(64bit)

which would be fine except that the rpm contains libgrass_rli.so.

 [vagrant@localhost ~]$ rpm -qilp /vagrant_rpms/grass-6.4.4-1.el6.x86_64.rpm | grep _rli
 /usr/local/lib/libgrass_rli.6.4.4.so 
 /usr/local/lib/libgrass_rli.so

I've experimented with various provides: lines in the spec file to no avail, can any one see what's wrong?

EDIT

[vagrant@localhost ~]$ rpm -qp --provides /vagrant_rpms/grass-6.4.4-1.el6.x86_64.rpm                                                                            
libgrass_I.6.4.4.so()(64bit)                                                    
libgrass_Iortho.6.4.4.so()(64bit)                                               
libgrass_arraystats.6.4.4.so()(64bit)                                           
libgrass_bitmap.6.4.4.so()(64bit)                                               
libgrass_btree.6.4.4.so()(64bit)                                                
libgrass_cdhc.6.4.4.so()(64bit)                                                 
libgrass_cluster.6.4.4.so()(64bit)                                              
libgrass_datetime.6.4.4.so()(64bit)                                             
libgrass_dbmibase.6.4.4.so()(64bit)                                             
libgrass_dbmiclient.6.4.4.so()(64bit)                                           
libgrass_dbmidriver.6.4.4.so()(64bit)                                           
libgrass_dbstubs.6.4.4.so()(64bit)                                              
libgrass_dgl.6.4.4.so()(64bit)                                                  
libgrass_dig2.6.4.4.so()(64bit)                                                 
libgrass_display.6.4.4.so()(64bit)                                              
libgrass_driver.6.4.4.so()(64bit)                                               
libgrass_dspf.6.4.4.so()(64bit)
libgrass_edit.6.4.4.so()(64bit)
libgrass_form.6.4.4.so()(64bit)
libgrass_g3d.6.4.4.so()(64bit)
libgrass_gis.6.4.4.so()(64bit)
libgrass_gmath.6.4.4.so()(64bit)
libgrass_gpde.6.4.4.so()(64bit)
libgrass_gproj.6.4.4.so()(64bit)
libgrass_interpdata.6.4.4.so()(64bit)
libgrass_interpfl.6.4.4.so()(64bit)
libgrass_lidar.6.4.4.so()(64bit)
libgrass_linkm.6.4.4.so()(64bit)
libgrass_lrs.6.4.4.so()(64bit)
libgrass_neta.6.4.4.so()(64bit)
libgrass_nviz.6.4.4.so()(64bit)
libgrass_ogsf.6.4.4.so()(64bit)
libgrass_pngdriver.6.4.4.so()(64bit)
libgrass_psdriver.6.4.4.so()(64bit)
libgrass_qtree.6.4.4.so()(64bit)
libgrass_raster.6.4.4.so()(64bit)
libgrass_rli.6.4.4.so()(64bit)
libgrass_rli.so
libgrass_rowio.6.4.4.so()(64bit)
libgrass_rtree.6.4.4.so()(64bit)
libgrass_segment.6.4.4.so()(64bit)
libgrass_shape.6.4.4.so()(64bit)
libgrass_sim.6.4.4.so()(64bit)
libgrass_sites.6.4.4.so()(64bit)
libgrass_sqlp.6.4.4.so()(64bit)
libgrass_stats.6.4.4.so()(64bit)
libgrass_symb.6.4.4.so()(64bit)
libgrass_trans.6.4.4.so()(64bit)
libgrass_vask.6.4.4.so()(64bit)
libgrass_vect.6.4.4.so()(64bit)
libgrass_vedit.6.4.4.so()(64bit)
grass = 6.4.4-1.el6
grass(x86-64) = 6.4.4-1.el6

Also the extracted file looks ok:

[vagrant@localhost ~]$ file /tmp/libgrass_rli.6.4.4.so
/tmp/libgrass_rli.6.4.4.so: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, not stripped
3

There are 3 answers

1
John Bollinger On BEST ANSWER

rpmbuild normally scans all the files packaged into the RPM to automatically identify shared libraries the RPM provides, and an RPM's requirements can be self-satisfied. There are therefore two main possibilities:

  • perhaps the RPM contains an i386 (i.e. 32-bit) version of the library, whereas a 64-bit version is what's actually required, or in some other way the packaged file is not of the correct type;
  • alternatively, rpmbuild's automatic provides scanning may have been disabled or mucked up (this would be a function of the spec file).

A wrong library architecture is unlikely unless you are packaging a pre-built library, or unless you are building both 32-bit and 64-bit libraries for the same RPM (and failing to install the latter, or installing both to the same location so that one clobbers the other).

Since you're developing the RPM yourself, I suppose you know whether you are mucking with the auto-provides.

0
Robert On

If neither of the other existing answers work for you, make sure you've set the SONAME for your library. This is set via the 'soname' linker option which adds meta information to specify the library's shared object name. The Automatic Dependencies section of the "Maximum RPM" guide does a decent job of explaining how this relates to the rpm build process.

This answer (to a different question) explains SONAME's purpose quite well, and the question itself explains the syntax.

Here's the most important portions of that answer, lightly edited for clarity and grammar:

soname is used to indicate what binary api compatibility your library supports.

SONAME is used at compilation time by the linker to determine, from the library file, what the actual target library version is. gcc -lNAME will seek for libNAME.so (symlink or file) then extract its SONAME that will certainly be more specific (e.g. libfoo.so links to libfoo.so.1.2.4 that contains SONAME libfoo.so.1).

And here's the syntax:

gcc -shared -fPIC -Wl,-soname,libfoo.so.1 -o libfoo.so.1.2.4 foo.c

See also the Program Library HOWTO's section of "Creating a Shared Library" for further explanation.

2
Roman Cheplyaka On

A likely reason why your shared library is not detected by the "automatic provides" mechanism is that it is not executable.

Add something like this to your %install section:

find %buildroot -type f \( -name '*.so' -o -name '*.so.*' \) -exec chmod 755 {} +

Source.