]>
Commit | Line | Data |
---|---|---|
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 |
14 | function(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() | |
36 | endfunction() | |
37 | ||
38 | macro(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) | |
45 | endmacro() | |
46 | ||
31f18b77 FG |
47 | function(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}") | |
171 | endfunction() | |
172 | ||
11fdf7f2 TL |
173 | set(Boost_context_DEPENDENCIES thread chrono system date_time) |
174 | set(Boost_coroutine_DEPENDENCIES context system) | |
175 | set(Boost_filesystem_DEPENDENCIES system) | |
176 | set(Boost_iostreams_DEPENDENCIES regex) | |
177 | set(Boost_thread_DEPENDENCIES chrono system date_time atomic) | |
178 | ||
31f18b77 | 179 | macro(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) | |
243 | endmacro() | |
244 | ||
245 | function(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() | |
260 | endfunction() | |
261 | ||
262 | # override add_library() to add Boost headers dependency | |
263 | function(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 |
269 | endfunction() |
270 | ||
271 | function(add_executable target) | |
272 | _add_executable(${target} ${ARGN}) | |
273 | maybe_add_boost_dep(${target}) | |
274 | endfunction() |