[ 上一頁 ] [ 目錄 ] [ 1 ] [ 2 ] [ 3 ] [ 4 ] [ 5 ] [ 6 ] [ 7 ] [ 8 ] [ 9 ] [ 10 ] [ A ] [ 下一頁 ]


Debian新維護人員手冊
第 3 章 - 修改來源程式碼


一般情況下,程式會把它們自己安裝到/usr/local子目錄中。但是Debian的軟體 包裝檔絕對不能使用那個目錄,因為它被保留給系統管理員(或是使用者)使用。這就是 說你必需要仔細看一下你的程式的建構系統(build system),通常從Makefile開 始。它是make(1)將會使用的用於自動建構程式的腳 本。要了解更多關於Makefiles的內容,請參考“rules”檔案, 第 4.4 節

注意如果你的程式使用了GNU的automake(1)和/或autoconf(1),也就意味著來源程式碼 是在Makefile.am和/或Makefile.in檔案中,相對的,你需要修改這些檔案。這是 因為在每一次automake的執行中,Makefile.in等檔案中的資訊將會通 過Makefile.am等檔案來重新產生,並且每次執行./configure時,類似的操作會 執行在Makefile等檔案上,它們會被根據Makefile.in檔案重新產生。修 改Makefile.am檔案需要一些關於automake的知識,你可以閱讀automake的info項 目,然而修改Makefile.in檔案和修改Makfile檔案是差不多的,不過要注意一下 變數,例如,任何被“@”包裝檔圍的字串如@CFLAGS@或@LN_S@將會在每次 ./configure 執行時用實際的值取代掉。

還需要注意的是,在這裡我們沒有地方討論所有的修改上游來源程式碼的細節,這裡 我們只有一些人們經常會會遇到的問題。


3.1 在一個子目錄中安裝

大多數的程式都能夠以某種方式把自己安裝到系統現有的目錄結構上,所以它們 的可執行檔案已經存在於你的$PATH中,並且你也可以在一般的位置找到它們的文 檔和手冊。然而,如果你這樣做,這些程式將會和你系統上的其它程式混合在一 起。這樣的話,對於打包裝檔工具而言要想把它們同不屬於這個套裝軟體的程式區分開 就很困難了。

因此,你還必須要做一些其它的事情:把程式安裝到一個臨時的子目錄中,從這 裡打包裝檔工具可以建立一個可以工作的.deb套裝軟體。在這個目錄中的所有內容都將 會被安裝到使用者的系統中,當他們安裝你的套裝軟體時,唯一的不同是dpkg將會把 這些檔案安裝到檔案系統的根目錄上。

這個暫時檔案目錄通常建立在來源程式碼目錄的debian/子目錄中。一般情況下,它的 名字是debian/packagename

有一件事情請記住,盡管你要把程式安裝到debian/packagename目錄中,但在安 裝.deb檔案的時候,它仍應當可以正常地安裝到根目錄中。所以你絕對不能讓軟 件包裝檔的建構系統把類似 於/home/me/deb/gentoo-0.9.12/usr/share/gentoo的字串寫入到軟 件包裝檔中。

對於使用GNU autoconf的程式而言,這個工作是非常簡單的。大多數這樣的程式 的makefile腳本預設狀態下就允許程式被安裝到任何的子目錄中,並以(例如)/usr 作為它的典型前綴。當偵測到你的程式使用了autoconf時,dh_make發現將會自動 設定命令完成這一工作,因此你可以略過下面的部分。但對於其它的程式,你極 有可能不得不檢查並修改Makefile檔案。

這裡是gentoo的Makefile檔案的相應部分:

        # Where to put binary on 'make install'?
        BIN     = /usr/local/bin
      
        # Where to put icons on 'make install'?
        ICONS   = /usr/local/share/gentoo

我們發現這個檔案被設定成為安裝到/usr/local目錄下。將這些路 徑改為:

        # Where to put binary on 'make install'?
        BIN     = $(DESTDIR)/usr/bin
      
        # Where to put icons on 'make install'?
        ICONS   = $(DESTDIR)/usr/share/gentoo

但為什麼要在這個目錄中而不是其它的呢?這是因為Debian絕不會把檔案安裝 到/usr/local目錄中──那個目錄是留給系統管理員用的。這些檔案 在Debian系統上都會被安裝到/usr目錄下。

在檔案系統層次標準中描述了更多的關於二進位、圖示、文件等檔案放置位置的 資訊(請參考/usr/share/doc/debian-policy/fhs/)。我建議你瀏覽一下其中可能 與你的套裝軟體有關的部分。

