青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

GNU Automake

Posted on 2008-06-27 09:43 T.S Liu 閱讀(1546) 評論(0)  編輯 收藏 引用 所屬分類: makefile

Automake是一個從文件`Makefile.am'自動生成`Makefile.in' 的工具。每個`Makefile.am'基本上是一系列make的宏定義(make規則也會偶爾出現)。生成的`Makefile.in's服從GNU Makefile標準。

GNU Makefile標準文檔(參見GNU編碼標準中的‘Makefile慣例’節)長、復雜,而且會發生改變。Automake的目的就是解除個人GNU維護者維護Makefile的負擔(并且讓Automake的維護者來承擔這個負擔)。

典型的Automake輸入文件是一系列簡單的宏定義。處理所有這樣的文件以創建 `Makefile.in'。在一個項目(project)的每個目錄中通常包含一個 `Makefile.am'

Automake在幾個方面對一個項目做了限制;例如它假定項目使用Autoconf (參見Autoconf手冊),并且對`configure.in'的內容施加了某些限制。

為生成`Makefile.in',Automake需要perl。但是由Automake創建的發布完全服從GNU標準,并且在創建中不需要perl

請把關于Automake的建議和bug發送到 automake-bugs@gnu.org

通用性概念

一些基本概念將有助于理解Automake是如何工作的。

通用操作

Automake讀入`Makefile.am'并且生成`Makefile.in'。在`Makefile.am'中定義的一些宏和目標(targets)指揮automake生成更多特定的代碼;例如一個`bin_PROGRAMS'宏定義將生成一個需要被編譯、連接的目標。

`Makefile.am'中的宏定義和目標被復制到生成的文件中。這使得你可以把任何代碼添加到生成的`Makefile.in'文件中。例如,Automake的發布包含了非標準的cvs-dist目標,Automake的維護者用它從他的版本控制系統中創建發布版本。

Automake不能識別GNU對make的擴展。在`Makefile.am'中使用這些擴展將導致錯誤或者令人不解的行為。

Automake試圖明智地把注釋和相鄰的目標(或者變量定義)關聯起來。

`Makefile.am'中定義的目標通常覆蓋了所有由automake 自動生成的擁有相似名字的目標。雖然Automake提供了這一功能,但最好避免使用它,因為有些時候生成的規則將是十分特別的。

類似地,在`Makefile.am'中定義的變量將覆蓋任何通常由automake 創建的變量定義。該功能比覆蓋目標定義的功能要常用得多。需要警告的是許多由 automake生成的變量都被認為是內部使用的,并且它們的名字可能在未來的版本中改變。

在檢驗變量定義的時候,Automake將遞歸地檢驗定義中的變量引用。例如,如果Automake 在如下片斷中搜索`foo_SOURCES'的內容。

xs = a.c b.c
foo_SOURCES = c.c $(xs)

它將把文件`a.c'`b.c'`c.c'作為`foo_SOURCES' 的內容。

Automake還允許給出被復制到輸出中的注釋;所有以`##'開頭的行將被Automake徹底忽略。

作為慣例,`Makefile.am'的第一行是:

## Process this file with automake to produce Makefile.in

深度

automake支持三種目錄層次: “flat”、“shallow”和“deep”。

一個flat(平)包指的是所有文件都在一個目錄中的包。為這類包提供的`Makefile.am' 缺少宏SUBDIRS。這類包的一個例子是termutils

一個deep(深)包指的是所有的源代碼都被儲存在子目錄中的包;頂層目錄主要包含配置信息。GNU cpio 是這類包的一個很好的例子,GNU tar也是。deep包的頂層`Makefile.am'將包括宏SUBDIRS,但沒有其它定義需要創建的對象的宏。

一個shallow(淺)包指的是主要的源代碼儲存在頂層目錄中,而各個部分(典型的是庫)則儲存在子目錄中的包。Automake本身就是這類包(GNU make也是如此,它現在已經不使用automake)。

嚴格性

Automake的目的是用于維護GNU包,它為適應那些希望使用它的人做出了一些努力,但并不指望應用所有的GNU慣例。

按照這個目標,Automake支持三級嚴格性---嚴格性指的是Automake 將如何檢查包所服從的標準。

可用的嚴格性級別有:

`foreign'(外來)
Automake將僅僅檢查那些為保證正確操作所必需的事項。例如,盡管GNU標準指出文件`NEWS'必須存在,在本方式下,并不需要它。該模式名來自于Automake 是被設計成用于GNU程序的事實的;它放松了標準模式的操作規則。
`gnu'
Automake將盡可能地檢查包是否服從GNU標準。這是缺省設置。
`gnits'
Automake將按照還沒有完成的Gnits標準進行檢查。它們是基于GNU標準的,但更加詳盡。除非你是Gnits標準的參與奉獻者,我們建議您在Gnits標準正式出版之前不要使用這一選項。

關于嚴格性級別的精確含義的詳細說明,參見--gnu--gnits的效果

統一命名機制

Automake變量通常服從統一的命名機制,以易于確定如何創建和安裝程序(和其它派生對象)。這個機制還支持在運行configure的時候確定應該創建那些對象。

在運行make時,某些變量被用于確定應該創建那些對象。這些變量被稱為主(primary)變量。例如,主變量PROGRAMS 保存了需要被編譯和連接的程序的列表。

另一組變量用于確定應該把創建了的對象安裝在哪里。這些變量在主變量之后命名,但是含有一個前綴以指出那個標準目錄將作為安裝目錄。標準目錄名在GNU標準中給出(參見GNU編碼標準中的`為Directory Variables'節)。 Automake用pkglibdirpkgincludedirpkgdatadir擴展了這個列表;除了把`@PACKAGE@'附加其后之外,與非`pkg'版本是相同的。例如,pkglibdir被定義為$(datadir)/@PACKAGE@.

對于每個主變量,還有一個附加的變量,它的名字是在主變量名之前加一個`EXTRA_'。該變量用于儲存根據configure的運行結果,可能創建、也可能不創建的對象列表。引入該變量是因為Automake必須靜態地知道需要創建的對象的完整列表以創建在所有情況下都能夠工作的`Makefile.in'

例如,在配置時刻cpio確定創建哪些程序。一部分程序被安裝在bindir,還有一部分程序被安裝在sbindir

EXTRA_PROGRAMS = mt rmt
bin_PROGRAMS = cpio pax
sbin_PROGRAMS = @PROGRAMS@

定義沒有前綴的主變量(比如說PROGRAMS)是錯誤的。

在構造變量名的時候,通常省略后綴`dir';因此我們使用 `bin_PROGRAMS'而不是`bindir_PROGRAMS'.

不是每種對象都可以安裝在任何目錄中。Automake將記錄它們以試圖找出錯誤。Automake還將診斷目錄名中明顯的拼寫錯誤。

有時標準目錄--即使在Automake擴展之后---是不夠的。特別在有些時候,為了清晰起見,把對象安裝到預定義目錄的子目錄中是十分有用的。為此,Automake允許你擴展可能的安裝目錄列表。如果定義了一個添加了后綴`dir'的變量(比如說`zardir'),則給定的前綴(比如`zar')就是合法的。

例如,在HTML支持成為Automake的一部分之前,你可以使用它安裝原始的HTML文檔。

htmldir = $(prefix)/html
html_DATA = automake.html

特殊前綴`noinst'表示根本不會安裝這些有問題的對象。

特殊前綴`check'表示僅僅在運行make check 命令的時候才創建這些有問題的對象。

可能的主變量名有`PROGRAMS'`LIBRARIES'`LISP'`SCRIPTS'`DATA'`HEADERS'`MANS'`TEXINFOS'

派生變量是如何命名的

有時Makefile變量名是從用戶提供的某些文本中派生而來的。例如程序名被重寫到Makefile宏名中。Automake把這些文本規范化,以使它可以不必服從Makefile的變量名規則。在名字中除了字母、數字和下劃線之外的所有字符都將用下劃線代替。例如,如果你的程序被命名為sniff-glue,那么派生出的變量名將是sniff_glue_SOURCES,而不是sniff-glue_SOURCES

一些實例軟件包

一個簡單的例子,從起點到終點

讓我們假定你剛剛寫完zardoz,一個是你的頭從一個漩渦漂流到另一個漩渦的程序。你已經使用了autoconf以提供一個可移植的框架,但你的`Makefile.in'還未完成,所以你需要automake

第一步是更新你的`configure.in'以包含automake需要的命令。完成這一步的最簡單方式是在AC_INIT之后添加AM_INIT_AUTOMAKE

AM_INIT_AUTOMAKE(zardoz, 1.0)

因為你的程序不含有任何復雜性的因素(例如,它不使用gettext,它不需要共享庫),你已經完成了這一步工作。很容易吧!

現在你必須重新生成`configure'。但為此,你需要告訴autoconf 如何找到你使用的新宏。完成該任務的最簡單的方式是使用aclocal程序為你生成你的`aclocal.m4'。但是等等...你已經有了一個`aclocal.m4',這是因為你必須為你的程序寫一些宏。aclocal允許你把你自己的宏放到 `acinclude.m4'中去,所以簡單地改名并且運行:

mv aclocal.m4 acinclude.m4
aclocal
autoconf

現在是你為zardoz寫的`Makefile.am'的時候了。 zardoz是一個用戶程序,所以你需要把它安裝到其它用戶程序安裝的地方去。 zardoz還有一些Texinfo文檔。你的`configure.in'腳本使用 AC_REPLACE_FUNCS,因此你需要與`@LIBOBJS@'連接。所以這里你寫:

bin_PROGRAMS = zardoz
zardoz_SOURCES = main.c head.c float.c vortex9.c gun.c
zardoz_LDADD = @LIBOBJS@
info_TEXINFOS = zardoz.texi

現在你運行automake --add-missing以生成你的`Makefile.in' 并且得到任何你可能需要的附加文件,現在你完成了你的任務!

一個經典的程序

