CMake とは、autoconf みたいに Makefile を作るツールです。Makefile 以外にも Visual Studio や Xcode の設定ファイルも作れるらしい。
基本的な文法
- CMake への入力
- Directories:
- CMakeLists.txt 親ディレクトリのここを最初に読む。
- add_subdirectory() で子ディレクトリを追加できる。
- Scripts: (script).cmake
- cmake -P で実行する。
- Modules: (module).cmake
- include() で呼び出す。
- Directories:
- コマンドの文法
- コマンド名は大文字小文字を区別しない。(こういうのやめて欲しい。。。)
- add_executable(hello world.c) のように書く。
- 引数は色々な方法で指定出できる。
- Bracket Argument: [===[abcdef]===] の形式。
- Quoted Argument: "abcdef" の形式。
- Unquoted Argument: abcdef の形式
- 変数の文法
- 変数は大文字小文字を区別する。
- 代入:
- 普通の変数: set(変数名 値)
- 環境変数: set(ENV{変数名} 値)
- 利用: Quoted Argument か Unquoted Argument の中で ${変数名} と書く。
- if() の中だけ 変数名 のように書く。
- 環境変数は if() の中でも $ENV{変数名} と書く。
- コメント
- Bracket Comment: #[===[abcdef]===] と書く。カッコ閉じるまで。
- Line Comment: # abcdef と書く。一行のみ。
主なコマンド
- add_executable(name source...)
- 実行ファイル name をソースファイル source ...から作る
- add_library(name [STATIC | SHARED | MODULE] source ...)
- ライブラリターゲット name を source ... から作る
- 二番目の引数でライブラリの種類を選べる
- STATIC: アーカイブファイルができる。
- SHARED: 動的ライブラリができる。
- MODULE: dlopen で動的に読むファイルができる。
- 無指定の場合 BUILD_SHARED_LIB=ON なら SHARED、そうでなければ STATIC
- target_link_libraries(target item ...)
- ターゲット target を item にリンクする。
- target とは add_executable または add_library で作ったターゲット
- item とは
- ライブラリのターゲット名
- ライブラリファイルのフルパス
- ライブラリ名
- リンクフラグ
Package
CMake は find_package(パッケージ名) で Package (ヘッダファイルやライブラリなどの依存)のありかを探す。解決するには二つの方法がある。
- Module mode:
- Find(Package).cmake を実行。
- CMake 以外で作られたパッケージを探すのに使う。
- Config mode:
- (Package)Config.cmake または (package)-config.cmake を実行。
- CMake で作られたパッケージを探すのに使う。
Module mode を先に試して見つからなかったら Config mode を実行する。find_package によりパッケージの位置を示す変数がセットされる。変数の内容は cmake ファイルによってそれぞれだが、典型的には次のような変数名が使われる。
- (PACKAGE)_INCLUDE_DIRS
- (PACKAGE)_VERSION
これらのパッケージを探す位置がちょっとむずかしいがだいたい二通りあるらしい。
-
CMAKE_SYSTEM_PREFIX_PATH
で指定されたパスのリスト: システムにインストールされたパッケージを探す。CMAKE_PREFIX_PATH
を使って追加する事も出来る。 -
CMake Package Registry: Unix では
~/.cmake/packages/<パッケージ名>
に間接的に記述されている。CMakeLists.txt にexport
コマンドがあると、make install
しなくてもmake
だけでここに登録される。インストール不要なので開発時に便利。
詳しくは Finding Packages — Mastering CMake に書いてある。
cmake コマンド利用時よく使う変数
-
CMAKE_INSTALL_PREFIX
:-
cmake -DCMAKE_INSTALL_PREFIX=$HOME/local
のようにすると標準以外の場所にインストールできる。 - ここで指定したディレクトリは同時に find_package の検索パス (
CMAKE_SYSTEM_PREFIX_PATH
) にも追加されるので同じ場所にインストールした他のパッケージを参照できる。
-
-
CMAKE_PREFIX_PATH
:-
cmake -DCMAKE_PREFIX_PATH=$HOME/local
のようにすると標準以外の場所にインストールしたパッケージを find_package で探す事ができる。 - CMAKE_SYSTEM_PREFIX_PATH に直接追加せずこの変数を使うべき。
-
-
CMAKE_VERBOSE_MAKEFILE
:- cmake は make 時に省略してログを出す。
cmake -DCMAKE_VERBOSE_MAKEFILE=1
のようにすると元の詳しいログが出る。 -
VERBOSE=1 make
でも同じ。
- cmake は make 時に省略してログを出す。
-
CMAKE_POSITION_INDEPENDENT_CODE
:- Position Independent Code を生成するフラグ。
-
... can not be used when making a shared object; recompile with -fPIC
というエラーが出たらライブラリにこれを付けてビルドすると-fPIC
を付けてビルドしてくれる。 - 例えば protobuf を自分でビルドする時など CMakeList.txt を編集したくない時は
cmake -DCMAKE_POSITION_INDEPENDENT_CODE=ON .
のようにする。
VSCode の CMake Tools でこれらの CMake 変数を設定するには以下のように settings.json に書く。
{
"cmake.configureSettings": {
"CMAKE_PREFIX_PATH": "/root/local"
}
}
cmake よく使う コマンド
-
add_compile_options
:- 任意のコンパイルオプションを足す。
add_compile_options(-pedantic -Wall)
のようにすると警告レベルを変えられる。互換性が無いので使わないほうが良いらしい。-
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pedantic -Wall -Wextra -Wconversion")
汚いがこちらの方が動いた。
参考
- Mastering CMake — Mastering CMake
- cmake-language(7) — CMake 3.24.2 Documentation
- Using Dependencies Guide — CMake 3.24.2 Documentation
- Finding Packages — Mastering CMake
- CMAKE_INSTALL_PREFIX — CMake 3.24.2 Documentation
- CMAKE_PREFIX_PATH — CMake 3.24.2 Documentation
- Configuring CMake Tools — CMake Tools 1.4.0 documentation