|
| 1 | +.template 0 |
| 2 | +############################################################################### |
| 3 | +# Copyright (c) 2014-2025 libbitcoin developers (see COPYING). |
| 4 | +# |
| 5 | +# GSL generate libbitcoin CMakeLists.txt. |
| 6 | +# |
| 7 | +# This is a code generator built using the iMatix GSL code generation |
| 8 | +# language. See https://github.com/imatix/gsl for details. |
| 9 | +############################################################################### |
| 10 | +# Functions |
| 11 | +############################################################################### |
| 12 | + |
| 13 | +function emit_CMakeLists(repository, repositories) |
| 14 | + define my.repository = emit_CMakeLists.repository |
| 15 | + define my.repositories = emit_CMakeLists.repositories |
| 16 | + |
| 17 | + copyleft(my.repository.name) |
| 18 | + |
| 19 | + emit_initialization(my.repository) |
| 20 | + |
| 21 | + emit_includes() |
| 22 | + |
| 23 | + emit_pkgconfig_matching_variables() |
| 24 | + |
| 25 | + emit_flags(my.repository) |
| 26 | + |
| 27 | + emit_options(my.repository) |
| 28 | + |
| 29 | + emit_compound_flags(my.repository) |
| 30 | + |
| 31 | + emit_defines(my.repository) |
| 32 | + |
| 33 | + emit_dependencies(my.repository) |
| 34 | +endfunction |
| 35 | + |
| 36 | +function emit_flags(repository) |
| 37 | + define my.repository = emit_flags.repository |
| 38 | + define my.std_prefix = "std=c++" |
| 39 | + |
| 40 | + if (count(my.repository->configure.flag, starts_with(count.name, my.std_prefix) > 0)) |
| 41 | + define my.std_flag = my.repository->configure->flag(\ |
| 42 | + starts_with(_flag.name, my.std_prefix), _flag) |
| 43 | + define my.standard = right(my.std_flag.name,\ |
| 44 | + string.length(my.std_flag.name) - string.length(my.std_prefix)) |
| 45 | + emit_cxx_standard(my.standard) |
| 46 | + endif |
| 47 | + |
| 48 | + new compile_options as _options |
| 49 | + for my.repository->configure.flag as _flag |
| 50 | + if (starts_with(_flag.name, my.std_prefix)) |
| 51 | + next |
| 52 | + endif |
| 53 | + |
| 54 | + if (((_flag.context = "c") | (_flag.context = "c++")) &\ |
| 55 | + (count(_options.flag, (count.name = _flag.name)) = 0)) |
| 56 | + copy _flag to _options |
| 57 | + endif |
| 58 | + endfor |
| 59 | + emit_add_compile_options(_options) |
| 60 | + endnew |
| 61 | +endfunction |
| 62 | + |
| 63 | +function emit_options(repository) |
| 64 | + define my.repository = emit_options.repository |
| 65 | + for my.repository->configure.option as _option |
| 66 | + emit_option(_option) |
| 67 | + endfor |
| 68 | +endfunction |
| 69 | + |
| 70 | +function emit_compound_flags(repository) |
| 71 | + define my.repository = emit_compound_flags.repository |
| 72 | + for my.repository->configure.compound as _compound |
| 73 | + emit_compound_flag(_compound, my.repository) |
| 74 | + endfor |
| 75 | +endfunction |
| 76 | + |
| 77 | +function emit_dependencies(repository) |
| 78 | + define my.repository = emit_dependencies.repository |
| 79 | + |
| 80 | + for my.repository->configure.dependency as _dependency |
| 81 | + if (is_boost_dependency(_dependency)) |
| 82 | + emit_dependency_boost(_dependency, my.repository) |
| 83 | + elsif (is_boost_lib_dependency(_dependency)) |
| 84 | + elsif (is_pthread_dependency(_dependency)) |
| 85 | + emit_dependency_pthread(_dependency, my.repository) |
| 86 | + elsif (is_versioned_dependency(_dependency)) |
| 87 | + emit_dependency_versioned(_dependency, my.repository) |
| 88 | + else |
| 89 | + emit_dependency(_dependency, my.repository) |
| 90 | + endif |
| 91 | + endfor |
| 92 | +endfunction |
| 93 | + |
| 94 | +function emit_dependency_boost(dependency, repository, indent) |
| 95 | + define my.prefix = "boost_" |
| 96 | + define my.dependency = emit_dependency_boost.dependency |
| 97 | + define my.repository = emit_dependency_boost.repository |
| 98 | + define my.indent = default_defined(emit_dependency_boost.indent) |
| 99 | + |
| 100 | + new features as _features |
| 101 | + # locate boost components |
| 102 | + populate_features(_features, my.prefix, my.repository) |
| 103 | + |
| 104 | + # emit |
| 105 | + emit_boost_use_static_libs() |
| 106 | + emit_find_package(my.dependency, _features, my.indent) |
| 107 | + endnew |
| 108 | +endfunction |
| 109 | + |
| 110 | +############################################################################### |
| 111 | +# Macros |
| 112 | +############################################################################### |
| 113 | +.endtemplate |
| 114 | +.template 1 |
| 115 | +. |
| 116 | +.macro emit_initialization(repository, indent) |
| 117 | +. define my.repository = emit_initialization.repository |
| 118 | +. define my.indent = default_defined(emit_initialization.indent) |
| 119 | +. heading2("Cmake project initialization.") |
| 120 | +$(my.indent)cmake_minimum_required( VERSION 3.18 FATAL_ERROR ) |
| 121 | + |
| 122 | +$(my.indent)project( $(my.repository.name) LANGUAGES C CXX ) |
| 123 | + |
| 124 | +$(my.indent)enable_testing() |
| 125 | + |
| 126 | +$(my.indent)set( CANONICAL_LIB_NAME $<IF:$<BOOL:${MSVC}>,"$(my.repository.name)","$(my.repository->package.library)"> ) |
| 127 | + |
| 128 | +$(my.indent)set_property( GLOBAL PROPERTY USE_FOLDERS ON ) |
| 129 | +$(my.indent)set( PACKAGE_VERSION "$(my.repository.version)" ) |
| 130 | +$(my.indent)set( VERSION "${PACKAGE_VERSION}" ) |
| 131 | + |
| 132 | +.endmacro # emit_initialization |
| 133 | +. |
| 134 | +.macro emit_includes(indent) |
| 135 | +. define my.indent = default_defined(emit_includes.indent) |
| 136 | +. heading2("Common includes.") |
| 137 | +$(my.indent)list( APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/modules" ) |
| 138 | + |
| 139 | +$(my.indent)include(CheckCXXCompilerFlag) |
| 140 | +$(my.indent)include(CheckCXXSourceCompiles) |
| 141 | +$(my.indent)include(CheckCXXSymbolExists) |
| 142 | +$(my.indent)include(CheckIncludeFiles) |
| 143 | +$(my.indent)include(CheckLinkerFlag) |
| 144 | +$(my.indent)include(CheckSymbolExists) |
| 145 | +$(my.indent)include(CMakePackageConfigHelpers) |
| 146 | +$(my.indent)include(FindThreads) |
| 147 | +$(my.indent)include(GNUInstallDirs) |
| 148 | + |
| 149 | +.endmacro # emit_includes |
| 150 | +. |
| 151 | +.macro emit_pkgconfig_matching_variables(indent) |
| 152 | +. define my.indent = default_defined(emit_pkgconfig_matching_variables.indent) |
| 153 | +. heading2("Match pkg-config.in expected variables.") |
| 154 | +$(my.indent)set( prefix "${CMAKE_PREFIX_PATH}" ) |
| 155 | +$(my.indent)set( exec_prefix "\${prefix}" ) |
| 156 | +$(my.indent)set( libdir "\${exec_prefix}/lib" ) |
| 157 | +$(my.indent)set( includedir "\${exec_prefix}/include" ) |
| 158 | + |
| 159 | +.endmacro # emit_pkgconfig_matching_variables |
| 160 | +. |
| 161 | +.macro emit_cxx_standard(standard, indent) |
| 162 | +. define my.indent = default_defined(emit_cxx_standard.indent) |
| 163 | +. heading2("Check for baseline language coverage in the compiler for the C++$(my.standard) standard.") |
| 164 | +$(my.indent)set( CMAKE_CXX_STANDARD $(my.standard) ) |
| 165 | +$(my.indent)set( CMAKE_CXX_STANDARD_REQUIRED ON ) |
| 166 | + |
| 167 | +.endmacro # emit_cxx_standard |
| 168 | +. |
| 169 | +.macro emit_add_compile_options(options, indent) |
| 170 | +. define my.indent = default_defined(emit_add_compile_options.indent) |
| 171 | +. define my.options = emit_add_compile_options.options |
| 172 | +. |
| 173 | +. heading2("Add compiler options") |
| 174 | +. for my.options.flag as _flag by defined(_flag.compiler) ?? _flag.compiler ? "" |
| 175 | +. define my.opt_indent = defined(_flag.compiler) ?? join(" ", my.indent, "") ? "$(my.indent)" |
| 176 | +# $(_flag.comment) |
| 177 | +. if (defined(_flag.compiler)) |
| 178 | +$(my.indent)if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "$(compiler_id(_flag.compiler))") |
| 179 | +. endif |
| 180 | +$(my.opt_indent)check_cxx_compiler_flag( "-$(_flag.name)" HAS_FLAG_$(_flag.name:upper) ) |
| 181 | +$(my.opt_indent)if ( HAS_FLAG_$(_flag.name:upper) ) |
| 182 | + $(my.opt_indent)add_compile_options( $<$<COMPILE_LANGUAGE:CXX>:-$(_flag.name)> ) |
| 183 | +$(my.opt_indent)else() |
| 184 | + $(my.opt_indent)message( FATAL_ERROR "Compiler does not support -$(_flag.name)" ) |
| 185 | +$(my.opt_indent)endif() |
| 186 | +. if defined(_flag.compiler) |
| 187 | +$(my.indent)endif() |
| 188 | +. endif |
| 189 | + |
| 190 | +. endfor |
| 191 | +.endmacro # emit_add_compile_options |
| 192 | +. |
| 193 | +.macro emit_option(option, indent) |
| 194 | +. define my.indent = default_defined(emit_option.indent) |
| 195 | +. define my.option = emit_option.option |
| 196 | +. require(my.option, "option", "description") |
| 197 | +. require(my.option, "option", "name") |
| 198 | +. require(my.option, "option", "type") |
| 199 | +. |
| 200 | +. define my.type = get_option_type(my.option) |
| 201 | +. define my.symbol = get_option_symbol_generic(my.option, "-", "false") |
| 202 | +. define my.data_type = get_option_data_type(my.option) |
| 203 | +. |
| 204 | +. define my.implement = is_true(my.option.inherited) ?? "Inherit" ? "Implement" |
| 205 | +. define my.output = is_true(my.option.substitute) ?? " and output ${$(my.option.name)}" ? "" |
| 206 | +. define my.defines = defined(my.option.define) ?? " and define $(my.option.define:upper,c)" ? "" |
| 207 | +. define my.conditional = is_true(my.option.conditional) ?? " and declare $(my.symbol)" ? "" |
| 208 | +. heading2("$(my.implement) -D$(my.symbol)$(my.defines)$(my.output)$(my.conditional).") |
| 209 | +. |
| 210 | +. if (!is_true(my.option.inherited)) |
| 211 | +$(my.indent)set( $(my.symbol) "$(get_option_default(my.option))" CACHE $(my.data_type:upper) "$(my.option.description)" ) |
| 212 | + |
| 213 | +. endif |
| 214 | +. |
| 215 | +. if (!is_empty(my.option.define)) |
| 216 | +. define my.define_clause = get_option_define_clause(my.option, my.symbol) |
| 217 | +. |
| 218 | +$(my.indent)if ($(my.define_clause)) |
| 219 | + $(my.indent)add_definitions( -D$(my.option.define) ) |
| 220 | +$(my.indent)endif() |
| 221 | + |
| 222 | +. endif |
| 223 | +. |
| 224 | +. if (is_true(my.option.substitute) & defined(my.option.value)) |
| 225 | +$(my.indent)if ($(my.symbol)) |
| 226 | + $(my.indent)set( $(my.option.name:c) "$(my.option.value)" ) |
| 227 | +$(my.indent)endif() |
| 228 | + |
| 229 | +. endif |
| 230 | +.endmacro # emit_option |
| 231 | +. |
| 232 | +.macro emit_compound_flag(compound, repository, indent) |
| 233 | +. define my.indent = default_defined(emit_compound_flag.indent) |
| 234 | +. define my.compound = emit_compound_flag.compound |
| 235 | +. define my.repository = emit_compound_flag.repository |
| 236 | +. define my.define_prefix = "$(my.compound.type:upper)_" |
| 237 | +. |
| 238 | +. if defined(my.compound.option) |
| 239 | +. define my.option = my.repository->configure->option(name = my.compound.name) |
| 240 | +. if !defined(my.option) |
| 241 | +. abort("Matching option '$(my.compound.option)' not found for '$(my.compound.name)'.") |
| 242 | +. endif |
| 243 | +. endif |
| 244 | +. |
| 245 | +. my.opt_indent = defined(my.option) ?? join(" ", my.indent, "") ? "$(my.indent)" |
| 246 | +. define my.flags = join_flags_name(my.compound) |
| 247 | +. define my.symbol_prefix = defined(my.option) ?? "HAS_FLAGS_" ? my.define_prefix |
| 248 | +. |
| 249 | +. if defined(my.option) |
| 250 | +$(my.indent)if ($(get_option_symbol_generic(my.option, "-", "false"))) |
| 251 | +. endif |
| 252 | +$(my.opt_indent)check_cxx_compiler_flag("$(my.flags)" $(my.symbol_prefix)$(my.compound.name:upper)) |
| 253 | + |
| 254 | +$(my.opt_indent)if ($(my.symbol_prefix)$(my.compound.name:upper)) |
| 255 | +. for my.compound.flag as _flag where defined(_flag.name) & !is_empty(_flag.name) |
| 256 | + $(my.opt_indent)add_compile_options( $<$<COMPILE_LANGUAGE:CXX>:-$(_flag.name)> ) |
| 257 | +. endfor |
| 258 | +. if defined(my.compound->program) |
| 259 | + $(my.opt_indent)set( CMAKE_REQUIRED_FLAGS_PREV "${CMAKE_REQUIRED_FLAGS}" ) |
| 260 | + $(my.opt_indent)set( CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} $(my.flags)" ) |
| 261 | +. endif |
| 262 | +$(my.opt_indent)endif() |
| 263 | + |
| 264 | +. if defined(my.compound->program) |
| 265 | +$(my.opt_indent)check_cxx_source_compiles(" |
| 266 | +. for my.compound->program.include as _include |
| 267 | + $(my.opt_indent)#include <$(_include.header)> |
| 268 | +. endfor |
| 269 | + $(my.opt_indent)int main() { |
| 270 | +. for my.compound->program.loc as _loc |
| 271 | + $(my.opt_indent)$(_loc) |
| 272 | +. endfor |
| 273 | + $(my.opt_indent)}" $(my.define_prefix)$(my.compound.name:upper)) |
| 274 | + |
| 275 | +$(my.opt_indent)if ($(my.symbol_prefix)$(my.compound.name:upper)) |
| 276 | + $(my.opt_indent)set( CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS_PREV}" ) |
| 277 | +$(my.opt_indent)endif() |
| 278 | + |
| 279 | +. endif |
| 280 | +. |
| 281 | +$(my.opt_indent)if ( $(my.define_prefix)$(my.compound.name:upper) ) |
| 282 | + $(my.opt_indent)add_compile_definitions( $(my.define_prefix)$(my.compound.name:upper) ) |
| 283 | + $(my.opt_indent)set( $(my.compound.name:lower) "-D$(my.compound.type:upper)_$(my.compound.name:upper)" ) |
| 284 | +$(my.opt_indent)else() |
| 285 | + $(my.opt_indent)message( FATAL_ERROR "Failed to enable $(my.define_prefix)$(my.compound.name:upper)" ) |
| 286 | +$(my.opt_indent)endif() |
| 287 | +. if defined(my.option) |
| 288 | +$(my.indent)endif() |
| 289 | +. endif |
| 290 | + |
| 291 | +.endmacro # emit_compound_flag |
| 292 | +. |
| 293 | +.macro emit_find_package(dependency, features, indent) |
| 294 | +. define my.dependency = emit_find_package.dependency |
| 295 | +. define my.features = emit_find_package.features |
| 296 | +. define my.indent = default_defined(emit_find_package.indent) |
| 297 | +. require(my.dependency, "dependency", "name") |
| 298 | +. |
| 299 | +. heading2("Find $(my.dependency.name)") |
| 300 | +. if (count(my.features.element) > 0) |
| 301 | +$(my.indent)find_package( $(my.dependency.name:neat) $(my.dependency.version) REQUIRED COMPONENTS |
| 302 | +. for my.features.element as _element |
| 303 | + $(my.indent)$(_element.name)$(last() ?? " )" ? "") |
| 304 | +. endfor |
| 305 | + |
| 306 | +. for my.features.element as _element |
| 307 | +$(my.indent)set( $(my.dependency.name)_$(_element.name)_LIBS "-l$(my.dependency.name)_$(_element.name)" ) |
| 308 | +. endfor |
| 309 | +. else |
| 310 | +$(my.indent)find_package( $(my.dependency.name) $(my.dependency.version) ) |
| 311 | +. endif |
| 312 | + |
| 313 | +.# NOTE: enable-ndebug hardcoded match to configuration option |
| 314 | +$(my.indent)set( $(my.dependency.name:neat)_LIBRARY_DIR $<IF:$<BOOL:${enable-ndebug}>,"\${$(my.dependency.name:neat)_LIBRARY_DIR_RELEASE}","\${$(my.dependency.name:neat)_LIBRARY_DIR_DEBUG}">) |
| 315 | + |
| 316 | +$(my.indent)set( $(my.dependency.name)_CPPFLAGS "-I\${$(my.dependency.name:neat)_INCLUDE_DIR}" ) |
| 317 | +$(my.indent)set( $(my.dependency.name)_LDFLAGS "-L\${$(my.dependency.name:neat)_LIBRARY_DIR}" ) |
| 318 | + |
| 319 | +.endmacro # emit_find_package |
| 320 | +. |
| 321 | +.endtemplate |
| 322 | +.template 0 |
| 323 | +############################################################################### |
| 324 | +# Generation |
| 325 | +############################################################################### |
| 326 | +function generate_CMakeLists(path_prefix, repositories) |
| 327 | + define my.repositories = generate_CMakeLists.repositories |
| 328 | + define my.proj_relative = project_relative_cmake_path() |
| 329 | + define my.filename = "CMakeLists.txt" |
| 330 | + |
| 331 | + for my.repositories.repository as _repository |
| 332 | + require(_repository, "repository", "name") |
| 333 | + define my.output_path = append_path(append_path(my.path_prefix,\ |
| 334 | + _repository.name), my.proj_relative) |
| 335 | + create_directory(my.output_path) |
| 336 | + define my.out_file = append_path(my.output_path, my.filename) |
| 337 | + notify(my.out_file) |
| 338 | + output(my.out_file) |
| 339 | + emit_CMakeLists(_repository, my.repositories) |
| 340 | + close |
| 341 | + endfor _repository |
| 342 | +endfunction # generate_cmakelists |
| 343 | + |
| 344 | +############################################################################### |
| 345 | +# Execution |
| 346 | +############################################################################### |
| 347 | +[global].root = ".." |
| 348 | +[global].trace = 0 |
| 349 | +[gsl].ignorecase = 0 |
| 350 | + |
| 351 | +# Note: expected context root libbitcoin-build directory |
| 352 | +gsl from "library/math.gsl" |
| 353 | +gsl from "library/string.gsl" |
| 354 | +gsl from "library/collections.gsl" |
| 355 | +gsl from "templates/cmake/utilities.gsl" |
| 356 | +gsl from "utilities.gsl" |
| 357 | + |
| 358 | +generate_CMakeLists("output", generate) |
| 359 | + |
| 360 | +.endtemplate |
0 commit comments