2007年2月20日 星期二

autoconf手冊(二)

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

現有的測試

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

這些宏列印消息以告訴用戶它們正在測試的特徵,以及它們的測試結果。它們為未來營運的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
# 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預處理器宏和輸出變量︰

如果在相應的系統中,就根據系統類型定義宏SVR4、DGUX、UMAX或者UMAX4_3。
如果它找到了``nlist.h'',就定義NLIST_STRUCT。
如果架構``struct nlist''含有成員``n_un'',就定義NLIST_NAME_UNION。
如果在編譯``getloadavg.c''時定義了LDAV_PRIVILEGED,為了使getloadavg能夠工作,程式就必須特殊地安裝在系統中,並且本宏定義GETLOADAVG_PRIVILEGED。
本宏設定輸出變量NEED_SETGID。如果需要進行特別的安裝,它的值就是``true'',否則值就是``false''。如果NEED_SETGID為``true'',本宏把KMEM_GROUP 設定成將擁有被安裝的程式的組(group)的名字。

宏︰ AC_FUNC_GETMNTENT
為Irix 4、PTX和Unixware在庫``sun''、``seq''和``gen''中分別查找getmntent函數。那麼,如果可以使用getmntent,就定義HAVE_GETMNTENT。
宏︰ AC_FUNC_GETPGRP
如果getpgrp不接受參數(POSIX.1版),就定義GETPGRP_VOID。否則,它就是一個把進程ID作為參數的BSD版本。本宏根本不檢查getpgrp是否存在;如果你需要檢查它的存在性,就首先為 getpgrp函數調用AC_CHECK_FUNC。
宏︰ AC_FUNC_MEMCMP
如果不能使用memcmp函數,或者不能處理8位數據(就像SunOS 4.1.3中的那樣),就把``memcmp.o'' 添加到輸出變量LIBOBJS中去。
宏︰ AC_FUNC_MMAP
如果函數mmap存在並且能夠正確地工作,就定義HAVE_MMAP。只檢查已經映射(already-mapped)的內存的私有固定映射(private fixed mapping)。
宏︰ AC_FUNC_SELECT_ARGTYPES
確定函數select的每個參數的正確類型,並且把這些類型分別定義成SELECT_TYPE_ARG1、 SELECT_TYPE_ARG234和SELECT_TYPE_ARG5。SELECT_TYPE_ARG1的缺省值是``int'',SELECT_TYPE_ARG234的缺省值是``int *'', SELECT_TYPE_ARG5的缺省值是``struct timeval *''。
宏︰ AC_FUNC_SETPGRP
如果setpgrp不接受參數(POSIX.1版),就定義SETPGRP_VOID。否則,該函數就是一個把兩個進程ID作為參數的BSD版本。本宏並不檢查函數setpgrp是否存在;如果你需要檢查該函數的存在性,就首先為setpgrp調用AC_CHECK_FUNC。
宏︰ AC_FUNC_SETVBUF_REVERSED
如果函數setvbuf的第二個參數是緩沖區的類型並且第三個參數是緩沖區指標,而不是其他形式,就定義SETVBUF_REVERSED。這是在System V第3版以前的情況。
宏︰ AC_FUNC_STRCOLL
如果函數strcoll存在並且可以正確地工作,就定義HAVE_STRCOLL。由於有些系統包含了錯誤定義的strcoll,這時就不應該使用strcoll,因此本宏要比``AC_CHECK_FUNCS(strcoll)''多作一些檢查。
宏︰ AC_FUNC_STRFTIME
對於SCO UNIX,在庫``intl''中查找strftime。而後,如果可以使用strftime,就定義HAVE_STRFTIME。
宏︰ AC_FUNC_UTIME_NULL
如果``utime(file, NULL)''把file的時間標記設定成現下,就定義 HAVE_UTIME_NULL。
宏︰ AC_FUNC_VFORK
如果找到了``vfork.h'',就定義HAVE_VFORK_H。如果找不到可以工作的vfork,就把vfork定義成fork。本宏檢查一些已知的vfork實現中的錯誤並且認為如果vfork的實現含有任何一個錯誤,系統就不含有可以工作的vfork。由於子進程很少改變它們的信號句柄(signal handler),所以如果子進程的signal調用(invocation)修改了父進程的信號句柄,將不會被當作實現的錯誤。
宏︰ AC_FUNC_VPRINTF
如果找到了vprintf,就定義HAVE_VPRINTF。否則,如果找到了_doprnt,就定義HAVE_DOPRNT。(如果可以使用vprintf,你就可以假定也可以使用vfprintf 和vsprintf。)
宏︰ AC_FUNC_WAIT3
如果找到了wait3並且該函數填充它的第三個參數的內容(``struct rusage *''),就定義HAVE_WAIT3。在HP-UX中,該函數並不這樣做。

沒有留言: