include boost in CMake - c++

I try to include the current version of the Boost library into my cmake file. But I 'm struggle with the full include. I have already included the boost::filesystem library. So I hope this is not a big change in the code.
Here my Cmake include that works for me:
#include boost
#===========================================================================
set(Boost_INCLUDE_DIR "/Volumes/Code/boost_1_79_0")
set(Boost_LIBRARY_DIR "/Volumes/Code/boost_1_79_0/stage/lib")
find_package(Boost
1.79.0 REQUIRED
COMPONENTS
filesystem
)
if(NOT Boost_FOUND)
message(FATAL_ERROR "Boost Not found")
else()
message(STATUS "Boost version ${Boost_VERSION} found")
endif()
include_directories(include)
include_directories(${Boost_INCLUDE_DIR})
target_link_libraries(${EXECUTABLE}
PUBLIC
Boost::filesystem)
#===========================================================================
Then I tried that and it failed:
#include boost
#===========================================================================
set(Boost_INCLUDE_DIR "/Volumes/Code/boost_1_79_0")
set(Boost_LIBRARY_DIR "/Volumes/Code/boost_1_79_0/stage/lib")
find_package(Boost
1.79.0 REQUIRED
COMPONENTS
filesystem
optional
)
if(NOT Boost_FOUND)
message(FATAL_ERROR "Boost Not found")
else()
message(STATUS "Boost version ${Boost_VERSION} found")
endif()
include_directories(include)
include_directories(${Boost_INCLUDE_DIR})
target_link_libraries(${EXECUTABLE}
PUBLIC
Boost::filesystem
Boost::optional)
#===========================================================================
Does anyone know a way to integrate all Boost Libraries without listing them or sees my mistake?
If someone has suggestions for improvements, feel free to teaching me.

set(Boost_INCLUDE_DIR "/Volumes/Code/boost_1_79_0")
set(Boost_LIBRARY_DIR "/Volumes/Code/boost_1_79_0/stage/lib")
That's not how you should use CMake: your solution just hardcodes paths, and the whole idea of CMake is that you can take a CMake project and build it on a different machine, where paths and necessary flags are different.
So, delete that altogether. You want to have
set(BOOST_REQUIRED_COMPONENTS
filesystem
optional
)
set(BOOST_MIN_VERSION 1.79.0) # or whatever you need!
# Here you can either append or set a root to look into
# In general, **don't do that**! Your boost build and installation
# should come with the correct CMake configure scripts to automate this!
# If you set it here, the people trying to build your code on a different
# machine **WILL** hate you.
# set(BOOST_ROOT "/Volumes/Code/boost_1_79_0")
find_package(
Boost ${BOOST_MIN_VERSION} REQUIRED
COMPONENTS ${BOOST_REQUIRED_COMPONENTS}
)
target_link_libraries(${EXECUTABLE} PUBLIC
Boost::filesystem
Boost::optional
)
target_include_directories(${EXECUTABLE} PRIVATE include)
You whole setting include_directories(${Boost_INCLUDE_DIR}) is redundant (and a bad idea); target_link_libraries( ... Boost::...) does that automatically.
Does anyone know a way to integrate all Boost Libraries without listing them or sees my mistake?
You don't do that, or your linking takes forever, you produce, under circumstances, gigantic object files and executables, and all for the advantage of not having to write down each Boost component as you use them, in a single place!
So, you could use the ALL meta-compoent (which was introduced by Boost 1.73), but I'd strongly encourage you not to do that.

Related

cmake cannot find boost in a custom location or stock location

