]> git.proxmox.com Git - ceph.git/blobdiff - ceph/cmake/modules/BuildBoost.cmake
update sources to ceph Nautilus 14.2.1
[ceph.git] / ceph / cmake / modules / BuildBoost.cmake
index c7cd39a1107707d2063db1f7bb8663b223fbee08..f46cc0d485375e8d1bbcc77f336541107ec0474a 100644 (file)
 #  Boost_USE_MULTITHREADED : boolean (default: OFF)
 #  BOOST_J: integer (defanult 1)
 
+function(check_boost_version source_dir expected_version)
+  set(version_hpp "${source_dir}/boost/version.hpp")
+  if(NOT EXISTS ${version_hpp})
+    message(FATAL_ERROR "${version_hpp} not found. Please either \"rm -rf ${source_dir}\" "
+      "so I can download Boost v${expected_version} for you, or make sure ${source_dir} "
+      "contains a full copy of Boost v${expected_version}.")
+  endif()
+  file(STRINGS "${version_hpp}" BOOST_VERSION_LINE
+    REGEX "^#define[ \t]+BOOST_VERSION[ \t]+[0-9]+$")
+  string(REGEX REPLACE "^#define[ \t]+BOOST_VERSION[ \t]+([0-9]+)$"
+    "\\1" BOOST_VERSION "${BOOST_VERSION_LINE}")
+  math(EXPR BOOST_VERSION_PATCH "${BOOST_VERSION} % 100")
+  math(EXPR BOOST_VERSION_MINOR "${BOOST_VERSION} / 100 % 1000")
+  math(EXPR BOOST_VERSION_MAJOR "${BOOST_VERSION} / 100000")
+  set(version "${BOOST_VERSION_MAJOR}.${BOOST_VERSION_MINOR}.${BOOST_VERSION_PATCH}")
+  if(version VERSION_LESS expected_version)
+    message(FATAL_ERROR "Boost v${version} in ${source_dir} is not new enough. "
+      "Please either \"rm -rf ${source_dir}\" so I can download Boost v${expected_version} "
+      "for you, or make sure ${source_dir} contains a copy of Boost v${expected_version}.")
+  else()
+    message(STATUS "boost (${version} >= ${expected_version}) already in ${source_dir}")
+  endif()
+endfunction()
+
+macro(list_replace list old new)
+  list(FIND ${list} ${old} where)
+  if(where GREATER -1)
+    list(REMOVE_AT ${list} ${where})
+    list(INSERT ${list} ${where} ${new})
+  endif()
+  unset(where)
+endmacro()
+
 function(do_build_boost version)
   cmake_parse_arguments(Boost_BUILD "" "" COMPONENTS ${ARGN})
   set(boost_features "variant=release")
@@ -32,7 +65,20 @@ function(do_build_boost version)
   set(BOOST_CXXFLAGS "-fPIC -w") # check on arm, etc <---XXX
   list(APPEND boost_features "cxxflags=${BOOST_CXXFLAGS}")
 
