Search code examples
boostcmakerpath

How to use CMake RPath for boost.Python


I'm writing a Python extension module in C++ using Boost.Python. However, I would like to use a newer version of the Boost library than the system installation offers. This newer version of boost is contained in BOOST_ROOT=$HOME/opt/boost/1.55.0.

Following this guide on how to use RPath in CMake I came up with the following CMakeLists.txt.

cmake_minimum_required(VERSION 2.8)
project("test")
set(PROJECT_DESC "Test Boost.Python")

set(CMAKE_SKIP_BUILD_RPATH  FALSE)
set(CMAKE_BUILD_WITH_INSTALL_RPATH TRUE) 
set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)

add_definitions(-std=c++11 -Wall -Wextra -pedantic)

find_package(PythonInterp REQUIRED)
find_package(PythonLibsNew REQUIRED)
find_package(Boost COMPONENTS python REQUIRED)
message(STATUS "Using Boost installation in:")
message(STATUS "  INCLUDE: ${Boost_INCLUDE_DIRS}")
message(STATUS "  LIB: ${Boost_LIBRARIES}")

include_directories(
    ${PROJECT_SOURCE_DIR}
    ${PYTHON_INCLUDE_DIRS}
    ${Boost_INCLUDE_DIRS} 
)

macro(add_python_module _name _srccpp)
    PYTHON_ADD_MODULE(${_name} ${_srccpp})
    target_link_libraries(${_name} ${Boost_LIBRARIES})
endmacro()

add_python_module(ownership ownership.cpp)

Then I run the following commands to build the module

mkdir build; cd build
cmake -DCMAKE_INSTALL_PATH="$BOOST_ROOT/lib" ..
make

The status message after running cmake points to the right boost installation. (The CMake boost module picks up the environment variable $BOOST_ROOT) I.e. the CMake variable Boost_LIBARIES points to $BOOST_ROOT/lib/libboost_python.so.

But, if I check which libraries would actually be used, the system libraries are listed:

$ ldd ownership.so
# ...
libboost_python.so.1.53.0 => /usr/lib64/libboost_python.so.1.53.0 (0x00007f09abfc1000)
# ...

This is version 1.53, even though the status message above explicitely pointed to 1.55.

What am I doing wrong? How can I get ldd to pick the library in $BOOST_ROOT/lib/libboost_python.so.1.55.0?


Solution

  • First of all as I already mentioned in commens you don't need to use CMake RPATH-manipulations options. Example: http://pastebin.com/UDyYbQ1d, output: standard and custom

    Do you know of a way of convincing CMake otherwise even if LIBRARY_PATH is set

    This issue is not related to CMake, it's compiler responsibility. Read this discussion.

    Solution

    You can clear LIBRARY_PATH if you set BOOST_ROOT variable explicitly. And you can check environment variable in CMakeLists.txt to avoid this problem in future:

    string(COMPARE NOTEQUAL "$ENV{LIBRARY_PATH}" "" library_path_warning)
    if(library_path_warning)
      message(
          WARNING
          "LIBRARY_PATH environment variable is not empty ($ENV{LIBRARY_PATH}) "
          "This may cause dynamic linking errors!"
      )
    endif()