天天看點

AutoconfAutoconf目錄介紹建立configure腳本初始化和輸出檔案現有的測試編寫測試測試的結果編寫宏手工配置站點配置運作configure腳本重新建立一個配置關于Autoconf的問題從版本1中更新Autoconf的曆史陳舊的宏名環境變量索引輸出變量索引預處理器符号索引宏索引

Autoconf

Creating Automatic Configuration Scripts

Edition 2.13, for Autoconf version 2.13

December 1998

by David MacKenzie and Ben Elliston

目錄

  • 介紹
  • 建立

    configure

    腳本
    • 編寫`configure.in'
    • autoscan

      建立`configure.in'
    • ifnames

      列舉條件
    • autoconf

      建立

      configure

    • autoreconf

      更新

      configure

      腳本
  • 初始化和輸出檔案
    • 尋找

      configure

      的輸入檔案
    • 建立輸出檔案
    • Makefile中的替換
      • 預定義輸出變量
      • 建立目錄
      • 自動地重新建立
    • 配置頭檔案
      • 配置頭檔案模闆
      • autoheader

        建立`config.h.in'
    • 在子目錄中配置其它包
    • 預設的字首
    • configure

      中的版本号
  • 現有的測試
    • 對程式的選擇
      • 對特定程式的檢查
      • 對普通程式和檔案的檢查
    • 庫檔案
    • 庫函數
      • 對特定函數的檢查
      • 對普通函數的檢查
    • 頭檔案
      • 對特定頭檔案的檢查
      • 對普通頭檔案的檢查
    • 結構
    • 類型定義
      • 對特定類型定義的檢查
      • 對普通類型定義的檢查
    • C編譯器的特征
    • Fortran 77編譯器的特征
    • 系統服務
    • UNIX變種
  • 編寫測試
    • 檢驗聲明
    • 檢驗文法
    • 檢驗庫
    • 檢查運作時的特征
      • 運作測試程式
      • 測試程式指南
      • 測試函數
    • 可移植的Shell程式設計
    • 測試值和檔案
    • 多種情況
    • 對語言的選擇
  • 測試的結果
    • 定義C預處理器符号
    • 設定輸出變量
    • 緩存結果
      • 緩存變量名
      • 緩存檔案
    • 列印消息
  • 編寫宏
    • 宏定義
    • 宏名
    • 引用
    • 宏之間的依賴性
      • 首要的宏
      • 建議的順序
      • 過時的宏
  • 手工配置
    • 指定系統的類型
    • 擷取規範的系統類型
    • 系統類型變量
    • 使用系統類型
  • 站點配置
    • 與外部軟體一起工作
    • 選擇包選項
    • 配置站點細節
    • 在安裝的時候改變程式的名稱
      • 轉換選項
      • 轉換的例子
      • 轉換的規則
    • 設定站點預設值
  • 運作

    configure

    腳本
  • 重新建立一個配置
  • 關于Autoconf的問題
    • 釋出

      configure

      腳本
    • 為什麼需要使用GNU

      m4

    • 我如何解開死結?
    • 為什麼不使用Imake?
  • 從版本1中更新
    • 改變了的檔案名
    • 改變了的Makefile
    • 改變了的宏
    • autoupdate

      更新

      configure

    • 改變了的結果
    • 改變了的宏的編寫
  • Autoconf的曆史
    • 起源(Genesis)
    • 出發(Exodus)
    • 上路(Leviticus)
    • 發展(Numbers)
    • 現狀(Deuteronomy)
  • 陳舊的宏名
  • 環境變量索引
  • 輸出變量索引
  • 預處理器符号索引
  • 宏索引

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和庫的影響。

最好讓每個宏調用在`configure.in'中占據單獨的一行。大部分宏并不添加額外的新行; 它們依賴于在宏調用之後的新行以結束指令。這種方法使得生成的

configure

腳本 在不必添加大量的空行的情況下比較容易閱讀。在宏調用的同一行中設定shell變量通常是安全的, 這是因為shell允許出現沒有用新行間隔的指派。

在調用帶參數的宏的時候,在宏名和左括号之間不能出現任何空格。如果參數被

m4

引用字元`['和`]'所包含,參數就可以多于一行。如果你有一個長行, 比如說一個檔案名清單,你通常可以在行的結尾使用反斜線以便在邏輯上把它與下一行進行連接配接 (這是由shell實作的,Autoconf對此沒有進行任何特殊的處理)。

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

