iT邦幫忙

2022 iThome 鐵人賽

DAY 7
0

CMake

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。

等待安裝過程。

完成。

CMakeList

那...在我們認識CMake之前,我們在解決方案的資料夾中建立src資料夾來存放我們的原始碼,並將Source.cpp移到src裡面,將其餘檔案都刪除。在管理專案中,我們需要撰寫CMakeList來控制建構過程。因此我們先建立一個CMakeList.txt。我們的資料夾會是這樣。

test
├─ CMakeLists.txt
└─ src
     └─ Source.cpp
  • CMakeLists.txt
#設定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 語法

透過上面的小介紹後,我們大致上可以知道CMake幫助我們來生成解決方案與專案,因此我們便不需要在專案有變動時手動的在Visual Studio裡面設定、而在不同環境中也能快速且方便的將我們的專案跑起來。接下來我們就來看看更多的CMake語法吧。

語法相關

  • message
    可以印出訊息,而CMake基本的資料型態就是string。
message(helloworld)
# helloworld
  • set
    設定變數var,若值由空格分開則會以list的方式被儲存,若需要字串間有空格則可以以雙引號刮住。
set(var hello)
message(${var})
# hello

set(var hello world)
# var 為 list "hello","world"

set(var "hello world")
# var 為 string "hello world"
  • foreach
    for迴圈,語法如下。
foreach(<loop_var> <items>)
  <commands>
endforeach()
set(var hello world)
foreach(word var)
  message(${word})
endforeach()

# hello
# world

編譯相關

  • add_subdirectory
    添加一個子目錄去build,記得該目錄需要含有CMakeLists。
add_subdirectory(source_dir [binary_dir] [EXCLUDE_FROM_ALL])
  • add_executable
    添加Source file並新建一個名為name的應用程式專案。
add_executable(<name> [WIN32] [MACOSX_BUNDLE]
               [EXCLUDE_FROM_ALL]
               [source1] [source2 ...])
  • add_library
    添加Source file並建立一個名為name的函式庫
add_library(<name> [STATIC | SHARED | MODULE]
            [EXCLUDE_FROM_ALL]
            [<source>...])
  • find_package
    尋找一個第三方的套件是否存在,通常Windows的預設路徑為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
    編譯時所需要用到的include目錄,而target必須是以add_executable或是add_library所生成。
target_include_directories(<target> [SYSTEM] [AFTER|BEFORE]
  <INTERFACE|PUBLIC|PRIVATE> [items1...]
  [<INTERFACE|PUBLIC|PRIVATE> [items2...] ...])
  • target_link_libraries
    鏈接時所需要用到的libraries或flag,而target必須是以add_executable或是add_library所生成。
target_link_libraries(<target> ... <item>... ...)
  • set_target_properties
    用來設置target的屬性,例如輸出的檔名等等...,這裡有具體的可修改屬性列表。
set_target_properties(target1 target2 ...
                      PROPERTIES prop1 value1
                      prop2 value2 ...)
  • target_compile_options
    可以設定編譯時的行為、選項。
target_compile_options(<target> [BEFORE]
  <INTERFACE|PUBLIC|PRIVATE> [items1...]
  [<INTERFACE|PUBLIC|PRIVATE> [items2...] ...])
  • target_compile_definitions
    設定編譯時要使用的前置處理器。
target_compile_definitions(<target>
  <INTERFACE|PUBLIC|PRIVATE> [items1...]
  [<INTERFACE|PUBLIC|PRIVATE> [items2...] ...])

常用變數

除了常用的函式語法,CMake還有不少預設的變數可以使用。

  • CMAKE_SOURCE_DIR
    CMake開始建置的進入點。
  • PROJECT_SOURCE_DIR
    最上層的專案,也就是包含project()指令的那層資料夾。
  • CMAKE_CURRENT_SOURCE_DIR
    目前正處於的CMakeLists.txt的位置。
  • Flag
    當與目前的作業系統或是編譯器相符時會回傳true的BOOL值的變數。
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
/images/emoticon/emoticon06.gif


上一篇
「專案建立及管理」 —— 開發環境
下一篇
「專案建立及管理」 —— vcpkg
系列文
《今天也走在開發遊戲引擎的路上》12
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言