This question is one that has occurred before on SO. For instance this question:
Cmake doesn't find Boost
But the answers there and elsewhere don't seem to work.
On Ubuntu 16.04 with the stock boost 1.58.0 installed, I have also built, in a custom location, boost 1.68.0.
Now I am trying to compile a simple c++ program using boost, with cmake. It does not find boost. Either version (although 1.68.0 is the one I really want to use).
It gives:
-- Could NOT find Boost (missing: Boost_DIR)
The CMakeLists.txt file is below. CMake 3.12.1 is being used.
cmake_minimum_required(VERSION 3.0.0)
set(CMAKE_CXX_STANDARD 17)
project(mytest CXX)
set(Boost_DEBUG ON)
set(Boost_DETAILED_FAILURE_MSG ON)
set(BOOST_ROOT /home/hal/projects/boost/boost)
# set(Boost_DIR /home/hal/projects/boost/boost)
#set(Boost_USE_DEBUG_LIBS ON)
#set(Boost_USE_STATIC_LIBS ON)
#set(Boost_USE_MULTITHREADED ON)
# set(Boost_USE_STATIC_RUNTIME OFF)
#set(Boost_INCLUDE_DIR /home/hal/projects/boost/boost )
set(Boost_ADDITIONAL_VERSIONS "1.58" "1.58.0")
#set(BOOST_INCLUDEDIR /home/hal/projects/boost/boost/include )
#set(BOOST_LIBRARYDIR /home/hal/projects/boost/boost/lib )
#SET(CMAKE_INCLUDE_PATH ${CMAKE_INCLUDE_PATH} "/home/hal/projects/boost/boost")
#SET(CMAKE_LIBRARY_PATH ${CMAKE_LIBRARY_PATH} "/home/hal/projects/boost/boost/lib")
find_package(Boost 1.68.0 COMPONENTS system date_time PATHS /home/hal/projects/boost/boost )
if(Boost_FOUND)
include_directories(${Boost_INCLUDE_DIRS})
add_executable(mytest main.cpp)
target_link_libraries(mytest ${Boost_LIBRARIES} stdc++)
endif()
Unless you work with implementing of searching packaging, option PATHS for find_package is not such useful, just remove it:
find_package(Boost 1.68.0 COMPONENTS system date_time)
Explanations
There are two ways for search packages in CMake:
With XXXConfig.cmake script, shipped with a specific package installation. In this script all paths (libraries, include directories, etc.) are hardcoded.
With FindXXX.cmake script, shipped with CMake itself. This script searches the libraries and headers under the system directories (like /usr/local/lib) but also takes hints from the user.
By default, the second way is tried; only if FindXXX.cmake script is absent, the first way is used.
But some options for find_package are applied only for the first way, and PATHS is exactly an option of this sort: it specifies paths where XXXConfig.cmake file can be found. With such options, find_package uses the second way - it tries to find XXXConfig.cmake script and execute it. But it seems that your Boost installation lacks of this config script, so CMake fails to find Boost.

how to include boost headers in own header-only library

