說起項目構(gòu)建工具,Linux 用戶最熟悉的恐怕就是 Autotools,它將編譯安裝這個步驟大大簡化。但對于項目作者來說,想要使用 Autotools 生成有效的配置文件著實需要下一番功夫,用現(xiàn)在流行的話來說就是用戶體驗不夠友好。對 Unix shell 的依賴,也使得 Autotools 天生對于跨平臺支持不佳。
后來我從大貓同學那里聽說了 CMake,CMake 使用 C++ 編寫,原生支持跨平臺,不需要像 Autotools 那樣寫一堆的配置文件,只需一個 CMakeLists.txt 文件即可。簡潔的使用方式,強大的功能使得我立馬對 CMake 情有獨鐘。在后來的使用過程中,雖然會遇到一些因為使用習慣帶來的小困擾,但我對于 CMake 還是基本滿意的。直到我發(fā)現(xiàn)了 GYP。
GYP(Generate Your Projects)是由 Chromium 團隊開發(fā)的跨平臺自動化項目構(gòu)建工具,Chromium 便是通過 GYP 進行項目構(gòu)建管理。為什么我要選擇 GYP,而放棄 CMake 呢?功能上 GYP 和 CMake 很是相似,在我看來,它們的最大區(qū)別在于配置文件的編寫方式和其中蘊含的思想。
編寫 CMake 配置文件相比 Autotools 來說已經(jīng)簡化很多,一個最簡單的配置文件只需要寫上源文件及生成類型(可執(zhí)行文件、靜態(tài)庫、動態(tài)庫等)即可。對分支語句和循環(huán)語句的支持也使得 CMake 更加靈活。但是,CMake 最大的問題也是在這個配置文件,請看下面這個示例文件:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
|
你能一眼看出這個配置文件干了什么嗎?其實這個配置文件想要產(chǎn)生的目標(target)只有一個,就是通過${VP8SRC}
編譯生成的靜態(tài)庫,但因為加上了條件判斷,及各種平臺相關(guān)配置,使得這個配置文件看起來很是復雜。在我看來,編寫 CMake 配置文件是一種線性思維,對于同一個目標的配置可能會零散分布在各個地方。而 GYP 則相當不同,GYP 的配置文件更多地強調(diào)模塊化、結(jié)構(gòu)化。看看下面這個示例文件:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
|
我們可以立馬看出上面這個配置文件的輸出目標只有一個,也就是 foo
,它是一個庫文件(至于是靜態(tài)的還是動態(tài)的這需要在生成項目時指定),它依賴的目標、宏定義、包含的頭文件路徑、源文件是什么,以及根據(jù)不同平臺設(shè)定的不同配置等。這種定義配置文件的方式相比 CMake 來說,讓我覺得更加舒服,也更加清晰,特別是當一個輸出目標的配置越來越多時,使用 CMake 來管理可能會愈加混亂。
配置文件的編寫方式是我區(qū)分 GYP 和 CMake 之間最大的不同點,當然 GYP 也有一些小細節(jié)值得注意,比如支持跨平臺項目工程文件輸出,Windows 平臺默認是 Visual Studio,Linux 平臺默認是 Makefile,Mac 平臺默認是 Xcode,這個功能 CMake 也同樣支持,只是缺少了 Xcode。Chromium 團隊成員也撰文詳細比較了 GYP 和 CMake 之間的優(yōu)缺點,在開發(fā) GYP 之前,他們也曾試圖轉(zhuǎn)到 SCons(這個我沒用過,有經(jīng)驗的同學可以比較一下),但是失敗了,于是 GYP 就誕生了。
當然 GYP 也不是沒有缺點,相反,我覺得它的「缺點」一大堆:
- 文檔不夠完整,項目不夠正式,某些地方還保留著 Chromium 的影子,看起來像是還沒有完全獨立出來。
- 大量的括號嵌套,很容易讓人看暈,有過 Lisp 使用經(jīng)驗的同學可以對號入座。對于有括號恐懼癥,或者不使用現(xiàn)代編輯器的同學基本可以繞行。
- 為了支持跨平臺,有時不得不加入某些特定平臺的配置信息,比如只適用于 Visual Studio 的
RuntimeLibrary
配置,這不利于跨平臺配置文件的編寫,也無形中增加了編寫復雜度。 - 不支持
make clean
,唯一的方法就是將輸出目錄整個刪除或者手動刪除其中的某些文件。
如果你已經(jīng)打算嘗試 GYP,那一定記得在生成項目工程文件時加上 --depth
參數(shù),譬如:
$ gyp --depth=. foo.gyp
這也是一個從 Chromium 項目遺留下來的歷史問題。
也許你根本用不上跨平臺特性,但是 GYP 依然值得嘗試。我編寫了一份 GYP 配置文件的模板,有興趣的同學可以參考。GYP 和 CMake 分別代表了兩種迥異的「風格」,至于孰優(yōu)孰劣,還得仁者見仁,智者見智。