File: cmake_modules.patch

package info (click to toggle)
btas 1.0.0-1.1
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 2,132 kB
  • sloc: cpp: 26,486; ansic: 1,545; makefile: 5
file content (669 lines) | stat: -rw-r--r-- 27,551 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
--- /dev/null	2025-03-18 20:37:21.187999959 +0100
+++ ./cmake/modules/FetchWfn91LinAlgModules.cmake	2025-03-30 12:07:38.473256684 +0200
@@ -0,0 +1,24 @@
+# - fetches github.com/wavefunction91/linalg-cmake-modules
+
+# prerequisites:
+# 1. cmake with FetchContent
+cmake_minimum_required (VERSION 3.11.0)
+# 2. linalg-cmake-modules try_compile's C code
+get_property(_enabled_languages GLOBAL PROPERTY ENABLED_LANGUAGES)
+if (NOT C IN_LIST _enabled_languages)
+    enable_language(C)
+endif(NOT C IN_LIST _enabled_languages)
+
+# download linalg-cmake-modules, if needed
+include(FetchContent)
+FetchContent_Declare(
+        linalg-cmake-modules
+        QUIET
+        GIT_REPOSITORY  https://github.com/wavefunction91/linalg-cmake-modules.git
+        GIT_TAG         0bc70fba80f798f3093771f450e906eb31f3b056
+)
+FetchContent_GetProperties(linalg-cmake-modules)
+if(NOT linalg-cmake-modules_POPULATED)
+    FetchContent_Populate(linalg-cmake-modules)
+    list(APPEND CMAKE_MODULE_PATH "${linalg-cmake-modules_SOURCE_DIR}")
+endif(NOT linalg-cmake-modules_POPULATED)
--- /dev/null	2025-03-18 20:37:21.187999959 +0100
+++ ./cmake/modules/FindLinalg.cmake	2025-03-30 11:54:38.152904265 +0200
@@ -0,0 +1,23 @@
+# finds BLAS, LAPACK and, if ENABLE_SCALAPACK=TRUE, ScaLAPACK
+# include(FetchWfn91LinAlgModules) if want to use NWChemEx/WFN91's linear algebra discovery modules
+
+if (ENABLE_SCALAPACK)
+    find_package(ScaLAPACK REQUIRED)
+    # Propagate ScaLAPACK -> BLAS/LAPACK if not set
+    # (ScaLAPACK necessarily contains a BLAS/LAPACK linker by standard)
+    # TODO: Tell David to write a macro that hides this verbosity from user space
+    if (NOT BLAS_LIBRARIES)
+        set(BLAS_LIBRARIES "${ScaLAPACK_LIBRARIES}" CACHE STRING "BLAS LIBRARIES")
+    endif ()
+    if (NOT LAPACK_LIBRARIES)
+        set(LAPACK_LIBRARIES "${ScaLAPACK_LIBRARIES}" CACHE STRING "LAPACK LIBRARIES")
+    endif ()
+else (ENABLE_SCALAPACK)
+    find_package(LAPACK REQUIRED)
+    # Propagate LAPACK -> BLAS if not set
+    # (LAPACK necessarily contains a BLAS linker by standard)
+    # TODO: Tell David to write a macro that hides this verbosity from user space
+    if (NOT BLAS_LIBRARIES)
+        set(BLAS_LIBRARIES "${LAPACK_LIBRARIES}" CACHE STRING "BLAS LIBRARIES")
+    endif ()
+endif (ENABLE_SCALAPACK)
--- /dev/null	2025-03-18 20:37:21.187999959 +0100
+++ ./cmake/modules/FindOrFetchLinalgPP.cmake	2025-03-30 11:55:24.623203575 +0200
@@ -0,0 +1,105 @@
+# BLAS++ / LAPACK++
+include(CTest) # defines BUILD_TESTING option
+set(OLD_BUILD_TESTING "${BUILD_TESTING}") # Save testing state
+set(BUILD_TESTING OFF CACHE BOOL "Enable Testing" FORCE) # Disable LinAlgPP Testing
+
+if (NOT TARGET blaspp)
+    find_package(blaspp QUIET CONFIG)
+
+    if (TARGET blaspp)
+        message(STATUS "Found blaspp CONFIG at ${blaspp_CONFIG}")
+    else (TARGET blaspp)
+        cmake_minimum_required(VERSION 3.14.0)  # for FetchContent_MakeAvailable
+        include(FetchContent)
+        include(${CMAKE_CURRENT_LIST_DIR}/versions.cmake)
+        FetchContent_Declare(blaspp
+                GIT_REPOSITORY https://github.com/icl-utk-edu/blaspp.git
+                GIT_TAG ${VGCMAKEKIT_TRACKED_BLASPP_TAG}
+                )
+
+        FetchContent_MakeAvailable(blaspp)
+
+        # set blaspp_CONFIG to the install location so that we know where to find it
+        set(blaspp_CONFIG ${CMAKE_INSTALL_PREFIX}/lib/blaspp/blasppConfig.cmake)
+    endif (TARGET blaspp)
+endif (NOT TARGET blaspp)
+
+if (NOT TARGET lapackpp)
+    find_package(OpenMP QUIET) #XXX Open LAPACKPP issue for this...
+    find_package(lapackpp QUIET CONFIG)
+    if (TARGET lapackpp)
+        message(STATUS "Found lapackpp CONFIG at ${lapackpp_CONFIG}")
+    else (TARGET lapackpp)
+        cmake_minimum_required(VERSION 3.14.0)  # for FetchContent_MakeAvailable
+        include(FetchContent)
+        include(${CMAKE_CURRENT_LIST_DIR}/versions.cmake)
+        FetchContent_Declare(lapackpp
+                GIT_REPOSITORY https://github.com/icl-utk-edu/lapackpp.git
+                GIT_TAG ${VGCMAKEKIT_TRACKED_LAPACKPP_TAG}
+                )
+
+        FetchContent_MakeAvailable(lapackpp)
+
+        # set lapackpp_CONFIG to the install location so that we know where to find it
+        set(lapackpp_CONFIG ${CMAKE_INSTALL_PREFIX}/lib/lapackpp/lapackppConfig.cmake)
+    endif (TARGET lapackpp)
+endif (NOT TARGET lapackpp)
+
+##################### Introspect BLAS/LAPACK libs
+
+# Check if BLAS/LAPACK is MKL
+include(CheckFunctionExists)
+include(CMakePushCheckState)
+cmake_push_check_state(RESET)
+set(CMAKE_REQUIRED_LIBRARIES "${blaspp_libraries}" m)
+check_function_exists(mkl_dimatcopy BLAS_IS_MKL)
+cmake_pop_check_state()
+
+# blaspp_header library is a target that permits #include'ing library-specific headers, e.g. mkl.h
+if (NOT TARGET blaspp_headers)
+
+    add_library(blaspp_headers INTERFACE)
+
+    if (BLAS_IS_MKL)
+        foreach (_lib ${blaspp_libraries})
+            if (EXISTS ${_lib} AND _lib MATCHES libmkl_)
+                string(REGEX REPLACE "/lib/(intel64_lin/|intel64/|)libmkl_.*" "" _mklroot "${_lib}")
+            elseif (_lib MATCHES "^-L")
+                string(REGEX REPLACE "^-L" "" _mklroot "${_lib}")
+                string(REGEX REPLACE "/lib(/intel64_lin|/intel64|)(/|)" "" _mklroot "${_mklroot}")
+            endif ()
+            if (_mklroot)
+                break()
+            endif (_mklroot)
+        endforeach ()
+
+        set(_mkl_include)
+        if (EXISTS "${_mklroot}/include")
+            set(_mkl_include "${_mklroot}/include")
+        elseif (EXISTS "/usr/include/mkl") # ubuntu package
+            set(_mkl_include "/usr/include/mkl")
+        endif ()
+        if (_mkl_include AND EXISTS "${_mkl_include}")
+            target_include_directories(blaspp_headers INTERFACE "${_mkl_include}")
+        endif (_mkl_include AND EXISTS "${_mkl_include}")
+
+    endif (BLAS_IS_MKL)
+
+    # mirror blaspp: see https://github.com/icl-utk-edu/blaspp/blob/1507102eb77070bf6f786ad54c4453402eb2fa42/CMakeLists.txt#L512
+    include(GNUInstallDirs)
+    if (WIN32)
+        set( blaspp_install_configdir "blaspp" )
+    else()
+        set( blaspp_install_configdir "${CMAKE_INSTALL_LIBDIR}/cmake/blaspp" )
+    endif()
+
+    install(TARGETS blaspp_headers EXPORT blaspp_headers)
+    export(EXPORT blaspp_headers FILE "${PROJECT_BINARY_DIR}/blaspp_headers-targets.cmake")
+    install(EXPORT blaspp_headers
+            FILE "blaspp_headers-targets.cmake"
+            DESTINATION "${blaspp_install_configdir}"
+            )
+
+endif (NOT TARGET blaspp_headers)
+
+set(BUILD_TESTING "${OLD_BUILD_TESTING}" CACHE BOOL "Enable Testing" FORCE) # Potentially re-enable testing based on saved state
--- /dev/null	2025-03-18 20:37:21.187999959 +0100
+++ ./cmake/modules/FindOrFetchBoost.cmake	2025-03-30 11:55:49.854322394 +0200
@@ -0,0 +1,505 @@
+# -*- mode: cmake -*-
+
+# definitions:
+# - "library": e.g. Boost.PropertyTree, corresponds to the contents of subdirectory contained in libs/
+# - "component": Boost package components given via
+#   - COMPONENTS and OPTIONAL_COMPONENTS) to the find_package command used to import Boost in CMake, or
+#   - Boost_INCLUDE_LIBRARIES variable passed to the Boost CMake harness used by the FetchContent command to build Boost
+#     from source
+# - "target": an IMPORTED CMake target defined by Boost, e.g. Boost::headers
+
+# facts:
+# - every library X (Boost.X) is usually also a component X, but
+#   - some correspond to multiple components or versioned components (e.g. Boost.Python is a library that corresponds to components pythonXY and numpyXY,
+#     where XY is the Python version), and some correspond to no components or a part of a component (e.g. ccomponent
+#     "headers"  contains all header-only libraries
+#   - basically, original Boost CMake toolkit (i.e., the FindBoost CMake module) had 1 component (boost)
+#     for all header-onlu libraries and one component for each non-header-only library
+#   - modular Boost CMake harness has at least component per library (header-only or otherwise),
+#     but sometimes more than 1
+# - every component X usually correspond to IMPORTED target Boost::X ; exceptions include:
+#   - Boost::boost is not a component; Boost::headers is an alias for Boost::boost
+#   - targets Boost::numeric_{conversion,interval,odeint,ublas} are defined by component numeric
+
+# input variables:
+# Boost_REQUIRED_COMPONENTS: list of required components; these are components defined by the modular Boost (not by the old cmake harness)
+# Boost_OPTIONAL_COMPONENTS: list of optional components; these are components defined by the modular Boost (not by the old cmake harness)
+# Boost_FETCH_IF_MISSING: if set to ON, will download and build Boost if it is not found
+
+# hints:
+# BOOST_ROOT: preferred installation prefix (see https://cmake.org/cmake/help/latest/module/FindBoost.html)
+# BOOST_INCLUDEDIR: preferred include directory e.g. <prefix>/include. (see https://cmake.org/cmake/help/latest/module/FindBoost.html)
+
+# output variables:
+# Boost_BUILT_FROM_SOURCE: ON if Boost was built from source
+# Boost_USE_CONFIG: if Boost_BUILT_FROM_SOURCE is ON, this indicates whether found Boost via config mode
+# Boost_CONFIG: if Boost_BUILT_FROM_SOURCE and Boost_USE_CONFIG are ON, this specifies the config file used
+# Boost_IS_MODULARIZED: if Boost targets are modularized (i.e. not the old cmake harness)
+# Boost_FOUND_COMPONENTS: list of modular components that were found
+# Boost_FOUND_TARGETS: list of modular targets (X in Boost::X or boost_X) that were found
+# Boost_FOUND_COMPONENTS_NONMODULAR: list of non-modular components that were found
+# Boost_FOUND_TARGETS_NONMODULAR: list of non-modular targets (X in Boost::X) that were found
+# Boost_MODULAR_TARGETS_NOT_BUILT_BY_INSTALL: CACHE variable containing the list of modular targets that
+#   are not built automatically when the "install" target is built; if Boost_BUILT_FROM_SOURCE is ON,
+#   for each target X in this list user will want to add an artificial dependence of their target(s)
+#   on target boost_X
+
+# list of all non-modular components
+set(Boost_ALL_COMPONENTS_NONMODULAR
+        headers
+        # see https://www.boost.org/doc/libs/master/more/getting_started/unix-variants.html#header-only-libraries
+        chrono
+        context
+        graph
+        filesystem
+        iostreams
+        locale
+        log
+        math_tr1
+        math_c99
+        mpi
+        program_options
+        python
+        random
+        regex
+        serialization
+        thread
+        timer
+        wave
+   )
+
+# list of all modular components
+set(Boost_ALL_COMPONENTS
+        algorithm
+        align
+        any
+        atomic
+        array
+        assert
+        bind
+        chrono
+        circular_buffer
+        compute
+        concept_check
+        config
+        container
+        container_hash
+        conversion
+        core
+        date_time
+        describe
+        detail
+        dynamic_bitset
+        endian
+        exception
+        filesystem
+        function
+        functional
+        function_types
+        fusion
+        headers
+        integer
+        intrusive
+        io
+        iostreams
+        iterator
+        lexical_cast
+        logic
+        math
+        move
+        mp11
+        mpl
+        multiprecision
+        multi_index
+        numeric_conversion
+        numeric_interval
+        #numeric_odeint
+        numeric_ublas
+        optional
+        parameter
+        phoenix
+        pool
+        predef
+        preprocessor
+        property_tree
+        proto
+        random
+        range
+        ratio
+        regex
+        serialization
+        smart_ptr
+        spirit
+        static_assert
+        system
+        test
+        thread
+        throw_exception
+        tokenizer
+        tti
+        tuple
+        typeof
+        type_index
+        type_traits
+        unordered
+        utility
+        uuid
+        variant
+        variant2
+        winapi)
+
+set(Boost_MODULAR_TARGETS_NOT_BUILT_BY_INSTALL "filesystem;unit_test_framework" CACHE STRING "list of Boost targets not built by install target")
+
+# converts modular component _comp to list of targets defined by the component
+# target name x means TARGET Boost::x is defined
+macro(component_to_targets _comp _targets)
+    if (${${_comp}} STREQUAL test)
+        set(${_targets} unit_test_framework)
+    else()
+        set(${_targets} ${${_comp}})
+    endif()
+endmacro()
+
+macro(intersection _out _in1 _in2)
+    set(${_out})
+    foreach(x IN LISTS ${_in1})
+        if(x IN_LIST ${_in2})
+            list(APPEND ${_out} ${x})
+        endif()
+    endforeach()
+endmacro()
+
+# elements in _in1 that are not in _in2
+macro(difference _out _in1 _in2)
+    set(${_out})
+    foreach(x IN LISTS ${_in1})
+        if(NOT(x IN_LIST ${_in2}))
+            list(APPEND ${_out} ${x})
+        endif()
+    endforeach()
+endmacro()
+
+# Limit scope of the search if BOOST_ROOT or BOOST_INCLUDEDIR is provided.
+if (BOOST_ROOT OR BOOST_INCLUDEDIR)
+    set(Boost_NO_SYSTEM_PATHS TRUE)
+endif()
+
+intersection(Boost_REQUIRED_COMPONENTS_NONMODULAR Boost_REQUIRED_COMPONENTS Boost_ALL_COMPONENTS_NONMODULAR)
+intersection(Boost_OPTIONAL_COMPONENTS_NONMODULAR Boost_OPTIONAL_COMPONENTS Boost_ALL_COMPONENTS_NONMODULAR)
+# Boost_REQUIRED_COMPONENTS_NONMODULAR may intersect with Boost_OPTIONAL_COMPONENTS_NONMODULAR, exclude those components from Boost_OPTIONAL_COMPONENTS_NONMODULAR
+difference(Boost_OPTIONAL_COMPONENTS_NONMODULAR_NOT_IN_REQUIRES Boost_OPTIONAL_COMPONENTS_NONMODULAR Boost_REQUIRED_COMPONENTS_NONMODULAR)
+set(Boost_OPTIONAL_COMPONENTS_NONMODULAR ${Boost_OPTIONAL_COMPONENTS_NONMODULAR_NOT_IN_REQUIRES})
+
+# detect which Boost targets I already have
+foreach(__comp headers ${Boost_REQUIRED_COMPONENTS_NONMODULAR} ${Boost_OPTIONAL_COMPONENTS_NONMODULAR})
+    component_to_targets(__comp __targets)
+    foreach(tgt IN LISTS __targets)
+        if (TARGET Boost::${tgt})
+            set(vgck_imported_boost_${tgt} 0)
+        else()
+            set(vgck_imported_boost_${tgt} 1)
+        endif()
+    endforeach()
+endforeach()
+
+# try config first
+# OPTIONAL_COMPONENTS in FindBoost available since 3.11
+cmake_minimum_required(VERSION 3.11.0)
+# if Boost was loaded via config file or have not found Boost yet
+if (DEFINED Boost_CONFIG OR NOT TARGET Boost::headers)
+  find_package(Boost ${Boost_OLDEST_BOOST_VERSION} CONFIG COMPONENTS ${Boost_REQUIRED_COMPONENTS_NONMODULAR} OPTIONAL_COMPONENTS ${Boost_OPTIONAL_COMPONENTS_NONMODULAR})
+endif()
+if (NOT DEFINED Boost_CONFIG AND NOT TARGET Boost::headers)
+    if(POLICY CMP0167)
+      cmake_policy(SET CMP0167 NEW)
+    endif()
+    find_package(Boost ${Boost_OLDEST_BOOST_VERSION} COMPONENTS ${Boost_REQUIRED_COMPONENTS_NONMODULAR} OPTIONAL_COMPONENTS ${Boost_OPTIONAL_COMPONENTS_NONMODULAR})
+    if (TARGET Boost::headers)
+        set(Boost_USE_CONFIG FALSE)
+    endif(TARGET Boost::headers)
+else()
+    set(Boost_USE_CONFIG TRUE)
+endif()
+
+# Boost::* targets by default are not GLOBAL, so to allow users of LINALG_LIBRARIES to safely use them we need to make them global
+# more discussion here: https://gitlab.kitware.com/cmake/cmake/-/issues/17256
+foreach(__comp headers ${Boost_REQUIRED_COMPONENTS_NONMODULAR} ${Boost_OPTIONAL_COMPONENTS_NONMODULAR})
+    component_to_targets(__comp __targets)
+    foreach(tgt IN LISTS __targets)
+        if (TARGET Boost::${tgt} AND vgck_imported_boost_${tgt})
+            get_target_property(_boost_tgt_${tgt}_is_imported_global Boost::${tgt} IMPORTED_GLOBAL)
+            if (NOT _boost_tgt_${tgt}_is_imported_global)
+                set_target_properties(Boost::${tgt} PROPERTIES IMPORTED_GLOBAL TRUE)
+            endif()
+            unset(_boost_tgt_${tgt}_is_imported_global)
+        endif()
+    endforeach()
+endforeach()
+
+# detect which components are missing
+set(__missing_nonmodular_boost_components )  # there should not be any if find_package succeeded, i.e. Boost_FOUND is true
+foreach(__comp IN LISTS Boost_REQUIRED_COMPONENTS_NONMODULAR)
+    component_to_targets(__comp __targets)
+    foreach(tgt IN LISTS __targets)
+        if (NOT TARGET Boost::${tgt})
+            list(APPEND __missing_nonmodular_boost_components ${__comp})
+        endif()
+    endforeach()
+endforeach()
+set(__missing_required_modular_boost_components )
+foreach(__comp IN LISTS Boost_REQUIRED_COMPONENTS)
+    component_to_targets(__comp __targets)
+    foreach(tgt IN LISTS __targets)
+        if (NOT TARGET Boost::${tgt})
+            list(APPEND __missing_required_modular_boost_components ${__comp})
+        endif()
+    endforeach()
+endforeach()
+
+# if Boost was loaded via find_package check if have all REQUIRED components
+if (Boost_FOUND)
+    if (__missing_nonmodular_boost_components)
+        message(FATAL_ERROR "Boost was discovered successfully via find_package(Boost) but components \"${__missing_nonmodular_boost_components}\" required by ${PROJECT_NAME} were not found")
+    endif()
+endif()
+
+if (NOT Boost_FOUND AND __missing_required_modular_boost_components AND Boost_FETCH_IF_MISSING)
+
+  message(WARNING "FetchContent'ing Boost")
+
+  # Boost can only be build once in a source tree
+  if (Boost_POPULATED)
+      message(FATAL_ERROR "Boost was not found by project ${PROJECT_NAME} and Boost_FETCH_IF_MISSING=ON, but someone already build Boost via FetchContent with components \"${__missing_required_modular_boost_components}\" required by this project are missing; add these components to the original FetchContent stanza")
+  endif()
+
+  include (FetchContent)
+  cmake_minimum_required (VERSION 3.24.0)  # for ExternalProject_add's DOWNLOAD_EXTRACT_TIMESTAMP option
+
+  set(BOOST_SUPERPROJECT_VERSION 1.84.0)
+  FetchContent_Declare(
+          Boost
+          URL https://github.com/boostorg/boost/releases/download/boost-${BOOST_SUPERPROJECT_VERSION}/boost-${BOOST_SUPERPROJECT_VERSION}.tar.xz
+          URL_HASH MD5=893b5203b862eb9bbd08553e24ff146a
+          DOWNLOAD_EXTRACT_TIMESTAMP ON
+  )
+
+  if (NOT DEFINED BOOST_INCLUDE_LIBRARIES)
+      set(BOOST_INCLUDE_LIBRARIES headers)
+  else()
+      list(APPEND BOOST_INCLUDE_LIBRARIES headers)
+  endif()
+  if (DEFINED Boost_REQUIRED_COMPONENTS)
+      list(APPEND BOOST_INCLUDE_LIBRARIES ${Boost_REQUIRED_COMPONENTS})
+  endif()
+  if (DEFINED Boost_OPTIONAL_COMPONENTS)
+      list(APPEND BOOST_INCLUDE_LIBRARIES ${Boost_OPTIONAL_COMPONENTS})
+  endif()
+  list(REMOVE_DUPLICATES BOOST_INCLUDE_LIBRARIES)
+  message(WARNING "FetchContent Boost package with the following components: ${BOOST_INCLUDE_LIBRARIES}")
+  # for now build everything
+  set(BOOST_INCLUDE_LIBRARIES_CURRENT ${BOOST_INCLUDE_LIBRARIES})
+  unset(BOOST_INCLUDE_LIBRARIES)
+
+  FetchContent_GetProperties(Boost)
+
+  if(NOT Boost_POPULATED)
+
+    message(STATUS "Fetching Boost")
+    FetchContent_Populate(Boost)
+    message(STATUS "Fetching Boost done")
+    FetchContent_GetProperties(Boost
+            SOURCE_DIR Boost_SOURCE_DIR
+            BINARY_DIR Boost_BINARY_DIR
+    )
+
+    message(STATUS "Configuring Boost: downloaded to ${Boost_SOURCE_DIR}, to be built in ${Boost_BINARY_DIR}")
+    add_subdirectory(${Boost_SOURCE_DIR} ${Boost_BINARY_DIR} EXCLUDE_FROM_ALL)
+    # unity build not supported for some Boost libraries
+    foreach (unity_broken_lib locale serialization)
+      if (TARGET boost_${unity_broken_lib})
+        message(STATUS "Will disable unity-build for boost_${unity_broken_lib}")
+        set_property(TARGET boost_${unity_broken_lib} PROPERTY UNITY_BUILD OFF)
+      endif()
+    endforeach()
+
+  endif()
+
+  # TODO figure out how to deduce the list of dependent components
+  # for now just use all of them, i.e. Boost_ALL_COMPONENTS
+  set(BOOST_INCLUDE_LIBRARIES ${BOOST_INCLUDE_LIBRARIES_CURRENT})
+  set(BOOST_INCLUDE_LIBRARIES_FULL "headers;${BOOST_INCLUDE_LIBRARIES};${Boost_ALL_COMPONENTS}")
+  list(REMOVE_DUPLICATES BOOST_INCLUDE_LIBRARIES_FULL)
+
+  # Boost install is only enabled when Boost is the top-level project, and there is no way to override
+  # this, so here we invoke boost_install commands ourselves; this requires setting some variables that are set
+  # by BoostRoot.cmake
+  set(BOOST_SKIP_INSTALL_RULES OFF)
+  set(BOOST_SUPERPROJECT_SOURCE_DIR "${Boost_SOURCE_DIR}")
+  set(BOOST_INSTALL_CMAKEDIR "lib/cmake")
+  if (DEFINED PROJECT_VERSION)
+      set(ACTUAL_PROJECT_VERSION ${PROJECT_VERSION})
+  endif(DEFINED PROJECT_VERSION)
+  set(PROJECT_VERSION ${BOOST_SUPERPROJECT_VERSION})
+  foreach(lib IN LISTS BOOST_INCLUDE_LIBRARIES_FULL)
+
+      # deduce the location of headers ... for some libraries it does not match the basic pattern
+      set(__HEADER_DIRECTORY "${BOOST_SUPERPROJECT_SOURCE_DIR}/libs/${lib}/include")
+      if (lib STREQUAL numeric_conversion)
+          set(__HEADER_DIRECTORY ${BOOST_SUPERPROJECT_SOURCE_DIR}/libs/numeric/conversion/include)
+      endif()
+      if (lib STREQUAL numeric_interval)
+          set(__HEADER_DIRECTORY ${BOOST_SUPERPROJECT_SOURCE_DIR}/libs/numeric/interval/include)
+      endif()
+      if (lib STREQUAL numeric_odeint)
+          set(__HEADER_DIRECTORY ${BOOST_SUPERPROJECT_SOURCE_DIR}/libs/numeric/odeint/include)
+      endif()
+      if (lib STREQUAL numeric_ublas)
+          set(__HEADER_DIRECTORY ${BOOST_SUPERPROJECT_SOURCE_DIR}/libs/numeric/ublas/include)
+      endif()
+
+      # convert the list of components to a list of targets
+      component_to_targets(lib __lib_targets)
+      # convert target T to boost_T
+      set(__lib_targets_w_boost_prepended )
+      foreach(__target IN LISTS __lib_targets)
+          list(APPEND __lib_targets_w_boost_prepended boost_${__target})
+      endforeach()
+
+      boost_install(TARGETS "${__lib_targets_w_boost_prepended}" VERSION "${BOOST_SUPERPROJECT_VERSION}" HEADER_DIRECTORY "${__HEADER_DIRECTORY}")
+
+      # Create the targets file in build tree also
+      foreach(__target IN LISTS __lib_targets_w_boost_prepended)
+          export(EXPORT ${__target}-targets
+                 NAMESPACE Boost::
+                 FILE "${PROJECT_BINARY_DIR}/${__target}-targets.cmake")
+      endforeach()
+  endforeach()
+
+  if (DEFINED ACTUAL_PROJECT_VERSION)
+      set(PROJECT_VERSION ${ACTUAL_PROJECT_VERSION})
+  else(DEFINED ACTUAL_PROJECT_VERSION)
+      unset(PROJECT_VERSION)
+  endif(DEFINED ACTUAL_PROJECT_VERSION)
+
+  # result
+  set(Boost_BUILT_FROM_SOURCE ON)
+  set(Boost_IS_MODULARIZED ON)
+
+endif(NOT Boost_FOUND AND __missing_required_modular_boost_components AND Boost_FETCH_IF_MISSING)
+
+# extract components that were found
+set(Boost_FOUND_COMPONENTS_NONMODULAR )
+set(Boost_FOUND_COMPONENTS )
+set(Boost_FOUND_TARGETS_NONMODULAR )
+set(Boost_FOUND_TARGETS )
+foreach(__comp headers ${Boost_REQUIRED_COMPONENTS_NONMODULAR} ${Boost_OPTIONAL_COMPONENTS_NONMODULAR})
+    component_to_targets(__comp __targets)
+    foreach(tgt IN LISTS __targets)
+        if (TARGET Boost::${tgt})
+            list(APPEND Boost_FOUND_COMPONENTS_NONMODULAR ${__comp})
+            list(APPEND Boost_FOUND_TARGETS_NONMODULAR ${tgt})
+        endif()
+    endforeach()
+endforeach()
+list(REMOVE_DUPLICATES Boost_FOUND_COMPONENTS_NONMODULAR)
+list(REMOVE_DUPLICATES Boost_FOUND_TARGETS_NONMODULAR)
+foreach(__comp headers ${Boost_REQUIRED_COMPONENTS} ${Boost_OPTIONAL_COMPONENTS})
+    component_to_targets(__comp __targets)
+    foreach(tgt IN LISTS __targets)
+        if (TARGET Boost::${tgt})
+            list(APPEND Boost_FOUND_COMPONENTS ${__comp})
+            list(APPEND Boost_FOUND_TARGETS ${tgt})
+        endif()
+    endforeach()
+endforeach()
+list(REMOVE_DUPLICATES Boost_FOUND_COMPONENTS)
+list(REMOVE_DUPLICATES Boost_FOUND_TARGETS)
+
+# Boost::boost is an alias for Boost::headers defined by boost-config.cmake
+if (Boost_IS_MODULARIZED AND NOT TARGET Boost::boost AND TARGET boost_headers)
+    add_library(Boost::boost ALIAS boost_headers)
+endif()
+
+set(Boost_CONFIG_FILE_CONTENTS
+"
+# converts modular component _comp to list of targets defined by the component
+# target name x means TARGET Boost::x is defined .. this is provided just in case on needs to map components to targets
+macro(component_to_targets _comp _targets)
+    if (\${\${_comp}} STREQUAL test)
+        set(\${_targets} unit_test_framework)
+    else()
+        set(\${_targets} \${\${_comp}})
+    endif()
+endmacro()
+
+#########################################
+# import boost components, if any missing
+#########################################
+set(Boost_IS_MODULARIZED ${Boost_IS_MODULARIZED})
+if (Boost_IS_MODULARIZED)
+  set(Boost_FOUND_COMPONENTS ${Boost_FOUND_COMPONENTS})
+  set(Boost_FOUND_TARGETS ${Boost_FOUND_TARGETS})
+else(Boost_IS_MODULARIZED)
+  set(Boost_FOUND_COMPONENTS ${Boost_FOUND_COMPONENTS_NONMODULAR})
+  set(Boost_FOUND_TARGETS ${Boost_FOUND_TARGETS_NONMODULAR})
+endif(Boost_IS_MODULARIZED)
+
+set(Boost_DEPS_LIBRARIES_NOT_FOUND_CHECK \"NOT;TARGET;Boost::headers\")
+foreach(_tgt \${Boost_FOUND_TARGETS})
+  list(APPEND Boost_DEPS_LIBRARIES_NOT_FOUND_CHECK \"OR;NOT;TARGET;Boost::\${_tgt}\")
+endforeach(_tgt)
+
+if(\${Boost_DEPS_LIBRARIES_NOT_FOUND_CHECK})
+  include( CMakeFindDependencyMacro )
+  set(Boost_BUILT_FROM_SOURCE ${Boost_BUILT_FROM_SOURCE})
+  if (NOT Boost_BUILT_FROM_SOURCE)
+    set(Boost_USE_CONFIG ${Boost_USE_CONFIG})
+    # OPTIONAL_COMPONENTS in FindBoost available since 3.11
+    cmake_minimum_required(VERSION 3.11.0)
+    if (Boost_USE_CONFIG)
+      set(Boost_CONFIG ${Boost_CONFIG})
+      if (NOT Boost_CONFIG OR NOT EXISTS \${Boost_CONFIG})
+        message(FATAL_ERROR \"Expected Boost config file at \${Boost_CONFIG}; directory moved since BTAS configuration?\")
+      endif()
+      get_filename_component(Boost_DIR \${Boost_CONFIG} DIRECTORY)
+      find_dependency(Boost REQUIRED OPTIONAL_COMPONENTS \${Boost_FOUND_COMPONENTS} PATHS \${Boost_DIR} NO_DEFAULT_PATH)
+    else (Boost_USE_CONFIG)
+      set(BOOST_INCLUDEDIR ${Boost_INCLUDE_DIR})
+      set(BOOST_LIBRARYDIR ${Boost_LIBRARY_DIR_RELEASE})
+      if (NOT BOOST_LIBRARYDIR OR NOT EXISTS \${BOOST_LIBRARYDIR})
+        set(BOOST_LIBRARYDIR ${Boost_LIBRARY_DIR_DEBUG})
+      endif()
+      set(Boost_NO_SYSTEM_PATHS OFF)
+      if (BOOST_LIBRARYDIR AND BOOST_INCLUDEDIR)
+        if (EXISTS \${BOOST_LIBRARYDIR} AND EXISTS \${BOOST_INCLUDEDIR})
+          set(Boost_NO_SYSTEM_PATHS ON)
+        endif()
+      endif()
+      find_dependency(Boost REQUIRED OPTIONAL_COMPONENTS \${Boost_FOUND_COMPONENTS})
+    endif (Boost_USE_CONFIG)
+  else(NOT Boost_BUILT_FROM_SOURCE)
+    foreach(_tgt IN LISTS Boost_FOUND_TARGETS)
+      if (NOT TARGET Boost::\${_tgt})
+        find_dependency(boost_\${_tgt} CONFIG REQUIRED)
+      endif()
+    endforeach(_tgt)
+  endif(NOT Boost_BUILT_FROM_SOURCE)
+endif(\${Boost_DEPS_LIBRARIES_NOT_FOUND_CHECK})
+
+"
+)
+
+# postcond check
+if (Boost_IS_MODULARIZED)
+    set(__required_components ${Boost_REQUIRED_COMPONENTS})
+else ()
+    set(__required_components ${Boost_REQUIRED_COMPONENTS_NONMODULAR})
+endif()
+foreach(__comp IN LISTS __required_components)
+    component_to_targets(__comp __targets)
+    foreach(tgt IN LISTS __targets)
+        if (NOT TARGET Boost::${tgt})
+            message(FATAL_ERROR "FindOrFetchBoost: TARGET Boost::${tgt} is required but not available; set Boost_FETCH_IF_MISSING=ON to build Boost as part of the project")
+        endif()
+    endforeach()
+endforeach()