天天看點

跟濤哥一起學嵌入式 18:Autotools發展史

在linux下面撸過代碼、做過開發的,想必都聽說過Makefile。

對,是Makefile,不是make love。如果你看成了後者,隻能說:同志,你的三觀有問題,需要格式化你的硬碟!

跟濤哥一起學嵌入式 18:Autotools發展史

在linux開發程式,沒有內建開發環境IDE(integrated development environment),沒有VC++6.0,

隻有Makefile和冰冷黑漆漆的shell視窗,寒冷的夜,考驗着每一個工程師疲憊的心

Makefile文法複雜、難以維護。對于一個小項目還好,對于大型的項目和開源項目,現在流行使用一些工具自動生成Makefile,可以大大減輕軟體開發人員的負擔。

比較常見的工具有GNU Autotools、CMake、QMake、SCons、Ant等。今天講講GNU Autotools,這個工具在開源軟體和大型項目中被廣泛地使用。

Autotools主要有Autoconf、automake、libtool等軟體包工具組成,我們可以稱為Autotools三劍客。

使用這幾個工具,雖然能幫助我們自動生成Makefile,但是指令過程複雜,中間會生成大量的各種配置檔案和腳本。很多人往往會覺得很麻煩、搞不懂裡面錯綜複雜的關系,今天以這些工具的發展過程,給大家理理裡面的關系。

一、手工makefile時代

早期我們在Unix、linux環境下開發軟體,makefile都是手寫的。通過makefile,我們就可以使用make指令直接去編譯我們的源代碼。

跟濤哥一起學嵌入式 18:Autotools發展史

後來,随着Unix版本越來越多,各分支差異越來越大,我們寫的makefile,有時候在其它Unix平台上可能就編譯失敗,比如庫的問題等。不同的作業系統版本,庫和頭檔案的路徑可能不一樣。怎麼辦?

後來我們通過手寫一個配置腳本configure來解決這個問題:針對你目前的Unix平台,通過腳本對makefile進行配置,就可以在目前平台上愉快地編譯了。

跟濤哥一起學嵌入式 18:Autotools發展史

二、Autoconf時代

後來linux作業系統問世,後續的版本也越來越多,各種釋出版本錯綜複雜,比如Redhat系列、debian系列等。差異越來越大,甚至包括作業系統的接口都出現差異。這時候别說makefile能不能正确編譯的問題了,就連我們編寫的應用程式,即使編譯正确,也有可能在其它的平台上運作不起來。這個問題,大家都知道,後來出現了POSIX API标準,就是可移植的作業系統接口。就是無論你是釋出什麼版本的Unix、Linux,OS的接口要遵循這個标準,這樣我們編寫的應用程式才能在linux、Unix等系列版本的作業系統上暢通無阻地運作。

而對于makefile來說,為了适配作業系統的更多版本,隻能不斷地添加代碼,這就導緻configure腳本越來遠大,導緻後來開發人員再也受不了了,維護成本越來越高。

1991年,David Mackenzie開發了Autoconf工具,用來自動生成configure腳本。因為對于大多數使用者來說,對于不同版本的差異、庫的版本、底層的細節,鬼才懶得管。他們關心的就是庫檔案、頭檔案的位置、軟體最終的安裝路徑是在哪裡。是以這個工具的出現,大大解放了開發人員的時間,給廣大程式員帶來了福音。

使用者隻需要定義幾個宏,表示我們關心的配置選項,儲存在configure.ac檔案裡,然後使用Autoconf工具就可以幫我們自動生成configure腳本了!

跟濤哥一起學嵌入式 18:Autotools發展史

Autoconf工具真是比大姨媽還貼心,為了減輕程式員的負擔,configure.ac檔案也不用我們手寫了。Autoconf工具包裡有個autoscan工具,可以自動掃描我們的項目,生成一個configure.scan檔案,裡面自動添加了很多宏,省得我們再手工添加。

