如何创建一个多架构的deb包?

我正在努力制作一个可以在Ubuntu 12.04-13.*的1386和amd64上安装的软件包。我已经发现,在amd64上唯一的区别是我需要安装32位库。依赖于ia32-libs会在系统中存在时(即使这样做有些多余),但是13.*甚至没有该软件包。因此,我试图通过':i386'扩展名进行安装。当我执行sudo apt-get install blah:i386 ...等时,它可以正常工作。

下面的控制文件在12.04上产生了"Dependency not satisfiable: libgcc1:i386"的消息。

包名: foo 版本号: 1.0-1 分类: 基础 优先级: 可选 维护者: bar@gmail.com 架构: 全部 依赖关系: libgcc1:i386, gcc-4.6-base:i386, libstdc++5:i386, libstdc++6:i386, libsasl2-2:i386, libgstreamermm-0.10-2:i386, libfreetype6:i386, libfontconfig1:i386, libX11-6:i386, libXrender1:i386, libice6:i386, libxext6:i386, libsm6:i386 描述: foo非常棒 foo真的很棒 已安装大小: 71140
因此,根据其他一些地方的说法,我制作了以下控制文件:
包:foo-amd64 版本:1.0-1 部分:基础 优先级:可选 维护者:bar@gmail.com 架构:amd64 依赖:foo,libgcc1:i386,gcc-4.6-base:i386,libstdc++5:i386,libstdc++6:i386,libsasl2-2:i386,libgstreamermm-0.10-2:i386,libfreetype6:i386, libfontconfig1:i386,libX11-6:i386,libXrender1:i386,libice6:i386,libxext6:i386,libsm6:i386 描述:foo很棒 foo真的很棒 已安装大小:71140
包:foo 版本:1.0-1 部分:基础 优先级:可选 维护者:bar@gmail.com 架构:i386 依赖:gksu 多架构:foreign 描述:foo很棒 foo真的很棒 已安装大小:71140
这个控制文件无法编译,因为我收到以下错误信息:dpkg-deb: error: parsing file 'foo/DEBIAN/control' near line 25 package 'foo': several package info entries found, only one allowed。我应该如何正确操作?
编辑:此软件包不附带源代码。它附带的是编译好的32位二进制文件,因此需要依赖于32位版本的库。
1个回答

你不需要创建分离的包名来实现多架构。只需输入以下命令即可:
Package: foo-amd64
Version: 1.0-1
Section: base
Priority: optional
Maintainer: bar@gmail.com
Architecture: any
Multi-Arch: same
Depends: foo, libgcc1, gcc-4.6-base, libstdc++5, libstdc++6, libsasl2-2, libgstreamermm-0.10-2, libfreetype6,
 libfontconfig1, libX11-6, libXrender1, libice6, libxext6, libsm6
Description: foo is awesome
 Foo is really awesome
Installed-Size: 71140

这将根据您的构建环境变量同时构建amd64和i386软件包。如果您使用recipes,有多种方法可以将您的软件包转换为多架构。

dh(1)和autotools

最简单的要转换的软件包是使用autoconf上游和Debian打包中的dh(1)的软件包。

  1. 在debian/control中列出的任何提供共享库的软件包中,添加Build-depend on debhelper (>= 9)。
  2. 在debian/control中列出的任何提供共享库的软件包中,添加Pre-Depends: ${misc:Pre-Depends}。
  3. 更新debian/compat为'9'。
  4. 将debian/*.install中的/usr/lib/替换为/usr/lib/*/。
  5. 如果debian/*.install中列出了/usr/lib(或其子目录)作为安装目标,或者在debian/*.links中列出了链接的目标, 您需要将$(DEB_HOST_MULTIARCH)的值替换为此文件中的值。请参阅“下面的动态debian/*文件”。
  6. 在debian/rules中,将任何出现的/usr/lib替换为/usr/lib/$(DEB_HOST_MULTIARCH)。
  7. 如果您在前两个步骤中的任一步骤中需要在debian/rules中使用$(DEB_HOST_MULTIARCH),请通过调用以下命令在debian/rules中设置DEB_HOST_MULTIARCH:DEB_HOST_MULTIARCH ?= $(shell dpkg-architecture -qDEB_HOST_MULTIARCH)。
  8. 构建软件包并验证共享库软件包是否只包含预期的文件,以及-dev软件包是否仍然可用后,在debian/control中将此共享库软件包标记为Multi-Arch: same。
  9. 如果通用软件包(即“all”)可能被共享库软件包使用,请在debian/control中将其标记为Multi-Arch: foreign。

如果您在debian/rules中覆盖了debhelper命令,尽管其他构建步骤使用dh(1),您可能需要按照下面的说明来修改mv、cp或rm命令。

在 Debian 打包实现指南https://wiki.debian.org/Multiarch/Implementation中有更多的例子。您也可以使用 lithian 确保您的软件包完全符合要求。


啊,我忘了提到的一个重要区别就是这个软件包不带源代码。它只提供编译好的32位二进制文件,因此需要依赖于32位版本的库。 - chacham15
@chacham15 你究竟想要安装哪个软件包? - Braiam
我创建的一个程序(无法公开源代码)。 - chacham15
等一下,我告诉你如何重新打包二进制文件/源代码/其他内容。如果你的程序不支持amd64架构,你只需要按照我描述的方式修改打包的方面即可。 - Braiam
不,它支持amd64,但需要那些额外的依赖项。然而,如上所述,这些依赖项无法被识别。 - chacham15
如果你有源代码,为什么不重新构建软件并只分发二进制文件呢?就像上帝(Debian)所说的那样。使用构建工具构建软件包并不意味着源代码已经包含在二进制包中。 - Braiam
代码在64位下无法编译。 - chacham15
@chacham15 就像我说的一样,这里有一个链接(我也摘录了其中的一部分),介绍如何重新打包 Debian 二进制文件。通常我会从源代码构建,但我相信你可以按照所示的方法对文件进行微调以完成同样的操作。 - Braiam
引用: 在 Debian 7(Wheezy)中,为了确保在从 Squeeze 升级时,在将共享库软件包解压到新的多架构库路径之前(并从 /usr/lib 中删除旧版本的库),每个共享库必须在多架构支持包上声明 Pre-Depends。从 Debian 8(Jessie)开始不再需要这样做,并且现已弃用。Debhelper将自动正确填写${misc:Pre-Depends}变量。 - patryk.beza