CMake の LINK_DIRECTORIES と CMAKE_PREFIX_PATH の違い

2024-04-02

CMake の Properties: Targets における LINK_DIRECTORIES の詳細解説

この解説では、以下の内容を詳しく説明します:

  • LINK_DIRECTORIES の役割: リンカにライブラリの場所を伝える
  • 設定方法:
    • link_directories() コマンド
    • target_link_directories() コマンド
    • CMAKE_MODULE_PATH 変数
    • ターゲットプロパティファイル
  • 動作の詳細:
    • 複数のディレクトリ指定
    • 検索順序
    • キャッシュと再利用
    • 相対パスと絶対パス
  • Generator Expressions の利用:
    • 条件分岐によるディレクトリ指定
    • 変数や環境変数による動的なディレクトリ指定
  • その他の関連情報:
    • LINK_INTERFACE_DIRECTORIES プロパティ
    • list() コマンド
    • get_property() コマンド
  • トラブルシューティング:
    • ライブラリが見つからない場合
    • シンボルが見つからない場合
  • 参考資料:
    • CMake 公式ドキュメント
    • チュートリアル
    • 書籍

LINK_DIRECTORIES は、ターゲットがリンクする必要がある共有ライブラリや静的ライブラリを見つけるためのディレクトリをリンカに伝えます。これは、以下の状況で特に重要になります:

  • ライブラリが標準の場所にインストールされていない場合: 多くの場合、サードパーティ製のライブラリは標準の場所にインストールされていないため、LINK_DIRECTORIES を使用してその場所を指定する必要があります。
  • プロジェクト内でライブラリを共有する場合: プロジェクト内で作成したライブラリを他のターゲットで使用したい場合は、LINK_DIRECTORIES を使用してそのライブラリの場所を指定する必要があります。

設定方法

LINK_DIRECTORIES は、以下の方法で設定することができます:

1 link_directories() コマンド

これは、LINK_DIRECTORIES を設定する最も一般的な方法です。以下の例のように、ディレクトリをカンマ区切りで指定します:

link_directories(/usr/local/lib, /path/to/other/lib)

2 target_link_directories() コマンド

このコマンドは、特定のターゲットにのみ LINK_DIRECTORIES を設定するために使用されます。以下の例のように、ターゲット名とディレクトリを指定します:

target_link_directories(my_target PUBLIC /usr/local/lib)

CMAKE_MODULE_PATH 変数は、CMake モジュールを探すためのディレクトリを指定するために使用されますが、LINK_DIRECTORIES を設定するためにも使用できます。以下の例のように、ディレクトリをカンマ区切りで指定します:

set(CMAKE_MODULE_PATH /usr/local/lib, /path/to/other/lib)

ターゲットプロパティファイルを使用して、LINK_DIRECTORIES を設定することもできます。以下の例のように、LINK_DIRECTORIES プロパティにディレクトリを指定します:

set_target_properties(my_target PROPERTIES LINK_DIRECTORIES /usr/local/lib)

動作の詳細

1 複数のディレクトリ指定

LINK_DIRECTORIES には、複数のディレクトリをカンマ区切りで指定することができます。リンカは、これらのディレクトリを指定された順序で検索します。

2 検索順序

リンカは、以下の順序でライブラリを検索します:

  1. LINK_DIRECTORIES で指定されたディレクトリ
  2. ターゲットの依存関係にあるターゲットの LINK_DIRECTORIES
  3. システムのデフォルトのライブラリ検索パス

3 キャッシュと再利用

LINK_DIRECTORIES で設定されたディレクトリは、CMake キャッシュに保存されます。そのため、次回ビルドを行う



CMake の LINK_DIRECTORIES に関するサンプルコード

基本的なサンプル

# ターゲット "my_exe" に対して、"/usr/local/lib" と "/path/to/other/lib" をライブラリ検索ディレクトリとして指定
target_link_directories(my_exe PUBLIC /usr/local/lib /path/to/other/lib)