你可以在檔案`configure.in'中添加注釋。注釋以

m4

預定義宏

dnl

開頭,該宏丢棄在下一個新行之前的所有文本。這些注釋并不在生成的

configure

腳本中 出現。例如,把下面給出的行作為檔案`configure.in'的開頭是有好處的:

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

autoscan

建立`configure.in'

程式

autoscan

可以幫助你為軟體包建立`configure.in'檔案。如果在指令行中給出了目錄,

autoscan

就在給定目錄及其子目錄樹中檢查源檔案,如果沒有給出目錄,就在目前目錄及其子目錄樹中 進行檢查。它搜尋源檔案以尋找一般的移植性問題并建立一個檔案`configure.scan',該檔案就是軟體包 的`configure.in'預備版本。

在把`configure.scan'改名為`configure.in'之前,你應該手工地檢查它;它可能需要一些調整。

autoscan

偶爾會按照相對于其他宏的錯誤的順序輸出宏,為此

autoconf

将給出警告;你需要 手工地移動這些宏。還有,如果你希望包使用一個配置頭檔案,你必須添加一個對

AC_CONFIG_HEADER

的調用。 (參見配置頭檔案)。可能你還必須在你的程式中修改或者添加一些

#if

指令以使得程式可以與Autoconf合作。(關于有助于該工作的程式的詳情,參見 用

ifnames

列舉條件)。

autoscan

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

隻有在你安裝了Perl的情況下才安裝

autoscan

autoscan

接受如下選項:

--help

列印指令行選項的概述并且退出。

--macrodir=dir

在目錄 dir中,而不是在預設安裝目錄中尋找資料檔案。你還可以把環境變量

AC_MACRODIR

設定成 一個目錄;本選項将覆寫該環境變量。

--verbose

列印它檢查的檔案名稱以及在這些檔案中發現的可能感興趣的符号。它的輸出可能很冗長。

--version

列印Autoconf的版本号并且退出。

ifnames

列舉條件

在為一個軟體包編寫`configure.in'時,

ifnames

可以提供一些幫助。它列印出包已經在C預處理條件 中使用的辨別符。如果包已經被設定得具備了某些可移植性,該程式可以幫助你找到

configure

所需要進行 的檢查。它可能有助于補足由

autoscan

生成的`configure.in'中的某些缺陷。 (參見用

autoscan

建立`configure.in')。

ifnames

掃描所有在指令行中給出的C源代碼檔案(如果沒有給出,就掃描标準輸入)并且把排序後的、由 所有出現在這些檔案中的

#if

#elif

#ifdef

或者

#ifndef

指令中的辨別符清單輸出到标準輸出中。它為每個辨別符輸出單獨的一行,行中辨別符之後是一個由空格分隔的、使用 了該辨別符的檔案名清單。

ifnames

接受如下選項:

--help

-h

列印指令行選項的概述并且退出。

--macrodir=dir

-m dir

在目錄 dir中,而不是預設安裝目錄中尋找Autoconf宏檔案。僅僅被用于擷取版本号。 你還可以把環境變量

AC_MACRODIR

設定成一個目錄;本選項将覆寫該環境變量。

--version

列印Autoconf的版本号并且退出。

autoconf

建立

configure

為了從`configure.in'生成

configure

,不帶參數地運作程式

autoconf

autoconf

用使用Autoconf宏的

m4

宏處理器處理`configure.in'。 如果你為

autoconf

提供了參數,它讀入給出的檔案而不是`configure.in'并且 把配置腳本輸出到标準輸出而不是

configure

。如果你給

autoconf

以參數`-', 它将從标準輸入,而不是`configure.in'中讀取并且把配置腳本輸出到标準輸出。

Autoconf宏在幾個檔案中定義。在這些檔案中,有些是與Autconf一同釋出的;

autoconf

首先讀入它們。 而後它在包含了釋出的Autoconf宏檔案的目錄中尋找可能出現的檔案`acsite.m4',并且在目前目錄中尋找 可能出現的檔案`aclocal.m4'。這些檔案可以包含你的站點的或者包自帶的Autoconf宏定義(詳情請參見 編寫宏)。如果宏在多于一個由

autoconf

讀入了的檔案中被 定義,那麼後面的定義将覆寫前面的定義。

autoconf

接受如下參數:

--help

-h

輸出指令行選項的概述并且退出。

--localdir=dir

-l dir

