$b") 宏: AC_DEFINE_UNQUOTED (variable [, value [, description]]) 類似於AC_DEFINE,但還要對variable和value進行三種shell替換(每種替換隻進行一次):變數擴展(`$'),命令替換(``'),以及反斜線傳義符(`').值中的單引號和雙引號沒有特殊的意義.在vari"/> $b") 宏: AC_DEFINE_UNQUOTED (variable [, value [, description]]) 類似於AC_DEFINE,但還要對variable和value進行三種shell替換(每種替換隻進行一次):變數擴展(`$'),命令替換(``'),以及反斜線傳義符(`').值中的單引號和雙引號沒有特殊的意義.在vari"/>
歡迎您光臨本站 註冊首頁

autoconf手冊(六)

←手機掃碼閱讀     火星人 @ 2014-03-09 , reply:0


AC_DEFINE(EQUATION, "$a > $b")
宏: AC_DEFINE_UNQUOTED (variable [, value [, description]])
類似於AC_DEFINE,但還要對variable和value進行三種shell替換(每種替換隻進行一次):變數擴展(`$'),命令替換(``'),以及反斜線傳義符(`').值中的單引號和雙引號沒有特殊的意義.在variable或者value是一個shell變數的時候用本宏代替AC_DEFINE.例如:

AC_DEFINE_UNQUOTED(config_machfile, "${machfile}")
AC_DEFINE_UNQUOTED(GETGROUPS_T, $ac_cv_type_getgroups)
AC_DEFINE_UNQUOTED(${ac_tr_hdr})

由於Bourne shell在語法上的特異性,不要用分號來分隔對AC_DEFINE或者AC_DEFINE_UNQUOTED的調用和其它的宏調用或者shell代碼;這將在最終的configure腳本中導致語法錯誤.你既可以使用空格,也可以使用換行.就是這樣:

AC_CHECK_HEADER(elf.h, AC_DEFINE(SVR4) LIBS="$LIBS -lelf")

或者:

AC_CHECK_HEADER(elf.h,
AC_DEFINE(SVR4)
LIBS="$LIBS -lelf")

而不是:

AC_CHECK_HEADER(elf.h, AC_DEFINE(SVR4); LIBS="$LIBS -lelf")

設置輸出變數
記錄測試結果的一種方式是設置輸出變數,該變數是shell變數,它的值將被替換到configure輸出的文件中.下面的兩個宏創建新的輸出變數.關於總是可用的輸出變數的列表,參見預定義輸出變數.
宏: AC_SUBST (variable)
從一個shell變數創建一個輸出變數.讓AC_OUTPUT把變數variable替換到輸出文件中(通常是一個或多個 `Makefile').這意味著AC_OUTPUT將把輸入文件中的`@variable@'實例替換成調用AC_OUTPUT時shell變數variable的值.variable的值不能包含新行.
宏: AC_SUBST_FILE (variable)
另一種從shell變數創建輸出變數的方式.讓AC_OUTPUT把由shell變數variable給出的文件名的文件的內容(不進行替換)插入到輸出文件中.這意味著AC_OUTPUT將在輸出文件中(比如`Makefile.in')把輸入文件中的`@variable@'實例替換為調用AC_OUTPUT時shell變數variable的值指明的文件的內容.如果沒有文件可以插入,就把變數設置成`/dev/null'.



本宏用於把包含特殊依賴性或者為特殊主機或目標機準備的其它make指令的`Makefile'片斷插入 `Makefile'.例如,`configure.in'可以包含:

AC_SUBST_FILE(host_frag)dnl
host_frag=$srcdir/conf/sun4.mh

那麼`Makefile.in'就應該包含:

@host_frag@

緩存結果
為了避免在各種configure腳本中重複地對相同的特徵進行檢查(或者重複地運行同一個腳本), configure把它的檢查的許多結果儲存在緩存文件.如果在configure腳本運行時,它找到了緩存文件,它就從中讀取從前運行的結果並且不再重新運行這些檢查.因此,configure將比每次都運行所有的檢查要快得多.
宏: AC_CACHE_VAL (cache-id, commands-to-set-it)
確認由cache-id指定的檢查的結果是可用的.如果檢查的結果在讀入的緩存文件中,並且configure 沒有用`--quiet'或者`--silent'調用,就列印一條消息以說明該結果已經被緩存了;否則,就運行 shell命令commands-to-set-it.這些命令不應具有副作用,但設置變數cache-id除外.它們尤其不應該調用 AC_DEFINE;緊隨與對AC_CACHE_VAL的調用之後的代碼應該根據緩存的值調用AC_DEFINE 作這件事.此外,它們不應該列印任何消息,比如說使用AC_MSG_CHECKING;應該在調用AC_CACHE_VAL 之前列印,以便不論測試的結果是從緩存中檢索而得到的,還是通過運行shell命令而確定的,都會列印消息.如果是運行 shell命令以確定值,該值將在configure創建它的輸出文件之前被儲存到緩存文件中.關於如何選擇 cache-id變數的名稱,參見緩存變數名.
宏: AC_CACHE_CHECK (message, cache-id, commands)
這是一個更詳盡地處理了列印消息的AC_CACHE_VAL版本.本宏為這些宏的最常見的應用提供了便捷的縮寫.它為message調用AC_MSG_CHECKING,而後以cache-id和commands為參數調用AC_CACHE_VAL,以cache-id為參數調用AC_MSG_RESULT.


宏: AC_CACHE_LOAD
從已經存在的緩存文件中裝入值,如果找不到緩存文件,就創建一個新的緩存文件.本宏由AC_INIT自動調用.
宏: AC_CACHE_SAVE
把所有緩存的值刷新到緩存文件中.本宏由AC_OUTPUT自動調用,但在configure.in的關鍵點調用 AC_CACHE_SAVE是十分有用的.假如配置腳本中途失敗(abort)了,這些關鍵點仍然可以緩存一部分結果.

緩存變數名
緩存變數的名字應該符合如下格式:

package-prefix_cv_value-type_specific-value[_additional-options]

例如,`ac_cv_header_stat_broken'或者`ac_cv_prog_gcc_traditional'.變數名的各個部分為:

package-prefix
你的包或者組織的縮寫;除了為了方便而使用小寫字母以外,與你使用的作為本地Autoconf宏的開頭的前綴一樣.對於由發布的Autoconf宏使用的緩存值,它是`ac'.
_cv_
表明本shell變數是一個緩存值.
value-type
關於緩存值類別的慣例,以生成一個合理的命名系統.在Autoconf中使用的值在宏名中列出.
specific-value
指明本測試應用於緩存值類的那個成員.例如,那個函數(`alloca')、程序(`gcc')或者輸出變數(`INSTALL').
additional-options
給出應用本測試的特定成員的任何特殊行為.例如,`broken'或者`set'.如果沒有用,名字的這個部分可能被忽略掉.
賦予緩存變數的值不能含有新行.通常,它們的是將是布爾(`yes'或`no')或者文件名或者函數名;,這並不是一個重要的限制.

緩存文件
緩存文件是一個緩存了在一個系統上進行配置測試的結果,以便在配置腳本和配置的運行之間共享的shell腳本.它對於其他系統來說是沒有用的.如果它的內容某些原因而變得無效了,用戶可以刪除或者編輯它.

在預設情況下,configure把`./config.cache'作為緩存文件,如果它還不存在,就創建它. configure接受選項`--cache-file=file'以使用不同的緩存文件;這就是configure在調用子目錄中的configure腳本時所作的工作.關於使用宏AC_CONFIG_SUBDIRS在子目錄中進行配置的信息,參見 在子目錄中配置其它包.



給出`--cache-file=/dev/null'會關閉緩存,這是為調試configure提供的.只有在調用`config.status'時給出選項`--recheck',這將導致它重新運行configure,它才會注意到緩存文件.如果你預計需要一個長的調試時期,你還可以通過在`configure.in'的開頭重新定義緩存宏而關閉對configure腳本的裝入和儲存:

define([AC_CACHE_LOAD], )dnl
define([AC_CACHE_SAVE], )dnl
AC_INIT(whatever)
... rest of configure.in ...

試圖為特定的系統類型發布緩存文件是錯誤的.這裡存在太多的導致錯誤的空間,並帶來太多的用於維護它們的管理開銷.對於任何不能被自動猜測出來的特徵,應使用規範系統類型和連接文件的方法(參見手工配置).

在特定系統中,每當有人運行configure腳本時,緩存文件將逐漸積累起來;緩存文件在一開始並不存在.運行configure會把新的緩存結果與現存的緩存文件結合起來.為了讓它透明地工作,只要每次都使用相同的C編譯器,站點初始化(site initialization)腳本可以指定一個站點範圍(site-wide)的緩存文件以代替預設的緩存文件.(參見設定本地預設值).

如果你的配置腳本,或者configure.in中的宏調用,偶爾導致配置過程的失敗,在幾個關鍵點進行緩存可能是有用的.在有希望修正導致上次運行的錯誤的時候,這樣做將減少重新運行configure腳本的時間.

... AC_INIT, etc. ...
dnl checks for programs
AC_PROG_CC
AC_PROG_GCC_TRADITIONAL
... more program checks ...
AC_CACHE_SAVE

dnl checks for libraries
AC_CHECK_LIB(nsl, gethostbyname)
AC_CHECK_LIB(socket, connect)
... more lib checks ...
AC_CACHE_SAVE

dnl Might abort...
AM_PATH_GTK(1.0.2, , exit 1)
AM_PATH_GTKMM(0.9.5, , exit 1)

列印消息
configure腳本需要為運行它們的用戶提供幾種信息.下列的宏為每種信息以適當的方式列印消息.所有宏的參數都應該由shell雙引號括起來,以便shell可以對它們進行變數替換和反引號替換.你可以把消息用 m4引用字元括起來以列印包含括弧的消息:



AC_MSG_RESULT([never mind, I found the BASIC compiler])

這些宏都是對shell命令echo的封裝.configure應該很少需要直接運行echo來為用戶列印消息.使用這些宏是的修改每種消息如何列印及何時列印變得容易了;這些修改只需要對宏的定義進行就行了,而所有的調用都將自動地改變.
宏: AC_MSG_CHECKING (feature-description)
告知用戶configure正在檢查特定的特徵.本宏列印一條以`checking '開頭,以`...' 結尾,不帶新行的消息.它必須跟隨一條對AC_MSG_RESULT的調用以列印檢查的結果和新行. feature-description應該是類似於 `whether the Fortran compiler accepts C comments'或者`for c89'的東西.

如果運行configure給出了選項`--quiet'或者選項`--silent',本宏什麼也不列印.

宏: AC_MSG_RESULT (result-description)
告知用戶測試的結果.result-description幾乎總是檢查的緩存變數的值,典型的值是`yes'、 `no'或者文件名.本宏應該在AC_MSG_CHECKING之後調用,並且result-description 應該完成由AC_MSG_CHECKING所列印的消息.

如果運行configure給出了選項`--quiet'或者選項`--silent',本宏什麼也不列印.

宏: AC_MSG_ERROR (error-description)
告知用戶一條使configure不能完成的錯誤.本宏在標準錯誤輸出中列印一條錯誤消息並且以非零狀態退出 configure.error-description應該是類似於`invalid value $HOME for $HOME'的東西.
宏: AC_MSG_WARN (problem-description)
告知configure的使用者可能出現的問題.本宏在標準錯誤輸出中列印消息;configure繼續向後運行,調用AC_MSG_WARN的宏應該為它們所警告的情況提供一個預設的(備份)行為. problem-description應該是類似於`ln -s seems to make hard links'的東西.

下列兩個宏是AC_MSG_CHECKING和AC_MSG_RESULT的過時的替代版本.


宏: AC_CHECKING (feature-description)
除了在feature-description之後列印新行,本宏與AC_MSG_CHECKING相同.它主要用於列印對一組特徵測試的整體目的的描述,例如:

AC_CHECKING(if stack overflow is detectable)
宏: AC_VERBOSE (result-description)
除了應該在AC_CHECKING,而不是在AC_MSG_CHECKING之後調用,本宏與AC_MSG_RESULT相同;它在列印消息前列印一個tab.它已經過時了.

編寫宏
當你編寫了一個可以用於多個軟體包的特徵測試時,最好用一個新宏把它封裝起來.下面是一些關於編寫 Autoconf宏的要求(instructions)和指導(guidelines).

宏定義
Autoconf宏是用宏AC_DEFUN定義的,該宏與m4的內置define宏相似.除了定義一個宏,AC_DEFUN把某些用於限制宏調用順序的代碼添加到其中.(參見首要的宏).

一個Autoconf宏像下面那樣定義:

AC_DEFUN(macro-name, [macro-body])

這裡的方括弧並不表示可選的文本:它們應當原樣出現在宏定義中,以避免宏擴展問題(參見引用).你可以使用`$1'、`$2'等等來訪問傳遞給宏的任何參數.

為使用m4註釋,使用m4內置的dnl;它使m4放棄本行中其後的所有文本.在調用AC_INIT之前,所有的輸出都被取消,在`acsite.m4'和`aclocal.m4'中的宏定義之間不需要它.

關於編寫m4宏的更完整的信息,參見GNU m4中的`如何定義新宏'.

宏名
所有Autoconf宏都以`AC_'起頭以防止偶然地與其它文本發生衝突.所有它們用於內部目的的shell變數幾乎全部是由小寫字母組成的,並且以`ac_'開頭的名字.為了確保你的宏不會與現在的或者將來的Autoconf宏衝突,你應該給你自己的宏名和任何它們某些原因而需要使用的shell變數添加前綴.它可能是你名字的開頭字元,或者你的組織或軟體包名稱的縮寫.



大部分Autoconf宏的名字服從一個表明特徵檢查的種類命名慣例.宏名由幾個單片語成,由下劃線分隔,可以是最常見的,也可以是最特殊的.它們的緩存變數名服從相同的慣例.(關於它們的詳細信息,參見緩存變數名).

`AC_'之後的第一個單詞通常給出被測試特徵的類別.下面是Autoconf為特殊測試宏使用的類別,它們是你很可能要編寫的宏.它們的全小寫形式還用於緩存變數.在可能的地方使用它們;如果不能,就發明一個你自己的類別.

C
C語言內置特徵.
DECL
在頭文件中對C變數的聲明.
FUNC
庫中的函數.
GROUP
文件的UNIX組擁有者(group owner).
HEADER
頭文件.
LIB
C庫.
PATH
包括程序在內的,到文件的全路徑名.
PROG
程序的基本名(base name).
STRUCT
頭文件中對C結構的定義.
SYS
操作系統特徵.
TYPE
C內置或者聲明類型.
VAR
庫中的C變數.
在類別之後就是特定的被測試特徵的名稱.宏名中所有的其它單詞指明了特徵的特殊方面.例如,AC_FUNC_UTIME_NULL檢查用NULL指針調用utime函數時該函數的行為.

一個作為另一個宏的內部子程序的宏的名字應該以使用它的宏的名字開頭,而後是說明內部宏作了什麼的一個或多個單詞.例如,AC_PATH_X有內部宏AC_PATH_X_XMKMF和AC_PATH_X_DIRECT.

引用
由其他的宏調用的宏將被m4進行幾次求值;每次求值都可能需要一層引號以防止對宏或者m4 內置宏的不必要擴展,例如說`define'和`$1'.引號還需要出現在含有逗號的宏參數中,這是逗號把參數與參數分隔開來.還有,把所有含有新行和調用其它宏的宏參數引起來是一個好主意.

Autoconf把m4的引用字元從預設的``'和`''改為`['和`]',這是許多宏使用``'和`'',這不方便.然而,在少數情況下,宏需要使用方括弧(通常在C程序文本或者常規表達式中).在這些情況下,它們使用m4內置命令changequote暫時地把引用字元改為 `

<<'和`>>'.(有時,如果它們不需要引用任何東西,它們就通過把引用字元設置成空字元串以完全關閉引用.)下面是一個例子:

AC_TRY_LINK(
changequote(<<, >>)dnl
<<#include
#ifndef tzname /* For SGI.*/
extern char *tzname[]; /* RS6000 and others reject char **tzname.*/
#endif>>,
changequote([, ])dnl
[atoi(*tzname);], ac_cv_var_tzname=yes, ac_cv_var_tzname=no)

當你用新編寫的宏創建configure腳本時,仔細地驗證它以檢查你是否需要在你的宏之中添加更多的引號.如果一個或多個單詞在m4的輸出中消失了,你就需要更多的引號.當你不能確定的時候,就使用引號.

但是,還有放置了過多層的引號的可能.如果這發生了,configure腳本的結果將包含未擴展的宏.程序autoconf通過執行`grep AC_ configure'來檢查這個問題.

宏之間的依賴性
為了正確地工作,有些Autoconf宏要求在調用它們之前調用其它的宏.Autoconf提供了一種方式以確保在需要時,某個宏已經被調用過了,以及一種在宏可能導致不正確的操作時給出警告的方式.

首要的宏
你編寫的宏可能需要使用從前有其它宏計算出來的結果.例如,AC_DECL_YYTEXT要檢驗flex或 lex的輸出,它要求調用AC_PROG_LEX以設置shell變數LEX.

比強制宏的用戶跟蹤宏以前的依賴性更好的是,你可以使用宏AC_REQUIRE以自動地完成這一任務. AC_REQUIRE可以確保只在需要的時候調用宏,並且只被調用一次.
宏: AC_REQUIRE (macro-name)
如果還沒有調用m4宏macro-name,就調用它(不帶任何參數).確保macro-name 用方括弧引起來了.macro-name必須已經用AC_DEFUN定義了,或者包含一個對AC_PROVIDE 的調用以指明它已經被調用了.

一個替代AC_DEFUN的方法是使用define並且調用AC_PROVIDE.這個技術並不防止出現嵌套的消息,它已經是過時的了.


宏: AC_PROVIDE (this-macro-name)
記錄this-macro-name已經被調用了的事實.this-macro-name應該是調用AC_PROVIDE的宏的名字.一個獲取它的簡單方式是從m4內置變數$0中獲得,就像:

AC_PROVIDE([$0])

建議的順序
有些宏在都被調用的時候,一個宏就需要在另一個宏之前運行,但是它們並不要求調用另一個宏.例如,應該在任何運行C編譯器的宏之前調用修改了C編譯器行為的宏.在文檔中給出了許多這樣的依賴性.

當`configure.in'文件中的宏違背了這類依賴性,Autoconf就提供宏AC_BEFORE以警告用戶.警告出現在從`configure.in'創建configure的時候,而不是在運行configure的時候.例如,AC_PROG_CPP檢查C編譯器是否可以在給出`-E'的情況下運行C預處理器.因而應該在任何改變將要使用的C編譯器的宏之後調用它 .AC_PROG_CC包含:

AC_BEFORE([$0], [AC_PROG_CPP])dnl

如果在調用AC_PROG_CC時,已經調用了AC_PROG_CPP,它就警告用戶.
宏: AC_BEFORE (this-macro-name, called-macro-name)
如果已經調用了called-macro-name,就讓m4在標準錯誤輸出上列印一條警告消息. this-macro-name應該是調用AC_BEFORE的宏的名字.macro-name必須已經用 AC_DEFUN定義了,或者包含一個對AC_PROVIDE的調用以指明它已經被調用了.

過時的宏
配置和移植技術已經演化了好些年了.對於特定的問題,通常已經提出了更好的解決辦法,或者同類的方法(ad-hoc approaches)已經被系統化了.結果就是有些宏現在已經被認為是過時了;它們仍然能工作,但不再被認為是最佳選擇. Autoconf提供了宏AC_OBSOLETE,當用戶使用過時的宏時,就在生成configure腳本的時候對用戶提出警告,以鼓勵他們跟上潮流.一個調用實例是:

AC_OBSOLETE([$0], [; use AC_CHECK_HEADERS(unistd.h) instead])dnl


宏: AC_OBSOLETE (this-macro-name [, suggestion])
讓m4在標準錯誤輸出上列印一條消息以警告this-macro-name是過時的,並且給出調用過時的宏的文件名和行號.this-macro-name應該是調用AC_OBSOLETE的宏的名字.如果給出了suggestion,就在警告消息的末尾列印它;例如,它可以建議用某個宏來代替 this-macro-name.

手工配置
有幾種特徵不能通過運行測試程序而自動猜測出來.例如,目標文件格式的細節,或者需要傳遞給編譯器或連接器的特殊選項.你可以使用同類手段(ad-hoc means)來檢查這類特徵,比如說讓configure檢查uname程序的輸出,或者尋找僅僅在特定系統中出現的庫.然而,Autoconf為處理不可猜測的特徵提供了統一的手段.

指定系統的類型
類似與其它GNU configure腳本,Autoconf生成的configure腳本可以根據系統類型的規範名 (canonical name)做出決定,該規範系統名的形式為:

cpu-company-system

configure通常可以猜測出它正在運行的系統類型的規範名.為此,它運行一個稱為config.guess 的腳本,該腳本使用uname或者預定義的C預處理器符號來推斷系統類型的規範名.

另外,用戶可以通過給configure傳遞命令行參數而指定系統類型.在交叉編譯時必須這樣作.在大多數交叉編譯的複雜情況下,要涉及到三種系統類型.用於指定它們的選項是:

--build=build-type
對包進行配置和編譯的系統類型(很少用到);
--host=host-type
包將運行的系統類型;
--target=target-type
包中任何編譯器工具將生成的代碼的系統類型.
如果用戶給configure一個非選項參數,如果用戶沒有顯式地用選項指明,它就作為預設情況表示主機類型、目標類型和創建系統類型.如果給出了主機類型而沒有給出目標類型和創建類型,目標類型和創建類型就被設置為主機類型.如果你正在交叉編譯,你仍然必須在configure的命令行中給出你使用的交叉工具(cross-tools)的名稱,特別是C編譯器.例如,



CC=m68k-coff-gcc configure --target=m68k-coff

configure能夠識別許多系統類型的短別名;例如,可以在命令行中給出`decstation'而不是 `mips-dec-ultrix4.2'.configure運行一個被稱為config.sub的腳本以使系統類型別名規範化.



[火星人 ] autoconf手冊(六)已經有832次圍觀

http://coctec.com/docs/linux/show-post-57640.html