FindPackageモジュールはもう古い?CMakeFindDependencyMacroモジュールでスマートな依存関係管理


CMakeFindDependencyMacro モジュールは、CMake の FindPackage モジュールをラップするもので、パッケージ依存関係をより簡単に管理するための機能を提供します。FindPackage モジュールは、特定のパッケージがインストールされているかどうかを検出し、そのパッケージに必要なヘッダーファイルやライブラリを CMake プロジェクトに追加します。

使用方法

CMakeFindDependencyMacro モジュールを使用するには、以下の構文を使用します。

find_dependency(<dep> [REQUIRED] [COMPONENTS <components>] [HINTS <hints>] [NO_DEFAULT_COMPONENTS])
  • NO_DEFAULT_COMPONENTS: デフォルトのコンポーネントを無効にします。
  • HINTS: パッケージの検索パスを指定します。
  • COMPONENTS: 必要なパッケージコンポーネントを指定します。
  • REQUIRED: パッケージが必須であることを指定します。このオプションを指定しないと、パッケージが見つからない場合、CMake は警告を出力するだけで処理を続行します。
  • <dep>: 依存関係となるパッケージの名前を指定します。

利点

CMakeFindDependencyMacro モジュールを使用する利点は次のとおりです。

  • 複数のコンポーネントを持つパッケージに対応できる
  • 依存関係の管理が容易になる
  • FindPackage モジュールよりも簡潔で読みやすいコードとなる

以下の例は、foo パッケージと bar パッケージを依存関係とする CMakeLists.txt ファイルを示しています。

cmake_minimum_required(VERSION 3.16)

project(myproject)

find_dependency(foo REQUIRED COMPONENTS headers libraries)
find_dependency(bar REQUIRED COMPONENTS foo::bar)

この例では、foo パッケージと bar パッケージが必須であることを指定し、foo パッケージのヘッダーファイルとライブラリ、bar パッケージの foo::bar コンポーネントを CMake プロジェクトに追加します。

詳細

CMakeFindDependencyMacro モジュールの詳細については、CMake のドキュメントを参照してください。

  • FindPackage モジュールの代わりに CMakeFindDependencyMacro モジュールを使用することをお勧めします。
  • CMakeFindDependencyMacro モジュールは、CMake 3.16 以降で使用できます。

プログラミング例

以下は、CMakeFindDependencyMacro モジュールを使用してパッケージ依存関係を管理するプログラミング例を示しています。

例 1: 単一のパッケージ依存関係

cmake_minimum_required(VERSION 3.16)

project(myproject)

find_dependency(foo REQUIRED COMPONENTS headers libraries)

add_executable(myprogram main.cpp)
target_link_libraries(myprogram foo::libraries)
cmake_minimum_required(VERSION 3.16)

project(myproject)

find_dependency(foo REQUIRED COMPONENTS headers libraries)
find_dependency(bar REQUIRED COMPONENTS foo::bar)

add_executable(myprogram main.cpp)
target_link_libraries(myprogram foo::libraries bar::foo::bar)
cmake_minimum_required(VERSION 3.16)

project(myproject)

find_dependency(foo REQUIRED COMPONENTS headers libraries foo::bar)
find_dependency(bar REQUIRED COMPONENTS foo::bar)

add_executable(myprogram main.cpp)
target_link_libraries(myprogram foo::libraries bar::foo::bar)


例 1: 単一のパッケージ依存関係

cmake_minimum_required(VERSION 3.16)

project(myproject)

find_dependency(foo REQUIRED COMPONENTS headers libraries)

add_executable(myprogram main.cpp)
target_link_libraries(myprogram foo::libraries)

例 2: 複数のコンポーネントを持つパッケージ依存関係

cmake_minimum_required(VERSION 3.16)

project(myproject)

find_dependency(foo REQUIRED COMPONENTS headers libraries foo::bar)
find_dependency(bar REQUIRED COMPONENTS foo::bar)

add_executable(myprogram main.cpp)
target_link_libraries(myprogram foo::libraries bar::foo::bar)

この例では、foo パッケージと bar パッケージが必要です。find_dependency コマンドを使用して、パッケージがインストールされているかどうかを CMake が検出します。パッケージが見つかった場合、CMake は必要なヘッダーファイル、ライブラリ、およびコンポーネントをプロジェクトに追加します。

例 3: オプションのパッケージ依存関係

cmake_minimum_required(VERSION 3.16)

project(myproject)

find_dependency(foo OPTIONAL COMPONENTS headers libraries)

add_executable(myprogram main.cpp)
target_link_libraries(myprogram foo::libraries)

この例では、foo パッケージはオプションです。find_dependency コマンドを使用して、パッケージがインストールされているかどうかを CMake が検出します。パッケージが見つかった場合、CMake は必要なヘッダーファイルとライブラリをプロジェクトに追加します。パッケージが見つからない場合、CMake は警告を出力するだけで処理を続行します。

