この記事は
CMakeというビルドマネジメントツールの入門的解説です。
CMakeとは
- 公式サイト: https://cmake.org/
- 主にC言語、C++などC系言語のビルドに利用される
- CMake以前、C系言語のビルドには多数のビルドシステム(MakefileやNinjaやIDEなど)が乱立していた。これを隠蔽し包括的に扱える様にしたのがCMake
- cmakeにはコマンド版とGUI版がある
- ここではコマンド版のみ扱います。
CMakeの基本的な使い方
- ビルド対象のソースコード(
*.c
や*.cpp
など)を書く -
CMakeLists.txt
を書く -
cmake
コマンドを利用してプロジェクトファイル(※)をGenerateする -
cmake
コマンドまたは各ビルドシステムを利用して、プロジェクトファイルからビルドする
※プロジェクトファイルとは上記ビルドシステムがビルドする際の設定&指示ファイル
ビルドシステムによって異なり、Makefile
や*.sln
や*.xcodeproj
、*.ninja
などがある。
cmake以前はこのプロジェクトファイル自体を直接記述してビルドしていたが、cmakeによりこのプロジェクトファイル生成が自動化されるようになった。
割愛(1. ビルド対象のソースコード(*.c
や*.cpp
など)を書く)
ソースコード自体はこの記事のスコープ外なので割愛します。
2. CMakeLists.txtを書く
例えば、
プロジェクトルート/
|- sample.cpp
|- CMakeLists.txt
の様にファイルを用意し
cmake_minimum_required(VERSION 3.2 FATAL_ERROR)
# set the project name and version
project(MyProject VERSION 1.0)
add_executable(sample.exe sample.cpp)
のようにCMakeLists.txtを記述します。
CMakeLists.txt
には実行ファイルやライブラリファイルを生成する際に必要なソースファイルや手順(依存関係など)を記述しています。
なお、書き方は多岐に渡るため、詳細はこの記事では説明しません。
3. cmake
コマンドを利用してプロジェクトファイルをGenerateする
cmake [<options>] <path-to-source>
cmake [<options>] <path-to-existing-build>
cmake [<options>] -S <path-to-source> -B <path-to-build>
この様にcmakeコマンドを実行することでプロジェクトファイルを生成します。
の中にはジェネレータを指定する-G
などもあります。
cmake -S . -B build/ -G"Unix Makefiles"
すると、 build
ディレクトリにプロジェクトファイルであるMakefileやCMake関連のファイルが生成されます。
4. cmake
コマンドまたは各ビルドシステムを利用して、プロジェクトファイルからビルドする
cmake --build <dir> [<options>] [-- <build-tool-options>]
cmake --build <dir> --target <tgt>... [<options>] [-- <build-tool-options>]
のようなコマンドでビルドします。
cmakeコマンドで実行することも、ジェネレータで指定したビルドシステムのコマンド(makeなど)で実行することもできます。
-
<dir>
は3
で指定した<path-to-build>
を指定する。-
<path-to-build>
を指定していない場合はカレントディレクトリになっているはず。
-
- targetについて
- 明示的に指定すると指定したターゲットのみビルドされる
- 指定しなかった場合は
all
ターゲットが指定される
cmake --build build/ --target sample.exe
とするとsample.exeが生成されます。
ここで指定しているのは
ターゲット名
であり、出力したいファイル名ではありませんので、やっぱりsample1.exe
という名前のファイルで出力したいからと言って--target sample1.exe
としてもエラーになります。
CMakeの主な概念
プロジェクト
一纏まりのソースコードにつける名前。
通常一つ設定される。(使い方によっては複数のプロジェクトを含んだようなものもある。)
上述のビルドシステム用プロジェクトファイルのプロジェクトとは若干異なるもの。
CMakeLists.txtの中でproject
関数を読んでプロジェクト名やバージョンなどを設定する。
ターゲット(target)
ビルドと言っても、一つのプロジェクトで複数の実行ファイルやライブラリファイルを作成したり、テスト実行したり、様々なタスクがある。
この一つ一つのタスクを指定したものがターゲット。
ターゲットには大きく以下の3種類がありCMakeLists.txt内に記述される。
- 実行ファイルの生成(add_executable)
- ライブラリファイルの生成(add_library)
- カスタムターゲットの実行(add_custom_target)
その他:
- ターゲット間に依存性を定義出来る
- デフォルトで
all
というターゲットがある。add_executableなどでEXCLUDE_FROM_ALL
を明示的に指定していない場合はallターゲットに組み込まれる。 - 参照:cmake-buildsystem
- 参照:Qiita| CMake: カスタムターゲットによるグループ化
ジェネレータ(Generator)
各ビルドシステム(※)毎のプロジェクトファイルを生成するモジュールでCMakeでのプロジェクトファイル生成時には内部的に利用される。
※Makefile(Borland Makefiles, Unix Makefilesなど)やNinja、VisualStudioやXcodeなどIDEなどがある。
明示的にどのジェネレータを利用するかも指定可能。
プロパティと変数
- 変数はset関数を参照
- プロパティはset_property関数を参照
*.cmakeファイル
(概念とはちょっと違うけど書いておきます。)
cmakeを利用しているプロジェクトではCMakeLists.txtだけでなく、*.cmake
といったファイルを作成しているものがあります。
出来ること/使える関数はCMakeLists.txtも*.cmake
も大差ありませんが、
CMakeList.txtファイルはCMakeList.txtファイルが配置されたディレクトリ毎の設定やターゲットや依存関係を書くのに対し、
*.cmake
ファイルはディレクトリに依存しないので、CMakeList.txtで利用する関数やパラメータを定義やディレクトリに依存しないようなカスタムターゲットを作成するにに利用されます。
CMakeList.txtファイルからinclude
やfind_package
といった関数を通して読み込まれます。
Makefileからcmake実行
(これも概念ではないですが書いておきます)
プロジェクトファイルを生成するためのCMakeですが、CMakeコマンド実行にもオプションがあり、そのコマンドを生成するためにMakefile/makeを利用しているオープンソースプロジェクトなどがあります。
生成対象のビルドシステムもMakefileだったりすると
(cmake実行用の)Makefileを用意する
↓
(makeコマンドから)cmake実行する
↓
(ビルド用の)Makefileが作成される
のようなMakefileを作るためにMakefileを用意する、といったややこしい構図になるため、初見だと混乱します。(というか私が混乱した)
主な関数と使い方(アルファベット順)
(自分の関心のあるものについて書いています。時々追加していくかもです。)
add_custom_target
他のターゲット作成関数のadd_library
やadd_executable
で作成されるターゲットでは実行ファイルやライブラリファイルを生成するが、この関数はそういったファイル生成を目的としないターゲットを作成する。
ターゲット間の依存関係を設定するのにも利用される
add_dependencies
https://cmake.org/cmake/help/latest/command/add_dependencies.html
ターゲット間の依存性を設定する関数。
ターゲット実行時に依存性が設定されている場合、その依存先のターゲットが先立って実行されるようになる。
add_executable
https://cmake.org/cmake/help/latest/command/add_executable.html
実行ファイル生成ターゲットを作成します。
- add_executableの使い方には以下の3種類があります。
- Normal Executables
- Imported Executables
- Alias Executables
Normal Executables
add_executable(<name> [WIN32] [MACOSX_BUNDLE]
[EXCLUDE_FROM_ALL]
[source1] [source2 ...])
一般的な実行ファイル(*.exe
など)作成用のターゲットを作成します。
Imported Executables
add_executable(<name> IMPORTED [GLOBAL])
外部で生成された実行ファイル読み込むターゲット。
他のターゲットやその内部処理で該当の実行ファイルを利用する際に利用される。
Alias Executables
add_executable(<name> ALIAS <target>)
ターゲットに別名を付ける。
add_library
https://cmake.org/cmake/help/latest/command/add_library.html
ライブラリ生成ターゲットを作成します。
- add_libraryの使い方には以下の5種類があります。
- Normal Libraries
- Object Libraries
- Interface Libraries
- Imported Libraries
- Alias Libraries
Normal Libraries
add_library(<name> [STATIC | SHARED | MODULE]
[EXCLUDE_FROM_ALL]
[<source>...])
一般的なライブラリファイル(*.lib
や*.a
など)作成用のターゲットを作成します。
STATIC,SHARED,MODULEについてはライブラリのリンク方法をきっちり区別しようが分かりやすいと思います。
STATIC
静的ライブラリ(ビルド時にリンクされるライブラリ)を作成する
SHARED
実行ファイルを実行するときに読み込まれる動的ライブラリを作成する
MODULE
プログラムが任意にライブラリをロードした時に読み込まれる動的ライブラリを作成する
Object Libraries
add_library(<name> OBJECT [<source>...])
オブジェクトライブラリを生成する。
オブジェクトライブラリは、ソースコードのコンパイルするが、ライブラリ間をリンクしたり、一纏めのファイルにしたりはしない。
例えば、
sample_lib1.cpp
sample_lib2.cpp
からライブラリ作成する際、Normal Librariesでは一つの*.so
/*.a
/*.dylib
が生成されるが、オブジェクトライブラリとして作成すると、sample_lib1.cpp
のライブラリファイルとsample_lib2.cpp
のライブラリファイルの2つが生成される。
使い方としては、ここで指定したターゲットを最終生成物とするのではなく、他のターゲットが依存する先のターゲットとして利用する。
Interface Libraries
add_library(<name> INTERFACE)
ソースコードもコンパイルせず、実体としてのファイル生成もしないライブラリ生成用ターゲット
ここで設定したInterface Libraries
は
target_link_libraries(<target> INTERFACE <item>...)
やtarget_sources(<target> INTERFACE <item>...)
などで他のターゲットと紐付けられた後、target_link_libraries()で目的のターゲットに紐付けられます。(ライブラリの橋渡しを行うようなイメージです。)
例:
add_library(my_interface_lib INTERFACE)
でInterface Libraries
を作成し
target_link_libraries(my_interface_lib INTERFACE some_lib)
で、Interface Libraries
のmy_interface_libと(Interface Librariesではない)some_libとを紐付けた後、
target_link_libraries(main_target PRIVATE my_interface_lib)
のようにしてmain_targetとmy_interface_libを紐付けることで、
main_target
とsome_lib
とを紐付けます。
Imported Libraries
add_library(<name> <type> IMPORTED [GLOBAL])
プロジェクト外で用意されたライブラリを読み込みます。
<type>
はそのライブラリがどのタイプかを指定する。
STATIC, SHARED, MODULE, UNKNOWN, OBJECT, INTERFACEがある
- STATIC, SHARED, MODULEについては上述の通り。
- UNKNOWNはfind_package()で見つけたモジュールに対して利用する。(たぶん)
- OBJECTは
IMPORTED_OBJECTS
というプロパティで指定したオブジェクトファイルの場所を元にオブジェクトライブラリターゲットを生成する - INTERFACEは
INTERFACE_INCLUDE_DIRECTORIES
やINTERFACE_COMPILE_DEFINITIONS
などのINTERFACE_*
プロパティを元にInterface Libraryを生成する(たぶん)
Alias Libraries
add_library(<name> ALIAS <target>)
add_subdirectory
https://cmake.org/cmake/help/latest/command/add_subdirectory.html
ソースコードを置いているサブディレクトリ追加する
例えば
プロジェクトルート/
|- src/
|- main.cpp
|- CMakeLists.txt ・・・[1]
|- modules/
|- CMakeLists.txt ・・・[2]
|- module1.cpp
|- module2.cpp
のような構成のプロジェクトの場合CMakeLists.txt ・・・[1]
からは同じディレクトリにあるmain.cppしか読読み込めない。
modulesディレクトリにあるソースコードを読み込むためにCMakeLists.txt ・・・[1]
に
add_subdirectory(modules)
の様に指定する。
cmake_parse_arguments
https://cmake.org/cmake/help/latest/command/cmake_parse_arguments.html
関数やマクロ定義の中で利用される。
例えば
function(my_install)
set(options OPTIONAL FAST)
set(oneValueArgs DESTINATION RENAME)
set(multiValueArgs TARGETS CONFIGURATIONS)
cmake_parse_arguments(MY_INSTALL "${options}" "${oneValueArgs}"
"${multiValueArgs}" ${ARGN} )
:
endfunction()
の様に内部でcmake_parse_arguments
を利用したmy_install
関数を定義し、
my_install(TARGETS foo bar DESTINATION bin OPTIONAL blub CONFIGURATIONS)
の様に呼び出すと、以下の様に変数が設定される
MY_INSTALL_OPTIONAL = TRUE
MY_INSTALL_FAST = FALSE # optionsのFASTは呼び出し時に指定しなかったのでFALSEになる。
MY_INSTALL_DESTINATION = "bin"
MY_INSTALL_RENAME <UNDEFINED> # one_value_keywordsのRENAMEは呼び出し時に指定しなかったのでない。
MY_INSTALL_TARGETS = "foo;bar" # multi_value_keywordsのTARGETSにはlistとして複数の値が指定される。
MY_INSTALL_CONFIGURATIONS <UNDEFINED> # multi_value_keywordsのCONFIGURATIONSは呼び出し時に指定しなかったのでない。
MY_INSTALL_UNPARSED_ARGUMENTS = "blub" # optionsの"OPTIONAL"の後に指定された変数はOPTIONALに紐付けられたりしない。
MY_INSTALL_KEYWORDS_MISSING_VALUES = "CONFIGURATIONS" # "CONFIGURATIONS"に対して値指定はなかった
少々複雑、以下を参照するとよいかも:
cmakeでオプション付きの関数を定義する
configure_file
configure_file(<input> <output>
[COPYONLY] [ESCAPE_QUOTES] [@ONLY]
[NO_SOURCE_PERMISSIONS]
[NEWLINE_STYLE [UNIX|DOS|WIN32|LF|CRLF] ])
ファイルをコピーしつつ、コピー元のファイルで@VAR@
や${VAR}
で書かれた部分を該当の変数値で置き換える
file
多数のモードが有るが幾つかかいつまんで。
MAKE_DIRECTORY
file(MAKE_DIRECTORY [<directories>...])
ディレクトリを作成する
GLOB, GLOB_RECURSE
file(GLOB <variable>
[LIST_DIRECTORIES true|false] [RELATIVE <path>] [CONFIGURE_DEPENDS]
[<globbing-expressions>...])
file(GLOB_RECURSE <variable> [FOLLOW_SYMLINKS]
[LIST_DIRECTORIES true|false] [RELATIVE <path>] [CONFIGURE_DEPENDS]
[<globbing-expressions>...])
<globbing-expressions>
(正規表現に似たもの)に一致するファイルのリストを<variable>
に代入する
GLOB_RECURSE
だとサブディレクトリ以下もチェックする。その際FOLLOW_SYMLINKS
が指定されているとシンボリックリンクの先もチェックされる
RELATIVE
が指定されていると指定されているパスからの相対パスとして処理される。
通常GLOBではディレクトリも含むが、LIST_DIRECTORIES
がfalseになっているとディレクトリは省略される
なお、ソースコードを読み込むのにこのGLOBを利用するのは推奨されない。
GLOBだとファイルが追加・削除されたときに追従できないので。
(キャッシュを削除して処理すれば、、だが毎度時間がかかる)
READ
file(READ <filename> <variable>
[OFFSET <offset>] [LIMIT <max-in>] [HEX])
<filename>
から読み取って<variable>
の変数に代入する
なお、読み込んだファイルの変数をどう使うかというと、string関数などで意図する文字列があるかをチェックして別の変数に代入したりする。
RELATIVE_PATH
file(RELATIVE_PATH <variable> <directory> <file>)
<directory>
から<file>
への相対パスを計算して<variable>
に代入する
STRINGS
file(STRINGS <filename> <variable> [<options>...])
<filename>
から読み取って一行毎を<variable>
の変数にlistとして代入する
TO_CMAKE_PATH
file(TO_CMAKE_PATH "<path>" <variable>)
<path>
に指定されたパス表記をCMake表記のパスに変換して<variable>
に代入する
WRITE
file(WRITE <filename> <content>...)
<filename>
に<content>
の内容を書き込む
find_package
find_package(<PackageName> [version] [EXACT] [QUIET] [MODULE]
[REQUIRED] [[COMPONENTS] [components...]]
[OPTIONAL_COMPONENTS components...]
[NO_POLICY_SCOPE])
外部プロジェクトを探してその設定を読み込む。
主にcmakeインストール時に組み込まれて以下のコマンドで出てくるFind***
というモジュールの読み込みに使う
cmake --help-module-list
-
<PackageName>
:読み込む対象のパッケージ -
[version]
:必要とするパッケージバージョン -
[EXACT]
:上記バージョンと完全一致する必要があるか。(上記バージョンの記述でも指定出来るの) -
[QUIET]
:メッセージを出力するか否か -
[MODULE]
:後述のModule
モードかConfig
モードかの指定 -
[REQUIRED]
:REQUIRED指定して対象パッケージが存在しなかった場合はCMakeの処理を止める -
[COMPONENTS]
:対象パッケージが必要とするコンポーネント -
[OPTIONAL_COMPONENTS]
:対象パッケージが(必須ではなく)利用するコンポーネント -
[NO_POLICY_SCOPE]
:割愛
Module
モードとConfig
モード
Module
モードでは
Find<PackageName>.cmake
というファイルを探し、見つかれば実行され、見つからなければConfig
モードに移行する。
Config
モードは以下の様に検索対象を詳細指定して検索する。
なお、Config
モードでも見つからなかったらエラーメッセージを出力する。
find_package(<PackageName> [version] [EXACT] [QUIET]
[REQUIRED] [[COMPONENTS] [components...]]
[OPTIONAL_COMPONENTS components...]
[CONFIG|NO_MODULE]
[NO_POLICY_SCOPE]
[NAMES name1 [name2 ...]]
[CONFIGS config1 [config2 ...]]
[HINTS path1 [path2 ... ]]
[PATHS path1 [path2 ... ]]
[PATH_SUFFIXES suffix1 [suffix2 ...]]
[NO_DEFAULT_PATH]
[NO_PACKAGE_ROOT_PATH]
[NO_CMAKE_PATH]
[NO_CMAKE_ENVIRONMENT_PATH]
[NO_SYSTEM_ENVIRONMENT_PATH]
[NO_CMAKE_PACKAGE_REGISTRY]
[NO_CMAKE_BUILDS_PATH] # Deprecated; does nothing.
[NO_CMAKE_SYSTEM_PATH]
[NO_CMAKE_SYSTEM_PACKAGE_REGISTRY]
[CMAKE_FIND_ROOT_PATH_BOTH |
ONLY_CMAKE_FIND_ROOT_PATH |
NO_CMAKE_FIND_ROOT_PATH])
参考CMakeを使ってみた (7) find_packageとpkg_check_modulesによるライブラリ探索
find_program
https://cmake.org/cmake/help/latest/command/find_program.html
find_program (<VAR> name)
例: find_program(LCOV_PATH lcov)
の様に利用
nameに該当するプログラムが(OS上に)存在する場合はに指定した変数に、その実行ファイルパスを格納する。
なかった場合は<VAR>-NOTFOUND
となる
function
https://cmake.org/cmake/help/latest/command/function.html
独自の関数を定義するための関数
function(<name> [<arg1> ...])
<commands>
endfunction()
function(foo)
<commands>
endfunction()
と定義した関数は
foo()
Foo()
FOO()
cmake_language(CALL foo)
のいずれでも呼び出せるが、基本全て小文字で扱うことが推奨される
引数について
ARGC
:渡された引数の数
ARGV#
:"#"部分は数字(ARGV0,ARGV1,ARGV2,...)。渡された引数が入っている変数
ARGN
:渡された引数がlistとして入っている変数。
引数を明示的に定義した場合
function(<name> SAMP_ARG1 SAMP_ARG2)
<commands>
endfunction()
の様に引数を変数定義していれば、
SAMP_ARG1,SAMP_ARG2にもそれぞれ渡された引数値が入る。
この場合は
${SAMP_ARG1} == ${ARGV0}
${SAMP_ARG2} == ${ARGV1}
となる。
また、明示的に引数定義されている場合は、呼び出し時に対応する引数を渡さないとエラーになる。
get_filename_component
get_filename_component(<var> <FileName> <mode> [CACHE])
<FileName>
に当てはまるファイル名やパス名を<var>
の変数に代入する関数。
(<mode>
では当てはまり方を指定する。)
get_filename_componentはCMakeのversion 3.19からcmake_path()に取って代わられています。
include
https://cmake.org/cmake/help/latest/command/include.html
上述の".cmake"のようなCMake codeを読み込んで実行*する
list
list変数を扱う関数で、様々なモードが有る。
なお、list変数の作成は通常変数と同じくset関数を利用する
また、list変数は内部的には;
で区切られた文字列群
macro
macro(<name> [<arg1> ...])
<commands>
endmacro()
マクロ作成関数
macroとfunctionは非常に似ているが以下の点で異なる
- 変数の意味合いが違い、macroでの
ARGN
,ARGC
,ARGV
,ARGV#
といったものはCMakeとしての変数ではなく、C言語のプリプロセッサが置き換える場所になる。- 変数利用時の指定の仕方に注意が必要
- functionは呼び出し時にfunction側に移動して実行されるが、macroは該当のソースコードを利用先に埋め込む形になる。
- 特にmacro利用時はreturnのスコープに影響してややこしくなるので、macroではreturnは利用しない方が良い
message
https://cmake.org/cmake/help/latest/command/message.html
massage([<mode>] "message text")
cmakeコマンド実行時にメッセージ出力する
例:message(STATUS "Building for code coverage")
の様に利用
- mode には幾つかあるが代表的なものだと
- 指定無し or NOTICE: stderrに出力される
- STATUS: ユーザが必要とするだろう情報
- FATAL_ERROR: メッセージを出しつつ、処理を停止する
option
https://cmake.org/cmake/help/latest/command/option.html
CMakeLists.txt上で定義されたoptionは、cmake
コマンド実行時に指定出来るようになる
例
option(PYTHON_COVERAGE "Python code coverage" OFF)
if(PYTHON_COVERAGE)
message(STATUS "python coverage enabled")
set(PYTHON_EXECUTABLE coverage run -p)
endif()
と記述しておき、cmakeコマンド実行時に
cmake -DPYTHON_COVERAGE=ON
の様に実行する
project
https://cmake.org/cmake/help/latest/command/project.html
プロジェクト名やバージョンなどを設定する。
set
https://cmake.org/cmake/help/latest/command/set.html
通常変数、キャッシュ変数、環境変数を作成する。
set(VALUE_A a 1 2)
message(${VALUE_A})
→a12と表示される
set(VALUE_B 1234 CACHE STRING SampleCache)
message(${VALUE_B})
message($CACHE{VALUE_B})
→1234と表示される
通常変数と異なり、スクリプトのどこからでも生成・参照出来る
環境変数設定は利用例が少ないので割愛
set_property
https://cmake.org/cmake/help/latest/command/set_property.html
cmakeには変数(通常変数、キャッシュ変数、環境変数)とは別に、プロパティという各種動作設定が格納される変数領域があり、それを設定するためのもの。
プロパティ取得関数のget_property
と対になる。
set_source_files_properties
set_source_files_properties(<files> ...
[DIRECTORY <dirs> ...]
[TARGET_DIRECTORY <targets> ...]
PROPERTIES <prop1> <value1>
[<prop2> <value2>] ...)
<files>
に指定したソースファイルにProperties on Source Filesのプロパティ(※)を設定する
※例えばGENERATEDという、該当のソースファイルが、ビルド時に外部システムまたはCMake自身によって生成されるものかを指定することによって、非存在チェックを免除する設定などがある。
target_compile_definitions
target_compile_definitions(<target>
<INTERFACE|PUBLIC|PRIVATE> [items1...]
[<INTERFACE|PUBLIC|PRIVATE> [items2...] ...])
<target>
に指定したターゲット実行時に、
-
PUBLIC
とPRIVATE
はCOMPILE_DEFINITIONSの埋め込みをおこなう。- COMPILE_DEFINITIONSとはターゲットのソースコードコンパイル時のプリプロセッサ定義。
-
PUBLIC
とINTERFACE
はINTERFACE_COMPILE_DEFINITIONSの埋め込みを行う。
要はソースコードの
#ifdef XXXXX
とかに埋め込む値の設定
target_compile_definitions(foo PUBLIC -DFOO)
の様に-D
で指定すると該当の項目は削除される
target_link_libraries
target_link_libraries(<target> ... <item>... ...)
ターゲットにライブラリを紐付ける。
-
<target>
はadd_executable
やadd_library
で生成されたターゲットを指定する。 -
<item>
は幾つかパターンがある- add_libraryで生成された他のライブラリターゲット
- ライブラリファイルへのフルパス
- 素のライブラリ名(紐付けたいライブラリファイルがfoo.libだったら
foo
) - リンクフラグ
- ビルドシステムによってリンク(ビルド)時に指定されるオプションの指定
- generator expression
- 評価計算され、上記(ライブラリターゲット、フルパス、ライブラリ名など)として扱われる
-
debug
,optimized
,general
キーワードと上記の<item>
- 詳細は割愛
target_link_libraries(<target>
<PRIVATE|PUBLIC|INTERFACE> <item>...
[<PRIVATE|PUBLIC|INTERFACE> <item>...]...)
というような使い方が多い。
PRIVATE|PUBLIC|INTERFACEがそれぞれなんなのかは以下が詳しい。
参考CMake: target_link_libraries(PUBLIC/PRIVATE/INTERFACE) の実践的な解説