openSUSE:Build Service Debian builds

跳转至: 导航, 搜索


Icon-obsolete.png 這篇文章現在已經過期了!
原因:英文的太老,待修正。请参考 Packaging_for_Debian_and_Ubuntu
請參考這篇文章的 討論 頁,以獲得進一步資訊。

Debian 软件包(.deb) 打包

本专题讲述了如何为 openSUSE 构建服务支持的 Debian 系 Linux 发行版打包。Debian 系被构建服务支持的发行版有:

  • Debian
    • Debian 5.0 (Lenny)
    • Debian 6.0 原因:Update
    • Debian 6.2 注:OBS 的显示依然是 6.0
  • xUbuntu
    • xUbuntu 6.06 原因:End-Of-Life
    • xUbuntu 8.04 原因:End-Of-Life
    • xUbuntu 9.04
    • xUbuntu 9.10 原因:End-Of-Life
    • xUbuntu 10.04
    • xUbuntu 10.10 原因:End-Of-Life
    • xUbuntu 11.04
    • xUbuntu 11.10
    • xUbuntu 11.04

Debian 的 deb 包被分成两个部分:二进制包和源代码。二进制包以 .deb 结尾,包含你想要分发的已编译好的程序。但是,源代码包不是类似 SRPM 那种机制的单一文件,而是分拆成了三个文件:

  • 上游提供的源代码压缩包。
  • 一个 diff 文件
  • 一个 .dsc 文件
构建服务不能为 Debian 系的发行版创建源代码源,只能提供二进制 deb。

因此,一定要记住一个标准的 Debian 软件源(实际上)是由至少两个文件夹组成的:

(你的源的根目录)
|
+-binary
+-source

构建服务会直接以发行版名创建二进制包的文件夹(例如: http://download.opensuse.org/repositories/home:/EmmeG/Debian_Etch/ 对应的是二进制包的文件夹而不是你的 Debian 源的根目录,那个应该是:http://download.opensuse.org/repositories/home:/EmmeG/ )。

同时,还要注意创建一个二进制 .deb 包不需要组成源代码包的那三个文件,那三个文件是用来创建一个源代码源,让用户通过 apt-get 在他本地计算机上自动编译和打包的。(所以我们在构建服务的 Source 下要放这三个文件,因为这里构建服务起到了「本地计算机」的作用。)

构建服务不会创建源代码源,所以你也不需要知道那三个文件是怎么构成和应用的。

构建服务同时也使用了一些技巧,在 .dsc 文件里可以通过 'detransform' 标签来提供一些额外的信息。具体的用法在 如何使 Debian 系编译更简单, 程序的源代码在 debtransform。构建服务接受如下三个标签:

  • DEBTRANSFORM-TAR
  • DEBTRANSFORM-FILES-TAR
  • DEBTRANSFORM-SERIES

它们可以用来指定某个 .tar.gz 文件作为源文件,那个文件可以既作为 RPM 的源文件也作为 Debian 系的源文件; 也可以用来重复使用 RPM 的补丁(打到 Debian 上)。你可以像这样在 DEBTRANSFORM-FILES-TAR 里指定多个 tar.gz 文件:

Debtransform-Files-Tar: debian.tar.gz debian-control-xUbuntu_6.06.tar.gz

编译 .deb 包所需的 rpm

openSUSE 系的发行版想要在本地使用 osc (osc build ....) 编译 .deb 包需要安装如下软件包:

  • deb (for 'dpkg')
  • binutils (for 'ar')

使用这条命令来安装它们:

# zypper install deb binutils


创建 .deb 必须要的文件

成功创建 .deb 包需要如下文件:

  1. packageName.dsc
  2. debian.changelog
  3. debian.control
  4. debian.rules

当然啦,源代码压缩包 (tar.bz2) 也是要的。

packageName.dsc

下面是一个最小化的模板:

Format: 1.0
Source: packageName
Version: 5.6-3
Binary: packageName
Maintainer: 名 姓 <email@hostname.org>
Architecture: any
Build-Depends: debhelper (>= 4.1.16), nameOfPackageNeededToBuildIt
Files: 
 d57283ebb8157ae919762c58419353c8 133282 packageName_5.6.orig.tar.gz
 2fecf324a32123b08cefc0f047bca5ee 63176 packageName_5.6-1.diff.tar.gz

上面的模板只包含了必要字段,可选字段的说明可以去看: http://www.debian.org/doc/debian-policy/ch-controlfields.html

简要说明下标签的意思以帮助理解:

  1. Format(格式) : 是 .deb 包格式的版本,用 1.0 就好。
  2. Source(源代码): 是上游压缩包的全名,去掉 .tar.gz 后缀。
  3. Version(版本号): 是由源代码的版本号和包的释出号组成的; 模板中的 5.6 是源代码的版本号,在 '-' 后面的 3 是 Debian 包的释出号。每次你变动了用来编译 deb 包的文件,都必须给它加上 1。
  4. Binary(二进制包名) : 是 apt-get 包管理器看到的二进制包名 (例如: 安装它你需要使用 apt-get install 你在这里写的名字 )
  5. Maintainer(维护者) : 是上游维护者的名字 (不是你的,也不是打包者的)
  6. Architecture×架构) : 是你想要编译的 CPU 架构。
  7. Build-Depends(编译依赖) : 是编译它需要的库文件。你必须写上 'debhelper (>= 4.1.16)' 因为它包含了系统编译所需的所有帮助代码片段。
  8. Files(文件): 理论上你必须注明 .orig.tar.gz 和 .diff.tar.gz 的 MD5SUM 序列和以比特计数的大小,实际操作上给出一部分就行,如果它们不对也没什么要紧的。重要的是格式有两行三列不能搞错。(例如:你可以只替换文件中的名字,就号了,构建服务会搞定剩下的。)

