CMakeで外部バイナリ参照を簡単にする!ポリシーCMP0070徹底解説

2024-04-02

CMakeポリシー CMP0070 の詳細解説

CMakeポリシー CMP0070 は、プロジェクト内のターゲットが IMPORTED 属性を持つ場合の動作を制御します。このポリシーは、ターゲットが外部ソースによって生成されたバイナリファイルを参照する場合に役立ちます。

デフォルトの動作

CMake 3.13 以前では、IMPORTED 属性を持つターゲットは、その依存関係にあるターゲットがビルドされる前に存在している必要がありました。これは、依存関係が事前にビルドされていない場合、ビルドが失敗することを意味していました。

CMP0070 の影響

CMP0070 を OLD に設定すると、CMake は IMPORTED 属性を持つターゲットの依存関係が事前に存在していない場合でも、ビルドを続行します。ただし、依存関係が見つからない場合は、警告が表示されます。

CMP0070 を NEW に設定すると、CMake は IMPORTED 属性を持つターゲットの依存関係が事前に存在していない場合、エラーを出力します。

使用例

以下の例は、CMP0070 ポリシーの使用方法を示しています。

cmake_minimum_required(VERSION 3.13)

set(POLICY_CMP0070 NEW)

add_library(foo SHARED IMPORTED)
set_target_properties(foo PROPERTIES IMPORTED_LOCATION "/path/to/libfoo.so")

add_executable(bar DEPENDS foo)

target_link_libraries(bar foo)

この例では、foo ターゲットは IMPORTED 属性と /path/to/libfoo.so へのパスを持つ IMPORTED_LOCATION プロパティを使用して作成されます。

POLICY_CMP0070NEW に設定されているため、bar ターゲットがビルドされる前に libfoo.so ファイルが存在しない場合、エラーが発生します。

注意事項

  • CMP0070 ポリシーは、CMake 3.13 以降でのみ使用できます。
  • IMPORTED 属性を持つターゲットの依存関係が事前に存在しない場合、ビルドの順序が重要になる可能性があります。
  • CMP0070 を NEW に設定すると、依存関係が見つからない場合にエラーが発生するため、注意が必要です。


CMake ポリシー CMP0070 のサンプルコード

cmake_minimum_required(VERSION 3.13)

set(POLICY_CMP0070 OLD)

add_library(foo SHARED IMPORTED)
set_target_properties(foo PROPERTIES IMPORTED_LOCATION "/path/to/libfoo.so")

add_executable(bar DEPENDS foo)

target_link_libraries(bar foo)

この例では、foo ターゲットは存在しない /path/to/libfoo.so ファイルを参照します。POLICY_CMP0070OLD に設定されているため、ビルドは警告付きで成功します。

例 2: 依存関係が存在しない場合のエラー

cmake_minimum_required(VERSION 3.13)

set(POLICY_CMP0070 NEW)

add_library(foo SHARED IMPORTED)
set_target_properties(foo PROPERTIES IMPORTED_LOCATION "/path/to/libfoo.so")

add_executable(bar DEPENDS foo)

target_link_libraries(bar foo)

この例では、foo ターゲットは存在しない /path/to/libfoo.so ファイルを参照します。POLICY_CMP0070NEW に設定されているため、ビルドはエラーで失敗します。

例 3: 事前存在チェックと依存関係の順序

cmake_minimum_required(VERSION 3.13)

set(POLICY_CMP0070 NEW)

file(EXISTS "/path/to/libfoo.so" EXISTS_FOO)

if(EXISTS_FOO)
  add_library(foo SHARED IMPORTED)
  set_target_properties(foo PROPERTIES IMPORTED_LOCATION "/path/to/libfoo.so")
else()
  message(FATAL_ERROR "libfoo.so does not exist")
endif()

add_executable(bar DEPENDS foo)

target_link_libraries(bar foo)

この例では、libfoo.so ファイルが存在するかどうかを事前にチェックしてから、foo ターゲットを作成します。foo ターゲットは bar ターゲットよりも前に作成されるため、依存関係の順序が正しくなります。

注意: これらのサンプルコードはあくまでも参考であり、実際のユースケースに合わせて変更する必要があります。



CMakeで外部バイナリ参照時の他の方法

find_package() モジュールは、特定のライブラリやフレームワークがインストールされているかどうかを検出し、必要な情報を CMake 変数に設定します。

find_package(Foo REQUIRED)

target_link_libraries(bar PRIVATE Foo::Foo)

この例では、Foo パッケージがインストールされているかどうかを find_package() モジュールが検出します。見つかった場合は、Foo::Foo ターゲットへのリンクに必要な情報が CMake 変数に設定されます。

外部プロジェクトファイルは、外部ソースによって生成されたバイナリファイルを CMake プロジェクトに統合するための仕組みです。

add_custom_target(foo
  COMMAND /path/to/build_foo
  WORKING_DIRECTORY /path/to/foo
  BYPRODUCTS /path/to/libfoo.so)

