How can I get CMake to find my alternative Boost i

2020-01-25 04:52发布

问题:

I have installed the most recent version of Boost in /usr/local (with includes in /usr/local/include/boost and libraries in /usr/local/lib/boost) and I am now attempting to install Wt from source, but CMake (version 2.6) can't seem to find the Boost installation. It tries to give helpful suggestions about setting BOOST_DIR and Boost_LIBRARYDIR, but I haven't been able to get it to work by tweaking these variables.

The most recent error message that I get is that it can't find the libraries, but it seems to indicate that it is using "/usr/local/include" for the include path, which isn't correct (and I can't seem to fix it). Is there a solution for this off the top of their head, or do I need to go mucking around inside CMake to figure it out?

回答1:

You should have a look at FindBoost.cmake script, which handles Boost detection and setting up all Boost variables. It typically resides in /usr/share/cmake-2.6/Modules/. In it, you will find documentation. For instance:

# These last three variables are available also as environment variables:
#
#   BOOST_ROOT or BOOSTROOT      The preferred installation prefix for searching for
#                                Boost.  Set this if the module has problems finding
#                                the proper Boost installation.
#

In contrast to BOOST_ROOT, the variables you are referring to are actually variables that are set by the FindBoost module. Note that you don't have to (and probably also don't want to) edit your CMake project configuration to set BOOST_ROOT. Instead, you should use the environment variable, e.g. calling

# BOOST_ROOT=/usr/local/... ccmake .



回答2:

I was finally able to get what I wanted with

cmake -DCMAKE_INSTALL_PREFIX=$TARGET \
    -DBoost_NO_BOOST_CMAKE=TRUE \
    -DBoost_NO_SYSTEM_PATHS=TRUE \
    -DBOOST_ROOT:PATHNAME=$TARGET \
    -DBoost_LIBRARY_DIRS:FILEPATH=${TARGET}/lib


回答3:

The short version

You only need BOOST_ROOT, but you're going to want to disable searching the system for your local Boost if you have multiple installations or cross-compiling for iOS or Android. In which case add Boost_NO_SYSTEM_PATHS is set to false.

set( BOOST_ROOT "" CACHE PATH "Boost library path" )
set( Boost_NO_SYSTEM_PATHS on CACHE BOOL "Do not search system for Boost" )

Normally this is passed on the CMake command-line using the syntax -D<VAR>=value.

The longer version

Officially speaking the FindBoost page states these variables should be used to 'hint' the location of Boost.

This module reads hints about search locations from variables:

BOOST_ROOT             - Preferred installation prefix
 (or BOOSTROOT)
BOOST_INCLUDEDIR       - Preferred include directory e.g. <prefix>/include
BOOST_LIBRARYDIR       - Preferred library directory e.g. <prefix>/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)

This makes a theoretically correct incantation:

cmake -DBoost_NO_SYSTEM_PATHS=TRUE \
      -DBOOST_ROOT=/path/to/boost-dir

When you compile from source

include( ExternalProject )

set( boost_URL "http://sourceforge.net/projects/boost/files/boost/1.63.0/boost_1_63_0.tar.bz2" )
set( boost_SHA1 "9f1dd4fa364a3e3156a77dc17aa562ef06404ff6" )
set( boost_INSTALL ${CMAKE_CURRENT_BINARY_DIR}/third_party/boost )
set( boost_INCLUDE_DIR ${boost_INSTALL}/include )
set( boost_LIB_DIR ${boost_INSTALL}/lib )

ExternalProject_Add( boost
        PREFIX boost
        URL ${boost_URL}
        URL_HASH SHA1=${boost_SHA1}
        BUILD_IN_SOURCE 1
        CONFIGURE_COMMAND
        ./bootstrap.sh
        --with-libraries=filesystem
        --with-libraries=system
        --with-libraries=date_time
        --prefix=<INSTALL_DIR>
        BUILD_COMMAND
        ./b2 install link=static variant=release threading=multi runtime-link=static
        INSTALL_COMMAND ""
        INSTALL_DIR ${boost_INSTALL} )

set( Boost_LIBRARIES
        ${boost_LIB_DIR}/libboost_filesystem.a
        ${boost_LIB_DIR}/libboost_system.a
        ${boost_LIB_DIR}/libboost_date_time.a )
message( STATUS "Boost static libs: " ${Boost_LIBRARIES} )

Then when you call this script you'll need to include the boost.cmake script (mine is in the a subdirectory), include the headers, indicate the dependency, and link the libraries.

include( boost )
include_directories( ${boost_INCLUDE_DIR} )
add_dependencies( MyProject boost )
target_link_libraries( MyProject
                       ${Boost_LIBRARIES} )


回答4:

Generally the most common mistake is not cleaning your build directory after adding new options. I have Boost installed from system packet manager. Its version is 1.49.

I also downloaded Boost 1.53 and "installed" it under $HOME/installs.

The only thing that I had to do in my project was to (I keep sources in my_project_directory/src):

cd my_project_directory
mkdir build
cd build
cmake -DCMAKE_INCLUDE_PATH=$HOME/installs/include -DCMAKE_LIBRARY_PATH=$HOME/installs/lib ../src

And that's it. Ta bum tss.

But if I'd make after cd build -> cmake ../src it would set Boost from the system path. Then doing cmake -DCMAKE_INCLUDE_PATH=$HOME/installs/include -DCMAKE_LIBRARY_PATH=$HOME/installs/lib ../src would change nothing.

You have to clean your build directory ( cd build && rm -rf * ;) )



回答5:

