LINK_LIBRARIES_ONLY_TARGETSでライブラリリンクの安全性と信頼性を向上させる


LINK_LIBRARIES_ONLY_TARGETS は、CMake の "Properties: Targets" におけるターゲット プロパティであり、ターゲットにリンクするライブラリが必ずターゲットであることを保証します。これは、CMake バージョン 3.23 で導入された新機能です。

詳細

従来の CMake では、ターゲットにリンクするライブラリを指定する際に、単なるライブラリ名やパスを指定することができました。しかし、この方法では、指定されたライブラリが必ずしも存在するターゲットであるとは限らず、エラーが発生する可能性がありました。

LINK_LIBRARIES_ONLY_TARGETS プロパティを TRUE に設定すると、CMake はターゲットにリンクするすべてのライブラリが実際に存在するターゲットであることを検証します。もし存在しないターゲットが指定された場合、CMake はエラーを出力します。

利点

LINK_LIBRARIES_ONLY_TARGETS プロパティを使用することにより、以下の利点が得られます。

  • コードの可読性と保守性を向上させる: ターゲットにリンクするライブラリがすべてターゲットであることを保証することで、コードの可読性と保守性を向上させることができます。
  • ビルドエラーを防ぐ: 存在しないターゲットをリンクしようとした場合に、CMake がエラーを出力するため、ビルドエラーを防ぐことができます。

設定方法

LINK_LIBRARIES_ONLY_TARGETS プロパティは、ターゲット プロパティシートを使用して設定することができます。以下の例では、mytarget というターゲットの LINK_LIBRARIES_ONLY_TARGETS プロパティを TRUE に設定しています。

target_properties(mytarget PROPERTIES LINK_LIBRARIES_ONLY_TARGETS TRUE)
  • このプロパティを有効にすると、CMake はターゲットにリンクするすべてのライブラリを検証するため、ビルド処理が少し遅くなる場合があります。
  • LINK_LIBRARIES_ONLY_TARGETS プロパティは、CMake バージョン 3.23 以降でのみ使用可能です。


例 1: 単一ターゲット

この例では、mytarget というターゲットに mylib1mylib2 というライブラリをリンクします。LINK_LIBRARIES_ONLY_TARGETS プロパティを TRUE に設定することで、CMake はこれらのライブラリが実際に存在するターゲットであることを検証します。

target_libraries(mytarget mylib1 mylib2)
target_properties(mytarget PROPERTIES LINK_LIBRARIES_ONLY_TARGETS TRUE)

例 2: 複数のターゲット

この例では、mytarget1mytarget2 という 2 つのターゲットにライブラリをリンクします。mytarget1mylib1mylib2 にリンクし、mytarget2mylib3 にリンクします。LINK_LIBRARIES_ONLY_TARGETS プロパティを各ターゲットに設定することで、CMake はそれぞれのターゲットにリンクするライブラリが実際に存在するターゲットであることを検証します。

target_libraries(mytarget1 mylib1 mylib2)
target_properties(mytarget1 PROPERTIES LINK_LIBRARIES_ONLY_TARGETS TRUE)

target_libraries(mytarget2 mylib3)
target_properties(mytarget2 PROPERTIES LINK_LIBRARIES_ONLY_TARGETS TRUE)

例 3: 外部ライブラリ

この例では、mytarget というターゲットに Boost ライブラリをリンクします。LINK_LIBRARIES_ONLY_TARGETS プロパティを TRUE に設定することで、CMake は Boost ライブラリが実際に存在するターゲットであることを検証します。

find_package(Boost COMPONENTS system REQUIRED)

target_libraries(mytarget Boost::system)
target_properties(mytarget PROPERTIES LINK_LIBRARIES_ONLY_TARGETS TRUE)
  • このプロパティを有効にすると、CMake はターゲットにリンクするすべてのライブラリを検証するため、ビルド処理が少し遅くなる場合があります。
  • LINK_LIBRARIES_ONLY_TARGETS プロパティは、CMake バージョン 3.23 以降でのみ使用可能です。
  • 上記の例はあくまでサンプルであり、実際の使用状況に合わせて調整する必要があります。
  • 注意事項を明確にしました。


サブディレクトリ

ライブラリが別々のディレクトリに格納されている場合は、add_subdirectory コマンドを使用してそのディレクトリをビルドプロセスに含めることができます。このコマンドは、サブディレクトリの CMakeLists.txt ファイルを自動的に読み込み、その中のターゲットとライブラリをビルドします。

add_subdirectory(path/to/library)

この方法を使用すると、target_link_libraries コマンドでライブラリを明示的に指定する必要がなくなります。

インポートライブラリ

ライブラリが CMake プロジェクトの一部として既にビルドされている場合は、target_link_libraries コマンドを使用してそのライブラリをターゲットにリンクすることができます。

target_link_libraries(mytarget anothertarget)

この方法を使用すると、ライブラリの名前を覚える必要がなく、CMake がライブラリを自動的に検索してくれます。

pkg-config

Unix 系システムでは、pkg-config ツールを使用してライブラリをリンクすることができます。pkg-config は、ライブラリの場所、ヘッダーファイル、リンクフラグなどの情報を提供します。

pkg_config_use_lib(mytarget boost>=1.60)

この方法を使用すると、CMake がシステム上のライブラリを自動的に検出してリンクしてくれます。

手動リンク

上記のいずれの方法も使用できない場合は、ライブラリを手動でリンクすることができます。これには、target_link_libraries コマンドにライブラリのファイルパスとリンクフラグを渡す必要があります。

target_link_libraries(mytarget "/path/to/library.lib" "-L/path/to/library/dir")

この方法は、最も低レベルの方法ですが、他の方法がうまくいかない場合に役立ちます。

最適な方法の選択

使用する方法は、プロジェクトの要件によって異なります。一般的には、以下の指針に従うことをお勧めします。

  • Unix 系システムでは、pkg-config を使用します。
  • ライブラリが CMake プロジェクトの一部として既にビルドされている場合は、target_link_libraries コマンドを使用します。
  • ライブラリが別々のディレクトリに格納されている場合は、add_subdirectory コマンドを使用します。