使用 GNU autotools 改造一個軟件項目

使用 GNU autotools 改造一個軟件項目

及永剛

[email protected]

2006 年 3 月 24 日  版本:0.3

本文不是一篇規範的教程,而是用一個軟件項目作爲例子,演示使用 GNU autotools 進行軟件管理的思路和過程。

目 錄 

 

 

示例項目

這裏借用了 Wei Mingzhi <[email protected]> 開發的麻將遊戲來進行演示,在此,先對他表示感謝!

示例軟件下載:

http://planet.time.net.my/TechnologyPark/semj/mahjong.tar.bz2

 

軟件佈局

將下載的軟件包解壓到一個目錄

 

$ cd ~/work
$ tar xjf mahjong.tar.bz2

可以看到這是一個典型的 Windows 風格的軟件項目佈局,在 mahjong 目錄下放着程序的源碼,程序運行時使用的數據文件放在子目錄下面。

作者還提供了一個 Makefile,一個 DOS 風格的 !play.bat 批處理文件,一個編譯好的 mj.exe 可執行文件。在 Win32 平臺上運行 !play.bat 就可以直接運行程序。在 Unix/Linux 系統上,進入 mahjong 目錄,鍵入 make 命令,如果一切順利的話,將生成 mj 可執行文件,然後在命令行上運行 ./mj 程序,也可以啓動麻將遊戲。

對於一個 Windows 程序來講,該軟件佈局可以說非常清晰明瞭。但在 Unix/Linux 系統上,執行 make 命令就可能遇到問題:編譯找不到頭文件,或者連接找不到庫文件。而在 make 成功以後,運行麻將程序必須先進入該 majiong 目錄,才能執行程序。如果要像其他的程序一樣,可以在任意目錄使用,就要專門爲這一個程序修改 PATH 環境變量,或者再寫一個啓動腳本,並將它複製到 /usr/bin 這樣的目錄下。

 

Makefile 分析

 

 1  #
 2  # Copyright (c) 2005, Wei Mingzhi. All rights reserved.
 3  #
 4  # Use, redistributions and modifications of this file is
 5  # unrestricted provided the above copyright notice is
 6  # preserved.
 7  #
 8  
 9  OBJ = /
10          bot.o config.o game.o general.o hand.o ini.o main.o /
11          player.o text.o tile.o util.o
12  
13  HEADERS = /
14          bot.h game.h general.h hand.h ini.h main.h player.h /
15          tile.h
16  
17  CC = gcc
18  CXX = g++
19  
20  TARGET = mj
21  
22  BASEFLAGS = -g3 -D_DEBUG=1
23  #BASEFLAGS = -s -O3
24  
25  CFLAGS = ${BASEFLAGS} `sdl-config --cflags`
26  LDFLAGS = ${BASEFLAGS} `sdl-config --libs` -lSDL_image /
27            -lSDL_mixer -lSDL_ttf
28  
29  all: ${TARGET}
30  
31  ${TARGET}: ${OBJ}
32          ${CXX} ${LDFLAGS} -o ${TARGET} ${OBJ}
33  
34  clean:
35          rm -f *.o ${TARGET}
36  
37  distclean:
38          rm -f *.o ${TARGET}
39  
40  %.o:    %.cpp ${HEADERS}
41          ${CXX} ${CFLAGS} -c ___FCKpd___1lt; -o $@
42  
43  %.o:    %.c ${HEADERS}
44          ${CC} ${CFLAGS} -c ___FCKpd___1lt; -o $@

