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

轉一個automake的教程

Posted on 2008-06-27 09:42 T.S Liu 閱讀(21549) 評論(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 行加入編譯時的調試信息;第 2526 行使用了 sdl-config 工
具偵測 SDL 開發庫編譯鏈接信息,在 26 行還指明需要連接 SDL_imageSDL_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.inGNU 對自己發布的軟件
有嚴格的規范,比如必須附帶許可證聲明文件 COPYING 等等,否則 automake 執行時會
報錯automake 提供了三種軟件等級: foreigngnu 和 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 輸入文件后都需要再次運行
aclocalautomakeautoconf 這些命令,為了方便起見,可以將他們放到一個 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 的過程,是讓不了解的人熟悉這個工具但真正的理解,還需要將它運用到自
己的軟件項目當中,不斷地實踐,不斷地思考和總結




腳注

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

Feedback

# re: 轉一個automake的教程[未登錄]  回復  更多評論   

2013-08-27 19:12 by wei
一晃憶是五年后,時光啊,
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <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>
            欧美日韩一视频区二区| 亚洲色图综合久久| 久久这里只有精品视频首页| 亚洲欧美久久久| 久久国产精品毛片| 欧美激情精品久久久| 久久综合精品一区| 欧美资源在线| 久久国产精品色婷婷| 久久久精品国产99久久精品芒果| 欧美中文字幕在线观看| 久久精品国产第一区二区三区最新章节| 午夜在线视频观看日韩17c| 欧美一区二区三区在线| 久久天天躁狠狠躁夜夜av| 欧美大片免费观看| 久久一二三区| 亚洲精品国产品国语在线app| 欧美一区二区大片| 欧美国产视频日韩| 亚洲视屏在线播放| 久久九九热re6这里有精品| 久久一区亚洲| 欧美日韩国产精品一区二区亚洲| 国产精品白丝jk黑袜喷水| 国产视频一区二区三区在线观看| 伊人色综合久久天天五月婷| 夜夜爽99久久国产综合精品女不卡 | 一区二区三区**美女毛片| 亚洲一区二区免费看| 久久成人国产| 欧美日韩国产一级| 136国产福利精品导航网址| 99国产精品久久久久久久| 欧美伊久线香蕉线新在线| 亚洲国产精品久久91精品| 午夜久久久久久| 欧美精品一区二区精品网| 国产手机视频一区二区| 亚洲精品国精品久久99热一| 欧美亚洲综合另类| 亚洲人成7777| 久久久久高清| 国产欧美一区二区精品性色| 亚洲精品免费在线| 久久婷婷影院| 午夜精品久久久久久久白皮肤| 欧美精品福利视频| 亚洲国产精品免费| 久久女同互慰一区二区三区| 亚洲视频自拍偷拍| 欧美色大人视频| 99re66热这里只有精品4| 蜜臀av性久久久久蜜臀aⅴ四虎| 亚洲午夜精品17c| 欧美剧在线观看| 亚洲激情图片小说视频| 欧美视频福利| 激情久久影院| 一本一本a久久| 欧美国产丝袜视频| 久久精品亚洲精品国产欧美kt∨| 国产精品一区二区在线观看网站 | 欧美在线观看网址综合| 夜夜精品视频一区二区| 欧美日本免费| 一本一本久久| 一区二区高清视频| 国产精品劲爆视频| 亚洲综合精品一区二区| 一本色道88久久加勒比精品| 欧美日韩免费高清| 国产精品99久久久久久久vr | 亚洲欧美另类在线观看| 日韩一级黄色片| 国产精品高潮呻吟久久av无限| 一区二区三区导航| 亚洲一区二区三区中文字幕在线| 欧美午夜精品久久久久久超碰| 亚洲视频在线一区观看| 亚洲午夜在线视频| 国产日韩欧美制服另类| 久热精品视频在线观看一区| 久久视频精品在线| 亚洲精品免费电影| 亚洲私人黄色宅男| 国产一区二区毛片| 欧美高清在线精品一区| 欧美日韩精品综合| 久久久国产成人精品| 韩国一区二区三区美女美女秀| 久久久久亚洲综合| 欧美夫妇交换俱乐部在线观看| 中文欧美日韩| 欧美一区二区三区视频| 亚洲激情网站免费观看| 在线午夜精品| 亚洲电影观看| 一区二区激情| 依依成人综合视频| 亚洲乱码国产乱码精品精天堂 | 久久久一区二区三区| 久久欧美中文字幕| 亚洲一区亚洲| 老司机精品久久| 亚洲一区二区欧美| 久久综合久久综合九色| 亚洲一区二区三区中文字幕| 久久精品国产999大香线蕉| 亚洲人成网站在线播| 亚洲在线播放| 日韩视频在线观看国产| 性做久久久久久| a4yy欧美一区二区三区| 亚洲精品一区二区在线观看| 亚洲欧美日韩综合aⅴ视频| 久久美女性网| 欧美亚洲视频一区二区| 欧美成人免费大片| 久久久高清一区二区三区| 欧美日韩精品综合| 欧美激情91| 国产精品资源在线观看| 亚洲人屁股眼子交8| 国产亚洲一区精品| 亚洲天堂偷拍| av成人免费观看| 久久亚洲二区| 久久香蕉国产线看观看av| 国产乱码精品一区二区三区忘忧草 | 香蕉av777xxx色综合一区| 亚洲精品久久久久中文字幕欢迎你 | 欧美aa国产视频| 久久亚洲欧美| 国产日韩精品视频一区| 99视频一区二区三区| 日韩一区二区精品在线观看| 蜜桃精品一区二区三区| 麻豆9191精品国产| 精品va天堂亚洲国产| 欧美在线视频免费播放| 欧美在线亚洲在线| 国产精品综合视频| 亚洲欧美日本另类| 久久精品99久久香蕉国产色戒| 国产欧美日本一区二区三区| 亚洲在线观看视频网站| 久久国产欧美| 一区二区在线视频观看| 久久久99免费视频| 久久久五月天| 曰本成人黄色| 欧美大片在线看免费观看| 亚洲黄色免费| 99精品国产99久久久久久福利| 欧美一二三区精品| 欧美日韩精品| 这里是久久伊人| 欧美一区二区三区啪啪| 国产精品亚洲欧美| 欧美专区日韩专区| 欧美激情视频在线免费观看 欧美视频免费一 | 欧美在线你懂的| 蜜臀av在线播放一区二区三区| 国产一区二区三区四区在线观看| 久久精品国产清自在天天线| 欧美承认网站| 亚洲综合色婷婷| 一区二区三区在线看| 欧美黄色免费| 亚洲一二三四区| 欧美高清视频在线播放| 午夜精彩视频在线观看不卡| 国产精品成av人在线视午夜片| 亚洲一区影音先锋| 久久综合一区| 亚洲色图自拍| 精久久久久久| 欧美日韩精品欧美日韩精品| 欧美一区二区大片| 最新日韩欧美| 欧美在线观看一区二区| 亚洲国产欧美在线人成| 国产精品日韩一区| 免费看亚洲片| 亚洲自拍高清| 亚洲欧洲一区二区天堂久久| 亚洲欧美制服另类日韩| 亚洲二区三区四区| 国产毛片精品国产一区二区三区| 免费在线看成人av| 午夜激情综合网| 999在线观看精品免费不卡网站| 久久天堂成人| 亚洲欧美日韩国产综合在线 | 久久久久久网站| 亚洲一区二区欧美| 亚洲免费久久| 亚洲日韩视频| 亚洲成人在线网站|