原文:
How To Create a GNU Autoconf / Automake Based Configure Script for Your Application
http://www3.fh-swf.de/fbin/roth/download/prg3.howto_autoconfmake.pdf
by Prof.Dr. Walter Roth
University of Applied Science Suedwestfalen, Germany
================================================
1. 本文檔的基本信息
2. 為什麼使用GNU AutoXXX Tools?
3. 它是如何工作的?
4. 你需要什麼?
5. 一步一步為“Hello World”創建配置腳本
6. 比較復雜的應用
7. 參考文獻
==============================================================
1. 本文檔的基本信息
1.1. 印刷
有些字體比較難認,所以用下面這個表給出一些字符的圖像,這對命令很重要。本文檔用Times New Roman的12號字體寫普通文本,用Courier的11號字體寫命令行和源代碼。注意:雙線可能會畫成一個比較長的單線
1.2. 名詞定義
應用(Application)是指你開發的程序。
目標系統(target system)是用於安裝你的程序的計算機。
開發系統(development system)是指開發程序所用計算機
2. 為什麼使用GNU AutoXXX Tools?
使用Autoconf和Automake是唯一的(合理的)為你的應用創建Makefile的方法,只要你的應用工作在任何有GNU工具的系統上。GNU工具可用於所有的Unix、Windows(Cywin)和MacOS系統
3. 它是如何工作的?
GNU Autoconf由多個程序組成,最終由它們為你的應用創建Makefile。它會為源碼的每個子目錄創建一個Makefile。由於Makefile是針對特定的用戶機器的(目標系統),也就是你的程序運行的系統,所以必須在用戶機器上創建。目標系統的所有信息對於這個機器都是可用的。Makefile是由冗長的腳步程序“configure”創建的,這個腳本必須隨你的源代碼一起提供。在目標系統上,configure是根據它運行的一些測試結果來創建Makefile的,這些結果已經事先寫在了Makefile.am文件。Makefile支持很多不同的目標,第一個就是“all”。make all會為你的程序創建二進制文件。install目標會安裝這些二進制文件,uninstall用於卸載。這樣的話,用戶就可以很方便的使用你的程序,只需應用的頂層目錄上,運行如下三條命令即可:
[python]第二條命令就相當於make all,因為all是第一個目標。當然,目標系統必須有可用make工具和一個編譯器。但是,這要用configure檢查,如果configure沒有找到所有它需要的程序,它會停止並返回錯誤信息。
可是,必須在你的系統上創建configure腳本,這是個非常復雜的任務。
4. 你需要什麼?
首先,需要你的源碼。確保處在頂層目錄,並且包含了所有的文件,編譯時不會報錯。
你可能要添加一些新文件,為你的應用提供一些必要的文檔。下面這些文件是必須存在於頂層目錄的:
文件名
內容
INSTALL
安裝描述。你可以從其他基於automake的應用中拷貝一個標准的INSTALL文件,然後添加一些針對你的應用的信息。
README
用戶應該知道的一些關於本應用的信息。最好在文件的開始處簡單描述一些這個應用的目的
AUTHORS
作者列表。
NEWS
關於本應用的最新的新聞
ChangLog
本應用的修訂歷史
這些文件可以不包含任何內容,因此,第一次運行時,你可以只創建一些空文件。但是,這些文檔對用戶是很重要的。你應該花點時間好好的寫了它們。README文件是最重要的一個。讓它盡可能的保護一些有用的信息。
然後,當然是需要GNU工具。幸運的是,現在所有的Linux發行版都包含了GNU工具。你可以驗證一些它們是否已經安裝。要檢查的話,只需鍵入:
[python]它會產生類似下面的結果:
[python]5. 一步一步為“Hello World”創建配置腳本
5.1. 簡評
下面內容中的命令都用Courier字體。所有的命令都可以在普通用戶中使用,無需變成root。例子中使用的應用叫做myapplication,版本是1.0。該應用只有一個文件夾“myapplication”,單一源文件main.c。你要自己編輯源代碼、文檔、configure.ac和makefile.am文件。其他的都可以自動生成。
5.2. 准備源碼
進入應用的頂層目錄。
[python]建立前面提到的那些空文檔文件,稍後再填寫它們。
[python]5.3. 新建makefile.am
5.3.1. 構建應用
makefile.am包含了關於應用的信息,配置腳本需要這些信息來創建最終的Makefile。必須建立一個makefile.am,它的內容包括目標、源代碼和應用的子目錄。下面是myapplication的makefile.am,沒有子目錄:
[python]第一行是默認的內容,每個makefile.am都可以使用。第二行列出了要建立和安裝到目標系統的二進制程序文件。本例中只有一個myapplication,它將被安裝到SUSE9.0系統的/usr/bin目錄下,這是一個默認目錄。如果你要構建多於一個的程序,或要安裝到其他目錄,請查看第7章的Automake文檔。
第三行列出了該應用的所有源文件。第一個詞是由應用名稱和_SOURCES組成的。
5.3.2. 安裝文件
makefile.am不僅僅管理應用的構建過程,還定義了要安裝到目標系統的文件的目標路徑。automake已經提前定義了標准的安裝目錄,其中最重要的幾個目錄是:
prefix :安裝目錄樹的頂層,標准是/usr/local(KDE是/opt/kde)
binary :二進制程序的目錄
libexecdir :程序的庫的目錄
還有更多的提前定義的目錄,請閱讀“The GNU Coding Startding”的目錄變量(5)。安裝到這些目錄的文件會像下面這樣被列出了:
[python]如果你需要將某些文件安裝到非標准目錄下,就要自己定義。名字必須以dir作為後綴。例如:
[python]html目錄就會處於prefix之下。在makefile.am定義要安裝的文件,如下:
[python]除了標准目錄,automake還為個別包定義了目錄:pkglibdir、pkgincludedir和pkgdatadir,可以用它們將你的文件安裝到標准的bin、lib或data目錄下的獨立子目錄。這些安裝目錄會用包的名字命名。
並不是所有文件都要被最終安裝。例如,圖標(或圖標),它們被編譯到可執行文件後就不再需要了。但它們並不是真正的源文件。由於它們必須包含在最終的發布中,所有要把它們作為EXTRA_dist文件列出了。
5.4. 新建configure.ac
注意:在比較早的automake和autoconf版本中,configure.ac被叫做configure.in。autoscan工具會掃描你的源代碼,然後創建一個默認的configure.ac初始文件。因此,你可以在源代碼的頂層目錄執行autoscan,生成一個configure.scan文件作為configure.ac的模板。
[python]編輯configure.scan文件,修改下面這幾行:
[python]用你的應用的名字替換FULL-PACKAGE-NAME,VERSION就是它的版本號。BUG-REPORT-ADDRESS應該設一個Email地址,以便報告Bug。例如:
[python]接下來添加一行,來調用automake。
[python]這一行使用PACKAGE_NAME和PACKAGE_VERSION變量,它們都是AC_INIT中定義過的,最終會傳遞給automake。@表示它包含字符串的是一個變量標識符。沒有用@的字符串直接按字面傳遞,結果包含在PACKAGE_NAME_PACKAGE_VERSION。
AC_CONFIG_SRCDIR用於檢測源代碼目錄下的config.h文件。AC_CONFIG_HEADER表示你想要使用一個配置頭文件。
下面的宏用於檢測構建應用所需的各種程序,把你需要用在目標系統上的程序都添加到這裡。
在typedefs這一組,你可以檢測目標機器上的系統的特殊屬性。AC_HEADER_STDBOOL是autoscan為本例添加的,用於檢測stdbool.h的可用性和C99的bool類型是否存在。AC_C_CONST用於檢測例程所需的常量機制。
最後,你可以在AC_CONFIG_FILES中指定所有你想要配置生成的makefile文件,這些文件將由AC_OUTPUT輸出,通常將它卸載文件的最後一行。
5.5. 新建config.h.in
運行autoheader可以根據configure.ac文件創建一個config.h.in。如果你想要指定config.h中包含#define,必須在configure.ac中定義。查看autoconf文檔中的AC_CONFIG_HEADER。
[python]這樣就會建立config.h文件,文件的內容是用預處理描述應用程序的代碼。下面這段文本是例程的config.h.in文件的一部分。
[python]5.6. 新建aclocal.m4
很幸運有一個程序可以完成這個工作。只需執行:
[python]如果沒有找到你所需的宏,就不得不自己去寫了。“Goat book”(1)會告訴你怎麼做。
5.7. 新建configure
現在,autoconf就可以用autoconfig.ac和aclocal.m4創建一個配置腳本了。只需運行:
[python]這樣會產生一個配置腳本,對於一個GUI應用,可能超過2000行。
5.8. 新建makefile.in
makefile.in包含很多從makefile.am自動添加的信息。makefile.in是配置腳本最終創建Makefile所必須的。很幸運的是,automake程序可以為你完成這個工作。可是,一些應用程序發布包所必須的文件還沒有添加到應用的頂層目錄。如果你運行下面的命令,automake將從GNU工具中拷貝這些文件,然後創建makefile.in:
[python]或
[python]5.9. 測試包
現在,配置腳本已經准備好了,可以在任何GNU支持系統上創建Makefile。configure接受很多命令行參數。運行./configure可以得到一個概述。最重要的參數可能是--enable-FEATURE,這裡的FEATURE有很多選擇。對於程序開發而言,經常要用到--enabl-debug=full來選擇調試。對於用戶,--prefix和--with-LIBRARY-dir可以控制很多安裝路徑。先試一下不用任何參數運行configure。會在源碼的頂層目錄產生一個Makefile,prefix設為/usr/local。只需鍵入:
[python]然後,測試一下新的makefile:
[python]應該會沒有任何錯誤的編譯應用。注意,不要用root用戶運行make install,否則會將程序安裝到默認的prefix下,那很可能是一個錯誤的地址。運行如下命令就能將應用安裝到默認的prefix:
[python]你的Makefile支持所有的標准的目標,例如clean、dist、uninstall等等。
要得到一個程序的開發版本,需要重新運行configure,生成一個支持調試的makefile。
[python]然後運行:
[python]這樣,編譯的程序就包含了調試信息。因此,可執行文件也會比之前編譯的大很多。現在你就可以在調試器中運行你的程序了。
6. 比較復雜的應用
6.1. 帶有子目錄的應用
你需要在頂層目錄(myapplication)和每個子目錄(src、doc、img)都有一個makefile.am。像myapplication/CVS這樣的子目錄不算發布包的一部分,必須跳過。相應目錄的直接子目錄必須像下面這樣在makefile.am中列出了:
[python]不需要在SUBDIRS中指定子目錄下的目錄。每個子目錄下的makefile.am只需指定本目錄下的直接子目錄。
例如,頂層目錄是myapplication,CVS子目錄用於管理CVS,src是源碼,doc是文檔,img是圖片,myapplication目錄下的頂級makefile.am就應該是這樣:
[python]提供一個好主意,為大多數autoXXX工具創建和使用的文件使用用一個叫做admin的單獨目錄。這會使頂層目錄更具可讀性。你要做的就是在AC_INIT後面直接添加:
[python]源文件通常被列在myapplication_SOURCES列表。但是,這次的源文件在src目錄下,所以要把它們列在myapplication/src/makefile.am文件中。二進制文件列表bin_PROGRAMS也在這個文件中指定。如下:
[python]對於其他的非源代碼文件,如果想將它們包含在發布包中,就必須作為EXTRA_DIST文件列出。如果doc目錄中包含一個index.html文件,你必須將它添加到myapplication/doc/makefile.am文件的EXTRA_DIST列表中:
[python]下面是myapplication/img目錄下的makefile.am文件:
[python]運行autoscan,並按照3.3節描述的那樣編輯configure.scan文件。在文件末尾的AC_CONFIG_FILES宏中為每個要包含在發布包的子目錄列一個makefile文件。在頂層目錄(myapplication)下運行:
[python]那麼,automake將為每個makefile.in創建一個makefile.am。
6.2. 庫的應用
6.2.1. 靜態庫
靜態庫的構建很���應用,可是,目標要用_LIBRARIES變量指定。mylib庫可以用下面的這些方式指定:
如果它要被安裝在全局庫目錄下(默認:/usr/lib):
[python]如果它要被安裝在應用的lib目錄下(默認:/usr/myapplication/lib):
[python]如果它只是在構建的過程中使用,不需要安裝:
[python]6.2.2. 共享庫
構建共享庫是一個比較復雜的問題,你最好參考一下automake和libtool的文檔。這裡介紹一種簡單情況下工作方式:對於用libtool構建的庫使用_LTLIBRARIES宏。庫的名字要以lib開頭並以.la結尾(例如libmylib.la)。使用_SOURCES宏時,la前面的點(.)必須用下劃線(_)代替。對於要安裝到lib目錄下的mylib庫來說,它的宏可以這樣寫:
[python]運行automake之前,先運行libtoolize,會添加一些automake所需的文件。
7. 參考文獻
1. Gary Vaughan, Ben Elliston, Tom Tromey, Ian Taylor: “GNU Autoconf, Automake and Libtool”, New Riders Publishing, 2000, also available online at www.gnu.org
2. GNU Automake
http://www.gnu.org/software/automake/manual/automake.html
3. GNU Autoconf
http://www.gnu.org/software/autoconf/manual/autoconf-2.57/autoconf.html
4. Libtool
5. The GNU Coding Standards
http://www.gnu.org/prep/standards/standards.html