[本文轉載來源為:http://doc.sheup.com/linux/linux403.htm]
陳舊的宏名
在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
2007年2月20日 星期二
autoconf手冊(六)
[本文轉載來源為:http://doc.sheup.com/linux/linux403.htm]
我如何解開死結?
如果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需要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手冊(五)
[本文轉載來源為:http://doc.sheup.com/linux/linux403.htm]
獲取規範的系統類型
下列的宏使得configure腳本可以獲得系統類型。它們營運shell腳本config.guess以確定用戶在命令行中沒有給出的、它們需要的關於主機、目標和創建類型的所有值。它們營運config.sub對用戶給出的任何別名進行規範化。如果你使用這些宏,你必須把這兩個shell腳本與你的源代碼一同發布。關於 AC_CONFIG_AUX_DIR的訊息,你可以透過該宏設定configure查找這些腳本的目錄,請參見 創建輸出檔案。如果你沒有使用這些宏中的任意一個,configure 就忽略任何傳遞給它的``--host''、``--target''和``--build''選項。
宏︰ AC_CANONICAL_SYSTEM
檢測系統類型並把輸出變量設定成規範的系統類型。關於該宏設定變量的細節,參見系統類型變量。
宏︰ AC_CANONICAL_HOST
只執行AC_CANONICAL_SYSTEM中關於主機類型功能的子集。對於不是編譯工具鏈(compiler toolchain)一部分的程式,這就是所需要的全部功能。
宏︰ AC_VALIDATE_CACHED_SYSTEM_TUPLE (cmd)
如果緩存檔案與當前主機、目標和創建系統類型不一致,就執行cmd或者列印一個缺省的錯誤消息。
系統類型變量
在調用了AC_CANONICAL_SYSTEM之後,下列輸出變量包含了系統類型訊息。在調用了AC_CANONICAL_HOST 之後,只設定了下列host變量。
build,host,target
規範系統名稱;
build_alias,host_alias,target_alias
如果使用了config.guess,就是用戶指定的名稱或者規範名稱;
build_cpu,build_vendor,build_os
host_cpu,host_vendor,host_os
target_cpu,target_vendor,target_os
為方便而提供的規範名稱的獨立部分。
使用系統類型
你將如何使用規範的系統類型?通常,你在``configure.in''中的一個或多個case語句中使用它來選擇系統特定的C檔案。而後把那些使用基於系統名的檔案名的檔案連接到諸如``host.h''或``target.c''的普通的檔案上。case語句模型允許使用shell萬用字元對多種情況進行編組,就像下面的片斷︰
case ""$target"" in
i386-*-mach* i386-*-gnu*) obj_format=aout emulation=mach bfd_gas=yes ;;
i960-*-bout) obj_format=bout ;;
esac
宏︰ AC_LINK_FILES (source...,dest...)
使得AC_OUTPUT把每個存在檔案的source連接到對應連接名dest。如果可能,創建一個符號連接,否則就創建硬連接。dest和source應該是相對於頂層源代碼目錄或者創建目錄的相對路徑。可以多次調用本宏。
例如,下列調用︰
AC_LINK_FILES(config/${machine}.h config/${obj_format}.h,host.h object.h)
在當前目錄中創建``host.h'',它是一個到``srcdir/config/${machine}.h''的連接,並且創建``object.h'',它是一個到``srcdir/config/${obj_format}.h''的連接。
你還可以使用主機系統類型以尋找交叉編譯工具。關於完成該任務的宏AC_CHECK_TOOL的訊息,參見對普通程式和檔案的檢查。
站點配置
configure腳本支援幾種本地配置決策模式。它們是用戶指明外部軟體的位置,包括或除去可選的特徵,以修改過的名稱安裝的程式,以及為configure選項設定缺省值的手段。
與外部軟體一起工作
有些套裝軟件需要,或者可選地使用其它已經安裝的套裝軟件。用戶可以把命令行選項傳遞給configure 以指明使用那個外部軟體。選項採用下列形式之一︰
--with-package[=arg]
--without-package
例如,``--with-gnu-ld''的意思是使用GNU連接器而不是任何其它連接器。``--with-x''的意思是使用X Window系統。
用戶可以給出包名加``=''加參數的命令行參數。``no''是關於包的缺省參數;它表示不使用包。既不是``yes''又不是``no''的參數將包含其它包的名字或者版本號,以便更精確地指定本程式可以與之協同工作的包。如果沒有給出參數,``--without-package''的缺省參數為``yes''。 ``--without-package''等價於``--with-package=no''。
configure腳本並不對它們不支援的``--with-package''選項發出警告。本特徵允許頂層目錄中的configure腳本配置一個包含多個包的源代碼樹。在包支援不同的選項的時候,不會因為給出了只有一部分包支援的選項而導致不必要的錯誤消息。一個不幸的副作用是選項的拼寫錯誤就不能被檢查出來了。迄今為止還沒有處理該問題的更好辦法。
對於每個可能使用的外部套裝軟件,``configure.in''都應該調用AC_ARG_WITH以檢測 configure的用戶是否要求使用它。確定在缺省狀態下,是使用還是不使用每個包,以及那個參數是合法的,是你的任務。
宏︰ AC_ARG_WITH (package,help-string [,action-if-given [,action-if-not-given]])
如果用戶以選項``--with-package''或者``--without-package''調用 configure,就營運shell命令action-if-given。如果兩個選項都沒有給出,就營運shell命令 action-if-not-given。名字package給出了本程式應該與之協同工作的其它套裝軟件。它應該僅僅由字母、數字和破折號(dashes)組成。
shell命令action-if-given可以透過shell變量withval得到選項的參數,該變量的值實際上就是把 shell變量with_package的值中的所有``-''字符替換為``_''而得的。如果你願意,可以使用變量with_package。
參數help-string是對選項的描述,它看起來應該像︰
--with-readline support fancy command line editing
如果需要給出更多的細節,help-string可能多於一行。只要確保``configure --help''中的列的排列就可以了。不要在求助字元串中使用tab。你將需要用``[''和``]''包圍它以生成前導空格。
宏︰ AC_WITH (package,action-if-given [,action-if-not-given])
這是不支援求助字元串的AC_ARG_WITH的過時版本。
選擇包選項
如果套裝軟件含有可選的編譯時(compile-time)特徵,用戶就可以在調用configure時使用命令行選項來指明是否編譯它們。選項採用如下形式之一︰
--enable-feature[=arg]
--disable-feature
這些選項允許用戶選擇可選的選項進行創建和安裝。``--enable-feature''選項永遠不要使特徵的行為變得不同或者導致一個特徵代替另一個特徵。它們只應該導致程式的一部分被創建而另一部分不創建。
用戶可以透過在特徵名之後添加``=''和參數來給出參數。給出參數``no''表示 不能使用該特徵。一個帶有參數的特徵看起來就像``--enable-debug=stabs''。如果沒有給出參數,它的缺省值就是``yes''。``--disable-feature''等價於 ``--enable-feature=no''。
configure腳本並不對它們所不支援的``--enable-feature''選項發出警告。本特徵允許頂層目錄中的configure腳本配置一個包含多個包的源代碼樹。在包支援不同的選項的時候,不會因為給出了只有一部分包支援的選項而導致不必要的錯誤消息。一個不幸的副作用是選項的拼寫錯誤就不能被檢查出來了。迄今為止還沒有處理該問題的更好辦法。
對於每個可選的特徵,``configure.in''都應該調用AC_ARG_ENABLE以檢測configure 的用戶是否要求把該特徵包含進來。確定在缺省情況下,每個特徵是否被包含進來,以及那些選項是合法的,是你的任務。
宏︰ AC_ARG_ENABLE (feature,help-string [,action-if-given [,action-if-not-given]])
如果用戶以選項``--enable-feature''或者``--disable-feature''調用 configure,就營運shell命令action-if-given。如果兩個選項都沒有給出,就營運shell命令 action-if-not-given。名稱feature表示可選的用戶級功能。它應該僅僅由字母、數字和破折號(dashes)組成。
shell命令可以透過訪問shell變量enableval來得到選項的參數,該變量的值實際上就是把shell變量 enable_feature的值中所有的``-''字符替換成``_''而得到的。如果你願意,可以使用變量enable_feature。help-string參數類似於 AC_ARG_WITH中相應的參數(參見與外部軟體一起工作)。
宏︰ AC_ENABLE (feature,action-if-given [,action-if-not-given])
這是不支援求助字元串的AC_ARG_ENABLE的過時版本。
配置站點細節
有些套裝軟件需要複雜的與站點相關(site-specific)的訊息。例如用於某種服務、公司名稱和email聯繫位址的主名(host names)。因為有些配置腳本是透過Metaconfig模式交互地詢問這些訊息生成的,人們有時對於按非交互模式,由Autoconf生成配置腳本如何獲取這些訊息感到困惑。
這些站點配置訊息應該被儲存在一個僅僅由用戶,而不是程式,編輯的檔案中。檔案的位置既可以基於 prefix變量,也可以是一個標準的位置,比如說用戶的home目錄。它甚至可能透過一個環境變量給出。程式應該在營運時,而不是在編譯時,檢查那個檔案。營運時配置對於用戶來說更為方便,並且使得配置過程比在配置時獲取這些訊息要簡單。關於存放數據檔案的地點的詳細訊息,參見GNU編碼標準中的 ``為安裝目錄而提供的變量''。
在安裝的時候改變程式的名稱
Autoconf支援在安裝程式的時候修改程式的名稱。為了使用這些變換,``configure.in''必須調用宏 AC_ARG_PROGRAM。
宏︰ AC_ARG_PROGRAM
把對被安裝的程式的名稱進行替換的sed命令序列存入輸出變量program_transform_name中。
如果把下列任意選項傳遞給了configure,程式名就據此進行變換。否則,如果已經調用了AC_CANONICAL_SYSTEM並且``--target''的值給出了與主機類型(用``--host''給出的,或者是在config.sub中設定的缺省值)不同的類型,就把末尾附加了破折號的目標類型作為前綴。否則,就不進行程式名變換。
轉換選項
你可以把下列命令行選項傳遞給configure以指定名稱的轉換︰
--program-prefix=prefix
為名稱添加前綴prefix;
--program-suffix=suffix
為名稱添加後綴suffix;
--program-transform-name=expression
對名字作sed替換expression。
轉換的例子
這些變換對於作為交叉編譯開發環境的一部分的程式是有用的。例如,用``--target=i960-vxworks''選項配置的營運在Sun 4上的交叉彙編器通常以``i960-vxworks-as''為名稱進行安裝,而不是以``as''為名安裝,該名稱將於原來的Sun 4彙編器混淆。
如果你不希望安裝在你的系統上的GNU程式遮蔽具有相同名稱的其它程式,你可以強行要求程式名以``g''開頭。例如,如果你使用``--program-prefix=g''來配置GNU diff,那麼在你營運``make install'' 的時候,它就安裝到``/usr/local/bin/gdiff''。
作為更複雜的例子,你可以使用
--program-transform-name=''s/^/g/; s/^gg/g/; s/^gless/less/''
在源代碼樹中的大部分程式的名字之前附加``g'',已經含有一個``g''的程式,諸如gdb,和不是GNU程式的程式,比如說less和lesskey,除外。(它假定你有一個包含了設定成使用這些特徵的程式的源代碼樹。)
同時安裝某些程式的多個版本的一種方法是為其中一個程式的名稱或為所有程式的名稱附加版本號。例如,如果你還希望把 Autoconf版本1保留一段時間,你可以使用``--program-suffix=2''來配置Autoconf第2版,並且以名稱 ``/usr/local/bin/autoconf2''、``/usr/local/bin/autoheader2''等等來安裝程式。
轉換的規則
下面是如何在``Makefile.in''中使用變量program_transform_name︰
transform=@program_transform_name@
install: all
$(INSTALL_PROGRAM) myprog $(bindir)/``echo myprogsed ''$(transform)''``
uninstall:
rm -f $(bindir)/``echo myprogsed ''$(transform)''``
如果你要安裝多個程式,你可以透過一個循環來完成︰
PROGRAMS=cp ls rm
install:
for p in $(PROGRAMS); do
$(INSTALL_PROGRAM) $$p $(bindir)/``echo $$psed ''$(transform)''``;
done
uninstall:
for p in $(PROGRAMS); do
rm -f $(bindir)/``echo $$psed ''$(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工具。
獲取規範的系統類型
下列的宏使得configure腳本可以獲得系統類型。它們營運shell腳本config.guess以確定用戶在命令行中沒有給出的、它們需要的關於主機、目標和創建類型的所有值。它們營運config.sub對用戶給出的任何別名進行規範化。如果你使用這些宏,你必須把這兩個shell腳本與你的源代碼一同發布。關於 AC_CONFIG_AUX_DIR的訊息,你可以透過該宏設定configure查找這些腳本的目錄,請參見 創建輸出檔案。如果你沒有使用這些宏中的任意一個,configure 就忽略任何傳遞給它的``--host''、``--target''和``--build''選項。
宏︰ AC_CANONICAL_SYSTEM
檢測系統類型並把輸出變量設定成規範的系統類型。關於該宏設定變量的細節,參見系統類型變量。
宏︰ AC_CANONICAL_HOST
只執行AC_CANONICAL_SYSTEM中關於主機類型功能的子集。對於不是編譯工具鏈(compiler toolchain)一部分的程式,這就是所需要的全部功能。
宏︰ AC_VALIDATE_CACHED_SYSTEM_TUPLE (cmd)
如果緩存檔案與當前主機、目標和創建系統類型不一致,就執行cmd或者列印一個缺省的錯誤消息。
系統類型變量
在調用了AC_CANONICAL_SYSTEM之後,下列輸出變量包含了系統類型訊息。在調用了AC_CANONICAL_HOST 之後,只設定了下列host變量。
build,host,target
規範系統名稱;
build_alias,host_alias,target_alias
如果使用了config.guess,就是用戶指定的名稱或者規範名稱;
build_cpu,build_vendor,build_os
host_cpu,host_vendor,host_os
target_cpu,target_vendor,target_os
為方便而提供的規範名稱的獨立部分。
使用系統類型
你將如何使用規範的系統類型?通常,你在``configure.in''中的一個或多個case語句中使用它來選擇系統特定的C檔案。而後把那些使用基於系統名的檔案名的檔案連接到諸如``host.h''或``target.c''的普通的檔案上。case語句模型允許使用shell萬用字元對多種情況進行編組,就像下面的片斷︰
case ""$target"" in
i386-*-mach* i386-*-gnu*) obj_format=aout emulation=mach bfd_gas=yes ;;
i960-*-bout) obj_format=bout ;;
esac
宏︰ AC_LINK_FILES (source...,dest...)
使得AC_OUTPUT把每個存在檔案的source連接到對應連接名dest。如果可能,創建一個符號連接,否則就創建硬連接。dest和source應該是相對於頂層源代碼目錄或者創建目錄的相對路徑。可以多次調用本宏。
例如,下列調用︰
AC_LINK_FILES(config/${machine}.h config/${obj_format}.h,host.h object.h)
在當前目錄中創建``host.h'',它是一個到``srcdir/config/${machine}.h''的連接,並且創建``object.h'',它是一個到``srcdir/config/${obj_format}.h''的連接。
你還可以使用主機系統類型以尋找交叉編譯工具。關於完成該任務的宏AC_CHECK_TOOL的訊息,參見對普通程式和檔案的檢查。
站點配置
configure腳本支援幾種本地配置決策模式。它們是用戶指明外部軟體的位置,包括或除去可選的特徵,以修改過的名稱安裝的程式,以及為configure選項設定缺省值的手段。
與外部軟體一起工作
有些套裝軟件需要,或者可選地使用其它已經安裝的套裝軟件。用戶可以把命令行選項傳遞給configure 以指明使用那個外部軟體。選項採用下列形式之一︰
--with-package[=arg]
--without-package
例如,``--with-gnu-ld''的意思是使用GNU連接器而不是任何其它連接器。``--with-x''的意思是使用X Window系統。
用戶可以給出包名加``=''加參數的命令行參數。``no''是關於包的缺省參數;它表示不使用包。既不是``yes''又不是``no''的參數將包含其它包的名字或者版本號,以便更精確地指定本程式可以與之協同工作的包。如果沒有給出參數,``--without-package''的缺省參數為``yes''。 ``--without-package''等價於``--with-package=no''。
configure腳本並不對它們不支援的``--with-package''選項發出警告。本特徵允許頂層目錄中的configure腳本配置一個包含多個包的源代碼樹。在包支援不同的選項的時候,不會因為給出了只有一部分包支援的選項而導致不必要的錯誤消息。一個不幸的副作用是選項的拼寫錯誤就不能被檢查出來了。迄今為止還沒有處理該問題的更好辦法。
對於每個可能使用的外部套裝軟件,``configure.in''都應該調用AC_ARG_WITH以檢測 configure的用戶是否要求使用它。確定在缺省狀態下,是使用還是不使用每個包,以及那個參數是合法的,是你的任務。
宏︰ AC_ARG_WITH (package,help-string [,action-if-given [,action-if-not-given]])
如果用戶以選項``--with-package''或者``--without-package''調用 configure,就營運shell命令action-if-given。如果兩個選項都沒有給出,就營運shell命令 action-if-not-given。名字package給出了本程式應該與之協同工作的其它套裝軟件。它應該僅僅由字母、數字和破折號(dashes)組成。
shell命令action-if-given可以透過shell變量withval得到選項的參數,該變量的值實際上就是把 shell變量with_package的值中的所有``-''字符替換為``_''而得的。如果你願意,可以使用變量with_package。
參數help-string是對選項的描述,它看起來應該像︰
--with-readline support fancy command line editing
如果需要給出更多的細節,help-string可能多於一行。只要確保``configure --help''中的列的排列就可以了。不要在求助字元串中使用tab。你將需要用``[''和``]''包圍它以生成前導空格。
宏︰ AC_WITH (package,action-if-given [,action-if-not-given])
這是不支援求助字元串的AC_ARG_WITH的過時版本。
選擇包選項
如果套裝軟件含有可選的編譯時(compile-time)特徵,用戶就可以在調用configure時使用命令行選項來指明是否編譯它們。選項採用如下形式之一︰
--enable-feature[=arg]
--disable-feature
這些選項允許用戶選擇可選的選項進行創建和安裝。``--enable-feature''選項永遠不要使特徵的行為變得不同或者導致一個特徵代替另一個特徵。它們只應該導致程式的一部分被創建而另一部分不創建。
用戶可以透過在特徵名之後添加``=''和參數來給出參數。給出參數``no''表示 不能使用該特徵。一個帶有參數的特徵看起來就像``--enable-debug=stabs''。如果沒有給出參數,它的缺省值就是``yes''。``--disable-feature''等價於 ``--enable-feature=no''。
configure腳本並不對它們所不支援的``--enable-feature''選項發出警告。本特徵允許頂層目錄中的configure腳本配置一個包含多個包的源代碼樹。在包支援不同的選項的時候,不會因為給出了只有一部分包支援的選項而導致不必要的錯誤消息。一個不幸的副作用是選項的拼寫錯誤就不能被檢查出來了。迄今為止還沒有處理該問題的更好辦法。
對於每個可選的特徵,``configure.in''都應該調用AC_ARG_ENABLE以檢測configure 的用戶是否要求把該特徵包含進來。確定在缺省情況下,每個特徵是否被包含進來,以及那些選項是合法的,是你的任務。
宏︰ AC_ARG_ENABLE (feature,help-string [,action-if-given [,action-if-not-given]])
如果用戶以選項``--enable-feature''或者``--disable-feature''調用 configure,就營運shell命令action-if-given。如果兩個選項都沒有給出,就營運shell命令 action-if-not-given。名稱feature表示可選的用戶級功能。它應該僅僅由字母、數字和破折號(dashes)組成。
shell命令可以透過訪問shell變量enableval來得到選項的參數,該變量的值實際上就是把shell變量 enable_feature的值中所有的``-''字符替換成``_''而得到的。如果你願意,可以使用變量enable_feature。help-string參數類似於 AC_ARG_WITH中相應的參數(參見與外部軟體一起工作)。
宏︰ AC_ENABLE (feature,action-if-given [,action-if-not-given])
這是不支援求助字元串的AC_ARG_ENABLE的過時版本。
配置站點細節
有些套裝軟件需要複雜的與站點相關(site-specific)的訊息。例如用於某種服務、公司名稱和email聯繫位址的主名(host names)。因為有些配置腳本是透過Metaconfig模式交互地詢問這些訊息生成的,人們有時對於按非交互模式,由Autoconf生成配置腳本如何獲取這些訊息感到困惑。
這些站點配置訊息應該被儲存在一個僅僅由用戶,而不是程式,編輯的檔案中。檔案的位置既可以基於 prefix變量,也可以是一個標準的位置,比如說用戶的home目錄。它甚至可能透過一個環境變量給出。程式應該在營運時,而不是在編譯時,檢查那個檔案。營運時配置對於用戶來說更為方便,並且使得配置過程比在配置時獲取這些訊息要簡單。關於存放數據檔案的地點的詳細訊息,參見GNU編碼標準中的 ``為安裝目錄而提供的變量''。
在安裝的時候改變程式的名稱
Autoconf支援在安裝程式的時候修改程式的名稱。為了使用這些變換,``configure.in''必須調用宏 AC_ARG_PROGRAM。
宏︰ AC_ARG_PROGRAM
把對被安裝的程式的名稱進行替換的sed命令序列存入輸出變量program_transform_name中。
如果把下列任意選項傳遞給了configure,程式名就據此進行變換。否則,如果已經調用了AC_CANONICAL_SYSTEM並且``--target''的值給出了與主機類型(用``--host''給出的,或者是在config.sub中設定的缺省值)不同的類型,就把末尾附加了破折號的目標類型作為前綴。否則,就不進行程式名變換。
轉換選項
你可以把下列命令行選項傳遞給configure以指定名稱的轉換︰
--program-prefix=prefix
為名稱添加前綴prefix;
--program-suffix=suffix
為名稱添加後綴suffix;
--program-transform-name=expression
對名字作sed替換expression。
轉換的例子
這些變換對於作為交叉編譯開發環境的一部分的程式是有用的。例如,用``--target=i960-vxworks''選項配置的營運在Sun 4上的交叉彙編器通常以``i960-vxworks-as''為名稱進行安裝,而不是以``as''為名安裝,該名稱將於原來的Sun 4彙編器混淆。
如果你不希望安裝在你的系統上的GNU程式遮蔽具有相同名稱的其它程式,你可以強行要求程式名以``g''開頭。例如,如果你使用``--program-prefix=g''來配置GNU diff,那麼在你營運``make install'' 的時候,它就安裝到``/usr/local/bin/gdiff''。
作為更複雜的例子,你可以使用
--program-transform-name=''s/^/g/; s/^gg/g/; s/^gless/less/''
在源代碼樹中的大部分程式的名字之前附加``g'',已經含有一個``g''的程式,諸如gdb,和不是GNU程式的程式,比如說less和lesskey,除外。(它假定你有一個包含了設定成使用這些特徵的程式的源代碼樹。)
同時安裝某些程式的多個版本的一種方法是為其中一個程式的名稱或為所有程式的名稱附加版本號。例如,如果你還希望把 Autoconf版本1保留一段時間,你可以使用``--program-suffix=2''來配置Autoconf第2版,並且以名稱 ``/usr/local/bin/autoconf2''、``/usr/local/bin/autoheader2''等等來安裝程式。
轉換的規則
下面是如何在``Makefile.in''中使用變量program_transform_name︰
transform=@program_transform_name@
install: all
$(INSTALL_PROGRAM) myprog $(bindir)/``echo myprogsed ''$(transform)''``
uninstall:
rm -f $(bindir)/``echo myprogsed ''$(transform)''``
如果你要安裝多個程式,你可以透過一個循環來完成︰
PROGRAMS=cp ls rm
install:
for p in $(PROGRAMS); do
$(INSTALL_PROGRAM) $$p $(bindir)/``echo $$psed ''$(transform)''``;
done
uninstall:
for p in $(PROGRAMS); do
rm -f $(bindir)/``echo $$psed ''$(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手冊(四)
[本文轉載來源為:http://doc.sheup.com/linux/linux403.htm]
編寫測試
如果現有的特徵測試不能完成你所需要的工作,你就必須編寫一個新的。這些宏是創建模塊。它們為其它宏提供了檢查各種特徵是否存在並且報告結果的模式。
本章包括一些建議和一些關於現有的測試的為什麼要那樣編寫的原因。透過閱讀現有的測試,你還可以學到許多關於編寫 Autoconf測試的方法。如果在一個或多個Autoconf測試中出現了錯誤,這些訊息可以幫助你理解它們意味著什麼,這有助於你找到最佳的解決問題的辦法。
這些宏檢查C編譯器系統的輸出。它們並不為未來的使用而緩存測試的結果(參見緩存結果),這是因為它們沒有足夠的訊息以生成緩存變量名。基於同樣的原因,它們還不會輸出任何消息。對特殊的C的特徵進行的測試調用這些宏並且緩存它們的結果、列印關於它們所進行的測試的消息。
當你編寫了一個可以適用於多於一個套裝軟件的特徵測試時,最好的模式就是用一個新宏封裝它。關於如何封裝,參見 編寫宏。
檢驗聲明
宏AC_TRY_CPP用於檢測某個特定的頭檔案是否存在。你可以一次檢查一個頭檔案,或者如果你為了某些目的而希望多個頭檔案都存在,也可以一次檢查多個頭檔案。
宏︰ AC_TRY_CPP (includes, [action-if-true [, action-if-false]])
includes是C或C++的#include語句和聲明,對於它,將進行shell變量、反引用(backquote)、以及反斜線(backslash)替換。(實際上,它可以是任何C程式,但其它的語句可能沒有用。)如果預處理器在處理它的時候沒有報告錯誤,就營運shell命令action-if-true。否則營運shell命令action-if-false。
本宏使用CPPFLAGS,而不使用CFLAGS,這是因為``-g''、``-O''等選項對於許多C預處理器來說都是不合法的選項。
下面是如何確認在某個頭檔案中是否包含一個特定的聲明,比如說typedef、架構、架構成員或者一個函數。使用 AC_EGREP_HEADER而不是對頭檔案直接營運grep;在某些系統中,符號可能是在另一個你所檢查的 ``#include''檔案。
宏︰ AC_EGREP_HEADER (pattern, header-file, action-if-found [, action-if-not-found])
如果對系統頭檔案header-file營運預處理器所產生的輸出與egrep常規表達式pattern相匹配,就執行shell命令action-if-found,否則執行action-if-not-found。
為了檢查由頭檔案或者C預處理器預定義的C預處理器符號,使用AC_EGREP_CPP。下面是後者的一個例子︰
AC_EGREP_CPP(yes,
[#ifdef _AIX
yes
#endif
], is_aix=yes, is_aix=no)
宏︰ AC_EGREP_CPP (pattern, program, [action-if-found [, action-if-not-found]])
program是C或者C++的程式文本,對於它,將進行shell變量、反引號(backquote)以及反斜線(backslash)替換。如果對program營運預處理器產生的輸出與egrep常規表達式(regular expression)pattern 相匹配,就執行shell命令action-if-found,否則執行action-if-not-found。
如果宏還沒有調用AC_PROG_CPP或者AC_PROG_CXXCPP(根據當前語言來確定使用那個宏,參見對語言的選擇),本宏將調用它。
檢驗語法
為了檢查C、C++或者Fortran 77編譯器的語法特徵,比如說它是否能夠識別某個關鍵字,就使用AC_TRY_COMPILE 來嘗試編譯一個小的使用該特徵的程式。你還可以用它檢查不是所有系統都支援的架構和架構成員。
宏︰ AC_TRY_COMPILE (includes, function-body, [action-if-found [, action-if-not-found]])
創建一個C、C++或者Fortran 77測試程式(倚賴於當前語言,參見對語言的選擇),來察看由function-body組成的函數是否可以被編譯。
對於C和C++,includes是所有function-body中的代碼需要的#include語句(如果當前選擇的語言是Fortran 77,includes將被忽略)。如果當前選擇的語言是C或者C++,本宏還將在編譯的時侯使用CFLAGS或者CXXFLAGS,以及CPPFLAGS。如果當前選擇的語言是Fortran 77,那麼就在編譯的時候使用FFLAGS。
如果檔案被成功地編譯了,就營運shell命令action-if-found,否則營運action-if-not-found。
本宏並不試圖進行連接;如果你希望進行連接,使用AC_TRY_LINK (參見檢驗庫)。
檢驗庫
為了檢查一個庫、函數或者全局變量,Autoconf configure腳本試圖編譯並連接一個使用它的小程式。不像Metaconfig,它在缺省情況下對C庫使用nm或者ar以試圖確認可以使用那個函數。由於與函數相連接避免了處理nm和ar的各個變種的選項及輸出格式,而且不必處理標準庫的位置,所以與函數連接通常是更加可靠的辦法。如果需要,它還允許進行交叉配置或者檢查函數的營運是特徵。另一方面,它比一次性掃描庫要慢一些。
少數系統的連接器在出現找不到的函數錯誤(unresolved functions)時不返回失敗的退出狀態。這個錯誤使得由Autoconf 生成的配置腳本不能在這樣的系統中使用。然而,有些這樣的連接器允許給出選項以便正確地返回錯誤狀態。 Autoconf目前還不能自動地處理這個問題。如果用戶遇到了這樣的問題,他們可能可以透過在環境中設定LDFLAGS 以把連接器所需要的選項(例如,``-Wl,-dn'' on MIPS RISC/OS)傳遞給連接器,從而解決這個問題。
AC_TRY_LINK用於編譯測試程式,以測試函數和全局變量。AC_CHECK_LIB還用本宏把被測試的庫暫時地加入LIBS並試圖連接一個小程式,從而對庫進行檢查(參見庫檔案)。
宏︰ AC_TRY_LINK (includes, function-body, [action-if-found [, action-if-not-found]])
根據當前語言(參見對語言的選擇),創建一個測試程式以察看一個函數體為function-body的函數是否可以被編譯和連接。
對C和C++來說,includes給出了所有function-body中的代碼需要的#include語句(如果當前選定的語言是Fortran 77,includes將被忽略)。如果當前語言是C或者C++,本宏在編譯時還將使用 CFLAGS或者CXXFLAGS,以及CPPFLAGS。如果當前選定的語言是Fortran 77,那麼在編譯時將使用FFLAGS。然而,在任何情況下,連接都將使用LDFLAGS和LIBS。
如果檔案被成功地編譯和連接了,就營運shell命令action-if-found,否則就營運action-if-not-found。
宏︰ AC_TRY_LINK_FUNC (function, [action-if-found [, action-if-not-found]])
根據當前語言(參見對語言的選擇),創建一個測試程式以察看一個含有function 原型和對它的調用的程式是否可以被編譯和連接。
如果檔案被成功地編譯和連接了,就營運shell命令action-if-found,否則就營運action-if-not-found。
宏︰ AC_TRY_LINK_FUNC (function, [action-if-found [, action-if-not-found]])
試圖編譯並且連接一個與function相連接的小程式。如果檔案被成功地編譯和連接了,就營運shell命令 action-if-found,否則就營運action-if-not-found。
宏︰ AC_COMPILE_CHECK (echo-text, includes, function-body, action-if-found [, action-if-not-found])
本宏是AC_TRY_LINK的一個過時的版本。此外,如果echo-text不為空,它首先還要把 ``checking for echo-text''列印到標準輸出。用AC_MSG_CHECKING 和AC_MSG_RESULT來代替本宏的列印消息的功能(參見列印消息)。
檢驗營運時的特徵
有時候,你需要知道系統在營運時作了些什麼,比如說某個給定的函數是否具備某種能力或者是否含有錯誤。如果你能,你可以在你的程式初始化時自行檢查這類事件(比如說machine''s endianness)。
如果你實在需要在配置時刻檢查營運時的特徵,你可以編寫一個測試程式以確定結果,並且透過AC_TRY_RUN 來編譯和營運它。如果可能就避免營運測試程式,這是因為使用它們使得人們不能對你的包進行交叉編譯。
營運測試程式
如果你希望在配置的時候測試系統營運時的特徵,就使用如下的宏。
宏︰ AC_TRY_RUN (program, [action-if-true [, action-if-false [, action-if-cross-compiling]]])
program是C程式的文本,將對該文本進行shell變量和反引用(backquote)替換。如果它被成功地編譯和連接了並且在執行的時候返回的退出狀態為0,就營運shell命令action-if-true。否則就營運shell命令action-if-false;程式的退出狀態可以透過shell變量``$?''得到。本宏在編譯時使用CFLAGS或者CXXFLAGS以及 CPPFLAGS、LDFLAGS和LIBS。
如果使用的C編譯器生成的不是在configure營運的系統上營運的可執行檔案,那麼測試程式就不營運。如果給出了可選的shell命令action-if-cross-compiling,它們就代替生成的可執行檔案執行。否則, configure列印一條錯誤消息並且退出。
當交叉編譯使營運時測試變得不可能的時候,就嘗試提供一個應急(pessimistic)的缺省值以供使用。你透過把可選的最後一個參數傳遞給AC_TRY_RUN來完成這個工作。在每次生成configure的過程中,每次遇到沒有提供 action-if-cross-compiling參數的AC_TRY_RUN調用時,autoconf都列印一條警告消息。雖然用戶將不能為交叉編譯你的包而進行配置,你仍可以忽略該警告。與Autoconf一同發行的少數宏產生該警告消息。
為了為交叉編譯進行配置,你還可以根據規範系統名(canonical system name)為這些參數選擇值(參見手工配置)。另一種模式是把測試緩存檔案設定成目標系統的正確值(參見緩存結果)。
為了給嵌入到其它宏(包括少數與Autoconf一同發行的宏)中的,對AC_TRY_RUN的調用提供缺省值,你可以在它們營運之前調用AC_PROG_CC。那麼,如果shell變量cross_compiling被設定成 ``yes'',就使用另一種方法來獲取結果,而不是調用宏。
宏︰ AC_C_CROSS
本宏已經過時;它不作任何事情。
測試程式指南
測試程式不應該向標準輸出輸出任何訊息。如果測試成功,它們應該返回0,否則返回非0,以便於把成功的執行從core dump或者其它失敗中區分出來;段衝突(segmentation violations)和其它失敗產生一個非0的退出狀態。測試程式應該從main中exit,而不是return,這是因為在某些系統中(至少在老式的Sun上),main的return的參數將被忽略。
測試程式可以使用#if或者#ifdef來檢查由已經執行了的測試定義的預處理器宏的值。例如,如果你調用AC_HEADER_STDC,那麼在``configure.in''的隨後部分,你可以使用一個有條件地引入標準C頭檔案的測試程式︰
#if STDC_HEADERS
# include
#endif
如果測試程式需要使用或者創建數據檔案,其檔案名應該以``conftest''開頭,例如``conftestdata''。在營運測試程式之後或者腳本被中斷時,configure將透過營運``rm -rf conftest*''來清除數據檔案。
測試函數
在測試程式中的函數聲明應該條件地含有為C++提供的原型。雖然實際上測試程式很少需要帶參數的函數。
#ifdef __cplusplus
foo(int i)
#else
foo(i) int i;
#endif
測試程式聲明的函數也應該有條件地含有為C++提供的,需要``extern ""C""''的原型。要確保不要引入任何包含衝突原型的頭檔案。
#ifdef __cplusplus
extern ""C"" void *malloc(size_t);
#else
char *malloc();
#endif
如果測試程式以非法的參數調用函數(僅僅看它是否存在),就組織程式以確保它從不調用這個函數。你可以在另一個從不調用的函數中調用它。你不能把它放在對exit的調用之後,這是因為GCC第2版知道 exit永遠不會返回,並且把同一塊中該調用之後的所有代碼都優化掉。
如果你引入了任何頭檔案,確保使用正確數量的參數調用與它們相關的函數,即使它們不帶參數也是如此,以避免原型造成的編譯錯誤。GCC第2版為有些它自動嵌入(inline)的函數設定了內置原型;例如, memcpy。為了在檢查它們時避免錯誤,既可以給它們正確數量的參數,也可以以不同的返回類型(例如char)重新聲明它們。
可移植的Shell編程
在編寫你自己的測試時,為了使你的代碼可以移植,你應該避免使用某些shell腳本編程技術。 Bourne shell和諸如Bash和Korn shell之類的向上兼容的shell已經發展了多年,但為了避免麻煩,不要利用在UNIX版本7,circa 1977之後添加的新特徵。你不應該使用shell函數、別名、負字符集(negated character classes)或者其它不是在所有與Bourne兼容的shell中都能找到的特徵;把你自己限制到最低的風險中去。(the lowest common denominator)。即使是unset都不能夠被所有的shell所支援﹗還有,像下面那樣在指定解釋器的驚嘆號之後給出空格︰
#! /usr/bin/perl
如果你忽略了路徑之前的空格,那麼基於4.2BSD的系統(比如說Sequent DYNIX)將忽略這一行,這是因為它們把 ``#! /''看作一個四位元組的魔數(magic number)。
你在configure腳本中營運的外部程式,應該是一個相當小的集合。關於可用的外部程式清單,參見 GNU編碼標準中的‘Makefile中的工具’一節。這個限制允許用戶在只擁有相當少的程式時進行配置和編譯,這避免了套裝軟件之間過多的倚賴性。
此外,這些外部工具中的某些工具只有一部分特徵是可移植的。例如,不要倚賴ln支援``-f''選項,也不要倚賴cat含有任何選項。sed腳本不應該含有註釋,也不應該使用長於8個字符的分支標記。不要使用``grep -s''來禁止(suppress)輸出。而要把grep的標準輸出和標準錯誤輸出(在檔案不存在的情況下會輸出訊息到標準錯誤輸出)重新定向到``/dev/null''中。檢查grep的退出狀態以確定它是否找到了一個匹配。
測試值和檔案
configure腳本需要測試許多檔案和字元串的屬性。下面是在進行這些測試的時候需要提防的一些移植性問題。
程式test是進行許多檔案和字元串測試的模式。人們使用替代(alternate)名``[''來調用它,但因為``[''是一個m4的引用字符,在Autoconf代碼中使用``[''將帶來麻煩。
如果你需要透過test創建多個檢查,就用shell操作符``&&''和``'' 把它們組合起來,而不是使用test操作符``-a''和``-o''。在System V中, ``-a''和``-o''相對於unary操作符的優先級是錯誤的;為此,POSIX並未給出它們,所以使用它們是不可移植的。如果你在同一個語句中組合使用了``&&''和``'',要記住它們的優先級是相同的。
為了使得configure腳本可以支援交叉編譯,它們不能作任何測試主系統而不是測試目標系統的事。但你偶爾可以發現有必要檢查某些特定(arbitrary)檔案的存在。為此,使用``test -f''或者``test -r''。不要使用``test -x'',因為4.3BSD不支援它。
另一個不可移植的shell編程架構是
var=${var:-value}
它的目的是僅僅在沒有設定var的值的情況下,把var設定成value,但如果var已經含有值,即使是空字元串,也不修改var。老式BSD shell,包括 Ultrix sh,不接受這個冒號,並且給出錯誤並停止。一個可以移植的等價模式是
: ${var=value}
多種情況
有些操作是以幾種可能的模式完成的,它倚賴於UNIX的變種。檢查它們通常需要一個""case 語句""。Autoconf不能直接提供該語句;然而,透過用一個shell變量來記錄是否採用了操作的某種已知的模式,可以容易地類比該語句。
下面是用shell變量fstype記錄是否還有需要檢查的情況的例子。
AC_MSG_CHECKING(how to get filesystem type)
fstype=no
# The order of these tests is important.
AC_TRY_CPP([#include
#include ], AC_DEFINE(FSTYPE_STATVFS) fstype=SVR4)
if test $fstype = no; then
AC_TRY_CPP([#include
#include ], AC_DEFINE(FSTYPE_USG_STATFS) fstype=SVR3)
fi
if test $fstype = no; then
AC_TRY_CPP([#include
#include ], AC_DEFINE(FSTYPE_AIX_STATFS) fstype=AIX)
fi
# (more cases omitted here)
AC_MSG_RESULT($fstype)
對語言的選擇
既使用C又使用C++的包需要同時測試兩個編譯器。Autoconf生成的configure腳本在缺省情況下檢查C的特徵。以下的宏決定在``configure.in''的隨後部分使用那個語言的編譯器。
宏︰ AC_LANG_C
使用CC和CPP進行編譯測試並且把``.c''作為測試程式的擴展名。如果已經營運過AC_PROG_CC,就把把shell變量cross_compiling的值設定成該宏計算的結果,否則就設定為空。
宏︰ AC_LANG_CPLUSPLUS
使用CXX和CXXPP進行編譯測試並且把``.C''作為測試程式的擴展名。如果已經營運過AC_PROG_CXX,就把把shell變量cross_compiling的值設定成該宏計算的結果,否則就設定為空。
宏︰ AC_LANG_FORTRAN77
使用F77進行編譯測試並且把``.f''作為測試程式的擴展名。如果已經營運過AC_PROG_F77,就把把shell變量cross_compiling的值設定成該宏計算的結果,否則就設定為空。
宏︰ AC_LANG_SAVE
在堆棧中記錄當前的語言(由AC_LANG_C、AC_LANG_CPLUSPLUS或者AC_LANG_FORTRAN77 所設定)。不改變當前使用的語言。在需要暫時地切換到其它特殊語言的宏之中使用本宏和AC_LANG_RESTORE。
宏︰ AC_LANG_RESTORE
選擇儲存在棧頂的,由AC_LANG_SAVE設定的語言,並且把它從棧頂刪除。本宏等價於營運在最後被調用的 AC_LANG_SAVE之前最近的AC_LANG_C、AC_LANG_CPLUSPLUS或者 AC_LANG_FORTRAN77。
調用本宏的次數不要多於調用AC_LANG_SAVE的次數。
宏︰ AC_REQUIRE_CPP
確認已經找到了當前用於測試的預處理器。本宏根據當前選擇的語言,以AC_PROG_CPP或者AC_PROG_CXXCPP 為參數調用AC_REQUIRE(參見首要的宏)。
測試的結果
一旦configure確定了某個特徵是否存在,它將如何記錄這一訊息?這裡有四種記錄模式︰定義一個C預處理器符號、在輸出檔案中設定一個變量、為將來營運configure而把結果儲存到一個緩存檔案中,以及列印一條消息以便讓用戶知道測試的結果。
定義C預處理器符號
對一個特徵的檢測的常見回應是定義一個表示測試結果的C預處理器符號。這是透過調用AC_DEFINE 或者AC_DEFINE_UNQUOTED來完成的。
在缺省狀態下,AC_OUTPUT把由這些宏定義的符號放置到輸出變量DEFS中,該變量為每個定義了的符號添加一個選項``-Dsymbol=value''。與Autoconf第1版不同,在營運時不定義DEFS變量。為了檢查Autoconf宏是否已經定義了某個C預處理器符號,就檢查適當的緩存變量的值,例子如下︰
AC_CHECK_FUNC(vprintf, AC_DEFINE(HAVE_VPRINTF))
if test ""$ac_cv_func_vprintf"" != yes; then
AC_CHECK_FUNC(_doprnt, AC_DEFINE(HAVE_DOPRNT))
fi
如果已經調用了AC_CONFIG_HEADER,那麼就不是創建DEFS,而是由AC_OUTPUT 創建一個頭檔案,這是透過在一個暫時檔案中把正確的值替換到#define語句中來實現的。關於這種輸出的詳情,請參見配置頭檔案。
宏︰ AC_DEFINE (variable [, value [, description]])
定義C預處理器變量variable。如果給出了value,就把variable設定成那個值(不加任何改變),否則的話就設定為1。value不應該含有新行,同時如果你沒有使用AC_CONFIG_HEADER,它就不應該含有任何``#''字符,這是因為make將刪除它們。為了使用shell變量(你需要使用該變量定義一個包含了 m4引用字符``[''或者``]''的值),就使用AC_DEFINE_UNQUOTED。只有在你使用AC_CONFIG_HEADER的時候,description才有用。在這種情況下,description被作為註釋放置到生成的``config.h.in''的宏定義之前;不必在``acconfig.h''中提及該宏。下面的例子把 C預處理器變量EQUATION的值定義成常量字元串``""$a > $b""''︰
編寫測試
如果現有的特徵測試不能完成你所需要的工作,你就必須編寫一個新的。這些宏是創建模塊。它們為其它宏提供了檢查各種特徵是否存在並且報告結果的模式。
本章包括一些建議和一些關於現有的測試的為什麼要那樣編寫的原因。透過閱讀現有的測試,你還可以學到許多關於編寫 Autoconf測試的方法。如果在一個或多個Autoconf測試中出現了錯誤,這些訊息可以幫助你理解它們意味著什麼,這有助於你找到最佳的解決問題的辦法。
這些宏檢查C編譯器系統的輸出。它們並不為未來的使用而緩存測試的結果(參見緩存結果),這是因為它們沒有足夠的訊息以生成緩存變量名。基於同樣的原因,它們還不會輸出任何消息。對特殊的C的特徵進行的測試調用這些宏並且緩存它們的結果、列印關於它們所進行的測試的消息。
當你編寫了一個可以適用於多於一個套裝軟件的特徵測試時,最好的模式就是用一個新宏封裝它。關於如何封裝,參見 編寫宏。
檢驗聲明
宏AC_TRY_CPP用於檢測某個特定的頭檔案是否存在。你可以一次檢查一個頭檔案,或者如果你為了某些目的而希望多個頭檔案都存在,也可以一次檢查多個頭檔案。
宏︰ AC_TRY_CPP (includes, [action-if-true [, action-if-false]])
includes是C或C++的#include語句和聲明,對於它,將進行shell變量、反引用(backquote)、以及反斜線(backslash)替換。(實際上,它可以是任何C程式,但其它的語句可能沒有用。)如果預處理器在處理它的時候沒有報告錯誤,就營運shell命令action-if-true。否則營運shell命令action-if-false。
本宏使用CPPFLAGS,而不使用CFLAGS,這是因為``-g''、``-O''等選項對於許多C預處理器來說都是不合法的選項。
下面是如何確認在某個頭檔案中是否包含一個特定的聲明,比如說typedef、架構、架構成員或者一個函數。使用 AC_EGREP_HEADER而不是對頭檔案直接營運grep;在某些系統中,符號可能是在另一個你所檢查的 ``#include''檔案。
宏︰ AC_EGREP_HEADER (pattern, header-file, action-if-found [, action-if-not-found])
如果對系統頭檔案header-file營運預處理器所產生的輸出與egrep常規表達式pattern相匹配,就執行shell命令action-if-found,否則執行action-if-not-found。
為了檢查由頭檔案或者C預處理器預定義的C預處理器符號,使用AC_EGREP_CPP。下面是後者的一個例子︰
AC_EGREP_CPP(yes,
[#ifdef _AIX
yes
#endif
], is_aix=yes, is_aix=no)
宏︰ AC_EGREP_CPP (pattern, program, [action-if-found [, action-if-not-found]])
program是C或者C++的程式文本,對於它,將進行shell變量、反引號(backquote)以及反斜線(backslash)替換。如果對program營運預處理器產生的輸出與egrep常規表達式(regular expression)pattern 相匹配,就執行shell命令action-if-found,否則執行action-if-not-found。
如果宏還沒有調用AC_PROG_CPP或者AC_PROG_CXXCPP(根據當前語言來確定使用那個宏,參見對語言的選擇),本宏將調用它。
檢驗語法
為了檢查C、C++或者Fortran 77編譯器的語法特徵,比如說它是否能夠識別某個關鍵字,就使用AC_TRY_COMPILE 來嘗試編譯一個小的使用該特徵的程式。你還可以用它檢查不是所有系統都支援的架構和架構成員。
宏︰ AC_TRY_COMPILE (includes, function-body, [action-if-found [, action-if-not-found]])
創建一個C、C++或者Fortran 77測試程式(倚賴於當前語言,參見對語言的選擇),來察看由function-body組成的函數是否可以被編譯。
對於C和C++,includes是所有function-body中的代碼需要的#include語句(如果當前選擇的語言是Fortran 77,includes將被忽略)。如果當前選擇的語言是C或者C++,本宏還將在編譯的時侯使用CFLAGS或者CXXFLAGS,以及CPPFLAGS。如果當前選擇的語言是Fortran 77,那麼就在編譯的時候使用FFLAGS。
如果檔案被成功地編譯了,就營運shell命令action-if-found,否則營運action-if-not-found。
本宏並不試圖進行連接;如果你希望進行連接,使用AC_TRY_LINK (參見檢驗庫)。
檢驗庫
為了檢查一個庫、函數或者全局變量,Autoconf configure腳本試圖編譯並連接一個使用它的小程式。不像Metaconfig,它在缺省情況下對C庫使用nm或者ar以試圖確認可以使用那個函數。由於與函數相連接避免了處理nm和ar的各個變種的選項及輸出格式,而且不必處理標準庫的位置,所以與函數連接通常是更加可靠的辦法。如果需要,它還允許進行交叉配置或者檢查函數的營運是特徵。另一方面,它比一次性掃描庫要慢一些。
少數系統的連接器在出現找不到的函數錯誤(unresolved functions)時不返回失敗的退出狀態。這個錯誤使得由Autoconf 生成的配置腳本不能在這樣的系統中使用。然而,有些這樣的連接器允許給出選項以便正確地返回錯誤狀態。 Autoconf目前還不能自動地處理這個問題。如果用戶遇到了這樣的問題,他們可能可以透過在環境中設定LDFLAGS 以把連接器所需要的選項(例如,``-Wl,-dn'' on MIPS RISC/OS)傳遞給連接器,從而解決這個問題。
AC_TRY_LINK用於編譯測試程式,以測試函數和全局變量。AC_CHECK_LIB還用本宏把被測試的庫暫時地加入LIBS並試圖連接一個小程式,從而對庫進行檢查(參見庫檔案)。
宏︰ AC_TRY_LINK (includes, function-body, [action-if-found [, action-if-not-found]])
根據當前語言(參見對語言的選擇),創建一個測試程式以察看一個函數體為function-body的函數是否可以被編譯和連接。
對C和C++來說,includes給出了所有function-body中的代碼需要的#include語句(如果當前選定的語言是Fortran 77,includes將被忽略)。如果當前語言是C或者C++,本宏在編譯時還將使用 CFLAGS或者CXXFLAGS,以及CPPFLAGS。如果當前選定的語言是Fortran 77,那麼在編譯時將使用FFLAGS。然而,在任何情況下,連接都將使用LDFLAGS和LIBS。
如果檔案被成功地編譯和連接了,就營運shell命令action-if-found,否則就營運action-if-not-found。
宏︰ AC_TRY_LINK_FUNC (function, [action-if-found [, action-if-not-found]])
根據當前語言(參見對語言的選擇),創建一個測試程式以察看一個含有function 原型和對它的調用的程式是否可以被編譯和連接。
如果檔案被成功地編譯和連接了,就營運shell命令action-if-found,否則就營運action-if-not-found。
宏︰ AC_TRY_LINK_FUNC (function, [action-if-found [, action-if-not-found]])
試圖編譯並且連接一個與function相連接的小程式。如果檔案被成功地編譯和連接了,就營運shell命令 action-if-found,否則就營運action-if-not-found。
宏︰ AC_COMPILE_CHECK (echo-text, includes, function-body, action-if-found [, action-if-not-found])
本宏是AC_TRY_LINK的一個過時的版本。此外,如果echo-text不為空,它首先還要把 ``checking for echo-text''列印到標準輸出。用AC_MSG_CHECKING 和AC_MSG_RESULT來代替本宏的列印消息的功能(參見列印消息)。
檢驗營運時的特徵
有時候,你需要知道系統在營運時作了些什麼,比如說某個給定的函數是否具備某種能力或者是否含有錯誤。如果你能,你可以在你的程式初始化時自行檢查這類事件(比如說machine''s endianness)。
如果你實在需要在配置時刻檢查營運時的特徵,你可以編寫一個測試程式以確定結果,並且透過AC_TRY_RUN 來編譯和營運它。如果可能就避免營運測試程式,這是因為使用它們使得人們不能對你的包進行交叉編譯。
營運測試程式
如果你希望在配置的時候測試系統營運時的特徵,就使用如下的宏。
宏︰ AC_TRY_RUN (program, [action-if-true [, action-if-false [, action-if-cross-compiling]]])
program是C程式的文本,將對該文本進行shell變量和反引用(backquote)替換。如果它被成功地編譯和連接了並且在執行的時候返回的退出狀態為0,就營運shell命令action-if-true。否則就營運shell命令action-if-false;程式的退出狀態可以透過shell變量``$?''得到。本宏在編譯時使用CFLAGS或者CXXFLAGS以及 CPPFLAGS、LDFLAGS和LIBS。
如果使用的C編譯器生成的不是在configure營運的系統上營運的可執行檔案,那麼測試程式就不營運。如果給出了可選的shell命令action-if-cross-compiling,它們就代替生成的可執行檔案執行。否則, configure列印一條錯誤消息並且退出。
當交叉編譯使營運時測試變得不可能的時候,就嘗試提供一個應急(pessimistic)的缺省值以供使用。你透過把可選的最後一個參數傳遞給AC_TRY_RUN來完成這個工作。在每次生成configure的過程中,每次遇到沒有提供 action-if-cross-compiling參數的AC_TRY_RUN調用時,autoconf都列印一條警告消息。雖然用戶將不能為交叉編譯你的包而進行配置,你仍可以忽略該警告。與Autoconf一同發行的少數宏產生該警告消息。
為了為交叉編譯進行配置,你還可以根據規範系統名(canonical system name)為這些參數選擇值(參見手工配置)。另一種模式是把測試緩存檔案設定成目標系統的正確值(參見緩存結果)。
為了給嵌入到其它宏(包括少數與Autoconf一同發行的宏)中的,對AC_TRY_RUN的調用提供缺省值,你可以在它們營運之前調用AC_PROG_CC。那麼,如果shell變量cross_compiling被設定成 ``yes'',就使用另一種方法來獲取結果,而不是調用宏。
宏︰ AC_C_CROSS
本宏已經過時;它不作任何事情。
測試程式指南
測試程式不應該向標準輸出輸出任何訊息。如果測試成功,它們應該返回0,否則返回非0,以便於把成功的執行從core dump或者其它失敗中區分出來;段衝突(segmentation violations)和其它失敗產生一個非0的退出狀態。測試程式應該從main中exit,而不是return,這是因為在某些系統中(至少在老式的Sun上),main的return的參數將被忽略。
測試程式可以使用#if或者#ifdef來檢查由已經執行了的測試定義的預處理器宏的值。例如,如果你調用AC_HEADER_STDC,那麼在``configure.in''的隨後部分,你可以使用一個有條件地引入標準C頭檔案的測試程式︰
#if STDC_HEADERS
# include
#endif
如果測試程式需要使用或者創建數據檔案,其檔案名應該以``conftest''開頭,例如``conftestdata''。在營運測試程式之後或者腳本被中斷時,configure將透過營運``rm -rf conftest*''來清除數據檔案。
測試函數
在測試程式中的函數聲明應該條件地含有為C++提供的原型。雖然實際上測試程式很少需要帶參數的函數。
#ifdef __cplusplus
foo(int i)
#else
foo(i) int i;
#endif
測試程式聲明的函數也應該有條件地含有為C++提供的,需要``extern ""C""''的原型。要確保不要引入任何包含衝突原型的頭檔案。
#ifdef __cplusplus
extern ""C"" void *malloc(size_t);
#else
char *malloc();
#endif
如果測試程式以非法的參數調用函數(僅僅看它是否存在),就組織程式以確保它從不調用這個函數。你可以在另一個從不調用的函數中調用它。你不能把它放在對exit的調用之後,這是因為GCC第2版知道 exit永遠不會返回,並且把同一塊中該調用之後的所有代碼都優化掉。
如果你引入了任何頭檔案,確保使用正確數量的參數調用與它們相關的函數,即使它們不帶參數也是如此,以避免原型造成的編譯錯誤。GCC第2版為有些它自動嵌入(inline)的函數設定了內置原型;例如, memcpy。為了在檢查它們時避免錯誤,既可以給它們正確數量的參數,也可以以不同的返回類型(例如char)重新聲明它們。
可移植的Shell編程
在編寫你自己的測試時,為了使你的代碼可以移植,你應該避免使用某些shell腳本編程技術。 Bourne shell和諸如Bash和Korn shell之類的向上兼容的shell已經發展了多年,但為了避免麻煩,不要利用在UNIX版本7,circa 1977之後添加的新特徵。你不應該使用shell函數、別名、負字符集(negated character classes)或者其它不是在所有與Bourne兼容的shell中都能找到的特徵;把你自己限制到最低的風險中去。(the lowest common denominator)。即使是unset都不能夠被所有的shell所支援﹗還有,像下面那樣在指定解釋器的驚嘆號之後給出空格︰
#! /usr/bin/perl
如果你忽略了路徑之前的空格,那麼基於4.2BSD的系統(比如說Sequent DYNIX)將忽略這一行,這是因為它們把 ``#! /''看作一個四位元組的魔數(magic number)。
你在configure腳本中營運的外部程式,應該是一個相當小的集合。關於可用的外部程式清單,參見 GNU編碼標準中的‘Makefile中的工具’一節。這個限制允許用戶在只擁有相當少的程式時進行配置和編譯,這避免了套裝軟件之間過多的倚賴性。
此外,這些外部工具中的某些工具只有一部分特徵是可移植的。例如,不要倚賴ln支援``-f''選項,也不要倚賴cat含有任何選項。sed腳本不應該含有註釋,也不應該使用長於8個字符的分支標記。不要使用``grep -s''來禁止(suppress)輸出。而要把grep的標準輸出和標準錯誤輸出(在檔案不存在的情況下會輸出訊息到標準錯誤輸出)重新定向到``/dev/null''中。檢查grep的退出狀態以確定它是否找到了一個匹配。
測試值和檔案
configure腳本需要測試許多檔案和字元串的屬性。下面是在進行這些測試的時候需要提防的一些移植性問題。
程式test是進行許多檔案和字元串測試的模式。人們使用替代(alternate)名``[''來調用它,但因為``[''是一個m4的引用字符,在Autoconf代碼中使用``[''將帶來麻煩。
如果你需要透過test創建多個檢查,就用shell操作符``&&''和``'' 把它們組合起來,而不是使用test操作符``-a''和``-o''。在System V中, ``-a''和``-o''相對於unary操作符的優先級是錯誤的;為此,POSIX並未給出它們,所以使用它們是不可移植的。如果你在同一個語句中組合使用了``&&''和``'',要記住它們的優先級是相同的。
為了使得configure腳本可以支援交叉編譯,它們不能作任何測試主系統而不是測試目標系統的事。但你偶爾可以發現有必要檢查某些特定(arbitrary)檔案的存在。為此,使用``test -f''或者``test -r''。不要使用``test -x'',因為4.3BSD不支援它。
另一個不可移植的shell編程架構是
var=${var:-value}
它的目的是僅僅在沒有設定var的值的情況下,把var設定成value,但如果var已經含有值,即使是空字元串,也不修改var。老式BSD shell,包括 Ultrix sh,不接受這個冒號,並且給出錯誤並停止。一個可以移植的等價模式是
: ${var=value}
多種情況
有些操作是以幾種可能的模式完成的,它倚賴於UNIX的變種。檢查它們通常需要一個""case 語句""。Autoconf不能直接提供該語句;然而,透過用一個shell變量來記錄是否採用了操作的某種已知的模式,可以容易地類比該語句。
下面是用shell變量fstype記錄是否還有需要檢查的情況的例子。
AC_MSG_CHECKING(how to get filesystem type)
fstype=no
# The order of these tests is important.
AC_TRY_CPP([#include
#include ], AC_DEFINE(FSTYPE_STATVFS) fstype=SVR4)
if test $fstype = no; then
AC_TRY_CPP([#include
#include ], AC_DEFINE(FSTYPE_USG_STATFS) fstype=SVR3)
fi
if test $fstype = no; then
AC_TRY_CPP([#include
#include ], AC_DEFINE(FSTYPE_AIX_STATFS) fstype=AIX)
fi
# (more cases omitted here)
AC_MSG_RESULT($fstype)
對語言的選擇
既使用C又使用C++的包需要同時測試兩個編譯器。Autoconf生成的configure腳本在缺省情況下檢查C的特徵。以下的宏決定在``configure.in''的隨後部分使用那個語言的編譯器。
宏︰ AC_LANG_C
使用CC和CPP進行編譯測試並且把``.c''作為測試程式的擴展名。如果已經營運過AC_PROG_CC,就把把shell變量cross_compiling的值設定成該宏計算的結果,否則就設定為空。
宏︰ AC_LANG_CPLUSPLUS
使用CXX和CXXPP進行編譯測試並且把``.C''作為測試程式的擴展名。如果已經營運過AC_PROG_CXX,就把把shell變量cross_compiling的值設定成該宏計算的結果,否則就設定為空。
宏︰ AC_LANG_FORTRAN77
使用F77進行編譯測試並且把``.f''作為測試程式的擴展名。如果已經營運過AC_PROG_F77,就把把shell變量cross_compiling的值設定成該宏計算的結果,否則就設定為空。
宏︰ AC_LANG_SAVE
在堆棧中記錄當前的語言(由AC_LANG_C、AC_LANG_CPLUSPLUS或者AC_LANG_FORTRAN77 所設定)。不改變當前使用的語言。在需要暫時地切換到其它特殊語言的宏之中使用本宏和AC_LANG_RESTORE。
宏︰ AC_LANG_RESTORE
選擇儲存在棧頂的,由AC_LANG_SAVE設定的語言,並且把它從棧頂刪除。本宏等價於營運在最後被調用的 AC_LANG_SAVE之前最近的AC_LANG_C、AC_LANG_CPLUSPLUS或者 AC_LANG_FORTRAN77。
調用本宏的次數不要多於調用AC_LANG_SAVE的次數。
宏︰ AC_REQUIRE_CPP
確認已經找到了當前用於測試的預處理器。本宏根據當前選擇的語言,以AC_PROG_CPP或者AC_PROG_CXXCPP 為參數調用AC_REQUIRE(參見首要的宏)。
測試的結果
一旦configure確定了某個特徵是否存在,它將如何記錄這一訊息?這裡有四種記錄模式︰定義一個C預處理器符號、在輸出檔案中設定一個變量、為將來營運configure而把結果儲存到一個緩存檔案中,以及列印一條消息以便讓用戶知道測試的結果。
定義C預處理器符號
對一個特徵的檢測的常見回應是定義一個表示測試結果的C預處理器符號。這是透過調用AC_DEFINE 或者AC_DEFINE_UNQUOTED來完成的。
在缺省狀態下,AC_OUTPUT把由這些宏定義的符號放置到輸出變量DEFS中,該變量為每個定義了的符號添加一個選項``-Dsymbol=value''。與Autoconf第1版不同,在營運時不定義DEFS變量。為了檢查Autoconf宏是否已經定義了某個C預處理器符號,就檢查適當的緩存變量的值,例子如下︰
AC_CHECK_FUNC(vprintf, AC_DEFINE(HAVE_VPRINTF))
if test ""$ac_cv_func_vprintf"" != yes; then
AC_CHECK_FUNC(_doprnt, AC_DEFINE(HAVE_DOPRNT))
fi
如果已經調用了AC_CONFIG_HEADER,那麼就不是創建DEFS,而是由AC_OUTPUT 創建一個頭檔案,這是透過在一個暫時檔案中把正確的值替換到#define語句中來實現的。關於這種輸出的詳情,請參見配置頭檔案。
宏︰ AC_DEFINE (variable [, value [, description]])
定義C預處理器變量variable。如果給出了value,就把variable設定成那個值(不加任何改變),否則的話就設定為1。value不應該含有新行,同時如果你沒有使用AC_CONFIG_HEADER,它就不應該含有任何``#''字符,這是因為make將刪除它們。為了使用shell變量(你需要使用該變量定義一個包含了 m4引用字符``[''或者``]''的值),就使用AC_DEFINE_UNQUOTED。只有在你使用AC_CONFIG_HEADER的時候,description才有用。在這種情況下,description被作為註釋放置到生成的``config.h.in''的宏定義之前;不必在``acconfig.h''中提及該宏。下面的例子把 C預處理器變量EQUATION的值定義成常量字元串``""$a > $b""''︰
autoconf手冊(三)
[本文轉載來源為:http://doc.sheup.com/linux/linux403.htm]
對普通函數的檢查
這些宏被用於尋找沒有包括在特定函數測試宏中的函數。如果函數可能出現下除了缺省C庫以外的庫中,就要首先為這些庫調用AC_CHECK_LIB。如果你除了需要檢查函數是否存在之外,還要檢查函數的行為,你就不得不為此而編寫你自己的測試(參見編寫測試)。
宏︰ AC_CHECK_FUNC (function, [action-if-found [, action-if-not-found]])
如果可以使用C函數function,就營運shell命令action-if-found,否則營運 action-if-not-found。如果你只希望在函數可用的時候定義一個符號,就考慮使用 AC_CHECK_FUNCS。由於C++比C更加標準化,即使在調用了AC_LANG_CPLUSPLUS 的時候,本宏仍然用C的連接模式對函數進行檢查。(關於為測試選擇語言的詳情,請參見 對語言的選擇)
宏︰ AC_CHECK_FUNCS (function... [, action-if-found [, action-if-not-found]])
對於每個在以空格分隔的函數清單function中出現的函數,如果可用,就定義HAVE_function (全部大寫)。如果給出了action-if-found,它就是在找到一個函數的時候執行的附加的shell代碼。你可以給出 ``break''以便在找到第一個匹配的時候跳出循環。如果給出了action-if-not-found,它就在找不到某個函數的時候執行。
宏︰ AC_REPLACE_FUNCS (function...)
本宏的功能就類似於以將``function.o''添加到輸出變量LIBOBJS的shell 代碼為參數action-if-not-found,調用AC_CHECK_FUNCS。你可以透過用 ``#ifndef HAVE_function''包圍你為函數提供的替代版本的原型來聲明函數。如果系統含有該函數,它可能在一個你應該引入的頭檔案中進行聲明,所以你不應該重新聲明它,以避免聲明衝突。
頭檔案
下列宏檢查某些C頭檔案是否存在。如果沒有為你需要檢查的頭檔案定義特定的宏,而且你不需要檢查它的任何特殊屬性,那麼你就可以使用一個通用的頭檔案檢查宏。
對特定頭檔案的檢查
這些宏檢查特定的系統頭檔案--它們是否存在,以及在某些情況下它們是否定義了特定的符號。
宏︰ AC_DECL_SYS_SIGLIST
如果在系統頭檔案,``signal.h''或者``unistd.h'',中定義了變量sys_siglist,就定義SYS_SIGLIST_DECLARED。
宏︰ AC_DIR_HEADER
類似於調用AC_HEADER_DIRENT和AC_FUNC_CLOSEDIR_VOID,但為了指明找到了哪個頭檔案而定義了不同的一組C預處理器宏。本宏和它定義的名字是過時的。它定義的名字是︰
``dirent.h''
DIRENT
``sys/ndir.h''
SYSNDIR
``sys/dir.h''
SYSDIR
``ndir.h''
NDIR
此外,如果closedir不能返回一個有意義的值,就定義VOID_CLOSEDIR。
宏︰ AC_HEADER_DIRENT
對下列頭檔案進行檢查,並且為第一個找到的頭檔案定義``DIR'',以及列出的C預處理器宏︰
``dirent.h''
HAVE_DIRENT_H
``sys/ndir.h''
HAVE_SYS_NDIR_H
``sys/dir.h''
HAVE_SYS_DIR_H
``ndir.h''
HAVE_NDIR_H
源代碼中的目錄庫聲明應該以類似於下面的模式給出︰
#if HAVE_DIRENT_H
# include
# define NAMLEN(dirent) strlen((dirent)->d_name)
#else
# define dirent direct
# define NAMLEN(dirent) (dirent)->d_namlen
# if HAVE_SYS_NDIR_H
# include
# endif
# if HAVE_SYS_DIR_H
# include
# endif
# if HAVE_NDIR_H
# include
# endif
#endif
使用上述聲明,程式應該把變量定義成類型struct dirent,而不是struct direct,並且應該透過把指向struct direct的指標傳遞給宏NAMLEN來獲得目錄項的名稱的長度。
本宏還為SCO Xenix檢查庫``dir''和``x''。
宏︰ AC_HEADER_MAJOR
如果``sys/types.h''沒有定義major、minor和makedev,但``sys/mkdev.h''定義了它們,就定義MAJOR_IN_MKDEV;否則,如果``sys/sysmacros.h''定義了它們,就定義MAJOR_IN_SYSMACROS。
宏︰ AC_HEADER_STDC
如果含有標準C(ANSI C)頭檔案,就定義STDC_HEADERS。特別地,本宏檢查``stdlib.h''、``stdarg.h''、``string.h''和``float.h'';如果系統含有這些頭檔案,它可能也含有其他的標準C頭檔案。本宏還檢查``string.h''是否定義了memchr (並據此對其他mem函數做出假定),``stdlib.h''是否定義了free(並據此對malloc和其他相關函數做出假定),以及``ctype.h''宏是否按照標準C的要求而可以用於被設定了高位的字符。
因為許多含有GCC的系統並不含有標準C頭檔案,所以用STDC_HEADERS而不是__STDC__ 來決定系統是否含有服從標準(ANSI-compliant)的頭檔案(以及可能的C庫函數)。
在沒有標準C頭檔案的系統上,變種太多,以至於可能沒有簡單的模式對你所使用的函數進行定義以使得它們與系統頭檔案聲明的函數完全相同。某些系統包含了ANSI和BSD函數的混合;某些基本上是標準(ANSI)的,但缺少``memmove'';有些系統在``string.h''或者``strings.h''中以宏的模式定義了BSD函數;有些系統除了含有``string.h''之外,只含有BSD函數;某些系統在``memory.h'' 中定義內存函數,有些在``string.h''中定義;等等。對於一個字元串函數和一個內存函數的檢查可能就夠了;如果庫含有這些函數的標準版,那麼它就可能含有其他大部分函數。如果你在``configure.in'' 中安放了如下代碼︰
AC_HEADER_STDC
AC_CHECK_FUNCS(strchr memcpy)
那麼,在你的代碼中,你就可以像下面那樣放置聲明︰
#if STDC_HEADERS
# include
#else
# ifndef HAVE_STRCHR
# define strchr index
# define strrchr rindex
# endif
char *strchr (), *strrchr ();
# ifndef HAVE_MEMCPY
# define memcpy(d, s, n) bcopy ((s), (d), (n))
# define memmove(d, s, n) bcopy ((s), (d), (n))
# endif
#endif
如果你使用沒有等價的BSD版的函數,諸如memchr、memset、strtok 或者strspn,那麼僅僅使用宏就不夠了;你必須為每個函數提供一個實現。以memchr為例,一種僅僅在需要的時候(因為系統C庫中的函數可能經過了手工優化)與你的實現協作的簡單模式是把實現放入 ``memchr.c''並且使用``AC_REPLACE_FUNCS(memchr)''。
宏︰ AC_HEADER_SYS_WAIT
如果``sys/wait.h''存在並且它和POSIX.1相兼容,就定義HAVE_SYS_WAIT_H。如果``sys/wait.h''不存在,或者如果它使用老式BSD union wait,而不是 int來儲存狀態值,就可能出現不兼容。如果``sys/wait.h''不與POSIX.1兼容,那就不是引入該頭檔案,而是按照它們的常見解釋定義POSIX.1宏。下面是一個例子︰
#include
#if HAVE_SYS_WAIT_H
# include
#endif
#ifndef WEXITSTATUS
# define WEXITSTATUS(stat_val) ((unsigned)(stat_val) >> 8)
#endif
#ifndef WIFEXITED
# define WIFEXITED(stat_val) (((stat_val) & 255) == 0)
#endif
宏︰ AC_MEMORY_H
在``string.h''中,如果沒有定義memcpy, memcmp等函數,並且``memory.h'' 存在,就定義NEED_MEMORY_H。本宏已經過時;可以用AC_CHECK_HEADERS(memory.h)來代替。參見為AC_HEADER_STDC提供的例子。
宏︰ AC_UNISTD_H
如果系統含有``unistd.h'',就定義HAVE_UNISTD_H。本宏已經過時;可以用 ``AC_CHECK_HEADERS(unistd.h)''來代替。
檢查系統是否支援POSIX.1的模式是︰
#if HAVE_UNISTD_H
# include
# include
#endif
#ifdef _POSIX_VERSION
/* 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
# include
#else
# if HAVE_SYS_TIME_H
# include
# else
# include
# endif
#endif
宏︰ AC_STRUCT_ST_BLKSIZE
如果struct stat包含一個st_blksize成員,就定義HAVE_ST_BLKSIZE。
宏︰ AC_STRUCT_ST_BLOCKS
如果struct stat包含一個st_blocks成員,就定義HAVE_ST_BLOCKS。否則,就把``fileblocks.o''添加到輸出變量LIBOBJS中。
宏︰ AC_STRUCT_ST_RDEV
如果struct stat包含一個st_rdev成員,就定義HAVE_ST_RDEV。
宏︰ AC_STRUCT_TM
如果``time.h''沒有定義struct tm,就定義TM_IN_SYS_TIME,它意味著引入``sys/time.h''將得到一個定義得更好的struct tm。
宏︰ AC_STRUCT_TIMEZONE
確定如何獲取當前的時區。如果struct tm有tm_zone成員,就定義HAVE_TM_ZONE。否則,如果找到了外部數組tzname,就定義HAVE_TZNAME。
類型定義
以下的宏檢查C typedefs。如果沒有為你需要檢查的typedef定義特定的宏,並且你不需要檢查該類型的任何特殊的特徵,那麼你可以使用一個普通的typedef檢查宏。
對特定類型定義的檢查
這些宏檢查在``sys/types.h''和``stdlib.h''(如果它存在)中定義的特定的C typedef。
宏︰ AC_TYPE_GETGROUPS
把GETGROUPS_T定義成getgroups的數組參數的基類型gid_t或者int。
宏︰ AC_TYPE_MODE_T
如果沒有定義mode_t,就把mode_t定義成int。
宏︰ AC_TYPE_OFF_T
如果沒有定義off_t,就把off_t定義成long。
宏︰ AC_TYPE_PID_T
如果沒有定義pid_t,就把pid_t定義成int。
宏︰ AC_TYPE_SIGNAL
如果``signal.h''把signal聲明成一個指向返回值為void的函數的指標,就把RETSIGTYPE定義成void;否則,就把它定義成int。
把信號處理器(signal handler)的返回值類型定義為RETSIGTYPE︰
RETSIGTYPE
hup_handler ()
{
...
}
宏︰ AC_TYPE_SIZE_T
如果沒有定義size_t,就把size_t定義成unsigned。
宏︰ AC_TYPE_UID_T
如果沒有定義uid_t,就把uid_t定義成int並且把 gid_t定義成int。
對普通類型定義的檢查
本宏用於檢查沒有包括在特定類型測試宏中的typedef。
宏︰ AC_CHECK_TYPE (type, default)
如果``sys/types.h''或者``stdlib.h''或者``stddef.h''存在,而類型 type沒有在它們之中被定義,就把type定義成C(或者C++)預定義類型 default;例如,``short''或者``unsigned''。
C編譯器的特徵
下列宏檢查C編譯器或者機器架構的特徵。為了檢查沒有在此列出的特徵,使用AC_TRY_COMPILE (參見檢驗語法)或者AC_TRY_RUN (參見檢查營運時的特徵)
宏︰ AC_C_BIGENDIAN
如果字(word)按照最高位在前的模式儲存(比如Motorola和SPARC,但不包括Intel和VAX,CPUS),就定義 WORDS_BIGENDIAN。
宏︰ AC_C_CONST
如果C編譯器不能完全支援關鍵字const,就把const定義成空。有些編譯器並不定義 __STDC__,但支援const;有些編譯器定義__STDC__,但不能完全支援 const。程式可以假定所有C編譯器都支援const,並直接使用它;對於那些不能完全支援const的編譯器,``Makefile''或者配置頭檔案將把const定義為空。
宏︰ AC_C_INLINE
如果C編譯器支援關鍵字inline,就什麼也不作。如果C編譯器可以接受__inline__或者__inline,就把inline定義成可接受的關鍵字,否則就把inline定義為空。
宏︰ AC_C_CHAR_UNSIGNED
除非C編譯器預定義了__CHAR_UNSIGNED__,如果C類型char是無符號的,就定義 __CHAR_UNSIGNED__。
宏︰ AC_C_LONG_DOUBLE
如果C編譯器支援long double類型,就定義HAVE_LONG_DOUBLE。有些C編譯器並不定義__STDC__但支援long double類型;有些編譯器定義 __STDC__但不支援long double。
宏︰ AC_C_STRINGIZE
如果C預處理器支援字元串化操作符(stringizing operator),就定義HAVE_STRINGIZE。字元串化操作符是 ``#''並且它在宏定義中以如下模式出現︰
#define x(y) #y
宏︰ AC_CHECK_SIZEOF (type [, cross-size])
把SIZEOF_uctype定義為C(或C++)預定義類型type的,以位元組為單位的大小,例如``int'' or ``char *''。如果編譯器不能識別``type'',它就被定義為0。 uctype就是把type中所有小寫字母轉化為大寫字母,空格轉化成下劃線,星號轉化成``P'' 而得到的名字。在交叉編譯中,如果給出了cross-size,就使用它,否則configure就生成一個錯誤並且退出。
例如,調用
AC_CHECK_SIZEOF(int *)
在DEC Alpha AXP系統中,把SIZEOF_INT_P定義為8。
宏︰ AC_INT_16_BITS
如果C類型int是16為寬,就定義INT_16_BITS。本宏已經過時;更常見的模式是用 ``AC_CHECK_SIZEOF(int)''來代替。
宏︰ AC_LONG_64_BITS
如果C類型long int是64位寬,就定義LONG_64_BITS。本宏已經過時;更常見的模式是用``AC_CHECK_SIZEOF(long)''來代替。
Fortran 77編譯器的特徵
下列的宏檢查Fortran 77編譯器的特徵。為了檢查沒有在此列出的特徵,使用AC_TRY_COMPILE (參見檢驗語法)或者AC_TRY_RUN (參見檢驗營運時的特徵),但首先必須確認當前語言被設定成 Fortran 77 AC_LANG_FORTRAN77(參見對語言的選擇)。
宏︰ AC_F77_LIBRARY_LDFLAGS
為成功地連接Fotran 77或者共享庫而必須的Fortran 77內置函數(intrinsic)和營運庫確定連接選項(例如,``-L''和``-l'')。輸出變量FLIBS被定義為這些選項。
本宏的目的是用於那些需要把C++和Fortran 77源代碼混合到一個程式或者共享庫中的情況(參見GNU Automake中的``Mixing Fortran 77 With C and C++''節)。
例如,如果來自C++和Fortran 77編譯器的目標檔案必須被連接到一起,那麼必須用C++編譯器/連接器來連接(因為有些C++特定的任務要在連接時完成,這樣的任務有調用全局構造函數、模板的實例化、啟動例外(exception)支援,等等)。
然而,Fortran 77內置函數和營運庫也必須被連接,但C++編譯器/連接器在缺省情況下不知道如何添加這些 Fortran 77庫。因此,就創建AC_F77_LIBRARY_LDFLAGS宏以確認這些Fortran 77庫。
系統服務
下列宏檢查作業系統服務或者作業系統能力。
宏︰ AC_CYGWIN
檢查Cygwin環境。如果存在,就把shell變量CYGWIN設定成``yes''。如果不存在,就把CYGWIN設定成空字元串。
宏︰ AC_EXEEXT
根據編譯器的輸出,定義替換變量EXEEXT,但不包括.c、.o和.obj檔案。對於Unix來說典型的值為空,對Win32來說典型的值為``.exe''或者``.EXE''。
宏︰ AC_OBJEXT
根據編譯器的輸出,定義替換變量OBJEXT,但不包括.c檔案。對於Unix來說典型的值為``.o'',對Win32來說典型的值為``.obj''。
宏︰ AC_MINGW32
檢查MingW32編譯環境。如果存在,就把shell變量MINGW32設定成``yes''。如果不存在,就把MINGW32設定成空。
宏︰ AC_PATH_X
試圖找到X Window系統的頭檔案和庫檔案。如果用戶給出了命令行選項``--x-includes=dir''和 ``--x-libraries=dir'',就使用這些目錄。如果沒有給出任一個選項,或者都沒有給出,就透過營運xmkmf以處理一個測試``Imakefile'',並且檢查它所生成的``Makefile'',來得到沒有給出的目錄。如果這失敗了(比如說,xmkmf不存在),就在它們通常存在的幾個目錄中尋找。如果任何一種方法成功了,就把shell變量x_includes和x_libraries設定成相應的位置,除非這些目錄就在編譯器搜索的缺省目錄中。
如果兩種方法都失敗了,或者用戶給出命令行選項``--without-x'',就把shell變量no_x 設定成``yes'';否則就把它設定成空字元串。
宏︰ AC_PATH_XTRA
AC_PATH_X的增強版。它把X需要的C編譯器選項添加到輸出變量X_CFLAGS,並且把 X的連接選項添加到X_LIBS。如果不能使用X系統,就把``-DX_DISPLAY_MISSING'' 設定成X_CFLAGS。
本宏還檢查在某些系統中為了編譯X程式而需要的特殊庫。它把所有系統需要的庫添加到輸出變量X_EXTRA_LIBS。並且它檢查需要在``-lX11''之前被連接的特殊X11R6庫,並且把找到的所有庫添加到輸出變量X_PRE_LIBS。
宏︰ AC_SYS_INTERPRETER
檢查系統是否支援以形式為``#! /bin/csh''的行開頭的腳本選擇執行該腳本的解釋器。在營運本宏之後,configure.in中的shell代碼就可以檢查shell變量interpval;如果系統支援``#!'',interpval將被設定成``yes'',如果不支援就設定成``no''。
宏︰ AC_SYS_LONG_FILE_NAMES
如果系統支援長於14個字符的檔案名,就定義HAVE_LONG_FILE_NAMES。
宏︰ AC_SYS_RESTARTABLE_SYSCALLS
如果系統自動地重新啟動被信號所中斷的系統調用,就定義HAVE_RESTARTABLE_SYSCALLS。
UNIX變種
下列宏檢查對於有些程式來說需要特殊處理的一些作業系統,這是因為它們的頭檔案或庫檔案中含有特別怪異的東西。這些宏不討人喜歡;它們將根據它們所支援的函數或者它們提供的環境,被更加系統化的方法所代替。
宏︰ AC_AIX
如果在AIX系統中,就定義_ALL_SOURCE。允許使用一些BSD函數。應該在所有營運C編譯器的宏之前調用本宏。
宏︰ AC_DYNIX_SEQ
如果在Dynix/PTX (Sequent UNIX)系統中,就把``-lseq''添加到輸出變量LIBS中。本宏已經過時;用AC_FUNC_GETMNTENT來代替。
宏︰ AC_IRIX_SUN
如果在IRIX(Silicon Graphics UNIX)系統中,就把``-lsun''添加到輸出變量LIBS中。本宏已經過時。如果你用本宏來獲取getmntent,就用AC_FUNC_GETMNTENT來代替。如果你為了密碼(password)和組函數的NIS版本而使用本宏,就用``AC_CHECK_LIB(sun, getpwnam)''來代替。
宏︰ AC_ISC_POSIX
如果在POSIX化(POSIXized) ISC UNIX系統中,就定義_POSIX_SOURCE,並且把``-posix'' (對於GNU C編譯器)或者``-Xp''(對於其他C編譯器)添加到輸出變量CC中。本宏允許使用 POSIX工具。必須在調用AC_PROG_CC之後,在調用其他任何營運C編譯器的宏之前,調用本宏。
宏︰ AC_MINIX
如果在Minix系統中,就定義_MINIX和_POSIX_SOURCE,並且把_POSIX_1_SOURCE 定義成2。本宏允許使用POSIX工具。應該在所有營運C編譯器的宏之前調用本宏。
宏︰ AC_SCO_INTL
如果在SCO UNIX系統中,就把``-lintl''添加到輸出變量LIBS。本宏已經過時;用AC_FUNC_STRFTIME來代替。
宏︰ AC_XENIX_DIR
如果在Xenix系統中,就把``-lx''添加到輸出變量LIBS。還有,如果使用了``dirent.h'',就把``-ldir''添加到LIBS。本宏已經過時;用AC_HEADER_DIRENT來代替。
對普通函數的檢查
這些宏被用於尋找沒有包括在特定函數測試宏中的函數。如果函數可能出現下除了缺省C庫以外的庫中,就要首先為這些庫調用AC_CHECK_LIB。如果你除了需要檢查函數是否存在之外,還要檢查函數的行為,你就不得不為此而編寫你自己的測試(參見編寫測試)。
宏︰ AC_CHECK_FUNC (function, [action-if-found [, action-if-not-found]])
如果可以使用C函數function,就營運shell命令action-if-found,否則營運 action-if-not-found。如果你只希望在函數可用的時候定義一個符號,就考慮使用 AC_CHECK_FUNCS。由於C++比C更加標準化,即使在調用了AC_LANG_CPLUSPLUS 的時候,本宏仍然用C的連接模式對函數進行檢查。(關於為測試選擇語言的詳情,請參見 對語言的選擇)
宏︰ AC_CHECK_FUNCS (function... [, action-if-found [, action-if-not-found]])
對於每個在以空格分隔的函數清單function中出現的函數,如果可用,就定義HAVE_function (全部大寫)。如果給出了action-if-found,它就是在找到一個函數的時候執行的附加的shell代碼。你可以給出 ``break''以便在找到第一個匹配的時候跳出循環。如果給出了action-if-not-found,它就在找不到某個函數的時候執行。
宏︰ AC_REPLACE_FUNCS (function...)
本宏的功能就類似於以將``function.o''添加到輸出變量LIBOBJS的shell 代碼為參數action-if-not-found,調用AC_CHECK_FUNCS。你可以透過用 ``#ifndef HAVE_function''包圍你為函數提供的替代版本的原型來聲明函數。如果系統含有該函數,它可能在一個你應該引入的頭檔案中進行聲明,所以你不應該重新聲明它,以避免聲明衝突。
頭檔案
下列宏檢查某些C頭檔案是否存在。如果沒有為你需要檢查的頭檔案定義特定的宏,而且你不需要檢查它的任何特殊屬性,那麼你就可以使用一個通用的頭檔案檢查宏。
對特定頭檔案的檢查
這些宏檢查特定的系統頭檔案--它們是否存在,以及在某些情況下它們是否定義了特定的符號。
宏︰ AC_DECL_SYS_SIGLIST
如果在系統頭檔案,``signal.h''或者``unistd.h'',中定義了變量sys_siglist,就定義SYS_SIGLIST_DECLARED。
宏︰ AC_DIR_HEADER
類似於調用AC_HEADER_DIRENT和AC_FUNC_CLOSEDIR_VOID,但為了指明找到了哪個頭檔案而定義了不同的一組C預處理器宏。本宏和它定義的名字是過時的。它定義的名字是︰
``dirent.h''
DIRENT
``sys/ndir.h''
SYSNDIR
``sys/dir.h''
SYSDIR
``ndir.h''
NDIR
此外,如果closedir不能返回一個有意義的值,就定義VOID_CLOSEDIR。
宏︰ AC_HEADER_DIRENT
對下列頭檔案進行檢查,並且為第一個找到的頭檔案定義``DIR'',以及列出的C預處理器宏︰
``dirent.h''
HAVE_DIRENT_H
``sys/ndir.h''
HAVE_SYS_NDIR_H
``sys/dir.h''
HAVE_SYS_DIR_H
``ndir.h''
HAVE_NDIR_H
源代碼中的目錄庫聲明應該以類似於下面的模式給出︰
#if HAVE_DIRENT_H
# include
# define NAMLEN(dirent) strlen((dirent)->d_name)
#else
# define dirent direct
# define NAMLEN(dirent) (dirent)->d_namlen
# if HAVE_SYS_NDIR_H
# include
# endif
# if HAVE_SYS_DIR_H
# include
# endif
# if HAVE_NDIR_H
# include
# endif
#endif
使用上述聲明,程式應該把變量定義成類型struct dirent,而不是struct direct,並且應該透過把指向struct direct的指標傳遞給宏NAMLEN來獲得目錄項的名稱的長度。
本宏還為SCO Xenix檢查庫``dir''和``x''。
宏︰ AC_HEADER_MAJOR
如果``sys/types.h''沒有定義major、minor和makedev,但``sys/mkdev.h''定義了它們,就定義MAJOR_IN_MKDEV;否則,如果``sys/sysmacros.h''定義了它們,就定義MAJOR_IN_SYSMACROS。
宏︰ AC_HEADER_STDC
如果含有標準C(ANSI C)頭檔案,就定義STDC_HEADERS。特別地,本宏檢查``stdlib.h''、``stdarg.h''、``string.h''和``float.h'';如果系統含有這些頭檔案,它可能也含有其他的標準C頭檔案。本宏還檢查``string.h''是否定義了memchr (並據此對其他mem函數做出假定),``stdlib.h''是否定義了free(並據此對malloc和其他相關函數做出假定),以及``ctype.h''宏是否按照標準C的要求而可以用於被設定了高位的字符。
因為許多含有GCC的系統並不含有標準C頭檔案,所以用STDC_HEADERS而不是__STDC__ 來決定系統是否含有服從標準(ANSI-compliant)的頭檔案(以及可能的C庫函數)。
在沒有標準C頭檔案的系統上,變種太多,以至於可能沒有簡單的模式對你所使用的函數進行定義以使得它們與系統頭檔案聲明的函數完全相同。某些系統包含了ANSI和BSD函數的混合;某些基本上是標準(ANSI)的,但缺少``memmove'';有些系統在``string.h''或者``strings.h''中以宏的模式定義了BSD函數;有些系統除了含有``string.h''之外,只含有BSD函數;某些系統在``memory.h'' 中定義內存函數,有些在``string.h''中定義;等等。對於一個字元串函數和一個內存函數的檢查可能就夠了;如果庫含有這些函數的標準版,那麼它就可能含有其他大部分函數。如果你在``configure.in'' 中安放了如下代碼︰
AC_HEADER_STDC
AC_CHECK_FUNCS(strchr memcpy)
那麼,在你的代碼中,你就可以像下面那樣放置聲明︰
#if STDC_HEADERS
# include
#else
# ifndef HAVE_STRCHR
# define strchr index
# define strrchr rindex
# endif
char *strchr (), *strrchr ();
# ifndef HAVE_MEMCPY
# define memcpy(d, s, n) bcopy ((s), (d), (n))
# define memmove(d, s, n) bcopy ((s), (d), (n))
# endif
#endif
如果你使用沒有等價的BSD版的函數,諸如memchr、memset、strtok 或者strspn,那麼僅僅使用宏就不夠了;你必須為每個函數提供一個實現。以memchr為例,一種僅僅在需要的時候(因為系統C庫中的函數可能經過了手工優化)與你的實現協作的簡單模式是把實現放入 ``memchr.c''並且使用``AC_REPLACE_FUNCS(memchr)''。
宏︰ AC_HEADER_SYS_WAIT
如果``sys/wait.h''存在並且它和POSIX.1相兼容,就定義HAVE_SYS_WAIT_H。如果``sys/wait.h''不存在,或者如果它使用老式BSD union wait,而不是 int來儲存狀態值,就可能出現不兼容。如果``sys/wait.h''不與POSIX.1兼容,那就不是引入該頭檔案,而是按照它們的常見解釋定義POSIX.1宏。下面是一個例子︰
#include
#if HAVE_SYS_WAIT_H
# include
#endif
#ifndef WEXITSTATUS
# define WEXITSTATUS(stat_val) ((unsigned)(stat_val) >> 8)
#endif
#ifndef WIFEXITED
# define WIFEXITED(stat_val) (((stat_val) & 255) == 0)
#endif
宏︰ AC_MEMORY_H
在``string.h''中,如果沒有定義memcpy, memcmp等函數,並且``memory.h'' 存在,就定義NEED_MEMORY_H。本宏已經過時;可以用AC_CHECK_HEADERS(memory.h)來代替。參見為AC_HEADER_STDC提供的例子。
宏︰ AC_UNISTD_H
如果系統含有``unistd.h'',就定義HAVE_UNISTD_H。本宏已經過時;可以用 ``AC_CHECK_HEADERS(unistd.h)''來代替。
檢查系統是否支援POSIX.1的模式是︰
#if HAVE_UNISTD_H
# include
# include
#endif
#ifdef _POSIX_VERSION
/* 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
# include
#else
# if HAVE_SYS_TIME_H
# include
# else
# include
# endif
#endif
宏︰ AC_STRUCT_ST_BLKSIZE
如果struct stat包含一個st_blksize成員,就定義HAVE_ST_BLKSIZE。
宏︰ AC_STRUCT_ST_BLOCKS
如果struct stat包含一個st_blocks成員,就定義HAVE_ST_BLOCKS。否則,就把``fileblocks.o''添加到輸出變量LIBOBJS中。
宏︰ AC_STRUCT_ST_RDEV
如果struct stat包含一個st_rdev成員,就定義HAVE_ST_RDEV。
宏︰ AC_STRUCT_TM
如果``time.h''沒有定義struct tm,就定義TM_IN_SYS_TIME,它意味著引入``sys/time.h''將得到一個定義得更好的struct tm。
宏︰ AC_STRUCT_TIMEZONE
確定如何獲取當前的時區。如果struct tm有tm_zone成員,就定義HAVE_TM_ZONE。否則,如果找到了外部數組tzname,就定義HAVE_TZNAME。
類型定義
以下的宏檢查C typedefs。如果沒有為你需要檢查的typedef定義特定的宏,並且你不需要檢查該類型的任何特殊的特徵,那麼你可以使用一個普通的typedef檢查宏。
對特定類型定義的檢查
這些宏檢查在``sys/types.h''和``stdlib.h''(如果它存在)中定義的特定的C typedef。
宏︰ AC_TYPE_GETGROUPS
把GETGROUPS_T定義成getgroups的數組參數的基類型gid_t或者int。
宏︰ AC_TYPE_MODE_T
如果沒有定義mode_t,就把mode_t定義成int。
宏︰ AC_TYPE_OFF_T
如果沒有定義off_t,就把off_t定義成long。
宏︰ AC_TYPE_PID_T
如果沒有定義pid_t,就把pid_t定義成int。
宏︰ AC_TYPE_SIGNAL
如果``signal.h''把signal聲明成一個指向返回值為void的函數的指標,就把RETSIGTYPE定義成void;否則,就把它定義成int。
把信號處理器(signal handler)的返回值類型定義為RETSIGTYPE︰
RETSIGTYPE
hup_handler ()
{
...
}
宏︰ AC_TYPE_SIZE_T
如果沒有定義size_t,就把size_t定義成unsigned。
宏︰ AC_TYPE_UID_T
如果沒有定義uid_t,就把uid_t定義成int並且把 gid_t定義成int。
對普通類型定義的檢查
本宏用於檢查沒有包括在特定類型測試宏中的typedef。
宏︰ AC_CHECK_TYPE (type, default)
如果``sys/types.h''或者``stdlib.h''或者``stddef.h''存在,而類型 type沒有在它們之中被定義,就把type定義成C(或者C++)預定義類型 default;例如,``short''或者``unsigned''。
C編譯器的特徵
下列宏檢查C編譯器或者機器架構的特徵。為了檢查沒有在此列出的特徵,使用AC_TRY_COMPILE (參見檢驗語法)或者AC_TRY_RUN (參見檢查營運時的特徵)
宏︰ AC_C_BIGENDIAN
如果字(word)按照最高位在前的模式儲存(比如Motorola和SPARC,但不包括Intel和VAX,CPUS),就定義 WORDS_BIGENDIAN。
宏︰ AC_C_CONST
如果C編譯器不能完全支援關鍵字const,就把const定義成空。有些編譯器並不定義 __STDC__,但支援const;有些編譯器定義__STDC__,但不能完全支援 const。程式可以假定所有C編譯器都支援const,並直接使用它;對於那些不能完全支援const的編譯器,``Makefile''或者配置頭檔案將把const定義為空。
宏︰ AC_C_INLINE
如果C編譯器支援關鍵字inline,就什麼也不作。如果C編譯器可以接受__inline__或者__inline,就把inline定義成可接受的關鍵字,否則就把inline定義為空。
宏︰ AC_C_CHAR_UNSIGNED
除非C編譯器預定義了__CHAR_UNSIGNED__,如果C類型char是無符號的,就定義 __CHAR_UNSIGNED__。
宏︰ AC_C_LONG_DOUBLE
如果C編譯器支援long double類型,就定義HAVE_LONG_DOUBLE。有些C編譯器並不定義__STDC__但支援long double類型;有些編譯器定義 __STDC__但不支援long double。
宏︰ AC_C_STRINGIZE
如果C預處理器支援字元串化操作符(stringizing operator),就定義HAVE_STRINGIZE。字元串化操作符是 ``#''並且它在宏定義中以如下模式出現︰
#define x(y) #y
宏︰ AC_CHECK_SIZEOF (type [, cross-size])
把SIZEOF_uctype定義為C(或C++)預定義類型type的,以位元組為單位的大小,例如``int'' or ``char *''。如果編譯器不能識別``type'',它就被定義為0。 uctype就是把type中所有小寫字母轉化為大寫字母,空格轉化成下劃線,星號轉化成``P'' 而得到的名字。在交叉編譯中,如果給出了cross-size,就使用它,否則configure就生成一個錯誤並且退出。
例如,調用
AC_CHECK_SIZEOF(int *)
在DEC Alpha AXP系統中,把SIZEOF_INT_P定義為8。
宏︰ AC_INT_16_BITS
如果C類型int是16為寬,就定義INT_16_BITS。本宏已經過時;更常見的模式是用 ``AC_CHECK_SIZEOF(int)''來代替。
宏︰ AC_LONG_64_BITS
如果C類型long int是64位寬,就定義LONG_64_BITS。本宏已經過時;更常見的模式是用``AC_CHECK_SIZEOF(long)''來代替。
Fortran 77編譯器的特徵
下列的宏檢查Fortran 77編譯器的特徵。為了檢查沒有在此列出的特徵,使用AC_TRY_COMPILE (參見檢驗語法)或者AC_TRY_RUN (參見檢驗營運時的特徵),但首先必須確認當前語言被設定成 Fortran 77 AC_LANG_FORTRAN77(參見對語言的選擇)。
宏︰ AC_F77_LIBRARY_LDFLAGS
為成功地連接Fotran 77或者共享庫而必須的Fortran 77內置函數(intrinsic)和營運庫確定連接選項(例如,``-L''和``-l'')。輸出變量FLIBS被定義為這些選項。
本宏的目的是用於那些需要把C++和Fortran 77源代碼混合到一個程式或者共享庫中的情況(參見GNU Automake中的``Mixing Fortran 77 With C and C++''節)。
例如,如果來自C++和Fortran 77編譯器的目標檔案必須被連接到一起,那麼必須用C++編譯器/連接器來連接(因為有些C++特定的任務要在連接時完成,這樣的任務有調用全局構造函數、模板的實例化、啟動例外(exception)支援,等等)。
然而,Fortran 77內置函數和營運庫也必須被連接,但C++編譯器/連接器在缺省情況下不知道如何添加這些 Fortran 77庫。因此,就創建AC_F77_LIBRARY_LDFLAGS宏以確認這些Fortran 77庫。
系統服務
下列宏檢查作業系統服務或者作業系統能力。
宏︰ AC_CYGWIN
檢查Cygwin環境。如果存在,就把shell變量CYGWIN設定成``yes''。如果不存在,就把CYGWIN設定成空字元串。
宏︰ AC_EXEEXT
根據編譯器的輸出,定義替換變量EXEEXT,但不包括.c、.o和.obj檔案。對於Unix來說典型的值為空,對Win32來說典型的值為``.exe''或者``.EXE''。
宏︰ AC_OBJEXT
根據編譯器的輸出,定義替換變量OBJEXT,但不包括.c檔案。對於Unix來說典型的值為``.o'',對Win32來說典型的值為``.obj''。
宏︰ AC_MINGW32
檢查MingW32編譯環境。如果存在,就把shell變量MINGW32設定成``yes''。如果不存在,就把MINGW32設定成空。
宏︰ AC_PATH_X
試圖找到X Window系統的頭檔案和庫檔案。如果用戶給出了命令行選項``--x-includes=dir''和 ``--x-libraries=dir'',就使用這些目錄。如果沒有給出任一個選項,或者都沒有給出,就透過營運xmkmf以處理一個測試``Imakefile'',並且檢查它所生成的``Makefile'',來得到沒有給出的目錄。如果這失敗了(比如說,xmkmf不存在),就在它們通常存在的幾個目錄中尋找。如果任何一種方法成功了,就把shell變量x_includes和x_libraries設定成相應的位置,除非這些目錄就在編譯器搜索的缺省目錄中。
如果兩種方法都失敗了,或者用戶給出命令行選項``--without-x'',就把shell變量no_x 設定成``yes'';否則就把它設定成空字元串。
宏︰ AC_PATH_XTRA
AC_PATH_X的增強版。它把X需要的C編譯器選項添加到輸出變量X_CFLAGS,並且把 X的連接選項添加到X_LIBS。如果不能使用X系統,就把``-DX_DISPLAY_MISSING'' 設定成X_CFLAGS。
本宏還檢查在某些系統中為了編譯X程式而需要的特殊庫。它把所有系統需要的庫添加到輸出變量X_EXTRA_LIBS。並且它檢查需要在``-lX11''之前被連接的特殊X11R6庫,並且把找到的所有庫添加到輸出變量X_PRE_LIBS。
宏︰ AC_SYS_INTERPRETER
檢查系統是否支援以形式為``#! /bin/csh''的行開頭的腳本選擇執行該腳本的解釋器。在營運本宏之後,configure.in中的shell代碼就可以檢查shell變量interpval;如果系統支援``#!'',interpval將被設定成``yes'',如果不支援就設定成``no''。
宏︰ AC_SYS_LONG_FILE_NAMES
如果系統支援長於14個字符的檔案名,就定義HAVE_LONG_FILE_NAMES。
宏︰ AC_SYS_RESTARTABLE_SYSCALLS
如果系統自動地重新啟動被信號所中斷的系統調用,就定義HAVE_RESTARTABLE_SYSCALLS。
UNIX變種
下列宏檢查對於有些程式來說需要特殊處理的一些作業系統,這是因為它們的頭檔案或庫檔案中含有特別怪異的東西。這些宏不討人喜歡;它們將根據它們所支援的函數或者它們提供的環境,被更加系統化的方法所代替。
宏︰ AC_AIX
如果在AIX系統中,就定義_ALL_SOURCE。允許使用一些BSD函數。應該在所有營運C編譯器的宏之前調用本宏。
宏︰ AC_DYNIX_SEQ
如果在Dynix/PTX (Sequent UNIX)系統中,就把``-lseq''添加到輸出變量LIBS中。本宏已經過時;用AC_FUNC_GETMNTENT來代替。
宏︰ AC_IRIX_SUN
如果在IRIX(Silicon Graphics UNIX)系統中,就把``-lsun''添加到輸出變量LIBS中。本宏已經過時。如果你用本宏來獲取getmntent,就用AC_FUNC_GETMNTENT來代替。如果你為了密碼(password)和組函數的NIS版本而使用本宏,就用``AC_CHECK_LIB(sun, getpwnam)''來代替。
宏︰ AC_ISC_POSIX
如果在POSIX化(POSIXized) ISC UNIX系統中,就定義_POSIX_SOURCE,並且把``-posix'' (對於GNU C編譯器)或者``-Xp''(對於其他C編譯器)添加到輸出變量CC中。本宏允許使用 POSIX工具。必須在調用AC_PROG_CC之後,在調用其他任何營運C編譯器的宏之前,調用本宏。
宏︰ AC_MINIX
如果在Minix系統中,就定義_MINIX和_POSIX_SOURCE,並且把_POSIX_1_SOURCE 定義成2。本宏允許使用POSIX工具。應該在所有營運C編譯器的宏之前調用本宏。
宏︰ AC_SCO_INTL
如果在SCO UNIX系統中,就把``-lintl''添加到輸出變量LIBS。本宏已經過時;用AC_FUNC_STRFTIME來代替。
宏︰ AC_XENIX_DIR
如果在Xenix系統中,就把``-lx''添加到輸出變量LIBS。還有,如果使用了``dirent.h'',就把``-ldir''添加到LIBS。本宏已經過時;用AC_HEADER_DIRENT來代替。
autoconf手冊(二)
[本文轉載來源為: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中,該函數並不這樣做。
現有的測試
這些宏測試了包可能需要或者需要使用的特定的系統特徵。如果你要測試這些宏所不能測試的特徵,可能你可以用適當的參數調用主測試宏來達到目的(參見編寫測試)。
這些宏列印消息以告訴用戶它們正在測試的特徵,以及它們的測試結果。它們為未來營運的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中,該函數並不這樣做。
autoconf手冊(一)
[本文轉載來源為:http://doc.sheup.com/linux/linux403.htm]
autoconf手冊(一)
Autoconf
Creating Automatic Configuration Scripts
Edition 2.13, for Autoconf version 2.13
December 1998
by David MacKenzie and Ben Elliston
--------------------------------------------------------------------------------
Permission is granted to make and distribute verbatim copies of this manual provided the copyright notice and this permission notice are preserved on all copies.
Permission is granted to copy and distribute modified versions of this manual under the conditions for verbatim copying, provided that the entire resulting derived work is distributed under the terms of a permission notice identical to this one.
Permission is granted to copy and distribute translations of this manual into another language, under the above conditions for modified versions, except that this permission notice may be stated in a translation approved by the Free Software Foundation.
只要版權聲明和本許可聲明保留在所有副本中,您就被授權製作和發行本手冊的原文副本。
只要整個最終派生工作按照與本手冊相同的許可聲明發行,您就被授權按照與發行原文相同的條件複製和發行本手冊的修改版本。
除了本許可聲明應該使用由基金會批准的譯文之外,您被授權按照與上述修改版本相同的條件複製和發行本手冊的其它語言的譯文。
--------------------------------------------------------------------------------
本文檔由王立翻譯。 1999.12.16
譯者在此聲明︰不對任何由譯文錯誤或者對譯文的誤解承擔任何責任。
--------------------------------------------------------------------------------
介紹
A physicist, an engineer, and a computer scientist were
discussing the nature of God. Surely a Physicist, said the
physicist, because early in the Creation, God made Light; and you
know, Maxwell''s equations, the dual nature of electro-magnetic
waves, the relativist consequences... An Engineer!, said the
engineer, because before making Light, God split the Chaos into
Land and Water; it takes a hell of an engineer to handle that big
amount of mud, and orderly separation of solids from
liquids... The computer scientist shouted: And the Chaos,
where do you think it was coming from, hmm?
---Anonymous
Autoconf是一個用於生成可以自動地配置軟體源代碼包以適應多種Unix類系統的 shell腳本的工具。由Autoconf生成的配置腳本在營運的時候與Autoconf是無關的,就是說配置腳本的用戶並不需要擁有Autoconf。
由Autoconf生成的配置腳本在營運的時候不需要用戶的手工干預;通常它們甚至不需要透過給出參數以確定系統的類型。相反,它們對套裝軟件可能需要的各種特徵進行獨立的測試。(在每個測試之前,它們列印一個單行的消息以說明它們正在進行的檢測,以使得用戶不會因為等待腳本執行完畢而焦躁。)因此,它們在混合系統或者從各種常見Unix變種定製而成的系統中工作的很好。沒有必要維護檔案以儲存由各個Unix變種、各個發行版本所支援的特徵的清單。
對於每個使用了Autoconf的套裝軟件,Autoconf從一個列舉了該套裝軟件需要的,或者可以使用的系統特徵的清單的模板檔案中生成配置腳本。在shell代碼識別並附應了一個被列出的系統特徵之後,Autoconf允許多個可能使用(或者需要)該特徵的套裝軟件共享該特徵。如果後來因為某些原因需要調整shell代碼,就只要在一個地方進行修改;所有的配置腳本都將被自動地重新生成以使用更新了的代碼。
Metaconfig包在目的上與Autoconf很相似,但它生成的腳本需要用戶的手工干預,在配置一個大的源代碼樹的時候這是十分不方便的。不象Metaconfig腳本,如果在編寫腳本時小心謹慎, Autoconf可以支援交叉編譯(cross-compiling)。
Autoconf目前還不能完成幾項使套裝軟件可移植的工作。其中包括為所有標準的目標自動創建``Makefile''檔案,包括在缺少標準庫函數和頭檔案的系統上提供替代品。目前正在為在將來添加這些特徵而工作。
對於在C程式中的#ifdef中使用的宏的名字,Autoconf施加了一些限制(參見預處理器符號索引)。
Autoconf需要GNU m4以便於生成腳本。它使用了某些UNIX版本的m4 所不支援的特徵。它還會超出包括GNU m4 1.0在內的某些m4版本的內部限制。你必須使用GNU m4的1.1版或者更新的版本。使用1.3版或者更新的版本將比1.1 或1.2版快許多。
關於從版本1中升級的詳情,參見從版本1中升級。關於Autoconf的開發歷史,參見Autoconf的歷史。對與Autoconf有關的常見問題的回答,參見關於Autoconf的問題。
把守關口於Autoconf的建議和bug報告發送到bug-gnu-utils@prep.ai.mit.edu。請把你透過營運``autoconf --version''而獲得的Autoconf的版本號包括在內。
創建configure腳本
由Autoconf生成的配置腳本通常被稱為configure。在營運的時候,configure 創建一些檔案,在這些檔案中以適當的值替換配置參數。由configure創建的檔案有︰
一個或者多個``Makefile''檔案,在包的每個次目錄中都有一個(參見 Makefile中的替換);
有時創建一個C頭檔案,它的名字可以被配置,該頭檔案包含一些#define命令(參見配置頭檔案);
一個名為``config.status''的shell腳本,在營運時,它將重新創建上述檔案。(參見重新創建一個配置);
一個名為``config.cache''的shell腳本,它儲存了許多測試的營運結果(參見緩存檔案);
一個名為``config.log''的檔案,它包含了由編譯器生成的許多消息,以便於在configure出現錯誤時進行調試。
為了使用Autoconf創建一個configure腳本,你需要編寫一個Autoconf的輸入檔案 ``configure.in''並且對它營運autoconf。如果你自行編寫了特徵測試以補充 Autoconf所提供的測試,你可能還要編寫一個名為``aclocal.m4''的檔案和一個名為 ``acsite.m4''的檔案。如果你使用了包含#define指令的C頭檔案,你可能還要編寫``acconfig.h'',並且你需要與套裝軟件一同發布由Autoconf生成的檔案 ``config.h.in''。
下面是一個說明了在配置中使用的檔案是如何生成的圖。營運的程式都標以後綴``*''。可能出現的檔案被方括號(``[]'')括起來。autoconf和autoheader 還讀取安裝了的Autoconf宏檔案(透過讀取``autoconf.m4'')。
在準備發布套裝軟件的過程中使用的檔案︰
你的源檔案 --> [autoscan*] --> [configure.scan] --> configure.in
configure.in --. .------> autoconf* -----> configure
+---+
[aclocal.m4] --+ ``---.
[acsite.m4] ---''
+--> [autoheader*] -> [config.h.in]
[acconfig.h] ----.
+-----''
[config.h.top] --+
[config.h.bot] --''
Makefile.in -------------------------------> Makefile.in
在配置套裝軟件的過程中使用的檔案︰
.-------------> config.cache
configure* ------------+-------------> config.log
[config.h.in] -. v .-> [config.h] -.
+--> config.status* -+ +--> make*
Makefile.in ---'' ``-> Makefile ---''
編寫``configure.in''
為了為套裝軟件創建configure腳本,需要編寫一個名為``configure.in'' 的檔案,該檔案包含了對那些你的套裝軟件需要或者可以使用的系統特徵進行測試的Autoconf宏的調用。現有的Autoconf宏可以檢測許多特徵; 對於它們的描述可以參見現有的測試。對於大部分其他特徵,你可以使用Autconf模板宏以創建定製的測試;關於它們的詳情,參見 編寫測試。對於特別古怪或者特殊的特徵,``configure.in'' 可能需要包含一些手工編寫的shell命令。程式autoscan可以為你編寫``configure.in'' 開個好頭(詳情請參見用autoscan創建``configure.in'')。
除了少數特殊情況之外,在``configure.in''中調用Autoconf宏的順序並不重要。在每個``configure.in''中,必須在進行任何測試之間包含一個對AC_INIT的調用,並且在結尾處包含一個對AC_OUTPUT的調用(參見創建輸出檔案)。此外,有些宏要求其他的宏在它們之前被調用,這是因為它們透過檢查某些變量在前面設定的值以決定作些什麼。這些宏在獨立的說明中給出(參見現有的測試),而且如果沒有按照順序調用宏,在生成configure時會向你發出警告。
為了提升一致性,下面是調用Autoconf宏的推薦順序。通常,在本清單中靠後的項目倚賴於表中靠前的項目。例如,庫函數可能受到typedefs和庫的影響。
AC_INIT(file)
checks for programs
checks for libraries
checks for header files
checks for typedefs
checks for structures
checks for compiler characteristics
checks for library functions
checks for system services
AC_OUTPUT([file...])
最好讓每個宏調用在``configure.in''中佔據單獨的一行。大部分宏並不添加額外的新行;它們倚賴於在宏調用之後的新行以結束命令。這種方法使得生成的configure腳本在不必添加大量的空行的情況下比較容易閱讀。在宏調用的同一行中設定shell變量通常是安全的,這是因為shell允許出現沒有用新行間隔的賦值。
在調用帶參數的宏的時候,在宏名和左括號之間不能出現任何空格。如果參數被m4 引用字符``[''和``]''所包含,參數就可以多於一行。如果你有一個長行,比如說一個檔案名清單,你通常可以在行的結尾使用反斜線以便在邏輯上把它與下一行進行連接(這是由shell實現的,Autoconf對此沒有進行任何特殊的處理)。
有些宏處理兩種情況︰如果滿足了某個給定的條件就做什麼,如果沒有滿足某個給定的條件就做什麼。在有些地方,你可能希望在條件為真的情況下作些事,在為假時什麼也不作。反之亦然。為了忽略為真的情況,把空值作為參數action-if-found傳遞給宏。為了忽略為假的情況,可以忽略包括前面的逗號在內的宏的參數action-if-not-found。
你可以在檔案``configure.in''中添加註釋。註釋以m4預定義宏dnl 開頭,該宏丟棄在下一個新行之前的所有文本。這些註釋並不在生成的configure腳本中出現。例如,把下面給出的行作為檔案``configure.in''的開頭是有好處的︰
dnl Process this file with autoconf to produce a configure script.
用autoscan創建``configure.in''
程式autoscan可以幫助你為套裝軟件創建``configure.in''檔案。如果在命令行中給出了目錄, autoscan就在給定目錄及其次目錄樹中檢查源檔案,如果沒有給出目錄,就在當前目錄及其次目錄樹中進行檢查。它搜索源檔案以尋找一般的移植性問題並創建一個檔案``configure.scan'',該檔案就是套裝軟件的``configure.in''預備版本。
在把``configure.scan''改名為``configure.in''之前,你應該手工地檢查它;它可能需要一些調整。 autoscan偶爾會按照相對於其他宏的錯誤的順序輸出宏,為此autoconf將給出警告;你需要手工地移動這些宏。還有,如果你希望包使用一個配置頭檔案,你必須添加一個對AC_CONFIG_HEADER的調用。(參見配置頭檔案)。可能你還必須在你的程式中修改或者添加一些#if 指令以使得程式可以與Autoconf合作。(關於有助於該工作的程式的詳情,參見 用ifnames列舉條件)。
autoscan使用一些數據檔案,它們是隨發布的Autoconf宏檔案一起安裝的,以便當它在包中的源檔案中發現某些特殊符號時決定輸出那些宏。這些檔案都具有相同的格式。每一個都是由符號、空白和在符號出現時應該輸出的Autoconf 宏。以``#''開頭的行是註釋。
只有在你安裝了Perl的情況下才安裝autoscan。 autoscan接受如下選項︰
--help
列印命令行選項的概述並且退出。
--macrodir=dir
在目錄dir中,而不是在缺省安裝目錄中尋找數據檔案。你還可以把環境變量AC_MACRODIR設定成一個目錄;本選項將覆蓋該環境變量。
--verbose
列印它檢查的檔案名稱以及在這些檔案中發現的可能感興趣的符號。它的輸出可能很冗長。
--version
列印Autoconf的版本號並且退出。
用ifnames列舉條件
在為一個套裝軟件編寫``configure.in''時,ifnames可以提供一些幫助。它列印出包已經在C預處理條件中使用的標識符。如果包已經被設定得具備了某些可移植性,該程式可以幫助你找到configure所需要進行的檢查。它可能有助於補足由autoscan生成的``configure.in''中的某些缺陷。(參見用autoscan創建``configure.in'')。
ifnames掃描所有在命令行中給出的C源代碼檔案(如果沒有給出,就掃描標準輸入)並且把排序後的、由所有出現下這些檔案中的#if、#elif、#ifdef或者#ifndef 命令中的標識符清單輸出到標準輸出中。它為每個標識符輸出單獨的一行,行中標識符之後是一個由空格分隔的、使用了該標識符的檔案名清單。
ifnames接受如下選項︰
--help
-h
列印命令行選項的概述並且退出。
--macrodir=dir
-m dir
在目錄dir中,而不是缺省安裝目錄中尋找Autoconf宏檔案。僅僅被用於獲取版本號。你還可以把環境變量AC_MACRODIR設定成一個目錄;本選項將覆蓋該環境變量。
--version
列印Autoconf的版本號並且退出。
用autoconf創建configure
為了從``configure.in''生成configure,不帶參數地營運程式autoconf。 autoconf用使用Autoconf宏的m4宏處理器處理``configure.in''。如果你為autoconf提供了參數,它讀入給出的檔案而不是``configure.in''並且把配置腳本輸出到標準輸出而不是configure。如果你給autoconf以參數``-'',它將從標準輸入,而不是``configure.in''中讀取並且把配置腳本輸出到標準輸出。
Autoconf宏在幾個檔案中定義。在這些檔案中,有些是與Autconf一同發布的;autoconf首先讀入它們。而後它在包含了發布的Autoconf宏檔案的目錄中尋找可能出現的檔案``acsite.m4'',並且在當前目錄中尋找可能出現的檔案``aclocal.m4''。這些檔案可以包含你的站點的或者包自帶的Autoconf宏定義(詳情請參見 編寫宏)。如果宏在多於一個由autoconf讀入了的檔案中被定義,那麼後面的定義將覆蓋前面的定義。
autoconf接受如下參數︰
--help
-h
輸出命令行選項的概述並且退出。
--localdir=dir
-l dir
在目錄dir中,而不是當前目錄中尋找包檔案``aclocal.m4''。
--macrodir=dir
-m dir
在目錄dir中尋找安裝的宏檔案。你還可以把環境變量AC_MACRODIR設定成一個目錄;本選項將覆蓋該環境變量。
--version
列印Autoconf的版本號並且退出。
用autoreconf更新configure腳本
如果你有大量由Autoconf生成的configure腳本,程式autoreconf可以保留你的一些工作。它重複地營運autoconf(在適當的情況下還營運autoheader)以重新創建以當前目錄為根的目錄樹的Autoconf configure腳本和配置頭檔案。在缺省情況下,它只重新創建那些比對應的 ``configure.in''或者(如果出現)``aclocal.m4''要舊的檔案。由於在檔案沒有被改變的情況下, autoheader並不改變它的輸出檔案的時間標記(timestamp)。這是為了使工作量最小化,修改時間標記是不必要的。如果你安裝了新版本的Autoconf,你可以以選項``--force''調用autoreconf而重新創建 所有的檔案。
如果你在調用autoreconf時給出選項``--macrodir=dir''或者 ``--localdir=dir'',它將把它們傳遞給autoconf和autoheader (相對路徑將被正確地調整)。
在同一個目錄樹中,autoreconf不支援兩個目錄作為同一個大包的一部分(共享``aclocal.m4''和 ``acconfig.h''),也不支援每個目錄都是獨立包(每個目錄都有它們自己的``aclocal.m4''和 ``acconfig.h'')。如果你使用了``--localdir'',它假定所有的目錄都是同一個包的一部分。如果你沒有使用 ``--localdir'',它假定每個目錄都是一個獨立的包,這條限制在將來可能被取消。
關於在configure腳本的源檔案發生變化的情況下自動地重新創建它們的``Makefile''規則的細節,參見自動地重新創建。這種方法正確地處理了配置頭檔案模板的時間標記,但並不傳遞``--macrodir=dir''或者``--localdir=dir''。
autoreconf接受如下選項︰
--help
-h
列印命令行選項的概述並且退出。
--force
-f
即使在``configure''腳本和配置頭檔案比它們的輸入檔案(``configure.in'',如果出現了``aclocal.m4'',也包括它)更新的時候,也要重新創建它們。
--localdir=dir
-l dir
讓autoconf和autoheader在目錄dir中,而不是在每個包含``configure.in'' 的目錄中尋找包檔案``aclocal.m4''和(僅指autoheader)``acconfig.h'' (但不包括``file.top''和``file.bot'')。
--macrodir=dir
-m dir
在目錄dir中,而不是缺省安裝目錄中尋找Autoconf宏檔案。你還可以把環境變量 AC_MACRODIR設定成一個目錄;本選項將覆蓋該環境變量。
--verbose
列印autoreconf營運autoconf(如果適當,還有autoheader)的每個目錄的目錄名。
--version
列印Autoconf的版本號並且退出。
初始化和輸出檔案
Autoconf生成的configure腳本需要一些關於如何進行初始化,諸如如何尋找包的源檔案,的訊息;以及如何生成輸出檔案的訊息。本節敘述如何進行初始化和創建輸出檔案。
尋找configure的輸入檔案
所有configure腳本在作任何其他事情之前都必須調用AC_INIT。此外唯一必須調用的宏是 AC_OUTPUT(參見創建輸出檔案)。
宏︰ AC_INIT (unique-file-in-source-dir)
處理所有命令行參數並且尋找源代碼目錄。unique-file-in-source-dir是一些在包的源代碼目錄中檔案; configure在目錄中檢查這些檔案是否存在以確定該目錄是否包含源代碼。人們可能偶爾會用``--srcdir''給出錯誤的目錄;這是一種安全性檢查。詳情請參見營運configure腳本。
對於需要手工配置或者使用install程式的包來說,雖然在缺省源代碼位置在大部分情況下看起來是正確的,包還是可能需要透過調用AC_CONFIG_AUX_DIR來告訴 configure到那裡去尋找一些其他的shell腳本。
宏︰ AC_CONFIG_AUX_DIR (dir)
在目錄dir中使用``install-sh''、``config.sub''、``config.guess''和 Cygnus configure配置腳本。它們是配置中使用的輔助檔案。dir既可以是絕對路徑,也可以是相對於``srcdir''的相對路徑。缺省值是在``srcdir''或者 ``srcdir/..''或者``srcdir/../..''中首先找到``install-sh'' 的目錄。不對其他檔案進行檢查,以便使AC_PROG_INSTALL不會自動地發布其他輔助檔案。它還要檢查``install.sh'',但因為有些make程式包含了在沒有``Makefile''的情況下從``install.sh''中創建``install''的規則,所以那個名字過時了。
創建輸出檔案
每個Autoconf生成的configure腳本必須以對AC_OUTPUT的調用結尾。它是一個創建作為配置結果的``Makefile''以及其他一些可能的檔案的宏。此外唯一必須調用的宏是AC_INIT (參見尋找configure的輸入檔案)。
宏︰ AC_OUTPUT ([file... [, extra-cmds [, init-cmds]]])創建輸出檔案。
在``configure.in''的末尾調用本宏一次。參數file...是一個以空格分隔的輸出檔案的清單;它可能為空。本宏透過從一個輸入檔案(缺省情況下名為``file.in'')中複製,並替換輸出變量的值以創建每個給出的``file''。關於使用輸出變量的詳情,請參見Makefile中的替換。關於創建輸出變量的詳情,請參見設定輸出變量。如果輸出檔案所在的目錄不存在,本宏將創建該目錄(但不會創建目錄的父目錄)。通常,``Makefile''是按照這種模式創建的,但其他檔案,例如``.gdbinit'',也可以這樣創建。
如果調用了AC_CONFIG_HEADER、AC_LINK_FILES或者AC_CONFIG_SUBDIRS,本宏也將創建出現下它們的參數中的檔案。
一個典型的對AC_OUTPUT調用如下︰
AC_OUTPUT(Makefile src/Makefile man/Makefile X/Imakefile)
你可以透過在file之後添加一個用冒號分隔的輸入檔案清單以自行設定輸入檔案名。例如︰
AC_OUTPUT(Makefile:templates/top.mk lib/Makefile:templates/lib.mk)
AC_OUTPUT(Makefile:templates/vars.mk:Makefile.in:templates/rules.mk)
這樣做可以使得你的檔案名能夠被MS-DOS接受,或者可以把模板檔案(boilerplate)添加到檔案的開頭或者結尾。
如果你給出了extra-cmds,那麼這些命令將被插入到``config.status''中以便在``config.status'' 完成了其他的所有處理之後營運extra-cmds。如果給出了init-cmds,它們就被插入 extra-cmds之前,並且在configure中將對它們進行shell變量、命令和反斜線替換。你可以用 init-cmds把變量從configure中傳遞到extra-cmds。如果調用了 AC_OUTPUT_COMMANDS,在其中給出的命令將緊貼在由本宏給出的命令之前營運。
宏︰ AC_OUTPUT_COMMANDS (extra-cmds [, init-cmds])
指定在``config.status''末尾營運的附加的shell命令,以及用於初始化來自於configure 的所有變量的shell命令。本宏可以被調用多次。下面是一個不太實際的例子︰
fubar=27
AC_OUTPUT_COMMANDS([echo this is extra $fubar, and so on.], fubar=$fubar)
AC_OUTPUT_COMMANDS([echo this is another, extra, bit], [echo init bit])
如果你在次目錄中營運make,你應該透過使用make變量MAKE來營運它。 make的大部分版本把MAKE設定成make的程式名以及它所需要的任何選項。(但許多版本並沒有把在命令行中設定的變量的值包括進來,因此它們沒有被自動地傳遞。)一些老版本的 make並不設定這個變量。以下的宏使你可以在這些版本上使用它。
宏︰ AC_PROG_MAKE_SET
如果make預定義了變量MAKE,把輸出變量SET_MAKE定義為空。否則,把 SET_MAKE定義成``MAKE=make''。為SET_MAKE調用AC_SUBST。
為了使用這個宏,在每個其他的、營運MAKE的目錄中的``Makefile.in''添加一行︰
@SET_MAKE@
Makefiles中的替換
發布版本中每個包含了需要被編譯或者被安裝的檔案的目錄都應該含有一個檔案``Makefile.in'', configure將利用它在那個目錄中創建一個``Makefile''。為了創建``Makefile'',configure進行一個簡單的變量替換︰用configure 為``@variable@''選取的值,在``Makefile.in''中對它們進行替換。按照這種模式被替換到輸出檔案中的變量被稱為輸出變量。在configure中,它們是普通的shell變量。為了讓configure把特殊的變量替換到輸出檔案中,必須把那個變量的名字作為調用 AC_SUBST的參數。其他變量的任何``@variable@''都保持不變。關於使用AC_SUBST創建輸出變量的詳情,請參見設定輸出變量。
使用configure腳本的軟體應該發布檔案``Makefile.in'',而不是``Makefile'';這樣,用戶就可以在編譯它之前正確地為本地系統進行配置了。
關於應該把哪些東西放入``Makefile''的詳情,請參見GNU編碼標準中的``Makefile慣例''。
預定義輸出變量
有些輸出變量是由Autoconf宏預定義的。一部分Autoconf宏設定一些附加的輸出變量,這些變量在對這些宏的描述中被說明。關於輸出變量的完整清單,參見輸出變量索引。下面是每個預定義變量所包含的內容。關於變量名以``dir''結尾的變量,參見GNU編碼標準中的 ``為安裝目錄而提供的變量''。
變量︰ bindir
用於安裝由用戶營運的可執行檔案的目錄。
變量︰ configure_input
一個用於說明檔案是由configure自動生成的,並且給出了輸入檔案名的註釋。 AC_OUTPUT在它創建的每個``Makefile''檔案的開頭添加一個包括了這個變量的註釋行。對於其他檔案,你應該在每個輸入檔案開頭處的註釋中引用這個變量。例如,一個輸入shell腳本應該以如下行開頭︰
#! /bin/sh
# @configure_input@
這一行的存在也提醒了人們在編輯這個檔案之後需要用configure進行處理以使用它。
變量︰ datadir
用於安裝只讀的與架構無關的數據的目錄。
變量︰ exec_prefix
與架構有關的檔案的安裝前綴。
變量︰ includedir
用於安裝C頭檔案的目錄。
變量︰ infodir
用於安裝Info格式文檔的目錄。
變量︰ libdir
用於安裝目標代碼庫的目錄。
變量︰ libexecdir
用於安裝由其他程式營運的可執行檔案的目錄。
變量︰ localstatedir
用於安裝可以被修改的單機數據的目錄。
變量︰ mandir
用於安裝man格式的文檔的頂層目錄。
變量︰ oldincludedir
用於安裝由非gcc編譯器使用的C頭檔案的目錄。
變量︰ prefix
與架構無關的檔案的安裝前綴。
變量︰ sbindir
用於安裝由系統管理員營運的可執行檔案的目錄。
變量︰ sharedstatedir
用於安裝可以修改的、與架構無關的數據的目錄。
變量︰ srcdir
包含了由``Makefile''使用的源代碼的目錄。
變量︰ sysconfdir
用於安裝只讀的單機數據的目錄。
變量︰ top_srcdir
包的頂層源代碼目錄。在目錄的頂層,它與srcdir相同。
變量︰ CFLAGS
為C編譯器提供的調試和優化選項。如果在營運configure時,沒有在環境中設定它,就在你調用AC_PROG_CC的時候設定它的缺省值(如果你沒有調用AC_PROG_CC,它就為空)。 configure在編譯程式以測試C的特徵時,使用本變量。
變量︰ CPPFLAGS
為C預處理器和編譯器提供頭檔案搜索目錄選項(``-Idir'')以及其他各種選項。如果在營運 configure時,在環境中沒有設定本變量,缺省值就是空。configure在編譯或者預處理程式以測試C的特徵時,使用本變量。
變量︰ CXXFLAGS
為C++編譯器提供的調試和優化選項。如果在營運configure時,沒有在環境中設定本變量,那麼就在你調用AC_PROG_CXX時設定它的缺省值(如果你沒有調用AC_PROG_CXX,它就為空)。 configure在編譯程式以測試C++的特徵時,使用本變量。
變量︰ FFLAGS
為Fortran 77編譯器提供的調試和優化選項。如果在營運configure時,在環境中沒有設定本變量,那麼它的缺省值就在你調用AC_PROG_F77時被設定(如果你沒有調用AC_PROG_F77,它就為空)。 configure在編譯程式以測試Fortran 77的特徵時,使用本變量。
變量︰ DEFS
傳遞給C編譯器的``-D''選項。如果調用了AC_CONFIG_HEADER,configure就用 ``-DHAVE_CONFIG_H''代替``@DEFS@''(參見配置頭檔案)。在configure進行它的測試時,本變量沒有被定義,只有在創建輸出檔案時候才定義。關於如何檢查從前的測試結果,請參見設定輸出變量。
變量︰ LDFLAGS
為連接器提供的Stripping(``-s'')選項和其他各種選項。如果在營運configure時,在環境中沒有設定本變量,它的缺省值就是空。 configure在連接程式以測試C的特徵時使用本變量。
變量︰ LIBS
傳遞給連接器的``-l''和``-L''選項。
創建目錄
你可以支援從一個套裝軟件的一份源代碼拷貝中為多種架構同時進行編譯的功能。為每種架構生成的目標檔案都在它們自己的目錄中儲存。
為了支援這個功能,make用變量VPATH來尋找儲存在源代碼目錄中的檔案。 GNU make和其他大部分近來的make程式都可以這樣做。老版本的make 程式不支援VPATH;在使用它們的時候,源代碼必須與目標代碼處於同一個目錄。
為了支援VPATH,每個``Makefile.in''檔案都應該包含下列兩行︰
srcdir = @srcdir@
VPATH = @srcdir@
不要把VPATH設定成其他變量的值,比如說``VPATH = $(srcdir)'',這是因為某些版本的make並不對VPATH的值進行變量替換。
在configure生成``Makefile''的時候,它用正確的值對srcdir進行替換。
除非在隱含規則中,不要使用make變量$<,它将被展开成到源代码目录的文件的路径(通过VPATH找到的)。(诸如``.c.o''的隐含规则用于说明如何从``.c'' 文件创建``.o''文件)有些版本的make在隐含规则中不设置$<;它们被展开成空值。
``Makefile''命令行總是應該透過使用前綴``$(srcdir)/''來引用源代碼檔案。例如︰
time.info: time.texinfo
$(MAKEINFO) $(srcdir)/time.texinfo
自動地重新創建
你可以在包的頂層目錄中的``Makefile.in''檔案中添加如下的規則,以使得在你更新了配置檔案之後可以自動地更新配置訊息。這個例子包括了所有可選的檔案,例如``aclocal.m4''和那些與配置頭檔案有關的檔案。從``Makefile.in''規則中忽略所有你的所不需要的檔案。
因為VPATH機製的限制,應該包含``${srcdir}/''前綴。
在重新創建不改變``config.h.in''和``config.h''的內容的情況下,就不會改變這兩個檔案的時間標記,因此需要``stamp-''檔案。這個特徵避免了不必要的重新編譯工作。你應該把檔案``stamp-h.in'' 包含在你的包的發布中,以便make能夠把``config.h.in''看作是更新了的檔案。在一些老的BSD系統中,touch或者任何可能導致空檔案的命令不會更改時間標記,所以使用諸如echo 之類的命令。
${srcdir}/configure: configure.in aclocal.m4
cd ${srcdir} && autoconf
# autoheader might not change config.h.in, so touch a stamp file.
${srcdir}/config.h.in: stamp-h.in
${srcdir}/stamp-h.in: configure.in aclocal.m4 acconfig.h
config.h.top config.h.bot
cd ${srcdir} && autoheader
echo timestamp > ${srcdir}/stamp-h.in
config.h: stamp-h
stamp-h: config.h.in config.status
./config.status
Makefile: Makefile.in config.status
./config.status
config.status: configure
./config.status --recheck
此外,你應該把``echo timestamp > stamp-h''作為extra-cmds參數傳遞給AC_OUTPUT,以便``config.status''能夠確認``config.h''是更新了的。關於AC_OUTPUT的詳情,請參見 創建輸出檔案。
關於處理與配置相關的倚賴性問題的更多例子,請參見重新創建一個配置。
配置頭檔案
在包測試的C預處理器符號比較多的時候,用於把``-D''傳遞給編譯器的命令行就會變得很長。這導致了兩個問題。一個是透過觀察尋找make輸出中的錯誤變得困難了。更嚴重的是,命令行可能超過某些作業系統的長度限制。作為把``-D''選項傳遞給編譯器的替代辦法,configure 腳本可以創建一個包含了``#define''指令的C頭檔案。宏AC_CONFIG_HEADER 選擇了這種輸出。它應該在AC_INIT之後立即調用。
包應該在引入其他任何頭檔案之前``#include''配置頭檔案,以防止出現聲明中的不一致性(例如,配置頭檔案可能重定義了const)。使用``#include '' 並且把選項``-I.''(或者是``-I..'';或者是任何包含``config.h'' 的目錄)傳遞給C編譯器,而不是使用``#include ""config.h""''。按照這種模式,即使源代碼自行進行配置(可能是創建發布版本),其他創建目錄也可以在沒有找到``config.h''的情況下,從源代碼目錄進行配置。
宏︰ AC_CONFIG_HEADER (header-to-create ...)
使得AC_OUTPUT創建出現下以空格分隔的清單header-to-create中的檔案,以包含C預處理器#define語句,並在生成的檔案中用``-DHAVE_CONFIG_H'' ,而不是用DEFS的值,替換``@DEFS@''。常用在header-to-create 中的檔案名是``config.h''。
如果header-to-create給出的檔案已經存在並且它的內容和AC_OUTPUT將要生成的內容完全一致,這些檔案就保持不變。這樣做就使得對配置的某些修改不會導致對倚賴於頭檔案的目標檔案進行不必要的重新編譯。
通常輸入檔案被命名為``header-to-create.in'';然而,你可以透過在header-to-create 之後添加由冒號分隔的輸入檔案清單來覆蓋原輸入檔案名。例︰
AC_CONFIG_HEADER(defines.h:defines.hin)
AC_CONFIG_HEADER(defines.h:defs.pre:defines.h.in:defs.post)
這樣做使得你的檔案名能夠被MS-DOS所接受,或者可以把模板(boilerplate)添加到檔案的開頭和/或結尾。
配置頭檔案模板
你的發布版本應該包含一個如你所望的最終的頭檔案那樣的模板檔案,它包括註釋、以及#define 語句的缺省值。例如,假如你的``configure.in''進行了下列調用︰
AC_CONFIG_HEADER(conf.h)
AC_CHECK_HEADERS(unistd.h)
那麼你就應該在``conf.h.in''中包含下列代碼。在含有``unistd.h''的系統中,configure應該把0改成1。在其他系統中,這一行將保持不變。
/* Define as 1 if you have unistd.h. */
#define HAVE_UNISTD_H 0
如果你的代碼使用#ifdef而不是#if來測試配置選項,缺省值就可能是取消對一個變量的定義而不是把它定義成一個值。在含有``unistd.h''的系統中,configure將修改讀入的第二行 ``#define HAVE_UNISTD_H 1''。在其他的系統中,(在系統預定義了那個符號的情況下) configure將以註釋的模式排除這一行。
/* Define if you have unistd.h. */
#undef HAVE_UNISTD_H
用autoheader創建``config.h.in''
程式autoheader可以創建含有C的``#define''語句的模板檔案以供configure使用。如果``configure.in''調用了AC_CONFIG_HEADER(file),autoheader就創建 ``file.in'';如果給出了多檔案參數,就使用第一個檔案。否則,autoheader就創建 ``config.h.in''。
如果你為autoheader提供一個參數,它就使用給出的檔案而不是``configure.in'',並且把頭檔案輸出到標準輸出中去,而不是輸出到``config.h.in''。如果你把``-''作為參數提供給autoheader ,它就從標準輸入中,而不是從``configure.in''中讀出,並且把頭檔案輸出到標準輸出中去。
autoheader掃描``configure.in''並且找出它可能要定義的C預處理器符號。它從一個名為 ``acconfig.h''的檔案中複製註釋、#define和#undef語句,該檔案與Autoconf一同發布並且一同安裝。如果當前目錄中含有``acconfig.h''檔案,它也會使用這個檔案。如果你用AC_DEFINE 定義了任何附加的符號,你必須在創建的那個``acconfig.h''檔案中包含附加的符號。對於由 AC_CHECK_HEADERS、AC_CHECK_FUNCS、AC_CHECK_SIZEOF或者 AC_CHECK_LIB定義的符號,autoheader生成註釋和#undef語句,而不是從一個檔案中複製它們,這是因為可能的符號是無限的。
autoheader創建的檔案包含了大部分#define和#undef語句,以及相關的註釋。如果``./acconfig.h''包含了字元串``@TOP@'',autoheader就把在包含``@TOP@'' 的行之前的所有行複製到它生成的檔案的開頭。相似地,如果``./acconfig.h''包含了字元串``@BOTTOM@'', autoheader就把那一行之後的所有行複製到它生成的檔案的末尾。這兩個字元串的任何一個都可以被忽略,也可以被同時忽略。
產生相同效果的另一種辦法是在當前目錄中創建檔案``file.top''(通常是``config.h.top'')和/或檔案``file.bot''。如果它們存在,autoheader就把它們分別複製到它的輸出的開頭和末尾。不鼓勵使用它們是因為它們的檔案名含有兩個點,並因此不能在MS-DOS中儲存;它們在目錄中多創建了兩個檔案。但如果你給出選項``--localdir=dir''以使用在其他目錄中的``acconfig.h'',它們就為你提供了一種把定製的模板(boilerplate)放入各個獨立的``config.h.in''中的模式。
autoheader接受如下選項︰
--help
-h
列印對命令行選項的概述並且退出。
--localdir=dir
-l dir
在目錄dir中,而不是在當前目錄中,尋找包檔案``aclocal.m4''和``acconfig.h'' (但不包括``file.top''和``file.bot'')。
--macrodir=dir
-m dir
在目錄dir中尋找安裝的宏檔案和``acconfig.h''。你還可以把環境變量AC_MACRODIR 設定成一個目錄;本選項將覆蓋該環境變量。
--version
列印Autoconf的版本號並且退出。
在次目錄中配置其它包
在大多數情況下,調用AC_OUTPUT足以在次目錄中生成``Makefile''。然而,控制了多於一個獨立包的configure腳本可以使用AC_CONFIG_SUBDIRS來為每個次目錄中的其他包營運 configure腳本。
宏︰ AC_CONFIG_SUBDIRS (dir ...)
使得AC_OUTPUT在每個以空格分隔的清單中給出的次目錄dir中營運configure。如果沒有發現某個給出的dir,不會作為錯誤報告,所以一個configure腳本可以配置一個大的源代碼樹中出現的任何一個部分。如果在給出的dir中包含了``configure.in'',但沒有包含 configure,就使用由AC_CONFIG_AUXDIR找到的Cygnus configure腳本。
用與本configure腳本完全相同的命令行參數調用次目錄中的configure腳本,如果需要,會有較小的修改(例如,為緩沖檔案或者源代碼目錄調整相對路徑)。本宏還把輸出變量subdirs設定成目錄清單``dir...''。``Makefile''規則可以使用該變量以確定需要進入那些次目錄。這個宏可以多次調用。
缺省的前綴
在缺省狀態下,configure把它所安裝的檔案的前綴設定成``/usr/local''。 configure的用戶可以透過選項``--prefix''和``--exec-prefix''選擇一個不同的前綴。有兩種模式修改缺省的行為︰在創建configure時,和營運configure時。
有些套裝軟件在缺省情況下可能需要安裝到``/usr/local''以外的目錄中。為此,使用宏AC_PREFIX_DEFAULT。
宏︰ AC_PREFIX_DEFAULT (prefix)
把缺省的安裝前綴設定成prefix,而不是``/usr/local''。
對於用戶來說,讓configure根據它們已經安裝的相關程式的位置來猜測安裝前綴,可能會帶來方便。如果你希望這樣做,你可以調用AC_PREFIX_PROGRAM。
宏︰ AC_PREFIX_PROGRAM (program)
如果用戶沒有給出安裝前綴(使用選項``--prefix''),就按照shell的模式,在PATH中尋找 program,從而猜出一個安裝前綴。如果找到了program,就把前綴設定成包含program 的目錄的父目錄;否則,就不改變在``Makefile.in''中給定的前綴。例如,如果program是 gcc,並且PATH包括了``/usr/local/gnu/bin/gcc'',就把前綴設定為 ``/usr/local/gnu''。
configure中的版本號
以下的宏為configure腳本管理版本號。使用它們是可選的。
宏︰ AC_PREREQ (version)
確保使用的是足夠新的Autoconf版本。如果用於創建configure的Autoconf的版本比version 要早,就在標準錯誤輸出列印一條錯誤消息並不會創建configure。例如︰
AC_PREREQ(1.8)
如果你的``configure.in''倚賴於在不同Autoconf版本中改變了的、不明顯的行為,本宏就是有用的。如果它僅僅是需要近來增加的宏,那麼AC_PREREQ就不太有用,這是因為程式autoconf已經告訴了用戶那些宏沒有被找到。如果``configure.in''是由一個在提供AC_PREREQ之前的更舊的 Autoconf版本處理的,也會發生同樣的事。
宏︰ AC_REVISION (revision-info)
把刪除了任何美元符或者雙引號的修訂標記(revision stamp)複製到configure腳本中。本宏使得你的從``configure.in''傳遞到configure的修訂標記不會在你提交(check in) configure的時候被RCS或者CVS修改。你可以容易地決定一個特定的configure 對應與``configure.in''的哪個修訂版。
把本宏放在AC_INIT之前是個好主意,它可以使修訂號接近``configure.in''和configure 的開頭。為了支援你這樣做,AC_REVISION就像configure通常作的那樣,以 ``#! /bin/sh''開始它的輸出。
例如,在``configure.in''中這一行為︰
AC_REVISION($Revision: 1.30 $)dnl
在configure中產生了︰
#! /bin/sh # From configure.in Revision: 1.30
autoconf手冊(一)
Autoconf
Creating Automatic Configuration Scripts
Edition 2.13, for Autoconf version 2.13
December 1998
by David MacKenzie and Ben Elliston
--------------------------------------------------------------------------------
Permission is granted to make and distribute verbatim copies of this manual provided the copyright notice and this permission notice are preserved on all copies.
Permission is granted to copy and distribute modified versions of this manual under the conditions for verbatim copying, provided that the entire resulting derived work is distributed under the terms of a permission notice identical to this one.
Permission is granted to copy and distribute translations of this manual into another language, under the above conditions for modified versions, except that this permission notice may be stated in a translation approved by the Free Software Foundation.
只要版權聲明和本許可聲明保留在所有副本中,您就被授權製作和發行本手冊的原文副本。
只要整個最終派生工作按照與本手冊相同的許可聲明發行,您就被授權按照與發行原文相同的條件複製和發行本手冊的修改版本。
除了本許可聲明應該使用由基金會批准的譯文之外,您被授權按照與上述修改版本相同的條件複製和發行本手冊的其它語言的譯文。
--------------------------------------------------------------------------------
本文檔由王立翻譯。 1999.12.16
譯者在此聲明︰不對任何由譯文錯誤或者對譯文的誤解承擔任何責任。
--------------------------------------------------------------------------------
介紹
A physicist, an engineer, and a computer scientist were
discussing the nature of God. Surely a Physicist, said the
physicist, because early in the Creation, God made Light; and you
know, Maxwell''s equations, the dual nature of electro-magnetic
waves, the relativist consequences... An Engineer!, said the
engineer, because before making Light, God split the Chaos into
Land and Water; it takes a hell of an engineer to handle that big
amount of mud, and orderly separation of solids from
liquids... The computer scientist shouted: And the Chaos,
where do you think it was coming from, hmm?
---Anonymous
Autoconf是一個用於生成可以自動地配置軟體源代碼包以適應多種Unix類系統的 shell腳本的工具。由Autoconf生成的配置腳本在營運的時候與Autoconf是無關的,就是說配置腳本的用戶並不需要擁有Autoconf。
由Autoconf生成的配置腳本在營運的時候不需要用戶的手工干預;通常它們甚至不需要透過給出參數以確定系統的類型。相反,它們對套裝軟件可能需要的各種特徵進行獨立的測試。(在每個測試之前,它們列印一個單行的消息以說明它們正在進行的檢測,以使得用戶不會因為等待腳本執行完畢而焦躁。)因此,它們在混合系統或者從各種常見Unix變種定製而成的系統中工作的很好。沒有必要維護檔案以儲存由各個Unix變種、各個發行版本所支援的特徵的清單。
對於每個使用了Autoconf的套裝軟件,Autoconf從一個列舉了該套裝軟件需要的,或者可以使用的系統特徵的清單的模板檔案中生成配置腳本。在shell代碼識別並附應了一個被列出的系統特徵之後,Autoconf允許多個可能使用(或者需要)該特徵的套裝軟件共享該特徵。如果後來因為某些原因需要調整shell代碼,就只要在一個地方進行修改;所有的配置腳本都將被自動地重新生成以使用更新了的代碼。
Metaconfig包在目的上與Autoconf很相似,但它生成的腳本需要用戶的手工干預,在配置一個大的源代碼樹的時候這是十分不方便的。不象Metaconfig腳本,如果在編寫腳本時小心謹慎, Autoconf可以支援交叉編譯(cross-compiling)。
Autoconf目前還不能完成幾項使套裝軟件可移植的工作。其中包括為所有標準的目標自動創建``Makefile''檔案,包括在缺少標準庫函數和頭檔案的系統上提供替代品。目前正在為在將來添加這些特徵而工作。
對於在C程式中的#ifdef中使用的宏的名字,Autoconf施加了一些限制(參見預處理器符號索引)。
Autoconf需要GNU m4以便於生成腳本。它使用了某些UNIX版本的m4 所不支援的特徵。它還會超出包括GNU m4 1.0在內的某些m4版本的內部限制。你必須使用GNU m4的1.1版或者更新的版本。使用1.3版或者更新的版本將比1.1 或1.2版快許多。
關於從版本1中升級的詳情,參見從版本1中升級。關於Autoconf的開發歷史,參見Autoconf的歷史。對與Autoconf有關的常見問題的回答,參見關於Autoconf的問題。
把守關口於Autoconf的建議和bug報告發送到bug-gnu-utils@prep.ai.mit.edu。請把你透過營運``autoconf --version''而獲得的Autoconf的版本號包括在內。
創建configure腳本
由Autoconf生成的配置腳本通常被稱為configure。在營運的時候,configure 創建一些檔案,在這些檔案中以適當的值替換配置參數。由configure創建的檔案有︰
一個或者多個``Makefile''檔案,在包的每個次目錄中都有一個(參見 Makefile中的替換);
有時創建一個C頭檔案,它的名字可以被配置,該頭檔案包含一些#define命令(參見配置頭檔案);
一個名為``config.status''的shell腳本,在營運時,它將重新創建上述檔案。(參見重新創建一個配置);
一個名為``config.cache''的shell腳本,它儲存了許多測試的營運結果(參見緩存檔案);
一個名為``config.log''的檔案,它包含了由編譯器生成的許多消息,以便於在configure出現錯誤時進行調試。
為了使用Autoconf創建一個configure腳本,你需要編寫一個Autoconf的輸入檔案 ``configure.in''並且對它營運autoconf。如果你自行編寫了特徵測試以補充 Autoconf所提供的測試,你可能還要編寫一個名為``aclocal.m4''的檔案和一個名為 ``acsite.m4''的檔案。如果你使用了包含#define指令的C頭檔案,你可能還要編寫``acconfig.h'',並且你需要與套裝軟件一同發布由Autoconf生成的檔案 ``config.h.in''。
下面是一個說明了在配置中使用的檔案是如何生成的圖。營運的程式都標以後綴``*''。可能出現的檔案被方括號(``[]'')括起來。autoconf和autoheader 還讀取安裝了的Autoconf宏檔案(透過讀取``autoconf.m4'')。
在準備發布套裝軟件的過程中使用的檔案︰
你的源檔案 --> [autoscan*] --> [configure.scan] --> configure.in
configure.in --. .------> autoconf* -----> configure
+---+
[aclocal.m4] --+ ``---.
[acsite.m4] ---''
+--> [autoheader*] -> [config.h.in]
[acconfig.h] ----.
+-----''
[config.h.top] --+
[config.h.bot] --''
Makefile.in -------------------------------> Makefile.in
在配置套裝軟件的過程中使用的檔案︰
.-------------> config.cache
configure* ------------+-------------> config.log
[config.h.in] -. v .-> [config.h] -.
+--> config.status* -+ +--> make*
Makefile.in ---'' ``-> Makefile ---''
編寫``configure.in''
為了為套裝軟件創建configure腳本,需要編寫一個名為``configure.in'' 的檔案,該檔案包含了對那些你的套裝軟件需要或者可以使用的系統特徵進行測試的Autoconf宏的調用。現有的Autoconf宏可以檢測許多特徵; 對於它們的描述可以參見現有的測試。對於大部分其他特徵,你可以使用Autconf模板宏以創建定製的測試;關於它們的詳情,參見 編寫測試。對於特別古怪或者特殊的特徵,``configure.in'' 可能需要包含一些手工編寫的shell命令。程式autoscan可以為你編寫``configure.in'' 開個好頭(詳情請參見用autoscan創建``configure.in'')。
除了少數特殊情況之外,在``configure.in''中調用Autoconf宏的順序並不重要。在每個``configure.in''中,必須在進行任何測試之間包含一個對AC_INIT的調用,並且在結尾處包含一個對AC_OUTPUT的調用(參見創建輸出檔案)。此外,有些宏要求其他的宏在它們之前被調用,這是因為它們透過檢查某些變量在前面設定的值以決定作些什麼。這些宏在獨立的說明中給出(參見現有的測試),而且如果沒有按照順序調用宏,在生成configure時會向你發出警告。
為了提升一致性,下面是調用Autoconf宏的推薦順序。通常,在本清單中靠後的項目倚賴於表中靠前的項目。例如,庫函數可能受到typedefs和庫的影響。
AC_INIT(file)
checks for programs
checks for libraries
checks for header files
checks for typedefs
checks for structures
checks for compiler characteristics
checks for library functions
checks for system services
AC_OUTPUT([file...])
最好讓每個宏調用在``configure.in''中佔據單獨的一行。大部分宏並不添加額外的新行;它們倚賴於在宏調用之後的新行以結束命令。這種方法使得生成的configure腳本在不必添加大量的空行的情況下比較容易閱讀。在宏調用的同一行中設定shell變量通常是安全的,這是因為shell允許出現沒有用新行間隔的賦值。
在調用帶參數的宏的時候,在宏名和左括號之間不能出現任何空格。如果參數被m4 引用字符``[''和``]''所包含,參數就可以多於一行。如果你有一個長行,比如說一個檔案名清單,你通常可以在行的結尾使用反斜線以便在邏輯上把它與下一行進行連接(這是由shell實現的,Autoconf對此沒有進行任何特殊的處理)。
有些宏處理兩種情況︰如果滿足了某個給定的條件就做什麼,如果沒有滿足某個給定的條件就做什麼。在有些地方,你可能希望在條件為真的情況下作些事,在為假時什麼也不作。反之亦然。為了忽略為真的情況,把空值作為參數action-if-found傳遞給宏。為了忽略為假的情況,可以忽略包括前面的逗號在內的宏的參數action-if-not-found。
你可以在檔案``configure.in''中添加註釋。註釋以m4預定義宏dnl 開頭,該宏丟棄在下一個新行之前的所有文本。這些註釋並不在生成的configure腳本中出現。例如,把下面給出的行作為檔案``configure.in''的開頭是有好處的︰
dnl Process this file with autoconf to produce a configure script.
用autoscan創建``configure.in''
程式autoscan可以幫助你為套裝軟件創建``configure.in''檔案。如果在命令行中給出了目錄, autoscan就在給定目錄及其次目錄樹中檢查源檔案,如果沒有給出目錄,就在當前目錄及其次目錄樹中進行檢查。它搜索源檔案以尋找一般的移植性問題並創建一個檔案``configure.scan'',該檔案就是套裝軟件的``configure.in''預備版本。
在把``configure.scan''改名為``configure.in''之前,你應該手工地檢查它;它可能需要一些調整。 autoscan偶爾會按照相對於其他宏的錯誤的順序輸出宏,為此autoconf將給出警告;你需要手工地移動這些宏。還有,如果你希望包使用一個配置頭檔案,你必須添加一個對AC_CONFIG_HEADER的調用。(參見配置頭檔案)。可能你還必須在你的程式中修改或者添加一些#if 指令以使得程式可以與Autoconf合作。(關於有助於該工作的程式的詳情,參見 用ifnames列舉條件)。
autoscan使用一些數據檔案,它們是隨發布的Autoconf宏檔案一起安裝的,以便當它在包中的源檔案中發現某些特殊符號時決定輸出那些宏。這些檔案都具有相同的格式。每一個都是由符號、空白和在符號出現時應該輸出的Autoconf 宏。以``#''開頭的行是註釋。
只有在你安裝了Perl的情況下才安裝autoscan。 autoscan接受如下選項︰
--help
列印命令行選項的概述並且退出。
--macrodir=dir
在目錄dir中,而不是在缺省安裝目錄中尋找數據檔案。你還可以把環境變量AC_MACRODIR設定成一個目錄;本選項將覆蓋該環境變量。
--verbose
列印它檢查的檔案名稱以及在這些檔案中發現的可能感興趣的符號。它的輸出可能很冗長。
--version
列印Autoconf的版本號並且退出。
用ifnames列舉條件
在為一個套裝軟件編寫``configure.in''時,ifnames可以提供一些幫助。它列印出包已經在C預處理條件中使用的標識符。如果包已經被設定得具備了某些可移植性,該程式可以幫助你找到configure所需要進行的檢查。它可能有助於補足由autoscan生成的``configure.in''中的某些缺陷。(參見用autoscan創建``configure.in'')。
ifnames掃描所有在命令行中給出的C源代碼檔案(如果沒有給出,就掃描標準輸入)並且把排序後的、由所有出現下這些檔案中的#if、#elif、#ifdef或者#ifndef 命令中的標識符清單輸出到標準輸出中。它為每個標識符輸出單獨的一行,行中標識符之後是一個由空格分隔的、使用了該標識符的檔案名清單。
ifnames接受如下選項︰
--help
-h
列印命令行選項的概述並且退出。
--macrodir=dir
-m dir
在目錄dir中,而不是缺省安裝目錄中尋找Autoconf宏檔案。僅僅被用於獲取版本號。你還可以把環境變量AC_MACRODIR設定成一個目錄;本選項將覆蓋該環境變量。
--version
列印Autoconf的版本號並且退出。
用autoconf創建configure
為了從``configure.in''生成configure,不帶參數地營運程式autoconf。 autoconf用使用Autoconf宏的m4宏處理器處理``configure.in''。如果你為autoconf提供了參數,它讀入給出的檔案而不是``configure.in''並且把配置腳本輸出到標準輸出而不是configure。如果你給autoconf以參數``-'',它將從標準輸入,而不是``configure.in''中讀取並且把配置腳本輸出到標準輸出。
Autoconf宏在幾個檔案中定義。在這些檔案中,有些是與Autconf一同發布的;autoconf首先讀入它們。而後它在包含了發布的Autoconf宏檔案的目錄中尋找可能出現的檔案``acsite.m4'',並且在當前目錄中尋找可能出現的檔案``aclocal.m4''。這些檔案可以包含你的站點的或者包自帶的Autoconf宏定義(詳情請參見 編寫宏)。如果宏在多於一個由autoconf讀入了的檔案中被定義,那麼後面的定義將覆蓋前面的定義。
autoconf接受如下參數︰
--help
-h
輸出命令行選項的概述並且退出。
--localdir=dir
-l dir
在目錄dir中,而不是當前目錄中尋找包檔案``aclocal.m4''。
--macrodir=dir
-m dir
在目錄dir中尋找安裝的宏檔案。你還可以把環境變量AC_MACRODIR設定成一個目錄;本選項將覆蓋該環境變量。
--version
列印Autoconf的版本號並且退出。
用autoreconf更新configure腳本
如果你有大量由Autoconf生成的configure腳本,程式autoreconf可以保留你的一些工作。它重複地營運autoconf(在適當的情況下還營運autoheader)以重新創建以當前目錄為根的目錄樹的Autoconf configure腳本和配置頭檔案。在缺省情況下,它只重新創建那些比對應的 ``configure.in''或者(如果出現)``aclocal.m4''要舊的檔案。由於在檔案沒有被改變的情況下, autoheader並不改變它的輸出檔案的時間標記(timestamp)。這是為了使工作量最小化,修改時間標記是不必要的。如果你安裝了新版本的Autoconf,你可以以選項``--force''調用autoreconf而重新創建 所有的檔案。
如果你在調用autoreconf時給出選項``--macrodir=dir''或者 ``--localdir=dir'',它將把它們傳遞給autoconf和autoheader (相對路徑將被正確地調整)。
在同一個目錄樹中,autoreconf不支援兩個目錄作為同一個大包的一部分(共享``aclocal.m4''和 ``acconfig.h''),也不支援每個目錄都是獨立包(每個目錄都有它們自己的``aclocal.m4''和 ``acconfig.h'')。如果你使用了``--localdir'',它假定所有的目錄都是同一個包的一部分。如果你沒有使用 ``--localdir'',它假定每個目錄都是一個獨立的包,這條限制在將來可能被取消。
關於在configure腳本的源檔案發生變化的情況下自動地重新創建它們的``Makefile''規則的細節,參見自動地重新創建。這種方法正確地處理了配置頭檔案模板的時間標記,但並不傳遞``--macrodir=dir''或者``--localdir=dir''。
autoreconf接受如下選項︰
--help
-h
列印命令行選項的概述並且退出。
--force
-f
即使在``configure''腳本和配置頭檔案比它們的輸入檔案(``configure.in'',如果出現了``aclocal.m4'',也包括它)更新的時候,也要重新創建它們。
--localdir=dir
-l dir
讓autoconf和autoheader在目錄dir中,而不是在每個包含``configure.in'' 的目錄中尋找包檔案``aclocal.m4''和(僅指autoheader)``acconfig.h'' (但不包括``file.top''和``file.bot'')。
--macrodir=dir
-m dir
在目錄dir中,而不是缺省安裝目錄中尋找Autoconf宏檔案。你還可以把環境變量 AC_MACRODIR設定成一個目錄;本選項將覆蓋該環境變量。
--verbose
列印autoreconf營運autoconf(如果適當,還有autoheader)的每個目錄的目錄名。
--version
列印Autoconf的版本號並且退出。
初始化和輸出檔案
Autoconf生成的configure腳本需要一些關於如何進行初始化,諸如如何尋找包的源檔案,的訊息;以及如何生成輸出檔案的訊息。本節敘述如何進行初始化和創建輸出檔案。
尋找configure的輸入檔案
所有configure腳本在作任何其他事情之前都必須調用AC_INIT。此外唯一必須調用的宏是 AC_OUTPUT(參見創建輸出檔案)。
宏︰ AC_INIT (unique-file-in-source-dir)
處理所有命令行參數並且尋找源代碼目錄。unique-file-in-source-dir是一些在包的源代碼目錄中檔案; configure在目錄中檢查這些檔案是否存在以確定該目錄是否包含源代碼。人們可能偶爾會用``--srcdir''給出錯誤的目錄;這是一種安全性檢查。詳情請參見營運configure腳本。
對於需要手工配置或者使用install程式的包來說,雖然在缺省源代碼位置在大部分情況下看起來是正確的,包還是可能需要透過調用AC_CONFIG_AUX_DIR來告訴 configure到那裡去尋找一些其他的shell腳本。
宏︰ AC_CONFIG_AUX_DIR (dir)
在目錄dir中使用``install-sh''、``config.sub''、``config.guess''和 Cygnus configure配置腳本。它們是配置中使用的輔助檔案。dir既可以是絕對路徑,也可以是相對於``srcdir''的相對路徑。缺省值是在``srcdir''或者 ``srcdir/..''或者``srcdir/../..''中首先找到``install-sh'' 的目錄。不對其他檔案進行檢查,以便使AC_PROG_INSTALL不會自動地發布其他輔助檔案。它還要檢查``install.sh'',但因為有些make程式包含了在沒有``Makefile''的情況下從``install.sh''中創建``install''的規則,所以那個名字過時了。
創建輸出檔案
每個Autoconf生成的configure腳本必須以對AC_OUTPUT的調用結尾。它是一個創建作為配置結果的``Makefile''以及其他一些可能的檔案的宏。此外唯一必須調用的宏是AC_INIT (參見尋找configure的輸入檔案)。
宏︰ AC_OUTPUT ([file... [, extra-cmds [, init-cmds]]])創建輸出檔案。
在``configure.in''的末尾調用本宏一次。參數file...是一個以空格分隔的輸出檔案的清單;它可能為空。本宏透過從一個輸入檔案(缺省情況下名為``file.in'')中複製,並替換輸出變量的值以創建每個給出的``file''。關於使用輸出變量的詳情,請參見Makefile中的替換。關於創建輸出變量的詳情,請參見設定輸出變量。如果輸出檔案所在的目錄不存在,本宏將創建該目錄(但不會創建目錄的父目錄)。通常,``Makefile''是按照這種模式創建的,但其他檔案,例如``.gdbinit'',也可以這樣創建。
如果調用了AC_CONFIG_HEADER、AC_LINK_FILES或者AC_CONFIG_SUBDIRS,本宏也將創建出現下它們的參數中的檔案。
一個典型的對AC_OUTPUT調用如下︰
AC_OUTPUT(Makefile src/Makefile man/Makefile X/Imakefile)
你可以透過在file之後添加一個用冒號分隔的輸入檔案清單以自行設定輸入檔案名。例如︰
AC_OUTPUT(Makefile:templates/top.mk lib/Makefile:templates/lib.mk)
AC_OUTPUT(Makefile:templates/vars.mk:Makefile.in:templates/rules.mk)
這樣做可以使得你的檔案名能夠被MS-DOS接受,或者可以把模板檔案(boilerplate)添加到檔案的開頭或者結尾。
如果你給出了extra-cmds,那麼這些命令將被插入到``config.status''中以便在``config.status'' 完成了其他的所有處理之後營運extra-cmds。如果給出了init-cmds,它們就被插入 extra-cmds之前,並且在configure中將對它們進行shell變量、命令和反斜線替換。你可以用 init-cmds把變量從configure中傳遞到extra-cmds。如果調用了 AC_OUTPUT_COMMANDS,在其中給出的命令將緊貼在由本宏給出的命令之前營運。
宏︰ AC_OUTPUT_COMMANDS (extra-cmds [, init-cmds])
指定在``config.status''末尾營運的附加的shell命令,以及用於初始化來自於configure 的所有變量的shell命令。本宏可以被調用多次。下面是一個不太實際的例子︰
fubar=27
AC_OUTPUT_COMMANDS([echo this is extra $fubar, and so on.], fubar=$fubar)
AC_OUTPUT_COMMANDS([echo this is another, extra, bit], [echo init bit])
如果你在次目錄中營運make,你應該透過使用make變量MAKE來營運它。 make的大部分版本把MAKE設定成make的程式名以及它所需要的任何選項。(但許多版本並沒有把在命令行中設定的變量的值包括進來,因此它們沒有被自動地傳遞。)一些老版本的 make並不設定這個變量。以下的宏使你可以在這些版本上使用它。
宏︰ AC_PROG_MAKE_SET
如果make預定義了變量MAKE,把輸出變量SET_MAKE定義為空。否則,把 SET_MAKE定義成``MAKE=make''。為SET_MAKE調用AC_SUBST。
為了使用這個宏,在每個其他的、營運MAKE的目錄中的``Makefile.in''添加一行︰
@SET_MAKE@
Makefiles中的替換
發布版本中每個包含了需要被編譯或者被安裝的檔案的目錄都應該含有一個檔案``Makefile.in'', configure將利用它在那個目錄中創建一個``Makefile''。為了創建``Makefile'',configure進行一個簡單的變量替換︰用configure 為``@variable@''選取的值,在``Makefile.in''中對它們進行替換。按照這種模式被替換到輸出檔案中的變量被稱為輸出變量。在configure中,它們是普通的shell變量。為了讓configure把特殊的變量替換到輸出檔案中,必須把那個變量的名字作為調用 AC_SUBST的參數。其他變量的任何``@variable@''都保持不變。關於使用AC_SUBST創建輸出變量的詳情,請參見設定輸出變量。
使用configure腳本的軟體應該發布檔案``Makefile.in'',而不是``Makefile'';這樣,用戶就可以在編譯它之前正確地為本地系統進行配置了。
關於應該把哪些東西放入``Makefile''的詳情,請參見GNU編碼標準中的``Makefile慣例''。
預定義輸出變量
有些輸出變量是由Autoconf宏預定義的。一部分Autoconf宏設定一些附加的輸出變量,這些變量在對這些宏的描述中被說明。關於輸出變量的完整清單,參見輸出變量索引。下面是每個預定義變量所包含的內容。關於變量名以``dir''結尾的變量,參見GNU編碼標準中的 ``為安裝目錄而提供的變量''。
變量︰ bindir
用於安裝由用戶營運的可執行檔案的目錄。
變量︰ configure_input
一個用於說明檔案是由configure自動生成的,並且給出了輸入檔案名的註釋。 AC_OUTPUT在它創建的每個``Makefile''檔案的開頭添加一個包括了這個變量的註釋行。對於其他檔案,你應該在每個輸入檔案開頭處的註釋中引用這個變量。例如,一個輸入shell腳本應該以如下行開頭︰
#! /bin/sh
# @configure_input@
這一行的存在也提醒了人們在編輯這個檔案之後需要用configure進行處理以使用它。
變量︰ datadir
用於安裝只讀的與架構無關的數據的目錄。
變量︰ exec_prefix
與架構有關的檔案的安裝前綴。
變量︰ includedir
用於安裝C頭檔案的目錄。
變量︰ infodir
用於安裝Info格式文檔的目錄。
變量︰ libdir
用於安裝目標代碼庫的目錄。
變量︰ libexecdir
用於安裝由其他程式營運的可執行檔案的目錄。
變量︰ localstatedir
用於安裝可以被修改的單機數據的目錄。
變量︰ mandir
用於安裝man格式的文檔的頂層目錄。
變量︰ oldincludedir
用於安裝由非gcc編譯器使用的C頭檔案的目錄。
變量︰ prefix
與架構無關的檔案的安裝前綴。
變量︰ sbindir
用於安裝由系統管理員營運的可執行檔案的目錄。
變量︰ sharedstatedir
用於安裝可以修改的、與架構無關的數據的目錄。
變量︰ srcdir
包含了由``Makefile''使用的源代碼的目錄。
變量︰ sysconfdir
用於安裝只讀的單機數據的目錄。
變量︰ top_srcdir
包的頂層源代碼目錄。在目錄的頂層,它與srcdir相同。
變量︰ CFLAGS
為C編譯器提供的調試和優化選項。如果在營運configure時,沒有在環境中設定它,就在你調用AC_PROG_CC的時候設定它的缺省值(如果你沒有調用AC_PROG_CC,它就為空)。 configure在編譯程式以測試C的特徵時,使用本變量。
變量︰ CPPFLAGS
為C預處理器和編譯器提供頭檔案搜索目錄選項(``-Idir'')以及其他各種選項。如果在營運 configure時,在環境中沒有設定本變量,缺省值就是空。configure在編譯或者預處理程式以測試C的特徵時,使用本變量。
變量︰ CXXFLAGS
為C++編譯器提供的調試和優化選項。如果在營運configure時,沒有在環境中設定本變量,那麼就在你調用AC_PROG_CXX時設定它的缺省值(如果你沒有調用AC_PROG_CXX,它就為空)。 configure在編譯程式以測試C++的特徵時,使用本變量。
變量︰ FFLAGS
為Fortran 77編譯器提供的調試和優化選項。如果在營運configure時,在環境中沒有設定本變量,那麼它的缺省值就在你調用AC_PROG_F77時被設定(如果你沒有調用AC_PROG_F77,它就為空)。 configure在編譯程式以測試Fortran 77的特徵時,使用本變量。
變量︰ DEFS
傳遞給C編譯器的``-D''選項。如果調用了AC_CONFIG_HEADER,configure就用 ``-DHAVE_CONFIG_H''代替``@DEFS@''(參見配置頭檔案)。在configure進行它的測試時,本變量沒有被定義,只有在創建輸出檔案時候才定義。關於如何檢查從前的測試結果,請參見設定輸出變量。
變量︰ LDFLAGS
為連接器提供的Stripping(``-s'')選項和其他各種選項。如果在營運configure時,在環境中沒有設定本變量,它的缺省值就是空。 configure在連接程式以測試C的特徵時使用本變量。
變量︰ LIBS
傳遞給連接器的``-l''和``-L''選項。
創建目錄
你可以支援從一個套裝軟件的一份源代碼拷貝中為多種架構同時進行編譯的功能。為每種架構生成的目標檔案都在它們自己的目錄中儲存。
為了支援這個功能,make用變量VPATH來尋找儲存在源代碼目錄中的檔案。 GNU make和其他大部分近來的make程式都可以這樣做。老版本的make 程式不支援VPATH;在使用它們的時候,源代碼必須與目標代碼處於同一個目錄。
為了支援VPATH,每個``Makefile.in''檔案都應該包含下列兩行︰
srcdir = @srcdir@
VPATH = @srcdir@
不要把VPATH設定成其他變量的值,比如說``VPATH = $(srcdir)'',這是因為某些版本的make並不對VPATH的值進行變量替換。
在configure生成``Makefile''的時候,它用正確的值對srcdir進行替換。
除非在隱含規則中,不要使用make變量$<,它将被展开成到源代码目录的文件的路径(通过VPATH找到的)。(诸如``.c.o''的隐含规则用于说明如何从``.c'' 文件创建``.o''文件)有些版本的make在隐含规则中不设置$<;它们被展开成空值。
``Makefile''命令行總是應該透過使用前綴``$(srcdir)/''來引用源代碼檔案。例如︰
time.info: time.texinfo
$(MAKEINFO) $(srcdir)/time.texinfo
自動地重新創建
你可以在包的頂層目錄中的``Makefile.in''檔案中添加如下的規則,以使得在你更新了配置檔案之後可以自動地更新配置訊息。這個例子包括了所有可選的檔案,例如``aclocal.m4''和那些與配置頭檔案有關的檔案。從``Makefile.in''規則中忽略所有你的所不需要的檔案。
因為VPATH機製的限制,應該包含``${srcdir}/''前綴。
在重新創建不改變``config.h.in''和``config.h''的內容的情況下,就不會改變這兩個檔案的時間標記,因此需要``stamp-''檔案。這個特徵避免了不必要的重新編譯工作。你應該把檔案``stamp-h.in'' 包含在你的包的發布中,以便make能夠把``config.h.in''看作是更新了的檔案。在一些老的BSD系統中,touch或者任何可能導致空檔案的命令不會更改時間標記,所以使用諸如echo 之類的命令。
${srcdir}/configure: configure.in aclocal.m4
cd ${srcdir} && autoconf
# autoheader might not change config.h.in, so touch a stamp file.
${srcdir}/config.h.in: stamp-h.in
${srcdir}/stamp-h.in: configure.in aclocal.m4 acconfig.h
config.h.top config.h.bot
cd ${srcdir} && autoheader
echo timestamp > ${srcdir}/stamp-h.in
config.h: stamp-h
stamp-h: config.h.in config.status
./config.status
Makefile: Makefile.in config.status
./config.status
config.status: configure
./config.status --recheck
此外,你應該把``echo timestamp > stamp-h''作為extra-cmds參數傳遞給AC_OUTPUT,以便``config.status''能夠確認``config.h''是更新了的。關於AC_OUTPUT的詳情,請參見 創建輸出檔案。
關於處理與配置相關的倚賴性問題的更多例子,請參見重新創建一個配置。
配置頭檔案
在包測試的C預處理器符號比較多的時候,用於把``-D''傳遞給編譯器的命令行就會變得很長。這導致了兩個問題。一個是透過觀察尋找make輸出中的錯誤變得困難了。更嚴重的是,命令行可能超過某些作業系統的長度限制。作為把``-D''選項傳遞給編譯器的替代辦法,configure 腳本可以創建一個包含了``#define''指令的C頭檔案。宏AC_CONFIG_HEADER 選擇了這種輸出。它應該在AC_INIT之後立即調用。
包應該在引入其他任何頭檔案之前``#include''配置頭檔案,以防止出現聲明中的不一致性(例如,配置頭檔案可能重定義了const)。使用``#include '' 並且把選項``-I.''(或者是``-I..'';或者是任何包含``config.h'' 的目錄)傳遞給C編譯器,而不是使用``#include ""config.h""''。按照這種模式,即使源代碼自行進行配置(可能是創建發布版本),其他創建目錄也可以在沒有找到``config.h''的情況下,從源代碼目錄進行配置。
宏︰ AC_CONFIG_HEADER (header-to-create ...)
使得AC_OUTPUT創建出現下以空格分隔的清單header-to-create中的檔案,以包含C預處理器#define語句,並在生成的檔案中用``-DHAVE_CONFIG_H'' ,而不是用DEFS的值,替換``@DEFS@''。常用在header-to-create 中的檔案名是``config.h''。
如果header-to-create給出的檔案已經存在並且它的內容和AC_OUTPUT將要生成的內容完全一致,這些檔案就保持不變。這樣做就使得對配置的某些修改不會導致對倚賴於頭檔案的目標檔案進行不必要的重新編譯。
通常輸入檔案被命名為``header-to-create.in'';然而,你可以透過在header-to-create 之後添加由冒號分隔的輸入檔案清單來覆蓋原輸入檔案名。例︰
AC_CONFIG_HEADER(defines.h:defines.hin)
AC_CONFIG_HEADER(defines.h:defs.pre:defines.h.in:defs.post)
這樣做使得你的檔案名能夠被MS-DOS所接受,或者可以把模板(boilerplate)添加到檔案的開頭和/或結尾。
配置頭檔案模板
你的發布版本應該包含一個如你所望的最終的頭檔案那樣的模板檔案,它包括註釋、以及#define 語句的缺省值。例如,假如你的``configure.in''進行了下列調用︰
AC_CONFIG_HEADER(conf.h)
AC_CHECK_HEADERS(unistd.h)
那麼你就應該在``conf.h.in''中包含下列代碼。在含有``unistd.h''的系統中,configure應該把0改成1。在其他系統中,這一行將保持不變。
/* Define as 1 if you have unistd.h. */
#define HAVE_UNISTD_H 0
如果你的代碼使用#ifdef而不是#if來測試配置選項,缺省值就可能是取消對一個變量的定義而不是把它定義成一個值。在含有``unistd.h''的系統中,configure將修改讀入的第二行 ``#define HAVE_UNISTD_H 1''。在其他的系統中,(在系統預定義了那個符號的情況下) configure將以註釋的模式排除這一行。
/* Define if you have unistd.h. */
#undef HAVE_UNISTD_H
用autoheader創建``config.h.in''
程式autoheader可以創建含有C的``#define''語句的模板檔案以供configure使用。如果``configure.in''調用了AC_CONFIG_HEADER(file),autoheader就創建 ``file.in'';如果給出了多檔案參數,就使用第一個檔案。否則,autoheader就創建 ``config.h.in''。
如果你為autoheader提供一個參數,它就使用給出的檔案而不是``configure.in'',並且把頭檔案輸出到標準輸出中去,而不是輸出到``config.h.in''。如果你把``-''作為參數提供給autoheader ,它就從標準輸入中,而不是從``configure.in''中讀出,並且把頭檔案輸出到標準輸出中去。
autoheader掃描``configure.in''並且找出它可能要定義的C預處理器符號。它從一個名為 ``acconfig.h''的檔案中複製註釋、#define和#undef語句,該檔案與Autoconf一同發布並且一同安裝。如果當前目錄中含有``acconfig.h''檔案,它也會使用這個檔案。如果你用AC_DEFINE 定義了任何附加的符號,你必須在創建的那個``acconfig.h''檔案中包含附加的符號。對於由 AC_CHECK_HEADERS、AC_CHECK_FUNCS、AC_CHECK_SIZEOF或者 AC_CHECK_LIB定義的符號,autoheader生成註釋和#undef語句,而不是從一個檔案中複製它們,這是因為可能的符號是無限的。
autoheader創建的檔案包含了大部分#define和#undef語句,以及相關的註釋。如果``./acconfig.h''包含了字元串``@TOP@'',autoheader就把在包含``@TOP@'' 的行之前的所有行複製到它生成的檔案的開頭。相似地,如果``./acconfig.h''包含了字元串``@BOTTOM@'', autoheader就把那一行之後的所有行複製到它生成的檔案的末尾。這兩個字元串的任何一個都可以被忽略,也可以被同時忽略。
產生相同效果的另一種辦法是在當前目錄中創建檔案``file.top''(通常是``config.h.top'')和/或檔案``file.bot''。如果它們存在,autoheader就把它們分別複製到它的輸出的開頭和末尾。不鼓勵使用它們是因為它們的檔案名含有兩個點,並因此不能在MS-DOS中儲存;它們在目錄中多創建了兩個檔案。但如果你給出選項``--localdir=dir''以使用在其他目錄中的``acconfig.h'',它們就為你提供了一種把定製的模板(boilerplate)放入各個獨立的``config.h.in''中的模式。
autoheader接受如下選項︰
--help
-h
列印對命令行選項的概述並且退出。
--localdir=dir
-l dir
在目錄dir中,而不是在當前目錄中,尋找包檔案``aclocal.m4''和``acconfig.h'' (但不包括``file.top''和``file.bot'')。
--macrodir=dir
-m dir
在目錄dir中尋找安裝的宏檔案和``acconfig.h''。你還可以把環境變量AC_MACRODIR 設定成一個目錄;本選項將覆蓋該環境變量。
--version
列印Autoconf的版本號並且退出。
在次目錄中配置其它包
在大多數情況下,調用AC_OUTPUT足以在次目錄中生成``Makefile''。然而,控制了多於一個獨立包的configure腳本可以使用AC_CONFIG_SUBDIRS來為每個次目錄中的其他包營運 configure腳本。
宏︰ AC_CONFIG_SUBDIRS (dir ...)
使得AC_OUTPUT在每個以空格分隔的清單中給出的次目錄dir中營運configure。如果沒有發現某個給出的dir,不會作為錯誤報告,所以一個configure腳本可以配置一個大的源代碼樹中出現的任何一個部分。如果在給出的dir中包含了``configure.in'',但沒有包含 configure,就使用由AC_CONFIG_AUXDIR找到的Cygnus configure腳本。
用與本configure腳本完全相同的命令行參數調用次目錄中的configure腳本,如果需要,會有較小的修改(例如,為緩沖檔案或者源代碼目錄調整相對路徑)。本宏還把輸出變量subdirs設定成目錄清單``dir...''。``Makefile''規則可以使用該變量以確定需要進入那些次目錄。這個宏可以多次調用。
缺省的前綴
在缺省狀態下,configure把它所安裝的檔案的前綴設定成``/usr/local''。 configure的用戶可以透過選項``--prefix''和``--exec-prefix''選擇一個不同的前綴。有兩種模式修改缺省的行為︰在創建configure時,和營運configure時。
有些套裝軟件在缺省情況下可能需要安裝到``/usr/local''以外的目錄中。為此,使用宏AC_PREFIX_DEFAULT。
宏︰ AC_PREFIX_DEFAULT (prefix)
把缺省的安裝前綴設定成prefix,而不是``/usr/local''。
對於用戶來說,讓configure根據它們已經安裝的相關程式的位置來猜測安裝前綴,可能會帶來方便。如果你希望這樣做,你可以調用AC_PREFIX_PROGRAM。
宏︰ AC_PREFIX_PROGRAM (program)
如果用戶沒有給出安裝前綴(使用選項``--prefix''),就按照shell的模式,在PATH中尋找 program,從而猜出一個安裝前綴。如果找到了program,就把前綴設定成包含program 的目錄的父目錄;否則,就不改變在``Makefile.in''中給定的前綴。例如,如果program是 gcc,並且PATH包括了``/usr/local/gnu/bin/gcc'',就把前綴設定為 ``/usr/local/gnu''。
configure中的版本號
以下的宏為configure腳本管理版本號。使用它們是可選的。
宏︰ AC_PREREQ (version)
確保使用的是足夠新的Autoconf版本。如果用於創建configure的Autoconf的版本比version 要早,就在標準錯誤輸出列印一條錯誤消息並不會創建configure。例如︰
AC_PREREQ(1.8)
如果你的``configure.in''倚賴於在不同Autoconf版本中改變了的、不明顯的行為,本宏就是有用的。如果它僅僅是需要近來增加的宏,那麼AC_PREREQ就不太有用,這是因為程式autoconf已經告訴了用戶那些宏沒有被找到。如果``configure.in''是由一個在提供AC_PREREQ之前的更舊的 Autoconf版本處理的,也會發生同樣的事。
宏︰ AC_REVISION (revision-info)
把刪除了任何美元符或者雙引號的修訂標記(revision stamp)複製到configure腳本中。本宏使得你的從``configure.in''傳遞到configure的修訂標記不會在你提交(check in) configure的時候被RCS或者CVS修改。你可以容易地決定一個特定的configure 對應與``configure.in''的哪個修訂版。
把本宏放在AC_INIT之前是個好主意,它可以使修訂號接近``configure.in''和configure 的開頭。為了支援你這樣做,AC_REVISION就像configure通常作的那樣,以 ``#! /bin/sh''開始它的輸出。
例如,在``configure.in''中這一行為︰
AC_REVISION($Revision: 1.30 $)dnl
在configure中產生了︰
#! /bin/sh # From configure.in Revision: 1.30
2007年2月8日 星期四
遠端桌面連線port機碼位置
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp\PortNumber
訂閱:
文章 (Atom)