linux編譯程序的時候,通常是使用Makefile文件來進行編譯,這個是能夠提高效率的,但是對於大中型的項目,每個文件夾下都需要創建Makefile,並且改變項目目錄結構都需要調整Makefile文件,如果是小型項目的話,那花費的時間還是能夠接受的,但是大中型項目要調整目錄結構,這個工作量還是不小的。所以,我們可以通過使用cmake來解決這樣的問題。
本文首先簡單介紹什麼是cmake,它可以用來幹什麼,接著給出一個簡單的例子,讓初學者對cmake有一個大致的了解,然後拋出cmake文件,並針對該cmake文件進行詳細的解釋,最後再進行總結,並分享個人的學習心得。
一、什麼是cmake
cmake一款跨平臺的編譯工具, 它的全稱是cross platform make,注意這裡的make不是指linux下的make,使用它構建的工程,既可以生成linux下的makefile,也可以生成Mac系統的xcode的工程文件,還能夠生成window的projects等。cmake並不會生成最終的軟體程序,它只是生成標準的建構檔,例如linux的Makefile文件。簡單來說,cmake可以生產不同平臺的建構檔,然後再由建構檔來生成最終的軟體程序。
cmake組織檔的取名都為CMakeLists.txt, 現在許多開源軟體都採用cmake來組織代碼,可見其用處還是很大的,學習了解cmake對於學習開源軟體是有很大的幫助的。
二、入門例子
首先電腦上需要安裝cmake軟體,具體下載安裝方法,可以網絡搜索,這不是本文的主題,所以不進行說明。
linux上安裝成功之後,可以執行命令cmake –version來查看當前的cmake版本
創建一個main.cpp文件,其內容如下所示,列印一句字符信息。
接著在同級目錄下創建cmake文件 CMakeLists.txt
為了代碼乾淨,同級目錄下創建build目錄,進入build目錄,執行「cmake ./」命令來生成Makefile文件,接著執行命令make編譯,最後build目錄下生成二進位文件example_01, 執行程序可以輸出列印信息。
build目錄下生成的文件內容如下,Makefile是生成的建構檔,example_01是生成的可執行二進位程序。
三、cmake代替Makefile
上面只是cmake的一個簡單的入門例子,還不能明顯看出cmake的強大,對於中大型的項目來看,cmake的作用就比較明顯,特別是相同代碼不同平臺的編譯。
下面給出本章節將要詳細解釋說明的cmake文件,可以先熟悉下整體的流程,看不明白沒有關係,後面將針對該文件進行詳細的解釋說明。
接下來就來詳細說明上面的cmake文件的功能含義。
cmake_minimum_required指定cmake最低版本號要求,FATAL_ERROR 表示當發生警告時,用錯誤方式提示
CMAKE_INCLUDE_CURRENT_DIR 自動增加CMAKE_CURRENT_SOURCE_DIR和CMAKE_CURRENT_BINARY_DIR到每個目錄的include路徑。CMAKE_INCLUDE_CURRENT_DIR默認是關閉的。
當前測試工程的目錄結構如下:
message可以列印輸出變量信息, CMAKE_CURRENT_SOURCE_DIR、CMAKE_CURRENT_BINARY_DIR、PROJECT_SOURCE_DIR是cmake內置變量。
運行後輸出列印的信息, CMAKE_CURRENT_SOURCE_DIR表示當前正在處理的原始碼目錄,CMAKE_CURRENT_BINARY_DIR表示當前正在處理的二進位目錄,PROJECT_SOURCE_DIR表示當前工程的頂層原始碼目錄
EXECUTABLE_OUTPUT_PATH表示可執行文件輸出路徑
find_package()命令是用來查找依賴包, Pkg-Config維護它依賴庫路徑、頭文件路徑、編譯選項、連結選項等信息。
關鍵字ENV查看的是當前環境變量,linux上的環境變量可以通過export命令來查看。
message(STATUS 「LANG: $ENV{LANG}」)對應輸出的內容為:
find_program查找可執行程序。一個名為<VAR>的cache條目會被創建用來存儲該命令的結果。如果該程序被找到了,結果會存儲在該變量CCACHE_FOUND。
set_property給定範圍內設置一個命名屬性,GLOBAL域是唯一的,PROPERTY後面緊跟著要設置的屬性的名字。
function,定義函數name, 並且參數為<arg1> … , 函數只有在調用的時候才起作用。
include_directories包含頭文件的搜索路徑。
link_directories指定查找庫的目錄。
target_link_libraries標示連結的庫。<target>必須時 add_executable() or add_library() 命令創建。<item>則是連結的庫
file產生一個匹配 <globbing-expressions> 的文件列表並將它存儲到變量 <variable> 中,果 RELATIVE 標誌位被設定,將返回指定路徑的相對路徑。file的第一個參數設置為GLOB_RECURSE,則表示遍歷匹配目錄的所有子目錄並匹配文件。
add_custom_command,定義一個跟指定目標target關聯的新的命令,命令何時執行取決於PRE_BUILD | PRE_LINK | POST_BUILD這三個參數。
四、總結
創建cmake文件的過程,首先當然是先創建CMakeLists.txt文件,接著聲明cmake的版本要求,然後設置項目信息,再根據具體場景設置相關屬性以及生成的可執行目標。
上面講解的例子中,主要涉及到cmake的幾個知識點。具體如下:
cmake的變量:內置變量、環境變量以及自定義變量。查找命令:find_package、find_program定義函數:function查找文件:file搜索路徑:include_directories、link_directories、target_link_libraries自定義命令:add_custom_command設置目標: add_executable五、學習心得
學習cmake也有一段時間,網絡上也搜索了很多信息,但是總感覺說的不夠明白和全面。最後發現要想全面的了解cmake, 最有效的方法就是直接查看cmake的官方文檔。雖然是英文,但是只要耐心認真閱讀,就會發現裡面講的很全面。然後再結合具體的例子進行消化理解就可以。而對於cmake的變量的含義,除了查看cmake官方文檔之後,還可以通過message直接列印出變量信息來加深理解其含義。