# 全てのターゲットに対して、"/usr/local/lib" をライブラリ検索ディレクトリとして指定
link_directories(/usr/local/lib)

# CMAKE_MODULE_PATH 変数を使用して、"/usr/local/lib" と "/path/to/other/lib" をライブラリ検索ディレクトリとして指定
set(CMAKE_MODULE_PATH /usr/local/lib /path/to/other/lib)

条件分岐によるディレクトリ指定

# 条件分岐によって、異なるディレクトリを指定
if(WIN32)
  link_directories(/usr/local/lib/win32)
else()
  link_directories(/usr/local/lib/linux)
endif()

変数や環境変数による動的なディレクトリ指定

# 変数を使用して、ライブラリの場所を動的に指定
set(lib_dir "/usr/local/lib")

link_directories(${lib_dir})

# 環境変数を使用して、ライブラリの場所を動的に指定
link_directories(${ENV{LIBRARY_PATH}})

その他のサンプル

  • ターゲットプロパティファイルを使用する:
set(target_name "my_target")

set_target_properties(${target_name} PROPERTIES LINK_DIRECTORIES /usr/local/lib)
  • 複数のターゲットに対して同時に設定する:
foreach(target IN my_targets)
  target_link_directories(${target} PUBLIC /usr/local/lib)
endforeach()
  • list() コマンドを使用して、ディレクトリのリストを生成する:
set(lib_dirs)

list(APPEND lib_dirs /usr/local/lib)
list(APPEND lib_dirs /path/to/other/lib)

link_directories(${lib_dirs})
  • get_property() コマンドを使用して、ターゲットの LINK_DIRECTORIES プロパティを取得する:
get_property(target_dirs TARGET my_target PROPERTY LINK_DIRECTORIES)

message("Target 'my_target' has the following library search directories: ${target_dirs}")

注意点

  • LINK_DIRECTORIES で指定されたディレクトリが存在しない場合、リンカはエラーを出力します。
  • ライブラリの名前は、リンカによって異なります。詳細は、リンカのマニュアルを参照してください。


CMake の LINK_DIRECTORIES を設定するその他の方法

CMAKE_PREFIX_PATH 変数は、ライブラリやヘッダーファイルを含むディレクトリを指定するために使用されます。LINK_DIRECTORIES は CMAKE_PREFIX_PATH の値を自動的に使用するため、以下のように CMAKE_PREFIX_PATH を設定することで、LINK_DIRECTORIES を設定することができます:

set(CMAKE_PREFIX_PATH /usr/local)

# "my_target" は "/usr/local/lib" 以下にあるライブラリとリンク
target_link_libraries(my_exe my_library)

インストール済みパッケージの利用

多くの場合、ライブラリはパッケージマネージャーを使用してインストールされます。CMake はこれらのパッケージを自動的に検出し、LINK_DIRECTORIES を設定することができます。

例:

  • Debian/Ubuntu:
find_package(PkgConfig REQUIRED)
pkg_check_modules(PC_LIBRARY REQUIRED libmylibrary)

target_link_libraries(my_exe PUBLIC ${PC_LIBRARY_LIBDIR})
  • Fedora/CentOS:
find_package(PkgConfig REQUIRED)
pkg_check_modules(PC_LIBRARY REQUIRED libmylibrary)

target_link_libraries(my_exe PUBLIC ${PC_LIBRARY_LIBDIR})
  • Mac:
find_package(Cocoa REQUIRED)
find_package(MacPorts REQUIRED)

target_link_libraries(my_exe PUBLIC ${COCOA_LIBRARY_DIR} ${MACPORTS_LIBRARY_DIR})

外部モジュールの利用

CMake には、LINK_DIRECTORIES を設定するための外部モジュールが多数存在します。例:

これらのモジュールは、特定のライブラリやフレームワークを検出し、LINK_DIRECTORIES を含む必要な情報を提供します。

手動による設定

上記の方法でうまくいかない場合は、手動で LINK_DIRECTORIES を設定することができます。

