Link the static versions of the Boost libraries using CMake - c++

I've got both the static and the dynamic versions of the boost libraries in /usr/lib. Now I'd like CMake to prefer the static versions during the linkage of my executable. What can I do?

In your CMakeLists.txt file:
set(Boost_USE_STATIC_LIBS ON)
find_package(Boost REQUIRED ...)
Where I have ..., you optionally put the names of the libraries you want to use, and then target_link_libraries(targetname ${Boost_LIBRARIES}) later below. If you have a fairly recent distribution of CMake, it should work exactly as advertised. I do it exactly this way in my own projects.

Here is a full example of CMAKEFILE,For example, include boost program options
cmake_minimum_required(VERSION 3.15)
project(your_project)
set(Boost_USE_STATIC_LIBS ON)
find_package(Boost 1.70 COMPONENTS program_options REQUIRED)
set(CMAKE_CXX_STANDARD 14)
add_executable(your_project main.cpp)
target_link_libraries(rconpp Boost::program_options)
references:
cmake documents about BOOST

Related

CMake Boost Multiprecision not found

Here is my CMakeLists.txt file
cmake_minimum_required(VERSION 3.8)
project("pi-calc" VERSION 1.0)
find_package(Boost REQUIRED COMPONENTS multiprecision)
add_executable(pi-calc main.cpp)
target_link_libraries(pi-calc PRIVATE Boost::boost Boost::multiprecision)
This is the main part of error message, removing CMake find_package failure Call Stacks
Could NOT find Boost (missing: multiprecision) (found version "1.67.0")
I have tried googling around for a solution but couldn't find anything.
Many of Boost's libraries are header-only libraries, including the multiprecision library. You only need to explicitly call out the libraries in COMPONENTS that are not header-only, shown in the list here.
If you need a header-only library, such as multiprecision, you will get this for free from the Boost::boost target, which includes all the Boost headers. There is no need to list any COMPONENTS:
cmake_minimum_required(VERSION 3.8)
project("pi-calc" VERSION 1.0)
find_package(Boost REQUIRED)
add_executable(pi-calc main.cpp)
target_link_libraries(pi-calc PRIVATE Boost::boost)
Note, in CMake versions 3.15 and later, you should instead use the Boost::headers target, which supersedes the Boost::boost target.

CMake - Can't link shared library (subdirectory)

I am using CLion and mingw-w64.
My executable's CMakeLists.txt:
cmake_minimum_required(VERSION 3.12)
project(test_exe)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "D:\\test")
add_subdirectory(test_lib)
include_directories(test_lib/include;test_lib/deps/include)
link_directories(test_lib/deps/lib)
add_executable(test_exe main.cpp)
target_link_libraries(test_exe test_lib)
test_lib's CMakeLists.txt:
cmake_minimum_required(VERSION 3.12)
project(test_lib)
set(CMAKE_CXX_STANDARD 17)
include_directories(include;deps/include)
link_directories(deps/lib)
file(GLOB_RECURSE LIB_SOURCES "include/*.*" "src/*.*")
add_library(test_lib SHARED ${LIB_SOURCES})
target_link_libraries(test_lib libfreetype.a libpugixml.dll.a)
The problem is that when I add library with add_library(test_lib SHARED ${LIB_SOURCES}) I get undefined reference errors but when I add the library with add_library(test_lib ${LIB_SOURCES}) it works perfectly.
An empty project links as expected (both SHARED and STATIC) but I wonder why this one is not working? Because of the libraries I link in the test_lib's CMakeLists.txt?
When you build a static library, there is no linking taking place. It doesn't check that you have all required libraries.
When you do the same for shared librarie,s then on some platforms (like Windows, or on Linux with -X defs, I think), you need to solve all references.
And you have a shared library.

CMake: What is the difference between `include_directories` versus `target_link_libraries`

