前言:對於C/C++以及Linux用戶來說,編譯器,make,cmake這幾個工具是天天要接觸到的,那到底爲什麼要使用呢?本文做一個小小的總結。
一、編譯器gcc與g++
gcc是GNU Compiler Collection(就是GNU編譯器套件),也可以簡單認爲是編譯器,它可以編譯很多種編程語言(括C、C++、Objective-C、Fortran、Java等等)。
- 當你的程序只有一個源文件時,直接就可以用gcc命令編譯它。但是當你的程序包含很多個源文件時,用gcc命令逐個去編譯時,你就很容易混亂而且工作量大,爲什麼呢?
- 因爲各個文件之間還涉及到互相訪問與鏈接,錯綜複雜的關係一個一個處理很麻煩,很容易出錯,素衣需要一個工具來制定一個很好的編譯規則,這就是make的作用了
二、make工具
make工具可以看成是一個智能的批處理工具,它本身並沒有編譯和鏈接的功能,而是用類似於批處理的方式—通過調用makefile文件中用戶指定的命令來進行編譯和鏈接的。
2.1 makefile是什麼?
簡單的說就像一首歌的樂譜,make工具就像指揮家,指揮家根據樂譜指揮整個樂團怎麼樣演奏,make工具就根據makefile中的命令進行編譯和鏈接的。實際上makefile命令中就包含了調用gcc(也可以是別的編譯器)去編譯某個源文件的命令。
2.2 make的缺點
(1)各種各樣的make工具
你或許聽過好幾種 Make 工具,
- 例如 GNU Make ,QT 的 qmake ,微軟的 MS nmake,BSD Make(pmake),Makepp,等等。
這些 Make 工具遵循着不同的規範和標準,所執行的 Makefile 格式也千差萬別。這樣就帶來了一個嚴峻的問題:如果軟件想跨平臺,必須要保證能夠在不同平臺編譯。而如果使用上面的 Make 工具,就得爲每一種標準寫一次 Makefile ,這將是一件讓人抓狂的工作。
(2)makefile的編寫太麻煩
makefile在一些簡單的工程完全可以人工手下,但是當工程非常大的時候,手寫makefile也是非常麻煩的,如果換了個平臺makefile又要重新修改。
這時候就出現了Cmake這個工具,cmake就可以更加簡單的生成makefile文件給上面那個make用。當然cmake還有其他功能,就是可以跨平臺生成對應平臺能用的makefile,你不用再自己去修改了。
三、Cmake
CMake就是針對上面問題所設計的工具:它首先允許開發者編寫一種平臺無關的 CMakeList.txt 文件來定製整個編譯流程,然後再根據目標用戶的平臺進一步生成所需的本地化 Makefile 和工程文件,如 Unix 的 Makefile 或 Windows 的 Visual Studio 工程。從而做到“Write once, run everywhere”。顯然,CMake 是一個比上述幾種 make 更高級的編譯配置工具。一些使用 CMake 作爲項目架構系統的知名開源項目有 VTK、ITK、KDE、OpenCV、OSG 等。
可是cmake根據什麼生成makefile呢?它又要根據一個叫CMakeLists.txt文件(學名:組態檔)去生成makefile。
到最後CMakeLists.txt文件誰寫啊?親,是你自己手寫的。cmake是make maker,生成各種可以直接控制編譯過程的控制器的配置文件,比如makefile、各種IDE的配置文件。
四、一般的使用流程如下
在linux平臺使用CMake生成Makefile並編譯的一般流程如下:
- (1)編寫CMake配置文件CMakeLists.txt;
- (2)執行 cmake PATH 或者 ccmake PATH 生成Makefile。PATH是CMakeLists.txt所在目錄, cmake 與 ccmake 的區別在於後者提供了一個交互界面;它會自動搜索指定路徑PATH中的CMakelists.txt文件,進行操作,
- (3)執行 make -C PATH 命令進行編譯。 -C 表示到指定目錄下執行make, PATH 爲Makefile文件所在目錄。在Makefile文件所在目錄執行make命令,可以不需要帶任何參數,直接執行 make 命令進行編譯。
五、Linux源碼編譯的一般流程
經常使用Linux源碼編譯的人應該習慣使用兩套流程
- (1)流程一:./configure+make+make install
- (2)流程二:cmake+make+make install
現在集中回答幾個問題
5.1 ./configure和cmake有什麼異同點
相同點:
- (1)都是爲了生成編譯規則Makefile文件
- (2)他們都是爲了更加方便的開發部署程序的自動化工具autotools,automake和autoconf是非常有用的用來發布C程序的東西。autotools包含了一系列的工具,如aclocal 、autoscan 、autoconf 、autoheader、 automake等
不同點:
- (1)./configure就是執行你當前目錄下一個名叫configure的腳本,Configure是一個腳本配置工具,該文件裏面包含了很多的腳本命令。
- (2)cmake的目的也是一樣的,但是它所依據的是cmakelists.txt文件來生成Makefile文件
5.2 make和make install又有什麼區別
- make的作用是編譯,make的過程是把各種語言寫的源碼文件,變成可執行文件和各種庫文件。但是編譯出來的庫文件和可執行文件是分別放着的,還不像一個完整的程序包,沒有組織起來,
- make install是把這些編譯出來的可執行文件和庫文件複製到合適的地方。像一個真正安裝的程序包一樣。它的主要作用就是“文件拷貝”。它所依據的是內容也是來自Makefile文件裏面的內容。
實際上make和make install是兩個基本的過程,我們在使用ming-win64編譯OpenCV的時候就使用了這兩個步驟,在使用mingw32-make編譯完成之後,然後還要再使用mingw32-make install,將編譯好的可執行文件,庫文件拷貝到install文件夾之下的對應的文件夾裏面去。
即
- mingw32-make 編譯代碼,
- mingw32-make install 文件拷貝
實際上使用window上面的VS編譯OpenCV也是同樣的道理,只不過它是通過ALL_BUILD和INSTALL來完成的。
- 首先編譯ALL_INSTALL。ALL_BUILD相當於makefile裏面的默認目標,構建整個項目,但不包括install和單元測試什麼的。會將所有的代碼進行編譯,但是編譯的庫文件和可執行文件還沒有組織好;
- 然後編譯INSTALL。INSTALL是把編譯之後的文件拷貝到合適的文件夾之下。
總結:總的來說,源碼編譯必經的三個階段如下:
- 自動化工具(cmake,configure)構建Makefile;
- 所有項目的編譯(make)
- 編譯的結果的安裝,即文件拷貝(install)