2012-01-08 17 views
77

同じCMakeプロジェクト内でビルドされていない外部共有ライブラリに実行可能ファイルをリンクする方法を教えてください。私は、バイナリディレクトリbin/resにライブラリをコピーした後外部ライブラリへのCMakeリンク

だけでやってtarget_link_libraries(GLBall ${CMAKE_BINARY_DIR}/res/mylib.so)はエラーに

make[2]: *** No rule to make target `res/mylib.so', needed by `GLBall'. Stop. 
make[1]: *** [CMakeFiles/GLBall.dir/all] Error 2 
make: *** [all] Error 2 
(GLBall is the executable) 

を与えます。

私はRESULT-NOTFOUNDで失敗find_library(RESULT mylib.so PATHS ${CMAKE_BINARY_DIR}/res)

を使用してみました。

答えて

67

セットライブラリは、最初のパスを検索します。

LINK_DIRECTORIES(${CMAKE_BINARY_DIR}/res) 

をそしてちょうど行う

TARGET_LINK_LIBRARIES(GLBall mylib) 
+0

ありがとうございます! – Prime

+22

['link_directories'](http://www.cmake.org/cmake/help/v2.8.10/cmake.html#command:link_directories)の使用は、それ自身のドキュメントであってもお勧めしません。元の質問で失敗した 'find_library'呼び出しを解決するか、@ Andreの解決策を使う方が良いと思います。 – Fraser

+3

は、私はそれが特定のライブラリの場所を対象として、「インポート」ライブラリの対象ではなく、単にグローバルな検索パスを与える、より堅牢であることがわかりました。アンドレの答えを見てください。 –

79

arrowdodgerの答えが正しいと多くの場面で有利です。私は単に彼の答えの代替を追加する:

リンクディレクトリではなく、 "インポートされた"ライブラリターゲットを追加することができます。ような何か:

# Your-external "mylib", add GLOBAL if the imported library is located in directories above the current. 
add_library(mylib SHARED IMPORTED) 
# You can define two import-locations: one for debug and one for release. 
set_target_properties(mylib PROPERTIES IMPORTED_LOCATION ${CMAKE_BINARY_DIR}/res/mylib.so) 

そして、このライブラリはプロジェクトにより建設されたかのようにリンクされています

TARGET_LINK_LIBRARIES(GLBall mylib) 

このようなアプローチはあなたにもう少し柔軟性を与えるだろう:add_library()コマンドを見て、 many target-properties related to imported libraries

これは、「アップデートされたバージョンのlibs」で問題が解決するかどうかわかりません。

+2

' は、またはあなたが'インポート引数が、type'がエラー – Marvin

+1

@Marvinなしライブラリと呼ばれるadd_library取得しますオープニングブラケットはあなたが現在より上のディレクトリにインポートされたライブラリにアクセスしたい場合は、IMPORTED' '後'はGlobal'を追加する必要が –

+4

@Andre:私は後だと思う 'IMPORTED_LOCATION'おそらく ' add_library(MYLIB SHAREDインポート)だろう – Ela782

3

もう1つの選択肢として、Appstoreで作業している場合は、「エンタイトルメント」が必要であり、アップルフレームワークとリンクする必要があります。

資格が動作する場合(GameCenterなど)、にはが必要です。「ライブラリでバイナリをリンク」ビルドステップを実行し、「GameKit.framework」にリンクする必要があります。 CMakeはライブラリを "低レベル"でコマンドラインに "注入"するので、Xcodeはを実際にはと知らないので、ではありません。 Capabilities画面でGameKitを有効にします。

CMakeを使って "Link with Binaries"ビルドステップを行う方法の1つは、CMakeでxcodeprojを生成し、 'sed'を使って '&を検索'し、Xcodeが好きなようにGameKitを追加することです。 ..

スクリプトは次のようになります(Xcode 6.3.1用)。

s#\/\* Begin PBXBuildFile section \*\/#\/\* Begin PBXBuildFile section \*\/\ 
    26B12AA11C10544700A9A2BA \/\* GameKit.framework in Frameworks \*\/ = {isa = PBXBuildFile; fileRef = 26B12AA01C10544700A9A2BA \/\* GameKit.framework xxx\*\/; };#g 

s#\/\* Begin PBXFileReference section \*\/#\/\* Begin PBXFileReference section \*\/\ 
    26B12AA01C10544700A9A2BA \/\* GameKit.framework xxx\*\/ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = GameKit.framework; path = System\/Library\/Frameworks\/GameKit.framework; sourceTree = SDKROOT; };#g 