hello因為它經典的簡單性和多用性而出名。本節展示Automake將被如何用于Hello包。下面的例子來自于最新的GNU Hello,但剔除了所有僅為維護者使用的代碼和所有的版權注釋。

當然,GNU Hello比您的傳統的兩行的代碼具有更多的特征。GNU Hello是國際化的,進行選項處理,并且含有一個手冊和一個測試套件。GNU Hello是一個deep包。

這里是來自于GNU Hello的`configure.in'

dnl Process this file with autoconf to produce a configure script.
AC_INIT(src/hello.c)
AM_INIT_AUTOMAKE(hello, 1.3.11)
AM_CONFIG_HEADER(config.h)
dnl Set of available languages.
ALL_LINGUAS="de fr es ko nl no pl pt sl sv"
dnl Checks for programs.
AC_PROG_CC
AC_ISC_POSIX
dnl Checks for libraries.
dnl Checks for header files.
AC_STDC_HEADERS
AC_HAVE_HEADERS(string.h fcntl.h sys/file.h sys/param.h)
dnl Checks for library functions.
AC_FUNC_ALLOCA
dnl Check for st_blksize in struct stat
AC_ST_BLKSIZE
dnl internationalization macros
AM_GNU_GETTEXT
AC_OUTPUT([Makefile doc/Makefile intl/Makefile po/Makefile.in \
src/Makefile tests/Makefile tests/hello],
[chmod +x tests/hello])

`AM_'由Automake(或者Gettext庫)提供;其它的是標準Autoconf宏。

頂層`Makefile.am'

EXTRA_DIST = BUGS ChangeLog.O
SUBDIRS = doc intl po src tests

就像你所見到的,這里的所有工作實際上都是在子目錄中完成的。

`po'`intl'目錄是gettextize自動生成的;在這里我們不討論它們。

在`doc/Makefile.am'中我們看到:

info_TEXINFOS = hello.texi
hello_TEXINFOS = gpl.texi

它足以創建、安裝并且發布Hello手冊。

這里是`tests/Makefile.am':

TESTS = hello
EXTRA_DIST = hello.in testdata

腳本`hello'是由configure生成的,并且僅僅在測試時才生成。 make check將運行這個測試。

最后我們有`src/Makefile.am',所有實際工作在此完成:

bin_PROGRAMS = hello
hello_SOURCES = hello.c version.c getopt.c getopt1.c getopt.h system.h
hello_LDADD = @INTLLIBS@ @ALLOCA@
localedir = $(datadir)/locale
INCLUDES = -I../intl -DLOCALEDIR=\"$(localedir)\"

創建etags和ctags

這里是另一個復雜一些的例子。它展示了如何從同一個源文件(`etags.c')生成兩個程序(ctagsetags)。困難的部分是對 `etags.c'的每個編譯需要不同的cpp選項。

bin_PROGRAMS = etags ctags
ctags_SOURCES =
ctags_LDADD = ctags.o
etags.o: etags.c
$(COMPILE) -DETAGS_REGEXPS -c etags.c
ctags.o: etags.c
$(COMPILE) -DCTAGS -o ctags.o -c etags.c

其中ctags_SOURCES被定義為空--這種方式表明沒有替換隱含的值然而,隱含的值被用于從`etags.o'生成etags

ctags_LDADD用于把`ctags.o'添加到連接行中。 ctags_DEPENDENCIES由Automake生成。

如果你的編譯器不接受`-c'`-o',那么上述規則將不能工作。對此,最簡單的修正是引入偽依賴(bogus dependency)(以避免由并行 make所導致的問題):

etags.o: etags.c ctags.o
$(COMPILE) -DETAGS_REGEXPS -c etags.c
ctags.o: etags.c
$(COMPILE) -DCTAGS -c etags.c && mv etags.o ctags.o

同樣,如果使用了de-ANSI-fication的特征,這些顯式規則將不能工作;支持它需要一些更多的工作:

etags._o: etags._c ctags.o
$(COMPILE) -DETAGS_REGEXPS -c etags.c
ctags._o: etags._c
$(COMPILE) -DCTAGS -c etags.c && mv etags._o ctags.o

創建`Makefile.in'

為了為一個包創建所有的`Makefile.in',在頂層目錄不帶任何參數地運行automakeautomake將自動地尋找每個合適的`Makefile.am'(通過掃描 `configure.in';參見掃描`configure.in')并生成相應的`Makefile.in'automake認為包的組成是相當簡單的;它假定包僅僅在頂層目錄含有一個`configure.in'。如果你的包含有多個 `configure.in',那么你必須在每個含有`configure.in'的目錄中運行automake

你偶爾可能需要給automake參數;`.am'被添加到參數之后并且其結果將作為輸入文件名。該特征通常僅僅用于自動重新創建一個過時的 `Makefile.in'automake必須總是在項目的最頂層目錄中運行,即使用于重新生成某些子目錄中的`Makefile.in'也是如此。這是因為automake必須掃描`configure.in',并且因為在某些情況下,automake根據`Makefile.in'在子目錄中這一情況確定它的行為。

automake接受以下選項:

-a
--add-missing
Automake要求一些通用文件在特定的位置存在。例如如果`configure.in'運行了AC_CANONICAL_HOST,就需要`config.guess'。 Automake與幾個這樣的文件一同發布;只要可能,該選項將把缺少的文件自動添加到包中。通常如果Automake告訴你缺少文件,試一下本選項。
--amdir=dir
dir中而不是安裝目錄中,尋找Automake數據文件,它通常用于調試。
--build-dir=dir
告訴Automake創建目錄在那里。本選項在把依賴性添加到由make dist生成的 `Makefile.in'中的時候使用;在其它情況下不應該使用它。
--cygnus
按照Cygnus規則,而不是GNU或者Gnits規則,生成`Makefile.in',詳情請參見--cygnus的效果
--foreign
把全局嚴格性設置成`foreign'。詳情請參見嚴格性
--gnits
把全局嚴格性設置成`gnits'。詳情請參見 --gnu--gnits的效果
--gnu
把全局嚴格性設置成`gnu'。詳情請參見 --gnu--gnits的效果。這是缺省嚴格性。
--help
打印命令行選項的概述并且退出。
-i
--include-deps
包含生成的`Makefile.in'中所有自動生成的依賴信息(參見自動的依賴性跟蹤)。通常在制作發布版本時使用;參見需要發布哪些文件
--generate-deps
生成一個連接了所有自動生成的依賴信息的文件(參見 自動的依賴性跟蹤)文件,`.dep_segment'。通常在制作發布版本時使用;參見需要發布哪些文件。在維護為其它平臺所制作的`SMakefile'或者makefile(`Makefile.DOS',等等,)時是有用的。它只能與--include-deps--srcdir-name--build-dir一同使用。如果給出了本選項,不會實行任何其他處理。
--no-force
通常automake創建在`configure.in'中提到的所有 `Makefile.in'。本選項僅僅更新那些按照它們的依賴性過時了的 `Makefile.in'
-o dir
--output-dir=dir
把生成的`Makefile.in'放到目錄dir中。通常每個`Makefile.in'在對應的`Makefile.am'所在的目錄中創建。本選項被用于創建發布版本。
--srcdir-name=dir
告訴Automake與當前任務相關的源代碼目錄名。本選項在把依賴性引入由make dist生成的`Makefile.in'中時使用;它不應被用于其它情況。
-v
--verbose
讓Automake打印關于被讀入或創建的文件的信息。
--version
打印Automake的版本號并且退出。

掃描`configure.in'

Automake掃描包的`configure.in'以確定關于包的一些信息。 Automake需要一些autoconf宏并且一些變量必須在 `configure.in'中定義。Automake還用來自`configure.in' 的信息以進一步修整它的輸出。

為了簡化維護,Automake還支持一些autoconf宏。通過使用程序aclocal,可以自動地把這些宏附加到你的`aclocal.m4'中。

配置需求

達到Automake要求的最簡單方式就是使用宏AM_INIT_AUTOMAKE (參見由Automake支持的Autoconf宏)。但是如果你愿意,你可以手工完成所需的各個步驟:

  • AC_SUBST定義變量PACKAGEVERSIONPACKAGE應該是在捆綁發布的時候使用的包的名稱。例如,Automake把PACKAGE定義成`automake'VERSION應該是被開發的版本的版本號。我們建議你僅僅在你的包中定義版本號的地方創建`configure.in';這使得發布簡單化了。 除非在`Gnits'模式(參見 --gnu--gnits的效果),Automake 不會對PACKAGE或者VERSION進行任何解釋。
  • 如果要安裝一個程序或者一個腳本,使用宏AC_ARG_PROGRAM
  • 如果包不是平(flat)的,使用宏AC_PROG_MAKE_SET
  • 使用宏AM_SANITY_CHECK以確認創建環境的完整性。
  • 如果包安裝了任何腳本(參見可執行的腳本),使用宏AM_PROG_INSTALL。否則,使用AC_PROG_INSTALL
  • 使用AM_MISSING_PROG以確認在創建環境中,程序aclocalautoconfautomakeautoheadermakeinfo是否存在。下面是如何完成這個任務:
    missing_dir=`cd $ac_aux_dir && pwd`
        AM_MISSING_PROG(ACLOCAL, aclocal, $missing_dir)
        AM_MISSING_PROG(AUTOCONF, autoconf, $missing_dir)
        AM_MISSING_PROG(AUTOMAKE, automake, $missing_dir)
        AM_MISSING_PROG(AUTOHEADER, autoheader, $missing_dir)
        AM_MISSING_PROG(MAKEINFO, makeinfo, $missing_dir)
        

這里是Automake需要的,但是沒有被AM_INIT_AUTOMAKE運行的其它宏:

AC_OUTPUT
Automake用它確定創建那個文件。列出的名為Makefile的文件作為`Makefile'處理。對其它列出的文件進行不同的處理。目前唯一的不同是`Makefile'將被make distclean 刪除,而其它的文件將被make clean刪除。

Automake能夠識別的其它事情

Automake還將能夠識別某些宏的使用并且適當地修整生成的`Makefile.in'。目前能夠識別的宏以及它們的效果是:

AC_CONFIG_HEADER
Automake要求使用AM_CONFIG_HEADER,它類似于AC_CONFIG_HEADER 而且完成一些有用的Automake特定的工作。
AC_CONFIG_AUX_DIR
Automake將在調用本宏時命名的目錄中尋找各種求助腳本,例如`mkinstalldirs'。如果沒找到,將在其它標準的位置(頂層目錄中,或者在對應與當前`Makefile.am' 的源代碼目錄,任何一個都是合適的)中尋找腳本。 請幫助我:以給出尋找該目錄的完整列表。
AC_PATH_XTRA
Automake將把由AC_PATH_XTRA定義的變量的定義插入每個創建C程序或者庫的`Makefile.in'中。
AC_CANONICAL_HOST
AC_CHECK_TOOL
Automake將確認`config.guess'`config.sub'的存在。并且將引入`Makefile'變量`host_alias'`host_triplet'
AC_CANONICAL_SYSTEM
它類似于AC_CANONICAL_HOST,此外還定義了`Makefile' 變量`build_alias'`target_alias'
AC_FUNC_ALLOCA
AC_FUNC_GETLOADAVG
AC_FUNC_MEMCMP
AC_STRUCT_ST_BLOCKS
AC_FUNC_FNMATCH
AM_FUNC_STRTOD
AC_REPLACE_FUNCS
AC_REPLACE_GNU_GETOPT
AM_WITH_REGEX
Automake將確認為對應于這些宏的對象生成了適當的依賴關系。此外,Automake將驗證適當的源文件成為發布的一部分。使用這些宏,Automake并不需要任何C源代碼,所以automake -a 將不會安裝源代碼。詳情請參見創建一個庫
LIBOBJS
Automake將檢測把`.o'文件添加到LIBOBJS中的語句,并且按照與在AC_REPLACE_FUNCS中發現的文件相同的方式處理這些附加的文件。
AC_PROG_RANLIB
如果在包中創建了任何庫,就需要它。
AC_PROG_CXX
如果包含了任何C++源代碼,就需要它。
AM_PROG_LIBTOOL
Automake將啟動為libtool所做的處理(參見Libtool手冊)。
AC_PROG_YACC
如果找到了Yacc源文件,那么你必須使用這個宏或者在`configure.in' 中定義變量`YACC'。前者更好一些。
AC_DECL_YYTEXT
如果在包中有Lex源代碼,需要使用這個宏。
AC_PROG_LEX
如果找到了Lex源代碼,那么必須使用本宏。
ALL_LINGUAS
如果Automake發現在`configure.in'中設置了該變量,它將檢查目錄`po'以確認所有命名了的`.po' 文件都是存在的,并且所有存在的`.po'文件都被命了名。
AM_C_PROTOTYPES
在使用自動de-ANSI-fication時,需要它。參見自動de-ANSI-fication
AM_GNU_GETTEXT
使用了GNU gettext的包需要使用本宏。(參見Gettext)。它將與gettext一起發布。如果Automake看到這個宏,Automake將確認包是否符合gettext的某些要求。
AM_MAINTAINER_MODE
該宏為configure添加一個`--enable-maintainer-mode' 選項。如果使用了本宏,automake將關閉在生成的 `Makefile.in'中缺省的“maintainer-only”規則。在`Gnits'模式中,不允許使用本宏。(參見--gnu--gnits的效果)。
AC_SUBST
AC_CHECK_TOOL
AC_CHECK_PROG
AC_CHECK_PROGS
AC_PATH_PROG
AC_PATH_PROGS
上述任意一個宏的第一個參數將在每個生成的`Makefile.in' 中自動地被定義為一個變量。

