2011-07-08 16 views
6

解決策はありますが、喜びはありません。CMakeをブーストにリンクする。エラーLNK2005

私は2プロジェクトのCMakeソリューションを持っています。 1つはboostにリンクする静的ライブラリで、もう1つはboostと自分の静的ライブラリにリンクする実行可能ファイルです。 問題:Linuxでは、gccでうまくコンパイルできません。しかし、VS2008では、私はprogram_optionsのためだけに以下のタイプのリンカエラーを取得します。

libboost_program_options-vc90-mt-gd-1_46_1.lib(options_description.obj) : error LNK2005: "public: class boost::program_options::options_description_easy_init & __thiscall boost::program_options::options_description_easy_init::operator()(char const *,char const *)" ([email protected][email protected]@@[email protected]@Z) already defined in boost_program_options-vc90-mt-gd-1_46_1.lib(boost_program_options-vc90-mt-gd-1_46_1.dll) 

静的ライブラリとDLLライブラリの両方にリンクしているようですが、なぜですか?

だから私はこのようにCMakeFileとソリューションのディレクトリを持っている:

CMAKE_MINIMUM_REQUIRED(VERSION 2.8) 
    PROJECT(BBlockTools) 

    SET(TopDir ${CMAKE_CURRENT_SOURCE_DIR}) 
    ADD_SUBDIRECTORY(Utilities) 
    ADD_SUBDIRECTORY(BBlockFixer) 

そして、2つのプロジェクトのディレクトリ。ユーティリティ静的ライブラリで、CMakeFileに従うことによって作成されます。

PROJECT(Utilities) 

SET(Boost_USE_STATIC_LIBS ON) 
FIND_PACKAGE(Boost COMPONENTS system program_options REQUIRED) 
LINK_DIRECTORIES (${Boost_LIBRARY_DIRS}) 
INCLUDE_DIRECTORIES (${Boost_INCLUDE_DIRS}) 

SET(src_h Utilities.h) 
SET(src_cpp Utilities.cpp) 

ADD_LIBRARY(Utilities STATIC ${src_h} ${src_cpp}) 

TARGET_LINK_LIBRARIES(Utilities 
    ${Boost_SYSTEM_LIBRARY} 
    ${Boost_PROGRAM_OPTIONS_LIBRARY} 
    ${Boost_LIBRARIES} 
) 

そして、このCMakeFileによって作成された第二のプロジェクト:

PROJECT(BBlockFixer) 

SET(Boost_USE_STATIC_LIBS ON) 
FIND_PACKAGE(Boost COMPONENTS system filesystem program_options REQUIRED) 
LINK_DIRECTORIES (${BBlockTools_BINARY_DIR}/Utilities/Debug ${Boost_LIBRARY_DIRS}) 
INCLUDE_DIRECTORIES (${TopDir} ${Boost_INCLUDE_DIRS}) 

SET(src_cpp fixerMain.cpp) 

ADD_EXECUTABLE(BBlockFixer ${src_cpp}) 

TARGET_LINK_LIBRARIES(BBlockFixer 
    Utilities 
    ${Boost_FILESYSTEM_LIBRARY} 
    ${Boost_PROGRAM_OPTIONS_LIBRARY} 
    ${Boost_SYSTEM_LIBRARY} 
    ${Boost_LIBRARIES} 
) 

私はCMakeのに新たなんだので、私は非常に悪い何かをやっているかもしれないが、私は本当に何が起こっているのか分からない。私は問題を解決するprogram_optionsへのリンク入力を取り除く(私が再びcmakeを実行するまで)ように、VSプロジェクト(Fixer)を使い始めました。しかし、私は解決策ではないと思っています。なぜなら、それは何らかの理由でDLLライブラリと静的ライブラリの両方にリンクしているように見えるからです... FARD_PACKAGEからTARGET_LINK_LIBRARIESおよびprogram_optionsからBBlockFixerから$ {Boost_PROGRAM_OPTIONS_LIBRARY}を削除しようとしましたが、助けて。

私がCMakeで理解しているところから、私のBBlockFixerは静的なlibのprogram_optionsへのリンクを継承しています。しかし、このboost_program_options-vc90-mt-gd-1_46_1.lib(boost_program_options-vc90-mt-gd-1_46_1.dll)は私のプロジェクトにどこにリンクされましたか?

私は絶望的になっているので、助けていただければ幸いです。それほど難しいことではありません...

PS。私が設定したTopDirは、ユーティリティからの.hファイルを含めることができるように設定されています。しかし、私はそれを行うためのよりクリーンな方法がなければならないと確信していますか?

答えて

7

私はMSVCでは、いくつかのプラグマを使用して自動的にコンパイラに必要なライブラリへのリンクを指示し、すべてのリンク先を手動でリンカに指定する必要はありません。もちろん、これはCMakeの依存性解決に噛み、target_link_librariesを手動で指定します。

私は自動リンクを無効にするには、次の追加の定義を示唆したところ、私のanswer to a similar questionを見てみましょう:

add_definition(-DBOOST_ALL_NO_LIB) 

あなたが動的にリンクするとブーストのバージョンおよびコンポーネントに依存する場合は、次を追加する必要があります。

add_definitions(-DBOOST_ALL_DYN_LINK) 

も注意してください、あなたはfind_package()の呼び出しにしたいブーストコンポーネントを指定して、()の呼び出しあなたのtarget_link_librariesに再度手動でそれらを指定すること。必要に応じて、これに置き換えることもできます。

target_link_libraries(${Boost_LIBRARIES}) 
+0

ありがとうございます! 1秒前に私は、動的ライブラリをboost libsフォルダから移動することでこの問題を解決しました。 私が気づいたのは、静的ライブラリにリンクするように言ったとしても、cmake(FindBoost.cmake?)はそのフォルダ内の動的ライブラリしか見つけられませんでした。動的なものを最初に見つけたらそれを選択することが優先されるようです。 Linuxで明らかに私はboostの静的ライブラリしか持っていなかったので、衝突が発生しません。 これは、あなたが私にオートリンクについて教えてくれたことの効果ですか? 私は今、自動リンクを無効にしようとします:) ありがとう、Stefan – Stefan

+0

私はCMakeListファイルの3つすべてにadd_definitions(-DBOOST_ALL_NO_LIB)を入れてみましたが、CMakeがダイナミックライブラリを好むという事実は変更しませんでした。私はブーストlibフォルダから動的なlibsを動かすことに固執すると思います – Stefan

+0

Oho !!!私は実際にあなたから私のソリューションに他のプロジェクトもあったという事実を隠していました。それらの中には、SET(Boost_USE_STATIC_LIBS ON)を置くことを忘れていたものもありました。何らかの理由で、cmakeは、すべてのプロジェクトに対してconfig atステップの代わりに動的ライブラリを選択するようにしました。すばらしいです。今はどこにでも置いてもいいよ。 – Stefan

関連する問題