2007年2月20日 星期二

autoconf手冊(一)

[本文轉載來源為:http://doc.sheup.com/linux/linux403.htm]

autoconf手冊(一)

Autoconf
Creating Automatic Configuration Scripts
Edition 2.13, for Autoconf version 2.13
December 1998
by David MacKenzie and Ben Elliston

--------------------------------------------------------------------------------
Permission is granted to make and distribute verbatim copies of this manual provided the copyright notice and this permission notice are preserved on all copies.

Permission is granted to copy and distribute modified versions of this manual under the conditions for verbatim copying, provided that the entire resulting derived work is distributed under the terms of a permission notice identical to this one.

Permission is granted to copy and distribute translations of this manual into another language, under the above conditions for modified versions, except that this permission notice may be stated in a translation approved by the Free Software Foundation.

只要版權聲明和本許可聲明保留在所有副本中,您就被授權製作和發行本手冊的原文副本。

只要整個最終派生工作按照與本手冊相同的許可聲明發行,您就被授權按照與發行原文相同的條件複製和發行本手冊的修改版本。

除了本許可聲明應該使用由基金會批准的譯文之外,您被授權按照與上述修改版本相同的條件複製和發行本手冊的其它語言的譯文。
--------------------------------------------------------------------------------

本文檔由王立翻譯。 1999.12.16

譯者在此聲明︰不對任何由譯文錯誤或者對譯文的誤解承擔任何責任。
--------------------------------------------------------------------------------

介紹
A physicist, an engineer, and a computer scientist were
discussing the nature of God. Surely a Physicist, said the
physicist, because early in the Creation, God made Light; and you
know, Maxwell''s equations, the dual nature of electro-magnetic
waves, the relativist consequences... An Engineer!, said the
engineer, because before making Light, God split the Chaos into
Land and Water; it takes a hell of an engineer to handle that big
amount of mud, and orderly separation of solids from
liquids... The computer scientist shouted: And the Chaos,
where do you think it was coming from, hmm?

---Anonymous

Autoconf是一個用於生成可以自動地配置軟體源代碼包以適應多種Unix類系統的 shell腳本的工具。由Autoconf生成的配置腳本在營運的時候與Autoconf是無關的,就是說配置腳本的用戶並不需要擁有Autoconf。

由Autoconf生成的配置腳本在營運的時候不需要用戶的手工干預;通常它們甚至不需要透過給出參數以確定系統的類型。相反,它們對套裝軟件可能需要的各種特徵進行獨立的測試。(在每個測試之前,它們列印一個單行的消息以說明它們正在進行的檢測,以使得用戶不會因為等待腳本執行完畢而焦躁。)因此,它們在混合系統或者從各種常見Unix變種定製而成的系統中工作的很好。沒有必要維護檔案以儲存由各個Unix變種、各個發行版本所支援的特徵的清單。

對於每個使用了Autoconf的套裝軟件,Autoconf從一個列舉了該套裝軟件需要的,或者可以使用的系統特徵的清單的模板檔案中生成配置腳本。在shell代碼識別並附應了一個被列出的系統特徵之後,Autoconf允許多個可能使用(或者需要)該特徵的套裝軟件共享該特徵。如果後來因為某些原因需要調整shell代碼,就只要在一個地方進行修改;所有的配置腳本都將被自動地重新生成以使用更新了的代碼。

Metaconfig包在目的上與Autoconf很相似,但它生成的腳本需要用戶的手工干預,在配置一個大的源代碼樹的時候這是十分不方便的。不象Metaconfig腳本,如果在編寫腳本時小心謹慎, Autoconf可以支援交叉編譯(cross-compiling)。

Autoconf目前還不能完成幾項使套裝軟件可移植的工作。其中包括為所有標準的目標自動創建``Makefile''檔案,包括在缺少標準庫函數和頭檔案的系統上提供替代品。目前正在為在將來添加這些特徵而工作。

對於在C程式中的#ifdef中使用的宏的名字,Autoconf施加了一些限制(參見預處理器符號索引)。

Autoconf需要GNU m4以便於生成腳本。它使用了某些UNIX版本的m4 所不支援的特徵。它還會超出包括GNU m4 1.0在內的某些m4版本的內部限制。你必須使用GNU m4的1.1版或者更新的版本。使用1.3版或者更新的版本將比1.1 或1.2版快許多。

關於從版本1中升級的詳情,參見從版本1中升級。關於Autoconf的開發歷史,參見Autoconf的歷史。對與Autoconf有關的常見問題的回答,參見關於Autoconf的問題。

把守關口於Autoconf的建議和bug報告發送到bug-gnu-utils@prep.ai.mit.edu。請把你透過營運``autoconf --version''而獲得的Autoconf的版本號包括在內。

創建configure腳本
由Autoconf生成的配置腳本通常被稱為configure。在營運的時候,configure 創建一些檔案,在這些檔案中以適當的值替換配置參數。由configure創建的檔案有︰

一個或者多個``Makefile''檔案,在包的每個次目錄中都有一個(參見 Makefile中的替換);
有時創建一個C頭檔案,它的名字可以被配置,該頭檔案包含一些#define命令(參見配置頭檔案);
一個名為``config.status''的shell腳本,在營運時,它將重新創建上述檔案。(參見重新創建一個配置);
一個名為``config.cache''的shell腳本,它儲存了許多測試的營運結果(參見緩存檔案);
一個名為``config.log''的檔案,它包含了由編譯器生成的許多消息,以便於在configure出現錯誤時進行調試。
為了使用Autoconf創建一個configure腳本,你需要編寫一個Autoconf的輸入檔案 ``configure.in''並且對它營運autoconf。如果你自行編寫了特徵測試以補充 Autoconf所提供的測試,你可能還要編寫一個名為``aclocal.m4''的檔案和一個名為 ``acsite.m4''的檔案。如果你使用了包含#define指令的C頭檔案,你可能還要編寫``acconfig.h'',並且你需要與套裝軟件一同發布由Autoconf生成的檔案 ``config.h.in''。

下面是一個說明了在配置中使用的檔案是如何生成的圖。營運的程式都標以後綴``*''。可能出現的檔案被方括號(``[]'')括起來。autoconf和autoheader 還讀取安裝了的Autoconf宏檔案(透過讀取``autoconf.m4'')。

在準備發布套裝軟件的過程中使用的檔案︰

你的源檔案 --> [autoscan*] --> [configure.scan] --> configure.in

configure.in --. .------> autoconf* -----> configure
+---+
[aclocal.m4] --+ ``---.
[acsite.m4] ---''
+--> [autoheader*] -> [config.h.in]
[acconfig.h] ----.
+-----''
[config.h.top] --+
[config.h.bot] --''

Makefile.in -------------------------------> Makefile.in

在配置套裝軟件的過程中使用的檔案︰

.-------------> config.cache
configure* ------------+-------------> config.log

[config.h.in] -. v .-> [config.h] -.
+--> config.status* -+ +--> make*
Makefile.in ---'' ``-> Makefile ---''

編寫``configure.in''
為了為套裝軟件創建configure腳本,需要編寫一個名為``configure.in'' 的檔案,該檔案包含了對那些你的套裝軟件需要或者可以使用的系統特徵進行測試的Autoconf宏的調用。現有的Autoconf宏可以檢測許多特徵; 對於它們的描述可以參見現有的測試。對於大部分其他特徵,你可以使用Autconf模板宏以創建定製的測試;關於它們的詳情,參見 編寫測試。對於特別古怪或者特殊的特徵,``configure.in'' 可能需要包含一些手工編寫的shell命令。程式autoscan可以為你編寫``configure.in'' 開個好頭(詳情請參見用autoscan創建``configure.in'')。

除了少數特殊情況之外,在``configure.in''中調用Autoconf宏的順序並不重要。在每個``configure.in''中,必須在進行任何測試之間包含一個對AC_INIT的調用,並且在結尾處包含一個對AC_OUTPUT的調用(參見創建輸出檔案)。此外,有些宏要求其他的宏在它們之前被調用,這是因為它們透過檢查某些變量在前面設定的值以決定作些什麼。這些宏在獨立的說明中給出(參見現有的測試),而且如果沒有按照順序調用宏,在生成configure時會向你發出警告。

為了提升一致性,下面是調用Autoconf宏的推薦順序。通常,在本清單中靠後的項目倚賴於表中靠前的項目。例如,庫函數可能受到typedefs和庫的影響。

AC_INIT(file)
checks for programs
checks for libraries
checks for header files
checks for typedefs
checks for structures
checks for compiler characteristics
checks for library functions
checks for system services
AC_OUTPUT([file...])

最好讓每個宏調用在``configure.in''中佔據單獨的一行。大部分宏並不添加額外的新行;它們倚賴於在宏調用之後的新行以結束命令。這種方法使得生成的configure腳本在不必添加大量的空行的情況下比較容易閱讀。在宏調用的同一行中設定shell變量通常是安全的,這是因為shell允許出現沒有用新行間隔的賦值。

在調用帶參數的宏的時候,在宏名和左括號之間不能出現任何空格。如果參數被m4 引用字符``[''和``]''所包含,參數就可以多於一行。如果你有一個長行,比如說一個檔案名清單,你通常可以在行的結尾使用反斜線以便在邏輯上把它與下一行進行連接(這是由shell實現的,Autoconf對此沒有進行任何特殊的處理)。

有些宏處理兩種情況︰如果滿足了某個給定的條件就做什麼,如果沒有滿足某個給定的條件就做什麼。在有些地方,你可能希望在條件為真的情況下作些事,在為假時什麼也不作。反之亦然。為了忽略為真的情況,把空值作為參數action-if-found傳遞給宏。為了忽略為假的情況,可以忽略包括前面的逗號在內的宏的參數action-if-not-found。

你可以在檔案``configure.in''中添加註釋。註釋以m4預定義宏dnl 開頭,該宏丟棄在下一個新行之前的所有文本。這些註釋並不在生成的configure腳本中出現。例如,把下面給出的行作為檔案``configure.in''的開頭是有好處的︰

dnl Process this file with autoconf to produce a configure script.

用autoscan創建``configure.in''
程式autoscan可以幫助你為套裝軟件創建``configure.in''檔案。如果在命令行中給出了目錄, autoscan就在給定目錄及其次目錄樹中檢查源檔案,如果沒有給出目錄,就在當前目錄及其次目錄樹中進行檢查。它搜索源檔案以尋找一般的移植性問題並創建一個檔案``configure.scan'',該檔案就是套裝軟件的``configure.in''預備版本。

在把``configure.scan''改名為``configure.in''之前,你應該手工地檢查它;它可能需要一些調整。 autoscan偶爾會按照相對於其他宏的錯誤的順序輸出宏,為此autoconf將給出警告;你需要手工地移動這些宏。還有,如果你希望包使用一個配置頭檔案,你必須添加一個對AC_CONFIG_HEADER的調用。(參見配置頭檔案)。可能你還必須在你的程式中修改或者添加一些#if 指令以使得程式可以與Autoconf合作。(關於有助於該工作的程式的詳情,參見 用ifnames列舉條件)。

autoscan使用一些數據檔案,它們是隨發布的Autoconf宏檔案一起安裝的,以便當它在包中的源檔案中發現某些特殊符號時決定輸出那些宏。這些檔案都具有相同的格式。每一個都是由符號、空白和在符號出現時應該輸出的Autoconf 宏。以``#''開頭的行是註釋。

只有在你安裝了Perl的情況下才安裝autoscan。 autoscan接受如下選項︰

--help
列印命令行選項的概述並且退出。
--macrodir=dir
在目錄dir中,而不是在缺省安裝目錄中尋找數據檔案。你還可以把環境變量AC_MACRODIR設定成一個目錄;本選項將覆蓋該環境變量。
--verbose
列印它檢查的檔案名稱以及在這些檔案中發現的可能感興趣的符號。它的輸出可能很冗長。
--version
列印Autoconf的版本號並且退出。
用ifnames列舉條件
在為一個套裝軟件編寫``configure.in''時,ifnames可以提供一些幫助。它列印出包已經在C預處理條件中使用的標識符。如果包已經被設定得具備了某些可移植性,該程式可以幫助你找到configure所需要進行的檢查。它可能有助於補足由autoscan生成的``configure.in''中的某些缺陷。(參見用autoscan創建``configure.in'')。

ifnames掃描所有在命令行中給出的C源代碼檔案(如果沒有給出,就掃描標準輸入)並且把排序後的、由所有出現下這些檔案中的#if、#elif、#ifdef或者#ifndef 命令中的標識符清單輸出到標準輸出中。它為每個標識符輸出單獨的一行,行中標識符之後是一個由空格分隔的、使用了該標識符的檔案名清單。

ifnames接受如下選項︰

--help
-h
列印命令行選項的概述並且退出。
--macrodir=dir
-m dir
在目錄dir中,而不是缺省安裝目錄中尋找Autoconf宏檔案。僅僅被用於獲取版本號。你還可以把環境變量AC_MACRODIR設定成一個目錄;本選項將覆蓋該環境變量。
--version
列印Autoconf的版本號並且退出。
用autoconf創建configure
為了從``configure.in''生成configure,不帶參數地營運程式autoconf。 autoconf用使用Autoconf宏的m4宏處理器處理``configure.in''。如果你為autoconf提供了參數,它讀入給出的檔案而不是``configure.in''並且把配置腳本輸出到標準輸出而不是configure。如果你給autoconf以參數``-'',它將從標準輸入,而不是``configure.in''中讀取並且把配置腳本輸出到標準輸出。

Autoconf宏在幾個檔案中定義。在這些檔案中,有些是與Autconf一同發布的;autoconf首先讀入它們。而後它在包含了發布的Autoconf宏檔案的目錄中尋找可能出現的檔案``acsite.m4'',並且在當前目錄中尋找可能出現的檔案``aclocal.m4''。這些檔案可以包含你的站點的或者包自帶的Autoconf宏定義(詳情請參見 編寫宏)。如果宏在多於一個由autoconf讀入了的檔案中被定義,那麼後面的定義將覆蓋前面的定義。

autoconf接受如下參數︰

--help
-h
輸出命令行選項的概述並且退出。
--localdir=dir
-l dir
在目錄dir中,而不是當前目錄中尋找包檔案``aclocal.m4''。
--macrodir=dir
-m dir
在目錄dir中尋找安裝的宏檔案。你還可以把環境變量AC_MACRODIR設定成一個目錄;本選項將覆蓋該環境變量。
--version
列印Autoconf的版本號並且退出。
用autoreconf更新configure腳本
如果你有大量由Autoconf生成的configure腳本,程式autoreconf可以保留你的一些工作。它重複地營運autoconf(在適當的情況下還營運autoheader)以重新創建以當前目錄為根的目錄樹的Autoconf configure腳本和配置頭檔案。在缺省情況下,它只重新創建那些比對應的 ``configure.in''或者(如果出現)``aclocal.m4''要舊的檔案。由於在檔案沒有被改變的情況下, autoheader並不改變它的輸出檔案的時間標記(timestamp)。這是為了使工作量最小化,修改時間標記是不必要的。如果你安裝了新版本的Autoconf,你可以以選項``--force''調用autoreconf而重新創建 所有的檔案。

如果你在調用autoreconf時給出選項``--macrodir=dir''或者 ``--localdir=dir'',它將把它們傳遞給autoconf和autoheader (相對路徑將被正確地調整)。

在同一個目錄樹中,autoreconf不支援兩個目錄作為同一個大包的一部分(共享``aclocal.m4''和 ``acconfig.h''),也不支援每個目錄都是獨立包(每個目錄都有它們自己的``aclocal.m4''和 ``acconfig.h'')。如果你使用了``--localdir'',它假定所有的目錄都是同一個包的一部分。如果你沒有使用 ``--localdir'',它假定每個目錄都是一個獨立的包,這條限制在將來可能被取消。

關於在configure腳本的源檔案發生變化的情況下自動地重新創建它們的``Makefile''規則的細節,參見自動地重新創建。這種方法正確地處理了配置頭檔案模板的時間標記,但並不傳遞``--macrodir=dir''或者``--localdir=dir''。

autoreconf接受如下選項︰

--help
-h
列印命令行選項的概述並且退出。
--force
-f
即使在``configure''腳本和配置頭檔案比它們的輸入檔案(``configure.in'',如果出現了``aclocal.m4'',也包括它)更新的時候,也要重新創建它們。
--localdir=dir
-l dir
讓autoconf和autoheader在目錄dir中,而不是在每個包含``configure.in'' 的目錄中尋找包檔案``aclocal.m4''和(僅指autoheader)``acconfig.h'' (但不包括``file.top''和``file.bot'')。
--macrodir=dir
-m dir
在目錄dir中,而不是缺省安裝目錄中尋找Autoconf宏檔案。你還可以把環境變量 AC_MACRODIR設定成一個目錄;本選項將覆蓋該環境變量。
--verbose
列印autoreconf營運autoconf(如果適當,還有autoheader)的每個目錄的目錄名。
--version
列印Autoconf的版本號並且退出。
初始化和輸出檔案
Autoconf生成的configure腳本需要一些關於如何進行初始化,諸如如何尋找包的源檔案,的訊息;以及如何生成輸出檔案的訊息。本節敘述如何進行初始化和創建輸出檔案。

尋找configure的輸入檔案
所有configure腳本在作任何其他事情之前都必須調用AC_INIT。此外唯一必須調用的宏是 AC_OUTPUT(參見創建輸出檔案)。
宏︰ AC_INIT (unique-file-in-source-dir)
處理所有命令行參數並且尋找源代碼目錄。unique-file-in-source-dir是一些在包的源代碼目錄中檔案; configure在目錄中檢查這些檔案是否存在以確定該目錄是否包含源代碼。人們可能偶爾會用``--srcdir''給出錯誤的目錄;這是一種安全性檢查。詳情請參見營運configure腳本。

對於需要手工配置或者使用install程式的包來說,雖然在缺省源代碼位置在大部分情況下看起來是正確的,包還是可能需要透過調用AC_CONFIG_AUX_DIR來告訴 configure到那裡去尋找一些其他的shell腳本。
宏︰ AC_CONFIG_AUX_DIR (dir)
在目錄dir中使用``install-sh''、``config.sub''、``config.guess''和 Cygnus configure配置腳本。它們是配置中使用的輔助檔案。dir既可以是絕對路徑,也可以是相對於``srcdir''的相對路徑。缺省值是在``srcdir''或者 ``srcdir/..''或者``srcdir/../..''中首先找到``install-sh'' 的目錄。不對其他檔案進行檢查,以便使AC_PROG_INSTALL不會自動地發布其他輔助檔案。它還要檢查``install.sh'',但因為有些make程式包含了在沒有``Makefile''的情況下從``install.sh''中創建``install''的規則,所以那個名字過時了。

創建輸出檔案
每個Autoconf生成的configure腳本必須以對AC_OUTPUT的調用結尾。它是一個創建作為配置結果的``Makefile''以及其他一些可能的檔案的宏。此外唯一必須調用的宏是AC_INIT (參見尋找configure的輸入檔案)。
宏︰ AC_OUTPUT ([file... [, extra-cmds [, init-cmds]]])創建輸出檔案。


在``configure.in''的末尾調用本宏一次。參數file...是一個以空格分隔的輸出檔案的清單;它可能為空。本宏透過從一個輸入檔案(缺省情況下名為``file.in'')中複製,並替換輸出變量的值以創建每個給出的``file''。關於使用輸出變量的詳情,請參見Makefile中的替換。關於創建輸出變量的詳情,請參見設定輸出變量。如果輸出檔案所在的目錄不存在,本宏將創建該目錄(但不會創建目錄的父目錄)。通常,``Makefile''是按照這種模式創建的,但其他檔案,例如``.gdbinit'',也可以這樣創建。

如果調用了AC_CONFIG_HEADER、AC_LINK_FILES或者AC_CONFIG_SUBDIRS,本宏也將創建出現下它們的參數中的檔案。

一個典型的對AC_OUTPUT調用如下︰

AC_OUTPUT(Makefile src/Makefile man/Makefile X/Imakefile)

你可以透過在file之後添加一個用冒號分隔的輸入檔案清單以自行設定輸入檔案名。例如︰

AC_OUTPUT(Makefile:templates/top.mk lib/Makefile:templates/lib.mk)
AC_OUTPUT(Makefile:templates/vars.mk:Makefile.in:templates/rules.mk)

這樣做可以使得你的檔案名能夠被MS-DOS接受,或者可以把模板檔案(boilerplate)添加到檔案的開頭或者結尾。

如果你給出了extra-cmds,那麼這些命令將被插入到``config.status''中以便在``config.status'' 完成了其他的所有處理之後營運extra-cmds。如果給出了init-cmds,它們就被插入 extra-cmds之前,並且在configure中將對它們進行shell變量、命令和反斜線替換。你可以用 init-cmds把變量從configure中傳遞到extra-cmds。如果調用了 AC_OUTPUT_COMMANDS,在其中給出的命令將緊貼在由本宏給出的命令之前營運。

宏︰ AC_OUTPUT_COMMANDS (extra-cmds [, init-cmds])
指定在``config.status''末尾營運的附加的shell命令,以及用於初始化來自於configure 的所有變量的shell命令。本宏可以被調用多次。下面是一個不太實際的例子︰

fubar=27
AC_OUTPUT_COMMANDS([echo this is extra $fubar, and so on.], fubar=$fubar)
AC_OUTPUT_COMMANDS([echo this is another, extra, bit], [echo init bit])

如果你在次目錄中營運make,你應該透過使用make變量MAKE來營運它。 make的大部分版本把MAKE設定成make的程式名以及它所需要的任何選項。(但許多版本並沒有把在命令行中設定的變量的值包括進來,因此它們沒有被自動地傳遞。)一些老版本的 make並不設定這個變量。以下的宏使你可以在這些版本上使用它。
宏︰ AC_PROG_MAKE_SET
如果make預定義了變量MAKE,把輸出變量SET_MAKE定義為空。否則,把 SET_MAKE定義成``MAKE=make''。為SET_MAKE調用AC_SUBST。

為了使用這個宏,在每個其他的、營運MAKE的目錄中的``Makefile.in''添加一行︰

@SET_MAKE@

Makefiles中的替換
發布版本中每個包含了需要被編譯或者被安裝的檔案的目錄都應該含有一個檔案``Makefile.in'', configure將利用它在那個目錄中創建一個``Makefile''。為了創建``Makefile'',configure進行一個簡單的變量替換︰用configure 為``@variable@''選取的值,在``Makefile.in''中對它們進行替換。按照這種模式被替換到輸出檔案中的變量被稱為輸出變量。在configure中,它們是普通的shell變量。為了讓configure把特殊的變量替換到輸出檔案中,必須把那個變量的名字作為調用 AC_SUBST的參數。其他變量的任何``@variable@''都保持不變。關於使用AC_SUBST創建輸出變量的詳情,請參見設定輸出變量。

使用configure腳本的軟體應該發布檔案``Makefile.in'',而不是``Makefile'';這樣,用戶就可以在編譯它之前正確地為本地系統進行配置了。

關於應該把哪些東西放入``Makefile''的詳情,請參見GNU編碼標準中的``Makefile慣例''。

預定義輸出變量
有些輸出變量是由Autoconf宏預定義的。一部分Autoconf宏設定一些附加的輸出變量,這些變量在對這些宏的描述中被說明。關於輸出變量的完整清單,參見輸出變量索引。下面是每個預定義變量所包含的內容。關於變量名以``dir''結尾的變量,參見GNU編碼標準中的 ``為安裝目錄而提供的變量''。
變量︰ bindir
用於安裝由用戶營運的可執行檔案的目錄。
變量︰ configure_input
一個用於說明檔案是由configure自動生成的,並且給出了輸入檔案名的註釋。 AC_OUTPUT在它創建的每個``Makefile''檔案的開頭添加一個包括了這個變量的註釋行。對於其他檔案,你應該在每個輸入檔案開頭處的註釋中引用這個變量。例如,一個輸入shell腳本應該以如下行開頭︰

#! /bin/sh
# @configure_input@

這一行的存在也提醒了人們在編輯這個檔案之後需要用configure進行處理以使用它。

變量︰ datadir
用於安裝只讀的與架構無關的數據的目錄。
變量︰ exec_prefix
與架構有關的檔案的安裝前綴。
變量︰ includedir
用於安裝C頭檔案的目錄。
變量︰ infodir
用於安裝Info格式文檔的目錄。
變量︰ libdir
用於安裝目標代碼庫的目錄。
變量︰ libexecdir
用於安裝由其他程式營運的可執行檔案的目錄。
變量︰ localstatedir
用於安裝可以被修改的單機數據的目錄。
變量︰ mandir
用於安裝man格式的文檔的頂層目錄。
變量︰ oldincludedir
用於安裝由非gcc編譯器使用的C頭檔案的目錄。
變量︰ prefix
與架構無關的檔案的安裝前綴。
變量︰ sbindir
用於安裝由系統管理員營運的可執行檔案的目錄。
變量︰ sharedstatedir
用於安裝可以修改的、與架構無關的數據的目錄。
變量︰ srcdir
包含了由``Makefile''使用的源代碼的目錄。
變量︰ sysconfdir
用於安裝只讀的單機數據的目錄。
變量︰ top_srcdir
包的頂層源代碼目錄。在目錄的頂層,它與srcdir相同。
變量︰ CFLAGS
為C編譯器提供的調試和優化選項。如果在營運configure時,沒有在環境中設定它,就在你調用AC_PROG_CC的時候設定它的缺省值(如果你沒有調用AC_PROG_CC,它就為空)。 configure在編譯程式以測試C的特徵時,使用本變量。
變量︰ CPPFLAGS
為C預處理器和編譯器提供頭檔案搜索目錄選項(``-Idir'')以及其他各種選項。如果在營運 configure時,在環境中沒有設定本變量,缺省值就是空。configure在編譯或者預處理程式以測試C的特徵時,使用本變量。
變量︰ CXXFLAGS
為C++編譯器提供的調試和優化選項。如果在營運configure時,沒有在環境中設定本變量,那麼就在你調用AC_PROG_CXX時設定它的缺省值(如果你沒有調用AC_PROG_CXX,它就為空)。 configure在編譯程式以測試C++的特徵時,使用本變量。
變量︰ FFLAGS
為Fortran 77編譯器提供的調試和優化選項。如果在營運configure時,在環境中沒有設定本變量,那麼它的缺省值就在你調用AC_PROG_F77時被設定(如果你沒有調用AC_PROG_F77,它就為空)。 configure在編譯程式以測試Fortran 77的特徵時,使用本變量。
變量︰ DEFS
傳遞給C編譯器的``-D''選項。如果調用了AC_CONFIG_HEADER,configure就用 ``-DHAVE_CONFIG_H''代替``@DEFS@''(參見配置頭檔案)。在configure進行它的測試時,本變量沒有被定義,只有在創建輸出檔案時候才定義。關於如何檢查從前的測試結果,請參見設定輸出變量。
變量︰ LDFLAGS
為連接器提供的Stripping(``-s'')選項和其他各種選項。如果在營運configure時,在環境中沒有設定本變量,它的缺省值就是空。 configure在連接程式以測試C的特徵時使用本變量。
變量︰ LIBS
傳遞給連接器的``-l''和``-L''選項。

創建目錄
你可以支援從一個套裝軟件的一份源代碼拷貝中為多種架構同時進行編譯的功能。為每種架構生成的目標檔案都在它們自己的目錄中儲存。

為了支援這個功能,make用變量VPATH來尋找儲存在源代碼目錄中的檔案。 GNU make和其他大部分近來的make程式都可以這樣做。老版本的make 程式不支援VPATH;在使用它們的時候,源代碼必須與目標代碼處於同一個目錄。

為了支援VPATH,每個``Makefile.in''檔案都應該包含下列兩行︰

srcdir = @srcdir@
VPATH = @srcdir@

不要把VPATH設定成其他變量的值,比如說``VPATH = $(srcdir)'',這是因為某些版本的make並不對VPATH的值進行變量替換。

在configure生成``Makefile''的時候,它用正確的值對srcdir進行替換。

除非在隱含規則中,不要使用make變量$<,它将被展开成到源代码目录的文件的路径(通过VPATH找到的)。(诸如``.c.o''的隐含规则用于说明如何从``.c'' 文件创建``.o''文件)有些版本的make在隐含规则中不设置$<;它们被展开成空值。

``Makefile''命令行總是應該透過使用前綴``$(srcdir)/''來引用源代碼檔案。例如︰

time.info: time.texinfo
$(MAKEINFO) $(srcdir)/time.texinfo

自動地重新創建
你可以在包的頂層目錄中的``Makefile.in''檔案中添加如下的規則,以使得在你更新了配置檔案之後可以自動地更新配置訊息。這個例子包括了所有可選的檔案,例如``aclocal.m4''和那些與配置頭檔案有關的檔案。從``Makefile.in''規則中忽略所有你的所不需要的檔案。

因為VPATH機製的限制,應該包含``${srcdir}/''前綴。

在重新創建不改變``config.h.in''和``config.h''的內容的情況下,就不會改變這兩個檔案的時間標記,因此需要``stamp-''檔案。這個特徵避免了不必要的重新編譯工作。你應該把檔案``stamp-h.in'' 包含在你的包的發布中,以便make能夠把``config.h.in''看作是更新了的檔案。在一些老的BSD系統中,touch或者任何可能導致空檔案的命令不會更改時間標記,所以使用諸如echo 之類的命令。

${srcdir}/configure: configure.in aclocal.m4
cd ${srcdir} && autoconf

# autoheader might not change config.h.in, so touch a stamp file.
${srcdir}/config.h.in: stamp-h.in
${srcdir}/stamp-h.in: configure.in aclocal.m4 acconfig.h
config.h.top config.h.bot
cd ${srcdir} && autoheader
echo timestamp > ${srcdir}/stamp-h.in

config.h: stamp-h
stamp-h: config.h.in config.status
./config.status

Makefile: Makefile.in config.status
./config.status

config.status: configure
./config.status --recheck

此外,你應該把``echo timestamp > stamp-h''作為extra-cmds參數傳遞給AC_OUTPUT,以便``config.status''能夠確認``config.h''是更新了的。關於AC_OUTPUT的詳情,請參見 創建輸出檔案。

關於處理與配置相關的倚賴性問題的更多例子,請參見重新創建一個配置。

配置頭檔案
在包測試的C預處理器符號比較多的時候,用於把``-D''傳遞給編譯器的命令行就會變得很長。這導致了兩個問題。一個是透過觀察尋找make輸出中的錯誤變得困難了。更嚴重的是,命令行可能超過某些作業系統的長度限制。作為把``-D''選項傳遞給編譯器的替代辦法,configure 腳本可以創建一個包含了``#define''指令的C頭檔案。宏AC_CONFIG_HEADER 選擇了這種輸出。它應該在AC_INIT之後立即調用。

包應該在引入其他任何頭檔案之前``#include''配置頭檔案,以防止出現聲明中的不一致性(例如,配置頭檔案可能重定義了const)。使用``#include '' 並且把選項``-I.''(或者是``-I..'';或者是任何包含``config.h'' 的目錄)傳遞給C編譯器,而不是使用``#include ""config.h""''。按照這種模式,即使源代碼自行進行配置(可能是創建發布版本),其他創建目錄也可以在沒有找到``config.h''的情況下,從源代碼目錄進行配置。
宏︰ AC_CONFIG_HEADER (header-to-create ...)
使得AC_OUTPUT創建出現下以空格分隔的清單header-to-create中的檔案,以包含C預處理器#define語句,並在生成的檔案中用``-DHAVE_CONFIG_H'' ,而不是用DEFS的值,替換``@DEFS@''。常用在header-to-create 中的檔案名是``config.h''。

如果header-to-create給出的檔案已經存在並且它的內容和AC_OUTPUT將要生成的內容完全一致,這些檔案就保持不變。這樣做就使得對配置的某些修改不會導致對倚賴於頭檔案的目標檔案進行不必要的重新編譯。

通常輸入檔案被命名為``header-to-create.in'';然而,你可以透過在header-to-create 之後添加由冒號分隔的輸入檔案清單來覆蓋原輸入檔案名。例︰

AC_CONFIG_HEADER(defines.h:defines.hin)
AC_CONFIG_HEADER(defines.h:defs.pre:defines.h.in:defs.post)

這樣做使得你的檔案名能夠被MS-DOS所接受,或者可以把模板(boilerplate)添加到檔案的開頭和/或結尾。
配置頭檔案模板
你的發布版本應該包含一個如你所望的最終的頭檔案那樣的模板檔案,它包括註釋、以及#define 語句的缺省值。例如,假如你的``configure.in''進行了下列調用︰

AC_CONFIG_HEADER(conf.h)
AC_CHECK_HEADERS(unistd.h)

那麼你就應該在``conf.h.in''中包含下列代碼。在含有``unistd.h''的系統中,configure應該把0改成1。在其他系統中,這一行將保持不變。

/* Define as 1 if you have unistd.h. */
#define HAVE_UNISTD_H 0

如果你的代碼使用#ifdef而不是#if來測試配置選項,缺省值就可能是取消對一個變量的定義而不是把它定義成一個值。在含有``unistd.h''的系統中,configure將修改讀入的第二行 ``#define HAVE_UNISTD_H 1''。在其他的系統中,(在系統預定義了那個符號的情況下) configure將以註釋的模式排除這一行。

/* Define if you have unistd.h. */
#undef HAVE_UNISTD_H

用autoheader創建``config.h.in''
程式autoheader可以創建含有C的``#define''語句的模板檔案以供configure使用。如果``configure.in''調用了AC_CONFIG_HEADER(file),autoheader就創建 ``file.in'';如果給出了多檔案參數,就使用第一個檔案。否則,autoheader就創建 ``config.h.in''。

如果你為autoheader提供一個參數,它就使用給出的檔案而不是``configure.in'',並且把頭檔案輸出到標準輸出中去,而不是輸出到``config.h.in''。如果你把``-''作為參數提供給autoheader ,它就從標準輸入中,而不是從``configure.in''中讀出,並且把頭檔案輸出到標準輸出中去。

autoheader掃描``configure.in''並且找出它可能要定義的C預處理器符號。它從一個名為 ``acconfig.h''的檔案中複製註釋、#define和#undef語句,該檔案與Autoconf一同發布並且一同安裝。如果當前目錄中含有``acconfig.h''檔案,它也會使用這個檔案。如果你用AC_DEFINE 定義了任何附加的符號,你必須在創建的那個``acconfig.h''檔案中包含附加的符號。對於由 AC_CHECK_HEADERS、AC_CHECK_FUNCS、AC_CHECK_SIZEOF或者 AC_CHECK_LIB定義的符號,autoheader生成註釋和#undef語句,而不是從一個檔案中複製它們,這是因為可能的符號是無限的。

autoheader創建的檔案包含了大部分#define和#undef語句,以及相關的註釋。如果``./acconfig.h''包含了字元串``@TOP@'',autoheader就把在包含``@TOP@'' 的行之前的所有行複製到它生成的檔案的開頭。相似地,如果``./acconfig.h''包含了字元串``@BOTTOM@'', autoheader就把那一行之後的所有行複製到它生成的檔案的末尾。這兩個字元串的任何一個都可以被忽略,也可以被同時忽略。

產生相同效果的另一種辦法是在當前目錄中創建檔案``file.top''(通常是``config.h.top'')和/或檔案``file.bot''。如果它們存在,autoheader就把它們分別複製到它的輸出的開頭和末尾。不鼓勵使用它們是因為它們的檔案名含有兩個點,並因此不能在MS-DOS中儲存;它們在目錄中多創建了兩個檔案。但如果你給出選項``--localdir=dir''以使用在其他目錄中的``acconfig.h'',它們就為你提供了一種把定製的模板(boilerplate)放入各個獨立的``config.h.in''中的模式。

autoheader接受如下選項︰

--help
-h
列印對命令行選項的概述並且退出。
--localdir=dir
-l dir
在目錄dir中,而不是在當前目錄中,尋找包檔案``aclocal.m4''和``acconfig.h'' (但不包括``file.top''和``file.bot'')。
--macrodir=dir
-m dir
在目錄dir中尋找安裝的宏檔案和``acconfig.h''。你還可以把環境變量AC_MACRODIR 設定成一個目錄;本選項將覆蓋該環境變量。
--version
列印Autoconf的版本號並且退出。
在次目錄中配置其它包
在大多數情況下,調用AC_OUTPUT足以在次目錄中生成``Makefile''。然而,控制了多於一個獨立包的configure腳本可以使用AC_CONFIG_SUBDIRS來為每個次目錄中的其他包營運 configure腳本。
宏︰ AC_CONFIG_SUBDIRS (dir ...)
使得AC_OUTPUT在每個以空格分隔的清單中給出的次目錄dir中營運configure。如果沒有發現某個給出的dir,不會作為錯誤報告,所以一個configure腳本可以配置一個大的源代碼樹中出現的任何一個部分。如果在給出的dir中包含了``configure.in'',但沒有包含 configure,就使用由AC_CONFIG_AUXDIR找到的Cygnus configure腳本。

用與本configure腳本完全相同的命令行參數調用次目錄中的configure腳本,如果需要,會有較小的修改(例如,為緩沖檔案或者源代碼目錄調整相對路徑)。本宏還把輸出變量subdirs設定成目錄清單``dir...''。``Makefile''規則可以使用該變量以確定需要進入那些次目錄。這個宏可以多次調用。

缺省的前綴
在缺省狀態下,configure把它所安裝的檔案的前綴設定成``/usr/local''。 configure的用戶可以透過選項``--prefix''和``--exec-prefix''選擇一個不同的前綴。有兩種模式修改缺省的行為︰在創建configure時,和營運configure時。

有些套裝軟件在缺省情況下可能需要安裝到``/usr/local''以外的目錄中。為此,使用宏AC_PREFIX_DEFAULT。
宏︰ AC_PREFIX_DEFAULT (prefix)
把缺省的安裝前綴設定成prefix,而不是``/usr/local''。

對於用戶來說,讓configure根據它們已經安裝的相關程式的位置來猜測安裝前綴,可能會帶來方便。如果你希望這樣做,你可以調用AC_PREFIX_PROGRAM。
宏︰ AC_PREFIX_PROGRAM (program)
如果用戶沒有給出安裝前綴(使用選項``--prefix''),就按照shell的模式,在PATH中尋找 program,從而猜出一個安裝前綴。如果找到了program,就把前綴設定成包含program 的目錄的父目錄;否則,就不改變在``Makefile.in''中給定的前綴。例如,如果program是 gcc,並且PATH包括了``/usr/local/gnu/bin/gcc'',就把前綴設定為 ``/usr/local/gnu''。


configure中的版本號
以下的宏為configure腳本管理版本號。使用它們是可選的。
宏︰ AC_PREREQ (version)
確保使用的是足夠新的Autoconf版本。如果用於創建configure的Autoconf的版本比version 要早,就在標準錯誤輸出列印一條錯誤消息並不會創建configure。例如︰

AC_PREREQ(1.8)

如果你的``configure.in''倚賴於在不同Autoconf版本中改變了的、不明顯的行為,本宏就是有用的。如果它僅僅是需要近來增加的宏,那麼AC_PREREQ就不太有用,這是因為程式autoconf已經告訴了用戶那些宏沒有被找到。如果``configure.in''是由一個在提供AC_PREREQ之前的更舊的 Autoconf版本處理的,也會發生同樣的事。

宏︰ AC_REVISION (revision-info)
把刪除了任何美元符或者雙引號的修訂標記(revision stamp)複製到configure腳本中。本宏使得你的從``configure.in''傳遞到configure的修訂標記不會在你提交(check in) configure的時候被RCS或者CVS修改。你可以容易地決定一個特定的configure 對應與``configure.in''的哪個修訂版。

把本宏放在AC_INIT之前是個好主意,它可以使修訂號接近``configure.in''和configure 的開頭。為了支援你這樣做,AC_REVISION就像configure通常作的那樣,以 ``#! /bin/sh''開始它的輸出。

例如,在``configure.in''中這一行為︰
AC_REVISION($Revision: 1.30 $)dnl
在configure中產生了︰
#! /bin/sh # From configure.in Revision: 1.30

沒有留言: