How to properly link boost with cmake - boost

The root directory of boost ($ENV{BOOST_ROOT}) is
C:\Boost\boost_1_64_0
All compiled libraries (.dll, .lib) are in
C:\Boost\boost_1_64_0\lib64-msvc-14.1
They have both boost_xxx and libboost_xxx.
My cmake file is
set(BOOST_ROOT "$ENV{BOOST_ROOT}")
set(BOOST_LIBRARYDIR "$ENV{BOOST_ROOT}/lib64-msvc-14.1")
message("${BOOST_ROOT}")
message("${BOOST_LIBRARYDIR}")
message("${Boost_INCLUDE_DIR}")
if(MSVC)
add_definitions(-DBOOST_ALL_NO_LIB)
add_definitions(-DBOOST_ALL_DYN_LINK)
endif()
find_package(Boost 1.64.0 COMPONENTS system filesystem program_options REQUIRED)
And the output is
C:\Boost\boost_1_64_0
C:\Boost\boost_1_64_0/lib64-msvc-14.1
C:/Boost/boost_1_64_0
CMake Error at C:/Program
Files/CMake/share/cmake-3.8/Modules/FindBoost.cmake:1842 (message):
Unable to find the requested Boost libraries.
Boost version: 1.64.0
Boost include path: C:/Boost/boost_1_64_0
Could not find the following Boost libraries:
boost_system
boost_filesystem
boost_program_options
No Boost libraries were found. You may need to set BOOST_LIBRARYDIR
to the directory containing Boost libraries or BOOST_ROOT to the
location of Boost. Call Stack (most recent call first):
CMakeLists.txt:78 (find_package)
CMake Error at CMakeLists.txt:84 (message): Boost not found
Could someone help please? I have spent hours on this but couldn't figure out why this doesn't work.

