# 打包
分發自由軟件的標準形式是源代碼。無論軟件是否以源代碼的形式(例如解釋性語言Perl、Python和PHP等等)運行,還是必須首先編譯(例如C、C++和Java等),這一點是毋庸置疑的。通過編譯好的軟件,大多數用戶可能無需自己編譯源代碼,而只需安裝預先編譯的二進制包(見本章后面的[the section called “二進制包”](# "二進制包"))。然而,這些二進制包依然來自主源代碼分發包。原因是源代碼包明確定義了發布版本。當項目分發“Scanley?2.5.0”時,真正的含義是“源代碼文件的目錄樹,當編譯(如果需要)和安裝后將產生Scanley 2.5.0”。
對于源代碼發布的式樣有一個相對嚴格的標準。可能會有與標準的偏差出現,但是那只是例外,不是規則。除非有強有力的理由,否則你的項目也應該遵守這個標準。
### 格式
源代碼必須以標準格式傳輸目錄樹。對于Unix和類Unix的操作系統,習慣上是TAR格式,壓縮為**compress**、 **gzip**、**bzip**或**bzip2**。對于微軟Windows,分發目錄樹的標準方法是*zip*格式,也是壓縮格式,所以不必再進一步壓縮歸檔文件。
**TAR文件**
*TAR*代表了“Tape?ARchive”,因為tar格式用線性數據流表示了目錄樹,所以非常適于將目錄保存到磁帶。這個特性也使之成為已單個文件分發目錄樹的標準。生成壓縮的tar文件(*tarballs*)也非常簡單。在某些系統上,**tar**命令可以自己產生壓縮歸檔;在另外一些系統上,則需要使用單獨的壓縮程序。
### 命名和布局
打包的名稱必須包含軟件名稱和發布版本號,然后是特定歸檔類型的格式后綴名。例如Scanley 2.5.0在Unix上使用GNU Zip(gzip)壓縮的包類似:
scanley-2.5.0.tar.gz
或者是在Windows上使用zip壓縮:
scanley-2.5.0.zip
所有的這些歸檔解壓后,都應該能在當前目錄創建一個名為`scanley-2.5.0`的單獨目錄。這個新目錄中,所有的源代碼應該是處于準備好進行編譯(如果需要編譯)的布局。在新目錄樹的最上層,應該有一個`README`文件,解釋了軟件是什么,發布版本是哪個,并給出了其他資源的指針,例如項目站點以及其他有用的文件等。`README`旁邊也應該有一個`INSTALL`,說明在所有支持的操作系統上構建和安裝軟件的方法。就像[Chapter?2, *起步*](# "Chapter?2.?起步")的[the section called “如何為你的軟件應用許可證”](# "如何為你的軟件應用許可證")所說明的,應該有`COPYING`或`LICENSE`,說明軟件分發的條款。
也應當有一個`CHANGES`文件(有時稱為`NEWS`),解釋了發布版本的新功能。`CHANGES`文件按照逆向的歷史順序,匯集了所有發布版本的變更列表,所以最新的發布位于文件最頂部。完成這個列表通常是穩定發布分支的最后一項工作;一些項目會隨著開發列出所有的片段,而另外一些項目更傾向于在最后階段,讓某人根據版本控制日志組合信息一次完成。這個列表類似下面:
~~~
Version 2.5.0
(20 December 2004, from /branches/2.5.x)
http://svn.scanley.org/repos/svn/tags/2.5.0/
New features, enhancements:
* Added regular expression queries (issue #53)
* Added support for UTF-8 and UTF-16 documents
* Documentation translated into Polish, Russian, Malagasy
* ...
Bugfixes:
* fixed reindexing bug (issue #945)
* fixed some query bugs (issues #815, #1007, #1008)
* ...
~~~
根據具體情況,這個列表可能會很長,但是不需要包含所有的小bug修正和特性提升。它的目的僅僅是給用戶一個印象,通過升級到最新版本將會獲得哪些好處。實際上,習慣上會將變更列表包含在聲明郵件(見本章后面的[the section called “測試和發布”](# "測試和發布"))中,所以在編寫時要考慮你的讀者。
**CHANGES還是ChangeLog**
傳統上,名為*ChangeLog*的文件會列出項目的每個變更—也就是提交到版本控制系統的每個修訂版本。ChangeLog文件有許多種格式;具體的格式并不重要,但都需要包含相同的信息:變更的日期、作者和簡介(或僅僅是該變更的日志信息)。
`CHANGES`文件有所不同。盡管它也是變更的列表,但是僅應該包含對特定讀者比較重要的變更,而且準確日期和作者之類的元數據也可以省略。為了避免混淆,不要使用可替換的術語。一些項目使用“NEWS”而不是“CHANGES”,盡管避免了與“ChangeLog”混淆的可能,但卻有些用詞不當,因為文件CHANGES保留了所有發布版本的變更信息,所以在最頂部的新聞之后是許多舊聞。
文件ChangeLog可能會漸漸消失。當CVS是版本控制系統的唯一選擇時使用這個文件非常重要,因為變更數據很難從CVS中獲取。然而,在許多現在的版本控制系統中,ChangeLog中保存的信息可以在任意時間從版本控制版本庫中獲取,所以再使用一個靜態文件保存這些信息變得毫無意義—實際上,不僅僅是毫無意義,因為ChangeLog僅僅是重復版本庫已經保存的日志信息。
目錄樹中源代碼的布局與項目版本控制系統檢出的源代碼的布局應當相同,或者盡可能的近似。通常情況下,會有些區別,例如因為發布包會包含一些用于配置和編譯(見本章后面的[the section called “編譯和安裝”](# "編譯和安裝"))的生成文件,或者因為它包含了非本項目維護的,而用戶一般不會擁有的第三方軟件,。但是,即使發布的目錄樹與版本控制系統中的開發目錄樹完全一致,發布包本身也不應當是一個工作拷貝(見[*工作拷貝(working copy)*](#))。發布版本代表了一個靜態參考點—源文件特定的,不可改變的配置。如果它是工作拷貝,就會存在用戶不小心作出更新的風險,而用戶還會以為使用的是發布版本,盡管實際上已經有所不同。
請牢記無論打包方式如何,這個發布包應該是一樣的。這個發布版本—精確的引用了某人所說的“Scanley?2.5.0”—是zip文件或tarball解壓縮所創建的目錄樹。所以項目可以提供所有這些下載:
scanley-2.5.0.tar.bz2
scanley-2.5.0.tar.gz
scanley-2.5.0.zip
...但是通過解壓他們創建的源代碼樹必須相同。源代碼樹是分發物;具體的形式只是為了方便使用。源代碼包也可以有些許的差異:例如,在Windows包中,文本文件必須以CRLF作為行結束符(回車和換行),而Unix包應該使用LF。不同操作系統下如果因為編譯的原因需要有不同的布局,源包的布局也可以有所不同。然而,這些都是些無關緊要的變形。同一發布版本不同包的基本源代碼文件必須相同。
### 大寫還是不大寫
當通過名稱引用一個項目時,人們通常會以正常的名詞進行大寫,如果是縮略詞則也要大寫:”MySQL5.0“,”Scanley2.5.0“等等。是否在包名上大寫也取決于項目。例如,`Scanley-2.5.0.tar.gz`或`scanley-2.5.0.tar.gz`都可以(我個人傾向于后者,因為我不喜歡讓人去按shift鍵,不過很多項目使用有大寫的包)。重要的是解壓tarball得到的目錄使用相同的大小寫。不應該有什么意外:用戶總是預計解壓得到的目錄會和壓縮包使用相同的名稱。
### 預發布
當發送預發布或候選發布時,合格者成為發布號碼的一部分,所以在包的名稱中要包含這個名字。例如,在之前[the section called “版本號組成部分”](# "版本號組成部分")提到的alpha和beta系列的發布包名稱為:
scanley-2.3.0-alpha1.tar.gz
scanley-2.3.0-alpha2.tar.gz
scanley-2.3.0-beta1.tar.gz
scanley-2.3.0-beta2.tar.gz
scanley-2.3.0-beta3.tar.gz
scanley-2.3.0.tar.gz
第一個解壓后進入目錄`scanley-2.3.0-alpha1`,第二個是`scanley-2.3.0-alpha2`,以此類推。
### 編譯和安裝
對于需要從源代碼編譯的安裝的軟件,有許多經驗豐富的用戶希望能夠遵循的標準步驟。例如,以C、C++或特定其他編譯語言編寫的程序,在類Unix系統下的標準是輸入:
~~~
$ ./configure
$ make
# make install
~~~
第一個命令自動檢測構建過程中需要的環境,第二個命令在原地構建軟件(但不安裝),最后一個命令是在系統上安裝。前兩個命令作為普通用戶執行,而第三個以root用戶。設置系統的詳細信息可以看Vaughan、Elliston、Tromey和Taylor編寫的優秀圖書*GNU Autoconf, Automake, and Libtool*。它作為New Riders的treeware發布,內容也可以在網上[http://sources.redhat.com/autobook/](http://sources.redhat.com/autobook/)免費得到。
這不是唯一的標準,只是傳播最廣泛的一個。Ant([http://ant.apache.org/](http://ant.apache.org/))構建系統也漸漸流行,特別是Java編寫的項目,它擁有自己的構建和安裝的標準步驟。另外,特定的編程語言,例如Perl和Python都有大多數使用這些語言所推薦的相同方法(例如Perl模塊使用命令**perl?Makefile.pl**)。如果不是清楚適應于項目的標準,可以詢問資深的開發者;你可以安全的假定*某些*標準更加合適,即使一開始并不清楚是什么。
無論你的項目適合哪個標準,則如非必要一定不能與之偏離。標準安裝過程對于許多系統管理員已經成為條件反射。如果在你的項目`INSTALL`文件中看到了熟悉的實施步驟,他們就會認識到你的項目遵守了一般的習慣,也就會輕松的完成其他的事情。另外,就像在[Chapter?2, *起步*](# "Chapter?2.?起步")的[the section called “下載”](# "下載")中討論的,擁有標準的構建程序可以讓潛在的開發者滿意。
在Windows中,構建和安裝的標準比較薄弱。對于需要編譯的項目,通常要提供一個適用于標準微軟開發環境(Developer Studio、Visual Studio、VS.NET和MSVC++等等)工作空間/項目模型的目錄樹。取決于項目的本性,可以通過Cygwin([http://www.cygwin.com/](http://www.cygwin.com/))環境提供類Unix的構建選項。當然,如果你使用的語言或編程框架使用自己的構建和安裝習慣—例如Perl或Python—你應當使用該框架標準的方法,無論是Windows、Unix、Mac OS X或任何其他操作系統。
要樂于花費額外的精力讓項目遵守相關的構建或安裝標準。構建和安裝是切入點:如果一定需要,在這之后可以更加困難,但是如果用戶或開發者一開始就需要使用意想不到的步驟與軟件進行交互則是一種恥辱。
### 二進制包
盡管正式發布是源代碼包,大多數用戶會從二進制包安裝,可以通過他們操作系統的軟件分發機制得到,也可以從項目站點或第三方手工獲取。這里“二進制”并不一定是“已編譯”;它僅僅意味著一種預配置形式的包,允許用戶在自己的電腦上無需執行一般的基于源代碼的構建和安裝程序,便可以進行安裝。在RedHat GNU/Linux上,這是RPM系統;在Debian GNU/Linux上,則是(`.deb`)系統;在MS Windows,通常是`.MSI`文件或自安裝的`.exe`文件。
無論這些二進制包是由項目相關的人組裝,還是由關系較遠的第三方組裝,用戶都會*認為*其等同于項目的官方發布版本,會根據二進制包的行為在項目bug跟蹤系統上發起問題。因此,項目能否為打包者提供明確的指導方針就非常有意義,應該與他們更緊密的合作,認識到他們是否能夠清楚和準確的產生軟件。
打包者需要知道的主要問題是是否應當一直根據官方源代碼版本發布他們的二進制包。有時,打包者會喜歡獲取版本庫較晚版本的代碼,或者選擇在發布后包含某個變更,從而為用戶提供特定的bug修正或其他改進。打包者認為通過最新的代碼,他是在為用戶謀利益,但實際上這樣會導致許多混亂。項目已經準備好了接受某個發布版本以及trunk和分支上(那些故意運行最前沿代碼的人發現的)的bug報告。當一個bug來自這些源,回應者通常可以能確認bug在該快照出現,而且已經被修正,用戶可以升級或等待下個發布。如果是一個還未知的bug,擁有精確的發布版本時,重現就會比較簡單,在跟蹤系統中也比較容易分類。
項目沒有準備好根據未指明媒介或混血的版本接受bug報告。此類bug很難重現;另外,因為無法預期與來自發布之后開發的孤立變更進行交互的結果,所以產生的不正常也不應該成為對開發者進行譴責理由。我曾經非常沮喪的浪費了許多時間,因為某個bug似乎*消失了*,而實際上應該出現:某人運行的是輕微補丁的版本,基于(但不相同)官方發布版本,當預期的bug沒有出現時,每個人都會嘗試尋找原因。
在有一些情況下,打包者也確實需要在原發布基礎上做出一些修改。要鼓勵打包者向項目開發者提出這個問題,并描述他們的方案。他們可能得到許可,即使失敗,也至少會讓項目知道他們的目的,項目也可以關注一些不尋常的bug報告。開發者可以在項目站點上設置一個免責聲明,并告知所有的打包者在合適的地方放置同樣的東西,這樣該二進制包的用戶就可以知道他們獲取的東西與項目官方發布并不完全相同。這種情形并沒有任何敵意,但不幸的是經常會有這種結果。打包者與項目開發者有些不太一樣的目標。打包者主要希望為用戶提供最佳的開箱即用體驗。開發者也希望如此,但他們也需要確保自己知道別人所用軟件的版本,這樣可以獲取到一致的bug報告,并作出兼容性的保證。有時這些目標會有沖突。當發生這種情況時,需要牢記項目無法控制打包者,兩種方式都承擔了各自的義務。誠然項目通過產生軟件為打包者提供了服務。但是打包者也是在為項目服務,通過提供這種單調的工作讓軟件更廣泛的傳播。當然可以不認可打包者,但是不要遷怒于他們;只需要盡自己的可能將工作做好。
- 前言
- 為什么寫這本書?
- 誰應該讀本書?
- 資料來源
- 致謝
- 免責聲明
- 1. 介紹
- 歷史
- 現狀
- 2. 起步
- 從你擁有的開始
- 選擇許可證并應用
- 設置風格
- 通告
- 3. 技術基礎設施
- 一個項目需要什么
- 郵件列表
- 版本控制
- Bug跟蹤
- IRC / 實時聊天系統
- RSS供稿
- Wikis
- 網站
- 4. 社會和政治的基礎架構
- 慈善獨裁者
- 共識為基礎的民主(Consensus-based Democracy)
- 寫下所有的內容
- 5. 金錢
- 參與的類型
- 長期雇傭
- 作為一些個體出現,而不是一個整體
- 公開你的動機
- 錢不能讓你可愛
- 契約
- 資助非編程活動
- 市場營銷
- 6. 交流
- 人如其文
- 避免常見的陷阱
- 刺兒頭
- 處理成長
- Bug跟蹤系統中無對話
- 公開性
- 7. 打包、發布和日常開發
- 版本號
- 發布分支
- 穩定發布版本
- 打包
- 測試和發布
- 維護多發布線
- 發布和日常開發
- 8. 管理志愿者
- 從志愿者中獲取最多
- 像分擔技術任務一樣分擔管理任務
- 轉化
- 提交者
- 榮譽
- 分叉
- 9. 許可證,版權和專利
- 術語
- 許可證的方面
- GPL和許可證兼容性
- 選擇一個許可證
- 版權分配和所有權
- 雙許可證模式
- 專利
- 深入資源
- A. 自由版本控制系統
- B. 自由Bug跟蹤系統
- C. 為什么我要關注車棚的顏色?
- D. 報告bug的樣例指導
- E. 版權