[譯文] 如何開始一個真正的 GTK 項(xiàng)目(第三部分:配置 Automake)

原文地址:Advanced GTK Techniques


這篇教程中你將學(xué)會:

  • 生成指定那些文件參加編譯的 Makefile 文件骨宠;
  • 檢查程序所需庫纵装。

這篇文章是《如何開始一個真正的 GTK 項(xiàng)目》的一部分,如果你不想回看之前的章節(jié)沪摄,可以直接下載教學(xué)示例程序 app-skeleton1躯嫉。你也可以從頭開始纱烘。


現(xiàn)在我們把注意力放在 Automake 上,這是編譯系統(tǒng)中另一個重要成員祈餐。我們配置好 Automake 后擂啥,就可以開始編寫代碼。

Make 是一個程序帆阳,它從文件 Makefile 中讀取如何編譯源代碼的指令哺壶,然后將代碼轉(zhuǎn)換成可執(zhí)行文件。Makefile 的內(nèi)容取決于使用何種編譯器蜒谤,何種系統(tǒng)山宾,以及很多其它事項(xiàng)。如果你希望實(shí)現(xiàn)在之前章節(jié)描述的所有標(biāo)準(zhǔn) make target 內(nèi)容鳍徽,那么 Makefile 將會變得很長资锰。

這便是引入 Automake 的原因。Automake 可以讓這一切更加簡潔阶祭、抽象绷杜,并且不受平臺的限制。Automake 會尋找一個名為 Automake.am 的文件濒募,將其轉(zhuǎn)譯為一個類似于 Makefile 的文件:Makefile.in鞭盟。隨后,在運(yùn)行 configure 時瑰剃,它會最終轉(zhuǎn)化為 Makefile齿诉。

創(chuàng)建 Makefile.am

我們首先完整拷貝一份 app-skeleton1 目錄,將它命名為 app-skeleton2晌姚,或者直接重命名目錄亦可粤剧。我們當(dāng)前只需要在 Makefile.am 中添加一行:

# app-skeleton2/Makefile.am
SUBDIRS = src

SUBDIRS 變量告訴 Automake 需要在子目錄 src 中查找另外一個 Makefile.am。最終生成的 Makefile 也會相應(yīng)地在 src 中查找另外一個 Makefile舀凛。

Make 的遞歸

Peter Miller 曾有一篇著名的文章給出了對編寫遞歸 Makefile 的看法:《遞歸編寫 Make 是有害的》俊扳。建議閱讀一下這篇文章,也可以聽取其中一些你認(rèn)為有用的觀點(diǎn)猛遍。他的實(shí)現(xiàn)方法并不比本文的方法簡單多少馋记。事實(shí)上,在實(shí)際應(yīng)用中懊烤,大多數(shù)工程使用了遞歸式的 Make梯醒,所以至少你應(yīng)當(dāng)熟悉這種做法。

我們已經(jīng)告知了 Automake 進(jìn)入 src 目錄腌紧,那么我們也應(yīng)該在目錄中準(zhǔn)備一些讓它能用得上的東西茸习。創(chuàng)建一個 Makefile.am 是肯定的,此外還需要一些更重要的東西 —— 源代碼文件壁肋。在下一章節(jié)我們才會開始正式的編程工作号胚,現(xiàn)在可以先找個差不多的文件湊數(shù)籽慢。從 GTK 官方教程中拿來 “Hello World” 的例程不失為簡單快捷的辦法,我們不需要從網(wǎng)頁中手動復(fù)制猫胁,只需要 cd src 后拷貝一份即可:

wget http://git.gnome.org/browse/gtk+/plain/examples/hello-world.c

現(xiàn)在我們在 src 中創(chuàng)建 Makefile.am箱亿,并在文件中輸入以下內(nèi)容:

#app-skeleton2/src/Makefile.am
bin_PROGRAMS = app-skeleton
app_skeleton_SOURCES = hello-world.c