-  string(REPLACE ";" "," boost_with_libs "${Boost_BUILD_COMPONENTS}")
+  set(boost_with_libs)
+  foreach(c ${Boost_BUILD_COMPONENTS})
+    if(c MATCHES "^python([0-9])\$")
+      set(with_python_version "${CMAKE_MATCH_1}")
+      list(APPEND boost_with_libs "python")
+    elseif(c MATCHES "^python([0-9])\\.?([0-9])\$")
+      set(with_python_version "${CMAKE_MATCH_1}.${CMAKE_MATCH_2}")
+      list(APPEND boost_with_libs "python")
+    else()
+      list(APPEND boost_with_libs ${c})
+    endif()
+  endforeach()
+  list_replace(boost_with_libs "unit_test_framework" "test")
+  string(REPLACE ";" "," boost_with_libs "${boost_with_libs}")
   # build b2 and prepare the project-config.jam for boost
   set(configure_command
     ./bootstrap.sh --prefix=<INSTALL_DIR>
@@ -43,29 +89,41 @@ function(do_build_boost version)
     message(STATUS "BUILDING Boost Libraries at j ${BOOST_J}")
     list(APPEND b2 -j${BOOST_J})
   endif()
-  if(CMAKE_VERBOSE_MAKEFILE)
-    list(APPEND b2 -d1)
+  # suppress all debugging levels for b2
+  list(APPEND b2 -d0)
+
+  if(CMAKE_CXX_COMPILER_ID STREQUAL GNU)
+    set(toolset gcc)
+  elseif(CMAKE_CXX_COMPILER_ID STREQUAL Clang)
+    set(toolset clang)
   else()
-    list(APPEND b2 -d0)
+    message(SEND_ERROR "unknown compiler: ${CMAKE_CXX_COMPILER_ID}")
   endif()
 
-  if(NOT CMAKE_HOST_SYSTEM_PROCESSOR STREQUAL CMAKE_SYSTEM_PROCESSOR)
-    # we are crosscompiling
-    if(CMAKE_CXX_COMPILER_ID STREQUAL GNU)
-      set(b2_cc gcc)
-    elseif(CMAKE_CXX_COMPILER_ID STREQUAL Clang)
-      set(b2_cc clang)
-    else()
-      message(SEND_ERROR "unknown compiler: ${CMAKE_CXX_COMPILER_ID}")
-    endif()
-    # edit the config.jam so, b2 will be able to use the specified toolset
-    execute_process(
-      COMMAND
-      sed -i
-      "s|using ${b2_cc} ;|using ${b2_cc} : ${CMAKE_SYSTEM_PROCESSOR} : ${CMAKE_CXX_COMPILER} ;|"
-      ${PROJECT_SOURCE_DIR}/src/boost/project-config.jam)
-    # use ${CMAKE_SYSTEM_PROCESSOR} as the version identifier of compiler
-    list(APPEND b2 toolset=${b2_cc}-${CMAKE_SYSTEM_PROCESSOR})
+  set(user_config ${CMAKE_BINARY_DIR}/user-config.jam)
+  # edit the user-config.jam so b2 will be able to use the specified
+  # toolset and python
+  file(WRITE ${user_config}
+    "using ${toolset}"
+    " : "
+    " : ${CMAKE_CXX_COMPILER}"
+    " ;\n")
+  if(with_python_version)
+    find_package(PythonLibs ${with_python_version} QUIET REQUIRED)
+    string(REPLACE ";" " " python_includes "${PYTHON_INCLUDE_DIRS}")
+    file(APPEND ${user_config}
+      "using python"
+      " : ${with_python_version}"
+      " : ${PYTHON_EXECUTABLE}"
+      " : ${python_includes}"
+      " : ${PYTHON_LIBRARIES}"
+      " ;\n")
+  endif()
+  list(APPEND b2 --user-config=${user_config})
+
+  list(APPEND b2 toolset=${toolset})
+  if(with_python_version)
+    list(APPEND b2 python=${with_python_version})
   endif()
 
   set(build_command
@@ -76,17 +134,17 @@ function(do_build_boost version)
     ${b2} install)
   set(boost_root_dir "${CMAKE_BINARY_DIR}/boost")
   if(EXISTS "${PROJECT_SOURCE_DIR}/src/boost/bootstrap.sh")
-    message(STATUS "boost already in src")
+    check_boost_version("${PROJECT_SOURCE_DIR}/src/boost" ${version})
     set(source_dir
       SOURCE_DIR "${PROJECT_SOURCE_DIR}/src/boost")
-  elseif(version VERSION_GREATER 1.66)
+  elseif(version VERSION_GREATER 1.67)
     message(FATAL_ERROR "Unknown BOOST_REQUESTED_VERSION: ${version}")
   else()
     message(STATUS "boost will be downloaded...")
     # NOTE: If you change this version number make sure the package is available
     # at the three URLs below (may involve uploading to download.ceph.com)
-    set(boost_version 1.66.0)
-    set(boost_md5 b2dfbd6c717be4a7bb2d88018eaccf75)
+    set(boost_version 1.67.0)
+    set(boost_sha256 2684c972994ee57fc5632e03bf044746f6eb45d4920c343937a465fd67a5adba)
     string(REPLACE "." "_" boost_version_underscore ${boost_version} )
     set(boost_url 
       https://dl.bintray.com/boostorg/release/${boost_version}/source/boost_${boost_version_underscore}.tar.bz2)
@@ -98,10 +156,8 @@ function(do_build_boost version)
     endif()
     set(source_dir
       URL ${boost_url}
-      URL_MD5 ${boost_md5})
-    if(CMAKE_VERSION VERSION_GREATER 3.1)
-      list(APPEND source_dir DOWNLOAD_NO_PROGRESS 1)
-    endif()
+      URL_HASH SHA256=${boost_sha256}
+      DOWNLOAD_NO_PROGRESS 1)
   endif()
   # build all components in a single shot
   include(ExternalProject)
@@ -114,15 +170,32 @@ function(do_build_boost version)
     PREFIX "${boost_root_dir}")
 endfunction()
 
+set(Boost_context_DEPENDENCIES thread chrono system date_time)
+set(Boost_coroutine_DEPENDENCIES context system)
+set(Boost_filesystem_DEPENDENCIES system)
+set(Boost_iostreams_DEPENDENCIES regex)
+set(Boost_thread_DEPENDENCIES chrono system date_time atomic)
+
 macro(build_boost version)
-  do_build_boost(version ${ARGN})
+  do_build_boost(${version} ${ARGN})
   ExternalProject_Get_Property(Boost install_dir)
   set(Boost_INCLUDE_DIRS ${install_dir}/include)
   set(Boost_INCLUDE_DIR ${install_dir}/include)
+  set(Boost_VERSION ${version})
   # create the directory so cmake won't complain when looking at the imported
   # target
   file(MAKE_DIRECTORY ${Boost_INCLUDE_DIRS})
   cmake_parse_arguments(Boost_BUILD "" "" COMPONENTS ${ARGN})
