CMake: ターゲットのライブラリ検索ディレクトリを指定する「LINK_DIRECTORIES」を分かりやすく解説
CMake の "Properties: Targets" における "LINK_DIRECTORIES" は、リンカがライブラリを検索するディレクトリのリストを指定するプロパティです。これは、ターゲットが他のライブラリに依存している場合に、リンカがそれらのライブラリを見つけるために使用されます。
使用方法
"LINK_DIRECTORIES" プロパティは、target_link_directories()
コマンドを使用して設定できます。このコマンドは、ターゲットと、そのターゲットがリンクする必要があるライブラリのディレクトリを指定します。
target_link_libraries(my_target PRIVATE my_lib PUBLIC other_lib)
target_link_directories(my_target "/path/to/my_lib" "/path/to/other_lib")
この例では、my_target
ターゲットは my_lib
ライブラリと other_lib
ライブラリに依存しています。target_link_libraries()
コマンドは、これらのライブラリがターゲットにリンクされる必要があることを指定します。target_link_directories()
コマンドは、リンカがこれらのライブラリを見つけるために使用するディレクトリを指定します。
注意事項
"LINK_DIRECTORIES" プロパティは、一般的にはあまり使用されません。これは、find_package()
や find_library()
などのコマンドによって返されるライブラリの場所は、すでに絶対パスであるためです。これらのコマンドを使用してライブラリを見つけた場合は、target_link_libraries()
コマンドに直接これらの絶対パスを渡すだけで済みます。
代替方法
"LINK_DIRECTORIES" プロパティの代わりに、target_link_libraries()
コマンドにライブラリの絶対パスを渡すことをお勧めします。これは、より明確で簡潔なコードになります。
# ライブラリのディレクトリを指定します。
set(MY_LIB_DIR "/path/to/my_lib")
set(OTHER_LIB_DIR "/path/to/other_lib")
# ターゲットを定義します。
add_executable(my_target my_target.cpp)
# ターゲットが依存するライブラリを指定します。
target_link_libraries(my_target PRIVATE my_lib PUBLIC other_lib)
# リンカがライブラリを検索するディレクトリを指定します。
target_link_directories(my_target ${MY_LIB_DIR} ${OTHER_LIB_DIR})
このコードでは、以下のようになります。
target_link_directories()
コマンドを使用して、リンカがmy_lib
ライブラリとother_lib
ライブラリを見つけるために使用するディレクトリを指定します。target_link_libraries()
コマンドを使用して、my_target
ターゲットがmy_lib
ライブラリとother_lib
ライブラリに依存していることを指定します。my_target
ターゲットが定義されます。OTHER_LIB_DIR
変数には、other_lib
ライブラリのディレクトリパスが設定されます。MY_LIB_DIR
変数には、my_lib
ライブラリのディレクトリパスが設定されます。
このコードを実行すると、my_target
という名前の実行ファイルが生成されます。この実行ファイルは、my_lib
ライブラリと other_lib
ライブラリにリンクされます。
以下のコードは、LINK_DIRECTORIES
プロパティを使用せずに、find_package()
コマンドを使用してライブラリを見つける方法を示しています。
# ライブラリを検索します。
find_package(MyLib REQUIRED)
find_package(OtherLib REQUIRED)
# ターゲットを定義します。
add_executable(my_target my_target.cpp)
# ターゲットが依存するライブラリを指定します。
target_link_libraries(my_target MyLib::LIBRARIES OtherLib::LIBRARIES)
target_link_libraries()
コマンドを使用して、my_target
ターゲットがMyLib
ライブラリとOtherLib
ライブラリに依存していることを指定します。my_target
ターゲットが定義されます。OtherLib::LIBRARIES
変数には、OtherLib
ライブラリのライブラリファイルのパスが設定されます。MyLib::LIBRARIES
変数には、MyLib
ライブラリのライブラリファイルのパスが設定されます。find_package()
コマンドを使用して、MyLib
ライブラリとOtherLib
ライブラリを検索します。
find_package() モジュールを使用する
find_package()
モジュールは、CMake に付属のモジュールであり、システムにインストールされているライブラリを自動的に検出することができます。このモジュールを使用すると、LINK_DIRECTORIES
プロパティを手動で設定する必要がなくなり、コードがより簡潔で保守しやすくなります。
find_package(MyLib REQUIRED)
find_package(OtherLib REQUIRED)
add_executable(my_target my_target.cpp)
target_link_libraries(my_target MyLib::LIBRARIES OtherLib::LIBRARIES)
上記の例では、find_package()
モジュールを使用して MyLib
と OtherLib
ライブラリを検索しています。これらのライブラリが見つかると、MyLib::LIBRARIES
と OtherLib::LIBRARIES
変数にそれぞれのライブラリのライブラリファイルへのパスが設定されます。その後、target_link_libraries()
コマンドを使用して、これらの変数をターゲットのリンクライブラリリストに追加しています。
ライブラリの絶対パスを直接指定する
target_link_libraries()
コマンドにライブラリの絶対パスを直接渡すこともできます。この方法は、find_package()
モジュールが目的のライブラリを見つけることができない場合に役立ちます。
add_executable(my_target my_target.cpp)
target_link_libraries(my_target "/path/to/my_lib/libmylib.so" "/path/to/other_lib/libotherlib.so")
上記の例では、my_target
ターゲットが /path/to/my_lib/libmylib.so
と /path/to/other_lib/libotherlib.so
ライブラリファイルにリンクされています。
サブディレクトリを使用する
ライブラリがサブディレクトリに格納されている場合は、サブディレクトリを使用してCMake にライブラリの場所を伝えることができます。
add_subdirectory(my_lib)
add_subdirectory(other_lib)
add_executable(my_target my_target.cpp)
target_link_libraries(my_target MyLib::LIBRARIES OtherLib::LIBRARIES)
上記の例では、add_subdirectory()
コマンドを使用して my_lib
と other_lib
サブディレクトリをビルドしています。これらのサブディレクトリ内に CMakeLists.txt
ファイルがあると、CMake はそのファイルを使用してサブディレクトリ内のライブラリを自動的に検出します。
インクルードディレクトリを指定する
ライブラリのヘッダーファイルがインクルードディレクトリにある場合は、include_directories()
コマンドを使用してそのディレクトリをCMake に伝えることができます。
add_executable(my_target my_target.cpp)
target_include_directories(my_target "/path/to/my_lib/include" "/path/to/other_lib/include")
上記の例では、my_target
ターゲットが /path/to/my_lib/include
と /path/to/other_lib/include
ディレクトリにあるヘッダーファイルにアクセスできるように設定されています。
"LINK_DIRECTORIES" プロパティは、CMake においてライブラリを検索するディレクトリを指定するための代替方法として、上記のような方法が推奨されています。これらの代替方法は、より簡潔で保守しやすいコードを作成するのに役立ちます。
- 上記の例は、あくまでも基本的な例です。実際の状況に応じて、これらの方法を組み合わせて使用することができます。