makefile的編寫

ceph 運行的第一個文件:autogen.shhtml

#!/bin/sh -xlinux

 """git

 參考redis

 http://www.laruence.com/2008/11/11/606.htmlshell

 http://blog.chinaunix.net/uid-10915175-id-3256850.html緩存

 """electron

 #後續若存在返回非0,則腳本直接退出ide

set -e模塊化

 

#若ceph.in文件在哪一個路徑下沒有,退出函數

test -f src/ceph.in || {

    echo "You must run this script in the top-level ceph directory"

    exit 1

}

 

#定義了一個函數,這裏不是調用處,符號&&表示:comd1&&comd2,若comd1執行成功,

#返回0後,執行comd2---另外有符合||,表示comd1執行失敗後執行comd2

check_for_pkg_config() {

    which pkg-config >/dev/null && return

 

    echo

    echo "Error: could not find pkg-config"

    echo

    echo "Please make sure you have pkg-config installed."

    echo

    exit 1

}

 

#libtool 提供通用的庫編譯支持。

#libtoolize 提供了一種標準方式來將libtool支持加入到一個軟件包。

#libltdl隱藏 dlopening 庫的複雜細節。

if [ `which libtoolize` ]; then

    LIBTOOLIZE=libtoolize

elif [ `which glibtoolize` ]; then

    LIBTOOLIZE=glibtoolize

else

  echo "Error: could not find libtoolize"

  echo "  Please install libtoolize or glibtoolize."

  exit 1

fi

 

 

#判斷是否有.git這個路徑,這個是那個開源gitub的路徑,如有這個

#而後執行git submodule sync和git submodule update --init來更新相關的子項信息

#具體涉及到git中哪些子項,應該是.git中定義的

if test -d ".git" ; then

  if ! git submodule sync || ! git submodule update --init; then

    echo "Error: could not initialize submodule projects"

    echo "  Network connectivity might be required."

    exit 1

  fi

fi

 

rm -f config.cache

 

#aclocal是編譯的安裝工具, 經過configure.ac或者configure.in等,生成m4

#實際上依賴於工具:autoconf、automake

#-I是指路徑,m4是ceph的主路徑下的一個目錄,裏面都是.m4文件

#命令功能解釋: Generate 'aclocal.m4' by scanning 'configure.ac' or 'configure.in'

#--install             copy third-party files to the first -I directory

#要求執行的路徑下有:configure.ac文件

#以後執行automake的時候,會依賴configure文件和這個m4文件

aclocal -I m4 --install

 

#

#檢查是否有 pkg_config命令,這個命令能夠查詢全部庫/共享庫的版本號,標誌位等參數信息

check_for_pkg_config

D

#庫編譯,若是文件已存在,就覆蓋,而且經過複製的方式而不是連接,會將前面aclocal生成的m4宏文件拷到?裏面

$LIBTOOLIZE --force --copy

 

aclocal -I m4 --install

 

autoconf

autoheader

automake -a --add-missing -Wall

 

#若是對應的路徑存在,在那個路徑下,作libtoolize—autoconf--- autoheader-- automake

( cd src/gmock && autoreconf -fvi; )

( cd src/rocksdb && autoreconf -fvi; )

exit

 

 

makefile過程圖解:

 

aclocal

user input files   optional input     process          output files

================   ==============     =======          ============

 

                    acinclude.m4 - - - - -.

                                          V

                                      .-------,

configure.ac ------------------------>|aclocal|

                 {user macro files} ->|       |------> aclocal.m4和緩存文件夾autom4te.cache

                                      `-------'

 

其中,aclocal.m4主要保存本地宏定義信息

 

autoheader和autoconf:

根據configure.ac中的某些宏,好比cpp宏定義,運行m4,聲稱config.h.in

(autoconfig.h.in是configure的運行模板文件,裏面有宏參數)

user input files    optional input     process          output files

================    ==============     =======          ============

configure.ac ----------------------->|autoconf|----> configure,/autom4te.cache/request

此外,ceph10.2.2 在路徑autom4te.cache中生成了文件request,其中autom4te.cache是aclocal時自動生成的。

                    aclocal.m4 - - - - - - - .

                                             |

                                             V

                                     .----------,

configure.ac ----------------------->|autoheader|----> 更新request(若沒有能夠生成)

                                     `----------'

4.automake: automake將Makefile.am中定義的結構創建Makefile.in,而後configure腳本將生成的Makefile.in文件轉換爲Makefile。若是在configure.ac中定義了一些特殊的宏,好比AC_PROG_LIBTOOL,它會調用libtoolize,不然它會本身產生config.guess和config.sub

user input files   optional input   processes          output files

================   ==============   =========          ============

 

                                     .--------,

                                     |        | - - -> COPYING

                                     |        | - - -> INSTALL

                                     |        |------> install-sh

                                     |        |------> missing

                                     |automake|------> mkinstalldirs

configure.ac ----------------------->|        |

Makefile.am  ----------------------->|        |------> Makefile.in

                                     |        |------> stamp-h.in

                                 .---+        | - - -> config.guess

                                 |   |        | - - -> config.sub

                                 |   `------+-'

                                 |          | - - - -> config.guess

                                 |libtoolize| - - - -> config.sub

                                 |          |--------> ltmain.sh

                                 |          |--------> ltconfig

                                 `----------'