自動生成aclocal.m4

Automake包含了許多可以你的包中使用的的Autoconf宏;其中一些實際上是 Automake在某些情況下需要的。你必須在你的`aclocal.m4'中定義這些宏;否則autoconf將不能找到它們。

程序aclocal將基于`configure.in'的內容自動生成文件 `aclocal.m4'。它提供了一個不必四處尋找而獲得Automake提供的宏的便利方式。此外,aclocal機制對使用它的其它包來說,是可以擴展的。

在啟動時,aclocal掃描所有它能夠找到的`.m4'文件,以尋找宏定義。而后它掃描`configure.in'。任何在第一步中提到的宏,以及它所需要的宏,將被放到`aclocal.m4'中。

如果`acinclude.m4'存在,它的內容將被自動包含在 `aclocal.m4'中。這對于把本地宏合并到`configure'是有用的。

aclocal接受如下選項:

--acdir=dir
在目錄dir中,而不是在安裝目錄中,尋找宏文件。這通常用于調試。
--help
打印命令行選項的概述并且退出。
-I dir
把目錄dir添加到搜索`.m4'的目錄列表中。
--output=file
把輸出儲存到文件file中,而不是`aclocal.m4'中。
--print-ac-dir
打印aclocal將搜索`m4'文件的目錄名。當給出本選項的時候,不實施通常的處理。包可以用本選項確定應該把宏文件安裝到哪里。
--verbose
打印它所檢測的文件名。
--version
打印Automake的版本號并且退出。

由Automake支持的Autoconf宏

AM_CONFIG_HEADER
Automake將生成規則以自動地重新生成config頭文件。如果你使用本宏,你必須在你的源代碼目錄中創建文件`stamp-h.in'。它可以為空。
AM_CYGWIN32
檢查本configure是否是在`Cygwin32'環境中運行。(FIXME xref)。如果是,把輸出變量EXEEXT定義為 `.exe';否則,把它定義為空字符串。Automake識別該宏并且用它生成在`Cygwin32'中可以自動工作的`Makefile.in'。在`Cygwin32'環境中,即使在命令行中沒有明確指出,gcc 將生成文件名以`.exe'結尾的可執行文件。Automake向 `Makefile.in'添加特定的代碼以適當地處理它。
AM_FUNC_STRTOD
如果不能使用函數strtod,或者不能正確地工作(例如在SunOS 5.4上),就把`strtod.o'添加到輸出變量LIBOBJS中。
AM_FUNC_ERROR_AT_LINE
如果沒有找到error_at_line函數,就把`error.o'添加到LIBOBJS中。
AM_FUNC_MKTIME
檢查函數mktime。如果沒有找到,就把`mktime.o'添加到`LIBOBJS'中。
AM_FUNC_OBSTACK
檢查GNU obstacks代碼;如果沒有找到,就把`obstack.o'添加到`LIBOBJS'中。
AM_C_PROTOTYPES
檢查編譯器是否可以識別函數原型。如果可以識別,就定義`PROTOTYPES' 并且把輸出變量`U'`ANSI2KNR'設置為空。否則,把`U'設置成`_',并且把`ANSI2KNR' 設置成`./ansi2knr'。Automake使用這些值以實現自動de-ANSI-fication。
AM_HEADER_TIOCGWINSZ_NEEDS_SYS_IOCTL
如果使用TIOCGWINSZ需要`<sys/ioctl.h>',那么定義GWINSZ_IN_SYS_IOCTL。否則,TIOCGWINSZ 可以在`<termios.h>'中發現。
AM_INIT_AUTOMAKE
運行大部分`configure.in'需要的多個宏。本宏有兩個參數,包名稱和版本號。缺省情況下,本宏用AC_DEFINE定義`PACKAGE'`VERSION'。可以通過添加非空的第三個參數以避免這一行為。
AM_PATH_LISPDIR
搜索程序emacs,并且,如果找到了,把輸出變量lispdir 設置為到Emac的site-lisp目錄的完整路徑。
AM_PROG_CC_STDC
如果C編譯器的缺省狀態不是標準C(ANSI C),試圖把一個選項添加到輸出變量 CC中以使得C編譯器這樣做。本宏嘗試在各種系統中選擇標準C的各種選項。如果編譯器正確地處理函數原型,它就認為編譯器處于標準C模式。 如果你使用本宏,你應該在調用它之后檢查C編譯器是否被設置成接受標準C;如果不是,shell變量am_cv_prog_cc_stdc被設置成`no'。如果你按照標準C寫你的源代碼,你可以利用ansi2knr選項創建它的非標準C版本。
AM_PROG_INSTALL
類似與AC_PROG_INSTALL,但還定義了INSTALL_SCRIPT
AM_PROG_LEX
類似與帶有AC_DECL_YYTEXTAC_PROG_LEX,但在沒有lex的系統上使用腳本missing`HP-UX 10'是一個這樣的系統。
AM_SANITY_CHECK
它檢查并確保在創建目錄中被創建的文件比源代碼目錄中的文件要新。在時鐘設置不正確的系統中它可能失敗。本宏在AM_INIT_AUTOMAKE 中自動運行。
AM_SYS_POSIX_TERMIOS
檢查系統中,是否可以使用POSIX termios頭文件和函數。如果可以,就把shell變量 am_cv_sys_posix_termios設置為`yes'。如果不能使用,就把am_cv_sys_posix_termios設置為`no'
AM_TYPE_PTRDIFF_T
如果類型`ptrdiff_t'是在`<stddef.h>'中定義的,就定義`HAVE_PTRDIFF_T'
AM_WITH_DMALLOC
增加dmalloc包支持。如果用戶用`--with-dmalloc'進行配置,那么定義WITH_DMALLOC并且把`-ldmalloc'添加到LIBS。包dmalloc可以在ftp://ftp.letters.com/src/dmalloc/dmalloc.tar.gz 找到。
AM_WITH_REGEX
`--with-regex'添加到configure的命令行中。如果給出`--with-regex'(缺省設置),那么使用 `regex'常規表達式庫,`regex.o' 被添加到`LIBOBJS'中,并且定義`WITH_REGEX'。如果給出`--without-regex',那么使用`rx' 常規表達式庫,`rx.o'被添加到`LIBOBJS'中。

編寫你自己的aclocal宏

aclocal不含有任何宏的任何內置信息,所以擴展你自己的宏是十分容易的。

它通常被用于那些需要為使用它的其它程序提供它們自己的Autoconf宏的庫。例如gettext庫支持宏 AM_GNU_GETTEXT,該宏將被任何使用gettext的任何包所使用。在安裝庫的時候,它安裝宏以便aclocal可以找到它。

一個宏文件應該是一系列AC_DEFUN'。aclocal還懂得AC_REQUIRE,所以把每個宏儲存在一個單獨的文件中是安全的。

一個宏文件的文件名應該以`.m4'結尾。這類文件都應該安裝在`$(datadir)/aclocal'中。

