添加微信公眾號《Linux就該這么學》养距,掌握最新IT資訊動態(tài)卵佛,免費領(lǐng)取Linux課程以及專業(yè)的RHCE考前答疑服務(wù)。
《Linux就該這么學》在線免費閱讀地址:http://www.linuxprobe.com/
純手工打造每一篇開源資訊與技術(shù)干貨僚匆,數(shù)十萬程序員和Linuxer已經(jīng)關(guān)注
導讀 |
經(jīng)常使用Linux的開發(fā)人員或者運維人員他炊,可能對configure->make->make install相當熟悉。事實上姆吭,這叫GNU構(gòu)建系統(tǒng)榛做,利用腳本和make程序在特定平臺上構(gòu)建軟件。這種方式成為一種習慣内狸,被廣泛使用检眯。本文從用戶視角和開發(fā)者視角詳細說明,這種構(gòu)建方式的細節(jié)昆淡,以及開發(fā)者如何利用autoconf和automake等工具(autotools)創(chuàng)建兼容GNU構(gòu)建系統(tǒng)的項目轰传。 |
為了簡化可移植構(gòu)建的難度,在早期有一套autotools工具幫助程序員構(gòu)建軟件瘪撇。我們熟知的configure->make->make install三部曲,大多都是基于autotools來構(gòu)建的港庄。autotools是GNU程序的標準構(gòu)建系統(tǒng)倔既,所以其實我們經(jīng)常在使用三部曲。有些程序雖然也是這三部曲鹏氧,但卻不是用autotools實現(xiàn)的渤涌,比如nginx的源碼就是作者自己編寫的構(gòu)建程序。
用戶視角用戶通過configure->make->make install基于源碼安裝軟件把还。然而大部分用戶可能并不知道這個過程究竟做了些什么实蓬。
configure腳本是由軟件開發(fā)者維護并發(fā)布給用戶使用的shell腳本茸俭。這個腳本的作用是檢測系統(tǒng)環(huán)境,最終目的是生成Makefile和config.h安皱。
make通過讀取Makefile文件调鬓,開始構(gòu)建軟件。而make install可以將軟件安裝到需要安裝的位置酌伊。
如上圖腾窝,開發(fā)者在分發(fā)源碼包時,除了源代碼(.c .h…)居砖,還有許多用以支撐軟件構(gòu)建的文件和工具虹脯,其中最重要的文件就是Makefile.in和config.h.in。configure腳本執(zhí)行成功后奏候,將為每一個*.in文件處理成對應的非*.in文件循集。
大部分情況只生成Makefile和config.h,因為Makefile用于make程序識別并構(gòu)建軟件蔗草,而config.h中定義的宏咒彤,有助于軟件通過預編譯來改變自身的代碼,以適應目標平臺某些特殊性蕉世。有些軟件在configure階段蔼紧,還可以生成其他文件,這完全取決于如軟件本身狠轻。
configure當運行configure時奸例,將看到類似如下的系統(tǒng)檢查,這些檢查的多少取決于軟件本身的需要向楼,也就是由軟件開發(fā)者來定義和編寫的查吊。
checking?for?a?BSD-compatible?install...?/usr/bin/install?-c
checking?whether?build?environment?is?sane...?yes
checking?for?a?thread-safe?mkdir?-p...?/bin/mkdir?-p
checking?for?gawk...?gawk
checking?whether?make?sets?$(MAKE)...?yes
checking?for?gcc...?gcc
checking?for?C?compiler?default?output?file?name...?a.out
...
一般來說,configure主要檢查當前目標平臺的程序湖蜕、庫逻卖、頭文件、函數(shù)等的兼容性昭抒。這些檢查結(jié)果將作用于config.h和Makefile文件的生成评也。從而影響最終的編譯。
用戶也可以通過給configure配置參數(shù)來定制軟件需要包含或不需要包含的組件灭返、安裝路徑等行為盗迟。這些參數(shù)分為5組,可以通過執(zhí)行./configure --help來查看熙含,軟件提供哪些配置參數(shù):
安裝路徑相關(guān)配置罚缕。最常見的是--prefix。
程序名配置怎静。例如--program-suffix可用于為生成的程序添加后綴邮弹。
跨平臺編譯黔衡。不太常用。
動態(tài)庫靜態(tài)庫選項腌乡。用于控制是否生成某種類型的庫文件盟劫。
程序組件選項。用于配置程序是否將某種功能編譯到程序中导饲,一般形如--with-xxx捞高。這可能是最常用的配置,而且由軟件開發(fā)者來定義渣锦。
(*表示這是幾乎所有軟件都支持的配置硝岗,因為這些配置是autotool生成的configure腳本默認支持的。)
configure在執(zhí)行過程中袋毙,除了生成Makefile外型檀,還會生成的文件包括但不限于:
config.log 日志文件
config.cache 緩存,以提高下一次configure的速度听盖,需通過-C來指定才會生成
config.status 實際調(diào)用編譯工具構(gòu)建軟件的shell腳本
如果軟件通過libtool構(gòu)建胀溺,還會生成libtool腳本。關(guān)于libtool腳本如何生成皆看,請看開發(fā)者視角仓坞。
configure經(jīng)常會中途出錯,這一般是由于當前平臺不具有構(gòu)建該軟件所必需的依賴(庫腰吟、函數(shù)无埃、頭文件、程序…)毛雇。此時嫉称,不要慌張,仔細查看輸出灵疮,解決這些依賴织阅。
開發(fā)者視角開發(fā)者除了編寫軟件本身的代碼外,還需要負責生成構(gòu)建軟件所需要文件和工具震捣。當我接觸到autotools后荔棉,我發(fā)現(xiàn),雖然有工具的幫助蒿赢,但這件事情依舊十分復雜江耀。
對于C或C++程序員,在早期诉植,構(gòu)建跨平臺的應用程序是相當繁瑣的一件事情,而且對于經(jīng)驗不足的程序員而言昵观,甚至難度巨大晾腔。因為構(gòu)建可移植的程序的必要前提是對各個平臺足夠了解舌稀,這往往要花上相當長的時間去積累。
Unix系統(tǒng)的分支復雜度很高灼擂,不同的商用版或開源版或多或少都有差異壁查。這些差異主要體現(xiàn)在:系統(tǒng)組件、系統(tǒng)調(diào)用剔应。我們主要將Unix分為如下幾個大類:IBM-AIX HP-UX Apple-DARWIN Solaris Linux FreeBSD睡腿。Unix分支大全
因此,對于開發(fā)者而言峻贮,要么自己編寫構(gòu)建用的腳本席怪,這往往需要極其扎實的shell能力和平臺熟悉度。另一個選擇就是部分依賴工具纤控。autoconf和automake就是這樣的工具挂捻。
autoreconf為了生成configure腳本和Makefile.in等文件,開發(fā)者需要創(chuàng)建并維護一個configure.ac文件(在早期船万,通常叫configure.in文件刻撒,雖然沒有區(qū)別,但強烈建議使用.ac耿导,因為.in文件往往意味著被configure腳本識別為模板文件并生成直接參與最終構(gòu)建的文件声怔,configure.in在命名上有歧義),以及一系列的Makefile.am。autoreconf程序能夠自動按照合理的順序調(diào)用autoconf automake aclocal等程序舱呻。
configure.ac用于生成configure腳本醋火。autoconf工具用來完成這一步。下面是一個configure.ac的例子:
AC_PREREQ([2.63])
AC_INIT([st],?[1.0],?[zhoupingtkbjb@163.com])
AC_CONFIG_SRCDIR([src/main.c])
AC_CONFIG_HEADERS([src/config.h])
AM_INIT_AUTOMAKE([foreign])
#?Checks?for?programs.
AC_PROG_CC
AC_PROG_LIBTOOL
#?Checks?for?libraries.
#?Checks?for?header?files.
#?Checks?for?typedefs,?structures,?and?compiler?characteristics.
#?Checks?for?library?functions.
AC_CONFIG_FILES([Makefile
??????????????? ?src/Makefile
?????????????????src/a/Makefile
?????????????????src/b/Makefile])
AC_OUTPUT
其中以AC_開頭的類似函數(shù)調(diào)用一樣的代碼狮荔,實際是一些被稱為“宏”的調(diào)用胎撇。這里的宏與C中的宏概念類似,會被替換展開殖氏。m4是一個經(jīng)典的宏工具晚树,autoconf正是構(gòu)建在m4之上,可以理解為autoconf預先實現(xiàn)了大量的雅采,用于檢測系統(tǒng)可移植性的宏爵憎,這些宏在展開后就是大量的shell腳本。所以編寫configure.ac需要對這些宏熟練掌握婚瓜,并且合理調(diào)用宝鼓。有時,甚至可以自己實現(xiàn)自己的宏巴刻。
autoscan和configure.scan可以通過調(diào)用autoscan命令得到一個初始化的configure.scan文件愚铡,然后重命名為configure.ac后,在此基礎(chǔ)上編輯configure.ac。autoscan會掃描源碼沥寥,并生成一些通用的宏調(diào)用碍舍、輸入的聲明以及輸出的聲明。盡管autoscan十分方便邑雅,但是沒人能夠在構(gòu)建之前片橡,就把代碼完全寫好,因此autoscan通常用于初始化configure.ac淮野。
autoheader和config.hautoheader命令掃描configure.ac中的內(nèi)容捧书,并確定需要如何生成config.h.in。每當configure.ac有所變化骤星,都可以通過再次執(zhí)行autoheader更新config.h.in经瓷。在configure.ac通過AC_CONFIG_HEADERS([config.h])告訴autoheader應當生成config.h.in的路徑。在實際的編譯階段妈踊,生成的編譯命令會加上-DHAVE_CONFIG_H定義宏了嚎,于是在代碼中,我們可以通過下面代碼安全的引用config.h廊营。
/bin/sh?../../libtool?--tag=CC???--mode=compile?gcc?-DHAVE_CONFIG_H?...
#ifdef?HAVE_CONFIG_H
#include?<config.h>
#endif
config.h包含了大量的宏定義歪泳,其中包括軟件包的名字等信息,程序可以直接使用這些宏;更重要的是露筒,程序可以根據(jù)其中的對目標平臺的可移植性相關(guān)的宏呐伞,通過條件編譯,動態(tài)的調(diào)整編譯行為慎式。
automake和Makfile.am手工編寫Makefile是一件相當煩瑣的事情伶氢,而且,如果項目復雜的話瘪吏,編寫難度將越來越大癣防。因而,automake工具應運而生掌眠。我們可以編寫像下面這樣的Makefile.am文件蕾盯,并依靠automake來生成Makefile.in:
SUBDIRS?=?a?b
bin_PROGRAMS????=?st
st_SOURCES??????=?main.c
st_LDADD????????=?$(top_builddir)/src/a/liba.la?$(top_builddir)/src/b/libb.la
這里通過SUBDIRS聲明了兩個子目錄,子目錄的中的構(gòu)建需要靠a/Makefile.am和b/Makefile.am來進行蓝丙,這樣多目錄組織起來就方便多了级遭。
bin_PROGRAMS聲明一個可執(zhí)行文件目標,st_SOURCES指定這個目標所依賴的源代碼文件渺尘。另外挫鸽,st_LDADD聲明了可執(zhí)行文件在連接時,需要依賴的Libtool庫文件鸥跟。
通過這個Makefile.am文件生成的Makefile.in文件相當大丢郊,不便貼出,但是可以想象,Makefile.in要比我們手工編寫的Makefile文件復雜的多蚂夕。
automake的出現(xiàn)晚于autoconf迅诬,所以automake是作為autoconf的擴展來實現(xiàn)的。通過在configure.ac中聲明AM_INIT_AUTOMAKE告訴autoconf需要配置和調(diào)用automake婿牍。
aclocal上面提到,configure.ac實際是依靠宏展開來得到configure的惩歉。因此等脂,能否成功生成取決于,宏定義能否找到撑蚌。autoconf會從自身安裝路徑下來尋找事先定義好了宏上遥。然而對于像automake、libtool和gettext等第三方擴展宏争涌,甚至是開發(fā)者自行編寫的宏就一無所知了粉楚。于是,存在這個工具aclocal亮垫,將在configure.ac同一目錄下生成aclocal.m4模软,在掃描configure.ac的過程中,將第三方擴展和開發(fā)者自己編寫的宏定義復制進去饮潦。這樣燃异,autoconf在遇到不認識的宏時,就會從aclocal.m4中查找继蜡。
下面這張圖更為詳細的展現(xiàn)了整個工具鏈是如何互相配合的筹误。
libtool試圖解決不同平臺下迟郎,庫文件的差異。libtool實際是一個shell腳本,實際工作過程中搀军,調(diào)用了目標平臺的cc編譯器和鏈接器,以及給予合適的命令行參數(shù)格侯。libtool可以單獨使用格仲,這里只介紹與autotools集成使用相關(guān)的內(nèi)容。
automake支持libtool構(gòu)建聲明殴俱。在Makefile.am中政冻,普通的庫文件目標寫作xxx_LIBRARIES:
noinst_LIBRARIES?=?liba.a
liba_SOURCES?=?ao1.c?ao2.c?ao3.c
而對于一個libtool目標,寫作xxx_LTLIBRARIES线欲,并以.la作為后綴聲明庫文件明场。
noinst_LTLIBRARIES?=?liba.la
liba_la_SOURCES?=?ao1.c?ao2.c?ao3.c
在configure.ac中需要聲明LT_INIT:
...
AM_INIT_AUTOMAKE([foreign])
LT_INIT
...
有時,如果需要用到libtool中的某些宏李丰,則推薦將這些宏copy到項目中苦锨。首先,通過AC_CONFIG_MACRO_DIR([m4])指定使用m4目錄存放第三方宏;然后在最外層的Makefile.am中加入ACLOCAL_AMFLAGS = -I m4。
all-in-one上面討論了很多關(guān)于autoreconf的細節(jié)舟舒。實際上拉庶,如今我們可以直接調(diào)用autoreconf --install來自動調(diào)用上面提到的所有子命令。這里--install參數(shù)試圖將輔助的腳本和宏copy到當前項目目錄中秃励,下面是執(zhí)行時的輸出:
autoreconf:?Entering?directory?`.'
autoreconf:?configure.ac:?not?using?Gettext
autoreconf:?running:?aclocal
autoreconf:?configure.ac:?tracing
autoreconf:?running:?libtoolize?--copy
libtoolize:?putting?auxiliary?files?in?`.'.
libtoolize:?copying?file?`./ltmain.sh'
libtoolize:?Consider?adding?`AC_CONFIG_MACRO_DIR([m4])'?to?configure.ac?and
libtoolize:?rerunning?libtoolize,?to?keep?the?correct?libtool?macros?in-tree.
libtoolize:?Consider?adding?`-I?m4'?to?ACLOCAL_AMFLAGS?in?Makefile.am.
autoreconf:?running:?/usr/bin/autoconf
autoreconf:?running:?/usr/bin/autoheader
autoreconf:?running:?automake?--add-missing?--copy?--no-force
configure.ac:10:?installing?`./config.guess'
configure.ac:10:?installing?`./config.sub'
configure.ac:9:?installing?`./install-sh'
configure.ac:9:?installing?`./missing'
src/Makefile.am:?installing?`./depcomp'
autoreconf:?Leaving?directory?`.'
當我們以--install參數(shù)運行時氏仗,libtoolize --copy被調(diào)用,這將使得ltmain.sh被copy進來;接下來分別執(zhí)行autoconf和autoheader;automake的參數(shù)為--add-missing --copy --no-force夺鲜,這將使得幾個輔助腳本和文件被安裝到目錄下皆尔。
這些輔助文件默認安裝在configure.ac同一個目錄下,如果你希望用另一個目錄來存放他們币励,可以配置AC_CONFIG_AUX_DIR慷蠕,例如AC_CONFIG_AUX_DIR([build-aux])將使用build-aux目錄來存放輔助文件。
如果不使用--install參數(shù)食呻,輔助文件要么不copy流炕,要么以軟鏈的形式創(chuàng)建。推薦使用--install仅胞,因為這樣每辟,其他軟件維護可以避免由于構(gòu)建工具版本不一致造成問題。
輔助文件一個依靠GNU構(gòu)建系統(tǒng)開發(fā)的軟件除了源碼之外饼问,還有很多輔助的文件影兽,有些是腳本,有些是文本文件莱革。下面將逐一解釋這些文件:
-
aclocal.m4:上面提到了峻堰,這個宏定義文件里面包含了第三方的宏定義,用于autoconf展開configure.ac
-
NEWS README AUTHORS ChangeLog:這些文件是GNU軟件的標配盅视,不過在項目中不一定需要加入捐名。如果項目中沒有這些文件,每次autoreconf會提示缺少文件闹击,不過這并不影響镶蹋。如果不想看到這些錯誤提示,可以用AM_INIT_AUTOMAKE([foreign])來配置automake赏半。foreign參數(shù)就是告訴automake不要這么較真:)
-
config.guess config.sub:由automake產(chǎn)生贺归,兩個用于目標平臺檢測的腳本
-
depcomp install-sh:由automake產(chǎn)生,用于完成編譯和安裝的腳本
-
missing:由automake產(chǎn)生
-
ltmain.sh:有l(wèi)ibtoolize產(chǎn)生断箫,該腳本用于在configure階段配置生成可運行于目標平臺的libtool腳本
-
ylwrap:由automake產(chǎn)生拂酣,如果檢測構(gòu)建需要使用lex和yacc,那么會產(chǎn)生這個包裝腳本
autogen.sh:在早期仲义,autoreconf并不存在婶熬,軟件開發(fā)者往往需要自己編寫腳本剑勾,按照順序調(diào)用autoconf autoheader automake等工具程序。這個文件就是這樣的腳本赵颅。起這么個名字可能是習慣性的
本文總概念上闡述了autotool系列工具是如何工作的虽另。相比如今現(xiàn)成的IDE,GNU構(gòu)建系統(tǒng)其實是非常難用的饺谬,學習成本比較高捂刺。
原文來自:http://os.51cto.com/art/201609/518191.htm
本文地址:http://www.linuxprobe.com/system-gnu-autotool.html編輯:馮琪,審核員:逄增寶
《Linux就該這么學》是由資深運維專家劉遄及全國多名紅帽架構(gòu)師(RHCA)基于最新RHEL7系統(tǒng)共同編寫的高質(zhì)量Linux技術(shù)自學教程募寨,極其適合用于Linux技術(shù)入門教程或講課輔助教材叠萍。
? 劉遄老師QQ:5604241
? 學員助教QQ:5604674
? Linux技術(shù)交流A群(滿):560843
? Linux技術(shù)交流B群:340829
? Linux技術(shù)交流C群:463590
? 官方站點:www.linuxprobe.com
? 電腦在線閱讀效果更佳:
http://www.linuxprobe.com/chapter-00.html
按住圖片3秒,即可自動關(guān)注绪商。
點擊左下角查看更多熱門技術(shù)
添加微信公眾號《Linux就該這么學》,掌握最新IT資訊動態(tài)辅鲸,免費領(lǐng)取Linux課程以及專業(yè)的RHCE考前答疑服務(wù)格郁。
《Linux就該這么學》在線免費閱讀地址:http://www.linuxprobe.com/
閱讀原文:http://linux-love.lofter.com/post/1e7041ab_ca9f0ef