TopC++ 入門 › 実践 › CMake

CMake 入門 — モダン C++ の標準ビルドシステム

大規模 C++ プロジェクトはほぼ CMake でビルドします。Makefile を書かず CMakeLists.txt を書くと、Linux/Mac/Windows の全環境で同じ設定が使えます。最小例から始めて target_link_libraries まで。

1. 最小の CMakeLists.txt

CMakeLists.txt
cmake_minimum_required(VERSION 3.16)
project(hello LANGUAGES CXX)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

add_executable(hello hello.cpp)

ビルド手順(out-of-source)

$ cmake -S . -B build $ cmake --build build $ ./build/hello

-S でソース、-B でビルドディレクトリ。ビルド成果物を別ディレクトリに隔離できるのが Makefile より強い点です。

2. 複数ファイル構成

src/CMakeLists.txt
add_executable(app
    main.cpp
    util.cpp
    server.cpp)
target_include_directories(app PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include)
target_compile_options(app PRIVATE -Wall -Wextra -Wpedantic)

PRIVATE は「この target だけで使う」の意味。ライブラリで PUBLIC を指定すると依存先にも伝搬します。

3. ライブラリを作る

CMakeLists.txt
add_library(mymath STATIC
    src/math.cpp
    src/vec.cpp)
target_include_directories(mymath PUBLIC
    ${CMAKE_CURRENT_SOURCE_DIR}/include)

add_executable(app src/main.cpp)
target_link_libraries(app PRIVATE mymath)

STATIC は .a、SHARED は .so/.dylib/.dll。INTERFACE はヘッダオンリーライブラリ用。

指定意味
PRIVATEこの target のみで使う
INTERFACEこの target を使う人だけに渡す
PUBLIC両方(PRIVATE + INTERFACE)

4. 外部ライブラリを使う

find_package(システムにインストール済み)

boost を使う
find_package(Boost 1.71 REQUIRED COMPONENTS system filesystem)
target_link_libraries(app PRIVATE Boost::system Boost::filesystem)

FetchContent(その場でダウンロード)

fmtlib をフェッチ
include(FetchContent)
FetchContent_Declare(fmt
    GIT_REPOSITORY https://github.com/fmtlib/fmt.git
    GIT_TAG        10.2.1)
FetchContent_MakeAvailable(fmt)

target_link_libraries(app PRIVATE fmt::fmt)
FetchContent は CMake 3.14 以降。依存ライブラリのインストールを不要にできる現代的な方法。

5. Debug / Release の切替

$ cmake -S . -B build-debug -DCMAKE_BUILD_TYPE=Debug $ cmake -S . -B build-release -DCMAKE_BUILD_TYPE=Release $ cmake --build build-release

CMAKE_BUILD_TYPE は Debug/Release/RelWithDebInfo/MinSizeRel の 4 種。-g-O2 などが自動で適用されます。

6. Sanitizer を有効化

CMakeLists.txt
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
    target_compile_options(app PRIVATE -fsanitize=address,undefined)
    target_link_options(app PRIVATE -fsanitize=address,undefined)
endif()

7. よく使うコマンド早見表

コマンド用途
cmake -S src -B buildconfigure
cmake --build build -j 88 並列ビルド
cmake --build build --target cleanクリーン
cmake --install build --prefix /usr/localインストール
ctest --test-dir buildテスト実行
cmake -G Ninja ...Ninja ジェネレータ(高速)