add_executable(bar DEPENDS foo)

target_link_libraries(bar /path/to/libfoo.so)

この例では、/path/to/build_foo コマンドを実行して libfoo.so ファイルを生成します。foo ターゲットは、libfoo.so ファイルの生成を依存関係として持ちます。

手動でパスを設定する

target_link_libraries() コマンドを使用して、外部バイナリのパスを手動で設定できます。

add_executable(bar)

target_link_libraries(bar /path/to/libfoo.so)

この例では、bar ターゲットは /path/to/libfoo.so ファイルにリンクされます。

各方法の比較

方法利点欠点
CMP0070簡潔で使いやすい依存関係の順序に注意が必要
find_package()パッケージ管理が容易パッケージが存在しない場合、ビルドが失敗する
外部プロジェクトファイル柔軟性が高い設定が複雑になる場合がある
手動でパスを設定する汎用性が高い設定ミスが発生しやすい

どの方法を選択するかは、プロジェクトの要件と CMake のバージョンによって異なります。

  • CMake 3.13 以降を使用している場合は、CMP0070 ポリシーが最も簡潔で使いやすい方法です。
  • 依存関係の順序が重要な場合は、find_package() モジュールを使用するのが安全です。
  • 柔軟性が高い方法が必要場合は、外部プロジェクトファイルを使用できます。
  • 汎用性が高い方法が必要場合は、手動でパスを設定できます。



CMakeコマンド「ctest_submit()」でテスト結果をCDashサーバーに送信

ctest_submit()は、CMakeの「Commands」カテゴリに属するコマンドで、テスト結果をCDashなどのダッシュボードサーバーに送信するために使用されます。テスト実行後の結果を可視化、共有したい場合に役立ちます。基本構文オプション解説



CMakeにおける"get_target_property()"コマンド: ターゲットの情報を自在に操る

get_target_property()コマンドは、CMakeプロジェクトで定義されたターゲットからプロパティを取得するために使用されます。ターゲットプロパティは、ターゲットのビルド方法や動作を制御するために使用される情報です。構文引数VAR: ターゲットプロパティの値を格納する変数名


CMake find_file() コマンドの代替方法:もっと柔軟なファイル検索

<variable>: 検索結果を格納する CMake 変数<file_names>: 検索するファイル名のリスト (スペース区切り)<path_list>: 検索するパス名のリスト (スペース区切り)<options>: 検索オプション (後述)


CMake: find_library()とtarget_link_directories()の連携

target_link_directories()コマンドは、CMakeプロジェクト内のターゲットに対して、リンカがライブラリを検索するディレクトリを指定するために使用されます。これは、ターゲットがリンクするライブラリが標準の検索パスに存在しない場合に特に重要です。


CMake の if() コマンド: デバッグとトラブルシューティング

構文条件式if() コマンドの引数には、条件式を指定します。条件式は、以下のいずれかの形式で記述できます。変数の比較: <variable> <operator> <value>コマンドの存在チェック: COMMAND <command-name>



CMakeの環境変数:LD_LIBRARY_PATH、CPATH、CMAKE_PREFIX_PATHの役割と設定方法

CMAKE_PREFIX_PATHの概要CMAKE_PREFIX_PATHは、find_package()、find_program()、find_library()、find_file()、**find_path()**などのコマンドが、必要なライブラリやヘッダーファイルなどを検索する際に使用するディレクトリを指定します。これは、複数のディレクトリに分散してインストールされたライブラリやヘッダーファイルを、一括して検索できるようにするためのものです。


CMake の IMPORTED_LINK_INTERFACE_MULTIPLICITY プロパティに関するサンプルコード

IMPORTED_LINK_INTERFACE_MULTIPLICITY プロパティは、CMake の "Properties: Targets" において、インポートされた静的ライブラリのサイクルにおける繰り返しカウントを設定するために使用されます。これは、LINK_INTERFACE_MULTIPLICITY プロパティのインポートターゲット版です。


CMake include() で効率的なビルドを実現

include() は CMake の重要なコマンドの一つで、他の CMake ファイルやモジュールを読み込むために使用されます。 これにより、コードを分割し、再利用性と保守性を向上させることができます。機能他の CMake ファイルを読み込んで、その中のコマンドを実行する


CMAKE_TLS_VERIFY:環境変数、GUI、C++コードなど、多彩な設定方法

CMAKE_TLS_VERIFY は、CMake の Variables における重要な設定項目です。これは、file(DOWNLOAD) や file(UPLOAD) コマンド、および ExternalProject や FetchContent モジュールによる内部的な file(DOWNLOAD) 呼び出しにおいて、TLS 検証 を有効にするかどうかを制御します。


CMakeにおける「CMAKE_LIBRARY_PATH」変数の詳細解説

デフォルト値CMAKE_LIBRARY_PATH はデフォルトで空の文字列に設定されています。つまり、CMakeはライブラリを検索する際に、現在のディレクトリのみを調べます。設定方法CMAKE_LIBRARY_PATH は、CMakeLists