configure.in Makefile.am解析

引用自:http://blog.chinaunix.net/u/22878/showart_421774.html

 

用前面所介紹的基本概念,已經可以編譯全功能的Gtk+/Gnome應用程序了。但是還有一個大問題:如何配置編譯選項?一些實用工具如automake、autoconf、libtool等,可以用來簡化這一過程。

  爲了方便維護,同時,也是爲了便於使用這些實用工具,應該在編寫代碼時遵從一些約定。如果要將程序發佈爲自由軟件,最好能使程序源代碼的目錄結 構遵從“GNU項目編碼標準”。即使應用程序是私有的商用程序,不想公開源代碼,從技術上來說,這麼做也是一個非常好的選擇,因爲這些標準都是經過實踐檢 驗,能夠讓你節省大量的時間和精力。另外還應該在程序代碼中包含INSTALL、README的文件。

  2.11.1生成源代碼樹

  差不多所有的Gnome應用程序都使用同樣的基於GNU工具automake、autoconf和libtool的編譯系統。Gtk+和 Gnome提供了一套autoconf宏,用於生成可移植的、符合標準的編譯設置。我們用一個稱GnomeHello的應用程序來演示Gnome的特性。

  Gnome應用程序遵從一系列的約定來生成源代碼樹和發佈的tar文件,大多數約定被自由軟件社區廣泛使用。這些約定的許多方面已經在“GNU項目編碼標準”(GNUProject’sCodingStandards

  http://www.gnu.org/prep/standards_toc.html)和Linux文件系統層次標準 (LinuxFilesystemHierarchyStandard:http://www.pathname.com/fhs/)中正式化了。GNU 工具集,包括automake和autoconf使遵從這些標準變得很容易。然而,有時候你可能不想使用GNU工具集,例如,你也許需要一個統一的在 Windows和MacOS平臺上都能工作的編譯工具(一些工具確實能在Windows平臺上工作,它們使用Cygnus的“Cygwin”環境,參看 http://sourceware.cygnus.com/cygwin)。

  如果使用了autoconf和automake,除了編譯應用程序,用戶並不需要有這些工具。使用這些工具的目的是創建能在用戶環境使用的、可 移植的shell腳本和Makefile文件。Autoconf實際上是一個工具集,其中包含aclocal、autoheader和autoconf等 可執行文件。這些工具生成一個可移植的shell腳本—configure,configure和軟件包一起發佈給用戶。它探查編譯系統,生成 Makefile文件和一個特殊的頭文件config.h。由configure生成的文件能適應用戶系統的特定環境。configure腳本從一個稱爲 Makefile.in的模板文件生成每個Makefile文件。

  automake由一個手寫的Makefile.am生成Makefile.in文件。Makefile.in文件隨軟件一同發佈,當用戶運行 configure時會自動生成Makefile。Libtool軟件包是第三個重要的GNU工具,它的作用是確定共享庫在特定平臺上的特性。因爲共享庫 在不同平臺上可能會有所不同。

  下面有一些Gnome軟件包應該具有的特徵:

  一個README文件,介紹軟件包。

  一個INSTALL文件,解釋怎樣編譯、安裝軟件包。

  一個configure腳本,能使程序自動適應特定平臺的特徵(或者該平臺所缺乏的特性)。configure可以帶一個參數--prefix,指定要安裝的軟件包的位置。標準的make目標,比如clean等等。

  一個COPYING文件,包含軟件包的版權信息。

  一個ChangeLog文件,記錄了軟件的變化。

  打包文件,一般用gzip壓縮,在名字中包含軟件包的版本(例如foo-0.2.1.tar.gz)。它們應該解開到單個目錄中,目錄應該以軟件包及其版本命名,比如foo-0.2.1。

  國際化是由GNUgettext軟件包提供的。將gettext軟件包隨應用程序提供給用戶,這樣用戶沒有gettext也能夠實現國際化。

  下面是創建Gtk+/Gnome應用程序源代碼樹框架的重要步驟:

  1)創建一個頂級目錄,用以容納應用程序的所有組件,包括編譯文件、文檔以及翻譯文件。

  2)通常在頂級目錄下創建一個src子目錄,將所有的源代碼放在該目錄下,並與其他文件分開。

  3)在頂級目錄下,創建AUTHORS、NEWS、COPYING和README文件。還可以創建一個空的ChangeLog文件。

  4)寫一個configure.in文件;configure.in文件的主要作用是決定使用什麼樣的編譯器、編譯標誌以及鏈接標誌。configure.in還可以使用#define符號反映當前平臺的特徵;它把這些優先放在自動生成的config.h文件裏。

  5)寫一個acconfig.h文件。它是config.h.in文件要使用的模板文件。這個文件應該撤銷每個可能在config.h中定義了 的符號以避免重複定義(一般在config.h中用#define定義,用#undef撤銷定義)autoheader程序基於acconfig.h創建 config.h.in文件,autoconf程序創建config.h文件。autoheader是autoconf軟件包中的實用程序。

  6)創建一個空的stamp.h.in文件。在configure.in中的AM_CONFIG_HEADER宏會用到它。

  7)在頂級目錄下,寫一個Makefile.am文件,在其中列出每個包含源代碼的子目錄;在每個子目錄中也寫一個Makefile.am文件。

  8)運行gettext軟件包中的gettextize程序。這樣可以創建intl和po目錄,這是軟件國際化所需要的。在intl目錄中包含 GNUgettext源代碼。如果編譯程序的用戶沒有gettext,它們可以在執行configure腳本時傳一個--with-included- gettext參數,讓configure在intl目錄下自動編譯一個gettext的靜態版本。在po容納了翻譯文件後,gettextize也會創 建一個稱爲po/Makefile.in.in的文件,用於編譯翻譯文件。

  9)創建一個po/POTFILES.in文件,在其中列出應該掃描字符串以便翻譯的源文件。最初的POTFILES.in文件可以是空的。

  10)從其他的Gnome模塊中複製一個autogen.sh文件和它的宏目錄。必須根據自己的軟件包的名稱修改autogen.sh文件。運 行autogen.sh文件將調用libtoolize、aclocal、autoheader、automake以及autoconf。

  11)autogen.sh用--add-missing參數調用文件automake。這會添加一些文件,比如帶有通用安裝指導的 INSTALL文件。編輯INSTALL,在其中包含任何針對應用程序的安裝指南。autogen.sh會在每個目錄下創建一個Makefile。

  2.11.2configure.in文件

  autoconf處理configure.in文件,生成一個configure腳本。configure是一個可移植的shell腳本,它檢 查編譯環境以決定哪些庫可用,所用平臺有什麼特徵,哪些庫和頭文件已經找到等等。基於這些信息,它修改編譯標記,生成Makefile文件,並/或輸出一 個包含已定義的預處理符號的config.h文件。configure並不需要運行autoconf,所以在發佈應用程序之前生成這個文件,這樣,用戶就 不必有autoconf軟件包。
