CMakeのチュートリアルをやる(Step1)
CMake Tutorial
CMakeをC++プロジェクトなどで使うことは多いのですが、付け焼刃の知識しかなくて正しい書き方がいまだにわからない... なので初心に戻って、CMakeの公式が作ったチュートリアルをやっていこうと思います。
この記事はその時のメモみたいなものです。
参考はこちら。 チュートリアルの元となるプロジェクトファイルたちもここからダウンロードできます。
CMake Tutorial — CMake 3.25.0-rc3 Documentation
Step1: 標準的なプロジェクトの作成
次の要素が含まれている。
- 自作のヘッダーファイルをインクルードするための設定
- 実行ファイルの作り方
- バージョン情報を付加したヘッダーファイルの自動生成
ファイルとしては、上のURLからダウンロードしたCMAKE-x.xx.x-RC3-TUTORIAL_SOURCEのStep1を参照しています。
目的
tutorial.cxxをCMakeLists.txtを使ってコンパイルする。
最小構成:実行ファイルを作る
CMakeLists.txtの最小構成だろうと思われるものを作って、そこから付け加えていく流れでまとめます。
tutorial.cxxをコンパイルしてTutorialという名前の実行ファイルを作るCMakeLists.txtは次の通り:
cmake_minimum_required(VERSION 3.10) project(Tutorial VERSION 1.0) add_executable(Tutorial tutorial.cxx)
cmake_minimum_required
cmake_minimum_required(VERSION 3.10)
のように必要とされる最小のcmakeバージョンを指定できます。
私のcmakeはバージョン3.16.3だったので、cmake_minimum_required(VERSION 3.17)
としてみたら、ちゃんと次のエラーが出た。
CMake Error at CMakeLists.txt:2 (cmake_minimum_required): CMake 3.17 or higher is required. You are running version 3.16.3
project
project(Tutorial VERSION 1.0)
のようにプロジェクト名と、バージョン情報を付加できます。
CMakeが自動生成する変数の名前が プロジェクトでつけた名前_...
のようになる。また${PROJECT_NAME}
でプロジェクト名を参照できます。
バージョン情報はあってもなくてもいいみたいですが、つけておくとTutorial_VERSION_MAJOR
とTutorial_VERSION_MINOR
という変数が自動生成されて、にそれぞれ1と0が入るみたい。
add_executable
add_executable(Tutorial tutorial.cxx)
コンパイルの対象となるソースファイル(tutorial.cxx
)を指定して実行ファイル(Tutorial
)を作ります。
ターゲット(生成される実行ファイル名)はプロジェクト名と同じじゃなくてもいい。
機能追加1:C++バージョンの指定
CMake
cmake_minimum_required(VERSION 3.10) project(Tutorial VERSION 1.0) set(CMAKE_CXX_STANDARD 11) set(CMAKE_CXX_STANDARD_REQUIRED True) add_executable(Tutorial tutorial.cxx)
CMAKE_CXX_STANDARD CMAKE_CXX_STANDARD_REQUIRED
set(XXX YYY)
というコマンドを使うことで、YYY
という値を持つXXX
という変数を定義することができます。
そして、set(CMAKE_CXX_STANDARD 11)
のようにすることで、ビルドに使うC++バージョンを設定できます。
また、set(CMAKE_CXX_STANDARD_REQUIRED True)
としておくとC++11が使えない環境でのビルドにエラーを出すことができるようです。
※ 実行ファイルを作るadd_executableより前に指定する必要がある
チュートリアルでは、C++11にしかない機能がコンパイルできるようになることを確認しています。
補足:target_compile_features
上の変数を直接いじる方法以外に、最近のCMakeではtarget_compile_features(Tutorial PUBLIC cxx_std_11)
とC++バージョンを指定するやり方が主流のようです。
この機能によって、プロジェクトごとではなくターゲットごと(実行ファイルとかライブラリごと)にC++のバージョンを設定できるので使いやすい。
(もしかしてこのチュートリアル古い...???)
このPUBLICについては一旦考えずに次に進めましょう。
機能追加2: プロジェクトのバージョン情報をヘッダファイルからソースファイルへ教示
CMakeLists.txtで定義した変数の情報をソースファイルへ流す機能として、ソースファイルがインクルードするヘッダファイルへバージョン情報を自動で書き込む機能を追加します。
cmake_minimum_required(VERSION 3.10) project(Tutorial VERSION 1.0) set(CMAKE_CXX_STANDARD 11) set(CMAKE_CXX_STANDARD_REQUIRED True) configure_file(TutorialConfig.h.in TutorialConfig.h) add_executable(Tutorial tutorial.cxx) target_include_directories(Tutorial PUBLIC "${PROJECT_BINARY_DIR}")
configure_file
configure_file(TutorialConfig.h.in TutorialConfig.h)
TutorialConfig.h.inは事前に用意する次のようなファイル。
#define Tutorial_VERSION_MAJOR @Tutorial_VERSION_MAJOR@ #define Tutorial_VERSION_MINOR @Tutorial_VERSION_MINOR@
ここで、@Tutorial_VERSION_MAJOR@
など見慣れない書き方がされているが、ここはCMakeによって後で書き直される部分を明示しています。
configure_file
はこのようなヘッダファイルのひな型に対して、現在までに定義された変数を使ってC++のためのヘッダファイルを生成します。
この例では、Tutorial_VERSION_MAJOR
とTutorial_VERSION_MAJOR
がproject(Tutorial VERSION 1.0)
コマンドによって1と0になっているので、
次のようなヘッダファイルが生成されると考えることができます。
#define Tutorial_VERSION_MAJOR 1 #define Tutorial_VERSION_MINOR 0
実際、ビルドを走らせるとビルドフォルダ内に、この内容のTutorialConfig.hというファイルが生成されます。
target_include_directories
target_include_directories(Tutorial PUBLIC "${PROJECT_BINARY_DIR}")
一旦、PUBLIC
という単語は忘れる(後できっと説明される)。
このコマンドによって、add_executable
を実行したときに、ソースファイルがヘッダファイルをインクルードするときに探索するディレクトリを指定することができます。
${PROJECT_BINARY_DIR}
変数はCMakeが自動生成してくれるもので、ビルドファイルを指し示します。
今回、ヘッダファイルはソースファイルと同じディレクトリではなく、ビルドフォルダ内に自動生成されるので、このような探索するディレクトリを明示する必要があります。
そして、このヘッダファイルをソースファイルからインクルードすれば、バージョン情報をmain関数から参照してprintすることができますね。
#include "TutorialConfig.h" ... std::cout << "Version: " << Tutorial_VERSION_MAJOR << "." << Tutorial_VERSION_MINOR << std::endl; ...