CMake linking to boost. error LNK2005 - c++

Been looking around all day for a solution but no joy.
I have a CMake solution with 2 projects. The one is a static library which links to boost, and the other is an executable which links to boost and my own static library.
Problem is: In Linux it compiles fine with gcc. But in VS2008 I get the following type of linker errors for program_options only.
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)
Looks like it's linking to both the static lib and the dll lib...but why?
So I have a solution directory with a CMakeFile like this:
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
PROJECT( BBlockTools )
SET( TopDir ${CMAKE_CURRENT_SOURCE_DIR} )
ADD_SUBDIRECTORY( Utilities )
ADD_SUBDIRECTORY( BBlockFixer )
And then the two project directories. Utilities is a static library and is created by following 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'm new to CMake so I might be doing something very bad but I really can't find out what's going on. I started playing around with the VS Project(Fixer) like removing the link input to program_options which fixes the problem(until I run cmake again). But I think that isn't the solution since from how it looks it's linking both to the dll lib and to the static lib for some reason...
I tried removing ${Boost_PROGRAM_OPTIONS_LIBRARY} from BBlockFixer from TARGET_LINK_LIBRARIES and program_options from FIND_PACKAGE but doesnt help.
From what I understand in CMake my BBlockFixer inherits the links to program_options from my static lib which should be all fine. But where did this boost_program_options-vc90-mt-gd-1_46_1.lib(boost_program_options-vc90-mt-gd-1_46_1.dll) get linked into my project?
Any help would be appreciated because I'm becoming desperate. It can't really be that hard...
PS. this TopDir I set is so that I can include the .h file from the Utilities. But I'm sure there must be a cleaner way to do it or?

My guess is that you are still auto-linking: On MSVC, boost uses some pragma's to automically instruct the compiler to link to the necessary libraries and there is then no need to specify all the link-targets manually to the linker. Of course, this bites with the dependency-resolution of CMake and you specifying target_link_libraries manually.
Take a look at my answer to a similar question where I suggested the following extra definition to disable auto-linking:
add_definition( -DBOOST_ALL_NO_LIB )
You may need to add the following when linking dynamically and depending on the Boost version and the components:
add_definitions( -DBOOST_ALL_DYN_LINK )
Note also that you specify the Boost components you want in the find_package() call and then specify them again manually in your target_link_libraries() call. Depending a bit on your need, you could also replace this with
target_link_libraries( ${Boost_LIBRARIES} )

Related

Building a MacOS executable for distribution using cmake including OpenCV

I have a cmakelists.txt file that compiles my MacOS application using OpenCV, C++, OpenGL, based on information I found on SO. When I try copying the folder of the executable to another Mac, I get an error due to missing OpenCV libs, expected in a different folder from my executable.
Is there a change I can make to the file so that it will include the OpenCV compiled code in the executable, or its folder for distribution? For what it's worth I am using CMake because I could not figure out a simpler way to get it to build.
cmake_minimum_required( VERSION 3.1 )
project( go)
set (CMAKE_CXX_STANDARD 11)
find_package( OpenCV REQUIRED )
find_library( COCOA_FW Cocoa )
find_library( OPENGL_FW OpenGL )
find_library( IOKIT_FW IOKit )
add_executable( go main.cpp gl_utils.cpp user_interface.cpp geometry_2d.cpp)
target_include_directories( go PRIVATE ${CMAKE_SOURCE_DIR}/include )
target_link_libraries( go ${OpenCV_LIBS} ${COCOA_FW} ${OPENGL_FW} ${IOKIT_FW} ${CMAKE_SOURCE_DIR}/common/libGLEW.a ${CMAKE_SOURCE_DIR}/common/libglfw3.a)
On another question related: Static OpenCV compile
set(OpenCV_STATIC ON)
find_package(OpenCV REQUIRED)
Now for the find_library( OPENGL_FW OpenGL ), you will need to be more explicit:
# This could change based on the OpenGL library you have installed.
find_library( OPENGL_FW libGL.a )

