web-dev-qa-db-ja.com

CMake-ExternalProject_add()からダウンロードされたライブラリへのリンク

ExternalProject_add()を使用して依存関係をダウンロード/インストールしようとしています。インストールはうまくいきますが、ダウンロードしたライブラリを実際にリンクする方法がわかりません。

ダウンロードしたばかりのライブラリでtarget_link_libraries()を呼び出したいのですが、ライブラリへのパスはシステムによって異なります。

これがシステムの依存関係である場合、find_package()を呼び出すだけで済みますが、パッケージはデフォルトの検索パスにインストールされていません。モジュールモードでfind_packageの検索パスを指定できないと思います。

動作しないCMakeLists.txtのスニペットを次に示します。

ExternalProject_Add(
protobuf
URL http://protobuf.googlecode.com/files/protobuf-2.4.1.tar.gz
CONFIGURE_COMMAND <SOURCE_DIR>/configure --prefix=<INSTALL_DIR>
PREFIX ${MYPROJ_SOURCE_DIR}/dependencies
)
find_package(protobuf REQUIRED)
set(LIBS ${LIBS} ${PROTOBUF_LIBRARIES})
target_link_libraries (mybinary ${LIBS})
48
Brett Thomas

ExternalProject_Addを使用している場合は、CMakeを実行して外部プロジェクトを構成するときに何も検出されないため、find_packageを使用できません。

したがって、ライブラリの場所がプラットフォームによって異なる場合は、プラットフォームに基づいた条件付きロジックが必要になります。 (ここではprotobufのライブラリや構造がわからないので、これは単なる例ですが、正しい方向に進むはずです...)次のようなもの:

if(WIN32)
  set(PROTOBUF_LIB_DIR "${MYPROJ_SOURCE_DIR}/dependencies/win"
  set(prefix "")
  set(suffix ".lib")
elseif(Apple)
  set(PROTOBUF_LIB_DIR "${MYPROJ_SOURCE_DIR}/dependencies/mac"
  set(prefix "lib")
  set(suffix ".a")
else()
  set(PROTOBUF_LIB_DIR "${MYPROJ_SOURCE_DIR}/dependencies/linux"
  set(prefix "lib")
  set(suffix ".a")
endif()

set(PROTOBUF_LIBRARIES
  "${PROTOBUF_LIB_DIR}/${prefix}protobufLib1${suffix}"
  "${PROTOBUF_LIB_DIR}/${prefix}protobufLib2${suffix}")

確かに、これはfind_packageを使用するよりも便利ではありません。ビルド済み/インストール済みのパッケージを使用できる場合は、find_packageを使用できるようにする必要があります。ただし、プロジェクトの一部としてソースコードから他のパッケージをビルドする必要がある場合、ExternalProject_Addは、すべての詳細を抽象化することはできませんが、便利です。

19
DLRdave

外部プロジェクトをダウンロードしているので、ダウンロードしたばかりなので、どこにあるのかすでにわかっているので、「検索」する必要はありません。

私はそれをadd_libraryで動作させました。これは私の実際のコードです:

ExternalProject_Add(ForexConnectDownload
    PREFIX 3rd_party
    #--Download step--------------
    URL http://fxcodebase.com/bin/forexconnect/1.3.1/ForexConnectAPI-1.3.1-Linux-x86_64.tar.gz
    URL_HASH SHA1=7fdb90a2d45085feb8b76167cae419ad4c211d6b
    #--Configure step-------------
    CONFIGURE_COMMAND ""
    #--Build step-----------------
    BUILD_COMMAND ""
    #--Install step---------------
    UPDATE_COMMAND "" # Skip annoying updates for every build
    INSTALL_COMMAND ""
)

SET(FXCM_INCLUDE_DIR ${CMAKE_CURRENT_BINARY_DIR}/3rd_party/src/ForexConnectDownload/include)
SET(FXCM_LIB_DIR ${CMAKE_CURRENT_BINARY_DIR}/3rd_party/src/ForexConnectDownload/lib)

add_library(ForexConnect SHARED IMPORTED)
set_target_properties(ForexConnect PROPERTIES IMPORTED_LOCATION ${FXCM_LIB_DIR}/libForexConnect.so)

そこから、それに依存する各プログラムにはadd_dependencies そしてもちろん target_link_libraries。例えば:

include_directories(${FXCM_INCLUDE_DIR})
add_executable(syncDatabase syncDatabase.cpp trader/database.cpp trader/fxcm.cpp)
target_link_libraries(syncDatabase ForexConnect)
add_dependencies(syncDatabase ForexConnectDownload)
  • include_directories-ディレクトリを検索するように指示します
  • target_link_libraries-名前を付けたとおりにライブラリを追加します(変数ではありません)

Add_dependenciesは、必要なディレクトリを含める前に待機させます。

それは私にとってはトリックです。 make -j4で動作します。すべての依存関係を正しく取得します。

22
matiu

上記のDLRdaveの回答を拡張するには、CMAKEが各プラットフォームに適切な変数を提供するため、静的ライブラリの接頭辞と接尾辞を手動で設定する必要はありません。

詳細については、 CMake有用な変数 を参照してください。

例えば:

  • CMAKE_SHARED_LIBRARY_PREFIX
  • CMAKE_SHARED_LIBRARY_SUFFIX
  • CMAKE_STATIC_LIBRARY_PREFIX
  • CMAKE_STATIC_LIBRARY_SUFFIX
18
aled

この問題を解決するために使用できる別のイディオム:

  1. Find_packageコマンドをオプションにします(「必須」を削除します)
  2. Find_packageが成功した場合にのみターゲットをビルドする条件コードを追加します。
  3. find_packageは失敗し、ターゲットは最初はビルドされませんが、外部プロジェクトはビルドされます。
  4. Cmake/makeを再度実行します。今回はfind_packageが成功し、ターゲットがビルドされます。

このイディオムの動作は https://github.com/biometrics/likely で確認できます。

4
jklontz

link_directoriesコマンドを使用して、特定のディレクトリ内のライブラリをリンクできます。あなたの場合、ディレクトリは外部プロジェクトがビルドされたものでした。

ExternalProject_Add(MyExternalLibrary ...)

出力ディレクトリを検索パスに追加します。

link_directories(${CMAKE_BINARY_DIR}/lib/MyExternalLibrary-prefix/lib)

リンクディレクトリを指定して、実行可能ファイルafterを必ず追加してください。

add_executable(MyProgram main.c)

プロジェクトをリンクするライブラリを指定します。

target_link_libraries(MyProgram ExternalLibraryName)

外部プロジェクトに依存することを忘れないでください:

add_dependencies(MyProgram MyExternalLibrary)
4
joke