Makefile 很清楚:第 20 行定義 TARGET 變量爲 mj,第 29 行表明 make 默認的 target 也就是生成 `mj';第 17 行加入編譯時的調試信息;第 25、26、27 行使用了 sdl-config 工具偵測 SDL 開發庫編譯鏈接信息,在 26、27 行還指明需要連接 SDL_image、SDL_mixser 和 SDL_ttf 庫。

 

GNU 的軟件風格

一個標準的 GNU 軟件,編譯安裝都是使用下面三個步驟:

 

$ ./configure
$ make
$ make install

configure 腳本運行時可以偵測系統的環境,確定軟件安裝目錄,然後生成 Makefile 文件。make 調用系統中的編譯器進行編譯和連接。make install 將軟件安裝到設定的目錄。

用戶執行 configure 時可以通過它的命令行參數指定自己所需的編譯選項,比如安裝目錄通過 --prefix=PREFIX 設置,如果不指定,缺省情況下 PREFIX 是 /usr/local。默認安裝時,執行文件安裝到 /usr/local/bin 目錄,庫安裝到 /usr/local/lib 目錄,數據文件安裝到 /usr/local/share 目錄。

由於 GNU 的軟件風格方便易用,通用性好,可移植性高,現在大多數 Unix/Linux 系統上的自由軟件都採用這種方式分發軟件。

 

準備 autotools

GNU autotools 主要包含三個軟件: autoconf,automake 和 libtool。當前流行的有新舊兩個版本,本例採用的是新版本,分別對應的是: autoconf 2.59,automake 1.9.6 和 libtool 1.5.18。

很多 linux 發行版都會默認安裝這幾個工具。本例是在 NetBSD 下進行操作,安裝這幾個軟件包是通過 pkgsrc,它們在 pkgsrc 目錄爲 devel/autoconf、devel/automake 和 devel/libtool。

 

改造文件佈局

原來軟件的根目錄下面放的是程序的源碼,按照 GNU 的習慣,將它們放到 src 子目錄,根目錄留給 configure 這類文件使用,其他的數據文件保持不變,仍然放在各自的子目錄。

先創建一個目錄 majiang,然後根據需要將 mahjong 目錄下的文件複製過來。由於是爲 Unix/Linux 系統進行改寫,原目錄裏的 win32 相關文件就不用複製到新目錄。

 

$ cd ~/work/majiang
$ ls
data/  docs/  fonts/  images/  music/  sound/  src/

 

autoscan

autoconf 軟件包裏面的 autoscan 工具可以掃描工作目錄,生成一個 configure.ac 的模板文件 configure.scan。

 

$ cd ~/work/majiang
$ autoscan

autoscan 命令在當前目錄生成的 configure.scan 文件內容爲:

 

 1  #                                               -*- Autoconf -*-
 2  # Process this file with autoconf to produce a configure script.
 3  
 4  AC_PREREQ(2.59)
 5  AC_INIT(FULL-PACKAGE-NAME, VERSION, BUG-REPORT-ADDRESS)
 6  AC_CONFIG_SRCDIR([src/bot.h])
 7  AC_CONFIG_HEADER([config.h])
 8  
 9  # Checks for programs.
10  AC_PROG_CXX
11  AC_PROG_CC
12  
13  # Checks for libraries.
14  
15  # Checks for header files.
16  AC_HEADER_STDC
17  AC_CHECK_HEADERS([limits.h malloc.h stdlib.h string.h unistd.h])
18  
19  # Checks for typedefs, structures, and compiler characteristics.
20  AC_HEADER_STDBOOL
21  AC_C_CONST
22  AC_C_INLINE
23  
24  # Checks for library functions.
25  AC_FUNC_MALLOC
26  AC_FUNC_REALLOC
27  AC_CHECK_FUNCS([memset strcasecmp strchr strdup])
28  AC_OUTPUT

# 號開始的行是註釋,其他都是 m4 宏命令。將它改名爲 configure.ac,然後在此基礎上進行修改。

 

configure.ac 的基本結構

configure.ac 文件是 autoconf 的輸入文件,經過 autoconf 處理,展開裏面的 m4 宏,輸出的是 configure 腳本。

第 4 行聲明本文件要求的 autoconf 版本,因爲本例使用了新版本 2.59,所以在此註明。

第 5 行 AC_INIT 宏用來定義軟件的名稱和版本等信息,本例寫成:

 

AC_INIT(majiang, 1.0)

這裏省略了 BUG-REPORT-ADDRESS 參數,它是可選項,一般寫成作者的郵件地址。

第 6 行 AC_CONFIG_SRCDIR 宏通過偵測所指定的源碼文件是否存在,來確定源碼目錄的有效性。可以選擇源碼目錄中的任何一個文件作爲代表,比如將 autoscan 選擇的 bot.h 文件改成 main.cpp:

 

AC_CONFIG_SRCDIR([src/main.cpp])

宏參數中使用 `[ ]',是爲了表明其中的字符串是一個整體。