在目錄 dir中,而不是目前目錄中尋找封包件 `aclocal.m4'。

--macrodir=dir

-m dir

在目錄 dir中尋找安裝的宏檔案。你還可以把環境變量

AC_MACRODIR

設定成 一個目錄;本選項将覆寫該環境變量。

--version

列印Autoconf的版本号并且退出。

autoreconf

更新

configure

腳本

如果你有大量由Autoconf生成的

configure

腳本,程式

autoreconf

可以保留你的一些工作。 它重複地運作

autoconf

(在适當的情況下還運作

autoheader

)以重新建立以目前目錄為根 的目錄樹的Autoconf

configure

腳本和配置頭檔案。在預設情況下,它隻重新建立那些比對應的 `configure.in'或者(如果出現)`aclocal.m4'要舊的檔案。由于在檔案沒有被改變的情況下,

autoheader

并不改變它的輸出檔案的時間标記(timestamp)。這是為了使工作量最小化,修改時間标記是不必要的。 如果你安裝了新版本的Autoconf,你可以以選項`--force'調用

autoreconf

而重新建立 所有的檔案。

如果你在調用

autoreconf

時給出選項`--macrodir=dir'或者 `--localdir=dir',它将把它們傳遞給

autoconf

autoheader

(相對路徑将被正确地調整)。

在同一個目錄樹中,

autoreconf

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

關于在

configure

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

autoreconf

接受如下選項:

--help

-h

列印指令行選項的概述并且退出。

--force

-f

即使在 `configure'腳本和配置頭檔案比它們的輸入檔案( `configure.in',如果出現 了 `aclocal.m4',也包括它)更新的時候,也要重新建立它們。

--localdir=dir

-l dir

autoconf

autoheader

在目錄 dir中,而不是在每個包含 `configure.in' 的目錄中尋找封包件 `aclocal.m4'和(僅指

autoheader

) `acconfig.h' (但不包括 `file.top'和 `file.bot')。

--macrodir=dir

-m dir

在目錄 dir中,而不是預設安裝目錄中尋找Autoconf宏檔案。你還可以把環境變量

AC_MACRODIR

設定成一個目錄;本選項将覆寫該環境變量。

--verbose

列印

autoreconf

運作

autoconf

(如果适當,還有

autoheader

) 的每個目錄的目錄名。

--version

列印Autoconf的版本号并且退出。

初始化和輸出檔案

Autoconf生成的

configure

腳本需要一些關于如何進行初始化,諸如如何尋找包的源檔案,的資訊; 以及如何生成輸出檔案的資訊。本節叙述如何進行初始化和建立輸出檔案。

尋找

configure

的輸入檔案

所有

configure

腳本在作任何其他事情之前都必須調用

AC_INIT

。此外唯一必須調用的宏是

AC_OUTPUT

(參見建立輸出檔案)。

宏: AC_INIT (unique-file-in-source-dir)
處理所有指令行參數并且尋找源代碼目錄。 unique-file-in-source-dir是一些在包的源代碼目錄中檔案;

configure

在目錄中檢查這些檔案是否存在以确定該目錄是否包含源代碼。 人們可能偶爾會用 `--srcdir'給出錯誤的目錄;這是一種安全性檢查。 詳情請參見 運作

configure

腳本。

對于需要手工配置或者使用

install

程式的包來說,雖然在預設源代碼位置在大部分情況 下看起來是正确的,包還是可能需要通過調用

AC_CONFIG_AUX_DIR

來告訴

configure

到那裡去尋找一些其他的shell腳本。

宏: AC_CONFIG_AUX_DIR (dir)
在目錄 dir中使用 `install-sh'、 `config.sub'、 `config.guess'和 Cygnus

configure

配置腳本。它們是配置中使用的輔助檔案。 dir既可以是絕對路徑, 也可以是相對于 `srcdir'的相對路徑。預設值是在 `srcdir'或者 `srcdir/..'或者 `srcdir/../..'中首先找到 `install-sh' 的目錄。不對其他檔案進行檢查,以便使

AC_PROG_INSTALL

不會自動地釋出其他輔助檔案。它還要 檢查 `install.sh',但因為有些

make

程式包含了在沒有 `Makefile'的情況下 從 `install.sh'中建立 `install'的規則,是以那個名字過時了。

建立輸出檔案

每個Autoconf生成的

configure

腳本必須以對

AC_OUTPUT

的調用結尾。它是一個建立 作為配置結果的`Makefile'以及其他一些可能的檔案的宏。此外唯一必須調用的宏是

AC_INIT

(參見尋找

configure

的輸入檔案)。

宏: AC_OUTPUT ([file... [, extra-cmds [, init-cmds]]])

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

如果調用了

AC_CONFIG_HEADER

AC_LINK_FILES

或者

