Open4

CMake入門

yoshiyasu1111yoshiyasu1111

CMakeLists.txt

CMakeプロジェクトはCMakeLists.txtにより動作が設定されます。ソースツリーのルートに少なくとも1つ用意する必要があります。必須の設定項目はcmake_minimum_requiredprojectの2つです。

cmake_minimum_required()

CMakeの最小バージョンを指定します。システムが正しいCMakeのバージョンを持っているかどうかをチェックします

project()

言語とメタデータの設定をします。<PROJECT_NAME>は必須項目で、その他は任意です。2つの形式のうちどちらかを使用します。

project(<PROJECT_NAME> [<language-name>])
project(<PROJECT_NAME>
    [VERSION <major>[.<minor>[.<patch>[.<tweak>]]]]
    [DESCRIPTION <project-description-string>]
    [HOMEPAGE_URL <url-string>]
    [LANGUAGES <language-name>]
)

VERSIONを設定すると以下の変数が利用できるようになります。

  • PROJECT_VERSION
  • PROJECT_VERSION_MAJOR
  • PROJECT_VERSION_MINOR
  • PROJECT_VERSION_PATCH
  • PROJECT_VERSION_TWEAK

message()

指定されたメッセージの文字列をログに記録します。

変数

変数はパッケージの設定や、ソースファイルに渡して最終的な実行ファイルで利用することができます。

変数の利用

${<変数>}のように変数は’${'と'}'で囲えば利用することができます。

たとえば以下のようなCMakeLists.txtを用意してcmake -S . -B buildコマンドを実行すると変数の値を表示することができます。

CMakeLists.txt
cmake_minimum_required(VERSION 3.25)
project(hello
    VERSION 0.1.0.0
    DESCRIPTION "sample hello project"
    HOMEPAGE_URL "https://github.com/yoshiyasu1111/cmake-from-source_template"
    LANGUAGES CXX
)
message("プロジェクトの名前: ${PROJECT_NAME}")
message("プロジェクトの名前: ${CMAKE_PROJECT_NAME}")
message("プロジェクトのソースディレクトリ: ${PROJECT_SOURCE_DIR}")
message("プロジェクトのビルドディレクトリ: ${PROJECT_BINARY_DIR}")
message("プロジェクトのバージョン: ${PROJECT_VERSION}")
message("プロジェクトのバージョン: ${CMAKE_PROJECT_VERSION}")
message("プロジェクトのメジャーバージョン: ${PROJECT_VERSION_MAJOR}")
message("プロジェクトのマイナーバージョン: ${PROJECT_VERSION_MINOR}")
message("プロジェクトのパッチーバージョン: ${PROJECT_VERSION_PATCH}")
message("プロジェクトのツイークバージョン: ${PROJECT_VERSION_TWEAK}")
message("プロジェクトの説明: ${PROJECT_DESCRIPTION}")
$ cmake -S . -B build
-- The CXX compiler identification is GNU 11.3.0
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /usr/bin/c++ - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
プロジェクトの名前: hello
プロジェクトの名前: hello
プロジェクトのソースディレクトリ: /work/work
プロジェクトのビルドディレクトリ: /work/work/build
プロジェクトのバージョン: 0.1.0.0
プロジェクトのバージョン: 0.1.0.0
プロジェクトのメジャーバージョン: 0
プロジェクトのマイナーバージョン: 1
プロジェクトのパッチーバージョン: 0
プロジェクトのツイークバージョン: 0
プロジェクトの説明: sample hello project
-- Configuring done
-- Generating done
-- Build files have been written to: /work/work/build
yoshiyasu1111yoshiyasu1111

file()

ファイルシステムへのアクセスを必要とするファイル操作やパス操作を実行します。

ファイル名: <filename>に内容:<content>を書き込みます。

file({WRITE | APPEND} <filename> <content>)

ファイル名:<filename>内容を文字列として変数:<variable>に読み込みます。

file(STRINGS <filename> <variable>)
CMakeLists.txt
cmake_minimum_required(VERSION 3.25)
project(hello
    VERSION 0.1.0.0
    DESCRIPTION "sample hello project"
    HOMEPAGE_URL "https://github.com/yoshiyasu1111/cmake-from-source_template"
    LANGUAGES CXX
)
file(WRITE hello.txt "I write a contents.")
file(STRINGS hello.txt STRING_READ_FILE)
message("${STRING_READ_FILE}")
$ cmake -S . -B build
I write a contents.
$ cat hello.txt 
I write a contents.
yoshiyasu1111yoshiyasu1111

