前言
本文根據《Autotools - A Practioner's Guide to GNU Autoconf, Automake, and Libtool》第一章翻譯整理,省略了部分語句。
本文
正如序言裡所講,GNU Autotools的目的是使得終端使用者的生活變得簡單,而不是維護者的。雖然如此,從長遠來看,作為一個工程管理者,使用Autotools會使你的工作變得簡單,儘管可能不是你所懷疑的理由。Autotools架構儘可能簡單,給出它所提供的功能。Autotools的真正目的是雙重的:它為你的使用者服務,並且使你的工程令人難以置信地可移植---甚至在你從沒測試過,安裝過或構建過你的代碼的系統上。
在這本書中,我會經常使用詞語Autotools的,雖然你在GNU歸檔中找不到使用這個詞的軟體包。我用這個詞表示下列三個GNU包,它們被社區認為是GNU編譯系統中的一部分
> Autoconf: 用於為工程產生配置指令碼;
> Automake: 用於簡化建立一致性和功能性Makefile的過程;
> Libtools: 用於為共用庫的可移植建立提供一個抽象;
其它構建工具,例如開源源碼包CMake和SCons,嘗試提供與Autotools相同功能的但是以一個更加使用者友善的方式。但是,這些工具試圖躲在圖形化使用者介面和指令碼構建者之後的功能,實際上最終使它們的功能變得較弱。
誰應該使用Autotools
如果你正在寫目標機是Unix或Linux的開源軟體,你應該絕對正使用GNU Autotools。即使是你在為Unix或Linux寫專有軟體,你將會極大地受益於它們。Autotools會提供你一個構建環境,允許你的工程成功地在你將來的版本或分支構建,使用幾乎沒有改變的構建指令碼。這是有用的,甚至你只是打算針對單一的Linux發行版,因為,說實話,你真的無法提前知道你的公司將來是否會希望你的軟體運行在其它平台上。
語言的選擇
在決定是否使用Autotools,你程式設計語言的選擇是另一個重要的因素。記住Autotools由GNU設計用於管理GNU工程。在GNU社區,有兩個因素決定一種電腦程式設計語言的重要性:
> 有沒有GNU包用這個語言編寫
> GNU編譯工具集是否支援這個語言
基於這兩個標準,Autotools為下列語言提供原生支援(由原生支援,我的意思是Autotools會在這些語言中編譯,連結,和運行源碼級特性檢查):
> C
> C++
> Objective C
> Fortran
> Fortran 77
> Erlang
因此,如果你想構建一個Java包,你可以配置Automake來這麼做(如我們在第8和第9章所見),但你不能要求Autoconf來編譯,連結,或運行基於Java的檢查,因為Autoconf根本就不原生地支援Java。然而,你可以找到Autoconf宏(在後續章節中,我將更為詳細地涉及)來提升Autoconf的能力,以管理用Java寫的工程的配置過程。
開源軟體開發人員正積極地在gcj編譯器和工具集方面進行工作,因此一些原生Java支援可能最終會被添加到Autoconf。但是截至到編寫這本書時,gcj仍然有些不成熟,目前很少有GNU包用Java編寫,因此問題對於GNU社區來講仍然不是至關重要。
產生你的軟體包編譯系統
GNU Autotools架構套件括三個主要的包:Autoconf,Automake,和Libtool。這些包中的工具可以產生依賴於實用軟體的代碼和來自gettext,m4,sed,make,和perl等其它包的功能。
對於Autotools,區分維護者的系統和終端使用者的系統是重要的。Autotools的設計目的指明,一個Autotools產生的編譯系統,應該緊緊依賴現成的並預先安裝在終端使用者機器上的工具。例如,維護者使用的機器建立一個分支需要Perl解譯器,但是一個終端使用者啟動並執行機器從發行分支包構建產品並不需要Perl。
一個必然的結果是,終端使用者的機器不需要安裝Autotools,一個終端使用者的系統只需要一個合理的符合POSIX標準版本的make和Bourne shell的一些變種,以執行產生的配置指令碼。當然,任何包也會需要編譯器,連結器,和其它被項目維護者認為必要的工具來講原代碼檔案轉換成可執行二進位程式,協助檔案和其它運行時資源。
如果你曾經下載,構建和安裝來自tarball(一種以.tar.gz, .tgz, .tar.bz2或其它擴充的壓縮歸檔檔案)的軟體,毫無疑問你知道整體的過程。它通常看上去像這樣:
$ gzip -cd hackers-delight-1.0.tar.gz | tar xvf -...$ cd hackers-delight-1.0$ ./configure && make...$ sudo make install...
Autoconf
儘管配置指令碼很長又很複雜,使用者只需要在執行時指定一些變數。大多數變數是簡單的選擇,關於組件,特性,和選項,例如:編譯系統在哪裡可以找到庫和標頭檔。最終產品我想安裝在哪裡。我想把哪些可選的組件構建進我的產品。
Autoconf產生的配置指令碼提供了一個通用的選項集,這對所有運行在POSIX系統上的可移植軟體項目都是重要的。這包括修改標準位置(一個我將在第2章中涉及的概念)的選項,也包括定義在configure.ac檔案的項目特定選項(我將在第3章中討論)。
Autoconf包提供多個程式,包括下面的:
> autoconf
> autoheader
> autom4te
> autoreconf
> autoscan
> autoupdate
> ifnames
autoconf
autoconf是個簡單地Bourne shell指令碼。它主要的功能是確保當前shell包含必要的功能來執行M4宏處理器(我將會在第3章討論Autoconf的M4使用)。該指令碼的剩餘部分解析命令列參數,並執行autom4te。
autoreconf
autoreconf工具執行每個工程所要求的autoconf,automake和libtool軟體包中的組態工具。autoreconf最大限度地減少報告時間戳記,特性,和項目狀態變化的重生量。它被寫為試圖鞏固現有維護者編寫的,基於指令碼的工具,以正確的順序運行所有需要的Autotools。你可以認為autoreconf是那種智能的Autotools引導工具。如果所有你有的是一個configure.ac檔案,你可以與運行autoreconf來執行所有你需要的工具,以正確的順序,從而使configure會被合適地產生。
autoheader
autoheader工具產生一種C/C++相容的標頭檔模板,根據configure.ac裡面的多種結構。這個檔案通常被稱為config.h.in。當終端使用者執行configure,配置指令碼根據config.h.in產生config.h。作為一個維護者,你將會使用autoheader來產生會包括在你的分支軟體包中的模板檔案。(我們會在第3章中詳細研究autoheader)。
autoscan
autoscan程式為新的工程產生一個預設的configure.ac檔案;它也可以檢查一個存在的Autotools工程的缺陷和機會以作增強。(我們將會在第3章和第8章中詳細套路autoscan)。autoscan對於一個使用不是基於Autotools的編譯系統作為一個工程的起始點是非常有用的,但是它也可能在提示增強一個現有基於Autotools工程的功能也是有用的。
autoupdate
autoupdate工具用於升級configure.ac或模板(.in)檔案,以匹配當前Autotools版本所支援的文法。
ifnames
ifnames程式是一個在通常情況下並未充分使用的小工具,它可以接受命令列中的源檔案名稱列表,顯示stdout裝置上的C前置處理器定義列表。這個工具被設計用於協助維護者決定放入configure.ac和Makefile.am檔案中的內容,以使得它們可移植。如果你的工程考慮寫成某種程度上可移植,ifnames可以協助你決定那些試圖可移植的部分在你源碼樹中的位置,給出潛在的可移植定義的名字。
autom4te
autom4te工具是一種為M4的智能緩衝封裝器,被其它大多數Autotools工具所使用。autom4te緩衝減少了相繼工具訪問configure.ac的時間多達30%。我並不想花費太多時間在autom4te(發音automate),因為它主要由內部的Autotools的使用。它工作的唯一標誌是autom4te.cache目錄會在你工程的頂層目錄出現,在你運行autoconf或autoreconf之後。
攜手合作
前面所列的工作中,autoconf和autoheader是項目維護者在產生configure指令碼時唯一會直接使用的,autoreconf是開發人員唯一需要直接執行的。圖1-1顯示了輸入檔案和autoconf與autoheader相互作用,產生相應的產品檔案。
注意:在本書中我都會使用圖1-1中的資料流圖。黑色盒子代表Autotools軟體包;白色盒子自代表產生對象。方角盒子是指令碼;圓角盒子是資料檔案。這裡大多數標籤的意義應該是明顯的,至少有一個需要解釋下:術語ac-vars是指Autoconf特定替換文本。很快我會解釋框滴漸層的aclocal.m4盒子。
這套工具的主要任務是產生一個配置指令碼,可以用來配置一個工程構建目錄。這個指令碼不會依賴Autotools它們自己;事實上,autoconf被設計為產生可以運行在所有類Unix平台和絕大多數Bourne shell變種上的配置指令碼。這意味著你可以用autoconf產生一個配置指令碼,然後可以在沒有安裝Autotools的機器上執行這個指令碼。
autoconf和autoheader程式要麼直接由使用者執行,要麼由autoreconf間接執行。它們從你工程中的configure.ac檔案和多種符合Autoconf的M4宏定義檔案中擷取輸入,使用autom4te維護緩衝資訊。autoconf產生一個叫configure的配置指令碼,一種非常容易移植的Bourne shell指令碼,使你的工程提供許多有用的配置能力。autoheader基於在configure.ac中的特定宏定義產生config.h.in模板。
Automake