如何在debian包中为共享库调整符号文件

时间:2012-09-30 19:13:40

标签: ubuntu debian packaging symbols

我正在尝试将我的Ubuntu PPA中的ktorrent升级到最新的上游版本。它还需要更新的libktorrent包。似乎libktorrent以不兼容的方式被更改,因此导致新的包libktorrent5而不是以前可用的libktorrent4。

但是,当我尝试在PPA上构建软件包时,我会收到有关不同符号的错误。我尝试了一些方法来修复它,但每次输出都会失败。

是否有一些指南如何正确生成符号文件?

完整版本和构建日志为here

dh_strip debug symbol extraction: disabling for PPA build dh_strip debug symbol extraction: not doing anything since NO_PKG_MANGLE is given    dh_makeshlibs -Xusr/lib/kde4/ -a -O--parallel -O--
-O--dbg-package=libktorrent-dbg dpkg-gensymbols: warning: some new symbols appeared in the symbols file: see diff output below dpkg-gensymbols: warning: some symbols or patterns disappeared in the symbols file: see diff output below dpkg-gensymbols: warning: debian/libktorrent5/DEBIAN/symbols doesn't match completely debian/libktorrent5.symbols
--- debian/libktorrent5.symbols (libktorrent5_1.3.0-0ubuntu0~ppa4_amd64)
+++ dpkg-gensymbolsNTCQU9   2012-09-30 02:21:19.000000000 +0000 @@ -2912,13 +2912,20 @@   _ZTVN3utp9UTPServer7PrivateE@Base 1.2.0   _ZTVN3utp9UTPServerE@Base 1.2.0   _ZTVN3utp9UTPSocketE@Base 1.2.0
- _ZThn12_N2bt5UTPex5visitE14QSharedPointerINS_4PeerEE@Base 1.3.0
- _ZThn52_N3dht11FindNodeRspD0Ev@Base 1.3.0
- _ZThn52_N3dht11FindNodeRspD1Ev@Base 1.3.0
- _ZThn52_N3dht11GetPeersRspD0Ev@Base 1.3.0
- _ZThn52_N3dht11GetPeersRspD1Ev@Base 1.3.0
- _ZThn8_N2bt4Peer12chunkAllowedEj@Base 1.3.0
- _ZThn8_N2bt4Peer12handlePacketEPKhj@Base 1.3.0
+#MISSING: 1.3.0-0ubuntu0~ppa4# _ZThn12_N2bt5UTPex5visitE14QSharedPointerINS_4PeerEE@Base 1.3.0
+ _ZThn16_N2bt4Peer12chunkAllowedEj@Base 1.3.0-0ubuntu0~ppa4
+ _ZThn16_N2bt4Peer12handlePacketEPKhj@Base 1.3.0-0ubuntu0~ppa4
+ _ZThn24_N2bt5UTPex5visitE14QSharedPointerINS_4PeerEE@Base 1.3.0-0ubuntu0~ppa4
+#MISSING: 1.3.0-0ubuntu0~ppa4# _ZThn52_N3dht11FindNodeRspD0Ev@Base 1.3.0
+#MISSING: 1.3.0-0ubuntu0~ppa4# _ZThn52_N3dht11FindNodeRspD1Ev@Base 1.3.0
+#MISSING: 1.3.0-0ubuntu0~ppa4# _ZThn52_N3dht11GetPeersRspD0Ev@Base 1.3.0
+#MISSING: 1.3.0-0ubuntu0~ppa4# _ZThn52_N3dht11GetPeersRspD1Ev@Base 1.3.0
+ _ZThn80_N3dht11FindNodeRspD0Ev@Base 1.3.0-0ubuntu0~ppa4
+ _ZThn80_N3dht11FindNodeRspD1Ev@Base 1.3.0-0ubuntu0~ppa4
+ _ZThn80_N3dht11GetPeersRspD0Ev@Base 1.3.0-0ubuntu0~ppa4
+ _ZThn80_N3dht11GetPeersRspD1Ev@Base 1.3.0-0ubuntu0~ppa4
+#MISSING: 1.3.0-0ubuntu0~ppa4# _ZThn8_N2bt4Peer12chunkAllowedEj@Base 1.3.0
+#MISSING: 1.3.0-0ubuntu0~ppa4# _ZThn8_N2bt4Peer12handlePacketEPKhj@Base 1.3.0   (c++)"non-virtual thunk to bt::ChunkDownload::getStats(bt::ChunkDownloadInterface::Stats&)@Base"
1.2.0   (c++)"non-virtual thunk to bt::ChunkDownload::~ChunkDownload()@Base" 1.2.0   (c++)"non-virtual thunk to bt::DataCheckerJob::acquired()@Base" 1.2.0 dh_makeshlibs: dpkg-gensymbols -plibktorrent5 -Idebian/libktorrent5.symbols
-Pdebian/libktorrent5 -edebian/libktorrent5/usr/lib/libktorrent.so.5.0.0  returned exit code 1

