Compound CMake to enhance. error LNK2005

Looking around all day for a decision, but without joy.

I have a CMake solution with two projects. One of them is a static library that references boost, and the other is an executable that references boost and my own static library. The problem is that on Linux it compiles with gcc. But in VS2008, I get the following linker errors only for 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) 

It looks like it references both the static lib library and the dll lib ... but why?

So, I have a solution catalog with CMakeFile as follows:

  CMAKE_MINIMUM_REQUIRED(VERSION 2.8) PROJECT( BBlockTools ) SET( TopDir ${CMAKE_CURRENT_SOURCE_DIR} ) ADD_SUBDIRECTORY( Utilities ) ADD_SUBDIRECTORY( BBlockFixer ) 

And then two project directories. Utilities are a static library and are created using 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} ) 

And the second project created by this 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} ) 

I am new to CMake, so I can do something really bad, but I really can’t understand what is going on. I started playing with VS Project (Fixer), like removing input links in program_options, which fixes the problem (until I ran cmake again). But I think this is not a solution, because because of how it looks, it for some reason associates with both dll lib and static lib ... I tried to remove $ {Boost_PROGRAM_OPTIONS_LIBRARY} from BBlockFixer from TARGET_LINK_LIBRARIES and program_options from FIND_PACKAGE, but does not help.

From what I understand in CMake, my BBlockFixer inherits links to program_options from my static library, which should be all right. But where is this boost_program_options-vc90-mt-gd-1_46_1.lib (boost_program_options-vc90-mt-gd-1_46_1.dll) related to my project?

Any help would be appreciated because I am becoming desperate. It can't be that hard ...

PS. this TopDir that I installed so that I can include the .h file from Utilities. But I'm sure there should be a cleaner way to do this or?

+6
source share
1 answer

I assume that you are still auto-linking: in MSVC boost uses some pragma to automatically instruct the compiler to link to the required libraries, and then there is no need to specify all link links manually for the linker. Of course, this bites with CMake dependency resolution and manually specifies target_link_libraries.

Take a look at my answer to a similar question , where I suggested the following additional definition to disable auto-binding:

 add_definition( -DBOOST_ALL_NO_LIB ) 

You may need to add the following data during a dynamic connection and depending on the version of Boost and the components:

 add_definitions( -DBOOST_ALL_DYN_LINK ) 

Notice that you specify the Boost components that you want in the find_package () call, and then manually specify them manually in the target_link_libraries () call. You can also replace this with

 target_link_libraries( ${Boost_LIBRARIES} ) 
+7
source

Source: https://habr.com/ru/post/892314/


All Articles