內容目錄
本教程文件已被重寫為另外的 Debian 維護者指導 文件,其中包含了更新的內容與更多實際例子。請使用新的教程作為主要的教程文件。
讓我們嘗試創建一個自己的軟件包(或者,“收養”一個已存在的軟件包則更好)。
如果你要基於某個上遊程序構建軟件包,那麼典型的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 頁面
the Debian Package Tracker 頁面
如果軟件包已經存在,直接安裝就好了!:-) 如果它是被 拋棄(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 中的一些條件,但至少 必須是可分發的。
如果你不清楚你的軟體應該分入哪一類,則把許可證文本發送到 [email protected] 請他人提出意見。
程式 不能 給 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 政策(Debian Policy)以及約定俗成的做法來調整 軟體包名 和 上游版本 。
在 軟體包名 裡只能含有 小寫字母
(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="[email protected]" 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 ,請認真研讀
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 命令的基礎打包腳本,不過對它的描述已經超出了我們的討論範圍。