CMake: 静的ライブラリのリンプロパティ伝達:最善の方法を選択!CMP0099 vs 代替方法
CMakeポリシー CMP0099 は、静的ライブラリのプライベート依存関係におけるリンプロパティの伝達動作を制御します。これは、CMake 3.17 で導入された新しい動作であり、古いバージョンの CMake との互換性を保つために提供されています。
詳細
CMake 3.16 以前では、静的ライブラリのインターフェースリンプロパティは、そのライブラリのプライベート依存関係には伝達されませんでした。つまり、依存関係にある実行可能ファイルは、静的ライブラリ自体のリンプロパティのみを継承していました。しかし、CMake 3.17 以降では、リンプロパティはプライベート依存関係にも伝達されるようになりました。これは、すべての依存関係が同じリンオプションとディレクトリを使用することを保証し、一貫したビルドと実行環境を実現するのに役立ちます。
影響
CMP0099 ポリシーが OLD
に設定されている場合、CMake は古い動作を使用し、リンプロパティはプライベート依存関係に伝達されません。一方、NEW
に設定されている場合、新しい動作が使用され、リンプロパティはすべての依存関係に伝達されます。
設定方法
このポリシーは、cmake_policy
コマンドを使用して設定できます。
cmake_policy(CMP0099 NEW)
この例では、ポリシーは NEW
値に設定され、リンプロパティはすべての依存関係に伝達されます。
互換性
古い CMake バージョンとの互換性を保つために、CMP0099 ポリシーはデフォルトで OLD
に設定されています。ただし、新しい動作の利点を享受するために、プロジェクトを NEW
に更新することをお勧めします。
例
以下の例は、CMP0099 ポリシーが NEW
に設定されている場合の動作を示しています。
target_link_libraries(mytarget PRIVATE foo bar)
target_link_properties(foo INTERFACE_LINK_DIRECTORIES "/usr/local/lib")
target_get_property(mytarget INTERFACE_LINK_DIRECTORIES MY_LINK_DIRECTORIES)
message(STATUS "mytarget のリンクディレクトリ: ${MY_LINK_DIRECTORIES}")
この例では、foo
ライブラリは /usr/local/lib
ディレクトリにあるリンカブルオブジェクトを検索します。CMP0099 ポリシーが NEW
に設定されているため、このディレクトリは mytarget
実行可能ファイルのリンカブルオブジェクトの検索にも使用されます。
CMakeポリシー CMP0099 は、静的ライブラリのプライベート依存関係におけるリンプロパティの伝達動作を制御します。これは、新しい CMake バージョンにおける重要な変更であり、古いバージョンの CMake との互換性を保つために提供されています。プロジェクトを新しい動作に更新することをお勧めします。
- このポリシーは、CMake 3.17 以降でのみ使用できます。
- CMP0099 ポリシーは、静的ライブラリのみを対象としています。共有ライブラリのリンプロパティは、常にすべての依存関係に伝達されます。
例 1: ポリシーの設定
この例では、cmake_policy
コマンドを使用して CMP0099 ポリシーを NEW
値に設定します。
cmake_policy(CMP0099 NEW)
例 2: リンプロパティの伝達
この例では、静的ライブラリと実行可能ファイルを使用して、リンプロパティの伝達をデモンストレーションします。
# 静的ライブラリを定義する
add_library(foo STATIC foo.c)
target_link_properties(foo INTERFACE_LINK_DIRECTORIES "/usr/local/lib")
# 実行可能ファイルを定義する
add_executable(mytarget mytarget.c)
target_link_libraries(mytarget PRIVATE foo)
# mytarget のリンクディレクトリを取得する
target_get_property(mytarget INTERFACE_LINK_DIRECTORIES MY_LINK_DIRECTORIES)
# 結果を出力する
message(STATUS "mytarget のリンクディレクトリ: ${MY_LINK_DIRECTORIES}")
説明
message
コマンドは、メッセージを出力するために使用されます。最初の引数はメッセージのタイプ、2番目の引数はメッセージの内容です。この例では、mytarget
実行可能ファイルのリンクディレクトリがコンソールに出力されます。target_get_property
コマンドは、ターゲットのプロパティを取得するために使用されます。最初の引数はターゲットの名前、2番目の引数はプロパティの名前、3番目の引数はプロパティの値を格納する変数です。この例では、mytarget
実行可能ファイルのINTERFACE_LINK_DIRECTORIES
プロパティがMY_LINK_DIRECTORIES
変数に格納されます。target_link_libraries
コマンドは、ターゲットのライブラリ依存関係を設定するために使用されます。最初の引数はターゲットの名前、2番目の引数はライブラリのリストです。この例では、mytarget
実行可能ファイルはfoo
ライブラリにプライベートに依存します。add_executable
コマンドは、実行可能ファイルを定義するために使用されます。最初の引数は実行可能ファイルの名前、2番目の引数はソースファイルのリストです。この例では、mytarget
という名前の実行可能ファイルがmytarget.c
ファイルから作成されます。target_link_properties
コマンドは、ターゲットのリンプロパティを設定するために使用されます。最初の引数はターゲットの名前、2番目の引数はプロパティの名前、3番目の引数はプロパティの値です。この例では、foo
ライブラリのINTERFACE_LINK_DIRECTORIES
プロパティが/usr/local/lib
に設定されています。これは、foo
ライブラリをビルドするときに、リンカはこのディレクトリにあるリンカブルオブジェクトを検索することを意味します。add_library
コマンドは、静的ライブラリを定義するために使用されます。最初の引数はライブラリの名前、2番目の引数はソースファイルのリストです。この例では、foo
という名前の静的ライブラリがfoo.c
ファイルから作成されます。cmake_policy
コマンドは、CMake ポリシーを設定するために使用されます。最初の引数はポリシーの名前、2番目の引数はポリシーの値です。この例では、CMP0099
ポリシーがNEW
値に設定されています。
- このコードは、静的ライブラリと実行可能ファイルのみを対象としています。共有ライブラリのリンプロパティは、常にすべての依存関係に伝達されます。
- このコードは、CMake 3.17 以降でのみ使用できます。
CMP0099 の代替方法として、以下の方法が考えられます。
ターゲットプロパティの設定
ターゲットプロパティを使用して、リンプロパティを個別に設定できます。これは、CMP0099 ポリシーを使用するよりも柔軟性が高い方法です。
target_link_libraries(mytarget PRIVATE foo bar)
# mytarget のリンプロパティを設定する
target_link_properties(mytarget LINK_DIRECTORIES "/usr/local/lib")
# foo のリンプロパティを設定する
target_link_properties(foo INTERFACE_LINK_DIRECTORIES "/opt/local/lib")
この例では、mytarget
実行可能ファイルは /usr/local/lib
ディレクトリにあるリンカブルオブジェクトを検索し、foo
ライブラリは /opt/local/lib
ディレクトリにあるリンカブルオブジェクトを検索します。
ターゲットコマンドの使用
ターゲットコマンドを使用して、リンカオプションを個別に設定できます。これは、シンプルなケースに適した方法です。
target_link_libraries(mytarget PRIVATE foo bar)
# mytarget のリンオプションを設定する
target_link_options(mytarget PRIVATE "-L/usr/local/lib")
# foo のリンオプションを設定する
target_link_options(foo PRIVATE "-L/opt/local/lib")
カスタムターゲットの使用
カスタムターゲットを使用して、リンカオプションとリンカブルオブジェクトを個別に設定できます。これは、複雑なケースに適した方法です。
# カスタムターゲットを定義する
add_custom_target(mytarget_link)
# mytarget_link ターゲットにリンカオプションを追加する
target_link_options(mytarget_link PRIVATE "-L/usr/local/lib")
# mytarget_link ターゲットにリンカブルオブジェクトを追加する
add_custom_command(TARGET mytarget_link COMMAND ${CMAKE_LINKER} ${ARGLIST})
# mytarget に mytarget_link ターゲットを依存させる
add_dependencies(mytarget mytarget_link)
この例では、mytarget
実行可能ファイルは /usr/local/lib
ディレクトリにあるリンカブルオブジェクトを検索します。
サードパーティのライブラリの使用
サードパーティのライブラリを使用して、リンプロパティを管理することもできます。CMake には、FindXXX
モジュールと呼ばれるサードパーティライブラリを見つけるためのモジュールがいくつか用意されています。これらのモジュールは、ライブラリのリンプロパティを設定するために使用できます。
find_package(FooBar REQUIRED)
# mytarget に FooBar ライブラリをリンクする
target_link_libraries(mytarget PRIVATE FooBar::FooBar)
この例では、mytarget
実行可能ファイルは FooBar
ライブラリにリンクされます。FooBar::FooBar
ターゲットは、FooBar
ライブラリのリンプロパティを設定します。
CMP0099 ポリシーは、静的ライブラリのプライベート依存関係におけるリンプロパティの伝達動作を制御するための便利な方法ですが、代替方法もいくつかあります。どの方法を使用するかは、プロジェクトのニーズと要件によって異なります。
FindXXX
モジュールは、CMake バージョンによって異なります。- カスタムターゲットは、CMake 2.4 以降でのみ使用できます。
- ターゲットプロパティとターゲットコマンドは、CMake 2.8 以降でのみ使用できます。