#.rst: # # Detect, build, and link Boost libraries. # This modules downloads the .zip archive from SourceForge at # Autocmake update time. # Note that the build-up commands are not Windows-compatible! # # Your autocmake.cfg should look like this:: # # [boost] # override: {'major': 1, 'minor': 59, 'patch': 0, 'components': 'chrono;timer;system'} # source: https://github.com/coderefinery/autocmake/raw/master/modules/boost/boost.cmake # # Cross-dependencies between required components are not checked for. # For example, Boost.Timer depends on Boost.Chrono and Boost.System thus you # should ask explicitly for all three. # If the self-build of Boost components is triggered the `BUILD_CUSTOM_BOOST` variable is set # to `TRUE`. The CMake target `custom_boost` is also added. # You should use these two to ensure the right dependencies between your targets # and the Boost headers/libraries, in case the self-build is triggered. # For example:: # # if(BUILD_CUSTOM_BOOST) # add_dependencies(your_target custom_boost) # endif() # # will ensure that `your_target` is built after `custom_boost` if and only if the self-build # of Boost took place. This is an important step to avoid race conditions when building # on multiple processes. # # Dependencies:: # # mpi - Only if the Boost.MPI library is a needed component # python_libs - Only if the Boost.Python library is a needed component # # Variables used:: # # BOOST_MINIMUM_REQUIRED - Minimum required version of Boost # BOOST_COMPONENTS_REQUIRED - Components (compiled Boost libraries) required # PROJECT_SOURCE_DIR # PROJECT_BINARY_DIR # CMAKE_BUILD_TYPE # MPI_FOUND # BUILD_CUSTOM_BOOST # # autocmake.cfg configuration:: # # major=1 # minor=48 # patch=0 # components='' # fetch: https://github.com/coderefinery/autocmake/raw/master/modules/boost/boost_unpack.cmake # https://github.com/coderefinery/autocmake/raw/master/modules/boost/boost_userconfig.cmake # https://github.com/coderefinery/autocmake/raw/master/modules/boost/boost_configure.cmake # https://github.com/coderefinery/autocmake/raw/master/modules/boost/boost_build.cmake # https://github.com/coderefinery/autocmake/raw/master/modules/boost/boost_install.cmake # https://github.com/coderefinery/autocmake/raw/master/modules/boost/boost_headers.cmake # https://github.com/coderefinery/autocmake/raw/master/modules/boost/boost_cleanup.cmake # http://sourceforge.net/projects/boost/files/boost/%(major)s.%(minor)s.%(patch)s/boost_%(major)s_%(minor)s_%(patch)s.zip # docopt: --boost-headers= Include directories for Boost [default: '']. # --boost-libraries= Library directories for Boost [default: '']. # --build-boost= Deactivate Boost detection and build on-the-fly [default: OFF]. # define: '-DBOOST_INCLUDEDIR="{0}"'.format(arguments['--boost-headers']) # '-DBOOST_LIBRARYDIR="{0}"'.format(arguments['--boost-libraries']) # '-DFORCE_CUSTOM_BOOST="{0}"'.format(arguments['--build-boost']) # '-DBOOST_MINIMUM_REQUIRED="%(major)s.%(minor)s.%(patch)s"' # '-DBOOST_COMPONENTS_REQUIRED="%(components)s"' # FIXME Maintainer should be able to choose between fail (end-user has to satisfy dependency # on its own) and soft-fail (self-build of Boost) # Underscore-separated version number string(REGEX REPLACE "\\." "_" BOOSTVER ${BOOST_MINIMUM_REQUIRED}) # Where the Boost .zip archive is located # CMAKE_CURRENT_LIST_DIR is undefined in CMake 2.8.2 # see https://public.kitware.com/Bug/print_bug_page.php?bug_id=11675 # workaround: create CMAKE_CURRENT_LIST_DIR get_filename_component(CMAKE_CURRENT_LIST_DIR ${CMAKE_CURRENT_LIST_FILE} PATH) set(BOOST_ARCHIVE_LOCATION ${CMAKE_CURRENT_LIST_DIR}) set(BOOST_ARCHIVE boost_${BOOSTVER}.zip) # FIXME These are possibly not always good settings set(Boost_USE_STATIC_LIBS ON) set(Boost_USE_MULTITHREADED ON) set(Boost_USE_STATIC_RUNTIME OFF) set(Boost_DEBUG OFF) set(Boost_DETAILED_FAILURE_MESSAGE OFF) set(BUILD_CUSTOM_BOOST FALSE) if(FORCE_CUSTOM_BOOST) set(BUILD_CUSTOM_BOOST TRUE) message(STATUS "Force automatic build of Boost") # Just to avoid unused variable warning from CMake set(BOOST_INCLUDEDIR "") set(BOOST_LIBRARYDIR "") else() # Read from cache, needed for rebuilds set(BOOST_INCLUDEDIR ${Boost_INCLUDE_DIR}) set(BOOST_LIBRARYDIR ${Boost_LIBRARY_DIR}) find_package(Boost ${BOOST_MINIMUM_REQUIRED} COMPONENTS "${BOOST_COMPONENTS_REQUIRED}") if(NOT Boost_FOUND) set(BUILD_CUSTOM_BOOST TRUE) endif() endif() if(BUILD_CUSTOM_BOOST) ## Preliminary work # 0. Root directory for the custom build set(CUSTOM_BOOST_LOCATION ${PROJECT_BINARY_DIR}/boost) file(MAKE_DIRECTORY ${CUSTOM_BOOST_LOCATION}) # 1. Where Boost will be built set(BOOST_BUILD_DIR ${CUSTOM_BOOST_LOCATION}/boost_${BOOSTVER}) # 2. Select toolset according to compilers specified by the user set(toolset "") if(CMAKE_CXX_COMPILER_ID MATCHES Intel) set(toolset "intel-linux") elseif(CMAKE_CXX_COMPILER_ID MATCHES Clang) set(toolset "clang") else() if(CMAKE_SYSTEM_NAME MATCHES Darwin) set(toolset "darwin") else() set(toolset "gcc") endif() endif() string(TOLOWER ${CMAKE_BUILD_TYPE} type) # CMAKE_CURRENT_LIST_DIR is undefined in CMake 2.8.2 # see https://public.kitware.com/Bug/print_bug_page.php?bug_id=11675 # workaround: create CMAKE_CURRENT_LIST_DIR get_filename_component(CMAKE_CURRENT_LIST_DIR ${CMAKE_CURRENT_LIST_FILE} PATH) include(${CMAKE_CURRENT_LIST_DIR}/boost_unpack.cmake) include(${CMAKE_CURRENT_LIST_DIR}/boost_userconfig.cmake) if(NOT "${BOOST_COMPONENTS_REQUIRED}" STREQUAL "") # Non-empty list. Compiled libraries needed # Transform the ;-separated list to a ,-separated list (digested by the Boost build toolchain!) string(REPLACE ";" "," b2_needed_components "${BOOST_COMPONENTS_REQUIRED}") # Replace unit_test_framework (used by CMake's find_package) with test (understood by Boost build toolchain) string(REPLACE "unit_test_framework" "test" b2_needed_components "${b2_needed_components}") set(select_libraries "--with-libraries=${b2_needed_components}") string(REPLACE ";" ", " printout "${BOOST_COMPONENTS_REQUIRED}") message(STATUS " Libraries to be built: ${printout}") message(STATUS " Toolset to be used: ${toolset}") include(${CMAKE_CURRENT_LIST_DIR}/boost_configure.cmake) include(${CMAKE_CURRENT_LIST_DIR}/boost_build.cmake) include(${CMAKE_CURRENT_LIST_DIR}/boost_install.cmake) else() # Empty list. Header-only libraries needed # Just unpack to known location message(STATUS " No libraries required, installing headers") include(${CMAKE_CURRENT_LIST_DIR}/boost_headers.cmake) endif() include(${CMAKE_CURRENT_LIST_DIR}/boost_cleanup.cmake) add_custom_target(custom_boost DEPENDS ${CUSTOM_BOOST_LOCATION}/boost.cleanedup) # 4. Set all variables related to Boost that find_package would have set set(Boost_FOUND TRUE) string(REGEX REPLACE "\\." "0" Boost_VERSION ${BOOST_MINIMUM_REQUIRED}) math(EXPR Boost_MAJOR_VERSION "${Boost_VERSION} / 100000") math(EXPR Boost_MINOR_VERSION "${Boost_VERSION} / 100 % 1000") math(EXPR Boost_SUBMINOR_VERSION "${Boost_VERSION} % 100") set(Boost_LIB_VERSION ${Boost_MAJOR_VERSION}_${Boost_MINOR_VERSION}) set(Boost_INCLUDE_DIR ${CUSTOM_BOOST_LOCATION}/include CACHE PATH "Boost include directory" FORCE) set(Boost_LIBRARY_DIR ${CUSTOM_BOOST_LOCATION}/lib CACHE PATH "Boost library directory" FORCE) foreach(_component ${BOOST_COMPONENTS_REQUIRED}) string(TOUPPER ${_component} _COMP) set(Boost_${_COMP}_FOUND TRUE) set(Boost_${_COMP}_LIBRARY libboost_${_component}.a) set(Boost_${_COMP}_LIBRARY_DEBUG ${Boost_LIBRARY_DIR}/${Boost_${_COMP}_LIBRARY} CACHE FILEPATH "Boost ${_component} library (debug)" FORCE) set(Boost_${_COMP}_LIBRARY_RELEASE ${Boost_LIBRARY_DIR}/${Boost_${_COMP}_LIBRARY} CACHE FILEPATH "Boost ${_component} library (release)" FORCE) list(APPEND Boost_LIBRARIES ${Boost_${_COMP}_LIBRARY}) endforeach() set(Boost_INCLUDE_DIRS ${Boost_INCLUDE_DIR}) set(Boost_LIBRARY_DIRS ${Boost_LIBRARY_DIR}) if(CMAKE_SYSTEM_NAME MATCHES Linux) list(APPEND Boost_LIBRARIES rt) endif() endif() include_directories(SYSTEM ${Boost_INCLUDE_DIRS}) link_directories(${Boost_LIBRARY_DIRS})