頂層`Makefile.am'

在非平(non-flat)包中,頂層`Makefile.am'必須告訴Automake 應該在那個子目錄中進行創建。這通過變量SUBDIRS來完成。

SUBDIRS保存了需要進行各種創建的子目錄列表。在生成的`Makefile'中的許多目標(例如,all)即需要在本目錄下運行,也需要在所有特定的子目錄下運行。需要指出,出現在 SUBDIRS中的子目錄并不一定含有`Makefile.am' ;只要在配置(運行configuration)之后含有`Makefile'就行了。這使得你可以從不使用Automake的軟件包(例如,gettext)中引入庫。在SUBDIRS中提到的目錄必須是當前目錄的直接子目錄。例如,你可以把`src/subdir'添加到SUBDIRS中。

在一個深(deep)包中,頂層`Makefile.am'通常十分簡短。例如,下面是Hello發布版中的`Makefile.am'

EXTRA_DIST = BUGS ChangeLog.O README-alpha
SUBDIRS = doc intl po src tests

就像在GNU Inetutils中的情況一樣,如果你只需要創建整個包的一個子集,你可以覆蓋變量SUBDIRS。在你的 `Makefile.am'中包含:

SUBDIRS = @SUBDIRS@

而后在你的`configure.in'中,你可以指明:

SUBDIRS = "src doc lib po"
AC_SUBST(SUBDIRS)

以上修改的結果是:automake將創建包以獲得subdirs,但實際上在運行configure之前并沒有把目錄列表包括進來。

SUBDIRS可以包含配置替換(例如,`@DIRS@'); Automake本身并不實際檢查這個變量的內容。

如果定義了SUBDIRS,那么你的`configure.in' 必須包含AC_PROG_MAKE_SET

SUBDIRS的使用并不限于頂層目錄中的`Makefile.am'。 Automake可以用于構造任意深度的包。

創建程序和庫

Automake的大部分功能的目的是使創建C程序和庫變得容易些。

創建一個程序

在一個含有將被創建成一個程序(而不是創建成一個庫)的源代碼的目錄中,要使用主變量`PROGRAMS'。程序可以安裝到`bindir'`sbindir'`libexecdir'`pkglibdir'中,或者根本不安裝(`noinst')。

例如:

bin_PROGRAMS = hello

在這種簡單的情況下,最終的`Makefile.in'將含有代碼以生成名為hello的一個程序。變量hello_SOURCES 用于確定哪些源代碼應該被創建到可執行文件中去:

hello_SOURCES = hello.c version.c getopt.c getopt1.c getopt.h system.h

它將導致所有提及的`.c'文件被編譯成對應的`.o' 文件。而后被一同連接以生成`hello'

如果需要`prog_SOURCES',但并未定義它,那么它被缺省地設置成單個文件`prog.c'。在上面的例子中,對hello_SOURCES 的定義實際上是多余的。

可以把多個程序創建到一個目錄中。多個程序可以共享一個源代碼文件。源代碼文件必須在需要它的每個`_SOURCES'中列出。

出現在`_SOURCES'中的頭文件將被包含在發布版本中,其它的頭文件將被忽略。因為它并不明顯,你不應該把由`configure'生成的頭文件包含在變量`_SOURCES'中;不應該發布這個文件。也可以列出lex(`.l')和yacc(`.y')文件;參見對Yacc和Lex的支持

即使不是所有的文件在所有的情況下都需要被創建,Automake也必須知道所有可能被連接到程序中的源文件。所有僅僅是可能被創建的文件應該被適當地添加到變量`EXTRA_'中。例如,如果`hello-linux.c' 是有條件地被包含在hello中,`Makefile.am'應該包括:

EXTRA_hello_SOURCES = hello-linux.c

類似地,有時候需要在配置的時刻確定創建那些程序。例如GNU cpio 僅僅在特殊情況下才創建mtrmt

在這種情況下,你必須把可能創建的所有程序都告訴automake,但同時使生成的`Makefile.in'使用由configure 指明的程序。這可以通過在EXTRA_PROGRAMS中列出所有可能創建的程序的同時,把configure提供的值的替換到每個`_PROGRAMS'變量的定義中,來完成。

如果你需要和configure沒有找到的庫相連接,你可以使用LDADD來完成。該變量實際上可以用于把任何選項添加到連接器的命令行中。

有時,要在一個目錄中創建多個程序,但并不共享相同的連接時刻需求(link-time requirement)。在這種情況下,你可以使用變量`prog_LDADD' (其中prog是出現在某些`_PROGRAMS'變量中的程序名)來覆蓋全局的LDADD。(對于某個程序來說,如果存在這個變量,那么那個程序的連接就不使用LDADD。)

例如,在GNU cpio中,paxcpiomt 需要和庫`libcpio.a'連接。然而,rmt在同一個目錄中創建,并且不需要與`libcpio.a'連接。此外,mtrmt也僅僅在這種結構下創建。這里是cpio的`src/Makefile.am' 內容(有刪節):

bin_PROGRAMS = cpio pax @MT@
libexec_PROGRAMS = @RMT@
EXTRA_PROGRAMS = mt rmt
LDADD = ../lib/libcpio.a @INTLLIBS@
rmt_LDADD =
cpio_SOURCES = ...
pax_SOURCES = ...
mt_SOURCES = ...
rmt_SOURCES = ...

變量`prog_LDADD'并不適用與傳遞程序特定的連接器選項(除了`-l'`-L'之外)。所以,為此請使用變量`prog_LDFLAGS'

有時候,是否創建一個程序依賴于不屬于那個程序的某些其它目標。通過使用變量`prog_DEPENDENCIES'可以實現該功能。每個程序都依賴于這個變量的內容,但是不對它進行進一步的解釋。

如果沒有給出`prog_DEPENDENCIES',它就由Automake來計算。自動獲取的值是進行了大部分配置替換后的`prog_LDADD'內容,即刪除了`-l'`-L'選項。沒有進行的配置替換僅僅是 `@LIBOBJS@' and `@ALLOCA@';沒有進行這些替換是因為它們不會使生成的`prog_DEPENDENCIES'含有非法的值。

創建一個庫

創建庫與創建程序十分類似。在這種情況下,主變量的名字是`LIBRARIES'。庫可以安裝到libdirpkglibdir之中。

關于如何使用Libtool和主變量`LTLIBRARIES'創建共享庫的詳情,請參見創建共享庫

每個`_LIBRARIES'變量都是需要被創建的庫的列表。例如創建一個名為`libcpio.a'的庫,但并不安裝它,你可以寫:

noinst_LIBRARIES = libcpio.a

確定那些源代碼應該被創建到庫中的方式與創建程序的情況完全相同,是通過變量`_SOURCES'。需要指出的是,庫的名字是規范化的(參見派生變量是如何命名的),所以對應與`liblob.a'`_SOURCES'變量對應的變量名為`liblob_a_SOURCES',而不是`liblob.a_SOURCES'

通過使用變量`library_LIBADD',可以把額外的對象添加到庫中。這應該由configure確定的對象使用。再看看cpio:

libcpio_a_LIBADD = @LIBOBJS@ @ALLOCA@

對LIBOBJS和ALLOCA的特別處理

Automake顯式地識別對@LIBOBJS@@ALLOCA@的使用,并用該信息,以及從 `configure.in'中派生出的LIBOBJS文件列表,把適當的源文件自動添加到發布版本中。(參見需要發布哪些文件)。這些源文件還按照依賴跟蹤機制進行自動處理,參見自動依賴跟蹤

在任何`_LDADD'`_LIBADD'變量中, @LIBOBJS@@ALLOCA@都將被自動識別出來。

創建一個共享庫

創建共享庫是一件相對復雜的事情。為此,提供了GNU Libtool以使我們可以按照與平臺無關的方式創建共享庫(參見Libtool手冊)。

Automake使用Libtool來創建在主變量`LTLIBRARIES'中聲明的庫。每個`_LTLIBRARIES'變量都是一個需要創建的共享庫的列表。例如,為了創建一個名為`libgettext.a'的庫和它對應的共享庫,并且把它安裝到`libdir',可以寫:

lib_LTLIBRARIES = libgettext.la

需要指出的是:共享庫必須被安裝,所以不允許使用 `noinst_LTLIBRARIES'`check_LTLIBRARIES'

對于每個庫,變量`library_LIBADD'包含了需要被添加到共享庫中的額外的libtool對象(`.lo'文件)。變量`library_LDFLAGS'包含了所有附加的libtool選項,例如`-version-info'或者`-static'

普通的庫可能需要使用@LIBOBJS@,而libtool庫必須是使用 @LTLIBOBJS@。必須這樣做是因為libtool所操作的目標文件并不僅僅是`.o'。libtool手冊包含了關于這個問題的細節。

對于安裝在某些目錄中的庫,automake將自動提供適當的 `-rpath'選項。然而,對于那些在配置時刻才能都確定的庫(因而必須在EXTRA_LTLIBRARIES中給出),automake 并不知道它們最終安裝的目錄;對于這類庫,你必須把 `-rpath'選項手工地添加到適當的`_LDFLAGS' 變量中去。

詳情請參見Libtool手冊

創建一個程序時使用的變量

有時有必要知道那個`Makefile'變量被Automake用于編譯;例如在某些特殊情況下,你可能需要完成你自己的編譯任務。

