Reputation: 13140
My CMakeLists.txt file makes cmake point to the wrong version of Boost:
find_package(Boost COMPONENTS program_options)
In my case it points to Boost 1.39 in /otherDir/boost
instead of Boost 1.50 in /usr/local/include/boost
.
Since the version of Boost will change, I would like to avoid specifying it with:
find_package(Boost 1.50 COMPONENTS program_options)
or having to set the environment variable $ENV{BOOST_ROOT}.
The problem is due to the fact that the directory hierarchy has the following structure:
/usr/local/include/boost
/otherDir/boost
/otherDir/otherNeededFiles
and my CMakeLists.txt file contains:
include_directories(${Boost_INCLUDE_DIRS})
include_directories(/usr/local/include)
include_directories(/otherDir)
The value of Boost_INCLUDE_DIRS
is correct (/usr/local/include
), as the value of Boost_LIBRARIES
(/usr/local/lib/libboost_program_options.a
).
If I rename /otherDir/boost
as /otherDir/boost_old
, the linker is happy and points to the latest boost version. However I am not allowed to rename that directory.
Is it possible to do the equivalent of:
find_package(Boost latest COMPONENTS program_options)
Thank you.
Upvotes: 0
Views: 2696
Reputation: 1945
This is what we use. ${THIRD_PARTY}/boost/boost_1_55_0/... is what is on disk. Boost_NO_SYSTEM_PATHS makes it ignore other possible locations. Only the version I care about is inside ${THIRD_PARTY}/boost, so I have exact control over updating.
# get boost
set(Boost_NO_SYSTEM_PATHS ON)
set(BOOST_ROOT ${THIRD_PARTY}/boost)
set(Boost_USE_STATIC_LIBS OFF)
set(Boost_USE_MULTITHREADED ON)
find_package(Boost COMPONENTS REQUIRED
system
date_time
filesystem
thread
regex)
include_directories(${Boost_INCLUDE_DIRS})
link_directories(${Boost_LIBRARY_DIRS})
message(STATUS "BOOST_ROOT = ${BOOST_ROOT}")
message(STATUS "Boost_VERSION = ${Boost_VERSION}")
message(STATUS "Boost_LIB_VERSION = ${Boost_LIB_VERSION}")
message(STATUS "Boost_MAJOR_VERSION = ${Boost_MAJOR_VERSION}")
message(STATUS "Boost_MINOR_VERSION = ${Boost_MINOR_VERSION}")
message(STATUS "Boost_LIBRARIES = ${Boost_LIBRARIES}")
message(STATUS "Boost_INCLUDE_DIRS = ${Boost_INCLUDE_DIRS}")
message(STATUS "Boost_LIBRARY_DIRS = ${Boost_LIBRARY_DIRS}")
What you want is not reliable due to how FindBoost works. It will look in all locations for "system" and then use the first one found. Even if this means the other required ones are not there. Worse, in your case it is using old versions.
Upvotes: 1
Reputation: 6784
Something like
find_package(Boost latest COMPONENTS program_options)
is not automatically possible with your application layout as find macros in CMake are only heuristics. This means each find macro searches for a library in a list of possible directories envisioned by the programmer of the find macro. Usually a find macro will take the first occurrence of a library it found, but there is no rule like that. The only additional specification currently generically envisioned by CMake is version matching for either a minimum or an exact version. And even the implementation of this matching is currently performed by each find macro on its own and might even be ignored. Hence, there is no such thing as latest available in a generic form.
What you could do is to copy the Find_Boost.cmake from CMake over to you own project (if licenses permit) and modify it in a way that it will always search for the highest version available. But of course then you have to maintain that macro on your own which will cause work, especially for the complex boost installation layout.
Generally, if you have multiple version of the same software installed outside of standard location this is knowledge that should not be embedded inside the build logic of specific projects, because this might lead to problems on other systems with other assumptions. Instead it is knowledge of the administrator of the system which he or she has to pass into the build system of the project externally. My recommendation would be that inside your find_package call you correctly specify the minimum version of boost you require for your software to compile and run. However, the specific version to use from your specific installation on your system needs to be passed in externally by defining BOOST_ROOT on the CMake command line.
Upvotes: 1