debian.changelog

Debian 创建软件包(.deb)的机制是在源代码树里插入一个叫做 debian 的带有很多自动化编译和打包过程必要的文件的文件夹。

你不需要自己做这步,构建服务会自动帮你创建并把所有以 debian. 开头的文件都放在里面。这对所有 deb 系的发行版都有效!!因此,在一个乌斑兔源里你需要创建的文件叫做 debian.chagngelog 而不是 ubuntu.changelog.

还是一个最小化的模板:

packageName (5.6-3) stable; urgency=low 
// 注意中间的一个空格; urgency 是管 Debian FTP 上传的次序的,跟 OBS 没关系,默认就好

[一个空格]* Initial Release
        [一个空格]更新了 A,B,C,D

[一个空格]-- 打包者名字 <打包者邮件>[两个空格]  Mon, 25 Dec 2007 10:50:38 +0100
// 注意日期格式。

// 其中我空的行是可以被 Debian 自动忽略的行,别的地方空行就会出错。

不要以为它就是一个 changelog 而已,语法限制很多的,即使一个诸如丢失空格这样的小问题也会让你所有的建包过程统统失败!!:-(

所以呀,你们这些魔法师一定要注意语法问题啊!参考 http://www.debian.org/doc/debian-policy/ch-source.html#s-dpkgchangelog

debian.control

这个文件用来描述软件包和软件包依赖。下面是一个最小化的模板

Source: packageName
Section: sectionName
Priority: optional
Maintainer: yourName <yourEmail@hostname.de>
Build-Depends: debhelper (>= 4.1.16), nameOfPackageNeededToBuildIt

Package: nameOfPackage
Architecture: any
Depends: ${shlibs:Depends}
Description: 第一行是简短介绍,相当于 spec 的 Summary。
[这里有一个空格]第二行是长描述,相当于 spec 的 description。
 这里的语法是很平常的。 (参考 Debian 打包策略以避免错误 http://www.debian.org/doc/debian-policy/ch-controlfields.html#s-f- Description)

这里面有一些是重复的信息,所以你可以从 .dsc 文件复制过来。比如 'Build-Depends','Architecture',还有'Package' 和 'Binary' 是一样的,'Maintainer' 和 debian.changelog 最后一行的名字是一样的。

debian.rules

这是一个 Makefile 风格的文件,包含解压,编译,安装和打包源代码所需要的全部命令。

你可以任意修改本文件,最好简单改几行让它工作就好,剩下的就由它去吧。

#!/usr/bin/make -f
# Sample debian/rules that uses debhelper.
# GNU copyright 1997 to 1999 by Joey Hess.

# 去掉下面的 # 号来激活调试模式。
#export DH_VERBOSE=1

# 这行定义了使用 debhelper 的哪个兼容版本
export DH_COMPAT=4

CFLAGS = -g
ifneq (,$(findstring noopt,$(DEB_BUILD_OPTIONS)))
CFLAGS += -O0
else
CFLAGS += -O2
endif

build: build-stamp
build-stamp:
	dh_testdir

	# 在这里添加编译所需的代码
	./configure
	make all
	# --- 编译过程结束

	touch build-stamp

clean:
	dh_testdir
	dh_testroot
	rm -f build-stamp

	# 在这里添加编译过程结束所需的清理代码
	make clean || true
	# --- 清理过程的结束

	dh_clean

install: build
	dh_testdir
	dh_testroot
	dh_clean -k
	dh_installdirs

	# 在这里添加安装代码
	# 安装的 DESTDIR 必须是 /usr/src/packages/BUILD/debian/<nameOfPackage>
	make install DESTDIR=/usr/src/packages/BUILD/debian/ace
	# --- 安装过程结束

# 在这里编译和系统架构无关的文件
binary-indep: build install
	# 默认是不需要操作这里的。

# 在这里编译和系统架构有关的文件
binary-arch: build install
	dh_testdir
	dh_testroot
#	dh_installdebconf
	dh_installdocs
	dh_installexamples
	dh_installmenu
#	dh_installlogrotate
#	dh_installemacsen
#	dh_installpam
#	dh_installmime
#	dh_installinit
	dh_installcron
	dh_installman
	dh_installinfo
#	dh_undocumented
	dh_installchangelogs
	dh_link
	dh_strip
	dh_compress
	dh_fixperms
#	dh_makeshlibs
	dh_installdeb
#	dh_perl
	dh_shlibdeps
	dh_gencontrol
	dh_md5sums
	dh_builddeb

binary: binary-indep binary-arch
.PHONY: build clean binary-indep binary-arch binary install

添加补丁

想要给你的源代码打上一个补丁,你需要添加一个 debian.series 文件,该文件包含了补丁名称和要传递给 patch 程序的参数,例如:

avoid_sysarg.patch -p0

另一种创建 Debian 软件包(.deb)的方法

上面说过创建 deb 包,你至少需要这五个文件:

  1. packageName.dsc
  2. debian.changelog
  3. debian.control
  4. debian.rules
  5. 源代码压缩包 (tar.gz)

然后还有一种办法:通过原生的 Debian 或者 Ubuntu 工具创建(或重复使用)一个标准的 Debian 源代码包!一个标准的 Debian 源代码包有以下三个文件:

  • 源代码压缩包
  • 补丁文件 (可选)
  • 一个 debian.tar.gz 压缩包 (可选)
  • 一个 .dsc 文件

这样的源代码 deb 包,Debian 文档告诉我们说可以在 Debian 系统上通过诸如 dpkg-buildpackage -S 或者 dpkg-source -b 这样代码创建出来。

这样的三个文件可以作为源文件上传到构建服务,构建服务就可以用它们来制造软件包了。那些 debian.xxx 文件中的信息依然存在,只不过被隐藏到补丁文件或者源代码压缩包里了。

通常情况下,Debian 的源代码 deb 包都是由于一些跟我们的构建服务无关的原因创造出来的。如果有这样的包,我们没有理由再造轮子。

另外,源代码处理服务 中的 添加文件 特性也可以用来指定文件的 URL,这样,构建服务就会自动从 Debian 或者 Ubuntu 的源代码源里下载那三个文件了。

如果你使用 http://packages.ubuntu.com/ (Ubuntu 查找包系统)查找一个源代码 deb 包,在页脚会显示一个源代码 deb 包的 URL,那三个文件的 URL 在源代码 deb 包的页面。这些 URL 可以复制粘贴到构建服务的 添加文件 页面。(在页面的 "从远程 URL 上传" 字段。) 通过这种方法你可以不用任何源文件就让构建服务重新编译 Ubuntu 统一源中的一个包。

为不同的发行版版本提供不同的配置文件

想要针对多个 Debian 或 Ubuntu 版本使用不同的配置,你需要使用另一个方法来创建 Debian 包。.dsc 文件要使用类似针对多个 spec 文件的方法的命名方式,包名-源名.dsc。如有必要,不同的 .dsc 文件可以请求不同的源代码压缩包。

举例:

  • wonderproj-xUbuntu_10.10.dsc
  • wonderproj-new_0.0.1-1.debian.tar.gz
  • wonderproj-new_0.0.1.orig.tar.bz2

在本例中, wonderproj-xUbuntu_10.10.dsc 里面是这样的:

Format: 3.0 (quilt)
Source: wonderproj-new
Binary: wonderproj-new
Architecture: any
Version: 0.0.1-1
Maintainer: I.M.Coder <im@wonder-code.org>
Standards-Version: 0.0.1
Build-Depends:  cdbs, cmake, debhelper, pkg-kde-tools, kdelibs5-dev
Checksums-Sha1:
 0ba9af478421ce1b0ca652b0d035a49ed4f5513f 2893892 wonderproj-new_0.0.1.orig.tar.bz2
 f0d12c000ac09c48439408e2978eea56f152ae1c 20710 wonderproj-new_0.0.1-1.debian.tar.gz
Checksums-Sha256:
 0afd23eecf11a8d387019a007064c6554dad3adaf640c28a39a12143ac8ccc19 2893892 wonderproj-new_0.0.1.orig.tar.bz2
 f10e4a9ff5b629b2b73e8b6ca97f4d47b7ac4e53c33930db1e5fefc317f2c123 20710 wonderproj-new_0.0.1-1.debian.tar.gz
Files:
 437a8d1df895203af8b08e64717a6e30 2893892 wonderproj-new_0.0.1.orig.tar.bz2
 0323ebdd4a1983de61a5e4f326194426 20710 wonderproj-new_0.0.1-1.debian.tar.gz=

配置源文件列表

创建完 .deb 文件后,你需要添加源到 sources.list 文件(可能在 /etc/apt/)以便于使用 apt-get 来安装你的软件包。

下面是个小例子。

deb http://download.opensuse.org/repositories/home:/robermann79:/codesounding/Ubuntu_8.10  ./

问题在于 apt-get 不能处理带镜像的 HTTP 转向(302),因此它会认为那是个错误。

这不是 apt-get 的 bug。这是 apt 开发者做出的决定;他们认为针对软件源使用 302 重定向是不安全的。(为什么?他们没有告诉我们。他们只说了那不安全)

因此我们应该直接添加镜像的 URL,通过以下两种方式:

  1. 如果你有服务器,在那里做个源镜像,指导用户从那里下载
  2. http://old-en.opensuse.org/Mirrors_Development_Build 里搜索一个服务器,在那里做镜像,指导用户从那里下载(希望那个镜像是永久的)

最快的方法 是从源本身来获取一个镜像列表:

  • 浏览镜像列表:
http://download.opensuse.org/repositories/<project>://<package>/<repository>/Packages?mirrorlist

例如

http://download.opensuse.org/repositories/home://robermann79://codesounding/Ubuntu_8.10/Packages?mirrorlist
  • 从那些镜像里面挑一个:
http://widehat.opensuse.org/repositories/home:/robermann79:/codesounding/Ubuntu_8.10/Packages

像下面那样去掉最后的 /Packages 路径,然后添加剩下的 URL 到你的 /etc/apt/sources.list。

deb http://widehat.opensuse.org/repositories/home:/robermann79:/codesounding/Ubuntu_8.10 ./

现在 apt-get 就能工作了。

添加 apt-key 密钥到系统

对于更加新的基于 GNU/Linux 的 Debian 发行版,你还要添加源的密钥到 apt 可接受密钥列表里面。

然后你就能添加下载密钥啦:

sudo apt-key add <downloaded-file>

实例

你可以在原作者的私人车库里找到实例: https://build.opensuse.org/project/show?project=home%3AEmmeG

常见误区

软件包名的注意事项

RPM 包没有 Debian 那么严格的语法。所以在上传你的存档包前要特别注意!

tar.bz2 格式的注意事项

Debian 4.0 以前、Ubuntu 8.04 以前允许使用 .tar.bz2 格式压缩源代码。这种格式可以让 deb 和 rpm 共享源代码。Debian 5.0、Ubuntu 8.10 以后,Debian 打包策略的修改只允许使用 .tar.gz 格式了。为了让构建服务所有平台的 rpm 和 deb 编译都能共享源代码,建议使用 .tar.gz 格式压缩源代码。

如果上游的压缩包是使用 .tar.bz2 格式或者其它格式的,可以使用「重压缩」服务改压缩成标准 .tar.gz 格式。

示例:

<services>
  <service name="download_url">
    <param name="host">master.dl.sourceforge.net</param>
    <param name="protocol">http</param>
    <param name="path">/project/someproject/somefolder/someproject.data.tar</param>
  </service>
  <service name="recompress">
    <param name="file">_service:download_url:someproject.data.tar</param>
    <param name="compression">gz</param>
  </service>
</services>

注意 _service:download_url: 这个前缀是必须的,如果你使用源代码处理服务下载的文件没有这个前缀,重压缩服务是不起作用的。

在网页界面,你需要在创建完条目之后根据上面的例子编辑服务参数(默认的是不对的)。

安装前代码片段 (postinst) 的注意事项

If you need to run some script on post installation, you could: 如果在安装前你需要执行一些代码片段,你应该

  • 上传一个名为 debian.postinst 的文件
  • 把你的 package.postinst 文件放到 debian.tar.gz 里。

看这个包的例子:https://build.opensuse.org/package/show?package=openvas-scanner&project=security%3AOpenVAS%3ASTABLE%3Av4

补丁格式

Debian 4.0 和 Ubuntu 8.x 以下,要求使用 -p0 层级的补丁里面,将要被补缀的原始文件和新文件的文件名必须相同。(Bug #492297)

Ubuntu 6.06 在 @@..@@ 行后不允许有字符。例如:

@@ -37,7 +37,7 @@ openvas-libraries.tmpl: openvas-librarie

会出错,

@@ -37,7 +37,7 @@

会正常工作。

链接 -dev 包到主包

Ubuntu 6.06 不能处理 .control 文件里的 "(= ${binary:Version})" 标签,你需要用 "(= ${Source-Version})" 来代替。