9

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
Ian Turton
  • 10,018
  • 1
  • 28
  • 47
  • What does `rpm -qp --provides /vagrant_rpms/grass-6.4.4-1.el6.x86_64.rpm` say? If you extract that library from the rpm `rpm2cpio /vagrant_rpms/grass-6.4.4-1.el6.x86_64.rpm | cpio -i --to-stdout ./usr/local/lib/libgrass_rli.6.4.4.so > /tmp/libgrass_rli.6.4.4.so` what does `file /tmp/libgrass_rli.6.4.4.so` say about it? – Etan Reisner Dec 12 '14 at 14:51
  • I've added those outputs in but they look ok to me – Ian Turton Dec 12 '14 at 15:12
  • Note that your 'provides' list indeed does not list the feature RPM complains about: "libgrass_rli.so()(64bit)". It does list "libgrass_rli.so" and "libgrass_rli.6.4.4.so()(64bit)", but these are both different. Perhaps the "libgrass_rli.so" you are packaging is a broken symlink. I have updated my answer to account for that possibility. – John Bollinger Dec 12 '14 at 15:12
  • Those file names are interesting. Don't soversions usually go *after* the `.so` not before it? What does `nm /tmp/libgrass_rli.6.4.4.so` say? – Etan Reisner Dec 12 '14 at 18:30
  • 2
    I have seen if the library is not executable, eg, mode 0666, `rpmbuild` will not recognize it when building the list of "provides". Changing all libs with `chmod +x *.so*` fixed my problem. – Danny Mar 25 '21 at 03:40
  • I am having exactly the same error today. But the surprising part it , it is coming only for the "sonames" of the lib & not the lib itself. Anyone is aware exactly what could be the problem? I am using cmake using "set_property(TARGET ${VERSION_TARGET} PROPERTY VERSION "${SO_VERSION_STRING}") & set_property(TARGET ${VERSION_TARGET} PROPERTY SOVERSION "${MAJOR_STRING}") " lines. – AnotherDeveloper Nov 25 '21 at 09:04

3 Answers3

12

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.

Roman Cheplyaka
  • 37,738
  • 7
  • 72
  • 121
3

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.

Robert
  • 181
  • 7
2

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.

John Bollinger
  • 160,171
  • 8
  • 81
  • 157
  • 1
    Everything seems to point to it being 64 bit (as required) and I haven't mucked with the auto-provides (that I know about) – Ian Turton Dec 12 '14 at 15:01