CMake 介紹——圖
CMake特點
- CMake需要使用者用CMake規範的語法編寫CMake指令碼,該語法簡單易用,入門極其順手
- 原生支援 C/C++/Fortran/Java 的相依性的自動分析功能,免除了程式設計師對程式碼依賴的調整,對整個開發工作幫助很大
- 支援 SWIG、Qt、FLTK 開發框架
- 支援跨平臺編譯,這是CMake名字的來源
- 能夠轉換特殊平臺的 IDE 專案文件,如xcode
- 與Dart、CTest 和 CPack 整合,可以組成自動化的構建系統
CMake vs GNU AutoTools
使用CMake,程式設計師必需編寫好CMake指令碼CMAkeLists.txt,對於一些複雜的專案,可能需要編寫CMake模組,但對於構建過程而言,則是極其簡單的。 相形之下,GNU AutoTools是很複雜的,無論是程式設計師在撰寫Makefile.am,還是構建時的步驟。致命的是,GNU AutoTools間很難相容。
GNU AutoTools構建流程
CMake 構建流程
另外,CMake的構建過程會比GNU AutTools在速度上有優勢,在輸出上更是很友好。
下面的是來自Google的趨勢圖,可以看出CMake的應用情況。
簡單的CMake專案
我們先來看個簡單的CMake專案。這裡有4個檔案:CMakeLists.txt, main.cpp, pr.cpp, pr.h。
CMakeLists.txt的內容如下:project(MyProject)
cmake_minimum_required(VERSION2.8)
add_library(pr SHARED pr.cpp)
target_link_libraries(pr m) add_library(prs STATIC pr.cpp) target_link_libraries(prs m) set_target_properties(prs PROPERTIES OUTPUT_NAME pr) add_executable(mypr main.cpp) target_link_libraries(mypr pr)
set(PR_HEADER pr.h) install(TARGETS mypr pr prs RUNTIME DESTINATION bin LIBRARY DESTINATION lib ARCHIVE DESTINATION lib/static) install(FILES ${PR_HEADER} DESTINATION include)
這個CMake指令碼聲明瞭此專案名為MyProject,並要求cmake的最少版本為2.8。 通常情況下2.6以上的特性不會用到,除非在一些複雜的專案中要自己處理一些問題而用到例如function這樣的巨集。
- add_executable的作用是指示CMake生成一個可執行檔案。
- add_library的作用是指示CMake生成一個庫,根據引數SHARED還是STATIC來決定生成動態庫還是靜態庫。
- target_link_libraries指示傳遞給ld的外部庫,相當於傳給gcc的-lxx。
- set_target_properties則是用於修改構建目標的一些屬性,如上的語句則是讓目標prs的輸出libprs.a改名為libpr.a。
- set是CMake中常用的命令,用於設定變數,也能修改內部變數
- install用於生成make install使用的語句
要構建這個專案,可在所在目錄建立一個目錄,例如名為build,並切換到該目錄,然後執行cmake .. && make
路徑
一般的專案會涉及到多個模組,文件以及測試用例等。下圖為一般CMake專案的檔案佈局。每一層目錄如果包含有構建目標,一般都會有一個CMakeLists.txt。
包含CMakeLists.txt的子目錄通常由上層的CMakeLists.txt用語句add_subdirectory來包含。對於這個專案而言,頂層的CMakeLists.txt包含如下的語句:add_subdirectory(include)
add_subdirectory(src)
add_subdirectory(tests)
add_subdirectory(docs)
在多個模組的情況下,可能一個模組的連結依賴於其它模組,例如一個可執行二進位制需要連結某些模組,此時link_directories將有發揮作用。
如在CMakeLists.txt增加:link_directories(${MyProject_BINARY_DIR}/src/libxxx
${MyProject_BINARY_DIR}/src/libyyy)
將指示CMake在LDFLAGS附加-Lsrc/libxxx -Lsrc/libyyy。
放置在src下的程式碼要引用include的標頭檔案,可以使用相對路徑引用,也可以讓include放置在標頭檔案搜尋路徑中,即CPPFLAGS,-Iinclude。如何指示CMake呢?只需要加上include_directories(BEFORE include),或者include_directories(BEFORE ${MyProject_SOURCE_DIR}/include),前者引用CMakeLists.txt的相對路徑,而後者則是依專案的完整路徑。
其它
在上面提及到set可以修改一些內部變數,例如可以修改編譯器的引數,如set(CMAKE_C_FLAGS ”-std=c99 -O2 -pipe -Wall -Wextra”)
set(CMAKE_C_FLAGS_DEBUG ”${CMAKE_C_FLAGS} -g -ggdb -pg”)
set(CMAKE_C_FLAGS_RELEASE ”${CMAKE_C_FLAGS} -s -DNDEBUG”)
CMake還提供了一些find函式,如find_package、find_library,用於檢查專案構建的依賴或者控制功能的開啟。 這些功能已經超出今天的簡單介紹,有興趣的朋友請參考官方資訊。
參考