+  foreach(c ${Boost_BUILD_COMPONENTS})
+    list(APPEND components ${c})
+    if(Boost_${c}_DEPENDENCIES)
+      list(APPEND components ${Boost_${c}_DEPENDENCIES})
+      list(REMOVE_DUPLICATES components)
+    endif()
+  endforeach()
+  set(Boost_BUILD_COMPONENTS ${components})
+  unset(components)
+
   foreach(c ${Boost_BUILD_COMPONENTS})
     string(TOUPPER ${c} upper_c)
     if(Boost_USE_STATIC_LIBS)
@@ -131,6 +204,9 @@ macro(build_boost version)
       add_library(Boost::${c} SHARED IMPORTED)
     endif()
     add_dependencies(Boost::${c} Boost)
+    if(c MATCHES "^python")
+      set(c "python${PYTHON_VERSION_MAJOR}${PYTHON_VERSION_MINOR}")
+    endif()
     if(Boost_USE_STATIC_LIBS)
       set(Boost_${upper_c}_LIBRARY
         ${install_dir}/lib/${CMAKE_STATIC_LIBRARY_PREFIX}boost_${c}${CMAKE_STATIC_LIBRARY_SUFFIX})
@@ -138,44 +214,46 @@ macro(build_boost version)
       set(Boost_${upper_c}_LIBRARY
         ${install_dir}/lib/${CMAKE_SHARED_LIBRARY_PREFIX}boost_${c}${CMAKE_SHARED_LIBRARY_SUFFIX})
     endif()
+    unset(buildid)
     set_target_properties(Boost::${c} PROPERTIES
       INTERFACE_INCLUDE_DIRECTORIES "${Boost_INCLUDE_DIRS}"
       IMPORTED_LINK_INTERFACE_LANGUAGES "CXX"
       IMPORTED_LOCATION "${Boost_${upper_c}_LIBRARY}")
     list(APPEND Boost_LIBRARIES ${Boost_${upper_c}_LIBRARY})
   endforeach()
+  foreach(c ${Boost_BUILD_COMPONENTS})
+    if(Boost_${c}_DEPENDENCIES)
+      foreach(dep ${Boost_${c}_DEPENDENCIES})
+        list(APPEND dependencies Boost::${dep})
+      endforeach()
+      set_target_properties(Boost::${c} PROPERTIES
+        INTERFACE_LINK_LIBRARIES "${dependencies}")
+      unset(dependencies)
+    endif()
+  endforeach()
 
   # for header-only libraries
-  if(CMAKE_VERSION VERSION_LESS 3.3)
-    # only ALIAS and INTERFACE target names allow ":" in it, but
-    # INTERFACE library is not allowed until cmake 3.1
-    add_custom_target(Boost.boost DEPENDS Boost)
-  else()
-    add_library(Boost.boost INTERFACE IMPORTED)
-    set_target_properties(Boost.boost PROPERTIES
-      INTERFACE_INCLUDE_DIRECTORIES "${Boost_INCLUDE_DIRS}")
-    add_dependencies(Boost.boost Boost)
-  endif()
+  add_library(Boost::boost INTERFACE IMPORTED)
+  set_target_properties(Boost::boost PROPERTIES
+    INTERFACE_INCLUDE_DIRECTORIES "${Boost_INCLUDE_DIRS}")
+  add_dependencies(Boost::boost Boost)
   find_package_handle_standard_args(Boost DEFAULT_MSG
     Boost_INCLUDE_DIRS Boost_LIBRARIES)
   mark_as_advanced(Boost_LIBRARIES BOOST_INCLUDE_DIRS)
 endmacro()
 
 function(maybe_add_boost_dep target)
-  get_target_property(imported ${target} IMPORTED)
-  if(imported)
-    return()
-  endif()
   get_target_property(type ${target} TYPE)
   if(NOT type MATCHES "OBJECT_LIBRARY|STATIC_LIBRARY|SHARED_LIBRARY|EXECUTABLE")
     return()
   endif()
   get_target_property(sources ${target} SOURCES)
+  string(GENEX_STRIP "${sources}" sources)
   foreach(src ${sources})
     get_filename_component(ext ${src} EXT)
     # assuming all cxx source files include boost header(s)
     if(ext MATCHES ".cc|.cpp|.cxx")
-      add_dependencies(${target} Boost.boost)
+      add_dependencies(${target} Boost::boost)
       return()
     endif()
   endforeach()
@@ -184,7 +262,10 @@ endfunction()
 # override add_library() to add Boost headers dependency
 function(add_library target)
   _add_library(${target} ${ARGN})
-  maybe_add_boost_dep(${target})
+  # can't add dependencies to aliases or imported libraries
+  if (NOT ";${ARGN};" MATCHES ";(ALIAS|IMPORTED);")
+    maybe_add_boost_dep(${target})
+  endif()
 endfunction()
 
 function(add_executable target)