I had a similar issue, CMake finding a vendor-installed Boost only, but my cluster had a locally installed version which is what I wanted it to use. Red Hat Linux 6.

Anyway, it looks like all the BOOSTROOT, BOOST_ROOT, and Boost_DIR stuff would get annoyed unless one also sets Boost_NO_BOOST_CMAKE (e.g add to cmd line -DBoost_NO_BOOST_CMAKE=TRUE).

(I will concede the usefulness of CMake for multiplatform, but I can still hate it.)



回答6:

There is a generic method to give CMake directions about where to find libraries.

When looking for a library, CMake looks first in the following variables:

  • CMAKE_LIBRARY_PATH and LD_LIBRARY_PATH for libraries
  • CMAKE_INCLUDE_PATH and INCLUDE_PATH for includes

If you declare your Boost files in one of the environment variables, CMake will find it. Example:

export CMAKE_LIBRARY_PATH="/stuff/lib.boost.1.52/lib:$CMAKE_LIBRARY_PATH"
export CMAKE_INCLUDE_PATH="/stuff/lib.boost.1.52/include:$CMAKE_INCLUDE_PATH"

If it's too cumbersome, you can also use a nice installing tool I wrote that will do everything for you: C++ version manager



回答7:

I had a similar issue, and I could use customized Boost libraries by adding the below lines to my CMakeLists.txt file:

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 REQUIRED regex date_time system filesystem thread graph program_options)
include_directories(${BOOST_INCLUDE_DIRS})


回答8:

After digging around in CMake and experimenting, I determined that CMake was unhappy with the fact that all of my Boost libraries were contained in /usr/local/lib/boost and not /usr/local/lib. Once I soft-linked them back out, the build worked.



回答9:

I spent most of my evening trying to get this working. I tried all of the -DBOOST_* &c. directives with CMake, but it kept linking to my system Boost libraries, even after clearing and re-configuring my build area repeatedly.

At the end I modified the generated Makefile and voided the cmake_check_build_system target to do nothing (like 'echo ""') so that it wouldn't overwrite my changes when I ran make, and then did 'grep -rl "lboost_python" * | xargs sed -i "s:-lboost_python:-L/opt/sw/gcc5/usr/lib/ -lboost_python:g' in my build/ directory to explicitly point all the build commands to the Boost installation I wanted to use. Finally, that worked.

I acknowledge that it is an ugly kludge, but I am just putting it out here for the benefit of those who come up against the same brick wall, and just want to work around it and get work done.



回答10:

I also encountered the same problem, but trying the hints here didn't help, unfortunately.

The only thing that helped was to download the newest version from the Boost page, compile and install it as described in Installing Boost 1.50 on Ubuntu 12.10.

In my case I worked with Boost 1.53.



回答11:

I ran into a similar problem on a Linux server, where two versions of Boost have been installed. One is the precompiled 1.53.0 version which counts as old in 2018; it's in /usr/include and /usr/lib64. The version I want to use is 1.67.0, as a minimum version of 1.65.1 is required for another C++ library I'm installing; it's in /opt/boost, which has include and lib subdirectories. As suggested in previous answers, I set variables in CMakeLists.txt to specify where to look for Boost 1.67.0 as follows

include_directories(/opt/boost/include/)
include_directories(/opt/boost/lib/)
set(BOOST_ROOT /opt/boost/)
set(BOOST_INCLUDEDIR /opt/boost/include/)
set(BOOST_LIBRARYDIR /opt/boost/lib)
set(Boost_NO_SYSTEM_PATHS TRUE)
set(Boost_NO_BOOST_CMAKE TRUE)

But CMake doesn't honor those changes. Then I found an article online: CMake can use a local Boost, and realized that I need to change the variables in CMakeCache.txt. There I found that the Boost-related variables are still pointing to the default Boost 1.53.0, so no wonder CMake doesn't honor my changes in CMakeLists.txt. Then I set the Boost-related variables in CMakeCache.txt

Boost_DIR:PATH=Boost_DIR-NOTFOUND
Boost_INCLUDE_DIR:PATH=/opt/boost/include/
Boost_LIBRARY_DIR_DEBUG:PATH=/opt/boost/lib
Boost_LIBRARY_DIR_RELEASE:PATH=/opt/boost/lib

I also changed the variables pointing to the non-header, compiled parts of the Boost library to point to the version I want. Then CMake successfully built the library that depends on a recent version of Boost.



回答12:

While configure could find my Boost installation, CMake could not.

Locate FindBoost.cmake and look for LIBRARY_HINTS to see what sub-packages it is looking for. In my case it wanted the MPI and graph libraries.

 # Compute component-specific hints.
  set(_Boost_FIND_LIBRARY_HINTS_FOR_COMPONENT "")
  if(${COMPONENT} STREQUAL "mpi" OR ${COMPONENT} STREQUAL "mpi_python" OR
     ${COMPONENT} STREQUAL "graph_parallel")
    foreach(lib ${MPI_CXX_LIBRARIES} ${MPI_C_LIBRARIES})
      if(IS_ABSOLUTE "${lib}")
        get_filename_component(libdir "${lib}" PATH)
        string(REPLACE "\\" "/" libdir "${libdir}")
        list(APPEND _Boost_FIND_LIBRARY_HINTS_FOR_COMPONENT ${libdir})
      endif()
    endforeach()
  endif()

apt-cache search ... I installed the dev packages since I was building code, and the dev package drags in all the dependencies. I'm not so sure that a standard Boost install needs Open MPI, but this is OK for now.

sudo apt-get install libboost-mpi-dev libboost-mpi-python-dev
sudo apt-get install libboost-graph-parallel-dev