第 7 行的 AC_CONFIG_HEADER 宏用於生成 config.h 文件,裏面存放 configure 腳本偵測到的信息。如果程序需要使用其中的定義,就在源碼中加入

 

#include <config.h>

其他的一些宏是標準的偵測過程,可以保留不動。

configure.ac 文件要求 AC_INIT 宏必須放在開頭位置,AC_OUTPUT 放在文件末,中間用來檢測編譯環境的各種宏沒有特別的先後次序要求,由宏之間相互關係決定。

 

Makefile 文件的產生

前面 configure.ac 裏面的宏,主要作用是偵測系統,並沒有編譯相關的設置。因爲這些信息是寫在 Makefile.am 裏面,然後用 automake 工具轉換成 Makefile.in,configure 腳本執行時再讀取 Makefile.in,並與偵測信息一起寫到 Makefile 文件。

在 autotools 的命名習慣中,後綴 ac 的文件是 autoconf 的輸入文件,後綴 am 的文件是 automake 的輸入文件,後綴 in 的文件是 configure 的輸入文件。autoconf 舊版本中 configure.in 等同於 configure.ac,雖然新版本也可以識別,但它不符合命名規則,所以新版本的文件應該使用 ac 後綴。

簡單的 Makefile.in 可以手動編寫,如果使用 automake 產生,需要在 configure.ac 裏面加入 AM_INIT_AUTOMAKE 宏進行聲明。

要輸出 Makefile,還需要在 configure.ac 中使用 AC_CONFIG_FILES 宏指明。該宏並不是只處理 Makefile,而是將 FILE.in 文件轉換爲 FILE 文件。因爲 make 可以遍歷子目錄,如果子目錄中存在 Makefile,也將同時處理。在本例中 src 目錄下是源碼,其他是數據文件,可以使用單獨一個 Makefile 放在根目錄下面,也可以用多個 Makefile。由於每個子目錄的 Makefile 只處理本目錄的文件,分工明確,是模塊化的方法,推薦使用。因此在 configure.ac 裏面增加下面的宏,表示軟件根目錄和子目錄中都需要生成 Makefile 文件:

 

AC_CONFIG_FILES([Makefile 
                 src/Makefile
                 data/Makefile
                 docs/Makefile
                 fonts/Makefile
                 images/Makefile
                 music/Makefile
                 sound/Makefile])

 

編寫 Makefile.am

 

軟件根目錄 Makefile.am

由於該目錄下面保存的是與 autotools 相關的文件,沒有需要編譯安裝的文件,所以只註明需要進一步處理的子目錄信息:

 

SUBDIRS = src data docs fonts images music sound

 

src/Makefile.am

此目錄裏是源代碼,最終生成 mj 可執行文件,在其 Makefile.am 中寫入

 

bin_PROGRAMS = mj

mj_SOURCES = bot.h /
             bot.cpp /
             config.cpp /
             game.h /
             game.cpp /
             general.h /
             general.cpp /
             hand.h /
             hand.cpp /
             ini.h /
             ini.cpp /
             main.h /
             main.cpp /
             player.h /
             player.cpp /
             text.cpp /
             tile.h /
             tile.cpp /
             util.cpp

