Autoconfhtml
configure
腳本
configure
腳本
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.c++
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.shell
本文檔由王立翻譯。 1999.12.16數據庫
譯者在此聲明:不對任何由譯文錯誤或者對譯文的誤解承擔任何責任。express
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
建立的文件有:
#define
命令 (參見配置頭文件);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
腳本,須要編寫一個名爲`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和庫的影響。
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_INIT(file)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
AC_MACRODIR
設置成 一個目錄;本選項將覆蓋該環境變量。
--verbose
--version
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
AC_MACRODIR
設置成一個目錄;本選項將覆蓋該環境變量。
--version
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
--macrodir=dir
-m dir
AC_MACRODIR
設置成 一個目錄;本選項將覆蓋該環境變量。
--version
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
--localdir=dir
-l dir
autoconf
和
autoheader
在目錄
dir中,而不是在每一個包含
`configure.in' 的目錄中尋找包文件
`aclocal.m4'和(僅指
autoheader
)
`acconfig.h' (但不包括
`file.top'和
`file.bot')。
--macrodir=dir
-m dir
AC_MACRODIR
設置成一個目錄;本選項將覆蓋該環境變量。
--verbose
autoreconf
運行
autoconf
(若是適當,還有
autoheader
) 的每一個目錄的目錄名。
--version
Autoconf生成的configure
腳本須要一些關於如何進行初始化,諸如如何尋找包的源文件,的信息; 以及如何生成輸出文件的信息。本節敘述如何進行初始化和建立輸出文件。
configure
的輸入文件全部configure
腳本在做任何其餘事情以前都必須調用AC_INIT
。此外惟一必須調用的宏是 AC_OUTPUT
(參見建立輸出文件)。
configure
在目錄中檢查這些文件是否存在以肯定該目錄是否包含源代碼。 人們可能偶爾會用
`--srcdir'給出錯誤的目錄;這是一種安全性檢查。 詳情請參見
運行configure
腳本。
對於須要手工配置或者使用install
程序的包來講,雖然在缺省源代碼位置在大部分狀況 下看起來是正確的,包仍是可能須要經過調用AC_CONFIG_AUX_DIR
來告訴 configure
到那裏去尋找一些其餘的shell腳本。
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_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
,在其中給出的命令將緊貼在由本宏給出的命令以前運行。
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
並不設定這個變量。如下的宏使你能夠在這些版本上使用它。
make
預約義了變量
MAKE
,把輸出變量
SET_MAKE
定義爲空。不然,把
SET_MAKE
定義成
`MAKE=make'。爲
SET_MAKE
調用
AC_SUBST
。
爲了使用這個宏,在每一個其餘的、運行MAKE
的目錄中的`Makefile.in'添加一行:
@SET_MAKE@
發佈版本中每一個包含了須要被編譯或者被安裝的文件的目錄都應該含有一個文件`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編碼標準中的 `爲安裝目錄而提供的變量'。
configure
自動生成的,而且給出了輸入文件名的註釋。
AC_OUTPUT
在它建立的每一個
`Makefile'文件的開頭添加一個包括了這個變量的註釋行。 對於其餘文件,你應該在每一個輸入文件開頭處的註釋中引用這個變量。例如,一個輸入shell腳本應該以以下 行開頭:
#! /bin/sh # @configure_input@
這一行的存在也提醒了人們在編輯這個文件以後須要用configure
進行處理以使用它。
configure
時,沒有在環境中設置它,就在你 調用
AC_PROG_CC
的時候設置它的缺省值(若是你沒有調用
AC_PROG_CC
,它就爲空)。
configure
在編譯程序以測試C的特徵時,使用本變量。
configure
時,在環境中沒有設置本變量,缺省值就是空。
configure
在編譯或者預處理 程序以測試C的特徵時,使用本變量。
configure
時,沒有在環境中設置本變量,那麼 就在你調用
AC_PROG_CXX
時設置它的缺省值(若是你沒有調用
AC_PROG_CXX
,它就爲空)。
configure
在編譯程序以測試C++的特徵時,使用本變量。
configure
時,在環境中沒有設置本變量,那麼它的 缺省值就在你調用
AC_PROG_F77
時被設置(若是你沒有調用
AC_PROG_F77
,它就爲空)。
configure
在編譯程序以測試Fortran 77的特徵時,使用本變量。
AC_CONFIG_HEADER
,
configure
就用
`-DHAVE_CONFIG_H'代替
`@DEFS@'(參見
配置頭文件)。 在
configure
進行它的測試時,本變量沒有被定義,只有在建立輸出文件時候才定義。關於如何檢查從前的 測試結果,請參見
設定輸出變量。
configure
時, 在環境中沒有設置本變量,它的缺省值就是空。
configure
在鏈接程序以測試C的特徵時使用本變量。
你能夠支持從一個軟件包的一份源代碼拷貝中爲多種結構同時進行編譯的功能。爲每種結構生成的目標文件都在 它們本身的目錄中儲存。
爲了支持這個功能,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 <config.h>'而且把選項`-I.'(或者是`-I..';或者是任何包含`config.h' 的目錄)傳遞給C編譯器,而不是使用`#include "config.h"'。按照這種方式,即便源代碼 自行進行配置(多是建立發佈版本),其餘建立目錄也能夠在沒有找到`config.h'的狀況下, 從源代碼目錄進行配置。
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
--macrodir=dir
-m dir
AC_MACRODIR
設置成一個目錄;本選項將覆蓋該環境變量。
--version
在大多數狀況下,調用AC_OUTPUT
足以在子目錄中生成`Makefile'。然而,控制了多於一個 獨立包的configure
腳本能夠使用AC_CONFIG_SUBDIRS
來爲每一個子目錄中的其餘包運行 configure
腳本。
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
。
對於用戶來講,讓configure
根據它們已經安裝的相關程序的位置來猜想安裝前綴,可能會帶來方便。若是你 但願這樣作,你能夠調用AC_PREFIX_PROGRAM
。
PATH
中尋找
program,從而猜出一個安裝前綴。若是找到了
program,就把前綴設置成包含
program 的目錄的父目錄;不然,就不改變在
`Makefile.in'中給定的前綴。例如,若是
program是
gcc
,而且
PATH
包括了
`/usr/local/gnu/bin/gcc',就把前綴設置爲
`/usr/local/gnu'。
configure
中的版本號如下的宏爲configure
腳本管理版本號。使用它們是可選的。
configure
的Autoconf的版本比
version 要早,就在標準錯誤輸出打印一條錯誤消息並不會建立
configure
。例如:
AC_PREREQ(1.8)
若是你的`configure.in'依賴於在不一樣Autoconf版本中改變了的、不明顯的行爲,本宏就是有用的。 若是它僅僅是須要近來增長的宏,那麼AC_PREREQ
就不太有用,這是由於程序autoconf
已經 告訴了用戶那些宏沒有被找到。若是`configure.in'是由一個在提供AC_PREREQ
以前的更舊的 Autoconf版本處理的,也會發生一樣的事。
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
這些宏測試了包可能須要或者須要使用的特定的系統特徵。若是你要測試這些宏所不能測試的特徵,可能你能夠用 適當的參數調用主測試宏來達到目的(參見編寫測試)。
這些宏打印消息以告訴用戶它們正在測試的特徵,以及它們的測試結果。它們爲將來運行的configure
儲存測試結果(參見緩存結果)。
在這些宏中,有的宏設置輸出變量。關於如何獲取它們的值,請參見Makefile中的替換。 在下面出現的術語「定義name」是「把C預處理符號name定義成1」的簡稱。 關於如何把這些符號的定義放入你的程序中,參見定義C預處理器符號。
這些宏檢查了特定程序的存在或者特定程序的特徵。它們被用於在幾個能夠相互替代的程序間進行選擇,而且在決定選用 某一個的時候做些什麼。若是沒有爲你要使用的程序定義特定的宏,而且你不須要檢查它的任何特殊的特徵,那麼你就 能夠選用一個通用程序檢查宏。
這些宏檢查特定的程序--它們是否存在,而且在某些狀況下它們是否支持一些特徵。
yytext
的類型是
`char *'而不是
`char []',就定義
YYTEXT_POINTER
。 本宏還把輸出變量
LEX_OUTPUT_ROOT
設置由lex生成的文件名的基文件名;一般是
`lex.yy', 但有時是其餘的東西。它的結果依使用
lex
仍是使用
flex
而定。
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'。換句話說,它檢查建立系統類型 是否與主機系統類型不一樣(目標系統與本測試無關)。關於對交叉編譯的支持,參見手工配置。
CPP
設置成運行C預處理器的命令。若是
`$CC -E'不能工做,就使用
`/lib/cpp'。 只有對以
`.c'爲擴展名的文件運行
CPP
纔是能夠移植的(portable)。
若是當前語言是C(參見對語言的選擇),許多特定的測試宏經過調用AC_TRY_CPP
、 AC_CHECK_HEADER
、AC_EGREP_HEADER
或者AC_EGREP_CPP
,間接地使用了CPP
的值。
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'。換句話說,它檢查建立系統類型是否與主機系統類型不一樣 (目標系統類型與本測試無關)。關於對交叉編譯的支持,參見手工配置。
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
的值。
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'。
ioctl
不能正確地工做,就把
`-traditional'添加到輸出變量
CC
中。這一般發生在舊系統上沒有安裝修正了的頭文件 的時候。由於新版本的GNU C編譯器在安裝的時候自動地修正了頭文件,它就不是一個廣泛的問題了。
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'文件便可。
flex
,就把輸出變量
LEX
設置成
`flex',而且在flex庫在標準位置的時候, 把
LEXLIB
設置成
`-lfl'。不然,就把
LEX
設置成
`lex'而且把
LEXLIB
設置成
`-ll'。
LN_S
設置成
`ln -s',不然就把它設置成
`ln'。
若是鏈接出如今其餘目錄而不是在當前目錄中,它的含義依賴因而使用了`ln',仍是使用了`ln -s'。 爲了用`$(LN_S)'安全地建立鏈接,既能夠找到正在使用的形式而且調整參數,也能夠老是在建立鏈接的 目錄中調用ln
。
換句話說,它不能像下面那樣工做:
$(LN_S) foo /x/bar
而是要:
(cd /x && $(LN_S) foo bar)
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
。而且爲每一個找到的文件定義
`HAVEfile',定義成1。
PATH
之中。若是找到了,就把變量
variable設置成
value-if-found,不然就在給出了
value-if-not-found的時候 把
variable設置成它。即便首先在搜索路徑中找到
reject(一個絕對文件名),本宏也會忽略它; 在那種狀況下,用找到的
prog-to-check-for,不一樣於
reject的絕對文件名來設置
variable。 若是
variable已經被設置了,就什麼也不做。爲
variable調用
AC_SUBST
。
PATH
中尋找每一個出如今以空格分隔的列表
progs-to-check-for中的程序。 若是找到了,就把
variable設置成那個程序的名字。不然,繼續尋找列表中的下一個程序。若是列表 中的任何一個程序都沒有被找到,就把
variable設置成
value-if-not-found;若是沒有 給出
value-if-not-found,
variable的值就不會被改變。爲
variable調用
AC_SUBST
。
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_CHECK_PROG
,但在找到
prog-to-check-for的時候,把
variable設置 成
prog-to-check-for的完整路徑。
AC_CHECK_PROGS
,但在找到任何一個
progs-to-check-for的時候,把
variable 設置成找到的程序的完整路徑。
下列的宏檢查某些C、C++或者Fortran 77庫文件是否存在。
action-if-found是一個在與庫成功地進行了鏈接的時候運行的shell命令列表; action-if-not-found是一個在與庫的鏈接失敗的時候運行的shell命令列表。 若是沒有給出action-if-found,缺省的動做就是把`-llibrary'添加到 LIBS
中,而且定義`HAVE_LIBlibrary'(所有使用大寫字母)。
若是與library的鏈接致使了未定義符號錯誤(unresolved symbols),而這些錯誤能夠經過與其餘庫的鏈接來解決, 就把這些庫用空格分隔,並做爲other-libraries參數給出:`-lXt -lX11'。不然,本宏 對library是否存在的檢測將會失敗,這是由於對測試程序的鏈接將老是由於含有未定義符號錯誤而失敗。
main
的,對
AC_CHECK_LIB
的調用。 此外,
library能夠寫做
`foo'、
`-lfoo'或者
`libfoo.a'。 對於以上任一種形式,編譯器都使用
`-lfoo'。可是,
library不能是一個shell變量; 它必須是一個文字名(literal name)。本宏是一個過期的宏。
AC_TRY_LINK_FUNC
,然後爲每一個在
search-libs中列舉的庫調用
AC_TRY_LINK_FUNC
。
若是找到了函數,就運行action-if-found。不然運行action-if-not-found。
若是與庫library的鏈接致使了未定義符號錯誤,而這些錯誤能夠經過與附加的庫進行鏈接來解決,就把這些庫 用空格分隔,並做爲other-libraries參數給出:`-lXt -lX11'。不然,本宏對function 是否存在的檢測將老是失敗,這是由於對測試程序的鏈接將老是由於含有未定義符號錯誤而失敗。
AC_TRY_LINK_FUNC
。爲找到的第一個含有
function的庫,把
`-llibrary'添加到
LIBS
中,而且執行
action-if-found。不然就執行
action-if-not-found。
如下的宏用於檢測特定的C庫函數。若是沒有爲你須要的函數定義特定的宏,並且你不須要檢查它的任何特殊性質, 那麼你能夠使用一個通用函數檢測宏。
這些宏用於檢測特定的C函數--它們是否存在,以及在某些狀況下,當給出了特定的參數時,它們是如何響應的。
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)。
/* AIX requires this to be the first thing in the file. */ #ifndef __GNUC__ # if HAVE_ALLOCA_H # include <alloca.h> # else # ifdef _AIX #pragma alloca # else # ifndef alloca /* predefined by HP cc +Olibcalls */ char *alloca (); # endif # endif # endif #endif
getloadavg
函數,本宏就定義
HAVE_GETLOADAVG
, 而且把爲了得到該函數而須要的庫添加到
LIBS
中。
不然,它就把`getloadavg.o'添加到輸出變量LIBOBJS
之中,而且可能定義幾個其餘的C預處理器 宏和輸出變量:
SVR4
、DGUX
、UMAX
或者UMAX4_3
。NLIST_STRUCT
。NLIST_NAME_UNION
。LDAV_PRIVILEGED
,爲了使getloadavg
可以 工做,程序就必須特殊地安裝在系統中,而且本宏定義GETLOADAVG_PRIVILEGED
。NEED_SETGID
。若是須要進行特別的安裝,它的值就是`true',不然 值就是`false'。若是NEED_SETGID
爲`true',本宏把KMEM_GROUP
設置成將擁有被安裝的程序的組(group)的名字。
getmntent
函數。 那麼,若是能夠使用
getmntent
,就定義
HAVE_GETMNTENT
。
getpgrp
不接受參數(POSIX.1版),就定義
GETPGRP_VOID
。不然,它就是一個把 進程ID做爲參數的BSD版本。本宏根本不檢查
getpgrp
是否存在;若是你須要檢查它的存在性,就首先爲
getpgrp
函數調用
AC_CHECK_FUNC
。
mmap
存在而且可以正確地工做,就定義
HAVE_MMAP
。只檢查已經映射(already-mapped) 的內存的私有固定映射(private fixed mapping)。
select
的每一個參數的正確類型,而且把這些類型分別定義成
SELECT_TYPE_ARG1
、
SELECT_TYPE_ARG234
和
SELECT_TYPE_ARG5
。
SELECT_TYPE_ARG1
的缺省值 是
`int',
SELECT_TYPE_ARG234
的缺省值是
`int *',
SELECT_TYPE_ARG5
的缺省值是
`struct timeval *'。
setpgrp
不接受參數(POSIX.1版),就定義
SETPGRP_VOID
。不然,該函數就是一個 把兩個進程ID做爲參數的BSD版本。本宏並不檢查函數
setpgrp
是否存在;若是你須要檢查該函數的存在 性,就首先爲
setpgrp
調用
AC_CHECK_FUNC
。
setvbuf
的第二個參數是緩衝區的類型而且第三個參數是緩衝區指針,而不是其餘形式, 就定義
SETVBUF_REVERSED
。這是在System V第3版之前的狀況。
strcoll
存在而且能夠正確地工做,就定義
HAVE_STRCOLL
。 因爲有些系統包含了錯誤定義的
strcoll
,這時就不該該使用
strcoll
, 所以本宏要比
`AC_CHECK_FUNCS(strcoll)'多做一些檢查。
HAVE_VFORK_H
。若是找不到能夠工做的
vfork
, 就把
vfork
定義成
fork
。本宏檢查一些已知的
vfork
實現中的錯誤 而且認爲若是
vfork
的實現含有任何一個錯誤,系統就不含有能夠工做的
vfork
。 因爲子進程不多改變它們的信號句柄(signal handler),因此若是子進程的
signal
調用(invocation) 修改了父進程的信號句柄,將不會被看成實現的錯誤。
vprintf
,就定義
HAVE_VPRINTF
。不然,若是找到了
_doprnt
, 就定義
HAVE_DOPRNT
。(若是能夠使用
vprintf
,你就能夠假定也能夠使用
vfprintf
和
vsprintf
。)
這些宏被用於尋找沒有包括在特定函數測試宏中的函數。若是函數可能出如今除了缺省C庫之外的庫中,就 要首先爲這些庫調用AC_CHECK_LIB
。若是你除了須要檢查函數是否存在以外,還要檢查函數 的行爲,你就不得不爲此而編寫你本身的測試(參見編寫測試)。
AC_CHECK_FUNCS
。因爲C++比C更加標準化,即便在調用了
AC_LANG_CPLUSPLUS
的時候,本宏仍然用C的鏈接方式對函數進行檢查。(關於爲測試選擇語言的詳情,請參見
對語言的選擇)
HAVE_function
(所有大寫)。若是給出了
action-if-found,它就是在找到一個函數的時候執行的附加的shell代碼。你能夠給出
`break'以便在找到第一個匹配的時候跳出循環。若是給出了
action-if-not-found,它就在找不到 某個函數的時候執行。
LIBOBJS
的shell 代碼爲參數
action-if-not-found,調用
AC_CHECK_FUNCS
。你能夠經過用
`#ifndef HAVE_function'包圍你爲函數提供的替代版本的原型來聲明函數。 若是系統含有該函數,它可能在一個你應該引入的頭文件中進行聲明,因此你不該該從新聲明它,以免聲明衝突。
下列宏檢查某些C頭文件是否存在。若是沒有爲你須要檢查的頭文件定義特定的宏,並且你不須要檢查它的任何特殊 屬性,那麼你就能夠使用一個通用的頭文件檢查宏。
這些宏檢查特定的系統頭文件--它們是否存在,以及在某些狀況下它們是否認義了特定的符號。
sys_siglist
, 就定義
SYS_SIGLIST_DECLARED
。
AC_HEADER_DIRENT
和
AC_FUNC_CLOSEDIR_VOID
,但爲了指明找到了 哪一個頭文件而定義了不一樣的一組C預處理器宏。本宏和它定義的名字是過期的。它定義的名字是:
DIRENT
SYSNDIR
SYSDIR
NDIR
此外,若是closedir
不能返回一個有意義的值,就定義VOID_CLOSEDIR
。
HAVE_DIRENT_H
HAVE_SYS_NDIR_H
HAVE_SYS_DIR_H
HAVE_NDIR_H
源代碼中的目錄庫聲明應該以相似於下面的方式給出:
#if HAVE_DIRENT_H # include <dirent.h> # define NAMLEN(dirent) strlen((dirent)->d_name) #else # define dirent direct # define NAMLEN(dirent) (dirent)->d_namlen # if HAVE_SYS_NDIR_H # include <sys/ndir.h> # endif # if HAVE_SYS_DIR_H # include <sys/dir.h> # endif # if HAVE_NDIR_H # include <ndir.h> # endif #endif
使用上述聲明,程序應該把變量定義成類型struct dirent
,而不是struct direct
,而且應該 經過把指向struct direct
的指針傳遞給宏NAMLEN
來得到目錄項的名稱的長度。
本宏還爲SCO Xenix檢查庫`dir'和`x'。
major
、
minor
和
makedev
, 但
`sys/mkdev.h'定義了它們,就定義
MAJOR_IN_MKDEV
; 不然,若是
`sys/sysmacros.h'定義了它們,就定義
MAJOR_IN_SYSMACROS
。
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 <string.h> #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)'。
HAVE_SYS_WAIT_H
。 若是
`sys/wait.h'不存在,或者若是它使用老式BSD
union wait
,而不是
int
來儲存狀態值,就可能出現不兼容。若是
`sys/wait.h'不與POSIX.1兼容, 那就不是引入該頭文件,而是按照它們的常看法釋定義POSIX.1宏。下面是一個例子:
#include <sys/types.h> #if HAVE_SYS_WAIT_H # include <sys/wait.h> #endif #ifndef WEXITSTATUS # define WEXITSTATUS(stat_val) ((unsigned)(stat_val) >> 8) #endif #ifndef WIFEXITED # define WIFEXITED(stat_val) (((stat_val) & 255) == 0) #endif
memcpy
,
memcmp
等函數,而且
`memory.h' 存在,就定義
NEED_MEMORY_H
。本宏已通過時;能夠用
AC_CHECK_HEADERS(memory.h)
來代替。 參見爲
AC_HEADER_STDC
提供的例子。
HAVE_UNISTD_H
。本宏已通過時;能夠用
`AC_CHECK_HEADERS(unistd.h)'來代替。
檢查系統是否支持POSIX.1的方式是:
#if HAVE_UNISTD_H # include <sys/types.h> # include <unistd.h> #endif #ifdef _POSIX_VERSION /* Code for POSIX.1 systems. */ #endif
在POSIX.1系統中包含了`unistd.h'的時候定義_POSIX_VERSION
。 若是系統中沒有`unistd.h',那麼該系統就必定不是POSIX.1系統。可是,有些非POSIX.1(non-POSIX.1) 系統也含有`unistd.h'。
rindex
、
bzero
等頭文件或函數,就定義
USG
。 定義
USG
就隱含地代表了系統含有
`string.h'、
strrchr
、
memset
等頭文件或函數。
符號USG
已通過時了。做爲本宏的替代,參見爲AC_HEADER_STDC
提供的例子。
這些宏被用於尋找沒有包括在特定測試宏中的系統頭文件。若是你除了檢查頭文件是否存在以外還要檢查它的內容, 你就不得不爲此而編寫你本身的測試(參見編寫測試)。
AC_CHECK_HEADERS
。
HAVE_header-file
(所有大寫)。若是給出了
action-if-found, 它就是在找到一個頭文件的時候執行的附加shell代碼。你能夠把
`break'做爲它的值 以便在第一次匹配的時候跳出循環。若是給出了
action-if-not-found,它就在找不到 某個頭文件的時候被執行。
如下的宏檢查某些結構或者某些結構成員。爲了檢查沒有在此給出的結構,使用AC_EGREP_CPP
(參見檢驗聲明)或者使用AC_TRY_COMPILE
(參見檢驗語法)。
S_ISDIR
、
S_ISREG
等宏不能正確 地工做(返回錯誤的正數),就定義
STAT_MACROS_BROKEN
。這種狀況出如今Tektronix UTekV、 Amdahl UTS和Motorola System V/88上。
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 <sys/time.h> # include <time.h> #else # if HAVE_SYS_TIME_H # include <sys/time.h> # else # include <time.h> # endif #endif
struct stat
包含一個
st_blocks
成員,就定義
HAVE_ST_BLOCKS
。 不然,就把
`fileblocks.o'添加到輸出變量
LIBOBJS
中。
struct tm
,就定義
TM_IN_SYS_TIME
,它意味着 引入
`sys/time.h'將獲得一個定義得更好的
struct tm
。
struct tm
有
tm_zone
成員,就定義
HAVE_TM_ZONE
。 不然,若是找到了外部數組
tzname
,就定義
HAVE_TZNAME
。
如下的宏檢查C typedefs。若是沒有爲你須要檢查的typedef定義特定的宏,而且你不須要檢查該類型 的任何特殊的特徵,那麼你能夠使用一個普通的typedef檢查宏。
這些宏檢查在`sys/types.h'和`stdlib.h'(若是它存在)中定義的特定的C typedef。
signal
聲明成一個指向返回值爲
void
的函數的指針, 就把
RETSIGTYPE
定義成
void
;不然,就把它定義成
int
。
把信號處理器(signal handler)的返回值類型定義爲RETSIGTYPE
:
RETSIGTYPE hup_handler () { ... }
本宏用於檢查沒有包括在特定類型測試宏中的typedef。
下列宏檢查C編譯器或者機器結構的特徵。爲了檢查沒有在此列出的特徵,使用AC_TRY_COMPILE
(參見檢驗語法)或者AC_TRY_RUN
(參見檢查運行時的特徵)
const
,就把
const
定義成空。有些編譯器並不定義
__STDC__
,但支持
const
;有些編譯器定義
__STDC__
,但不能徹底支持
const
。程序能夠假定全部C編譯器都支持
const
,並直接使用它;對於那些不能徹底 支持
const
的編譯器,
`Makefile'或者配置頭文件將把
const
定義爲空。
inline
,就什麼也不做。若是C編譯器能夠接受
__inline__
或者
__inline
,就把
inline
定義成可接受的關鍵字,不然就把
inline
定義爲空。
long double
類型,就定義
HAVE_LONG_DOUBLE
。 有些C編譯器並不定義
__STDC__
但支持
long double
類型;有些編譯器定義
__STDC__
但不支持
long double
。
HAVE_STRINGIZE
。字符串化操做符是
`#'而且它在宏定義中以以下方式出現:
#define x(y) #y
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。
long int
是64位寬,就定義
LONG_64_BITS
。 本宏已通過時;更常見的方式是用
`AC_CHECK_SIZEOF(long)'來代替。
下列的宏檢查Fortran 77編譯器的特徵。爲了檢查沒有在此列出的特徵,使用AC_TRY_COMPILE
(參見檢驗語法)或者AC_TRY_RUN
(參見檢驗運行時的特徵),但首先必須確認當前語言被設置成 Fortran 77 AC_LANG_FORTRAN77
(參見對語言的選擇)。
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庫。
下列宏檢查操做系統服務或者操做系統能力。
xmkmf
以處理一個測試
`Imakefile',而且檢查它所生成的
`Makefile',來獲得沒有 給出的目錄。若是這失敗了(好比說,
xmkmf
不存在),就在它們一般存在的幾個目錄中尋找。若是任何一種 方法成功了,就把shell變量
x_includes
和
x_libraries
設置成相應的位置,除非這些目錄就在 編譯器搜索的缺省目錄中。
若是兩種方法都失敗了,或者用戶給出命令行選項`--without-x',就把shell變量no_x
設置成`yes';不然就把它設置成空字符串。
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
。
configure.in
中的shell代碼就能夠檢查shell變量
interpval
; 若是系統支持
`#!',
interpval
將被設置成
`yes',若是不支持 就設置成
`no'。
下列宏檢查對於有些程序來講須要特殊處理的一些操做系統,這是由於它們的頭文件或庫文件中含有特別 怪異的東西。這些宏不討人喜歡;它們將根據它們所支持的函數或者它們提供的環境,被更加系統化的方法所代替。
LIBS
中。 本宏已通過時;用
AC_FUNC_GETMNTENT
來代替。
LIBS
中。 本宏已通過時。若是你用本宏來獲取
getmntent
,就用
AC_FUNC_GETMNTENT
來代替。 若是你爲了口令(password)和組函數的NIS版本而使用本宏,就用
`AC_CHECK_LIB(sun, getpwnam)'來代替。
_POSIX_SOURCE
,而且把
`-posix'(對於GNU C編譯器)或者
`-Xp'(對於其餘C編譯器)添加到輸出變量
CC
中。本宏容許使用 POSIX工具。必須在調用
AC_PROG_CC
以後,在調用其餘任何運行C編譯器的宏以前,調用本宏。
_MINIX
和
_POSIX_SOURCE
,而且把
_POSIX_1_SOURCE
定義成2。本宏容許使用POSIX工具。應該在全部運行C編譯器的宏以前調用本宏。
LIBS
。還有,若是使用了
`dirent.h', 就把
`-ldir'添加到
LIBS
。本宏已通過時;用
AC_HEADER_DIRENT
來代替。
若是現有的特徵測試不能完成你所須要的工做,你就必須編寫一個新的。這些宏是建立模塊。它們爲其它宏提供了檢查各類 特徵是否存在而且報告結果的方式。
本章包括一些建議和一些關於現有的測試的爲何要那樣編寫的緣由。經過閱讀現有的測試,你還能夠學到許多關於編寫 Autoconf測試的方法。若是在一個或多個Autoconf測試中出現了錯誤,這些信息能夠幫助你理解它們意味着什麼,這有助 於你找到最佳的解決問題的辦法。
這些宏檢查C編譯器系統的輸出。它們並不爲將來的使用而緩存測試的結果(參見緩存結果), 這是由於它們沒有足夠的信息以生成緩存變量名。基於一樣的緣由,它們還不會輸出任何消息。對特殊的C的特徵進行的測試 調用這些宏而且緩存它們的結果、打印關於它們所進行的測試的消息。
當你編寫了一個能夠適用於多於一個軟件包的特徵測試時,最好的方式就是用一個新宏封裝它。關於如何封裝,參見 編寫宏。
宏AC_TRY_CPP
用於檢測某個特定的頭文件是否存在。你能夠一次檢查一個頭文件,或者若是你爲了某些目的 而但願多個頭文件都存在,也能夠一次檢查多個頭文件。
#include
語句和聲明,對於它,將進行shell變量、反引用(backquote)、以及反斜線 (backslash)替換。(實際上,它能夠是任何C程序,但其它的語句可能沒有用。)若是預處理器在處理它的時候沒有報告錯誤, 就運行shell命令
action-if-true。不然運行shell命令
action-if-false。
本宏使用CPPFLAGS
,而不使用CFLAGS
,這是由於`-g'、`-O'等選項對於 許多C預處理器來講都是不合法的選項。
下面是如何確認在某個頭文件中是否包含一個特定的聲明,好比說typedef、結構、結構成員或者一個函數。使用 AC_EGREP_HEADER
而不是對頭文件直接運行grep
;在某些系統中,符號多是在另外一個你所檢查的`#include'文件。
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)
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
來嘗試編譯一個小的使用該特徵的程序。你還能夠用它檢查不是全部系統都支持的結構和結構成員。
對於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
並試圖鏈接一個小程序,從而對庫進行檢查(參見庫文件)。
對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。
若是文件被成功地編譯和鏈接了,就運行shell命令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
來編譯和運行它。若是可能就避免運行測試程序,這是由於使用它們使得人們不能對你的包進行交叉編譯。
若是你但願在配置的時候測試系統運行時的特徵,就使用以下的宏。
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',就使用另外一種方法來獲取結果,而不是調用宏。
測試程序不該該向標準輸出輸出任何信息。若是測試成功,它們應該返回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 <stdlib.h> #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腳本編程技術。 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 <sys/statvfs.h> #include <sys/fstyp.h>], AC_DEFINE(FSTYPE_STATVFS) fstype=SVR4) if test $fstype = no; then AC_TRY_CPP([#include <sys/statfs.h> #include <sys/fstyp.h>], AC_DEFINE(FSTYPE_USG_STATFS) fstype=SVR3) fi if test $fstype = no; then AC_TRY_CPP([#include <sys/statfs.h> #include <sys/vmount.h>], AC_DEFINE(FSTYPE_AIX_STATFS) fstype=AIX) fi # (more cases omitted here) AC_MSG_RESULT($fstype)
既使用C又使用C++的包須要同時測試兩個編譯器。Autoconf生成的configure
腳本 在缺省狀況下檢查C的特徵。如下的宏決定在`configure.in'的隨後部分使用那個語言的編譯器。
CC
和
CPP
進行編譯測試而且把
`.c'做爲測試程序的擴展名。 若是已經運行過
AC_PROG_CC
,就把把shell變量
cross_compiling
的值設置成該宏計算的結果, 不然就設置爲空。
CXX
和
CXXPP
進行編譯測試而且把
`.C'做爲測試程序的擴展名。 若是已經運行過
AC_PROG_CXX
,就把把shell變量
cross_compiling
的值設置成該宏計算的結果, 不然就設置爲空。
F77
進行編譯測試而且把
`.f'做爲測試程序的擴展名。 若是已經運行過
AC_PROG_F77
,就把把shell變量
cross_compiling
的值設置成該宏計算的結果, 不然就設置爲空。
AC_LANG_C
、
AC_LANG_CPLUSPLUS
或者
AC_LANG_FORTRAN77
所設定)。不改變當前使用的語言。在須要暫時地切換到其它特殊語言的宏之中使用本宏和
AC_LANG_RESTORE
。
AC_LANG_SAVE
設置的語言,而且把它從棧頂刪除。本宏等價於運行在最後被調用的
AC_LANG_SAVE
以前最近的
AC_LANG_C
、
AC_LANG_CPLUSPLUS
或者
AC_LANG_FORTRAN77
。
調用本宏的次數不要多於調用AC_LANG_SAVE
的次數。
AC_PROG_CPP
或者
AC_PROG_CXXCPP
爲參數調用
AC_REQUIRE
(參見
首要的宏)。
一旦configure
肯定了某個特徵是否存在,它將如何記錄這一信息?這裏有四種記錄方式: 定義一個C預處理器符號、在輸出文件中設置一個變量、爲未來運行configure
而把結果儲存到一個緩存文件中, 以及打印一條消息以便讓用戶知道測試的結果。
對一個特徵的檢測的常見迴應是定義一個表示測試結果的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_CONFIG_HEADER
,它就不該該含有 任何
`#'字符,這是由於
make
將刪除它們。爲了使用shell變量(你須要使用該變量定義一個包含了
m4
引用字符
`['或者
`]'的值),就使用
AC_DEFINE_UNQUOTED
。只有在 你使用
AC_CONFIG_HEADER
的時候,
description纔有用。在這種狀況下,
description被 做爲註釋放置到生成的
`config.h.in'的宏定義以前;沒必要在
`acconfig.h'中說起該宏。下面的例子把 C預處理器變量
EQUATION
的值定義成常量字符串
`"$a > $b"':
AC_DEFINE(EQUATION, "$a > $b")
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_OUTPUT
把變量
variable替換到輸出文件中(一般是一個或多個
`Makefile')。這意味着
AC_OUTPUT
將把輸入文件中的
`@variable@'實例替換成 調用
AC_OUTPUT
時shell變量
variable的值。
variable的值不能包含新行。
AC_OUTPUT
把由shell變量
variable給出的文件名的文件的內容 (不進行替換)插入到輸出文件中。這意味着
AC_OUTPUT
將在輸出文件中(好比
`Makefile.in')把輸入文件中 的
`@variable@'實例替換爲調用
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'就應該包含:
@host_frag@
爲了不在各類configure
腳本中重複地對相同的特徵進行檢查(或者重複地運行同一個腳本), configure
把它的檢查的許多結果儲存在緩存文件。若是在configure
腳本運行時,它找到了 緩存文件,它就從中讀取從前運行的結果而且再也不從新運行這些檢查。所以,configure
將比每次都運行全部的檢查 要快得多。
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_VAL
版本。本宏爲這些宏的最多見的應用提供了便捷的縮寫。 它爲
message調用
AC_MSG_CHECKING
,然後以
cache-id和
commands爲參數 調用
AC_CACHE_VAL
,最後以
cache-id爲參數調用
AC_MSG_RESULT
。
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'。 變量名的各個部分爲:
_cv_
賦予緩存變量的值不能含有新行。一般,它們的是將是布爾(`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
來爲 用戶打印消息。使用這些宏使得修改每種消息如何打印及什麼時候打印變得容易了;這些修改只須要對宏的定義進行就好了, 而全部的調用都將自動地改變。
configure
正在檢查特定的特徵。本宏打印一條以
`checking '開頭,以
`...'結尾,並且不帶新行的消息。它必須跟隨一條對
AC_MSG_RESULT
的調用以打印檢查的結果和新行。
feature-description應該是相似於
`whether the Fortran compiler accepts C++ comments'或者
`for c89'的東西。
若是運行configure
給出了選項`--quiet'或者選項`--silent',本宏什麼也不打印。
AC_MSG_CHECKING
以後調用,而且
result-description 應該完成由
AC_MSG_CHECKING
所打印的消息。
若是運行configure
給出了選項`--quiet'或者選項`--silent',本宏什麼也不打印。
configure
不能完成的錯誤。本宏在標準錯誤輸出中打印一條錯誤消息而且以非零狀態退出
configure
。
error-description應該是相似於
`invalid value $HOME for \$HOME'的東西。
configure
的使用者可能出現的問題。本宏在標準錯誤輸出中打印消息;
configure
繼續向後運行, 因此調用
AC_MSG_WARN
的宏應該爲它們所警告的狀況提供一個缺省的(備份)行爲。
problem-description應該是相似於
`ln -s seems to make hard links'的東西。
下列兩個宏是AC_MSG_CHECKING
和AC_MSG_RESULT
的過期的替代版本。
AC_MSG_CHECKING
相同。 它主要用於打印對一組特徵測試的總體目的的描述,例如:
AC_CHECKING(if stack overflow is detectable)
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
DECL
FUNC
GROUP
HEADER
LIB
PATH
PROG
STRUCT
SYS
TYPE
VAR
在類別以後就是特定的被測試特徵的名稱。宏名中全部的其它單詞指明瞭特徵的特殊方面。 例如,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 <time.h> #ifndef tzname /* For SGI. */ extern char *tzname[]; /* RS6000 and others reject 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
能夠確保只在須要的時候調用宏,而且只被調用一次。
m4
宏
macro-name,就調用它(不帶任何參數)。確保
macro-name 用方括號引發來了。
macro-name必須已經用
AC_DEFUN
定義了,或者包含一個對
AC_PROVIDE
的調用以指明它已經被調用了。
一個替代AC_DEFUN
的方法是使用define
而且調用AC_PROVIDE
。 由於這個技術並不防止出現嵌套的消息,它已是過期的了。
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
,它就警告用戶。
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
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
的腳本以使 系統類型別名規範化。
下列的宏使得configure
腳本能夠得到系統類型。它們運行shell腳本config.guess
以肯定 用戶在命令行中沒有給出的、它們須要的關於主機、目標和建立類型的全部值。它們運行config.sub
對 用戶給出的任何別名進行規範化。若是你使用這些宏,你必須把這兩個shell腳本與你的源代碼一同發佈。關於 AC_CONFIG_AUX_DIR
的信息,你能夠經過該宏設置configure
查找這些腳本的目錄,請參見 建立輸出文件。若是你沒有使用這些宏中的任意一個,configure
就忽略任何傳遞給它的`--host'、`--target'和`--build'選項。
AC_CANONICAL_SYSTEM
中關於主機類型功能的子集。 對於不是編譯工具鏈(compiler toolchain)一部分的程序,這就是所須要的所有功能。
在調用了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_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
的用戶是否要求使用它。肯定在缺省狀態下,是使用仍是不使用每一個包,以及那個參數是合法的, 是你的任務。
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。你將須要用`['和`]'包圍它以生成前導空格。
若是軟件包含有可選的編譯時(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
的用戶是否要求把該特徵包含進來。肯定在缺省狀況下,每一個特徵是否被包含進來,以及那些選項是合法的,是你的任務。
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
中相應的參數(參見與外部軟件一塊兒工做)。
有些軟件包須要複雜的與站點相關(site-specific)的信息。例如用於某種服務、公司名稱和email聯繫地址的主名(host names)。 由於有些配置腳本是經過Metaconfig方式交互地詢問這些信息生成的,人們有時對於按非交互方式, 由Autoconf生成配置腳本如何獲取這些信息感到困惑。
這些站點配置信息應該被儲存在一個僅僅由用戶,而不是程序,編輯的文件中。文件的位置既能夠基於 prefix
變量,也能夠是一個標準的位置,好比說用戶的home目錄。它甚至可能經過一個環境變量給出。 程序應該在運行時,而不是在編譯時,檢查那個文件。運行時配置對於用戶來講更爲方便,而且使得配置過程比 在配置時獲取這些信息要簡單。關於存放數據文件的地點的詳細信息,參見GNU編碼標準中的 `爲安裝目錄而提供的變量'。
Autoconf支持在安裝程序的時候修改程序的名稱。爲了使用這些變換,`configure.in'必須調用宏 AC_ARG_PROGRAM
。
sed
命令序列存入輸出變量
program_transform_name
中。
若是把下列任意選項傳遞給了configure
,程序名就據此進行變換。 不然,若是已經調用了AC_CANONICAL_SYSTEM
而且`--target'的值給出了與主機類型 (用`--host'給出的,或者是在config.sub
中設置的缺省值)不一樣的類型,就把末尾附加了 破折號的目標類型做爲前綴。不然,就不進行程序名變換。
你能夠把下列命令行選項傳遞給configure
以指定名稱的轉換:
--program-prefix=prefix
--program-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
:
transform=@program_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'檢查幾個可以改變它的行爲的可選的環境變量:
configure
合成一個的時候有用。
如下的變量爲分開發布的包提供了一種共享由configure
計算的結果的方式。若是某些包須要它們中某個包, 多是一個通用庫,所須要的特徵的超集那麼這樣作就是有用的。這些變量容許一個`config.status'文件建立 由它的`configure.in'所指明的文件以外的文件,所以它就能夠被用於不一樣的包。
#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的問題。下面是被說起的一些問題。
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而且是沒有版權的。
m4
?爲何Autoconf須要使用GNU ? m4
許多m4
的實現含有編碼性(hard-coded)的,對宏的大小和數量的限制,Autoconf超過了這些限制。 它們還缺乏一些內置宏,沒有它們,諸如Autoconf之類的複雜應用程序將難以應付,它們包括:
builtin indir patsubst __file__ __line__
由於只有軟件維護者須要使用Autoconf,而且由於GNU m4
易於配置和安裝,須要安裝GNU m4
好像是合理的。許多GNU和其它自由軟件的維護者,由於他們更喜好GNU工具,都已經安裝了大部分GNU工具。
若是Autoconf須要GNU 而且GNU 還有一個Autoconf 腳本, 我如何解開這個死結?它好像是一個相似於雞和蛋的問題! m4m4configure
這其實是一種誤解。雖然GNU m4
帶有一個由Autoconf生成的configure
腳本,但在運行腳本 及安裝GNU m4
的時候並不須要安裝Autoconf。只有在你須要修改m4
的configure
腳本的時候,這只是少數幾我的(主要是它的維護者)必須去做的事,才須要Autoconf。
爲何不用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
中設置的,也沒必要複製。
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.in'文件中添加`@CFLAGS@'、`@CPPFLAGS@'和`@LDFLAGS@', 以便它們能夠在configure
運行的時候利用環境中的這些變量的值。這樣作不是必須的,但對用戶來講比較方便。
對於AC_OUTPUT
的每一個非`Makefile'的輸入文件,你還應該添加一條含有`@configure_input@'的註釋, 以便輸出文件將會包含一條註釋以說明它們是由configure
生成的。 自動地爲每種人們在AC_OUTPUT
中輸出的文件選擇正確的註釋語法須要作太多的工做。
把`config.log'和`config.cache'添加到你要在distclean
目標中刪除的文件的列表中。
若是你的`Makefile.in'以下:
prefix = /usr/local exec_prefix = ${prefix}
你必須把它修改爲:
prefix = @prefix@ exec_prefix = @exec_prefix@
不使用`@'字符的老式的對這些變量的替換行爲已經被刪除了。
在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版中,大部分宏被重命名以使用一個更統1、更具備描述性的命名機制。關於對新的命名機制的描述, 參見宏名。雖然舊宏名仍然能夠工做(關於舊宏名和對應的新宏名的列表, 參見陳舊的宏名),若是你更新它們以使用新的宏名,你能夠使你的 `configure.in'文件更加可讀而且易於使用當前的Autoconf文檔。
若是沒有給出參數,autoupdate
就更新`configure.in',而且經過添加後綴`~' (或者在設置了環境變量SIMPLE_BACKUP_SUFFIX
的時候,使用該環境變量的值)以備份原始版本。 若是你帶參數調用autoupdate
,它就讀入那個文件而不是讀入`configure.in',而且把 更新的文件輸出到標準輸出。
autoupdate
接受下列選項:
--help
-h
--macrodir=dir
-m dir
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?它是如何演變到今天的形式的?(爲何它看起來就像大猩猩的吐沫?) 若是你不困惑,那麼本章就不包含對你有用的信息,你也可能會跳過它。若是你困惑,那就讓它明白些...
在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'文件。
因爲我從用戶那裏得到了反饋,我組合了許多改進,使用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
的前端,而且我也有興趣試試一種新語言。
由於個人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的修正。
在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年二月到六月間咱們對處理移植性問題感到厭倦的時候。
在積累了一個關於但願添加的主要特徵的長長的列表,而且在幾年之中各式各樣的人們提供的補丁殘留了古怪的效果以後。 在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的第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檢查的環境變量的列表。
這是一個按照字母順序排序的,Autoconf將在它所建立的文件(一般是一個或更多`Makefile') 中進行替換的變量的列表。關於這些是如何實現的,請參見設定輸出變量。
Jump to: a - b - c - d - e - f - h - i - k - l - m - n - o - p - r - s - t - x - y
這是一個按照字母順序排序的,由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
這是按字母排序的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
This document was generated on 20 June 1999 using the texi2html translator version 1.52.