Then Notes 隨筆

CMake – 跨平台的自動化建置系統

Introduction

CMake 是一個用於管理程式碼建置(Build)的工具。最初,CMake 的設計是用來產生不同的 Makefile,但發展至今 CMake 已經可以產生現代化的建置設定檔,例如 Visual Studio 與 Xcode 的專案檔。

CMake 廣泛用於 C/C++ 為主的專案,但它當然也可以適用於其他程式語言!一個最基本的設定檔如下,取自 Modern CMake

# Almost all CMake files should start with this
# You should always specify a range with the newest
# and oldest tested versions of CMake. This will ensure
# you pick up the best policies.
cmake_minimum_required(VERSION 3.1...3.24)

# This is your project statement. You should always list languages;
# Listing the version is nice here since it sets lots of useful variables
project(
  ModernCMakeExample
  VERSION 1.0
  LANGUAGES CXX)

# If you set any CMAKE_ variables, that can go here.
# (But usually don't do this, except maybe for C++ standard)

# Find packages go here.

# You should usually split this into folders, but this is a simple example

# This is a "default" library, and will match the *** variable setting.
# Other common choices are STATIC, SHARED, and MODULE
# Including header files here helps IDEs but is not required.
# Output libname matches target name, with the usual extensions on your system
add_library(MyLibExample simple_lib.cpp simple_lib.hpp)

# Link each target with other targets or add options, etc.

# Adding something we can run - Output name matches target name
add_executable(MyExample simple_example.cpp)

# Make sure you link your targets with this command. It can also link libraries and
# even flags, so linking a target that does not exist will not give a configure-time error.
target_link_libraries(MyExample PRIVATE MyLibExample)

CMake with C++ 17/20/23

我們先寫一個必須使用 C++ 17 標準才能編譯的程式碼來測試,例如筆者使用 C++ 17 所支援的折疊運算式(fold expression)撰寫加法函式,main.cc 如下:

#include <iostream>
using namespace std;

template <typename... Args>
auto sum(Args... args)
{
    return (args + ...);
}

int main()
{
    cout << sum(1, 2, 3, 4, 5) << endl;
    return 0;
}

建立 CMakeLists.txt 在同一個目錄,這邊利用 target_compile_features 選項啟用 cxx_std_17(C++ 17)的支援。如果您看一些比較舊版的教學,可能會使用 set 來指定 CMAKE_CXX_STANDARDCMAKE_CXX_STANDARD_REQUIRED,但既然有新方法就用新方法吧!

CMakeLists.txt

cmake_minimum_required(VERSION 3.1...3.24)

project(
    CPP17
    VERSION 1.0
    LANGUAGES CXX
)

add_executable(CPP17 main.cc)

target_compile_features(CPP17 PUBLIC cxx_std_17)

除了 C++ 17 外,當然還有其他的標準可供選擇:

然後在同目錄中建立一個 build 資料夾,所以整體目錄結構長這樣:

.
├── build/
├── CMakeLists.txt
└── main.cc

執行以下命令

$ cd build
$ cmake ..
$ cmake --build .

即可完成編譯建置程式專案。

Reference