有些變量是從Autoconf中繼承而來的;它們是CCCFLAGSCPPFLAGSDEFSLDFLAGSLIBS

還有一些附加的變量是Automake自行定義的:

INCLUDES
一個`-I'選項的列表。如果你需要包含特殊的目錄,你可以在你的`Makefile.am'中設置它。 automake已經自動地提供了一些`-I'選項。特別地,它生成`-I$(srcdir)'和一個指向保存了 `config.h'的目錄的`-I'選項(如果你已經使用了AC_CONFIG_HEADER或者AM_CONFIG_HEADER)。 除了`-I'以外,INCLUDES實際上還可以用于添加任何cpp選項。例如,有時用它把任意的`-D'選項傳遞給編譯器。
COMPILE
實際用于編譯C源文件的命令。文件名被添加到它的后面以形成完整的命令行。
LINK
實際用于連接C程序的命令。

對Yacc和Lex的支持

Automake對Yacc和Lex有一些特殊的支持。

Automake假定由yacc(或lex)生成的`.c'文件是以輸入文件名為基礎命名的。就是說,對于yacc源文件`foo.y', automake將認為生成的中間文件是`foo.c'(而不是更加傳統的 `y.tab.c')。

yacc源文件的擴展名被用于確定生成的`C'`C++' 文件的擴展名。使用擴展名`.y'的文件將被轉化成 `.c'文件;類似地,擴展名`.yy'轉化成 `.cc'`.y++'轉化成`c++'`.yxx'轉化成`.cxx';類似地,Lex源文件可以用于生成`C'或者`C++';擴展名 `.l'`.ll'`.l++'`.lxx'都可以被識別。

你不應該在任何`SOURCES'變量中明確地提及中間的(`C'或者`C++')文件;只要列出源文件就可以了。

由yacc(或lex)生成的中間文件將被包含在由它創建的任何發布版本中。這樣用戶就不需要擁有yacc或lex了。

如果出現了yacc源文件,那么你的`configure.in'必須定義變量`YACC'。完成這個任務最容易的方式是使用宏`AC_PROG_YACC'

相似地,如果出現了lex源文件,那么你的`configure.in' 必須定義變量`LEX'。你可以用宏`AC_PROG_LEX' 來完成這個工作。Automake對lex的支持還要求你使用宏 `AC_DECL_YYTEXT'--automake需要知道 `LEX_OUTPUT_ROOT'的值。

Automake允許在一個程序中使用多個yacc (或lex)源文件。 Automake使用一個稱為ylwrap的小程序在子目錄中運行 yacc(或者lex)。必須這樣做是因為 yacc的輸出文件名被修改了,并且并行的make可以同時地處理多于一個的yacc實例。ylwrap和automake一同發布。它應該出現在由`AC_CONFIG_AUX_DIR'給出的目錄,如果沒有在`configure.in'中給出這個宏,它就應該出現在當前目錄中。

對于yacc,僅僅管理鎖是不夠的。yacc的輸出還總是在內部使用相同的符號名,所以不可能把兩個yacc解析器(parser)連接到同一個可執行文件中。

我們建議使用如下在gdb中應用的改名方式:

#define	yymaxdepth c_maxdepth
#define	yyparse	c_parse
#define	yylex	c_lex
#define	yyerror	c_error
#define	yylval	c_lval
#define	yychar	c_char
#define	yydebug	c_debug
#define	yypact	c_pact
#define	yyr1	c_r1
#define	yyr2	c_r2
#define	yydef	c_def
#define	yychk	c_chk
#define	yypgo	c_pgo
#define	yyact	c_act
#define	yyexca	c_exca
#define yyerrflag c_errflag
#define yynerrs	c_nerrs
#define	yyps	c_ps
#define	yypv	c_pv
#define	yys	c_s
#define	yy_yys	c_yys
#define	yystate	c_state
#define	yytmp	c_tmp
#define	yyv	c_v
#define	yy_yyv	c_yyv
#define	yyval	c_val
#define	yylloc	c_lloc
#define yyreds	c_reds
#define yytoks	c_toks
#define yylhs	c_yylhs
#define yylen	c_yylen
#define yydefred c_yydefred
#define yydgoto	c_yydgoto
#define yysindex c_yysindex
#define yyrindex c_yyrindex
#define yygindex c_yygindex
#define yytable	 c_yytable
#define yycheck	 c_yycheck

對于每一個define,用任何你喜歡的東西替換前綴`c_'。這些定義可以為bisonbyacc和傳統的 yacc工作。如果你發現某個解析器使用了這里所沒有提到的符號,請告訴我們以便把它添加到上述列表中。

C++和其它語言

Automake對C++提供了完整的支持,對其它語言也有一些不完善的支持。對其它語言的支持將根據實際需要被添加進來。

任何包括了C++代碼的包都必須在`configure.in'中定義輸出變量`CXX';完成這一任務的最簡單方式就是使用宏AC_PROG_CXX

在出現C++源文件的時候需要定義幾個附加的變量:

CXX
C++編譯器的名稱。
CXXFLAGS
傳遞給C++編譯器的任何選項。
CXXCOMPILE
實際用于編譯C++源文件的命令。文件名將被添加到它的后面以構成完整的命令行。
CXXLINK
實際用于連接C++程序的命令。

自動de-ANSI-fication

雖然GNU標準允許使用標準C,使用標準C可能使包難以移植到一些舊的編譯器上(典型的是SunOS)。

在實際的編譯發生之前,Automake允許你通過對每個源文件實施"de-ANSI-fying" 以在這一類機器上進行工作。

如果`Makefile.am'變量AUTOMAKE_OPTIONS (參見改變Automake的行為)包括了選項ansi2knr那么處理de-ANSI-fication的代碼就被插入到生成的`Makefile.in'中。

這使得目錄中的每個C源文件都被看作標準C。如果有標準C編譯器可以使用,就使用它。如果沒有標準C編譯器可用,就用程序ansi2knr 把文件轉換成K&R C,而后再被編譯。

程序ansi2knr相當簡單。它假定源代碼按照特定的方式進行排版;詳情請參見ansi2knr的man。

支持de-ANSI-fication需要把源文件`ansi2knr.c'`ansi2knr.1'與標準C源代碼放在同一個包中;這些文件與Automake 一同發布。此外,包的`configure.in'必須調用宏AM_C_PROTOTYPES

Automake還負責在當前包的其它目錄中尋找ansi2knr的支持文件。這通過把到達適當目錄的相對路徑添加到選項ansi2knr之前來完成。例如,假定一個包的標準C代碼儲存在子目錄`src'`lib'中。文件`ansi2knr.c'`ansi2knr.1'出現在`lib'中。那么下述內容應該在`src/Makefile.am'中出現:

AUTOMAKE_OPTIONS = ../lib/ansi2knr

如果沒有給出前綴,就假定文件在當前目錄中。

自動依賴性跟蹤

作為開發者,經常痛苦地在每次項目的include文件的依賴關系發生變化的時候對`Makefile.in'進行更新。 automake提供了一種方式以自動跟蹤依賴關系的變化,并且在生成的`Makefile.in'中給出這些依賴關系。

當前這種支持需要使用GNU makegcc。如果有足夠的必要性,將來可能提供對不同的依賴性生成程序的支持。在此之前,如果當前目錄中定義了任何C程序或者庫,在缺省狀態下就啟動這種模式,因而你可能從非GNU make那里得到一個`Must be a separator'錯誤。

當你決定創建一個發布版本時,目標dist 將用`--include-deps'和其它選項重新運行automake。這將是的以前生成的依賴關系被插入到生成的`Makefile.in'中,并因而被插入到發布之中。這一步驟還不會把依賴性生成代碼包括進來,所以那些下載你的發布版本的人就不必使用GNU makegcc,而且不會導致錯誤。

在添加到`Makefile.in'的時候,所有系統特定的依賴性都被自動刪除了。這可以通過把文件羅列在變量`OMIT_DEPENDENCIES' 中來實現。例如:automake將刪除所有對系統頭文件的引用。有時有必要指明應該刪除哪個頭文件。例如,如果你的 `configure.in'使用了`AM_WITH_REGEX',那么就應該刪除任何與`rx.h'或者 `regex.h'有關的依賴性,這是因為在用戶配置包之前還不知道應該使用那個頭文件。

實際上,automake足夠地聰明以至于可以處理諸如常規表達式頭文件的特殊情況。如果使用了`AM_GNU_GETTEXT',它還將自動忽略 `libintl.h'

自動依賴性跟蹤功能可以通過在變量AUTOMAKE_OPTIONS 中設置no-dependencies來關閉。

如果你打開由make dist創建的發布版本,而且你希望重新添加依賴性跟蹤的代碼,只要重新運行automake就行了。

實際的依賴性文件被儲存在創建目錄下的一個名為`.deps' 的子目錄中。這些依賴性是機器特有的。如果你愿意,刪除它們是安全的;它們將在下次創建的時候自動重建。

其它派生對象

Automake可以處理不是C程序的其它派生對象。有時對實際創建這類對象的支持必須顯式地給出,但Automake仍然會自動地處理安裝和發布。

可執行腳本

定義和安裝腳本程序是可能的。這種程序被羅列在主變量`SCRIPTS'中。 automake沒有為腳本定義任何依賴性關系; `Makefile.am'應該包含正確的規則。

automake并不假定腳本是派生的對象;這些對象必須被手工地刪除;詳情請參見清除了些什么

automake本身就是在配置時刻從`automake.in' 中生成的腳本。下面給出了如何處理它:

bin_SCRIPTS = automake

因為automake出現在宏AC_OUTPUT中,自動地生成了一個關于它的目標。

腳本對象可以安裝在bindirsbindirlibexecdir或者pkgdatadir中。

頭文件

頭文件由`HEADERS'變量族所指定。通常是不安裝頭文件的,所以變量noinst_HEADERS是最常用的。

