make makefile cmake qmake都是什麼,有什麼區別?

查了一下好像是編譯用的,既然是編譯為什麼我們不用g++ javac 來編譯呢?我猜答案是方便一點,但是具體方便在哪呢,請明示。還有它們之間如果有相似性的話,也幫我比較一下吧,謝謝各位大神。


1. make 是用來執行Makefile的

2. Makefile是類unix環境下(比如Linux)的類似於批處理的"腳本"文件。其基本語法是: 目標+依賴+命令,只有在目標文件不存在,或目標依賴的文件更舊,命令才會被執行。由此可見,Makefile和make可適用於任意工作,不限於編程。比如,可以用來管理latex。

3. Makefile+make可理解為類unix環境下的項目管理工具,但它太基礎了,抽象程度不高,而且在windows下不太友好(針對visual studio用戶),於是就有了跨平台項目管理工具cmake

4. cmake是跨平台項目管理工具,它用更抽象的語法來組織項目。雖然,仍然是目標,依賴之類的東西,但更為抽象和友好,比如你可用math表示數學庫,而不需要再具體指定到底是math.dll還是libmath.so,在windows下它會支持生成visual studio的工程,在linux下它會生成Makefile,甚至它還能生成eclipse工程文件。也就是說,從同一個抽象規則出發,它為各個編譯器定製工程文件。

5. cmake是抽象層次更高的項目管理工具,cmake命令執行的CMakeLists.txt文件

6. qmake是Qt專用的項目管理工具,對應的工程文件是*.pro,在Linux下面它也會生成Makefile,當然,在命令行下才會需要手動執行qmake,完全可以在qtcreator這個專用的IDE下面打開*.pro文件,使用qmake命令的繁瑣細節不用你管了。

總結一下,make用來執行Makefile,cmake用來執行CMakeLists.txt,qmake用來處理*.pro工程文件。Makefile的抽象層次最低,cmake和qmake在Linux等環境下最後還是會生成一個Makefile。cmake和qmake支持跨平台,cmake的做法是生成指定編譯器的工程文件,而qmake完全自成體系。

具體使用時,Linux下,小工程可手動寫Makefile,大工程用automake來幫你生成Makefile,要想跨平台,就用cmake。如果GUI用了Qt,也可以用qmake+*.pro來管理工程,這也是跨平台的。當然,cmake中也有針對Qt的一些規則,並代替qmake幫你將qt相關的命令整理好了。

另外,需要指出的是,make和cmake主要命令只有一條,make用於處理Makefile,cmake用來轉譯CMakeLists.txt,而qmake是一個體系,用於支撐一個編程環境,它還包含除qmake之外的其它多條命令(比如uic,rcc,moc)。

上個簡圖,其中cl表示visual studio的編譯器,gcc表示linux下的編譯器


1.gcc是GNU Compiler Collection(就是GNU編譯器套件),也可以簡單認為是編譯器,它可以編譯很多種編程語言(括C、C++、Objective-C、Fortran、Java等等)。

2.當你的程序只有一個源文件時,直接就可以用gcc命令編譯它。

3.但是當你的程序包含很多個源文件時,用gcc命令逐個去編譯時,你就很容易混亂而且工作量大

4.所以出現了make工具

make工具可以看成是一個智能的批處理工具,它本身並沒有編譯和鏈接的功能,而是用類似於批處理的方式—通過調用makefile文件中用戶指定的命令來進行編譯和鏈接的。

5.makefile是什麼?簡單的說就像一首歌的樂譜,make工具就像指揮家,指揮家根據樂譜指揮整個樂團怎麼樣演奏,make工具就根據makefile中的命令進行編譯和鏈接的。

6.makefile命令中就包含了調用gcc(也可以是別的編譯器)去編譯某個源文件的命令。

7.makefile在一些簡單的工程完全可以人工手下,但是當工程非常大的時候,手寫makefile也是非常麻煩的,如果換了個平台makefile又要重新修改。

8.這時候就出現了Cmake這個工具,cmake就可以更加簡單的生成makefile文件給上面那個make用。當然cmake還有其他功能,就是可以跨平台生成對應平台能用的makefile,你不用再自己去修改了。

9.可是cmake根據什麼生成makefile呢?它又要根據一個叫CMakeLists.txt文件(學名:組態檔)去生成makefile。

10.到最後CMakeLists.txt文件誰寫啊?親,是你自己手寫的。

11.當然如果你用IDE,類似VS這些一般它都能幫你弄好了,你只需要按一下那個三角形

12.接著是qmake,qmake是什麼,先說一下Qt這個東西。Qt是跨平台C++圖形用戶界面應用程序開發框架。它既可以開發GUI程序,也可用於開發非GUI程序,比如控制台工具和伺服器。簡單的說就是C++的第三方庫,使用這個庫你可以很容易生成windows,Linux,MAC os等等平台的圖形界面。現在的Qt還包含了開發各種軟體一般需要用到的功能模塊(網路,資料庫,XML,多線程啊等等),比你直接用C++(只帶標準內褲那種)要方便和簡單。

13.你可以用Qt簡簡單單就實現非常複雜的功能,是因為Qt對C++進行了擴展,你寫一行代碼,Qt在背後幫你寫了幾百上千行,而這些多出來的代碼就是靠Qt專有的moc編譯器(The Meta-Object Compiler)和uic編譯器(User Interface Complier)來重新翻譯你那一行代碼。問題來了,你在進行程序編譯前就必須先調用moc和uic對Qt源文件進行預處理,然後再調用編譯器進行編譯。上面說的那種普通makefile文件是不適用的,它沒辦法對qt源文件進行預處理。所以qmake就產生了。

