当它存在于rpm文件中时,“丢失”用于rpm安装的lib

时间:2014-12-12 14:37:32

标签: rpm rpmbuild grass

我为centos生成一个rpm文件但是当我尝试在干净的机器上安装它时,它失败了:

 --> 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)

除了rpm包含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

我已经尝试过各种各样的提供:spec文件中的行无济于事,任何人都能看到错误的内容吗?

修改

[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

提取的文件看起来还不错:

[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 个答案:

答案 0 :(得分:7)

“自动提供”机制未检测到您的共享库的一个可能原因是它不可执行。

%install部分添加以下内容:

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

Source

答案 1 :(得分:2)

rpmbuild通常扫描打包到RPM中的所有文件,以自动识别RPM提供的共享库,并且RPM的要求可以自​​我满足。因此有两种主要可能性:

  • 也许RPM包含库的i386(即32位)版本,而64位版本是实际需要的版本,或者以其他方式包装文件的类型不正确;
  • 或者,rpmbuild自动提供扫描可能已被禁用或混乱(这将是规范文件的功能)。

错误的库架构是不可能的,除非您打包预先构建的库,或者除非您为同一RPM构建32位和64位库(并且未能安装后者,或者将两者都安装到相同的位置,以便一个人破坏另一个)。

由于您自己开发RPM,我想您知道自己是否正在使用自动提供。

答案 2 :(得分:2)

如果其他任何现有答案都不适合您,请确保已为媒体库设置了SONAME。这是通过“ soname”链接器选项设置的,该选项添加了元信息以指定库的共享对象名称。 “最大RPM”指南的Automatic Dependencies部分在解释这与rpm构建过程之间的关系方面做得很不错。

This answer(针对另一个问题)很好地说明了SONAME的目的,而问题本身也说明了语法。

以下是该答案中最重要的部分,为清晰和语法进行了轻松编辑:

soname用于指示您的库支持哪些二进制api兼容性。

链接器在编译时使用

SONAME来从库文件中确定实际的目标库版本。 gcc -l NAME将寻找lib NAME。so(符号链接或文件),然后提取肯定更具体的SONAME(例如libfoo.so到libfoo.so.1.2的链接) .4包含SONAME libfoo.so.1)。

这是语法:

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

有关更多说明,另请参见“创建共享库”的Program Library HOWTO部分。