First of all, what CMake version do you use? Recently a regression fix was included into 3.8.1 release -- it was about backslashes in BOOST_ROOT.
Secondly, you don't need to specify anything else ('cept maybe the BOOST_ROOT) if you are using official prebuilt Windows binaries -- FindBoost.cmake would try to find them as well. (Unfortunately I can't recall since what version.)
Never do set(BOOST_ROOT...) in your CMakeLists.txt -- just pass this parameter to cmake run via -D option. A better way is the following:
if(NOT DEFINED BOOST_ROOT AND NOT "${ENV{BOOST_ROOT}" STREQUAL "")
set(BOOST_ROOT "$ENV{BOOST_ROOT}")
endif()
Use imported targets to link w/ needed Boost libraries and to modify compile/linker flags per taget. Please avoid to modify "global" compiler/linker options -- i.e. use corresponding target_xxx commands instead of add_definitions & etc.

I use the following script to load boost with CMake (working with Linux and Windows) :
set(BoostPath "${DefaultBoostPath}" CACHE PATH "Path to Boost")
message(STATUS "Path to Boost: ${BoostPath}")
set(BOOST_ROOT "${BoostPath}")
set(Boost_USE_MULTITHREAD ON)
set(Boost_USE_STATIC_LIBS ON)
set(Boost_NO_SYSTEM_PATHS ON)
set(Boost_ADDITIONAL_VERSIONS "1.57.0" "1.57" "1.58.0" "1.58" "1.59.0" "1.59" "1.60.0" "1.60" "1.61.0" "1.61" "1.62.0" "1.62" "1.63.0" "1.63" "1.64.0" "1.64")
find_package(Boost ${RequiredBoostVersion} REQUIRED COMPONENTS ${RequiredBoostComponents})
mark_as_advanced(FORCE Boost_DIR)
set(BoostVersion "${Boost_MAJOR_VERSION}.${Boost_MINOR_VERSION}.${Boost_SUBMINOR_VERSION}")
message(STATUS "Boost version: ${BoostVersion}")
if(CompilerName STREQUAL "gcc")
set(System_LIBRARIES ${System_LIBRARIES} pthread rt)
endif()
You can see I have to add some versions of Boost because my version of CMake doesn't know last versions.
What's your CMake version ? Maybe it's the same problem.

Where are your headers? I don't think it found the include directory (which is necessary for this to be successful).
Search for FindBoost.cmake in your cmake installation directory, there are lots of useful things in there for troubleshooting.
using set(Boost_DEBUG ON) can help you figure out which paths are searched and what the filenames of the libraries are searched. You can specify the include directory (directory where folder boost is stored) with set(Boost_INCLUDEDIRS ${BOOST_ROOT}/inc), though what I just showed is one of the places that FindBoost.cmake searches.
Also, you don't need set(BOOST_ROOT "$ENV{BOOST_ROOT}"). FindBoost.cmake does that for you if you don't set ${BOOST_ROOT}.
Note that if you just downloaded boost, extracted the archive to ${BOOST_ROOT} and compiled with b2, then all of your files are in ${BOOST_ROOT}/stage. This is also a good place for them to reside. If you manually copy files somewhere else, then FindBoost may have some troubles finding them.

Related

CMake found and NOT found boost simultaneously

I am trying to install ismrmrd and following the installation guide for Windows.
In the step cmake-gui.exe my cmake is not finding installed Boost.
After adding those lines to CMakeLists.txt the result became interesting.
Any ideas?
UPDATE 8/21
thanks vre and user1234567
Now I changed to boost 1.66 and still no luck.
The new screenshot shows FindBoost is not complain anything now.
But still not any boost found.
UPDATE 8/22
After adding
cmake_policy(SET CMP0074 NEW)
and
set(Boost_USE_STATIC_LIBS ON) set(Boost_USE_MULTITHREADED ON) find_package(Boost REQUIRED system filesystem) include_directories(${Boost_INCLUDE_DIRS}) target_link_libraries(ismrmrd ${Boost_LIBRARIES}) into CMakeLists.txt by the suggestion from vre
The resulting error became this screenshot
As it is to long for comments I try to come up with a recipe:
The commands needed for using Boost header only/static libraries are:
set(Boost_ADDITIONAL_VERSIONS 1.66.0 1.66)
set(BOOST_ROOT "C:/local/boost_1_66_0")
set(Boost_USE_STATIC_LIBS ON)
set(Boost_USE_MULTITHREADED ON)
For using solely header only libraries use
find_package(Boost)
otherwise name the components (libraries) to be used after the COMPONENTS keyword and use
find_package(Boost COMPONENTS <e.g. filesystem system ...>)
if (Boost_FOUND)
include_directories(${Boost_INCLUDE_DIRS})
add_definitions( "-DHAS_BOOST" )
endif()
Later you reference the imported targets (libraries) for header only Boost in a call
target_link_libraries(yourproject Boost::boost)
or for named library components in a call
target_link_libraries(yourproject ${Boost_LIBRARIES})
Be sure to always delete the CMakeCache.txt file in the build directory when making changes to the CMakeLists.txt regarding Boost and Boost components, as it might cache the values of a previous CMake run.

Cmake can find boost but not boost core

I have installed the libboost-all-dev packaged on Ubuntu.
Cmake 3.10.2 can find boost but not "boost_core".
When I change the find package line to:
find_package(Boost REQUIRED COMPONENTS core)
Then it complains that it can't find "boost_core".
I actually just need boost/iterator...
How to make cmake find that?
Thanks.
CMakeLists.txt:
cmake_minimum_required(VERSION 3.10)
project(test_boost_iterator)
set(CMAKE_CXX_STANDARD 11)
find_package(Boost REQUIRED)
include_directories(${Boost_INCLUDE_DIR})
add_definitions( "-DHAS_BOOST" )
add_executable(test_boost_iterator main.cpp)
Success message (before replacing the find_package line):
-- Boost version: 1.65.1
-- Configuring done
-- Generating done
Error message (after replacing the find_package line)
Unable to find the requested Boost libraries.
Boost version: 1.65.1
Boost include path: /usr/include
Could not find the following Boost libraries:
boost_core
No Boost libraries were found. You may need to set BOOST_LIBRARYDIR to the
directory containing Boost libraries or BOOST_ROOT to the location of
Boost.
Call Stack (most recent call first):
CMakeLists.txt:6 (find_package)
As I know there is no such a boost library core. You can check if a library should be linked here.
And Boost.Iterator is a header-only library, so you don't need to link anything. Just include <boost/iterator/...>. If you can't include, check whether these includes actually exist in your local boost distro.
I checked it for boost::counting_iterator<int> and all works well for me.

MSVC build Boost but Cmake findBoost doesn't work?

To reproduce my issue... I download Boost, then I run booststrap and b2 --build-dir=C:\Users\xxx\Downloads\my_boost_build_dir --prefix=C:\Users\xxx\Downloads\my_boost_install_dir --layout=system variant=release link=static install. Everything seems so far so good. The provided prefix (install) dir is populated with headers and libs.
But here's where things start going wrong. If I write the following cmake file...
find_package(Boost REQUIRED)
message("Boost_FOUND" ${Boost_FOUND})
message("Boost_INCLUDE_DIRS" ${Boost_INCLUDE_DIRS})
message("Boost_LIBRARY_DIRS" ${Boost_LIBRARY_DIRS})
message("Boost_LIBRARIES" ${Boost_LIBRARIES})
message("Boost_CHRONO_FOUND" ${Boost_CHRONO_FOUND})
message("Boost_CHRONO_LIBRARY" ${Boost_CHRONO_LIBRARY})
add_executable(main main.cpp)
target_link_libraries(main PRIVATE Boost::boost Boost::chrono)
...and I configure it with the path to the boost install dir cmake .. -DCMAKE_PREFIX_PATH=C:\Users\xxx\Downloads\my_boost_install_dir, then I get the following output and error...
Boost_FOUND1
Boost_INCLUDE_DIRSC:/Users/xxx/Downloads/my_boost_install_dir/include
Boost_LIBRARY_DIRSC:/Users/xxx/Downloads/my_boost_install_dir/lib
Boost_LIBRARIES
Boost_CHRONO_FOUND
Boost_CHRONO_LIBRARY
-- Configuring done
CMake Error at CMakeLists.txt:14 (add_executable):
Target "main" links to target "Boost::chrono" but the target was not found.
Perhaps a find_package() call is missing for an IMPORTED target, or an
ALIAS target is missing?
Boost is found, the include and lib dirs are found, but the chrono library (and all other libraries) are not. Maybe I need to explicitly name my components? So I tried this cmake instead...
find_package(Boost REQUIRED COMPONENTS chrono)
message("Boost_FOUND" ${Boost_FOUND})
message("Boost_INCLUDE_DIRS" ${Boost_INCLUDE_DIRS})
message("Boost_LIBRARY_DIRS" ${Boost_LIBRARY_DIRS})
message("Boost_LIBRARIES" ${Boost_LIBRARIES})
message("Boost_CHRONO_FOUND" ${Boost_CHRONO_FOUND})
message("Boost_CHRONO_LIBRARY" ${Boost_CHRONO_LIBRARY})
add_executable(main main.cpp)
target_link_libraries(main PRIVATE Boost::boost Boost::chrono)
But this produces the following output and error.
CMake Error at C:/Program Files/CMake/share/cmake-3.9/Modules/FindBoost.cmake:1877 (message):
Unable to find the requested Boost libraries.
Boost version: 1.64.0
Boost include path: C:/Users/xxx/Downloads/my_boost_install_dir/include
Could not find the following Boost libraries:
boost_chrono
Some (but not all) of the required Boost libraries were found. You may
need to install these additional Boost libraries. Alternatively, set
BOOST_LIBRARYDIR to the directory containing Boost libraries or BOOST_ROOT
to the location of Boost.
Call Stack (most recent call first):
CMakeLists.txt:5 (find_package)
Boost_FOUND0
Boost_INCLUDE_DIRSC:/Users/xxx/Downloads/my_boost_install_dir/include
Boost_LIBRARY_DIRS
Boost_LIBRARIES
Boost_CHRONO_FOUND
Boost_CHRONO_LIBRARY
Like before, it found boost and the headers, but for some reason it can't find the libraries.
If you want to use specific (non-header-only) Boost components, you have to specify them in find_package. In your case:
find_package(Boost COMPONENTS chrono REQUIRED)
According to https://cmake.org/cmake/help/v3.0/module/FindBoost.html
find_package(Boost) follow the hints below to find boost directories:
BOOST_ROOT - Preferred installation prefix (or BOOSTROOT)
BOOST_INCLUDEDIR - Preferred include directory e.g.
/include
BOOST_LIBRARYDIR - Preferred library directory e.g. /lib
Boost_NO_SYSTEM_PATHS - Set to ON to disable searching in locations
not
specified by these hint variables. Default is OFF.
Boost_ADDITIONAL_VERSIONS
- List of Boost versions not known to this module
(Boost install locations may contain the version)
If you don't know where is the default location to put your boost libraries and include files, you should set these variables before find_package.

XCode #include bug - not found in header file but in cxx

I created a XCode project with CMake including the Boost 1.55 library and I got into a problem I can't solve by myself.
The include
#include "boost/filesystem.hpp"
just works in EIATHelper.cxx, but not in header EIATHelper.h. In the header it says "file not found" and consequently the build fails. But still the include seems to work, because Xcode doesn't bitch about the used objects defined in "the missing" filesystem.hpp.
Important! When I put the include and all my code into the .cxx files everything works (build/execute).
I added a screenshot who may helps to understand the problem better. (of course I didn't use the double #include):
The project is completely created with CMake.
CMakeLists.txt from subfolder header:
project(${PROJECT_NAME})
add_library(helper
${PROJECT_NAME}Helper.h
${PROJECT_NAME}Helper.cxx
)
set(BOOST_ROOT /Users/name/Libs/Boost/bin)
set(Boost_USE_STATIC_LIBS ON)
set(Boost_USE_MULTITHREADED OFF)
set(Boost_USE_STATIC_RUNTIME OFF)
set(Boost_DEBUG ON)
set(BOOST_INCLUDEDIR /Users/name/Libs/Boost/bin/include)
set(BOOST_LIBRARYDIR /Users/name/Libs/Boost/bin/lib)
find_package(Boost COMPONENTS
system
filesystem
log
log_setup
)
include_directories(${Boost_INCLUDE_DIRS})
if(NOT Boost_FOUND)
message("Boost was NOT found")
endif()
target_link_libraries(helper ${BOOST_LIBRARIES})
Edit: I created a Eclipse CDT4 Project with CMake, same problem here. Header filsystem.hpp not found in the EIATHelper.h. So I guess something has to be wrong with my project settings, regardless of the IDE.
just works in EIATHelper.cxx, but not in header EIATHelper.h
No, it's not. EIATHelper.cxx includes EIATHelper.h, so "header not found" error appears
first in EIATHelper.h and is kind of a fatal error - compilation stops without processing EIATHelper.cxx (hence without reporting any errors in EIATHelper.cxx).
I'm pretty sure that error is in finding boost libraries. Some notes:
BOOST_INCLUDEDIR and BOOST_LIBRARYDIR is a hints. If you set BOOST_ROOT and libraries is in a standard paths (lib and include) you don't need them.
Boost is mandatory for EIATHelper.{h,cxx} it's better to use REQUIRED suboption
(you don't need to check Boost_FOUND):
find_package(Boost REQUIRED system filesystem log log_setup)
CMake variables is case-sensitive, use Boost_LIBRARIES instead of BOOST_LIBRARIES
Do not hardcode BOOST_ROOT variable, it's not user friendly. At least do something like that:
if(NOT BOOST_ROOT)
set(BOOST_ROOT /some/default/path/to/boost)
endif()

Boost include headers not found using cmake

This question is very similar to Why is this boost header file not included, however the hints there don't (seem to) solve my problem.
I got a CMakeLists.txt
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
PROJECT(jetorigin)
SET(Boost_ADDITIONAL_VERSIONS "1.43" "1.43.0" "1.44" "1.44.0" "1.45" "1.45.0")
SET(BOOST_ROOT "$ENV{HOME}/usr")
MESSAGE(STATUS "** Search Boost root: ${BOOST_ROOT}")
FIND_PACKAGE(Boost 1.43 COMPONENTS filesystem regex REQUIRED)
MESSAGE(STATUS "** Boost Include: ${Boost_INCLUDE_DIR}")
MESSAGE(STATUS "** Boost Libraries: ${Boost_LIBRARY_DIRS}")
MESSAGE(STATUS "** Boost Libraries: ${Boost_LIBRARIES}")
INCLUDE_DIRECTORIES(${BOOST_INCLUDE_DIR})
LINK_DIRECTORIES(${Boost_LIBRARY_DIRS})
ADD_SUBDIRECTORY(src)
And include some boost headers in my code like this:
#include <boost/regex.hpp>
#include <boost/filesystem.hpp>
#include <boost/filesystem/fstream.hpp>
Now the output from cmake looks ok
-- ** Search Boost root: /home/oli/usr
-- Boost version: 1.43.0
-- Found the following Boost libraries:
-- filesystem
-- regex
-- ** Boost Include: /home/oli/usr/include
-- ** Boost Libraries: /home/oli/usr/lib
-- ** Boost Libraries: /home/oli/usr/lib/libboost_filesystem.so;/home/oli/usr/lib/libboost_regex.so
But I get this error:
error: boost/regex.hpp: No such file or directory
(and similar for the other includes). Full output from make VERBOSE=1 can be found here http://pastebin.ca/2039425. It looks as though there is no -I flag added even though Boost_INCLUDE_DIR seems to be set correctly.
I'm using CMake 2.8.1 by the way.
I would very much appreciate any hints on what is going wrong here..
EDIT:
I've found the problem. Seems I pulled some ancient version of my standard CMakeLists.txt from the depths of my archives. It needs to be:
INCLUDE_DIRECTORIES(${Boost_INCLUDE_DIR})
(note the non-capitalized "Boost")...
Maybe older versions of CMake have been more tolerant in this respect or by bad luck I simply chose to start with a version of my CMakeLists.txt with an unfixed bug..
Since you did not specify a mode for find_package, it attempts to first use MODULE mode, and then CONFIG mode. As per the docs for the FindBoost module, the cache variable storing the directory containing Boost headers is named Boost_INCLUDE_DIR and not BOOST_INCLUDE_DIR. As per the CMake language docs' section on variables, CMake variable names are case-sensitive. I don't know why you had another CMakeLists.txt file with BOOST_INCLUDE_DIR working.

Resources