眼前的任務就是寫一個configure.in文件。文件基本上是一系列的m4宏,根據傳遞給它們的參數,這些宏 擴展爲shell腳本代碼段。還可以手工書寫shell代碼。要真正理解怎樣寫configure.in文件要求有一些m4的知識以及一些 Bourneshell的知識。幸運的是,有省事的方法;可以找一個已有的configure.in文件,然後修改它以適應你的應用程序。還有一個很全面 的autoconf手冊,裏面介紹了很多隨autoconf發佈的預先寫好的宏。
Gtk+和Gnome的開發者已經進一步簡化了這些工作,提供了一些宏用於在用戶的系統中定位Gtk+和Gnome。
下面是一個簡單的configure.in文件,來自於Gnome版的“Hello,World”:

  AC_INIT(src/hello.c)
  AM_CONFIG_HEADER(config.h)
  AM_INIT_AUTOMAKE(GnomeHello,0.1)
  AM_MAINTAINER_MODE
  AM_ACLOCAL_INCLUDE(macros)
  GNOME_INIT
  AC_PROG_CC
  AC_ISC_POSIX
  AC_HEADER_STDC
  AC_ARG_PROGRAM
  AM_PROG_LIBTOOL
  GNOME_COMPILE_WARNINGS
  ALL_LINGUAS="deesfrnorusvfi"
  AM_GNU_GETTEXT
  AC_SUBST(CFLAGS)
  AC_SUBST(CPPFLAGS)
  AC_SUBST(LDFLAGS)
  AC_OUTPUT([
   Makefile
   macros/Makefile
   src/Makefile
   intl/Makefile
   po/Makefile.in
   pixmaps/Makefile
   doc/Makefile
   doc/C/Makefile
   doc/es/Makefile
  ])

  上面以AC開頭的宏來自autoconf,以AM開頭的宏來自automake。要從autoconf或 automake中尋求幫助,這一點很有用。以GNOME開頭的宏來自於Gnomemacros目錄。這些宏都是用m4宏語言寫的。如果將 autoconf和automake安裝在/usr目錄下,autoconf和automake中的標準宏一般放在/usr/share/aclocal 目錄下。

  AC_INIT總是configure.in中的第一個宏。它擴展爲許多可由其他configure腳本共享的模板文件代碼。這些代碼解析傳到 configure中的命令行參數。這個宏的一個參數是一個文件名,這個文件應該在源代碼目錄中,它用於健全性檢查,以保證configure腳本已正確 定位源文件目錄。

  AM_CONFIG_HEADER指定了要創建的頭文件,差不多總是config.h。創建的頭文件包含由configure定義的C預處理符 號。最低限度應該定義PACKAGE和VERSION符號,這樣可以將應用程序名稱和版本傳送到代碼中,而無須對它們硬編碼(非公用的源文件應該包含 config.h(#include<config.h>)以利用這些定義。然而,不要將config.h文件安裝到系統中,因爲它有可能與 其他的軟件包衝突)。

  AM_INIT_AUTOMAKE初始化automake。傳到這個宏裏的參數是要編譯的應用程序的名稱和版本號(這些參數成爲config.h中定義的PACKAGE和VERSION值)。

  AM_MAINTAINER_MODE關閉缺省時僅供程序維護者使用的makefile目標,並修改以使configure能理解 --enable-maintainer-mode選項。--enable-maintainer-mode將maintaineronly目標重新打 開。僅供維護者使用的makefile目標允許最終用戶清除自動生成的文件, 比如configure,這意味着要修復編譯故障,必須安裝有autoconf和automake軟件。注意, 因爲autogen.sh腳本主要是給開發人員用的,autogen.sh會自動傳遞一個--enable- maintainer-mode選項給configure。

  AM_ACLOCAL_INCLUDE指定一個附加的目錄,用於搜索m4宏。在這裏,它指定爲macros子目錄。在這個目錄中應該有Gnome宏的拷貝。

  GNOME_INIT給configure添加一個與Gnome相關的命令行參數個數,併爲Gnome程序定義一些makefile變量,這些 變量中包含了必要的預處理程序和鏈接程序標誌。這些標誌是由gnome-config腳本取得的。安裝gnome-libs時會安裝gnome- config腳本。

  AC_PROG_CC定位C編譯器。

  AC_ISC_POSIX添加一些在某些平臺上實現POSIX兼容需要的標誌。

  AC_HEADER_STDC檢查當前平臺上是否有標準的ANSI頭文件,如果有,則定義STDC_HEADERS。

  AC_ARG_PROGRAM添加一些選項到configure中,讓用戶能夠修改安裝程序的名稱(如果在用戶系統上碰巧有一個與要安裝的程序名稱相同的程序,這是很有用的)。

  AM_PROG_LIBTOOL是由automake用來設置libtool的用途的。只在計劃編譯共享庫或動態可加載模塊時才需要設置這個值。

  GNOME_COMPILE_WARNINGS給gcc命令行添加許多警告選項,但是在其他絕大多數的編譯器上什麼也不做。

  ALL_LINGUAS=“es”不是一個宏,只是一句shell代碼。它包含一個由空格分隔的語言種類縮寫表,對應於po子目錄下的.po文件。.po文件包含翻譯成其他語言的文本,所以ALL_LINGUAS應該列出程序已經被翻譯成的所有語言。

  AM_GNU_GETTEXT由automake使用,但是這個宏會隨gettext軟件包發佈。它讓 automake執行一些與國際化相關的任務。

  AC_SUBST輸出一個變量到由configure生成的文件中。具體內容將在後面說明。

  AC_OUTPUT列出由configure腳本創建的文件。這些文件都是由帶.in後綴的同名文件生成的。例如,src/Makefile是 由src/Makefile.in生成的,config.h是由config.h.in生成的。在執行AC_OUTPUT宏時,configure腳本處 理包含有兩個@符號標誌的變量(例如@PACKAGE@)的文件。只有用AC_SUBST輸出了變量,它才能識別這些變量(許多在上面討論過的預先寫好的 宏都用AC_SUBST定義變量)。這些特徵用於將一個Makefile.in文件轉換成一個Makefile文件。典型情況下,Makefile.in 是由automake從Makefile.am生成的(不過,你可以只用autoconf,而不用automake,自己編寫一個 Makefile.in)。

  2.11.3Makefile.am文件

  automake處理Makefile.am,生成一個符合標準的Makefile.in文件。automake會做很多工作:例如,它維護源 文件之間的依賴關係;生成所有的標準目標,比如install和clean;它還生成更復雜的目標:如果Makefile.am是正確的,簡單輸入 makedist就會創建一個標準的.tar.gz文件。

  一般情況是在最上層目錄下寫一個Makefile.am,然後在每一個子目錄下分別寫一個Makefile.am文件。automake會從最 上層開始遞歸處理各個Makefile.am,然後生成一個Makefile.in。在最上層目錄的Makefile.am通常都很簡單,下面是一個例 子:

  SUBDIRS=macrospointlsrcpixmapsdoc
  EXTRA_DIST=/
  gnome-hello.desktop
  Applicationsdir=$(datadir)/gnome/apps/Applications
  Applications_DATA=gnome-hello.desktop

  上面程序的第一行通知automake在給定的子目錄中遞歸查找Makefile.am文件。在src子目錄的Makefile.am是這樣的:

  INCLUDES=-I$(top_srcdir)-I$(includedir)$(GNOME_INCLUDEDIR)/
  -DG_LOG_DOMAIN=/"GnomeHello/"
  -DGNOMELOCALEDIR=/""$(datadir)/locale"/"/
  -I../intl-I$(top_srcdir)/intl
  bin_PROGRAMS=gnome-hello
  gnome_hello_SOURCES=/
  app.c/
  hello.c/
  menus.c/
  app.h/
  hello.h/
  menus.h
  gnome_hello_LDADD=$(GNOMEUI_LIBS)$(GNOME_LIBDIR)$(INTLLIBS)

  automake能夠理解許多“不可思議的變量”,並用這些變量創建Makefile.in文件。在上面的小例子中,用到了下面的變量:

  INCLUDES指定了在編譯階段(與連接階段相對)中傳遞給C編譯器的標誌。這一行用到的變量來自

  2.11.2節中的configure.in文件。

  bin_PROGRAMS列出了要編譯的程序。

  hello_SOURCES列出了要編譯和連接的文件,這些文件是依賴生成hello程序的。程序名必須列在bin_PROGRAMS中。在這個變量中的所有文件都被自動包含在發佈包中。

  hello_LDADD列出了要傳遞給連接程序的標誌。在這個例子中是由configure決定的Gnome庫標誌。

  INCLUDES行中有幾個在所有的Gnome程序中都應該用到的元素。應該定義G_LOG_DOMAIN,來自與校驗和斷言代碼中的錯誤信息 會報告這個值,這樣就能夠判定錯誤是發生在什麼地方(在代碼中,還是在一個庫中)。GNOMELOCALEDIR用於定位翻譯文件。intl目錄被添加到 了頭文件的搜索路徑,這樣應用程序就能夠找到intl頭文件。

  在Makefile.am中還可以做很多複雜的事,特別是,可以添加兩端帶有@符號的、能帶入到configure腳本中的變量。可以有條件地包含基於configure校驗的Makefile文件中的一部分,還可以建立庫。automake的手冊介紹了細節內容。

  表2-1概括了由automake生成的最常見的make目標。當然,缺省的make目標是all,它編譯整個程序。GNU代碼標準 (http://www.gnu.org/prep/standards_toc.html)中有這些make目標和GNUMakefile文件的詳細信 息。

  2.11.4安裝支持文件

  完整的Gnome應用程序還有許多代碼以外的東西。它們有在線幫助(要列在Gnome的主菜單上),有界面翻譯,還有一個桌面圖標。它們也許帶 一個pixmap以及一個用在“關於”對話框上的徽標、一個用於“嚮導”的圖形或者一個用以幫助用戶快速區別菜單項或列表元素的小圖標。下面的內容介紹怎 樣發佈這些文件。

  1.安裝數據文件:文檔和pixmap

  文檔和pixmap的安裝方法是差不多的。automake允許你將數據文件安裝到任意位置,可以用配置文件中定義的變量決定將它們安裝到哪裏。

  (1)pixmap

  要從Makefile.am中安裝數據文件,只需簡單地爲安裝目標指定一個名字(pixmap就不錯)然後爲該目錄和要安裝到目錄裏的文件分別創建一個變量。例如:

  EXTRA_DIST=gnome-hello-logo.png
  pixmapdir=$(datadir)/pixmaps
  pixmap_DATA=gnome-hello-logo.png
  fill

  “pixmap”字符串將pixmap_DATA變量和pixmapdir變量連接起來。automake解釋_DATA前綴,並在 Makefile.in中生成適當的安裝規則。這個Makefile.am片斷將gnome-hello-logo.png文件安裝 到$(datadir)/pixmaps目錄下,$(datadir)是由configure分配的變量。典型情況下,$(datadir)是/usr /local/share(更精確的說,是$(prefix)/share),這是獨立於體系結構的數據文件(也就是,幾個具有不同二進制文件格式的系統 共享的文件)的標準位置。

  Gnome的pixmap圖片的標準位置是$(datadir)/pixmaps,所以在例子中我們這樣用。Gnome項目鼓勵在所有的 pixmap圖片中使用PNG格式,這個格式是gdk_imlib(Gnome圖象加載庫)支持的。它的文件尺寸小,速度快,也不存在專利問題。

  (2)文檔

  安裝文檔使用同樣的原則,不過稍有一點複雜。Gnome文檔通常是用DocBook寫的。DocBook是一個 SGMLDTD(DocumentTypeDefinition,文檔類型定義),就像HTML一樣。然而,DocBook的文檔標籤是爲技術文檔設計 的。用DocBook寫的文檔可以轉換爲其他格式,包括PostScript和HTML。依照標準,應該安裝HTML格式的文檔,用戶就可以用Web瀏覽 器或Gnome幫助瀏覽器閱讀文檔。

  Gnome庫和幫助瀏覽器能理解一個名爲topic.dat的文件,這個文件只是一個含有相應URL的幫助主題列表。它起應用程序幫助主題索引的作用。下面是一個例子,只有兩條:

  gnome-hello.htmlGnomeHellomanual
  advanced.htmlAdvancedTopics
  URL路徑相對於所安裝的幫助文件的目錄。

  應該預先考慮文檔可能會翻譯爲其他語言。最好爲每一個地區建立一個子目錄,例如,缺省地區(C)或es(西班牙語)。使用這種方法翻譯程序不會 引起混亂。一般將Gnome幫助安裝在以地區開頭的目錄下,這種做法用其他觀點來看也是很方便的。文檔目錄看起來也許和GnomeHello示例程序差不 多:

  doc/
  Makefile.am
  C/
  Makefile.am
  gnome-hello.sgml
  topic.dat
  es/
  Makefile.am
  gnome-hello.sgml
  topic.dat

  下面是doc/C/Makefile.am:

  gnome_hello_helpdir=$(datadir)/gnome/help/gnome-hello/C
  gnome_hello_help_DATA=/
  gnome-hello.html/
  topic.dat
  SGML_FILES=/
  gnome-hello.sgml
  #filesthataren’tinabinary/data/librarytargethavetobelistedhere
  #tobeincludedinthetarballwhenyou‘makedist’
  EXTRA_DIST=/
  topic.dat/
  $(SGML_FILES)
  ##The-beforethecommandmeanstoignoreitifitfails.Thatway
  ##peoplecanstillbuildthesoftwarewithoutthedocbooktools
  all:
  gnome-hello.html:gnome-hello/gnome-hello.html
  -cpgnome-hello/gnome-hello.html.
  gnome-hello/gnome-hello.html:$(SGML_FILES)
  -db2htmlgnome-hello.sgml
  ##whenwemakedist,weincludethegeneratedHTMLsopeopledon’t
  ##havetohavethedocbooktools
  dist-hook:
  mkdir$(distdir)/gnome-hello
  -cpgnome-hello/*.htmlgnome-hello/*.css$(distdir)/gnome-hello
  -cpgnome-hello.html$(distdir)
  install-data-local:gnome-hello.html
  $(mkinstalldirs)$(gnome_hello_helpdir)/images
  -forfilein$(srcdir)/gnome-hello/*.html$(srcdir)/gnome-hello/*.css;do/
  basefile=`basename$$file`;/
  $(INSTALL_DATA)$(srcdir)/$$file$(gnome_hello_helpdir)/$$basefile;/
  done
  gnome-hello.ps:gnome-hello.sgml
  -db2ps$<
  gnome-hello.rtf:gnome-hello.sgml
  -db2rtf$<

  需要特別注意的是生成的HTML文件的安裝目錄:$(datadir)/gnome/help/gnome-hello/C。Gnome庫在這 裏查找幫助文件。每個應用程序的幫助都放在$(datadir)/gnome/help下的它自己的目錄下。每個地區的文檔都安裝在應用程序目錄的對應於 地區的子目錄下。

  2..desktop入口

  Gnome程序帶有一個.desktop入口,它是一個以desktop爲後綴的文本文件,描述應用程序應該放在Gnome主菜單的什麼位置。 安裝一個.desktop入口文件可以讓應用程序顯示在Gnome面板菜單(主菜單)中。下面是gnome-hello.desktop文件:

  [DesktopEntry]
  Name=GnomeHello
  Name[es]=GnomeHola
  Name[fi]=GNOME-hei
  Name[no]=Gnomehallo
  Name[sv]=GnomeHej
  Comment=HelloWorld
  Comment[es]=HolaMundo
  Comment[fi]=Hei,maailma
  Comment[sv]=HejV?rlden
  Comment[no]=Halloverden
  Exec=gnome-hello
  Icon=gnome-hello-logo.png
  Terminal=0
  Type=Application

  這個文件由鍵-值對組成。Name鍵指定在缺省地區場合的名稱;任何鍵都可以有一個用於標明地區的字符串,放在一對方括號裏面。當登錄到X窗口 時,如果指定了不同的地區,系統會根據語言從這裏讀取相應的字符串。Comment鍵是一個“工具提示”或“暗示”,用以更詳細地描述應用程序。Exec 是用來執行程序的命令行。Terminal是布爾類型,如果爲非0值,程序在一個終端內運行。在這裏Type應該是“Application”
安裝一個.desktop條目很簡單。下面是GnomeHello中的最頂層的Makefile.am文件:

  SUBDIRS=macrospointlsrcpixmapsdoc
  EXTRA_DIST=/
  gnome-hello.desktop
  Applicationsdir=$(datadir)/gnome/apps/Applications
  Applications_DATA=gnome-hello.desktop

  注意,在$(datadir)/gnome/apps/下有一個目錄樹,可以將應用程序安裝到下面子目錄所對應的類別中。GnomeHello 將自己安裝在“Applications”類中,而其他的應用程序也許會選擇Games、Graphics、Internet或者其他合適的地方。儘量選 擇一個已經存在的類別,而不是自己建一個。

  Makefile.am中的EXTRA_DIST變量列出了需要包含在發佈軟件包(壓縮的tar文件)中的文件。最重要的文件會自動包含進來,例如,所有作爲二進制或庫的源文件的文件都會自動包含。

  然而,automake並不認識.desktop文件,或SGML文檔,所有這些文件必須列在EXTRA_DIST中。如果將這些文件留在EXTRA_DIST之外,用makedistcheck命令編譯發佈程序通常會失敗。

發佈了18 篇原創文章 · 獲贊 3 · 訪問量 8萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章