am 文件裏變量通過命名判斷其含義,保留的字符串間用下劃線分隔。

bin_PROGRAMS 表示列出二進制的程序,值爲多個空格分開的程序列表,這裏僅有一個 mj。

mj_SOURCES 列出的是組成 mj 程序的文件,文件比較多的時候,每個文件寫成一行容易看清楚。

 

data/Makefile.am

本目錄的文件是 mj 運行時讀取的數據,它的 Makefile.am 可以這樣寫

 

mjdatadir = $(pkgdatadir)/data
mjdata_DATA = mj.ini titles.txt
EXTRA_DIST = $(mjdata_DATA)

因爲 datadir 是保留的關鍵字,所以用 mjdatadir 代替,pkgdatadir 指向 $prefix/share/FULL-PACKAGE-NAME 目錄,因爲在 AC_INIT 中已經聲明 FULL-PACKAGE-NAME 爲 majiang,pkgdatadir 就等於 $prefix/share/majiang 目錄。

其中 mjdatadir 讓 data 目錄下的文件安裝到 $prefix/share/majiang/data 目錄裏面。

mjdata_DATA 列出此目錄下需要安裝的文件,然後用 EXTRA_DIST 變量註明。

餘下幾個子目錄都與 data 目錄類似。

 

docs/Makefile.am

 

docsdir = $(pkgdatadir)/docs
docs_DATA = gkai00mp.txt  gpl.html  readme.txt
EXTRA_DIST = $(docs_DATA)

 

fonts/Makefile.am

 

fontsdir = $(pkgdatadir)/fonts
fonts_DATA = brush.ttf  gkai00mp.ttf
EXTRA_DIST = $(fonts_DATA)

 

images/Makefile.am

 

imagesdir = $(pkgdatadir)/images
images_DATA =   bgame.jpg /
                mjgirl1a.jpg /
                mjgirl2a.jpg /
                mjgirl3a.jpg /
                mjgirl4a.jpg /
                tiles.jpg /
                electron.jpg /
                mjgirl1b.jpg /
                mjgirl2b.jpg /
                mjgirl3b.jpg /
                mjgirl4b.jpg /
                gameover.jpg /
                mjgirl1c.jpg /
                mjgirl2c.jpg /
                mjgirl3c.jpg /
                mjgirl4c.jpg
EXTRA_DIST = $(images_DATA)

 

music/Makefile.am

 

musicdir = $(pkgdatadir)/music
music_DATA =    bet.ogg /
                bonus.ogg /
                music.ogg /
                musicb.ogg /
                musice.ogg /
                win.ogg /
                bgame.ogg /
                gameover.ogg /
                music1.ogg /
                musicc.ogg /
                musicp.ogg
EXTRA_DIST = $(music_DATA)

 

sound/Makefile.am

 

sounddir = $(pkgdatadir)/sound
sound_DATA =    boom.wav /
                ding.wav /
                discard.wav /
                discard2.wav /
                flash.wav /
                snd1.wav /
                snd2.wav /
                snd3.wav /
                snd4.wav
EXTRA_DIST = $(sound_DATA)

 

運行 autotools

準備好 configure.ac 和 Makefile.am,就可以用 autotools 的命令處理這些文件。開始可能會出現錯誤,不過沒關係,可以按照錯誤信息的提示逐步進行修正。

首先要使用的是 aclocal 命令,它根據 configure.ac 的定義,將需要使用的 m4 宏定義複製到 aclocal.m4 裏面。缺省時,搜索 m4 宏是從 autoconf 的安裝目錄和系統的 aclocal 目錄。如果需要使用其他路徑下的宏,可以通過命令行的 -I 選項指定。

接着使用 autoheader 命令,它負責生成 config.h.in 文件,這裏面的 C 語言宏定義也是通過解析 configure.ac 產生。