Automake 的主要工作是設(shè)定變量,SUBDIRS 是其中一個案例弃秆。很多 Automake 變量的名稱由兩部分組成届惋,舉個例子,一個名為 something_PROGRAMS 的變量表示一個列表菠赚,包含了需要由 Automake 生成的可執(zhí)行文件的名稱脑豹。something 表示運(yùn)行 make install 時程序的安裝位置,所以 bin_PROGRAMS = app-skeleton 說明了 Automake 生成的 Makefile 將把 app-skeleton 安裝在 /usr/local/bin 中(你也可以把 bin 換成其它名稱衡查,Makefile 可通過 configure 靈活定制瘩欺,這一點(diǎn)可參閱之前的教程)。

順著這種命名的思路拌牲,app_skeleton_SOURCES = hello-world.c 表示名為 app-skeleton 的程序編譯依賴的源文件為 hello-world.c击碗,也就是我們剛剛下載的文件(如果程序名包含了變量不允許的字符,Automake 將把它變?yōu)橄聞澗€)们拙。

我們還需要讓 configure 幫我們把剛才編寫好的文件轉(zhuǎn)換成一個新的 Makefile。我們把 configure.ac 中的 AC_CONFIG_FILES 替換成:

#app-skeleton2/configure.ac
AC_CONFIG_FILES([
    Makefile
    src/Makefile
])

最后阁吝,我們還需要指派 configure 去找一個合適的 C 編譯器砚婆,在 AM_INIT_AUTOMAKE 后面加上一句 AC_PROG_CC 即可(CC 表示 C Compiler,Linux 中一般為為 gcc)突勇。

現(xiàn)在装盯,運(yùn)行 autoreconf./configureconfigure 的輸出將比之前的略長(你可以看到它在尋找一個 C 編譯器)甲馋,并且會有更多文件產(chǎn)生埂奈。到目前為止,一切運(yùn)行良好定躏。不過當(dāng)你運(yùn)行 make 時账磺,會收到滿屏的錯誤:所有的 GTK 函數(shù)都未定義,編譯器也找不到 gtk/gtk.h 頭文件痊远。

引入 GTK 庫

我們需要指定哪些庫將被程序使用垮抗。這個工作在 configure.ac 中完成,然后 configure 會去查找這些庫并將它們的變量放入 Makefile 中碧聪。借此機(jī)會冒版,我們可以重新組織 configure.ac,還能學(xué)習(xí)一些新的宏逞姿。

現(xiàn)在將 configure.ac 分成四個部分:

  • 初始化:完成初始化編譯系統(tǒng)的準(zhǔn)備工作辞嗡;

  • 工具箱:告訴 Autoconf 我們需要使用哪些工具捆等。configure 會幫我們查找這些工具,如果沒有找到便會報錯续室;

  • 庫:在此列出需要用到的庫栋烤。同樣地,如果 configure 沒有找到猎贴,它就會報錯班缎;

  • 輸出:輸出上述檢測的結(jié)果以供 make 使用。

注釋

你可以在 configure.ac 或者 Makefile.am 中使用注釋她渴,在一行的開頭輸入 “#” 即可达址。configure.ac 中也可以為在一行開頭輸入 “dnl”(Delete until New Line)。二者的區(qū)別在于 “dnl” 會被 Autoconf 完全忽略趁耗,而 “#” 會被一同拷貝進(jìn) configure 文件中沉唠。當(dāng) configure 中出現(xiàn)錯誤時,注釋有助于我們在 configure.ac 中快速定位引起錯誤的部分苛败。

在“初始化”部分满葛,輸入:

# app-skeleton2/configure.ac
AC_INIT([App Skeleton], [2], [philip.chimento@gmail.com])
AC_CONFIG_SRCDIR([src/hello-world.c])
AM_INIT_AUTOMAKE([-Wall foreign])
AM_SILENT_RULES([yes])

