為什麼會選擇 make,cmake 之流來控制程序編譯,而不是用現成的腳本語言,如 Python?
make的核心是自動查找有變化的源文件和target,有變化的就重新編譯,然後它是一個倒序結構。
如果你把編譯成功一個項目當作一個目標,常規的思路是我先執行1,然後2,然後3,然後4,在複雜有些分支啥的。
但是實際上,一個項目的依賴其實是很複雜的樹形結構。你想寫一個順序執行的1,2,3,4就很難。同時,這些文件可能有些被修改了,那麼我們希望編譯系統不要重複編譯那些已經編譯過的內容。該怎麼辦么?首先我們假設你有如下一個依賴鏈。你可以手工編譯xxx.c成為xxx.o,手工編譯yyy1.c和yyy2.c成為yyy.o,等等。正序寫這麼一個編譯腳本不難。判斷一下那個文件修改了也不難。但是一個項目是發展的,滿滿的依賴樹越來越複雜怎麼辦?
Makefile的寫法其實就是用文字來表達這顆依賴樹,把最終目標寫在前面,然後列出,這個目標需要的幾個前驅依賴是什麼,然後,這幾個前驅依賴需要的依賴又是什麼。這樣就自然而然的把問題簡化了。
我當年做搜索到時候,我們有一堆日誌放在某個目錄,我就寫了一個Makefile腳本來處理它們,把統計結果當作最終目標,每個日誌文件(用通配符來枚舉全部可能的日誌文件)當作前驅依賴。然後定期執行這個Makefile,這樣老的處理過的日誌就不會參與運算,只有新的日誌才會參與運算。
當然Makefile發展了無數年,make工具發展了無數代,在這個基本原理上有了大量的擴充,有autotools,cmake這類東西,裡面包含了很多自己的擴展,你需要先理解他們的一些自身的設計和功能才行。自己造輪子,不也得過一遍功能,等你過一遍學會了,發現也就那樣,搞不好還喜歡呢,也就不會想自己寫了。
只要是語言都是圖靈完備的,不存在實現不了。Ruby/Perl 的此類DSL不也很多,大部分也就實現個子集罷了。有啊 SCons 我覺得比makefile難用...
我就用python寫make,因為我總是記不住make的各種規則。
這個我還是有點發言權,python的應該也有, Linux上SDK自動構建工具Yocto(大概是這個名字,可能有拼寫錯誤)就是python的。。。但是你要考慮現實問題:1. python可能需要各種第三方庫支持,公司里大家很多時候都是登錄到伺服器上開發,普通工程師沒有root許可權,缺庫的時候無法自己導入。。2. 不同公司開發環境會有差異,有些用Ubuntu,有些用Fedora,python可能用2.7也可能用3.0,缺庫問題是常態。。3.大家很多時候都在用遠程終端登錄,沒有桌面環境,用python寫的編譯系統,可能沒法通過圖形界面配置。。。4. Make是Linux系統原生的東西,可以和Kconfig配合,在遠程終端上就可以配置,很少有缺庫的情況(當然一般剛開始nurse庫可能要下載一下),把SDK release給客戶的時候,出現的兼容問題比較少,一般普通用戶許可權就能解決了。。。。5.綜上所述,公司的伺服器是共用的,不是私人的桌面電腦。。。自己私人的開發環境,愛用什麼就配什麼,沒啥撕逼的。
棄療吧,騷年。來搞前端,用gulp或grunt,很爽……
大家都知道,寫程序大體步驟為:
1.用編輯器編寫源代碼,如.c文件。
2.用編譯器編譯代碼生成目標文件,如.o。
3.用鏈接器連接目標代碼生成可執行文件,如.exe。
但如果源文件太多,一個一個編譯時就會特別麻煩,於是人們想到,為什麼不設計一種類似批處理的程序,來批處理編譯源文件呢,於是就有了make工具,它是一個自動化編譯工具,你可以使用一條命令實現完全編譯。但是你需要編寫一個規則文件,make依據它來批處理編譯,這個文件就是makefile,所以編寫makefile文件也是一個程序員所必備的技能。
對於一個大工程,編寫makefile實在是件複雜的事,於是人們又想,為什麼不設計一個工具,讀入所有源文件之後,自動生成makefile呢,於是就出現了cmake工具,它能夠輸出各種各樣的makefile或者project文件,從而幫助程序員減輕負擔。但是隨之而來也就是編寫cmakelist文件,它是cmake所依據的規則。所以在編程的世界裡沒有捷徑可走,還是要腳踏實地的。
原文件--camkelist ---cmake ---makefile ---make ---生成可執行文件
解釋下名詞make unix平台下的構建工具cmake 跨平台構建工具msbuild vs的構建工具vs Microsoft Visual Studio 集成開發環境 IDEIDE都有工程文件,那就是makefile.工程文件是IDE管理的.所以,你該去找個給力的IDE.
題主原話「我這幾天要做一個東西,要本地編譯github上面一個小項目,其中一個選擇make,另一個選擇了cmake來編譯。沒辦法,只好看看make,cmake官方文檔來學習下如何編譯。」我只能理解說是這個小項目提供了兩種Makefile生成方式,一個是GNU的Automake那一套,一個是CMake那一套。無論哪種對於「編譯這個項目」來說都是十分簡單的。而且一般項目如果編譯方式和標準流程不一樣都會有README的啊!!!!!連README都沒的項目要麼是個垃圾完全不要考慮用它,要麼實在是過於簡單了根本不需要讓你考慮怎麼才能編譯它的問題。能先看看README嗎?對於Automake那一套,無外乎
autoreconf 或者 ./bootstrap之類
./configure
make
對於CMake那一套,無外乎
mkdir build
cd build
cmake ../
make
根本不需要你去研究Makefile.am,CMakeLists.txt都是怎麼寫的,不需要關心什麼「語法」。又沒有讓你從頭給一個項目寫一個編譯控制文件,你只要照著標準流程會用就好了。
就算哪天你也要給自己的項目寫CMakeLists.txt,CMake的語法也夠簡單了。這都學不會,當什麼程序猿。百度內部有個叫comake的系統就是python寫的,原則上用python沒啥問題,更多的是歷史和習慣問題吧。
題主可以去看下 scons純py寫的構建工具.或者google家的gyp.
1 cmake make的語法和unix shell比較接近,有了了解之後你會發現它們也很自然。2 這種特定的用途,用來管理生成目標之間的依賴關係,僅僅是通用程序設計語言能力的一個很小的子集,在這裡使用這種領域專用的語言,可以在簡化語法的同時使表意更明確。3 如果你什麼時候需要在build前後同時執行一些其他的hook,那麼寫個shell script或者python程序,做一些其他的事情再調用make/cmake可能更合理。
怎麼沒有,scons啊
如果不限於Python語言, gradle 已經實現了您的需求。Gradle 這個工具是用Groovy腳本語言(基於jvm 的語言,和java 無縫集成)實現的。你在gradle可以直接寫Groovy做一些任務: 刪除文件,if else, 能寫任何groovy 語句,毫無限制。
可以試試xmake 基於lua的。。
你說的waf?scon?
Mastering CMake 里的一段話,應該能解答你的問題: