CMake found and NOT found boost simultaneously - boost

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.

Related

CMake doesn't add dependency libraries to the project files

I am writing a simple example code using pcl just as the link
http://pointclouds.org/documentation/tutorials/writing_pcd.php.
Even though I follow the link, Visual studio reports link errors.
The reason is that pcl depends on boost library and cmake doesn't
add boost library to the project setting files of visual studio.
If I add boost library with the following line, everything will be OK.
target_link_libraries(progname ${Boost_LIBRARIES})
Why doesn't CMake handle this? Is there a better solution?
CMake: 3.13.2,
Visual studio: Community 2017
PCL: PCL-1.9.1-AllInOne-msvc2017-win64.exe
Edit:
CMakeLists.txt
cmake_minimum_required(VERSION 2.6 FATAL_ERROR)
project(MY_GRAND_PROJECT)
set(Boost_DEBUG ON)
set(Boost_USE_STATIC_LIBS OFF)
set(Boost_USE_MULTITHREADED ON)
set(Boost_USE_STATIC_RUNTIME OFF)
find_package(Boost 1.45.0)
find_package(PCL 1.9.1 REQUIRED COMPONENTS common io)
include_directories(${PCL_INCLUDE_DIRS})
link_directories(${PCL_LIBRARY_DIRS})
add_definitions(${PCL_DEFINITIONS})
add_executable(pcd_write_test pcd_write.cpp)
target_link_libraries(pcd_write_test ${PCL_COMMON_LIBRARIES} ${PCL_IO_LIBRARIES} ${Boost_LIBRARIES})
According to the PCLConfig.cmake script in the official repo, Boost libraries are appended to the PCL_LIBRARIES variable. (This is performed near the end of the script).
So, for automatically link with Boost libraries when use PCL, you need to use PCL_LIBRARIES variable for linking, not PCL_<comp>_LIBRARIES variables.
I don't know, whether given behaviour is intended or not. If you assume that Boost libraries should be part of PCL_<comp>_LIBRARIES variables too, then you may fill a bug-report about that.

How to properly link boost with cmake

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.

CMake and Visual Studio 2010 and Additional Library Directories

How can I tell CMake that I want it to generate a Visual Studio 2010 solution by setting also the "Additional Library Directories" field in the "Linker" section of the Project properties?
Language is C++ and not using the .NET platform, simply I want that my project to find the stage/lib dir where Boost .lib and .dll are stored...
Obviously, I have tried with following settings but, while the field Additional include dirs for the compiler are correctly set, the Additional library dirs for the linker still remains empty...
unset(Boost_LIBRARIES)
find_package(Boost 1.55.0 REQUIRED COMPONENTS system filesystem)
if(Boost_FOUND)
set(Boost_USE_STATIC_LIBS OFF)
set(Boost_USE_MULTITHREADED ON)
set(BOOST_LIBRARYDIR stage/lib)
include_directories(${Boost_INCLUDE_DIRS})
endif()
...
target_link_libraries(cpp-lib ${Boost_LIBRARIES})
I specify also that I want to use the dynamic version of Boost libs, that is why I set the switch USE_STATIC_LIBS to OFF for the use of the static version of Boost at the beginning of the CMakelists.txt.
This is what has been put in the Additional Dependencies field (beyond the usual .lib automatically specified there by Visual Studio):
C:\Program Files\boost\boost_1_56_0\stage\lib\boost_system-vc100-mt-gd-1_56.lib
C:\Program Files\boost\boost_1_56_0\stage\lib\boost_filesystem-vc100-mt-gd-1_56.lib
Beyond the wrong field in which this has been written, I would also add that the above lines are not what I want. I would like to have only the specification of the Boost .lib and .dll path, that is simply:
C:\Program Files\boost\boost_1_56_0\stage\lib\
I have tried by putting this last path in the Linker->General->Additional Library Directories field and all compiles fine, so I need a way to tell CMake to set the correct path (the last above) in the correct field (Linker->General->Additional Library Directories).
Tnx a lot
D.
By using link_directories(), I was able to update "Additional Library Directories" field in the "Linker" section of the Project properties.
find_package(Boost 1.55.0 REQUIRED COMPONENTS system filesystem)
if(Boost_FOUND)
set(Boost_USE_STATIC_LIBS OFF)
set(Boost_USE_MULTITHREADED ON)
set(BOOST_LIBRARYDIR stage/lib)
include_directories(${Boost_INCLUDE_DIRS})
link_directories(${Boost_LIBRARY_DIRS})
endif()
... so I need a way to tell CMake to set the correct path (the last
above) in the correct field (Linker->General->Additional Library
Directories).
CMake link_directories maps to VS Properties->Linker->General->Additional Library Directories
Related to it, CMake target_link_libraries maps to VS Properties->Linker->Input->Additional Dependencies.
Take a look at CMake and Visual Studio which lists other CMake commands in the context of Visual Studio with an example.

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()