1 个答案:

答案 0 :(得分:8)

如果发布了具有不同导出符号的库(作为不同版本),则库的任何“使用者”(即,动态链接它的每个应用程序/库)都需要跟踪它所需的库的特定版本

e.g。如果您的应用程序仅使用符号“dht :: FindNodeRsp :: FindNodeRsp()”并且此符号是在库的0.7版本中引入的,那么您的应用程序至少需要0.7版本的库(即使当前版本为0.9)

在debian上,这个过程是(或者:可以)在“符号”文件的帮助下自动化。 例如如果您打包应用程序,打包过程(确切地说:dpkg-shlibdeps)将检查您的应用程序从哪个库导入哪些符号,并与库包的符号文件进行交叉检查以获得所需库的估计值 - 版本

看来你的包已经有了一个符号文件(好!)

您唯一需要做的就是根据您已有的信息更新此文件。你应该通过将构建日志中的diff-output与实际符号文件进行比较,并在符号文件中添加适当的行来明确地执行手动

示例(添加新符号)

e.g。想象您的构建日志包含如下所示的行:

+ _ZThn52_N3dht11FindNodeRspD1Ev@Base 1.3.0

这意味着在库的_ZThn52_N3dht11FindNodeRspD1Ev@Base版本中添加了新的符号+1.3.0)。由于受损的名称几乎不可读(至少是人类),您可能希望通过c++filt运行它以对其进行去除:

 $ echo _ZThn52_N3dht11FindNodeRspD1Ev@Base | c++filt 
 non-virtual thunk to dht::FindNodeRsp::~FindNodeRsp()@Base

在这种情况下,您应该在符号文件中添加一个新行:

 (c++)"non-virtual thunk to dht::FindNodeRsp::~FindNodeRsp()@Base" 1.3.0

请注意,您可能应该删除本地版本的后缀,例如1.3.0-0ubuntu0~ppa4应该变为1.3.0-0ubuntu0~(留下尾随波浪号)

示例(删除符号)

遗憾的是,您获得的输出表明,您的库中已删除了许多符号。 这很糟糕,因为它破坏了兼容性! (如果您的应用程序(仅)使用版本1.0.3中引入但在版本2.3.0中删除的符号dht::FindNodeRsp::~FindNodeRsp(),则可以将其与版本1.0.3链接,但您也可以使用版本1.2.5 ,因为它仍然提供此符号;您的应用程序将不关心库中可能存在或不存在的其他符号。

因为它会破坏兼容性,所以首先应确保碰撞库的主要版本号 - packagename

e.g。如果您的库已删除(上游)版本“1.0.3”和“1.0.4”之间的符号,并且原始(二进制)包名称为“libfoo1”(用于打包上游“1.0.3”),那么您应该将(二进制)包名称更改为“libfoo2”(即使上游版本仍然是1.something)

这是 MUST ,由Debian政策决定!

重命名二进制包名称,很可能涉及将符号文件从debian/libfoo1.symbols重命名为debian/libfoo2.symbols

完成后,从符号文件中删除有问题的行。

架构问题:32位与64位

您可能会遇到某些类型的问题,这些类型在各种体系结构上“看起来”不同,特别是64位系统与32位系统。 这些类型中最常见的是size_t,可以扩展为unsigned longunsigned int,具体取决于您的体系结构。

幸运的是,存在处理(某些)这些情况的工具,例如, pkgkde-gensymbols的{​​{1}}替代dpkg-gensymbols

要使用它,请将符号文件中的相关条目修改为以下内容(假设您的库导出符号“foo :: bar(size_t n)”

pkg-kde-tools

然后,您必须告诉您的 (c++|subst)"foo::bar({c++:size_t})@Base" 1.2.3 文件使用debian/rules而不是标准。 如果您使用CDBS进行打包,请在普通包含后添加以下行:

pkgkde-gensymbols

咨询pkg-kde-tools的 include /usr/share/pkg-kde-tools/makefiles/1/cdbs/symbolshelper.mk ,了解如何为其他构建系统执行此操作,例如: README.Debian和/或“标准”简单KDE包。