autoconf手冊(一)
2005-08-24 10:00 am
作者:linux寶庫 (http://www.linuxmine.com)
來自:linux寶庫 (http://www.linuxmine.com)
現存:http://www.linuxmine.com/3733.html
聯系:linuxmine#gmail.com
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報告發送到[email protected]。請把你通過運作`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]]])
autoconf手冊(二)
建立輸出檔案。
在`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'添加一行:
@[email protected]
Makefiles中的替換
釋出版本中每個包含了需要被編譯或者被安裝的檔案的目錄都應該含有一個檔案`Makefile.in', configure将利用它在那個目錄中建立一個`Makefile'。為了建立`Makefile',configure進行一個簡單的變量替換:用 configure 為`@[email protected]'選取的值,在`Makefile.in'中對它們進行替換。按照這種方式被替換到輸出檔案中的變量被稱為輸出變量。在 configure中,它們是普通的shell變量。為了讓configure把特殊的變量替換到輸出檔案中,必須把那個變量的名字作為調用 AC_SUBST的參數。其他變量的任何`@[email protected]'都保持不變。關于使用AC_SUBST建立輸出變量的詳情,請參見設定輸出變量。
使用configure腳本的軟體應該釋出檔案`Makefile.in',而不是`Makefile';這樣,使用者就可以在編譯它之前正确地為本地系統進行配置了。
關于應該把哪些東西放入`Makefile'的詳情,請參見GNU編碼标準中的`Makefile慣例'。
預定義輸出變量
有些輸出變量是由Autoconf宏預定義的。一部分Autoconf宏設定一些附加的輸出變量,這些變量在對這些宏的描述中被說明。關于輸出變量的完整清單,參見輸出變量索引。下面是每個預定義變量所包含的内容。關于變量名以`dir'結尾的變量,參見GNU編碼标準中的 `為安裝目錄而提供的變量'。
變量: bindir
用于安裝由使用者運作的可執行檔案的目錄。
變量: configure_input
一個用于說明檔案是由configure自動生成的,并且給出了輸入檔案名的注釋。 AC_OUTPUT在它建立的每個`Makefile'檔案的開頭添加一個包括了這個變量的注釋行。對于其他檔案,你應該在每個輸入檔案開頭處的注釋中引用這個變量。例如,一個輸入shell腳本應該以如下行開頭:
#! /bin/sh
# @[email protected]
這一行的存在也提醒了人們在編輯這個檔案之後需要用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'代替`@[email protected]'(參見配置頭檔案)。在configure進行它的測試時,本變量沒有被定義,隻有在建立輸出檔案時候才定義。關于如何檢查從前的測試結果,請參見設定輸出變量。
變量: LDFLAGS
為連接配接器提供的Stripping(`-s')選項和其他各種選項。如果在運作configure時,在環境中沒有設定本變量,它的預設值就是空。 configure在連接配接程式以測試C的特征時使用本變量。
變量: LIBS
傳遞給連接配接器的`-l'和`-L'選項。
建立目錄
你可以支援從一個軟體包的一份源代碼拷貝中為多種結構同時進行編譯的功能。為每種結構生成的目标檔案都在它們自己的目錄中儲存。
為了支援這個功能,make用變量VPATH來尋找儲存在源代碼目錄中的檔案。 GNU make和其他大部分近來的make程式都可以這樣做。老版本的make 程式不支援VPATH;在使用它們的時候,源代碼必須與目标代碼處于同一個目錄。
為了支援VPATH,每個`Makefile.in'檔案都應該包含下列兩行:
srcdir = @[email protected]
VPATH = @[email protected]
不要把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的值,替換`@[email protected]'。常用在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 HAVE_UNISTD_H 0
如果你的代碼使用#ifdef而不是#if來測試配置選項,預設值就可能是取消對一個變量的定義而不是把它定義成一個值。在含有`unistd.h'的系統中,configure将修改讀入的第二行 `#define HAVE_UNISTD_H 1'。在其他的系統中,(在系統預定義了那個符号的情況下) configure将以注釋的方式排除這一行。
#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'包含了字元串 `@[email protected]',autoheader就把在包含`@[email protected]' 的行之前的所有行複制到它生成的檔案的開頭。相似地,如果`./acconfig.h'包含了字元串`@[email protected]', 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
autoconf手冊(三)
現有的測試
這些宏測試了包可能需要或者需要使用的特定的系統特征。如果你要測試這些宏所不能測試的特征,可能你可以用适當的參數調用主測試宏來達到目的(參見編寫測試)。
這些宏列印消息以告訴使用者它們正在測試的特征,以及它們的測試結果。它們為未來運作的configure 儲存測試結果(參見緩存結果)。
在這些宏中,有的宏設定輸出變量。關于如何擷取它們的值,請參見Makefile中的替換。在下面出現的術語“定義name”是“把C預處理符号name定義成1”的簡稱。關于如何把這些符号的定義放入你的程式中,參見定義C預處理器符号。
對程式的選擇
這些宏檢查了特定程式的存在或者特定程式的特征。它們被用于在幾個可以互相替代的程式間進行選擇,并且在決定選用某一個的時候作些什麼。如果沒有為你要使用的程式定義特定的宏,并且你不需要檢查它的任何特殊的特征,那麼你就可以選用一個通用程式檢查宏。
對特定程式的檢查
這些宏檢查特定的程式--它們是否存在,并且在某些情況下它們是否支援一些特征。
宏: AC_DECL_YYTEXT
如果yytext的類型是`char *'而不是`char []',就定義YYTEXT_POINTER。本宏還把輸出變量LEX_OUTPUT_ROOT設定由lex生成的檔案名的基檔案名;通常是 `lex.yy',但有時是其他的東西。它的結果依使用lex還是使用flex而定。
宏: AC_PROG_AWK
按順序查找mawk、gawk、nawk和awk,并且把輸出變量AWK 的值設定成第一個找到的程式名。首先尋找mawk是因為據說它是最快的實作。
宏: AC_PROG_CC
确定C的編譯器。如果在環境中沒有設定CC,就查找gcc,如果沒有找到,就使用cc。把輸出變量CC設定為找到的編譯器的名字。
如果要使用GNU C編譯器,把shell變量GCC設定為`yes',否則就設定成空。如果還沒有設定輸出變量 CFLAGS,就為GNU C編譯器把CFLAGS設定成`-g -O2'(在GCC不接受`-g' 的系統中就設定成`-O2'),為其他編譯器把CFLAGS設定成`-g'。
如果被使用的C編譯器并不生成可以在configure運作的系統上運作的可執行檔案,就把shell變量 cross_compiling設定成`yes',否則設定成`no'。換句話說,它檢查建立系統類型是否與主機系統類型不同(目标系統與本測試無關)。關于對交叉編譯的支援,參見手工配置。
宏: AC_PROG_CC_C_O
對于不能同時接受`-c'和`-o'選項的C編譯器,定義NO_MINUS_C_MINUS_O。
宏: AC_PROG_CPP
把輸出變量CPP設定成運作C預處理器的指令。如果`$CC -E'不能工作,就使用`/lib/cpp'。隻有對以`.c'為擴充名的檔案運作CPP才是可以移植的(portable)。
如果目前語言是C(參見對語言的選擇),許多特定的測試宏通過調用AC_TRY_CPP、 AC_CHECK_HEADER、AC_EGREP_HEADER或者AC_EGREP_CPP,間接地使用了CPP的值。
宏: AC_PROG_CXX
确定C++編譯器。檢查環境變量CXX或者CCC(按照這個順序)是否被設定了;如果設定了,就把輸出變量 CXX設定成它的值。否則就搜尋類似名稱(c++、g++、gcc、CC、 cxx和cc++)的C++編譯器。如果上述測試都失敗了,最後的辦法就是把CXX設定成 gcc。
如果使用GNU C++編譯器,就把shell變量GXX設定成`yes',否則就設定成空。如果還沒有設定輸出變量CXXFLAGS,就為GNU C++編譯器把CXXFLAGS設定成`-g -O2' (在G++不接受`-g'的系統上設定成`-O2'),或者為其他編譯器把CXXFLAGS設定成 `-g'。 .
如果使用的C++編譯器并不生成在configure運作的系統上運作的可執行檔案,就把shell變量cross_compiling 設定成`yes',否則就設定成`no'。換句話說,它檢查建立系統類型是否與主機系統類型不同(目标系統類型與本測試無關)。關于對交叉編譯的支援,參見手工配置。
宏: AC_PROG_CXXCPP
把輸出變量CXXCPP設定成運作C++預處理器的指令。如果`$CXX -E'不能工作,使用`/lib/cpp'。隻有對以`.c'、`.C'或者`.cc'為擴充名的檔案運作CPP才是可以移植的(portable)。
如果目前語言是C++(參見對語言的選擇),許多特定的測試宏通過調用 AC_TRY_CPP、AC_CHECK_HEADER、AC_EGREP_HEADER或者AC_EGREP_CPP,間接地使用了CXXCPP的值。
宏: AC_PROG_F77
确定Fortran 77編譯器。如果在環境中沒有設定F77,就按順序檢查g77、f77和 f2c。把輸出變量F77設定成找到的編譯器的名字。
如果使用g77(GNU Fortran 77編譯器),那麼AC_PROG_F77将把shell變量G77設定成 `yes',否則就設定成空。如果在環境中沒有設定輸出變量FFLAGS,那麼就為g77 把FFLAGS設定成`-g -02'(或者在g77不支援`-g'的時候設定成 `-O2')。否則,就為所有其它的Fortran 77編譯器把FFLAGS設定成`-g'。
宏: AC_PROG_F77_C_O
測試Fortran 77編譯器是否能夠同時接受選項`-c'和`-o',并且如果不能同時接受的話,就定義F77_NO_MINUS_C_MINUS_O。
宏: AC_PROG_GCC_TRADITIONAL
如果在沒有給出`-traditional'的情況下,用GNU C和ioctl不能正确地工作,就把 `-traditional'添加到輸出變量CC中。這通常發生在舊系統上沒有安裝修正了的頭檔案的時候。因為新版本的GNU C編譯器在安裝的時候自動地修正了頭檔案,它就不是一個普遍的問題了。
宏: AC_PROG_INSTALL
如果在目前PATH中找到了一個與BSD相容的install程式,就把輸出變量INSTALL設定成到該程式的路徑。否則,就把INSTALL設定成 `dir/install-sh -c',檢查由 AC_CONFIG_AUX_DIR指明的目錄(或者它的預設目錄)以确定dir(參見建立輸出檔案)。本宏還把變量INSTALL_PROGRAM和INSTALL_SCRIPT 設定成`${INSTALL}',并且把INSTALL_DATA設定成`${INSTALL} -m 644'。
本宏忽略各種已經确認的不能工作的install程式。為了提高速度,它更希望找到一個C程式而不是shell腳本。除了`install-sh',它還能夠使用`install.sh',但因為有些make含有一條在沒有 `Makefile'的情況下,從`install.sh'建立`install'的規則,是以這個名字過時了。
你可能使用的`install-sh'的一個副本來自于Autoconf。如果你使用AC_PROG_INSTALL,你必須在你的釋出版本中包含 `install-sh'或者`install.sh',否則即使你所在的系統含有一個好的install 程式,configure也将輸出一條找不到它們的錯誤消息。
如果你因為你自己的安裝程式提供了一些在标準install程式中沒有的特征,而需要使用你自己的安裝程式,就沒有必要使用AC_PROG_INSTALL;直接把你的程式的路徑名放入你的`Makefile.in'檔案即可。
宏: AC_PROG_LEX
如果找到了flex,就把輸出變量LEX設定成`flex',并且在flex庫在标準位置的時候,把LEXLIB設定成`-lfl'。否則,就把LEX設定成`lex'并且把 LEXLIB設定成`-ll'。
宏: AC_PROG_LN_S
如果`ln -s'能夠在目前檔案系統中工作(作業系統和檔案系統支援符号連接配接),就把輸出變量 LN_S設定成`ln -s',否則就把它設定成`ln'。
如果連接配接出現在其他目錄而不是在目前目錄中,它的含義依賴于是使用了`ln',還是使用了`ln -s'。為了用`$(LN_S)'安全地建立連接配接,既可以找到正在使用的形式并且調整參數,也可以總是在建立連接配接的目錄中調用ln。
換句話說,它不能像下面那樣工作:
$(LN_S) foo /x/bar
而是要:
(cd /x && $(LN_S) foo bar)
宏: AC_PROG_RANLIB
如果找到了ranlib,就把輸出變量RANLIB設定成`ranlib',否則就設定成 `:'(什麼也不作)。
宏: AC_PROG_YACC
如果找到了bison,就把輸出變量YACC設定成`bison -y'。否則,如果找到了byacc。就把YACC設定成`byacc'。否則,就把YACC設定成`yacc'。
對普通程式和檔案的檢查
這些宏用于尋找沒有包含在特定程式測試宏中的程式。如果你除了需要确定程式是否存在,還需要檢測程式的行為,你就不得不為它編寫你自己的測試了(參見編寫測試)。在預設情況下,這些宏使用環境變量PATH。如果你需要檢查可能不會出現在PATH中的程式,你可能要按照下面的方式給出修改了的路徑:
AC_PATH_PROG(INETD, inetd, /usr/libexec/inetd,
$PATH:/usr/libexec:/usr/sbin:/usr/etc:etc)
宏: AC_CHECK_FILE (file [, action-if-found [, action-if-not-found]])
檢查檔案file是否出現在本地系統中。如果找到了,就執行action-if-found。否則,就在給出了 action-if-not-found的時候執行action-if-not-found。
宏: AC_CHECK_FILES (files[, action-if-found [, action-if-not-found]])
為每個在files中給出的檔案運作AC_CHECK_FILE。并且為每個找到的檔案定義 `HAVEfile',定義成1。
宏: AC_CHECK_PROG (variable, prog-to-check-for, value-if-found [, value-if-not-found [, path, [ reject ]]])
檢查程式prog-to-check-for是否存在于PATH之中。如果找到了,就把變量 variable設定成value-if-found,否則就在給出了value-if-not-found的時候把variable設定成它。即使首先在搜尋路徑中找到reject(一個絕對檔案名),本宏也會忽略它;在那種情況下,用找到的prog-to-check-for,不同于reject的絕對檔案名來設定variable。如果variable已經被設定了,就什麼也不作。為variable調用AC_SUBST。
宏: AC_CHECK_PROGS (variable, progs-to-check-for [, value-if-not-found [, path]])
在PATH中尋找每個出現在以空格分隔的清單progs-to-check-for中的程式。如果找到了,就把variable設定成那個程式的名字。否則,繼續尋找清單中的下一個程式。如果清單中的任何一個程式都沒有被找到,就把variable設定成value-if-not-found;如果沒有給出value-if-not-found,variable的值就不會被改變。為variable調用 AC_SUBST。
宏: AC_CHECK_TOOL (variable, prog-to-check-for [, value-if-not-found [, path]])
除了把AC_CANONICAL_HOST确定的主機類型和破折号作為字首之外,類似于AC_CHECK_PROG,尋找prog-to-check- for(參見擷取規範的系統類型)。例如,如果使用者運作`configure --host=i386-gnu',那麼下列調用:
AC_CHECK_TOOL(RANLIB, ranlib, :)
當`i386-gnu-ranlib'在PATH中存在的時候,就把RANLIB設定成`i386-gnu-ranlib',或者當`ranlib'在 PATH中存在的時候,就把RANLIB設定成`ranlib',或者在上述兩個程式都不存在的時候,把RANLIB設定成`:'。
宏: AC_PATH_PROG (variable, prog-to-check-for [, value-if-not-found [, path]])
類似于AC_CHECK_PROG,但在找到prog-to-check-for的時候,把variable設定成prog-to-check-for的完整路徑。
宏: AC_PATH_PROGS (variable, progs-to-check-for [, value-if-not-found [, path]])
類似于AC_CHECK_PROGS,但在找到任何一個progs-to-check-for的時候,把variable 設定成找到的程式的完整路徑。
庫檔案
下列的宏檢查某些C、C++或者Fortran 77庫檔案是否存在。
宏: AC_CHECK_LIB (library, function [, action-if-found [, action-if-not-found [, other-libraries]]])
依賴于目前的語言(參見對語言的選擇),試圖通過檢查一個測試程式是否可以和庫library進行連接配接以擷取C、C++或者Fortran 77函數function,進而确認函數function 是可以使用的。library是庫的基本名字;例如,為了檢查`-lmp',就把`mp'作為參數library。
action-if-found是一個在與庫成功地進行了連接配接的時候運作的shell指令清單; action-if-not-found是一個在與庫的連接配接失敗的時候運作的shell指令清單。如果沒有給出action-if-found,預設的動作就是把`-llibrary'添加到 LIBS中,并且定義`HAVE_LIBlibrary'(全部使用大寫字母)。
如果與library的連接配接導緻了未定義符号錯誤(unresolved symbols),而這些錯誤可以通過與其他庫的連接配接來解決,就把這些庫用空格分隔,并作為other-libraries參數給出:`-lXt -lX11'。否則,本宏對library是否存在的檢測将會失敗,這是因為對測試程式的連接配接将總是因為含有未定義符号錯誤而失敗。
宏: AC_HAVE_LIBRARY (library, [, action-if-found [, action-if-not-found [, other-libraries]]])
本宏等價于function參數為main的,對AC_CHECK_LIB的調用。此外,library可以寫作`foo'、`-lfoo'或者 `libfoo.a'。對于以上任一種形式,編譯器都使用`-lfoo'。但是,library不能是一個shell變量;它必須是一個文字名(literal name)。本宏是一個過時的宏。
宏: AC_SEARCH_LIBS (function, search-libs [, action-if-found [, action-if-not-found [, other-libraries]]])
如果function還不可用,就尋找一個定義了function的庫。這等同于首先不帶庫調用 AC_TRY_LINK_FUNC,而後為每個在search-libs中列舉的庫調用AC_TRY_LINK_FUNC。
如果找到了函數,就運作action-if-found。否則運作action-if-not-found。
如果與庫library的連接配接導緻了未定義符号錯誤,而這些錯誤可以通過與附加的庫進行連接配接來解決,就把這些庫用空格分隔,并作為other- libraries參數給出:`-lXt -lX11'。否則,本宏對function 是否存在的檢測将總是失敗,這是因為對測試程式的連接配接将總是因為含有未定義符号錯誤而失敗。
宏: AC_SEARCH_LIBS (function, search-libs[, action-if-found [, action-if-not-found]])
本宏等價于為每個在search-libs中列舉的庫調用一次AC_TRY_LINK_FUNC。為找到的第一個含有 function的庫,把`-llibrary'添加到LIBS中,并且執行 action-if-found。否則就執行action-if-not-found。
庫函數
以下的宏用于檢測特定的C庫函數。如果沒有為你需要的函數定義特定的宏,而且你不需要檢查它的任何特殊性質,那麼你可以使用一個通用函數檢測宏。
對特定函數的檢查
這些宏用于檢測特定的C函數--它們是否存在,以及在某些情況下,當給出了特定的參數時,它們是如何響應的。
宏: AC_FUNC_ALLOCA
檢測如何獲得alloca。本宏試圖通過檢查`alloca.h'或者預定義C預處理器宏 __GNUC__和_AIX來獲得alloca的内置(builtin)版本。如果本宏找到了`alloca.h',它就定義HAVE_ALLOCA_H。
如果上述嘗試失敗了,本宏就在标準C庫中尋找函數。如果下列任何方法成功了,本宏就定義HAVE_ALLOCA。否則,它把輸出變量ALLOCA設定成 `alloca.o'并且定義C_ALLOCA (這樣程式就可以周期性地調用`alloca(0)'以進行垃圾的收集)。本變量是從LIBOBJS中分離出來的,是以在隻有一部分程式使用 LIBOBJS中的代碼時,多個程式就可以不必建立實際的庫而共享ALLOCA的值。
本宏并不試圖從System V R3的`libPW'中,或者從System V R4的`libucb'中擷取alloca,這是因為這些庫包含了一些造成麻煩的不相容的函數。有些版本甚至不含有alloca或者含有帶bug的版本。如果你仍然需要使用它們的alloca,用ar把`alloca.o'從這些庫中提取出來,而不是編譯`alloca.c'。
使用alloca的源檔案應該以如下一段代碼開頭,以正确地聲明它。在某些AIX版本中,對alloca 的聲明必須在除了注釋和預處理指令之前的任何東西之前出現。#pragma指令被縮進(indented),以便讓預标準C編譯器(pre-ANSI C compiler)忽略它,而不是導緻錯誤(choke on it)。
#ifndef __GNUC__
# if HAVE_ALLOCA_H
# include
# else
# ifdef _AIX
#pragma alloca
# else
# ifndef alloca
char *alloca ();
# endif
# endif
# endif
#endif
宏: AC_FUNC_CLOSEDIR_VOID
如果函數closedir不傳回有意義的值,就定義CLOSEDIR_VOID。否則,調用者就應該把它的傳回值作為錯誤訓示器來進行檢查。
宏: AC_FUNC_FNMATCH
如果可以使用fnmatch函數,并且能夠工作(不象SunOS 5.4中的fnmatch那樣),就定義HAVE_FNMATCH。
宏: AC_FUNC_GETLOADAVG
檢查如何才能獲得系統平均負載。如果系統含有getloadavg函數,本宏就定義HAVE_GETLOADAVG,并且把為了獲得該函數而需要的庫添加到LIBS中。
否則,它就把`getloadavg.o'添加到輸出變量LIBOBJS之中,并且可能定義幾個其他的C預處理器宏和輸出變量:
如果在相應的系統中,就根據系統類型定義宏SVR4、DGUX、UMAX或者UMAX4_3。
如果它找到了`nlist.h',就定義NLIST_STRUCT。
如果結構`struct nlist'含有成員`n_un',就定義NLIST_NAME_UNION。
如果在編譯`getloadavg.c'時定義了LDAV_PRIVILEGED,為了使getloadavg能夠工作,程式就必須特殊地安裝在系統中,并且本宏定義GETLOADAVG_PRIVILEGED。
本宏設定輸出變量NEED_SETGID。如果需要進行特别的安裝,它的值就是`true',否則值就是`false'。如果NEED_SETGID為`true',本宏把KMEM_GROUP 設定成将擁有被安裝的程式的組(group)的名字。
宏: AC_FUNC_GETMNTENT
為Irix 4、PTX和Unixware在庫`sun'、`seq'和`gen'中分别查找getmntent函數。那麼,如果可以使用getmntent,就定義HAVE_GETMNTENT。
宏: AC_FUNC_GETPGRP
如果getpgrp不接受參數(POSIX.1版),就定義GETPGRP_VOID。否則,它就是一個把程序ID作為參數的BSD版本。本宏根本不檢查getpgrp是否存在;如果你需要檢查它的存在性,就首先為 getpgrp函數調用AC_CHECK_FUNC。
宏: AC_FUNC_MEMCMP
如果不能使用memcmp函數,或者不能處理8位資料(就像SunOS 4.1.3中的那樣),就把`memcmp.o' 添加到輸出變量LIBOBJS中去。
宏: AC_FUNC_MMAP
如果函數mmap存在并且能夠正确地工作,就定義HAVE_MMAP。隻檢查已經映射(already-mapped)的記憶體的私有固定映射(private fixed mapping)。
宏: AC_FUNC_SELECT_ARGTYPES
确定函數select的每個參數的正确類型,并且把這些類型分别定義成SELECT_TYPE_ARG1、 SELECT_TYPE_ARG234和SELECT_TYPE_ARG5。SELECT_TYPE_ARG1的預設值是`int', SELECT_TYPE_ARG234的預設值是`int *', SELECT_TYPE_ARG5的預設值是`struct timeval *'。
宏: AC_FUNC_SETPGRP
如果setpgrp不接受參數(POSIX.1版),就定義SETPGRP_VOID。否則,該函數就是一個把兩個程序ID作為參數的BSD版本。本宏并不檢查函數setpgrp是否存在;如果你需要檢查該函數的存在性,就首先為setpgrp調用AC_CHECK_FUNC。
宏: AC_FUNC_SETVBUF_REVERSED
如果函數setvbuf的第二個參數是緩沖區的類型并且第三個參數是緩沖區指針,而不是其他形式,就定義SETVBUF_REVERSED。這是在System V第3版以前的情況。
宏: AC_FUNC_STRCOLL
如果函數strcoll存在并且可以正确地工作,就定義HAVE_STRCOLL。由于有些系統包含了錯誤定義的strcoll,這時就不應該使用strcoll,是以本宏要比`AC_CHECK_FUNCS(strcoll)'多作一些檢查。
宏: AC_FUNC_STRFTIME
對于SCO UNIX,在庫`intl'中查找strftime。而後,如果可以使用strftime,就定義HAVE_STRFTIME。
宏: AC_FUNC_UTIME_NULL
如果`utime(file, NULL)'把file的時間标記設定成現在,就定義 HAVE_UTIME_NULL。
宏: AC_FUNC_VFORK
如果找到了`vfork.h',就定義HAVE_VFORK_H。如果找不到可以工作的vfork,就把vfork定義成fork。本宏檢查一些已知的 vfork實作中的錯誤并且認為如果vfork的實作含有任何一個錯誤,系統就不含有可以工作的vfork。由于子程序很少改變它們的信号句柄(signal handler),是以如果子程序的signal調用(invocation)修改了父程序的信号句柄,将不會被當作實作的錯誤。
宏: AC_FUNC_VPRINTF
如果找到了vprintf,就定義HAVE_VPRINTF。否則,如果找到了_doprnt,就定義HAVE_DOPRNT。(如果可以使用vprintf,你就可以假定也可以使用vfprintf 和vsprintf。)
宏: AC_FUNC_WAIT3
如果找到了wait3并且該函數填充它的第三個參數的内容(`struct rusage *'),就定義HAVE_WAIT3。在HP-UX中,該函數并不這樣做。
autoconf手冊(四)
對普通函數的檢查
這些宏被用于尋找沒有包括在特定函數測試宏中的函數。如果函數可能出現在除了預設C庫以外的庫中,就要首先為這些庫調用AC_CHECK_LIB。如果你除了需要檢查函數是否存在之外,還要檢查函數的行為,你就不得不為此而編寫你自己的測試(參見編寫測試)。
宏: AC_CHECK_FUNC (function, [action-if-found [, action-if-not-found]])
如果可以使用C函數function,就運作shell指令action-if-found,否則運作 action-if-not-found。如果你隻希望在函數可用的時候定義一個符号,就考慮使用 AC_CHECK_FUNCS。由于C++比C更加标準化,即使在調用了AC_LANG_CPLUSPLUS 的時候,本宏仍然用C的連接配接方式對函數進行檢查。(關于為測試選擇語言的詳情,請參見 對語言的選擇)
宏: AC_CHECK_FUNCS (function... [, action-if-found [, action-if-not-found]])
對于每個在以空格分隔的函數清單function中出現的函數,如果可用,就定義HAVE_function (全部大寫)。如果給出了action-if-found,它就是在找到一個函數的時候執行的附加的shell代碼。你可以給出 `break'以便在找到第一個比對的時候跳出循環。如果給出了action-if-not-found,它就在找不到某個函數的時候執行。
宏: AC_REPLACE_FUNCS (function...)
本宏的功能就類似于以将`function.o'添加到輸出變量LIBOBJS的shell 代碼為參數action-if-not-found,調用AC_CHECK_FUNCS。你可以通過用 `#ifndef HAVE_function'包圍你為函數提供的替代版本的原型來聲明函數。如果系統含有該函數,它可能在一個你應該引入的頭檔案中進行聲明,是以你不應該重新聲明它,以避免聲明沖突。
頭檔案
下列宏檢查某些C頭檔案是否存在。如果沒有為你需要檢查的頭檔案定義特定的宏,而且你不需要檢查它的任何特殊屬性,那麼你就可以使用一個通用的頭檔案檢查宏。
對特定頭檔案的檢查
這些宏檢查特定的系統頭檔案--它們是否存在,以及在某些情況下它們是否定義了特定的符号。
宏: AC_DECL_SYS_SIGLIST
如果在系統頭檔案,`signal.h'或者`unistd.h',中定義了變量sys_siglist,就定義SYS_SIGLIST_DECLARED。
宏: AC_DIR_HEADER
類似于調用AC_HEADER_DIRENT和AC_FUNC_CLOSEDIR_VOID,但為了指明找到了哪個頭檔案而定義了不同的一組C預處理器宏。本宏和它定義的名字是過時的。它定義的名字是:
`dirent.h'
DIRENT
`sys/ndir.h'
SYSNDIR
`sys/dir.h'
SYSDIR
`ndir.h'
NDIR
此外,如果closedir不能傳回一個有意義的值,就定義VOID_CLOSEDIR。
宏: AC_HEADER_DIRENT
對下列頭檔案進行檢查,并且為第一個找到的頭檔案定義`DIR',以及列出的C預處理器宏:
`dirent.h'
HAVE_DIRENT_H
`sys/ndir.h'
HAVE_SYS_NDIR_H
`sys/dir.h'
HAVE_SYS_DIR_H
`ndir.h'
HAVE_NDIR_H
源代碼中的目錄庫聲明應該以類似于下面的方式給出:
#if HAVE_DIRENT_H
# include
# define NAMLEN(dirent) strlen((dirent)->d_name)
#else
# define dirent direct
# define NAMLEN(dirent) (dirent)->d_namlen
# if HAVE_SYS_NDIR_H
# include
# endif
# if HAVE_SYS_DIR_H
# include
# endif
# if HAVE_NDIR_H
# include
# endif
#endif
使用上述聲明,程式應該把變量定義成類型struct dirent,而不是struct direct,并且應該通過把指向struct direct的指針傳遞給宏NAMLEN來獲得目錄項的名稱的長度。
本宏還為SCO Xenix檢查庫`dir'和`x'。
宏: AC_HEADER_MAJOR
如果`sys/types.h'沒有定義major、minor和makedev,但`sys/mkdev.h'定義了它們,就定義MAJOR_IN_MKDEV;否則,如果`sys/sysmacros.h'定義了它們,就定義MAJOR_IN_SYSMACROS。
宏: AC_HEADER_STDC
如果含有标準C(ANSI C)頭檔案,就定義STDC_HEADERS。特别地,本宏檢查`stdlib.h'、`stdarg.h'、`string.h'和 `float.h';如果系統含有這些頭檔案,它可能也含有其他的标準C頭檔案。本宏還檢查`string.h'是否定義了memchr (并據此對其他mem函數做出假定),`stdlib.h'是否定義了free(并據此對malloc和其他相關函數做出假定),以及`ctype.h' 宏是否按照标準C的要求而可以用于被設定了高位的字元。
因為許多含有GCC的系統并不含有标準C頭檔案,是以用STDC_HEADERS而不是__STDC__ 來決定系統是否含有服從标準(ANSI-compliant)的頭檔案(以及可能的C庫函數)。
在沒有标準C頭檔案的系統上,變種太多,以至于可能沒有簡單的方式對你所使用的函數進行定義以使得它們與系統頭檔案聲明的函數完全相同。某些系統包含了 ANSI和BSD函數的混合;某些基本上是标準(ANSI)的,但缺少`memmove';有些系統在`string.h'或者`strings.h'中以宏的方式定義了BSD函數;有些系統除了含有`string.h'之外,隻含有BSD函數;某些系統在`memory.h' 中定義記憶體函數,有些在`string.h'中定義;等等。對于一個字元串函數和一個記憶體函數的檢查可能就夠了;如果庫含有這些函數的标準版,那麼它就可能含有其他大部分函數。如果你在`configure.in' 中安放了如下代碼:
AC_HEADER_STDC
AC_CHECK_FUNCS(strchr memcpy)
那麼,在你的代碼中,你就可以像下面那樣放置聲明:
#if STDC_HEADERS
# include
#else
# ifndef HAVE_STRCHR
# define strchr index
# define strrchr rindex
# endif
char *strchr (), *strrchr ();
# ifndef HAVE_MEMCPY
# define memcpy(d, s, n) bcopy ((s), (d), (n))
# define memmove(d, s, n) bcopy ((s), (d), (n))
# endif
#endif
如果你使用沒有等價的BSD版的函數,諸如memchr、memset、strtok 或者strspn,那麼僅僅使用宏就不夠了;你必須為每個函數提供一個實作。以memchr為例,一種僅僅在需要的時候(因為系統C庫中的函數可能經過了手工優化)與你的實作協作的簡單方式是把實作放入 `memchr.c'并且使用`AC_REPLACE_FUNCS(memchr)'。
宏: AC_HEADER_SYS_WAIT
如果`sys/wait.h'存在并且它和POSIX.1相相容,就定義HAVE_SYS_WAIT_H。如果`sys/wait.h'不存在,或者如果它使用老式BSD union wait,而不是 int來儲存狀态值,就可能出現不相容。如果`sys/wait.h'不與POSIX.1相容,那就不是引入該頭檔案,而是按照它們的常見解釋定義 POSIX.1宏。下面是一個例子:
#include
#if HAVE_SYS_WAIT_H
# include
#endif
#ifndef WEXITSTATUS
# define WEXITSTATUS(stat_val) ((unsigned)(stat_val) >> 8)
#endif
#ifndef WIFEXITED
# define WIFEXITED(stat_val) (((stat_val) & 255) == 0)
#endif
宏: AC_MEMORY_H
在`string.h'中,如果沒有定義memcpy, memcmp等函數,并且`memory.h' 存在,就定義NEED_MEMORY_H。本宏已經過時;可以用AC_CHECK_HEADERS(memory.h)來代替。參見為 AC_HEADER_STDC提供的例子。
宏: AC_UNISTD_H
如果系統含有`unistd.h',就定義HAVE_UNISTD_H。本宏已經過時;可以用 `AC_CHECK_HEADERS(unistd.h)'來代替。
檢查系統是否支援POSIX.1的方式是:
#if HAVE_UNISTD_H
# include
# include
#endif
#ifdef _POSIX_VERSION
#endif
在POSIX.1系統中包含了`unistd.h'的時候定義_POSIX_VERSION。如果系統中沒有`unistd.h',那麼該系統就一定不是POSIX.1系統。但是,有些非POSIX.1(non-POSIX.1)系統也含有`unistd.h'。
宏: AC_USG
如果系統并不含有`strings.h'、rindex、bzero等頭檔案或函數,就定義USG。定義USG就隐含地表明了系統含有`string.h'、strrchr、memset等頭檔案或函數。
符号USG已經過時了。作為本宏的替代,參見為AC_HEADER_STDC提供的例子。
對普通頭檔案的檢查
這些宏被用于尋找沒有包括在特定測試宏中的系統頭檔案。如果你除了檢查頭檔案是否存在之外還要檢查它的内容,你就不得不為此而編寫你自己的測試(參見編寫測試)。
宏: AC_CHECK_HEADER (header-file, [action-if-found [, action-if-not-found]])
如果系統頭檔案header-file存在,就執行shell指令action-if-found,否則執行action-if-not-found。如果你隻需要在可以使用頭檔案的時候定義一個符号,就考慮使用 AC_CHECK_HEADERS。
宏: AC_CHECK_HEADERS (header-file... [, action-if-found [, action-if-not-found]])
對于每個在以空格分隔的參數清單header-file出現的頭檔案,如果存在,就定義 HAVE_header-file(全部大寫)。如果給出了action-if-found,它就是在找到一個頭檔案的時候執行的附加shell代碼。你可以把`break'作為它的值以便在第一次比對的時候跳出循環。如果給出了action-if-not-found,它就在找不到某個頭檔案的時候被執行。
結構
以下的宏檢查某些結構或者某些結構成員。為了檢查沒有在此給出的結構,使用AC_EGREP_CPP (參見檢驗聲明)或者使用AC_TRY_COMPILE (參見檢驗文法)。
宏: AC_HEADER_STAT
如果在`sys/stat.h'中定義的S_ISDIR、S_ISREG等宏不能正确地工作(傳回錯誤的正數),就定義 STAT_MACROS_BROKEN。這種情況出現在Tektronix UTekV、 Amdahl UTS和Motorola System V/88上。
宏: AC_HEADER_TIME
如果程式可能要同時引入`time.h'和`sys/time.h',就定義TIME_WITH_SYS_TIME。在一些老式系統中, `sys/time.h'引入了`time.h',但`time.h'沒有用多個包含保護起來,是以程式不應該顯式地同時包含這兩個檔案。例如,本宏在既使用struct timeval或 struct timezone,又使用struct tm程式中有用。它最好和 HAVE_SYS_TIME_H一起使用,該宏可以通過調用AC_CHECK_HEADERS(sys/time.h)來檢查。
#if TIME_WITH_SYS_TIME
# include
# include
#else
# if HAVE_SYS_TIME_H
# include
# else
# include
# endif
#endif
宏: AC_STRUCT_ST_BLKSIZE
如果struct stat包含一個st_blksize成員,就定義HAVE_ST_BLKSIZE。
宏: AC_STRUCT_ST_BLOCKS
如果struct stat包含一個st_blocks成員,就定義HAVE_ST_BLOCKS。否則,就把`fileblocks.o'添加到輸出變量LIBOBJS中。
宏: AC_STRUCT_ST_RDEV
如果struct stat包含一個st_rdev成員,就定義HAVE_ST_RDEV。
宏: AC_STRUCT_TM
如果`time.h'沒有定義struct tm,就定義TM_IN_SYS_TIME,它意味着引入`sys/time.h'将得到一個定義得更好的struct tm。
宏: AC_STRUCT_TIMEZONE
确定如何擷取目前的時區。如果struct tm有tm_zone成員,就定義HAVE_TM_ZONE。否則,如果找到了外部數組tzname,就定義HAVE_TZNAME。
類型定義
以下的宏檢查C typedefs。如果沒有為你需要檢查的typedef定義特定的宏,并且你不需要檢查該類型的任何特殊的特征,那麼你可以使用一個普通的typedef檢查宏。
對特定類型定義的檢查
這些宏檢查在`sys/types.h'和`stdlib.h'(如果它存在)中定義的特定的C typedef。
宏: AC_TYPE_GETGROUPS
把GETGROUPS_T定義成getgroups的數組參數的基類型gid_t或者int。
宏: AC_TYPE_MODE_T
如果沒有定義mode_t,就把mode_t定義成int。
宏: AC_TYPE_OFF_T
如果沒有定義off_t,就把off_t定義成long。
宏: AC_TYPE_PID_T
如果沒有定義pid_t,就把pid_t定義成int。
宏: AC_TYPE_SIGNAL
如果`signal.h'把signal聲明成一個指向傳回值為void的函數的指針,就把RETSIGTYPE定義成void;否則,就把它定義成int。
把信号處理器(signal handler)的傳回值類型定義為RETSIGTYPE:
RETSIGTYPE
hup_handler ()
{
...
}
宏: AC_TYPE_SIZE_T
如果沒有定義size_t,就把size_t定義成unsigned。
宏: AC_TYPE_UID_T
如果沒有定義uid_t,就把uid_t定義成int并且把 gid_t定義成int。
對普通類型定義的檢查
本宏用于檢查沒有包括在特定類型測試宏中的typedef。
宏: AC_CHECK_TYPE (type, default)
如果`sys/types.h'或者`stdlib.h'或者`stddef.h'存在,而類型 type沒有在它們之中被定義,就把type定義成C(或者C++)預定義類型 default;例如,`short'或者`unsigned'。
C編譯器的特征
下列宏檢查C編譯器或者機器結構的特征。為了檢查沒有在此列出的特征,使用AC_TRY_COMPILE (參見檢驗文法)或者AC_TRY_RUN (參見檢查運作時的特征)
宏: AC_C_BIGENDIAN
如果字(word)按照最高位在前的方式儲存(比如Motorola和SPARC,但不包括Intel和VAX,CPUS),就定義 WORDS_BIGENDIAN。
宏: AC_C_CONST
如果C編譯器不能完全支援關鍵字const,就把const定義成空。有些編譯器并不定義 __STDC__,但支援const;有些編譯器定義__STDC__,但不能完全支援 const。程式可以假定所有C編譯器都支援const,并直接使用它;對于那些不能完全支援const的編譯器,`Makefile'或者配置頭檔案将把const定義為空。
宏: AC_C_INLINE
如果C編譯器支援關鍵字inline,就什麼也不作。如果C編譯器可以接受__inline__或者__inline,就把inline定義成可接受的關鍵字,否則就把inline定義為空。
宏: AC_C_CHAR_UNSIGNED
除非C編譯器預定義了__CHAR_UNSIGNED__,如果C類型char是無符号的,就定義 __CHAR_UNSIGNED__。
宏: AC_C_LONG_DOUBLE
如果C編譯器支援long double類型,就定義HAVE_LONG_DOUBLE。有些C編譯器并不定義__STDC__但支援long double類型;有些編譯器定義 __STDC__但不支援long double。
宏: AC_C_STRINGIZE
如果C預處理器支援字元串化操作符(stringizing operator),就定義HAVE_STRINGIZE。字元串化操作符是 `#'并且它在宏定義中以如下方式出現:
#define x(y) #y
宏: AC_CHECK_SIZEOF (type [, cross-size])
把SIZEOF_uctype定義為C(或C++)預定義類型type的,以位元組為機關的大小,例如`int' or `char *'。如果編譯器不能識别`type',它就被定義為0。 uctype就是把type中所有小寫字母轉化為大寫字母,空格轉化成下劃線,星号轉化成`P' 而得到的名字。在交叉編譯中,如果給出了cross-size,就使用它,否則configure就生成一個錯誤并且退出。
例如,調用
AC_CHECK_SIZEOF(int *)
在DEC Alpha AXP系統中,把SIZEOF_INT_P定義為8。
宏: AC_INT_16_BITS
如果C類型int是16為寬,就定義INT_16_BITS。本宏已經過時;更常見的方式是用 `AC_CHECK_SIZEOF(int)'來代替。
宏: AC_LONG_64_BITS
如果C類型long int是64位寬,就定義LONG_64_BITS。本宏已經過時;更常見的方式是用`AC_CHECK_SIZEOF(long)'來代替。
Fortran 77編譯器的特征
下列的宏檢查Fortran 77編譯器的特征。為了檢查沒有在此列出的特征,使用AC_TRY_COMPILE (參見檢驗文法)或者AC_TRY_RUN (參見檢驗運作時的特征),但首先必須确認目前語言被設定成 Fortran 77 AC_LANG_FORTRAN77(參見對語言的選擇)。
宏: AC_F77_LIBRARY_LDFLAGS
為成功地連接配接Fotran 77或者共享庫而必須的Fortran 77内置函數(intrinsic)和運作庫确定連接配接選項(例如,`-L'和`-l')。輸出變量FLIBS被定義為這些選項。
本宏的目的是用于那些需要把C++和Fortran 77源代碼混合到一個程式或者共享庫中的情況(參見GNU Automake中的`Mixing Fortran 77 With C and C++'節)。
例如,如果來自C++和Fortran 77編譯器的目标檔案必須被連接配接到一起,那麼必須用C++編譯器/連接配接器來連接配接(因為有些C++特定的任務要在連接配接時完成,這樣的任務有調用全局構造函數、模闆的執行個體化、啟動例外(exception)支援,等等)。
然而,Fortran 77内置函數和運作庫也必須被連接配接,但C++編譯器/連接配接器在預設情況下不知道如何添加這些 Fortran 77庫。是以,就建立AC_F77_LIBRARY_LDFLAGS宏以确認這些Fortran 77庫。
系統服務
下列宏檢查作業系統服務或者作業系統能力。
宏: AC_CYGWIN
檢查Cygwin環境。如果存在,就把shell變量CYGWIN設定成`yes'。如果不存在,就把CYGWIN設定成空字元串。
宏: AC_EXEEXT
根據編譯器的輸出,定義替換變量EXEEXT,但不包括.c、.o和.obj檔案。對于Unix來說典型的值為空,對Win32來說典型的值為`.exe'或者`.EXE'。
宏: AC_OBJEXT
根據編譯器的輸出,定義替換變量OBJEXT,但不包括.c檔案。對于Unix來說典型的值為`.o',對Win32來說典型的值為`.obj'。
宏: AC_MINGW32
檢查MingW32編譯環境。如果存在,就把shell變量MINGW32設定成`yes'。如果不存在,就把MINGW32設定成空。
宏: AC_PATH_X
試圖找到X Window系統的頭檔案和庫檔案。如果使用者給出了指令行選項`--x-includes=dir'和 `--x-libraries=dir',就使用這些目錄。如果沒有給出任一個選項,或者都沒有給出,就通過運作xmkmf以處理一個測試 `Imakefile',并且檢查它所生成的`Makefile',來得到沒有給出的目錄。如果這失敗了(比如說,xmkmf不存在),就在它們通常存在的幾個目錄中尋找。如果任何一種方法成功了,就把shell變量x_includes和x_libraries設定成相應的位置,除非這些目錄就在編譯器搜尋的預設目錄中。
如果兩種方法都失敗了,或者使用者給出指令行選項`--without-x',就把shell變量no_x 設定成`yes';否則就把它設定成空字元串。
宏: AC_PATH_XTRA
AC_PATH_X的增強版。它把X需要的C編譯器選項添加到輸出變量X_CFLAGS,并且把 X的連接配接選項添加到X_LIBS。如果不能使用X系統,就把`-DX_DISPLAY_MISSING' 設定成X_CFLAGS。
本宏還檢查在某些系統中為了編譯X程式而需要的特殊庫。它把所有系統需要的庫添加到輸出變量X_EXTRA_LIBS。并且它檢查需要在`-lX11'之前被連接配接的特殊X11R6庫,并且把找到的所有庫添加到輸出變量X_PRE_LIBS。
宏: AC_SYS_INTERPRETER
檢查系統是否支援以形式為`#! /bin/csh'的行開頭的腳本選擇執行該腳本的解釋器。在運作本宏之後,configure.in中的shell代碼就可以檢查shell變量 interpval;如果系統支援`#!',interpval将被設定成`yes',如果不支援就設定成`no'。
宏: AC_SYS_LONG_FILE_NAMES
如果系統支援長于14個字元的檔案名,就定義HAVE_LONG_FILE_NAMES。
宏: AC_SYS_RESTARTABLE_SYSCALLS
如果系統自動地重新啟動被信号所中斷的系統調用,就定義HAVE_RESTARTABLE_SYSCALLS。
UNIX變種
下列宏檢查對于有些程式來說需要特殊處理的一些作業系統,這是因為它們的頭檔案或庫檔案中含有特别怪異的東西。這些宏不讨人喜歡;它們将根據它們所支援的函數或者它們提供的環境,被更加系統化的方法所代替。
宏: AC_AIX
如果在AIX系統中,就定義_ALL_SOURCE。允許使用一些BSD函數。應該在所有運作C編譯器的宏之前調用本宏。
宏: AC_DYNIX_SEQ
如果在Dynix/PTX (Sequent UNIX)系統中,就把`-lseq'添加到輸出變量LIBS中。本宏已經過時;用AC_FUNC_GETMNTENT來代替。
宏: AC_IRIX_SUN
如果在IRIX(Silicon Graphics UNIX)系統中,就把`-lsun'添加到輸出變量LIBS中。本宏已經過時。如果你用本宏來擷取getmntent,就用 AC_FUNC_GETMNTENT來代替。如果你為了密碼(password)群組函數的NIS版本而使用本宏,就用`AC_CHECK_LIB (sun, getpwnam)'來代替。
宏: AC_ISC_POSIX
如果在POSIX化(POSIXized) ISC UNIX系統中,就定義_POSIX_SOURCE,并且把`-posix' (對于GNU C編譯器)或者`-Xp'(對于其他C編譯器)添加到輸出變量CC中。本宏允許使用 POSIX工具。必須在調用AC_PROG_CC之後,在調用其他任何運作C編譯器的宏之前,調用本宏。
宏: AC_MINIX
如果在Minix系統中,就定義_MINIX和_POSIX_SOURCE,并且把_POSIX_1_SOURCE 定義成2。本宏允許使用POSIX工具。應該在所有運作C編譯器的宏之前調用本宏。
宏: AC_SCO_INTL
如果在SCO UNIX系統中,就把`-lintl'添加到輸出變量LIBS。本宏已經過時;用AC_FUNC_STRFTIME來代替。
宏: AC_XENIX_DIR
如果在Xenix系統中,就把`-lx'添加到輸出變量LIBS。還有,如果使用了`dirent.h',就把`-ldir'添加到LIBS。本宏已經過時;用AC_HEADER_DIRENT來代替。
autoconf手冊(五)
編寫測試
如果現有的特征測試不能完成你所需要的工作,你就必須編寫一個新的。這些宏是建立子產品。它們為其它宏提供了檢查各種特征是否存在并且報告結果的方式。
本章包括一些建議和一些關于現有的測試的為什麼要那樣編寫的原因。通過閱讀現有的測試,你還可以學到許多關于編寫 Autoconf測試的方法。如果在一個或多個Autoconf測試中出現了錯誤,這些資訊可以幫助你了解它們意味着什麼,這有助于你找到最佳的解決問題的辦法。
這些宏檢查C編譯器系統的輸出。它們并不為未來的使用而緩存測試的結果(參見緩存結果),這是因為它們沒有足夠的資訊以生成緩存變量名。基于同樣的原因,它們還不會輸出任何消息。對特殊的C的特征進行的測試調用這些宏并且緩存它們的結果、列印關于它們所進行的測試的消息。
當你編寫了一個可以适用于多于一個軟體包的特征測試時,最好的方式就是用一個新宏封裝它。關于如何封裝,參見 編寫宏。
檢驗聲明
宏AC_TRY_CPP用于檢測某個特定的頭檔案是否存在。你可以一次檢查一個頭檔案,或者如果你為了某些目的而希望多個頭檔案都存在,也可以一次檢查多個頭檔案。
宏: AC_TRY_CPP (includes, [action-if-true [, action-if-false]])
includes是C或C++的#include語句和聲明,對于它,将進行shell變量、反引用(backquote)、以及反斜線(backslash)替換。(實際上,它可以是任何C程式,但其它的語句可能沒有用。)如果預處理器在處理它的時候沒有報告錯誤,就運作shell指令 action-if-true。否則運作shell指令action-if-false。
本宏使用CPPFLAGS,而不使用CFLAGS,這是因為`-g'、`-O'等選項對于許多C預處理器來說都是不合法的選項。
下面是如何确認在某個頭檔案中是否包含一個特定的聲明,比如說typedef、結構、結構成員或者一個函數。使用 AC_EGREP_HEADER而不是對頭檔案直接運作grep;在某些系統中,符号可能是在另一個你所檢查的 `#include'檔案。
宏: AC_EGREP_HEADER (pattern, header-file, action-if-found [, action-if-not-found])
如果對系統頭檔案header-file運作預處理器所産生的輸出與egrep正常表達式pattern相比對,就執行shell指令action-if-found,否則執行action-if-not-found。
為了檢查由頭檔案或者C預處理器預定義的C預處理器符号,使用AC_EGREP_CPP。下面是後者的一個例子:
AC_EGREP_CPP(yes,
[#ifdef _AIX
yes
#endif
], is_aix=yes, is_aix=no)
宏: AC_EGREP_CPP (pattern, program, [action-if-found [, action-if-not-found]])
program是C或者C++的程式文本,對于它,将進行shell變量、反引号(backquote)以及反斜線(backslash)替換。如果對 program運作預處理器産生的輸出與egrep正常表達式(regular expression)pattern 相比對,就執行shell指令action-if-found,否則執行action-if-not-found。
如果宏還沒有調用AC_PROG_CPP或者AC_PROG_CXXCPP(根據目前語言來确定使用那個宏,參見對語言的選擇),本宏将調用它。
檢驗文法
為了檢查C、C++或者Fortran 77編譯器的文法特征,比如說它是否能夠識别某個關鍵字,就使用AC_TRY_COMPILE 來嘗試編譯一個小的使用該特征的程式。你還可以用它檢查不是所有系統都支援的結構和結構成員。
宏: AC_TRY_COMPILE (includes, function-body, [action-if-found [, action-if-not-found]])
建立一個C、C++或者Fortran 77測試程式(依賴于目前語言,參見對語言的選擇),來察看由function-body組成的函數是否可以被編譯。
對于C和C++,includes是所有function-body中的代碼需要的#include語句(如果目前選擇的語言是Fortran 77,includes将被忽略)。如果目前選擇的語言是C或者C++,本宏還将在編譯的時侯使用CFLAGS或者CXXFLAGS,以及 CPPFLAGS。如果目前選擇的語言是Fortran 77,那麼就在編譯的時候使用FFLAGS。
如果檔案被成功地編譯了,就運作shell指令action-if-found,否則運作action-if-not-found。
本宏并不試圖進行連接配接;如果你希望進行連接配接,使用AC_TRY_LINK (參見檢驗庫)。
檢驗庫
為了檢查一個庫、函數或者全局變量,Autoconf configure腳本試圖編譯并連接配接一個使用它的小程式。不像Metaconfig,它在預設情況下對C庫使用nm或者ar以試圖确認可以使用那個函數。由于與函數相連接配接避免了處理nm和ar的各個變種的選項及輸出格式,而且不必處理标準庫的位置,是以與函數連接配接通常是更加可靠的辦法。如果需要,它還允許進行交叉配置或者檢查函數的運作是特征。另一方面,它比一次性掃描庫要慢一些。
少數系統的連接配接器在出現找不到的函數錯誤(unresolved functions)時不傳回失敗的退出狀态。這個錯誤使得由Autoconf 生成的配置腳本不能在這樣的系統中使用。然而,有些這樣的連接配接器允許給出選項以便正确地傳回錯誤狀态。 Autoconf目前還不能自動地處理這個問題。如果使用者遇到了這樣的問題,他們可能可以通過在環境中設定LDFLAGS 以把連接配接器所需要的選項(例如,`-Wl,-dn' on MIPS RISC/OS)傳遞給連接配接器,進而解決這個問題。
AC_TRY_LINK用于編譯測試程式,以測試函數和全局變量。AC_CHECK_LIB還用本宏把被測試的庫暫時地加入LIBS并試圖連接配接一個小程式,進而對庫進行檢查(參見庫檔案)。
宏: AC_TRY_LINK (includes, function-body, [action-if-found [, action-if-not-found]])
根據目前語言(參見對語言的選擇),建立一個測試程式以察看一個函數體為function-body的函數是否可以被編譯和連接配接。
對C和C++來說,includes給出了所有function-body中的代碼需要的#include語句(如果目前標明的語言是Fortran 77,includes将被忽略)。如果目前語言是C或者C++,本宏在編譯時還将使用 CFLAGS或者CXXFLAGS,以及CPPFLAGS。如果目前標明的語言是Fortran 77,那麼在編譯時将使用FFLAGS。然而,在任何情況下,連接配接都将使用LDFLAGS和LIBS。
如果檔案被成功地編譯和連接配接了,就運作shell指令action-if-found,否則就運作action-if-not-found。
宏: AC_TRY_LINK_FUNC (function, [action-if-found [, action-if-not-found]])
根據目前語言(參見對語言的選擇),建立一個測試程式以察看一個含有function 原型和對它的調用的程式是否可以被編譯和連接配接。
如果檔案被成功地編譯和連接配接了,就運作shell指令action-if-found,否則就運作action-if-not-found。
宏: AC_TRY_LINK_FUNC (function, [action-if-found [, action-if-not-found]])
試圖編譯并且連接配接一個與function相連接配接的小程式。如果檔案被成功地編譯和連接配接了,就運作shell指令 action-if-found,否則就運作action-if-not-found。
宏: AC_COMPILE_CHECK (echo-text, includes, function-body, action-if-found [, action-if-not-found])
本宏是AC_TRY_LINK的一個過時的版本。此外,如果echo-text不為空,它首先還要把 `checking for echo-text'列印到标準輸出。用AC_MSG_CHECKING 和AC_MSG_RESULT來代替本宏的列印消息的功能(參見列印消息)。
檢驗運作時的特征
有時候,你需要知道系統在運作時作了些什麼,比如說某個給定的函數是否具備某種能力或者是否含有錯誤。如果你能,你可以在你的程式初始化時自行檢查這類事件(比如說machine's endianness)。
如果你實在需要在配置時刻檢查運作時的特征,你可以編寫一個測試程式以确定結果,并且通過AC_TRY_RUN 來編譯和運作它。如果可能就避免運作測試程式,這是因為使用它們使得人們不能對你的包進行交叉編譯。
運作測試程式
如果你希望在配置的時候測試系統運作時的特征,就使用如下的宏。
宏: AC_TRY_RUN (program, [action-if-true [, action-if-false [, action-if-cross-compiling]]])
program是C程式的文本,将對該文本進行shell變量和反引用(backquote)替換。如果它被成功地編譯和連接配接了并且在執行的時候傳回的退出狀态為0,就運作shell指令action-if-true。否則就運作shell指令action-if-false;程式的退出狀态可以通過 shell變量`$?'得到。本宏在編譯時使用CFLAGS或者CXXFLAGS以及 CPPFLAGS、LDFLAGS和LIBS。
如果使用的C編譯器生成的不是在configure運作的系統上運作的可執行檔案,那麼測試程式就不運作。如果給出了可選的shell指令action- if-cross-compiling,它們就代替生成的可執行檔案執行。否則, configure列印一條錯誤消息并且退出。
當交叉編譯使運作時測試變得不可能的時候,就嘗試提供一個應急(pessimistic)的預設值以供使用。你通過把可選的最後一個參數傳遞給 AC_TRY_RUN來完成這個工作。在每次生成configure的過程中,每次遇到沒有提供 action-if-cross-compiling參數的AC_TRY_RUN調用時,autoconf都列印一條警告消息。雖然使用者将不能為交叉編譯你的包而進行配置,你仍可以忽略該警告。與Autoconf一同發行的少數宏産生該警告消息。
為了為交叉編譯進行配置,你還可以根據規範系統名(canonical system name)為這些參數選擇值(參見手工配置)。另一種方式是把測試緩存檔案設定成目标系統的正确值(參見緩存結果)。
為了給嵌入到其它宏(包括少數與Autoconf一同發行的宏)中的,對AC_TRY_RUN的調用提供預設值,你可以在它們運作之前調用 AC_PROG_CC。那麼,如果shell變量cross_compiling被設定成 `yes',就使用另一種方法來擷取結果,而不是調用宏。
宏: AC_C_CROSS
本宏已經過時;它不作任何事情。
測試程式指南
測試程式不應該向标準輸出輸出任何資訊。如果測試成功,它們應該傳回0,否則傳回非0,以便于把成功的執行從core dump或者其它失敗中區分出來;段沖突(segmentation violations)和其它失敗産生一個非0的退出狀态。測試程式應該從main中exit,而不是return,這是因為在某些系統中(至少在老式的 Sun上),main的return的參數将被忽略。
測試程式可以使用#if或者#ifdef來檢查由已經執行了的測試定義的預處理器宏的值。例如,如果你調用AC_HEADER_STDC,那麼在`configure.in'的随後部分,你可以使用一個有條件地引入标準C頭檔案的測試程式:
#if STDC_HEADERS
# include
#endif
如果測試程式需要使用或者建立資料檔案,其檔案名應該以`conftest'開頭,例如`conftestdata'。在運作測試程式之後或者腳本被中斷時,configure将通過運作`rm -rf conftest*'來清除資料檔案。
測試函數
在測試程式中的函數聲明應該條件地含有為C++提供的原型。雖然實際上測試程式很少需要帶參數的函數。
#ifdef __cplusplus
foo(int i)
#else
foo(i) int i;
#endif
測試程式聲明的函數也應該有條件地含有為C++提供的,需要`extern "C"'的原型。要確定不要引入任何包含沖突原型的頭檔案。
#ifdef __cplusplus
extern "C" void *malloc(size_t);
#else
char *malloc();
#endif
如果測試程式以非法的參數調用函數(僅僅看它是否存在),就組織程式以確定它從不調用這個函數。你可以在另一個從不調用的函數中調用它。你不能把它放在對 exit的調用之後,這是因為GCC第2版知道 exit永遠不會傳回,并且把同一塊中該調用之後的所有代碼都優化掉。
如果你引入了任何頭檔案,確定使用正确數量的參數調用與它們相關的函數,即使它們不帶參數也是如此,以避免原型造成的編譯錯誤。GCC第2版為有些它自動嵌入(inline)的函數設定了内置原型;例如, memcpy。為了在檢查它們時避免錯誤,既可以給它們正确數量的參數,也可以以不同的傳回類型(例如char)重新聲明它們。
可移植的Shell程式設計
在編寫你自己的測試時,為了使你的代碼可以移植,你應該避免使用某些shell腳本程式設計技術。 Bourne shell和諸如Bash和Korn shell之類的向上相容的shell已經發展了多年,但為了避免麻煩,不要利用在UNIX版本7,circa 1977之後添加的新特征。你不應該使用shell函數、别名、負字元集(negated character classes)或者其它不是在所有與Bourne相容的shell中都能找到的特征;把你自己限制到最低的風險中去。(the lowest common denominator)。即使是unset都不能夠被所有的shell所支援!還有,像下面那樣在指定解釋器的驚歎号之後給出空格:
#! /usr/bin/perl
如果你忽略了路徑之前的空格,那麼基于4.2BSD的系統(比如說Sequent DYNIX)将忽略這一行,這是因為它們把 `#! /'看作一個四位元組的魔數(magic number)。
你在configure腳本中運作的外部程式,應該是一個相當小的集合。關于可用的外部程式清單,參見 GNU編碼标準中的‘Makefile中的工具’一節。這個限制允許使用者在隻擁有相當少的程式時進行配置和編譯,這避免了軟體包之間過多的依賴性。
此外,這些外部工具中的某些工具隻有一部分特征是可移植的。例如,不要依賴ln支援`-f'選項,也不要依賴cat含有任何選項。sed腳本不應該含有注釋,也不應該使用長于8個字元的分支标記。不要使用`grep -s'來禁止(suppress)輸出。而要把grep的标準輸出和标準錯誤輸出(在檔案不存在的情況下會輸出資訊到标準錯誤輸出)重新定向到 `/dev/null'中。檢查grep的退出狀态以确定它是否找到了一個比對。
測試值和檔案
configure腳本需要測試許多檔案和字元串的屬性。下面是在進行這些測試的時候需要提防的一些移植性問題。
程式test是進行許多檔案和字元串測試的方式。人們使用替代(alternate)名`['來調用它,但因為`['是一個m4的引用字元,在Autoconf代碼中使用`['将帶來麻煩。
如果你需要通過test建立多個檢查,就用shell操作符`&&'和`||' 把它們組合起來,而不是使用test操作符`-a'和`-o'。在System V中, `-a'和`-o'相對于unary操作符的優先級是錯誤的;為此,POSIX并未給出它們,是以使用它們是不可移植的。如果你在同一個語句中組合使用了 `&&'和`||',要記住它們的優先級是相同的。
為了使得configure腳本可以支援交叉編譯,它們不能作任何測試主系統而不是測試目标系統的事。但你偶爾可以發現有必要檢查某些特定(arbitrary)檔案的存在。為此,使用`test -f'或者`test -r'。不要使用`test -x',因為4.3BSD不支援它。
另一個不可移植的shell程式設計結構是
var=${var:-value}
它的目的是僅僅在沒有設定var的值的情況下,把var設定成value,但如果var已經含有值,即使是空字元串,也不修改var。老式BSD shell,包括 Ultrix sh,不接受這個冒号,并且給出錯誤并停止。一個可以移植的等價方式是
: ${var=value}
多種情況
有些操作是以幾種可能的方式完成的,它依賴于UNIX的變種。檢查它們通常需要一個"case 語句"。Autoconf不能直接提供該語句;然而,通過用一個shell變量來記錄是否采用了操作的某種已知的方式,可以容易地模拟該語句。
下面是用shell變量fstype記錄是否還有需要檢查的情況的例子。
AC_MSG_CHECKING(how to get filesystem type)
fstype=no
# The order of these tests is important.
AC_TRY_CPP([#include
#include ], AC_DEFINE(FSTYPE_STATVFS) fstype=SVR4)
if test $fstype = no; then
AC_TRY_CPP([#include
#include ], AC_DEFINE(FSTYPE_USG_STATFS) fstype=SVR3)
fi
if test $fstype = no; then
AC_TRY_CPP([#include
#include ], AC_DEFINE(FSTYPE_AIX_STATFS) fstype=AIX)
fi
# (more cases omitted here)
AC_MSG_RESULT($fstype)
對語言的選擇
既使用C又使用C++的包需要同時測試兩個編譯器。Autoconf生成的configure腳本在預設情況下檢查C的特征。以下的宏決定在`configure.in'的随後部分使用那個語言的編譯器。
宏: AC_LANG_C
使用CC和CPP進行編譯測試并且把`.c'作為測試程式的擴充名。如果已經運作過AC_PROG_CC,就把把shell變量cross_compiling的值設定成該宏計算的結果,否則就設定為空。
宏: AC_LANG_CPLUSPLUS
使用CXX和CXXPP進行編譯測試并且把`.C'作為測試程式的擴充名。如果已經運作過AC_PROG_CXX,就把把shell變量cross_compiling的值設定成該宏計算的結果,否則就設定為空。
宏: AC_LANG_FORTRAN77
使用F77進行編譯測試并且把`.f'作為測試程式的擴充名。如果已經運作過AC_PROG_F77,就把把shell變量cross_compiling的值設定成該宏計算的結果,否則就設定為空。
宏: AC_LANG_SAVE
在堆棧中記錄目前的語言(由AC_LANG_C、AC_LANG_CPLUSPLUS或者AC_LANG_FORTRAN77 所設定)。不改變目前使用的語言。在需要暫時地切換到其它特殊語言的宏之中使用本宏和AC_LANG_RESTORE。
宏: AC_LANG_RESTORE
選擇儲存在棧頂的,由AC_LANG_SAVE設定的語言,并且把它從棧頂删除。本宏等價于運作在最後被調用的 AC_LANG_SAVE之前最近的AC_LANG_C、AC_LANG_CPLUSPLUS或者 AC_LANG_FORTRAN77。
調用本宏的次數不要多于調用AC_LANG_SAVE的次數。
宏: AC_REQUIRE_CPP
确認已經找到了目前用于測試的預處理器。本宏根據目前選擇的語言,以AC_PROG_CPP或者AC_PROG_CXXCPP 為參數調用AC_REQUIRE(參見首要的宏)。
測試的結果
一旦configure确定了某個特征是否存在,它将如何記錄這一資訊?這裡有四種記錄方式:定義一個C預處理器符号、在輸出檔案中設定一個變量、為将來運作configure而把結果儲存到一個緩存檔案中,以及列印一條消息以便讓使用者知道測試的結果。
定義C預處理器符号
對一個特征的檢測的常見回應是定義一個表示測試結果的C預處理器符号。這是通過調用AC_DEFINE 或者AC_DEFINE_UNQUOTED來完成的。
在預設狀态下,AC_OUTPUT把由這些宏定義的符号放置到輸出變量DEFS中,該變量為每個定義了的符号添加一個選項`-Dsymbol= value'。與Autoconf第1版不同,在運作時不定義DEFS變量。為了檢查Autoconf宏是否已經定義了某個C預處理器符号,就檢查适當的緩存變量的值,例子如下:
AC_CHECK_FUNC(vprintf, AC_DEFINE(HAVE_VPRINTF))
if test "$ac_cv_func_vprintf" != yes; then
AC_CHECK_FUNC(_doprnt, AC_DEFINE(HAVE_DOPRNT))
fi
如果已經調用了AC_CONFIG_HEADER,那麼就不是建立DEFS,而是由AC_OUTPUT 建立一個頭檔案,這是通過在一個暫時檔案中把正确的值替換到#define語句中來實作的。關于這種輸出的詳情,請參見配置頭檔案。
宏: AC_DEFINE (variable [, value [, description]])
定義C預處理器變量variable。如果給出了value,就把variable設定成那個值(不加任何改變),否則的話就設定為1。value不應該含有新行,同時如果你沒有使用AC_CONFIG_HEADER,它就不應該含有任何`#'字元,這是因為make将删除它們。為了使用shell變量(你需要使用該變量定義一個包含了 m4引用字元`['或者`]'的值),就使用AC_DEFINE_UNQUOTED。隻有在你使用AC_CONFIG_HEADER的時候, description才有用。在這種情況下,description被作為注釋放置到生成的`config.h.in'的宏定義之前;不必在 `acconfig.h'中提及該宏。下面的例子把 C預處理器變量EQUATION的值定義成常量字元串`"$a > $b"':
autoconf手冊(六)
AC_DEFINE(EQUATION, "$a > $b")
宏: AC_DEFINE_UNQUOTED (variable [, value [, description]])
類似于AC_DEFINE,但還要對variable和value進行三種shell替換(每種替換隻進行一次):變量擴充(`$'),指令替換(``'),以及反斜線傳義符(`/')。值中的單引号和雙引号沒有特殊的意義。在variable或者value是一個shell變量的時候用本宏代替 AC_DEFINE。例如:
AC_DEFINE_UNQUOTED(config_machfile, "${machfile}")
AC_DEFINE_UNQUOTED(GETGROUPS_T, $ac_cv_type_getgroups)
AC_DEFINE_UNQUOTED(${ac_tr_hdr})
由于Bourne shell在文法上的特異性,不要用分号來分隔對AC_DEFINE或者AC_DEFINE_UNQUOTED的調用和其它的宏調用或者shell代碼;這将在最終的configure腳本中導緻文法錯誤。你既可以使用空格,也可以使用換行。就是這樣:
AC_CHECK_HEADER(elf.h, AC_DEFINE(SVR4) LIBS="$LIBS -lelf")
或者:
AC_CHECK_HEADER(elf.h,
AC_DEFINE(SVR4)
LIBS="$LIBS -lelf")
而不是:
AC_CHECK_HEADER(elf.h, AC_DEFINE(SVR4); LIBS="$LIBS -lelf")
設定輸出變量
記錄測試結果的一種方式是設定輸出變量,該變量是shell變量,它的值将被替換到configure輸出的檔案中。下面的兩個宏建立新的輸出變量。關于總是可用的輸出變量的清單,參見預定義輸出變量。
宏: AC_SUBST (variable)
從一個shell變量建立一個輸出變量。讓AC_OUTPUT把變量variable替換到輸出檔案中(通常是一個或多個 `Makefile')。這意味着AC_OUTPUT将把輸入檔案中的`@[email protected]'執行個體替換成調用AC_OUTPUT時shell變量 variable的值。variable的值不能包含新行。
宏: AC_SUBST_FILE (variable)
另一種從shell變量建立輸出變量的方式。讓AC_OUTPUT把由shell變量variable給出的檔案名的檔案的内容(不進行替換)插入到輸出檔案中。這意味着AC_OUTPUT将在輸出檔案中(比如`Makefile.in')把輸入檔案中的`@[email protected]'執行個體替換為調用 AC_OUTPUT時shell變量variable的值指明的檔案的内容。如果沒有檔案可以插入,就把變量設定成`/dev/null'。
本宏用于把包含特殊依賴性或者為特殊主機或目标機準備的其它make指令的`Makefile'片斷插入 `Makefile'。例如,`configure.in'可以包含:
AC_SUBST_FILE(host_frag)dnl
host_frag=$srcdir/conf/sun4.mh
那麼`Makefile.in'就應該包含:
@[email protected]
緩存結果
為了避免在各種configure腳本中重複地對相同的特征進行檢查(或者重複地運作同一個腳本), configure把它的檢查的許多結果儲存在緩存檔案。如果在configure腳本運作時,它找到了緩存檔案,它就從中讀取從前運作的結果并且不再重新運作這些檢查。是以,configure将比每次都運作所有的檢查要快得多。
宏: AC_CACHE_VAL (cache-id, commands-to-set-it)
确認由cache-id指定的檢查的結果是可用的。如果檢查的結果在讀入的緩存檔案中,并且configure 沒有用`--quiet'或者`--silent'調用,就列印一條消息以說明該結果已經被緩存了;否則,就運作 shell指令commands-to-set-it。這些指令不應具有副作用,但設定變量cache-id除外。它們尤其不應該調用 AC_DEFINE;緊随與對AC_CACHE_VAL的調用之後的代碼應該根據緩存的值調用AC_DEFINE 作這件事。此外,它們不應該列印任何消息,比如說使用AC_MSG_CHECKING;應該在調用AC_CACHE_VAL 之前列印,以便不論測試的結果是從緩存中檢索而得到的,還是通過運作shell指令而确定的,都會列印消息。如果是運作 shell指令以确定值,該值将在configure建立它的輸出檔案之前被儲存到緩存檔案中。關于如何選擇 cache-id變量的名稱,參見緩存變量名。
宏: AC_CACHE_CHECK (message, cache-id, commands)
這是一個更詳盡地處理了列印消息的AC_CACHE_VAL版本。本宏為這些宏的最常見的應用提供了便捷的縮寫。它為message調用 AC_MSG_CHECKING,而後以cache-id和commands為參數調用AC_CACHE_VAL,最後以cache-id為參數調用 AC_MSG_RESULT。
宏: AC_CACHE_LOAD
從已經存在的緩存檔案中裝入值,如果找不到緩存檔案,就建立一個新的緩存檔案。本宏由AC_INIT自動調用。
宏: AC_CACHE_SAVE
把所有緩存的值重新整理到緩存檔案中。本宏由AC_OUTPUT自動調用,但在configure.in的關鍵點調用 AC_CACHE_SAVE是十分有用的。假如配置腳本中途失敗(abort)了,這些關鍵點仍然可以緩存一部分結果。
緩存變量名
緩存變量的名字應該符合如下格式:
package-prefix_cv_value-type_specific-value[_additional-options]
例如,`ac_cv_header_stat_broken'或者`ac_cv_prog_gcc_traditional'。變量名的各個部分為:
package-prefix
你的包或者組織的縮寫;除了為了友善而使用小寫字母以外,與你使用的作為本地Autoconf宏的開頭的字首一樣。對于由釋出的Autoconf宏使用的緩存值,它是`ac'。
_cv_
表明本shell變量是一個緩存值。
value-type
關于緩存值類别的慣例,以生成一個合理的命名系統。在Autoconf中使用的值在宏名中列出。
specific-value
指明本測試應用于緩存值類的那個成員。例如,那個函數(`alloca')、程式(`gcc')或者輸出變量(`INSTALL')。
additional-options
給出應用本測試的特定成員的任何特殊行為。例如,`broken'或者`set'。如果沒有用,名字的這個部分可能被忽略掉。
賦予緩存變量的值不能含有新行。通常,它們的是将是布爾(`yes'或`no')或者檔案名或者函數名;是以,這并不是一個重要的限制。
緩存檔案
緩存檔案是一個緩存了在一個系統上進行配置測試的結果,以便在配置腳本和配置的運作之間共享的shell腳本。它對于其他系統來說是沒有用的。如果它的内容因為某些原因而變得無效了,使用者可以删除或者編輯它。
在預設情況下,configure把`./config.cache'作為緩存檔案,如果它還不存在,就建立它。 configure接受選項`--cache-file=file'以使用不同的緩存檔案;這就是configure在調用子目錄中的configure 腳本時所作的工作。關于使用宏AC_CONFIG_SUBDIRS在子目錄中進行配置的資訊,參見 在子目錄中配置其它包。
給出`--cache-file=/dev/null'會關閉緩存,這是為調試configure提供的。隻有在調用`config.status'時給出選項`--recheck',這将導緻它重新運作configure,它才會注意到緩存檔案。如果你預計需要一個長的調試時期,你還可以通過在 `configure.in'的開頭重新定義緩存宏而關閉對configure腳本的裝入和儲存:
define([AC_CACHE_LOAD], )dnl
define([AC_CACHE_SAVE], )dnl
AC_INIT(whatever)
... rest of configure.in ...
試圖為特定的系統類型釋出緩存檔案是錯誤的。這裡存在太多的導緻錯誤的空間,并帶來太多的用于維護它們的管理開銷。對于任何不能被自動猜測出來的特征,應使用規範系統類型和連接配接檔案的方法(參見手工配置)。
在特定系統中,每當有人運作configure腳本時,緩存檔案将逐漸積累起來;緩存檔案在一開始并不存在。運作configure會把新的緩存結果與現存的緩存檔案結合起來。為了讓它透明地工作,隻要每次都使用相同的C編譯器,站點初始化(site initialization)腳本可以指定一個站點範圍(site-wide)的緩存檔案以代替預設的緩存檔案。(參見設定本地預設值)。
如果你的配置腳本,或者configure.in中的宏調用,偶爾導緻配置過程的失敗,在幾個關鍵點進行緩存可能是有用的。在有希望修正導緻上次運作的錯誤的時候,這樣做将減少重新運作configure腳本的時間。
... AC_INIT, etc. ...
dnl checks for programs
AC_PROG_CC
AC_PROG_GCC_TRADITIONAL
... more program checks ...
AC_CACHE_SAVE
dnl checks for libraries
AC_CHECK_LIB(nsl, gethostbyname)
AC_CHECK_LIB(socket, connect)
... more lib checks ...
AC_CACHE_SAVE
dnl Might abort...
AM_PATH_GTK(1.0.2, , exit 1)
AM_PATH_GTKMM(0.9.5, , exit 1)
列印消息
configure腳本需要為運作它們的使用者提供幾種資訊。下列的宏為每種資訊以适當的方式列印消息。所有宏的參數都應該由shell雙引号括起來,以便shell可以對它們進行變量替換和反引号替換。你可以把消息用 m4引用字元括起來以列印包含括号的消息:
AC_MSG_RESULT([never mind, I found the BASIC compiler])
這些宏都是對shell指令echo的封裝。configure應該很少需要直接運作echo來為使用者列印消息。使用這些宏使得修改每種消息如何列印及何時列印變得容易了;這些修改隻需要對宏的定義進行就行了,而所有的調用都将自動地改變。
宏: AC_MSG_CHECKING (feature-description)
告知使用者configure正在檢查特定的特征。本宏列印一條以`checking '開頭,以`...' 結尾,而且不帶新行的消息。它必須跟随一條對AC_MSG_RESULT的調用以列印檢查的結果和新行。 feature-description應該是類似于 `whether the Fortran compiler accepts C++ comments'或者`for c89'的東西。
如果運作configure給出了選項`--quiet'或者選項`--silent',本宏什麼也不列印。
宏: AC_MSG_RESULT (result-description)
告知使用者測試的結果。result-description幾乎總是檢查的緩存變量的值,典型的值是`yes'、 `no'或者檔案名。本宏應該在AC_MSG_CHECKING之後調用,并且result-description 應該完成由AC_MSG_CHECKING所列印的消息。
如果運作configure給出了選項`--quiet'或者選項`--silent',本宏什麼也不列印。
宏: AC_MSG_ERROR (error-description)
告知使用者一條使configure不能完成的錯誤。本宏在标準錯誤輸出中列印一條錯誤消息并且以非零狀态退出 configure。error-description應該是類似于`invalid value $HOME for /$HOME'的東西。
宏: AC_MSG_WARN (problem-description)
告知configure的使用者可能出現的問題。本宏在标準錯誤輸出中列印消息;configure繼續向後運作,是以調用AC_MSG_WARN的宏應該為它們所警告的情況提供一個預設的(備份)行為。 problem-description應該是類似于`ln -s seems to make hard links'的東西。
下列兩個宏是AC_MSG_CHECKING和AC_MSG_RESULT的過時的替代版本。
宏: AC_CHECKING (feature-description)
除了在feature-description之後列印新行,本宏與AC_MSG_CHECKING相同。它主要用于列印對一組特征測試的整體目的的描述,例如:
AC_CHECKING(if stack overflow is detectable)
宏: AC_VERBOSE (result-description)
除了應該在AC_CHECKING,而不是在AC_MSG_CHECKING之後調用,本宏與AC_MSG_RESULT相同;它在列印消息前首先列印一個tab。它已經過時了。
編寫宏
當你編寫了一個可以用于多個軟體包的特征測試時,最好用一個新宏把它封裝起來。下面是一些關于編寫 Autoconf宏的要求(instructions)和指導(guidelines)。
宏定義
Autoconf宏是用宏AC_DEFUN定義的,該宏與m4的内置define宏相似。除了定義一個宏,AC_DEFUN把某些用于限制宏調用順序的代碼添加到其中。(參見首要的宏)。
一個Autoconf宏像下面那樣定義:
AC_DEFUN(macro-name, [macro-body])
這裡的方括号并不表示可選的文本:它們應當原樣出現在宏定義中,以避免宏擴充問題(參見引用)。你可以使用`$1'、`$2'等等來通路傳遞給宏的任何參數。
為使用m4注釋,使用m4内置的dnl;它使m4放棄本行中其後的所有文本。因為在調用AC_INIT之前,所有的輸出都被取消,是以在`acsite.m4'和`aclocal.m4'中的宏定義之間不需要它。
關于編寫m4宏的更完整的資訊,參見GNU m4中的`如何定義新宏'。
宏名
所有Autoconf宏都以`AC_'起頭以防止偶然地與其它文本發生沖突。所有它們用于内部目的的shell變量幾乎全部是由小寫字母組成的,并且以 `ac_'開頭的名字。為了確定你的宏不會與現在的或者将來的Autoconf宏沖突,你應該給你自己的宏名和任何它們因為某些原因而需要使用的 shell變量添加字首。它可能是你名字的開頭字元,或者你的組織或軟體包名稱的縮寫。
大部分Autoconf宏的名字服從一個表明特征檢查的種類命名慣例。宏名由幾個單詞組成,由下劃線分隔,可以是最常見的,也可以是最特殊的。它們的緩存變量名服從相同的慣例。(關于它們的詳細資訊,參見緩存變量名)。
`AC_'之後的第一個單詞通常給出被測試特征的類别。下面是Autoconf為特殊測試宏使用的類别,它們是你很可能要編寫的宏。它們的全小寫形式還用于緩存變量。在可能的地方使用它們;如果不能,就發明一個你自己的類别。
C
C語言内置特征。
DECL
在頭檔案中對C變量的聲明。
FUNC
庫中的函數。
GROUP
檔案的UNIX組擁有者(group owner)。
HEADER
頭檔案。
LIB
C庫。
PATH
包括程式在内的,到檔案的全路徑名。
PROG
程式的基本名(base name)。
STRUCT
頭檔案中對C結構的定義。
SYS
作業系統特征。
TYPE
C内置或者聲明類型。
VAR
庫中的C變量。
在類别之後就是特定的被測試特征的名稱。宏名中所有的其它單詞指明了特征的特殊方面。例如,AC_FUNC_UTIME_NULL檢查用NULL指針調用utime函數時該函數的行為。
一個作為另一個宏的内部子程式的宏的名字應該以使用它的宏的名字開頭,而後是說明内部宏作了什麼的一個或多個單詞。例如,AC_PATH_X有内部宏AC_PATH_X_XMKMF和AC_PATH_X_DIRECT。
引用
由其他的宏調用的宏将被m4進行幾次求值;每次求值都可能需要一層引号以防止對宏或者m4 内置宏的不必要擴充,例如說`define'和`$1'。引号還需要出現在含有逗号的宏參數中,這是因為逗号把參數與參數分隔開來。還有,把所有含有新行和調用其它宏的宏參數引起來是一個好主意。
Autoconf把m4的引用字元從預設的``'和`''改為`['和`]',這是因為許多宏使用``'和`'',這不友善。然而,在少數情況下,宏需要使用方括号(通常在C程式文本或者正常表達式中)。在這些情況下,它們使用m4内置指令changequote暫時地把引用字元改為 `<<'和`>>'。(有時,如果它們不需要引用任何東西,它們就通過把引用字元設定成空字元串以完全關閉引用。)下面是一個例子:
AC_TRY_LINK(
changequote(<<, >>)dnl
<<#include
#ifndef tzname
extern char *tzname[];
#endif>>,
changequote([, ])dnl
[atoi(*tzname);], ac_cv_var_tzname=yes, ac_cv_var_tzname=no)
當你用新編寫的宏建立configure腳本時,仔細地驗證它以檢查你是否需要在你的宏之中添加更多的引号。如果一個或多個單詞在m4的輸出中消失了,你就需要更多的引号。當你不能确定的時候,就使用引号。
但是,還有放置了過多層的引号的可能。如果這發生了,configure腳本的結果将包含未擴充的宏。程式autoconf通過執行`grep AC_ configure'來檢查這個問題。
宏之間的依賴性
為了正确地工作,有些Autoconf宏要求在調用它們之前調用其它的宏。Autoconf提供了一種方式以確定在需要時,某個宏已經被調用過了,以及一種在宏可能導緻不正确的操作時給出警告的方式。
首要的宏
你編寫的宏可能需要使用從前有其它宏計算出來的結果。例如,AC_DECL_YYTEXT要檢驗flex或 lex的輸出,是以它要求首先調用AC_PROG_LEX以設定shell變量LEX。
比強制宏的使用者跟蹤宏以前的依賴性更好的是,你可以使用宏AC_REQUIRE以自動地完成這一任務。 AC_REQUIRE可以確定隻在需要的時候調用宏,并且隻被調用一次。
宏: AC_REQUIRE (macro-name)
如果還沒有調用m4宏macro-name,就調用它(不帶任何參數)。確定macro-name 用方括号引起來了。macro-name必須已經用AC_DEFUN定義了,或者包含一個對AC_PROVIDE 的調用以指明它已經被調用了。
一個替代AC_DEFUN的方法是使用define并且調用AC_PROVIDE。因為這個技術并不防止出現嵌套的消息,它已經是過時的了。
宏: AC_PROVIDE (this-macro-name)
記錄this-macro-name已經被調用了的事實。this-macro-name應該是調用AC_PROVIDE的宏的名字。一個擷取它的簡單方式是從m4内置變量$0中獲得,就像:
AC_PROVIDE([$0])
建議的順序
有些宏在都被調用的時候,一個宏就需要在另一個宏之前運作,但是它們并不要求調用另一個宏。例如,應該在任何運作C編譯器的宏之前調用修改了C編譯器行為的宏。在文檔中給出了許多這樣的依賴性。
當`configure.in'檔案中的宏違背了這類依賴性,Autoconf就提供宏AC_BEFORE以警告使用者。警告出現在從 `configure.in'建立configure的時候,而不是在運作configure的時候。例如,AC_PROG_CPP檢查C編譯器是否可以在給出`-E'的情況下運作C預處理器。因而應該在任何改變将要使用的C編譯器的宏之後調用它 。是以AC_PROG_CC包含:
AC_BEFORE([$0], [AC_PROG_CPP])dnl
如果在調用AC_PROG_CC時,已經調用了AC_PROG_CPP,它就警告使用者。
宏: AC_BEFORE (this-macro-name, called-macro-name)
如果已經調用了called-macro-name,就讓m4在标準錯誤輸出上列印一條警告消息。 this-macro-name應該是調用AC_BEFORE的宏的名字。macro-name必須已經用 AC_DEFUN定義了,或者包含一個對AC_PROVIDE的調用以指明它已經被調用了。
過時的宏
配置和移植技術已經演化了好些年了。對于特定的問題,通常已經提出了更好的解決辦法,或者同類的方法(ad-hoc approaches)已經被系統化了。結果就是有些宏現在已經被認為是過時了;它們仍然能工作,但不再被認為是最佳選擇。 Autoconf提供了宏AC_OBSOLETE,當使用者使用過時的宏時,就在生成configure腳本的時候對使用者提出警告,以鼓勵他們跟上潮流。一個調用執行個體是:
AC_OBSOLETE([$0], [; use AC_CHECK_HEADERS(unistd.h) instead])dnl
宏: AC_OBSOLETE (this-macro-name [, suggestion])
讓m4在标準錯誤輸出上列印一條消息以警告this-macro-name是過時的,并且給出調用過時的宏的檔案名和行号。this-macro- name應該是調用AC_OBSOLETE的宏的名字。如果給出了suggestion,就在警告消息的末尾列印它;例如,它可以建議用某個宏來代替 this-macro-name。
手工配置
有幾種特征不能通過運作測試程式而自動猜測出來。例如,目标檔案格式的細節,或者需要傳遞給編譯器或連接配接器的特殊選項。你可以使用同類手段(ad-hoc means)來檢查這類特征,比如說讓configure檢查uname程式的輸出,或者尋找僅僅在特定系統中出現的庫。然而,Autoconf為處理不可猜測的特征提供了統一的手段。
指定系統的類型
類似與其它GNU configure腳本,Autoconf生成的configure腳本可以根據系統類型的規範名 (canonical name)做出決定,該規範系統名的形式為:
cpu-company-system
configure通常可以猜測出它正在運作的系統類型的規範名。為此,它運作一個稱為config.guess 的腳本,該腳本使用uname或者預定義的C預處理器符号來推斷系統類型的規範名。
另外,使用者可以通過給configure傳遞指令行參數而指定系統類型。在交叉編譯時必須這樣作。在大多數交叉編譯的複雜情況下,要涉及到三種系統類型。用于指定它們的選項是:
--build=build-type
對包進行配置和編譯的系統類型(很少用到);
--host=host-type
包将運作的系統類型;
--target=target-type
包中任何編譯器工具将生成的代碼的系統類型。
如果使用者給configure一個非選項參數,如果使用者沒有顯式地用選項指明,它就作為預設情況表示主機類型、目标類型和建立系統類型。如果給出了主機類型而沒有給出目标類型和建立類型,目标類型和建立類型就被設定為主機類型。如果你正在交叉編譯,你仍然必須在configure的指令行中給出你使用的交叉工具(cross-tools)的名稱,特别是C編譯器。例如,
CC=m68k-coff-gcc configure --target=m68k-coff
configure能夠識别許多系統類型的短别名;例如,可以在指令行中給出`decstation'而不是 `mips-dec-ultrix4.2'。configure運作一個被稱為config.sub的腳本以使系統類型别名規範化。
autoconf手冊(七)
擷取規範的系統類型
下列的宏使得configure腳本可以獲得系統類型。它們運作shell腳本config.guess以确定使用者在指令行中沒有給出的、它們需要的關于主機、目标和建立類型的所有值。它們運作config.sub對使用者給出的任何别名進行規範化。如果你使用這些宏,你必須把這兩個shell腳本與你的源代碼一同釋出。關于 AC_CONFIG_AUX_DIR的資訊,你可以通過該宏設定configure查找這些腳本的目錄,請參見建立輸出檔案。如果你沒有使用這些宏中的任意一個,configure 就忽略任何傳遞給它的`--host'、`--target'和`--build'選項。
宏: AC_CANONICAL_SYSTEM
檢測系統類型并把輸出變量設定成規範的系統類型。關于該宏設定變量的細節,參見系統類型變量。
宏: AC_CANONICAL_HOST
隻執行AC_CANONICAL_SYSTEM中關于主機類型功能的子集。對于不是編譯工具鍊(compiler toolchain)一部分的程式,這就是所需要的全部功能。
宏: AC_VALIDATE_CACHED_SYSTEM_TUPLE (cmd)
如果緩存檔案與目前主機、目标和建立系統類型不一緻,就執行cmd或者列印一個預設的錯誤消息。
系統類型變量
在調用了AC_CANONICAL_SYSTEM之後,下列輸出變量包含了系統類型資訊。在調用了AC_CANONICAL_HOST 之後,隻設定了下列host變量。
build,host,target
規範系統名稱;
build_alias,host_alias,target_alias
如果使用了config.guess,就是使用者指定的名稱或者規範名稱;
build_cpu,build_vendor,build_os
host_cpu,host_vendor,host_os
target_cpu,target_vendor,target_os
為友善而提供的規範名稱的獨立部分。
使用系統類型
你将如何使用規範的系統類型?通常,你在`configure.in'中的一個或多個case語句中使用它來選擇系統特定的C檔案。而後把那些使用基于系統名的檔案名的檔案連接配接到諸如`host.h'或`target.c'的普通的檔案上。case語句模型允許使用shell通配符對多種情況進行編組,就像下面的片斷:
case "$target" in
i386-*-mach* | i386-*-gnu*) obj_format=aout emulation=mach bfd_gas=yes ;;
i960-*-bout) obj_format=bout ;;
esac
宏: AC_LINK_FILES (source...,dest...)
使得AC_OUTPUT把每個存在檔案的source連接配接到對應連接配接名dest。如果可能,建立一個符号連接配接,否則就建立硬連接配接。dest和source應該是相對于頂層源代碼目錄或者建立目錄的相對路徑。可以多次調用本宏。
例如,下列調用:
AC_LINK_FILES(config/${machine}.h config/${obj_format}.h,host.h object.h)
在目前目錄中建立`host.h',它是一個到`srcdir/config/${machine}.h'的連接配接,并且建立`object.h',它是一個到`srcdir/config/${obj_format}.h'的連接配接。
你還可以使用主機系統類型以尋找交叉編譯工具。關于完成該任務的宏AC_CHECK_TOOL的資訊,參見對普通程式和檔案的檢查。
站點配置
configure腳本支援幾種本地配置決策方式。它們是使用者指明外部軟體的位置,包括或除去可選的特征,以修改過的名稱安裝的程式,以及為configure選項設定預設值的手段。
與外部軟體一起工作
有些軟體包需要,或者可選地使用其它已經安裝的軟體包。使用者可以把指令行選項傳遞給configure 以指明使用那個外部軟體。選項采用下列形式之一:
--with-package[=arg]
--without-package
例如,`--with-gnu-ld'的意思是使用GNU連接配接器而不是任何其它連接配接器。`--with-x'的意思是使用X Window系統。
使用者可以給出包名加`='加參數的指令行參數。`no'是關于包的預設參數;它表示不使用包。既不是`yes'又不是`no'的參數将包含其它包的名字或者版本号,以便更精确地指定本程式可以與之協同工作的包。如果沒有給出參數,`--without-package'的預設參數為`yes'。 `--without-package'等價于`--with-package=no'。
configure腳本并不對它們不支援的`--with-package'選項發出警告。本特征允許頂層目錄中的configure腳本配置一個包含多個包的源代碼樹。在包支援不同的選項的時候,不會因為給出了隻有一部分包支援的選項而導緻不必要的錯誤消息。一個不幸的副作用是選項的拼寫錯誤就不能被檢查出來了。迄今為止還沒有處理該問題的更好辦法。
對于每個可能使用的外部軟體包,`configure.in'都應該調用AC_ARG_WITH以檢測 configure的使用者是否要求使用它。确定在預設狀态下,是使用還是不使用每個包,以及那個參數是合法的,是你的任務。
宏: AC_ARG_WITH (package,help-string [,action-if-given [,action-if-not-given]])
如果使用者以選項`--with-package'或者`--without-package'調用 configure,就運作shell指令action-if-given。如果兩個選項都沒有給出,就運作shell指令 action-if-not-given。名字package給出了本程式應該與之協同工作的其它軟體包。它應該僅僅由字母、數字和破折号(dashes)組成。
shell指令action-if-given可以通過shell變量withval得到選項的參數,該變量的值實際上就是把 shell變量with_package的值中的所有`-'字元替換為`_'而得的。如果你願意,可以使用變量with_package。
參數help-string是對選項的描述,它看起來應該像:
--with-readline support fancy command line editing
如果需要給出更多的細節,help-string可能多于一行。隻要確定`configure --help'中的列的排列就可以了。不要在求助字元串中使用tab。你将需要用`['和`]'包圍它以生成前導空格。
宏: AC_WITH (package,action-if-given [,action-if-not-given])
這是不支援求助字元串的AC_ARG_WITH的過時版本。
選擇包選項
如果軟體包含有可選的編譯時(compile-time)特征,使用者就可以在調用configure時使用指令行選項來指明是否編譯它們。選項采用如下形式之一:
--enable-feature[=arg]
--disable-feature
這些選項允許使用者選擇可選的選項進行建立和安裝。`--enable-feature'選項永遠不要使特征的行為變得不同或者導緻一個特征代替另一個特征。它們隻應該導緻程式的一部分被建立而另一部分不建立。
使用者可以通過在特征名之後添加`='和參數來給出參數。給出參數`no'表示不能使用該特征。一個帶有參數的特征看起來就像`--enable-debug=stabs'。如果沒有給出參數,它的預設值就是`yes'。`-- disable-feature'等價于 `--enable-feature=no'。
configure腳本并不對它們所不支援的`--enable-feature'選項發出警告。本特征允許頂層目錄中的configure腳本配置一個包含多個包的源代碼樹。在包支援不同的選項的時候,不會因為給出了隻有一部分包支援的選項而導緻不必要的錯誤消息。一個不幸的副作用是選項的拼寫錯誤就不能被檢查出來了。迄今為止還沒有處理該問題的更好辦法。
對于每個可選的特征,`configure.in'都應該調用AC_ARG_ENABLE以檢測configure 的使用者是否要求把該特征包含進來。确定在預設情況下,每個特征是否被包含進來,以及那些選項是合法的,是你的任務。
宏: AC_ARG_ENABLE (feature,help-string [,action-if-given [,action-if-not-given]])
如果使用者以選項`--enable-feature'或者`--disable-feature'調用 configure,就運作shell指令action-if-given。如果兩個選項都沒有給出,就運作shell指令 action-if-not-given。名稱feature表示可選的使用者級功能。它應該僅僅由字母、數字和破折号(dashes)組成。
shell指令可以通過通路shell變量enableval來得到選項的參數,該變量的值實際上就是把shell變量 enable_feature的值中所有的`-'字元替換成`_'而得到的。如果你願意,可以使用變量enable_feature。help- string參數類似于 AC_ARG_WITH中相應的參數(參見與外部軟體一起工作)。
宏: AC_ENABLE (feature,action-if-given [,action-if-not-given])
這是不支援求助字元串的AC_ARG_ENABLE的過時版本。
配置站點細節
有些軟體包需要複雜的與站點相關(site-specific)的資訊。例如用于某種服務、公司名稱和email聯系位址的主名(host names)。因為有些配置腳本是通過Metaconfig方式互動地詢問這些資訊生成的,人們有時對于按非互動方式,由Autoconf生成配置腳本如何擷取這些資訊感到困惑。
這些站點配置資訊應該被儲存在一個僅僅由使用者,而不是程式,編輯的檔案中。檔案的位置既可以基于 prefix變量,也可以是一個标準的位置,比如說使用者的home目錄。它甚至可能通過一個環境變量給出。程式應該在運作時,而不是在編譯時,檢查那個檔案。運作時配置對于使用者來說更為友善,并且使得配置過程比在配置時擷取這些資訊要簡單。關于存放資料檔案的地點的詳細資訊,參見GNU編碼标準中的 `為安裝目錄而提供的變量'。
在安裝的時候改變程式的名稱
Autoconf支援在安裝程式的時候修改程式的名稱。為了使用這些變換,`configure.in'必須調用宏 AC_ARG_PROGRAM。
宏: AC_ARG_PROGRAM
把對被安裝的程式的名稱進行替換的sed指令序列存入輸出變量program_transform_name中。
如果把下列任意選項傳遞給了configure,程式名就據此進行變換。否則,如果已經調用了AC_CANONICAL_SYSTEM并且`-- target'的值給出了與主機類型(用`--host'給出的,或者是在config.sub中設定的預設值)不同的類型,就把末尾附加了破折号的目标類型作為字首。否則,就不進行程式名變換。
轉換選項
你可以把下列指令行選項傳遞給configure以指定名稱的轉換:
--program-prefix=prefix
為名稱添加字首prefix;
--program-suffix=suffix
為名稱添加字尾suffix;
--program-transform-name=expression
對名字作sed替換expression。
轉換的例子
這些變換對于作為交叉編譯開發環境的一部分的程式是有用的。例如,用`--target=i960-vxworks'選項配置的運作在Sun 4上的交叉彙編器通常以`i960-vxworks-as'為名稱進行安裝,而不是以`as'為名安裝,該名稱将于原來的Sun 4彙編器混淆。
如果你不希望安裝在你的系統上的GNU程式遮蔽具有相同名稱的其它程式,你可以強行要求程式名以`g'開頭。例如,如果你使用`--program- prefix=g'來配置GNU diff,那麼在你運作`make install' 的時候,它就安裝到`/usr/local/bin/gdiff'。
作為更複雜的例子,你可以使用
--program-transform-name='s/^/g/; s/^gg/g/; s/^gless/less/'
在源代碼樹中的大部分程式的名字之前附加`g',已經含有一個`g'的程式,諸如gdb,和不是GNU程式的程式,比如說less和lesskey,除外。(它假定你有一個包含了設定成使用這些特征的程式的源代碼樹。)
同時安裝某些程式的多個版本的一種方法是為其中一個程式的名稱或為所有程式的名稱附加版本号。例如,如果你還希望把 Autoconf版本1保留一段時間,你可以使用`--program-suffix=2'來配置Autoconf第2版,并且以名稱 `/usr/local/bin/autoconf2'、`/usr/local/bin/autoheader2'等等來安裝程式。
轉換的規則
下面是如何在`Makefile.in'中使用變量program_transform_name:
[email protected]_transform_name@
install: all
$(INSTALL_PROGRAM) myprog $(bindir)/`echo myprog|sed '$(transform)'`
uninstall:
rm -f $(bindir)/`echo myprog|sed '$(transform)'`
如果你要安裝多個程式,你可以通過一個循環來完成:
PROGRAMS=cp ls rm
install:
for p in $(PROGRAMS); do /
$(INSTALL_PROGRAM) $$p $(bindir)/`echo $$p|sed '$(transform)'`; /
done
uninstall:
for p in $(PROGRAMS); do /
rm -f $(bindir)/`echo $$p|sed '$(transform)'`; /
done
是否在文檔檔案中進行變換(Texinfo或者man)是個麻煩的問題;由于名稱變換的幾個原因,好像不存在完美的答案。文檔對于特定的結構來說并不特殊,并且Texinfo檔案與系統文檔并不沖突。但它們可能與同一檔案的早期版本沖突,而且 man手冊有時與系統文檔沖突。作為一個折衷,可能最好是對man手冊進行名稱替換而不對Texinfo手冊進行替換。
設定站點預設值
Autoconf生成的configure腳本允許你的站點(site)為某些配置值提供預設值。你可以通過建立站點範圍(site-wide)或者系統範圍(system-wide)的初始化檔案來達到這個目的。
如果設定了環境變量CONFIG_SITE,configure就把它的值作為讀入的shell腳本的名稱。否則如果 `prefix/share/config.site'存在,它就讀入該腳本,否則如果`prefix/etc/config.site'存在,它就讀入該腳本。是以,如果出現沖突,在機器特定檔案中的設定将覆寫那些與機器獨立的檔案中的設定。
站點檔案(site files)可以是任意shell腳本,但隻能包含某種适于包含在其中的代碼。因為configure在它讀入所有站點檔案之後讀取任何緩存檔案,站點檔案可以定義一個預設的緩存檔案以便在本系統中運作的所有Autoconf生成的 configure之間共享。如果你在站點檔案中設定了預設緩存檔案,那麼再在那個站點檔案中設定輸出變量 CC就是個好主意,這是因為緩存檔案僅僅對特定的編譯器來說是合法的,但許多系統還有好幾個可用的編譯器。
你可以在站點檔案中檢驗或者覆寫由指令行選項設定的值;與選項對應的shell變量的名稱與選項的名字的唯一差別是選項名中所有的破折号應變換成的下劃線。選項`--without-'和`--disable-'是個例外,出現它們就如同出現對應的 `--with-'或者`--enable-'并且把值設定為`no'。是以, `--cache-file=localcache'把變量cache_file的值設定為`localcache'; `--enable-warnings=no'或者`--disable-warnings'把變量enable_warnings 的值設定為`no';`--prefix=/usr'把變量prefix設定為`/usr';等等。
如果你需要為其它輸出變量設定與預設值不同的值(你通常不得不在指令行中重複地進行設定),比如說CFLAGS,站點檔案就是進行這種設定的好地方。如果你為prefix或者exec_prefix設定了非預設值(你放置站點檔案的地方),如果你用環境變量CONFIG_SITE給出了站點檔案,你就可以在站點檔案中設定這些非預設值。
你可以在站點檔案中設定一些緩存值。如果你正在進行交叉編譯,這樣做就是有用的,以避免對需要運作測試程式的特征進行檢查。你可以為 `prefix/etc/config.site'中的系統正确地設定這些值來“預備緩存(prime cache)”。為了找到你要設定的緩存變量名,可以在受到影響的configure腳本中尋找帶有`_cv_'的shell變量,也可以在 Autoconf m4源代碼中尋找這些宏。
緩存檔案将十分謹慎而不至于覆寫任何在站點檔案中設定的變量。類似地,你不應該在站點檔案中覆寫指令行選項。你的代碼應該在修改諸如prefix和cache_file的變量之前,檢查它們的預設值(就是在靠近configure開頭的地方設定的值)。
下面是一個例子檔案`/usr/share/local/gnu/share/config.site'。(如果沒有把CONFIG_SITE設定成其它檔案,)指令`configure --prefix=/usr/share/local/gnu' 将讀入該檔案。
# config.site for configure
# Change some defaults.
test "$prefix" = NONE && prefix=/usr/share/local/gnu
test "$exec_prefix" = NONE && exec_prefix=/usr/local/gnu
test "$sharedstatedir" = '${prefix}/com' && sharedstatedir=/var
test "$localstatedir" = '${prefix}/var' && localstatedir=/var
#
# Give Autoconf 2.x generated configure scripts a shared default
# cache file for feature test results,architecture-specific.
if test "$cache_file" = ./config.cache; then
cache_file="$prefix/var/config.cache"
# A cache file is only valid for one C compiler.
CC=gcc
fi
運作configure腳本
下面是關于如何配置使用configure腳本的軟體包的說明,适用于包中的`INSTALL'檔案。你可能要使用的普通文本的`INSTALL'與Autoconf一同發行。
重新建立一個配置
configure腳本建立一個名為`config.status'的檔案,用它描述在包最後一次進行配置時給出的配置選項。該檔案是一個shell腳本檔案,如果運作它,将重新建立相同的配置。
你可以用`--recheck'選項調用`config.status'以更新它自身。如果你修改了configure,該選項是有用的,這是因為某些測試的結果可能會與上一次運作的結果不同。選項`--recheck'以與從前使用的參數相同的參數,再加上`--no-create'選項以防止 configure運作`config.status'并建立 `Makefile'和其它檔案,再加上`--no-recursion'選項以防止configure在子目錄中運作其它的configure,來重新運作configure。(這樣做是讓其它的`Makefile'規則可以在 `config.status'改變時運作它;關于一個例子,參見自動地重新建立)。
`config.status'還接受選項`--help',它列印`config.status'接受的選項的概述。還接受選項`--version',它列印用于建立生成`config.status'的configure腳本的 Autoconf的版本号。
`config.status'檢查幾個能夠改變它的行為的可選的環境變量:
變量: CONFIG_SHELL
用于運作帶有`--recheck'選項的configure的腳本。它必須是Bourne相容的。預設shell是`/bin/sh'。
變量: CONFIG_STATUS
為shell腳本提供的,用于記錄配置的檔案名。預設的檔案名是`./config.status'。該變量在一個包使用了另一個包的一部分,并且由于兩個包是分開維護的而不能把configure合成一個的時候有用。
以下的變量為分開釋出的包提供了一種共享由configure計算的結果的方式。如果某些包需要它們中某個包,可能是一個通用庫,所需要的特征的超集那麼這樣做就是有用的。這些變量允許一個`config.status'檔案建立由它的`configure.in'所指明的檔案之外的檔案,是以它就可以被用于不同的包。
變量: CONFIG_FILES
用于執行`@[email protected]'替換的檔案。預設的檔案在`configure.in'中作為參數提供給 AC_OUTPUT。
變量: CONFIG_HEADERS
用于替換C #define語句的檔案。預設的檔案作為參數提供給AC_CONFIG_HEADER;如果沒有調用那個宏,`config.status'就忽略本變量。
這些變量還允許你編寫隻重新生成一部分檔案的`Makefile'規則。例如,在上面給出的依賴性之中(參見自動地重新建立),在 `configure.in'發生改變時, `config.status'将運作兩次。如果你對此感到厭煩,你可以使得每次運作都僅僅重新生成關于那條規則的檔案。
config.h: stamp-h
stamp-h: config.h.in config.status
CONFIG_FILES= CONFIG_HEADERS=config.h ./config.status
echo > stamp-h
Makefile: Makefile.in config.status
CONFIG_FILES=Makefile CONFIG_HEADERS= ./config.status
(如果`configure.in'并不調用AC_CONFIG_HEADER,就不必在make規則中設定 CONFIG_HEADERS。)
關于Autoconf的問題
有時我們會遇到幾個關于Autoconf的問題。下面是被提及的一些問題。
釋出configure腳本
對發行由Autoconf生成的configure有什麼限制?它們是如何影響我那些使用它們的程式的?
關于由Autoconf生成的配置腳本是如何發行和如何被使用的,并沒有限制。在Autoconf第1版中,它們是服從GNU通用公共許可證的。我們仍然鼓勵軟體的作者按照諸如GPL的條款發行他們的作品,但Autoconf并不要求這樣做。
關于可能由configure使用的其它檔案,`config.h.in'服從你為你的`configure.in'而使用的任何版權規定,這是因為它是從那個檔案和公有檔案`acconfig.h'中派生出來的。當`config.sub'和 `config.guess'被用于由Autoconf生成的、允許你按照與你的軟體包其它部分相同的條款釋出的configure 腳本中時,它們就是GPL的一個例外。`install-sh'是來自于X Consortium并且是沒有版權的。
為什麼需要使用GNU m4?
為什麼Autoconf需要使用GNU m4?
許多m4的實作含有編碼性(hard-coded)的,對宏的大小和數量的限制,Autoconf超過了這些限制。它們還缺少一些内置宏,沒有它們,諸如Autoconf之類的複雜應用程式将難以應付,它們包括:
builtin
indir
patsubst
__file__
__line__
因為隻有軟體維護者需要使用Autoconf,并且因為GNU m4易于配置和安裝,需要安裝GNU m4 好像是合理的。許多GNU和其它自由軟體的維護者,因為他們更喜愛GNU工具,都已經安裝了大部分GNU工具。
autoconf手冊(八)
我如何解開死結?
如果Autoconf需要GNU m4并且GNU m4還有一個Autoconf configure腳本,
我如何解開這個死結?它好像是一個類似于雞和蛋的問題!
這實際上是一種誤解。雖然GNU m4帶有一個由Autoconf生成的configure腳本,但在運作腳本及安裝GNU m4的時候并不需要安裝Autoconf。隻有在你需要修改m4的configure 腳本的時候,這隻是少數幾個人(主要是它的維護者)必須去作的事,才需要Autoconf。
為什麼不使用Imake?
為什麼不用Imake來代替configure腳本?
有些人已經提出了這個問題,是以在改編之後,我把給他們的解釋寫在這裡。
下面是對Richard Pixley的問題的回答:
由Autoconf生成的腳本經常地在它以前從未設定過的機器上工作。這就是說,它善于推斷新系統的配置。而Imake不能做到。
Imake使用含有主機特定資料的通用資料庫。對X11來說,這種方法具有意義是因為釋出版本是由一個控制整個資料庫的總管機關管理的一組工具組成的。
GNU工具并不按這種方式發行。每個GNU工具都有一個維護者;這些維護者散布在世界各地。使用統一的資料庫将使維護變成噩夢。 Autoconf可能成為這類資料庫,但實際上它沒有。不是列舉主機的依賴性,它列舉的是程式的需求。
如果你把GNU套件看作一組本地工具,那麼問題就很相似了。但GNU開發工具可以作為交叉工具(cross tools)而在幾乎所有主機+目标機的組合中進行配置。所有的這些配置都可以同時(concurrency)安裝。它們甚至可以被配置成可以在不同主機上共享與主機獨立的資訊的形式。Imake不能處理這些問題。
Imake模闆是标準的一種形式。GNU編碼标準在沒有強加相同的限制的情況下,解決了相同的問題。
下面是一些由Per Bothner撰寫的進一步的解釋:
Imake的一個長處是它易于通過使用cpp的`#include'和宏機制生成大的Makefile。然而,cpp是不可程式設計的:它含有有限的條件工具,而不含有循環。而且cpp不能檢查它的環境。
所有這些問題可以通過使用sh而不是cpp來解決。shell是完全可程式設計的、含有宏替換、可以執行(或者編制)其它的shell腳本,并且可以檢查它的環境。
Paul Eggert更詳細地闡述:
使用Autoconf,安裝者不必假定Imake自身已經被安裝并且正常地工作了。這對于習慣使用Imake的人們來說,看起來不是突出的長處。但在許多主機上,并沒有安裝Imake或者預設的安裝不能很好地工作,為此,要求安裝Imake就阻礙了在這些主機上使用由Imake配置的軟體包。例如, Imake模闆和配置檔案可能不能适當地安裝在一個主機上,或者Imake建立過程可能會錯誤地假定所有的源代碼檔案都在一個大目錄樹中,或者Imake 配置可能使用某個編譯器而包或者安裝器需要使用另一個編譯器,或者包需要的Imake的版本号與系統支援的版本号不比對。這些問題在Autoconf中很少出現,這是因為包附帶屬于它自己的獨立配置處理器。
還有,Imake通常會在make和安裝者的C預處理器之間遇到難以預期的影響。這裡的基本問題是,C預處理器是為處理C程式而不是`Makefile' 而設計的。這對Autoconf來說問題小得多,它使用通用目的預處理器m4,并且包的作者(而不是安裝者)以标準的方式進行預處理。
最後,Mark Eichin解釋道:
Imake還不是完全可擴充的。為了把新特征添加到Imake中,你需要提供你自己的項目模闆,并且複制已經存在的特征的主要部分。這意味着對于複雜的項目來說,使用由買主提供的(vendor-provided)Imake模闆不能提供任何平衡作用--這是因為它們不包括你自己的項目的任何東西(除非它是一個X11程式)。
但是,另一方面:
一個Imake勝過configure的長處是: `Imakefile'總是趨向于比`Makefile.in'簡短(同樣地,備援較少)。但是,這兒有一個修正的方法--至少對于Kerberos V5樹來說,我們已經在整個樹中進行了修改以調用通用的 `post.in'和`pre.in' `Makefile'片斷。這意味着大部分通用的東西,即使它們通常是在configure中設定的,也不必複制。
從版本1中更新
Autoconf第2版基本上與第1版是向後相容的。但是,它給出了作某些事的更好方法,并且不再支援版本1中一些醜陋的東西。是以,根據你的 `configure.in'檔案的複雜性,你可能必須作一些手工的工作以更新到版本2。本章指出了一些在更新的時候需要注意的問題。還有,可能你的 configure腳本可以從版本2中的新特征中獲得一些好處;在Autoconf釋出包中的`NEWS'檔案概括了改變的部分。
首先,确認你安裝了1.1版或者更高版本的GNU m4,最好是1.3版或者更高版本。在1.1版之前的版本含有bug 以至于它不能與Autoconf版本2一同工作。版本1.3及其後的版本比早期的版本更快一些,這是因為1.3版的GNU m4 對轉換(diversions)進行了更有效的實作并且能夠在可以快速讀回的檔案中當機(freeze)它的内部狀态。
改變了的檔案名
如果你随Autoconf一起安裝了`aclocal.m4'(相對于特定軟體包的源代碼目錄中的`aclocal.m4'),你必須把它重命名為`acsite.m4'。參見用autoconf建立configure。
如果你與你的軟體包一同釋出`install.sh',就把它重命名為`install-sh'以便make的内置規則不會無意地從該檔案建立一個稱為`install'的檔案。AC_PROG_INSTALL将尋找這兩個名字的腳本,但最好使用新名字。
如果你使用`config.h.top'或者`config.h.bot',你仍然可以使用它們,但如果你把它們混合到 `acconfig.h'之中,将減少你的麻煩。參見用autoheader建立`config.h.in'。
改變了的Makefile
在你的`Makefile.in'檔案中添加`@[email protected]'、`@[email protected]'和`@[email protected]',以便它們可以在configure運作的時候利用環境中的這些變量的值。這樣做不是必須的,但對使用者來說比較友善。
對于AC_OUTPUT的每個非`Makefile'的輸入檔案,你還應該添加一條含有 `@[email protected]'的注釋,以便輸出檔案将會包含一條注釋以說明它們是由configure生成的。自動地為每種人們在 AC_OUTPUT中輸出的檔案選擇正确的注釋文法需要做太多的工作。
把`config.log'和`config.cache'添加到你要在distclean目标中删除的檔案的清單中。
如果你的`Makefile.in'如下:
prefix = /usr/local
exec_prefix = ${prefix}
你必須把它修改成:
prefix = @[email protected]
exec_prefix = @[email protected]
不使用`@'字元的老式的對這些變量的替換行為已經被删除了。
改變了的宏
在Autoconf第2版中,重新命名了許多宏。你仍然可以使用舊名字,但新名字更清晰,并且易于找到相關文檔。關于為舊宏名提供新宏名的清單,參見陳舊的宏名。用autoupdate程式轉換你的`configure.in'以使用新的宏名。參見用autoupdate更新configure。
有些宏已經被能夠更好地完成工作的類似宏所代替,但在調用上并不相容。如果你在運作autoconf時受到了關于調用過時宏的警告,你可以安全地忽略它們,但如果你按照列印的建議替換過時的宏,你的configure腳本通常可以工作的更好。特别地,報告測試結果的機制已經改變了。如果你使用了echo 或者AC_VERBOSE(可能是通過AC_COMPILE_CHECK),如果你改用AC_MSG_CHECKING和AC_MSG_RESULT,你的configure腳本的輸出将更加美觀。參見列印消息。這些宏能夠更好地與緩存變量協同工作。參見緩存結果。
用autoupdate更新configure
程式autoupdate把使用Autoconf舊宏名的`configure.in'檔案更新為使用目前宏名的檔案。在Autoconf第2版中,大部分宏被重命名以使用一個更統一、更具有描述性的命名機制。關于對新的命名機制的描述,參見宏名。雖然舊宏名仍然可以工作(關于舊宏名和對應的新宏名的清單,參見陳舊的宏名),如果你更新它們以使用新的宏名,你可以使你的 `configure.in'檔案更加可讀并且易于使用目前的Autoconf文檔。
如果沒有給出參數,autoupdate就更新`configure.in',并且通過添加字尾`~' (或者在設定了環境變量SIMPLE_BACKUP_SUFFIX的時候,使用該環境變量的值)以備份原始版本。如果你帶參數調用autoupdate,它就讀入那個檔案而不是讀入`configure.in',并且把更新的檔案輸出到标準輸出。
autoupdate接受下列選項:
--help
-h
列印指令行選項的概述并且退出。
--macrodir=dir
-m dir
在目錄dir中,而不是在預設安裝目錄中尋找Autoconf宏檔案。你還可以把環境變量AC_MACRODIR設定成一個目錄;本選項覆寫該環境變量。
--version
列印autoupdate的版本号并且退出。
改變了的結果
如果你通過檢驗shell變量DEFS來檢驗以前測試的結果,你需要把這些檢驗替換為對那些測試的緩存變量的檢查。在configure運作的時候, DEFS不再存在;它僅僅在生成輸出檔案的時候才被建立。這種與第1版的不同是因為正确地對變量實行引用(quoting)實在太麻煩而且在每次調用 AC_DEFINE都要實行引用是低效的。參見緩存變量名。
例如,下面是為Autoconf第1版編寫的`configure.in'的片斷:
AC_HAVE_FUNCS(syslog)
case "$DEFS" in
*-DHAVE_SYSLOG*) ;;
*) # syslog is not in the default libraries. See if it's in some other.
saved_LIBS="$LIBS"
for lib in bsd socket inet; do
AC_CHECKING(for syslog in -l$lib)
LIBS="$saved_LIBS -l$lib"
AC_HAVE_FUNCS(syslog)
case "$DEFS" in
*-DHAVE_SYSLOG*) break ;;
*) ;;
esac
LIBS="$saved_LIBS"
done ;;
esac
這裡是為版本2編寫的方式:
AC_CHECK_FUNCS(syslog)
if test $ac_cv_func_syslog = no; then
# syslog is not in the default libraries. See if it's in some other.
for lib in bsd socket inet; do
AC_CHECK_LIB($lib, syslog, [AC_DEFINE(HAVE_SYSLOG)
LIBS="$LIBS $lib"; break])
done
fi
如果你通過在引号的後邊添加反斜線以處理AC_DEFINE_UNQUOTED中的bug,你需要删除它們。它現在以可以預期的方式工作,并且不需要特别地處理引号(處理反斜線)。參見設定輸出變量。
所有由Autoconf宏設定的布爾shell變量現在用`yes'來表示真值。雖然為了向後相容,有些宏使用空字元串表示假,大部分宏使用`no'來表示假。如果你依賴于shell變量用諸如1或者`t'來表示真,你就需要改變你的測試。
改變了的宏的編寫
在定義你自己的宏時,你現在應該使用AC_DEFUN而不是define。 AC_DEFUN自動調用AC_PROVIDE并且確定通過AC_REQUIRE調用該宏不會被其他宏所打斷,進而防止在螢幕上出現嵌套的 `checking...'消息。繼續按照老辦法行事沒有實際上的傷害,但它缺乏便利和吸引力。參見宏定義。
你可能把與Autoconf一同發行的宏作為如何解決問題的指南。看看它們的新版本将是一個好主意,因為風格已經有些改進并且它們利用了一些新的特征。
如果你利用未公開的(undocumented)Autoconf内部元素(宏、變量、變換(diversions))作了微妙的工作,就要檢查你是否需要修改些什麼以适應已經發生的變化。可能你甚至能夠用版本2中公開(officially)支援的技術來代替你的拼裝(kludging)。但也可能不能。
為了加快你自行編寫的特征測試,為它們添加緩存。看看你所有的測試是否足夠一般化,進而具有足夠的用途以把它們封裝到你可以共享的宏中去。
Autoconf的曆史
你可能會困惑,最初為什麼要編寫Autoconf?它是如何演變到今天的形式的?(為什麼它看起來就像大猩猩的吐沫?)如果你不困惑,那麼本章就不包含對你有用的資訊,你也可能會跳過它。如果你困惑,那就讓它明白些...
起源(Genesis)
在1991年六月,我為自由軟體基金會維護了許多GNU工具。由于它們被移植到更多的平台并且增加了更多的程式,使用者必須在`Makefile'中選擇的 `-D'選項的數目(大約20個)變得難以承受。尤其是我-- 我不得不在許多不同的系統上對每個新的釋出版本進行測試。是以我編寫了一個簡單的shell腳本為fileutils包猜測一些正确的設定,并且把它作為 fileutils 2.0的一部分進行釋出。這個configure能夠勝任工作,是以,我在下個月中,手工對其進行了修改以用于其他幾個GNU工具包,進而建立了相似的 configure腳本。 Brian Berliner也修改了我的腳本以用與它的CVS修訂控制系統。
那個夏天以後,我得知Richard Stallman和Richard Pixley正在開發用于GNU編譯器工具的類似腳本;是以我對我的 configure進行了修改以支援它們的進化的界面:把名為`Makefile.in'的檔案當作模闆;添加`+srcdir',作為許多選項的第一個選項;并建立`config.status'檔案。
出發(Exodus)
由于我從使用者那裡獲得了回報,我組合了許多改進,使用Emacs進行搜尋和替換、剪切(cut)和粘貼(paste),在每個腳本中進行類似的修改。随着我修改更多的GNU工具包以使用configure腳本,完全用手工更新它們就不可能了。Rich Murphey,GNU圖形工具的維護者,在給我發送的郵件中說configure腳本很好,并問我是否有一個可以生成它們的工具可以發給他。沒有,我想,但我将會有!是以我開始考慮如何生成它們。這樣,從手工編寫configure腳本的苦力向功能強大而易于使用的Autoconf前進的旅程開始了。
Cygnus configure,它大約也在那個時候被開發,是表驅動的;這意味着用少量的大體上不可猜測的特征來處理離散數量的系統類型(例如目标檔案格式的細節)。Brian Fox為Bash開發的自動配置系統采用了類似的方法。為了統一用法,我好像必須絕望地試圖為每個作業系統的變種的特征維護一個及時更新的資料庫。更容易和更可靠的辦法是不檢查大多數特征--特别是在那些人們已經在本地深入地研究或者安裝了買主提供的更新檔的雜合的系統。
我考慮到使用與Cygnus configure相似的結構,就是提供一個單獨的configure腳本,在運作時讀入`configure.in'的片斷。但是我不想讓每個包都釋出所有的特征測試,是以我選擇了使用預處理器從每個`configure.in'中建立不同的configure。這個方法還提供了更多的控制和便利。
我簡要地察看了被Larry Wall、Harlan Stenn和Raphael Manfredi采用的Metaconfig包,但我為了幾個原因而不采用它。這種方式生成的Configure腳本是互動式的,我認為太不友善了;我不喜歡它測試某些特征的方式(例如庫函數);我不知道它是否還有人維護,并且我所見到的Configure腳本在許多現代系統(例如System V R4和NeXT)中都不能工作;設定在支援某個特征或者不支援該特征時所進行的動作也不是很友善;我發現它難于學習;并且對于我的需要,它太大、太複雜了(我沒有意識到Autoconf最終将變得多麼大)。
我考慮過使用Perl來生成我的風格的configure腳本,但顯然m4更加适合于簡單的文本替換工作:由于輸出是隐含的,它的工作比較少。還有,每個人都已經擁有它了。(一開始,我并不依賴于 GNU對m4的擴充。)我在Maryland大學的一些朋友最近用一些程式,包括tvtwm,制作了m4的前端,并且我也有興趣試試一種新語言。
上路(Leviticus)
因為我的configure在沒有與使用者進行互動的條件下自動地确定了系統的能力,我決定把生成它們的程式稱作Autoconfig。但附加了版本号之後,這個名字對于老式的UNIX檔案系統來說就太長了,是以我把它縮短成Autoconf。
在1991年秋天,我召集了一群期望獲得移植性的家夥(alpha測試者)以給我提供回報進而使我可以壓縮(encapsulate)我用m4宏寫的腳本并且繼續添加特征、改進檢查中采用的技術。測試者中的傑出人物有Pinard,他提出了建立一個`autoconf'來運作m4并且檢查找不到的宏調用的想法;還有Richard Pixley,他建議通過運作編譯器而不是在檔案系統中尋找引入檔案和符号,以獲得更精确的結果;還有Kerl Berry,他使得Autoconf可以配置 Tex并且把宏索引添加到文檔中;還有Ian Taylor,他增加了對建立C頭檔案的支援以代替在`Makefile'中添加 `-D'選項的方法,以便他可以把Autoconf用于他的UUCP包。alpha測試者愉快地、一次又一次地随着 Autoconf不同釋出版本中的Autoconf名稱和宏調用慣例的改變而調整他們的檔案。他們都貢獻了許多特定的檢查、絕妙的想法,以及對bug的修正。
發展(Numbers)
在1992年七月,在alpha測試之後一個月,我釋出了Autoconf 1.0,并且修改了許多GNU包以使用它。我對它帶來的正面作用感到很吃驚。很多人,包括那些編寫并不屬于GNU工程的軟體(例如TCL、FSP和 Kerberos V5)的人們,開始使用它,以至于我無法跟蹤他們了。随着很多使用configure腳本的人報告他們所遇到的問題,Autoconf繼續快速地得到改進,
Autoconf成為考驗m4實作的酷刑般的測試。由于Autoconf定義的宏的長度,UNIX m4開始失敗(dump core),同時也發現了GNU m4中的一些bug。最終,我們意識到我們需要使用一些隻有 GNU m4才提供的特征。特别的,4.3BSD m4含有一組增強了的内置宏;System V版本更好一些,但仍然不能提供我們所需要的所有東西。
随着Autoconf得到人們越來越多的重視,對Autoconf進行了更多的開發(并且有了我不能預見的用途)。Karl Berry添加了對X11的檢查。david zuhn貢獻了對C++的支援。Pinard使Autoconf能夠診斷非法的參數。Jim Blandy勇敢地用它配置了GNU Emacs,并且為某些未來的改進打下了基礎。Roland McGrath用它配置了GNU C庫,編寫了autoheader 腳本以自動建立C頭檔案模闆,并且為configure添加了一個`--verbose'選項。 Noah Friedman添加了`--macrodir'選項和環境變量AC_MACRODIR。(他還提出了術語 autoconfiscate,用來表示“調整軟體包以使用Autoconf”。)Roland和Noah改進了AC_DEFINE 中的引用保護并且修正了許多bug,特别是在1993年二月到六月間我們對處理移植性問題感到厭倦的時候。
現狀(Deuteronomy)
在積累了一個關于希望添加的主要特征的長長的清單,并且在幾年之中各式各樣的人們提供的更新檔殘留了古怪的效果之後。在1994年四月,處理對Cygnus 的支援時,我開始對Autoconf進行一次主要的修訂。我添加了大部分Cygnus configure 有,而Autoconf缺少的特征,主要是在david zuhn和Ken Raeburn的幫助下改編Cygnus configure的相關部分。這些特征包括對使用`config.sub'、`config.guess'、`--host'和 `--target'的支援;建立對檔案的連接配接;以及在子目錄中運作configure腳本。添加這些特征使得Ken可以放棄GNU as,Rob Savoye可以放棄DejaGNU,而改用Autoconf。
作為對其他人的要求的回應,我添加了更多的特征。許多人要求configure腳本能夠在不同的運作中共享檢查的結果,這是因為它們實在太慢了(尤其是像 Cygnus那樣在配置一個大的源代碼樹的時候)。 Mike Haertel建議增加與位置有關的初始化腳本。釋出必須在MS-DOS中解包(unpack)的軟體的人們要求提供一種覆寫那些諸如 `config.h.in'那樣的、含有兩個點的檔案名中的`.in'擴充名的方法。 Jim Avera通過AC_DEFINE和AC_SUBST中的引用擴充了對程式的檢測;他的洞察力帶來了重要的改進。Richard Stallman要求把編譯器的輸出送到`config.log'中,而不是送到`/dev/null'中,以幫助人們調試Emacs configure腳本。
由于我對程式品質的不滿,我進行了一些其他的修改。我減少了用于顯示檢查結果的消息的二義性,總是列印結果。我識别宏的名字并且消除編碼風格的不一緻性。我添加了一些我所開發的附加工具以助于修改源代碼包以使用Autoconf。在Pinard的幫助下,我建立了不會在彼此的消息中導緻沖突的宏。(這個特征暴露了他草率地修正的、GNU m4 中的一些性能瓶頸!)我重新組織了人們需要解決的問題的文檔。并且我開始了一組測試(testsuite),這是因為經驗已經表明:在我們修改 Autoconf的時候,它有明顯的回歸傾向。
一些alpha測試者再次給出了難以估量的回報,特别是 Pinard、Jim Meyering、Karl Berry、Rob Savoye、Ken Raeburn和Mark Eichin。
最後,2.0版本準備好了。而且我們也很高興。(我們又有閑暇時間了。我想。哇,很好。)
autoconf手冊(九)
陳舊的宏名
在Autoconf的第2版,大部分宏被重新命名以使用更加統一和具有描述性的命名方案。下面是被重新命名了的宏的原來名字,随後給出了這些宏現在的名字。雖然為了保持向後相容,舊名字仍然能夠被autoconf程式所接受,舊名字都被看作過時的。關于新的命名方案,參見宏名。
AC_ALLOCA
AC_FUNC_ALLOCA
AC_ARG_ARRAY
因為用途有限而被删除了。
AC_CHAR_UNSIGNED
AC_C_CHAR_UNSIGNED
AC_CONST
AC_C_CONST
AC_CROSS_CHECK
AC_C_CROSS
AC_ERROR
AC_MSG_ERROR
AC_FIND_X
AC_PATH_X
AC_FIND_XTRA
AC_PATH_XTRA
AC_FUNC_CHECK
AC_CHECK_FUNC
AC_GCC_TRADITIONAL
AC_PROG_GCC_TRADITIONAL
AC_GETGROUPS_T
AC_TYPE_GETGROUPS
AC_GETLOADAVG
AC_FUNC_GETLOADAVG
AC_HAVE_FUNCS
AC_CHECK_FUNCS
AC_HAVE_HEADERS
AC_CHECK_HEADERS
AC_HAVE_POUNDBANG
AC_SYS_INTERPRETER (不同的調用慣例)
AC_HEADER_CHECK
AC_CHECK_HEADER
AC_HEADER_EGREP
AC_EGREP_HEADER
AC_INLINE
AC_C_INLINE
AC_LN_S
AC_PROG_LN_S
AC_LONG_DOUBLE
AC_C_LONG_DOUBLE
AC_LONG_FILE_NAMES
AC_SYS_LONG_FILE_NAMES
AC_MAJOR_HEADER
AC_HEADER_MAJOR
AC_MINUS_C_MINUS_O
AC_PROG_CC_C_O
AC_MMAP
AC_FUNC_MMAP
AC_MODE_T
AC_TYPE_MODE_T
AC_OFF_T
AC_TYPE_OFF_T
AC_PID_T
AC_TYPE_PID_T
AC_PREFIX
AC_PREFIX_PROGRAM
AC_PROGRAMS_CHECK
AC_CHECK_PROGS
AC_PROGRAMS_PATH
AC_PATH_PROGS
AC_PROGRAM_CHECK
AC_CHECK_PROG
AC_PROGRAM_EGREP
AC_EGREP_CPP
AC_PROGRAM_PATH
AC_PATH_PROG
AC_REMOTE_TAPE
因為用途有限而被删除了。
AC_RESTARTABLE_SYSCALLS
AC_SYS_RESTARTABLE_SYSCALLS
AC_RETSIGTYPE
AC_TYPE_SIGNAL
AC_RSH
因為用途有限而被删除了。
AC_SETVBUF_REVERSED
AC_FUNC_SETVBUF_REVERSED
AC_SET_MAKE
AC_PROG_MAKE_SET
AC_SIZEOF_TYPE
AC_CHECK_SIZEOF
AC_SIZE_T
AC_TYPE_SIZE_T
AC_STAT_MACROS_BROKEN
AC_HEADER_STAT
AC_STDC_HEADERS
AC_HEADER_STDC
AC_STRCOLL
AC_FUNC_STRCOLL
AC_ST_BLKSIZE
AC_STRUCT_ST_BLKSIZE
AC_ST_BLOCKS
AC_STRUCT_ST_BLOCKS
AC_ST_RDEV
AC_STRUCT_ST_RDEV
AC_SYS_SIGLIST_DECLARED
AC_DECL_SYS_SIGLIST
AC_TEST_CPP
AC_TRY_CPP
AC_TEST_PROGRAM
AC_TRY_RUN
AC_TIMEZONE
AC_STRUCT_TIMEZONE
AC_TIME_WITH_SYS_TIME
AC_HEADER_TIME
AC_UID_T
AC_TYPE_UID_T
AC_UTIME_NULL
AC_FUNC_UTIME_NULL
AC_VFORK
AC_FUNC_VFORK
AC_VPRINTF
AC_FUNC_VPRINTF
AC_WAIT3
AC_FUNC_WAIT3
AC_WARN
AC_MSG_WARN
AC_WORDS_BIGENDIAN
AC_C_BIGENDIAN
AC_YYTEXT_POINTER
AC_DECL_YYTEXT
環境變量索引
這是一個按照字母順序排序的,由Autoconf檢查的環境變量的清單。
Jump to: a - c - s
a
AC_MACRODIR, AC_MACRODIR, AC_MACRODIR, AC_MACRODIR, AC_MACRODIR, AC_MACRODIR
c
CONFIG_FILES
CONFIG_HEADERS
CONFIG_SHELL
CONFIG_SITE
CONFIG_STATUS
s
SIMPLE_BACKUP_SUFFIX
輸出變量索引
這是一個按照字母順序排序的,Autoconf将在它所建立的檔案(通常是一個或更多`Makefile')中進行替換的變量的清單。關于這些是如何實作的,請參見設定輸出變量。
Jump to: a - b - c - d - e - f - h - i - k - l - m - n - o - p - r - s - t - x - y
a
ALLOCA
AWK
b
bindir
build
build_alias
build_cpu
build_os
build_vendor
c
CC, CC, CC
CFLAGS, CFLAGS
configure_input
CPP
CPPFLAGS
CXX
CXXCPP
CXXFLAGS, CXXFLAGS
d
datadir
DEFS
e
exec_prefix
EXEEXT
f
F77
FFLAGS, FFLAGS
FLIBS
h
host
host_alias
host_cpu
host_os
host_vendor
i
includedir
infodir
INSTALL
INSTALL_DATA
INSTALL_PROGRAM
INSTALL_SCRIPT
k
KMEM_GROUP
l
LDFLAGS
LEX
LEX_OUTPUT_ROOT
LEXLIB
libdir
libexecdir
LIBOBJS, LIBOBJS, LIBOBJS, LIBOBJS, LIBOBJS
LIBS, LIBS, LIBS
LN_S
localstatedir
m
mandir
n
NEED_SETGID
o
OBJEXT
oldincludedir
p
prefix
program_transform_name
r
RANLIB
s
sbindir
SET_MAKE
sharedstatedir
srcdir
subdirs
sysconfdir
t
target
target_alias
target_cpu
target_os
target_vendor
top_srcdir
x
X_CFLAGS
X_EXTRA_LIBS
X_LIBS
X_PRE_LIBS
y
YACC
預處理器符号索引
這是一個按照字母順序排序的,由Autoconf宏定義的C預處理符号的清單。為了與Autoconf協同工作,C源代碼應該在#if指令中使用這些名字。
Jump to: _ - c - d - f - g - h - i - l - m - n - o - p - r - s - t - u - v - w - y
_
__CHAR_UNSIGNED__
_ALL_SOURCE
_MINIX
_POSIX_1_SOURCE
_POSIX_SOURCE, _POSIX_SOURCE
_POSIX_VERSION
c
C_ALLOCA
CLOSEDIR_VOID
const
d
DGUX
DIRENT
f
F77_NO_MINUS_C_MINUS_O
g
GETGROUPS_T
GETLODAVG_PRIVILEGED
GETPGRP_VOID
gid_t
h
HAVE_ALLOCA_H
HAVE_CONFIG_H
HAVE_DIRENT_H
HAVE_DOPRNT
HAVE_function
HAVE_GETMNTENT
HAVE_header
HAVE_LONG_DOUBLE
HAVE_LONG_FILE_NAMES
HAVE_MMAP
HAVE_NDIR_H
HAVE_RESTARTABLE_SYSCALLS
HAVE_ST_BLKSIZE
HAVE_ST_BLOCKS
HAVE_ST_RDEV
HAVE_STRCOLL
HAVE_STRFTIME
HAVE_STRINGIZE
HAVE_SYS_DIR_H
HAVE_SYS_NDIR_H
HAVE_SYS_WAIT_H
HAVE_TM_ZONE
HAVE_TZNAME
HAVE_UNISTD_H
HAVE_UTIME_NULL
HAVE_VFORK_H
HAVE_VPRINTF
HAVE_WAIT3
i
inline
INT_16_BITS
l
LONG_64_BITS
m
MAJOR_IN_MKDEV
MAJOR_IN_SYSMACROS
mode_t
n
NDIR
NEED_MEMORY_H
NEED_SETGID
NLIST_NAME_UNION
NLIST_STRUCT
NO_MINUS_C_MINUS_O
o
off_t
p
pid_t
r
RETSIGTYPE
s
SELECT_TYPE_ARG1
SELECT_TYPE_ARG234
SELECT_TYPE_ARG5
SETPGRP_VOID
SETVBUF_REVERSED
size_t
STDC_HEADERS
SVR4
SYS_SIGLIST_DECLARED
SYSDIR
SYSNDIR
t
TIME_WITH_SYS_TIME
TM_IN_SYS_TIME
u
uid_t
UMAX
UMAX4_3
USG
v
vfork
VOID_CLOSEDIR
w
WORDS_BIGENDIAN
y
YYTEXT_POINTER
宏索引
這是按字母排序的Autoconf宏清單。為了使清單易于使用,宏以沒有字首`AC_'的形式列出。
Jump to: a - b - c - d - e - f - g - h - i - l - m - o - p - r - s - t - u - v - w - x - y
a
AIX
ALLOCA
ARG_ARRAY
ARG_ENABLE
ARG_PROGRAM
ARG_WITH
b
BEFORE
c
C_BIGENDIAN
C_CHAR_UNSIGNED
C_CONST
C_CROSS
C_INLINE
C_LONG_DOUBLE
C_STRINGIZE
CACHE_CHECK
CACHE_LOAD
CACHE_SAVE
CACHE_VAL
CANONICAL_HOST
CANONICAL_SYSTEM
CHAR_UNSIGNED
CHECK_FILE
CHECK_FILES
CHECK_FUNC
CHECK_FUNCS
CHECK_HEADER
CHECK_HEADERS
CHECK_LIB
CHECK_PROG
CHECK_PROGS
CHECK_SIZEOF
CHECK_TOOL
CHECK_TYPE
CHECKING
COMPILE_CHECK
CONFIG_AUX_DIR
CONFIG_HEADER
CONFIG_SUBDIRS
CONST
CROSS_CHECK
CYGWIN
d
DECL_SYS_SIGLIST
DECL_YYTEXT
DEFINE
DEFINE_UNQUOTED
DEFUN
DIR_HEADER
DYNIX_SEQ
e
EGREP_CPP
EGREP_HEADER
ENABLE
ERROR
EXEEXT
f
F77_LIBRARY_LDFLAGS
FIND_X
FIND_XTRA
FUNC_ALLOCA
FUNC_CHECK
FUNC_CLOSEDIR_VOID
FUNC_FNMATCH
FUNC_GETLOADAVG
FUNC_GETMNTENT
FUNC_GETPGRP
FUNC_MEMCMP
FUNC_MMAP
FUNC_SELECT_ARGTYPES
FUNC_SETPGRP
FUNC_SETVBUF_REVERSED
FUNC_STRCOLL
FUNC_STRFTIME
FUNC_UTIME_NULL
FUNC_VFORK
FUNC_VPRINTF
FUNC_WAIT3
g
GCC_TRADITIONAL
GETGROUPS_T
GETLOADAVG
h
HAVE_FUNCS
HAVE_HEADERS
HAVE_LIBRARY
HAVE_POUNDBANG
HEADER_CHECK
HEADER_DIRENT
HEADER_EGREP
HEADER_MAJOR
HEADER_STAT
HEADER_STDC
HEADER_SYS_WAIT
HEADER_TIME
i
INIT
INLINE
INT_16_BITS
IRIX_SUN
ISC_POSIX
l
LANG_C
LANG_CPLUSPLUS
LANG_FORTRAN77
LANG_RESTORE
LANG_SAVE
LINK_FILES
LN_S
LONG_64_BITS
LONG_DOUBLE
LONG_FILE_NAMES
m
MAJOR_HEADER
MEMORY_H
MINGW32
MINIX
MINUS_C_MINUS_O
MMAP
MODE_T
MSG_CHECKING
MSG_ERROR
MSG_RESULT
MSG_WARN
o
OBJEXT
OBSOLETE
OFF_T
OUTPUT
p
PATH_PROG
PATH_PROGS
PATH_X
PATH_XTRA
PID_T
PREFIX
PREFIX_PROGRAM
PREREQ
PROG_AWK
PROG_CC
PROG_CC_C_O
PROG_CPP
PROG_CXX
PROG_CXXCPP
PROG_F77_C_O
PROG_FORTRAN
PROG_GCC_TRADITIONAL
PROG_INSTALL
PROG_LEX
PROG_LN_S
PROG_MAKE_SET
PROG_RANLIB
PROG_YACC
PROGRAM_CHECK
PROGRAM_EGREP
PROGRAM_PATH
PROGRAMS_CHECK
PROGRAMS_PATH
PROVIDE
r
REMOTE_TAPE
REPLACE_FUNCS
REQUIRE
REQUIRE_CPP
RESTARTABLE_SYSCALLS
RETSIGTYPE
REVISION
RSH
s
SCO_INTL
SEARCH_LIBS, SEARCH_LIBS
SET_MAKE
SETVBUF_REVERSED
SIZE_T
SIZEOF_TYPE
ST_BLKSIZE
ST_BLOCKS
ST_RDEV
STAT_MACROS_BROKEN, STAT_MACROS_BROKEN
STDC_HEADERS
STRCOLL
STRUCT_ST_BLKSIZE
STRUCT_ST_BLOCKS
STRUCT_ST_RDEV
STRUCT_TIMEZONE
STRUCT_TM
SUBST
SUBST_FILE
SYS_INTERPRETER
SYS_LONG_FILE_NAMES
SYS_RESTARTABLE_SYSCALLS
SYS_SIGLIST_DECLARED
t
TEST_CPP
TEST_PROGRAM
TIME_WITH_SYS_TIME
TIMEZONE
TRY_COMPILE
TRY_CPP
TRY_LINK
TRY_LINK_FUNC, TRY_LINK_FUNC
TRY_RUN
TYPE_GETGROUPS
TYPE_MODE_T
TYPE_OFF_T
TYPE_PID_T
TYPE_SIGNAL
TYPE_SIZE_T
TYPE_UID_T
u
UID_T
UNISTD_H
USG
UTIME_NULL
v
VALIDATE_CACHED_SYSTEM_TUPLE
VERBOSE
VFORK
VPRINTF
w
WAIT3
WARN
WITH
WORDS_BIGENDIAN
x
XENIX_DIR
y
YYTEXT_POINTER