AC_CONFIG_SUBDIRS

,本宏 也将建立出現在它們的參數中的檔案。

一個典型的對

AC_OUTPUT

調用如下:
AC_OUTPUT(Makefile src/Makefile man/Makefile X/Imakefile)       
你可以通過在file之後添加一個用冒号分隔的輸入檔案清單以自行設定輸入檔案名。例如:
AC_OUTPUT(Makefile:templates/top.mk lib/Makefile:templates/lib.mk) AC_OUTPUT(Makefile:templates/vars.mk:Makefile.in:templates/rules.mk)       

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

如果你給出了extra-cmds,那麼這些指令将被插入到`config.status'中以便在`config.status' 完成了其他的所有處理之後運作extra-cmds。如果給出了init-cmds,它們就被插入 extra-cmds之前,并且在

configure

中将對它們進行shell變量、指令和反斜線替換。你可以用 init-cmds把變量從

configure

中傳遞到extra-cmds。如果調用了

AC_OUTPUT_COMMANDS

,在其中給出的指令将緊貼在由本宏給出的指令之前運作。
宏: AC_OUTPUT_COMMANDS (extra-cmds [, init-cmds])
指定在 `config.status'末尾運作的附加的shell指令,以及用于初始化來自于

configure

的所有變量的shell指令。本宏可以被調用多次。下面是一個不太實際的例子:
fubar=27 AC_OUTPUT_COMMANDS([echo this is extra $fubar, and so on.], fubar=$fubar) AC_OUTPUT_COMMANDS([echo this is another, extra, bit], [echo init bit])       

如果你在子目錄中運作

make

,你應該通過使用

make

變量

MAKE

來運作它。

make

的大部分版本把

MAKE

設定成

make

的程式名以及它所需要的任何選項。 (但許多版本并沒有把在指令行中設定的變量的值包括進來,是以它們沒有被自動地傳遞。)一些老版本的

make

并不設定這個變量。以下的宏使你可以在這些版本上使用它。

宏: AC_PROG_MAKE_SET
如果

make

預定義了變量

MAKE

,把輸出變量

SET_MAKE

定義為空。否則,把

SET_MAKE

定義成 `MAKE=make'。為

SET_MAKE

調用

AC_SUBST

為了使用這個宏,在每個其他的、運作

MAKE

的目錄中的`Makefile.in'添加一行:

@SET_MAKE@       

Makefiles中的替換

釋出版本中每個包含了需要被編譯或者被安裝的檔案的目錄都應該含有一個檔案`Makefile.in',

configure

将利用它在那個目錄中建立一個`Makefile'。 為了建立`Makefile',

configure

進行一個簡單的變量替換:用

configure

為`@variable@'選取的值,在`Makefile.in'中對它們進行替換。 按照這種方式被替換到輸出檔案中的變量被稱為輸出變量。在

configure

中,它們是普通 的shell變量。為了讓

configure

把特殊的變量替換到輸出檔案中,必須把那個變量的名字作為調用

AC_SUBST

的參數。其他變量的任何`@variable@'都保持不變。關于 使用

AC_SUBST

建立輸出變量的詳情,請參見設定輸出變量。

使用

configure

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

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

預定義輸出變量

有些輸出變量是由Autoconf宏預定義的。一部分Autoconf宏設定一些附加的輸出變量,這些變量在對這些宏的描述 中被說明。關于輸出變量的完整清單,參見輸出變量索引。下面是每個預 定義變量所包含的内容。關于變量名以`dir'結尾的變量,參見GNU編碼标準中的 `為安裝目錄而提供的變量'。

變量: bindir
用于安裝由使用者運作的可執行檔案的目錄。
變量: configure_input
一個用于說明檔案是由

configure

自動生成的,并且給出了輸入檔案名的注釋。

AC_OUTPUT