我們將版本號改為 2,此外還有兩個新的宏:

  • AC_CONFIG_SRCDIR

    這是一個安全行檢查罢屈,用于確認(rèn)其所指定位置確有一個 hello-world.c嘀韧。我們需要把它的參數(shù)設(shè)定為項(xiàng)目中一個獨(dú)一無二的代碼文件,這里我們寫上目前唯一的代碼文件缠捌。

  • AM_SILENT_RULES

    生成 Makefile 的過程通常產(chǎn)生非常長的信息锄贷,我們一般不需要看這么多,而且大量無用的信息刷屏可能會讓你忽視夾在其中的警告和錯誤信息曼月。AM_SILENT_RULES([yes]) 將屏蔽這些消息谊却,只輸出一些總結(jié)信息。一個真正的程序員可能會使用 AM_SILENT_RULES([no])哑芹,然后運(yùn)行 ./configure --enable-silent-rules 來保證政治正確性炎辨。

    如果你開啟了靜默模式,但還是希望能檢查所有輸出信息聪姿,可以使用 make V=1 命令(V 表示 Verbose)碴萧。

在“工具箱”部分,輸入

# app-skeleton2/configure.ac
AC_PROG_CC
PKG_PROG_PKG_CONFIG

這里有一個新的宏 PKG_PROG_PKG_CONFIG末购,它會在項(xiàng)目中加入用于檢查和引用庫的工具 —— pkg-config勿决。這個宏并非 AC_ 或者 AM_ 開頭,而是 PKG_招盲,說明這是一個由 pkg-config 提供的功能低缩。

在“庫”部分,我們用 pkg-config 引入我們需要的庫:

# app-skeleton2/configure.ac
PKG_CHECK_MODULES([APP_SKELETON], [
    glib-2.0
    gtk+-3.0
])

PKG_CHECK_MODULES 的第一個參數(shù) APP_SKELETON 為程序名,第二個參數(shù)列出了一系列 pkg-config 模塊咆繁。一個模塊代表了 pkg-config 可以識別的一個庫讳推。這個宏使用 pkg-config 查找計(jì)算機(jī)中的庫愕鼓,然后生成兩個變量:APP_SKELETON_CFLAGS —— 包含了庫的引用信息(類似于 gcc 中的 -I 參數(shù))露懒;APP_SKELETON_LIBS —— 包含了庫的鏈接信息(類似于 gcc 中的 -L-l 參數(shù))窃肠。這些變量可用于 Makefile 的編輯兽间。

這個宏表示我們將使用 glib-2.0gtk+-3.0 兩個庫。如果你不知道需要用到庫的模塊名日裙,可以到 /usr/share/pkgconfig/usr/lib/pkgconfig 中查找以 .pc 結(jié)尾的文件(譯者注:也可以在終端中輸入 pkg-config --list-all 查看)弦疮。一些庫并不能用 pkg-config 引入阻肩,而是需要其它的方法匀伏,我們在這里不做介紹洒忧。

最后的“輸出”部分與之前相同:

# app-skeleton2/configure.ac
AC_CONFIG_FILES([
    Makefile
    src/Makefile
])
AC_OUTPUT

全部搞定后,我們在 src/Makefile.am 中使用由 pkg-config 生成的 APP_SKELETON_CFLAGSAPP_SKELETON_LIBS 變量:

# app-skeleton2/src/Makefile.am
AM_CFLAGS = $(APP_SKELETON_CFLAGS)
bin_PROGRAMS = app-skeleton
app_skeleton_SOURCES = hello-world.c
app_skeleton_LDADD = $(APP_SKELETON_LIBS)

AM_CFLAGS 中的定義將會應(yīng)用到這個 Makefile.am 文件里的所有編譯指令中够颠。相反地熙侍,app_skeleton_LDADD 變量只會在鏈接 app-skeleton 程序時被使用。

譯者注:原文作者使用了簡便的引用庫方法:將所有用到的庫綁定到 APP_SKELETON 變量中履磨。其實(shí)蛉抓,更為穩(wěn)妥的做法應(yīng)該為將每個庫分離對待,這樣有利于模塊的靈活調(diào)用剃诅。具體做法為修改 configure.ac 中的 PKG_CHECK_MODULES 宏:

#app-skeleton2/configure.ac
PKG_CHECK_MODULES([GLIB], [
    glib-2.0
])
PKG_CHECK_MODULES([GTK], [
    gtk+-3.0
])

然后修改 src/Makefile.am 中相關(guān)的變量:

