Home CMake教學系列一使用CMake編譯專案
Post
Cancel

CMake教學系列一使用CMake編譯專案

安裝最新版的CMake,越新越好,因為新版的CMake提供更多的工具幫你尋找函式庫或套件,尤其如果你需要用到CUDA,新版的CMake可以省去你許多的麻煩

安裝CMake

Ubuntu可以跟著這篇官方教學安裝最新的CMake

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
sudo apt-get update
sudo apt-get install ca-certificates gpg wget

test -f /usr/share/doc/kitware-archive-keyring/copyright ||
wget -O - https://apt.kitware.com/keys/kitware-archive-latest.asc 2>/dev/null | gpg --dearmor - | sudo tee /usr/share/keyrings/kitware-archive-keyring.gpg >/dev/null

# Ubuntu 20.04
echo 'deb [signed-by=/usr/share/keyrings/kitware-archive-keyring.gpg] https://apt.kitware.com/ubuntu/ focal main' | sudo tee /etc/apt/sources.list.d/kitware.list >/dev/null
sudo apt-get update

test -f /usr/share/doc/kitware-archive-keyring/copyright ||
sudo rm /usr/share/keyrings/kitware-archive-keyring.gpg

sudo apt-get install kitware-archive-keyring

sudo apt-get install cmake

嘗試用CMake編譯程式

讓我們嘗試用CMake編譯一個開源專案

1
2
git clone https://github.com/CLIUtils/CLI11.git # 下載專案
cd CLI11 #進入資料夾

然後我們就可以開始編譯,過程中你會發現CMake幫你建立了一個build資料夾,第一行指令-S表示source directoryB會幫你建立一個build資料夾如果他不存在的話,CMake產生的東西會全部放在build資料夾裡面,你隨時可以刪除他而且他也不需要被版本控制。第二行的-j讓你可以指定要用多少核心來加速編譯。第三行-t代表執行測試程式,如果你沒有測試程式也可以不需要這行指令。

1
2
3
cmake -S . -B build
cmake --build build -j 8
cmake --build build -t test

你很容易在網路上看到CMake傳統的編譯方式,不過在CMake 3.15之後你可以用前面提到的新的方法,他可以幫你處理掉一些小麻煩。

1
2
3
4
5
mkdir build
cd build
cmake ..
make
make test

查看編譯選項

CLI11資料夾中,你可以用cmake -S . -L列出所有你可以設定的選項,有些是CMake內建的選項,有些是這著專案中設定讓你可以選的選項。cmake -S . -LH不但會列出所有選項,還把說明文字也印出來。在許多開源專案用CMake編譯的時候經常會需要知道他提供哪些選項,這個指令會非常有幫助。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
$ cmake -S . -B build -LH
-- CMake 3.22.1
-- Could NOT find Doxygen (missing: DOXYGEN_EXECUTABLE) 
-- Doxygen not found, building docs has been disabled
-- Configuring done
-- Generating done
-- Build files have been written to: /home/steven/CLI11/build
-- Cache values
// Build the testing tree.
BUILD_TESTING:BOOL=OFF

// Path to a file.
Boost_INCLUDE_DIR:PATH=Boost_INCLUDE_DIR-NOTFOUND

// Turn on boost test (currently may fail with Boost 1.70)
CLI11_BOOST:BOOL=ON

// Build CLI11 examples
CLI11_BUILD_EXAMPLES:BOOL=ON

// Build CLI11 json example
CLI11_BUILD_EXAMPLES_JSON:BOOL=OFF

// Build the tests with NVCC to check for warnings there - requires CMake 3.9+
CLI11_CUDA_TESTS:BOOL=OFF

// Install the CLI11 folder to include during install process
CLI11_INSTALL:BOOL=OFF
...以下省略

如果你想要設定選項值,你可以在CMake指令中用-D加上選項名稱來設定,例如

1
cmake -DCLI11_INSTALL=ON -S . -B build

這時候被設定的值會被保存在build資料夾裡面的CMakeCache.txt。你可以打開這份文件並且找到這個選項被設定的值。你可以看到CLI11_INSTALL:BOOL=ON

1
2
3
4
5
6
7
8
9
10
11
...以上省略
//Build the tests with NVCC to check for warnings there - requires
// CMake 3.9+
CLI11_CUDA_TESTS:BOOL=OFF

//Install the CLI11 folder to include during install process
CLI11_INSTALL:BOOL=ON

//Value Computed by CMake
CLI11_IS_TOP_LEVEL:STATIC=ON
...以下省略

如果在設定一次就可以發現他的值被改成OFF

1
cmake -DCLI11_INSTALL=OFF -S . -B build
1
2
3
4
5
6
7
8
9
10
11
...以上省略
//Build the tests with NVCC to check for warnings there - requires
// CMake 3.9+
CLI11_CUDA_TESTS:BOOL=OFF

//Install the CLI11 folder to include during install process
CLI11_INSTALL:BOOL=OFF

//Value Computed by CMake
CLI11_IS_TOP_LEVEL:STATIC=ON
...以下省略

另外還有一些常見的CMake標準選項你可以設定

CMake除錯技巧

這節特別重要,如果要自己撰寫CMakeLists.txt話十分有用。--trace-source選項讓你指定你有興趣的檔案,並且依照他執行的順序依序印出他所執行的行數

1
cmake build --trace-source="CMakeLists.txt"

動手寫第一個CMakeLists.txt

我們將製作一個簡單的C語言程式,並且寫一個CMakeLists.txt

1
2
3
mkdir cmakeQuickStart
cd cmakeQuickStart
code .

cmakeQuickStart資料夾內建立一個CMakeLists.txt和一個simple.cpp

  1. cmake_minimum_required指定使用這份CMakeLists.txt最小所需的CMake版本。
  2. project指定專案名稱,而專案使用的語言預設為C++和C。如果要指定專案語言可以輸入LANGUAGES參數。
  3. 最後你要輸出執行檔或是library。add_executable指令輸出執行檔,add_library指令輸出library,輸出的執行檔或是library檔名在跟第一個參數一樣。在這裡特別注意,add_executableadd_library第一個參數為兩個東西命名,首先他命名了輸出檔案的檔案名稱,其次是他命名了一個CMake的targettarget在後面會很常用到。
1
2
3
4
5
6
7
/* simple.c or simple.cpp */
#include <stdio.h>

int main() {
    printf("Hello, World!\n");
    return 0;
}
1
2
3
4
5
cmake_minimum_required(VERSION 3.15)

project(MyProject)

add_executable(myexample simple.cpp)

你也可以把CMakeLists.txt改成下面這樣,他指定了CMake的版本範圍,並且為專案增加說明和版本號

1
2
3
4
5
6
7
8
9
10
11
12
cmake_minimum_required(VERSION 3.15...3.21)

project(MyProject
  VERSION
    1.0
  DESCRIPTION
    "Very nice project"
  LANGUAGES
    CXX
)

add_executable(myexample simple.cpp)

接下來你就可以編譯你的程式了,編譯後你會看到build資料夾出現一個myexample檔,跟你在add_executable指定的名稱一樣

1
2
cmake -S . -B build
cmake  --build build

More Modern CMake https://hsf-training.github.io/hsf-training-cmake-webpage/

An Introduction to Modern CMake https://cliutils.gitlab.io/modern-cmake/

This post is licensed under CC BY 4.0 by the author.

Python的class method使用情境

三個重要工具結合Python和C++