CMake doesn't find Boost libraries

2019-01-23 04:50发布

问题:

I'm trying to use a CMake script to compile a Boost-based application on Windows. The header-only libraries work fine, but CMake fails to find the libraries (the following Boost libraries could not be found: boost_serialization). The relevant part of the CMake script is:

# Path where CMake can find additional libraries
SET(CMAKE_PREFIX_PATH Libs)

# Boost
SET(Boost_ADDITIONAL_VERSIONS "1.47" "1.47.0")
SET(Boost_USE_STATIC_LIBS   ON)
find_package(Boost REQUIRED COMPONENTS serialization)

I have a folder called "Libs" inside my project where third-party libraries such as DevIL and Boost are stored, so I set this first. It works fine for Devil and Boost header-only stuff, so I assume I should not need the BOOST_ROOT variable. The Boost installation is the standard source distribution from boost.org which I compiled with BJam. The libraries are stored in boost_1_47_0\bin.v2\libs, and I didn't change anything in the build process.

I think it is a bit odd, that the boost_1_47_0\libs folder doesn't contain any library files but BJam files and other stuff, but that shouldn't be a problem since this seems to be the normal way to build Boost on Windows from the source.

I looked at the Debug output from the FindBoost.cmake file (I'm using the default script from CMake 2.8) and it doesn't seem to look into bin.v2. Instead it searches boost_ROOT/lib, but when I copied the content from bin.v2\libs to lib it still didn't find anything.

So what is an elegant way to find Boost that will also work on other platforms with common Boost distributions?

回答1:

I would try setting BOOST_ROOT inside your CMakeLists.txt file. I know that CMake 2.8.6 will find Boost 1.47.0 when you set the Boost_ADDITIONAL_VERSIONS variable since it works for me on Windows when I have BOOST_ROOT set.

Here is what I have in one project:


    set( BOOST_COMPONENTS_NEEDED serialization )

    # The following verifyies that BOOST_ROOT is set properly.
    if(NOT BOOST_ROOT AND NOT $ENV{BOOST_ROOT} STREQUAL "")
        FILE( TO_CMAKE_PATH $ENV{BOOST_ROOT} BOOST_ROOT )
        if( NOT EXISTS ${BOOST_ROOT} )
            MESSAGE( STATUS  ${BOOST_ROOT} " does not exist. Checking if BOOST_ROOT was a quoted string.." )
            STRING( REPLACE "\"" "" BOOST_ROOT ${BOOST_ROOT} )
            if( EXISTS ${BOOST_ROOT} )
                MESSAGE( STATUS "After removing the quotes " ${BOOST_ROOT} " was now found by CMake" )
            endif( EXISTS ${BOOST_ROOT})
        endif( NOT EXISTS ${BOOST_ROOT} )

    # Save the BOOST_ROOT in the cache
        if( NOT EXISTS ${BOOST_ROOT} )
            MESSAGE( WARNING ${BOOST_ROOT} " does not exist." )
        else(NOT EXISTS ${BOOST_ROOT})
            SET (BOOST_ROOT ${BOOST_ROOT} CACHE STRING "Set the value of BOOST_ROOT to point to the root folder of your boost install." FORCE)
            #SET (BOOST_INCLUDEDIR ${BOOST_ROOT}/Include)
            #SET (BOOST_LIBRARYDIR ${BOOST_ROOT}/lib)
        endif( NOT EXISTS ${BOOST_ROOT} )

    endif(NOT BOOST_ROOT AND NOT $ENV{BOOST_ROOT} STREQUAL "")

    if( WIN32 AND NOT BOOST_ROOT )
        MESSAGE( WARNING "Please set the BOOST_ROOT environment variable." )
    endif( WIN32 AND NOT BOOST_ROOT )

    set(Boost_ADDITIONAL_VERSIONS "1.47" "1.47.0")
    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.47.0 COMPONENTS ${BOOST_COMPONENTS_NEEDED})
    if(Boost_FOUND)
        MESSAGE( STATUS "Setting up boost." )
        include_directories(${Boost_INCLUDE_DIRS})
        if(Boost_DEBUG)
            MESSAGE( STATUS "BOOST Libraries " ${Boost_LIBRARIES} )
            FOREACH(BOOST_COMPONENT ${BOOST_COMPONENTS_NEEDED})
                STRING( TOUPPER ${BOOST_COMPONENT} BOOST_COMPONENT_UPCASE )
                MESSAGE( STATUS "Boost " ${BOOST_COMPONENT} ": " ${Boost_${BOOST_COMPONENT_UPCASE}_LIBRARY} )
                MESSAGE( STATUS "Boost " ${BOOST_COMPONENT} " Debug: " ${Boost_${BOOST_COMPONENT_UPCASE}_LIBRARY_DEBUG} )
                MESSAGE( STATUS "Boost " ${BOOST_COMPONENT} " Release: " ${Boost_${BOOST_COMPONENT_UPCASE}_LIBRARY_RELEASE} )
            ENDFOREACH(BOOST_COMPONENT)
        endif(Boost_DEBUG)
    endif(Boost_FOUND)



回答2:

Well, I solved the problem, but I'm not fully satisfied with my solution.

In my opinion the problem was that BJam creates a too complex folder structure. Now I just copied the library files from "boost_1_47_0\bin.v2\libs\serialization\build\msvc-9.0\debug\link-static\threading-multi" to "boost_1_47_0\lib".

I have to do this by hand, but I'm not using that many Boost libraries, so this step is OK in my opinion. I will document my solution aside the CMake script, so other users should get along with that.



回答3:

I've had a problem with this before. For some reason b2 (aka BJam) created the Boost libraries with a leading "lib".

The CMake script will not look for a file named libboost_thread.lib. It will only find boost_thread.lib. Remove the leading lib and CMake should find them.



回答4:

I came here with a similar issue and just wanted to say my fix was similar, but not exactly the same.

My install prefix was C:\lib\boost\boost_1_57_0. I set a BOOST_ROOT environment variable pointing to that directory, but CMake (3.1.0) still couldn't find the headers. I realized the headers defaulted to install to C:\lib\boost\boost_1_57_0\include\boost-1_57\boost. I'm not going to run multiple versions so I just moved the final Boost directory down one and removed the boost-1_57 directory and ended up with headers here:

C:\lib\boost\boost_1_57_0\include\boost

And CMake found everything.



回答5:

You can add the following option to the command line of CMake to tell CGAL to use the static Boost libraries:

-DCGAL_Boost_USE_STATIC_LIBS=true