Table of Contents
There is an old Latin saying: “fabricando fit faber” (“practice makes perfect”).
强烈建议使用简单的包来练习和试验 Debian 打包的所有步骤。本章为您的练习提供了许多上游案例。
这也可以作为许多编程主题的介绍性示例。
请注意,Debian 对以下事项非常注意:
通过以下方式以实现通用操作系统:
在 “Chapter 5, Simple packaging” 中介绍的典型打包示例是本章节的先决条件。
在以下数小节中,有些细节被刻意模糊。请尝试阅读相关文件,并且尝试自行厘清它们。
Tip | |
---|---|
The best source of a packaging example is the current Debian archive itself. Please use the “Debian Code Search” service to find pertinent examples. |
以下是一个从空目录由零开始构建简单的 Debian 软件包的示例。
这是一个很棒的平台,可以使您获得所有的模板文件,而不会使您正在处理的上游源码树变得一团糟。
让我们假设这个空目录为 debhello-0.1。
$ mkdir debhello-0.1 $ tree . └── debhello-0.1 2 directories, 0 files
Let’s generate the maximum amount of template files.
Let’s also use the “-p debhello -t -u 0.1 -r 1” options to make the missing upstream tarball with default -x3 and T options.
$ cd /path/to/debhello-0.1 $ debmake -p debhello -t -u 0.1 -r 1 I: set parameters ...
我们来检查一下自动产生的模板文件。
$ cd /path/to $ tree . ├── debhello-0.1 │ └── debian │ ├── README.Debian │ ├── README.source │ ├── changelog │ ├── clean │ ├── control │ ├── copyright │ ├── debhello.bug-control.ex │ ├── debhello.bug-presubj.ex │ ├── debhello.bug-script.ex │ ├── debhello.conffiles.ex │ ├── debhello.cron.d.ex │ ├── debhello.cron.daily.ex │ ├── debhello.cron.hourly.ex │ ├── debhello.cron.monthly.ex │ ├── debhello.cron.weekly.ex │ ├── debhello.default.ex │ ├── debhello.emacsen-install.ex │ ├── debhello.emacsen-remove.ex │ ├── debhello.emacsen-startup.ex │ ├── debhello.lintian-overrides.ex │ ├── debhello.service.ex │ ├── debhello.tmpfile.ex │ ├── dirs │ ├── gbp.conf │ ├── install │ ├── links │ ├── maintscript.ex │ ├── manpage.1.ex │ ├── manpage.asciidoc.ex │ ├── manpage.md.ex │ ├── manpage.sgml.ex │ ├── manpage.xml.ex │ ├── patches │ │ └── series │ ├── postinst.ex │ ├── postrm.ex │ ├── preinst.ex │ ├── prerm.ex │ ├── rules │ ├── salsa-ci.yml │ ├── source │ │ ├── format │ │ ├── lintian-overrides.ex │ │ ├── local-options.ex │ │ ├── local-patch-header.ex │ │ ├── options.ex │ │ └── patch-header.ex │ ├── tests │ │ └── control │ ├── upstream │ │ └── metadata │ └── watch ├── debhello-0.1.tar.gz └── debhello_0.1.orig.tar.gz -> debhello-0.1.tar.gz 7 directories, 50 files
现在,您可以复制 debhello-0.1/debian/ 目录下所有生成的模板文件到您的软件包中。
此处是一个从 POSIX shell 命令行界面程序创建简单的 Debian 软件包的示例,我们假设它没有使用任何构建系统。
让我们假设上游的源码包为 debhello-0.2.tar.gz。
此类源码不具有自动化方法,所以必须手动安装文件。
For example:
$ tar -xzmf debhello-0.2.tar.gz $ cd debhello-0.2 $ sudo cp scripts/hello /bin/hello ...
Let’s get this source as tar file from a remote site and make it the Debian package.
下载 debhello-0.2.tar.gz.
$ wget http://www.example.org/download/debhello-0.2.tar.gz ... $ tar -xzmf debhello-0.2.tar.gz $ tree . ├── debhello-0.2 │ ├── README.md │ ├── data │ │ ├── hello.desktop │ │ └── hello.png │ ├── man │ │ └── hello.1 │ └── scripts │ └── hello └── debhello-0.2.tar.gz 5 directories, 6 files
这里的 POSIX shell 脚本 hello 非常的简单。
hello(v=0.2).
$ cat debhello-0.2/scripts/hello #!/bin/sh -e echo "Hello from the shell!" echo "" echo -n "Type Enter to exit this program: " read X
此处的 hello.desktop 支持 “桌面项(Desktop Entry)规范”。
hello.desktop(v=0.2).
$ cat debhello-0.2/data/hello.desktop [Desktop Entry] Name=Hello Name[fr]=Bonjour Comment=Greetings Comment[fr]=Salutations Type=Application Keywords=hello Exec=hello Terminal=true Icon=hello.png Categories=Utility;
此处的 hello.png 是图标的图像文件。
让我们使用 debmake 命令来打包。这里使用 -b':sh' 选项来指明生成的二进制包是一个 shell 脚本。
$ cd /path/to/debhello-0.2 $ debmake -b':sh' -x1 I: set parameters ... I: sanity check of parameters I: pkg="debhello", ver="0.2", rev="1" I: *** start packaging in "debhello-0.2". *** I: provide debhello_0.2.orig.tar.gz for non-native Debian package I: pwd = "/path/to" I: $ ln -sf debhello-0.2.tar.gz debhello_0.2.orig.tar.gz I: pwd = "/path/to/debhello-0.2" I: parse binary package settings: :sh I: binary package=debhello Type=script / Arch=all M-A=foreign I: analyze the source tree I: build_type = Unknown I: scan source for copyright+license text and file extensions I: 25 %, ext = md ...
让我们来检查一下自动产生的模板文件。
执行基本的 debmake 命令后的源码树。(v=0.2).
$ cd /path/to $ tree . ├── debhello-0.2 │ ├── README.md │ ├── data │ │ ├── hello.desktop │ │ └── hello.png │ ├── debian │ │ ├── README.Debian │ │ ├── README.source │ │ ├── changelog │ │ ├── clean │ │ ├── control │ │ ├── copyright │ │ ├── dirs │ │ ├── gbp.conf │ │ ├── install │ │ ├── links │ │ ├── patches │ │ │ └── series │ │ ├── rules │ │ ├── salsa-ci.yml │ │ ├── source │ │ │ ├── format │ │ │ ├── local-options.ex │ │ │ └── local-patch-header.ex │ │ ├── tests │ │ │ └── control │ │ ├── upstream │ │ │ └── metadata │ │ └── watch │ ├── man │ │ └── hello.1 │ └── scripts │ └── hello ├── debhello-0.2.tar.gz └── debhello_0.2.orig.tar.gz -> debhello-0.2.tar.gz 10 directories, 26 files
debian/rules(模板文件,v=0.2):.
$ cd /path/to/debhello-0.2 $ cat debian/rules #!/usr/bin/make -f # You must remove unused comment lines for the released package. #export DH_VERBOSE = 1 %: dh $@
这基本上是带有 dh 命令的标准 debian/rules 文件。因为这是个脚本软件包,所以这个 debian/rules 模板文件没有与构建标记(build flag)相关的内容。
debian/control(模板文件,v=0.2):.
$ cat debian/control Source: debhello Section: unknown Priority: optional Maintainer: "Osamu Aoki" <[email protected]> Build-Depends: debhelper-compat (= 13) Standards-Version: 4.6.2 Homepage: <insert the upstream URL, if relevant> Rules-Requires-Root: no #Vcs-Git: https://salsa.debian.org/debian/debhello.git #Vcs-Browser: https://salsa.debian.org/debian/debhello Package: debhello Architecture: all Multi-Arch: foreign Depends: ${misc:Depends} Description: auto-generated package by debmake This Debian binary package was auto-generated by the debmake(1) command provided by the debmake package.
Since this is the shell script package, the debmake command sets “Architecture: all” and “Multi-Arch: foreign”. Also, it sets required substvar parameters as “Depends: ${misc:Depends}”. These are explained in “Chapter 6, Basics for packaging”.
因为这个上游源码缺少上游的 Makefile,所以这个功能需要由维护者提供。这个上游源码仅包含脚本文件和数据文件,没有 C 的源码文件,因此 构建(build) 的过程可以被跳过,但是需要实现 安装(install) 的过程。对于这种情况,通过添加 debian/install 和 debian/manpages 文件可以很好地实现这一功能,且不会使 debian/rules 文件变得复杂。
作为维护者,我们要把这个 Debian 软件包做得更好。
debian/rules(维护者版本,v=0.2):.
$ cd /path/to/debhello-0.2 $ vim debian/rules ... hack, hack, hack, ... $ cat debian/rules #!/usr/bin/make -f export DH_VERBOSE = 1 %: dh $@
debian/control(维护者版本,v=0.2):.
$ vim debian/control ... hack, hack, hack, ... $ cat debian/control Source: debhello Section: devel Priority: optional Maintainer: Osamu Aoki <[email protected]> Build-Depends: debhelper-compat (= 13) Standards-Version: 4.6.2 Homepage: https://salsa.debian.org/debian/debmake-doc Rules-Requires-Root: no Package: debhello Architecture: all Multi-Arch: foreign Depends: ${misc:Depends} Description: Simple packaging example for debmake This Debian binary package is an example package. (This is an example only)
Warning | |
---|---|
If you leave “Section: unknown” in the template debian/control file unchanged, the lintian error may cause a build failure. |
debian/install(维护者版本,v=0.2):.
$ vim debian/install ... hack, hack, hack, ... $ cat debian/install data/hello.desktop usr/share/applications data/hello.png usr/share/pixmaps scripts/hello usr/bin
debian/manpages(维护者版本,v=0.2):.
$ vim debian/manpages ... hack, hack, hack, ... $ cat debian/manpages man/hello.1
在 debian/ 目录下还有一些其它的模板文件。它们也需要进行更新。
debian/ 目录下的模板文件。(v=0.2):.
$ rm -f debian/clean debian/dirs debian/links $ rm -f debian/README.source debian/source/*.ex $ rm -rf debian/patches $ tree -F debian debian/ ├── README.Debian ├── changelog ├── control ├── copyright ├── gbp.conf ├── install ├── manpages ├── rules* ├── salsa-ci.yml ├── source/ │ └── format ├── tests/ │ └── control ├── upstream/ │ └── metadata └── watch 4 directories, 13 files
您可以在此源代码树中使用 debuild 命令(或其等效命令)创建非原生的 Debian 软件包。如下所示,该命令的输出非常详细,并且解释了它所做的事。
$ cd /path/to/debhello-0.2 $ debuild dpkg-buildpackage -us -uc -ui -i dpkg-buildpackage: info: source package debhello dpkg-buildpackage: info: source version 0.2-1 dpkg-buildpackage: info: source distribution unstable dpkg-buildpackage: info: source changed by Osamu Aoki <[email protected]> dpkg-source -i --before-build . dpkg-buildpackage: info: host architecture amd64 debian/rules clean dh clean dh_clean rm -f debian/debhelper-build-stamp ... debian/rules binary dh binary dh_update_autotools_config dh_autoreconf create-stamp debian/debhelper-build-stamp dh_prep rm -f -- debian/debhello.substvars rm -fr -- debian/.debhelper/generated/debhello/ debian/debhello/ debi... dh_auto_install --destdir=debian/debhello/ ... Finished running lintian.
现在我们来看看成果如何。
通过 debuild 生成的第 0.2 版的 debhello 文件:.
$ cd /path/to $ tree -FL 1 ./ ├── debhello-0.2/ ├── debhello-0.2.tar.gz ├── debhello_0.2-1.debian.tar.xz ├── debhello_0.2-1.dsc ├── debhello_0.2-1_all.deb ├── debhello_0.2-1_amd64.build ├── debhello_0.2-1_amd64.buildinfo ├── debhello_0.2-1_amd64.changes └── debhello_0.2.orig.tar.gz -> debhello-0.2.tar.gz 2 directories, 8 files
您可以看见生成的全部文件。
debhello_0.2-1.debian.tar.xz 包含了 Debian 对上游源代码的修改,具体如下所示。
压缩过的归档文件 debhello_0.2-1.debian.tar.xz 中的内容物:.
$ tar -tzf debhello-0.2.tar.gz debhello-0.2/ debhello-0.2/data/ debhello-0.2/data/hello.desktop debhello-0.2/data/hello.png debhello-0.2/man/ debhello-0.2/man/hello.1 debhello-0.2/scripts/ debhello-0.2/scripts/hello debhello-0.2/README.md $ tar --xz -tf debhello_0.2-1.debian.tar.xz debian/ debian/README.Debian debian/changelog debian/control debian/copyright debian/gbp.conf debian/install debian/manpages debian/rules debian/salsa-ci.yml debian/source/ debian/source/format debian/tests/ debian/tests/control debian/upstream/ debian/upstream/metadata debian/watch
debhello_0.2-1_amd64.deb 包含了将要安装至系统中的文件,如下所示。
debhello_0.2-1_all.deb 二进制软件包中的内容:.
$ dpkg -c debhello_0.2-1_all.deb drwxr-xr-x root/root ... ./ drwxr-xr-x root/root ... ./usr/ drwxr-xr-x root/root ... ./usr/bin/ -rwxr-xr-x root/root ... ./usr/bin/hello drwxr-xr-x root/root ... ./usr/share/ drwxr-xr-x root/root ... ./usr/share/applications/ -rw-r--r-- root/root ... ./usr/share/applications/hello.desktop drwxr-xr-x root/root ... ./usr/share/doc/ drwxr-xr-x root/root ... ./usr/share/doc/debhello/ -rw-r--r-- root/root ... ./usr/share/doc/debhello/README.Debian -rw-r--r-- root/root ... ./usr/share/doc/debhello/changelog.Debian.gz -rw-r--r-- root/root ... ./usr/share/doc/debhello/copyright drwxr-xr-x root/root ... ./usr/share/man/ drwxr-xr-x root/root ... ./usr/share/man/man1/ -rw-r--r-- root/root ... ./usr/share/man/man1/hello.1.gz drwxr-xr-x root/root ... ./usr/share/pixmaps/ -rw-r--r-- root/root ... ./usr/share/pixmaps/hello.png
此处是生成的 debhello_0.2-1_all.deb 的依赖项列表。
debhello_0.2-1_all.deb 的依赖项列表:.
$ dpkg -f debhello_0.2-1_all.deb pre-depends \ depends recommends conflicts breaks
(No extra dependency packages required since this is a POSIX shell program.)
Note | |
---|---|
If you wish to replace upstream provided PNG file data/hello.png with maintainer provided one debian/hello.png, editing debian/install isn’t enough. When you add debian/hello.png, you need to add a line “include-binaries” to debian/source/options since PNG is a binary file. See dpkg-source(1). |
下面是从 POSIX shell 命令行界面程序创建简单的 Debian 软件包的示例,我们假设它使用 Makefile 作为构建系统。
让我们假设上游的源码包为 debhello-1.0.tar.gz。
这一类源代码设计可以用这样的方式安装成为非系统文件:
$ tar -xzmf debhello-1.0.tar.gz $ cd debhello-1.0 $ make install
Debian packaging requires changing this “make install” process to install files to the target system image location instead of the normal location under /usr/local.
让我们取得源码并制作 Debian 软件包。
下载 debhello-1.0.tar.gz.
$ wget http://www.example.org/download/debhello-1.0.tar.gz ... $ tar -xzmf debhello-1.0.tar.gz $ tree . ├── debhello-1.0 │ ├── Makefile │ ├── README.md │ ├── data │ │ ├── hello.desktop │ │ └── hello.png │ ├── man │ │ └── hello.1 │ └── scripts │ └── hello └── debhello-1.0.tar.gz 5 directories, 7 files
这里的 Makefile 正确使用 $(DESTDIR) 和 $(prefix)。其他的所有文件都和 “Section 13.2, “无 Makefile(shell,命令行界面)”” 中的一样,并且大多数的打包工作也都一样。
Makefile(v=1.0).
$ cat debhello-1.0/Makefile prefix = /usr/local all: : # do nothing install: install -D scripts/hello \ $(DESTDIR)$(prefix)/bin/hello install -m 644 -D data/hello.desktop \ $(DESTDIR)$(prefix)/share/applications/hello.desktop install -m 644 -D data/hello.png \ $(DESTDIR)$(prefix)/share/pixmaps/hello.png install -m 644 -D man/hello.1 \ $(DESTDIR)$(prefix)/share/man/man1/hello.1 clean: : # do nothing distclean: clean uninstall: -rm -f $(DESTDIR)$(prefix)/bin/hello -rm -f $(DESTDIR)$(prefix)/share/applications/hello.desktop -rm -f $(DESTDIR)$(prefix)/share/pixmaps/hello.png -rm -f $(DESTDIR)$(prefix)/share/man/man1/hello.1 .PHONY: all install clean distclean uninstall
让我们使用 debmake 命令来打包。这里使用 -b':sh' 选项来指明生成的二进制包是一个 shell 脚本。
$ cd /path/to/debhello-1.0 $ debmake -b':sh' -x1 I: set parameters ... I: sanity check of parameters I: pkg="debhello", ver="1.0", rev="1" I: *** start packaging in "debhello-1.0". *** I: provide debhello_1.0.orig.tar.gz for non-native Debian package I: pwd = "/path/to" I: $ ln -sf debhello-1.0.tar.gz debhello_1.0.orig.tar.gz I: pwd = "/path/to/debhello-1.0" I: parse binary package settings: :sh I: binary package=debhello Type=script / Arch=all M-A=foreign I: analyze the source tree I: build_type = make I: scan source for copyright+license text and file extensions I: 25 %, ext = md ...
让我们来检查一下自动产生的模板文件。
debian/rules(模板文件,v=1.0):.
$ cd /path/to/debhello-1.0 $ cat debian/rules #!/usr/bin/make -f # You must remove unused comment lines for the released package. #export DH_VERBOSE = 1 %: dh $@ #override_dh_auto_install: # dh_auto_install -- prefix=/usr #override_dh_install: # dh_install --list-missing -X.pyc -X.pyo
作为维护者,我们要把这个 Debian 软件包做得更好。
debian/rules(维护者版本,v=1.0):.
$ cd /path/to/debhello-1.0 $ vim debian/rules ... hack, hack, hack, ... $ cat debian/rules #!/usr/bin/make -f export DH_VERBOSE = 1 %: dh $@ override_dh_auto_install: dh_auto_install -- prefix=/usr
因为上游源码含有正确的上游 Makefile 文件,所以没有必要再去创建 debian/install 和 debian/manpages 文件。
debian/control 文件和 “Section 13.2, “无 Makefile(shell,命令行界面)”” 中的完全一致。
在 debian/ 目录下还有一些其它的模板文件。它们也需要进行更新。
debian/ 目录下的模板文件。(v=1.0):.
$ rm -f debian/clean debian/dirs debian/install debian/links $ rm -f debian/README.source debian/source/*.ex $ rm -rf debian/patches $ tree -F debian debian/ ├── README.Debian ├── changelog ├── control ├── copyright ├── gbp.conf ├── rules* ├── salsa-ci.yml ├── source/ │ └── format ├── tests/ │ └── control ├── upstream/ │ └── metadata └── watch 4 directories, 11 files
其余的打包操作基本上和 “Section 13.2, “无 Makefile(shell,命令行界面)”” 中的相同。
Here is an example of creating a simple Debian package from a Python3 CLI program using pyproject.toml.
让我们取得源码并制作 Debian 软件包。
下载 debhello-1.1.tar.gz.
$ wget http://www.example.org/download/debhello-1.1.tar.gz ... $ tar -xzmf debhello-1.1.tar.gz $ tree . ├── debhello-1.1 │ ├── LICENSE │ ├── MANIFEST.in │ ├── README.md │ ├── data │ │ ├── hello.desktop │ │ └── hello.png │ ├── manpages │ │ └── hello.1 │ ├── pyproject.toml │ └── src │ └── debhello │ ├── __init__.py │ └── main.py └── debhello-1.1.tar.gz 6 directories, 10 files
Here, the content of this debhello source tree as follows.
pyproject.toml (v=1.1) — PEP 517 configuration.
$ cat debhello-1.1/pyproject.toml [build-system] requires = ["setuptools >= 61.0"] # REQUIRED if [build-system] table is used... build-backend = "setuptools.build_meta" # If not defined, then legacy behavi... [project] name = "debhello" version = "1.1.0" description = "Hello Python (CLI)" readme = {file = "README.md", content-type = "text/markdown"} requires-python = ">=3.12" license = {file = "LICENSE.txt"} keywords = ["debhello"] authors = [ {name = "Osamu Aoki", email = "[email protected]" }, ] maintainers = [ {name = "Osamu Aoki", email = "[email protected]" }, ] classifiers = [ "Development Status :: 5 - Production/Stable", "Intended Audience :: Developers", "Topic :: System :: Archiving :: Packaging", "License :: OSI Approved :: MIT License", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.12", "Programming Language :: Python :: 3 :: Only", # Others "Operating System :: POSIX :: Linux", "Natural Language :: English", ] [project.urls] "Homepage" = "https://salsa.debian.org/debian/debmake" "Bug Reports" = "https://salsa.debian.org/debian/debmake/issues" "Source" = "https://salsa.debian.org/debian/debmake" [project.scripts] hello = "debhello.main:main" [tool.setuptools] package-dir = {"" = "src"} packages = ["debhello"] include-package-data = true
MANIFEST.in (v=1.1) — for tar-ball.
$ cat debhello-1.1/MANIFEST.in include data/* include manpages/*
src/debhello/__init__.py (v=1.1).
$ cat debhello-1.1/src/debhello/__init__.py """ debhello program (CLI) """
src/debhello/main.py (v=1.1) — command entry point.
$ cat debhello-1.1/src/debhello/main.py """ debhello program """ import sys __version__ = '1.1.0' def main(): # needed for console script print(' ========== Hello Python3 ==========') print('argv = {}'.format(sys.argv)) print('version = {}'.format(debhello.__version__)) return if __name__ == "__main__": sys.exit(main())
让我们使用 debmake 命令来打包。这里使用 -b':py3' 选项来指明生成的二进制包包含 Python3 脚本和模块文件。
$ cd /path/to/debhello-1.1 $ debmake -b':py3' -x1 I: set parameters ... I: sanity check of parameters I: pkg="debhello", ver="1.1", rev="1" I: *** start packaging in "debhello-1.1". *** I: provide debhello_1.1.orig.tar.gz for non-native Debian package I: pwd = "/path/to" I: $ ln -sf debhello-1.1.tar.gz debhello_1.1.orig.tar.gz I: pwd = "/path/to/debhello-1.1" I: parse binary package settings: :py3 I: binary package=debhello Type=python3 / Arch=all M-A=foreign I: analyze the source tree W: setuptools build system. I: build_type = Python (pyproject.toml: PEP-518, PEP-621, PEP-660) I: scan source for copyright+license text and file extensions ...
让我们来检查一下自动产生的模板文件。
debian/rules(模板文件,v=1.1):.
$ cd /path/to/debhello-1.1 $ cat debian/rules #!/usr/bin/make -f # You must remove unused comment lines for the released package. #export DH_VERBOSE = 1 %: dh $@ --with python3 --buildsystem=pybuild
这基本上是带有 dh 命令的标准 debian/rules 文件。
The use of the “--with python3” option invokes dh_python3 to calculate Python dependencies, add maintainer scripts to byte compiled files, etc. See dh_python3(1).
The use of the “--buildsystem=pybuild” option invokes various build systems for requested Python versions in order to build modules and extensions. See pybuild(1).
debian/control(模板文件,v=1.1):.
$ cat debian/control Source: debhello Section: unknown Priority: optional Maintainer: "Osamu Aoki" <[email protected]> Build-Depends: debhelper-compat (= 13), dh-python, pybuild-plugin-pyproject, python3-all, python3-setuptools Standards-Version: 4.6.2 Homepage: <insert the upstream URL, if relevant> Rules-Requires-Root: no #Vcs-Git: https://salsa.debian.org/debian/debhello.git #Vcs-Browser: https://salsa.debian.org/debian/debhello #X-Python3-Version: >= 3.7 Package: debhello Architecture: all Multi-Arch: foreign Depends: ${misc:Depends}, ${python3:Depends} Description: auto-generated package by debmake This Debian binary package was auto-generated by the debmake(1) command provided by the debmake package.
Since this is the Python3 package, the debmake command sets “Architecture: all” and “Multi-Arch: foreign”. Also, it sets required substvar parameters as “Depends: ${python3:Depends}, ${misc:Depends}”. These are explained in “Chapter 6, Basics for packaging”.
作为维护者,我们要把这个 Debian 软件包做得更好。
debian/rules(维护者版本,v=1.1):.
$ cd /path/to/debhello-1.1 $ vim debian/rules ... hack, hack, hack, ... $ cat debian/rules #!/usr/bin/make -f export PYBUILD_NAME=debhello export PYBUILD_VERBOSE=1 export DH_VERBOSE=1 %: dh $@ --with python3 --buildsystem=pybuild
debian/control(维护者版本,v=1.1):.
$ vim debian/control ... hack, hack, hack, ... $ cat debian/control Source: debhello Section: devel Priority: optional Maintainer: Osamu Aoki <[email protected]> Build-Depends: debhelper-compat (= 13), pybuild-plugin-pyproject, python3-all Standards-Version: 4.6.2 Rules-Requires-Root: no Vcs-Browser: https://salsa.debian.org/debian/debmake-doc Vcs-Git: https://salsa.debian.org/debian/debmake-doc.git Homepage: https://salsa.debian.org/debian/debmake-doc Package: debhello Architecture: all Depends: ${misc:Depends}, ${python3:Depends} Description: Simple packaging example for debmake This is an example package to demonstrate Debian packaging using the debmake command. . The generated Debian package uses the dh command offered by the debhelper package and the dpkg source format `3.0 (quilt)'.
在 debian/ 目录下还有一些其它的模板文件。它们也需要进行更新。
This debhello command comes with the upstream-provided manpage and desktop file but the upstream pyproject.toml doesn’t install them. So you need to update debian/install and debian/manpages as follows:
debian/install (maintainer version, v=1.1):
$ vim debian/copyright ... hack, hack, hack, ... $ cat debian/copyright Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ Upstream-Name: debhello Upstream-Contact: Osamu Aoki <[email protected]> Source: https://salsa.debian.org/debian/debmake-doc Files: * Copyright: 2015-2024 Osamu Aoki <[email protected]> License: Expat Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: . The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. . THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
debian/manpages (maintainer version, v=1.1):
$ vim debian/install ... hack, hack, hack, ... $ cat debian/install data/hello.desktop usr/share/applications data/hello.png usr/share/pixmaps
其余的打包工作与 “Section 13.3, “Makefile(shell,命令行界面)”” 中的几乎一致。
debian/ 目录下的模板文件。(v=1.1):.
$ rm -f debian/clean debian/dirs debian/links $ rm -f debian/README.source debian/source/*.ex $ rm -rf debian/patches $ tree -F debian debian/ ├── README.Debian ├── changelog ├── control ├── copyright ├── gbp.conf ├── install ├── manpages ├── rules* ├── salsa-ci.yml ├── source/ │ └── format ├── tests/ │ └── control ├── upstream/ │ └── metadata └── watch 4 directories, 13 files
此处是生成的 debhello_1.1-1_all.deb 包的依赖项列表。
debhello_1.1-1_all.deb 的依赖项列表:.
$ dpkg -f debhello_1.1-1_all.deb pre-depends \ depends recommends conflicts breaks Depends: python3:any
此处是一个从 POSIX shell 图形界面程序构建简单的 Debian 软件包的示例,我们假设程序使用 Makefile 作为构建系统。
上游是基于 “Section 13.3, “Makefile(shell,命令行界面)”” 中的源代码,并带有增强的图形界面支持。
让我们假设上游的源码包为 debhello-1.2.tar.gz。
让我们取得源码并制作 Debian 软件包。
下载 debhello-1.2.tar.gz.
$ wget http://www.example.org/download/debhello-1.2.tar.gz ... $ tar -xzmf debhello-1.2.tar.gz $ tree . ├── debhello-1.2 │ ├── Makefile │ ├── README.md │ ├── data │ │ ├── hello.desktop │ │ └── hello.png │ ├── man │ │ └── hello.1 │ └── scripts │ └── hello └── debhello-1.2.tar.gz 5 directories, 7 files
此处的 hello 已经被重写以便使用 zenity 命令来使其成为 GTK+ 图形界面程序。
hello(v=1.2).
$ cat debhello-1.2/scripts/hello #!/bin/sh -e zenity --info --title "hello" --text "Hello from the shell!"
这里,作为图形界面程序,桌面文件被更新为 Terminal=false。
hello.desktop(v=1.2).
$ cat debhello-1.2/data/hello.desktop [Desktop Entry] Name=Hello Name[fr]=Bonjour Comment=Greetings Comment[fr]=Salutations Type=Application Keywords=hello Exec=hello Terminal=false Icon=hello.png Categories=Utility;
其余的所有文件都与 “Section 13.3, “Makefile(shell,命令行界面)”” 中的一致。
Let’s package this with the debmake command. Here, the “-b':sh'” option is used to specify that the generated binary package is a shell script.
$ cd /path/to/debhello-1.2 $ debmake -b':sh' -x1 I: set parameters ... I: sanity check of parameters I: pkg="debhello", ver="1.2", rev="1" I: *** start packaging in "debhello-1.2". *** I: provide debhello_1.2.orig.tar.gz for non-native Debian package I: pwd = "/path/to" I: $ ln -sf debhello-1.2.tar.gz debhello_1.2.orig.tar.gz I: pwd = "/path/to/debhello-1.2" I: parse binary package settings: :sh I: binary package=debhello Type=script / Arch=all M-A=foreign I: analyze the source tree I: build_type = make I: scan source for copyright+license text and file extensions I: 25 %, ext = md ...
让我们来检查一下自动产生的模板文件。
debian/control(模板文件,v=1.2):.
$ cat debian/control Source: debhello Section: unknown Priority: optional Maintainer: "Osamu Aoki" <[email protected]> Build-Depends: debhelper-compat (= 13) Standards-Version: 4.6.2 Homepage: <insert the upstream URL, if relevant> Rules-Requires-Root: no #Vcs-Git: https://salsa.debian.org/debian/debhello.git #Vcs-Browser: https://salsa.debian.org/debian/debhello Package: debhello Architecture: all Multi-Arch: foreign Depends: ${misc:Depends} Description: auto-generated package by debmake This Debian binary package was auto-generated by the debmake(1) command provided by the debmake package.
作为维护者,我们要把这个 Debian 软件包做得更好。
debian/control(维护者版本,v=1.2):.
$ vim debian/control ... hack, hack, hack, ... $ cat debian/control Source: debhello Section: devel Priority: optional Maintainer: Osamu Aoki <[email protected]> Build-Depends: debhelper-compat (= 13) Standards-Version: 4.6.2 Homepage: https://salsa.debian.org/debian/debmake-doc Rules-Requires-Root: no Package: debhello Architecture: all Multi-Arch: foreign Depends: zenity, ${misc:Depends} Description: Simple packaging example for debmake This Debian binary package is an example package. (This is an example only)
请注意,这里需要手动添加 zenity 依赖。
debian/rules 文件与 “Section 13.3, “Makefile(shell,命令行界面)”” 中的完全一致。
在 debian/ 目录下还有一些其它的模板文件。它们也需要进行更新。
debian/ 目录下的模板文件。(v=1.2):.
$ rm -f debian/clean debian/dirs debian/install debian/links $ rm -f debian/README.source debian/source/*.ex $ rm -rf debian/patches $ tree -F debian debian/ ├── README.Debian ├── changelog ├── control ├── copyright ├── gbp.conf ├── rules* ├── salsa-ci.yml ├── source/ │ └── format ├── tests/ │ └── control ├── upstream/ │ └── metadata └── watch 4 directories, 11 files
其余的打包工作与 “Section 13.3, “Makefile(shell,命令行界面)”” 中的几乎一致。
此处是 debhello_1.2-1_all.deb 的依赖项列表。
debhello_1.2-1_all.deb 的依赖项列表:.
$ dpkg -f debhello_1.2-1_all.deb pre-depends \ depends recommends conflicts breaks Depends: zenity
Here is an example of creating a simple Debian package from a Python3 GUI program using pyproject.toml.
让我们假设上游源码包为 debhello-1.3.tar.gz。
让我们取得源码并制作 Debian 软件包。
下载 debhello-1.3.tar.gz.
$ wget http://www.example.org/download/debhello-1.3.tar.gz ... $ tar -xzmf debhello-1.3.tar.gz $ tree . ├── debhello-1.3 │ ├── LICENSE │ ├── MANIFEST.in │ ├── README.md │ ├── data │ │ ├── hello.desktop │ │ └── hello.png │ ├── manpages │ │ └── hello.1 │ ├── pyproject.toml │ └── src │ └── debhello │ ├── __init__.py │ └── main.py └── debhello-1.3.tar.gz 6 directories, 10 files
Here, the content of this debhello source tree as follows.
pyproject.toml (v=1.3) — PEP 517 configuration.
$ cat debhello-1.3/pyproject.toml [build-system] requires = ["setuptools >= 61.0"] # REQUIRED if [build-system] table is used... build-backend = "setuptools.build_meta" # If not defined, then legacy behavi... [project] name = "debhello" version = "1.3.0" description = "Hello Python (GUI)" readme = {file = "README.md", content-type = "text/markdown"} requires-python = ">=3.12" license = {file = "LICENSE.txt"} keywords = ["debhello"] authors = [ {name = "Osamu Aoki", email = "[email protected]" }, ] maintainers = [ {name = "Osamu Aoki", email = "[email protected]" }, ] classifiers = [ "Development Status :: 5 - Production/Stable", "Intended Audience :: Developers", "Topic :: System :: Archiving :: Packaging", "License :: OSI Approved :: MIT License", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.12", "Programming Language :: Python :: 3 :: Only", # Others "Operating System :: POSIX :: Linux", "Natural Language :: English", ] [project.urls] "Homepage" = "https://salsa.debian.org/debian/debmake" "Bug Reports" = "https://salsa.debian.org/debian/debmake/issues" "Source" = "https://salsa.debian.org/debian/debmake" [project.scripts] hello = "debhello.main:main" [tool.setuptools] package-dir = {"" = "src"} packages = ["debhello"] include-package-data = true
MANIFEST.in (v=1.3) — for tar-ball.
$ cat debhello-1.3/MANIFEST.in include data/* include manpages/*
src/debhello/__init__.py (v=1.3).
$ cat debhello-1.3/src/debhello/__init__.py """ debhello program (GUI) """
src/debhello/main.py (v=1.3) — command entry point.
$ cat debhello-1.3/src/debhello/main.py #!/usr/bin/python3 from gi.repository import Gtk __version__ = '1.3.0' class TopWindow(Gtk.Window): def __init__(self): Gtk.Window.__init__(self) self.title = "Hello World!" self.counter = 0 self.border_width = 10 self.set_default_size(400, 100) self.set_position(Gtk.WindowPosition.CENTER) self.button = Gtk.Button(label="Click me!") self.button.connect("clicked", self.on_button_clicked) self.add(self.button) self.connect("delete-event", self.on_window_destroy) def on_window_destroy(self, *args): Gtk.main_quit(*args) def on_button_clicked(self, widget): self.counter += 1 widget.set_label("Hello, World!\nClick count = %i" % self.counter) def main(): window = TopWindow() window.show_all() Gtk.main() if __name__ == '__main__': main()
让我们使用 debmake 命令来打包。这里使用 -b':py3' 选项来指明生成的二进制包包含 Python3 脚本和模块文件。
$ cd /path/to/debhello-1.3 $ debmake -b':py3' -x1 I: set parameters ... I: sanity check of parameters I: pkg="debhello", ver="1.3", rev="1" I: *** start packaging in "debhello-1.3". *** I: provide debhello_1.3.orig.tar.gz for non-native Debian package I: pwd = "/path/to" I: $ ln -sf debhello-1.3.tar.gz debhello_1.3.orig.tar.gz I: pwd = "/path/to/debhello-1.3" I: parse binary package settings: :py3 I: binary package=debhello Type=python3 / Arch=all M-A=foreign I: analyze the source tree W: setuptools build system. I: build_type = Python (pyproject.toml: PEP-518, PEP-621, PEP-660) I: scan source for copyright+license text and file extensions ...
The result is practically the same as in “Section 13.4, “pyproject.toml (Python3, CLI)””.
作为维护者,我们要把这个 Debian 软件包做得更好。
debian/rules(维护者版本,v=1.3):.
$ cd /path/to/debhello-1.3 $ vim debian/rules ... hack, hack, hack, ... $ cat debian/rules #!/usr/bin/make -f export PYBUILD_NAME=debhello export PYBUILD_VERBOSE=1 export DH_VERBOSE=1 %: dh $@ --with python3 --buildsystem=pybuild
debian/control(维护者版本,v=1.3):.
$ vim debian/control ... hack, hack, hack, ... $ cat debian/control Source: debhello Section: devel Priority: optional Maintainer: Osamu Aoki <[email protected]> Build-Depends: debhelper-compat (= 13), pybuild-plugin-pyproject, python3-all Standards-Version: 4.6.2 Homepage: https://salsa.debian.org/debian/debmake-doc Rules-Requires-Root: no Package: debhello Architecture: all Multi-Arch: foreign Depends: gir1.2-gtk-3.0, python3-gi, ${misc:Depends}, ${python3:Depends} Description: Simple packaging example for debmake This Debian binary package is an example package. (This is an example only)
请注意,此处需要手动添加 python3-gi 和 gir1.2-gtk-3.0 依赖。
The rest of the packaging activities are practically the same as in <pyproject>>.
此处是 debhello_1.3-1_all.deb 的依赖项列表。
debhello_1.3-1_all.deb 的依赖项列表:.
$ dpkg -f debhello_1.3-1_all.deb pre-depends \ depends recommends conflicts breaks Depends: gir1.2-gtk-3.0, python3-gi, python3:any
这里给出了从简单的 C 语言源代码创建简单的 Debian 软件包的例子,并假设上游使用了 Makefile 作为构建系统。
此处的上游源代码是 “Chapter 5, Simple packaging” 中的源代码的增强版本。它带有手册页、桌面文件和桌面图标。并且为了更加贴合实际,它还有一个外部库文件 libm。
让我们假设上游源码包为 debhello-1.4.tar.gz。
这一类源代码设计可以用这样的方式安装成为非系统文件:
$ tar -xzmf debhello-1.4.tar.gz $ cd debhello-1.4 $ make $ make install
Debian packaging requires changing this “make install” process to install files into the target system image location instead of the normal location under /usr/local.
让我们取得源码并制作 Debian 软件包。
下载 debhello-1.4.tar.gz.
$ wget http://www.example.org/download/debhello-1.4.tar.gz ... $ tar -xzmf debhello-1.4.tar.gz $ tree . ├── debhello-1.4 │ ├── LICENSE │ ├── Makefile │ ├── README.md │ ├── data │ │ ├── hello.desktop │ │ └── hello.png │ ├── man │ │ └── hello.1 │ └── src │ ├── config.h │ └── hello.c └── debhello-1.4.tar.gz 5 directories, 9 files
此处的源码如下所示。
src/hello.c(v=1.4):.
$ cat debhello-1.4/src/hello.c #include "config.h" #include <math.h> #include <stdio.h> int main() { printf("Hello, I am " PACKAGE_AUTHOR "!\n"); printf("4.0 * atan(1.0) = %10f8\n", 4.0*atan(1.0)); return 0; }
src/config.h(v=1.4):.
$ cat debhello-1.4/Makefile prefix = /usr/local all: src/hello src/hello: src/hello.c $(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) -o $@ $^ -lm install: src/hello install -D src/hello \ $(DESTDIR)$(prefix)/bin/hello install -m 644 -D data/hello.desktop \ $(DESTDIR)$(prefix)/share/applications/hello.desktop install -m 644 -D data/hello.png \ $(DESTDIR)$(prefix)/share/pixmaps/hello.png install -m 644 -D man/hello.1 \ $(DESTDIR)$(prefix)/share/man/man1/hello.1 clean: -rm -f src/hello distclean: clean uninstall: -rm -f $(DESTDIR)$(prefix)/bin/hello -rm -f $(DESTDIR)$(prefix)/share/applications/hello.desktop -rm -f $(DESTDIR)$(prefix)/share/pixmaps/hello.png -rm -f $(DESTDIR)$(prefix)/share/man/man1/hello.1 .PHONY: all install clean distclean uninstall
Makefile(v=1.4):.
$ cat debhello-1.4/src/config.h #define PACKAGE_AUTHOR "Osamu Aoki"
请注意,此 Makefile 含有正确的手册页、桌面文件、桌面图标的 install 对象。
让我们使用 debmake 命令打包。
$ cd /path/to/debhello-1.4 $ debmake -x1 I: set parameters ... I: sanity check of parameters I: pkg="debhello", ver="1.4", rev="1" I: *** start packaging in "debhello-1.4". *** I: provide debhello_1.4.orig.tar.gz for non-native Debian package I: pwd = "/path/to" I: $ ln -sf debhello-1.4.tar.gz debhello_1.4.orig.tar.gz I: pwd = "/path/to/debhello-1.4" I: parse binary package settings: I: binary package=debhello Type=bin / Arch=any M-A=foreign I: analyze the source tree I: build_type = make I: scan source for copyright+license text and file extensions I: 33 %, ext = c ...
其余的工作与 “Section 5.6, “Step 2: Generate template files with debmake”” 中的几乎一致。
像 “Section 5.7, “第三步:编辑模板文件”” 中所写的一样,让我们这些维护者来把这个 Debian 软件包做的更好。
If the DEB_BUILD_MAINT_OPTIONS environment variable is not exported in debian/rules, lintian warns “W: debhello: hardening-no-relro usr/bin/hello” for the linking of libm.
debian/control 文件与 “Section 5.7, “第三步:编辑模板文件”” 中的完全一致,因为 libm 库是 libc6 库的一部分,所以它总是可获得的(优先级:必需 / Priority: required)。
在 debian/ 目录下还有一些其它的模板文件。它们也需要进行更新。
debian/ 目录下的模板文件。(v=1.4):.
$ rm -f debian/clean debian/dirs debian/links $ rm -f debian/README.source debian/source/*.ex $ rm -rf debian/patches $ tree -F debian debian/ ├── README.Debian ├── changelog ├── control ├── copyright ├── gbp.conf ├── install ├── rules* ├── salsa-ci.yml ├── source/ │ └── format ├── tests/ │ └── control ├── upstream/ │ └── metadata └── watch 4 directories, 12 files
其余的打包步骤与 “Section 5.8, “Step 4: Building package with debuild”” 中的基本一致。
此处是生成的二进制包的依赖项列表。
生成的二进制包的依赖项列表(v=1.4):.
$ dpkg -f debhello-dbgsym_1.4-1_amd64.deb pre-depends \ depends recommends conflicts breaks Depends: debhello (= 1.4-1) $ dpkg -f debhello_1.4-1_amd64.deb pre-depends \ depends recommends conflicts breaks Depends: libc6 (>= 2.34)
这里给出了从简单的 C 语言源代码创建简单的 Debian 软件包的例子,并假设上游使用了 Makefile.in 和 configure 作为构建系统。
此处的源码示例是 “Section 13.7, “Makefile(单个二进制软件包)”” 中的源代码的增强版本。它也有一个外部链接库 libm,并且它的源代码可以使用 configure 脚本进行配置,然后生成相应的 Makefile、src/config.h 文件。
让我们假设上游源码包为 debhello-1.5.tar.gz。
此类型的源码旨在作为非系统文件安装,例如:
$ tar -xzmf debhello-1.5.tar.gz $ cd debhello-1.5 $ ./configure --with-math $ make $ make install
让我们取得源码并制作 Debian 软件包。
下载 debhello-1.5.tar.gz.
$ wget http://www.example.org/download/debhello-1.5.tar.gz ... $ tar -xzmf debhello-1.5.tar.gz $ tree . ├── debhello-1.5 │ ├── LICENSE │ ├── Makefile.in │ ├── README.md │ ├── configure │ ├── data │ │ ├── hello.desktop │ │ └── hello.png │ ├── man │ │ └── hello.1 │ └── src │ └── hello.c └── debhello-1.5.tar.gz 5 directories, 9 files
此处的源码如下所示。
src/hello.c(v=1.5):.
$ cat debhello-1.5/src/hello.c #include "config.h" #ifdef WITH_MATH # include <math.h> #endif #include <stdio.h> int main() { printf("Hello, I am " PACKAGE_AUTHOR "!\n"); #ifdef WITH_MATH printf("4.0 * atan(1.0) = %10f8\n", 4.0*atan(1.0)); #else printf("I can't do MATH!\n"); #endif return 0; }
Makefile.in(v=1.5):.
$ cat debhello-1.5/Makefile.in prefix = @prefix@ all: src/hello src/hello: src/hello.c $(CC) @VERBOSE@ \ $(CPPFLAGS) \ $(CFLAGS) \ $(LDFLAGS) \ -o $@ $^ \ @LINKLIB@ install: src/hello install -D src/hello \ $(DESTDIR)$(prefix)/bin/hello install -m 644 -D data/hello.desktop \ $(DESTDIR)$(prefix)/share/applications/hello.desktop install -m 644 -D data/hello.png \ $(DESTDIR)$(prefix)/share/pixmaps/hello.png install -m 644 -D man/hello.1 \ $(DESTDIR)$(prefix)/share/man/man1/hello.1 clean: -rm -f src/hello distclean: clean uninstall: -rm -f $(DESTDIR)$(prefix)/bin/hello -rm -f $(DESTDIR)$(prefix)/share/applications/hello.desktop -rm -f $(DESTDIR)$(prefix)/share/pixmaps/hello.png -rm -f $(DESTDIR)$(prefix)/share/man/man1/hello.1 .PHONY: all install clean distclean uninstall
configure(v=1.5):.
$ cat debhello-1.5/configure #!/bin/sh -e # default values PREFIX="/usr/local" VERBOSE="" WITH_MATH="0" LINKLIB="" PACKAGE_AUTHOR="John Doe" # parse arguments while [ "${1}" != "" ]; do VAR="${1%=*}" # Drop suffix =* VAL="${1#*=}" # Drop prefix *= case "${VAR}" in --prefix) PREFIX="${VAL}" ;; --verbose|-v) VERBOSE="-v" ;; --with-math) WITH_MATH="1" LINKLIB="-lm" ;; --author) PACKAGE_AUTHOR="${VAL}" ;; *) echo "W: Unknown argument: ${1}" esac shift done # setup configured Makefile and src/config.h sed -e "s,@prefix@,${PREFIX}," \ -e "s,@VERBOSE@,${VERBOSE}," \ -e "s,@LINKLIB@,${LINKLIB}," \ <Makefile.in >Makefile if [ "${WITH_MATH}" = 1 ]; then echo "#define WITH_MATH" >src/config.h else echo "/* not defined: WITH_MATH */" >src/config.h fi echo "#define PACKAGE_AUTHOR \"${PACKAGE_AUTHOR}\"" >>src/config.h
Please note that the configure command replaces strings with @…@ in Makefile.in to produce Makefile and creates src/config.h.
让我们使用 debmake 命令打包。
$ cd /path/to/debhello-1.5 $ debmake -x1 I: set parameters ... I: sanity check of parameters I: pkg="debhello", ver="1.5", rev="1" I: *** start packaging in "debhello-1.5". *** I: provide debhello_1.5.orig.tar.gz for non-native Debian package I: pwd = "/path/to" I: $ ln -sf debhello-1.5.tar.gz debhello_1.5.orig.tar.gz I: pwd = "/path/to/debhello-1.5" I: parse binary package settings: I: binary package=debhello Type=bin / Arch=any M-A=foreign I: analyze the source tree I: build_type = configure I: scan source for copyright+license text and file extensions I: 17 %, ext = in ...
结果与 “Section 5.6, “Step 2: Generate template files with debmake”” 中的相似,但是并不完全一致。
让我们来检查一下自动产生的模板文件。
debian/rules(模板文件,v=1.5):.
$ cd /path/to/debhello-1.5 $ cat debian/rules #!/usr/bin/make -f # You must remove unused comment lines for the released package. #export DH_VERBOSE = 1 #export DEB_BUILD_MAINT_OPTIONS = hardening=+all #export DEB_CFLAGS_MAINT_APPEND = -Wall -pedantic #export DEB_LDFLAGS_MAINT_APPEND = -Wl,-O1 %: dh $@
作为维护者,我们要把这个 Debian 软件包做得更好。
debian/rules(维护者版本,v=1.5):.
$ cd /path/to/debhello-1.5 $ vim debian/rules ... hack, hack, hack, ... $ cat debian/rules #!/usr/bin/make -f export DH_VERBOSE = 1 export DEB_BUILD_MAINT_OPTIONS = hardening=+all export DEB_CFLAGS_MAINT_APPEND = -Wall -pedantic export DEB_LDFLAGS_MAINT_APPEND = -Wl,--as-needed %: dh $@ override_dh_auto_configure: dh_auto_configure -- \ --with-math \ --author="Osamu Aoki"
在 debian/ 目录下还有一些其它的模板文件。它们也需要进行更新。
其余的打包步骤与 “Section 5.8, “Step 4: Building package with debuild”” 中的基本一致。
Here is an example of creating a simple Debian package from a simple C source program using Autotools = Autoconf and Automake (Makefile.am and configure.ac) as its build system.
此种源码通常也带有上游自动生成的 Makefile.in 和 configure 文件。在 autotools-dev 软件包的帮助下,我们可以按 “Section 13.8, “Makefile.in + configure(单个二进制软件包)”” 中所介绍的,使用这些文件进行打包。
The better alternative is to regenerate these files using the latest Autoconf and Automake packages if the upstream provided Makefile.am and configure.ac are compatible with the latest version. This is advantageous for porting to new CPU architectures, etc. This can be automated by using the “--with autoreconf” option for the dh command.
让我们假设上游的源码包为 debhello-1.6.tar.gz。
此类型的源码旨在作为非系统文件安装,例如:
$ tar -xzmf debhello-1.6.tar.gz $ cd debhello-1.6 $ autoreconf -ivf # optional $ ./configure --with-math $ make $ make install
让我们取得源码并制作 Debian 软件包。
下载 debhello-1.6.tar.gz.
$ wget http://www.example.org/download/debhello-1.6.tar.gz ... $ tar -xzmf debhello-1.6.tar.gz $ tree . ├── debhello-1.6 │ ├── LICENSE │ ├── Makefile.am │ ├── README.md │ ├── configure.ac │ ├── data │ │ ├── hello.desktop │ │ └── hello.png │ ├── man │ │ ├── Makefile.am │ │ └── hello.1 │ └── src │ ├── Makefile.am │ └── hello.c └── debhello-1.6.tar.gz 5 directories, 11 files
此处的源码如下所示。
src/hello.c(v=1.6):.
$ cat debhello-1.6/src/hello.c #include "config.h" #ifdef WITH_MATH # include <math.h> #endif #include <stdio.h> int main() { printf("Hello, I am " PACKAGE_AUTHOR "!\n"); #ifdef WITH_MATH printf("4.0 * atan(1.0) = %10f8\n", 4.0*atan(1.0)); #else printf("I can't do MATH!\n"); #endif return 0; }
Makefile.am(v=1.6):.
$ cat debhello-1.6/Makefile.am SUBDIRS = src man $ cat debhello-1.6/man/Makefile.am dist_man_MANS = hello.1 $ cat debhello-1.6/src/Makefile.am bin_PROGRAMS = hello hello_SOURCES = hello.c
configure.ac(v=1.6):.
$ cat debhello-1.6/configure.ac # -*- Autoconf -*- # Process this file with autoconf to produce a configure script. AC_PREREQ([2.69]) AC_INIT([debhello],[2.1],[[email protected]]) AC_CONFIG_SRCDIR([src/hello.c]) AC_CONFIG_HEADERS([config.h]) echo "Standard customization chores" AC_CONFIG_AUX_DIR([build-aux]) AM_INIT_AUTOMAKE([foreign]) # Add #define PACKAGE_AUTHOR ... in config.h with a comment AC_DEFINE(PACKAGE_AUTHOR, ["Osamu Aoki"], [Define PACKAGE_AUTHOR]) echo "Add --with-math option functionality to ./configure" AC_ARG_WITH([math], [AS_HELP_STRING([--with-math], [compile with math library @<:@default=yes@:>@])], [], [with_math="yes"] ) echo "==== withval := \"$withval\"" echo "==== with_math := \"$with_math\"" # m4sh if-else construct AS_IF([test "x$with_math" != "xno"],[ echo "==== Check include: math.h" AC_CHECK_HEADER(math.h,[],[ AC_MSG_ERROR([Couldn't find math.h.] ) ]) echo "==== Check library: libm" AC_SEARCH_LIBS(atan, [m]) #AC_CHECK_LIB(m, atan) echo "==== Build with LIBS := \"$LIBS\"" AC_DEFINE(WITH_MATH, [1], [Build with the math library]) ],[ echo "==== Skip building with math.h." AH_TEMPLATE(WITH_MATH, [Build without the math library]) ]) # Checks for programs. AC_PROG_CC AC_CONFIG_FILES([Makefile man/Makefile src/Makefile]) AC_OUTPUT
Tip | |
---|---|
Without “foreign” strictness level specified in AM_INIT_AUTOMAKE() as above, automake defaults to “gnu” strictness level requiring several files in the top-level directory. See “3.2 Strictness” in the automake document. |
让我们使用 debmake 命令打包。
$ cd /path/to/debhello-1.6 $ debmake -x1 I: set parameters ... I: sanity check of parameters I: pkg="debhello", ver="1.6", rev="1" I: *** start packaging in "debhello-1.6". *** I: provide debhello_1.6.orig.tar.gz for non-native Debian package I: pwd = "/path/to" I: $ ln -sf debhello-1.6.tar.gz debhello_1.6.orig.tar.gz I: pwd = "/path/to/debhello-1.6" I: parse binary package settings: I: binary package=debhello Type=bin / Arch=any M-A=foreign I: analyze the source tree I: build_type = Autotools with autoreconf I: scan source for copyright+license text and file extensions I: 33 %, ext = am ...
结果与 “Section 13.8, “Makefile.in + configure(单个二进制软件包)”” 中的类似,但是并不完全一致。
让我们来检查一下自动产生的模板文件。
debian/rules(模板文件,v=1.6):
$ cd /path/to/debhello-1.6 $ cat debian/rules #!/usr/bin/make -f # You must remove unused comment lines for the released package. #export DH_VERBOSE = 1 #export DEB_BUILD_MAINT_OPTIONS = hardening=+all #export DEB_CFLAGS_MAINT_APPEND = -Wall -pedantic #export DEB_LDFLAGS_MAINT_APPEND = -Wl,-O1 %: dh $@ --with autoreconf #override_dh_install: # dh_install --list-missing -X.la -X.pyc -X.pyo
作为维护者,我们要把这个 Debian 软件包做得更好。
debian/rules(维护者版本,v=1.6):.
$ cd /path/to/debhello-1.6 $ vim debian/rules ... hack, hack, hack, ... $ cat debian/rules #!/usr/bin/make -f export DH_VERBOSE = 1 export DEB_BUILD_MAINT_OPTIONS = hardening=+all export DEB_CFLAGS_MAINT_APPEND = -Wall -pedantic export DEB_LDFLAGS_MAINT_APPEND = -Wl,--as-needed %: dh $@ --with autoreconf override_dh_auto_configure: dh_auto_configure -- \ --with-math
在 debian/ 目录下还有一些其它的模板文件。它们也需要进行更新。
其余的打包步骤与 “Section 5.8, “Step 4: Building package with debuild”” 中的基本一致。
Here is an example of creating a simple Debian package from a simple C source program using CMake (CMakeLists.txt and some files such as config.h.in) as its build system.
The cmake command generates the Makefile file based on the CMakeLists.txt file and its -D option. It also configures the file as specified in its configure_file(…) by replacing strings with @…@ and changing the #cmakedefine … line.
让我们假设上游的源码包为 debhello-1.7.tar.gz。
此类型的源码旨在作为非系统文件安装,例如:
$ tar -xzmf debhello-1.7.tar.gz $ cd debhello-1.7 $ mkdir obj-x86_64-linux-gnu # for out-of-tree build $ cd obj-x86_64-linux-gnu $ cmake .. $ make $ make install
让我们取得源码并制作 Debian 软件包。
下载 debhello-1.7.tar.gz.
$ wget http://www.example.org/download/debhello-1.7.tar.gz ... $ tar -xzmf debhello-1.7.tar.gz $ tree . ├── debhello-1.7 │ ├── CMakeLists.txt │ ├── LICENSE │ ├── README.md │ ├── data │ │ ├── hello.desktop │ │ └── hello.png │ ├── man │ │ ├── CMakeLists.txt │ │ └── hello.1 │ └── src │ ├── CMakeLists.txt │ ├── config.h.in │ └── hello.c └── debhello-1.7.tar.gz 5 directories, 11 files
此处的源码如下所示。
src/hello.c(v=1.7):.
$ cat debhello-1.7/src/hello.c #include "config.h" #ifdef WITH_MATH # include <math.h> #endif #include <stdio.h> int main() { printf("Hello, I am " PACKAGE_AUTHOR "!\n"); #ifdef WITH_MATH printf("4.0 * atan(1.0) = %10f8\n", 4.0*atan(1.0)); #else printf("I can't do MATH!\n"); #endif return 0; }
src/config.h.in(v=1.7):.
$ cat debhello-1.7/src/config.h.in /* name of the package author */ #define PACKAGE_AUTHOR "@PACKAGE_AUTHOR@" /* math library support */ #cmakedefine WITH_MATH
CMakeLists.txt(v=1.7):.
$ cat debhello-1.7/CMakeLists.txt cmake_minimum_required(VERSION 2.8) project(debhello) set(PACKAGE_AUTHOR "Osamu Aoki") add_subdirectory(src) add_subdirectory(man) $ cat debhello-1.7/man/CMakeLists.txt install( FILES ${CMAKE_CURRENT_SOURCE_DIR}/hello.1 DESTINATION share/man/man1 ) $ cat debhello-1.7/src/CMakeLists.txt # Always define HAVE_CONFIG_H add_definitions(-DHAVE_CONFIG_H) # Interactively define WITH_MATH option(WITH_MATH "Build with math support" OFF) #variable_watch(WITH_MATH) # Generate config.h from config.h.in configure_file( "${CMAKE_CURRENT_SOURCE_DIR}/config.h.in" "${CMAKE_CURRENT_BINARY_DIR}/config.h" ) include_directories("${CMAKE_CURRENT_BINARY_DIR}") add_executable(hello hello.c) install(TARGETS hello RUNTIME DESTINATION bin )
让我们使用 debmake 命令打包。
$ cd /path/to/debhello-1.7 $ debmake -x1 I: set parameters ... I: sanity check of parameters I: pkg="debhello", ver="1.7", rev="1" I: *** start packaging in "debhello-1.7". *** I: provide debhello_1.7.orig.tar.gz for non-native Debian package I: pwd = "/path/to" I: $ ln -sf debhello-1.7.tar.gz debhello_1.7.orig.tar.gz I: pwd = "/path/to/debhello-1.7" I: parse binary package settings: I: binary package=debhello Type=bin / Arch=any M-A=foreign I: analyze the source tree I: build_type = Cmake I: scan source for copyright+license text and file extensions I: 33 %, ext = text ...
结果与 “Section 13.8, “Makefile.in + configure(单个二进制软件包)”” 中的类似,但是并不完全一致。
让我们来检查一下自动产生的模板文件。
debian/rules(模板文件,v=1.7):.
$ cd /path/to/debhello-1.7 $ cat debian/rules #!/usr/bin/make -f # You must remove unused comment lines for the released package. #export DH_VERBOSE = 1 #export DEB_BUILD_MAINT_OPTIONS = hardening=+all #export DEB_CFLAGS_MAINT_APPEND = -Wall -pedantic #export DEB_LDFLAGS_MAINT_APPEND = -Wl,-O1 %: dh $@ #override_dh_auto_configure: # dh_auto_configure -- \ # -DCMAKE_LIBRARY_ARCHITECTURE="$(DEB_TARGET_MULTIARCH)"
debian/control(模板文件,v=1.7):.
$ cat debian/control Source: debhello Section: unknown Priority: optional Maintainer: "Osamu Aoki" <[email protected]> Build-Depends: cmake, debhelper-compat (= 13) Standards-Version: 4.6.2 Homepage: <insert the upstream URL, if relevant> Rules-Requires-Root: no #Vcs-Git: https://salsa.debian.org/debian/debhello.git #Vcs-Browser: https://salsa.debian.org/debian/debhello Package: debhello Architecture: any Multi-Arch: foreign Depends: ${misc:Depends}, ${shlibs:Depends} Description: auto-generated package by debmake This Debian binary package was auto-generated by the debmake(1) command provided by the debmake package.
作为维护者,我们要把这个 Debian 软件包做得更好。
debian/rules(维护者版本,v=1.7):.
$ cd /path/to/debhello-1.7 $ vim debian/rules ... hack, hack, hack, ... $ cat debian/rules #!/usr/bin/make -f export DH_VERBOSE = 1 export DEB_BUILD_MAINT_OPTIONS = hardening=+all export DEB_CFLAGS_MAINT_APPEND = -Wall -pedantic export DEB_LDFLAGS_MAINT_APPEND = -Wl,--as-needed %: dh $@ override_dh_auto_configure: dh_auto_configure -- -DWITH-MATH=1
debian/control(维护者版本,v=1.7):.
$ vim debian/control ... hack, hack, hack, ... $ cat debian/control Source: debhello Section: devel Priority: optional Maintainer: Osamu Aoki <[email protected]> Build-Depends: cmake, debhelper-compat (= 13) Standards-Version: 4.6.2 Homepage: https://salsa.debian.org/debian/debmake-doc Rules-Requires-Root: no Package: debhello Architecture: any Multi-Arch: foreign Depends: ${misc:Depends}, ${shlibs:Depends} Description: Simple packaging example for debmake This Debian binary package is an example package. (This is an example only)
在 debian/ 目录下还有一些其它的模板文件。它们也需要进行更新。
其余的打包工作与 “Section 13.8, “Makefile.in + configure(单个二进制软件包)”” 中的近乎一致。
Here is an example of creating a set of Debian binary packages including the executable package, the shared library package, the development file package, and the debug symbol package from a simple C source program using Autotools = Autoconf and Automake (which use Makefile.am and configure.ac as their input files) as its build system.
让我们用与 “Section 13.9, “Autotools(单个二进制文件)”” 中的相同的方式打包。
让我们假设上游源码包为 debhello-2.0.tar.gz。
此类型的源码旨在作为非系统文件安装,例如:
$ tar -xzmf debhello-2.0.tar.gz $ cd debhello-2.0 $ autoreconf -ivf # optional $ ./configure --with-math $ make $ make install
让我们取得源码并制作 Debian 软件包。
下载 debhello-2.0.tar.gz.
$ wget http://www.example.org/download/debhello-2.0.tar.gz ... $ tar -xzmf debhello-2.0.tar.gz $ tree . ├── debhello-2.0 │ ├── LICENSE │ ├── Makefile.am │ ├── README.md │ ├── configure.ac │ ├── data │ │ ├── hello.desktop │ │ └── hello.png │ ├── lib │ │ ├── Makefile.am │ │ ├── sharedlib.c │ │ └── sharedlib.h │ ├── man │ │ ├── Makefile.am │ │ └── hello.1 │ └── src │ ├── Makefile.am │ └── hello.c └── debhello-2.0.tar.gz 6 directories, 14 files
此处的源码如下所示。
src/hello.c(v=2.0):.
$ cat debhello-2.0/src/hello.c #include "config.h" #include <stdio.h> #include <sharedlib.h> int main() { printf("Hello, I am " PACKAGE_AUTHOR "!\n"); sharedlib(); return 0; }
lib/sharedlib.h 与 lib/sharedlib.c(v=1.6):.
$ cat debhello-2.0/lib/sharedlib.h int sharedlib(); $ cat debhello-2.0/lib/sharedlib.c #include <stdio.h> int sharedlib() { printf("This is a shared library!\n"); return 0; }
Makefile.am(v=2.0):.
$ cat debhello-2.0/Makefile.am # recursively process `Makefile.am` in SUBDIRS SUBDIRS = lib src man $ cat debhello-2.0/man/Makefile.am # manpages (distributed in the source package) dist_man_MANS = hello.1 $ cat debhello-2.0/lib/Makefile.am # libtool librares to be produced lib_LTLIBRARIES = libsharedlib.la # source files used for lib_LTLIBRARIES libsharedlib_la_SOURCES = sharedlib.c # C pre-processor flags used for lib_LTLIBRARIES #libsharedlib_la_CPPFLAGS = # Headers files to be installed in <prefix>/include include_HEADERS = sharedlib.h # Versioning Libtool Libraries with version triplets libsharedlib_la_LDFLAGS = -version-info 1:0:0 $ cat debhello-2.0/src/Makefile.am # program executables to be produced bin_PROGRAMS = hello # source files used for bin_PROGRAMS hello_SOURCES = hello.c # C pre-processor flags used for bin_PROGRAMS AM_CPPFLAGS = -I$(srcdir) -I$(top_srcdir)/lib # Extra options for the linker for hello # hello_LDFLAGS = # Libraries the `hello` binary to be linked hello_LDADD = $(top_srcdir)/lib/libsharedlib.la
configure.ac(v=2.0):.
$ cat debhello-2.0/configure.ac # -*- Autoconf -*- # Process this file with autoconf to produce a configure script. AC_PREREQ([2.69]) AC_INIT([debhello],[2.2],[[email protected]]) AC_CONFIG_SRCDIR([src/hello.c]) AC_CONFIG_HEADERS([config.h]) echo "Standard customization chores" AC_CONFIG_AUX_DIR([build-aux]) AM_INIT_AUTOMAKE([foreign]) # Set default to --enable-shared --disable-static LT_INIT([shared disable-static]) # find the libltdl sources in the libltdl sub-directory LT_CONFIG_LTDL_DIR([libltdl]) # choose one LTDL_INIT([recursive]) #LTDL_INIT([subproject]) #LTDL_INIT([nonrecursive]) # Add #define PACKAGE_AUTHOR ... in config.h with a comment AC_DEFINE(PACKAGE_AUTHOR, ["Osamu Aoki"], [Define PACKAGE_AUTHOR]) # Checks for programs. AC_PROG_CC # only for the recursive case AC_CONFIG_FILES([Makefile lib/Makefile man/Makefile src/Makefile]) AC_OUTPUT
让我们用 debmake 命令将这些打包到多个包中:
Here, the -b\',libsharedlib1,libsharedlib-dev' option is used to specify the generated binary packages.
$ cd /path/to/debhello-2.0 $ debmake -b',libsharedlib1,libsharedlib-dev' -x1 I: set parameters ... I: sanity check of parameters I: pkg="debhello", ver="2.0", rev="1" I: *** start packaging in "debhello-2.0". *** I: provide debhello_2.0.orig.tar.gz for non-native Debian package I: pwd = "/path/to" I: $ ln -sf debhello-2.0.tar.gz debhello_2.0.orig.tar.gz I: pwd = "/path/to/debhello-2.0" I: parse binary package settings: ,libsharedlib1,libsharedlib-dev I: binary package=debhello Type=bin / Arch=any M-A=foreign I: binary package=libsharedlib1 Type=lib / Arch=any M-A=same I: binary package=libsharedlib-dev Type=dev / Arch=any M-A=same I: analyze the source tree I: build_type = Autotools with autoreconf ...
结果与 “Section 13.8, “Makefile.in + configure(单个二进制软件包)”” 中的相似,但是这个具有更多的模板文件。
让我们来检查一下自动产生的模板文件。
debian/rules(模板文件,v=2.0):.
$ cd /path/to/debhello-2.0 $ cat debian/rules #!/usr/bin/make -f # You must remove unused comment lines for the released package. #export DH_VERBOSE = 1 #export DEB_BUILD_MAINT_OPTIONS = hardening=+all #export DEB_CFLAGS_MAINT_APPEND = -Wall -pedantic #export DEB_LDFLAGS_MAINT_APPEND = -Wl,-O1 %: dh $@ --with autoreconf #override_dh_install: # dh_install --list-missing -X.la -X.pyc -X.pyo
作为维护者,我们要把这个 Debian 软件包做得更好。
debian/rules(维护者版本,v=2.0):.
$ cd /path/to/debhello-2.0 $ vim debian/rules ... hack, hack, hack, ... $ cat debian/rules #!/usr/bin/make -f export DH_VERBOSE = 1 export DEB_BUILD_MAINT_OPTIONS = hardening=+all export DEB_CFLAGS_MAINT_APPEND = -Wall -pedantic export DEB_LDFLAGS_MAINT_APPEND = -Wl,--as-needed %: dh $@ --with autoreconf override_dh_missing: dh_missing -X.la
debian/control(维护者版本,v=2.0):.
$ vim debian/control ... hack, hack, hack, ... $ cat debian/control Source: debhello Section: devel Priority: optional Maintainer: Osamu Aoki <[email protected]> Build-Depends: debhelper-compat (= 13), dh-autoreconf Standards-Version: 4.6.2 Homepage: https://salsa.debian.org/debian/debmake-doc Rules-Requires-Root: no Package: debhello Architecture: any Multi-Arch: foreign Depends: libsharedlib1 (= ${binary:Version}), ${misc:Depends}, ${shlibs:Depends} Description: Simple packaging example for debmake This package contains the compiled binary executable. . This Debian binary package is an example package. (This is an example only) Package: libsharedlib1 Section: libs Architecture: any Multi-Arch: same Pre-Depends: ${misc:Pre-Depends} Depends: ${misc:Depends}, ${shlibs:Depends} Description: Simple packaging example for debmake This package contains the shared library. Package: libsharedlib-dev Section: libdevel Architecture: any Multi-Arch: same Depends: libsharedlib1 (= ${binary:Version}), ${misc:Depends} Description: Simple packaging example for debmake This package contains the development files.
debian/*.install(维护者版本,v=2.0):.
$ vim debian/copyright ... hack, hack, hack, ... $ cat debian/copyright Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ Upstream-Name: debhello Upstream-Contact: Osamu Aoki <[email protected]> Source: https://salsa.debian.org/debian/debmake-doc Files: * Copyright: 2015-2021 Osamu Aoki <[email protected]> License: Expat Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: . The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. . THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
因为上游源码已经具有正确的自动生成的 Makefile 文件,所以没有必要再去创建 debian/install 和 debian/manpages 文件。
在 debian/ 目录下还有一些其它的模板文件。它们也需要进行更新。
debian/ 目录下的模板文件。(v=2.0):.
$ rm -f debian/clean debian/dirs debian/install debian/links $ rm -f debian/README.source debian/source/*.ex $ rm -rf debian/patches $ tree -F debian debian/ ├── README.Debian ├── changelog ├── control ├── copyright ├── debhello.dirs ├── debhello.doc-base ├── debhello.docs ├── debhello.examples ├── debhello.info ├── debhello.install ├── debhello.links ├── debhello.manpages ├── gbp.conf ├── libsharedlib-dev.install ├── libsharedlib1.install ├── libsharedlib1.symbols ├── rules* ├── salsa-ci.yml ├── source/ │ └── format ├── tests/ │ └── control ├── upstream/ │ └── metadata └── watch 4 directories, 22 files
其余的打包工作与 “Section 13.8, “Makefile.in + configure(单个二进制软件包)”” 中的近乎一致。
此处是生成的二进制包的依赖项列表。
生成的二进制包的依赖项列表(v=2.0):.
$ dpkg -f debhello-dbgsym_2.0-1_amd64.deb pre-depends \ depends recommends conflicts breaks Depends: debhello (= 2.0-1) $ dpkg -f debhello_2.0-1_amd64.deb pre-depends \ depends recommends conflicts breaks Depends: libsharedlib1 (= 2.0-1), libc6 (>= 2.34) $ dpkg -f libsharedlib-dev_2.0-1_amd64.deb pre-depends \ depends recommends conflicts breaks Depends: libsharedlib1 (= 2.0-1) $ dpkg -f libsharedlib1-dbgsym_2.0-1_amd64.deb pre-depends \ depends recommends conflicts breaks Depends: libsharedlib1 (= 2.0-1) $ dpkg -f libsharedlib1_2.0-1_amd64.deb pre-depends \ depends recommends conflicts breaks Depends: libc6 (>= 2.2.5)
Here is an example of creating a set of Debian binary packages including the executable package, the shared library package, the development file package, and the debug symbol package from a simple C source program using CMake (CMakeLists.txt and some files such as config.h.in) as its build system.
让我们假设上游源码包为 debhello-2.1.tar.gz。
此类型的源码旨在作为非系统文件安装,例如:
$ tar -xzmf debhello-2.1.tar.gz $ cd debhello-2.1 $ mkdir obj-x86_64-linux-gnu $ cd obj-x86_64-linux-gnu $ cmake .. $ make $ make install
让我们取得源码并制作 Debian 软件包。
下载 debhello-2.1.tar.gz.
$ wget http://www.example.org/download/debhello-2.1.tar.gz ... $ tar -xzmf debhello-2.1.tar.gz $ tree . ├── debhello-2.1 │ ├── CMakeLists.txt │ ├── LICENSE │ ├── README.md │ ├── data │ │ ├── hello.desktop │ │ └── hello.png │ ├── lib │ │ ├── CMakeLists.txt │ │ ├── sharedlib.c │ │ └── sharedlib.h │ ├── man │ │ ├── CMakeLists.txt │ │ └── hello.1 │ └── src │ ├── CMakeLists.txt │ ├── config.h.in │ └── hello.c └── debhello-2.1.tar.gz 6 directories, 14 files
此处的源码如下所示。
src/hello.c(v=2.1):.
$ cat debhello-2.1/src/hello.c #include "config.h" #include <stdio.h> #include <sharedlib.h> int main() { printf("Hello, I am " PACKAGE_AUTHOR "!\n"); sharedlib(); return 0; }
src/config.h.in(v=2.1):.
$ cat debhello-2.1/src/config.h.in /* name of the package author */ #define PACKAGE_AUTHOR "@PACKAGE_AUTHOR@"
lib/sharedlib.c 与 lib/sharedlib.h(v=2.1):.
$ cat debhello-2.1/lib/sharedlib.h int sharedlib(); $ cat debhello-2.1/lib/sharedlib.c #include <stdio.h> int sharedlib() { printf("This is a shared library!\n"); return 0; }
CMakeLists.txt(v=2.1):.
$ cat debhello-2.1/CMakeLists.txt cmake_minimum_required(VERSION 2.8) project(debhello) set(PACKAGE_AUTHOR "Osamu Aoki") add_subdirectory(lib) add_subdirectory(src) add_subdirectory(man) $ cat debhello-2.1/man/CMakeLists.txt install( FILES ${CMAKE_CURRENT_SOURCE_DIR}/hello.1 DESTINATION share/man/man1 ) $ cat debhello-2.1/src/CMakeLists.txt # Always define HAVE_CONFIG_H add_definitions(-DHAVE_CONFIG_H) # Generate config.h from config.h.in configure_file( "${CMAKE_CURRENT_SOURCE_DIR}/config.h.in" "${CMAKE_CURRENT_BINARY_DIR}/config.h" ) include_directories("${CMAKE_CURRENT_BINARY_DIR}") include_directories("${CMAKE_SOURCE_DIR}/lib") add_executable(hello hello.c) target_link_libraries(hello sharedlib) install(TARGETS hello RUNTIME DESTINATION bin )
让我们使用 debmake 命令打包。
$ cd /path/to/debhello-2.1 $ debmake -b',libsharedlib1,libsharedlib-dev' -x1 I: set parameters ... I: sanity check of parameters I: pkg="debhello", ver="2.1", rev="1" I: *** start packaging in "debhello-2.1". *** I: provide debhello_2.1.orig.tar.gz for non-native Debian package I: pwd = "/path/to" I: $ ln -sf debhello-2.1.tar.gz debhello_2.1.orig.tar.gz I: pwd = "/path/to/debhello-2.1" I: parse binary package settings: ,libsharedlib1,libsharedlib-dev I: binary package=debhello Type=bin / Arch=any M-A=foreign I: binary package=libsharedlib1 Type=lib / Arch=any M-A=same I: binary package=libsharedlib-dev Type=dev / Arch=any M-A=same I: analyze the source tree I: build_type = Cmake ...
结果与 “Section 13.8, “Makefile.in + configure(单个二进制软件包)”” 中的类似,但是并不完全一致。
让我们来检查一下自动产生的模板文件。
debian/rules(模板文件,v=2.1):.
$ cd /path/to/debhello-2.1 $ cat debian/rules #!/usr/bin/make -f # You must remove unused comment lines for the released package. #export DH_VERBOSE = 1 #export DEB_BUILD_MAINT_OPTIONS = hardening=+all #export DEB_CFLAGS_MAINT_APPEND = -Wall -pedantic #export DEB_LDFLAGS_MAINT_APPEND = -Wl,-O1 %: dh $@ #override_dh_auto_configure: # dh_auto_configure -- \ # -DCMAKE_LIBRARY_ARCHITECTURE="$(DEB_TARGET_MULTIARCH)"
作为维护者,我们要把这个 Debian 软件包做得更好。
debian/rules(维护者版本,v=2.1):.
$ cd /path/to/debhello-2.1 $ vim debian/rules ... hack, hack, hack, ... $ cat debian/rules #!/usr/bin/make -f export DH_VERBOSE = 1 export DEB_BUILD_MAINT_OPTIONS = hardening=+all export DEB_CFLAGS_MAINT_APPEND = -Wall -pedantic export DEB_LDFLAGS_MAINT_APPEND = -Wl,--as-needed DEB_HOST_MULTIARCH ?= $(shell dpkg-architecture -qDEB_HOST_MULTIARCH) %: dh $@ override_dh_auto_configure: dh_auto_configure -- \ -DCMAKE_LIBRARY_ARCHITECTURE="$(DEB_HOST_MULTIARCH)"
debian/control(维护者版本,v=2.1):.
$ vim debian/control ... hack, hack, hack, ... $ cat debian/control Source: debhello Section: devel Priority: optional Maintainer: Osamu Aoki <[email protected]> Build-Depends: cmake, debhelper-compat (= 13) Standards-Version: 4.6.2 Homepage: https://salsa.debian.org/debian/debmake-doc Rules-Requires-Root: no Package: debhello Architecture: any Multi-Arch: foreign Depends: libsharedlib1 (= ${binary:Version}), ${misc:Depends}, ${shlibs:Depends} Description: Simple packaging example for debmake This package contains the compiled binary executable. . This Debian binary package is an example package. (This is an example only) Package: libsharedlib1 Section: libs Architecture: any Multi-Arch: same Pre-Depends: ${misc:Pre-Depends} Depends: ${misc:Depends}, ${shlibs:Depends} Description: Simple packaging example for debmake This package contains the shared library. Package: libsharedlib-dev Section: libdevel Architecture: any Multi-Arch: same Depends: libsharedlib1 (= ${binary:Version}), ${misc:Depends} Description: Simple packaging example for debmake This package contains the development files.
debian/*.install(维护者版本,v=2.1):.
$ vim debian/copyright ... hack, hack, hack, ... $ cat debian/copyright Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ Upstream-Name: debhello Upstream-Contact: Osamu Aoki <[email protected]> Source: https://salsa.debian.org/debian/debmake-doc Files: * Copyright: 2015-2021 Osamu Aoki <[email protected]> License: Expat Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: . The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. . THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
需要对上游的 CMakeList.txt 进行修补,以便应对多架构的路径。
debian/patches/*(维护者版本,v=2.1):.
... hack, hack, hack, ... $ cat debian/libsharedlib1.symbols libsharedlib.so.1 libsharedlib1 #MINVER# sharedlib@Base 2.1
因为上游源码已经具有正确的自动生成的 Makefile 文件,所以没有必要再去创建 debian/install 和 debian/manpages 文件。
在 debian/ 目录下还有一些其它的模板文件。它们也需要进行更新。
debian/ 目录下的模板文件。(v=2.1):.
$ rm -f debian/clean debian/dirs debian/install debian/links $ rm -f debian/README.source debian/source/*.ex $ tree -F debian debian/ ├── README.Debian ├── changelog ├── control ├── copyright ├── debhello.dirs ├── debhello.doc-base ├── debhello.docs ├── debhello.examples ├── debhello.info ├── debhello.install ├── debhello.links ├── debhello.manpages ├── gbp.conf ├── libsharedlib-dev.install ├── libsharedlib1.install ├── libsharedlib1.symbols ├── patches/ │ ├── 000-cmake-multiarch.patch │ └── series ├── rules* ├── salsa-ci.yml ├── source/ │ └── format ├── tests/ │ └── control ├── upstream/ │ └── metadata └── watch 5 directories, 24 files
其余的打包工作与 “Section 13.8, “Makefile.in + configure(单个二进制软件包)”” 中的近乎一致。
此处是生成的二进制包的依赖项列表。
生成的二进制包的依赖项列表(v=2.1):.
$ dpkg -f debhello-dbgsym_2.1-1_amd64.deb pre-depends \ depends recommends conflicts breaks Depends: debhello (= 2.1-1) $ dpkg -f debhello_2.1-1_amd64.deb pre-depends \ depends recommends conflicts breaks Depends: libsharedlib1 (= 2.1-1), libc6 (>= 2.34) $ dpkg -f libsharedlib-dev_2.1-1_amd64.deb pre-depends \ depends recommends conflicts breaks Depends: libsharedlib1 (= 2.1-1) $ dpkg -f libsharedlib1-dbgsym_2.1-1_amd64.deb pre-depends \ depends recommends conflicts breaks Depends: libsharedlib1 (= 2.1-1) $ dpkg -f libsharedlib1_2.1-1_amd64.deb pre-depends \ depends recommends conflicts breaks Depends: libc6 (>= 2.2.5)
此处是更新 “Section 13.11, “Autotools(多个二进制软件包)”” 中提供的简单上游 C 语言源代码 debhello-2.0.tar.gz 以便进行国际化(i18n)并创建更新后的上游 C 语言源代码 debhello-2.0.tar.gz 的示例。
在实际情况中,此软件包应该已被国际化过。所以此示例用作帮助您了解国际化的具体实现方法。
Tip | |
---|---|
负责维护国际化的维护者的日常活动就是将通过缺陷追踪系统(BTS)反馈给您的 po 翻译文件添加至 po/ 目录,然后更新 po/LINGUAS 文件的语言列表。 |
让我们取得源码并制作 Debian 软件包。
下载 debhello-2.0.tar.gz(国际化版).
$ wget http://www.example.org/download/debhello-2.0.tar.gz ... $ tar -xzmf debhello-2.0.tar.gz $ tree . ├── debhello-2.0 │ ├── LICENSE │ ├── Makefile.am │ ├── README.md │ ├── configure.ac │ ├── data │ │ ├── hello.desktop │ │ └── hello.png │ ├── lib │ │ ├── Makefile.am │ │ ├── sharedlib.c │ │ └── sharedlib.h │ ├── man │ │ ├── Makefile.am │ │ └── hello.1 │ └── src │ ├── Makefile.am │ └── hello.c └── debhello-2.0.tar.gz 6 directories, 14 files
使用 gettextize 命令将此源代码树国际化,并删除由 Autotools 自动生成的文件。
运行 gettextize(国际化版):.
$ cd /path/to/debhello-2.0 $ gettextize Creating po/ subdirectory Creating build-aux/ subdirectory Copying file ABOUT-NLS Copying file build-aux/config.rpath Not copying intl/ directory. Copying file po/Makefile.in.in Copying file po/Makevars.template Copying file po/Rules-quot Copying file po/boldquot.sed Copying file po/[email protected] Copying file po/[email protected] Copying file po/insert-header.sin Copying file po/quot.sed Copying file po/remove-potcdate.sin Creating initial po/POTFILES.in Creating po/ChangeLog Creating directory m4 Copying file m4/gettext.m4 Copying file m4/iconv.m4 Copying file m4/lib-ld.m4 Copying file m4/lib-link.m4 Copying file m4/lib-prefix.m4 Copying file m4/nls.m4 Copying file m4/po.m4 Copying file m4/progtest.m4 Creating m4/ChangeLog Updating Makefile.am (backup is in Makefile.am~) Updating configure.ac (backup is in configure.ac~) Creating ChangeLog Please use AM_GNU_GETTEXT([external]) in order to cause autoconfiguration to look for an external libintl. Please create po/Makevars from the template in po/Makevars.template. You can then remove po/Makevars.template. Please fill po/POTFILES.in as described in the documentation. Please run 'aclocal' to regenerate the aclocal.m4 file. You need aclocal from GNU automake 1.9 (or newer) to do this. Then run 'autoconf' to regenerate the configure file. You will also need config.guess and config.sub, which you can get from the CV... of the 'config' project at http://savannah.gnu.org/. The commands to fetch th... are $ wget 'http://savannah.gnu.org/cgi-bin/viewcvs/*checkout*/config/config/conf... $ wget 'http://savannah.gnu.org/cgi-bin/viewcvs/*checkout*/config/config/conf... You might also want to copy the convenience header file gettext.h from the /usr/share/gettext directory into your package. It is a wrapper around <libintl.h> that implements the configure --disable-nl... option. Press Return to acknowledge the previous 6 paragraphs. $ rm -rf m4 build-aux *~
让我们确认一下 po/ 目录下生成的文件。
po 目录下的文件(国际化版):.
$ ls -l po total 60 -rw-rw-r-- 1 osamu osamu 494 Jul 24 10:14 ChangeLog -rw-rw-r-- 1 osamu osamu 17577 Jul 24 10:14 Makefile.in.in -rw-rw-r-- 1 osamu osamu 3376 Jul 24 10:14 Makevars.template -rw-rw-r-- 1 osamu osamu 59 Jul 24 10:14 POTFILES.in -rw-rw-r-- 1 osamu osamu 2203 Jul 24 10:14 Rules-quot -rw-rw-r-- 1 osamu osamu 217 Jul 24 10:14 boldquot.sed -rw-rw-r-- 1 osamu osamu 1337 Jul 24 10:14 [email protected] -rw-rw-r-- 1 osamu osamu 1203 Jul 24 10:14 [email protected] -rw-rw-r-- 1 osamu osamu 672 Jul 24 10:14 insert-header.sin -rw-rw-r-- 1 osamu osamu 153 Jul 24 10:14 quot.sed -rw-rw-r-- 1 osamu osamu 432 Jul 24 10:14 remove-potcdate.sin
Let’s update the configure.ac by adding “AM_GNU_GETTEXT([external])”, etc..
configure.ac(国际化版):.
$ vim configure.ac ... hack, hack, hack, ... $ cat configure.ac # -*- Autoconf -*- # Process this file with autoconf to produce a configure script. AC_PREREQ([2.69]) AC_INIT([debhello],[2.2],[[email protected]]) AC_CONFIG_SRCDIR([src/hello.c]) AC_CONFIG_HEADERS([config.h]) echo "Standard customization chores" AC_CONFIG_AUX_DIR([build-aux]) AM_INIT_AUTOMAKE([foreign]) # Set default to --enable-shared --disable-static LT_INIT([shared disable-static]) # find the libltdl sources in the libltdl sub-directory LT_CONFIG_LTDL_DIR([libltdl]) # choose one LTDL_INIT([recursive]) #LTDL_INIT([subproject]) #LTDL_INIT([nonrecursive]) # Add #define PACKAGE_AUTHOR ... in config.h with a comment AC_DEFINE(PACKAGE_AUTHOR, ["Osamu Aoki"], [Define PACKAGE_AUTHOR]) # Checks for programs. AC_PROG_CC # desktop file support required AM_GNU_GETTEXT_VERSION([0.19.3]) AM_GNU_GETTEXT([external]) # only for the recursive case AC_CONFIG_FILES([Makefile po/Makefile.in lib/Makefile man/Makefile src/Makefile]) AC_OUTPUT
让我们从 po/Makevars.template 文件中创建 po/Makevars 文件。
po/Makevars(国际化版):.
... hack, hack, hack, ... $ diff -u po/Makevars.template po/Makevars --- po/Makevars.template 2024-07-24 10:14:46.440850967 +0900 +++ po/Makevars 2024-07-24 10:14:46.520852183 +0900 @@ -18,14 +18,14 @@ # or entity, or to disclaim their copyright. The empty string stands for # the public domain; in this case the translators are expected to disclaim # their copyright. -COPYRIGHT_HOLDER = Free Software Foundation, Inc. +COPYRIGHT_HOLDER = Osamu Aoki <[email protected]> # This tells whether or not to prepend "GNU " prefix to the package # name that gets inserted into the header of the $(DOMAIN).pot file. # Possible values are "yes", "no", or empty. If it is empty, try to # detect it automatically by scanning the files in $(top_srcdir) for # "GNU packagename" string. -PACKAGE_GNU = +PACKAGE_GNU = no # This is the email address or URL to which the translators shall report # bugs in the untranslated strings: $ rm po/Makevars.template
Let’s update C sources for the i18n version by wrapping strings with _(…).
src/hello.c (国际化版):.
... hack, hack, hack, ... $ cat src/hello.c #include "config.h" #include <stdio.h> #include <sharedlib.h> #include <libintl.h> #define _(string) gettext (string) int main() { printf(_("Hello, I am " PACKAGE_AUTHOR "!\n")); sharedlib(); return 0; }
lib/sharedlib.c(国际化版):.
... hack, hack, hack, ... $ cat lib/sharedlib.c #include <stdio.h> #include <libintl.h> #define _(string) gettext (string) int sharedlib() { printf(_("This is a shared library!\n")); return 0; }
新版本的 gettext(v = 0.19)可以直接处理桌面文件的国际化版本。
data/hello.desktop.in(国际化版):.
$ fgrep -v '[ja]=' data/hello.desktop > data/hello.desktop.in $ rm data/hello.desktop $ cat data/hello.desktop.in [Desktop Entry] Name=Hello Comment=Greetings Type=Application Keywords=hello Exec=hello Terminal=true Icon=hello.png Categories=Utility;
让我们列出输入文件,以便在 po/POTFILES.in 中提取可翻译的字符串。
po/POTFILES.in(国际化版):.
... hack, hack, hack, ... $ cat po/POTFILES.in src/hello.c lib/sharedlib.c data/hello.desktop.in
此处是在 SUBDIRS 环境变量中添加 po 目录后更新过的根 Makefile.am 文件。
Makefile.am (国际化版):.
$ cat Makefile.am # recursively process `Makefile.am` in SUBDIRS SUBDIRS = po lib src man ACLOCAL_AMFLAGS = -I m4 EXTRA_DIST = build-aux/config.rpath m4/ChangeLog
让我们创建一个翻译模板文件 debhello.pot。
po/debhello.pot(国际化版):.
$ xgettext -f po/POTFILES.in -d debhello -o po/debhello.pot -k_ $ cat po/debhello.pot # SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. # #, fuzzy msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2024-07-24 10:14+0900\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Language-Team: LANGUAGE <[email protected]>\n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=CHARSET\n" "Content-Transfer-Encoding: 8bit\n" #: src/hello.c:9 #, c-format msgid "Hello, I am " msgstr "" #: lib/sharedlib.c:7 #, c-format msgid "This is a shared library!\n" msgstr "" #: data/hello.desktop.in:3 msgid "Hello" msgstr "" #: data/hello.desktop.in:4 msgid "Greetings" msgstr "" #: data/hello.desktop.in:6 msgid "hello" msgstr ""
让我们添加法语的翻译。
po/LINGUAS 与 po/fr.po(国际化版):.
$ echo 'fr' > po/LINGUAS $ cp po/debhello.pot po/fr.po $ vim po/fr.po ... hack, hack, hack, ... $ cat po/fr.po # SOME DESCRIPTIVE TITLE. # This file is put in the public domain. # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. # msgid "" msgstr "" "Project-Id-Version: debhello 2.2\n" "Report-Msgid-Bugs-To: [email protected]\n" "POT-Creation-Date: 2015-03-01 20:22+0900\n" "PO-Revision-Date: 2015-02-21 23:18+0900\n" "Last-Translator: Osamu Aoki <[email protected]>\n" "Language-Team: French <[email protected]>\n" "Language: ja\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #: src/hello.c:34 #, c-format msgid "Hello, my name is %s!\n" msgstr "Bonjour, je m'appelle %s!\n" #: lib/sharedlib.c:29 #, c-format msgid "This is a shared library!\n" msgstr "Ceci est une bibliothèque partagée!\n" #: data/hello.desktop.in:3 msgid "Hello" msgstr "" #: data/hello.desktop.in:4 msgid "Greetings" msgstr "Salutations" #: data/hello.desktop.in:6 msgid "hello" msgstr "" #: data/hello.desktop.in:9 msgid "hello.png" msgstr ""
打包工作与 “Section 13.11, “Autotools(多个二进制软件包)”” 中的近乎一致。
You can find more i18n examples by following “Section 13.14, “细节””.
所示示例的实际细节及其变体可通过以下方式获得。
如何取得细节.
$ apt-get source debmake-doc $ cd debmake-doc* $ cd examples $ view examples/README.md
Follow the exact instruction in examples/README.md.
$ cd examples $ make
Now, each directory named as examples/debhello-?.?_build-? contains the Debian packaging example.
Notable examples are: