SpECTRE Documentation Coverage Report
Current view: top level - __w/spectre/spectre/docs/Installation - BuildSystem.md Hit Total Coverage
Commit: e168c1aa7e6b7eeddf3f9be0a985c755ae24c13d Lines: 0 1 0.0 %
Date: 2026-09-15 09:43:04
Legend: Lines: hit not hit

          Line data    Source code
       1           0 : \cond NEVER
       2             : Distributed under the MIT License.
       3             : See LICENSE.txt for details.
       4             : \endcond
       5             : # Build System - CMake {#spectre_build_system}
       6             : 
       7             : \tableofcontents
       8             : 
       9             : SpECTRE uses [CMake](https://cmake.org/) for the build system. In this
      10             : guide we'll outline how to configure SpECTRE and
      11             : describe some [commonly used CMake flags](#common_cmake_flags).
      12             : We'll also go over how to
      13             : [add new source files](#adding_source_files),
      14             : [libraries](#adding_libraries),
      15             : [unit tests](#adding_unit_tests), [executables](#adding_executables), and
      16             : [external dependencies](#adding_external_dependencies).
      17             : 
      18             : # Configuring
      19             : 
      20             : The command to configure SpECTRE will look like this
      21             : 
      22             : ```
      23             : cmake -D FLAG1=OPT1 ... -D FLAGN=OPTN <SPECTRE_ROOT>
      24             : ```
      25             : 
      26             : where `FLAG{1..N}` are CMake flags that are detailed in the section on
      27             : [commonly used CMake flags](#common_cmake_flags).
      28             : 
      29             : CMake will look in your `$PATH` environment variable for all of the
      30             : [build dependencies](installation.html#build_dependencies) and will use the
      31             : first one it finds that satisfies the requirements. However, if a dependency is
      32             : not in your `$PATH`, there are multiple versions of a dependency, or you just
      33             : want to customize your configuration, you'll have to tell CMake which dependency
      34             : you want to use and where it is using CMake flags. To that end, even though the
      35             : [commonly used CMake flags](#common_cmake_flags) section has a more detailed
      36             : list of the flags available, the following list has the *most common* CMake
      37             : flags you'll need to customize your configuration (e.g. compilers, charm, build
      38             : type, and library types):
      39             : 
      40             : - CMAKE_C_COMPILER
      41             : - CMAKE_CXX_COMPILER
      42             : - CMAKE_Fortran_COMPILER
      43             : - CHARM_ROOT
      44             : - CMAKE_BUILD_TYPE
      45             : - BUILD_SHARED_LIBS
      46             : 
      47             : \note If you are on a cluster, take a look at the
      48             : [installation on clusters](installation_on_clusters.html)
      49             : instructions. If you are on a cluster we support, we will already have an
      50             : environment setup and an easy way for you to configure the build without having
      51             : to specify flags yourself.
      52             : 
      53             : ## Configuring with CMake presets {#cmake_presets}
      54             : 
      55             : Instead of passing flags on the command line every time, you can use
      56             : [CMake presets](https://cmake.org/cmake/help/latest/manual/cmake-presets.7.html)
      57             : to capture a configuration once and select it with `cmake --preset <name>`. The
      58             : build directory of a preset defaults to `build-<name>` in the source tree.
      59             : 
      60             : We provide a few standard presets that you can reuse on any machine:
      61             : 
      62             : - `debug`: a `Debug` build (`-O0`, all `ASSERT`s and sanity checks enabled),
      63             :   used while actively developing and debugging.
      64             : - `release-debug`: a `Release` build with `SPECTRE_DEBUG=ON`, so it keeps the
      65             :   `ASSERT`s and sanity checks but is optimized. **This is the preferred default
      66             :   for most runs**: the checks catch subtle bugs that only surface in long
      67             :   simulations and cost very little performance.
      68             : - `release`: a fully optimized `Release` build with no debug checks. Use this
      69             :   only when full performance is absolutely necessary.
      70             : 
      71             : These presets are assembled from building blocks defined in
      72             : `support/Environments/Presets.json`: `debug-flags`, `release-flags` and
      73             : `release-debug-flags`. You can combine these build-type flags with your own
      74             : machine-specific configuration that supplies the compilers and dependency paths.
      75             : 
      76             : - **On a personal machine**, create a `CMakeUserPresets.json` file in the source
      77             :   root (this file is git-ignored). Define a preset with your local compiler
      78             :   settings and dependency paths (e.g. name it `local`), then add
      79             :   `debug`/`release`/`release-debug` presets that combine `local` with the
      80             :   build-type flags. CMake reads `CMakeUserPresets.json` automatically, so `cmake
      81             :   --preset release-debug` will use your configuration. Here's an example
      82             :   `CMakeUserPresets.json`:
      83             :   ```json
      84             :   {
      85             :     "version": 7,
      86             :     "configurePresets": [
      87             :       {
      88             :         "name": "local",
      89             :         "inherits": "base",
      90             :         "hidden": true,
      91             :         "generator": "Ninja",
      92             :         "cacheVariables": {
      93             :           "CMAKE_C_COMPILER": "clang",
      94             :           "CMAKE_CXX_COMPILER": "clang++",
      95             :           "CMAKE_Fortran_COMPILER": "gfortran",
      96             :           "MEMORY_ALLOCATOR": "SYSTEM"
      97             :         }
      98             :       },
      99             :       {
     100             :         "name": "debug",
     101             :         "inherits": ["local", "debug-flags"]
     102             :       },
     103             :       {
     104             :         "name": "release",
     105             :         "inherits": ["local", "release-flags"]
     106             :       },
     107             :       {
     108             :         "name": "release-debug",
     109             :         "inherits": ["local", "release-debug-flags"]
     110             :       }
     111             :     ]
     112             :   }
     113             :   ```
     114             : - **On a supercomputer**, we supply preset files on supported machines. To use
     115             :   the correct preset file, set the `SPECTRE_MACHINE` environment variable
     116             :   (supported machines are listed in support/Environments/). Then, `cmake
     117             :   --preset release-debug` works just the same as on a personal machine (it pulls
     118             :   the correct presets through `CMakePresets.json` in the repository root). Use
     119             :   the environment shell scripts in support/Environments/ to load
     120             :   modules and set `SPECTRE_MACHINE`.
     121             : - **In git worktrees**, `CMakeUserPresets.json` is symlinked from the main
     122             :   checkout by a git hook, see `USE_GIT_HOOKS` below.
     123             : 
     124             : ## Commonly Used CMake flags {#common_cmake_flags}
     125             : The following are common flags used to control building SpECTRE with CMake (in
     126             : alphabetical order):
     127             : - ASAN
     128             :   - Whether or not to turn on the address sanitizer compile flags
     129             :     (`-fsanitize=address`) (default is `OFF`)
     130             : - BLAZE_USE_ALWAYS_INLINE
     131             :   - Force Blaze inlining (default is `ON`)
     132             :   - If disabled or if the platform is unable to 100% guarantee inlining,
     133             :     falls back to `BLAZE_USE_STRONG_INLINE` (see below)
     134             :   - Forced inlining reduces function call overhead, and so generally reduces
     135             :     runtime. However, it does increase compile time and compile memory usage. It
     136             :     is also easier to use a debugger when forced inlining is disabled. If you
     137             :     are encountering debugger messages like `function inlined`, then forced
     138             :     inlining should be disabled.
     139             : - BLAZE_USE_STRONG_INLINE
     140             :   - Increase the likelihood of Blaze inlining (default is `ON`)
     141             :   - Strong inlining reduces function call overhead, and so generally reduces
     142             :     runtime. However, it does increase compile time and compile memory usage. It
     143             :     is also easier to use a debugger when strong inlining is disabled. If you
     144             :     are encountering debugger messages like `function inlined`, then strong
     145             :     inlining should be disabled.
     146             : - BOOTSTRAP_PY_DEPS and BOOTSTRAP_PY_DEV_DEPS
     147             :   - Install missing Python dependencies into the build directory, as listed in
     148             :     `support/Python/requirements.txt` and `support/Python/dev_requirements.txt`,
     149             :     respectively. This is an alternative to creating a Python environment and
     150             :     installing the packages yourself. If you run into problems with packages
     151             :     like h5py, numpy or scipy you can/should still install them yourself to make
     152             :     sure they use the correct HDF5, BLAS, etc.
     153             :     (default is `OFF`)
     154             : - BUILD_DOCS
     155             :   - Enable building documentation. (default is `ON`)
     156             : - BUILD_PYTHON_BINDINGS
     157             :   - Build python libraries to call SpECTRE C++ code from python
     158             :     (default is `ON`)
     159             : - BUILD_SHARED_LIBS
     160             :   - Whether shared libraries are built instead of static libraries
     161             :     (default is `OFF`)
     162             : - BUILD_TESTING
     163             :   - Enable building tests. (default is `ON`)
     164             : - CHARM_ROOT
     165             :   - The path to the build directory of `Charm++`
     166             : - CHARM_TRACE_PROJECTIONS
     167             :   - Enables tracing with Charm++ projections. Specifically, enables the link
     168             :     flag `-tracemode projections`. (default is `OFF`)
     169             : - CHARM_TRACE_SUMMARY
     170             :   - Enables trace summaries with Charm++ projections. Specifically, enables
     171             :     the link flag `-tracemode summary`. (default is `OFF`)
     172             : - CMAKE_BUILD_TYPE
     173             :   - Sets the build type.  Common options:
     174             :     - `Debug` (the default if the flag is not specified): sets flags
     175             :       that trigger additional error checking
     176             :     - `Release`
     177             : - CMAKE_C_COMPILER
     178             :   - The `C` compiler used (defaults to whatever is determined by
     179             :     `CMake/Modules/CMakeDetermineCCompiler.cmake`, usually `cc`)
     180             : - CMAKE_C_FLAGS
     181             :   - Additional flags passed to the `C` compiler.
     182             : - CMAKE_CXX_COMPILER
     183             :   - The `C++` compiler used (defaults to whatever is determined by
     184             :     `CMake/Modules/CMakeDetermineCXXCompiler.cmake`, usually `c++`)
     185             : - CMAKE_CXX_FLAGS
     186             :   - Additional flags passed to the `C++` compiler.
     187             : - CMAKE_Fortran_COMPILER
     188             :   - The `Fortran` compiler used (defaults to whatever is determined by
     189             :     `CMake/Modules/CMakeDetermineFortranCompiler.cmake`)
     190             : - CMAKE_Fortran_FLAGS
     191             :   - Additional flags passed to the `Fortran` compiler.
     192             : - CMAKE_INSTALL_PREFIX
     193             :   - Location where the `install` target copies executables, libraries, etc. Make
     194             :     sure to set this variable before you `install`, or a default location such
     195             :     as `/usr/local` is used.
     196             : - CMAKE_RUNTIME_OUTPUT_DIRECTORY
     197             :   - Sets the directory where the library and executables are placed.
     198             :     By default libraries end up in `<BUILD_DIR>/lib` and executables
     199             :     in `<BUILD_DIR>/bin`.
     200             : - COVERAGE
     201             :   - Enable code coverage with GCOV and LCOV (default `OFF`)
     202             : - DEBUG_SYMBOLS
     203             :   - Whether or not to use debug symbols (default is `ON`)
     204             :   - Disabling debug symbols will reduce compile time and total size of the build
     205             :     directory.
     206             : - DOCS_ONLY
     207             :   - Build _only_ documentation (default is `OFF`). Requires `BUILD_DOCS=ON`.
     208             : - ENABLE_OPENMP
     209             :   - Enable OpenMP parallelization in some parts of the code, such as Python
     210             :     bindings and interpolating volume data files. Note that simulations do not
     211             :     typically use OpenMP parallelization, so this flag only applies to tools.
     212             : - ENABLE_PARAVIEW
     213             :   - Try to find ParaView to enable 3D rendering tools (default is `OFF`)
     214             : - ENABLE_PROFILING
     215             :   - Enables various options to make profiling SpECTRE easier
     216             :     (default is `OFF`)
     217             : - ENABLE_PYTHON
     218             :   - Enables Python. (default is `ON`)
     219             :   - Set to `OFF` for a minimal build on systems without a recent Python
     220             :     installation. Warning: Many things will not work!!
     221             :   - Note: Even when disabled, a minimal Python installation
     222             :     (Python ≥ 2.7) is still required.
     223             :   - BUILD_PYTHON_BINDINGS, BUILD_TESTING, BUILD_DOCS should be `OFF`.
     224             : - ENABLE_WARNINGS
     225             :   - Whether or not warning flags are enabled (default is `ON`)
     226             : - FUKA_ROOT
     227             :   - Set to a path to a [FUKA](https://bitbucket.org/fukaws/fuka) installation to
     228             :     enable loading FUKA initial data into SpECTRE. Can be the FUKA repository
     229             :     root or the directory where `libkadath.a` was installed. Also requires FFTW
     230             :     to be installed (see FUKA docs on dependencies).
     231             : - GSL_STATIC
     232             :   - If set, then the GNU Scientific Library is statically linked.
     233             : - KEEP_FRAME_POINTER
     234             :   - Whether to keep the frame pointer. Needed for profiling or other cases
     235             :     where you need to be able to figure out what the call stack is.
     236             :     (default is `OFF`)
     237             : - MACHINE
     238             :   - Select a machine that we know how to run on, such as a particular
     239             :     supercomputer. A file named MACHINE.yaml must exist in support/Machines and
     240             :     a submit script template named MACHINE.sh must exist in
     241             :     support/SubmitScripts.
     242             : - MEMORY_ALLOCATOR
     243             :   - Set which memory allocator to use. If there are unexplained segfaults or
     244             :     other memory issues, it would be worth setting `MEMORY_ALLOCATOR=SYSTEM` to
     245             :     see if that resolves the issue. It could be the case that different
     246             :     third-party libraries accidentally end up using different allocators, which
     247             :     is undefined behavior and will result in complete chaos.
     248             :     (default is `JEMALLOC`)
     249             : - PY_DEV_MODE
     250             :   - Enable development mode for the Python package, meaning that Python files
     251             :     are symlinked rather than copied to the build directory. Allows to edit and
     252             :     test Python code much easier, in particular when it uses compiled Python
     253             :     bindings, but doesn't replace CMake placeholders in the Python code such as
     254             :     the project version. (default is `OFF`)
     255             : - SPEC_ROOT
     256             :   - Set to a path to a SpEC installation (the SpEC repository root) to link in
     257             :     SpEC libraries. In particular, the SpEC::Exporter library is linked in and
     258             :     enables loading SpEC data into SpECTRE. See \ref installation for details.
     259             : - SPECTRE_AUTODIFF
     260             :   - Enable automatic differentation (default is `OFF`). This is required for
     261             :     computing Hessians.
     262             : - SPECTRE_DEBUG
     263             :   - Defines `SPECTRE_DEBUG` macro to enable `ASSERT`s and other debug
     264             :     checks so they can be used in Release builds. That is, you get sanity checks
     265             :     and compiler optimizations. You cannot disable the checks in Debug builds,
     266             :     so this option has no effect in Debug builds.
     267             :     (default is `OFF` in release)
     268             : - SPECTRE_DEBUG_Og
     269             :   - Compile Debug builds with `-Og` instead of the default `-O0`.
     270             :     `-Og` is specifically designed to preserve debuggability while enabling
     271             :     optimizations that do not interfere with source-level debugging.
     272             :     Has no effect when `SPECTRE_OPTIMIZE_SIZE=ON` (which uses `-Oz`).
     273             :     (default is `ON`)
     274             : - SPECTRE_NAN_INIT
     275             :   - Defines `SPECTRE_NAN_INIT` macro to initialize memory to NaN in various
     276             :     places to catch use of uninitialized values.
     277             :     (default is the value of `SPECTRE_DEBUG`, or `ON` in Debug builds)
     278             : - SPECTRE_OPTIMIZE_SIZE
     279             :   - Optimize for executable size instead of speed (adds the `-Oz` compiler
     280             :     flag). The default is `OFF`, unless on Apple Silicon machines, where the
     281             :     default is `ON`. This is because of a bug in macOS on Apple Silicon, which
     282             :     means executables larger than 2GB in size cannot run. Disabling this option
     283             :     on Apple Silicon can improve debugging tests (which are small enough so the
     284             :     bug does not affect them).
     285             : - SPECTRE_FETCH_MISSING_DEPS
     286             :   - Download missing dependencies and build them alongside the SpECTRE source.
     287             :     (default is `OFF`)
     288             : - SPECTRE_Fortran_STATIC_LIBS (default: `OFF`)
     289             :   - Use static version of `libgfortran` and `libquadmath`.
     290             : - SPECTRE_INPUT_FILE_TEST_MIN_PRIORITY
     291             :   - Minimum priority of input file tests to run. Possible values are: `low` (not
     292             :     usually run on CI), `normal` (run at least once on CI), `high` (run always
     293             :     on CI). (default is `normal`)
     294             : - SPECTRE_KOKKOS (default: `OFF`)
     295             :   - Enable Kokkos support. You must have Kokkos installed and detectable.
     296             : - SPECTRE_LTO
     297             :   - Enable link-time optimization if the compiler supports it.
     298             : - SPECTRE_LTO_CORES
     299             :   - Specifies the number of cores to use for parallelizing LTO. Must be a
     300             :     positive integer or "auto". This is only available when `SPECTRE_LTO=ON` and
     301             :     the compiler supports LTO.
     302             : - SPECTRE_TEST_RUNNER
     303             :   - Run test executables through a wrapper.  This might be `charmrun`, for
     304             :     example.  (default is to not use one)
     305             : - SPECTRE_TEST_TIMEOUT_FACTOR (and specific overrides
     306             :   SPECTRE_X_TEST_TIMEOUT_FACTOR for X one of UNIT, STANDALONE, INPUT_FILE, or
     307             :   PYTHON)
     308             :   - Multiply the timeout for the respective set of tests by this factor (default
     309             :     is `1`).
     310             :   - This is useful to run tests on slower machines.
     311             : - SPECTRE_USE_ALWAYS_INLINE
     312             :   - Force SpECTRE inlining (default is `ON`)
     313             :   - Forced inlining reduces function call overhead, and so generally reduces
     314             :     runtime. However, it does increase compile time and compile memory usage. It
     315             :     is also easier to use a debugger when forced inlining is disabled. If you
     316             :     are encountering debugger messages like `function inlined`, then forced
     317             :     inlining should be disabled.
     318             : - STRIP_SYMBOLS
     319             :   - Whether or not to strip all symbols (default is `OFF`)
     320             :   - If enabled strips all extraneous symbols from libraries and executables,
     321             :     further reducing the size of them.
     322             : - STUB_EXECUTABLE_OBJECT_FILES
     323             :   - Replace object files from executables after linking with empty stubs
     324             :     (default is `OFF`)
     325             :   - This is useful for drastically reducing the build size in CI, but since the
     326             :     object files are replaced with empty stubs will generally cause linking
     327             :     problems if used during development.
     328             : - STUB_LIBRARY_OBJECT_FILES
     329             :   - Replace object files from libraries after linking with empty stubs
     330             :     (default is `OFF`)
     331             :   - This is useful for drastically reducing the build size in CI, but since the
     332             :     object files are replaced with empty stubs will generally cause linking
     333             :     problems if used during development.
     334             : - UBSAN_INTEGER
     335             :   - Whether or not to turn on the undefined behavior sanitizer
     336             :     [unsigned integer
     337             :     overflow](https://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html) flag
     338             :     (`-fsanitize=integer`) (default is `OFF`)
     339             : - UBSAN_UNDEFINED
     340             :   - Whether or not to turn on the undefined behavior sanitizer
     341             :     [undefined
     342             :     behavior](https://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html)
     343             :     compile flags (`-fsanitize=undefined`) (default is `OFF`)
     344             : - UNIT_TESTS_IN_TEST_EXECUTABLES
     345             :   - Whether to build the `unit-tests` target as part of the `test-executables`
     346             :     target. This is used to build only the non-unit tests in the CI build
     347             :     that doesn't use the PCH. (default is `ON`)
     348             : - USE_CCACHE
     349             :   - Use ccache to cache build output so that rebuilding parts of the source tree
     350             :     is faster. The cache will use up space on disk, with the default being
     351             :     around 2-5GB. If you are performing a one time build to test something
     352             :     specific you should consider disabling ccache in order to avoid removing
     353             :     cached files that may be useful in other builds.
     354             :     (default is `ON`)
     355             : - USE_FORMALINE
     356             :   - Write the source tree into HDF5 files written to disk in order to increase
     357             :     reproducibility of results.
     358             :     (default is `ON`)
     359             : - USE_GIT_HOOKS
     360             :   - Use git hooks to perform some sanity checks so that small goofs are caught
     361             :     before they are committed. These checks are particularly useful because they
     362             :     also run automatically on \ref github_actions_guide "CI" and must pass
     363             :     before pull requests are merged. The hooks are shared between all git
     364             :     worktrees of the repository and use the tools of the last configured build.
     365             :     A `post-checkout` hook also symlinks git-ignored personal files such as
     366             :     `CMakeUserPresets.json` from the main checkout into new worktrees.
     367             :     (default is `ON`)
     368             : - USE_LD
     369             :   - Override the automatically chosen linker. The options are `ld`, `gold`, and
     370             :     `lld`.
     371             :     (default is `OFF`)
     372             : - USE_PCH
     373             :   - Whether or not to use pre-compiled headers (default is `ON`)
     374             : - USE_SLEEF
     375             :   - Whether to use [Sleef](https://github.com/shibatch/sleef) with Blaze to
     376             :     vectorize addition math functions like `sin`, `cos`, and `exp`.
     377             :     (default is `OFF`)
     378             :   - \note Blaze isn't tested super thoroughly across different architectures so
     379             :     there's unfortunately no guarantee that Blaze+Sleef will work everywhere.
     380             : - USE_XSIMD
     381             :   - Whether to use [xsimd](https://github.com/xtensor-stack/xsimd) with Blaze to
     382             :     vectorize addition math functions like `sin`, `cos`, and `exp`.
     383             :     Defines the macro `SPECTRE_USE_XSIMD`, which can be check to enable manual
     384             :     vectorization where necessary.
     385             :     (default is `ON`)
     386             : 
     387             : ## CMake targets
     388             : 
     389             : To see all possible build targets, once you configure SpECTRE run
     390             : 
     391             : ```
     392             : make list
     393             : ```
     394             : 
     395             : This will be a long list of all libraries, test executables, simulation
     396             : executables, and custom build targets. The custom targets that are
     397             : available to build with `make` or `ninja` are:
     398             : 
     399             : - unit-tests
     400             :   - Build unit tests, which you can run with `ctest -L unit`. Available if
     401             :     `BUILD_TESTING` is `ON` (the default).
     402             : - test-executables
     403             :   - Build all tests, including executables, so you can run all tests with
     404             :     `ctest`. Available if `BUILD_TESTING` is `ON` (the default). To compile
     405             :     `test-executables` you may have to reduce the number of cores you build on
     406             :     in parallel to avoid running out of memory.
     407             : - all-pybindings
     408             :   - Build Python bindings. See \ref spectre_using_python for details.
     409             : - cli
     410             :   - Same as all-pybindings
     411             : - install
     412             :   - Install targets that have been built to the `CMAKE_INSTALL_PREFIX`. Doesn't
     413             :     try to build anything else.
     414             : 
     415             : # Editing the build system
     416             : 
     417             : \note When editing `CMakeLists.txt` files, it is conventional to
     418             : indent multiline commands by two spaces (except for the first line),
     419             : and to separate most commands by blank lines.
     420             : 
     421             : ## Adding Source Files {#adding_source_files}
     422             : 
     423             : SpECTRE organizes source files into subdirectories of `src` that are
     424             : compiled into libraries.  To add a new source file `FILE.cpp` to an
     425             : existing library in `src/PATH/DIR`, just edit
     426             : `src/PATH/DIR/CMakeLists.txt` and add `FILE.cpp` to the list of files
     427             : in
     428             : ```
     429             : spectre_target_sources(
     430             :   ${LIBRARY}
     431             :   PRIVATE
     432             :   <list_of_files>
     433             :   )
     434             : ```
     435             : such that the resulting `<list_of_files>` is in alphabetical order.
     436             : 
     437             : ## Adding Header Files {#adding_header_files}
     438             : 
     439             : Similarly to [adding new source files](#adding_source_files), you can add a new
     440             : header file `FILE.hpp` to a library by editing the `CMakeLists.txt` in that
     441             : directory and adding `FILE.hpp` to the list of files in
     442             : ```
     443             : spectre_target_headers(
     444             :   ${LIBRARY}
     445             :   INCLUDE_DIRECTORY ${CMAKE_SOURCE_DIR}/src
     446             :   HEADERS
     447             :   <list_of_files>
     448             : )
     449             : ```
     450             : 
     451             : \note Any `.tpp` files also go in this list of header files.
     452             : 
     453             : ## Adding Libraries {#adding_libraries}
     454             : 
     455             : To add a source file `FILE.cpp` that is compiled into a new library `LIB` in a
     456             : directory `src/PATH/DIR` (either in a new directory, or in an existing
     457             : directory that either does not have a `CMakeLists.txt` file, or does
     458             : not create a library in the existing `CMakeLists.txt`):
     459             : - Create (if necessary) a `CMakeLists.txt` file in `DIR`, with the following
     460             : two lines at the top:
     461             : ```
     462             : # Distributed under the MIT License.
     463             : # See LICENSE.txt for details.
     464             : ```
     465             : - In the parent directory (i.e. `src/PATH`), (if necessary) add the
     466             : following line to its `CMakeLists.txt` file (if necessary, recursively
     467             : do the previous step and this one until you reach a `CMakeLists.txt` that
     468             : adds the appropriate subdirectory):
     469             : ```
     470             : add_subdirectory(DIR)
     471             : ```
     472             : If there are already other `add_subdirectory()` lines in the file, place
     473             : the new one so that the subdirectories are in alphabetical order.
     474             : - Add the line:
     475             : ```
     476             : set(LIBRARY LIB)
     477             : ```
     478             : where convention is that `LIB` = `DIR`.  As library names must be
     479             : unique, this is not always possible, in which case the convention is to
     480             : prepend the parent directory to `DIR`.
     481             : - Add the lines
     482             : ```
     483             : add_spectre_library(${LIBRARY})
     484             : 
     485             : spectre_target_sources(
     486             :   ${LIBRARY}
     487             :   PRIVATE
     488             :   FILE.cpp
     489             :   )
     490             : 
     491             : spectre_target_headers(
     492             :   ${LIBRARY}
     493             :   INCLUDE_DIRECTORY ${CMAKE_SOURCE_DIR}/src
     494             :   HEADERS
     495             :   FILE.hpp
     496             :   )
     497             : 
     498             : target_link_libraries(
     499             :   ${LIBRARY}
     500             :   PUBLIC
     501             :   <list_of_public_libraries>
     502             :   PRIVATE
     503             :   <list_of_private_libraries>
     504             :   INTERFACE
     505             :   <list_of_interface_libraries>
     506             :   )
     507             : ```
     508             : where each `<list_of_X_libraries>` is an alphabetized list
     509             : of libraries of the form
     510             : ```
     511             :   SomeLibrary
     512             :   SomeOtherLibrary
     513             :   YetAnotherLibrary
     514             : ```
     515             : The libraries listed under `INTERFACE` are those included in at
     516             : least one `.hpp` file in `LIB` but never used in any `.cpp` files
     517             : in `LIB`.  The libraries listed under `PRIVATE` are used in
     518             : at least one `.cpp` file in `LIB` but not in any `.hpp` file
     519             : in `LIB`.  The libraries listed under `PUBLIC` are used in at
     520             : least one `.hpp` file and at least one `.cpp` file in `LIB`.
     521             : Note that a library counts as being used in a `.cpp` file if the
     522             : corresponding `.hpp` file includes it. In other words, list a dependency
     523             : as `PRIVATE` if it is needed only to compile the library, but not for
     524             : including headers. List a dependency as `INTERFACE` if it is not needed
     525             : to compile the library, but is needed for including headers. List a
     526             : dependency as `PUBLIC` if it is needed for both.
     527             : 
     528             : \note If your library only contains header files, you must specify `INTERFACE`
     529             : like so in the `add_spectre_library(${LIBRARY} INTERFACE)` function. You should
     530             : also omit the `spectre_target_sources` lines as well.
     531             : 
     532             : ## Adding Unit Tests {#adding_unit_tests}
     533             : 
     534             : We use the [Catch](https://github.com/philsquared/Catch) testing
     535             : framework for unit tests. All unit tests are housed in `tests/Unit`
     536             : with subdirectories for each subdirectory of `src`. Add the `cpp` file
     537             : to the appropriate subdirectory and also to the `CMakeLists.txt` in
     538             : that subdirectory. Inside the source file you can create a new test by
     539             : adding a `SPECTRE_TEST_CASE("Unit.Dir.Component",
     540             : "[Unit][Dir][Tag]")`. The `[Tag]` is optional and you can have more
     541             : than one, but the tags should be used quite sparingly.  The purpose of
     542             : the tags is to be able to run all unit tests or all tests of a
     543             : particular set of components, e.g. `ctest -L Data` to run all tests
     544             : inside the `Data` directory. Please see \ref writing_unit_tests
     545             : "writing unit tests", other unit tests and the [Catch
     546             : documentation](https://github.com/philsquared/Catch) for more help on
     547             : writing tests. Unit tests should take as short a time as possible,
     548             : with a goal of less than two seconds.  Please also limit the number of
     549             : distinct cases (by using `SECTION`s).
     550             : 
     551             : You can check the unit test coverage of your code by installing all the optional
     552             : components and then running `make unit-test-coverage` (after re-running CMake).
     553             : This will create the
     554             : directory `BUILD_DIR/docs/html/unit-test-coverage/` which is where the coverage
     555             : information is located. Open the `index.html` file in your browser and make
     556             : sure that your tests are indeed checking all lines of your code. Your pull
     557             : requests might not be merged until your line coverage is over 90% (we are aiming
     558             : for 100% line coverage wherever possible). Unreachable lines of code can be
     559             : excluded from coverage analysis by adding the inline comment `LCOV_EXCL_LINE`
     560             : or a block can be excluded using `LCOV_EXCL_START` and `LCOV_EXCL_STOP`.
     561             : However, this should be used extremely sparingly since unreachable code paths
     562             : should be removed from the code base altogether.
     563             : 
     564             : ## Adding Executables {#adding_executables}
     565             : 
     566             : All general executables are found in `src/Executables`, while those
     567             : for specific evolution (elliptic) systems are found in
     568             : `src/Evolution/Executables` (`src/Elliptic/Executables`).  See \ref
     569             : dev_guide_creating_executables "how to create executables".
     570             : 
     571             : ## Adding External Dependencies {#adding_external_dependencies}
     572             : 
     573             : To add an external dependency, first add a `SetupDEPENDENCY.cmake`
     574             : file to the `cmake` directory. If CMake
     575             : does not already support `find_package` for the library you're adding
     576             : you can write your own `FindDEPENDENCY.cmake` file.
     577             : The `SetupDEPENDENCY.cmake` file must then be included in
     578             : the root `spectre/CMakeLists.txt`. Be sure to test both that setting
     579             : `LIBRARY_ROOT` works correctly for your library, and also that if the
     580             : library is required that CMake fails gracefully if the library is not
     581             : found.
     582             : 
     583             : # Dependencies
     584             : 
     585             : ## Checking Dependencies
     586             : 
     587             : Getting dependencies of libraries correct is quite difficult. SpECTRE offers the
     588             : CMake function `check_spectre_libs_dependencies`, defined in
     589             : `cmake/SpectreCheckDependencies.cmake`, to check the dependencies for all
     590             : libraries in the `libs` target. Individual target dependencies can be checked
     591             : using the `check_target_dependencies` CMake function defined in
     592             : `cmake/SpectreCheckTargetDependencies.cmake`. Please see those functions in the
     593             : source tree for more details on how to use them.
     594             : 
     595             : ## Formaline
     596             : 
     597             : SpECTRE's implementation of Formaline is based on, but distinct in
     598             : implementation from, the
     599             : [original design](https://github.com/hypercott/formaline)
     600             : which embeds an archive of the source tree into the executable. The original
     601             : design creates a C/C++ file with a function that returns an array/vector of
     602             : `char`s (a byte stream). However, this results in a very large source file (50MB
     603             : or more), which is very slow to compile and ends up more than doubling the link
     604             : time. Instead, SpECTRE's Formaline implementation uses the linker `ld` to
     605             : encode a file into an object, which means
     606             : rather than creating a large source file, we can directly encode the source tree
     607             : archive into the binary at the linking stage.
     608             : 
     609             : Most of SpECTRE's Formaline is implemented
     610             : inside the `tools/WrapExecutableLinker.sh` script. Function declarations are
     611             : provided in `Utilities/Formaline.hpp` and a small function that writes the
     612             : source file to disk is defined in `Utilities/Formaline.cpp`. The first
     613             : Formaline-related thing done in `WrapExecutableLinker.sh` is to archive
     614             : everything in the source directory tracked by git. Once the archive is created
     615             : we run `ld -r -b binary -o object.o src.tar.gz` (with unique names for
     616             : `object.o` and `src.tar.gz` for each executable that is built to avoid name
     617             : collisions) to generate an object file with the source file encoded from
     618             : `_binary_src_tar_gz_start` to `_binary_src_tar_gz_end`. Next we write a C++
     619             : source file that defines a function `get_archive` to convert the byte stream
     620             : into a `std::vector<char>`. We also encode the output of `printenv`, the various
     621             : `PATH` environment variables, and the CMake generated `BuildInfo.txt` file
     622             : into the source file. Finally, the generated source file is built during the
     623             : linking phase and the object file containing the source archive is linked into
     624             : the executable.
     625             : 
     626             : To further aid in reproducibility, the `printenv` output and
     627             : `BuildInfo.txt` contents are written to HDF5 files as part of the
     628             : `h5::Header` object. The archive of the source tree is written using the
     629             : `h5::SourceArchive` object and can be extracted by running
     630             : ```
     631             : h5dump -d /src.tar.gz -b LE -o src.tar.gz /path/to/hdf5/file.h5
     632             : ```
     633             : 
     634             : # Using Kokkos
     635             : 
     636             : Kokkos support is still extremely experimental, but can be enabled by passing
     637             : `-D SPECTRE_KOKKOS=ON` to CMake. You must pass additional CMake flags that
     638             : Kokkos will use to configure itself. For example, to enable CUDA support you
     639             : must pass `-D Kokkos_ENABLE_CUDA=ON`. See the
     640             : [Kokkos documentation](https://kokkos.org/kokkos-core-wiki/keywords.html) for
     641             : details.
     642             : 
     643             : ## Nvidia Compiler
     644             : 
     645             : If you are using CUDA to compile for Nvidia GPUs but do not have the target GPU
     646             : on the system you are compiling on then you must also tell CMake what CUDA
     647             : architecture to use. You can do this by passing `-D CMAKE_CUDA_ARCHITECTURES=80`
     648             : to CMake. You must choose the architecture that will be compatible with the GPU
     649             : you plan to use. Note that this is actually called the compute capability
     650             : version by Nvidia and can be viewed
     651             : [here](https://developer.nvidia.com/cuda-gpus).

Generated by: LCOV version 1.14