I am building a moderately sized C++ library and have cobbled together my CMakeLists.txt file from a bunch of different examples, etc. I was trying to understand the difference between include_directories versus the target_link_libraries instructions.
I list some of my code below, but just wanted to preface with a comment. I use the Boost library to build some of my code. So I have an instruction to INCLUDE_DIRECTORIES(${Boost_INCLUDE_DIRS}) to include the Boost source directories in the build process. So I assume that Cmake will include these Boost Source files when building any executable--without any additional explicit instruction.
But later I have a TARGET_LINK_LIBRARIES( gd_validator ${Boost_LIBRARIES} ) when building an executable. So that suggests that I need to not only include the Boost directory, but then also explicitly link it with the executable.
So I was not sure if I actually needed both steps, or if I just needed the INCLUDE_DIRECTORIES instruction and that was it.
cmake_minimum_required(VERSION 3.7)
project(XXX)
find_package(Boost 1.58.0 REQUIRED COMPONENTS system filesystem program_options chrono timer date_time REQUIRED)
if(NOT Boost_FOUND)
message(FATAL_ERROR "NOTICE: This demo requires Boost and will not be compiled.")
endif()
set(Boost_USE_STATIC_LIBS ON)
set(Boost_USE_MULTITHREADED ON)
set(Boost_USE_STATIC_RUNTIME OFF)
INCLUDE_DIRECTORIES(${Boost_INCLUDE_DIRS})
LINK_DIRECTORIES(${Boost_LIBRARY_DIRS})
file(GLOB lib_SRC RELATIVE "lib/" "*.h" "*.cpp")
file(GLOB test_SRC RELATIVE "tests/" "*.h" "*.cpp")
# need to fix the instruction below to reference library
set(SOURCE_FILES ${lib_SRC} tests/testComplexCreator.cpp tests/testDataFormatter.cpp tests/testComplexAnalysis.cpp tests/testFascadeClass.cpp)
add_library(libXXX SHARED ${SOURCE_FILES})
add_executable(${PROJECT_NAME} main.cpp random_mat_vector_generator.h random_mat_vector_generator.cpp)
add_executable(gd_validator gudhi_validator.cpp)
TARGET_LINK_LIBRARIES( gd_validator ${Boost_LIBRARIES} )
Yes, you need both.
include_directories will tell to the compiler where to look for the header files, in this case, the header files for the boost library.
target_link_libraries will tell to the linker which libraries you want to link against your executable.
While headers will provide (most of the time) just the interface to access the library, the library itself is precompiled and linked to your application.
include_directories specifies the directories to be searched for included files (headers). target_link_libraries specifies the libraries to be linked to your target (executable or library).
Two completely​ different things.

Boost log, GCC 4.4 and CMake

