內容目錄
讓我們嘗試創建一個自己的軟件包(或者,“收養”一個已存在的軟件包則更好)。
如果你要基於某個上遊程序構建軟件包,那麼典型的Debian軟件包構建流程就會包含生成幾個特定的文件,如下:
獲取上游軟件的拷貝,通常爲壓縮過的tar格式。
package
-version
.tar.gz
在上遊程序的 debian
目錄下添加 Debian 特定的打包修改,並以 3.0
(quilt)
格式創建一個非本地源碼包。(也就是指用於構建 Debian 軟家包的輸入文件集合)
package
_version
.orig.tar.gz
package
_version
-revision
.debian.tar.gz
[4]
package
_version
-revision
.dsc
從 Debian 源碼包構建 Debian 二進制包;二進制包的格式通常是.deb
(或者
.udeb
,Debian Installer 專用)
package
_version
-revision
_arch
.deb
請注意,在 Debian 軟件包文件名中,分隔
和
package
的字符從 tarball 名稱的
version
-
(連字符)換成了 _
(下劃線)。
在上述的文件名中,將
部分替換爲
package name, 將
package
部分替換爲 upstream version,
將version
部分替換爲 Debian revision,以及將
revision
部分替換爲 package architecture,根據 Debian 方針手冊。 [5]
arch
本大綱中的每一步都會在後續的章節中輔以詳細的例子進行解釋。
可能你已經選好了要製作的軟件包。第一件要做的事是檢查它是否已經存在於發行版倉庫中了,參考方法如下:
aptitude 命令
the Debian packages 頁面
如果軟件包已經存在,直接安裝就好了!:-) 如果它是被 拋棄(orphaned) 的——也就是說它的維護者被設置爲 Debian QA Group,那麼你可以嘗試接手維護它。你也可以“收養”維護者發出“Request for Adoption”(RFA)請求的軟件包。[6]
軟件包歸屬狀態有這幾種:
作爲旁註必須指出,Debian 已經擁有了絕大多數類型軟件的軟件包,倉庫中軟件包的數量也遠遠超過了有上傳權限的貢獻者的數量。因此,爲已經在倉庫中的軟件包貢獻力量是非常受其他開發者歡迎的(且更容易獲得 sponsorship)[7]。你可以通過非常多的方式來實現這一目的:
接手被拋棄而仍然被很多人使用的套件。
加入 打包小組。
爲某些常用的套件分類 Bug。
在需要時準備 QA 或 NMU 上傳。
如果你有能力“收養”那個軟件包,下載(使用 apt-get source
或其他類似的工具)並分析它的代碼。這篇文檔沒有包含有關如何接手軟件包的詳細信息,但幸運的是由於接手軟件包時起始的工作已經有人完成,接手的工作應比從頭開始輕鬆得多。儘管如此,請繼續閱讀,下面給出的建議會對你很有幫助。
packagename
如果你要製作的套件是全新的,並且希望它出現在 Debian 中,請按照以下的步驟進行:
首先,你必須知道這個軟件的可用性,並且需要試用一段時間。
你必須在 Work-Needing and Prospective
Packages 上查看以確定沒有其他人已經開始了工作。如果沒有,則提交一份 ITP (Intent To Package) Bug
報告到 wnpp
僞軟件包(可以使用
reportbug)。如果已經有人在處理,則在需要的情況下聯繫他或他們。如果不需要你的幫助,就尋找其他你感興趣且沒有人維護的軟件包吧。
該軟件 必須有一個許可證。
對於 main
類的軟件, Debian 方針要求它 完全兼容
Debian Free Software Guidelines (Debian 自由軟件準則) (DFSG) 並且 不要求用
main
類以外的軟件來編譯或執行。這是最理想的狀況。
對於 contrib
類的軟件,其許可證必須滿足 DFSG 的全部條件,但可以依賴於
main
之外的軟件包以完成編譯或運行。
對於 non-free
類的軟件,其許可證可以不滿足 DFSG 中的一些條件,但至少 必須是可分發的。
如果你不清楚你的軟體應該分入哪一類,則把許可證文本發送到 debian-legal@lists.debian.org 請他人提出意見。
程序 不應該 給 Debian 系統帶來安全和維護上的問題。
程序應當有良好的文檔,最好源代碼也容易理解(比如,不混亂)。
你應該與程序的作者取得聯繫問一下他是否認爲程序應當被打包,以及他是否對 Debian 友好。能夠詢問作者關於程序的任何問題是非常重要的,所以不要嘗試打包一個無人維護的軟件。
程序一定 不應該 setuid 到 root 。更好的情況是它不 setuid 或 setgid 到任何用戶或組。
程序不應該是守護進程,也不應該進入 */sbin
目錄或者以 root 打開任何端口。
當然,這些問題都只是爲了安全,並試圖讓你不至於在比如 setuid 守護進程等問題上犯錯誤而激怒了用戶... 當你在打包方面有了更多經驗時,就可以處理這樣的軟件包了。
我們鼓勵你,作爲一個新維護人員,選擇易於打包和維護的軟件包,而不鼓勵選擇複雜的軟件包。
簡單軟件包
單二進制軟件包,arch = all (比如像壁紙那樣的資料集)
單二進制軟件包,arch = all (用解釋型語言編寫的可執行腳本文件,比如 POSIX shell)
中等複雜軟件包
單二進制軟件包,arch = any (用C/C++等語言編寫的 ELF 二進制可執行文件)
複合二進制軟件包,arch = any + all (包含ELF二進制可執行程序+文檔的軟件包)
既不是 tar.gz
也不是 tar.bz2
格式的上有源代碼
源代碼中包含不可分發的內容。
高複雜軟件包
被其他軟件包使用的解釋器模塊包
被其他軟件包使用的一般ELF庫文件包
複合二進制的軟件包,包含ELF庫文件包
多上游的源碼包
內核模塊軟件包
內核補丁軟件包
包含冷門維護者腳本的軟件包
打包高複雜軟件包並非難如登天,但需要更多知識。你應該針對每一個複雜特性來搜尋針對性的指南。比如,一些語言有它們自己的子策略文檔:
還有一句拉丁諺語:fabricando fit faber (熟能生巧)。我們
強烈 建議你在閱讀這篇教程的時候,用一個簡單軟件包來實踐和實驗所有的 Debian
打包步驟。下邊的步驟創建了一個微不足道的軟件包 hello-sh-1.0.tar.gz
,它可以提供一個良好的起點:[8]
$ mkdir -p hello-sh/hello-sh-1.0; cd hello-sh/hello-sh-1.0 $ cat > hello <<EOF #!/bin/sh # (C) 2011 Foo Bar, GPL2+ echo "Hello!" EOF $ chmod 755 hello $ cd .. $ tar -cvzf hello-sh-1.0.tar.gz hello-sh-1.0
第一件要做的事就是找到並下載原始的源代碼。我們假定你已經從作者的主頁上找到了它的源代碼。Unix 下的自由軟件源代碼通常是以
tar+gzip 格式(擴展名爲
.tar.gz
)或
tar+bzip2 格式(擴展名爲
.tar.bz2
)或tar+xz
(擴展名爲.tar.xz
)的形式提供的。通常歸檔文件中包含了一個名爲
的子目錄,裏麪包含了全部的源代碼。
package
-version
如果最新你版本的源代碼可通過像 Git,Subversion,CVS 這樣的版本控制系統獲得,你可以用 git
clone
, svn co
, 或 cvs co
來下載它,並自行將它重新打包爲 tar+gzip, 別忘了
--exclude-vcs
選項。
如果你的程序源代碼是以其他形式提供的(比如文件名以 .Z
或
.zip
結尾[9]),則使用合適的工具將其解包,再重新打包。
如果你的程序源代碼中包含一些不符合DFSG的內容,你應當解包後移除它們,再以添加了 dfsg
的上游版本號重新打包。
作爲示例,我將使用一個名爲 gentoo 的程序,它是一個 GTK+ 文件管理器。[10]
在你的用戶主目錄下創建一個子目錄,命名爲 debian
或 deb
或其他你喜歡且合適的名字(本例中使用 ~/gentoo
)。把下載好的歸檔文件放在其中並解包(使用
tar xzf gentoo-0.9.12.tar.gz
命令)。要確定解包過程中沒有發生錯誤,即便是有一點
不恰當
也不行,因爲在別人的系統上解包這些文件時,可能他們的工具並不忽略這些反常的現象,於是就會出現問題。在你的終端屏幕上,應該看到如下的情形。
$ mkdir ~/gentoo ; cd ~/gentoo
$ wget http://www.example.org
/gentoo-0.9.12.tar.gz
$ tar xvzf gentoo-0.9.12.tar.gz
$ ls -F
gentoo-0.9.12/
gentoo-0.9.12.tar.gz
現在又有了一個新的子目錄,名爲 gentoo-0.9.12
。進入該目錄並
徹底 讀完其中的文檔。通常情況下這些文檔被命名爲
README*
、INSTALL*
、*.lsm
或 *.html
。你必須找到關於如何正確編譯和安裝程序的指導(最可能的是他們會默認你希望把程序安裝到
/usr/local/bin
目錄;但事實上你不能那樣做,詳細的內容稍後將在 節 3.3, “把文件安裝到目的位置” 中說明)。
開始打包時原始碼目錄應當是絕對乾淨(原始)的,或者直接使用剛剛解壓縮得到的原始碼。
帶有 Makefile
文件的簡單程序可以很容易地使用 make
來編譯。[11] 其中的一些還支持 make
check
,這可以完成一系列自檢。編譯好後可以使用 make install
來將程序安裝到目標目錄。
現在嘗試編譯和運行你的程式,確保它工作正常,且在安裝和運行時不會導致其他問題。
你還可以運行 make clean
(或更好的 make
distclean
)來清理編譯目錄。有時還會帶有 make uninstall
用以反安裝已經安裝了的檔案。
非常多的自由軟件是使用 C 和 C++ 語言編寫的。其中的有很多使用 Autotools 或 CMake
來使其可以在不同平臺上移植。這些工具首先用於生成 Makefile
和其他必須的源文件,然後這些程序可以使用正常的 make; make install
來編譯和安裝。
Autotools 是 GNU 編譯系統工具,包括 Autoconf、Automake、Libtool 和
gettext。你可以通過
configure.ac
、Makefile.am
和
Makefile.in
等文件來識別這種類型的源代碼。[12]
使用 Autotools 的第一步是在上游作者在代碼中運行 autoreconf -i -f
,然後把生成的文件同源代碼一起分發。
configure.ac-----+-> autoreconf -+-> configure Makefile.am -----+ | +-> Makefile.in src/Makefile.am -+ | +-> src/Makefile.in | +-> config.h.in automake aclocal aclocal.m4 autoheader
編輯 configure.ac
和 Makefile.am
等檔案需要一些關於 autoconf 和 automake 的知識。參考
info autoconf
和 info automake
。
使用 Autotools 的第二步是用戶獲得分發的源代碼後在源碼目錄下運行 ./configure &&
make
來將其編譯成爲 binary
(二進制可執行程序)。
Makefile.in -----+ +-> Makefile -----+-> make -> binary
src/Makefile.in -+-> ./configure -+-> src/Makefile -+
config.h.in -----+ +-> config.h -----+
|
config.status -+
config.guess --+
你可以改變 Makefile
文件中的許多設置,比如修改默認的文件安裝位置(使用
./configure --prefix=/usr
)。
儘管不是必須的:你還可以使用 autoreconf -i -f
來更新
configure
和其他相關文件,這樣做有可能提高源代碼的兼容性。 [13]
CMake 是另一個可選的構建系統,你可以通過
CMakeLists.txt
文件來識別使用它的源代碼。
如果上游源代碼以像 gentoo-0.9.12.tar.gz
的形式分發,你可以用
gentoo
作爲(源代碼) 軟件包名
,並用 0.9.12
作爲 上游版本。
它們會被 debian/changelog
這個文件用到;該文件一會會在 節 4.3, “changelog
” 部分詳細描述。
雖然這個簡單的方法在大部分情況下能夠顯靈,但你仍需要能根據 Debian 方針和慣例來調整 軟件包名 和 上游版本 。
你必須讓 軟件包名 裏只留下 小寫字母
(a-z
), 數字 (0-9
), 加號
(+
) 和 減號 (-
) , 以及 點號
(.
)。 軟件包名最短長度兩個字符;必須以字母開頭;不能與庫存軟件包名衝突。相信我,把軟件包名的長度控制在 30
字符以內是明智之舉。 [14]
如果上游在它的名稱中使用了一些通用術語比如 test-suite
,
那麼將其重命名,以顯式指明其內容並避免命名空間污染。 [15]
你可以讓 upstream version 中只包含字母和數字
(0-9A-Za-z
), 加號 (+
), 波浪號
(~
), 以及 點號(.
)。它必須以數字開頭
(0-9
)。 [16]
如果可能的話,最好把它的長度控制在8字符以內。 [17]
如果上游不使用像 2.30.32
這樣的常規版本格式,而是用類似
11Apr29
這樣的日期作爲版本,亦即隨機的代號字符串,或者以VCS的哈希值作爲版本號的一部分,那麼請確認將其從
upstream version 中移除。 這樣的信息可以記錄在
debian/changelog
文件中。 如果你需要發明一個版本字符串,請使用
YYYYMMDD
這個格式作爲上游版本,比如 20110429
。這可以確保
dpkg 在升級軟件包時正確解讀新版本。 如果需要確保未來能夠平滑過渡到類似
0.1
這樣的版本號的話,請使用 0~YYMMDD
格式作爲上游版本,例如
0~110429
。
版本字符串 [18] 可以用 dpkg(1) 來進行比較:
$ dpkg --compare-versionsver1
op
ver2
版本比較規則可以總結爲以下幾點:
字符串會被從頭到尾進行比較。
字母比數字大。
數字作爲整數進行比較。
字母按照 ASCII 編碼順序進行比較。
對於點號 (.
),加號 (+
),以及波浪號
(~
) 則要應用特殊規則,具體如下:
0.0
< 0.5
<
0.10
< 0.99
<
1
< 1.0~rc1
<
1.0
< 1.0+b1
<
1.0+nmu1
< 1.1
<
2.0
有一種比較棘手的情況,當上游釋出
gentoo-0.9.12-ReleaseCandidate-99.tar.gz
作爲
gentoo-0.9.12.tar.gz
的預發佈版本時,就需要確保升級工作妥當進行:重命名該上游源代碼爲
gentoo-0.9.12~rc99.tar.gz
.
首先我們設置兩個 環境變量,$DEBEMAIL
和
$DEBFULLNAME
,這樣能使使大多數 Debian
維護工具能夠正確識別你用於維護軟件包的姓名和電子郵件地址。[19]
$ cat >>~/.bashrc <<EOF DEBEMAIL="your.email.address@example.org" DEBFULLNAME="Firstname Lastname" export DEBEMAIL DEBFULLNAME EOF $ . ~/.bashrc
一般的 Debian 軟件包是由上遊程序產生的 外來 Debian 軟件包。 若你想要用上游源代碼
gentoo-0.9.12.tar.gz
創建一個外來 Debian 軟件包,你可以爲它創建一個初始的外來
Debian 軟件包,通過如下方法調用 dh_make 命令:
$ cd ~/gentoo $ wget http://example.org/gentoo-0.9.12.tar.gz $ tar -xvzf gentoo-0.9.12.tar.gz $ cd gentoo-0.9.12 $ dh_make -f ../gentoo-0.9.12.tar.gz
當然,請用你原始源碼歸檔的名字來替換 filename (文件名)。 [20] 詳情請參見 dh_make(8) 。
你應該會看到一些輸出,它們詢問你想要創建什麼類型的軟件包。這裏的 Gentoo 是一個單一二進制包 -- 它僅僅創建一個二進制包, 亦即, 一個
.deb
文件 -- 於是我們就選擇第一項 (用 s
鍵),
檢查屏幕上的信息, 並按
鍵來確認。
[21]
ENTER
執行 dh_make 後,上一級目錄中自動創建了一份上游 tarball 的副本,名爲
gentoo_0.9.12.orig.tar.gz
,這個文件和稍後介紹的
debian.tar.gz
在一起滿足了 Debian 非本地源代碼包的要求。
$ cd ~/gentoo ; ls -F gentoo-0.9.12/ gentoo-0.9.12.tar.gz gentoo_0.9.12.orig.tar.gz
請注意 gentoo_0.9.12.orig.tar.gz
這個文件名的兩個關鍵特點:
軟件包名稱和版本是以字符 _
(下劃線)分隔的。
.tar.gz
擴展名前插有 .orig
。
你應該可以注意到 debian
目錄下有了許多模板文件。這些文件將在 章 4, debian
目錄中的必須內容 和 章 5, debian
目錄下的其他檔案
中一一解釋。你還應該明白,打包沒辦法變成全自動的過程。你還需要按照 章 3, 修改原始碼 中的方法來爲 Debian
修改軟件包。此後,你還要按照 章 6, 構建套件 中敘述的合適的方法來構建 Debian 軟件包,並按照 章 7, 檢査套件中的錯誤 中的方法進行測試,最終依照 章 9, 上傳套件
的介紹將其上傳。本教程將對所有的這些步驟進行解釋。
如果你在修改過程中不小心刪除或弄壞了某些模板檔案,你可以使用 dh_make 加上
--addmissing
參數來將其還原。
更新一個已存在的軟件包可能比較複雜,因爲它可能使用了舊技術。在學習基本功的階段,請只創建全新的軟件包;稍後的 章 8, 更新套件中會有更細緻的講解。
請注意,源代碼文件不必包含任何在節 2.4, “簡易構建系統” 和 節 2.5, “常见的可移植的構建系統”
中談論到的構建系統。 就算僅僅是圖像數據集合之類的也可以。文件的安裝可以使用 debhelper
的配置文件來擺平,比如
debian/install
(參見 節 5.11, “install
”)。
[4] 對於舊式的 1.0
格式非本地 Debian 源碼包,應當使用
。 package
_version
-revision
.diff.gz
[5] 參見 5.6.1 "Source", 5.6.7 "Package", 以及 5.6.12 "Version"。 package architecture 遵循 Debian Policy Manual, 5.6.8 "Architecture" 並且會在軟件包構建的過程中被自動分配。
[7] 當然了,總有值得打包的新軟件。
[8] 不用擔心失蹤的 Makefile
。你可以參照 節 5.11, “install
” ,簡單地通過
debhelper 來安裝 hello
程序,或者修改上游源代碼來添加帶有install
目標的新Makefile
,參照章 3, 修改原始碼
[9] 當檔案副檔名不足以判斷檔案類型時,可以使用 file 命令來判斷。
[11]
許多現代程序都配有一個叫做 configure
的腳本,它被執行的時候會生成一個爲你機器定製的
Makefile
。
[12] 關於 Autotools 這個龐然大物的討論已經超出本篇小教程的討論範圍。而本節旨在提供關鍵字和參考。如果你需要使用它,請認真研讀 Autotools Tutorial 以及
/usr/share/doc/autotools-dev/README.Debian.gz
的本地副本。
[13] 你可以用 dh-autoreconf
軟件包來將這個過程自動化。參見
節 4.4.3, “定製 rules
檔案”.
[14] 在 aptitude 工具中,軟件包名字段的默認最大長度爲 30。 而對於 90% 以上的軟件包來說,軟件包名都少於 24 個字符。
[15] 如果你遵循 Debian Developer's Reference 5.1. "New packages", 那麼在 ITP 過程中總是會遇到這樣的問題。
[16] 這一條更嚴格的規則能幫助你避免混淆文件名。
[17] aptitude 命令的版本字段默認長度爲10。其中通常 Debian 修訂號和前置的連字符會消耗2個位置。對於 80% 以上的軟件包來說,上游版本小於8字符,Debian 修訂號小於2字符。對於 90% 以上的軟件包來說,上游版本小於10字符,Debian 修訂號小於3字符。
[18] 版本字符串可以是 upstream version
(
), Debian revision
(version
), 或者 version
(revision
)。
關於 Debian 修訂號如何增長的信息,請參見 節 8.1, “新的 Debian 版本”Debian revision 。
version
-revision
[19] 以下默認你以 Bash 作爲登陸 shell。如果你使用其他的 shell,例如 Z shell,那就使用它們的配置文件代替這裏提到的
~/.bashrc
。
[20] 如果上游源代碼已經提供了 debian
目錄 以及其內容,那麼帶上參數
--addmissing
來執行dh_make 命令。 新的源碼包格式
3.0 (quilt)
的魯棒性(Robust)已經足夠優秀,以不至於損壞,即使對於這類軟件包。
另外,你可能需要更新上游提供的內容,以滿足你的 Debian 軟件包之需。
[21] 此處有這幾種選擇: s
代表單一二進制包, i
代表獨立於體繫結構的軟件包,
m
代表複合二進制包, l
代表庫文件包,k
代表內核模塊包, n
代表內核補丁包,
b
代表 cdbs
軟件包。本教程專注於使用 dh 命令 (來自 debhelper
軟件包) 來創建單一二進制包,但 也會涉及到如何用它來創建 獨立於體繫結構
或 複合二進制軟件包。軟件包 cdbs
提供了 另一套可以代替
dh 命令的基礎打包腳本,不過對它的描述已經超出了我們的討論範圍。