Trying to use boost::filesystem by adding Boost libraries in CMakeLists.txt but does not work

I wanted to use boost::filesystem for my C++ code so I decided to add boost libraries into my CMakeLists.txt but I keep getting this message and it's not working right.
ipo: warning #11012: unable to find #loader_path/libboost_system-mt.dylib
Here is my CMakeLists.txt file.
cmake_minimum_required ( VERSION 3.10 )
set ( CMAKE_CXX_COMPILER icpc )
set ( CMAKE_CXX_STANDARD 17 )
set ( CMAKE_CXX_FLAGS "-fast -qopenmp -Wall" )
project( FLattice CXX )
# Add include files (-I option)
include_directories ( ${PROJECT_SOURCE_DIR}/include )
include_directories ( /opt/fftw/include )
# Specify the Library directory (-L option)
link_directories ( /opt/fftw/lib )
# Add executing files
file ( GLOB lib_codes ${PROJECT_SOURCE_DIR}/lib/*.cpp )
add_executable ( ${PROJECT_NAME} main.cpp ${lib_codes} )
# Boost
set(boost_min_ver 1.69.0)
set(boost_libs system filesystem)
find_package(Boost ${boost_min_ver})
if(Boost_FOUND)
find_package(Boost ${boost_min_ver} COMPONENTS ${boost_libs})
include_directories(${Boost_INCLUDE_DIRS})
target_link_libraries(${PROJECT_NAME} ${Boost_LIBRARIES})
endif()
# Link external libraries
target_link_libraries ( ${PROJECT_NAME} fftw3 )
# Link project "library" when compile FLattice
# target_link_libraries ( FLattice library_code )
# Add sub-directory
# add_subdirectory ( lib )
I installed Boost by brew install boost and I simply just added the #Boost part to my original CMakeLists.txt file.
What am I doing wrong? Any thoughts?
update Seems like the program is working fine (I thought it wasn't working, but it was). However, I still get the same warning message.
ipo: warning #11012: unable to find #loader_path/libboost_system-mt.dylib
I started to think that this warning is an Intel issue and not a boost issue as in https://software.intel.com/en-us/forums/intel-c-compiler/topic/518493.

Add library to Cmake project

Perhaps I simply can't find it, but I want to add some code to a project of mine (libunwind found here http://www.nongnu.org/libunwind/download.html)
This library does not come with a CMakeLists.txt file and when I try to include it cmake complains about this fact. Right now I've simply added the libunwind directory to my external code and added a reference in my main CMakeLists.txt
Any input would be great.
Dealing with libraries there are 2 options for you :
If you've downloaded and was able to build and install it you can try to find it later on inside you CMAKE like this ( in case of Boost ) and link to your target:
find_package( Boost COMPONENTS date_time system serialization thread program_options filesystem unit_test_framework regex chrono REQUIRED )
if( NOT Boost_FOUND )
message( FATAL_ERROR "Cannot find boost!" )
endif( NOT Boost_FOUND )
message(STATUS "boost found")
include_directories( ${Boost_INCLUDE_DIRS} )
link_directories( ${Boost_LIBRARY_DIRS} )
target_link_libraries(YOUR_TARGET_NAME ${Boost_LIBRARIES})
2. You can add external library sources as a stand-alone target and use smth like this for CMake to build it :
set (sources
async_waiter.h
async_waiter_impl.h
async_waiter_impl.cpp
)
add_library( async_waiter ${sources} )
and later on link you target to it with :
target_link_libraries(YOUR_TARGET_NAME async_waiter)
If you want to build it each time along with your project, the easiest way would be to:
Add the source code somewhere into your project tree
Add a custom CMake target which should run before the compilation starts
In that custom target, run whatever is needed to compile the library (in your case it's ./configure -> make -> make install.
However that is rarely needed and most of the times you should just build the library once and link it as any other external library.

Undefined reference to SDL with CMake

I'm working on a project using the SDL (v1.2.15-7) and CMake (3.2.1). In the *.h files I added the #include <SDL.h> and when I compile it, I have a bunch of errors : undefined reference to SDL_...
I think the mistake comes from the CMakeLists.txt but I really don't know where.
Here's the file content :
CMAKE_MINIMUM_REQUIRED( VERSION 2.8 )
SET( PROJ_NAME "Project" )
SET( PROJ_PATH ${CMAKE_SOURCE_DIR} )
SET( PROJ_OUT_PATH ${CMAKE_BINARY_DIR} )
SET( PROJ_INCLUDES "include" )
FILE( GLOB_RECURSE PROJ_SOURCES src/*cpp test/*cpp doc/*)
FILE( GLOB_RECURSE PROJ_HEADERS ${PROJ_INCLUDES}/${PROJ_NAME}/*.h )
PROJECT( ${PROJ_NAME} )
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x")
FIND_PACKAGE( SDL REQUIRED )
SET( PROJ_LIBRARIES ${SDL_LIBS} )
INCLUDE_DIRECTORIES( ${PROJ_INCLUDES} ${SDL_INCLUDE_DIR} )
ADD_EXECUTABLE( ${PROJ_NAME} ${PROJ_SOURCES} ${PROJ_HEADERS} )
TARGET_LINK_LIBRARIES( ${PROJ_NAME} ${PROJ_LIBRARIES} )
I also tried #include SDL/SDL.h
The error message is coming from the linker, in which case it means you're not linking against the SDL libraries.
The CMake documentation specifies that the FindSDL module defines a variable named SDL_LIBRARY, but you're using SDL_LIBS. So, SET(PROJ_LIBRARIES ${SDL_LIBRARY}) instead.
When using a standard module for finding a package, try browsing the documentation first to take a look at the variables it defines. The names aren't always standard.
Try using SDL_LIBRARY instead of SDL_LIBS
You forgot to link your target to SDL_LIBRARIES in the last line of your CMakeLists.txt.
The linker produces the error, so it is unrelated to your includes.

Want to make standalone program with cmake

My program uses giblib and Imlib2 library and it is built with cmake.
It works perfectly in my computer but not in other's.
I guess the reason is I installed every library what my program needs but other's doesn't.
My goal is making standalone program. (don't need to install any other library addtionally)
What should I add in cmake file?
projectDef.cmake source code
file (GLOB PLATFORM RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}
X11/[^.]*.cpp
X11/[^.]*.h
X11/[^.]*.cmake
)
SOURCE_GROUP(X11 FILES ${PLATFORM})
add_definitions(
)
set (SOURCES
${SOURCES}
${PLATFORM}
)
add_x11_plugin(${PROJECT_NAME} SOURCES)
target_link_libraries(${PROJECT_NAME}
${PLUGIN_INTERNAL_DEPS}
)
include_directories(/usr/include/giblib)
include_directories(/usr/include/X11)
target_link_libraries(MyProject X11)
target_link_libraries(MyProject Imlib2)
target_link_libraries(MyProject giblib)
CMakeList.txt source code
cmake_minimum_required (VERSION 2.6)
set (CMAKE_BACKWARDS_COMPATIBILITY 2.6)
set(BUILD_SHARED_LIBS OFF)
set(CMAKE_EXE_LINKER_FLAGS "-static")
Project(${PLUGIN_NAME})
file (GLOB GENERAL RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}
[^.]*.cpp
[^.]*.h
[^.]*.cmake
)
include_directories(${PLUGIN_INCLUDE_DIRS})
SET_SOURCE_FILES_PROPERTIES(
${GENERATED}
PROPERTIES
GENERATED 1
)
SOURCE_GROUP(Generated FILES
${GENERATED}
)
SET( SOURCES
${GENERAL}
${GENERATED}
)
include_platform()
Try starting with this options in your root CMakeLists.txt:
set(BUILD_SHARED_LIBS OFF)
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static")
BUILD_SHARED_LIBS is only needed if your project has its own libraries (add_library).
With the -static linker flag, you need static libs for ALL your additional libraries too! One common problem when static linking is to avoid circular dependencies.