i am using Jetbrains CLion 2017.3 and the bundled CMake version 3.9.6 with mingw64 5.0 version/g++ 7.1.
Although reading the "Mastering CMake" ( i am new to CMake !) i have many difficulties to understand the basics. Since 3 days i am searching for a CMake solution to create a own header-only library that uses the boost (1.66.0 ) libraries.
Using my CMakeLists.txt results in finding the boost libraries, but i cannot include boost headers in a header file from my current source directory.
My current source diretory contains the "CMakeLists.txt" and the header file
"test_boost.h".
If i try to include boost headers in the header file "test_boost.h", boost headers cannot be found !
What i am doing wrong ?
My CMakeLists.txt :
cmake_minimum_required(VERSION 3.9)
project(headerOnlyLib1)
set(CMAKE_CXX_STANDARD 11)
set(ENV{BOOST_ROOT} "C:/dev/boost/mingw/boost_1_66_0/boost")
set(Boost_USE_STATIC_LIBS ON) # only find static libs
set(Boost_USE_MULTITHREADED ON)
set(Boost_USE_STATIC_RUNTIME OFF)
find_package(BOOST 1.66 REQUIRED)
IF (Boost_FOUND)
message(STATUS "BOOST FOUND !")
ELSE()
message(STATUS "BOOST NOT Found !")
endif()
add_library(headerOnlyLib INTERFACE)
target_include_directories(headerOnlyLib INTERFACE ${CMAKE_CURRENT_SOURCE_DIR})
target_include_directories(headerOnlyLib INTERFACE ${Boost_INCLUDE_DIRS})
target_link_libraries(headerOnlyLib ${Boost_LIBRARIES})
Short answer: You can't.
A "header-only library" is just that, one or more headers, only. It's not something that is linked or really stand-alone.
If your header-only library have dependencies, then the users of your library also have those dependencies and need to include them in their own build.
I think that you can, but you need to be more specific in defining your boost dependencies.
For example, the CMakeLists.txt file here depends upon boost::system for boost::asio. The dependency is defined as follows:
find_package(Boost REQUIRED COMPONENTS system)
if(Boost_FOUND)
target_include_directories(${PROJECT_NAME} PRIVATE ${Boost_INCLUDE_DIRS})
# Boost::asio is header only but it requires Boost::system
target_link_libraries(${PROJECT_NAME} INTERFACE Boost::system)
.
.
.
endif(Boost_FOUND)
In your case, the target is Boost::boost for header-only dependencies, see FindBoost. So the relevant part becomes:
find_package(Boost 1.66 REQUIRED COMPONENTS boost)
IF (Boost_FOUND)
message(STATUS "BOOST FOUND !")
target_include_directories(headerOnlyLib INTERFACE ${Boost_INCLUDE_DIRS})
ELSE()
message(STATUS "BOOST NOT Found !")
endif()
I recommend watching Daniel Pfeifer's talk at C++ Now 2017 for more information.
A lot has changed since "Mastering CMake" was written...

Cmake error when adding Boost library

I am trying to add Boost library to my project using the CMakeLists.txt in the follwing way:
set(BOOST_INCLUDEDIR "C:/boost_1_57_0")
set(BOOST_LIBRARYDIR "C:/boost_1_57_0/stage/lib")
find_package(Boost 1.57.0 COMPONENTS filesystem)
include_directories(${Boost_INCLUDE_DIRS})
add_executable(test test.cpp)
target_link_libraries(test ${Boost_LIBRARIES})
However, I get the followng error: LINK : fatal error LNK1104: cannot open file 'libboost_filesystem-vc120-mt-1_57.lib'
libboost_filesystem-vc120-mt-1_57.lib is located in the stage/lib folder, so I don't know what is going on. I am compiling with Visual Studio 2013.
Any thoughts?
Try setting the Boost_USE_STATIC_LIBS and Boost_USE_MULTITHREADED CMake variables to ON before using find_package, i.e.:
set( Boost_USE_STATIC_LIBS ON )
set( Boost_USE_MULTITHREADED ON )
find_package( Boost 1.57.0 COMPONENTS filesystem )
I've come across this problem before and it seems as though, on multithreaded windows systems, the Boost bootstrap installer compiles multithreaded, static libraries by default. However, the CMake FindBoost script (which is used by find_package) searches for single-threaded, dynamic libraries by default.
Since you're using VS compiler I'll say you're working on Windows.
The error refers to the linker, which is failing to find boost libraries, as noticed.
Taking into account that the library exists in the boost path, my solution was to do a file(COPY) for the specific library, as a last resort.
if(WIN32)
set(BOOST_ROOT "C:/boost_1_57_0")
set(BOOST_LIBRARYDIR ${BOOST_ROOT}/stage/lib/)
endif()
find_package(Boost 1.57.0 EXACT REQUIRED system filesystem)
if(Boost_FOUND)
message(STATUS "found boost, Boost_LIBRARIES <" ${Boost_LIBRARIES} ">")
include_directories(${Boost_INCLUDE_DIRS})
link_directories(${Boost_LIBRARY_DIRS})
set(Boost_USE_MULTITHREADED ON)
set(Boost_USE_STATIC_RUNTIME OFF)
else()
message(STATUS "boost not found")
endif()
target_link_libraries(boost_test ${Boost_LIBRARIES})
file(COPY "${Boost_LIBRARY_DIRS}/boost_filesystem-vc120-mt-1_57.dll" DESTINATION "${CMAKE_CURRENT_BINARY_DIR}")
You may add some log messages to the CMake in order to know the values returned in the
find_package.
Make sure the architecture (x64) matches.
$ cmake -A x64 ..
Use link_directories command before adding executables just like include_directories.
link_directories(${Boost_LIBRARY_DIRS})