所有的頭文件都必須在某些地方列出;沒有列出的頭文件將不會出現在發布版本中。通常最清楚的方式是和程序的其它源代碼一起列出不會被安裝的頭文件。參見創建一個程序。在變量`_SOURCES'中列出的頭文件不需要在任何 `_HEADERS'變量中再次列出。

頭文件可以安裝到includediroldincludedir或者 pkgincludedir中。

與體系結構無關的數據文件

Automake使用`DATA'族變量來支持對各種數據文件的安裝。

這些數據可以安裝在目錄datadirsysconfdirsharedstatedirlocalstatedir或者pkgdatadir中。

在缺省狀態下,數據文件不會被包含在發布版本中。

下面是automake如何安裝它的附加數據文件:

pkgdata_DATA = clean-kr.am clean.am ...

已創建的源代碼

有時候,一個可以被稱作“源文件”的文件(例如一個C `.h'文件)實際上是從其它文件中派生出來的。這類文件應該被羅列在變量 BUILT_SOURCES中。

在缺省狀態下,不會編譯已創建的源文件。你必須在一些其它的`_SOURCES'變量中明確地給出它們,以便對其進行編譯。

需要說明的是,在某些情況下,BUILT_SOURCES將以令人驚訝的方式工作。為了獲得已創建的源文件以進行自動依賴性跟蹤,`Makefile'必須依賴于 $(BUILT_SOURCES)。這導致這些源文件可能在某些可笑的時候被重新創建。

其它的GNU工具

因為Automake被設計成為GNU程序自動生成`Makefile.in',它為與其它GNU工具進行互操作做出了努力。

Emacs Lisp

Automake為Emacs Lisp提供了一些支持。主變量`LISP'被用于保存一個`.el'文件的列表。該主變量的可能前綴有:`lisp_'`noinst_'。如果定義了lisp_LISP,那么 `configure.in'就必須運行AM_PATH_LISPDIR (參見Automake支持的Autoconf宏).

在缺省狀態下,Automake將使用通過AM_PATH_LISPDIR 找到的Emacs按字節編譯(byte-compile)所有Emacs Lisp源文件。如果你不希望使用字節編譯,請把變量`ELCFILES'定義為空。 字節編譯的Emacs Lisp文件并不能在所有版本的Emacs間移植,所以如果你希望在同一個地方安裝多于一個版本的Emacs,你可以關閉它。進一步,許多包并沒有從字節編譯中獲得實際的好處。我們仍然建議你不要改變缺省設置。對站點進行特殊的配置以適用于它們自身,可能比為其它所有人創建不和諧的安裝要更好一些。

Gettext

如果在`configure.in'中出現了AM_GNU_GETTEXT,那么Automake就開啟對GNU gettext的支持,一個支持國際化的消息編目系統(參見GNU gettext工具中的`GNU Gettext'節)。

在Automake中對gettext的支持需要把兩個子目錄附加到包中,`intl'`po'。Automake確認這些目錄的存在并且在SUBDIRS中被給出。

更進一步,Automake檢查在`configure.in'中包含了與所有合法的`.po'文件相對應的`ALL_LINGUAS'定義,并且沒有多余的定義。

Guile

Automake為構造Guile模塊提供了一些自動支持。如果宏AM_INIT_GUILE_MODULE 出現在`configure.in'中,Automake將開啟對Guile的支持。

現在對Guile的支持僅僅表示宏AM_INIT_GUILE_MODULE

  • 運行了AM_INIT_AUTOMAKE
  • 帶路徑`..'運行了AC_CONFIG_AUX_DIR

隨著Guile模塊代碼的成熟,無疑Automake的支持也將會更好。

Libtool

Automake通過主變量`LTLIBRARIES'提供了對GNU Libtool的支持(參見Libtool手冊)參見創建一個共享庫

Java

通過主變量`JAVA',Automake為Java的編譯提供了少量支持。

任何在變量`_JAVA'列舉的`.java'文件在創建時刻將用JAVAC進行編譯。在缺省狀態,`.class'文件不會被包含在發布版本中。

目前Automake正試圖限制只能在`Makefile.am'中使用一個`_JAVA'主變量。引入這個限制是因為,通常是不可能知道哪個`.class'文件是從哪個`.java' 文件中生成的 -- 因此不可能知道哪個文件應該被安裝到哪里。

創建文檔

目前Automake提供了對Texinfo和man的支持。

Texinfo

如果當前目錄中含有Texinfo源文件,你必須在主變量`TEXINFOS' 中給出聲明。通常Texinfo文件被轉換成info,因此經常在這里使用宏info_TEXINFOS。需要指出的是任何Texinfo源文件的文件名的擴展名都必須是`.texi'或者`.texinfo'

如果`.texi'文件@includes `version.texi',就將自動生成那個文件。 `version.texi'定義了三個你可以引用的Texinfo宏:EDITIONVERSIONUPDATED。前兩個宏保存了你的包的版本號(為清晰起見而分別保存);最后一個宏是最后一次修改主文件的日期。對`version.texi'的支持需要程序mdate-sh;這個程序由Automake提供。

有時,一個info文件實際上依賴于多個`.texi'文件。例如,在GNU Hello中,`hello.texi'包括了文件`gpl.texi'。你可以通過使用變量`texi_TEXINFOS'告訴Automake 這一依賴性。下面就是Hello處理它的代碼:

info_TEXINFOS = hello.texi
hello_TEXINFOS = gpl.texi

在缺省狀態下,Automake認為`texinfo.tex'出現在Texinfo源文件所在的目錄中。然而,如果你在`configure.in'中使用了AC_CONFIG_AUX_DIR 那么將到那個目錄中去尋找`texinfo.tex'文件。如果給出了 `--add-missing',Automake將自動提供`texinfo.tex'

如果你的包在許多目錄中儲存了Texinfo文件,你可以用變量TEXINFO_TEX 來告訴automake到那里去尋找你的包的規范`texinfo.tex'文件。這個變量的值應該是從當前`Makefile.am'`texinfo.tex' 的相對路徑。

TEXINFO_TEX = ../doc/texinfo.tex

選項`no-texinfo.tex'可以消除對`texinfo.tex'的需要。但使用變量TEXINFO_TEX更好些,因為它使得目標dvi 仍然可以工作。

Automake生成一個install-info目標;一些人顯式地使用它。在缺省狀態下,info文檔通過運行`make install'來安裝。可以通過給出選項no-installinfo以阻止執行這一操作。

Man手冊

一個包還可以包含man手冊。(參見GNU關于此事的標準,GNU編碼標準中的`Man手冊'節。)用主變量`MANS'聲明Man手冊。通常使用宏man_MANS。根據文件的擴展名,Man手冊被自動地安裝到mandir的正確子目錄中。

在缺省狀態下,man手冊通過運行`make install'安裝。然而,因為GNU項目并不需要man手冊,許多維護者沒有花費時間以及時更新man手冊。在這些情況下,給出選項no-installman 將阻止對man手冊的安裝。用戶仍然可以顯式地使用`make install-man' 來安裝它們。

下面是GNU cpio如何處理它的文檔(它同時包括了Texinfo文檔和 man手冊):

info_TEXINFOS = cpio.texi
man_MANS = cpio.1 mt.1

Texinfo源文件和info文檔都被看作用于創建發布版本的源代碼。

Man手冊現在并不被看作源代碼,因為man手冊有時是自動生成的。

安裝了些什么

自然地,一旦你的程序被創建了,Automake實際上處理了安裝程序的細節。所有PROGRAMSSCRIPTSLIBRARIESLISPDATAHEADERS中列出的文件都被自動地安裝在適當的位置。

Automake還可以處理對info文檔和man手冊的安裝。

Automake生成分離的install-datainstall-exec目標,如果安裝器(installer)在共享的目錄結構中為多個機器進行安裝,這些目標允許與機器獨立的部分僅僅被安裝一次。目標install依賴于這兩個目標。

Automake還生成一個uninstall目標,一個 installdirs目標,和一個install-strip目標。

通過定義目標install-exec-local,或者目標install-data-local 就可以擴展這一機制。如果這些目標存在,它們將在運行`make install'時運行。

使用標準目錄前綴`data'`info'`man'`include'`oldinclude'`pkgdata'或者 `pkginclude'的變量(例如,`data_DATA')將由 `install-data'安裝。

使用標準目錄前綴`bin'`sbin'`libexec'`sysconf'`localstate'`lib'或者 `pkglib'的變量(例如,`bin_PROGRAMS')將由 `install-exec'安裝。

任何使用了含有`exec'的用戶定義目錄前綴的變量(例如,`myexecbin_PROGRAMS')將由`install-exec'安裝。所有使用其它用戶定義的前綴的變量將由`install-data'安裝。

Automake在所有的install規則中生成對變量`DESTDIR'的支持;參見GNU編碼標準中的`Makefile慣例'節。

清除了些什么

GNU Makefile標準給出了許多不同的清除規則。通常由Automake自動確定可以清除哪些文件。當然,Automake還能識別一些為指明需要額外地清除的文件而定義的變量。這些變量是 MOSTLYCLEANFILESCLEANFILESDISTCLEANFILESMAINTAINERCLEANFILES

需要發布哪些文件

