make和cmake

當工程中只有一個源文件時,能夠直接使用gcc命令來編譯,但如有多個源文件而且引用了外包時,包與包之間可能還存在各類依賴,使用gcc編譯則會顯得很是複雜混亂。在這種狀況下,make則可讓整個過程變得簡潔高效。make命令自己是沒有編譯、連接的功能,而是經過調用用戶在Makefile中的命令來執行編譯連接工做。Makefile中能夠調用gcc等各類編譯器或其餘命令來執行任務。值得一提的是,當源碼文件發生變化時,make能夠自動的指出哪個文件須要更新,同時也自動肯定以適當的順序進行更新文件,當一個非源碼文件依賴的另外一個非源碼文件發生改變時。 每次當咱們改變了系統中的一小部分源碼的時候,從新編譯整個程序的效率是很低的。而make僅僅更新那些直接或者間接依賴這些改變了的源碼文件的非源碼文件。但若想實現跨平臺的編譯,則得從新寫Makefile文件(好比在Linux中,Makefile中使用gcc做爲編譯器,但在windows(Visual Studio)則應該換成cl.exe做爲編譯器,命令的參數也應該作相應的修改),也是不小的工程量。cmake則是用來處理跨平臺的問題。它能夠根據CMakeLists.txt來跨平臺生成對應平臺能用的makefile。linux

1. Make是用來執行Makefile的,Makefile裏面是類Unix環境下的與Windows的批處理文件(.bat)相似的腳本文件。其基本語法是: 目標+依賴+命令,只有在目標文件不存在或目標比依賴的文件更舊,命令纔會被執行。因而可知,Makefile和make可適用於任意工做,不限於編程。好比,能夠用來管理latex。Makefile的語法舉例:假設有五個文件file1.cpp, file2.cpp, file2.h,其中file1.cpp中include了file2.h。若想生成可執行文件a.out,Makefile文件以下:編程

a.out: file1.o file2.o gcc file1.o file2.o -o a.out file1.o:file1.c file1.h gcc -c file1.c -o file1.o file2.o:file2.c file2.h gcc -c file2.c -o file2.o clean: rm -rf *.o helloworld 

注意:每一個命令行前都必須有tab符號。 

解釋: 

a.out: file1.o file2.o # a.out依賴file1.o file2.o兩個目標文件。 

gcc file1.o file2.o -o helloworld # 編譯出a.out可執行文件。-o表示你指定的目標文件名。 

file1.o: file1.c # file1.o依賴file1.c文件。 

gcc -c file1.c -o file1.o: # 編譯出file1.o文件。-c表示gcc 只把給它的文件編譯成目標文件。 

clean: 

rm -rf *.o a.out 

當用戶鍵入make clean命令時,會刪除 *.o 和a.out文件。 

寫好Makefile文件,在命令行中直接鍵入make命令,就會執行Makefile中的內容了。 windows

2. Makefile+make過於基礎,抽象程度不高,並且在windows下不太友好(針對visual studio用戶),因而就有了跨平臺項目管理工具cmake。cmake用更抽象的語法來組織項目,cmake命令執行的CMakeLists.txt文件。雖然,仍然是目標,依賴之類的東西,但更爲抽象和友好,好比你可用math表示數學庫,而不須要再具體指定究竟是math.dll仍是libmath.so,在windows下它會支持生成visual studio的工程,在linux下它會生成Makefile。也就是說,從同一個抽象規則出發,它爲各個編譯器定製工程文件。工具

總結:make用來執行Makefile,cmake用來執行CMakeLists.txt。Makefile的抽象層次最低,cmake在Linux等環境下會生成一個Makefile。cmake經過生成指定編譯器的工程文件來支持跨平臺的。spa

具體使用時,Linux下,只有少數幾個文件,能夠直接使用gcc來編譯,小工程可手動寫Makefile,大工程用cmake生成Makefile從而實現跨平臺。命令行



參考code

https://www.zhihu.com/question/27455963/answer/36722992blog

相關文章
相關標籤/搜索