]> git.proxmox.com Git - ceph.git/blame - ceph/cmake/modules/BuildBoost.cmake
import new upstream nautilus stable release 14.2.8
[ceph.git] / ceph / cmake / modules / BuildBoost.cmake
CommitLineData
31f18b77
FG
1# This module builds Boost
2# executables are. It sets the following variables:
3#
4# Boost_FOUND : boolean - system has Boost
5# Boost_LIBRARIES : list(filepath) - the libraries needed to use Boost
6# Boost_INCLUDE_DIRS : list(path) - the Boost include directories
7#
8# Following hints are respected
9#
10# Boost_USE_STATIC_LIBS : boolean (default: OFF)
11# Boost_USE_MULTITHREADED : boolean (default: OFF)
12# BOOST_J: integer (defanult 1)
13
11fdf7f2
TL
14function(check_boost_version source_dir expected_version)
15 set(version_hpp "${source_dir}/boost/version.hpp")
16 if(NOT EXISTS ${version_hpp})
17 message(FATAL_ERROR "${version_hpp} not found. Please either \"rm -rf ${source_dir}\" "
18 "so I can download Boost v${expected_version} for you, or make sure ${source_dir} "
19 "contains a full copy of Boost v${expected_version}.")
20 endif()
21 file(STRINGS "${version_hpp}" BOOST_VERSION_LINE
22 REGEX "^#define[ \t]+BOOST_VERSION[ \t]+[0-9]+$")
23 string(REGEX REPLACE "^#define[ \t]+BOOST_VERSION[ \t]+([0-9]+)$"
24 "\\1" BOOST_VERSION "${BOOST_VERSION_LINE}")
25 math(EXPR BOOST_VERSION_PATCH "${BOOST_VERSION} % 100")
26 math(EXPR BOOST_VERSION_MINOR "${BOOST_VERSION} / 100 % 1000")
27 math(EXPR BOOST_VERSION_MAJOR "${BOOST_VERSION} / 100000")
28 set(version "${BOOST_VERSION_MAJOR}.${BOOST_VERSION_MINOR}.${BOOST_VERSION_PATCH}")
29 if(version VERSION_LESS expected_version)
30 message(FATAL_ERROR "Boost v${version} in ${source_dir} is not new enough. "
31 "Please either \"rm -rf ${source_dir}\" so I can download Boost v${expected_version} "
32 "for you, or make sure ${source_dir} contains a copy of Boost v${expected_version}.")
33 else()
34 message(STATUS "boost (${version} >= ${expected_version}) already in ${source_dir}")
35 endif()
36endfunction()
37
38macro(list_replace list old new)
39 list(FIND ${list} ${old} where)
40 if(where GREATER -1)
41 list(REMOVE_AT ${list} ${where})
42 list(INSERT ${list} ${where} ${new})
43 endif()
44 unset(where)
45endmacro()
46
31f18b77
FG
47function(do_build_boost version)
48 cmake_parse_arguments(Boost_BUILD "" "" COMPONENTS ${ARGN})
49 set(boost_features "variant=release")
50 if(Boost_USE_MULTITHREADED)
51 list(APPEND boost_features "threading=multi")
52 else()
53 list(APPEND boost_features "threading=single")
54 endif()
55 if(Boost_USE_STATIC_LIBS)
56 list(APPEND boost_features "link=static")
57 else()
58 list(APPEND boost_features "link=shared")
59 endif()
60 if(CMAKE_SIZEOF_VOID_P EQUAL 8)
61 list(APPEND boost_features "address-model=64")
62 else()
63 list(APPEND boost_features "address-model=32")
64 endif()
65 set(BOOST_CXXFLAGS "-fPIC -w") # check on arm, etc <---XXX
66 list(APPEND boost_features "cxxflags=${BOOST_CXXFLAGS}")
67
11fdf7f2
TL
68 set(boost_with_libs)
69 foreach(c ${Boost_BUILD_COMPONENTS})
70 if(c MATCHES "^python([0-9])\$")
71 set(with_python_version "${CMAKE_MATCH_1}")
72 list(APPEND boost_with_libs "python")
73 elseif(c MATCHES "^python([0-9])\\.?([0-9])\$")
74 set(with_python_version "${CMAKE_MATCH_1}.${CMAKE_MATCH_2}")
75 list(APPEND boost_with_libs "python")
76 else()
77 list(APPEND boost_with_libs ${c})
78 endif()
79 endforeach()
80 list_replace(boost_with_libs "unit_test_framework" "test")
81 string(REPLACE ";" "," boost_with_libs "${boost_with_libs}")
31f18b77
FG
82 # build b2 and prepare the project-config.jam for boost
83 set(configure_command
84 ./bootstrap.sh --prefix=<INSTALL_DIR>
85 --with-libraries=${boost_with_libs})
86
87 set(b2 ./b2)
88 if(BOOST_J)
89 message(STATUS "BUILDING Boost Libraries at j ${BOOST_J}")
90 list(APPEND b2 -j${BOOST_J})
91 endif()
11fdf7f2
TL
92 # suppress all debugging levels for b2
93 list(APPEND b2 -d0)
94
95 if(CMAKE_CXX_COMPILER_ID STREQUAL GNU)
96 set(toolset gcc)
97 elseif(CMAKE_CXX_COMPILER_ID STREQUAL Clang)
98 set(toolset clang)
31f18b77 99 else()
11fdf7f2 100 message(SEND_ERROR "unknown compiler: ${CMAKE_CXX_COMPILER_ID}")
31f18b77
FG
101 endif()
102
11fdf7f2
TL
103 set(user_config ${CMAKE_BINARY_DIR}/user-config.jam)
104 # edit the user-config.jam so b2 will be able to use the specified
105 # toolset and python
106 file(WRITE ${user_config}
107 "using ${toolset}"
108 " : "
109 " : ${CMAKE_CXX_COMPILER}"
110 " ;\n")
111 if(with_python_version)
112 find_package(PythonLibs ${with_python_version} QUIET REQUIRED)
113 string(REPLACE ";" " " python_includes "${PYTHON_INCLUDE_DIRS}")
114 file(APPEND ${user_config}
115 "using python"
116 " : ${with_python_version}"
117 " : ${PYTHON_EXECUTABLE}"
118 " : ${python_includes}"
119 " : ${PYTHON_LIBRARIES}"
120 " ;\n")
121 endif()
122 list(APPEND b2 --user-config=${user_config})
123
124 list(APPEND b2 toolset=${toolset})
125 if(with_python_version)
126 list(APPEND b2 python=${with_python_version})
31f18b77
FG
127 endif()
128
129 set(build_command
130 ${b2} headers stage
131 #"--buildid=ceph" # changes lib names--can omit for static
132 ${boost_features})
133 set(install_command
134 ${b2} install)
135 set(boost_root_dir "${CMAKE_BINARY_DIR}/boost")
3a9019d9 136 if(EXISTS "${PROJECT_SOURCE_DIR}/src/boost/bootstrap.sh")
11fdf7f2 137 check_boost_version("${PROJECT_SOURCE_DIR}/src/boost" ${version})
31f18b77
FG
138 set(source_dir
139 SOURCE_DIR "${PROJECT_SOURCE_DIR}/src/boost")
92f5a8d4 140 elseif(version VERSION_GREATER 1.72)
31f18b77
FG
141 message(FATAL_ERROR "Unknown BOOST_REQUESTED_VERSION: ${version}")
142 else()
b32b8144
FG
143 message(STATUS "boost will be downloaded...")
144 # NOTE: If you change this version number make sure the package is available
145 # at the three URLs below (may involve uploading to download.ceph.com)
92f5a8d4
TL
146 set(boost_version 1.72.0)
147 set(boost_sha256 59c9b274bc451cf91a9ba1dd2c7fdcaf5d60b1b3aa83f2c9fa143417cc660722)
31f18b77 148 string(REPLACE "." "_" boost_version_underscore ${boost_version} )
b32b8144
FG
149 set(boost_url
150 https://dl.bintray.com/boostorg/release/${boost_version}/source/boost_${boost_version_underscore}.tar.bz2)
151 if(CMAKE_VERSION VERSION_GREATER 3.7)
152 set(boost_url
153 "${boost_url} http://downloads.sourceforge.net/project/boost/boost/${boost_version}/boost_${boost_version_underscore}.tar.bz2")
154 set(boost_url
155 "${boost_url} https://download.ceph.com/qa/boost_${boost_version_underscore}.tar.bz2")
156 endif()
31f18b77
FG
157 set(source_dir
158 URL ${boost_url}
11fdf7f2
TL
159 URL_HASH SHA256=${boost_sha256}
160 DOWNLOAD_NO_PROGRESS 1)
31f18b77
FG
161 endif()
162 # build all components in a single shot
163 include(ExternalProject)
164 ExternalProject_Add(Boost
165 ${source_dir}
166 CONFIGURE_COMMAND CC=${CMAKE_C_COMPILER} CXX=${CMAKE_CXX_COMPILER} ${configure_command}
167 BUILD_COMMAND CC=${CMAKE_C_COMPILER} CXX=${CMAKE_CXX_COMPILER} ${build_command}
168 BUILD_IN_SOURCE 1
169 INSTALL_COMMAND ${install_command}
170 PREFIX "${boost_root_dir}")
171endfunction()
172
11fdf7f2
TL
173set(Boost_context_DEPENDENCIES thread chrono system date_time)
174set(Boost_coroutine_DEPENDENCIES context system)
175set(Boost_filesystem_DEPENDENCIES system)
176set(Boost_iostreams_DEPENDENCIES regex)
177set(Boost_thread_DEPENDENCIES chrono system date_time atomic)
178
31f18b77 179macro(build_boost version)
11fdf7f2 180 do_build_boost(${version} ${ARGN})
31f18b77
FG
181 ExternalProject_Get_Property(Boost install_dir)
182 set(Boost_INCLUDE_DIRS ${install_dir}/include)
183 set(Boost_INCLUDE_DIR ${install_dir}/include)
11fdf7f2 184 set(Boost_VERSION ${version})
31f18b77
FG
185 # create the directory so cmake won't complain when looking at the imported
186 # target
187 file(MAKE_DIRECTORY ${Boost_INCLUDE_DIRS})
188 cmake_parse_arguments(Boost_BUILD "" "" COMPONENTS ${ARGN})
11fdf7f2
TL
189 foreach(c ${Boost_BUILD_COMPONENTS})
190 list(APPEND components ${c})
191 if(Boost_${c}_DEPENDENCIES)
192 list(APPEND components ${Boost_${c}_DEPENDENCIES})
193 list(REMOVE_DUPLICATES components)
194 endif()
195 endforeach()
196 set(Boost_BUILD_COMPONENTS ${components})
197 unset(components)
198
31f18b77
FG
199 foreach(c ${Boost_BUILD_COMPONENTS})
200 string(TOUPPER ${c} upper_c)
201 if(Boost_USE_STATIC_LIBS)
202 add_library(Boost::${c} STATIC IMPORTED)
203 else()
204 add_library(Boost::${c} SHARED IMPORTED)
205 endif()
206 add_dependencies(Boost::${c} Boost)
11fdf7f2
TL
207 if(c MATCHES "^python")
208 set(c "python${PYTHON_VERSION_MAJOR}${PYTHON_VERSION_MINOR}")
209 endif()
31f18b77
FG
210 if(Boost_USE_STATIC_LIBS)
211 set(Boost_${upper_c}_LIBRARY
212 ${install_dir}/lib/${CMAKE_STATIC_LIBRARY_PREFIX}boost_${c}${CMAKE_STATIC_LIBRARY_SUFFIX})
213 else()
214 set(Boost_${upper_c}_LIBRARY
215 ${install_dir}/lib/${CMAKE_SHARED_LIBRARY_PREFIX}boost_${c}${CMAKE_SHARED_LIBRARY_SUFFIX})
216 endif()
11fdf7f2 217 unset(buildid)
31f18b77
FG
218 set_target_properties(Boost::${c} PROPERTIES
219 INTERFACE_INCLUDE_DIRECTORIES "${Boost_INCLUDE_DIRS}"
220 IMPORTED_LINK_INTERFACE_LANGUAGES "CXX"
221 IMPORTED_LOCATION "${Boost_${upper_c}_LIBRARY}")
222 list(APPEND Boost_LIBRARIES ${Boost_${upper_c}_LIBRARY})
223 endforeach()
11fdf7f2
TL
224 foreach(c ${Boost_BUILD_COMPONENTS})
225 if(Boost_${c}_DEPENDENCIES)
226 foreach(dep ${Boost_${c}_DEPENDENCIES})
227 list(APPEND dependencies Boost::${dep})
228 endforeach()
229 set_target_properties(Boost::${c} PROPERTIES
230 INTERFACE_LINK_LIBRARIES "${dependencies}")
231 unset(dependencies)
232 endif()
233 endforeach()
31f18b77
FG
234
235 # for header-only libraries
11fdf7f2
TL
236 add_library(Boost::boost INTERFACE IMPORTED)
237 set_target_properties(Boost::boost PROPERTIES
238 INTERFACE_INCLUDE_DIRECTORIES "${Boost_INCLUDE_DIRS}")
239 add_dependencies(Boost::boost Boost)
31f18b77
FG
240 find_package_handle_standard_args(Boost DEFAULT_MSG
241 Boost_INCLUDE_DIRS Boost_LIBRARIES)
242 mark_as_advanced(Boost_LIBRARIES BOOST_INCLUDE_DIRS)
243endmacro()
244
245function(maybe_add_boost_dep target)
31f18b77
FG
246 get_target_property(type ${target} TYPE)
247 if(NOT type MATCHES "OBJECT_LIBRARY|STATIC_LIBRARY|SHARED_LIBRARY|EXECUTABLE")
248 return()
249 endif()
250 get_target_property(sources ${target} SOURCES)
11fdf7f2 251 string(GENEX_STRIP "${sources}" sources)
31f18b77
FG
252 foreach(src ${sources})
253 get_filename_component(ext ${src} EXT)
254 # assuming all cxx source files include boost header(s)
255 if(ext MATCHES ".cc|.cpp|.cxx")
11fdf7f2 256 add_dependencies(${target} Boost::boost)
31f18b77
FG
257 return()
258 endif()
259 endforeach()
260endfunction()
261
262# override add_library() to add Boost headers dependency
263function(add_library target)
264 _add_library(${target} ${ARGN})
11fdf7f2
TL
265 # can't add dependencies to aliases or imported libraries
266 if (NOT ";${ARGN};" MATCHES ";(ALIAS|IMPORTED);")
267 maybe_add_boost_dep(${target})
268 endif()
31f18b77
FG
269endfunction()
270
271function(add_executable target)
272 _add_executable(${target} ${ARGN})
273 maybe_add_boost_dep(${target})
274endfunction()