生成的`Makefile.in'中的dist目標可以用于產生用gzip壓縮了的發布tar文件。 tar文件是根據`PACKAGE'變量和`VERSION'變量命名的;精確地說,被命名為`package-version.tar.gz'

在大部分情況下,發布版本中的文件由Automake自動尋找:所有的源文件被自動地包含在發布版本中,還有所有的 `Makefile.am'`Makefile.in'。Automake定義了一些常用的內置文件,如果出現在當前目錄中,那么就被自動地包含在發布版本中。可以用`automake --help'打印它們。此外,由configure 讀入的文件(例如,對應于由AC_OUTPUT調用指明的文件的源文件)將被自動地包含在發布版本中。

有時,除此而外仍然有一些文件需要被發布而沒有包含在自動規則之中。這些文件應該在變量EXTRA_DIST中列出。需要指出的是,EXTRA_DIST只能處理當前目錄中的文件;其它目錄中的文件將使make dist在運行時發生錯誤。

如果你定義了SUBDIRS,automake將遞歸地把子目錄包含在發布版本中。如果是有條件地定義SUBDIRS(參見條件),通常automake將把所有可能出現在SUBDIRS中的所有目錄包含在發布版本中。如果你需要有條件地給出一組目錄,你可以設置變量DIST_SUBDIRS以精確地列出需要包含在發布版本中的子目錄。

有時在發布版本打包之前修改發布版本是有用的。如果目標dist-hook存在,它可以在填充發布目錄之后,創建tar(或shar)文件之前運行。使用該功能的一種方式是發布新的`Makefile.am'被刪除了的子目錄中的文件。

dist-hook:
mkdir $(distdir)/random
cp -p random/a1 random/a2 $(distdir)/random

Automake還生成一個distcheck目標,它有助于確認給定的發布版本實際上是可以工作的。 distcheck首先創建發布版本,而后試圖進行一個VPATH創建。

對測試套件的支持

Automake支持兩種形式的測試套件。

如果定義了變量TESTS,它的值被看作為了運行測試而運行的程序列表。程序可以是派生對象或者是源對象;生成的規則將在srcdir`.'中尋找。應該在srcdir(它可以既是環境變量,又是make變量)中尋找程序需要的數據文件,所以它們在一個分離的目錄中進行創建的工作(參見Autoconf手冊中的`創建目錄'節),并且是在特別的目標distcheck中創建的(參見那些需要被發布)。

在運行的終點將打印失敗的次數。如果一個測試程序以狀態77退出,在最后的計數中它的結果將被忽略。這一特征允許不可移植的測試在對它來說沒有意義的環境下被忽略。

變量TESTS_ENVIRONMENT可以用于為測試運行而設置環境變量;在該規則中設置環境變量srcdir。如果你所有的測試程序都是腳本,你還可以把TESTS_ENVIRONMENT設置成一個對shell的調用(例如`$(SHELL) -x');這對調試測試結果來說是有用的。

如果`dejagnu'出現在AUTOMAKE_OPTIONS中,那么就假定運行一個基于dejagnu的測試套件。變量 DEJATOOL的值被作為--tool的參數傳遞給 runtest;它的缺省值是包的名字。

在缺省狀態下,變量RUNTESTDEFAULTFLAGS保存了傳遞給dejagnu的--tool--srcdir選項;如果有必要,可以覆蓋它。

還可以覆蓋變量EXPECTRUNTESTRUNTESTFLAGS以提供項目特定的值。例如,如果你正在測試編譯器工具鏈(toolchain),你就需要這樣做。這是因為缺省值并沒有把主機名和目標名考慮進去。

在上述兩種情況中,測試都是通過`make check'來完成的。

改變Automake的行為

Automake的各種特征可以在`Makefile.am'中用各種選項進行控制。這些選項在一個名為AUTOMAKE_OPTIONS的特殊變量中被列出。目前可以理解的選項有:

gnits
gnu
foreign
cygnus
設置適當的嚴格性。選項gnits還隱含了readme-alphacheck-news
ansi2knr
path/ansi2knr
打開自動de-ANSI-fication功能。參見自動de-ANSI-fication。如果以一個路徑開頭,那么生成的`Makefile.in'將在特別給定的目錄中尋找程序`ansi2knr'。通常,路徑應該是到同一個發布版本中的其它目錄的相對路徑(雖然Automake并不進行這項檢查)。
check-news
給出該選項后,如果當前的版本號沒有出現在`NEWS'文件中的前幾行中,將導致make dist的失敗。
dejagnu
生成dejagnu特定的規則。參見對測試套件的支持
dist-shar
就象普通的dist目標那樣生成dist-shar目標。這個新目標將創建一個發布版本的shar包。
dist-zip
就象普通的dist目標那樣生成dist-zip目標。這個新目標將創建一個發布版本的zip包。
dist-tarZ
就象普通的dist目標那樣生成dist-tarZ目標。這個新目標將創建一個發布版本的tar包;假定使用傳統的tarcompress。警告:如果你實際上在使用GNU tar,那么生成的包可能含有不可移植的結構。
no-dependencies
這與在命令行中使用選項`--include-deps'相類似,但在那些你不希望使用自動依賴性跟蹤的場合下更為有用。參見自動依賴性跟蹤。在這個情況下將有效地關閉自動依賴性跟蹤。
no-installinfo
給出該選項后,生成的`Makefile.in'在缺省的狀態下將不會創建或者安裝info文檔。然而,目標info和目標install-info 仍然是可用的安裝選項。在`GNU'嚴格性以及更高的嚴格性中這個選項是不允許使用的。
no-installman
給出這個選項后,生成的`Makefile.in'在缺省狀態下將不會安裝man手冊。然而,目標install-man仍然是可用的安裝選項。在`GNU'嚴格性以及更高的嚴格性中這個選項是不允許使用的。
no-texinfo.tex
即使在本目錄中含有texinfo文件,也不需要`texinfo.tex'
readme-alpha
如果本發布是一個alpha版本,并且存在文件`README-alpha',那么它將被添加到發布版本中。如果給出了該選項,版本號應該是以下兩種形式之一。第一種形式是`MAJOR.MINOR.ALPHA',其中每個元素都是一個數字;最后的點和數字應該被忽略以用于非alpha版本。第二種形式是`MAJOR.MINORALPHA',其中ALPHA是一個文字;對于非alpha版本來說,應該忽略它。
version
可以給出版本號(例如,`0.30')。如果Automake并不比要求的版本號新,將不會創建`Makefile.in'

automake能夠診斷不能識別的選項。

其它規則

還有一些不適于放在任何其它地方的幾條規則。

etags之間的界面

在某些環境下,automake將生成規則以產生由GNU Emacs使用的`TAGS'文件。

如果出現了任何C源代碼或者頭文件,那么就為該目錄創建目標tags和目標TAGS

在運行的時候,將在多個目錄包的頂層目錄創建一個tags文件,它將生成一個包括了對所有子目錄的`TAGS'文件的引用的`TAGS'文件。

此外,如果定義了變量ETAGS_ARGS,將生成目標tags。該變量用于包含了能夠被標記,但是不能夠被etags所識別的源文件的目錄。

下面是Automake如何為它的源代碼生成標記和它的Texinfo文件中的結點。

ETAGS_ARGS = automake.in --lang=none \
--regex='/^@node[ \t]+\([^,]+\)/\1/' automake.texi

如果你把文件名添加到`ETAGS_ARGS',你將可能還要設置`TAGS_DEPENDENCIES'。該變量的內容將直接添加到目標tags的依賴列表中。

Automake還將生成一個將在源代碼上運行mkidID目標。它僅僅可以在一個目錄到目錄的基礎(directory-by-directory basis)上使用。

處理新的文件擴展名

有時,為處理Automake不能識別的文件類型而引入新的隱含規則是有用的。如果這樣做,你必須把這些新的后綴告訴GNU Make。可以通過把新后綴的列表添加到變量SUFFIXES來完成。

例如,目前automake不能對Java提供任何支持。如果你寫了一個用于從`.java' 源文件生成`.class'文件的宏,你還需要把這些后綴添加到列表中:

SUFFIXES = .java .class

條件

Automake支持一種簡單的條件。

在使用條件之前,你必須在configure.in文件中使用 AM_CONDITIONAL定義它。宏AM_CONDITIONAL 接受兩個參數。

AM_CONDITIONAL的第一個參數是條件的名字。它應該是一個以字母開頭并且僅僅由字母、數字和下劃線組成的簡單字符串。

AM_CONDITIONAL的第二個參數是一個適用于shell的if語句的shell條件。該條件將在運行configure的時候被求值。

條件典型地依賴于用戶提供給configure腳本的選項。下面是一個演示如果在用戶使用了`--enable-debug'選項的情況下為真的條件的例子。

AC_ARG_ENABLE(debug,
[  --enable-debug    Turn on debugging],
[case "${enableval}" in
yes) debug=true ;;
no)  debug=false ;;
*) AC_MSG_ERROR(bad value ${enableval} for --enable-debug) ;;
esac],[debug=false])
AM_CONDITIONAL(DEBUG, test x$debug = xtrue)

下面是一個如何在`Makefile.am'中使用條件的例子:

if DEBUG
DBG = debug
else
DBG =
endif
noinst_PROGRAMS = $(DBG)

這個小例子還可以被處理以用于EXTRA_PROGRAMS。(參見創建一個程序)。

你只能在if語句中測試單個變量。可以忽略else語句。條件可以嵌套到任意深度。

需要指出的是Automake中的條件與GNU Make中的條件是不相同的。Automake的條件在配置時刻由`configure'腳本完成檢查,并且將影響`Makefile.in'`Makefile'的轉換。它們是基于傳遞給`configure'的選項和`configure'對本地系統的檢測結果的。 GNU Make條件則在make時完成檢查,并且是基于傳遞給make程序的變量或者是基于在`Makefile'中定義的變量的。

Automake條件在任何make下都可以工作。

--gnu--gnits的效果

選項`--gnu'(或者`AUTOMAKE_OPTIONS'中的`gnu')將使得 automake執行如下檢查:

  • 在包的頂層目錄中應該含有文件`INSTALL'`NEWS'`README'`COPYING'`AUTHORS'`ChangeLog'
  • 禁止使用選項`no-installman'`no-installinfo'

需要指出的是,該選項將在未來進行擴展以進行更多的檢查;熟悉GNU標準的精確需求是值得推薦的。此外,`--gnu'可以要求某些非標準GNU程序為了各種僅由維護者使用的目標而存在;例如,在將來`make dist'可能會需要pathchk