add_executable()

指定されたソースファイルを使用して、プロジェクトに実行ファイルを追加します。

add_executable(<name>
    [EXCLUDE_FROM_ALL]
    [source1] [source2 ...]
)

[source]で指定したソースファイルからビルドする実行形式ターゲット <name> を追加します。<name>はプロジェクト内で一意でなければならない。

EXCLUE_FROM_ALLにtrue値を設定すると、そのターゲットが含まれるディレクトリと、祖先のすべてのターゲットから除外されます。

実行例

次のようなCMakeLists.txtとhello.cppを用意します。

$ tree
.
├── CMakeLists.txt
└── hello.cpp
CMakeLists.txt
cmake_minimum_required(VERSION 3.25)
project(greeting
    VERSION 0.1.0.0
    DESCRIPTION "sample hello project"
    HOMEPAGE_URL "https://github.com/yoshiyasu1111/cmake-from-source_template"
    LANGUAGES CXX
)
add_executable(hello
    hello.cpp
)
hello.cpp
#include <iostream>

int main(void)
{
    std::cout << "Hello World!" << std::endl;

    return 0;
}

プロジェクトのビルドシステムの生成とビルドを実行します。

$ cmake -S . -B build
$ cmake --build build

./buildディレクトリにhelloが生成されています。

$ ./build/hello 
Hello World!
yoshiyasu1111yoshiyasu1111

add_library()

指定されたソースファイルを使用して、プロジェクトにライブラリを追加します。

静的ライブラリ

add_library(<name> STATIC [source ...])

静的ライブラリ<name>をソースコード[source ...]から生成します。

実行例〜静的ライブラリ〜

次のようなCMakeLists.txtとhello.cppを用意します。

$ tree
.
├── CMakeLists.txt
└── hello.cpp
CMakeLists.txt
cmake_minimum_required(VERSION 3.25)
project(greeting
    VERSION 0.1.0.0
    DESCRIPTION "sample hello project"
    HOMEPAGE_URL "https://github.com/yoshiyasu1111/cmake-from-source_template"
    LANGUAGES CXX
)
add_library(hello
    STATIC
        hello.cpp
)
hello.cpp
#include <iostream>

int main(void)
{
    std::cout << "Hello World!" << std::endl;

    return 0;
}

プロジェクトのビルドシステムの生成とビルドを実行します。

$ cmake -S . -B build
-- The CXX compiler identification is GNU 11.3.0
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /usr/bin/c++ - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done
-- Generating done
-- Build files have been written to: /work/build
$ cmake --build build
[ 50%] Building CXX object CMakeFiles/hello.dir/hello.cpp.o
[100%] Linking CXX static library libhello.a
[100%] Built target hello

./buildディレクトリにライブラリlibhello.aが生成されています。

$ ls -lh ./build/libhello.a 
-rw-r--r-- 1 gccuser gccuser 2.9K Dec  8 08:30 ./build/libhello.a

共有ライブラリ

add_library(<name> SHARED [source ...])

共有ライブラリ<name>をソースコード[source ...]から生成します。

実行例〜共有ライブラリ〜

次のようなCMakeLists.txtとhello.cppを用意します。

$ tree
.
├── CMakeLists.txt
└── hello.cpp
CMakeLists.txt
cmake_minimum_required(VERSION 3.25)
project(greeting
    VERSION 0.1.0.0
    DESCRIPTION "sample hello project"
    HOMEPAGE_URL "https://github.com/yoshiyasu1111/cmake-from-source_template"
    LANGUAGES CXX
)
add_library(hello
    SHARED
        hello.cpp
)
hello.cpp
#include <iostream>

int main(void)
{
    std::cout << "Hello World!" << std::endl;

    return 0;
}

プロジェクトのビルドシステムの生成とビルドを実行します。

$ cmake -S . -B build
-- The CXX compiler identification is GNU 11.3.0
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /usr/bin/c++ - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done
-- Generating done
-- Build files have been written to: /work/build
$ cmake --build build
[ 50%] Building CXX object CMakeFiles/hello.dir/hello.cpp.o
[100%] Linking CXX shared library libhello.so
[100%] Built target hello

./buildディレクトリにライブラリlibhello.soが生成されています。

$ ls -lh ./build/libhello.so 
-rwxr-xr-x 1 gccuser gccuser 16K Dec  8 08:54 ./build/libhello.so