製作DEB包的方法
由於個人水平有限,難免有很多不適當的地方,有什麼翻譯錯誤的,請多多指教^_^
Chapter 1. Getting started The Right Way
這一章沒做記錄
Chapter 2. First steps
2.1 建立debian包的工作流
- 獲取原始碼,原始碼通常都是一個壓縮包 (package-version.tar.gz)
- 把debian打包所需要的資訊寫到debian目錄中,然後把這份修改過的原始碼以3.0(quilt格式)打包
- 製作debian的二進位制包,通常是以.deb為字尾。(package_version-revision_arch.deb)
2.2 選擇你的程式
如果你想製作一個包,首先你要決定你要製作一個什麼軟體的包。首先,你要確定你這個包有沒有人已經制作好。如果有人已經制作好了,直接安裝就好了。如果你找到的是一個已經沒有人維護,但是還可以用的包,你可以接過來繼續維護。 如果你需要製作一個全新的包,並希望它出現在Debian中,請按照以下步驟進行:- 你要確定你的軟體有價值的,並且可用的。
- 你要確定這個包還沒有人在做。
- 你的軟體必須要有license
- 軟體包不應該對Debian系統的安全造成威脅。
2.3 獲取原始碼
你可以直接獲取已經做成tar包的原始碼,或者可以從VCS系統中獲取(svn ,git, cvs),然後用tar把原始碼壓縮成一個包(壓縮的時候可以加上--exclude-vcs,就可以忽略版本控制的檔案)。接著你應該仔細的閱讀以下里面的一些說明檔案,起碼要知道應該怎麼去編譯和安裝。 開始打包時,原始碼目錄應該是絕對乾淨的(原始)的,或者直接使用剛剛解壓包得到的。2.4 簡單的編譯
一個簡單的程式通常包含一個Makefile,你可以呼叫make去對它進行編譯和make install進行安裝。有些還包含了make check,用來檢查剛剛編譯出來的檔案有沒有問題。2.5 主流的編譯方法
通常是使用autotools(autoconf, automake ,libtool和gettext)工具來支援多平臺。工具的具體方法這裡不作介紹了。
2.6 軟體包的名稱和版本
軟體的包名只能夠包含小寫字母(a-z),阿拉伯數字(1-9),還有加號(+),減號(-),還有點(.)。而且長度不能小於2,推薦長度是小於30個字元。 包的版本號只能夠包含字母數字(a-zA-Z1-9),還有加號(+),減號(-),還有點(.),波浪號(~)。 如果上游的原始碼版本號不是用普通的版本號(2.30.32),而是用(11Apr29)的,或者一些CVS系統生成的隨機字元的話,應該要把這些字元從版本號中刪除,但可以把它記錄在debian/changelog中。 deb包的版本號對比可以用dpkg的命令來進行對比:dpkg --compare-versions vers1 op vers2
版本對比的規則如下:
- 字串從頭到位進行比較
- 字母要比數字要大
- 數字會作為整數進行比較
- 字母的比較是根據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
2.7.設定dh_make
設定兩個環境變數:$DEBEMAIL和$DEBFULLNAME
分別用於給打包程式識別你的Email和名字。
你可以在~/.bashrc中設定好,並且把它export出來。
2.8初始化非自己的包
很多時候一些原始碼都是直接從網上下載下來的,如果你想通過這些原始碼生成一個新的的deb包,你可以使用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
這裡會提示你選擇生成包的型別,根據自己的需要選擇就行了。這裡選擇的是s。然後觀察上一級目錄,會生成一個新的檔案,名字為:
gentoo_0.9.12.orig.tar.gz
觀察這個包,有兩個特點,名字和版本號之間是以下劃線_來分隔的,還有就是在.tar前面加入了.orig
你還應該注意到在原始碼目錄的debian資料夾下有很多臨時檔案,他們的作用會在第四和第五章進行解析。你也應該知道,打包過程不可能完全自動化,你應該修改原始碼以適應Debian。然後,你就可以適當的方法去建立一個deb包,檢測和上傳軟體包。這些步驟在後面都會解析。
如果你在修改過程中不小心刪除或者破壞了某些模版檔案,你應該是用dh_make --addmissing來將其還原。
升級軟體包的過程可能會比較複雜,如果是剛開始學,應該用一個新的包。
2.3.初始化本地的包
如果有一個包是你自己管理的,或者是隻有你自己去使用的話,你可以使用不同於上面的方法去初始化這個包,具體的命令如下:
$ cd ~/mypackage-1.0
$ dh_make --native
跟上面不同的地方就是,這個命令只是不會生成一個tar包。剩下的幾乎都是一樣的。Chapter 3. Modifying the source
3.1-3.2主要是講解如何修改修改原始碼的,因為這部分主要是利用quilt來修改原始碼的bug,對於打包來說意義不大,所以就不詳細說了。
3.3.把軟體安裝到目標路徑
很多第三方的軟體會預設安裝到目錄/usr/local下。
但是在Debian,這是由系統管理員保留給私人使用的,所以必須使用/usr/bin來代替/usr/local/bin,服從FHS
通常是使用make來編譯,make install來安裝程式到目標目錄。Debian為了提供個pre-build的可安裝的包,修改了編譯包的機制,使其可以安裝到一個臨時目錄而不是最終的目錄。
對於普通的程式安裝有兩個差異,一個是Debian的包管理,另外一個是可以透明的通過debhelper的db_auto_configure和db_auto_install來解決安裝的問題。不過它需要滿足一下兩個條件:1.Makefile滿足GNU並且支援變數$DESTDIR。2.源的存放必須準從FHS
很多程式都遵從GNU的約定,所以他們使用autoconf很輕易地打成包。大概有90%的機會,debhelper可以在一個沒有修改過的原始碼裡面正常工作,所以打包並沒有想象中的那麼難。
如果你想去修改Makefile,你應該小心地支援$DESTDIR。雖然這個值木有新增,預設為空,但是會在安裝的時候都加入到每個檔案的目錄名前面。這個打包指令碼會把$DESTDIR設定為一個臨時目錄。
如果從一個原始碼包中生成一個二進位制的包,dh_auto_install會把臨時目錄設為debian/package。當別人安裝你的包的時候,在debian/package中的所有檔案都會被安裝到別人的機器上面。唯一不同的地方就是dpkg會把檔案安裝到根目錄下而不是你的工作目錄。
記住,即使你的程式可以安裝在debian/package,但是它安裝在root目錄下還是要能夠正確執行的。所以你不能夠在程式碼裡面把路徑寫死。
當你修改完程式碼後,應該用呼叫dqulit來生成補丁,並把新補丁增加到debian/patches目錄中。
3.4.不一樣的庫名稱
這是一個常見的問題。相同的庫在不同的平臺下面會不盡相同,所以Makefile裡面如果指定錯了庫名,只需要修改一下就可以了。
Chapter 4. Required files under the debian
directory
在原始檔下有一個新的子目錄叫debian的,這裡包含了一系列的檔案,這些檔案可以供我們根據我們的需要進行修改,然後控制包的的一些行為。裡面最重要的檔案主要是control,changelog,copyright和rule,他們是每一個包都需要的。
4.1.control
這裡包含的資訊是給dpkg , dselect, apt-get, apt-cache, aptitude等包管理工具去控制包的。它們會在第五章裡面進行定義 。下面是一個由dh_make建立的一個control檔案。
Source: gentoo
Section: unknown
Priority: extra
Maintainer: Josip Rodin <[email protected]>
Build-Depends: debhelper (>=9)
Standards-Version: 3.9.4
Homepage: <insert the upstream URL, if relevant>
Package: gentoo
Architecture: any
Depends: ${shlibs:Depends}, ${misc:Depends}
Description: <insert up to 60 chars description>
<insert long description, indented with spaces>
1-7行是原始碼包的控制資訊,9-13行是二進位制包的控制資訊(也就是聲稱之後的安裝包了),每個域的說明都已經在上面解析了,不過不是很詳細,詳細的請檢視原文件。
- 原始碼包的包名
- 是該原始碼包要進入發行版的那個分類中,例如:main,non-free,contrib,admin,devel,doc,libs,mail.net,x11,還有很多沒有例舉出來
- 告訴使用者這個安裝包的重要性 ,optional與required,important,standard能並存, extra 與non-extra不能並存
- 管理員的名字和Email。這裡一定要有一個合法的Email地址,因為因為一旦有bug,bug管理系統就會給你傳送郵件通知你。這裡要避免使用逗號,&號和句號。
- 生成安裝包所需要依賴的包,你可以增加多一行Build-Depends-Indep來指定更多的依賴檔案。例如gcc和make這些工作,已經被隱含的包含在essential的包裡面了。如果你還需要其他包的話,可以把它們新增到這行。如果是依賴多個包,用分號把他們隔開。對於所有需要用dh命令來打包的包來說,都需要加上debhelper (>-9)去滿足Debian Policy的clean需求。如果生成的二進位制包是有Arahitecure:any的,所以來的包基本上都是寫在Build-Depeds裡面的,很少寫在Build-Depends-Indep。如果是生成的二進位制包有Architecure:all的話,在Build-Depends中只記錄為了滿足Debian Policy requirement的clean目標的依賴,其他的依賴都可以寫到Build-Depends-Indep中。如果你不知道應該用那個,則應該使用Build-Depends以保證安全。
- 你的軟體的主頁
- 二進位制包的名字,通常和原始碼包保持一致
- 描述你的包是為了那個架構而打生成的。 any:與架構有關,普遍是跟編譯的語言有關 。 all:與架構無關,大多這樣的包是包含了文件,圖片還有一些由解析性的語言編寫的指令碼。如果我們的程式是用C語言寫的話,我們可以不用管這個欄位,應該dpkg-gencontrol會根據實際情況來填寫一個正確的值。
- debian包管理系統最強大的功能之一。每個軟體包都可以和其他軟體包有各種不同的關係。除了Depends之後,其他關聯的還有Recommands,Suggests,Pre-Depends,Breaks,Conflicts,Provides和Replaces.包管理工具通常都是用相同的方法去處理這些關係的,如果不是的話,它會進行解析的。
- Depends ==> 此軟體包僅當它依賴的軟體包均已安裝後才可以安裝,此處寫明你的程式所必須的軟體包。 Recommends ==》不是嚴格要求的,不過你的程式通常都會用到。apt-get和aptitude在安裝的時候會提示把這些依賴一起安裝,但是dpkg則不會。 Suggests ==》不是一定需要的,但是有的話能使你的程式更加完美。aptitude會提示,dpkg和apt-get則不會提示。 Pre-Depends==》比Depends搶,軟體包在預依賴的軟體包已經安裝並且正確配置後才可以安裝,所以使用此項時應該十分謹慎。 Conflicts==》僅當所有衝突的軟體包都已經被刪除後才可以安裝。 Breaks==》當安裝完這個包,就會破壞列表中的包。它通常是指定同一個軟體的舊版本。通常是高階包管理工具用來更具列表中的軟體。 Provides==》一些包可以從virtual-package-names-list.txt.gz後去多個可選的虛擬名字,如果你的虛擬包包含一個函式,你就應該使用它(?不懂) Replaces==》當你的程式要替換其他軟體包的某些檔案,或是完整地替換另一個軟體包(與Conflicts一起用)。列出軟體包中的某些檔案會被你的軟體包所覆蓋。 以上所有的域都有相同的語法,當依賴的包只需要二選一的時候,可以通過管道符|來隔開兩個包。這裡還可以限制每個依賴包的版本,可以使用<<,<=,=,>=,>>來表示大於,大於等於,等於,小於等於,小於。例子:libbbar1 (=1.3.4)。 最後需要了解的是類似${shlibs:Depends} 這樣的用法,${shlibs:Depends}是負責計算出你你ELF檔案和動態庫所依賴的所有檔案。
- 簡短的描述
- 這個包的詳細描述,不過需要注意的是,每一行的第一列都需要為空,並且不能有空行,但是你可以輸入一點去模擬這是一個空行。
前端軟體例如aptitude在排列包或者選取預設包的時候,會用到Section和Priority。一旦你把包傳上去Debian後,這個包的維護人員就可以修改這兩個值,在這種情況下,你會收到郵件的通知。
在Depends欄位中,你還需要知道的就是${shlibs:Depends} , ${perl:Depends} , ${misc:Depends}
- dh_shlibdeps(1) 會用來找出二進位制包所依賴的動態庫,它會為每個二進位制包生成一個列表,列表中包含了該包所以來的檔案和動態庫。這是用來取代${shlibs:Depends}的
- dh_perl(1) 這個是用來找出perl或者perlapi的依賴檔案的。它是用來取代${perl:Depends}的
- 一些debhelper命令會導致生成的包增加一些依賴,所有這名都會未二進位制包生成一個依賴列表。這是用來取代${misc:Depends}的
- dh_gencontrol(1)是為每個二進位制包生成DEBIAN/control的。它用於取代${shlibs:Depends}, ${perl:Depends}, ${misc:Depends}等等
4.2.copyright
這個檔案主要包含的是軟體的版權資訊和許可證資訊。dh_make會自動幫你生成一個模板。你可以使用dh_make --copyright gpl2去生成一個基於GPL-2的模板。
4.3.changlog
這是一個必要的檔案。它是用於被dpkg和其他程式來獲取軟體的版本號,修訂號,釋出狀態和urgency。對於你來說,這個檔案同樣重要,因為它可以記錄下你所做的更改。它可以幫助其他使用者知道你的包更新了什麼東西。他會儲存在/usr/share/doc/<pkgname>/changlog.Debian.gz。
gentoo (0.9.12-1) unstable; urgency=low (包含了包名,版本號,修訂號和urgency。這裡的名字必須和原始碼包的名字相同。釋出狀態應該為unstable,為了防止包在未完全開發好的情況下上傳,可以把釋出狀態設定為UNRELEASED)
* Initial release (Closes: #nnnn) <nnnn is the bug number of your ITP> (3-5行是修改的記錄)
-- Josip Rodin <[email protected]> Mon, 22 Mar 2010 00:37:31 +0100
4.4.rules
現在我們去看dpkg-buildpackage會用來控制生成包的檔案rules。這個檔案實際上是一個Makefile檔案,但是和原始碼的Makefile不是同一個。在debian裡,這個檔案與其他檔案不同,它被設定為可執行檔案。
4.4.1.Target of the rules file
每一個rule檔案都像其他Makefile那樣,包含了一些規則,這些規則主要是定義了一個目標和如何生成這個目標。規則的格式和Makefile的一樣,目標在一行的開頭,然後接下來的行在行頭用TAB鍵填充,然後寫入生成目標的方法。空行或者行頭用#註釋的行會被忽略。
你想呼叫那個目標,你就把目標加作為命令列的引數就可以了。
rules的格式與普通的Makefile檔案一致,有需要了解的可以直接去找關於Makefile的文章。
下面的是對Makefile目標的一些簡單的描述:
clean(必選):刪除編譯過程中生成的檔案和一些沒用的檔案
build(必選):從原始碼編譯生成目標程式和格式化的文件
build-arch(必選):從原始碼編譯出跟平臺相關的程式
build-indep(必選):從原始碼編譯出跟平臺無關的程式
install(可選):安裝debian目錄下的所有二進位制包。如果定義了,binary*這類的目標將會依賴它。
binary(必選):生成所有二進位制包(binary-arch和binary-indep的有效組合)
binary-arch(必選):在父目錄生成一個跟平臺相關的二進位制包
binary-indep(必選):在父目錄生成一個跟平臺無關的二進位制包
get-orig-source(可選):從網上獲取最新版本的原始碼包
4.4.2 Default rules file
dh_make會生成一個簡單的但是很有用的rules檔案
#!/usr/bin/make -f
# -*- makefile -*-
# Sample debian/rules that uses debhelper.
# This file was originally written by Joey Hess and Craig Small.
# As a special exception, when this file is copied by dh-make into a
# dh-make output file, you may use that output file without restriction.
# This special exception was added by Craig Small in version 0.37 of dh-make.
# Uncomment this to turn on verbose mode.
#export DH_VERBOSE=1 把這行開啟可以讓每一個dh命令的輸出都打印出來,或者通過export DH_OPTIONS=-v引數
%:
dh [email protected]
12-13行是使用模式規則去呼叫一些隱含的規則。百分號意味著是“所有規則”,他是通過指定目標名來條用dh命令。dh命令是一個包裝好的指令碼,它可以根據引數來呼叫一系列適當的dh_*命令。
debian/rules clean呼叫dh clean, 它會依次執行以下的命令:
dh_testdir
dh_auto_clean
dh_clean
debian/rules build呼叫dh build,它會依次執行以下的命令:
dh_testdir
dh_auto_configure
dh_auto_build
dh_auto_test
fakeroot debian/rules binary呼叫fakeroot dh binary,它會依次執行以下的命令:
dh_testroot
dh_prep
dh_installdirs
dh_auto_install
dh_install
dh_installdocs
dh_installchangelogs
dh_installexamples
dh_installman
dh_installcatalogs
dh_installcron
dh_installdebconf
dh_installemacsen
dh_installifupdown
dh_installinfo
dh_installinit
dh_installmenu
dh_installmime
dh_installmodules
dh_installlogcheck
dh_installlogrotate
dh_installpam
dh_installppp
dh_installudev
dh_installwm
dh_installxfonts
dh_bugfiles
dh_lintian
dh_gconf
dh_icons
dh_perl
dh_usrlocal
dh_link
dh_compress
dh_fixperms
dh_strip
dh_makeshlibs
dh_shlibdeps
dh_installdeb
dh_gencontrol
dh_md5sums
dh_builddeb
fakeroot debian/rules binary-arch呼叫fakeroot dh binary-arch,它執行的命令的順序和fakeroot dh binary一樣,但是每個命令都添加了引數-a
fakeroot debian/rules binary-indep呼叫fakeroot dh binary-indep,它執行命令的順序基本上和fakeroot db binary一樣,但是不包含dh_strip, dh_makeshlibs和dh_shlibdeps,並且每條命令都添加了引數-i
dh_*命令大部分都可以直接從它的名字知道它的作用,但是在一個基於Makefile的典型打包環境之,還是有幾個是值得注意一下的,特意在這裡給出了簡單的解析,
dh_auto_chean通常會呼叫make distclean假如Makefile中存在distclean這個目標。
dh_auto_configure通常會呼叫./configure +引數 當檔案configure存在的時候。
dh_auto_build通常會執行make來執行Makefile的第一個目標。
dh_auto_test通常會執行make test加入Makefile中有test這個目標。
dh_auto_install通常會執行make install假如Makefile中有install這個目標。
所有需要用到fakeroot的目標都會包含dh_testroot,它是用來把自己偽裝成為一個root使用者。
最重要的一點就是又dh_make生成的rules中的內容只是一些建議,它對於大部分包來說是可以用的,但是對於一些複雜的包來說,就需要你自己去定製了。
雖然install不是必須的,但是也是支援的,fakeroot dh install 的行為跟fakeroot dh binary有點類似,但是它會在執行完dh_fixperms後就停止執行了。
4.4.3.Customization of rules file
有很多方法來定製使用dh命令建立新的的rules檔案。
dh [email protected]命令可以根據以下的方法來自定義:
- 增加對dh_python2命令的支援(推薦):
----在Build-Depends中包含python
----使用dh [email protected] --with python2
----使用python的框架去處理Python的模組
- 增加對dh_pysupport命令的支援(不推薦):
----在Build-Depends中包含python-support
----使用dh [email protected] --with pysupport
----使用python-support的框架去處理Python的模組
- 增加對dh_pycentral命令的支援(不推薦):
----在Build-Depends中包含python-central
----使用dh [email protected] --with python-central
----這會使dh_pysupport命令無效
----使用python-central的框架去處理Python的模組
- 增加對dh_installtex命令的支援:
----在Build-Depends中包含tex-common
----使用dh [email protected] --with tex
----註冊型別為1的字型,斷句樣式和TeX的格式
- 增加對dh_quilt_patch和dh_quilt_unpatch命令的支援:
----在Build-Depends中包含quilt
----使用dh [email protected] --with quilt
----這是quilt 1.0格式的包打補丁,3.0格式的不需要,補丁檔案放在debian/patches中
- 增加對dh_dkms命令的支援:
----在Build-Depends中包含dkms
----使用dh [email protected] --with dkms
----這是使用核心模組去處理DKMS
- 增加對dh_autotools-dev_updateconfig和dh_autotools-dev_restoreconfig命令的支援:
----在Build-Depends中包含autotools-dev
----使用dh [email protected] --with autotools-dev
----更新和恢復config.sub和config.guess
- 增加對dh_autoreconf和dh_autoreconf_clean命令的支援:
----在Build-Depends中包含dh-autoreconf
----使用dh [email protected] --with autoreconf
----在編譯之後更新和還原GNU Build System檔案
- 增加對dh_girepository命令的支援:
----在Build-Depends中包含gobject-introspection
----使用dh [email protected] --with gir
- 增加對bash completion特性的支援:
----在Build-Depends中包含bash-completion
----使用dh [email protected] --with bash-completion
----這是通過配置檔案debian/package.bash-completion來安裝bash completions
很多被dh命令呼叫的dh_*命令都可以通過debian資料夾內的相應的配置檔案來定製的。
你可能需要通過帶引數的dh命令來呼叫dh_*命令,或者呼叫額外的命令,或者直接跳過他們。在這樣的情況下,你可以在rules檔案下生成一個新的目標override_dh_foo來改變dh_foo命令。
請注意dh_auto_*命令會因為要考慮到各種各樣的條件,所以傾向於做比上面討論過的操作更多的操作。但是如果用override_dh_*去簡化它的話,並非一個好的注意。
這裡需要注意的是,dh_auto_*命令總是希望能做得更多,所以它需要考慮到各種各樣的條件。但是用override_dh_*來簡化它並不是一個好的做法(除了override_dh_auto_clean),因為它可能會忽略了debhelper的一些好的功能。 例如,如果你想使用autotools把系統的配置資料的儲存目錄從/etc改成/etc/gentoo的話,你可以把dh_auto_configure中傳給./configure命令的引數--sysconfig=/etc重寫了。override_dh_auto_configure:
dh_auto_configure -- --sysconfig=/etc/gentoo
在--後面的引數是會追加到預設的引數後面,用來覆蓋預設的引數的。如果要保留原有引數,只是重寫sysconfig引數,則使用dh_auto_config會比直接呼叫configure命令會好。如果原始碼中的Makefile需要你在make的時候指定build作為目標才可以編譯的話,你可以用下面的方法重寫:
override_dh_auto_build:
dh_auto_build -- build
這裡可以保證$(MAKE)除了只是增加了build作為引數外,其他引數都是用dh_auto_build的預設引數。
如果在原始碼中指定清理操作,不是用clean或者distclean,需要指定packageclean目標才可以清理原始碼,你可以使用下面的方法:
override_dh_auto_clean:
$(MAKE) packageclean
如果你的Makefile中包含了test這個目標,但是在打包的過程中不想執行這個目標的話,可以使用一個空的override_dh_auto_test來實現:
override_dh_auto_test:
如果原始碼有一個與眾不同的changlog檔案FIXES,dh_installchangelogs預設情況下是不會安裝它的。dh_installchangelogs命令需要在引數中指定FIXES才可以。
override_dh_installchangelogs:
dh_installchangelogs FIXES
如果你需要使用新的dh命令,應該的使用4.4.1中明確提到的目標名字作為目標,而不是自己新增加的,因為新增加的可能會造成額外的影響,但是我們可能很難去發現。如果可以的話,應該儘量把目標限制在override_dh_*的目標中,並且保證它們是完全獨立的。
Chapter 5. Other files under the debian
directory
如果需要控制打包過程中debhelper的行為,你應該通過在debian的目錄下放置一些可選的配置檔案來實現。這一章會介紹裡面的每個檔案的作用和格式。
dh_make命令會在debian資料夾內生成一些模板的配置檔案,大多數的字尾名是.ex的。有一部分是用二進位制報的名字做為字首的。
一些被debhelper用的配置檔案或許沒有被db_make生成,在這種情況下,你需要手動生成一個並且編輯它。
如果你需要debian目錄中的所有檔案都打到包裡面,就應該做到下面的幾條:
- 如果有.ex或者.EX字尾的檔案,刪除他們的字尾(即重新命名去掉字尾)
- 用二進位制的包名取代配置檔案中的“package”
- 根據你的需要修改模組檔案
- 刪除你不需要的配置檔案
- 根據需修改control檔案
- 根據需要修改rules檔案
5.1.README。Debian
記錄你的包與官方包之間額外的細節的或者不同之處的檔案。gentoo for Debian
-----------------
<possible notes regarding this package - if none, delete this file>
-- Josip Rodin <[email protected]>, Wed, 11 Nov 1998 21:02:14 +0100
如果沒有東西需要記錄,可以刪除。
5.2.compat
定義debhelper相容性的等級,你可以設定它為9級。echo 9 > debian/compat
5.3conffiles
最令人氣憤的東西莫過於當你花費了大量時間去修改一個程式,但是你的改變只是為了一個小小的升級。Debian可以解決這個問題,它通過把需要儲存的配置檔案儲存到conffiles。當你升級一個包,你會被提示時候保留舊的配置檔案。 dh_install(1)會自動把/etc目錄下面的檔案新增到conffiles,所以你不需要手動去指定它們。對於大多數的包來說,只要在/etc目錄下面的檔案才需要新增到conffiles檔案中,所以 這個檔案可以不需要。 如果你的程式使用的配置檔案被它自己重寫過,最好的還是不要把它加入到conffiles中,因為dpkg一定會提示使用者去驗證一下被修改了那些東西。 如果你打的包所用的/etc下的配置檔案是會被每個人戶都修改的,這裡會有兩個比較流行的方法,既不需要把它們加到conffiles,也不需要用到dpkg。- 由維護指令碼,把存在/var目錄下的檔案做一個軟連線到/etc目錄下。
- 由維護指令碼在/etc目錄下生成一個檔案。
5.4package.cron.*
如果你的包需要需要定期執行一下操作的話,你可以用下面說到的檔案去設定它。 你可以設定每小時,每天,每日,每週,每月或者你喜歡的任何時候。- package.cron.hourly : 會安裝到/etc/cron.hourly/package,每個小時執行一次
- package.cron.daily : 會安裝到/etc/cron.daily/package,每日執行一次
- package.cron.weekly : 會安裝到/etc/cron.weekly/package,每週執行一次
- package.cron.monthly : 會安裝到/etc/cron.monthly/package,每月執行一次
- package.cron.d : 會安裝到/etc/cron.d/package, 會據該檔案內設定的週期來執行
5.5.dirs
這個檔案具體指明瞭一些我們需要的,但是在安裝的過程中(又dh_auto_install呼叫make install DESTDIR=...)沒有生成的資料夾。這意味著Makefile中沒有滿足我們的需要,出現了一些問題。 在install檔案中列出的檔案,不需要先建立檔案所存在的目錄(系統會自動建立)。 最好的方法就是你先安裝一下這個包,如果是有問題了,在使用dirs這個檔案。 如果你遇上了錯誤,最好是第一部就直接執行安裝。在dirs檔案內的目錄名前面沒有斜槓符號的(即不是絕對路徑)5.6.package.doc-base
如果你的軟體包中除了使用者手冊和info page意外,還有一些文件的話,你應該使用doc-base檔案把這個檔案註冊到系統中,讓使用者可以用dhelp(1),dwww(1)或dcocentral(1)這些命令來找到它。 這通常包含HTML, PS和PDF檔案,放置在/usr/share/doc/packagename/中。 下面是gentoo包的gentoo.doc-base檔案:Document: gentoo
Title: Gentoo Manual
Author: Emil Brink
Abstract: This manual describes what Gentoo is, and how it can be used.
Section: File Management
Format: HTML
Index: /usr/share/doc/gentoo/html/index.html
Files: /usr/share/doc/gentoo/html/*.html
關於這個檔案格式的更多資訊,可以檢視/usr/share/doc/doc-base/doc-base.html/index.html。5.7.docs
這個檔案制定了我們使用dh_installdocs(1)安裝到臨時目錄的檔名 預設情況下它會把程式碼目錄頂層所有名為BUGS、README*、TODO等的檔案都加入到其中。5.8.emacsen-*
如果你的軟體包提供可以在安裝時編譯為位元組碼的Emacs檔案,你可以使用這些檔案設定。 它們會被dh_installemacsen(1)安裝到臨時目錄。 如果你不需要這些,就刪除它們。5.9.package.examples
dh_installexamples(1)會將列出的檔案和目錄作為示例檔案安裝。5.10.package.init 和 package.default
如果你的程式是一個需要在開機就啟動的daemon,你顯然唔使我一開始的建議,不是嗎? package.init這個檔案會會安裝為/etc/init.d/package,用於啟動和停止daemon程序。它相當於dh_make命令提供的init.d.ex檔案。你可以重新命名和編輯它,在編輯的時候應該確保它包含了一個LSB的相容的頭。它會被dh_installinit安裝到臨時目錄。 package.default這個檔案會安裝為/etc/default/package,這個檔案是被init指令碼設定預設值的。這個檔案通常用於禁用守護程序,或者設定預設的引數或者超時時間。如果你的init指令碼有一定的可配置特性, 你可以在這裡進行配置,而不是在它自己的init指令碼設定。 如果是原始碼包中已經提供了一個init指令碼,你可以自己選擇使不使用它。如果你不想使用原始碼提供的init檔案,那麼你必須自己重寫一個了。即使原始碼包中提供的看起來沒什麼問題,並且已經安裝到了合適的地方,但是你依舊需要去建立rc的軟連線(在/etc/rcX.d中,控制開機啟動)。建立軟連線你可以通過重寫dh_installinit來實現:override_dh_installinit:
dh_installinit --onlyscripts
5.11.install
如果在執行make install的時候,有一些檔案不被安裝到包的臨時目錄中,但是你又是需要這些檔案的話,你應該把這些需要加進去的檔案的檔名寫入到install檔案中。他會被dh_install(1)命令所安裝。不過你首先要確定你要安裝的檔案是不是應該又這個指令碼去控制,例如文件檔案應該又doc檔案去控制,而不應該寫到這個檔案中。 在這個檔案中,一個檔案對應一行,格式為原始檔(相對於最頂層的編譯目錄),然後空格,最後加上安裝目錄(相對於安裝的目錄)。加入src/bar這個檔案需要安裝,那麼install檔案裡面應該這樣寫:src/bar usr/bin
這意味著當這個包被安裝完之後,bar會在/usr/bin/bar中。
只有安裝的相對目錄沒有變化的情況下,寫在install才會寫入檔名。這樣的格式通常用於把一個很大的包拆分為幾個小包,然後把它的配置檔案改成package-1.install, package-2.install等。
5.12.package.info
如果你的軟體包含info package,你應該把它寫入到package.info檔案中。5.13.package.links
包維護人員需要在建立包的目錄中增加連線的話,你應該把這個連線的完整路徑和目標路徑寫入到package.links檔案中,然後讓dh_link(1)命令去安裝到真正的目錄中。5.14.{package.,source}/lintinan-overrides
如果Debian的策略允許lintian報告一個錯誤的診斷情況時,你可以用package.lintian-overriades或者source/lintian-overrides去把這些錯誤通知給禁止了。更多的資訊請看/usr/share/doc/lintian/lintian.html/index.html,並且不要濫用這個工功能。5.15.manpage.*
你的程式應該有手冊頁,如果沒有,你應該生成它。dh_make命令會生成一些手冊檔案的模板。最後應該刪掉一些沒有用的模組。 5.15.1.manpage.1.ex 這個檔案是用nroff寫的。 5.15.2.manpage.sgml.ex 這個檔案是用SGML寫的。 5.15.3.manpage.xml.ex 這個檔案是用XML寫的5.16.package.manpages
如果你的包包含手冊頁,你應該把他列在package.manpages檔案中,並使用dh_install命令去安裝它。 把docs/gentoo.1作為gentoo包的手冊頁安裝到系統中,應該建立gentoo.manpages並寫入docs/gentoo.1
5.17.menu
X Windows系統使用者通常有視窗管理器,並且帶有可定製的選單用於啟動程式。如果它們安裝了Debian的menu包,整個系統中所有已安裝軟體的一系列選單將會被自動建立。 這裡有一個又dm_make建立的預設檔案:?package(gentoo):needs=X11|text|vc|wm \
section=Applications/see-menu-manual\
title=gentoo command=/usr/bin/gentoo
冒號後的第一個域是needs,它指定了程式需要何種介面。修改此處為列出的選項之一,例如X11或text。
下一個域是section,它指定了選單和子選單應該出現在什麼地方。
title域是程式的名稱,它可以用大寫字母開頭,只需保證它不是很長。
最後的command域是執行此程式時使用的命令。
你還可以新增其他的域,例如longtitle, icon, hints等等,詳細資訊可以看dh_installmenu(1), menufile(5), update-menus(1)。
5.18.NEWS
dh_installchangelogs(1)命令會安裝這個檔案。5.19.{pre,post}{inst,rm}
postinst,preinst,postrm和prerm檔案被稱為維護指令碼。這些指令碼被放置在包裡面的控制區內,並且被dpkg用來控制安裝,升級和刪除。 作為一個新手,你應該避免手動地去修改這些維護者指令碼,更多的資訊你可以檢視這裡,還有應該仔細看一看dm_make生成的一些例子。 但是如果你堅持去做,你應該保證他們不單止可以安裝,升級,還需要刪除和徹底清除。 升級到一個新的版本應該是安靜的和不需要互動的(即使用者不知道程式已經通過升級來修復了部分Bug,並且為使用者提供了新的特性)。 當一個包升級的時候需要互動(例如配置檔案分佈在不同的home目錄並且有完全不同的結構),你可以考慮作到最差的情況下應該提供返回一個安全的狀態(例如禁用服務),並提供適當的檔案所需的策略去解決問題( README.Debian和NEWS.Debian )。 不要讓使用者通過維護指令碼呼叫debconf來打擾使用者去升級軟體。5.20.package.symbols
講動態庫打成一個包對於初學者來說並不容易,因為應該儘量避免。因此,如果你的包包含了動態庫,你應該有debian/package.symbols檔案。 這個檔案主要是用來管理動態庫之間的相容性的。5.21.TODO
dh_installdocs命令會安裝它。5.22.watch
用於uscan的manpage。5.23.source/format
在debian/source/format中只包含一行,寫明瞭此原始碼包的格式(檢視dpkg-source(1))獲得完整列表。在squeeze後,它應該是以下兩者之一:- 3.0 (native) - Debian native 軟體
- 3.0 (quilt) - 其他所有軟體
5.24.soruce/local-options
如果你希望使用版本控制系統(VCS)時,你可以建立一個分支(例如叫做upstream)來跟蹤上游程式碼,和另一個分支(對於Git而言典型的是master分支)來跟蹤你的Debian軟體包。對於後者,用場會將未應用補丁的上游原始碼和你的debian/*檔案放在一起以便容易合併上游的新程式碼。 建立完包以後,這裡的原始碼正常來說都是已經被打了補丁的了。在你把原始碼提交到master分支之前,你必須手動的呼叫dquilt pop -a命令來去掉已經打上了的補丁。你可以在這個可選的檔案debian/source/local-options中寫入unapply-patches,讓它自動完成去除補丁的操作。這個檔案的作用只會改變打二進位制包,而不會影響到打原始碼包。這個檔案可能也應該包含abort-on-upstream-changes(詳情情況dpkg-source(1))。unapply-patches
abort-on-upstream-changes
5.25.source/options
在打包的時候,在原始碼樹上會自動生成一些很大的,但是沒有用的補丁檔案。你可以通過自定義一些模組(例如dh_autoreconf)的行為來解決這個問題。 你可以提供給命令dpkg-source的選項--extend-diff-ignore提供一個Perl正則表示式作為引數,就可以忽略那些在建立原始碼包時候自動建立的檔案了。 解決自動生成檔案這個問題,通過的做法就是在原始碼包中增加source/options檔案,裡面例如命令dpkg-source的引數。下面的展示的就是忽略config.sbu, config.guess和Makefile,不為這三個檔案做補丁檔案。extend-diff-ignore= "(^|/)
(config\.sub | config\.guess | Makefile)$"
5.26.patches
在1.0版本,在debian目錄中有一個很大的,包含了包的維護檔案檔案的壓縮包diff.gz,它會被用於被原始碼包打補丁。這樣的方法既不方便理解,也不方便使用。 在最新的3.0 (quilt)原始碼格式中,debian/patches/*目錄中存放著用於被quilt呼叫的補丁檔案。這些補丁檔案和其他資料檔案都被包含在debian目錄下,都會被打包成一個debian.tar.gz的檔案。自從dpkg-source命令可以處理quilt格式的補丁後,在build-Depends中就可以不用加入quilt這個依賴了。 quilt命令的使用可以參考quilt(1)。它會在deibna/patches目錄下,以堆的方式用-p1補丁檔案的格式記錄原始碼的修改。而且在debian目錄外的原始碼樹不會受到任何影響。補丁的順序記錄在deiban/patces/series檔案中。你可以很容易apply(=push), un-apply(=pop),或者更新補丁。Chapter 6. Building the package
我們現在已經準備好了去編譯一個新的包了6.1.完整的(重)編譯
為了可以完整的編譯一個新的包,你要確保你已經安裝了:- build-essential包
- control檔案中Build-Depends中所指定的包
- control檔案中Build-Depends-indep中所指定的包
dpkg-buildpackage
- 它會做所有執行以下的操作並且為你生成二進位制包和原始碼包。
- 清理原始碼(debian/rules clean)
- 建立原始碼包(dpkg-source -b)
- 編譯程式(debian/rules build)
- 編譯二進位制包(fakeroot deiban/rules binary)
- 用gpg簽署.dsc檔案
- 使用dpkg-genchanges和gpg生成並簽署上傳用的.change檔案
dpkg-buildpackage -us -uc
對於一個非原生的包,例如gentoo,你會在父目錄下看到下列的檔案:
- gentoo_0.9.12.orig.tar.gz
- gentoo_0.9.12-1.dsc
- gentoo_0.9.12-1.debian.tar.gz
- gentoo_0.9.12-1_i386.deb
- gentoo_0.9.12-1_i386.changes
對於一個自己做的包,例如Mypackage,你會在編譯完成後在父母路看到一下的包:
- mypackage_1.0.tar.gz
由dpkg-source生成的原始碼包。(它的字尾不是orig.tar.gz)
- mypackage_1.0.dsc
這是原始碼內容的摘要。(這裡沒有Debian的修訂號)
- mypackage_1.0_i386.deb
這是完整編譯後的二進位制安裝包(這裡沒有Debian的修訂號)
- mypackage_1.0_i386.changes
這個檔案記錄了當前修訂版所有的修改。
6.2.Autobuilder
Debian在很多不同架構的計算機通過執行buildd守護程序來提供很多包含autobuilder netword功能的埠。即使你不需要你自己來做這些,但是你應該清楚它會對你的包做了什麼操作。下面我們大概的看看他是怎麼給多種架構重建你的包的。
對於 Architecture: any 的包,你應該保證用於重新打包的系統有安裝以下的程式:
- build-essential安裝包
- 在Build-Depends中列出的包
然後你可以在原始碼目錄裡以下命令:
dpkg-buildpackage -B
它會自動編譯出依賴依賴框架的二進位制包,它主要做的是:
- 清理原始碼樹 (debian/rules clean)
- 構建程式 (debian/rules build)
- 構建平臺依賴的二進位制包 (fakeroot debian/rules binary-arch)
- 用gpg編譯原始檔.dsc
- 使用dpkg-genchanges和gpg生成和上傳.change檔案
這就是為什麼你的軟體包在其他平臺上可用的原因了。
雖然當平常我們打包的時候是需要安裝Build-Depends-Indep裡所指定的軟體,但是在autobuilder裡面是不會要求去安裝的,因為它只會構建基於架構的二進位制包。正常打包與autobuilding之間的區別就是要你應該在debian/control檔案中的Build-Depends和Build-Depends-Indep記錄下那些依賴的包
6.3.debuild命令
你以後可以通過debuild命令來自動呼叫dpkg-buildpackage命令來打包。
你可以在debuild的配置檔案/etc/devscripts.conf或者~/.devscripts檔案中自定義debuild行為,推薦至少應該包含以下的條目:
DEBSIGN_KEYID=Your_GPG_keyID
DEBUILD_LINTIAN_OPTS=-i -I --show-overrides
有了這些,安裝包就會被用你的GPG Key ID簽名,並且會用lintian命令去檢查它的細節。
清理原始碼並且重新生成一個包是很簡單的,你只要執行
$ debuild
如果你的包只是給自己用,你可以跳過.dsc檔案中的和.changes檔案的簽名,命令如下:
$ debuild -us -uc
你可以誒用一下命令清理原始碼樹:
$ debuild clean
6.4.pbuilder package
要在一個乾淨的環境(chroot)去驗證包的依賴,pbuilder是非常有用的。
6.5.git-buildpackage 命令以及相近的命令
6.6.快速重建
當需要構建一個很大的包的時候,當你只是調整debian/rules檔案後,你肯定不想從頭開始編譯。出於測試的目的,你可以不重新編譯原始碼而生成一個.deb包:
$ fakeroot debian/rules binary
或者執行一下的命令看它是否執行
$ fakeroot debian/rules build
一旦完成了除錯,記住按照前面說的正常過程重新構建你的軟體包。你可坑無法正常上傳此種方法構建的.deb包。
Chapter 7. 檢查軟體包中的錯誤
在你包軟體包上傳到公開的倉庫之前,你必須要先測試這個軟體包會不會有錯。這裡會介紹一些技術用來檢查軟體包是否有錯。 一個很好的方法就是不是打包的機器上安裝這個包。你必須密切關注任何的警告或者錯誤輸出。7.1 可疑的修改
如果你建立完一個非本地的軟體包後,在debian/patches目錄中發現一個類似debian-changes-*這樣的自動生成的補丁檔案,可能是你不小心改變上游軟體的了一些檔案或者構建的指令碼修改了檔案。如果是你的錯誤,就把問題解決掉。如果是構建指令碼導致的,通過定製rules檔案或者source/options檔案來解決根本的問題。7.2 驗證包的安裝
你必須測試你的包能夠正常安裝。 debi命令可以幫助你去測試安裝所有生成的二進位制包。sudo debi gentoo_0.9.12-1_i386.changes
避免在不同的作業系統中安裝會有問題,你從Debian的倉庫下載Contents-i386,來保證的捏包與現有的安裝包沒有檔名的衝突。apt-file命令可以很方便的完成這個任務。如果真的有衝突,就需要才去行動去避免真正的問題。重新命名檔案,把檔案移動到一個被多個包依賴的包中, 與其他軟體包的維護者協調,或者在debian/control長度Confilcts欄位中進行說明。7.3 驗證包的維護指令碼
所有的維護指令碼(preinst, prerm, postinst和postrm) 很難是完全正確的,除非他們是通過debhelper來生成的。如果你是一個新手的話,就不要使用它們了。 如果一個包需要使用這些不是很重要的維護指令碼,不僅僅需要測試install,還需要測試remove,purge和升級。在刪除或者完全刪除的時候,很多維護指令碼都會在這個時候有bug出現。使用dpkg命令去測試他們。sudo dpkg -r gentoo
sudo dpkg -P gentoo
sudo dpkg -i gentoo_version-revision_i386.deb
整個測試過程應該按照以下序列:
- 如果可能,安裝前一個版本的軟體包
- 從前一個版本升級軟體包
- 降級到前一個版本
- 徹底刪除該軟體包
- 全新安裝該軟體包
- 解除安裝該軟體包
- 再次安裝該軟體包
- 徹底刪除該軟體包
7.4 呼叫lintian
使用lintian(1)來檢查你的.changes檔案。lintian命令會執行很多測試指令碼來檢查常見的打包錯誤。lintian -i -I --show-overrides gentoo_0.9.12-1_i386.changes
當然,需要把檔名替換成你生成的.change檔案。lintian命令的輸出會使用下面的標示符號:
- E : 錯誤; 肯定違法策略或者安裝包有錯
- W: 警告; 可能違反策略或者安裝包有錯
- I : 提示資訊,輸出安裝包某方面的資訊
- N : 代表註釋,幫助你除錯的詳細資訊
- O : 代表已覆蓋:一個被lintian-overrides檔案覆蓋的資訊,但由於使用--show-override選項而顯示
7.5 debc命令
你可以通過debc命令來列出二進位制的debian包中的檔案debc package.changes
7.6 debdiff命令
你可以使用debdiff(1)命令比較兩個Debian原始碼包的內容debdiff old-package.dsc new-package.dsc
你還可以使用debdiff(1)命令比較兩個Debian二進位制包的檔案列表
debdiff old-package.changes new-package.changes
這對於確定在原始碼包中修改了什麼或者在升級時無意中的修改是非常有用的。7.7 interdiff命令
你可以使用interdiff(1)命令比較兩個diff.gz檔案。這對已更新使用舊的1.0原始碼格式的軟體包時,檢查是否有意外的變更非常有用。interdiff -z old-package.diff.gz new-package.diff.gz
3.0格式的原始碼會在patches/*目錄中把修改儲存成多個patch檔案。你也可以使用interdiff去檢視每一個patch檔案來跟蹤原始碼的變化。