下來運行 automake 命令處理 Makefile.am,生成 Makefile.in。GNU 對自己發佈的軟件有嚴格的規範,比如必須附帶許可證聲明文件 COPYING 等等,否則 automake 執行時會報錯。automake 提供了三種軟件等級: foreign、gnu 和 gnits,讓用戶選擇採用,默認等級爲 gnu。本例使用 foreign 等級,它只檢測必須的文件。有一些必需的腳本文件可以從 automake 軟件包裏複製過來,在執行時使用 --add-missing 選項可以讓 automake 自動添加,默認方式是採用符號鏈接,如加上 --copy 選項則可以使用複製方式。本例中,automake 的命令如下:

 

$ automake --foreign --add-missing --copy

最後,使用 autoconf 命令生成 configure 腳本文件。

 

SDL 庫的偵測

這個麻將遊戲是基於 SDL 庫開發的,一般系統默認不會安裝,因此 configure 腳本的一個任務就是檢查用戶的系統中是否有該軟件包。

autoconf 提供了很多宏可以實現偵測功能,但首先應該查看 SDL 軟件包是否已經提供相應的宏。通過 pkgsrc 的工具可以看到:

 

$ pkg_info -L SDL|grep m4
/usr/pkg/share/aclocal/sdl.m4

即 SDL 軟件包提供了一個 sdl.m4 宏,放在系統的 aclocal 目錄下。

在這個宏文件的註釋中說明了使用的方法:

 

dnl AM_PATH_SDL([MINIMUM-VERSION,[ACTION-IF-FOUND[,ACTION-IF-NOT-FOUND]]])
dnl Test for SDL, and define SDL_CFLAGS and SDL_LIBS

也就是說在 configure.ac 裏面調用 AM_PATH_SDL 宏,就可以偵測 SDL。找到 SDL 庫以後,該宏還輸出 SDL_CFLAGS 和 SDL_LIBS 編譯連接選項,它們實際上就是調用 `sdl-config --cflags` 和 `sdl-config --libs`

於是在 configure.ac 裏面加入 AM_PATH_SDL 宏

 

# Checks for libraries.
SDL_VERSION=1.2.0
AM_PATH_SDL($SDL_VERSION,
            :,
	    AC_MSG_ERROR([*** SDL version $SDL_VERSION not found!])
)

當前 SDL 的版本爲 1.2.9,於是 MINIMUM-VERSION 就設爲 1.2.0。如果在系統中偵測到需要的庫,沒什麼額外的操作,假如沒有找到,則給出錯誤信息。

AM_PATH_SDL 輸出 SDL_CFLAGS 和 SDL_LIBS 編譯參數,需要添加到 src/Makefile.am 裏面:

 

mj_CPPFLAGS = @SDL_CFLAGS@
mj_LDFLAGS = @SDL_LIBS@