例:

set(lib_dir "/path/to/my/library")

link_directories(${lib_dir})

# "my_target" は "/path/to/my/library" 以下にあるライブラリとリンク
target_link_libraries(my_exe my_library)

上記の情報に加えて、特定の状況や環境に合わせた情報が必要な場合は、Google 検索や CMake フォーラムなどを活用して情報収集を行うことをお勧めします。




CMake で変数を削除する3つの方法:unset() 以外にも使えるテクニック

<variable_name> は、削除したい変数の名前です。変数の名前は、文字、数字、下線(_)で構成され、先頭に数字以外のアクティブ文字が来る必要があります。変数の削除この例では、MY_VAR という変数を作成し、"Hello, world!" という値を設定します。その後、unset() コマンドを使用して MY_VAR を削除します。2番目の message() コマンドは、MY_VAR が削除されたことを確認するために使用されます。



CMakeのCommandsにおけるuse_mangled_mesa()

use_mangled_mesa() は CMake の Commands における関数で、Mesa ライブラリの mangled シンボル名を解決するために使用されます。Mesa は OpenGL の実装であり、古いバージョンの Mesa ではシンボル名が mangled されるため、use_mangled_mesa() を使用してこれらのシンボル名を解決する必要があります。


CMakeコマンド mark_as_advanced() の詳細解説

mark_as_advanced() は、CMakeプロジェクトで特定のキャッシュ変数を "詳細設定" としてマークするために使用されるコマンドです。このコマンドによって、GUI ツールでこれらの変数はデフォルトでは表示されなくなり、ユーザーは "詳細設定" オプションを有効にするまで編集できなくなります。


CMake try_compile() を使って特定のライブラリがインストールされているかどうかを確認する方法

try_compile() は、CMake の強力なコマンドの一つで、コードを実際にコンパイルすることなく、コンパイルが成功するかどうかを確認することができます。これは、特定のコンパイラやオプションがシステム上で使用可能かどうかをテストしたり、コードの移植性を検証したりする際に非常に便利です。


プログラミング初心者でもわかる!CMake の "set_directory_properties()" コマンドの使い方

set_directory_properties() コマンドは、CMakeプロジェクト内のディレクトリとサブディレクトリにプロパティを設定するために使用されます。これらのプロパティは、ビルドプロセス、インストール、その他の CMake 動作を制御するために使用できます。



C++ソースコードの動作検証:CheckCXXSourceRuns vs その他の方法

CheckCXXSourceRuns は、CMake のモジュールの一つで、C++ ソースコードが正しくコンパイルされ、実行できるかどうかを確認するために使用されます。これは、プロジェクトで必要な機能がサポートされているかどうか、または特定のコンパイラオプションが正しく動作するかどうかを検証するのに役立ちます。


CTEST_CUSTOM_MAXIMUM_NUMBER_OF_WARNINGS のその他の設定方法

CTEST_CUSTOM_MAXIMUM_NUMBER_OF_WARNINGS は CMake の変数で、テスト実行中に検出される警告の最大数を制御します。デフォルト値は 50 で、この値を超えると ctest_test() コマンドの出力が切り捨てられます。


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

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


CMakeプロジェクトの利便性を向上させる: "CMAKE_PROJECT_DESCRIPTION"変数の活用事例

CMAKE_PROJECT_DESCRIPTION 変数は、CMakeプロジェクトの説明を格納する変数です。これは、project() コマンドを使用してトップレベルの CMakeLists. txt ファイルで設定されます。複数の project() コマンドが存在する場合、最も最近呼び出されたものが有効になります。


CMAKE_XCODE_SCHEME_ZOMBIE_OBJECTSの詳細解説

CMAKE_XCODE_SCHEME_ZOMBIE_OBJECTS は、CMake 3.13 で導入された変数です。これは、Xcode プロジェクトで生成されるスキームの 診断 セクションにおける ゾンビオブジェクト の有効化を制御します。