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

使用 GNU autotools 改造一個軟件項目
作者:及永剛 <jungle{at}soforge{dot}com 
   發表時間:2006-05-23

示例項目:
這裏借用了 Wei Mingzhi <whistler_wmz{at}users{dot}sf{dot}net> 開發的麻將遊戲來進行演示,在此,先對他表示感謝!

示例軟件下載:
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
   
發佈了31 篇原創文章 · 獲贊 5 · 訪問量 23萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章