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