I am trying to get a simple boost.log example running on Linux using GCC 4.4.5, CMake 2.8.2 and Boost 1.53.0.
Compiling boost and boost log succeeded, but I keep getting issues when linking my test program to boost.log.
I use the following CMakeLists.txt file:
cmake_minimum_required(VERSION 2.8)
project(QuantibBoostLogTest)
# Include boost headers
set(Boost_USE_STATIC_LIBS ON)
set(Boost_USE_MULTITHREADED ON)
find_package(Threads)
find_package(Boost 1.53.0 COMPONENTS thread date_time filesystem system log log_setup REQUIRED)
if(Boost_FOUND)
include_directories( ${Boost_INCLUDE_DIRS} )
link_libraries(${CMAKE_THREAD_LIBS_INIT} ${Boost_LIBRARIES})
else(Boost_FOUND)
message(FATAL_ERROR "Cannot build Quantib Boost Log test without Boost. Please set Boost_DIR.")
endif(Boost_FOUND)
add_executable(quantibBoostLogTest boost_log_test.cxx)
install(TARGETS quantibBoostLogTest DESTINATION .)
CMake does detect the boost libraries correctly, but I still get linker errors, mostly of the form:
core.cpp:(.text+0x1b0e): undefined reference to `boost::detail::get_tss_data(void const*)'
I do link the thread libraries. Does anybody know how to solve this?
It seems like boost.log depends on boost.thread library then you need change order of libraries. See why link order does matter
Try following order
find_package(Boost 1.53.0 COMPONENTS log log_setup thread date_time filesystem system REQUIRED)
if it will not help try include them two times as following
link_libraries(${CMAKE_THREAD_LIBS_INIT} ${Boost_LIBRARIES} ${Boost_LIBRARIES})
The linker error you give has something to do with either not linking against a native threading library like pthreads and/or boost_thread. (or both)
1)
From what I see you don't link against pthreads library.
By merely calling a CMake custom module that tries to find the library doesn't mean it'll also link against it.
Try and do:
SET(CMAKE_THREAD_PREFER_PTHREAD true)
FIND_PACKAGE (Threads)
IF(Threads_FOUND)
INCLUDE_DIRECTORIES(SYSTEM ${Threads_INCLUDE_DIR})
MESSAGE("Are we using pthreads? ${CMAKE_USE_PTHREADS_INIT}")
TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${CMAKE_THREAD_LIBS_INIT})
ENDIF()
Check the FindThreads.cmake file of the CMake installation you have for more information regarding the use of the threads module.
You can usually find it in /usr/share/cmake-2.8/Modules/
2) Maybe the ordering of the linked Boost libraries is incorrect or the version you specified for Boost is invalid.
Try changing the boost version or don't specify it at all or change the order of the linked libraries
SET(Boost_USE_STATIC_LIBS ON)
SET(Boost_USE_MULTITHREADED ON)
FIND_PACKAGE(Boost 1.53.0 COMPONENTS **system thread filesystem date_time log log_setup** REQUIRED)
IF(Boost_FOUND)
INCLUDE_DIRECTORIES(SYSTEM ${Boost_INCLUDE_DIR})
LINK_DIRECTORIES(${Boost_LIBRARY_DIR})
MESSAGE("Boost information")
MESSAGE("Boost_INCLUDE_DIRS: ${Boost_INCLUDE_DIRS}")
MESSAGE("Boost_LIBRARY_DIRS: ${Boost_LIBRARY_DIRS}")
MESSAGE("Boost Libraries: ${Boost_LIBRARIES}")
TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${Boost_LIBRARIES})
ENDIF()
(The second contention might be completely wrong as I think the ordering of the elements specified after COMPONENTS in FIND_PACKAGE doesn't matter)

Using Boost.asio with cmake?

I want to static link boost.asio to my small project without external libs (having only single exe/bin file in result to distribute it). Boost.asio requires Boost.system and i start to drown trying to figure out how to compile this all.
How to use Boost.asio with cmake?
If I understand the actual question, it is fundamentally asking how to statically link against 3rd party libraries in CMake.
In my environment, I have installed Boost to /opt/boost.
The easiest way is to use FindBoost.cmake provided in a CMake installation:
set(BOOST_ROOT /opt/boost)
set(Boost_USE_STATIC_LIBS ON)
find_package(Boost COMPONENTS system)
include_directories(${Boost_INCLUDE_DIR})
add_executable(example example.cpp)
target_link_libraries(example ${Boost_LIBRARIES})
A variant that finds all Boost libraries and explicitly links against the system library:
set(BOOST_ROOT /opt/boost)
set(Boost_USE_STATIC_LIBS ON)
find_package(Boost REQUIRED)
include_directories(${Boost_INCLUDE_DIR})
add_executable(example example.cpp)
target_link_libraries(example ${Boost_SYSTEM_LIBRARY})
If you do not have a proper Boost installation, then there are two approaches to statically link against the libraries. The first approach creates an imported CMake target:
add_library(boost_system STATIC IMPORTED)
set_property(TARGET boost_system PROPERTY
IMPORTED_LOCATION /opt/boost/lib/libboost_system.a
)
include_directories(/opt/boost/include)
add_executable(example example.cpp)
target_link_libraries(example boost_system)
And the alternative is to explicitly list the library in target_link_libraries rather than the target:
include_directories(/opt/boost/include)
add_executable(example example.cpp)
target_link_libraries(example /opt/boost/lib/libboost_system.a)