例 4: カスタムヒントを使用したパッケージ依存関係

cmake_minimum_required(VERSION 3.16)

project(myproject)

find_dependency(foo REQUIRED COMPONENTS headers libraries HINTS "/usr/local/lib")

add_executable(myprogram main.cpp)
target_link_libraries(myprogram foo::libraries)

この例では、foo パッケージが必要です。find_dependency コマンドを使用して、パッケージがインストールされているかどうかを CMake が検出します。パッケージが見つからない場合、CMake は /usr/local/lib ディレクトリでパッケージを検索します。

cmake_minimum_required(VERSION 3.16)

project(myproject)

find_dependency(foo REQUIRED COMPONENTS libraries NO_DEFAULT_COMPONENTS)

add_executable(myprogram main.cpp)
target_link_libraries(myprogram foo::libraries)

この例では、foo パッケージが必要です。find_dependency コマンドを使用して、パッケージがインストールされているかどうかを CMake が検出します。パッケージが見つかった場合、CMake は必要なライブラリをプロジェクトに追加します。デフォルトのコンポーネントは追加されません。

これらの例は、CMakeFindDependencyMacro モジュールの基本的な使用方法を示しています。このモジュールを使用して、より複雑な依存関係を管理することもできます。



FindPackage モジュール

FindPackage モジュールは、CMakeFindDependencyMacro モジュールの基盤となるモジュールです。FindPackage モジュールは、特定のパッケージがインストールされているかどうかを検出し、そのパッケージに必要なヘッダーファイルやライブラリを CMake プロジェクトに追加します。

FindPackage モジュールを使用するには、以下の構文を使用します。

find_package(<package> [REQUIRED] [COMPONENTS <components>] [HINTS <hints>] [NO_DEFAULT_COMPONENTS])
  • NO_DEFAULT_COMPONENTS: デフォルトのコンポーネントを無効にします。
  • HINTS: パッケージの検索パスを指定します。
  • COMPONENTS: 必要なパッケージコンポーネントを指定します。
  • REQUIRED: パッケージが必須であることを指定します。このオプションを指定しないと、パッケージが見つからない場合、CMake は警告を出力するだけで処理を続行します。
  • <package>: 依存関係となるパッケージの名前を指定します。

利点

  • 既存の CMake プロジェクトとの互換性が高い
  • CMakeFindDependencyMacro モジュールよりも詳細な制御が可能

欠点

  • CMakeFindDependencyMacro モジュールよりもコードが冗長になる可能性がある

cmake_minimum_required(VERSION 3.16)

project(myproject)

find_package(foo REQUIRED COMPONENTS headers libraries)
find_package(bar REQUIRED COMPONENTS foo::bar)

add_executable(myprogram main.cpp)
target_link_libraries(myprogram foo::libraries bar::foo::bar)

手動によるヘッダーファイルとライブラリの追加

FindPackage モジュールや CMakeFindDependencyMacro モジュールを使用せずに、手動でヘッダーファイルとライブラリを追加することもできます。

利点

  • 最も詳細な制御が可能

欠点

  • 複雑でエラーが発生しやすい

以下の例は、foo パッケージと bar パッケージのヘッダーファイルとライブラリを CMake プロジェクトに追加する方法を示しています。

cmake_minimum_required(VERSION 3.16)

project(myproject)

# foo パッケージ

list(APPEND CMAKE_REQUIRED_INCLUDES "/usr/local/include/foo")
list(APPEND CMAKE_REQUIRED_LIBRARIES "foo")

# bar パッケージ

list(APPEND CMAKE_REQUIRED_INCLUDES "/usr/local/include/bar")
list(APPEND CMAKE_REQUIRED_LIBRARIES "bar")

add_executable(myprogram main.cpp)

この例では、foo パッケージと bar パッケージのヘッダーファイルとライブラリが /usr/local ディレクトリにあると仮定しています。

サードパーティのモジュール

CMakeFindDependencyMacro モジュールの代替となるサードパーティのモジュールがいくつかあります。

これらのモジュールは、より多くの機能と利点を提供する可能性がありますが、学習曲線がより急である場合があります。

独自のモジュールを作成して、パッケージ依存関係を管理することもできます。

利点

  • プロジェクトの特定のニーズに合わせたモジュールを作成できる

欠点

  • 時間と労力が必要

以下の例は、foo パッケージと bar パッケージの依存関係を管理するカスタムモジュールを示しています。

cmake_minimum_required(VERSION 3.16)

project(myproject)

module(FindFoo REQUIRED)
module(FindBar REQUIRED)

find_foo(REQUIRED COMPONENTS headers libraries)
find_bar(REQUIRED COMPONENTS foo::bar)

add_executable(myprogram main.cpp)
target_link_libraries(myprogram foo::