# app-skeleton2/src/Makefile.am
bin_PROGRAMS = app-skeleton
app_skeleton_SOURCES = hello-world.c
app_skeleton_CFLAGS = \
    $(GLIB_CFLAGS)  \
    $(GTK_CFLAGS)
app_skeleton_LDADD = \
    $(GLIB_LIBS)    \
    $(GTK_LIBS)

在大型項(xiàng)目中往往會生成多個可執(zhí)行文件或庫文件巷送,這樣也利于分別為每個目標(biāo)設(shè)定 cflagslibs 標(biāo)簽,更加清晰易讀矛辕。

現(xiàn)在我們再次編譯惩系,這次應(yīng)該就能正常工作了。注意這次編譯我們只需要輸入 make 即可如筛,Makefile (現(xiàn)在是 22 KB 了)會在檢測到 configure.ac 被修改后自動執(zhí)行 ./configure,同時也生成了新的自己抒抬。

你現(xiàn)在可以運(yùn)行 app-skeleton 來看看程序的效果:一個包含了一個按鈕控件的窗口杨刨,按鈕上寫著“Hello World”,按下之后會在終端打印“Hello World”并退出擦剑。

現(xiàn)在我們已經(jīng)有了像模像樣的編譯系統(tǒng)妖胀,接下來還有一些基礎(chǔ)工作等待著我們?nèi)ネ瓿桑喊惭b和翻譯。


文章許可協(xié)議:Attribution-NonCommercial-ShareAlike 3.0 Unported

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末惠勒,一起剝皮案震驚了整個濱河市赚抡,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌纠屋,老刑警劉巖涂臣,帶你破解...
    沈念sama閱讀 206,214評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡赁遗,警方通過查閱死者的電腦和手機(jī)署辉,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,307評論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來岩四,“玉大人哭尝,你說我怎么就攤上這事∑驶停” “怎么了材鹦?”我有些...
    開封第一講書人閱讀 152,543評論 0 341
  • 文/不壞的土叔 我叫張陵,是天一觀的道長耕姊。 經(jīng)常有香客問我桶唐,道長,這世上最難降的妖魔是什么箩做? 我笑而不...
    開封第一講書人閱讀 55,221評論 1 279
  • 正文 為了忘掉前任莽红,我火速辦了婚禮,結(jié)果婚禮上邦邦,老公的妹妹穿的比我還像新娘安吁。我一直安慰自己,他們只是感情好燃辖,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,224評論 5 371
  • 文/花漫 我一把揭開白布鬼店。 她就那樣靜靜地躺著,像睡著了一般黔龟。 火紅的嫁衣襯著肌膚如雪妇智。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,007評論 1 284
  • 那天氏身,我揣著相機(jī)與錄音巍棱,去河邊找鬼。 笑死蛋欣,一個胖子當(dāng)著我的面吹牛航徙,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播陷虎,決...
    沈念sama閱讀 38,313評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼到踏,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了尚猿?” 一聲冷哼從身側(cè)響起窝稿,我...
    開封第一講書人閱讀 36,956評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎凿掂,沒想到半個月后伴榔,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,441評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,925評論 2 323
  • 正文 我和宋清朗相戀三年潮梯,在試婚紗的時候發(fā)現(xiàn)自己被綠了骗灶。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,018評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡秉馏,死狀恐怖耙旦,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情萝究,我是刑警寧澤免都,帶...
    沈念sama閱讀 33,685評論 4 322
  • 正文 年R本政府宣布,位于F島的核電站帆竹,受9級特大地震影響绕娘,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜栽连,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,234評論 3 307
  • 文/蒙蒙 一险领、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧秒紧,春花似錦绢陌、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,240評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至叙淌,卻和暖如春秤掌,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背鹰霍。 一陣腳步聲響...
    開封第一講書人閱讀 31,464評論 1 261
  • 我被黑心中介騙來泰國打工闻鉴, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人茂洒。 一個月前我還...
    沈念sama閱讀 45,467評論 2 352
  • 正文 我出身青樓孟岛,卻偏偏與公主長得像,于是被迫代替她去往敵國和親获黔。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,762評論 2 345

推薦閱讀更多精彩內(nèi)容