選項`--gnits'進行`--gnu'所做的所有檢查,此外還進行如下檢查:

  • `make dist'將檢查以確認文件`NEWS'被更新到當前的版本。
  • 不允許出現文件`COPYING.LIB'。LGPL顯然是一個失敗的試驗。
  • 檢查文件`VERSION'以確保它的格式是符合Gnits標準的。
  • 如果`VERSION'表明本版本是alpha版本,并且文件`README-alpha' 出現在包的頂層目錄中,那么它就被包含在發布版本中。因為該模式是唯一對版本號格式實行限制的模式,所以上述操作在`--gnits' 模式下實施而不在其它模式下進行,因此,該模式也是automake唯一能夠自動確定是否把`README-alpha'包含在發布版本中的模式。
  • 需要出現文件`THANKS'

--cygnus的效果

對于如何構造`Makefile.in',Cygnus解決方案有一些不同的規則。把`--cygnus'傳遞給automake將使所有生成的`Makefile.in' 服從Cygnus規則。

下面是`--cygnus'的精確效果:

  • 總是在創建目錄中,而不是在源目錄創建Info文件。
  • 如果指明了Texinfo源文件,就不需要`texinfo.tex'。其設想是:應該提供該文件,但automake不能在適當的位置找到它。這種設想是Cygnus包典型的包裝方式的產物。
  • `make dist'將在創建目錄和源目錄中尋找文件。為了支持把info文件儲存在創建目錄中而提供這個功能。
  • 將在創建樹和用戶的`PATH'中尋找某些工具。這些工具是runtestexpectmakeinfotexi2dvi
  • 隱含--foreign選項。
  • 隱含選項`no-installinfo'和選項`no-dependencies'
  • 需要宏`AM_MAINTAINER_MODE'和宏`AM_CYGWIN32'
  • 目標check并不依賴于目標all

建議GNU維護者使用`gnu'嚴格性方式而不是特殊的Cygnus模式。

什么時候Automake不夠用

Automake的隱含語義意味著許多問題只要通過把一些make 目標和規則添加到`Makefile.in'中就可以解決了。 automake將忽略這些添加的目標和規則。

對于這種做法需要提出告誡。雖然你可以覆蓋已經被automake所使用的目標,但這通常是失策的,在非平包(non-flat)的頂層目錄中尤其如此。然而,你可以在你的`Makefile.in'中給出各種帶有`-local'的有用目標版本。 Automake將用那些用戶提供的目標補充標準的目標。

支持本地版本的目標有allinfodvicheckinstall-datainstall-execuninstall和各種clean目標(mostlycleancleandistcleanmaintainer-clean)。需要指出的是沒有 uninstall-exec-local或者uninstall-data-local目標;請使用uninstall-local。僅僅反安裝數據或僅僅反安裝可執行文件是沒有意義的。

例如,下面是把一個文件安裝到`/etc'的一種方式:

install-data-local:
$(INSTALL_DATA) $(srcdir)/afile /etc/afile

某些目標還可以在完成它的工作之后運行一個稱為hook的其它目標。 hook是在源目標名的后面添加`-hook'。允許使用hook的目標是 install-datainstall-execdistdistcheck

例如,下面是如果創建一個到已經安裝的程序的硬連接:

install-exec-hook:
ln $(bindir)/program $(bindir)/proglink

發布`Makefile.in'

Automake對于發布生成的`Makefile.in'沒有施加任何限制。我們仍然鼓勵軟件的作者按照諸如GPL之類的條款發布它們的作品,但是Automake 并不要求你這樣做。

一些可以通過選項--add-missing自動安裝的文件則受到 GPL的約束;打開每個文件檢查一下。

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            久久男人av资源网站| 销魂美女一区二区三区视频在线| 国产精品黄色在线观看| 亚洲国产成人高清精品| 欧美日韩在线观看一区二区三区 | 亚洲在线电影| 麻豆精品在线播放| 欧美激情精品| 亚洲欧美激情精品一区二区| 亚洲一区黄色| 久久久久免费视频| 欧美日韩精品在线播放| 国产精品免费一区二区三区在线观看| 欧美三级在线播放| 狠狠色伊人亚洲综合成人| 日韩视频免费在线观看| 午夜精品久久久久久久白皮肤| 欧美资源在线| 亚洲免费观看视频| 老司机精品久久| 伊人狠狠色丁香综合尤物| 国产在线视频不卡二| 亚洲国产美女| 久久精品国产精品| 亚洲另类在线视频| 久久亚洲影院| 精品1区2区3区4区| 香蕉成人久久| 亚洲无线观看| 欧美日韩一区在线播放| 亚洲国产精品99久久久久久久久| 亚洲婷婷综合色高清在线 | 久久久五月婷婷| 欧美视频中文字幕在线| 激情国产一区二区| 久久aⅴ国产紧身牛仔裤| 日韩午夜视频在线观看| 欧美日韩国产成人在线| 亚洲影音一区| 久久久久成人精品| 亚洲美女av网站| 一本到12不卡视频在线dvd| 国产精品午夜在线观看| 欧美va亚洲va国产综合| 国产婷婷一区二区| 一区二区三区欧美亚洲| 在线亚洲激情| 亚洲电影免费观看高清完整版在线| 农村妇女精品| 国产精品一区二区三区成人| 麻豆成人小视频| 欧美亚州在线观看| 久久精品91| 欧美日韩国产成人在线免费| 欧美亚洲视频一区二区| 欧美顶级艳妇交换群宴| 亚洲综合精品自拍| 免费日韩成人| 午夜精品视频一区| 欧美成人一区二区| 久久亚洲精品伦理| 国产精品九九| 亚洲精品乱码久久久久久日本蜜臀 | 欧美第一黄色网| 久久av一区二区三区| 久久久精品午夜少妇| 欧美电影打屁股sp| 久久亚洲午夜电影| 国产精品热久久久久夜色精品三区 | 久久色在线播放| 国产精品青草综合久久久久99| 亚洲人成小说网站色在线| 伊人成人开心激情综合网| 亚洲欧美文学| 麻豆亚洲精品| 亚洲第一区色| 欧美猛交免费看| 一本色道久久综合亚洲91| 一区二区三区精密机械公司| 欧美日韩1区2区| 亚洲系列中文字幕| 久久久久久亚洲综合影院红桃 | 亚洲高清视频一区二区| 老妇喷水一区二区三区| 亚洲电影在线看| 亚洲小少妇裸体bbw| 午夜免费电影一区在线观看| 国产精品免费网站在线观看| 欧美一区二区在线| 欧美激情一区二区三区成人| 亚洲一区制服诱惑| 亚洲福利国产精品| 国产精品jvid在线观看蜜臀| 欧美一区影院| 这里只有视频精品| 模特精品裸拍一区| 亚洲男女自偷自拍图片另类| 国产午夜精品久久久久久久| 久久男女视频| 午夜亚洲精品| 一区二区不卡在线视频 午夜欧美不卡'| 国产精品成人va在线观看| 麻豆精品在线播放| 亚洲欧美国产三级| 一区二区三区视频在线播放| 欧美激情精品久久久久久久变态| 午夜免费日韩视频| 午夜精品理论片| 午夜亚洲激情| 欧美亚洲三区| 久久九九国产精品| 久久婷婷亚洲| 免费中文日韩| 亚洲美女黄网| 夜夜精品视频| 亚洲一二区在线| 亚洲曰本av电影| 国内精品美女在线观看| 影音先锋日韩资源| 亚洲人成小说网站色在线| 亚洲精品国产精品久久清纯直播| 最新精品在线| 一区二区毛片| 午夜精品久久久久久99热软件| 销魂美女一区二区三区视频在线| 久久国产精品一区二区三区四区| 欧美一级午夜免费电影| 久久久青草婷婷精品综合日韩 | 欧美成人亚洲成人| 欧美激情在线观看| 国产欧美日本一区视频| 在线播放一区| 亚洲欧美一区二区在线观看| 久久嫩草精品久久久精品| 在线观看日韩精品| 日韩亚洲欧美一区| 久久超碰97中文字幕| 亚洲黄页视频免费观看| 午夜精品福利电影| 欧美日韩精品一二三区| 伊人成年综合电影网| 久久经典综合| 亚洲你懂的在线视频| 欧美视频1区| 一区二区三区你懂的| 欧美黄色一区二区| 久久九九国产精品怡红院| 国产精品卡一卡二| 先锋影音久久久| 午夜精品久久久久久久久| 国产精品s色| 久久精品99国产精品酒店日本| 99国产精品一区| 国产精品成人午夜| 亚洲一区免费视频| 亚洲视频专区在线| 国产精品视频免费一区| 亚洲一区视频| 亚洲一区二区网站| 影音先锋中文字幕一区二区| 久久精品国产久精国产一老狼| 亚洲在线免费观看| 狠狠色狠狠色综合| 亚洲国产人成综合网站| 欧美日韩美女在线观看| 午夜影院日韩| 巨乳诱惑日韩免费av| 亚洲天堂网在线观看| 久久精品国产99| 亚洲午夜激情网页| 久久国产精品久久久久久| 99精品国产高清一区二区| 亚洲女人小视频在线观看| 亚洲国产福利在线| 亚洲美女视频在线免费观看| 国产一区二区精品| 在线视频日本亚洲性| 91久久精品美女高潮| 欧美影院精品一区| 欧美久久一区| 免费精品视频| 黄色一区二区在线| 国产精品久久久久aaaa| 欧美激情免费在线| 狠狠综合久久| 欧美一级理论片| 午夜精品一区二区三区在线| 欧美大色视频| 亚洲精品国产品国语在线app | 久久激情婷婷| 久久精品人人爽| 国产综合色产| 久久综合999| 久久久久久欧美| 狠狠久久亚洲欧美专区| 久久经典综合| 美国成人直播| 亚洲毛片在线观看| 国产精品在线看| 欧美影视一区|