用 `@' 包圍的變量會在 configure 執行時被替換。

從 mahjong 的 Makefile 中看到,這個軟件還要使用 SDL_image、SDL_mixser 和 SDL_ttf 庫,但它們不屬於 SDL 軟件包,需要另外安裝。由於這些庫在 sdl.m4 中也沒有進行偵測,所以自己要寫一些腳本。

autotools 提供了一個 AC_CHECK_LIB 宏可以用來檢測庫,現在就使用它來檢測這幾個 SDL 庫。該宏的語法爲:

 

AC_CHECK_LIB (LIBRARY, FUNCTION, [ACTION-IF-FOUND],
          [ACTION-IF-NOT-FOUND], [OTHER-LIBRARIES])

第一個參數是庫名,第二個參數是庫中的一個函數,第三個參數是檢測到以後進行的動作,第四個參數是未檢測到以後的動作,第五個參數是其他的庫。

對於 SDL_image、SDL_mixer 和 SDL_ttf 對應的使用方法如下:

 

# Check for SDL_image library
AC_CHECK_LIB(SDL_image, IMG_Load, , AC_MSG_ERROR([
*** Unable to find SDL_image libary with PNG support
(http://www.libsdl.org/projects/SDL_image/)
]), `sdl-config --libs`)

# Check for SDL_mixer library
AC_CHECK_LIB(SDL_mixer, Mix_LoadMUS, , AC_MSG_ERROR([
*** Unable to find SDL_mixer libary with OGG support
(http://www.libsdl.org/projects/SDL_mixer/)
]), `sdl-config --libs`)

# Check for SDL_ttf library
AC_CHECK_LIB(SDL_ttf, TTF_OpenFont, , AC_MSG_ERROR([
*** Unable to find SDL_ttf libary
(http://www.libsdl.org/projects/SDL_ttf/)
]), `sdl-config --libs`)

其中 IMG_Load、Mix_LoadMUS 和 TTF_OpenFont 分別是源碼中調用的函數。

 

軟件使用的數據文件

原來 mj 讀取數據是從執行時目錄的子目錄中讀取,但現在將數據放到 $prefix/share/majiang 目錄下,需要通過一種途徑讓程序可以知道數據文件被安放的位置。

要達到這個目的有很多方法,這裏採用最直接的一種:將數據文件安裝目錄變量通過 CPPFLAGS 編譯參數傳遞給程序。

於是修改 src/Makefile.am 的 CPPFLAGS:

 

mj_CPPFLAGS = @SDL_CFLAGS@ -DDATA_DIR=/"${datadir}/majiang/"

相應地修改 src 目錄下的源碼,在讀取數據文件的地方,將讀取的路徑改成 DATA_DIR 裏對應的子目錄。例如,原先 config.cpp 中是:

 

void LoadCfg()
{
   cfg.Load("data/mj.ini");
}

現改成:

 

void LoadCfg()
{
   cfg.Load(DATA_DIR"data/mj.ini");
}

 

configure 選項

原來 mahjong 的 Makefile 第 22 行定義了 debug 調試選項,雖然也可以照樣放到 src/Makefile.am 的 CPPFLAGS 裏面實現,但 autotools 提供了一種更靈活的機制。

configure 腳本可以通過選項來設置編譯參數,現增加一個 --enable-debug 選項,需要 DEBUG 時,在命令行上加上它來打開,默認則關閉。

這項功能是使用 AC_ARG_ENABLE 宏實現:

 

AC_ARG_ENABLE (FEATURE, HELP-STRING, [ACTION-IF-GIVEN],
          [ACTION-IF-NOT-GIVEN])

其中 FEATURE 是名稱,HELP_STRING 爲說明信息,在使用 ./configure --help 時可以看到。最後兩個分別對應打開和關閉時的操作。

現在將 DEBUG 功能加入 configure.ac:

 

AC_ARG_ENABLE(debug,
	      [  --enable-debug          turn on debug],
	      CXXFLAGS="$CXXFLAGS -g3 -D_DEBUG=1")

 

autotools 腳本

每次修改了 configure.ac 或 Makefile.am 等 autotools 輸入文件後都需要再次運行 aclocal、automake、autoconf 這些命令,爲了方便起見,可以將他們放到一個 shell 腳本里面,例如:

 

#! /bin/sh
set -x
aclocal
autoheader
automake --foreign --add-missing --copy
autoconf

將上面內容保存到 autogen.sh 文件,並修改文件屬性爲 755。每次需要重新生成 configure 腳本時,執行 ./autogen.sh 即可。

 

使用 configure 產生的 Makefile

現在執行 ./autogen.sh 得到的 configure 腳本已經可以正常工作了,進入 ~/work/majiang 目錄,執行 ./configure,可以看到它檢查系統的過程,包括 SDL 和 SDL_image 等庫的偵測結果。使用 ./configure -help 可以看到 autotools 提供的幫助信息。

configure 執行的完畢,輸出軟件根目錄和幾個子目錄下面的 Makefile 文件。這些 Makefile 有幾個常用的 target:

 

  • make all

    不加任何 target,默認就是 all,作用是編譯軟件

     

  • make install

    安裝軟件包,如果安裝到系統目錄,需要 root 權限

     

  • make clean

    清除編譯產生的目標文件

     

  • make distclean

    可以同時清除編譯的結果和 configure 輸出的文件

     

  • make tags

    生成 etags 使用的 TAGS 文件

     

  • make dist

    生成軟件發佈包,爲 tar.gz 格式的壓縮包,文件名由軟件包名和版本組成。

 

最終的 configure.ac 文件

 

#                                               -*- Autoconf -*-
# Process this file with autoconf to produce a configure script.

AC_PREREQ(2.59)
AC_INIT([majiang], [1.0])
AC_CONFIG_SRCDIR([src/main.cpp])
AC_CONFIG_HEADER([config.h])

AC_CANONICAL_HOST
AC_CANONICAL_TARGET
AM_INIT_AUTOMAKE

# Checks for programs.
AC_PROG_CXX
AC_PROG_CC

AC_LANG(C++)

# Checks for libraries.
SDL_VERSION=1.2.0
AM_PATH_SDL($SDL_VERSION,
            :,
	    AC_MSG_ERROR([*** SDL version $SDL_VERSION not found!])
)

# Check for SDL_image library
AC_CHECK_LIB(SDL_image, IMG_LoadPNG_RW, , AC_MSG_ERROR([
*** Unable to find SDL_image libary with PNG support
(http://www.libsdl.org/projects/SDL_image/)
]), `sdl-config --libs`)

# Check for SDL_mixer library
AC_CHECK_LIB(SDL_mixer, Mix_LoadOGG_RW, , AC_MSG_ERROR([
*** Unable to find SDL_mixer libary with OGG support
(http://www.libsdl.org/projects/SDL_mixer/)
]), `sdl-config --libs`)

# Check for SDL_ttf library
AC_CHECK_LIB(SDL_ttf, TTF_OpenFont, , AC_MSG_ERROR([
*** Unable to find SDL_ttf libary
(http://www.libsdl.org/projects/SDL_ttf/)
]), `sdl-config --libs`)

# Checks for header files.
AC_HEADER_STDC
AC_CHECK_HEADERS([limits.h malloc.h stdlib.h string.h unistd.h])

# Checks for typedefs, structures, and compiler characteristics.
AC_HEADER_STDBOOL
AC_C_CONST
AC_C_INLINE

# Checks for library functions.
AC_FUNC_MALLOC
AC_FUNC_REALLOC
AC_CHECK_FUNCS([memset strcasecmp strchr strdup])

AC_ARG_ENABLE(debug,
	      [  --enable-debug          turn on debug],
	      CXXFLAGS="$CXXFLAGS -g3 -D_DEBUG=1")

AC_CONFIG_FILES([Makefile 
                 src/Makefile
                 data/Makefile
                 docs/Makefile
                 fonts/Makefile
                 images/Makefile
                 music/Makefile
                 sound/Makefile])
AC_OUTPUT

 

結束語

GNU 的很多工具經常給人一種感覺: 功能很強大,但也很難學。autotools 可以說是這類工具的一個典型,它需要用戶對 shell、make、軟件編譯、m4 宏語言,以及 Unix/Linux 操作系統各方面知識都有一定的瞭解。使用時又要 autoconf、automake、libtool 多個工具相互配合,如果要給軟件增加國際化功能,還要再瞭解和掌握 gettext、po 等工具和規則。

與學習其他知識一樣,所謂,其實是不瞭解,不熟悉。本文通過一個範例演示使用 autotools 的過程,是讓不瞭解的人熟悉這個工具。但真正的理解,還需要將它運用到自己的軟件項目當中,不斷地實踐,不斷地思考和總結。



腳註

... 多個工具相互配合 
由於本例軟件中沒有生成庫文件,所以沒有涉及 libtool 工具的使用。


Build by Ji YongGang <[email protected]>
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章