Reputation: 255
I'm trying to have CMake 2.8.6 link to boost::program_options using the following code in my CMakeLists.txt
FIND_PACKAGE(Boost COMPONENTS program_options REQUIRED)
INCLUDE_DIRECTORIES (${Boost_INCLUDE_DIR})
ADD_EXECUTABLE (segment segment.cpp)
TARGET_LINK_LIBRARIES (segment ${Boost_LIBRARIES})
The find command seems to succeed but passes the wrong directory to the linker. The package is actually in:
`/usr/lib64/libboost_program_options-mt.so.5`
but CMakeFiles/segment.dir/link.txt
lists the following:
/cm/shared/apps/gcc/4.4.6/bin/c++ CMakeFiles/segment.dir/segment.cpp.o -o segment -rdynamic /usr/lib64/lib64/libboost_program_options-mt.so.5 -lpthread -lrt -Wl,-rpath,/usr/lib64/lib64
Note the extra lib64
in the path. Also, the -l flag in front of the path seems to be missing.
When running CMake it reports that it correctly finds the package, and the {$Boost_LIBRARIES}
variable seems to list the correct libs:
Boost found.
Found Boost components:
program_options
${Boost_LIBRARIES} - optimized;boost_program_options-mt-shared;debug;boost_program_options-mt-shared-debug
The generated CMakeCache.txt file starts with:
//The directory containing a CMake configuration file for Boost.
Boost_DIR:PATH=/usr/lib64/boost
//Boost include directory
Boost_INCLUDE_DIR:FILEPATH=/usr/include
Which seems to be correct. But when running make it uses the path in link.txt above and I get the error:
make[2]: *** No rule to make target `/usr/lib64/lib64/libboost_program_options-mt.so.5', needed by `segment'. Stop.
make[1]: *** [CMakeFiles/segment.dir/all] Error 2
make: *** [all] Error 2
What might cause this extra injection of a subdir into the path? What might cause link.txt to be generated in this way? And how do I fix it (or work around it)?
Upvotes: 18
Views: 12088
Reputation: 2690
while building package from AUR following prefix helped to find Boost:
BOOST_ROOT=/usr
example:
BOOST_ROOT=/usr makepkg -si
Upvotes: 0
Reputation: 103
I noticed this issue on cmake version 2.8.11.2 with boost-1.41.0-18.el6.x86_64
The approved answer does not seem satisfactory because appending this define to the cmake runtime I get:
CMake Warning: Manually-specified variables were not used by the project:
Boost_NO_BOOST_CMAKE
I can't seem to comment or downvote due to not participating in stackoverflow enough. That is a chicken and egg problem!
I also can't seem to upvote the explanation by Kai Meyer. However, I think this really explains the problem.
From what I am gathering it seems that in summary, FindBoost.cmake provided by CMake seems to all of a sudden fail to find Boost, so the find code is now searching via the boost provided script for cmake, which in turn has a bug and seems to not return the correct path.
Upvotes: 0
Reputation: 326
This problem occurs when using some older versions of boost with cmake-2.8.6-rc2
or later, where the boost package finding code was changed.
The problem can be worked around by specifying -DBoost_NO_BOOST_CMAKE=ON
on the cmake command line.
The actual commit where this problem is introduced is 7da796d1fdd7cca07df733d010cd343f6f8787a9, and can be viewed here.
Upvotes: 26
Reputation: 71
The problem is with the boost-devel distributed file: /usr/lib64/boost/Boost-relwithdebinfo.cmake
The cmake-2.6 package does not use this file at all, because the FindBoost.cmake file returns (correct) full-paths to boost libraries. The cmake28-2.8.8 FindBoost.cmake file returns library strings like "boost_date_time-mt-shared", which are targets defined in /usr/lib64/boost/Boost-relwithdebinfo.cmake.
At the very top of /usr/lib64/boost/Boost-relwithdebinfo.cmake, a variable named _IMPORT_PREFIX is defined from the location of the cmake file itself, and then used like so:
#----------------------------------------------------------------
# Generated CMake target import file for configuration "RelWithDebInfo".
#----------------------------------------------------------------
# Commands may need to know the format version.
SET(CMAKE_IMPORT_FILE_VERSION 1)
# Compute the installation prefix relative to this file.
GET_FILENAME_COMPONENT(_IMPORT_PREFIX "${CMAKE_CURRENT_LIST_FILE}" PATH)
GET_FILENAME_COMPONENT(_IMPORT_PREFIX "${_IMPORT_PREFIX}" PATH)
# Import target "boost_date_time-static" for configuration "RelWithDebInfo"
SET_PROPERTY(TARGET boost_date_time-static APPEND PROPERTY IMPORTED_CONFIGURATIONS RELWITHDEBINFO)
SET_TARGET_PROPERTIES(boost_date_time-static PROPERTIES
IMPORTED_LOCATION_RELWITHDEBINFO "${_IMPORT_PREFIX}/lib64/libboost_date_time.a"
)
This sets _IMPORT_PREFIX to "/usr/lib64", which is concatenated with another string that has /lib64/ in it as well. I found that if I simply change the file to include a 3rd GET_FILENAME_COMPONENT call, it works fine. Like so:
#----------------------------------------------------------------
# Generated CMake target import file for configuration "RelWithDebInfo".
#----------------------------------------------------------------
# Commands may need to know the format version.
SET(CMAKE_IMPORT_FILE_VERSION 1)
# Compute the installation prefix relative to this file.
GET_FILENAME_COMPONENT(_IMPORT_PREFIX "${CMAKE_CURRENT_LIST_FILE}" PATH)
GET_FILENAME_COMPONENT(_IMPORT_PREFIX "${_IMPORT_PREFIX}" PATH)
GET_FILENAME_COMPONENT(_IMPORT_PREFIX "${_IMPORT_PREFIX}" PATH)
# Import target "boost_date_time-static" for configuration "RelWithDebInfo"
SET_PROPERTY(TARGET boost_date_time-static APPEND PROPERTY IMPORTED_CONFIGURATIONS RELWITHDEBINFO)
SET_TARGET_PROPERTIES(boost_date_time-static PROPERTIES
IMPORTED_LOCATION_RELWITHDEBINFO "${_IMPORT_PREFIX}/lib64/libboost_date_time.a"
)
Upvotes: 7
Reputation: 1455
I also see the problem on the pre-compiled cmake version 2.8.8 using CentOS 64-bit 6.2
Upvotes: 3
Reputation: 255
This seems to be an issue with CMake 2.8.6 on CentOS. When doing the same with 2.6.4 or 2.8.3 it works correctly. Also with 2.8.7 on OS X it also works correctly.
Upvotes: 4