当 rpm 文件中存在 rpm 安装时“缺少”lib

Posted

技术标签:

【中文标题】当 rpm 文件中存在 rpm 安装时“缺少”lib【英文标题】:"Missing" lib for rpm install when it is present in rpm file 【发布时间】:2015-02-11 07:09:50 【问题描述】:

我正在为 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

【问题讨论】:

rpm -qp --provides /vagrant_rpms/grass-6.4.4-1.el6.x86_64.rpm 说什么?如果您从 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 中提取该库,file /tmp/libgrass_rli.6.4.4.so 对此有何评论? 我已经添加了这些输出,但对我来说它们看起来不错 请注意,您的“提供”列表确实没有列出 RPM 抱怨的功能:“libgrass_rli.so()(64bit)”。它确实列出了“libgrass_rli.so”和“libgrass_rli.6.4.4.so()(64bit)”,但它们都是不同的。也许您正在打包的“libgrass_rli.so”是一个损坏的符号链接。我已经更新了我的答案以说明这种可能性。 那些文件名很有趣。转换不是通常 .so 之前而不是在它之前吗? nm /tmp/libgrass_rli.6.4.4.so 说什么? 我已经看到该库是否不可执行,例如,模式 0666,rpmbuild 在构建“提供”列表时将无法识别它。使用chmod +x *.so* 更改所有库解决了我的问题。 【参考方案1】:

如果其他现有答案都不适合您,请确保您已为您的图书馆设置了 SONAME。这是通过 'soname' 链接器选项设置的,该选项添加元信息以指定库的 共享对象 名称。 “最大 RPM”指南的 Automatic Dependencies 部分很好地解释了这与 rpm 构建过程的关系。

This answer(针对不同的问题)很好地解释了SONAME 的目的,问题本身也解释了语法。

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

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

SONAME 由链接器在编译时用于从库文件中确定实际的目标库版本。 gcc -lNAME 将寻找 libNAME.so (符号链接或文件)然后提取其SONAME 肯定会更具体(例如 libfoo.so 链接到包含 @987654331 的 libfoo.so.1.2.4 @libfoo.so.1)。

语法如下:

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

另请参阅“创建共享库”中的Program Library HOWTO 部分以获得进一步说明。

【讨论】:

【参考方案2】:

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

在您的%install 部分添加类似的内容:

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

Source.

【讨论】:

哇,不错。非常感谢。 已经搜索了半天。至少在带有redhat-rpm-config-9.1.0 的 CentOS7 中,共享库必须是可执行的。【参考方案3】:

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

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

除非您正在打包预构建的库,或者除非您为相同的 RPM 同时构建 32 位和 64 位库(并且未能安装后者,或者将两者都安装到相同的位置,这样一来就打倒另一个)。

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

【讨论】:

一切似乎都表明它是 64 位的(根据需要),而且我还没有对自动提供(我知道)感到厌烦

以上是关于当 rpm 文件中存在 rpm 安装时“缺少”lib的主要内容,如果未能解决你的问题,请参考以下文章

linux解压rpm文件怎么安装

Linux如何安装rpm格式的文件?

Linux如何安装rpm格式的文件?

linux rpm安装与yum安装,wegt下载完后加载

centos7中如何打包用户目录

rpm 规范文件的安装后脚本中的 yum/rpm install 命令