CMake 是一種跨平台的自動化建構工具。主要用來管理軟體建置,透過撰寫CMakeList來控制建構過程(build process),將工程搭建的步驟變得簡單容易。CMake能夠生成makefile、Visual Studio或是Xcode的project文件。
到CMake官網尋找符合的平台下載連結,這裡選擇Window並下載Installer版本。
點擊Next按鈕。
Accept並點擊Next按鈕。
選擇「Add CMake to the system PATH for the current user」並點擊Next。
選擇安裝的路徑並點擊Next。
點擊Install。
等待安裝過程。
完成。
那...在我們認識CMake之前,我們在解決方案的資料夾中建立src資料夾來存放我們的原始碼,並將Source.cpp移到src裡面,將其餘檔案都刪除。在管理專案中,我們需要撰寫CMakeList來控制建構過程。因此我們先建立一個CMakeList.txt。我們的資料夾會是這樣。
test
├─ CMakeLists.txt
└─ src
└─ Source.cpp
#設定CMake最低版本
cmake_minimum_required(VERSION 3.21)
#建立解決方案
project(test
VERSION 0.0.0
DESCRIPTION "DESCRIPTION"
LANGUAGES CXX
)
#設定C++標準
set(CMAKE_CXX_STANDARD 17)
#設定變數SOURCE 存放原始碼C++檔案
set(SOURCES
${CMAKE_SOURCE_DIR}/Source.cpp
)
#設定變數HEADERS 存放標頭檔
set(HEADERS
)
#新增一個應用程式,並列出其source files
add_executable(test ${SOURCES} ${HEADERS})
接著我們創建一個build資料夾並在裡面執行cmake指令。
/*建立build資料夾*/
mkdir build
/*移入build資料夾*/
cd build
/* cmake <CMakeLists所在的資料夾> */
cmake ../
會發現執行後多出了幾個文件,目錄中應該是如下圖,我們來一一介紹。
test
├─ CMakeLists.txt
├─ build
│ ├─ ALL_BUILD.vcxproj
│ ├─ ALL_BUILD.vcxproj.filters
│ ├─ CMakeCache.txt
│ ├─ CMakeFiles
│ ├─ ZERO_CHECK.vcxproj
│ ├─ ZERO_CHECK.vcxproj.filters
│ ├─ cmake_install.cmake
│ ├─ test.sln
│ ├─ test.vcxproj
│ └─ test.vcxproj.filters
└─ src
└─ Source.cpp
總共多出了三個副檔名為.vcxproj的專案(Project)和一個副檔名為.sln的解決方案。其中有ALL_BUILD與ZERO_CHECK我們在昨天的介紹並未提及,而它們是在運行CMake時會自動生成的兩個專案,他們的作用如下。
ALL_BUILD
會編譯、構建除了install和unit test以外所有的專案。
ZERO_CHECK
它將會檢查CMakeLists.txt的變化,如果與檢查出變化將會重新建構整個工程。
而還有其他與CMake相關的檔案
CMakeCache.txt
儲存Configure的結果,可以透過cmake-gui來更改。
cmake_install.cmake
CMakeLists.txt中使用INSTALL指令來設定,用於生成與安裝檔案。
透過上面的小介紹後,我們大致上可以知道CMake幫助我們來生成解決方案與專案,因此我們便不需要在專案有變動時手動的在Visual Studio裡面設定、而在不同環境中也能快速且方便的將我們的專案跑起來。接下來我們就來看看更多的CMake語法吧。
message(helloworld)
# helloworld
set(var hello)
message(${var})
# hello
set(var hello world)
# var 為 list "hello","world"
set(var "hello world")
# var 為 string "hello world"
foreach(<loop_var> <items>)
<commands>
endforeach()
set(var hello world)
foreach(word var)
message(${word})
endforeach()
# hello
# world
add_subdirectory(source_dir [binary_dir] [EXCLUDE_FROM_ALL])
add_executable(<name> [WIN32] [MACOSX_BUNDLE]
[EXCLUDE_FROM_ALL]
[source1] [source2 ...])
add_library(<name> [STATIC | SHARED | MODULE]
[EXCLUDE_FROM_ALL]
[<source>...])
C:\Program Files
find_package(<PackageName> [version] [EXACT] [QUIET] [MODULE]
[REQUIRED] [[COMPONENTS] [components...]]
[OPTIONAL_COMPONENTS components...]
[REGISTRY_VIEW (64|32|64_32|32_64|HOST|TARGET|BOTH)]
[GLOBAL]
[NO_POLICY_SCOPE]
[BYPASS_PROVIDER])
target_include_directories(<target> [SYSTEM] [AFTER|BEFORE]
<INTERFACE|PUBLIC|PRIVATE> [items1...]
[<INTERFACE|PUBLIC|PRIVATE> [items2...] ...])
target_link_libraries(<target> ... <item>... ...)
set_target_properties(target1 target2 ...
PROPERTIES prop1 value1
prop2 value2 ...)
target_compile_options(<target> [BEFORE]
<INTERFACE|PUBLIC|PRIVATE> [items1...]
[<INTERFACE|PUBLIC|PRIVATE> [items2...] ...])
target_compile_definitions(<target>
<INTERFACE|PUBLIC|PRIVATE> [items1...]
[<INTERFACE|PUBLIC|PRIVATE> [items2...] ...])
除了常用的函式語法,CMake還有不少預設的變數可以使用。
UNIX
WIN32 /*MINGW、CYGWIN、MSYS 時為 True*/
APPLE
MINGW
MSYS
CYGWIN
BORLAND
WATCOM
MSVC, MSVC_IDE, CMAKE_COMPILER_2005, MSVC60, MSVC70, MSVC71, MSVC80, MSVC90, MSVC10
/* 微軟的VS專案 */
要...要超時了Rrrrrrr