このブログ記事では、CMakeにおけるバージョン、オプション、インストール他について紹介します。

前回の記事では、小規模で基本的なプロジェクト用の CMakeLists.txt
ファイルのセットアップ方法を解説しました。
今回は、大規模なプロジェクトをセットアップする際により重要となるバージョン、オプション、インストールについて説明します。
バージョン
大規模なプロジェクトを扱う場合、さまざまなバージョンを配布することがあります。プロジェクトにバージョンを割り当てるには、project
引数を使用して、
例えば project(Project VERSION 1.0)
のように記述します。CMakeLists.txt
に設定したバージョンをソースコードから参照できるようにするため、
CMake によって ProjectConfig.h
という設定ファイルを生成させることができます。
cmake_minimum_required(VERSION 3.15)
project(PROJECT VERSION 1.0)
configure_file(ProjectConfig.h.in ProjectConfig.h)
add_executable(${PROJECT_NAME} main.cc)
target_include_directories(${PROJECT_NAME} PUBLIC ${PROJECT_BINARY_DIR})
configure_file
を使用して、ProjectConfig.h
をビルドディレクトリ内に ProjectConfig.h.in
から生成します。
このファイルを target_include_directories
を用いてインクルードします。ProjectConfig.h.in
では以下のようにバージョン情報を取得できます。
#define PROJECT_VERSION_MAJOR "@Project_VERSION_MAJOR@" // if version is 1.0, major is 1.
#define PROJECT_VERSION_MINOR "@Project_VERSION_MINOR@" // if version is 1.0, minor is 0.
ソースコードでは ProjectConfig.h を参照し、マクロとして定義されたこれらの変数にアクセスできます。
#include <iostream>
#include <ProjectConfig.h>
int main(int argc, char* argv[]) {
std::cout << argv[0] << " Version: " <<
PROJECT_VERSION_MAJOR << "." << PROJECT_VERSION_MINOR << std::endl;
return 0;
};
オプション
大規模なプロジェクトでは、オプションのライブラリを利用することで追加機能を実装する場合があります。
その際、ユーザーにライブラリや追加機能を利用するかどうかを選択させることができます。
例えば、C++ の通常の加算よりも高速に動作する魔法のような add
関数を提供する <Addition.h>
を考えます。
このライブラリを使用するかどうかのオプションを以下のように設定できます。
option(USE_ADDITION "A magical library for optimizing addition." ON)
if (USE_ADDITION)
add_subdirectory(Addition)
list(APPEND OPTIONAL_LIBS Addition)
list(APPEND OPTIONAL_INCLUDE_DIRS ${CMAKE_SOURCE_DIR}/Addition/include)
endif ()
target_link_libraries(${PROJECT_NAME} LibraryA ${OPTIONAL_LIBS})
target_include_directories(${PROJECT_NAME} PRIVATE ${CMAKE_SOURCE_DIR}/LibraryA/include ${OPTIONAL_INCLUDE_DIRS})
option
を利用して変数 USE_ADDITION
をデフォルトで ON
に設定し、USE_ADDITION
が有効であればライブラリを追加するかどうかを判断します。
USE_ADDITION
は、ProjectConfig.h.in
内で #define USE_ADDITION
と定義し、ソースコードで利用できます。
#include <iostream>
#include <ProjectConfig.h>
#ifdef USE_ADDITION
#include <Addition.h>
#endif
int main(int argc, char* argv[]) {
#ifdef USE_ADDITION
std::cout << "Using Addition Library: 1+2=" << add(1, 2) << std::endl;
#elif
std::cout << "Using Normal Addition 1+2=" << 1+2 << std::endl;
#endif
return 0;
};
実行可能ファイルとライブラリの検索
実行可能ファイルやライブラリをコードベース内で設定し、開発者やユーザーにデバイス上でインストールしてもらうのではなく、
すでにインストールされているものを利用する前提で構築できます。特に Git のような多くの人がすでにインストールしている大規模な実行ファイルやライブラリ
(Gitは DevOps シリーズで解説予定)については、プロジェクトディレクトリに含めるのではなく、ユーザーのコンピュータにインストール済みの Git を使用することが望ましいです。
必要な実行可能ファイルがインストールされていることを確認し、パスを取得するために、以下のように find_program
を使用できます。
cmake_minimum_required(VERSION 3.15)
project(PROJECT VERSION 1.0)
find_program(GIT_EXECUTABLE git)
if (GIT_EXECUTABLE)
message(STATUS "Git found at: ${GIT_EXECUTABLE}")
else ()
message(FATAL_ERROR "Git not found")
endif ()
find_program
は、実行可能ファイルが存在するかを確認し、その完全なパスを取得します。message
を使って、
実行可能ファイルが見つかったかどうかを通知できます。ライブラリについては、以下のように find_library
を使用して、
必要な数学ライブラリ libm.so
のパスを確認します。
find_library(MATH_LIBRARY m)
if (MATH_LIBRARY)
message(STATUS "Math library found: ${MATH_LIBRARY}")
else ()
message(FATAL_ERROR "Math library not found")
endif ()
target_link_libraries(${PROJECT_NAME} PRIVATE ${MATH_LIBRARY})
ライブラリには Find<name>.cmake
ファイルが設定されている場合があり、これを使って find_package
を利用することで、
ライブラリのパスと、通常必要となる追加情報を取得できます。例えば、FindGit.cmake
を使用して、
実行可能ファイルのパスやインストールされている Git のバージョンを取得できます。
find_package(Git)
if (GIT_FOUND)
message("Git found: ${GIT_EXECUTABLE}, Version: ${GIT_VERSION_STRING}")
execute_process(COMMAND ${GIT_EXECUTABLE} init)
else ()
message(FATAL_ERROR "Git not found")
endif ()
上記の例では、さらに execute_process
を使用して、find_package
で取得したパスを使って実行可能ファイルを実行しています。
大規模なライブラリを作成する際には、簡単にライブラリにアクセスできるように Find<name>.cmake
ファイルを設定することをお勧めします。
インストール
大規模なプロジェクトをビルドした後、それを配布し、ユーザーや開発者がコンピュータにインストールできるようにする必要があります。
CMake と install
を使用してこれを行うことができますが、CMake の背景知識がない初心者にとっては、CMake を使用してビルドする方法を学ぶ必要があります。
このプロセスを簡素化するために、readme.md
に以下のようなドキュメントを含めることができます。
To install the project, you need to install CMake and Git and run the following commands:
cmake -S . -DUSE_ADDITION=ON -B build
cd build
sudo make install
これらの詳細を隠すために、configure.sh
、build.sh
、install.sh
のようなシェルスクリプトを作成し、
それぞれに上記のコマンドを含めてユーザーに実行させることもできます。ただし、このアプローチでも、
初心者やコマンドラインを使用した経験がないユーザーにとっては依然として複雑かもしれません。
そのため、CPack を使用することで、どの OS でも簡単にインストールできるインターフェースをユーザーに提供できます。
これを利用するには、以下の行を追加するだけです。
include(InstallRequiredSystemLibraries)
set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/License.txt")
set(CPACK_VERSION_MAJOR "${Project_VERSION_MAJOR}")
set(CPACK_VERSION_MINOR "${Project_VERSION_MINOR}")
include(CPack)
CPack を利用するには、License.txt
ファイルをルートディレクトリに設定する必要があります。
ビルドディレクトリに移動し、cpack
を実行してプロジェクトをコンパイルします。
Linux では、Project--Linux.tar.gz
や Project--Linux.tar.Z
ファイルがビルドディレクトリに作成され、
それらと一緒に生成される Project--Linux.sh
を実行することでインストールできます。CPack には GUI を設定するためのものなど、
多くの設定オプションがありますが、ここでは CPack の基本的な使用方法を説明しました。
結論
この記事では、バージョンとオプションの設定方法、およびライブラリの検索方法とインストールの設定について解説しました。 CMake の関数に関するさらなる情報については、お使いのバージョンの公式ドキュメントを参照することをお勧めします。
リソース
- Code, Tech, and Tutorials. 2021. CMake Tutorial EP 4 | Versioning Source Code. YouTube.
- Code, Tech, and Tutorials. 2021. CMake Tutorial EP 5 | Making Libs Optional. YouTube.
- Code, Tech, and Tutorials. 2021. CMake Tutorial EP 6 | Installing Your Software! (part 1/2 of install). YouTube.
- Code, Tech, and Tutorials. 2021. CMake Tutorial EP 7 | Installing With CPack! (part 2/2 of install). YouTube.
- Code, Tech, and Tutorials. 2021. CMake Tutorial EP 8 | find_library(...) (part 1/2 of find lib). YouTube.
- Code, Tech, and Tutorials. 2021. CMake Tutorial EP 9 | find_package modules and config options (2/2 of find libs). YouTube.