5.autoconf:將configure.ac中的宏展開,生成configure腳本。這個過程可能要用到aclocal.m4中定義的宏。

user input files   optional input   processes          output files

================   ==============   =========          ============

 

aclocal.m4 ,autoconfig.h.in - - - - - - -.

                                         V

                                     .--------,

configure.ac ----------------------->|autoconf|------> configure

 

6. ./configure的過程


                                           .-------------> [config.cache]

     configure* --------------------------+-------------> config.log

                                          |

              [config.h.in] -.            v            .--> [autoconfig.h]
                             +-------> config.status* -+                  

              Makefile.in ---'                         `-->   Makefile

 

7. make過程

 

     [autoconfig.h] -.
                     +--> make* --->  程序
       Makefile   ---'

 

                                     .---------,

                   config.site - - ->|         |

                  config.cache - - ->|         | - - -> config.cache

                                     |         +-,

                                     `-+-------' |

                                       |         |----> config.status

                   config.h.in ------->|config-  |----> config.h

                   Makefile.in ------->|  .status|----> Makefile

                                       |         |----> stamp-h

                                       |         +--,

                                     .-+         |  |

                                     | `------+--'  |

                   ltmain.sh ------->|ltconfig|-------> libtool

                                     |        |     |

                                     `-+------'     |

                                       |config.guess|

                                       | config.sub |

                                       `------------'

 

                                   .--------,

                   Makefile ------>|        |

                   config.h ------>|        |

{project sources} ---------------->|        |--------> {project targets}

                                 .-+        +--,

                                 | `--------'  |

                                 |   libtool   |

                                 |   missing   |

                                 |  install-sh |

                                 |mkinstalldirs|

                                 `-------------'

 

 

 

參考文獻

http://www.07net01.com/program/579475.html

 

 

 

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

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

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

目 錄

· 示例項目
· 軟件佈局
· Makefile 分析
· GNU 的軟件風格
· 準備 autotools
· 改造文件佈局
· autoscan
· configure.ac 的基本結構
· Makefile 文件的產生
· 編寫 Makefile.am
軟件根目錄 Makefile.am
src/Makefile.am
data/Makefile.am
docs/Makefile.am
fonts/Makefile.am
images/Makefile.am
music/Makefile.am
sound/Makefile.am

· 運行 autotools
· SDL 庫的偵測
· 軟件使用的數據文件
· configure 選項
· autotools 腳本
· 使用 configure 產生的 Makefile
· 最終的 configure.ac 文件
· 結束語

示例項目

這裏借用了 Wei Mingzhi <whistler_wmz@users.sf.net> 開發的麻將遊戲來進行演示,在
此,先對他表示感謝!

示例軟件下載:



軟件佈局

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

$ 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 -lSDL_mixer -lSDL_ttf
27
28 all: ${TARGET}
29
30 ${TARGET}: ${OBJ}
31 ${CXX} ${LDFLAGS} -o ${TARGET} ${OBJ}
32
33 clean:
34 rm -f *.o ${TARGET}
35
36 distclean:
37 rm -f *.o ${TARGET}
38
39 %.o: %.cpp ${HEADERS}
40 ${CXX} ${CFLAGS} -c $< -o $@
41
42 %.o: %.c ${HEADERS}
43 ${CC} ${CFLAGS} -c $< -o $@

Makefile 很清楚:

第 20 行定義 TARGET 變量爲 mj,

第 28 行代表 make 默認的 target  也就是生成 `mj';

第 22 行加入編譯時的調試信息;

第 25-26 行使用了 sdl-config 工具偵測 SDL 開發庫編譯連接信息,在 26 行還指明須要鏈接 SDL_imageSDL_mixser 和SDL_ttf 庫

GNU 的軟件風格

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

$ ./configure
$ make
$ make install

configure 腳本運行時能夠偵測系統的環境,肯定軟件安裝目錄,而後生成 Makefile 文件(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,並與偵測信息configure.ac一塊兒寫到 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 文件(裏面寫各個路徑下的Makefile文件名,通常都叫Makefile,若不是這個標準名字,應該在調用make的時候要傳入文件名參數標誌,此外,AC_OUTPUT這個configure.ac的最後一個宏命令的參數也可設定爲Makefile,這樣也能夠有相同的結果)


由於 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

ATmj_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_imageSDL_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_imageSDL_mixer 和 SDL_ttf 對應的使用方法以下:

# 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`)

《軟件使用的數據文件》

原來 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()
{
char ini_file[260];
sprintf(ini_file, "%s/data/mj.ini", DATA_DIR);
cfg.Load(ini_file);
}

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 能夠說是這類 工具的一個典型,它須要用戶對 shellmake軟件編譯m4 宏語言,以及 Unix/Linux 操做系統各方面知識都有必定的瞭解使用時又要 autoconf automakelibtool 多個 工具相互配合^1,若是要給軟件增長國際化功能,還要再瞭解和掌握 gettextpo 等工具 和規則 與學習其餘知識同樣,所謂難,實際上是不瞭解,不熟悉本文經過一個範例演示使用 autotools 的過程,是讓不瞭解的人熟悉這個工具但真正的理解,還須要將它運用到自 己的軟件項目當中,不斷地實踐,不斷地思考和總結  

相關文章
相關標籤/搜索