在它建立的每個 `Makefile'檔案的開頭添加一個包括了這個變量的注釋行。 對于其他檔案,你應該在每個輸入檔案開頭處的注釋中引用這個變量。例如,一個輸入shell腳本應該以如下 行開頭:
#! /bin/sh # @configure_input@       
這一行的存在也提醒了人們在編輯這個檔案之後需要用

configure

進行處理以使用它。
變量: datadir
用于安裝隻讀的與結構無關的資料的目錄。
變量: exec_prefix
與結構有關的檔案的安裝字首。
變量: includedir
用于安裝C頭檔案的目錄。
變量: infodir
用于安裝Info格式文檔的目錄。
變量: libdir
用于安裝目标代碼庫的目錄。
變量: libexecdir
用于安裝由其他程式運作的可執行檔案的目錄。
變量: localstatedir
用于安裝可以被修改的單機資料的目錄。
變量: mandir
用于安裝man格式的文檔的頂層目錄。
變量: oldincludedir
用于安裝由非gcc編譯器使用的C頭檔案的目錄。
變量: prefix
與結構無關的檔案的安裝字首。
變量: sbindir
用于安裝由系統管理者運作的可執行檔案的目錄。
變量: sharedstatedir
用于安裝可以修改的、與結構無關的資料的目錄。
變量: srcdir
包含了由 `Makefile'使用的源代碼的目錄。
變量: sysconfdir
用于安裝隻讀的單機資料的目錄。
變量: top_srcdir
包的頂層源代碼目錄。在目錄的頂層,它與

srcdir

相同。
變量: CFLAGS
為C編譯器提供的調試和優化選項。如果在運作

configure

時,沒有在環境中設定它,就在你 調用

AC_PROG_CC

的時候設定它的預設值(如果你沒有調用

AC_PROG_CC

,它就為空)。

configure