14.qmake工具就是Qt公司製造出來,用來生成Qt 專用makefile文件,這種makefile文件就能自動智能調用moc和uic對源程序進行預處理和編譯。qmake當然必須也是跨平台的,跟cmake一樣能對應各種平台生成對應makefile文件。

15.qmake是根據Qt 工程文件(.pro)來生成對應的makefile的。工程文件(.pro)相對來說比較簡單,一般工程你都可以自己手寫,但是一般都是由Qt的開發環境 Qt Creator自動生成的,你還是只需要按下那個邪惡三角形就完事了。

16.還沒有完,由於qmake很簡單很好用又支持跨平台,而且是可以獨立於它的IDE,所以你也可以用在非Qt工程上面,照樣可以生成普通的makefile,只要在pro文件中加入CONFIG -= qt 就可以了。

17. 這樣qmake和cmake有什麼區別?

不好意思,cmake也是同樣支持Qt程序的,cmake也能生成針對qt 程序的那種特殊makefile,

只是cmake的CMakeLists.txt 寫起來相對與qmake的pro文件複雜點。

qmake 是為 Qt 量身打造的,使用起來非常方便,但是cmake功能比qmake強大。

一般的Qt工程你就直接使用qmake就可以了,cmake的強大功能一般人是用不到的。

當你的工程非常大的時候,又有qt部分的子工程,又有其他語言的部分子工程,據說用cmake會 方便,我也沒試過。


cmake is great. don"t waste time on other C++ build tools, seriously.


CMake is CMake, others are bullshit.


所有的 cmake/scons ... 這類工具,製造的問題比解決的問題還多,都是一些自以為是的業餘玩家搞出來的「玩具級產品」。

實際上,使用 Makefile 結合 shell 腳本,可以很方便地解決所有的編譯問題,用好 Makefile,可以讓你遠離這些玩具的毒害。

我一直盡量避免使用 cmake,但是總有一些第三方庫會使用 cmake,要把第三方庫集成進我們系統的自動編譯,每次都會被坑!特別是,我們使用不同的 c++ 編譯器/版本分別編譯不同的二進位和庫。

小坑:

  1. unix/linux/cygwin 中:C/C++ 編譯器、連接器變數,不使用標準的 CC/CXX/LD ....,而是使用 CMAKE_XXXXX
  2. 生成的 msvc 工程,編譯 完之後,會調用 cmake 再生成一遍工程文件,導致 visual c++ 頻繁載入工程文件,並且自己的所有修改(小修改經常不可避免)全部失效

大坑:

  1. 自作聰明地檢測 C 編譯器,如果 C 編譯器被設置為 C++ 編譯器,就會報錯,而且還沒法解決
  • C++ 編譯器在發現文件後綴名是 .c 時,會自動切換到 c 編譯器模式,cmake 有一種裝逼的方式可以把 c 文件當作 c++ 編譯,但這樣,會強制使用 c++ 模式編譯 c 文件

先總結這幾點,待續……


假設你需要編譯一個較大的工程,比如一個項目包含若干個子項目,一次編譯需要較長時間;

每次修改後你重修編譯總不至於要重新編譯整個工程吧。。。。

這就是Makefile優於gcc g++的地方,gcc g++編譯小項目倒可以。

事實上,Makefile是定義編譯規則、鏈接規則依賴關係的文件,可以看做是一系列的gcc/g++

命令。

但通常大項目各文件依賴關係複雜,makefile並不好寫;而cmake則提供了自動構造makefile的一種工具,很方便。同樣的工具還有autotool,但我覺得cmake更方便。最近,我已經完全轉入cmake編譯工程了,工程目錄十分清晰。至於qmake,是qt下編譯工具。


編譯代碼只要用gcc, javac, cl之類的工具就可以了。要編譯多個文件,當然可以寫個批處理。

但是考慮到:減少修改文件時運行這些命令的次數,要分析依賴。不同平台有不同的 toolchain,如 gcc,msvc,ndk gcc,clang,要便於切換。如果代碼依賴第三方庫,還要處理依賴關係。等等需求,批處理難呀。

所以要用更好用的工具,make, automake, cmake, qmake, scons, premake, gradle 等就是幫你做好部分這些需求,幫你管理好編譯流程。其中cmake比較重量級,輸出支持也是最好的,如生成vs工程文件。各有優劣,可以Google比較。


你們對著一個沒有需求的人說那麼多功能有啥用,等他編譯的程序夠大的時候他就會來關閉這個問題了。


按照特定規則 組織 源碼文件列表 的文本類型的文檔

用來指導 源碼文件的 鏈接 編譯 工作

他們之間 是 雷同 或者近似 關係。


我認為qmake遠比cmake複雜,因為官方教程寫的不好,很多用法看不 太懂,而cmake的教程相對比較清晰。其實構建工具本身也是一種編程語言,如果教程都不清晰,不能了解構建工具的全貌原理的話,用起來是相當不靠譜的,所以小工程用用qmake可以,大工程就需要去專研qmake的各種使用細節了(苦逼),比如

build_all:!build_pass {
CONFIG -= build_all
CONFIG += release
}

這句話是什麼意思?這個語法是相當怪異的。而你去看官方文檔,估計看半天仍然不能理解這句話是啥意思。當然如果你對qmake了解的相當熟悉(問題就是不知道怎麼去學)那麼用來構建大工程也沒有問題,畢竟qtcreator本身就是用qmake來構建的。總之,為了省事,還是學cmake吧,qmake的高級用法太難掌握了。


autotools,cmake,qmake 用來生成Makefile。

make用來執行Makefile。


CMake is your choice. Others is bullshit!


推薦閱讀:

TAG:編譯 | Makefile | make | CMake |