s#\/\* End PBXFileReference section \*\/#\/\* End PBXFileReference section \*\/\ 
\ 
\/\* Begin PBXFrameworksBuildPhase section \*\/\ 
    26B12A9F1C10543B00A9A2BA \/\* Frameworks \*\/ = {\ 
     isa = PBXFrameworksBuildPhase;\ 
     buildActionMask = 2147483647;\ 
     files = (\ 
      26B12AA11C10544700A9A2BA \/\* GameKit.framework in Frameworks xxx\*\/,\ 
     );\ 
     runOnlyForDeploymentPostprocessing = 0;\ 
    };\ 
\/\* End PBXFrameworksBuildPhase section \*\/\ 
#g 

s#\/\* CMake PostBuild Rules \*\/,#\/\* CMake PostBuild Rules \*\/,\ 
      26B12A9F1C10543B00A9A2BA \/\* Frameworks xxx\*\/,#g 
s#\/\* Products \*\/,#\/\* Products \*\/,\ 
      26B12AA01C10544700A9A2BA \/\* GameKit.framework xxx\*\/,#g 

このようにそれを「適用」し、「gamecenter.sed」し、これを保存し、(それはあなたのxcodeprojを変える!)

sed -i.pbxprojbak -f gamecenter.sed myproject.xcodeproj/project.pbxproj 

あなたのニーズに合うようにスクリプトコマンドを変更する必要があります。

警告:プロジェクトフォーマットが変更される可能性があるため、別のXcodeバージョンでは破損する可能性があります(ハードコードされた固有の番号は本当にユニークではありません)。 Appstore +エンタイトルメント(および自動ビルド)をサポートしていますが、これはしないでください。

これはCMakeのバグで、私はあなたがFOOと呼ばれるライブラリにリンクするとしhttp://cmake.org/Bug/view.php?id=14185http://gitlab.kitware.com/cmake/cmake/issues/14185

+0

特に、cmakeを外部ライブラリにリンクさせることは問題ではありません(上記の解決方法がいくつかあります)。これを自動化して、Apple Appstore *と*の資格で動作させることは難しい課題です。その特定のケースでは、XCodeはそのようにリンクされたライブラリを「認識」しないため、上記の解決策は機能しません。また、資格はうまく機能しません。 Afcodeのcmakeは、xcodeが 'アプリストアと互換性のある方法'で必要とするように、libariesを追加することはできません。私を教えてください。 – kalmiya

+1

は、ここであなたが行く:https://cmake.org/Bug/view.php?id=14185、私は一年前のことを投稿しました。 – kalmiya

+1

ああ、それは悲しい。完全を期すため、現在のところcommnetsを含まないない新しい問題追跡へのリンク:https://gitlab.kitware.com/cmake/cmake/issues/14185 – usr1234567

24

を参照してください、そのファイル名は通常、リンクfoo.dllまたはlibfoo.soものです。

1.ライブラリを見つける
ライブラリを見つける必要があります。ライブラリへのパスが分かっていても、これは良い考えです。ライブラリが消えたり、新しい名前がついたりすると、CMakeはエラーになります。これは、早期にエラーを発見し、問題を引き起こす原因をユーザーに(自分自身で)明らかにするのに役立ちます。 cmakeのは、実際のファイル名がどのように自分自身を把握しますライブラリのfooを見つけ、

find_library(FOO_LIB foo) 

FOO_LIB使用中のパスを格納する
/usr/lib/usr/lib64などの通常の場所と、PATHのパスをチェックします。

あなたはすでにあなたのライブラリの場所を知っています。それをCMAKE_PREFIX_PATHに追加してください。あなたがCMakeを呼び出すと、渡されたパスであなたのライブラリを探します。

時にはあなたが詳細については、マニュアルを参照して、ヒントやパスサフィックスを追加する必要があります。 https://cmake.org/cmake/help/latest/command/find_library.html

2.リンクあなたがFOO_LIBで完全なライブラリ名を持っているから1.ライブラリ を。あなたは、参照、あなたが図書館の前でPRIVATEPUBLIC、またはINTERFACEを追加したい場合があります

target_link_libraries(mylib "${FOO_LIB}") 

のようにターゲット mylibにライブラリをリンクするためにこれを使用しますドキュメント:あなたも、ヘッダファイルをインクルード find_libraryに似 find_pathを使用して、ヘッダファイルを検索したい場合は https://cmake.org/cmake/help/latest/command/target_link_libraries.html

3. [追加]を(。このステップは必須ではありませんかもしれません)
が含まれています。次に、target_link_librariesに似たtarget_include_directoriesのインクルードディレクトリを追加します。

ドキュメント: https://cmake.org/cmake/help/latest/command/find_path.htmlhttps://cmake.org/cmake/help/latest/command/target_include_directories.html

外部ソフトウェアで利用可能な場合は、find_packageによってfind_libraryfind_pathを置き換えることができます。

+2

私見ではこれが最善の答えです。しかし、 "project"の後に "find_library"、 "add_executable"の後に "target_link_libraries"を呼んでいなかったので、私は問題がありました。 – smoothware

関連する問題