在編譯程式以測試C的特征時,使用本變量。
變量: CPPFLAGS
為C預處理器和編譯器提供頭檔案搜尋目錄選項( `-Idir')以及其他各種選項。如果在運作

configure

時,在環境中沒有設定本變量,預設值就是空。

configure

在編譯或者預處理 程式以測試C的特征時,使用本變量。
變量: CXXFLAGS
為C++編譯器提供的調試和優化選項。如果在運作

configure

時,沒有在環境中設定本變量,那麼 就在你調用

AC_PROG_CXX

時設定它的預設值(如果你沒有調用

AC_PROG_CXX

,它就為空)。

configure

在編譯程式以測試C++的特征時,使用本變量。
變量: FFLAGS
為Fortran 77編譯器提供的調試和優化選項。如果在運作

configure

時,在環境中沒有設定本變量,那麼它的 預設值就在你調用

AC_PROG_F77

時被設定(如果你沒有調用

AC_PROG_F77

,它就為空)。

configure

在編譯程式以測試Fortran 77的特征時,使用本變量。
變量: DEFS
傳遞給C編譯器的 `-D'選項。如果調用了

AC_CONFIG_HEADER

configure

就用 `-DHAVE_CONFIG_H'代替 `@DEFS@'(參見 配置頭檔案)。 在

configure

進行它的測試時,本變量沒有被定義,隻有在建立輸出檔案時候才定義。關于如何檢查從前的 測試結果,請參見 設定輸出變量。
變量: LDFLAGS
為連接配接器提供的Stripping( `-s')選項和其他各種選項。如果在運作

configure

時, 在環境中沒有設定本變量,它的預設值就是空。

configure

在連接配接程式以測試C的特征時使用本變量。
變量: LIBS
傳遞給連接配接器的 `-l'和 `-L'選項。

建立目錄

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

為了支援這個功能,

make

用變量

VPATH

來尋找儲存在源代碼目錄中的檔案。 GNU

make

和其他大部分近來的

make

程式都可以這樣做。老版本的

make

程式不支援

VPATH

;在使用它們的時候,源代碼必須與目标代碼處于同一個目錄。

為了支援

VPATH

,每個`Makefile.in'檔案都應該包含下列兩行:

srcdir = @srcdir@ VPATH = @srcdir@       

不要把

VPATH

設定成其他變量的值,比如說`VPATH = $(srcdir)',這是因為 某些版本的

make

并不對

VPATH

的值進行變量替換。

configure

生成`Makefile'的時候,它用正确的值對

srcdir

進行替換。

除非在隐含規則中,不要使用

make

變量

$<

,它将被展開成到源代碼目錄的檔案 的路徑(通過

VPATH

找到的)。(諸如`.c.o'的隐含規則用于說明如何從`.c' 檔案建立`.o'檔案)有些版本的

make

在隐含規則中不設定

$<

; 它們被展開成空值。

`Makefile'指令行總是應該通過使用字首`$(srcdir)/'來引用源代碼檔案。例如:

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

自動地重新建立

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

因為

VPATH

機制的限制,應該包含`${srcdir}/'字首。

在重新建立不改變`config.h.in'和`config.h'的内容的情況下,就不會改變這兩個檔案的時間标記 ,是以需要`stamp-'檔案。這個特征避免了不必要的重新編譯工作。你應該把檔案`stamp-h.in' 包含在你的包的釋出中,以便

make

能夠把`config.h.in'看作是更新了的檔案。在一些 老的BSD系統中,

touch

或者任何可能導緻空檔案的指令不會更改時間标記,是以使用諸如

echo

之類的指令。

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

此外,你應該把`echo timestamp > stamp-h'作為extra-cmds參數傳遞給

AC_OUTPUT

, 以便`config.status'能夠确認`config.h'是更新了的。關于

AC_OUTPUT

的詳情,請參見 建立輸出檔案。

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

配置頭檔案

在包測試的C預處理器符号比較多的時候,用于把`-D'傳遞給編譯器的指令行就會變得很長。 這導緻了兩個問題。一個是通過觀察尋找

make

輸出中的錯誤變得困難了。更嚴重的是,指令行 可能超過某些作業系統的長度限制。作為把`-D'選項傳遞給編譯器的替代辦法,

configure

腳本可以建立一個包含了`#define'指令的C頭檔案。宏

AC_CONFIG_HEADER

選擇了這種輸出。它應該在

AC_INIT

之後立即調用。

包應該在引入其他任何頭檔案之前`#include'配置頭檔案,以防止出現聲明中的不一緻性 (例如,配置頭檔案可能重定義了

const

)。使用`#include <config.h>' 并且把選項`-I.'(或者是`-I..';或者是任何包含`config.h' 的目錄)傳遞給C編譯器,而不是使用`#include "config.h"'。按照這種方式,即使源代碼 自行進行配置(可能是建立釋出版本),其他建立目錄也可以在沒有找到`config.h'的情況下, 從源代碼目錄進行配置。

宏: AC_CONFIG_HEADER (header-to-create ...)
使得

AC_OUTPUT

建立出現在以空格分隔的清單 header-to-create中的檔案, 以包含C預處理器

#define

語句,并在生成的檔案中用 `-DHAVE_CONFIG_H' ,而不是用

DEFS

的值,替換 `@DEFS@'。常用在 header-to-create 中的檔案名是 `config.h'。

如果header-to-create給出的檔案已經存在并且它的内容和

AC_OUTPUT

将要生成的 内容完全一緻,這些檔案就保持不變。這樣做就使得對配置的某些修改不會導緻對依賴于頭檔案的目标檔案進行 不必要的重新編譯。

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

AC_CONFIG_HEADER(defines.h:defines.hin) AC_CONFIG_HEADER(defines.h:defs.pre:defines.h.in:defs.post)       
這樣做使得你的檔案名能夠被MS-DOS所接受,或者可以把模闆(boilerplate)添加到檔案的開頭和/或結尾。

配置頭檔案模闆

你的釋出版本應該包含一個如你所望的最終的頭檔案那樣的模闆檔案,它包括注釋、以及

#define

語句的預設值。例如,假如你的`configure.in'進行了下列調用:

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

那麼你就應該在`conf.h.in'中包含下列代碼。 在含有`unistd.h'的系統中,

configure

應該把0改成1。在其他系統中,這一行将保持不變。

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

如果你的代碼使用

#ifdef

而不是

#if

來測試配置選項,預設值就可能是取消對一個變量 的定義而不是把它定義成一個值。在含有`unistd.h'的系統中,

configure

将修改讀入的第二行 `#define HAVE_UNISTD_H 1'。在其他的系統中,(在系統預定義了那個符号的情況下)

configure

将以注釋的方式排除這一行。

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

autoheader

建立`config.h.in'

程式

autoheader

可以建立含有C的`#define'語句的模闆檔案以供

configure

使用。 如果`configure.in'調用了

AC_CONFIG_HEADER(file)

autoheader

就建立 `file.in';如果給出了多檔案參數,就使用第一個檔案。否則,

autoheader

就建立 `config.h.in'。

如果你為

autoheader

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

autoheader

,它就從标準輸入中,而不是從`configure.in'中讀出,并且把頭檔案輸出到标準輸出中去。

autoheader

掃描`configure.in'并且找出它可能要定義的C預處理器符号。它從一個名為 `acconfig.h'的檔案中複制注釋、

#define

#undef

語句,該檔案與Autoconf一同釋出 并且一同安裝。如果目前目錄中含有`acconfig.h'檔案,它也會使用這個檔案。如果你用

AC_DEFINE

定義了任何附加的符号,你必須在建立的那個`acconfig.h'檔案中包含附加的符号。對于由

AC_CHECK_HEADERS

AC_CHECK_FUNCS

AC_CHECK_SIZEOF

或者

AC_CHECK_LIB

定義的符号,

autoheader

生成注釋和

#undef

語句,而不是從一個 檔案中複制它們,這是因為可能的符号是無限的。

autoheader

建立的檔案包含了大部分

#define

#undef

語句,以及相關的注釋。 如果`./acconfig.h'包含了字元串`@TOP@',

autoheader

就把在包含`@TOP@' 的行之前的所有行複制到它生成的檔案的開頭。相似地,如果`./acconfig.h'包含了字元串`@BOTTOM@',

autoheader

就把那一行之後的所有行複制到它生成的檔案的末尾。這兩個字元串的任何一個都可以被忽略, 也可以被同時忽略。

産生相同效果的另一種辦法是在目前目錄中建立檔案`file.top'(通常是`config.h.top')和/或 檔案`file.bot'。如果它們存在,

autoheader

就把它們分别複制到它的輸出的開頭和末尾。 不鼓勵使用它們是因為它們的檔案名含有兩個點,并是以不能在MS-DOS中儲存;它們在目錄中多建立了兩個檔案。但如果你給出 選項`--localdir=dir'以使用在其他目錄中的`acconfig.h',它們就為你提供了一種把 定制的模闆(boilerplate)放入各個獨立的`config.h.in'中的方式。

autoheader

接受如下選項:

--help

-h

列印對指令行選項的概述并且退出。

--localdir=dir

-l dir

在目錄 dir中,而不是在目前目錄中,尋找封包件 `aclocal.m4'和 `acconfig.h' (但不包括 `file.top'和 `file.bot')。

--macrodir=dir

-m dir

在目錄 dir中尋找安裝的宏檔案和 `acconfig.h'。你還可以把環境變量

AC_MACRODIR

設定成一個目錄;本選項将覆寫該環境變量。

--version

列印Autoconf的版本号并且退出。

在子目錄中配置其它包

在大多數情況下,調用

AC_OUTPUT

足以在子目錄中生成`Makefile'。然而,控制了多于一個 獨立包的

configure

腳本可以使用

AC_CONFIG_SUBDIRS

來為每個子目錄中的其他包運作

configure

腳本。

宏: AC_CONFIG_SUBDIRS (dir ...)
使得

AC_OUTPUT

在每個以空格分隔的清單中給出的子目錄 dir中運作

configure

。 如果沒有發現某個給出的 dir,不會作為錯誤報告,是以一個

configure

腳本可以配置一個 大的源代碼樹中出現的任何一個部分。如果在給出的 dir中包含了 `configure.in',但沒有包含

configure

,就使用由

AC_CONFIG_AUXDIR

找到的Cygnus

configure

腳本。

用與本

configure

腳本完全相同的指令行參數調用子目錄中的

configure

腳本,如果需要, 會有較小的修改(例如,為緩沖檔案或者源代碼目錄調整相對路徑)。本宏還把輸出變量

subdirs

設定成 目錄清單`dir...'。`Makefile'規則可以使用該變量以确定需要進入那些子目錄。 這個宏可以多次調用。

預設的字首

在預設狀态下,

configure

把它所安裝的檔案的字首設定成`/usr/local'。

configure

的使用者可以通過選項`--prefix'和`--exec-prefix'選擇一個不同的字首。 有兩種方式修改預設的行為:在建立

configure

時,和運作

configure

時。

有些軟體包在預設情況下可能需要安裝到`/usr/local'以外的目錄中。為此,使用宏

AC_PREFIX_DEFAULT

宏: AC_PREFIX_DEFAULT (prefix)
把預設的安裝字首設定成 prefix,而不是 `/usr/local'。

對于使用者來說,讓

configure

根據它們已經安裝的相關程式的位置來猜測安裝字首,可能會帶來友善。如果你 希望這樣做,你可以調用

AC_PREFIX_PROGRAM

宏: AC_PREFIX_PROGRAM (program)
如果使用者沒有給出安裝字首(使用選項 `--prefix'),就按照shell的方式,在

PATH

中尋找 program,進而猜出一個安裝字首。如果找到了 program,就把字首設定成包含 program 的目錄的父目錄;否則,就不改變在 `Makefile.in'中給定的字首。例如,如果 program是

gcc

,并且

PATH

包括了 `/usr/local/gnu/bin/gcc',就把字首設定為 `/usr/local/gnu'。

configure

中的版本号

以下的宏為

configure

腳本管理版本号。使用它們是可選的。

宏: AC_PREREQ (version)
確定使用的是足夠新的Autoconf版本。如果用于建立

configure

的Autoconf的版本比 version 要早,就在标準錯誤輸出列印一條錯誤消息并不會建立

configure

。例如:
AC_PREREQ(1.8)       
如果你的`configure.in'依賴于在不同Autoconf版本中改變了的、不明顯的行為,本宏就是有用的。 如果它僅僅是需要近來增加的宏,那麼

AC_PREREQ

就不太有用,這是因為程式

autoconf

已經 告訴了使用者那些宏沒有被找到。如果`configure.in'是由一個在提供

AC_PREREQ

之前的更舊的 Autoconf版本處理的,也會發生同樣的事。
宏: AC_REVISION (revision-info)
把删除了任何美元符或者雙引号的修訂标記(revision stamp)複制到

configure

腳本中。 本宏使得你的從 `configure.in'傳遞到

configure

的修訂标記不會在你送出(check in)

configure

的時候被RCS或者CVS修改。你可以容易地決定一個特定的

configure

對應與 `configure.in'的哪個修訂版。

把本宏放在

AC_INIT

之前是個好主意,它可以使修訂号接近`configure.in'和

configure

的開頭。為了支援你這樣做,

AC_REVISION

就像

configure

通常作的那樣,以 `#! /bin/sh'開始它的輸出。

例如,在`configure.in'中這一行為:

AC_REVISION($Revision: 1.30 $)dnl       

configure

中産生了:
#! /bin/sh # From configure.in Revision: 1.30       

現有的測試

這些宏測試了包可能需要或者需要使用的特定的系統特征。如果你要測試這些宏所不能測試的特征,可能你可以用 适當的參數調用主測試宏來達到目的(參見編寫測試)。

這些宏列印消息以告訴使用者它們正在測試的特征,以及它們的測試結果。它們為未來運作的

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)。
/* 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       
宏: 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預處理器 宏和輸出變量:
  1. 如果在相應的系統中,就根據系統類型定義宏

    SVR4

    DGUX

    UMAX

    或者

    UMAX4_3

  2. 如果它找到了`nlist.h',就定義

    NLIST_STRUCT

  3. 如果結構`struct nlist'含有成員`n_un',就定義

    NLIST_NAME_UNION

  4. 如果在編譯`getloadavg.c'時定義了

    LDAV_PRIVILEGED

    ,為了使

    getloadavg

    能夠 工作,程式就必須特殊地安裝在系統中,并且本宏定義

    GETLOADAVG_PRIVILEGED

  5. 本宏設定輸出變量

    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中,該函數并不這樣做。

對普通函數的檢查

這些宏被用于尋找沒有包括在特定函數測試宏中的函數。如果函數可能出現在除了預設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 <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'。

宏: 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 <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)'。
宏: 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 <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       
宏: 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 <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'。
宏: 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 <sys/time.h> # include <time.h> #else # if HAVE_SYS_TIME_H #  include <sys/time.h> # else #  include <time.h> # 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測試中出現了錯誤,這些資訊可以幫助你了解它們意味着什麼,這有助 于你找到最佳的解決問題的辦法。

這些宏檢查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 <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程式設計

在編寫你自己的測試時,為了使你的代碼可以移植,你應該避免使用某些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'的随後部分使用那個語言的編譯器。

宏: 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"':
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

将把輸入檔案中的 `@variable@'執行個體替換成 調用

AC_OUTPUT

時shell變量 variable的值。 variable的值不能包含新行。
宏: AC_SUBST_FILE (variable)
另一種從shell變量建立輸出變量的方式。讓

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

将比每次都運作所有的檢查 要快得多。

宏: 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 <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

可以確定隻在需要的時候調用宏,并且隻被調用一次。

宏: 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)做出決定,該規範系統名的形式為:

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
檢測系統類型并把輸出變量設定成規範的系統類型。關于該宏設定變量的細節,參見 系統類型變量。
宏: 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-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'選項永遠不要使特征的行為 變得不同或者導緻一個特征代替另一個特征。它們隻應該導緻程式的一部分被建立而另一部分不建立。

使用者可以通過在特征名之後添加`='和參數來給出參數。給出參數`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
用于執行 `@variable@'替換的檔案。預設的檔案在 `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需要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'檔案中添加`@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版中,大部分宏被重命名以使用一個更統一、更具有描述性的命名機制。關于對新的命名機制的描述, 參見宏名。雖然舊宏名仍然可以工作(關于舊宏名和對應的新宏名的清單, 參見陳舊的宏名),如果你更新它們以使用新的宏名,你可以使你的 `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的第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
  • This document was generated on 20 June 1999 using the texi2html translator version 1.52.