How do you add Boost libraries in CMakeLists.txt?

I need to add Boost libraries into my CMakeLists.txt. How do you do it or how do you add it?
Put this in your CMakeLists.txt file (change any options from OFF to ON if you want):
set(Boost_USE_STATIC_LIBS OFF)
set(Boost_USE_MULTITHREADED ON)
set(Boost_USE_STATIC_RUNTIME OFF)
find_package(Boost 1.45.0 COMPONENTS *boost libraries here*)
if(Boost_FOUND)
include_directories(${Boost_INCLUDE_DIRS})
add_executable(progname file1.cxx file2.cxx)
target_link_libraries(progname ${Boost_LIBRARIES})
endif()
Obviously you need to put the libraries you want where I put *boost libraries here*. For example, if you're using the filesystem and regex library you'd write:
find_package(Boost 1.45.0 COMPONENTS filesystem regex)
You can use find_package to search for available boost libraries. It defers searching for Boost to FindBoost.cmake, which is default installed with CMake.
Upon finding Boost, the find_package() call will have filled many variables (check the reference for FindBoost.cmake). Among these are BOOST_INCLUDE_DIRS, Boost_LIBRARIES and Boost_XXX_LIBRARY variabels, with XXX replaced with specific Boost libraries. You can use these to specify include_directories and target_link_libraries.
For example, suppose you would need boost::program_options and boost::regex, you would do something like:
find_package( Boost REQUIRED COMPONENTS program_options regex )
include_directories( ${Boost_INCLUDE_DIRS} )
add_executable( run main.cpp ) # Example application based on main.cpp
# Alternatively you could use ${Boost_LIBRARIES} here.
target_link_libraries( run ${Boost_PROGRAM_OPTIONS_LIBRARY} ${Boost_REGEX_LIBRARY} )
Some general tips:
When searching, FindBoost checks the environment variable $ENV{BOOST_ROOT}. You can set this variable before calling find_package if necessary.
When you have multiple build-versions of boost (multi-threaded, static, shared, etc.) you can specify you desired configuration before calling find_package. Do this by setting some of the following variables to On: Boost_USE_STATIC_LIBS, Boost_USE_MULTITHREADED, Boost_USE_STATIC_RUNTIME
When searching for Boost on Windows, take care with the auto-linking. Read the "NOTE for Visual Studio Users" in the reference.
My advice is to disable auto-linking and use cmake's dependency handling: add_definitions( -DBOOST_ALL_NO_LIB )
In some cases, you may need to explicitly specify that a dynamic Boost is used: add_definitions( -DBOOST_ALL_DYN_LINK )
Adapting #LainIwakura's answer for modern CMake syntax with imported targets, this would be:
set(Boost_USE_STATIC_LIBS OFF)
set(Boost_USE_MULTITHREADED ON)
set(Boost_USE_STATIC_RUNTIME OFF)
find_package(Boost 1.45.0 COMPONENTS filesystem regex)
if(Boost_FOUND)
add_executable(progname file1.cxx file2.cxx)
target_link_libraries(progname Boost::filesystem Boost::regex)
endif()
Note that it is not necessary anymore to specify the include directories manually, since it is already taken care of through the imported targets Boost::filesystem and Boost::regex.
regex and filesystem can be replaced by any boost libraries you need.
May this could helpful for some people. I had a naughty error:
undefined reference to symbol '_ZN5boost6system15system_categoryEv'
//usr/lib/x86_64-linux-gnu/libboost_system.so.1.58.0: error adding symbols: DSO missing from command line
There were some issue of cmakeList.txt and somehow I was missing to explicitly include the "system" and "filesystem" libraries. So, I wrote these lines in CMakeLists.txt
These lines are written at the beginning before creating the executable of the project, as at this stage we don't need to link boost library to our project executable.
set(Boost_USE_STATIC_LIBS OFF)
set(Boost_USE_MULTITHREADED ON)
set(Boost_USE_STATIC_RUNTIME OFF)
set(Boost_NO_SYSTEM_PATHS TRUE)
if (Boost_NO_SYSTEM_PATHS)
set(BOOST_ROOT "${CMAKE_CURRENT_SOURCE_DIR}/../../3p/boost")
set(BOOST_INCLUDE_DIRS "${BOOST_ROOT}/include")
set(BOOST_LIBRARY_DIRS "${BOOST_ROOT}/lib")
endif (Boost_NO_SYSTEM_PATHS)
find_package(Boost COMPONENTS regex date_time system filesystem thread graph program_options)
find_package(Boost REQUIRED regex date_time system filesystem thread graph program_options)
find_package(Boost COMPONENTS program_options REQUIRED)
Now at the end of the file, I wrote these lines by considering "KeyPointEvaluation" as my project executable.
if(Boost_FOUND)
include_directories(${BOOST_INCLUDE_DIRS})
link_directories(${Boost_LIBRARY_DIRS})
add_definitions(${Boost_DEFINITIONS})
include_directories(${Boost_INCLUDE_DIRS})
target_link_libraries(KeyPointEvaluation ${Boost_LIBRARIES})
target_link_libraries( KeyPointEvaluation ${Boost_PROGRAM_OPTIONS_LIBRARY} ${Boost_FILESYSTEM_LIBRARY} ${Boost_REGEX_LIBRARY} ${Boost_SYSTEM_LIBRARY})
endif()
Try as saying Boost documentation:
set(Boost_USE_STATIC_LIBS ON) # only find static libs
set(Boost_USE_DEBUG_LIBS OFF) # ignore debug libs and
set(Boost_USE_RELEASE_LIBS ON) # only find release libs
set(Boost_USE_MULTITHREADED ON)
set(Boost_USE_STATIC_RUNTIME OFF)
find_package(Boost 1.66.0 COMPONENTS date_time filesystem system ...)
if(Boost_FOUND)
include_directories(${Boost_INCLUDE_DIRS})
add_executable(foo foo.cc)
target_link_libraries(foo ${Boost_LIBRARIES})
endif()
Don't forget to replace foo to your project name and components to yours!
I agree with the answers 1 and 2. However, I prefer to specify each library separately. This makes the depencencies clearer in big projects.
Yet, there is the danger of mistyping the (case-sensitive) variable names.
In that case there is no direct cmake error but some undefined references linker issues later on, which may take some time to resolve. Therefore I use the following cmake function:
function(VerifyVarDefined)
foreach(lib ${ARGV})
if(DEFINED ${lib})
else(DEFINED ${lib})
message(SEND_ERROR "Variable ${lib} is not defined")
endif(DEFINED ${lib})
endforeach()
endfunction(VerifyVarDefined)
For the example mentioned above, this looks like:
VerifyVarDefined(Boost_PROGRAM_OPTIONS_LIBRARY Boost_REGEX_LIBRARY)
target_link_libraries( run ${Boost_PROGRAM_OPTIONS_LIBRARY} ${Boost_REGEX_LIBRARY} )
If I had written "BOOST_PROGRAM_OPTIONS_LIBRARY" there would have been an error triggered by cmake and not much later triggered by the linker.
Additional information to answers above for those still having problems.
Last version of Cmake's FindBoost.cmake may not content last
version fo Boost. Add it if needed.
Use -DBoost_DEBUG=0 configuration flag to see info on problems.
See for library naming format. Use Boost_COMPILER and Boost_ARCHITECTURE suffix vars if needed.
If you are using custome boost path, set CMAKE_PREFIX_PATH firstly. So, cmake can find your custome boost.
list(FIND CMAKE_PREFIX_PATH ${CUSTOME_BOOST_DEP_PREFIX} _INDEX)
if (_INDEX EQUAL -1)
list(APPEND CMAKE_PREFIX_PATH ${CUSTOME_BOOST_DEP_PREFIX})
# set(CMAKE_PREFIX_PATH ${CMAKE_PREFIX_PATH} PARENT_SCOPE)
endif ()
By the way, if you run above code in sub cmake file, should set CMAKE_PREFIX_PATH back to parent scope.
set(CMAKE_PREFIX_PATH ${CMAKE_PREFIX_PATH} PARENT_SCOPE)
If you want find all components of boost, using below code.
find_package(Boost 1.76 COMPONENTS ALL)

Resources