CMake: ターゲットライブラリの依存関係を可視化!「INTERFACE_LINK_LIBRARIES」でプロジェクトを理解


INTERFACE_LINK_LIBRARIES は、CMake のターゲットプロパティであり、ターゲットが依存するライブラリを指定するために使用されます。これらのライブラリは、ターゲットをリンクする際に自動的に追加されます。

重要なポイント

  • INTERFACE_LINK_LIBRARIES に指定されたライブラリは、再帰的に 依存関係が解決されます。つまり、指定されたライブラリがさらに他のライブラリに依存している場合、それらのライブラリも自動的に追加されます。
  • プライベートにリンクするライブラリを指定するには、PRIVATE_LINK_LIBRARIES プロパティを使用します。
  • INTERFACE_LINK_LIBRARIES は、公開インターフェースの一部であるライブラリのみを指定します。つまり、これらのライブラリは、ターゲットを使用する他のプロジェクトからも利用できます。

構文

target_link_libraries(TARGET_NAME INTERFACE_LINK_LIBRARIES LIBRARY1 LIBRARY2 ...)

target_link_libraries(my_target INTERFACE_LINK_LIBRARIES foo bar)

この例では、my_target ターゲットは foo ライブラリと bar ライブラリに依存します。これらのライブラリは、my_target を使用する他のプロジェクトからも利用できます。

  • CMake の最新バージョンでは、INTERFACE_LINK_LIBRARIES_DIRECTINTERFACE_LINK_LIBRARIES_DIRECT_EXCLUDE プロパティを使用して、ターゲットの直接的なリンク依存関係を操作することができます。
  • INTERFACE_LINK_LIBRARIES プロパティは、target_link_libraries() コマンド以外にも、add_library() コマンドや install() コマンドでも使用できます。
  • INTERFACE_LINK_LIBRARIES プロパティは、ターゲットが生成するライブラリファイルにも適用されます。これは、ライブラリを他のライブラリとリンクする場合に役立ちます。
  • CMake のターゲットプロパティの詳細については、CMake のドキュメントを参照してください。
  • INTERFACE_LINK_LIBRARIES プロパティは、複雑な依存関係を管理する場合に役立ちます。


例 1: 単純な依存関係

この例では、my_app ターゲットは foo ライブラリと bar ライブラリに依存します。

cmake_minimum_required(VERSION 3.0)

project(my_app)

add_library(foo STATIC foo.c foo.h)
add_library(bar STATIC bar.c bar.h)

target_link_libraries(my_app INTERFACE_LINK_LIBRARIES foo bar)

add_executable(my_app main.c)
target_link_libraries(my_app my_app)

例 2: 再帰的な依存関係

この例では、my_app ターゲットは foo ライブラリに依存し、foo ライブラリは baz ライブラリに依存します。

cmake_minimum_required(VERSION 3.0)

project(my_app)

add_library(foo STATIC foo.c foo.h)
target_link_libraries(foo INTERFACE_LINK_LIBRARIES baz)

add_library(bar STATIC bar.c bar.h)

target_link_libraries(my_app INTERFACE_LINK_LIBRARIES foo bar)

add_executable(my_app main.c)
target_link_libraries(my_app my_app)

例 3: 静的ライブラリと共有ライブラリの混在

この例では、my_app ターゲットは静的ライブラリ foo と共有ライブラリ bar に依存します。

cmake_minimum_required(VERSION 3.0)

project(my_app)

add_library(foo STATIC foo.c foo.h)

add_library(bar SHARED bar.c bar.h)

target_link_libraries(my_app INTERFACE_LINK_LIBRARIES foo bar)

add_executable(my_app main.c)
target_link_libraries(my_app my_app)

説明

  • target_link_libraries() コマンドを使用して、実行可能ファイルの依存関係を指定します。
  • 各例では、add_executable() コマンドを使用して、実行可能ファイルを定義します。
  • INTERFACE_LINK_LIBRARIES プロパティを使用して、公開インターフェースの一部であるライブラリを指定します。
  • target_link_libraries() コマンドを使用して、ターゲットの依存関係を指定します。
  • 各例では、add_library() コマンドを使用して、ライブラリを定義します。

これらの例は、INTERFACE_LINK_LIBRARIES プロパティを使用して、CMake でターゲット間の依存関係をどのように管理できるかを示すほんの一例です。

  • 実際のプロジェクトでは、より複雑な依存関係を管理する必要がある場合があります。


以下に、INTERFACE_LINK_LIBRARIES の代替方法をいくつか紹介します。

TARGET_LINK_LIBRARIES プロパティ

TARGET_LINK_LIBRARIES プロパティは、ターゲットの直接的なリンク依存関係を指定するために使用されます。 INTERFACE_LINK_LIBRARIES プロパティと異なり、TARGET_LINK_LIBRARIES プロパティで指定されたライブラリは、ターゲットを使用する他のプロジェクトからは利用できません。

target_link_libraries(my_target TARGET_LINK_LIBRARIES foo bar)

PRIVATE_LINK_LIBRARIES プロパティ

PRIVATE_LINK_LIBRARIES プロパティは、ターゲットの非公開リンク依存関係を指定するために使用されます。 TARGET_LINK_LIBRARIES プロパティと異なり、PRIVATE_LINK_LIBRARIES プロパティで指定されたライブラリは、ターゲットを使用する他のプロジェクトからは利用できません。

target_link_libraries(my_target PRIVATE_LINK_LIBRARIES foo bar)

LINK_DIRECTORIES プロパティ

LINK_DIRECTORIES プロパティは、CMake がライブラリ検索パスに追加するディレクトリを指定するために使用されます。 ターゲットがこれらのディレクトリにあるライブラリに依存している場合、INTERFACE_LINK_LIBRARIES プロパティで明示的にライブラリを指定する必要はありません。

link_directories(/usr/local/lib)

target_link_libraries(my_target foo bar)

find_package() コマンド

find_package() コマンドは、特定のライブラリパッケージを検索し、その依存関係を自動的に解決するために使用されます。

find_package(FooBar REQUIRED)

target_link_libraries(my_target FooBar::LIBRARIES)

手動のリンカコマンド

CMake を使用せずに、手動のリンカコマンドを使用してターゲットの依存関係を指定することもできます。

g++ -o my_app main.c foo.o bar.o -lfoo -lbar

選択の指針

どの方法を使用するかは、状況によって異なります。

  • 複雑なリンカ設定が必要な場合は、手動のリンカコマンドを使用します。
  • ターゲットが特定のライブラリパッケージに依存している場合は、find_package() コマンドを使用します。
  • ターゲットの非公開リンク依存関係を指定する必要がある場合は、PRIVATE_LINK_LIBRARIES プロパティを使用します。
  • ターゲットの直接的なリンク依存関係のみを指定する必要がある場合は、TARGET_LINK_LIBRARIES プロパティを使用します。
  • 一般的な場合は、INTERFACE_LINK_LIBRARIES プロパティが最も適切です。
  • どの方法を使用するかわからない場合は、CMake のドキュメントを参照してください。