19

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?

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
JonathanK
  • 827
  • 1
  • 6
  • 23

5 Answers5

14

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)

Kevin
  • 16,549
  • 8
  • 60
  • 74
drescherjm
  • 10,365
  • 5
  • 44
  • 64
  • 1
    This help me a lot, thanks for this script. I'd to a a line just after the Boost_FOUND with this: LINK_DIRECTORIES(${Boost_LIBRARY_DIRS}) otherwise it keeps saying the library was not found. Hope this help others having the same problem. – Cross Jan 01 '15 at 23:31
  • -- Could NOT find Boost Boost version: 1.60.0 Boost include path: /usr/include Detected version of Boost is too old. Requested version was 1.64 (or newer). ..... Even when adding what is mentioned in the comment above (Windows 10 / CLion) – Pwnstar Jul 05 '17 at 10:49
6

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.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
JonathanK
  • 827
  • 1
  • 6
  • 23
  • 1
    I read the manual (http://www.boost.org/doc/libs/1_48_0/more/getting_started/windows.html) but used option 5.2. I found the stage directory with all the libraries in it and can now set this as my boost library dir, but next time I will try option 5.3. – JonathanK Nov 24 '11 at 10:32
  • You can also simply copy stage and boost (headers) directory around to make your own installation of Boost. e.g. boost/ -> C:\boost\include\boost and stage/* -> C:\boost\lib – mloskot Nov 24 '11 at 15:15
  • I had the same problem and I think it shouldn't be the user's task to set the paths, but it was the only solution I found. Library's folder structure should be coherent with find_package. There's no point in complicating things. CMake is supossed to make the user things easy to install. – Jav_Rock Jun 04 '12 at 08:36
0

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.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Chuck Claunch
  • 1,624
  • 1
  • 17
  • 29
  • 1
    Isn't there a difference between ***environment*** variables and ***CMake*** variables? – Peter Mortensen Sep 03 '18 at 14:18
  • Yes. CMake's [FindBoost module](https://github.com/Kitware/CMake/blob/master/Modules/FindBoost.cmake) uses the environment variable `BOOST_ROOT` in its attempts to locate Boost. It looks like newer versions actually may also use the environment variable `BOOSTROOT`. – Chuck Claunch Sep 04 '18 at 15:10
0

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.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
deft_code
  • 57,255
  • 29
  • 141
  • 224
  • I tried that but it didn't help Now the name is something like boost_serialization-vc90-mt-1_47.lib instead of libboost_serialization-vc90-mt-1_47.lib - and if I want to use some more libraries I really don't want to rename them all so that cmake can find them. In my opinion, find_package should do all the work for me... – JonathanK Nov 11 '11 at 15:47
  • 7
    Do not rename the libs. The "lib" prefix is for static libs, without the prefix is for DLLs. You should build with runtime-link=shared instead. – Andreas Haferburg Apr 27 '12 at 13:43
  • @AndreasHaferburg In my case I was specifically trying to static link boost into my application. – deft_code Apr 28 '12 at 13:58
-1

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
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131