整天都在寻找解决方案,但没有快乐。
我有一个包含2个项目的CMake解决方案。一个是链接到boost的静态库,另一个是链接到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 *)" (??Roptions_description_easy_init@program_options@boost@@QAEAAV012@PBD0@Z) already defined in boost_program_options-vc90-mt-gd-1_46_1.lib(boost_program_options-vc90-mt-gd-1_46_1.dll)
看起来它链接到静态lib和dll lib ...但为什么?
所以我有一个像这样的CMakeFile的解决方案目录:
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
PROJECT( BBlockTools )
SET( TopDir ${CMAKE_CURRENT_SOURCE_DIR} )
ADD_SUBDIRECTORY( Utilities )
ADD_SUBDIRECTORY( BBlockFixer )
然后是两个项目目录。 Utilities是一个静态库,通过跟随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的新手,所以我可能会做一些非常糟糕的事情,但我真的无法知道发生了什么。我开始玩VS Project(Fixer),比如删除对program_options的链接输入来修复问题(直到我再次运行cmake)。但我认为这不是解决方案,因为它看起来是由于某种原因链接到dll lib和静态lib ... 我尝试从TARGET_LINK_LIBRARIES中删除BBlockFixer中的$ {Boost_PROGRAM_OPTIONS_LIBRARY}和FIND_PACKAGE中的program_options,但没有帮助。
根据我在CMake中的理解,我的BBlockFixer从我的静态库继承了program_options的链接,应该没问题。但是这个boost_program_options-vc90-mt-gd-1_46_1.lib(boost_program_options-vc90-mt-gd-1_46_1.dll)在哪里被链接到我的项目中?
任何帮助都会受到赞赏,因为我变得绝望了。真的不是那么难......
PS。我设置的TopDir是这样的,我可以在Utilities中包含.h文件。但我确信必须有一个更清洁的方法来做或者?
答案 0 :(得分:7)
我的猜测是你仍然在自动链接:在MSVC上,boost使用一些pragma来自动指示编译器链接到必要的库,然后不需要手动指定链接器的所有链接目标。当然,这与CMake的依赖性解析相关,并且您手动指定了target_link_libraries。
请查看我的answer to a similar question,其中我建议使用以下额外定义来禁用自动链接:
add_definition( -DBOOST_ALL_NO_LIB )
在动态链接时,您可能需要添加以下内容,具体取决于Boost版本和组件:
add_definitions( -DBOOST_ALL_DYN_LINK )
另请注意,您在find_package()调用中指定了所需的Boost组件,然后在target_link_libraries()调用中再次手动指定它们。根据您的需要,您也可以用
替换它target_link_libraries( ${Boost_LIBRARIES} )