error: magic.h: No such file or directory (MacOS X V 10.6.8)

I am developing a project called "Duplicate File Finder" where I also want to extract the information about the type of the file i.e. png, zip, executable etc. I found out that libmagic (magic.h) can be used for finding filetype. But the problem I am facing for quite some time is that magic.h is not recognized when I compile the module. My project uses 'cmake' build system. I defined all the parameters in CMakeLists.txt and even it is not giving error when I am finding path and library for magic as it is installed in my system. I can do 'man libmagic' and it works. Following is my cmake file. Following is my CMakeLists.txt file.
cmake_minimum_required(VERSION 2.8)
project( duplicateFinder )
set(Boost_USE_STATIC_LIBS OFF)
set(Boost_USE_MULTITHREADED ON)
set(Boost_USE_STATIC_RUNTIME OFF)
set(USE_OPENSSL TRUE)
find_package(Boost 1.53.0 COMPONENTS system filesystem regex thread REQUIRED)
find_package(OpenSSL)
FIND_PATH(SQLITE3_INCLUDE_DIR sqlite3.h)
find_library(SQLITE3_LIBRARY sqlite3)
FIND_PATH(MAGIC_INCLUDE_DIR magic.h)
find_library(MAGIC_LIBRARY magic $ENV{MAGIC_LIB_PATH})
if(NOT MAGIC_INCLUDE_DIR)
message(SEND_ERROR "Failed to find magic.h")
endif()
if(NOT MAGIC_LIBRARY)
message(SEND_ERROR "Failed to find the magic library")
endif()
if(NOT SQLITE3_INCLUDE_DIR)
message(SEND_ERROR "Failed to find sqlite3.h")
endif()
if(NOT SQLITE3_LIBRARY)
message(SEND_ERROR "Failed to find the sqlite3 library")
endif()
if(Boost_FOUND)
include_directories(${Boost_INCLUDE_DIRS})
SET(duff_SOURCES src/run_duff.cpp src/sys_scan.cpp src/duff_utils.cpp)
SET(duff_HEADERS src/run_duff.h src/sys_scan.h src/duff_utils.cpp)
add_executable(bin/dup_finder ${duff_SOURCES} ${duff_HEADERS})
add_definitions( -DBOOST_ALL_NO_LIB )
add_definitions( -DBOOST_ALL_DYN_LINK )
target_link_libraries(bin/dup_finder ${Boost_LIBRARIES} ${Boost_FILESYSTEM_LIBRARY} ${Boost_SYSTEM_LIBRARY} ${Boost_REGEX_LIBRARY} ${Boost_THREAD_LIBRARY} ${OPENSSL_LIBRARIES} ${SQLITE3_LIBRARY} ${MAGIC_LIBRARY} )
endif()
I did an intensive research on Internet but was not able to solve the problem. I hope the problem statement is understandable. Can anybody help me in this regards. Thank you in advance.
You need to add
include_directories(${MAGIC_INCLUDE_DIR})
Additional comments: Since boost is REQUIRED, CMake will fail if it is not found, so it is a bit weird to wrap everything inside an if(Boost_FOUND).
It's doubly confusing since you link the non-boost libraries inside this if as well…
Also, you should add ${SQLITE3_INCLUDE_DIR} to the include_directories as well, since on another machine, they may be in a place not already included.

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)