因此,我們應該把二進位檔案安裝在/usr/bin目錄中而不是/usr/local/bin目錄 中,把手冊安裝在/usr/share/man/man1目錄中而不是/usr/local/man/man1目錄 中。也許你注意到在gentoo的makefile中並未涉及到手冊檔案,但Debian政策要 求每個程式都要有一篇手冊,因此我們稍後會製作一份並把它安裝 到/usr/share/man/man1中。

有一些程式並不像這樣使用makefile的變數來定義其路徑。這就意味著你不得不 去修改一些C來源程式來使其能夠在正確的位置找到檔案。但到哪裡去找又改找些什 麼呢?你可以使用這樣的命令:

        grep -nr -e 'usr/local/lib' --include='*.[c|h]' .

grep會遞歸地搜索整個來源程式碼目錄樹,並在找到相對的字串時告訴你它所在文 件的名字和在檔案中所處行的行號。

修改那些檔案,並用usr/*取代掉原來的/usr/local/*以及所有相關的內容。注意 不要為了修改這些地方而把代碼的其它部分搞亂。 :-)

之後,你應該找到install目標(尋找以“install:”開始的行)並修改所有對於目錄 的參照,使其和在Makefile的開始部分定義的一致。最初的時 候,gentoo的install目標是下面的樣子:

        install:        gentoo
                        install ./gentoo $(BIN)
                        install icons/* $(ICONS)
                        install gentoorc-example $(HOME)/.gentoorc

在我們修改以後它變成了這個樣子:

        install:        gentoo-target
                        install -d $(BIN) $(ICONS) $(DESTDIR)/etc
                        install ./gentoo $(BIN)
                        install -m644 icons/* $(ICONS)
                        install -m644 gentoorc-example $(DESTDIR)/etc/gentoorc

你一定已經注意到在其它命令之前有一個install -d命令。原來 的makefile腳本沒有它是因為一般情況下在運 行“make install”時,/usr/local/bin和其它的目錄都已經存在於檔案系統上了。 然而,我們是要把檔案安裝到我們的空的(或是是根本不存在的)目錄中,因此我 們不得不首先建立每一個目錄。

在rule檔案的結尾,我們還可以加入其它的內容,比如安裝上游作者忽略掉的附 加文件,如下所示:

                        install -d $(DESTDIR)/usr/share/doc/gentoo/html
                        cp -a docs/* $(DESTDIR)/usr/share/doc/gentoo/html

細心的讀者應該已經注意到我把“install:”一行中的“gentoo”改成 了“gentoo-target”。這被稱為無關bug修復 :-)

當你做了一些並不特定地與Debian套裝軟體相關的修改時,請一定要把它們發送給 上游的維護者,這樣這些修改就可以被包裝檔含在軟體的下一個版本中,這樣會對其 他人非常有用。還要記住不要使你的修改只是針對Debian或是Linux(甚至 是Unix!),在發送它們之前──讓它們具有可移植性。這將會使你的修改更容易 被接受。

注意,你不需要把debian/*檔案也發送給上游的人。


3.2 不一樣的程式庫名稱

有一個非常普遍的問題:在不同的平台上連結程式庫通常是不一樣的。例 如,Makefile中包裝檔含了對一個庫的參照,但Debian系統上並沒有這個程式庫。在這種 情況下,我們需要把它修改成為一個在Debian中確實存在並且完成相同功能的庫。

因此,如果在你的程式的Makefile(或是Makefile.in)中有類似於下面的一行(並 且使你的程式無法編譯了):

        LIBS = -lcurses -lsomething -lsomethingelse

可以把它改成這樣,一般情況下它都能工作:

        LIBS = -lncurses -lsomething -lsomethingelse

(作者已經注意到這並不是最好的例子,因為我們現在使用的libncurses套裝軟體在 發佈的時候包裝檔含了一個libcurses.so的符號連結,但他沒能想到更好的。歡迎你 提些建議 :-)


[ 上一頁 ] [ 目錄 ] [ 1 ] [ 2 ] [ 3 ] [ 4 ] [ 5 ] [ 6 ] [ 7 ] [ 8 ] [ 9 ] [ 10 ] [ A ] [ 下一頁 ]


Debian新維護人員手冊

version 1.2.3, 2005年4月3日.

Josip Rodin joy-mg@debian.org
華文版翻譯:李凌 lilingv@gmail.com
華文版翻譯:鄭原真 ycheng@slat.org