我們隻需要将這個configure.scan檔案重命名為configure.ac檔案,再修修補補,就可以了。

跟濤哥一起學嵌入式 18:Autotools發展史

Autoconf工具大大減輕了程式員的負擔,媽媽,再也不用擔心晚回家吃飯了

三、automake時代

然而,随着項目越來越大,makefile也越來越複雜,尤其是大型項目,手寫越來越困難,怎麼辦?

automake工具這個時候閃亮登場了!

對于開發人員來說,我們關心的就是這個項目要生成什麼可執行檔案,需要編譯哪些源檔案,至于怎麼編譯的?底層的連結細節,鬼才懶得管。程式員的加班已經夠多,内心已經夠疲憊,我們拒絕makefile的肆虐和壓迫!

使用automake工具,我們隻需要手工編寫一個makefile.am檔案,在裡面定義我們想要生成的目标、需要編譯的源檔案,然後使用automake工具就可以幫我們自動生成makefile!

但是此時的makefile,是通用的makefile,定義了程式編譯、連結的通用規則,儲存在makefile.in裡面。

如果想在特定平台上成功編譯,還需要我們前面的腳本configure配置一下,最終才生成我們項目的Makefile。

跟濤哥一起學嵌入式 18:Autotools發展史

Autoconf工具通過定義一系列的宏,提供給我們使用,讓我們去設定一些需要的配置選項、去配置我們的makefile。

後來Automake工具出現後,自定義了一些宏,對這些宏進行了擴充。比如,Autoconf以前都是單獨使用的,現在要跟automake配合使用,要在configure.ac檔案裡添加一個AM_INIT_AUTOMAKE這個宏。

這個宏是在automake工具包裡定義的,當我們運作autoconf指令的時候,就是出錯,因為找不到這個宏的定義。怎麼辦,咋辦?

後來在configure.ac同目錄下,定義一個aclocal.m4格式的檔案,裡面存放使用者定義的一些宏、或者automake的一些宏,這樣,autoconf運作的時候,就可以在這個檔案裡找到宏定義了。

偷懶,是人類社會進步的最大動力。後來,為了進一步減少工作量,又出現一個aclocal工具,會自動将automake、autoconf以及使用者定義的所有宏統統放在aclocal.m4檔案裡。

跟濤哥一起學嵌入式 18:Autotools發展史

為什麼要儲存在aclocal.m4這種格式的檔案裡?我也不知道....,m4,macro宏後面4個字母,縮寫就是m4.

文本檔案嘛,字尾名可以随便定義,比如我姓王,字尾名定義為.wang也是可以的。不要糾結于這些細節,我們的征途是建構makefile。

autoconf工具包裡還有一個autoheader工具,用來将configure.ac裡面的宏配置轉換為我們C語言格式的#define形式,并儲存在config.h.in檔案裡,當我們運作./configure生成makefile的時候,順便也會将config.h.in轉換為config.h檔案,這樣在我們的程式裡,如果想使用這些宏,就可以直接#include “config.h”就可以了。

跟濤哥一起學嵌入式 18:Autotools發展史

比如頭檔案裡面定義的軟體版本号VERSION宏,就可以在程式裡直接使用,列印在程式裡列印我們的軟體版本号。

四、libtool時代

随着Unix、Linux之間的差異越來越大,對動态共享庫的管理差異也越來越大,比如有些共享庫,使用.so格式,有的是.a,有的是.o的形式。運作時對動态庫的管理方式也一樣,有的作業系統支援動态加載,有的就不支援。這就對我們Makefile帶來了挑戰。怎麼辦?libtool的工具出現就是為了解決這個問題的,它通過對生成的動态庫進行抽象,統一生成.la的形式,可以支援十幾種各種不同的平台。

跟濤哥一起學嵌入式 18:Autotools發展史

具體的使用教程,可以參考我釋出的視訊教程:《Makefile工程實踐》第二季--使用autotools自動建構項目的Makefile。

繼續閱讀