我想将我的 qt 应用程序打包到 deb。在调查依赖项时,ldd
我得到了大约 50 个库。完整列表如下:
libgstreamer-plugins-base0.10-0,
libgstreamer0.10-0,
libglib2.0-0,
libasound2,
liboss4-salsa-asound2,
libssl1.0.0,
libx11-xcb1,
libxi6,
libxcb-render-util0,
libsm6,
libice6
libxcb1,
libxcb-glx0,
libxcb-render0,
libxcb-image0,
libxcb-icccm4,
libxcb-sync1,
libxcb-xfixes0,
libxcb-shm0,
libxcb-randr0,
libxcb-shape0,
libxcb-keysyms1,
libxcb-xkb1,
libxcb-dri2-0,
libxcb-present0,
libfontconfig1,
libfreetype6,
libxrender1,
libx11-6,
libjpeg-turbo8,
libpng12-0,
zlib1g,
libglib2.0-0,
libgl1-mesa-glx,
libstdc++6,
libgcc1,
libc6,
liborc-0.4-0,
libglib2.0-0,
libxml2,
libffi6,
libxext6,
libuuid1,
libxau6,
libxdmcp6,
libxcb-util0,
libexpat1,
libpcre3,
libglapi-mesa,
libxdamage1,
libxfixes3,
libxshmfence1,
libxxf86vm1,
libdrm2,
liblzma5
我想最小化这个列表,基于这个列表中某些库之间存在相互依赖关系的假设。
我的问题:
- 哪种工具可以帮助我最小化?
- 上面列表中的哪些依赖项是 Ubuntu 预先安装的?
答案1
我想最小化这个列表,基于这个列表中某些库之间存在相互依赖关系的假设。
你不应该这样做。依赖项列表应该包括你的软件直接依赖的每个库。这样做的原因是你的二进制文件需要该库,并且正是该库,才能在运行时正确链接。假设你尝试优化这一点:
- 你的程序依赖于 libX 和 libY
- libY 依赖于 libX
- 因此,您可以尝试通过指定仅依赖 libY 来尽量减少这种情况
现在,如果 libY 的作者或软件包维护者更改其代码以不再依赖 libX,会发生什么情况?您的软件包将崩溃。它崩溃是因为你做出了一个错误的假设 - libY 将始终依赖于 libX。该假设无效 - 软件包的依赖关系可以而且确实会随着时间的推移而发生变化。因此,如果您的程序需要 libX,则需要指定它。
好消息是,可以使用以下命令自动生成共享库列表dpkg-shlibdeps
:
https://www.debian.org/doc/debian-policy/ch-sharedlibs.html#s-dpkg-shlibdeps
8.6.1 生成共享库依赖项
当构建包含任何共享库或编译二进制文件的软件包时,它必须对每个共享库和编译二进制文件运行 dpkg-shlibdeps,以确定所使用的库以及软件包所需的依赖项。[66] 为此,请在源包中的 debian/rules 文件中调用 dpkg-shlibdeps。列出软件包中所有编译的二进制文件、库或可加载模块。[67] dpkg-shlibdeps 将使用共享库安装的符号或 shlibs 文件来生成依赖项信息。然后,软件包必须提供一个替换变量,将发现的依赖项信息放入其中。
如果你正在创建一个用于 Debian 安装程序的 udeb,你需要通过添加 -tudeb 选项[68] 来指定 dpkg-shlibdeps 应该使用 udeb 类型的依赖行。如果 shlibs 文件中没有 udeb 类型的依赖行,dpkg-shlibdeps 将回退到常规依赖行。
dpkg-shlibdeps 默认将依赖信息放入 debian/substvars 文件中,然后由 dpkg-gencontrol 使用。您需要在控制文件中的 Depends 字段中放置一个 ${shlibs:Depends} 变量,该变量由此源包构建,包含已编译的二进制文件、库或可加载模块。如果您有多个二进制包,则需要在每个包含已编译的库或二进制文件的二进制包上调用 dpkg-shlibdeps。例如,您可以使用 dpkg 实用程序的 -T 选项为每个二进制包指定不同的 substvars 文件。[69]
有关 dpkg-shlibdeps 的更多详细信息,请参阅 dpkg-shlibdeps(1)。
如果二进制文件 foo 明确链接到库 libbar(即,该库列在 ELF NEEDED 属性中,这是在创建二进制文件时在链接行中添加 -lbar 所致),则我们说二进制文件 foo 直接使用库 libbar。libbar 所需的其他库间接链接到 foo,动态链接器将在加载 libbar 时自动加载它们。软件包应该依赖于它直接使用的库,而不是它仅间接使用的库。直接使用的库的依赖项将自动引入间接使用的库。dpkg-shlibdeps 将自动处理此逻辑,但如果软件包维护人员出于某种原因必须覆盖其结果,则需要注意直接使用库和间接使用库之间的区别。[70]