aboutsummaryrefslogtreecommitdiff
path: root/thirdparty/ryml/ext/c4core/cmake
diff options
context:
space:
mode:
authorStefan Boberg <[email protected]>2026-02-23 11:19:52 +0100
committerGitHub Enterprise <[email protected]>2026-02-23 11:19:52 +0100
commit9aac0fd369b87e965fb34b5168646387de7ea1cd (patch)
tree367a820685a829adbab31cd1374b1af2cece4b7e /thirdparty/ryml/ext/c4core/cmake
parentchanged command names and descriptions to use class members instead of string... (diff)
downloadzen-9aac0fd369b87e965fb34b5168646387de7ea1cd.tar.xz
zen-9aac0fd369b87e965fb34b5168646387de7ea1cd.zip
implement yaml generation (#774)
this implements a yaml generation strategy similar to the JSON generation where we just build a string instead of building a ryml tree. This also removes the dependency on ryml for reduced binary/build times.
Diffstat (limited to 'thirdparty/ryml/ext/c4core/cmake')
-rw-r--r--thirdparty/ryml/ext/c4core/cmake/.gitignore1
-rw-r--r--thirdparty/ryml/ext/c4core/cmake/ConfigurationTypes.cmake120
-rw-r--r--thirdparty/ryml/ext/c4core/cmake/CreateSourceGroup.cmake31
-rw-r--r--thirdparty/ryml/ext/c4core/cmake/Doxyfile.full.in2566
-rw-r--r--thirdparty/ryml/ext/c4core/cmake/Doxyfile.in2566
-rw-r--r--thirdparty/ryml/ext/c4core/cmake/ExternalProjectUtils.cmake215
-rw-r--r--thirdparty/ryml/ext/c4core/cmake/FindD3D12.cmake75
-rw-r--r--thirdparty/ryml/ext/c4core/cmake/FindDX12.cmake76
-rw-r--r--thirdparty/ryml/ext/c4core/cmake/GetFlags.cmake53
-rw-r--r--thirdparty/ryml/ext/c4core/cmake/GetNames.cmake51
-rw-r--r--thirdparty/ryml/ext/c4core/cmake/LICENSE.txt20
-rw-r--r--thirdparty/ryml/ext/c4core/cmake/PVS-Studio.cmake275
-rw-r--r--thirdparty/ryml/ext/c4core/cmake/PatchUtils.cmake25
-rw-r--r--thirdparty/ryml/ext/c4core/cmake/PrintVar.cmake27
-rw-r--r--thirdparty/ryml/ext/c4core/cmake/README.md25
-rw-r--r--thirdparty/ryml/ext/c4core/cmake/TargetArchitecture.cmake180
-rw-r--r--thirdparty/ryml/ext/c4core/cmake/Toolchain-Arm-ubuntu.cmake29
-rw-r--r--thirdparty/ryml/ext/c4core/cmake/Toolchain-Armv7.cmake84
-rw-r--r--thirdparty/ryml/ext/c4core/cmake/Toolchain-PS4.cmake73
-rw-r--r--thirdparty/ryml/ext/c4core/cmake/Toolchain-XBoxOne.cmake93
-rw-r--r--thirdparty/ryml/ext/c4core/cmake/amalgamate_utils.py219
-rw-r--r--thirdparty/ryml/ext/c4core/cmake/bm-xp/.gitignore1
-rw-r--r--thirdparty/ryml/ext/c4core/cmake/bm-xp/README.md7
-rw-r--r--thirdparty/ryml/ext/c4core/cmake/bm-xp/bm.js475
-rw-r--r--thirdparty/ryml/ext/c4core/cmake/bm-xp/bm_plot.py746
-rw-r--r--thirdparty/ryml/ext/c4core/cmake/bm-xp/bm_run.py248
-rw-r--r--thirdparty/ryml/ext/c4core/cmake/bm-xp/bm_serve.py502
-rw-r--r--thirdparty/ryml/ext/c4core/cmake/bm-xp/bm_util.py147
-rw-r--r--thirdparty/ryml/ext/c4core/cmake/bm-xp/example_c4core.py1061
-rw-r--r--thirdparty/ryml/ext/c4core/cmake/bm-xp/example_mintm.py1061
-rw-r--r--thirdparty/ryml/ext/c4core/cmake/bm-xp/requirements.txt14
-rw-r--r--thirdparty/ryml/ext/c4core/cmake/bm-xp/template/index.html45
-rw-r--r--thirdparty/ryml/ext/c4core/cmake/c4CatSources.cmake105
-rw-r--r--thirdparty/ryml/ext/c4core/cmake/c4Doxygen.cmake121
-rw-r--r--thirdparty/ryml/ext/c4core/cmake/c4DoxygenConfig.cmake24
-rw-r--r--thirdparty/ryml/ext/c4core/cmake/c4GetTargetPropertyRecursive.cmake186
-rw-r--r--thirdparty/ryml/ext/c4core/cmake/c4Project.cmake3691
-rw-r--r--thirdparty/ryml/ext/c4core/cmake/c4SanitizeTarget.cmake292
-rw-r--r--thirdparty/ryml/ext/c4core/cmake/c4StaticAnalysis.cmake154
-rw-r--r--thirdparty/ryml/ext/c4core/cmake/c4stlAddTarget.cmake5
-rw-r--r--thirdparty/ryml/ext/c4core/cmake/compat/c4/gcc-4.8.hpp69
-rw-r--r--thirdparty/ryml/ext/c4core/cmake/compat/gtest_gcc-4.8.patch97
-rw-r--r--thirdparty/ryml/ext/c4core/cmake/requirements_doc.txt3
43 files changed, 0 insertions, 15858 deletions
diff --git a/thirdparty/ryml/ext/c4core/cmake/.gitignore b/thirdparty/ryml/ext/c4core/cmake/.gitignore
deleted file mode 100644
index ed8ebf583..000000000
--- a/thirdparty/ryml/ext/c4core/cmake/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-__pycache__ \ No newline at end of file
diff --git a/thirdparty/ryml/ext/c4core/cmake/ConfigurationTypes.cmake b/thirdparty/ryml/ext/c4core/cmake/ConfigurationTypes.cmake
deleted file mode 100644
index 45395ad1b..000000000
--- a/thirdparty/ryml/ext/c4core/cmake/ConfigurationTypes.cmake
+++ /dev/null
@@ -1,120 +0,0 @@
-
-
-# this function works both with multiconfig and single-config generators.
-function(set_default_build_type which)
- # CMAKE_CONFIGURATION_TYPES is available only for multiconfig generators.
- # so set the build type only if CMAKE_CONFIGURATION_TYPES does not exist.
- if(NOT CMAKE_CONFIGURATION_TYPES) # not a multiconfig generator?
- if(NOT CMAKE_BUILD_TYPE)
- if(NOT which)
- set(which RelWithDebInfo)
- endif()
- message("Defaulting to ${which} build.")
- set(CMAKE_BUILD_TYPE ${which} CACHE STRING "")
- endif()
- endif()
-endfunction()
-
-
-# https://stackoverflow.com/questions/31546278/where-to-set-cmake-configuration-types-in-a-project-with-subprojects
-function(setup_configuration_types)
- set(options0arg
- )
- set(options1arg
- DEFAULT
- )
- set(optionsnarg
- TYPES
- )
- cmake_parse_arguments("" "${options0arg}" "${options1arg}" "${optionsnarg}" ${ARGN})
-
- if(NOT TYPES)
- set(TYPES Release Debug RelWithDebInfo MinSizeRel)
- endif()
-
- # make it safe to call repeatedly
- if(NOT _setup_configuration_types_done)
- set(_setup_configuration_types_done 1 CACHE INTERNAL "")
-
- # No reason to set CMAKE_CONFIGURATION_TYPES if it's not a multiconfig generator
- # Also no reason mess with CMAKE_BUILD_TYPE if it's a multiconfig generator.
-
- if(CMAKE_CONFIGURATION_TYPES) # multiconfig generator?
- set(CMAKE_CONFIGURATION_TYPES "${TYPES}" CACHE STRING "")
- else() # single-config generator
- set_property(CACHE CMAKE_BUILD_TYPE PROPERTY HELPSTRING "Choose the type of build")
- set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "${TYPES}")
- # set the valid options for cmake-gui drop-down list
- endif()
- endif()
-endfunction()
-
-
-# https://stackoverflow.com/questions/31546278/where-to-set-cmake-configuration-types-in-a-project-with-subprojects
-function(add_configuration_type name)
- set(flag_vars
- C_FLAGS
- CXX_FLAGS
- SHARED_LINKER_FLAGS
- STATIC_LINKER_FLAGS
- MODULE_LINKER_FLAGS
- EXE_LINKER_FLAGS
- RC_FLAGS
- )
-
- set(options0arg
- PREPEND # when defaulting to a config, prepend to it instead of appending to it
- SET_MAIN_FLAGS # eg, set CMAKE_CXX_FLAGS from CMAKE_CXX_FLAGS_${name}
- )
- set(options1arg
- DEFAULT_FROM # take the initial value of the flags from this config
- )
- set(optionsnarg
- C_FLAGS
- CXX_FLAGS
- SHARED_LINKER_FLAGS
- STATIC_LINKER_FLAGS
- MODULE_LINKER_FLAGS
- EXE_LINKER_FLAGS
- RC_FLAGS
- )
- cmake_parse_arguments(_act "${options0arg}" "${options1arg}" "${optionsnarg}" ${ARGN})
-
- string(TOUPPER ${name} UNAME)
-
- # make it safe to call repeatedly
- if(NOT _add_configuration_type_${name})
- set(_add_configuration_type_${name} 1 CACHE INTERNAL "")
-
- setup_configuration_types()
-
- if(CMAKE_CONFIGURATION_TYPES) # multiconfig generator?
- set(CMAKE_CONFIGURATION_TYPES "${CMAKE_CONFIGURATION_TYPES};${name}" CACHE STRING "" FORCE)
- else() # single-config generator
- set_property(CACHE CMAKE_BUILD_TYPE PROPERTY HELPSTRING "Choose the type of build" FORCE)
- set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "${CMAKE_BUILD_TYPES};${name}" FORCE)
- # set the valid options for cmake-gui drop-down list
- endif()
-
- # now set up the configuration
- message(STATUS "config: CMAKE_${f}_${UNAME} --- ${val}")
- foreach(f ${flag_vars})
- set(val ${_act_${f}})
- message(STATUS "config: ${name}: ${f} --- ${val}")
- if(_act_DEFAULT_FROM)
- if(_act_PREPEND)
- set(val "${val} ${CMAKE_${f}_${_act_DEFAULT_FROM}}")
- else()
- set(val "${CMAKE_${f}_${_act_DEFAULT_FROM}} ${val}")
- endif()
- endif()
- message(STATUS "config: CMAKE_${f}_${UNAME} --- ${val}")
- set(CMAKE_${f}_${UNAME} "${val}" CACHE STRING "" FORCE)
- mark_as_advanced(CMAKE_${f}_${UNAME})
- if(_act_SET_MAIN_FLAGS)
- set(CMAKE_${f} "${CMAKE_${f}_${UNAME}}" CACHE STRING "" FORCE)
- endif()
- endforeach()
- endif()
-
-endfunction()
diff --git a/thirdparty/ryml/ext/c4core/cmake/CreateSourceGroup.cmake b/thirdparty/ryml/ext/c4core/cmake/CreateSourceGroup.cmake
deleted file mode 100644
index e8e144184..000000000
--- a/thirdparty/ryml/ext/c4core/cmake/CreateSourceGroup.cmake
+++ /dev/null
@@ -1,31 +0,0 @@
-# create hierarchical source groups based on a dir tree
-#
-# EXAMPLE USAGE:
-#
-# create_source_group("src" "${SRC_ROOT}" "${SRC_LIST}")
-#
-# Visual Studio usually has the equivalent to this:
-#
-# create_source_group("Header Files" ${PROJ_SRC_DIR} "${PROJ_HEADERS}")
-# create_source_group("Source Files" ${PROJ_SRC_DIR} "${PROJ_SOURCES}")
-#
-# TODO: <jpmag> this was taken from a stack overflow answer. Need to find it
-# and add a link here.
-
-macro(create_source_group GroupPrefix RootDir ProjectSources)
- set(DirSources ${ProjectSources})
- foreach(Source ${DirSources})
- #message(STATUS "s=${Source}")
- string(REGEX REPLACE "([\\^\\$*+?|])" "\\\\\\1" RootDirRegex "${RootDir}")
- string(REGEX REPLACE "${RootDirRegex}" "" RelativePath "${Source}")
- #message(STATUS " ${RelativePath}")
- string(REGEX REPLACE "[\\\\/][^\\\\/]*$" "" RelativePath "${RelativePath}")
- #message(STATUS " ${RelativePath}")
- string(REGEX REPLACE "^[\\\\/]" "" RelativePath "${RelativePath}")
- #message(STATUS " ${RelativePath}")
- string(REGEX REPLACE "/" "\\\\\\\\" RelativePath "${RelativePath}")
- #message(STATUS " ${RelativePath}")
- source_group("${GroupPrefix}\\${RelativePath}" FILES ${Source})
- #message(STATUS " ${Source}")
- endforeach(Source)
-endmacro(create_source_group)
diff --git a/thirdparty/ryml/ext/c4core/cmake/Doxyfile.full.in b/thirdparty/ryml/ext/c4core/cmake/Doxyfile.full.in
deleted file mode 100644
index f444cb742..000000000
--- a/thirdparty/ryml/ext/c4core/cmake/Doxyfile.full.in
+++ /dev/null
@@ -1,2566 +0,0 @@
-# Doxyfile 1.8.15
-
-# This file describes the settings to be used by the documentation system
-# doxygen (www.doxygen.org) for a project.
-#
-# All text after a double hash (##) is considered a comment and is placed in
-# front of the TAG it is preceding.
-#
-# All text after a single hash (#) is considered a comment and will be ignored.
-# The format is:
-# TAG = value [value, ...]
-# For lists, items can also be appended using:
-# TAG += value [value, ...]
-# Values that contain spaces should be placed between quotes (\" \").
-
-#---------------------------------------------------------------------------
-# Project related configuration options
-#---------------------------------------------------------------------------
-
-# This tag specifies the encoding used for all characters in the configuration
-# file that follow. The default is UTF-8 which is also the encoding used for all
-# text before the first occurrence of this tag. Doxygen uses libiconv (or the
-# iconv built into libc) for the transcoding. See
-# https://www.gnu.org/software/libiconv/ for the list of possible encodings.
-# The default value is: UTF-8.
-
-DOXYFILE_ENCODING = UTF-8
-
-# The PROJECT_NAME tag is a single word (or a sequence of words surrounded by
-# double-quotes, unless you are using Doxywizard) that should identify the
-# project for which the documentation is generated. This name is used in the
-# title of most generated pages and in a few other places.
-# The default value is: My Project.
-
-PROJECT_NAME = @_PROJ@
-
-# The PROJECT_NUMBER tag can be used to enter a project or revision number. This
-# could be handy for archiving the generated documentation or if some version
-# control system is used.
-
-PROJECT_NUMBER = @_VERSION@
-
-# Using the PROJECT_BRIEF tag one can provide an optional one line description
-# for a project that appears at the top of each page and should give viewer a
-# quick idea about the purpose of the project. Keep the description short.
-
-PROJECT_BRIEF = @_PROJ_BRIEF@
-
-# With the PROJECT_LOGO tag one can specify a logo or an icon that is included
-# in the documentation. The maximum height of the logo should not exceed 55
-# pixels and the maximum width should not exceed 200 pixels. Doxygen will copy
-# the logo to the output directory.
-
-PROJECT_LOGO =
-
-# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path
-# into which the generated documentation will be written. If a relative path is
-# entered, it will be relative to the location where doxygen was started. If
-# left blank the current directory will be used.
-
-OUTPUT_DIRECTORY = @_OUTPUT_DIR@
-
-# If the CREATE_SUBDIRS tag is set to YES then doxygen will create 4096 sub-
-# directories (in 2 levels) under the output directory of each output format and
-# will distribute the generated files over these directories. Enabling this
-# option can be useful when feeding doxygen a huge amount of source files, where
-# putting all generated files in the same directory would otherwise causes
-# performance problems for the file system.
-# The default value is: NO.
-
-CREATE_SUBDIRS = NO
-
-# If the ALLOW_UNICODE_NAMES tag is set to YES, doxygen will allow non-ASCII
-# characters to appear in the names of generated files. If set to NO, non-ASCII
-# characters will be escaped, for example _xE3_x81_x84 will be used for Unicode
-# U+3044.
-# The default value is: NO.
-
-ALLOW_UNICODE_NAMES = YES
-
-# The OUTPUT_LANGUAGE tag is used to specify the language in which all
-# documentation generated by doxygen is written. Doxygen will use this
-# information to generate all constant output in the proper language.
-# Possible values are: Afrikaans, Arabic, Armenian, Brazilian, Catalan, Chinese,
-# Chinese-Traditional, Croatian, Czech, Danish, Dutch, English (United States),
-# Esperanto, Farsi (Persian), Finnish, French, German, Greek, Hungarian,
-# Indonesian, Italian, Japanese, Japanese-en (Japanese with English messages),
-# Korean, Korean-en (Korean with English messages), Latvian, Lithuanian,
-# Macedonian, Norwegian, Persian (Farsi), Polish, Portuguese, Romanian, Russian,
-# Serbian, Serbian-Cyrillic, Slovak, Slovene, Spanish, Swedish, Turkish,
-# Ukrainian and Vietnamese.
-# The default value is: English.
-
-OUTPUT_LANGUAGE = English
-
-# The OUTPUT_TEXT_DIRECTION tag is used to specify the direction in which all
-# documentation generated by doxygen is written. Doxygen will use this
-# information to generate all generated output in the proper direction.
-# Possible values are: None, LTR, RTL and Context.
-# The default value is: None.
-
-OUTPUT_TEXT_DIRECTION = None
-
-# If the BRIEF_MEMBER_DESC tag is set to YES, doxygen will include brief member
-# descriptions after the members that are listed in the file and class
-# documentation (similar to Javadoc). Set to NO to disable this.
-# The default value is: YES.
-
-BRIEF_MEMBER_DESC = YES
-
-# If the REPEAT_BRIEF tag is set to YES, doxygen will prepend the brief
-# description of a member or function before the detailed description
-#
-# Note: If both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the
-# brief descriptions will be completely suppressed.
-# The default value is: YES.
-
-REPEAT_BRIEF = YES
-
-# This tag implements a quasi-intelligent brief description abbreviator that is
-# used to form the text in various listings. Each string in this list, if found
-# as the leading text of the brief description, will be stripped from the text
-# and the result, after processing the whole list, is used as the annotated
-# text. Otherwise, the brief description is used as-is. If left blank, the
-# following values are used ($name is automatically replaced with the name of
-# the entity):The $name class, The $name widget, The $name file, is, provides,
-# specifies, contains, represents, a, an and the.
-
-ABBREVIATE_BRIEF = "The $name class" \
- "The $name widget" \
- "The $name file" \
- is \
- provides \
- specifies \
- contains \
- represents \
- a \
- an \
- the
-
-# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then
-# doxygen will generate a detailed section even if there is only a brief
-# description.
-# The default value is: NO.
-
-ALWAYS_DETAILED_SEC = NO
-
-# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all
-# inherited members of a class in the documentation of that class as if those
-# members were ordinary class members. Constructors, destructors and assignment
-# operators of the base classes will not be shown.
-# The default value is: NO.
-
-INLINE_INHERITED_MEMB = YES
-
-# If the FULL_PATH_NAMES tag is set to YES, doxygen will prepend the full path
-# before files name in the file list and in the header files. If set to NO the
-# shortest path that makes the file name unique will be used
-# The default value is: YES.
-
-FULL_PATH_NAMES = YES
-
-# The STRIP_FROM_PATH tag can be used to strip a user-defined part of the path.
-# Stripping is only done if one of the specified strings matches the left-hand
-# part of the path. The tag can be used to show relative paths in the file list.
-# If left blank the directory from which doxygen is run is used as the path to
-# strip.
-#
-# Note that you can specify absolute paths here, but also relative paths, which
-# will be relative from the directory where doxygen is started.
-# This tag requires that the tag FULL_PATH_NAMES is set to YES.
-
-STRIP_FROM_PATH = @_STRIP_FROM_PATH@
-
-# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of the
-# path mentioned in the documentation of a class, which tells the reader which
-# header file to include in order to use a class. If left blank only the name of
-# the header file containing the class definition is used. Otherwise one should
-# specify the list of include paths that are normally passed to the compiler
-# using the -I flag.
-
-STRIP_FROM_INC_PATH = @_STRIP_FROM_INC_PATH@
-
-# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter (but
-# less readable) file names. This can be useful is your file systems doesn't
-# support long names like on DOS, Mac, or CD-ROM.
-# The default value is: NO.
-
-SHORT_NAMES = NO
-
-# If the JAVADOC_AUTOBRIEF tag is set to YES then doxygen will interpret the
-# first line (until the first dot) of a Javadoc-style comment as the brief
-# description. If set to NO, the Javadoc-style will behave just like regular Qt-
-# style comments (thus requiring an explicit @brief command for a brief
-# description.)
-# The default value is: NO.
-
-JAVADOC_AUTOBRIEF = YES
-
-# If the QT_AUTOBRIEF tag is set to YES then doxygen will interpret the first
-# line (until the first dot) of a Qt-style comment as the brief description. If
-# set to NO, the Qt-style will behave just like regular Qt-style comments (thus
-# requiring an explicit \brief command for a brief description.)
-# The default value is: NO.
-
-QT_AUTOBRIEF = YES
-
-# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make doxygen treat a
-# multi-line C++ special comment block (i.e. a block of //! or /// comments) as
-# a brief description. This used to be the default behavior. The new default is
-# to treat a multi-line C++ comment block as a detailed description. Set this
-# tag to YES if you prefer the old behavior instead.
-#
-# Note that setting this tag to YES also means that rational rose comments are
-# not recognized any more.
-# The default value is: NO.
-
-MULTILINE_CPP_IS_BRIEF = YES
-
-# If the INHERIT_DOCS tag is set to YES then an undocumented member inherits the
-# documentation from any documented member that it re-implements.
-# The default value is: YES.
-
-INHERIT_DOCS = YES
-
-# If the SEPARATE_MEMBER_PAGES tag is set to YES then doxygen will produce a new
-# page for each member. If set to NO, the documentation of a member will be part
-# of the file/class/namespace that contains it.
-# The default value is: NO.
-
-SEPARATE_MEMBER_PAGES = NO
-
-# The TAB_SIZE tag can be used to set the number of spaces in a tab. Doxygen
-# uses this value to replace tabs by spaces in code fragments.
-# Minimum value: 1, maximum value: 16, default value: 4.
-
-TAB_SIZE = 4
-
-# This tag can be used to specify a number of aliases that act as commands in
-# the documentation. An alias has the form:
-# name=value
-# For example adding
-# "sideeffect=@par Side Effects:\n"
-# will allow you to put the command \sideeffect (or @sideeffect) in the
-# documentation, which will result in a user-defined paragraph with heading
-# "Side Effects:". You can put \n's in the value part of an alias to insert
-# newlines (in the resulting output). You can put ^^ in the value part of an
-# alias to insert a newline as if a physical newline was in the original file.
-# When you need a literal { or } or , in the value part of an alias you have to
-# escape them by means of a backslash (\), this can lead to conflicts with the
-# commands \{ and \} for these it is advised to use the version @{ and @} or use
-# a double escape (\\{ and \\})
-
-ALIASES =
-
-# This tag can be used to specify a number of word-keyword mappings (TCL only).
-# A mapping has the form "name=value". For example adding "class=itcl::class"
-# will allow you to use the command class in the itcl::class meaning.
-
-TCL_SUBST =
-
-# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources
-# only. Doxygen will then generate output that is more tailored for C. For
-# instance, some of the names that are used will be different. The list of all
-# members will be omitted, etc.
-# The default value is: NO.
-
-OPTIMIZE_OUTPUT_FOR_C = NO
-
-# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java or
-# Python sources only. Doxygen will then generate output that is more tailored
-# for that language. For instance, namespaces will be presented as packages,
-# qualified scopes will look different, etc.
-# The default value is: NO.
-
-OPTIMIZE_OUTPUT_JAVA = NO
-
-# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran
-# sources. Doxygen will then generate output that is tailored for Fortran.
-# The default value is: NO.
-
-OPTIMIZE_FOR_FORTRAN = NO
-
-# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL
-# sources. Doxygen will then generate output that is tailored for VHDL.
-# The default value is: NO.
-
-OPTIMIZE_OUTPUT_VHDL = NO
-
-# Set the OPTIMIZE_OUTPUT_SLICE tag to YES if your project consists of Slice
-# sources only. Doxygen will then generate output that is more tailored for that
-# language. For instance, namespaces will be presented as modules, types will be
-# separated into more groups, etc.
-# The default value is: NO.
-
-OPTIMIZE_OUTPUT_SLICE = NO
-
-# Doxygen selects the parser to use depending on the extension of the files it
-# parses. With this tag you can assign which parser to use for a given
-# extension. Doxygen has a built-in mapping, but you can override or extend it
-# using this tag. The format is ext=language, where ext is a file extension, and
-# language is one of the parsers supported by doxygen: IDL, Java, Javascript,
-# Csharp (C#), C, C++, D, PHP, md (Markdown), Objective-C, Python, Slice,
-# Fortran (fixed format Fortran: FortranFixed, free formatted Fortran:
-# FortranFree, unknown formatted Fortran: Fortran. In the later case the parser
-# tries to guess whether the code is fixed or free formatted code, this is the
-# default for Fortran type files), VHDL, tcl. For instance to make doxygen treat
-# .inc files as Fortran files (default is PHP), and .f files as C (default is
-# Fortran), use: inc=Fortran f=C.
-#
-# Note: For files without extension you can use no_extension as a placeholder.
-#
-# Note that for custom extensions you also need to set FILE_PATTERNS otherwise
-# the files are not read by doxygen.
-
-EXTENSION_MAPPING =
-
-# If the MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all comments
-# according to the Markdown format, which allows for more readable
-# documentation. See https://daringfireball.net/projects/markdown/ for details.
-# The output of markdown processing is further processed by doxygen, so you can
-# mix doxygen, HTML, and XML commands with Markdown formatting. Disable only in
-# case of backward compatibilities issues.
-# The default value is: YES.
-
-MARKDOWN_SUPPORT = YES
-
-# When the TOC_INCLUDE_HEADINGS tag is set to a non-zero value, all headings up
-# to that level are automatically included in the table of contents, even if
-# they do not have an id attribute.
-# Note: This feature currently applies only to Markdown headings.
-# Minimum value: 0, maximum value: 99, default value: 0.
-# This tag requires that the tag MARKDOWN_SUPPORT is set to YES.
-
-TOC_INCLUDE_HEADINGS = 4
-
-# When enabled doxygen tries to link words that correspond to documented
-# classes, or namespaces to their corresponding documentation. Such a link can
-# be prevented in individual cases by putting a % sign in front of the word or
-# globally by setting AUTOLINK_SUPPORT to NO.
-# The default value is: YES.
-
-AUTOLINK_SUPPORT = YES
-
-# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want
-# to include (a tag file for) the STL sources as input, then you should set this
-# tag to YES in order to let doxygen match functions declarations and
-# definitions whose arguments contain STL classes (e.g. func(std::string);
-# versus func(std::string) {}). This also make the inheritance and collaboration
-# diagrams that involve STL classes more complete and accurate.
-# The default value is: NO.
-
-BUILTIN_STL_SUPPORT = YES
-
-# If you use Microsoft's C++/CLI language, you should set this option to YES to
-# enable parsing support.
-# The default value is: NO.
-
-CPP_CLI_SUPPORT = NO
-
-# Set the SIP_SUPPORT tag to YES if your project consists of sip (see:
-# https://www.riverbankcomputing.com/software/sip/intro) sources only. Doxygen
-# will parse them like normal C++ but will assume all classes use public instead
-# of private inheritance when no explicit protection keyword is present.
-# The default value is: NO.
-
-SIP_SUPPORT = NO
-
-# For Microsoft's IDL there are propget and propput attributes to indicate
-# getter and setter methods for a property. Setting this option to YES will make
-# doxygen to replace the get and set methods by a property in the documentation.
-# This will only work if the methods are indeed getting or setting a simple
-# type. If this is not the case, or you want to show the methods anyway, you
-# should set this option to NO.
-# The default value is: YES.
-
-IDL_PROPERTY_SUPPORT = YES
-
-# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC
-# tag is set to YES then doxygen will reuse the documentation of the first
-# member in the group (if any) for the other members of the group. By default
-# all members of a group must be documented explicitly.
-# The default value is: NO.
-
-DISTRIBUTE_GROUP_DOC = NO
-
-# If one adds a struct or class to a group and this option is enabled, then also
-# any nested class or struct is added to the same group. By default this option
-# is disabled and one has to add nested compounds explicitly via \ingroup.
-# The default value is: NO.
-
-GROUP_NESTED_COMPOUNDS = YES
-
-# Set the SUBGROUPING tag to YES to allow class member groups of the same type
-# (for instance a group of public functions) to be put as a subgroup of that
-# type (e.g. under the Public Functions section). Set it to NO to prevent
-# subgrouping. Alternatively, this can be done per class using the
-# \nosubgrouping command.
-# The default value is: YES.
-
-SUBGROUPING = YES
-
-# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and unions
-# are shown inside the group in which they are included (e.g. using \ingroup)
-# instead of on a separate page (for HTML and Man pages) or section (for LaTeX
-# and RTF).
-#
-# Note that this feature does not work in combination with
-# SEPARATE_MEMBER_PAGES.
-# The default value is: NO.
-
-INLINE_GROUPED_CLASSES = NO
-
-# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and unions
-# with only public data fields or simple typedef fields will be shown inline in
-# the documentation of the scope in which they are defined (i.e. file,
-# namespace, or group documentation), provided this scope is documented. If set
-# to NO, structs, classes, and unions are shown on a separate page (for HTML and
-# Man pages) or section (for LaTeX and RTF).
-# The default value is: NO.
-
-INLINE_SIMPLE_STRUCTS = YES
-
-# When TYPEDEF_HIDES_STRUCT tag is enabled, a typedef of a struct, union, or
-# enum is documented as struct, union, or enum with the name of the typedef. So
-# typedef struct TypeS {} TypeT, will appear in the documentation as a struct
-# with name TypeT. When disabled the typedef will appear as a member of a file,
-# namespace, or class. And the struct will be named TypeS. This can typically be
-# useful for C code in case the coding convention dictates that all compound
-# types are typedef'ed and only the typedef is referenced, never the tag name.
-# The default value is: NO.
-
-TYPEDEF_HIDES_STRUCT = NO
-
-# The size of the symbol lookup cache can be set using LOOKUP_CACHE_SIZE. This
-# cache is used to resolve symbols given their name and scope. Since this can be
-# an expensive process and often the same symbol appears multiple times in the
-# code, doxygen keeps a cache of pre-resolved symbols. If the cache is too small
-# doxygen will become slower. If the cache is too large, memory is wasted. The
-# cache size is given by this formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range
-# is 0..9, the default is 0, corresponding to a cache size of 2^16=65536
-# symbols. At the end of a run doxygen will report the cache usage and suggest
-# the optimal cache size from a speed point of view.
-# Minimum value: 0, maximum value: 9, default value: 0.
-
-LOOKUP_CACHE_SIZE = 0
-
-#---------------------------------------------------------------------------
-# Build related configuration options
-#---------------------------------------------------------------------------
-
-# If the EXTRACT_ALL tag is set to YES, doxygen will assume all entities in
-# documentation are documented, even if no documentation was available. Private
-# class members and static file members will be hidden unless the
-# EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES.
-# Note: This will also disable the warnings about undocumented members that are
-# normally produced when WARNINGS is set to YES.
-# The default value is: NO.
-
-EXTRACT_ALL = YES
-
-# If the EXTRACT_PRIVATE tag is set to YES, all private members of a class will
-# be included in the documentation.
-# The default value is: NO.
-
-EXTRACT_PRIVATE = YES
-
-# If the EXTRACT_PACKAGE tag is set to YES, all members with package or internal
-# scope will be included in the documentation.
-# The default value is: NO.
-
-EXTRACT_PACKAGE = YES
-
-# If the EXTRACT_STATIC tag is set to YES, all static members of a file will be
-# included in the documentation.
-# The default value is: NO.
-
-EXTRACT_STATIC = YES
-
-# If the EXTRACT_LOCAL_CLASSES tag is set to YES, classes (and structs) defined
-# locally in source files will be included in the documentation. If set to NO,
-# only classes defined in header files are included. Does not have any effect
-# for Java sources.
-# The default value is: YES.
-
-EXTRACT_LOCAL_CLASSES = YES
-
-# This flag is only useful for Objective-C code. If set to YES, local methods,
-# which are defined in the implementation section but not in the interface are
-# included in the documentation. If set to NO, only methods in the interface are
-# included.
-# The default value is: NO.
-
-EXTRACT_LOCAL_METHODS = YES
-
-# If this flag is set to YES, the members of anonymous namespaces will be
-# extracted and appear in the documentation as a namespace called
-# 'anonymous_namespace{file}', where file will be replaced with the base name of
-# the file that contains the anonymous namespace. By default anonymous namespace
-# are hidden.
-# The default value is: NO.
-
-EXTRACT_ANON_NSPACES = YES
-
-# If the HIDE_UNDOC_MEMBERS tag is set to YES, doxygen will hide all
-# undocumented members inside documented classes or files. If set to NO these
-# members will be included in the various overviews, but no documentation
-# section is generated. This option has no effect if EXTRACT_ALL is enabled.
-# The default value is: NO.
-
-HIDE_UNDOC_MEMBERS = NO
-
-# If the HIDE_UNDOC_CLASSES tag is set to YES, doxygen will hide all
-# undocumented classes that are normally visible in the class hierarchy. If set
-# to NO, these classes will be included in the various overviews. This option
-# has no effect if EXTRACT_ALL is enabled.
-# The default value is: NO.
-
-HIDE_UNDOC_CLASSES = NO
-
-# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, doxygen will hide all friend
-# (class|struct|union) declarations. If set to NO, these declarations will be
-# included in the documentation.
-# The default value is: NO.
-
-HIDE_FRIEND_COMPOUNDS = NO
-
-# If the HIDE_IN_BODY_DOCS tag is set to YES, doxygen will hide any
-# documentation blocks found inside the body of a function. If set to NO, these
-# blocks will be appended to the function's detailed documentation block.
-# The default value is: NO.
-
-HIDE_IN_BODY_DOCS = NO
-
-# The INTERNAL_DOCS tag determines if documentation that is typed after a
-# \internal command is included. If the tag is set to NO then the documentation
-# will be excluded. Set it to YES to include the internal documentation.
-# The default value is: NO.
-
-INTERNAL_DOCS = YES
-
-# If the CASE_SENSE_NAMES tag is set to NO then doxygen will only generate file
-# names in lower-case letters. If set to YES, upper-case letters are also
-# allowed. This is useful if you have classes or files whose names only differ
-# in case and if your file system supports case sensitive file names. Windows
-# and Mac users are advised to set this option to NO.
-# The default value is: system dependent.
-
-CASE_SENSE_NAMES = NO
-
-# If the HIDE_SCOPE_NAMES tag is set to NO then doxygen will show members with
-# their full class and namespace scopes in the documentation. If set to YES, the
-# scope will be hidden.
-# The default value is: NO.
-
-HIDE_SCOPE_NAMES = NO
-
-# If the HIDE_COMPOUND_REFERENCE tag is set to NO (default) then doxygen will
-# append additional text to a page's title, such as Class Reference. If set to
-# YES the compound reference will be hidden.
-# The default value is: NO.
-
-HIDE_COMPOUND_REFERENCE= NO
-
-# If the SHOW_INCLUDE_FILES tag is set to YES then doxygen will put a list of
-# the files that are included by a file in the documentation of that file.
-# The default value is: YES.
-
-SHOW_INCLUDE_FILES = YES
-
-# If the SHOW_GROUPED_MEMB_INC tag is set to YES then Doxygen will add for each
-# grouped member an include statement to the documentation, telling the reader
-# which file to include in order to use the member.
-# The default value is: NO.
-
-SHOW_GROUPED_MEMB_INC = YES
-
-# If the FORCE_LOCAL_INCLUDES tag is set to YES then doxygen will list include
-# files with double quotes in the documentation rather than with sharp brackets.
-# The default value is: NO.
-
-FORCE_LOCAL_INCLUDES = NO
-
-# If the INLINE_INFO tag is set to YES then a tag [inline] is inserted in the
-# documentation for inline members.
-# The default value is: YES.
-
-INLINE_INFO = YES
-
-# If the SORT_MEMBER_DOCS tag is set to YES then doxygen will sort the
-# (detailed) documentation of file and class members alphabetically by member
-# name. If set to NO, the members will appear in declaration order.
-# The default value is: YES.
-
-SORT_MEMBER_DOCS = NO
-
-# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the brief
-# descriptions of file, namespace and class members alphabetically by member
-# name. If set to NO, the members will appear in declaration order. Note that
-# this will also influence the order of the classes in the class list.
-# The default value is: NO.
-
-SORT_BRIEF_DOCS = NO
-
-# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen will sort the
-# (brief and detailed) documentation of class members so that constructors and
-# destructors are listed first. If set to NO the constructors will appear in the
-# respective orders defined by SORT_BRIEF_DOCS and SORT_MEMBER_DOCS.
-# Note: If SORT_BRIEF_DOCS is set to NO this option is ignored for sorting brief
-# member documentation.
-# Note: If SORT_MEMBER_DOCS is set to NO this option is ignored for sorting
-# detailed member documentation.
-# The default value is: NO.
-
-SORT_MEMBERS_CTORS_1ST = NO
-
-# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the hierarchy
-# of group names into alphabetical order. If set to NO the group names will
-# appear in their defined order.
-# The default value is: NO.
-
-SORT_GROUP_NAMES = NO
-
-# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be sorted by
-# fully-qualified names, including namespaces. If set to NO, the class list will
-# be sorted only by class name, not including the namespace part.
-# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES.
-# Note: This option applies only to the class list, not to the alphabetical
-# list.
-# The default value is: NO.
-
-SORT_BY_SCOPE_NAME = NO
-
-# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to do proper
-# type resolution of all parameters of a function it will reject a match between
-# the prototype and the implementation of a member function even if there is
-# only one candidate or it is obvious which candidate to choose by doing a
-# simple string match. By disabling STRICT_PROTO_MATCHING doxygen will still
-# accept a match between prototype and implementation in such cases.
-# The default value is: NO.
-
-STRICT_PROTO_MATCHING = NO
-
-# The GENERATE_TODOLIST tag can be used to enable (YES) or disable (NO) the todo
-# list. This list is created by putting \todo commands in the documentation.
-# The default value is: YES.
-
-GENERATE_TODOLIST = YES
-
-# The GENERATE_TESTLIST tag can be used to enable (YES) or disable (NO) the test
-# list. This list is created by putting \test commands in the documentation.
-# The default value is: YES.
-
-GENERATE_TESTLIST = YES
-
-# The GENERATE_BUGLIST tag can be used to enable (YES) or disable (NO) the bug
-# list. This list is created by putting \bug commands in the documentation.
-# The default value is: YES.
-
-GENERATE_BUGLIST = YES
-
-# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or disable (NO)
-# the deprecated list. This list is created by putting \deprecated commands in
-# the documentation.
-# The default value is: YES.
-
-GENERATE_DEPRECATEDLIST= YES
-
-# The ENABLED_SECTIONS tag can be used to enable conditional documentation
-# sections, marked by \if <section_label> ... \endif and \cond <section_label>
-# ... \endcond blocks.
-
-ENABLED_SECTIONS =
-
-# The MAX_INITIALIZER_LINES tag determines the maximum number of lines that the
-# initial value of a variable or macro / define can have for it to appear in the
-# documentation. If the initializer consists of more lines than specified here
-# it will be hidden. Use a value of 0 to hide initializers completely. The
-# appearance of the value of individual variables and macros / defines can be
-# controlled using \showinitializer or \hideinitializer command in the
-# documentation regardless of this setting.
-# Minimum value: 0, maximum value: 10000, default value: 30.
-
-MAX_INITIALIZER_LINES = 30
-
-# Set the SHOW_USED_FILES tag to NO to disable the list of files generated at
-# the bottom of the documentation of classes and structs. If set to YES, the
-# list will mention the files that were used to generate the documentation.
-# The default value is: YES.
-
-SHOW_USED_FILES = YES
-
-# Set the SHOW_FILES tag to NO to disable the generation of the Files page. This
-# will remove the Files entry from the Quick Index and from the Folder Tree View
-# (if specified).
-# The default value is: YES.
-
-SHOW_FILES = YES
-
-# Set the SHOW_NAMESPACES tag to NO to disable the generation of the Namespaces
-# page. This will remove the Namespaces entry from the Quick Index and from the
-# Folder Tree View (if specified).
-# The default value is: YES.
-
-SHOW_NAMESPACES = YES
-
-# The FILE_VERSION_FILTER tag can be used to specify a program or script that
-# doxygen should invoke to get the current version for each file (typically from
-# the version control system). Doxygen will invoke the program by executing (via
-# popen()) the command command input-file, where command is the value of the
-# FILE_VERSION_FILTER tag, and input-file is the name of an input file provided
-# by doxygen. Whatever the program writes to standard output is used as the file
-# version. For an example see the documentation.
-
-FILE_VERSION_FILTER =
-
-# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed
-# by doxygen. The layout file controls the global structure of the generated
-# output files in an output format independent way. To create the layout file
-# that represents doxygen's defaults, run doxygen with the -l option. You can
-# optionally specify a file name after the option, if omitted DoxygenLayout.xml
-# will be used as the name of the layout file.
-#
-# Note that if you run doxygen from a directory containing a file called
-# DoxygenLayout.xml, doxygen will parse it automatically even if the LAYOUT_FILE
-# tag is left empty.
-
-LAYOUT_FILE =
-
-# The CITE_BIB_FILES tag can be used to specify one or more bib files containing
-# the reference definitions. This must be a list of .bib files. The .bib
-# extension is automatically appended if omitted. This requires the bibtex tool
-# to be installed. See also https://en.wikipedia.org/wiki/BibTeX for more info.
-# For LaTeX the style of the bibliography can be controlled using
-# LATEX_BIB_STYLE. To use this feature you need bibtex and perl available in the
-# search path. See also \cite for info how to create references.
-
-CITE_BIB_FILES =
-
-#---------------------------------------------------------------------------
-# Configuration options related to warning and progress messages
-#---------------------------------------------------------------------------
-
-# The QUIET tag can be used to turn on/off the messages that are generated to
-# standard output by doxygen. If QUIET is set to YES this implies that the
-# messages are off.
-# The default value is: NO.
-
-QUIET = NO
-
-# The WARNINGS tag can be used to turn on/off the warning messages that are
-# generated to standard error (stderr) by doxygen. If WARNINGS is set to YES
-# this implies that the warnings are on.
-#
-# Tip: Turn warnings on while writing the documentation.
-# The default value is: YES.
-
-WARNINGS = YES
-
-# If the WARN_IF_UNDOCUMENTED tag is set to YES then doxygen will generate
-# warnings for undocumented members. If EXTRACT_ALL is set to YES then this flag
-# will automatically be disabled.
-# The default value is: YES.
-
-WARN_IF_UNDOCUMENTED = YES
-
-# If the WARN_IF_DOC_ERROR tag is set to YES, doxygen will generate warnings for
-# potential errors in the documentation, such as not documenting some parameters
-# in a documented function, or documenting parameters that don't exist or using
-# markup commands wrongly.
-# The default value is: YES.
-
-WARN_IF_DOC_ERROR = YES
-
-# This WARN_NO_PARAMDOC option can be enabled to get warnings for functions that
-# are documented, but have no documentation for their parameters or return
-# value. If set to NO, doxygen will only warn about wrong or incomplete
-# parameter documentation, but not about the absence of documentation. If
-# EXTRACT_ALL is set to YES then this flag will automatically be disabled.
-# The default value is: NO.
-
-WARN_NO_PARAMDOC = NO
-
-# If the WARN_AS_ERROR tag is set to YES then doxygen will immediately stop when
-# a warning is encountered.
-# The default value is: NO.
-
-WARN_AS_ERROR = NO
-
-# The WARN_FORMAT tag determines the format of the warning messages that doxygen
-# can produce. The string should contain the $file, $line, and $text tags, which
-# will be replaced by the file and line number from which the warning originated
-# and the warning text. Optionally the format may contain $version, which will
-# be replaced by the version of the file (if it could be obtained via
-# FILE_VERSION_FILTER)
-# The default value is: $file:$line: $text.
-
-WARN_FORMAT = "$file:$line: $text"
-
-# The WARN_LOGFILE tag can be used to specify a file to which warning and error
-# messages should be written. If left blank the output is written to standard
-# error (stderr).
-
-WARN_LOGFILE =
-
-#---------------------------------------------------------------------------
-# Configuration options related to the input files
-#---------------------------------------------------------------------------
-
-# The INPUT tag is used to specify the files and/or directories that contain
-# documented source files. You may enter file names like myfile.cpp or
-# directories like /usr/src/myproject. Separate the files or directories with
-# spaces. See also FILE_PATTERNS and EXTENSION_MAPPING
-# Note: If this tag is empty the current directory is searched.
-
-INPUT = @_INPUT@
-
-# This tag can be used to specify the character encoding of the source files
-# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses
-# libiconv (or the iconv built into libc) for the transcoding. See the libiconv
-# documentation (see: https://www.gnu.org/software/libiconv/) for the list of
-# possible encodings.
-# The default value is: UTF-8.
-
-INPUT_ENCODING = UTF-8
-
-# If the value of the INPUT tag contains directories, you can use the
-# FILE_PATTERNS tag to specify one or more wildcard patterns (like *.cpp and
-# *.h) to filter out the source-files in the directories.
-#
-# Note that for custom extensions or not directly supported extensions you also
-# need to set EXTENSION_MAPPING for the extension otherwise the files are not
-# read by doxygen.
-#
-# If left blank the following patterns are tested:*.c, *.cc, *.cxx, *.cpp,
-# *.c++, *.java, *.ii, *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h,
-# *.hh, *.hxx, *.hpp, *.h++, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, *.inc,
-# *.m, *.markdown, *.md, *.mm, *.dox, *.py, *.pyw, *.f90, *.f95, *.f03, *.f08,
-# *.f, *.for, *.tcl, *.vhd, *.vhdl, *.ucf, *.qsf and *.ice.
-
-FILE_PATTERNS = *.c \
- *.cc \
- *.cxx \
- *.cpp \
- *.c++ \
- *.java \
- *.ii \
- *.ixx \
- *.ipp \
- *.i++ \
- *.inl \
- *.idl \
- *.ddl \
- *.odl \
- *.h \
- *.hh \
- *.hxx \
- *.hpp \
- *.h++ \
- *.cs \
- *.d \
- *.php \
- *.php4 \
- *.php5 \
- *.phtml \
- *.inc \
- *.m \
- *.markdown \
- *.md \
- *.mm \
- *.dox \
- *.py \
- *.pyw \
- *.f90 \
- *.f95 \
- *.f03 \
- *.f08 \
- *.f \
- *.for \
- *.tcl \
- *.vhd \
- *.vhdl \
- *.ucf \
- *.qsf \
- *.ice \
- @_FILE_PATTERNS@
-
-# The RECURSIVE tag can be used to specify whether or not subdirectories should
-# be searched for input files as well.
-# The default value is: NO.
-
-RECURSIVE = YES
-
-# The EXCLUDE tag can be used to specify files and/or directories that should be
-# excluded from the INPUT source files. This way you can easily exclude a
-# subdirectory from a directory tree whose root is specified with the INPUT tag.
-#
-# Note that relative paths are relative to the directory from which doxygen is
-# run.
-
-EXCLUDE = @_EXCLUDE@
-
-# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or
-# directories that are symbolic links (a Unix file system feature) are excluded
-# from the input.
-# The default value is: NO.
-
-EXCLUDE_SYMLINKS = NO
-
-# If the value of the INPUT tag contains directories, you can use the
-# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude
-# certain files from those directories.
-#
-# Note that the wildcards are matched against the file with absolute path, so to
-# exclude all test directories for example use the pattern */test/*
-
-EXCLUDE_PATTERNS = @_EXCLUDE_PATTERNS@
-
-# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names
-# (namespaces, classes, functions, etc.) that should be excluded from the
-# output. The symbol name can be a fully qualified name, a word, or if the
-# wildcard * is used, a substring. Examples: ANamespace, AClass,
-# AClass::ANamespace, ANamespace::*Test
-#
-# Note that the wildcards are matched against the file with absolute path, so to
-# exclude all test directories use the pattern */test/*
-
-EXCLUDE_SYMBOLS = @_EXCLUDE_SYMBOLS@
-
-# The EXAMPLE_PATH tag can be used to specify one or more files or directories
-# that contain example code fragments that are included (see the \include
-# command).
-
-EXAMPLE_PATH = @_EXAMPLE_PATH@
-
-# If the value of the EXAMPLE_PATH tag contains directories, you can use the
-# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and
-# *.h) to filter out the source-files in the directories. If left blank all
-# files are included.
-
-EXAMPLE_PATTERNS = *
-
-# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be
-# searched for input files to be used with the \include or \dontinclude commands
-# irrespective of the value of the RECURSIVE tag.
-# The default value is: NO.
-
-EXAMPLE_RECURSIVE = YES
-
-# The IMAGE_PATH tag can be used to specify one or more files or directories
-# that contain images that are to be included in the documentation (see the
-# \image command).
-
-IMAGE_PATH =
-
-# The INPUT_FILTER tag can be used to specify a program that doxygen should
-# invoke to filter for each input file. Doxygen will invoke the filter program
-# by executing (via popen()) the command:
-#
-# <filter> <input-file>
-#
-# where <filter> is the value of the INPUT_FILTER tag, and <input-file> is the
-# name of an input file. Doxygen will then use the output that the filter
-# program writes to standard output. If FILTER_PATTERNS is specified, this tag
-# will be ignored.
-#
-# Note that the filter must not add or remove lines; it is applied before the
-# code is scanned, but not when the output code is generated. If lines are added
-# or removed, the anchors will not be placed correctly.
-#
-# Note that for custom extensions or not directly supported extensions you also
-# need to set EXTENSION_MAPPING for the extension otherwise the files are not
-# properly processed by doxygen.
-
-INPUT_FILTER =
-
-# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern
-# basis. Doxygen will compare the file name with each pattern and apply the
-# filter if there is a match. The filters are a list of the form: pattern=filter
-# (like *.cpp=my_cpp_filter). See INPUT_FILTER for further information on how
-# filters are used. If the FILTER_PATTERNS tag is empty or if none of the
-# patterns match the file name, INPUT_FILTER is applied.
-#
-# Note that for custom extensions or not directly supported extensions you also
-# need to set EXTENSION_MAPPING for the extension otherwise the files are not
-# properly processed by doxygen.
-
-FILTER_PATTERNS =
-
-# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using
-# INPUT_FILTER) will also be used to filter the input files that are used for
-# producing the source files to browse (i.e. when SOURCE_BROWSER is set to YES).
-# The default value is: NO.
-
-FILTER_SOURCE_FILES = NO
-
-# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file
-# pattern. A pattern will override the setting for FILTER_PATTERN (if any) and
-# it is also possible to disable source filtering for a specific pattern using
-# *.ext= (so without naming a filter).
-# This tag requires that the tag FILTER_SOURCE_FILES is set to YES.
-
-FILTER_SOURCE_PATTERNS =
-
-# If the USE_MDFILE_AS_MAINPAGE tag refers to the name of a markdown file that
-# is part of the input, its contents will be placed on the main page
-# (index.html). This can be useful if you have a project on for instance GitHub
-# and want to reuse the introduction page also for the doxygen output.
-
-USE_MDFILE_AS_MAINPAGE =
-
-#---------------------------------------------------------------------------
-# Configuration options related to source browsing
-#---------------------------------------------------------------------------
-
-# If the SOURCE_BROWSER tag is set to YES then a list of source files will be
-# generated. Documented entities will be cross-referenced with these sources.
-#
-# Note: To get rid of all source code in the generated output, make sure that
-# also VERBATIM_HEADERS is set to NO.
-# The default value is: NO.
-
-SOURCE_BROWSER = YES
-
-# Setting the INLINE_SOURCES tag to YES will include the body of functions,
-# classes and enums directly into the documentation.
-# The default value is: NO.
-
-INLINE_SOURCES = YES
-
-# Setting the STRIP_CODE_COMMENTS tag to YES will instruct doxygen to hide any
-# special comment blocks from generated source code fragments. Normal C, C++ and
-# Fortran comments will always remain visible.
-# The default value is: YES.
-
-STRIP_CODE_COMMENTS = NO
-
-# If the REFERENCED_BY_RELATION tag is set to YES then for each documented
-# entity all documented functions referencing it will be listed.
-# The default value is: NO.
-
-REFERENCED_BY_RELATION = YES
-
-# If the REFERENCES_RELATION tag is set to YES then for each documented function
-# all documented entities called/used by that function will be listed.
-# The default value is: NO.
-
-REFERENCES_RELATION = YES
-
-# If the REFERENCES_LINK_SOURCE tag is set to YES and SOURCE_BROWSER tag is set
-# to YES then the hyperlinks from functions in REFERENCES_RELATION and
-# REFERENCED_BY_RELATION lists will link to the source code. Otherwise they will
-# link to the documentation.
-# The default value is: YES.
-
-REFERENCES_LINK_SOURCE = YES
-
-# If SOURCE_TOOLTIPS is enabled (the default) then hovering a hyperlink in the
-# source code will show a tooltip with additional information such as prototype,
-# brief description and links to the definition and documentation. Since this
-# will make the HTML file larger and loading of large files a bit slower, you
-# can opt to disable this feature.
-# The default value is: YES.
-# This tag requires that the tag SOURCE_BROWSER is set to YES.
-
-SOURCE_TOOLTIPS = YES
-
-# If the USE_HTAGS tag is set to YES then the references to source code will
-# point to the HTML generated by the htags(1) tool instead of doxygen built-in
-# source browser. The htags tool is part of GNU's global source tagging system
-# (see https://www.gnu.org/software/global/global.html). You will need version
-# 4.8.6 or higher.
-#
-# To use it do the following:
-# - Install the latest version of global
-# - Enable SOURCE_BROWSER and USE_HTAGS in the configuration file
-# - Make sure the INPUT points to the root of the source tree
-# - Run doxygen as normal
-#
-# Doxygen will invoke htags (and that will in turn invoke gtags), so these
-# tools must be available from the command line (i.e. in the search path).
-#
-# The result: instead of the source browser generated by doxygen, the links to
-# source code will now point to the output of htags.
-# The default value is: NO.
-# This tag requires that the tag SOURCE_BROWSER is set to YES.
-
-USE_HTAGS = NO
-
-# If the VERBATIM_HEADERS tag is set the YES then doxygen will generate a
-# verbatim copy of the header file for each class for which an include is
-# specified. Set to NO to disable this.
-# See also: Section \class.
-# The default value is: YES.
-
-VERBATIM_HEADERS = YES
-
-# If the CLANG_ASSISTED_PARSING tag is set to YES then doxygen will use the
-# clang parser (see: http://clang.llvm.org/) for more accurate parsing at the
-# cost of reduced performance. This can be particularly helpful with template
-# rich C++ code for which doxygen's built-in parser lacks the necessary type
-# information.
-# Note: The availability of this option depends on whether or not doxygen was
-# generated with the -Duse_libclang=ON option for CMake.
-# The default value is: NO.
-
-CLANG_ASSISTED_PARSING = YES
-
-# If clang assisted parsing is enabled you can provide the compiler with command
-# line options that you would normally use when invoking the compiler. Note that
-# the include paths will already be set by doxygen for the files and directories
-# specified with INPUT and INCLUDE_PATH.
-# This tag requires that the tag CLANG_ASSISTED_PARSING is set to YES.
-
-CLANG_OPTIONS =
-
-# If clang assisted parsing is enabled you can provide the clang parser with the
-# path to the compilation database (see:
-# http://clang.llvm.org/docs/HowToSetupToolingForLLVM.html) used when the files
-# were built. This is equivalent to specifying the "-p" option to a clang tool,
-# such as clang-check. These options will then be passed to the parser.
-# Note: The availability of this option depends on whether or not doxygen was
-# generated with the -Duse_libclang=ON option for CMake.
-
-CLANG_DATABASE_PATH = @_CLANG_DATABASE_PATH@
-
-#---------------------------------------------------------------------------
-# Configuration options related to the alphabetical class index
-#---------------------------------------------------------------------------
-
-# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index of all
-# compounds will be generated. Enable this if the project contains a lot of
-# classes, structs, unions or interfaces.
-# The default value is: YES.
-
-ALPHABETICAL_INDEX = YES
-
-# The COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns in
-# which the alphabetical index list will be split.
-# Minimum value: 1, maximum value: 20, default value: 5.
-# This tag requires that the tag ALPHABETICAL_INDEX is set to YES.
-
-COLS_IN_ALPHA_INDEX = 5
-
-# In case all classes in a project start with a common prefix, all classes will
-# be put under the same header in the alphabetical index. The IGNORE_PREFIX tag
-# can be used to specify a prefix (or a list of prefixes) that should be ignored
-# while generating the index headers.
-# This tag requires that the tag ALPHABETICAL_INDEX is set to YES.
-
-IGNORE_PREFIX =
-
-#---------------------------------------------------------------------------
-# Configuration options related to the HTML output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_HTML tag is set to YES, doxygen will generate HTML output
-# The default value is: YES.
-
-GENERATE_HTML = YES
-
-# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. If a
-# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
-# it.
-# The default directory is: html.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-HTML_OUTPUT = html
-
-# The HTML_FILE_EXTENSION tag can be used to specify the file extension for each
-# generated HTML page (for example: .htm, .php, .asp).
-# The default value is: .html.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-HTML_FILE_EXTENSION = .html
-
-# The HTML_HEADER tag can be used to specify a user-defined HTML header file for
-# each generated HTML page. If the tag is left blank doxygen will generate a
-# standard header.
-#
-# To get valid HTML the header file that includes any scripts and style sheets
-# that doxygen needs, which is dependent on the configuration options used (e.g.
-# the setting GENERATE_TREEVIEW). It is highly recommended to start with a
-# default header using
-# doxygen -w html new_header.html new_footer.html new_stylesheet.css
-# YourConfigFile
-# and then modify the file new_header.html. See also section "Doxygen usage"
-# for information on how to generate the default header that doxygen normally
-# uses.
-# Note: The header is subject to change so you typically have to regenerate the
-# default header when upgrading to a newer version of doxygen. For a description
-# of the possible markers and block names see the documentation.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-HTML_HEADER =
-
-# The HTML_FOOTER tag can be used to specify a user-defined HTML footer for each
-# generated HTML page. If the tag is left blank doxygen will generate a standard
-# footer. See HTML_HEADER for more information on how to generate a default
-# footer and what special commands can be used inside the footer. See also
-# section "Doxygen usage" for information on how to generate the default footer
-# that doxygen normally uses.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-HTML_FOOTER =
-
-# The HTML_STYLESHEET tag can be used to specify a user-defined cascading style
-# sheet that is used by each HTML page. It can be used to fine-tune the look of
-# the HTML output. If left blank doxygen will generate a default style sheet.
-# See also section "Doxygen usage" for information on how to generate the style
-# sheet that doxygen normally uses.
-# Note: It is recommended to use HTML_EXTRA_STYLESHEET instead of this tag, as
-# it is more robust and this tag (HTML_STYLESHEET) will in the future become
-# obsolete.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-HTML_STYLESHEET =
-
-# The HTML_EXTRA_STYLESHEET tag can be used to specify additional user-defined
-# cascading style sheets that are included after the standard style sheets
-# created by doxygen. Using this option one can overrule certain style aspects.
-# This is preferred over using HTML_STYLESHEET since it does not replace the
-# standard style sheet and is therefore more robust against future updates.
-# Doxygen will copy the style sheet files to the output directory.
-# Note: The order of the extra style sheet files is of importance (e.g. the last
-# style sheet in the list overrules the setting of the previous ones in the
-# list). For an example see the documentation.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-HTML_EXTRA_STYLESHEET =
-
-# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or
-# other source files which should be copied to the HTML output directory. Note
-# that these files will be copied to the base HTML output directory. Use the
-# $relpath^ marker in the HTML_HEADER and/or HTML_FOOTER files to load these
-# files. In the HTML_STYLESHEET file, use the file name only. Also note that the
-# files will be copied as-is; there are no commands or markers available.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-HTML_EXTRA_FILES =
-
-# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen
-# will adjust the colors in the style sheet and background images according to
-# this color. Hue is specified as an angle on a colorwheel, see
-# https://en.wikipedia.org/wiki/Hue for more information. For instance the value
-# 0 represents red, 60 is yellow, 120 is green, 180 is cyan, 240 is blue, 300
-# purple, and 360 is red again.
-# Minimum value: 0, maximum value: 359, default value: 220.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-HTML_COLORSTYLE_HUE = 220
-
-# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of the colors
-# in the HTML output. For a value of 0 the output will use grayscales only. A
-# value of 255 will produce the most vivid colors.
-# Minimum value: 0, maximum value: 255, default value: 100.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-HTML_COLORSTYLE_SAT = 100
-
-# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to the
-# luminance component of the colors in the HTML output. Values below 100
-# gradually make the output lighter, whereas values above 100 make the output
-# darker. The value divided by 100 is the actual gamma applied, so 80 represents
-# a gamma of 0.8, The value 220 represents a gamma of 2.2, and 100 does not
-# change the gamma.
-# Minimum value: 40, maximum value: 240, default value: 80.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-HTML_COLORSTYLE_GAMMA = 80
-
-# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML
-# page will contain the date and time when the page was generated. Setting this
-# to YES can help to show when doxygen was last run and thus if the
-# documentation is up to date.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-HTML_TIMESTAMP = YES
-
-# If the HTML_DYNAMIC_MENUS tag is set to YES then the generated HTML
-# documentation will contain a main index with vertical navigation menus that
-# are dynamically created via Javascript. If disabled, the navigation index will
-# consists of multiple levels of tabs that are statically embedded in every HTML
-# page. Disable this option to support browsers that do not have Javascript,
-# like the Qt help browser.
-# The default value is: YES.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-HTML_DYNAMIC_MENUS = YES
-
-# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML
-# documentation will contain sections that can be hidden and shown after the
-# page has loaded.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-HTML_DYNAMIC_SECTIONS = NO
-
-# With HTML_INDEX_NUM_ENTRIES one can control the preferred number of entries
-# shown in the various tree structured indices initially; the user can expand
-# and collapse entries dynamically later on. Doxygen will expand the tree to
-# such a level that at most the specified number of entries are visible (unless
-# a fully collapsed tree already exceeds this amount). So setting the number of
-# entries 1 will produce a full collapsed tree by default. 0 is a special value
-# representing an infinite number of entries and will result in a full expanded
-# tree by default.
-# Minimum value: 0, maximum value: 9999, default value: 100.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-HTML_INDEX_NUM_ENTRIES = 100
-
-# If the GENERATE_DOCSET tag is set to YES, additional index files will be
-# generated that can be used as input for Apple's Xcode 3 integrated development
-# environment (see: https://developer.apple.com/xcode/), introduced with OSX
-# 10.5 (Leopard). To create a documentation set, doxygen will generate a
-# Makefile in the HTML output directory. Running make will produce the docset in
-# that directory and running make install will install the docset in
-# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find it at
-# startup. See https://developer.apple.com/library/archive/featuredarticles/Doxy
-# genXcode/_index.html for more information.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-GENERATE_DOCSET = NO
-
-# This tag determines the name of the docset feed. A documentation feed provides
-# an umbrella under which multiple documentation sets from a single provider
-# (such as a company or product suite) can be grouped.
-# The default value is: Doxygen generated docs.
-# This tag requires that the tag GENERATE_DOCSET is set to YES.
-
-DOCSET_FEEDNAME = "Doxygen generated docs"
-
-# This tag specifies a string that should uniquely identify the documentation
-# set bundle. This should be a reverse domain-name style string, e.g.
-# com.mycompany.MyDocSet. Doxygen will append .docset to the name.
-# The default value is: org.doxygen.Project.
-# This tag requires that the tag GENERATE_DOCSET is set to YES.
-
-DOCSET_BUNDLE_ID = org.doxygen.Project
-
-# The DOCSET_PUBLISHER_ID tag specifies a string that should uniquely identify
-# the documentation publisher. This should be a reverse domain-name style
-# string, e.g. com.mycompany.MyDocSet.documentation.
-# The default value is: org.doxygen.Publisher.
-# This tag requires that the tag GENERATE_DOCSET is set to YES.
-
-DOCSET_PUBLISHER_ID = org.doxygen.Publisher
-
-# The DOCSET_PUBLISHER_NAME tag identifies the documentation publisher.
-# The default value is: Publisher.
-# This tag requires that the tag GENERATE_DOCSET is set to YES.
-
-DOCSET_PUBLISHER_NAME = Publisher
-
-# If the GENERATE_HTMLHELP tag is set to YES then doxygen generates three
-# additional HTML index files: index.hhp, index.hhc, and index.hhk. The
-# index.hhp is a project file that can be read by Microsoft's HTML Help Workshop
-# (see: https://www.microsoft.com/en-us/download/details.aspx?id=21138) on
-# Windows.
-#
-# The HTML Help Workshop contains a compiler that can convert all HTML output
-# generated by doxygen into a single compiled HTML file (.chm). Compiled HTML
-# files are now used as the Windows 98 help format, and will replace the old
-# Windows help format (.hlp) on all Windows platforms in the future. Compressed
-# HTML files also contain an index, a table of contents, and you can search for
-# words in the documentation. The HTML workshop also contains a viewer for
-# compressed HTML files.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-GENERATE_HTMLHELP = NO
-
-# The CHM_FILE tag can be used to specify the file name of the resulting .chm
-# file. You can add a path in front of the file if the result should not be
-# written to the html output directory.
-# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
-
-CHM_FILE =
-
-# The HHC_LOCATION tag can be used to specify the location (absolute path
-# including file name) of the HTML help compiler (hhc.exe). If non-empty,
-# doxygen will try to run the HTML help compiler on the generated index.hhp.
-# The file has to be specified with full path.
-# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
-
-HHC_LOCATION =
-
-# The GENERATE_CHI flag controls if a separate .chi index file is generated
-# (YES) or that it should be included in the master .chm file (NO).
-# The default value is: NO.
-# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
-
-GENERATE_CHI = NO
-
-# The CHM_INDEX_ENCODING is used to encode HtmlHelp index (hhk), content (hhc)
-# and project file content.
-# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
-
-CHM_INDEX_ENCODING =
-
-# The BINARY_TOC flag controls whether a binary table of contents is generated
-# (YES) or a normal table of contents (NO) in the .chm file. Furthermore it
-# enables the Previous and Next buttons.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
-
-BINARY_TOC = NO
-
-# The TOC_EXPAND flag can be set to YES to add extra items for group members to
-# the table of contents of the HTML help documentation and to the tree view.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
-
-TOC_EXPAND = NO
-
-# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and
-# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated that
-# can be used as input for Qt's qhelpgenerator to generate a Qt Compressed Help
-# (.qch) of the generated HTML documentation.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-GENERATE_QHP = NO
-
-# If the QHG_LOCATION tag is specified, the QCH_FILE tag can be used to specify
-# the file name of the resulting .qch file. The path specified is relative to
-# the HTML output folder.
-# This tag requires that the tag GENERATE_QHP is set to YES.
-
-QCH_FILE =
-
-# The QHP_NAMESPACE tag specifies the namespace to use when generating Qt Help
-# Project output. For more information please see Qt Help Project / Namespace
-# (see: http://doc.qt.io/archives/qt-4.8/qthelpproject.html#namespace).
-# The default value is: org.doxygen.Project.
-# This tag requires that the tag GENERATE_QHP is set to YES.
-
-QHP_NAMESPACE = org.doxygen.Project
-
-# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating Qt
-# Help Project output. For more information please see Qt Help Project / Virtual
-# Folders (see: http://doc.qt.io/archives/qt-4.8/qthelpproject.html#virtual-
-# folders).
-# The default value is: doc.
-# This tag requires that the tag GENERATE_QHP is set to YES.
-
-QHP_VIRTUAL_FOLDER = doc
-
-# If the QHP_CUST_FILTER_NAME tag is set, it specifies the name of a custom
-# filter to add. For more information please see Qt Help Project / Custom
-# Filters (see: http://doc.qt.io/archives/qt-4.8/qthelpproject.html#custom-
-# filters).
-# This tag requires that the tag GENERATE_QHP is set to YES.
-
-QHP_CUST_FILTER_NAME =
-
-# The QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the
-# custom filter to add. For more information please see Qt Help Project / Custom
-# Filters (see: http://doc.qt.io/archives/qt-4.8/qthelpproject.html#custom-
-# filters).
-# This tag requires that the tag GENERATE_QHP is set to YES.
-
-QHP_CUST_FILTER_ATTRS =
-
-# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this
-# project's filter section matches. Qt Help Project / Filter Attributes (see:
-# http://doc.qt.io/archives/qt-4.8/qthelpproject.html#filter-attributes).
-# This tag requires that the tag GENERATE_QHP is set to YES.
-
-QHP_SECT_FILTER_ATTRS =
-
-# The QHG_LOCATION tag can be used to specify the location of Qt's
-# qhelpgenerator. If non-empty doxygen will try to run qhelpgenerator on the
-# generated .qhp file.
-# This tag requires that the tag GENERATE_QHP is set to YES.
-
-QHG_LOCATION =
-
-# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files will be
-# generated, together with the HTML files, they form an Eclipse help plugin. To
-# install this plugin and make it available under the help contents menu in
-# Eclipse, the contents of the directory containing the HTML and XML files needs
-# to be copied into the plugins directory of eclipse. The name of the directory
-# within the plugins directory should be the same as the ECLIPSE_DOC_ID value.
-# After copying Eclipse needs to be restarted before the help appears.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-GENERATE_ECLIPSEHELP = NO
-
-# A unique identifier for the Eclipse help plugin. When installing the plugin
-# the directory name containing the HTML and XML files should also have this
-# name. Each documentation set should have its own identifier.
-# The default value is: org.doxygen.Project.
-# This tag requires that the tag GENERATE_ECLIPSEHELP is set to YES.
-
-ECLIPSE_DOC_ID = org.doxygen.Project
-
-# If you want full control over the layout of the generated HTML pages it might
-# be necessary to disable the index and replace it with your own. The
-# DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) at top
-# of each HTML page. A value of NO enables the index and the value YES disables
-# it. Since the tabs in the index contain the same information as the navigation
-# tree, you can set this option to YES if you also set GENERATE_TREEVIEW to YES.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-DISABLE_INDEX = NO
-
-# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index
-# structure should be generated to display hierarchical information. If the tag
-# value is set to YES, a side panel will be generated containing a tree-like
-# index structure (just like the one that is generated for HTML Help). For this
-# to work a browser that supports JavaScript, DHTML, CSS and frames is required
-# (i.e. any modern browser). Windows users are probably better off using the
-# HTML help feature. Via custom style sheets (see HTML_EXTRA_STYLESHEET) one can
-# further fine-tune the look of the index. As an example, the default style
-# sheet generated by doxygen has an example that shows how to put an image at
-# the root of the tree instead of the PROJECT_NAME. Since the tree basically has
-# the same information as the tab index, you could consider setting
-# DISABLE_INDEX to YES when enabling this option.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-GENERATE_TREEVIEW = NO
-
-# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values that
-# doxygen will group on one line in the generated HTML documentation.
-#
-# Note that a value of 0 will completely suppress the enum values from appearing
-# in the overview section.
-# Minimum value: 0, maximum value: 20, default value: 4.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-ENUM_VALUES_PER_LINE = 4
-
-# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be used
-# to set the initial width (in pixels) of the frame in which the tree is shown.
-# Minimum value: 0, maximum value: 1500, default value: 250.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-TREEVIEW_WIDTH = 250
-
-# If the EXT_LINKS_IN_WINDOW option is set to YES, doxygen will open links to
-# external symbols imported via tag files in a separate window.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-EXT_LINKS_IN_WINDOW = NO
-
-# Use this tag to change the font size of LaTeX formulas included as images in
-# the HTML documentation. When you change the font size after a successful
-# doxygen run you need to manually remove any form_*.png images from the HTML
-# output directory to force them to be regenerated.
-# Minimum value: 8, maximum value: 50, default value: 10.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-FORMULA_FONTSIZE = 10
-
-# Use the FORMULA_TRANSPARENT tag to determine whether or not the images
-# generated for formulas are transparent PNGs. Transparent PNGs are not
-# supported properly for IE 6.0, but are supported on all modern browsers.
-#
-# Note that when changing this option you need to delete any form_*.png files in
-# the HTML output directory before the changes have effect.
-# The default value is: YES.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-FORMULA_TRANSPARENT = YES
-
-# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see
-# https://www.mathjax.org) which uses client side Javascript for the rendering
-# instead of using pre-rendered bitmaps. Use this if you do not have LaTeX
-# installed or if you want to formulas look prettier in the HTML output. When
-# enabled you may also need to install MathJax separately and configure the path
-# to it using the MATHJAX_RELPATH option.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-USE_MATHJAX = NO
-
-# When MathJax is enabled you can set the default output format to be used for
-# the MathJax output. See the MathJax site (see:
-# http://docs.mathjax.org/en/latest/output.html) for more details.
-# Possible values are: HTML-CSS (which is slower, but has the best
-# compatibility), NativeMML (i.e. MathML) and SVG.
-# The default value is: HTML-CSS.
-# This tag requires that the tag USE_MATHJAX is set to YES.
-
-MATHJAX_FORMAT = HTML-CSS
-
-# When MathJax is enabled you need to specify the location relative to the HTML
-# output directory using the MATHJAX_RELPATH option. The destination directory
-# should contain the MathJax.js script. For instance, if the mathjax directory
-# is located at the same level as the HTML output directory, then
-# MATHJAX_RELPATH should be ../mathjax. The default value points to the MathJax
-# Content Delivery Network so you can quickly see the result without installing
-# MathJax. However, it is strongly recommended to install a local copy of
-# MathJax from https://www.mathjax.org before deployment.
-# The default value is: https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/.
-# This tag requires that the tag USE_MATHJAX is set to YES.
-
-MATHJAX_RELPATH = https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/
-
-# The MATHJAX_EXTENSIONS tag can be used to specify one or more MathJax
-# extension names that should be enabled during MathJax rendering. For example
-# MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols
-# This tag requires that the tag USE_MATHJAX is set to YES.
-
-MATHJAX_EXTENSIONS =
-
-# The MATHJAX_CODEFILE tag can be used to specify a file with javascript pieces
-# of code that will be used on startup of the MathJax code. See the MathJax site
-# (see: http://docs.mathjax.org/en/latest/output.html) for more details. For an
-# example see the documentation.
-# This tag requires that the tag USE_MATHJAX is set to YES.
-
-MATHJAX_CODEFILE =
-
-# When the SEARCHENGINE tag is enabled doxygen will generate a search box for
-# the HTML output. The underlying search engine uses javascript and DHTML and
-# should work on any modern browser. Note that when using HTML help
-# (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets (GENERATE_DOCSET)
-# there is already a search function so this one should typically be disabled.
-# For large projects the javascript based search engine can be slow, then
-# enabling SERVER_BASED_SEARCH may provide a better solution. It is possible to
-# search using the keyboard; to jump to the search box use <access key> + S
-# (what the <access key> is depends on the OS and browser, but it is typically
-# <CTRL>, <ALT>/<option>, or both). Inside the search box use the <cursor down
-# key> to jump into the search results window, the results can be navigated
-# using the <cursor keys>. Press <Enter> to select an item or <escape> to cancel
-# the search. The filter options can be selected when the cursor is inside the
-# search box by pressing <Shift>+<cursor down>. Also here use the <cursor keys>
-# to select a filter and <Enter> or <escape> to activate or cancel the filter
-# option.
-# The default value is: YES.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-SEARCHENGINE = YES
-
-# When the SERVER_BASED_SEARCH tag is enabled the search engine will be
-# implemented using a web server instead of a web client using Javascript. There
-# are two flavors of web server based searching depending on the EXTERNAL_SEARCH
-# setting. When disabled, doxygen will generate a PHP script for searching and
-# an index file used by the script. When EXTERNAL_SEARCH is enabled the indexing
-# and searching needs to be provided by external tools. See the section
-# "External Indexing and Searching" for details.
-# The default value is: NO.
-# This tag requires that the tag SEARCHENGINE is set to YES.
-
-SERVER_BASED_SEARCH = NO
-
-# When EXTERNAL_SEARCH tag is enabled doxygen will no longer generate the PHP
-# script for searching. Instead the search results are written to an XML file
-# which needs to be processed by an external indexer. Doxygen will invoke an
-# external search engine pointed to by the SEARCHENGINE_URL option to obtain the
-# search results.
-#
-# Doxygen ships with an example indexer (doxyindexer) and search engine
-# (doxysearch.cgi) which are based on the open source search engine library
-# Xapian (see: https://xapian.org/).
-#
-# See the section "External Indexing and Searching" for details.
-# The default value is: NO.
-# This tag requires that the tag SEARCHENGINE is set to YES.
-
-EXTERNAL_SEARCH = NO
-
-# The SEARCHENGINE_URL should point to a search engine hosted by a web server
-# which will return the search results when EXTERNAL_SEARCH is enabled.
-#
-# Doxygen ships with an example indexer (doxyindexer) and search engine
-# (doxysearch.cgi) which are based on the open source search engine library
-# Xapian (see: https://xapian.org/). See the section "External Indexing and
-# Searching" for details.
-# This tag requires that the tag SEARCHENGINE is set to YES.
-
-SEARCHENGINE_URL =
-
-# When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the unindexed
-# search data is written to a file for indexing by an external tool. With the
-# SEARCHDATA_FILE tag the name of this file can be specified.
-# The default file is: searchdata.xml.
-# This tag requires that the tag SEARCHENGINE is set to YES.
-
-SEARCHDATA_FILE = searchdata.xml
-
-# When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the
-# EXTERNAL_SEARCH_ID tag can be used as an identifier for the project. This is
-# useful in combination with EXTRA_SEARCH_MAPPINGS to search through multiple
-# projects and redirect the results back to the right project.
-# This tag requires that the tag SEARCHENGINE is set to YES.
-
-EXTERNAL_SEARCH_ID =
-
-# The EXTRA_SEARCH_MAPPINGS tag can be used to enable searching through doxygen
-# projects other than the one defined by this configuration file, but that are
-# all added to the same external search index. Each project needs to have a
-# unique id set via EXTERNAL_SEARCH_ID. The search mapping then maps the id of
-# to a relative location where the documentation can be found. The format is:
-# EXTRA_SEARCH_MAPPINGS = tagname1=loc1 tagname2=loc2 ...
-# This tag requires that the tag SEARCHENGINE is set to YES.
-
-EXTRA_SEARCH_MAPPINGS =
-
-#---------------------------------------------------------------------------
-# Configuration options related to the LaTeX output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_LATEX tag is set to YES, doxygen will generate LaTeX output.
-# The default value is: YES.
-
-GENERATE_LATEX = NO
-
-# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. If a
-# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
-# it.
-# The default directory is: latex.
-# This tag requires that the tag GENERATE_LATEX is set to YES.
-
-LATEX_OUTPUT = latex
-
-# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be
-# invoked.
-#
-# Note that when not enabling USE_PDFLATEX the default is latex when enabling
-# USE_PDFLATEX the default is pdflatex and when in the later case latex is
-# chosen this is overwritten by pdflatex. For specific output languages the
-# default can have been set differently, this depends on the implementation of
-# the output language.
-# This tag requires that the tag GENERATE_LATEX is set to YES.
-
-LATEX_CMD_NAME =
-
-# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to generate
-# index for LaTeX.
-# Note: This tag is used in the Makefile / make.bat.
-# See also: LATEX_MAKEINDEX_CMD for the part in the generated output file
-# (.tex).
-# The default file is: makeindex.
-# This tag requires that the tag GENERATE_LATEX is set to YES.
-
-MAKEINDEX_CMD_NAME = makeindex
-
-# The LATEX_MAKEINDEX_CMD tag can be used to specify the command name to
-# generate index for LaTeX.
-# Note: This tag is used in the generated output file (.tex).
-# See also: MAKEINDEX_CMD_NAME for the part in the Makefile / make.bat.
-# The default value is: \makeindex.
-# This tag requires that the tag GENERATE_LATEX is set to YES.
-
-LATEX_MAKEINDEX_CMD = \makeindex
-
-# If the COMPACT_LATEX tag is set to YES, doxygen generates more compact LaTeX
-# documents. This may be useful for small projects and may help to save some
-# trees in general.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_LATEX is set to YES.
-
-COMPACT_LATEX = NO
-
-# The PAPER_TYPE tag can be used to set the paper type that is used by the
-# printer.
-# Possible values are: a4 (210 x 297 mm), letter (8.5 x 11 inches), legal (8.5 x
-# 14 inches) and executive (7.25 x 10.5 inches).
-# The default value is: a4.
-# This tag requires that the tag GENERATE_LATEX is set to YES.
-
-PAPER_TYPE = a4
-
-# The EXTRA_PACKAGES tag can be used to specify one or more LaTeX package names
-# that should be included in the LaTeX output. The package can be specified just
-# by its name or with the correct syntax as to be used with the LaTeX
-# \usepackage command. To get the times font for instance you can specify :
-# EXTRA_PACKAGES=times or EXTRA_PACKAGES={times}
-# To use the option intlimits with the amsmath package you can specify:
-# EXTRA_PACKAGES=[intlimits]{amsmath}
-# If left blank no extra packages will be included.
-# This tag requires that the tag GENERATE_LATEX is set to YES.
-
-EXTRA_PACKAGES =
-
-# The LATEX_HEADER tag can be used to specify a personal LaTeX header for the
-# generated LaTeX document. The header should contain everything until the first
-# chapter. If it is left blank doxygen will generate a standard header. See
-# section "Doxygen usage" for information on how to let doxygen write the
-# default header to a separate file.
-#
-# Note: Only use a user-defined header if you know what you are doing! The
-# following commands have a special meaning inside the header: $title,
-# $datetime, $date, $doxygenversion, $projectname, $projectnumber,
-# $projectbrief, $projectlogo. Doxygen will replace $title with the empty
-# string, for the replacement values of the other commands the user is referred
-# to HTML_HEADER.
-# This tag requires that the tag GENERATE_LATEX is set to YES.
-
-LATEX_HEADER =
-
-# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for the
-# generated LaTeX document. The footer should contain everything after the last
-# chapter. If it is left blank doxygen will generate a standard footer. See
-# LATEX_HEADER for more information on how to generate a default footer and what
-# special commands can be used inside the footer.
-#
-# Note: Only use a user-defined footer if you know what you are doing!
-# This tag requires that the tag GENERATE_LATEX is set to YES.
-
-LATEX_FOOTER =
-
-# The LATEX_EXTRA_STYLESHEET tag can be used to specify additional user-defined
-# LaTeX style sheets that are included after the standard style sheets created
-# by doxygen. Using this option one can overrule certain style aspects. Doxygen
-# will copy the style sheet files to the output directory.
-# Note: The order of the extra style sheet files is of importance (e.g. the last
-# style sheet in the list overrules the setting of the previous ones in the
-# list).
-# This tag requires that the tag GENERATE_LATEX is set to YES.
-
-LATEX_EXTRA_STYLESHEET =
-
-# The LATEX_EXTRA_FILES tag can be used to specify one or more extra images or
-# other source files which should be copied to the LATEX_OUTPUT output
-# directory. Note that the files will be copied as-is; there are no commands or
-# markers available.
-# This tag requires that the tag GENERATE_LATEX is set to YES.
-
-LATEX_EXTRA_FILES =
-
-# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated is
-# prepared for conversion to PDF (using ps2pdf or pdflatex). The PDF file will
-# contain links (just like the HTML output) instead of page references. This
-# makes the output suitable for online browsing using a PDF viewer.
-# The default value is: YES.
-# This tag requires that the tag GENERATE_LATEX is set to YES.
-
-PDF_HYPERLINKS = YES
-
-# If the USE_PDFLATEX tag is set to YES, doxygen will use pdflatex to generate
-# the PDF file directly from the LaTeX files. Set this option to YES, to get a
-# higher quality PDF documentation.
-# The default value is: YES.
-# This tag requires that the tag GENERATE_LATEX is set to YES.
-
-USE_PDFLATEX = YES
-
-# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \batchmode
-# command to the generated LaTeX files. This will instruct LaTeX to keep running
-# if errors occur, instead of asking the user for help. This option is also used
-# when generating formulas in HTML.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_LATEX is set to YES.
-
-LATEX_BATCHMODE = NO
-
-# If the LATEX_HIDE_INDICES tag is set to YES then doxygen will not include the
-# index chapters (such as File Index, Compound Index, etc.) in the output.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_LATEX is set to YES.
-
-LATEX_HIDE_INDICES = NO
-
-# If the LATEX_SOURCE_CODE tag is set to YES then doxygen will include source
-# code with syntax highlighting in the LaTeX output.
-#
-# Note that which sources are shown also depends on other settings such as
-# SOURCE_BROWSER.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_LATEX is set to YES.
-
-LATEX_SOURCE_CODE = NO
-
-# The LATEX_BIB_STYLE tag can be used to specify the style to use for the
-# bibliography, e.g. plainnat, or ieeetr. See
-# https://en.wikipedia.org/wiki/BibTeX and \cite for more info.
-# The default value is: plain.
-# This tag requires that the tag GENERATE_LATEX is set to YES.
-
-LATEX_BIB_STYLE = plain
-
-# If the LATEX_TIMESTAMP tag is set to YES then the footer of each generated
-# page will contain the date and time when the page was generated. Setting this
-# to NO can help when comparing the output of multiple runs.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_LATEX is set to YES.
-
-LATEX_TIMESTAMP = NO
-
-# The LATEX_EMOJI_DIRECTORY tag is used to specify the (relative or absolute)
-# path from which the emoji images will be read. If a relative path is entered,
-# it will be relative to the LATEX_OUTPUT directory. If left blank the
-# LATEX_OUTPUT directory will be used.
-# This tag requires that the tag GENERATE_LATEX is set to YES.
-
-LATEX_EMOJI_DIRECTORY =
-
-#---------------------------------------------------------------------------
-# Configuration options related to the RTF output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_RTF tag is set to YES, doxygen will generate RTF output. The
-# RTF output is optimized for Word 97 and may not look too pretty with other RTF
-# readers/editors.
-# The default value is: NO.
-
-GENERATE_RTF = NO
-
-# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. If a
-# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
-# it.
-# The default directory is: rtf.
-# This tag requires that the tag GENERATE_RTF is set to YES.
-
-RTF_OUTPUT = rtf
-
-# If the COMPACT_RTF tag is set to YES, doxygen generates more compact RTF
-# documents. This may be useful for small projects and may help to save some
-# trees in general.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_RTF is set to YES.
-
-COMPACT_RTF = NO
-
-# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated will
-# contain hyperlink fields. The RTF file will contain links (just like the HTML
-# output) instead of page references. This makes the output suitable for online
-# browsing using Word or some other Word compatible readers that support those
-# fields.
-#
-# Note: WordPad (write) and others do not support links.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_RTF is set to YES.
-
-RTF_HYPERLINKS = NO
-
-# Load stylesheet definitions from file. Syntax is similar to doxygen's
-# configuration file, i.e. a series of assignments. You only have to provide
-# replacements, missing definitions are set to their default value.
-#
-# See also section "Doxygen usage" for information on how to generate the
-# default style sheet that doxygen normally uses.
-# This tag requires that the tag GENERATE_RTF is set to YES.
-
-RTF_STYLESHEET_FILE =
-
-# Set optional variables used in the generation of an RTF document. Syntax is
-# similar to doxygen's configuration file. A template extensions file can be
-# generated using doxygen -e rtf extensionFile.
-# This tag requires that the tag GENERATE_RTF is set to YES.
-
-RTF_EXTENSIONS_FILE =
-
-# If the RTF_SOURCE_CODE tag is set to YES then doxygen will include source code
-# with syntax highlighting in the RTF output.
-#
-# Note that which sources are shown also depends on other settings such as
-# SOURCE_BROWSER.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_RTF is set to YES.
-
-RTF_SOURCE_CODE = NO
-
-#---------------------------------------------------------------------------
-# Configuration options related to the man page output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_MAN tag is set to YES, doxygen will generate man pages for
-# classes and files.
-# The default value is: NO.
-
-GENERATE_MAN = NO
-
-# The MAN_OUTPUT tag is used to specify where the man pages will be put. If a
-# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
-# it. A directory man3 will be created inside the directory specified by
-# MAN_OUTPUT.
-# The default directory is: man.
-# This tag requires that the tag GENERATE_MAN is set to YES.
-
-MAN_OUTPUT = man
-
-# The MAN_EXTENSION tag determines the extension that is added to the generated
-# man pages. In case the manual section does not start with a number, the number
-# 3 is prepended. The dot (.) at the beginning of the MAN_EXTENSION tag is
-# optional.
-# The default value is: .3.
-# This tag requires that the tag GENERATE_MAN is set to YES.
-
-MAN_EXTENSION = .3
-
-# The MAN_SUBDIR tag determines the name of the directory created within
-# MAN_OUTPUT in which the man pages are placed. If defaults to man followed by
-# MAN_EXTENSION with the initial . removed.
-# This tag requires that the tag GENERATE_MAN is set to YES.
-
-MAN_SUBDIR =
-
-# If the MAN_LINKS tag is set to YES and doxygen generates man output, then it
-# will generate one additional man file for each entity documented in the real
-# man page(s). These additional files only source the real man page, but without
-# them the man command would be unable to find the correct page.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_MAN is set to YES.
-
-MAN_LINKS = NO
-
-#---------------------------------------------------------------------------
-# Configuration options related to the XML output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_XML tag is set to YES, doxygen will generate an XML file that
-# captures the structure of the code including all documentation.
-# The default value is: NO.
-
-GENERATE_XML = YES
-
-# The XML_OUTPUT tag is used to specify where the XML pages will be put. If a
-# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
-# it.
-# The default directory is: xml.
-# This tag requires that the tag GENERATE_XML is set to YES.
-
-XML_OUTPUT = xml
-
-# If the XML_PROGRAMLISTING tag is set to YES, doxygen will dump the program
-# listings (including syntax highlighting and cross-referencing information) to
-# the XML output. Note that enabling this will significantly increase the size
-# of the XML output.
-# The default value is: YES.
-# This tag requires that the tag GENERATE_XML is set to YES.
-
-XML_PROGRAMLISTING = YES
-
-# If the XML_NS_MEMB_FILE_SCOPE tag is set to YES, doxygen will include
-# namespace members in file scope as well, matching the HTML output.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_XML is set to YES.
-
-XML_NS_MEMB_FILE_SCOPE = NO
-
-#---------------------------------------------------------------------------
-# Configuration options related to the DOCBOOK output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_DOCBOOK tag is set to YES, doxygen will generate Docbook files
-# that can be used to generate PDF.
-# The default value is: NO.
-
-GENERATE_DOCBOOK = NO
-
-# The DOCBOOK_OUTPUT tag is used to specify where the Docbook pages will be put.
-# If a relative path is entered the value of OUTPUT_DIRECTORY will be put in
-# front of it.
-# The default directory is: docbook.
-# This tag requires that the tag GENERATE_DOCBOOK is set to YES.
-
-DOCBOOK_OUTPUT = docbook
-
-# If the DOCBOOK_PROGRAMLISTING tag is set to YES, doxygen will include the
-# program listings (including syntax highlighting and cross-referencing
-# information) to the DOCBOOK output. Note that enabling this will significantly
-# increase the size of the DOCBOOK output.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_DOCBOOK is set to YES.
-
-DOCBOOK_PROGRAMLISTING = NO
-
-#---------------------------------------------------------------------------
-# Configuration options for the AutoGen Definitions output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_AUTOGEN_DEF tag is set to YES, doxygen will generate an
-# AutoGen Definitions (see http://autogen.sourceforge.net/) file that captures
-# the structure of the code including all documentation. Note that this feature
-# is still experimental and incomplete at the moment.
-# The default value is: NO.
-
-GENERATE_AUTOGEN_DEF = NO
-
-#---------------------------------------------------------------------------
-# Configuration options related to the Perl module output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_PERLMOD tag is set to YES, doxygen will generate a Perl module
-# file that captures the structure of the code including all documentation.
-#
-# Note that this feature is still experimental and incomplete at the moment.
-# The default value is: NO.
-
-GENERATE_PERLMOD = NO
-
-# If the PERLMOD_LATEX tag is set to YES, doxygen will generate the necessary
-# Makefile rules, Perl scripts and LaTeX code to be able to generate PDF and DVI
-# output from the Perl module output.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_PERLMOD is set to YES.
-
-PERLMOD_LATEX = NO
-
-# If the PERLMOD_PRETTY tag is set to YES, the Perl module output will be nicely
-# formatted so it can be parsed by a human reader. This is useful if you want to
-# understand what is going on. On the other hand, if this tag is set to NO, the
-# size of the Perl module output will be much smaller and Perl will parse it
-# just the same.
-# The default value is: YES.
-# This tag requires that the tag GENERATE_PERLMOD is set to YES.
-
-PERLMOD_PRETTY = YES
-
-# The names of the make variables in the generated doxyrules.make file are
-# prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. This is useful
-# so different doxyrules.make files included by the same Makefile don't
-# overwrite each other's variables.
-# This tag requires that the tag GENERATE_PERLMOD is set to YES.
-
-PERLMOD_MAKEVAR_PREFIX =
-
-#---------------------------------------------------------------------------
-# Configuration options related to the preprocessor
-#---------------------------------------------------------------------------
-
-# If the ENABLE_PREPROCESSING tag is set to YES, doxygen will evaluate all
-# C-preprocessor directives found in the sources and include files.
-# The default value is: YES.
-
-ENABLE_PREPROCESSING = YES
-
-# If the MACRO_EXPANSION tag is set to YES, doxygen will expand all macro names
-# in the source code. If set to NO, only conditional compilation will be
-# performed. Macro expansion can be done in a controlled way by setting
-# EXPAND_ONLY_PREDEF to YES.
-# The default value is: NO.
-# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
-
-MACRO_EXPANSION = NO
-
-# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES then
-# the macro expansion is limited to the macros specified with the PREDEFINED and
-# EXPAND_AS_DEFINED tags.
-# The default value is: NO.
-# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
-
-EXPAND_ONLY_PREDEF = NO
-
-# If the SEARCH_INCLUDES tag is set to YES, the include files in the
-# INCLUDE_PATH will be searched if a #include is found.
-# The default value is: YES.
-# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
-
-SEARCH_INCLUDES = YES
-
-# The INCLUDE_PATH tag can be used to specify one or more directories that
-# contain include files that are not input files but should be processed by the
-# preprocessor.
-# This tag requires that the tag SEARCH_INCLUDES is set to YES.
-
-INCLUDE_PATH =
-
-# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard
-# patterns (like *.h and *.hpp) to filter out the header-files in the
-# directories. If left blank, the patterns specified with FILE_PATTERNS will be
-# used.
-# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
-
-INCLUDE_FILE_PATTERNS =
-
-# The PREDEFINED tag can be used to specify one or more macro names that are
-# defined before the preprocessor is started (similar to the -D option of e.g.
-# gcc). The argument of the tag is a list of macros of the form: name or
-# name=definition (no spaces). If the definition and the "=" are omitted, "=1"
-# is assumed. To prevent a macro definition from being undefined via #undef or
-# recursively expanded use the := operator instead of the = operator.
-# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
-
-PREDEFINED =
-
-# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this
-# tag can be used to specify a list of macro names that should be expanded. The
-# macro definition that is found in the sources will be used. Use the PREDEFINED
-# tag if you want to use a different macro definition that overrules the
-# definition found in the source code.
-# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
-
-EXPAND_AS_DEFINED =
-
-# If the SKIP_FUNCTION_MACROS tag is set to YES then doxygen's preprocessor will
-# remove all references to function-like macros that are alone on a line, have
-# an all uppercase name, and do not end with a semicolon. Such function macros
-# are typically used for boiler-plate code, and will confuse the parser if not
-# removed.
-# The default value is: YES.
-# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
-
-SKIP_FUNCTION_MACROS = YES
-
-#---------------------------------------------------------------------------
-# Configuration options related to external references
-#---------------------------------------------------------------------------
-
-# The TAGFILES tag can be used to specify one or more tag files. For each tag
-# file the location of the external documentation should be added. The format of
-# a tag file without this location is as follows:
-# TAGFILES = file1 file2 ...
-# Adding location for the tag files is done as follows:
-# TAGFILES = file1=loc1 "file2 = loc2" ...
-# where loc1 and loc2 can be relative or absolute paths or URLs. See the
-# section "Linking to external documentation" for more information about the use
-# of tag files.
-# Note: Each tag file must have a unique name (where the name does NOT include
-# the path). If a tag file is not located in the directory in which doxygen is
-# run, you must also specify the path to the tagfile here.
-
-TAGFILES =
-
-# When a file name is specified after GENERATE_TAGFILE, doxygen will create a
-# tag file that is based on the input files it reads. See section "Linking to
-# external documentation" for more information about the usage of tag files.
-
-GENERATE_TAGFILE =
-
-# If the ALLEXTERNALS tag is set to YES, all external class will be listed in
-# the class index. If set to NO, only the inherited external classes will be
-# listed.
-# The default value is: NO.
-
-ALLEXTERNALS = NO
-
-# If the EXTERNAL_GROUPS tag is set to YES, all external groups will be listed
-# in the modules index. If set to NO, only the current project's groups will be
-# listed.
-# The default value is: YES.
-
-EXTERNAL_GROUPS = YES
-
-# If the EXTERNAL_PAGES tag is set to YES, all external pages will be listed in
-# the related pages index. If set to NO, only the current project's pages will
-# be listed.
-# The default value is: YES.
-
-EXTERNAL_PAGES = YES
-
-# The PERL_PATH should be the absolute path and name of the perl script
-# interpreter (i.e. the result of 'which perl').
-# The default file (with absolute path) is: /usr/bin/perl.
-
-PERL_PATH = /usr/bin/perl
-
-#---------------------------------------------------------------------------
-# Configuration options related to the dot tool
-#---------------------------------------------------------------------------
-
-# If the CLASS_DIAGRAMS tag is set to YES, doxygen will generate a class diagram
-# (in HTML and LaTeX) for classes with base or super classes. Setting the tag to
-# NO turns the diagrams off. Note that this option also works with HAVE_DOT
-# disabled, but it is recommended to install and use dot, since it yields more
-# powerful graphs.
-# The default value is: YES.
-
-CLASS_DIAGRAMS = YES
-
-# You can define message sequence charts within doxygen comments using the \msc
-# command. Doxygen will then run the mscgen tool (see:
-# http://www.mcternan.me.uk/mscgen/)) to produce the chart and insert it in the
-# documentation. The MSCGEN_PATH tag allows you to specify the directory where
-# the mscgen tool resides. If left empty the tool is assumed to be found in the
-# default search path.
-
-MSCGEN_PATH =
-
-# You can include diagrams made with dia in doxygen documentation. Doxygen will
-# then run dia to produce the diagram and insert it in the documentation. The
-# DIA_PATH tag allows you to specify the directory where the dia binary resides.
-# If left empty dia is assumed to be found in the default search path.
-
-DIA_PATH =
-
-# If set to YES the inheritance and collaboration graphs will hide inheritance
-# and usage relations if the target is undocumented or is not a class.
-# The default value is: YES.
-
-HIDE_UNDOC_RELATIONS = YES
-
-# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is
-# available from the path. This tool is part of Graphviz (see:
-# http://www.graphviz.org/), a graph visualization toolkit from AT&T and Lucent
-# Bell Labs. The other options in this section have no effect if this option is
-# set to NO
-# The default value is: NO.
-
-HAVE_DOT = NO
-
-# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is allowed
-# to run in parallel. When set to 0 doxygen will base this on the number of
-# processors available in the system. You can set it explicitly to a value
-# larger than 0 to get control over the balance between CPU load and processing
-# speed.
-# Minimum value: 0, maximum value: 32, default value: 0.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-DOT_NUM_THREADS = 0
-
-# When you want a differently looking font in the dot files that doxygen
-# generates you can specify the font name using DOT_FONTNAME. You need to make
-# sure dot is able to find the font, which can be done by putting it in a
-# standard location or by setting the DOTFONTPATH environment variable or by
-# setting DOT_FONTPATH to the directory containing the font.
-# The default value is: Helvetica.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-DOT_FONTNAME = Helvetica
-
-# The DOT_FONTSIZE tag can be used to set the size (in points) of the font of
-# dot graphs.
-# Minimum value: 4, maximum value: 24, default value: 10.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-DOT_FONTSIZE = 10
-
-# By default doxygen will tell dot to use the default font as specified with
-# DOT_FONTNAME. If you specify a different font using DOT_FONTNAME you can set
-# the path where dot can find it using this tag.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-DOT_FONTPATH =
-
-# If the CLASS_GRAPH tag is set to YES then doxygen will generate a graph for
-# each documented class showing the direct and indirect inheritance relations.
-# Setting this tag to YES will force the CLASS_DIAGRAMS tag to NO.
-# The default value is: YES.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-CLASS_GRAPH = YES
-
-# If the COLLABORATION_GRAPH tag is set to YES then doxygen will generate a
-# graph for each documented class showing the direct and indirect implementation
-# dependencies (inheritance, containment, and class references variables) of the
-# class with other documented classes.
-# The default value is: YES.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-COLLABORATION_GRAPH = YES
-
-# If the GROUP_GRAPHS tag is set to YES then doxygen will generate a graph for
-# groups, showing the direct groups dependencies.
-# The default value is: YES.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-GROUP_GRAPHS = YES
-
-# If the UML_LOOK tag is set to YES, doxygen will generate inheritance and
-# collaboration diagrams in a style similar to the OMG's Unified Modeling
-# Language.
-# The default value is: NO.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-UML_LOOK = NO
-
-# If the UML_LOOK tag is enabled, the fields and methods are shown inside the
-# class node. If there are many fields or methods and many nodes the graph may
-# become too big to be useful. The UML_LIMIT_NUM_FIELDS threshold limits the
-# number of items for each type to make the size more manageable. Set this to 0
-# for no limit. Note that the threshold may be exceeded by 50% before the limit
-# is enforced. So when you set the threshold to 10, up to 15 fields may appear,
-# but if the number exceeds 15, the total amount of fields shown is limited to
-# 10.
-# Minimum value: 0, maximum value: 100, default value: 10.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-UML_LIMIT_NUM_FIELDS = 10
-
-# If the TEMPLATE_RELATIONS tag is set to YES then the inheritance and
-# collaboration graphs will show the relations between templates and their
-# instances.
-# The default value is: NO.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-TEMPLATE_RELATIONS = NO
-
-# If the INCLUDE_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES tags are set to
-# YES then doxygen will generate a graph for each documented file showing the
-# direct and indirect include dependencies of the file with other documented
-# files.
-# The default value is: YES.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-INCLUDE_GRAPH = YES
-
-# If the INCLUDED_BY_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES tags are
-# set to YES then doxygen will generate a graph for each documented file showing
-# the direct and indirect include dependencies of the file with other documented
-# files.
-# The default value is: YES.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-INCLUDED_BY_GRAPH = YES
-
-# If the CALL_GRAPH tag is set to YES then doxygen will generate a call
-# dependency graph for every global function or class method.
-#
-# Note that enabling this option will significantly increase the time of a run.
-# So in most cases it will be better to enable call graphs for selected
-# functions only using the \callgraph command. Disabling a call graph can be
-# accomplished by means of the command \hidecallgraph.
-# The default value is: NO.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-CALL_GRAPH = NO
-
-# If the CALLER_GRAPH tag is set to YES then doxygen will generate a caller
-# dependency graph for every global function or class method.
-#
-# Note that enabling this option will significantly increase the time of a run.
-# So in most cases it will be better to enable caller graphs for selected
-# functions only using the \callergraph command. Disabling a caller graph can be
-# accomplished by means of the command \hidecallergraph.
-# The default value is: NO.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-CALLER_GRAPH = NO
-
-# If the GRAPHICAL_HIERARCHY tag is set to YES then doxygen will graphical
-# hierarchy of all classes instead of a textual one.
-# The default value is: YES.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-GRAPHICAL_HIERARCHY = YES
-
-# If the DIRECTORY_GRAPH tag is set to YES then doxygen will show the
-# dependencies a directory has on other directories in a graphical way. The
-# dependency relations are determined by the #include relations between the
-# files in the directories.
-# The default value is: YES.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-DIRECTORY_GRAPH = YES
-
-# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images
-# generated by dot. For an explanation of the image formats see the section
-# output formats in the documentation of the dot tool (Graphviz (see:
-# http://www.graphviz.org/)).
-# Note: If you choose svg you need to set HTML_FILE_EXTENSION to xhtml in order
-# to make the SVG files visible in IE 9+ (other browsers do not have this
-# requirement).
-# Possible values are: png, jpg, gif, svg, png:gd, png:gd:gd, png:cairo,
-# png:cairo:gd, png:cairo:cairo, png:cairo:gdiplus, png:gdiplus and
-# png:gdiplus:gdiplus.
-# The default value is: png.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-DOT_IMAGE_FORMAT = png
-
-# If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to
-# enable generation of interactive SVG images that allow zooming and panning.
-#
-# Note that this requires a modern browser other than Internet Explorer. Tested
-# and working are Firefox, Chrome, Safari, and Opera.
-# Note: For IE 9+ you need to set HTML_FILE_EXTENSION to xhtml in order to make
-# the SVG files visible. Older versions of IE do not have SVG support.
-# The default value is: NO.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-INTERACTIVE_SVG = NO
-
-# The DOT_PATH tag can be used to specify the path where the dot tool can be
-# found. If left blank, it is assumed the dot tool can be found in the path.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-DOT_PATH =
-
-# The DOTFILE_DIRS tag can be used to specify one or more directories that
-# contain dot files that are included in the documentation (see the \dotfile
-# command).
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-DOTFILE_DIRS =
-
-# The MSCFILE_DIRS tag can be used to specify one or more directories that
-# contain msc files that are included in the documentation (see the \mscfile
-# command).
-
-MSCFILE_DIRS =
-
-# The DIAFILE_DIRS tag can be used to specify one or more directories that
-# contain dia files that are included in the documentation (see the \diafile
-# command).
-
-DIAFILE_DIRS =
-
-# When using plantuml, the PLANTUML_JAR_PATH tag should be used to specify the
-# path where java can find the plantuml.jar file. If left blank, it is assumed
-# PlantUML is not used or called during a preprocessing step. Doxygen will
-# generate a warning when it encounters a \startuml command in this case and
-# will not generate output for the diagram.
-
-PLANTUML_JAR_PATH =
-
-# When using plantuml, the PLANTUML_CFG_FILE tag can be used to specify a
-# configuration file for plantuml.
-
-PLANTUML_CFG_FILE =
-
-# When using plantuml, the specified paths are searched for files specified by
-# the !include statement in a plantuml block.
-
-PLANTUML_INCLUDE_PATH =
-
-# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of nodes
-# that will be shown in the graph. If the number of nodes in a graph becomes
-# larger than this value, doxygen will truncate the graph, which is visualized
-# by representing a node as a red box. Note that doxygen if the number of direct
-# children of the root node in a graph is already larger than
-# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note that
-# the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH.
-# Minimum value: 0, maximum value: 10000, default value: 50.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-DOT_GRAPH_MAX_NODES = 50
-
-# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the graphs
-# generated by dot. A depth value of 3 means that only nodes reachable from the
-# root by following a path via at most 3 edges will be shown. Nodes that lay
-# further from the root node will be omitted. Note that setting this option to 1
-# or 2 may greatly reduce the computation time needed for large code bases. Also
-# note that the size of a graph can be further restricted by
-# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction.
-# Minimum value: 0, maximum value: 1000, default value: 0.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-MAX_DOT_GRAPH_DEPTH = 0
-
-# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent
-# background. This is disabled by default, because dot on Windows does not seem
-# to support this out of the box.
-#
-# Warning: Depending on the platform used, enabling this option may lead to
-# badly anti-aliased labels on the edges of a graph (i.e. they become hard to
-# read).
-# The default value is: NO.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-DOT_TRANSPARENT = NO
-
-# Set the DOT_MULTI_TARGETS tag to YES to allow dot to generate multiple output
-# files in one run (i.e. multiple -o and -T options on the command line). This
-# makes dot run faster, but since only newer versions of dot (>1.8.10) support
-# this, this feature is disabled by default.
-# The default value is: NO.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-DOT_MULTI_TARGETS = NO
-
-# If the GENERATE_LEGEND tag is set to YES doxygen will generate a legend page
-# explaining the meaning of the various boxes and arrows in the dot generated
-# graphs.
-# The default value is: YES.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-GENERATE_LEGEND = YES
-
-# If the DOT_CLEANUP tag is set to YES, doxygen will remove the intermediate dot
-# files that are used to generate the various graphs.
-# The default value is: YES.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-DOT_CLEANUP = YES
diff --git a/thirdparty/ryml/ext/c4core/cmake/Doxyfile.in b/thirdparty/ryml/ext/c4core/cmake/Doxyfile.in
deleted file mode 100644
index 6b464bf40..000000000
--- a/thirdparty/ryml/ext/c4core/cmake/Doxyfile.in
+++ /dev/null
@@ -1,2566 +0,0 @@
-# Doxyfile 1.8.15
-
-# This file describes the settings to be used by the documentation system
-# doxygen (www.doxygen.org) for a project.
-#
-# All text after a double hash (##) is considered a comment and is placed in
-# front of the TAG it is preceding.
-#
-# All text after a single hash (#) is considered a comment and will be ignored.
-# The format is:
-# TAG = value [value, ...]
-# For lists, items can also be appended using:
-# TAG += value [value, ...]
-# Values that contain spaces should be placed between quotes (\" \").
-
-#---------------------------------------------------------------------------
-# Project related configuration options
-#---------------------------------------------------------------------------
-
-# This tag specifies the encoding used for all characters in the configuration
-# file that follow. The default is UTF-8 which is also the encoding used for all
-# text before the first occurrence of this tag. Doxygen uses libiconv (or the
-# iconv built into libc) for the transcoding. See
-# https://www.gnu.org/software/libiconv/ for the list of possible encodings.
-# The default value is: UTF-8.
-
-DOXYFILE_ENCODING = UTF-8
-
-# The PROJECT_NAME tag is a single word (or a sequence of words surrounded by
-# double-quotes, unless you are using Doxywizard) that should identify the
-# project for which the documentation is generated. This name is used in the
-# title of most generated pages and in a few other places.
-# The default value is: My Project.
-
-PROJECT_NAME = @_PROJ@
-
-# The PROJECT_NUMBER tag can be used to enter a project or revision number. This
-# could be handy for archiving the generated documentation or if some version
-# control system is used.
-
-PROJECT_NUMBER = @_VERSION@
-
-# Using the PROJECT_BRIEF tag one can provide an optional one line description
-# for a project that appears at the top of each page and should give viewer a
-# quick idea about the purpose of the project. Keep the description short.
-
-PROJECT_BRIEF = @_PROJ_BRIEF@
-
-# With the PROJECT_LOGO tag one can specify a logo or an icon that is included
-# in the documentation. The maximum height of the logo should not exceed 55
-# pixels and the maximum width should not exceed 200 pixels. Doxygen will copy
-# the logo to the output directory.
-
-PROJECT_LOGO =
-
-# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path
-# into which the generated documentation will be written. If a relative path is
-# entered, it will be relative to the location where doxygen was started. If
-# left blank the current directory will be used.
-
-OUTPUT_DIRECTORY = @_OUTPUT_DIR@
-
-# If the CREATE_SUBDIRS tag is set to YES then doxygen will create 4096 sub-
-# directories (in 2 levels) under the output directory of each output format and
-# will distribute the generated files over these directories. Enabling this
-# option can be useful when feeding doxygen a huge amount of source files, where
-# putting all generated files in the same directory would otherwise causes
-# performance problems for the file system.
-# The default value is: NO.
-
-CREATE_SUBDIRS = NO
-
-# If the ALLOW_UNICODE_NAMES tag is set to YES, doxygen will allow non-ASCII
-# characters to appear in the names of generated files. If set to NO, non-ASCII
-# characters will be escaped, for example _xE3_x81_x84 will be used for Unicode
-# U+3044.
-# The default value is: NO.
-
-ALLOW_UNICODE_NAMES = YES
-
-# The OUTPUT_LANGUAGE tag is used to specify the language in which all
-# documentation generated by doxygen is written. Doxygen will use this
-# information to generate all constant output in the proper language.
-# Possible values are: Afrikaans, Arabic, Armenian, Brazilian, Catalan, Chinese,
-# Chinese-Traditional, Croatian, Czech, Danish, Dutch, English (United States),
-# Esperanto, Farsi (Persian), Finnish, French, German, Greek, Hungarian,
-# Indonesian, Italian, Japanese, Japanese-en (Japanese with English messages),
-# Korean, Korean-en (Korean with English messages), Latvian, Lithuanian,
-# Macedonian, Norwegian, Persian (Farsi), Polish, Portuguese, Romanian, Russian,
-# Serbian, Serbian-Cyrillic, Slovak, Slovene, Spanish, Swedish, Turkish,
-# Ukrainian and Vietnamese.
-# The default value is: English.
-
-OUTPUT_LANGUAGE = English
-
-# The OUTPUT_TEXT_DIRECTION tag is used to specify the direction in which all
-# documentation generated by doxygen is written. Doxygen will use this
-# information to generate all generated output in the proper direction.
-# Possible values are: None, LTR, RTL and Context.
-# The default value is: None.
-
-OUTPUT_TEXT_DIRECTION = None
-
-# If the BRIEF_MEMBER_DESC tag is set to YES, doxygen will include brief member
-# descriptions after the members that are listed in the file and class
-# documentation (similar to Javadoc). Set to NO to disable this.
-# The default value is: YES.
-
-BRIEF_MEMBER_DESC = YES
-
-# If the REPEAT_BRIEF tag is set to YES, doxygen will prepend the brief
-# description of a member or function before the detailed description
-#
-# Note: If both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the
-# brief descriptions will be completely suppressed.
-# The default value is: YES.
-
-REPEAT_BRIEF = YES
-
-# This tag implements a quasi-intelligent brief description abbreviator that is
-# used to form the text in various listings. Each string in this list, if found
-# as the leading text of the brief description, will be stripped from the text
-# and the result, after processing the whole list, is used as the annotated
-# text. Otherwise, the brief description is used as-is. If left blank, the
-# following values are used ($name is automatically replaced with the name of
-# the entity):The $name class, The $name widget, The $name file, is, provides,
-# specifies, contains, represents, a, an and the.
-
-ABBREVIATE_BRIEF = "The $name class" \
- "The $name widget" \
- "The $name file" \
- is \
- provides \
- specifies \
- contains \
- represents \
- a \
- an \
- the
-
-# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then
-# doxygen will generate a detailed section even if there is only a brief
-# description.
-# The default value is: NO.
-
-ALWAYS_DETAILED_SEC = NO
-
-# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all
-# inherited members of a class in the documentation of that class as if those
-# members were ordinary class members. Constructors, destructors and assignment
-# operators of the base classes will not be shown.
-# The default value is: NO.
-
-INLINE_INHERITED_MEMB = YES
-
-# If the FULL_PATH_NAMES tag is set to YES, doxygen will prepend the full path
-# before files name in the file list and in the header files. If set to NO the
-# shortest path that makes the file name unique will be used
-# The default value is: YES.
-
-FULL_PATH_NAMES = YES
-
-# The STRIP_FROM_PATH tag can be used to strip a user-defined part of the path.
-# Stripping is only done if one of the specified strings matches the left-hand
-# part of the path. The tag can be used to show relative paths in the file list.
-# If left blank the directory from which doxygen is run is used as the path to
-# strip.
-#
-# Note that you can specify absolute paths here, but also relative paths, which
-# will be relative from the directory where doxygen is started.
-# This tag requires that the tag FULL_PATH_NAMES is set to YES.
-
-STRIP_FROM_PATH = @_STRIP_FROM_PATH@
-
-# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of the
-# path mentioned in the documentation of a class, which tells the reader which
-# header file to include in order to use a class. If left blank only the name of
-# the header file containing the class definition is used. Otherwise one should
-# specify the list of include paths that are normally passed to the compiler
-# using the -I flag.
-
-STRIP_FROM_INC_PATH = @_STRIP_FROM_INC_PATH@
-
-# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter (but
-# less readable) file names. This can be useful is your file systems doesn't
-# support long names like on DOS, Mac, or CD-ROM.
-# The default value is: NO.
-
-SHORT_NAMES = NO
-
-# If the JAVADOC_AUTOBRIEF tag is set to YES then doxygen will interpret the
-# first line (until the first dot) of a Javadoc-style comment as the brief
-# description. If set to NO, the Javadoc-style will behave just like regular Qt-
-# style comments (thus requiring an explicit @brief command for a brief
-# description.)
-# The default value is: NO.
-
-JAVADOC_AUTOBRIEF = YES
-
-# If the QT_AUTOBRIEF tag is set to YES then doxygen will interpret the first
-# line (until the first dot) of a Qt-style comment as the brief description. If
-# set to NO, the Qt-style will behave just like regular Qt-style comments (thus
-# requiring an explicit \brief command for a brief description.)
-# The default value is: NO.
-
-QT_AUTOBRIEF = YES
-
-# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make doxygen treat a
-# multi-line C++ special comment block (i.e. a block of //! or /// comments) as
-# a brief description. This used to be the default behavior. The new default is
-# to treat a multi-line C++ comment block as a detailed description. Set this
-# tag to YES if you prefer the old behavior instead.
-#
-# Note that setting this tag to YES also means that rational rose comments are
-# not recognized any more.
-# The default value is: NO.
-
-MULTILINE_CPP_IS_BRIEF = YES
-
-# If the INHERIT_DOCS tag is set to YES then an undocumented member inherits the
-# documentation from any documented member that it re-implements.
-# The default value is: YES.
-
-INHERIT_DOCS = YES
-
-# If the SEPARATE_MEMBER_PAGES tag is set to YES then doxygen will produce a new
-# page for each member. If set to NO, the documentation of a member will be part
-# of the file/class/namespace that contains it.
-# The default value is: NO.
-
-SEPARATE_MEMBER_PAGES = NO
-
-# The TAB_SIZE tag can be used to set the number of spaces in a tab. Doxygen
-# uses this value to replace tabs by spaces in code fragments.
-# Minimum value: 1, maximum value: 16, default value: 4.
-
-TAB_SIZE = 4
-
-# This tag can be used to specify a number of aliases that act as commands in
-# the documentation. An alias has the form:
-# name=value
-# For example adding
-# "sideeffect=@par Side Effects:\n"
-# will allow you to put the command \sideeffect (or @sideeffect) in the
-# documentation, which will result in a user-defined paragraph with heading
-# "Side Effects:". You can put \n's in the value part of an alias to insert
-# newlines (in the resulting output). You can put ^^ in the value part of an
-# alias to insert a newline as if a physical newline was in the original file.
-# When you need a literal { or } or , in the value part of an alias you have to
-# escape them by means of a backslash (\), this can lead to conflicts with the
-# commands \{ and \} for these it is advised to use the version @{ and @} or use
-# a double escape (\\{ and \\})
-
-ALIASES =
-
-# This tag can be used to specify a number of word-keyword mappings (TCL only).
-# A mapping has the form "name=value". For example adding "class=itcl::class"
-# will allow you to use the command class in the itcl::class meaning.
-
-TCL_SUBST =
-
-# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources
-# only. Doxygen will then generate output that is more tailored for C. For
-# instance, some of the names that are used will be different. The list of all
-# members will be omitted, etc.
-# The default value is: NO.
-
-OPTIMIZE_OUTPUT_FOR_C = NO
-
-# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java or
-# Python sources only. Doxygen will then generate output that is more tailored
-# for that language. For instance, namespaces will be presented as packages,
-# qualified scopes will look different, etc.
-# The default value is: NO.
-
-OPTIMIZE_OUTPUT_JAVA = NO
-
-# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran
-# sources. Doxygen will then generate output that is tailored for Fortran.
-# The default value is: NO.
-
-OPTIMIZE_FOR_FORTRAN = NO
-
-# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL
-# sources. Doxygen will then generate output that is tailored for VHDL.
-# The default value is: NO.
-
-OPTIMIZE_OUTPUT_VHDL = NO
-
-# Set the OPTIMIZE_OUTPUT_SLICE tag to YES if your project consists of Slice
-# sources only. Doxygen will then generate output that is more tailored for that
-# language. For instance, namespaces will be presented as modules, types will be
-# separated into more groups, etc.
-# The default value is: NO.
-
-OPTIMIZE_OUTPUT_SLICE = NO
-
-# Doxygen selects the parser to use depending on the extension of the files it
-# parses. With this tag you can assign which parser to use for a given
-# extension. Doxygen has a built-in mapping, but you can override or extend it
-# using this tag. The format is ext=language, where ext is a file extension, and
-# language is one of the parsers supported by doxygen: IDL, Java, Javascript,
-# Csharp (C#), C, C++, D, PHP, md (Markdown), Objective-C, Python, Slice,
-# Fortran (fixed format Fortran: FortranFixed, free formatted Fortran:
-# FortranFree, unknown formatted Fortran: Fortran. In the later case the parser
-# tries to guess whether the code is fixed or free formatted code, this is the
-# default for Fortran type files), VHDL, tcl. For instance to make doxygen treat
-# .inc files as Fortran files (default is PHP), and .f files as C (default is
-# Fortran), use: inc=Fortran f=C.
-#
-# Note: For files without extension you can use no_extension as a placeholder.
-#
-# Note that for custom extensions you also need to set FILE_PATTERNS otherwise
-# the files are not read by doxygen.
-
-EXTENSION_MAPPING =
-
-# If the MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all comments
-# according to the Markdown format, which allows for more readable
-# documentation. See https://daringfireball.net/projects/markdown/ for details.
-# The output of markdown processing is further processed by doxygen, so you can
-# mix doxygen, HTML, and XML commands with Markdown formatting. Disable only in
-# case of backward compatibilities issues.
-# The default value is: YES.
-
-MARKDOWN_SUPPORT = YES
-
-# When the TOC_INCLUDE_HEADINGS tag is set to a non-zero value, all headings up
-# to that level are automatically included in the table of contents, even if
-# they do not have an id attribute.
-# Note: This feature currently applies only to Markdown headings.
-# Minimum value: 0, maximum value: 99, default value: 0.
-# This tag requires that the tag MARKDOWN_SUPPORT is set to YES.
-
-TOC_INCLUDE_HEADINGS = 4
-
-# When enabled doxygen tries to link words that correspond to documented
-# classes, or namespaces to their corresponding documentation. Such a link can
-# be prevented in individual cases by putting a % sign in front of the word or
-# globally by setting AUTOLINK_SUPPORT to NO.
-# The default value is: YES.
-
-AUTOLINK_SUPPORT = YES
-
-# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want
-# to include (a tag file for) the STL sources as input, then you should set this
-# tag to YES in order to let doxygen match functions declarations and
-# definitions whose arguments contain STL classes (e.g. func(std::string);
-# versus func(std::string) {}). This also make the inheritance and collaboration
-# diagrams that involve STL classes more complete and accurate.
-# The default value is: NO.
-
-BUILTIN_STL_SUPPORT = NO
-
-# If you use Microsoft's C++/CLI language, you should set this option to YES to
-# enable parsing support.
-# The default value is: NO.
-
-CPP_CLI_SUPPORT = NO
-
-# Set the SIP_SUPPORT tag to YES if your project consists of sip (see:
-# https://www.riverbankcomputing.com/software/sip/intro) sources only. Doxygen
-# will parse them like normal C++ but will assume all classes use public instead
-# of private inheritance when no explicit protection keyword is present.
-# The default value is: NO.
-
-SIP_SUPPORT = NO
-
-# For Microsoft's IDL there are propget and propput attributes to indicate
-# getter and setter methods for a property. Setting this option to YES will make
-# doxygen to replace the get and set methods by a property in the documentation.
-# This will only work if the methods are indeed getting or setting a simple
-# type. If this is not the case, or you want to show the methods anyway, you
-# should set this option to NO.
-# The default value is: YES.
-
-IDL_PROPERTY_SUPPORT = YES
-
-# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC
-# tag is set to YES then doxygen will reuse the documentation of the first
-# member in the group (if any) for the other members of the group. By default
-# all members of a group must be documented explicitly.
-# The default value is: NO.
-
-DISTRIBUTE_GROUP_DOC = NO
-
-# If one adds a struct or class to a group and this option is enabled, then also
-# any nested class or struct is added to the same group. By default this option
-# is disabled and one has to add nested compounds explicitly via \ingroup.
-# The default value is: NO.
-
-GROUP_NESTED_COMPOUNDS = YES
-
-# Set the SUBGROUPING tag to YES to allow class member groups of the same type
-# (for instance a group of public functions) to be put as a subgroup of that
-# type (e.g. under the Public Functions section). Set it to NO to prevent
-# subgrouping. Alternatively, this can be done per class using the
-# \nosubgrouping command.
-# The default value is: YES.
-
-SUBGROUPING = YES
-
-# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and unions
-# are shown inside the group in which they are included (e.g. using \ingroup)
-# instead of on a separate page (for HTML and Man pages) or section (for LaTeX
-# and RTF).
-#
-# Note that this feature does not work in combination with
-# SEPARATE_MEMBER_PAGES.
-# The default value is: NO.
-
-INLINE_GROUPED_CLASSES = NO
-
-# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and unions
-# with only public data fields or simple typedef fields will be shown inline in
-# the documentation of the scope in which they are defined (i.e. file,
-# namespace, or group documentation), provided this scope is documented. If set
-# to NO, structs, classes, and unions are shown on a separate page (for HTML and
-# Man pages) or section (for LaTeX and RTF).
-# The default value is: NO.
-
-INLINE_SIMPLE_STRUCTS = YES
-
-# When TYPEDEF_HIDES_STRUCT tag is enabled, a typedef of a struct, union, or
-# enum is documented as struct, union, or enum with the name of the typedef. So
-# typedef struct TypeS {} TypeT, will appear in the documentation as a struct
-# with name TypeT. When disabled the typedef will appear as a member of a file,
-# namespace, or class. And the struct will be named TypeS. This can typically be
-# useful for C code in case the coding convention dictates that all compound
-# types are typedef'ed and only the typedef is referenced, never the tag name.
-# The default value is: NO.
-
-TYPEDEF_HIDES_STRUCT = NO
-
-# The size of the symbol lookup cache can be set using LOOKUP_CACHE_SIZE. This
-# cache is used to resolve symbols given their name and scope. Since this can be
-# an expensive process and often the same symbol appears multiple times in the
-# code, doxygen keeps a cache of pre-resolved symbols. If the cache is too small
-# doxygen will become slower. If the cache is too large, memory is wasted. The
-# cache size is given by this formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range
-# is 0..9, the default is 0, corresponding to a cache size of 2^16=65536
-# symbols. At the end of a run doxygen will report the cache usage and suggest
-# the optimal cache size from a speed point of view.
-# Minimum value: 0, maximum value: 9, default value: 0.
-
-LOOKUP_CACHE_SIZE = 0
-
-#---------------------------------------------------------------------------
-# Build related configuration options
-#---------------------------------------------------------------------------
-
-# If the EXTRACT_ALL tag is set to YES, doxygen will assume all entities in
-# documentation are documented, even if no documentation was available. Private
-# class members and static file members will be hidden unless the
-# EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES.
-# Note: This will also disable the warnings about undocumented members that are
-# normally produced when WARNINGS is set to YES.
-# The default value is: NO.
-
-EXTRACT_ALL = NO
-
-# If the EXTRACT_PRIVATE tag is set to YES, all private members of a class will
-# be included in the documentation.
-# The default value is: NO.
-
-EXTRACT_PRIVATE = NO
-
-# If the EXTRACT_PACKAGE tag is set to YES, all members with package or internal
-# scope will be included in the documentation.
-# The default value is: NO.
-
-EXTRACT_PACKAGE = NO
-
-# If the EXTRACT_STATIC tag is set to YES, all static members of a file will be
-# included in the documentation.
-# The default value is: NO.
-
-EXTRACT_STATIC = NO
-
-# If the EXTRACT_LOCAL_CLASSES tag is set to YES, classes (and structs) defined
-# locally in source files will be included in the documentation. If set to NO,
-# only classes defined in header files are included. Does not have any effect
-# for Java sources.
-# The default value is: YES.
-
-EXTRACT_LOCAL_CLASSES = NO
-
-# This flag is only useful for Objective-C code. If set to YES, local methods,
-# which are defined in the implementation section but not in the interface are
-# included in the documentation. If set to NO, only methods in the interface are
-# included.
-# The default value is: NO.
-
-EXTRACT_LOCAL_METHODS = NO
-
-# If this flag is set to YES, the members of anonymous namespaces will be
-# extracted and appear in the documentation as a namespace called
-# 'anonymous_namespace{file}', where file will be replaced with the base name of
-# the file that contains the anonymous namespace. By default anonymous namespace
-# are hidden.
-# The default value is: NO.
-
-EXTRACT_ANON_NSPACES = NO
-
-# If the HIDE_UNDOC_MEMBERS tag is set to YES, doxygen will hide all
-# undocumented members inside documented classes or files. If set to NO these
-# members will be included in the various overviews, but no documentation
-# section is generated. This option has no effect if EXTRACT_ALL is enabled.
-# The default value is: NO.
-
-HIDE_UNDOC_MEMBERS = NO
-
-# If the HIDE_UNDOC_CLASSES tag is set to YES, doxygen will hide all
-# undocumented classes that are normally visible in the class hierarchy. If set
-# to NO, these classes will be included in the various overviews. This option
-# has no effect if EXTRACT_ALL is enabled.
-# The default value is: NO.
-
-HIDE_UNDOC_CLASSES = NO
-
-# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, doxygen will hide all friend
-# (class|struct|union) declarations. If set to NO, these declarations will be
-# included in the documentation.
-# The default value is: NO.
-
-HIDE_FRIEND_COMPOUNDS = NO
-
-# If the HIDE_IN_BODY_DOCS tag is set to YES, doxygen will hide any
-# documentation blocks found inside the body of a function. If set to NO, these
-# blocks will be appended to the function's detailed documentation block.
-# The default value is: NO.
-
-HIDE_IN_BODY_DOCS = NO
-
-# The INTERNAL_DOCS tag determines if documentation that is typed after a
-# \internal command is included. If the tag is set to NO then the documentation
-# will be excluded. Set it to YES to include the internal documentation.
-# The default value is: NO.
-
-INTERNAL_DOCS = NO
-
-# If the CASE_SENSE_NAMES tag is set to NO then doxygen will only generate file
-# names in lower-case letters. If set to YES, upper-case letters are also
-# allowed. This is useful if you have classes or files whose names only differ
-# in case and if your file system supports case sensitive file names. Windows
-# and Mac users are advised to set this option to NO.
-# The default value is: system dependent.
-
-CASE_SENSE_NAMES = NO
-
-# If the HIDE_SCOPE_NAMES tag is set to NO then doxygen will show members with
-# their full class and namespace scopes in the documentation. If set to YES, the
-# scope will be hidden.
-# The default value is: NO.
-
-HIDE_SCOPE_NAMES = NO
-
-# If the HIDE_COMPOUND_REFERENCE tag is set to NO (default) then doxygen will
-# append additional text to a page's title, such as Class Reference. If set to
-# YES the compound reference will be hidden.
-# The default value is: NO.
-
-HIDE_COMPOUND_REFERENCE= NO
-
-# If the SHOW_INCLUDE_FILES tag is set to YES then doxygen will put a list of
-# the files that are included by a file in the documentation of that file.
-# The default value is: YES.
-
-SHOW_INCLUDE_FILES = YES
-
-# If the SHOW_GROUPED_MEMB_INC tag is set to YES then Doxygen will add for each
-# grouped member an include statement to the documentation, telling the reader
-# which file to include in order to use the member.
-# The default value is: NO.
-
-SHOW_GROUPED_MEMB_INC = YES
-
-# If the FORCE_LOCAL_INCLUDES tag is set to YES then doxygen will list include
-# files with double quotes in the documentation rather than with sharp brackets.
-# The default value is: NO.
-
-FORCE_LOCAL_INCLUDES = NO
-
-# If the INLINE_INFO tag is set to YES then a tag [inline] is inserted in the
-# documentation for inline members.
-# The default value is: YES.
-
-INLINE_INFO = YES
-
-# If the SORT_MEMBER_DOCS tag is set to YES then doxygen will sort the
-# (detailed) documentation of file and class members alphabetically by member
-# name. If set to NO, the members will appear in declaration order.
-# The default value is: YES.
-
-SORT_MEMBER_DOCS = NO
-
-# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the brief
-# descriptions of file, namespace and class members alphabetically by member
-# name. If set to NO, the members will appear in declaration order. Note that
-# this will also influence the order of the classes in the class list.
-# The default value is: NO.
-
-SORT_BRIEF_DOCS = NO
-
-# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen will sort the
-# (brief and detailed) documentation of class members so that constructors and
-# destructors are listed first. If set to NO the constructors will appear in the
-# respective orders defined by SORT_BRIEF_DOCS and SORT_MEMBER_DOCS.
-# Note: If SORT_BRIEF_DOCS is set to NO this option is ignored for sorting brief
-# member documentation.
-# Note: If SORT_MEMBER_DOCS is set to NO this option is ignored for sorting
-# detailed member documentation.
-# The default value is: NO.
-
-SORT_MEMBERS_CTORS_1ST = NO
-
-# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the hierarchy
-# of group names into alphabetical order. If set to NO the group names will
-# appear in their defined order.
-# The default value is: NO.
-
-SORT_GROUP_NAMES = NO
-
-# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be sorted by
-# fully-qualified names, including namespaces. If set to NO, the class list will
-# be sorted only by class name, not including the namespace part.
-# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES.
-# Note: This option applies only to the class list, not to the alphabetical
-# list.
-# The default value is: NO.
-
-SORT_BY_SCOPE_NAME = NO
-
-# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to do proper
-# type resolution of all parameters of a function it will reject a match between
-# the prototype and the implementation of a member function even if there is
-# only one candidate or it is obvious which candidate to choose by doing a
-# simple string match. By disabling STRICT_PROTO_MATCHING doxygen will still
-# accept a match between prototype and implementation in such cases.
-# The default value is: NO.
-
-STRICT_PROTO_MATCHING = NO
-
-# The GENERATE_TODOLIST tag can be used to enable (YES) or disable (NO) the todo
-# list. This list is created by putting \todo commands in the documentation.
-# The default value is: YES.
-
-GENERATE_TODOLIST = YES
-
-# The GENERATE_TESTLIST tag can be used to enable (YES) or disable (NO) the test
-# list. This list is created by putting \test commands in the documentation.
-# The default value is: YES.
-
-GENERATE_TESTLIST = YES
-
-# The GENERATE_BUGLIST tag can be used to enable (YES) or disable (NO) the bug
-# list. This list is created by putting \bug commands in the documentation.
-# The default value is: YES.
-
-GENERATE_BUGLIST = YES
-
-# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or disable (NO)
-# the deprecated list. This list is created by putting \deprecated commands in
-# the documentation.
-# The default value is: YES.
-
-GENERATE_DEPRECATEDLIST= YES
-
-# The ENABLED_SECTIONS tag can be used to enable conditional documentation
-# sections, marked by \if <section_label> ... \endif and \cond <section_label>
-# ... \endcond blocks.
-
-ENABLED_SECTIONS =
-
-# The MAX_INITIALIZER_LINES tag determines the maximum number of lines that the
-# initial value of a variable or macro / define can have for it to appear in the
-# documentation. If the initializer consists of more lines than specified here
-# it will be hidden. Use a value of 0 to hide initializers completely. The
-# appearance of the value of individual variables and macros / defines can be
-# controlled using \showinitializer or \hideinitializer command in the
-# documentation regardless of this setting.
-# Minimum value: 0, maximum value: 10000, default value: 30.
-
-MAX_INITIALIZER_LINES = 30
-
-# Set the SHOW_USED_FILES tag to NO to disable the list of files generated at
-# the bottom of the documentation of classes and structs. If set to YES, the
-# list will mention the files that were used to generate the documentation.
-# The default value is: YES.
-
-SHOW_USED_FILES = YES
-
-# Set the SHOW_FILES tag to NO to disable the generation of the Files page. This
-# will remove the Files entry from the Quick Index and from the Folder Tree View
-# (if specified).
-# The default value is: YES.
-
-SHOW_FILES = YES
-
-# Set the SHOW_NAMESPACES tag to NO to disable the generation of the Namespaces
-# page. This will remove the Namespaces entry from the Quick Index and from the
-# Folder Tree View (if specified).
-# The default value is: YES.
-
-SHOW_NAMESPACES = YES
-
-# The FILE_VERSION_FILTER tag can be used to specify a program or script that
-# doxygen should invoke to get the current version for each file (typically from
-# the version control system). Doxygen will invoke the program by executing (via
-# popen()) the command command input-file, where command is the value of the
-# FILE_VERSION_FILTER tag, and input-file is the name of an input file provided
-# by doxygen. Whatever the program writes to standard output is used as the file
-# version. For an example see the documentation.
-
-FILE_VERSION_FILTER =
-
-# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed
-# by doxygen. The layout file controls the global structure of the generated
-# output files in an output format independent way. To create the layout file
-# that represents doxygen's defaults, run doxygen with the -l option. You can
-# optionally specify a file name after the option, if omitted DoxygenLayout.xml
-# will be used as the name of the layout file.
-#
-# Note that if you run doxygen from a directory containing a file called
-# DoxygenLayout.xml, doxygen will parse it automatically even if the LAYOUT_FILE
-# tag is left empty.
-
-LAYOUT_FILE =
-
-# The CITE_BIB_FILES tag can be used to specify one or more bib files containing
-# the reference definitions. This must be a list of .bib files. The .bib
-# extension is automatically appended if omitted. This requires the bibtex tool
-# to be installed. See also https://en.wikipedia.org/wiki/BibTeX for more info.
-# For LaTeX the style of the bibliography can be controlled using
-# LATEX_BIB_STYLE. To use this feature you need bibtex and perl available in the
-# search path. See also \cite for info how to create references.
-
-CITE_BIB_FILES =
-
-#---------------------------------------------------------------------------
-# Configuration options related to warning and progress messages
-#---------------------------------------------------------------------------
-
-# The QUIET tag can be used to turn on/off the messages that are generated to
-# standard output by doxygen. If QUIET is set to YES this implies that the
-# messages are off.
-# The default value is: NO.
-
-QUIET = NO
-
-# The WARNINGS tag can be used to turn on/off the warning messages that are
-# generated to standard error (stderr) by doxygen. If WARNINGS is set to YES
-# this implies that the warnings are on.
-#
-# Tip: Turn warnings on while writing the documentation.
-# The default value is: YES.
-
-WARNINGS = YES
-
-# If the WARN_IF_UNDOCUMENTED tag is set to YES then doxygen will generate
-# warnings for undocumented members. If EXTRACT_ALL is set to YES then this flag
-# will automatically be disabled.
-# The default value is: YES.
-
-WARN_IF_UNDOCUMENTED = YES
-
-# If the WARN_IF_DOC_ERROR tag is set to YES, doxygen will generate warnings for
-# potential errors in the documentation, such as not documenting some parameters
-# in a documented function, or documenting parameters that don't exist or using
-# markup commands wrongly.
-# The default value is: YES.
-
-WARN_IF_DOC_ERROR = YES
-
-# This WARN_NO_PARAMDOC option can be enabled to get warnings for functions that
-# are documented, but have no documentation for their parameters or return
-# value. If set to NO, doxygen will only warn about wrong or incomplete
-# parameter documentation, but not about the absence of documentation. If
-# EXTRACT_ALL is set to YES then this flag will automatically be disabled.
-# The default value is: NO.
-
-WARN_NO_PARAMDOC = NO
-
-# If the WARN_AS_ERROR tag is set to YES then doxygen will immediately stop when
-# a warning is encountered.
-# The default value is: NO.
-
-WARN_AS_ERROR = NO
-
-# The WARN_FORMAT tag determines the format of the warning messages that doxygen
-# can produce. The string should contain the $file, $line, and $text tags, which
-# will be replaced by the file and line number from which the warning originated
-# and the warning text. Optionally the format may contain $version, which will
-# be replaced by the version of the file (if it could be obtained via
-# FILE_VERSION_FILTER)
-# The default value is: $file:$line: $text.
-
-WARN_FORMAT = "$file:$line: $text"
-
-# The WARN_LOGFILE tag can be used to specify a file to which warning and error
-# messages should be written. If left blank the output is written to standard
-# error (stderr).
-
-WARN_LOGFILE =
-
-#---------------------------------------------------------------------------
-# Configuration options related to the input files
-#---------------------------------------------------------------------------
-
-# The INPUT tag is used to specify the files and/or directories that contain
-# documented source files. You may enter file names like myfile.cpp or
-# directories like /usr/src/myproject. Separate the files or directories with
-# spaces. See also FILE_PATTERNS and EXTENSION_MAPPING
-# Note: If this tag is empty the current directory is searched.
-
-INPUT = @_INPUT@
-
-# This tag can be used to specify the character encoding of the source files
-# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses
-# libiconv (or the iconv built into libc) for the transcoding. See the libiconv
-# documentation (see: https://www.gnu.org/software/libiconv/) for the list of
-# possible encodings.
-# The default value is: UTF-8.
-
-INPUT_ENCODING = UTF-8
-
-# If the value of the INPUT tag contains directories, you can use the
-# FILE_PATTERNS tag to specify one or more wildcard patterns (like *.cpp and
-# *.h) to filter out the source-files in the directories.
-#
-# Note that for custom extensions or not directly supported extensions you also
-# need to set EXTENSION_MAPPING for the extension otherwise the files are not
-# read by doxygen.
-#
-# If left blank the following patterns are tested:*.c, *.cc, *.cxx, *.cpp,
-# *.c++, *.java, *.ii, *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h,
-# *.hh, *.hxx, *.hpp, *.h++, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, *.inc,
-# *.m, *.markdown, *.md, *.mm, *.dox, *.py, *.pyw, *.f90, *.f95, *.f03, *.f08,
-# *.f, *.for, *.tcl, *.vhd, *.vhdl, *.ucf, *.qsf and *.ice.
-
-FILE_PATTERNS = *.c \
- *.cc \
- *.cxx \
- *.cpp \
- *.c++ \
- *.java \
- *.ii \
- *.ixx \
- *.ipp \
- *.i++ \
- *.inl \
- *.idl \
- *.ddl \
- *.odl \
- *.h \
- *.hh \
- *.hxx \
- *.hpp \
- *.h++ \
- *.cs \
- *.d \
- *.php \
- *.php4 \
- *.php5 \
- *.phtml \
- *.inc \
- *.m \
- *.markdown \
- *.md \
- *.mm \
- *.dox \
- *.py \
- *.pyw \
- *.f90 \
- *.f95 \
- *.f03 \
- *.f08 \
- *.f \
- *.for \
- *.tcl \
- *.vhd \
- *.vhdl \
- *.ucf \
- *.qsf \
- *.ice \
- @_FILE_PATTERNS@
-
-# The RECURSIVE tag can be used to specify whether or not subdirectories should
-# be searched for input files as well.
-# The default value is: NO.
-
-RECURSIVE = YES
-
-# The EXCLUDE tag can be used to specify files and/or directories that should be
-# excluded from the INPUT source files. This way you can easily exclude a
-# subdirectory from a directory tree whose root is specified with the INPUT tag.
-#
-# Note that relative paths are relative to the directory from which doxygen is
-# run.
-
-EXCLUDE = @_EXCLUDE@
-
-# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or
-# directories that are symbolic links (a Unix file system feature) are excluded
-# from the input.
-# The default value is: NO.
-
-EXCLUDE_SYMLINKS = NO
-
-# If the value of the INPUT tag contains directories, you can use the
-# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude
-# certain files from those directories.
-#
-# Note that the wildcards are matched against the file with absolute path, so to
-# exclude all test directories for example use the pattern */test/*
-
-EXCLUDE_PATTERNS = @_EXCLUDE_PATTERNS@
-
-# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names
-# (namespaces, classes, functions, etc.) that should be excluded from the
-# output. The symbol name can be a fully qualified name, a word, or if the
-# wildcard * is used, a substring. Examples: ANamespace, AClass,
-# AClass::ANamespace, ANamespace::*Test
-#
-# Note that the wildcards are matched against the file with absolute path, so to
-# exclude all test directories use the pattern */test/*
-
-EXCLUDE_SYMBOLS = @_EXCLUDE_SYMBOLS@
-
-# The EXAMPLE_PATH tag can be used to specify one or more files or directories
-# that contain example code fragments that are included (see the \include
-# command).
-
-EXAMPLE_PATH = @_EXAMPLE_PATH@
-
-# If the value of the EXAMPLE_PATH tag contains directories, you can use the
-# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and
-# *.h) to filter out the source-files in the directories. If left blank all
-# files are included.
-
-EXAMPLE_PATTERNS = *
-
-# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be
-# searched for input files to be used with the \include or \dontinclude commands
-# irrespective of the value of the RECURSIVE tag.
-# The default value is: NO.
-
-EXAMPLE_RECURSIVE = YES
-
-# The IMAGE_PATH tag can be used to specify one or more files or directories
-# that contain images that are to be included in the documentation (see the
-# \image command).
-
-IMAGE_PATH =
-
-# The INPUT_FILTER tag can be used to specify a program that doxygen should
-# invoke to filter for each input file. Doxygen will invoke the filter program
-# by executing (via popen()) the command:
-#
-# <filter> <input-file>
-#
-# where <filter> is the value of the INPUT_FILTER tag, and <input-file> is the
-# name of an input file. Doxygen will then use the output that the filter
-# program writes to standard output. If FILTER_PATTERNS is specified, this tag
-# will be ignored.
-#
-# Note that the filter must not add or remove lines; it is applied before the
-# code is scanned, but not when the output code is generated. If lines are added
-# or removed, the anchors will not be placed correctly.
-#
-# Note that for custom extensions or not directly supported extensions you also
-# need to set EXTENSION_MAPPING for the extension otherwise the files are not
-# properly processed by doxygen.
-
-INPUT_FILTER =
-
-# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern
-# basis. Doxygen will compare the file name with each pattern and apply the
-# filter if there is a match. The filters are a list of the form: pattern=filter
-# (like *.cpp=my_cpp_filter). See INPUT_FILTER for further information on how
-# filters are used. If the FILTER_PATTERNS tag is empty or if none of the
-# patterns match the file name, INPUT_FILTER is applied.
-#
-# Note that for custom extensions or not directly supported extensions you also
-# need to set EXTENSION_MAPPING for the extension otherwise the files are not
-# properly processed by doxygen.
-
-FILTER_PATTERNS =
-
-# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using
-# INPUT_FILTER) will also be used to filter the input files that are used for
-# producing the source files to browse (i.e. when SOURCE_BROWSER is set to YES).
-# The default value is: NO.
-
-FILTER_SOURCE_FILES = NO
-
-# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file
-# pattern. A pattern will override the setting for FILTER_PATTERN (if any) and
-# it is also possible to disable source filtering for a specific pattern using
-# *.ext= (so without naming a filter).
-# This tag requires that the tag FILTER_SOURCE_FILES is set to YES.
-
-FILTER_SOURCE_PATTERNS =
-
-# If the USE_MDFILE_AS_MAINPAGE tag refers to the name of a markdown file that
-# is part of the input, its contents will be placed on the main page
-# (index.html). This can be useful if you have a project on for instance GitHub
-# and want to reuse the introduction page also for the doxygen output.
-
-USE_MDFILE_AS_MAINPAGE =
-
-#---------------------------------------------------------------------------
-# Configuration options related to source browsing
-#---------------------------------------------------------------------------
-
-# If the SOURCE_BROWSER tag is set to YES then a list of source files will be
-# generated. Documented entities will be cross-referenced with these sources.
-#
-# Note: To get rid of all source code in the generated output, make sure that
-# also VERBATIM_HEADERS is set to NO.
-# The default value is: NO.
-
-SOURCE_BROWSER = YES
-
-# Setting the INLINE_SOURCES tag to YES will include the body of functions,
-# classes and enums directly into the documentation.
-# The default value is: NO.
-
-INLINE_SOURCES = NO
-
-# Setting the STRIP_CODE_COMMENTS tag to YES will instruct doxygen to hide any
-# special comment blocks from generated source code fragments. Normal C, C++ and
-# Fortran comments will always remain visible.
-# The default value is: YES.
-
-STRIP_CODE_COMMENTS = NO
-
-# If the REFERENCED_BY_RELATION tag is set to YES then for each documented
-# entity all documented functions referencing it will be listed.
-# The default value is: NO.
-
-REFERENCED_BY_RELATION = NO
-
-# If the REFERENCES_RELATION tag is set to YES then for each documented function
-# all documented entities called/used by that function will be listed.
-# The default value is: NO.
-
-REFERENCES_RELATION = NO
-
-# If the REFERENCES_LINK_SOURCE tag is set to YES and SOURCE_BROWSER tag is set
-# to YES then the hyperlinks from functions in REFERENCES_RELATION and
-# REFERENCED_BY_RELATION lists will link to the source code. Otherwise they will
-# link to the documentation.
-# The default value is: YES.
-
-REFERENCES_LINK_SOURCE = YES
-
-# If SOURCE_TOOLTIPS is enabled (the default) then hovering a hyperlink in the
-# source code will show a tooltip with additional information such as prototype,
-# brief description and links to the definition and documentation. Since this
-# will make the HTML file larger and loading of large files a bit slower, you
-# can opt to disable this feature.
-# The default value is: YES.
-# This tag requires that the tag SOURCE_BROWSER is set to YES.
-
-SOURCE_TOOLTIPS = YES
-
-# If the USE_HTAGS tag is set to YES then the references to source code will
-# point to the HTML generated by the htags(1) tool instead of doxygen built-in
-# source browser. The htags tool is part of GNU's global source tagging system
-# (see https://www.gnu.org/software/global/global.html). You will need version
-# 4.8.6 or higher.
-#
-# To use it do the following:
-# - Install the latest version of global
-# - Enable SOURCE_BROWSER and USE_HTAGS in the configuration file
-# - Make sure the INPUT points to the root of the source tree
-# - Run doxygen as normal
-#
-# Doxygen will invoke htags (and that will in turn invoke gtags), so these
-# tools must be available from the command line (i.e. in the search path).
-#
-# The result: instead of the source browser generated by doxygen, the links to
-# source code will now point to the output of htags.
-# The default value is: NO.
-# This tag requires that the tag SOURCE_BROWSER is set to YES.
-
-USE_HTAGS = NO
-
-# If the VERBATIM_HEADERS tag is set the YES then doxygen will generate a
-# verbatim copy of the header file for each class for which an include is
-# specified. Set to NO to disable this.
-# See also: Section \class.
-# The default value is: YES.
-
-VERBATIM_HEADERS = YES
-
-# If the CLANG_ASSISTED_PARSING tag is set to YES then doxygen will use the
-# clang parser (see: http://clang.llvm.org/) for more accurate parsing at the
-# cost of reduced performance. This can be particularly helpful with template
-# rich C++ code for which doxygen's built-in parser lacks the necessary type
-# information.
-# Note: The availability of this option depends on whether or not doxygen was
-# generated with the -Duse_libclang=ON option for CMake.
-# The default value is: NO.
-
-CLANG_ASSISTED_PARSING = YES
-
-# If clang assisted parsing is enabled you can provide the compiler with command
-# line options that you would normally use when invoking the compiler. Note that
-# the include paths will already be set by doxygen for the files and directories
-# specified with INPUT and INCLUDE_PATH.
-# This tag requires that the tag CLANG_ASSISTED_PARSING is set to YES.
-
-CLANG_OPTIONS =
-
-# If clang assisted parsing is enabled you can provide the clang parser with the
-# path to the compilation database (see:
-# http://clang.llvm.org/docs/HowToSetupToolingForLLVM.html) used when the files
-# were built. This is equivalent to specifying the "-p" option to a clang tool,
-# such as clang-check. These options will then be passed to the parser.
-# Note: The availability of this option depends on whether or not doxygen was
-# generated with the -Duse_libclang=ON option for CMake.
-
-CLANG_DATABASE_PATH = @_CLANG_DATABASE_PATH@
-
-#---------------------------------------------------------------------------
-# Configuration options related to the alphabetical class index
-#---------------------------------------------------------------------------
-
-# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index of all
-# compounds will be generated. Enable this if the project contains a lot of
-# classes, structs, unions or interfaces.
-# The default value is: YES.
-
-ALPHABETICAL_INDEX = YES
-
-# The COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns in
-# which the alphabetical index list will be split.
-# Minimum value: 1, maximum value: 20, default value: 5.
-# This tag requires that the tag ALPHABETICAL_INDEX is set to YES.
-
-COLS_IN_ALPHA_INDEX = 5
-
-# In case all classes in a project start with a common prefix, all classes will
-# be put under the same header in the alphabetical index. The IGNORE_PREFIX tag
-# can be used to specify a prefix (or a list of prefixes) that should be ignored
-# while generating the index headers.
-# This tag requires that the tag ALPHABETICAL_INDEX is set to YES.
-
-IGNORE_PREFIX =
-
-#---------------------------------------------------------------------------
-# Configuration options related to the HTML output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_HTML tag is set to YES, doxygen will generate HTML output
-# The default value is: YES.
-
-GENERATE_HTML = YES
-
-# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. If a
-# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
-# it.
-# The default directory is: html.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-HTML_OUTPUT = html
-
-# The HTML_FILE_EXTENSION tag can be used to specify the file extension for each
-# generated HTML page (for example: .htm, .php, .asp).
-# The default value is: .html.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-HTML_FILE_EXTENSION = .html
-
-# The HTML_HEADER tag can be used to specify a user-defined HTML header file for
-# each generated HTML page. If the tag is left blank doxygen will generate a
-# standard header.
-#
-# To get valid HTML the header file that includes any scripts and style sheets
-# that doxygen needs, which is dependent on the configuration options used (e.g.
-# the setting GENERATE_TREEVIEW). It is highly recommended to start with a
-# default header using
-# doxygen -w html new_header.html new_footer.html new_stylesheet.css
-# YourConfigFile
-# and then modify the file new_header.html. See also section "Doxygen usage"
-# for information on how to generate the default header that doxygen normally
-# uses.
-# Note: The header is subject to change so you typically have to regenerate the
-# default header when upgrading to a newer version of doxygen. For a description
-# of the possible markers and block names see the documentation.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-HTML_HEADER =
-
-# The HTML_FOOTER tag can be used to specify a user-defined HTML footer for each
-# generated HTML page. If the tag is left blank doxygen will generate a standard
-# footer. See HTML_HEADER for more information on how to generate a default
-# footer and what special commands can be used inside the footer. See also
-# section "Doxygen usage" for information on how to generate the default footer
-# that doxygen normally uses.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-HTML_FOOTER =
-
-# The HTML_STYLESHEET tag can be used to specify a user-defined cascading style
-# sheet that is used by each HTML page. It can be used to fine-tune the look of
-# the HTML output. If left blank doxygen will generate a default style sheet.
-# See also section "Doxygen usage" for information on how to generate the style
-# sheet that doxygen normally uses.
-# Note: It is recommended to use HTML_EXTRA_STYLESHEET instead of this tag, as
-# it is more robust and this tag (HTML_STYLESHEET) will in the future become
-# obsolete.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-HTML_STYLESHEET =
-
-# The HTML_EXTRA_STYLESHEET tag can be used to specify additional user-defined
-# cascading style sheets that are included after the standard style sheets
-# created by doxygen. Using this option one can overrule certain style aspects.
-# This is preferred over using HTML_STYLESHEET since it does not replace the
-# standard style sheet and is therefore more robust against future updates.
-# Doxygen will copy the style sheet files to the output directory.
-# Note: The order of the extra style sheet files is of importance (e.g. the last
-# style sheet in the list overrules the setting of the previous ones in the
-# list). For an example see the documentation.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-HTML_EXTRA_STYLESHEET =
-
-# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or
-# other source files which should be copied to the HTML output directory. Note
-# that these files will be copied to the base HTML output directory. Use the
-# $relpath^ marker in the HTML_HEADER and/or HTML_FOOTER files to load these
-# files. In the HTML_STYLESHEET file, use the file name only. Also note that the
-# files will be copied as-is; there are no commands or markers available.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-HTML_EXTRA_FILES =
-
-# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen
-# will adjust the colors in the style sheet and background images according to
-# this color. Hue is specified as an angle on a colorwheel, see
-# https://en.wikipedia.org/wiki/Hue for more information. For instance the value
-# 0 represents red, 60 is yellow, 120 is green, 180 is cyan, 240 is blue, 300
-# purple, and 360 is red again.
-# Minimum value: 0, maximum value: 359, default value: 220.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-HTML_COLORSTYLE_HUE = 220
-
-# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of the colors
-# in the HTML output. For a value of 0 the output will use grayscales only. A
-# value of 255 will produce the most vivid colors.
-# Minimum value: 0, maximum value: 255, default value: 100.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-HTML_COLORSTYLE_SAT = 100
-
-# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to the
-# luminance component of the colors in the HTML output. Values below 100
-# gradually make the output lighter, whereas values above 100 make the output
-# darker. The value divided by 100 is the actual gamma applied, so 80 represents
-# a gamma of 0.8, The value 220 represents a gamma of 2.2, and 100 does not
-# change the gamma.
-# Minimum value: 40, maximum value: 240, default value: 80.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-HTML_COLORSTYLE_GAMMA = 80
-
-# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML
-# page will contain the date and time when the page was generated. Setting this
-# to YES can help to show when doxygen was last run and thus if the
-# documentation is up to date.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-HTML_TIMESTAMP = NO
-
-# If the HTML_DYNAMIC_MENUS tag is set to YES then the generated HTML
-# documentation will contain a main index with vertical navigation menus that
-# are dynamically created via Javascript. If disabled, the navigation index will
-# consists of multiple levels of tabs that are statically embedded in every HTML
-# page. Disable this option to support browsers that do not have Javascript,
-# like the Qt help browser.
-# The default value is: YES.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-HTML_DYNAMIC_MENUS = YES
-
-# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML
-# documentation will contain sections that can be hidden and shown after the
-# page has loaded.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-HTML_DYNAMIC_SECTIONS = NO
-
-# With HTML_INDEX_NUM_ENTRIES one can control the preferred number of entries
-# shown in the various tree structured indices initially; the user can expand
-# and collapse entries dynamically later on. Doxygen will expand the tree to
-# such a level that at most the specified number of entries are visible (unless
-# a fully collapsed tree already exceeds this amount). So setting the number of
-# entries 1 will produce a full collapsed tree by default. 0 is a special value
-# representing an infinite number of entries and will result in a full expanded
-# tree by default.
-# Minimum value: 0, maximum value: 9999, default value: 100.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-HTML_INDEX_NUM_ENTRIES = 100
-
-# If the GENERATE_DOCSET tag is set to YES, additional index files will be
-# generated that can be used as input for Apple's Xcode 3 integrated development
-# environment (see: https://developer.apple.com/xcode/), introduced with OSX
-# 10.5 (Leopard). To create a documentation set, doxygen will generate a
-# Makefile in the HTML output directory. Running make will produce the docset in
-# that directory and running make install will install the docset in
-# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find it at
-# startup. See https://developer.apple.com/library/archive/featuredarticles/Doxy
-# genXcode/_index.html for more information.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-GENERATE_DOCSET = NO
-
-# This tag determines the name of the docset feed. A documentation feed provides
-# an umbrella under which multiple documentation sets from a single provider
-# (such as a company or product suite) can be grouped.
-# The default value is: Doxygen generated docs.
-# This tag requires that the tag GENERATE_DOCSET is set to YES.
-
-DOCSET_FEEDNAME = "Doxygen generated docs"
-
-# This tag specifies a string that should uniquely identify the documentation
-# set bundle. This should be a reverse domain-name style string, e.g.
-# com.mycompany.MyDocSet. Doxygen will append .docset to the name.
-# The default value is: org.doxygen.Project.
-# This tag requires that the tag GENERATE_DOCSET is set to YES.
-
-DOCSET_BUNDLE_ID = org.doxygen.Project
-
-# The DOCSET_PUBLISHER_ID tag specifies a string that should uniquely identify
-# the documentation publisher. This should be a reverse domain-name style
-# string, e.g. com.mycompany.MyDocSet.documentation.
-# The default value is: org.doxygen.Publisher.
-# This tag requires that the tag GENERATE_DOCSET is set to YES.
-
-DOCSET_PUBLISHER_ID = org.doxygen.Publisher
-
-# The DOCSET_PUBLISHER_NAME tag identifies the documentation publisher.
-# The default value is: Publisher.
-# This tag requires that the tag GENERATE_DOCSET is set to YES.
-
-DOCSET_PUBLISHER_NAME = Publisher
-
-# If the GENERATE_HTMLHELP tag is set to YES then doxygen generates three
-# additional HTML index files: index.hhp, index.hhc, and index.hhk. The
-# index.hhp is a project file that can be read by Microsoft's HTML Help Workshop
-# (see: https://www.microsoft.com/en-us/download/details.aspx?id=21138) on
-# Windows.
-#
-# The HTML Help Workshop contains a compiler that can convert all HTML output
-# generated by doxygen into a single compiled HTML file (.chm). Compiled HTML
-# files are now used as the Windows 98 help format, and will replace the old
-# Windows help format (.hlp) on all Windows platforms in the future. Compressed
-# HTML files also contain an index, a table of contents, and you can search for
-# words in the documentation. The HTML workshop also contains a viewer for
-# compressed HTML files.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-GENERATE_HTMLHELP = NO
-
-# The CHM_FILE tag can be used to specify the file name of the resulting .chm
-# file. You can add a path in front of the file if the result should not be
-# written to the html output directory.
-# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
-
-CHM_FILE =
-
-# The HHC_LOCATION tag can be used to specify the location (absolute path
-# including file name) of the HTML help compiler (hhc.exe). If non-empty,
-# doxygen will try to run the HTML help compiler on the generated index.hhp.
-# The file has to be specified with full path.
-# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
-
-HHC_LOCATION =
-
-# The GENERATE_CHI flag controls if a separate .chi index file is generated
-# (YES) or that it should be included in the master .chm file (NO).
-# The default value is: NO.
-# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
-
-GENERATE_CHI = NO
-
-# The CHM_INDEX_ENCODING is used to encode HtmlHelp index (hhk), content (hhc)
-# and project file content.
-# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
-
-CHM_INDEX_ENCODING =
-
-# The BINARY_TOC flag controls whether a binary table of contents is generated
-# (YES) or a normal table of contents (NO) in the .chm file. Furthermore it
-# enables the Previous and Next buttons.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
-
-BINARY_TOC = NO
-
-# The TOC_EXPAND flag can be set to YES to add extra items for group members to
-# the table of contents of the HTML help documentation and to the tree view.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
-
-TOC_EXPAND = NO
-
-# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and
-# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated that
-# can be used as input for Qt's qhelpgenerator to generate a Qt Compressed Help
-# (.qch) of the generated HTML documentation.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-GENERATE_QHP = NO
-
-# If the QHG_LOCATION tag is specified, the QCH_FILE tag can be used to specify
-# the file name of the resulting .qch file. The path specified is relative to
-# the HTML output folder.
-# This tag requires that the tag GENERATE_QHP is set to YES.
-
-QCH_FILE =
-
-# The QHP_NAMESPACE tag specifies the namespace to use when generating Qt Help
-# Project output. For more information please see Qt Help Project / Namespace
-# (see: http://doc.qt.io/archives/qt-4.8/qthelpproject.html#namespace).
-# The default value is: org.doxygen.Project.
-# This tag requires that the tag GENERATE_QHP is set to YES.
-
-QHP_NAMESPACE = org.doxygen.Project
-
-# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating Qt
-# Help Project output. For more information please see Qt Help Project / Virtual
-# Folders (see: http://doc.qt.io/archives/qt-4.8/qthelpproject.html#virtual-
-# folders).
-# The default value is: doc.
-# This tag requires that the tag GENERATE_QHP is set to YES.
-
-QHP_VIRTUAL_FOLDER = doc
-
-# If the QHP_CUST_FILTER_NAME tag is set, it specifies the name of a custom
-# filter to add. For more information please see Qt Help Project / Custom
-# Filters (see: http://doc.qt.io/archives/qt-4.8/qthelpproject.html#custom-
-# filters).
-# This tag requires that the tag GENERATE_QHP is set to YES.
-
-QHP_CUST_FILTER_NAME =
-
-# The QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the
-# custom filter to add. For more information please see Qt Help Project / Custom
-# Filters (see: http://doc.qt.io/archives/qt-4.8/qthelpproject.html#custom-
-# filters).
-# This tag requires that the tag GENERATE_QHP is set to YES.
-
-QHP_CUST_FILTER_ATTRS =
-
-# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this
-# project's filter section matches. Qt Help Project / Filter Attributes (see:
-# http://doc.qt.io/archives/qt-4.8/qthelpproject.html#filter-attributes).
-# This tag requires that the tag GENERATE_QHP is set to YES.
-
-QHP_SECT_FILTER_ATTRS =
-
-# The QHG_LOCATION tag can be used to specify the location of Qt's
-# qhelpgenerator. If non-empty doxygen will try to run qhelpgenerator on the
-# generated .qhp file.
-# This tag requires that the tag GENERATE_QHP is set to YES.
-
-QHG_LOCATION =
-
-# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files will be
-# generated, together with the HTML files, they form an Eclipse help plugin. To
-# install this plugin and make it available under the help contents menu in
-# Eclipse, the contents of the directory containing the HTML and XML files needs
-# to be copied into the plugins directory of eclipse. The name of the directory
-# within the plugins directory should be the same as the ECLIPSE_DOC_ID value.
-# After copying Eclipse needs to be restarted before the help appears.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-GENERATE_ECLIPSEHELP = NO
-
-# A unique identifier for the Eclipse help plugin. When installing the plugin
-# the directory name containing the HTML and XML files should also have this
-# name. Each documentation set should have its own identifier.
-# The default value is: org.doxygen.Project.
-# This tag requires that the tag GENERATE_ECLIPSEHELP is set to YES.
-
-ECLIPSE_DOC_ID = org.doxygen.Project
-
-# If you want full control over the layout of the generated HTML pages it might
-# be necessary to disable the index and replace it with your own. The
-# DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) at top
-# of each HTML page. A value of NO enables the index and the value YES disables
-# it. Since the tabs in the index contain the same information as the navigation
-# tree, you can set this option to YES if you also set GENERATE_TREEVIEW to YES.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-DISABLE_INDEX = NO
-
-# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index
-# structure should be generated to display hierarchical information. If the tag
-# value is set to YES, a side panel will be generated containing a tree-like
-# index structure (just like the one that is generated for HTML Help). For this
-# to work a browser that supports JavaScript, DHTML, CSS and frames is required
-# (i.e. any modern browser). Windows users are probably better off using the
-# HTML help feature. Via custom style sheets (see HTML_EXTRA_STYLESHEET) one can
-# further fine-tune the look of the index. As an example, the default style
-# sheet generated by doxygen has an example that shows how to put an image at
-# the root of the tree instead of the PROJECT_NAME. Since the tree basically has
-# the same information as the tab index, you could consider setting
-# DISABLE_INDEX to YES when enabling this option.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-GENERATE_TREEVIEW = NO
-
-# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values that
-# doxygen will group on one line in the generated HTML documentation.
-#
-# Note that a value of 0 will completely suppress the enum values from appearing
-# in the overview section.
-# Minimum value: 0, maximum value: 20, default value: 4.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-ENUM_VALUES_PER_LINE = 4
-
-# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be used
-# to set the initial width (in pixels) of the frame in which the tree is shown.
-# Minimum value: 0, maximum value: 1500, default value: 250.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-TREEVIEW_WIDTH = 250
-
-# If the EXT_LINKS_IN_WINDOW option is set to YES, doxygen will open links to
-# external symbols imported via tag files in a separate window.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-EXT_LINKS_IN_WINDOW = NO
-
-# Use this tag to change the font size of LaTeX formulas included as images in
-# the HTML documentation. When you change the font size after a successful
-# doxygen run you need to manually remove any form_*.png images from the HTML
-# output directory to force them to be regenerated.
-# Minimum value: 8, maximum value: 50, default value: 10.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-FORMULA_FONTSIZE = 10
-
-# Use the FORMULA_TRANSPARENT tag to determine whether or not the images
-# generated for formulas are transparent PNGs. Transparent PNGs are not
-# supported properly for IE 6.0, but are supported on all modern browsers.
-#
-# Note that when changing this option you need to delete any form_*.png files in
-# the HTML output directory before the changes have effect.
-# The default value is: YES.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-FORMULA_TRANSPARENT = YES
-
-# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see
-# https://www.mathjax.org) which uses client side Javascript for the rendering
-# instead of using pre-rendered bitmaps. Use this if you do not have LaTeX
-# installed or if you want to formulas look prettier in the HTML output. When
-# enabled you may also need to install MathJax separately and configure the path
-# to it using the MATHJAX_RELPATH option.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-USE_MATHJAX = NO
-
-# When MathJax is enabled you can set the default output format to be used for
-# the MathJax output. See the MathJax site (see:
-# http://docs.mathjax.org/en/latest/output.html) for more details.
-# Possible values are: HTML-CSS (which is slower, but has the best
-# compatibility), NativeMML (i.e. MathML) and SVG.
-# The default value is: HTML-CSS.
-# This tag requires that the tag USE_MATHJAX is set to YES.
-
-MATHJAX_FORMAT = HTML-CSS
-
-# When MathJax is enabled you need to specify the location relative to the HTML
-# output directory using the MATHJAX_RELPATH option. The destination directory
-# should contain the MathJax.js script. For instance, if the mathjax directory
-# is located at the same level as the HTML output directory, then
-# MATHJAX_RELPATH should be ../mathjax. The default value points to the MathJax
-# Content Delivery Network so you can quickly see the result without installing
-# MathJax. However, it is strongly recommended to install a local copy of
-# MathJax from https://www.mathjax.org before deployment.
-# The default value is: https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/.
-# This tag requires that the tag USE_MATHJAX is set to YES.
-
-MATHJAX_RELPATH = https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/
-
-# The MATHJAX_EXTENSIONS tag can be used to specify one or more MathJax
-# extension names that should be enabled during MathJax rendering. For example
-# MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols
-# This tag requires that the tag USE_MATHJAX is set to YES.
-
-MATHJAX_EXTENSIONS =
-
-# The MATHJAX_CODEFILE tag can be used to specify a file with javascript pieces
-# of code that will be used on startup of the MathJax code. See the MathJax site
-# (see: http://docs.mathjax.org/en/latest/output.html) for more details. For an
-# example see the documentation.
-# This tag requires that the tag USE_MATHJAX is set to YES.
-
-MATHJAX_CODEFILE =
-
-# When the SEARCHENGINE tag is enabled doxygen will generate a search box for
-# the HTML output. The underlying search engine uses javascript and DHTML and
-# should work on any modern browser. Note that when using HTML help
-# (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets (GENERATE_DOCSET)
-# there is already a search function so this one should typically be disabled.
-# For large projects the javascript based search engine can be slow, then
-# enabling SERVER_BASED_SEARCH may provide a better solution. It is possible to
-# search using the keyboard; to jump to the search box use <access key> + S
-# (what the <access key> is depends on the OS and browser, but it is typically
-# <CTRL>, <ALT>/<option>, or both). Inside the search box use the <cursor down
-# key> to jump into the search results window, the results can be navigated
-# using the <cursor keys>. Press <Enter> to select an item or <escape> to cancel
-# the search. The filter options can be selected when the cursor is inside the
-# search box by pressing <Shift>+<cursor down>. Also here use the <cursor keys>
-# to select a filter and <Enter> or <escape> to activate or cancel the filter
-# option.
-# The default value is: YES.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-SEARCHENGINE = YES
-
-# When the SERVER_BASED_SEARCH tag is enabled the search engine will be
-# implemented using a web server instead of a web client using Javascript. There
-# are two flavors of web server based searching depending on the EXTERNAL_SEARCH
-# setting. When disabled, doxygen will generate a PHP script for searching and
-# an index file used by the script. When EXTERNAL_SEARCH is enabled the indexing
-# and searching needs to be provided by external tools. See the section
-# "External Indexing and Searching" for details.
-# The default value is: NO.
-# This tag requires that the tag SEARCHENGINE is set to YES.
-
-SERVER_BASED_SEARCH = NO
-
-# When EXTERNAL_SEARCH tag is enabled doxygen will no longer generate the PHP
-# script for searching. Instead the search results are written to an XML file
-# which needs to be processed by an external indexer. Doxygen will invoke an
-# external search engine pointed to by the SEARCHENGINE_URL option to obtain the
-# search results.
-#
-# Doxygen ships with an example indexer (doxyindexer) and search engine
-# (doxysearch.cgi) which are based on the open source search engine library
-# Xapian (see: https://xapian.org/).
-#
-# See the section "External Indexing and Searching" for details.
-# The default value is: NO.
-# This tag requires that the tag SEARCHENGINE is set to YES.
-
-EXTERNAL_SEARCH = NO
-
-# The SEARCHENGINE_URL should point to a search engine hosted by a web server
-# which will return the search results when EXTERNAL_SEARCH is enabled.
-#
-# Doxygen ships with an example indexer (doxyindexer) and search engine
-# (doxysearch.cgi) which are based on the open source search engine library
-# Xapian (see: https://xapian.org/). See the section "External Indexing and
-# Searching" for details.
-# This tag requires that the tag SEARCHENGINE is set to YES.
-
-SEARCHENGINE_URL =
-
-# When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the unindexed
-# search data is written to a file for indexing by an external tool. With the
-# SEARCHDATA_FILE tag the name of this file can be specified.
-# The default file is: searchdata.xml.
-# This tag requires that the tag SEARCHENGINE is set to YES.
-
-SEARCHDATA_FILE = searchdata.xml
-
-# When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the
-# EXTERNAL_SEARCH_ID tag can be used as an identifier for the project. This is
-# useful in combination with EXTRA_SEARCH_MAPPINGS to search through multiple
-# projects and redirect the results back to the right project.
-# This tag requires that the tag SEARCHENGINE is set to YES.
-
-EXTERNAL_SEARCH_ID =
-
-# The EXTRA_SEARCH_MAPPINGS tag can be used to enable searching through doxygen
-# projects other than the one defined by this configuration file, but that are
-# all added to the same external search index. Each project needs to have a
-# unique id set via EXTERNAL_SEARCH_ID. The search mapping then maps the id of
-# to a relative location where the documentation can be found. The format is:
-# EXTRA_SEARCH_MAPPINGS = tagname1=loc1 tagname2=loc2 ...
-# This tag requires that the tag SEARCHENGINE is set to YES.
-
-EXTRA_SEARCH_MAPPINGS =
-
-#---------------------------------------------------------------------------
-# Configuration options related to the LaTeX output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_LATEX tag is set to YES, doxygen will generate LaTeX output.
-# The default value is: YES.
-
-GENERATE_LATEX = NO
-
-# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. If a
-# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
-# it.
-# The default directory is: latex.
-# This tag requires that the tag GENERATE_LATEX is set to YES.
-
-LATEX_OUTPUT = latex
-
-# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be
-# invoked.
-#
-# Note that when not enabling USE_PDFLATEX the default is latex when enabling
-# USE_PDFLATEX the default is pdflatex and when in the later case latex is
-# chosen this is overwritten by pdflatex. For specific output languages the
-# default can have been set differently, this depends on the implementation of
-# the output language.
-# This tag requires that the tag GENERATE_LATEX is set to YES.
-
-LATEX_CMD_NAME =
-
-# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to generate
-# index for LaTeX.
-# Note: This tag is used in the Makefile / make.bat.
-# See also: LATEX_MAKEINDEX_CMD for the part in the generated output file
-# (.tex).
-# The default file is: makeindex.
-# This tag requires that the tag GENERATE_LATEX is set to YES.
-
-MAKEINDEX_CMD_NAME = makeindex
-
-# The LATEX_MAKEINDEX_CMD tag can be used to specify the command name to
-# generate index for LaTeX.
-# Note: This tag is used in the generated output file (.tex).
-# See also: MAKEINDEX_CMD_NAME for the part in the Makefile / make.bat.
-# The default value is: \makeindex.
-# This tag requires that the tag GENERATE_LATEX is set to YES.
-
-LATEX_MAKEINDEX_CMD = \makeindex
-
-# If the COMPACT_LATEX tag is set to YES, doxygen generates more compact LaTeX
-# documents. This may be useful for small projects and may help to save some
-# trees in general.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_LATEX is set to YES.
-
-COMPACT_LATEX = NO
-
-# The PAPER_TYPE tag can be used to set the paper type that is used by the
-# printer.
-# Possible values are: a4 (210 x 297 mm), letter (8.5 x 11 inches), legal (8.5 x
-# 14 inches) and executive (7.25 x 10.5 inches).
-# The default value is: a4.
-# This tag requires that the tag GENERATE_LATEX is set to YES.
-
-PAPER_TYPE = a4
-
-# The EXTRA_PACKAGES tag can be used to specify one or more LaTeX package names
-# that should be included in the LaTeX output. The package can be specified just
-# by its name or with the correct syntax as to be used with the LaTeX
-# \usepackage command. To get the times font for instance you can specify :
-# EXTRA_PACKAGES=times or EXTRA_PACKAGES={times}
-# To use the option intlimits with the amsmath package you can specify:
-# EXTRA_PACKAGES=[intlimits]{amsmath}
-# If left blank no extra packages will be included.
-# This tag requires that the tag GENERATE_LATEX is set to YES.
-
-EXTRA_PACKAGES =
-
-# The LATEX_HEADER tag can be used to specify a personal LaTeX header for the
-# generated LaTeX document. The header should contain everything until the first
-# chapter. If it is left blank doxygen will generate a standard header. See
-# section "Doxygen usage" for information on how to let doxygen write the
-# default header to a separate file.
-#
-# Note: Only use a user-defined header if you know what you are doing! The
-# following commands have a special meaning inside the header: $title,
-# $datetime, $date, $doxygenversion, $projectname, $projectnumber,
-# $projectbrief, $projectlogo. Doxygen will replace $title with the empty
-# string, for the replacement values of the other commands the user is referred
-# to HTML_HEADER.
-# This tag requires that the tag GENERATE_LATEX is set to YES.
-
-LATEX_HEADER =
-
-# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for the
-# generated LaTeX document. The footer should contain everything after the last
-# chapter. If it is left blank doxygen will generate a standard footer. See
-# LATEX_HEADER for more information on how to generate a default footer and what
-# special commands can be used inside the footer.
-#
-# Note: Only use a user-defined footer if you know what you are doing!
-# This tag requires that the tag GENERATE_LATEX is set to YES.
-
-LATEX_FOOTER =
-
-# The LATEX_EXTRA_STYLESHEET tag can be used to specify additional user-defined
-# LaTeX style sheets that are included after the standard style sheets created
-# by doxygen. Using this option one can overrule certain style aspects. Doxygen
-# will copy the style sheet files to the output directory.
-# Note: The order of the extra style sheet files is of importance (e.g. the last
-# style sheet in the list overrules the setting of the previous ones in the
-# list).
-# This tag requires that the tag GENERATE_LATEX is set to YES.
-
-LATEX_EXTRA_STYLESHEET =
-
-# The LATEX_EXTRA_FILES tag can be used to specify one or more extra images or
-# other source files which should be copied to the LATEX_OUTPUT output
-# directory. Note that the files will be copied as-is; there are no commands or
-# markers available.
-# This tag requires that the tag GENERATE_LATEX is set to YES.
-
-LATEX_EXTRA_FILES =
-
-# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated is
-# prepared for conversion to PDF (using ps2pdf or pdflatex). The PDF file will
-# contain links (just like the HTML output) instead of page references. This
-# makes the output suitable for online browsing using a PDF viewer.
-# The default value is: YES.
-# This tag requires that the tag GENERATE_LATEX is set to YES.
-
-PDF_HYPERLINKS = YES
-
-# If the USE_PDFLATEX tag is set to YES, doxygen will use pdflatex to generate
-# the PDF file directly from the LaTeX files. Set this option to YES, to get a
-# higher quality PDF documentation.
-# The default value is: YES.
-# This tag requires that the tag GENERATE_LATEX is set to YES.
-
-USE_PDFLATEX = YES
-
-# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \batchmode
-# command to the generated LaTeX files. This will instruct LaTeX to keep running
-# if errors occur, instead of asking the user for help. This option is also used
-# when generating formulas in HTML.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_LATEX is set to YES.
-
-LATEX_BATCHMODE = NO
-
-# If the LATEX_HIDE_INDICES tag is set to YES then doxygen will not include the
-# index chapters (such as File Index, Compound Index, etc.) in the output.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_LATEX is set to YES.
-
-LATEX_HIDE_INDICES = NO
-
-# If the LATEX_SOURCE_CODE tag is set to YES then doxygen will include source
-# code with syntax highlighting in the LaTeX output.
-#
-# Note that which sources are shown also depends on other settings such as
-# SOURCE_BROWSER.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_LATEX is set to YES.
-
-LATEX_SOURCE_CODE = NO
-
-# The LATEX_BIB_STYLE tag can be used to specify the style to use for the
-# bibliography, e.g. plainnat, or ieeetr. See
-# https://en.wikipedia.org/wiki/BibTeX and \cite for more info.
-# The default value is: plain.
-# This tag requires that the tag GENERATE_LATEX is set to YES.
-
-LATEX_BIB_STYLE = plain
-
-# If the LATEX_TIMESTAMP tag is set to YES then the footer of each generated
-# page will contain the date and time when the page was generated. Setting this
-# to NO can help when comparing the output of multiple runs.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_LATEX is set to YES.
-
-LATEX_TIMESTAMP = NO
-
-# The LATEX_EMOJI_DIRECTORY tag is used to specify the (relative or absolute)
-# path from which the emoji images will be read. If a relative path is entered,
-# it will be relative to the LATEX_OUTPUT directory. If left blank the
-# LATEX_OUTPUT directory will be used.
-# This tag requires that the tag GENERATE_LATEX is set to YES.
-
-LATEX_EMOJI_DIRECTORY =
-
-#---------------------------------------------------------------------------
-# Configuration options related to the RTF output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_RTF tag is set to YES, doxygen will generate RTF output. The
-# RTF output is optimized for Word 97 and may not look too pretty with other RTF
-# readers/editors.
-# The default value is: NO.
-
-GENERATE_RTF = NO
-
-# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. If a
-# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
-# it.
-# The default directory is: rtf.
-# This tag requires that the tag GENERATE_RTF is set to YES.
-
-RTF_OUTPUT = rtf
-
-# If the COMPACT_RTF tag is set to YES, doxygen generates more compact RTF
-# documents. This may be useful for small projects and may help to save some
-# trees in general.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_RTF is set to YES.
-
-COMPACT_RTF = NO
-
-# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated will
-# contain hyperlink fields. The RTF file will contain links (just like the HTML
-# output) instead of page references. This makes the output suitable for online
-# browsing using Word or some other Word compatible readers that support those
-# fields.
-#
-# Note: WordPad (write) and others do not support links.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_RTF is set to YES.
-
-RTF_HYPERLINKS = NO
-
-# Load stylesheet definitions from file. Syntax is similar to doxygen's
-# configuration file, i.e. a series of assignments. You only have to provide
-# replacements, missing definitions are set to their default value.
-#
-# See also section "Doxygen usage" for information on how to generate the
-# default style sheet that doxygen normally uses.
-# This tag requires that the tag GENERATE_RTF is set to YES.
-
-RTF_STYLESHEET_FILE =
-
-# Set optional variables used in the generation of an RTF document. Syntax is
-# similar to doxygen's configuration file. A template extensions file can be
-# generated using doxygen -e rtf extensionFile.
-# This tag requires that the tag GENERATE_RTF is set to YES.
-
-RTF_EXTENSIONS_FILE =
-
-# If the RTF_SOURCE_CODE tag is set to YES then doxygen will include source code
-# with syntax highlighting in the RTF output.
-#
-# Note that which sources are shown also depends on other settings such as
-# SOURCE_BROWSER.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_RTF is set to YES.
-
-RTF_SOURCE_CODE = NO
-
-#---------------------------------------------------------------------------
-# Configuration options related to the man page output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_MAN tag is set to YES, doxygen will generate man pages for
-# classes and files.
-# The default value is: NO.
-
-GENERATE_MAN = NO
-
-# The MAN_OUTPUT tag is used to specify where the man pages will be put. If a
-# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
-# it. A directory man3 will be created inside the directory specified by
-# MAN_OUTPUT.
-# The default directory is: man.
-# This tag requires that the tag GENERATE_MAN is set to YES.
-
-MAN_OUTPUT = man
-
-# The MAN_EXTENSION tag determines the extension that is added to the generated
-# man pages. In case the manual section does not start with a number, the number
-# 3 is prepended. The dot (.) at the beginning of the MAN_EXTENSION tag is
-# optional.
-# The default value is: .3.
-# This tag requires that the tag GENERATE_MAN is set to YES.
-
-MAN_EXTENSION = .3
-
-# The MAN_SUBDIR tag determines the name of the directory created within
-# MAN_OUTPUT in which the man pages are placed. If defaults to man followed by
-# MAN_EXTENSION with the initial . removed.
-# This tag requires that the tag GENERATE_MAN is set to YES.
-
-MAN_SUBDIR =
-
-# If the MAN_LINKS tag is set to YES and doxygen generates man output, then it
-# will generate one additional man file for each entity documented in the real
-# man page(s). These additional files only source the real man page, but without
-# them the man command would be unable to find the correct page.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_MAN is set to YES.
-
-MAN_LINKS = NO
-
-#---------------------------------------------------------------------------
-# Configuration options related to the XML output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_XML tag is set to YES, doxygen will generate an XML file that
-# captures the structure of the code including all documentation.
-# The default value is: NO.
-
-GENERATE_XML = YES
-
-# The XML_OUTPUT tag is used to specify where the XML pages will be put. If a
-# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
-# it.
-# The default directory is: xml.
-# This tag requires that the tag GENERATE_XML is set to YES.
-
-XML_OUTPUT = xml
-
-# If the XML_PROGRAMLISTING tag is set to YES, doxygen will dump the program
-# listings (including syntax highlighting and cross-referencing information) to
-# the XML output. Note that enabling this will significantly increase the size
-# of the XML output.
-# The default value is: YES.
-# This tag requires that the tag GENERATE_XML is set to YES.
-
-XML_PROGRAMLISTING = YES
-
-# If the XML_NS_MEMB_FILE_SCOPE tag is set to YES, doxygen will include
-# namespace members in file scope as well, matching the HTML output.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_XML is set to YES.
-
-XML_NS_MEMB_FILE_SCOPE = NO
-
-#---------------------------------------------------------------------------
-# Configuration options related to the DOCBOOK output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_DOCBOOK tag is set to YES, doxygen will generate Docbook files
-# that can be used to generate PDF.
-# The default value is: NO.
-
-GENERATE_DOCBOOK = NO
-
-# The DOCBOOK_OUTPUT tag is used to specify where the Docbook pages will be put.
-# If a relative path is entered the value of OUTPUT_DIRECTORY will be put in
-# front of it.
-# The default directory is: docbook.
-# This tag requires that the tag GENERATE_DOCBOOK is set to YES.
-
-DOCBOOK_OUTPUT = docbook
-
-# If the DOCBOOK_PROGRAMLISTING tag is set to YES, doxygen will include the
-# program listings (including syntax highlighting and cross-referencing
-# information) to the DOCBOOK output. Note that enabling this will significantly
-# increase the size of the DOCBOOK output.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_DOCBOOK is set to YES.
-
-DOCBOOK_PROGRAMLISTING = NO
-
-#---------------------------------------------------------------------------
-# Configuration options for the AutoGen Definitions output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_AUTOGEN_DEF tag is set to YES, doxygen will generate an
-# AutoGen Definitions (see http://autogen.sourceforge.net/) file that captures
-# the structure of the code including all documentation. Note that this feature
-# is still experimental and incomplete at the moment.
-# The default value is: NO.
-
-GENERATE_AUTOGEN_DEF = NO
-
-#---------------------------------------------------------------------------
-# Configuration options related to the Perl module output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_PERLMOD tag is set to YES, doxygen will generate a Perl module
-# file that captures the structure of the code including all documentation.
-#
-# Note that this feature is still experimental and incomplete at the moment.
-# The default value is: NO.
-
-GENERATE_PERLMOD = NO
-
-# If the PERLMOD_LATEX tag is set to YES, doxygen will generate the necessary
-# Makefile rules, Perl scripts and LaTeX code to be able to generate PDF and DVI
-# output from the Perl module output.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_PERLMOD is set to YES.
-
-PERLMOD_LATEX = NO
-
-# If the PERLMOD_PRETTY tag is set to YES, the Perl module output will be nicely
-# formatted so it can be parsed by a human reader. This is useful if you want to
-# understand what is going on. On the other hand, if this tag is set to NO, the
-# size of the Perl module output will be much smaller and Perl will parse it
-# just the same.
-# The default value is: YES.
-# This tag requires that the tag GENERATE_PERLMOD is set to YES.
-
-PERLMOD_PRETTY = YES
-
-# The names of the make variables in the generated doxyrules.make file are
-# prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. This is useful
-# so different doxyrules.make files included by the same Makefile don't
-# overwrite each other's variables.
-# This tag requires that the tag GENERATE_PERLMOD is set to YES.
-
-PERLMOD_MAKEVAR_PREFIX =
-
-#---------------------------------------------------------------------------
-# Configuration options related to the preprocessor
-#---------------------------------------------------------------------------
-
-# If the ENABLE_PREPROCESSING tag is set to YES, doxygen will evaluate all
-# C-preprocessor directives found in the sources and include files.
-# The default value is: YES.
-
-ENABLE_PREPROCESSING = YES
-
-# If the MACRO_EXPANSION tag is set to YES, doxygen will expand all macro names
-# in the source code. If set to NO, only conditional compilation will be
-# performed. Macro expansion can be done in a controlled way by setting
-# EXPAND_ONLY_PREDEF to YES.
-# The default value is: NO.
-# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
-
-MACRO_EXPANSION = NO
-
-# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES then
-# the macro expansion is limited to the macros specified with the PREDEFINED and
-# EXPAND_AS_DEFINED tags.
-# The default value is: NO.
-# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
-
-EXPAND_ONLY_PREDEF = NO
-
-# If the SEARCH_INCLUDES tag is set to YES, the include files in the
-# INCLUDE_PATH will be searched if a #include is found.
-# The default value is: YES.
-# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
-
-SEARCH_INCLUDES = YES
-
-# The INCLUDE_PATH tag can be used to specify one or more directories that
-# contain include files that are not input files but should be processed by the
-# preprocessor.
-# This tag requires that the tag SEARCH_INCLUDES is set to YES.
-
-INCLUDE_PATH =
-
-# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard
-# patterns (like *.h and *.hpp) to filter out the header-files in the
-# directories. If left blank, the patterns specified with FILE_PATTERNS will be
-# used.
-# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
-
-INCLUDE_FILE_PATTERNS =
-
-# The PREDEFINED tag can be used to specify one or more macro names that are
-# defined before the preprocessor is started (similar to the -D option of e.g.
-# gcc). The argument of the tag is a list of macros of the form: name or
-# name=definition (no spaces). If the definition and the "=" are omitted, "=1"
-# is assumed. To prevent a macro definition from being undefined via #undef or
-# recursively expanded use the := operator instead of the = operator.
-# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
-
-PREDEFINED =
-
-# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this
-# tag can be used to specify a list of macro names that should be expanded. The
-# macro definition that is found in the sources will be used. Use the PREDEFINED
-# tag if you want to use a different macro definition that overrules the
-# definition found in the source code.
-# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
-
-EXPAND_AS_DEFINED =
-
-# If the SKIP_FUNCTION_MACROS tag is set to YES then doxygen's preprocessor will
-# remove all references to function-like macros that are alone on a line, have
-# an all uppercase name, and do not end with a semicolon. Such function macros
-# are typically used for boiler-plate code, and will confuse the parser if not
-# removed.
-# The default value is: YES.
-# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
-
-SKIP_FUNCTION_MACROS = YES
-
-#---------------------------------------------------------------------------
-# Configuration options related to external references
-#---------------------------------------------------------------------------
-
-# The TAGFILES tag can be used to specify one or more tag files. For each tag
-# file the location of the external documentation should be added. The format of
-# a tag file without this location is as follows:
-# TAGFILES = file1 file2 ...
-# Adding location for the tag files is done as follows:
-# TAGFILES = file1=loc1 "file2 = loc2" ...
-# where loc1 and loc2 can be relative or absolute paths or URLs. See the
-# section "Linking to external documentation" for more information about the use
-# of tag files.
-# Note: Each tag file must have a unique name (where the name does NOT include
-# the path). If a tag file is not located in the directory in which doxygen is
-# run, you must also specify the path to the tagfile here.
-
-TAGFILES =
-
-# When a file name is specified after GENERATE_TAGFILE, doxygen will create a
-# tag file that is based on the input files it reads. See section "Linking to
-# external documentation" for more information about the usage of tag files.
-
-GENERATE_TAGFILE =
-
-# If the ALLEXTERNALS tag is set to YES, all external class will be listed in
-# the class index. If set to NO, only the inherited external classes will be
-# listed.
-# The default value is: NO.
-
-ALLEXTERNALS = NO
-
-# If the EXTERNAL_GROUPS tag is set to YES, all external groups will be listed
-# in the modules index. If set to NO, only the current project's groups will be
-# listed.
-# The default value is: YES.
-
-EXTERNAL_GROUPS = YES
-
-# If the EXTERNAL_PAGES tag is set to YES, all external pages will be listed in
-# the related pages index. If set to NO, only the current project's pages will
-# be listed.
-# The default value is: YES.
-
-EXTERNAL_PAGES = YES
-
-# The PERL_PATH should be the absolute path and name of the perl script
-# interpreter (i.e. the result of 'which perl').
-# The default file (with absolute path) is: /usr/bin/perl.
-
-PERL_PATH = /usr/bin/perl
-
-#---------------------------------------------------------------------------
-# Configuration options related to the dot tool
-#---------------------------------------------------------------------------
-
-# If the CLASS_DIAGRAMS tag is set to YES, doxygen will generate a class diagram
-# (in HTML and LaTeX) for classes with base or super classes. Setting the tag to
-# NO turns the diagrams off. Note that this option also works with HAVE_DOT
-# disabled, but it is recommended to install and use dot, since it yields more
-# powerful graphs.
-# The default value is: YES.
-
-CLASS_DIAGRAMS = YES
-
-# You can define message sequence charts within doxygen comments using the \msc
-# command. Doxygen will then run the mscgen tool (see:
-# http://www.mcternan.me.uk/mscgen/)) to produce the chart and insert it in the
-# documentation. The MSCGEN_PATH tag allows you to specify the directory where
-# the mscgen tool resides. If left empty the tool is assumed to be found in the
-# default search path.
-
-MSCGEN_PATH =
-
-# You can include diagrams made with dia in doxygen documentation. Doxygen will
-# then run dia to produce the diagram and insert it in the documentation. The
-# DIA_PATH tag allows you to specify the directory where the dia binary resides.
-# If left empty dia is assumed to be found in the default search path.
-
-DIA_PATH =
-
-# If set to YES the inheritance and collaboration graphs will hide inheritance
-# and usage relations if the target is undocumented or is not a class.
-# The default value is: YES.
-
-HIDE_UNDOC_RELATIONS = YES
-
-# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is
-# available from the path. This tool is part of Graphviz (see:
-# http://www.graphviz.org/), a graph visualization toolkit from AT&T and Lucent
-# Bell Labs. The other options in this section have no effect if this option is
-# set to NO
-# The default value is: NO.
-
-HAVE_DOT = NO
-
-# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is allowed
-# to run in parallel. When set to 0 doxygen will base this on the number of
-# processors available in the system. You can set it explicitly to a value
-# larger than 0 to get control over the balance between CPU load and processing
-# speed.
-# Minimum value: 0, maximum value: 32, default value: 0.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-DOT_NUM_THREADS = 0
-
-# When you want a differently looking font in the dot files that doxygen
-# generates you can specify the font name using DOT_FONTNAME. You need to make
-# sure dot is able to find the font, which can be done by putting it in a
-# standard location or by setting the DOTFONTPATH environment variable or by
-# setting DOT_FONTPATH to the directory containing the font.
-# The default value is: Helvetica.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-DOT_FONTNAME = Helvetica
-
-# The DOT_FONTSIZE tag can be used to set the size (in points) of the font of
-# dot graphs.
-# Minimum value: 4, maximum value: 24, default value: 10.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-DOT_FONTSIZE = 10
-
-# By default doxygen will tell dot to use the default font as specified with
-# DOT_FONTNAME. If you specify a different font using DOT_FONTNAME you can set
-# the path where dot can find it using this tag.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-DOT_FONTPATH =
-
-# If the CLASS_GRAPH tag is set to YES then doxygen will generate a graph for
-# each documented class showing the direct and indirect inheritance relations.
-# Setting this tag to YES will force the CLASS_DIAGRAMS tag to NO.
-# The default value is: YES.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-CLASS_GRAPH = YES
-
-# If the COLLABORATION_GRAPH tag is set to YES then doxygen will generate a
-# graph for each documented class showing the direct and indirect implementation
-# dependencies (inheritance, containment, and class references variables) of the
-# class with other documented classes.
-# The default value is: YES.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-COLLABORATION_GRAPH = YES
-
-# If the GROUP_GRAPHS tag is set to YES then doxygen will generate a graph for
-# groups, showing the direct groups dependencies.
-# The default value is: YES.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-GROUP_GRAPHS = YES
-
-# If the UML_LOOK tag is set to YES, doxygen will generate inheritance and
-# collaboration diagrams in a style similar to the OMG's Unified Modeling
-# Language.
-# The default value is: NO.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-UML_LOOK = NO
-
-# If the UML_LOOK tag is enabled, the fields and methods are shown inside the
-# class node. If there are many fields or methods and many nodes the graph may
-# become too big to be useful. The UML_LIMIT_NUM_FIELDS threshold limits the
-# number of items for each type to make the size more manageable. Set this to 0
-# for no limit. Note that the threshold may be exceeded by 50% before the limit
-# is enforced. So when you set the threshold to 10, up to 15 fields may appear,
-# but if the number exceeds 15, the total amount of fields shown is limited to
-# 10.
-# Minimum value: 0, maximum value: 100, default value: 10.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-UML_LIMIT_NUM_FIELDS = 10
-
-# If the TEMPLATE_RELATIONS tag is set to YES then the inheritance and
-# collaboration graphs will show the relations between templates and their
-# instances.
-# The default value is: NO.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-TEMPLATE_RELATIONS = NO
-
-# If the INCLUDE_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES tags are set to
-# YES then doxygen will generate a graph for each documented file showing the
-# direct and indirect include dependencies of the file with other documented
-# files.
-# The default value is: YES.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-INCLUDE_GRAPH = YES
-
-# If the INCLUDED_BY_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES tags are
-# set to YES then doxygen will generate a graph for each documented file showing
-# the direct and indirect include dependencies of the file with other documented
-# files.
-# The default value is: YES.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-INCLUDED_BY_GRAPH = YES
-
-# If the CALL_GRAPH tag is set to YES then doxygen will generate a call
-# dependency graph for every global function or class method.
-#
-# Note that enabling this option will significantly increase the time of a run.
-# So in most cases it will be better to enable call graphs for selected
-# functions only using the \callgraph command. Disabling a call graph can be
-# accomplished by means of the command \hidecallgraph.
-# The default value is: NO.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-CALL_GRAPH = NO
-
-# If the CALLER_GRAPH tag is set to YES then doxygen will generate a caller
-# dependency graph for every global function or class method.
-#
-# Note that enabling this option will significantly increase the time of a run.
-# So in most cases it will be better to enable caller graphs for selected
-# functions only using the \callergraph command. Disabling a caller graph can be
-# accomplished by means of the command \hidecallergraph.
-# The default value is: NO.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-CALLER_GRAPH = NO
-
-# If the GRAPHICAL_HIERARCHY tag is set to YES then doxygen will graphical
-# hierarchy of all classes instead of a textual one.
-# The default value is: YES.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-GRAPHICAL_HIERARCHY = YES
-
-# If the DIRECTORY_GRAPH tag is set to YES then doxygen will show the
-# dependencies a directory has on other directories in a graphical way. The
-# dependency relations are determined by the #include relations between the
-# files in the directories.
-# The default value is: YES.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-DIRECTORY_GRAPH = YES
-
-# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images
-# generated by dot. For an explanation of the image formats see the section
-# output formats in the documentation of the dot tool (Graphviz (see:
-# http://www.graphviz.org/)).
-# Note: If you choose svg you need to set HTML_FILE_EXTENSION to xhtml in order
-# to make the SVG files visible in IE 9+ (other browsers do not have this
-# requirement).
-# Possible values are: png, jpg, gif, svg, png:gd, png:gd:gd, png:cairo,
-# png:cairo:gd, png:cairo:cairo, png:cairo:gdiplus, png:gdiplus and
-# png:gdiplus:gdiplus.
-# The default value is: png.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-DOT_IMAGE_FORMAT = png
-
-# If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to
-# enable generation of interactive SVG images that allow zooming and panning.
-#
-# Note that this requires a modern browser other than Internet Explorer. Tested
-# and working are Firefox, Chrome, Safari, and Opera.
-# Note: For IE 9+ you need to set HTML_FILE_EXTENSION to xhtml in order to make
-# the SVG files visible. Older versions of IE do not have SVG support.
-# The default value is: NO.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-INTERACTIVE_SVG = NO
-
-# The DOT_PATH tag can be used to specify the path where the dot tool can be
-# found. If left blank, it is assumed the dot tool can be found in the path.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-DOT_PATH =
-
-# The DOTFILE_DIRS tag can be used to specify one or more directories that
-# contain dot files that are included in the documentation (see the \dotfile
-# command).
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-DOTFILE_DIRS =
-
-# The MSCFILE_DIRS tag can be used to specify one or more directories that
-# contain msc files that are included in the documentation (see the \mscfile
-# command).
-
-MSCFILE_DIRS =
-
-# The DIAFILE_DIRS tag can be used to specify one or more directories that
-# contain dia files that are included in the documentation (see the \diafile
-# command).
-
-DIAFILE_DIRS =
-
-# When using plantuml, the PLANTUML_JAR_PATH tag should be used to specify the
-# path where java can find the plantuml.jar file. If left blank, it is assumed
-# PlantUML is not used or called during a preprocessing step. Doxygen will
-# generate a warning when it encounters a \startuml command in this case and
-# will not generate output for the diagram.
-
-PLANTUML_JAR_PATH =
-
-# When using plantuml, the PLANTUML_CFG_FILE tag can be used to specify a
-# configuration file for plantuml.
-
-PLANTUML_CFG_FILE =
-
-# When using plantuml, the specified paths are searched for files specified by
-# the !include statement in a plantuml block.
-
-PLANTUML_INCLUDE_PATH =
-
-# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of nodes
-# that will be shown in the graph. If the number of nodes in a graph becomes
-# larger than this value, doxygen will truncate the graph, which is visualized
-# by representing a node as a red box. Note that doxygen if the number of direct
-# children of the root node in a graph is already larger than
-# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note that
-# the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH.
-# Minimum value: 0, maximum value: 10000, default value: 50.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-DOT_GRAPH_MAX_NODES = 50
-
-# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the graphs
-# generated by dot. A depth value of 3 means that only nodes reachable from the
-# root by following a path via at most 3 edges will be shown. Nodes that lay
-# further from the root node will be omitted. Note that setting this option to 1
-# or 2 may greatly reduce the computation time needed for large code bases. Also
-# note that the size of a graph can be further restricted by
-# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction.
-# Minimum value: 0, maximum value: 1000, default value: 0.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-MAX_DOT_GRAPH_DEPTH = 0
-
-# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent
-# background. This is disabled by default, because dot on Windows does not seem
-# to support this out of the box.
-#
-# Warning: Depending on the platform used, enabling this option may lead to
-# badly anti-aliased labels on the edges of a graph (i.e. they become hard to
-# read).
-# The default value is: NO.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-DOT_TRANSPARENT = NO
-
-# Set the DOT_MULTI_TARGETS tag to YES to allow dot to generate multiple output
-# files in one run (i.e. multiple -o and -T options on the command line). This
-# makes dot run faster, but since only newer versions of dot (>1.8.10) support
-# this, this feature is disabled by default.
-# The default value is: NO.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-DOT_MULTI_TARGETS = NO
-
-# If the GENERATE_LEGEND tag is set to YES doxygen will generate a legend page
-# explaining the meaning of the various boxes and arrows in the dot generated
-# graphs.
-# The default value is: YES.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-GENERATE_LEGEND = YES
-
-# If the DOT_CLEANUP tag is set to YES, doxygen will remove the intermediate dot
-# files that are used to generate the various graphs.
-# The default value is: YES.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-DOT_CLEANUP = YES
diff --git a/thirdparty/ryml/ext/c4core/cmake/ExternalProjectUtils.cmake b/thirdparty/ryml/ext/c4core/cmake/ExternalProjectUtils.cmake
deleted file mode 100644
index f1328c6df..000000000
--- a/thirdparty/ryml/ext/c4core/cmake/ExternalProjectUtils.cmake
+++ /dev/null
@@ -1,215 +0,0 @@
-# (C) 2017 Joao Paulo Magalhaes <[email protected]>
-
-include(CMakeParseArguments)
-
-#------------------------------------------------------------------------------
-# Usage:
-#
-# ExternalProject_GetFwdArgs(output_var
-# [NO_DEFAULTS]
-# [VARS var1 var2 ...]
-# [EXCLUDE xvar1 xvar2 ...]
-# [QUIET]
-# )
-#
-# Get the current cmake environment in a sequence of -DVAR=${VAR}
-# tokens so that the environment can be forwarded to an external
-# cmake project through CMAKE_ARGS.
-#
-# Example:
-# ExternalProject_GetFwdArgs(FWD_ARGS)
-# ExternalProject_Add(foo SOURCE_DIR ../foo
-# CMAKE_ARGS ${FWD_ARGS}
-# ... etc)
-#
-# Use this function to enable forwarding the current cmake environment
-# to an external project. It outputs all the needed variables in the
-# form of a sequence of -DVAR=value, suitable for use in the CMAKE_ARGS
-# clause of ExternalProject_Add().
-#
-# This function uses ExternalProject_GetFwdVarNames() to find out the
-# list of variables to export. If this behaviour does not fit your
-# needs you can:
-#
-# * append more of your own variables (using the VARS
-# argument). The vars specified in this option will each be
-# added to the output in the form of -Dvar=${var}
-#
-# * you can also avoid any defaults obtained through usage of
-# ExternalProject_GetFwdNames() by specifying NO_DEFAULTS.
-#
-# Example with custom variable names (adding more):
-# ExternalProject_GetFwdVarNames(FWD_ARGS VARS USER_VAR1 USER_VAR2)
-# ExternalProjectAdd(foo SOURCE_DIR ../foo CMAKE_ARGS ${FWD_ARGS})
-#
-# Example with custom variable names (just your own):
-# ExternalProject_GetFwdVarNames(FWD_ARGS NO_DEFAULTS VARS USER_VAR1 USER_VAR2)
-# ExternalProjectAdd(foo SOURCE_DIR ../foo CMAKE_ARGS ${FWD_ARGS})
-#
-function(ExternalProject_GetFwdArgs output_var)
- set(options0arg
- NO_DEFAULTS
- QUIET
- )
- set(options1arg
- )
- set(optionsnarg
- VARS
- EXCLUDE
- )
- cmake_parse_arguments(_epgfa "${options0arg}" "${options1arg}" "${optionsnarg}" ${ARGN})
- if(NOT _epfga_NO_DEFAULTS)
- ExternalProject_GetFwdVarNames(_fwd_names)
- endif()
- if(_epgfa_VARS)
- list(APPEND _fwd_names ${_epgfa_VARS})
- endif()
- if(_epgfa_EXCLUDE)
- list(REMOVE_ITEM _fwd_names ${_epgfa_EXCLUDE})
- endif()
- set(_epgfa_args)
- foreach(_f ${_fwd_names})
- if(${_f})
- list(APPEND _epgfa_args -D${_f}=${${_f}})
- if(NOT _epfga_QUIET)
- message(STATUS "ExternalProject_GetFwdArgs: ${_f}=${${_f}}")
- endif()
- endif()
- endforeach()
- set(${output_var} "${_epgfa_args}" PARENT_SCOPE)
-endfunction(ExternalProject_GetFwdArgs)
-
-
-#------------------------------------------------------------------------------
-# Gets a default list with the names of variables to forward to an
-# external project. This function creates a list of common cmake
-# variable names which have an impact in the output binaries or their
-# placement.
-function(ExternalProject_GetFwdVarNames output_var)
- # these common names are irrespective of build type
- set(names
- CMAKE_GENERATOR
- CMAKE_INSTALL_PREFIX
- CMAKE_ARCHIVE_OUTPUT_DIRECTORY
- CMAKE_LIBRARY_OUTPUT_DIRECTORY
- CMAKE_RUNTIME_OUTPUT_DIRECTORY
- CMAKE_AR
- CMAKE_BUILD_TYPE
- CMAKE_INCLUDE_PATH
- CMAKE_LIBRARY_PATH
- #CMAKE_MODULE_PATH # this is dangerous as it can override the external project's build files.
- CMAKE_PREFIX_PATH
- BUILD_SHARED_LIBS
- CMAKE_CXX_COMPILER
- CMAKE_C_COMPILER
- CMAKE_LINKER
- CMAKE_MAKE_PROGRAM
- CMAKE_NM
- CMAKE_OBJCOPY
- CMAKE_RANLIB
- CMAKE_STRIP
- CMAKE_TOOLCHAIN_FILE
- #CMAKE_CONFIGURATION_TYPES # not this. external projects will have their own build configurations
- )
- # these names have per-build type values;
- # use CMAKE_CONFIGURATION_TYPES to construct the list
- foreach(v
- CMAKE_CXX_FLAGS
- CMAKE_C_FLAGS
- CMAKE_EXE_LINKER_FLAGS
- CMAKE_MODULE_LINKER_FLAGS
- CMAKE_SHARED_LINKER_FLAGS)
- list(APPEND names ${v})
- foreach(t ${CMAKE_CONFIGURATION_TYPES})
- string(TOUPPER ${t} u)
- list(APPEND names ${v}_${u})
- endforeach()
- endforeach()
- set(${output_var} "${names}" PARENT_SCOPE)
-endfunction(ExternalProject_GetFwdVarNames)
-
-
-#------------------------------------------------------------------------------
-macro(ExternalProject_Import name)
- set(options0arg
- )
- set(options1arg
- PREFIX # look only here when findind
- )
- set(optionsnarg
- INCLUDE_PATHS # use these dirs for searching includes
- LIBRARY_PATHS # use these dirs for searching libraries
- INCLUDES # find these includes and append them to ${name}_INCLUDE_DIRS
- INCLUDE_DIR_SUFFIXES
- LIBRARIES # find these libs and append them to ${name}_LIBRARIES
- LIBRARY_DIR_SUFFIXES
- )
- cmake_parse_arguments(_eep "${options0arg}" "${options1arg}" "${optionsnarg}" ${ARGN})
-
- if(NOT _eep_PREFIX)
- message(FATAL_ERROR "no prefix was given")
- endif()
-
- include(FindPackageHandleStandardArgs)
-
- #----------------------------------------------------------------
- # includes
-
- # the list of paths to search for includes
- set(_eep_ipaths ${_eep_PREFIX})
- foreach(_eep_i ${_eep_INCLUDE_DIRS})
- list(APPEND _eep_ipaths ${__eep_PREFIX}/${_eep_i})
- endforeach()
-
- # find the includes that were asked for, and add
- # their paths to the includes list
- set(_eep_idirs)
- foreach(_eep_i ${_eep_INCLUDES})
- find_path(_eep_path_${_eep_i} ${_eep_i}
- PATHS ${_eep_ipaths}
- PATH_SUFFIXES include ${_eep_INCLUDE_DIR_SUFFIXES}
- NO_DEFAULT_PATH
- )
- if(NOT _eep_path_${_eep_i})
- message(FATAL_ERROR "could not find include: ${_eep_i}")
- endif()
- #message(STATUS "include: ${_eep_i} ---> ${_eep_path_${_eep_i}}")
- list(APPEND _eep_idirs ${_eep_path_${_eep_i}})
- find_package_handle_standard_args(${_eep_i}_INCLUDE_DIR DEFAULT_MSG _eep_path_${_eep_i})
- endforeach()
- if(_eep_idirs)
- list(REMOVE_DUPLICATES _eep_idirs)
- endif()
-
- # save the include list
- set(${name}_INCLUDE_DIRS "${_eep_idirs}" CACHE STRING "" FORCE)
-
- #----------------------------------------------------------------
- # libraries
-
- # the list of paths to search for libraries
- set(_eep_lpaths ${_eep_PREFIX})
- foreach(_eep_i ${_eep_LIBRARIES})
- list(APPEND _eep_lpaths ${__eep_PREFIX}/${_eep_i})
- endforeach()
-
- # find any libraries that were asked for
- set(_eep_libs)
- foreach(_eep_i ${_eep_LIBRARIES})
- find_library(_eep_lib_${_eep_i} ${_eep_i}
- PATHS ${_eep_lpaths}
- PATH_SUFFIXES lib ${_eep_LIBRARY_DIR_SUFFIXES}
- NO_DEFAULT_PATH
- )
- if(NOT _eep_lib_${_eep_i})
- message(FATAL_ERROR "could not find library: ${_eep_i}")
- endif()
- #message(STATUS "lib: ${_eep_i} ---> ${_eep_lib_${_eep_i}}")
- list(APPEND _eep_libs ${_eep_lib_${_eep_i}})
- find_package_handle_standard_args(${_eep_i}_LIBRARY DEFAULT_MSG _eep_lib_${_eep_i})
- endforeach()
-
- # save the include list
- set(${name}_LIBRARIES ${_eep_libs} CACHE STRING "")
-
-endmacro(ExternalProject_Import)
diff --git a/thirdparty/ryml/ext/c4core/cmake/FindD3D12.cmake b/thirdparty/ryml/ext/c4core/cmake/FindD3D12.cmake
deleted file mode 100644
index 01e7a3ae9..000000000
--- a/thirdparty/ryml/ext/c4core/cmake/FindD3D12.cmake
+++ /dev/null
@@ -1,75 +0,0 @@
-# Find the win10 SDK path.
-if ("$ENV{WIN10_SDK_PATH}$ENV{WIN10_SDK_VERSION}" STREQUAL "" )
- get_filename_component(WIN10_SDK_PATH "[HKEY_LOCAL_MACHINE\\SOFTWARE\\WOW6432Node\\Microsoft\\Microsoft SDKs\\Windows\\v10.0;InstallationFolder]" ABSOLUTE CACHE)
- get_filename_component(TEMP_WIN10_SDK_VERSION "[HKEY_LOCAL_MACHINE\\SOFTWARE\\WOW6432Node\\Microsoft\\Microsoft SDKs\\Windows\\v10.0;ProductVersion]" ABSOLUTE CACHE)
- get_filename_component(WIN10_SDK_VERSION ${TEMP_WIN10_SDK_VERSION} NAME)
-elseif(TRUE)
- set (WIN10_SDK_PATH $ENV{WIN10_SDK_PATH})
- set (WIN10_SDK_VERSION $ENV{WIN10_SDK_VERSION})
-endif ("$ENV{WIN10_SDK_PATH}$ENV{WIN10_SDK_VERSION}" STREQUAL "" )
-
-# WIN10_SDK_PATH will be something like C:\Program Files (x86)\Windows Kits\10
-# WIN10_SDK_VERSION will be something like 10.0.14393 or 10.0.14393.0; we need the
-# one that matches the directory name.
-
-if (IS_DIRECTORY "${WIN10_SDK_PATH}/Include/${WIN10_SDK_VERSION}.0")
- set(WIN10_SDK_VERSION "${WIN10_SDK_VERSION}.0")
-endif (IS_DIRECTORY "${WIN10_SDK_PATH}/Include/${WIN10_SDK_VERSION}.0")
-
-
-# Find the d3d12 and dxgi include path, it will typically look something like this.
-# C:\Program Files (x86)\Windows Kits\10\Include\10.0.10586.0\um\d3d12.h
-# C:\Program Files (x86)\Windows Kits\10\Include\10.0.10586.0\shared\dxgi1_4.h
-find_path(D3D12_INCLUDE_DIR # Set variable D3D12_INCLUDE_DIR
- d3d12.h # Find a path with d3d12.h
- HINTS "${WIN10_SDK_PATH}/Include/${WIN10_SDK_VERSION}/um"
- DOC "path to WIN10 SDK header files"
- HINTS
- )
-
-find_path(DXGI_INCLUDE_DIR # Set variable DXGI_INCLUDE_DIR
- dxgi1_4.h # Find a path with dxgi1_4.h
- HINTS "${WIN10_SDK_PATH}/Include/${WIN10_SDK_VERSION}/shared"
- DOC "path to WIN10 SDK header files"
- HINTS
- )
-
-if ("${DXC_BUILD_ARCH}" STREQUAL "x64" )
- find_library(D3D12_LIBRARY NAMES d3d12.lib
- HINTS ${WIN10_SDK_PATH}/Lib/${WIN10_SDK_VERSION}/um/x64 )
-elseif (CMAKE_GENERATOR MATCHES "Visual Studio.*ARM" OR "${DXC_BUILD_ARCH}" STREQUAL "ARM")
- find_library(D3D12_LIBRARY NAMES d3d12.lib
- HINTS ${WIN10_SDK_PATH}/Lib/${WIN10_SDK_VERSION}/um/arm )
-elseif (CMAKE_GENERATOR MATCHES "Visual Studio.*ARM64" OR "${DXC_BUILD_ARCH}" STREQUAL "ARM64")
- find_library(D3D12_LIBRARY NAMES d3d12.lib
- HINTS ${WIN10_SDK_PATH}/Lib/${WIN10_SDK_VERSION}/um/arm64 )
-elseif ("${DXC_BUILD_ARCH}" STREQUAL "Win32" )
- find_library(D3D12_LIBRARY NAMES d3d12.lib
- HINTS ${WIN10_SDK_PATH}/Lib/${WIN10_SDK_VERSION}/um/x86 )
-endif ("${DXC_BUILD_ARCH}" STREQUAL "x64" )
-
-if ("${DXC_BUILD_ARCH}" STREQUAL "x64" )
- find_library(DXGI_LIBRARY NAMES dxgi.lib
- HINTS ${WIN10_SDK_PATH}/Lib/${WIN10_SDK_VERSION}/um/x64 )
-elseif (CMAKE_GENERATOR MATCHES "Visual Studio.*ARM" OR "${DXC_BUILD_ARCH}" STREQUAL "ARM")
- find_library(DXGI_LIBRARY NAMES dxgi.lib
- HINTS ${WIN10_SDK_PATH}/Lib/${WIN10_SDK_VERSION}/um/arm )
-elseif (CMAKE_GENERATOR MATCHES "Visual Studio.*ARM64" OR "${DXC_BUILD_ARCH}" STREQUAL "ARM64")
- find_library(DXGI_LIBRARY NAMES dxgi.lib
- HINTS ${WIN10_SDK_PATH}/Lib/${WIN10_SDK_VERSION}/um/arm64 )
-elseif ("${DXC_BUILD_ARCH}" STREQUAL "Win32" )
- find_library(DXGI_LIBRARY NAMES dxgi.lib
- HINTS ${WIN10_SDK_PATH}/Lib/${WIN10_SDK_VERSION}/um/x86 )
-endif ("${DXC_BUILD_ARCH}" STREQUAL "x64" )
-
-set(D3D12_LIBRARIES ${D3D12_LIBRARY} ${DXGI_LIBRARY})
-set(D3D12_INCLUDE_DIRS ${D3D12_INCLUDE_DIR} ${DXGI_INCLUDE_DIR})
-
-
-include(FindPackageHandleStandardArgs)
-# handle the QUIETLY and REQUIRED arguments and set D3D12_FOUND to TRUE
-# if all listed variables are TRUE
-find_package_handle_standard_args(D3D12 DEFAULT_MSG
- D3D12_INCLUDE_DIRS D3D12_LIBRARIES)
-
-mark_as_advanced(D3D12_INCLUDE_DIRS D3D12_LIBRARIES)
diff --git a/thirdparty/ryml/ext/c4core/cmake/FindDX12.cmake b/thirdparty/ryml/ext/c4core/cmake/FindDX12.cmake
deleted file mode 100644
index 5ae79ec07..000000000
--- a/thirdparty/ryml/ext/c4core/cmake/FindDX12.cmake
+++ /dev/null
@@ -1,76 +0,0 @@
-# Attempt to find the D3D12 libraries
-# Defines:
-#
-# DX12_FOUND - system has DX12
-# DX12_INCLUDE_PATH - path to the DX12 headers
-# DX12_LIBRARIES - path to the DX12 libraries
-# DX12_LIB - d3d12.lib
-
-set(DX12_FOUND "NO")
-
-if(WIN32)
- set(WIN10_SDK_DIR "C:/Program Files (x86)/Windows Kits/10")
- #set(WIN10_SDK_VERSION "10.0.10069.0")
- file(GLOB WIN10_SDK_VERSIONS
- LIST_DIRECTORIES TRUE
- RELATIVE "${WIN10_SDK_DIR}/Lib"
- "${WIN10_SDK_DIR}/Lib/*")
- list(SORT WIN10_SDK_VERSIONS)
- list(GET WIN10_SDK_VERSIONS -1 WIN10_SDK_VERSION)
-
- if(CMAKE_CL_64)
- set(w10ARCH x64)
- elseif(CMAKE_GENERATOR MATCHES "Visual Studio.*ARM" OR "${DXC_BUILD_ARCH}" STREQUAL "ARM")
- set(w10ARCH arm)
- elseif(CMAKE_GENERATOR MATCHES "Visual Studio.*ARM64" OR "${DXC_BUILD_ARCH}" STREQUAL "ARM64")
- set(w10ARCH arm64)
- else()
- set(w10ARCH x86)
- endif()
-
- # Look for the windows 8 sdk
- find_path(DX12_INC_DIR
- NAMES d3d12.h
- PATHS "${WIN10_SDK_DIR}/Include/${WIN10_SDK_VERSION}/um"
- DOC "Path to the d3d12.h file"
- )
- find_path(DXGI_INC_DIR
- NAMES dxgi1_4.h
- PATHS "${WIN10_SDK_DIR}/Include/${WIN10_SDK_VERSION}/shared"
- DOC "Path to the dxgi header file"
- )
-
- if(DX12_INC_DIR AND DXGI_INC_DIR)
- find_library(DX12_LIB
- NAMES d3d12
- PATHS "${WIN10_SDK_DIR}/Lib/${WIN10_SDK_VERSION}/um/${w10ARCH}"
- NO_DEFAULT_PATH
- DOC "Path to the d3d12.lib file"
- )
- find_library(DXGI_LIB
- NAMES dxgi
- PATHS "${WIN10_SDK_DIR}/Lib/${WIN10_SDK_VERSION}/um/${w10ARCH}"
- NO_DEFAULT_PATH
- DOC "Path to the dxgi.lib file"
- )
- if(DX12_LIB AND DXGI_LIB)
- set(DX12_FOUND "YES")
- set(DX12_LIBRARIES ${DX12_LIB} ${DXGI_LIB})
- mark_as_advanced(DX12_INC_DIR DX12_LIB)
- mark_as_advanced(DXGI_INC_DIR DXGI_LIB)
- endif()
- endif()
-endif(WIN32)
-
-if(DX12_FOUND)
- if(NOT DX12_FIND_QUIETLY)
- message(STATUS "DX12 headers found at ${DX12_INC_DIR}")
- endif()
-else()
- if(DX12_FIND_REQUIRED)
- message(FATAL_ERROR "Could NOT find Direct3D12")
- endif()
- if(NOT DX12_FIND_QUIETLY)
- message(STATUS "Could NOT find Direct3D12")
- endif()
-endif()
diff --git a/thirdparty/ryml/ext/c4core/cmake/GetFlags.cmake b/thirdparty/ryml/ext/c4core/cmake/GetFlags.cmake
deleted file mode 100644
index e7e9e5aa6..000000000
--- a/thirdparty/ryml/ext/c4core/cmake/GetFlags.cmake
+++ /dev/null
@@ -1,53 +0,0 @@
-
-function(_c4_intersperse_with_flag outvar flag)
- if(MSVC AND "${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") # it may be clang as well
- set(f "/${flag}")
- else()
- set(f "-${flag}")
- endif()
- set(out)
- foreach(i ${ARGN})
- if(NOT "${i}" STREQUAL "")
- set(out "${out} ${f} '${i}'")
-
- # ... Following this are several unsuccessful attempts to make
- # sure that an empty generator expression passed as part of the
- # arguments won't be expanded to nothing between successive
- # flags. For example, -I /some/include -I -I /other/include,
- # which is wrong as it misses an empty quote. This causes
- # clang-tidy in particular to fail. Maybe this is happening
- # because the result is passed to separate_arguments() which
- # prevents the lists from being evaluated correctly. Also, note
- # that add_custom_target() has the following options which may
- # help: COMMAND_EXPAND_LISTS and VERBATIM.
-
- # Anyway -- for now it is working, but maybe the generator
- # expression approach turns out to work while being much cleaner
- # than the current approach.
-
- #set(c $<GENEX_EVAL,$<BOOL:${i}>>)
- #set(c $<BOOL:${i}>) # i may be a generator expression the evaluates to empty
- #set(s "${f} ${i}")
- #set(e "${f} aaaaaaWTF")
- #list(APPEND out $<IF:${c},${s},${e}>)
- #list(APPEND out $<${c},${s}>)
- #list(APPEND out $<GENEX_EVAL:${c},${s}>)
- #list(APPEND out $<TARGET_GENEX_EVAL:${tgt},${c},${s}>)
- endif()
- endforeach()
- ## https://cmake.org/cmake/help/latest/manual/cmake-generator-expressions.7.html#string-valued-generator-expressions
- #if(ARGN)
- # set(out "${f}$<JOIN:${ARGN},;${f}>")
- #endif()
- set(${outvar} ${out} PARENT_SCOPE)
-endfunction()
-
-function(c4_get_define_flags outvar)
- _c4_intersperse_with_flag(out D ${ARGN})
- set(${outvar} ${out} PARENT_SCOPE)
-endfunction()
-
-function(c4_get_include_flags outvar)
- _c4_intersperse_with_flag(out I ${ARGN})
- set(${outvar} ${out} PARENT_SCOPE)
-endfunction()
diff --git a/thirdparty/ryml/ext/c4core/cmake/GetNames.cmake b/thirdparty/ryml/ext/c4core/cmake/GetNames.cmake
deleted file mode 100644
index a287372c0..000000000
--- a/thirdparty/ryml/ext/c4core/cmake/GetNames.cmake
+++ /dev/null
@@ -1,51 +0,0 @@
-function(get_lib_names lib_names base)
- set(${lib_names})
- foreach(__glnname ${ARGN})
- if(WIN32)
- set(__glnn ${__glnname}.lib)
- else()
- set(__glnn lib${__glnname}.a)
- endif()
- list(APPEND ${lib_names} "${base}${__glnn}")
- endforeach()
- set(lib_names ${lib_names} PARENT_SCOPE)
-endfunction()
-
-function(get_dll_names dll_names base)
- set(${dll_names})
- foreach(__glnname ${ARGN})
- if(WIN32)
- set(__glnn ${__glnname}.dll)
- else()
- set(__glnn lib${__glnname}.so)
- endif()
- list(APPEND ${dll_names} "${base}${__glnn}")
- endforeach()
- set(dll_names ${dll_names} PARENT_SCOPE)
-endfunction()
-
-function(get_script_names script_names base)
- set(${script_names})
- foreach(__glnname ${ARGN})
- if(WIN32)
- set(__glnn ${__glnname}.bat)
- else()
- set(__glnn ${__glnname}.sh)
- endif()
- list(APPEND ${script_names} "${base}${__glnn}")
- endforeach()
- set(script_names ${script_names} PARENT_SCOPE)
-endfunction()
-
-function(get_exe_names exe_names base)
- set(${exe_names})
- foreach(__glnname ${ARGN})
- if(WIN32)
- set(__glnn ${__glnname}.exe)
- else()
- set(__glnn ${__glnname})
- endif()
- list(APPEND ${exe_names} "${base}${__glnn}")
- endforeach()
- set(exe_names ${exe_names} PARENT_SCOPE)
-endfunction()
diff --git a/thirdparty/ryml/ext/c4core/cmake/LICENSE.txt b/thirdparty/ryml/ext/c4core/cmake/LICENSE.txt
deleted file mode 100644
index 47b6b4394..000000000
--- a/thirdparty/ryml/ext/c4core/cmake/LICENSE.txt
+++ /dev/null
@@ -1,20 +0,0 @@
-Copyright (c) 2018, Joao Paulo Magalhaes <[email protected]>
-
-Permission is hereby granted, free of charge, to any person obtaining
-a copy of this software and associated documentation files (the "Software"),
-to deal in the Software without restriction, including without limitation
-the rights to use, copy, modify, merge, publish, distribute, sublicense,
-and/or sell copies of the Software, and to permit persons to whom the
-Software is furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included
-in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
-DEALINGS IN THE SOFTWARE.
-
diff --git a/thirdparty/ryml/ext/c4core/cmake/PVS-Studio.cmake b/thirdparty/ryml/ext/c4core/cmake/PVS-Studio.cmake
deleted file mode 100644
index f0d217c2b..000000000
--- a/thirdparty/ryml/ext/c4core/cmake/PVS-Studio.cmake
+++ /dev/null
@@ -1,275 +0,0 @@
-# 2006-2008 (c) Viva64.com Team
-# 2008-2016 (c) OOO "Program Verification Systems"
-#
-# Version 2
-
-function (pvs_studio_relative_path VAR ROOT FILEPATH)
- set("${VAR}" "${FILEPATH}" PARENT_SCOPE)
- if ("${FILEPATH}" MATCHES "^/.*$")
- file(RELATIVE_PATH RPATH "${ROOT}" "${FILEPATH}")
- if (NOT "${RPATH}" MATCHES "^\\.\\..*$")
- set("${VAR}" "${RPATH}" PARENT_SCOPE)
- endif ()
- endif ()
-endfunction ()
-
-function (pvs_studio_join_path VAR DIR1 DIR2)
- if ("${DIR2}" MATCHES "^(/|~).*$" OR "${DIR1}" STREQUAL "")
- set("${VAR}" "${DIR2}" PARENT_SCOPE)
- else ()
- set("${VAR}" "${DIR1}/${DIR2}" PARENT_SCOPE)
- endif ()
-endfunction ()
-
-macro (pvs_studio_append_flags_from_property CXX C DIR PREFIX)
- if (NOT "${PROPERTY}" STREQUAL "NOTFOUND" AND NOT "${PROPERTY}" STREQUAL "PROPERTY-NOTFOUND")
- foreach (PROP ${PROPERTY})
- pvs_studio_join_path(PROP "${DIR}" "${PROP}")
- list(APPEND "${CXX}" "${PREFIX}${PROP}")
- list(APPEND "${C}" "${PREFIX}${PROP}")
- endforeach ()
- endif ()
-endmacro ()
-
-macro (pvs_studio_append_standard_flag FLAGS STANDARD)
- if ("${STANDARD}" MATCHES "^(99|11|14|17)$")
- if ("${PVS_STUDIO_PREPROCESSOR}" MATCHES "gcc|clang")
- list(APPEND "${FLAGS}" "-std=c++${STANDARD}")
- endif ()
- endif ()
-endmacro ()
-
-function (pvs_studio_set_directory_flags DIRECTORY CXX C)
- set(CXX_FLAGS "${${CXX}}")
- set(C_FLAGS "${${C}}")
-
- get_directory_property(PROPERTY DIRECTORY "${DIRECTORY}" INCLUDE_DIRECTORIES)
- pvs_studio_append_flags_from_property(CXX_FLAGS C_FLAGS "${DIRECTORY}" "-I")
-
- get_directory_property(PROPERTY DIRECTORY "${DIRECTORY}" COMPILE_DEFINITIONS)
- pvs_studio_append_flags_from_property(CXX_FLAGS C_FLAGS "" "-D")
-
- set("${CXX}" "${CXX_FLAGS}" PARENT_SCOPE)
- set("${C}" "${C_FLAGS}" PARENT_SCOPE)
-endfunction ()
-
-function (pvs_studio_set_target_flags TARGET CXX C)
- set(CXX_FLAGS "${${CXX}}")
- set(C_FLAGS "${${C}}")
-
- get_target_property(PROPERTY "${TARGET}" INCLUDE_DIRECTORIES)
- pvs_studio_append_flags_from_property(CXX_FLAGS C_FLAGS "${DIRECTORY}" "-I")
-
- get_target_property(PROPERTY "${TARGET}" COMPILE_DEFINITIONS)
- pvs_studio_append_flags_from_property(CXX_FLAGS C_FLAGS "" "-D")
-
- get_target_property(PROPERTY "${TARGET}" CXX_STANDARD)
- pvs_studio_append_standard_flag(CXX_FLAGS "${PROPERTY}")
-
- set("${CXX}" "${CXX_FLAGS}" PARENT_SCOPE)
- set("${C}" "${C_FLAGS}" PARENT_SCOPE)
-endfunction ()
-
-function (pvs_studio_set_source_file_flags SOURCE)
- set(LANGUAGE "")
-
- string(TOLOWER "${SOURCE}" SOURCE_LOWER)
- if ("${LANGUAGE}" STREQUAL "" AND "${SOURCE_LOWER}" MATCHES "^.*\\.(c|cpp|cc|cx|cxx|cp|c\\+\\+)$")
- if ("${SOURCE}" MATCHES "^.*\\.c$")
- set(LANGUAGE C)
- else ()
- set(LANGUAGE CXX)
- endif ()
- endif ()
-
- if ("${LANGUAGE}" STREQUAL "C")
- set(CL_PARAMS ${PVS_STUDIO_C_FLAGS} ${PVS_STUDIO_TARGET_C_FLAGS} -DPVS_STUDIO)
- elseif ("${LANGUAGE}" STREQUAL "CXX")
- set(CL_PARAMS ${PVS_STUDIO_CXX_FLAGS} ${PVS_STUDIO_TARGET_CXX_FLAGS} -DPVS_STUDIO)
- endif ()
-
- set(PVS_STUDIO_LANGUAGE "${LANGUAGE}" PARENT_SCOPE)
- set(PVS_STUDIO_CL_PARAMS "${CL_PARAMS}" PARENT_SCOPE)
-endfunction ()
-
-function (pvs_studio_analyze_file SOURCE SOURCE_DIR BINARY_DIR)
- set(PLOGS ${PVS_STUDIO_PLOGS})
- pvs_studio_set_source_file_flags("${SOURCE}")
-
- get_filename_component(SOURCE "${SOURCE}" REALPATH)
- pvs_studio_relative_path(SOURCE_RELATIVE "${SOURCE_DIR}" "${SOURCE}")
- pvs_studio_join_path(SOURCE "${SOURCE_DIR}" "${SOURCE}")
-
- set(LOG "${BINARY_DIR}/PVS-Studio/${SOURCE_RELATIVE}.plog")
- get_filename_component(LOG "${LOG}" REALPATH)
- get_filename_component(PARENT_DIR "${LOG}" DIRECTORY)
-
- if (EXISTS "${SOURCE}" AND NOT TARGET "${LOG}" AND NOT "${PVS_STUDIO_LANGUAGE}" STREQUAL "")
- add_custom_command(OUTPUT "${LOG}"
- COMMAND mkdir -p "${PARENT_DIR}"
- COMMAND rm -f "${LOG}"
- COMMAND "${PVS_STUDIO_BIN}" analyze
- --output-file "${LOG}"
- --source-file "${SOURCE}"
- ${PVS_STUDIO_ARGS}
- --cl-params ${PVS_STUDIO_CL_PARAMS} "${SOURCE}"
- WORKING_DIRECTORY "${BINARY_DIR}"
- DEPENDS "${SOURCE}" "${PVS_STUDIO_CONFIG}"
- VERBATIM
- COMMENT "Analyzing ${PVS_STUDIO_LANGUAGE} file ${SOURCE_RELATIVE}")
- list(APPEND PLOGS "${LOG}")
- endif ()
- set(PVS_STUDIO_PLOGS "${PLOGS}" PARENT_SCOPE)
-endfunction ()
-
-function (pvs_studio_analyze_target TARGET DIR)
- set(PVS_STUDIO_PLOGS "${PVS_STUDIO_PLOGS}")
- set(PVS_STUDIO_TARGET_CXX_FLAGS "")
- set(PVS_STUDIO_TARGET_C_FLAGS "")
-
- get_target_property(PROPERTY "${TARGET}" SOURCES)
- pvs_studio_relative_path(BINARY_DIR "${CMAKE_SOURCE_DIR}" "${DIR}")
- if ("${BINARY_DIR}" MATCHES "^/.*$")
- pvs_studio_join_path(BINARY_DIR "${CMAKE_BINARY_DIR}" "PVS-Studio/__${BINARY_DIR}")
- else ()
- pvs_studio_join_path(BINARY_DIR "${CMAKE_BINARY_DIR}" "${BINARY_DIR}")
- endif ()
-
- file(MAKE_DIRECTORY "${BINARY_DIR}")
-
- pvs_studio_set_directory_flags("${DIR}" PVS_STUDIO_TARGET_CXX_FLAGS PVS_STUDIO_TARGET_C_FLAGS)
- pvs_studio_set_target_flags("${TARGET}" PVS_STUDIO_TARGET_CXX_FLAGS PVS_STUDIO_TARGET_C_FLAGS)
-
- if (NOT "${PROPERTY}" STREQUAL "NOTFOUND" AND NOT "${PROPERTY}" STREQUAL "PROPERTY-NOTFOUND")
- foreach (SOURCE ${PROPERTY})
- pvs_studio_join_path(SOURCE "${DIR}" "${SOURCE}")
- pvs_studio_analyze_file("${SOURCE}" "${DIR}" "${BINARY_DIR}")
- endforeach ()
- endif ()
-
- set(PVS_STUDIO_PLOGS "${PVS_STUDIO_PLOGS}" PARENT_SCOPE)
-endfunction ()
-
-function (pvs_studio_add_target)
- macro (default VAR VALUE)
- if ("${${VAR}}" STREQUAL "")
- set("${VAR}" "${VALUE}")
- endif ()
- endmacro ()
-
- set(PVS_STUDIO_SUPPORTED_PREPROCESSORS "gcc|clang")
- if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
- set(DEFAULT_PREPROCESSOR "clang")
- else ()
- set(DEFAULT_PREPROCESSOR "gcc")
- endif ()
-
- set(OPTIONAL OUTPUT ALL)
- set(SINGLE LICENSE CONFIG TARGET LOG FORMAT BIN CONVERTER PLATFORM PREPROCESSOR CFG_TEXT)
- set(MULTI SOURCES C_FLAGS CXX_FLAGS ARGS DEPENDS ANALYZE)
- cmake_parse_arguments(PVS_STUDIO "${OPTIONAL}" "${SINGLE}" "${MULTI}" ${ARGN})
-
- if ("${PVS_STUDIO_CFG}" STREQUAL "" OR NOT "${PVS_STUDIO_CFG_TEXT}" STREQUAL "")
- set(PVS_STUDIO_EMPTY_CONFIG ON)
- else ()
- set(PVS_STUDIO_EMPTY_CONFIG OFF)
- endif ()
-
- default(PVS_STUDIO_CFG_TEXT "analysis-mode=4")
- default(PVS_STUDIO_CONFIG "${CMAKE_BINARY_DIR}/PVS-Studio.cfg")
- default(PVS_STUDIO_C_FLAGS "")
- default(PVS_STUDIO_CXX_FLAGS "")
- default(PVS_STUDIO_TARGET "pvs")
- default(PVS_STUDIO_LOG "PVS-Studio.log")
- default(PVS_STUDIO_BIN "pvs-studio-analyzer")
- default(PVS_STUDIO_CONVERTER "plog-converter")
- default(PVS_STUDIO_PREPROCESSOR "${DEFAULT_PREPROCESSOR}")
- default(PVS_STUDIO_PLATFORM "linux64")
-
- if (PVS_STUDIO_EMPTY_CONFIG)
- set(PVS_STUDIO_CONFIG_COMMAND echo "${PVS_STUDIO_CFG_TEXT}" > "${PVS_STUDIO_CONFIG}")
- else ()
- set(PVS_STUDIO_CONFIG_COMMAND touch "${PVS_STUDIO_CONFIG}")
- endif ()
-
- add_custom_command(OUTPUT "${PVS_STUDIO_CONFIG}"
- COMMAND ${PVS_STUDIO_CONFIG_COMMAND}
- WORKING_DIRECTORY "${BINARY_DIR}"
- COMMENT "Generating PVS-Studio.cfg")
-
-
- if (NOT "${PVS_STUDIO_PREPROCESSOR}" MATCHES "^${PVS_STUDIO_SUPPORTED_PREPROCESSORS}$")
- message(FATAL_ERROR "Preprocessor ${PVS_STUDIO_PREPROCESSOR} isn't supported. Available options: ${PVS_STUDIO_SUPPORTED_PREPROCESSORS}.")
- endif ()
-
- pvs_studio_append_standard_flag(PVS_STUDIO_CXX_FLAGS "${CMAKE_CXX_STANDARD}")
- pvs_studio_set_directory_flags("${CMAKE_CURRENT_SOURCE_DIR}" PVS_STUDIO_CXX_FLAGS PVS_STUDIO_C_FLAGS)
-
- if (NOT "${PVS_STUDIO_LICENSE}" STREQUAL "")
- pvs_studio_join_path(PVS_STUDIO_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}" "${PVS_STUDIO_LICENSE}")
- list(APPEND PVS_STUDIO_ARGS --lic-file "${PVS_STUDIO_LICENSE}")
- endif ()
- list(APPEND PVS_STUDIO_ARGS --cfg "${PVS_STUDIO_CONFIG}"
- --platform "${PVS_STUDIO_PLATFORM}"
- --preprocessor "${PVS_STUDIO_PREPROCESSOR}")
-
- set(PVS_STUDIO_PLOGS "")
-
- foreach (TARGET ${PVS_STUDIO_ANALYZE})
- set(DIR "${CMAKE_CURRENT_SOURCE_DIR}")
- string(FIND "${TARGET}" ":" DELIM)
- if ("${DELIM}" GREATER "-1")
- math(EXPR DELIMI "${DELIM}+1")
- string(SUBSTRING "${TARGET}" "${DELIMI}" "-1" DIR)
- string(SUBSTRING "${TARGET}" "0" "${DELIM}" TARGET)
- pvs_studio_join_path(DIR "${CMAKE_CURRENT_SOURCE_DIR}" "${DIR}")
- endif ()
- pvs_studio_analyze_target("${TARGET}" "${DIR}")
- list(APPEND PVS_STUDIO_DEPENDS "${TARGET}")
- endforeach ()
-
- set(PVS_STUDIO_TARGET_CXX_FLAGS "")
- set(PVS_STUDIO_TARGET_C_FLAGS "")
- foreach (SOURCE ${PVS_STUDIO_SOURCES})
- pvs_studio_analyze_file("${SOURCE}" "${CMAKE_CURRENT_SOURCE_DIR}" "${CMAKE_CURRENT_BINARY_DIR}")
- endforeach ()
-
- pvs_studio_relative_path(LOG_RELATIVE "${CMAKE_BINARY_DIR}" "${PVS_STUDIO_LOG}")
- if (PVS_STUDIO_PLOGS)
- set(COMMANDS COMMAND cat ${PVS_STUDIO_PLOGS} > "${PVS_STUDIO_LOG}")
- set(COMMENT "Generating ${LOG_RELATIVE}")
- if (NOT "${PVS_STUDIO_FORMAT}" STREQUAL "" OR PVS_STUDIO_OUTPUT)
- if ("${PVS_STUDIO_FORMAT}" STREQUAL "")
- set(PVS_STUDIO_FORMAT "errorfile")
- endif ()
- list(APPEND COMMANDS
- COMMAND mv "${PVS_STUDIO_LOG}" "${PVS_STUDIO_LOG}.pvs.raw"
- COMMAND "${PVS_STUDIO_CONVERTER}" -t "${PVS_STUDIO_FORMAT}" "${PVS_STUDIO_LOG}.pvs.raw" -o "${PVS_STUDIO_LOG}"
- COMMAND rm -f "${PVS_STUDIO_LOG}.pvs.raw")
- endif ()
- else ()
- set(COMMANDS COMMAND touch "${PVS_STUDIO_LOG}")
- set(COMMENT "Generating ${LOG_RELATIVE}: no sources found")
- endif ()
-
- add_custom_command(OUTPUT "${PVS_STUDIO_LOG}"
- ${COMMANDS}
- COMMENT "${COMMENT}"
- DEPENDS ${PVS_STUDIO_PLOGS}
- WORKING_DIRECTORY "${CMAKE_BINARY_DIR}")
-
- if (PVS_STUDIO_ALL)
- set(ALL "ALL")
- else ()
- set(ALL "")
- endif ()
-
- if (PVS_STUDIO_OUTPUT)
- set(COMMANDS COMMAND cat "${PVS_STUDIO_LOG}" 1>&2)
- else ()
- set(COMMANDS "")
- endif ()
-
- add_custom_target("${PVS_STUDIO_TARGET}" ${ALL} ${COMMANDS} WORKING_DIRECTORY "${CMAKE_BINARY_DIR}" DEPENDS ${PVS_STUDIO_DEPENDS} "${PVS_STUDIO_LOG}")
-endfunction ()
-
diff --git a/thirdparty/ryml/ext/c4core/cmake/PatchUtils.cmake b/thirdparty/ryml/ext/c4core/cmake/PatchUtils.cmake
deleted file mode 100644
index 164940e00..000000000
--- a/thirdparty/ryml/ext/c4core/cmake/PatchUtils.cmake
+++ /dev/null
@@ -1,25 +0,0 @@
-# create a script that applies a patch (it's different in windows)
-
-# to generate a patch:
-# subversion: svn diff --patch-compatible > path/to/the/patch.diff
-
-
-function(apply_patch patch where mark)
- if(NOT EXISTS "${mark}")
- if(NOT Patch_EXECUTABLE)
- find_package(Patch REQUIRED)
- endif()
- file(TO_NATIVE_PATH ${patch} patch_native)
- get_filename_component(patch_name "${patch}" NAME)
- message(STATUS "Applying patch: ${patch_name}")
- execute_process(
- COMMAND "${Patch_EXECUTABLE}" "-p0" "--input=${patch_native}"
- WORKING_DIRECTORY "${where}"
- RESULT_VARIABLE status)
- if(NOT status STREQUAL "0")
- message(FATAL_ERROR "could not apply patch: ${patch} ---> ${where}")
- else()
- file(TOUCH "${mark}")
- endif()
- endif()
-endfunction()
diff --git a/thirdparty/ryml/ext/c4core/cmake/PrintVar.cmake b/thirdparty/ryml/ext/c4core/cmake/PrintVar.cmake
deleted file mode 100644
index acd04e55b..000000000
--- a/thirdparty/ryml/ext/c4core/cmake/PrintVar.cmake
+++ /dev/null
@@ -1,27 +0,0 @@
-function(status)
- message(STATUS "${ARGV}")
-endfunction()
-
-function(print_var var)
- message(STATUS "${var}=${${var}} ${ARGN}")
-endfunction()
-
-function(print_vars)
- foreach(a ${ARGN})
- message(STATUS "${a}=${${a}}")
- endforeach(a)
-endfunction()
-
-function(debug_var debug var)
- if(${debug})
- message(STATUS "${var}=${${var}} ${ARGN}")
- endif()
-endfunction()
-
-function(debug_vars debug)
- if(${debug})
- foreach(a ${ARGN})
- message(STATUS "${a}=${${a}}")
- endforeach(a)
- endif()
-endfunction()
diff --git a/thirdparty/ryml/ext/c4core/cmake/README.md b/thirdparty/ryml/ext/c4core/cmake/README.md
deleted file mode 100644
index 13341daa0..000000000
--- a/thirdparty/ryml/ext/c4core/cmake/README.md
+++ /dev/null
@@ -1,25 +0,0 @@
-# cmake project utilities
-
-Useful cmake scripts, at [c4Project.cmake](c4Project.cmake).
-
-## Project utilities
-
-## Adding targets
-
-### Target types
-
-## Downloading and configuring third-party projects at configure time
-
-## Setting up tests
-
-### Coverage
-### Static analysis
-### Valgrind
-
-## Setting up benchmarks
-
-## License
-
-MIT License
-
-
diff --git a/thirdparty/ryml/ext/c4core/cmake/TargetArchitecture.cmake b/thirdparty/ryml/ext/c4core/cmake/TargetArchitecture.cmake
deleted file mode 100644
index 57baf662c..000000000
--- a/thirdparty/ryml/ext/c4core/cmake/TargetArchitecture.cmake
+++ /dev/null
@@ -1,180 +0,0 @@
-
-
-function(c4_get_architecture_defines output_var)
- c4_get_target_cpu_architecture(arch)
- if("${arch}" STREQUAL "x86_64")
- set(defines __x86_64__)
- elseif("${arch}" STREQUAL "i386")
- set(defines __i386__)
- elseif("${arch}" STREQUAL "armv8_64")
- set(defines __arm__ __aarch64__)
- elseif("${arch}" STREQUAL "armv8")
- set(defines __arm__ __ARM_ARCH_8__)
- elseif("${arch}" STREQUAL "armv7")
- set(defines __arm__ __ARM_ARCH_7__)
- elseif("${arch}" STREQUAL "armv6")
- set(defines __arm__ __ARM_ARCH_6__)
- elseif("${arch}" STREQUAL "armv5")
- set(defines __arm__ __ARM_ARCH_5__)
- elseif("${arch}" STREQUAL "armv4")
- set(defines __arm__ __ARM_ARCH_4T__)
- elseif("${arch}" STREQUAL "ia64")
- set(defines __ia64__)
- elseif("${arch}" STREQUAL "ppc64")
- set(defines __ppc64__)
- elseif("${arch}" STREQUAL "ia64")
- set(defines __ia64__)
- elseif("${arch}" STREQUAL "riscv64")
- set(defines __riscv64__)
- elseif("${arch}" STREQUAL "riscv32")
- set(defines __riscv32__)
- elseif("${arch}" STREQUAL "s390x")
- set(defines __s390x__)
- else()
- message(FATAL_ERROR "unknown target architecture: ${arch}")
- endif()
- set(${output_var} ${defines} PARENT_SCOPE)
-endfunction()
-
-
-# adapted from https://github.com/axr/solar-cmake/blob/master/TargetArch.cmake
-# Set ppc_support to TRUE before including this file or ppc and ppc64
-# will be treated as invalid architectures since they are no longer supported by Apple
-function(c4_get_target_cpu_architecture output_var)
- # this should be more or less in line with c4core/cpu.hpp
- set(archdetect_c_code "
-#if defined(__x86_64) || defined(__x86_64__) || defined(__amd64) || defined(_M_X64)
- #error cmake_ARCH x86_64
-#elif defined(__i386) || defined(__i386__) || defined(_M_IX86)
- #error cmake_ARCH i386
-#elif defined(__arm__) || defined(_M_ARM) \
- || defined(__TARGET_ARCH_ARM) || defined(__aarch64__) || defined(_M_ARM64)
- #if defined(__aarch64__) || defined(_M_ARM64)
- #error cmake_ARCH armv8_64
- #else
- #if defined(__ARM_ARCH_8__) || (defined(__TARGET_ARCH_ARM) && __TARGET_ARCH_ARM >= 8)
- #error cmake_ARCH armv8
- #elif defined(__ARM_ARCH_7__) || defined(_ARM_ARCH_7) \
- || defined(__ARM_ARCH_7A__) || defined(__ARM_ARCH_7R__) \
- || defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7S__) \
- || (defined(__TARGET_ARCH_ARM) && __TARGET_ARCH_ARM >= 7) \
- || (defined(_M_ARM) && _M_ARM >= 7)
- #error cmake_ARCH armv7
- #elif defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) \
- || defined(__ARM_ARCH_6T2__) || defined(__ARM_ARCH_6Z__) \
- || defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6ZK__) \
- || defined(__ARM_ARCH_6M__) \
- || (defined(__TARGET_ARCH_ARM) && __TARGET_ARCH_ARM >= 6)
- #error cmake_ARCH armv6
- #elif defined(__ARM_ARCH_5TEJ__) \
- || (defined(__TARGET_ARCH_ARM) && __TARGET_ARCH_ARM >= 5)
- #error cmake_ARCH armv5
- #elif defined(__ARM_ARCH_4T__) \
- || (defined(__TARGET_ARCH_ARM) && __TARGET_ARCH_ARM >= 4)
- #error cmake_ARCH armv4
- #else
- #error cmake_ARCH arm
- #endif
- #endif
-#elif defined(__ia64) || defined(__ia64__) || defined(_M_IA64)
- #error cmake_ARCH ia64
-#elif defined(__ppc__) || defined(__ppc) || defined(__powerpc__) \
- || defined(_ARCH_COM) || defined(_ARCH_PWR) || defined(_ARCH_PPC) \
- || defined(_M_MPPC) || defined(_M_PPC)
- #if defined(__ppc64__) || defined(__powerpc64__) || defined(__64BIT__)
- #error cmake_ARCH ppc64
- #else
- #error cmake_ARCH ppc32
- #endif
-#elif defined(__riscv)
- #if __riscv_xlen == 64
- #error cmake_ARCH riscv64
- #else
- #error cmake_ARCH riscv32
- #endif
-#elif defined(__s390x__) || defined(__zarch__)
- #error cmake_ARCH s390x
-#endif
-#error cmake_ARCH unknown
-")
- if(APPLE AND CMAKE_OSX_ARCHITECTURES)
- # On OS X we use CMAKE_OSX_ARCHITECTURES *if* it was set
- # First let's normalize the order of the values
-
- # Note that it's not possible to compile PowerPC applications if you are using
- # the OS X SDK version 10.6 or later - you'll need 10.4/10.5 for that, so we
- # disable it by default
- # See this page for more information:
- # http://stackoverflow.com/questions/5333490/how-can-we-restore-ppc-ppc64-as-well-as-full-10-4-10-5-sdk-support-to-xcode-4
-
- # Architecture defaults to i386 or ppc on OS X 10.5 and earlier, depending on the CPU type detected at runtime.
- # On OS X 10.6+ the default is x86_64 if the CPU supports it, i386 otherwise.
-
- foreach(osx_arch ${CMAKE_OSX_ARCHITECTURES})
- if("${osx_arch}" STREQUAL "ppc" AND ppc_support)
- set(osx_arch_ppc TRUE)
- elseif("${osx_arch}" STREQUAL "i386")
- set(osx_arch_i386 TRUE)
- elseif("${osx_arch}" STREQUAL "x86_64")
- set(osx_arch_x86_64 TRUE)
- elseif("${osx_arch}" STREQUAL "ppc64" AND ppc_support)
- set(osx_arch_ppc64 TRUE)
- else()
- message(FATAL_ERROR "Invalid OS X arch name: ${osx_arch}")
- endif()
- endforeach()
-
- # Now add all the architectures in our normalized order
- if(osx_arch_ppc)
- list(APPEND ARCH ppc)
- endif()
-
- if(osx_arch_i386)
- list(APPEND ARCH i386)
- endif()
-
- if(osx_arch_x86_64)
- list(APPEND ARCH x86_64)
- endif()
-
- if(osx_arch_ppc64)
- list(APPEND ARCH ppc64)
- endif()
- else()
- file(WRITE "${CMAKE_BINARY_DIR}/detect_cpu_arch.c" "${archdetect_c_code}")
-
- enable_language(C)
-
- # Detect the architecture in a rather creative way...
- # This compiles a small C program which is a series of ifdefs that selects a
- # particular #error preprocessor directive whose message string contains the
- # target architecture. The program will always fail to compile (both because
- # file is not a valid C program, and obviously because of the presence of the
- # #error preprocessor directives... but by exploiting the preprocessor in this
- # way, we can detect the correct target architecture even when cross-compiling,
- # since the program itself never needs to be run (only the compiler/preprocessor)
- try_run(
- run_result_unused
- compile_result_unused
- "${CMAKE_BINARY_DIR}"
- "${CMAKE_BINARY_DIR}/detect_cpu_arch.c"
- COMPILE_OUTPUT_VARIABLE ARCH
- CMAKE_FLAGS CMAKE_OSX_ARCHITECTURES=${CMAKE_OSX_ARCHITECTURES}
- )
-
- # Parse the architecture name from the compiler output
- string(REGEX MATCH "cmake_ARCH ([a-zA-Z0-9_]+)" ARCH "${ARCH}")
-
- # Get rid of the value marker leaving just the architecture name
- string(REPLACE "cmake_ARCH " "" ARCH "${ARCH}")
-
- # If we are compiling with an unknown architecture this variable should
- # already be set to "unknown" but in the case that it's empty (i.e. due
- # to a typo in the code), then set it to unknown
- if (NOT ARCH)
- set(ARCH unknown)
- endif()
- endif()
-
- set(${output_var} "${ARCH}" PARENT_SCOPE)
-endfunction()
diff --git a/thirdparty/ryml/ext/c4core/cmake/Toolchain-Arm-ubuntu.cmake b/thirdparty/ryml/ext/c4core/cmake/Toolchain-Arm-ubuntu.cmake
deleted file mode 100644
index 86d39dae1..000000000
--- a/thirdparty/ryml/ext/c4core/cmake/Toolchain-Arm-ubuntu.cmake
+++ /dev/null
@@ -1,29 +0,0 @@
-SET(CMAKE_SYSTEM_NAME Linux)
-SET(CMAKE_SYSTEM_PROCESSOR arm)
-SET(CMAKE_SYSTEM_VERSION 1)
-set(CMAKE_CROSSCOMPILING TRUE)
-
-find_program(CC_GCC arm-linux-gnueabihf-gcc REQUIRED)
-
-set(CMAKE_FIND_ROOT_PATH /usr/arm-gnueabihf)
-
-# Cross compiler
-SET(CMAKE_C_COMPILER arm-linux-gnueabihf-gcc)
-SET(CMAKE_CXX_COMPILER arm-linux-gnueabihf-g++)
-set(CMAKE_LIBRARY_ARCHITECTURE arm-linux-gnueabihf)
-
-# Search for programs in the build host directories
-SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
-
-# Libraries and headers in the target directories
-set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
-set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
-set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
-
-set(THREADS_PTHREAD_ARG "0" CACHE STRING "Result from TRY_RUN" FORCE)
-
-get_filename_component(TOOLCHAIN_DIR "${CC_GCC}" DIRECTORY)
-get_filename_component(TOOLCHAIN_DIR "${TOOLCHAIN_DIR}" DIRECTORY)
-set(TOOLCHAIN_SO_DIR "${TOOLCHAIN_DIR}/arm-linux-gnueabihf/")
-#/home/jpmag/local/arm/gcc-arm-9.2-2019.12-x86_64-arm-none-linux-gnueabihf
-set(CMAKE_CROSSCOMPILING_EMULATOR qemu-arm -L ${TOOLCHAIN_SO_DIR})
diff --git a/thirdparty/ryml/ext/c4core/cmake/Toolchain-Armv7.cmake b/thirdparty/ryml/ext/c4core/cmake/Toolchain-Armv7.cmake
deleted file mode 100644
index 7f6867126..000000000
--- a/thirdparty/ryml/ext/c4core/cmake/Toolchain-Armv7.cmake
+++ /dev/null
@@ -1,84 +0,0 @@
-# taken from https://stackoverflow.com/a/49086560
-
-# tested with the toolchain from ARM:
-# gcc-arm-9.2-2019.12-mingw-w64-i686-arm-none-linux-gnueabihf.tar.xz
-# found at
-# https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/gnu-a/downloads
-
-# see also:
-# https://stackoverflow.com/questions/42371788/how-to-run-helloworld-on-arm
-# https://dev.to/younup/cmake-on-stm32-the-beginning-3766
-
-SET(CMAKE_SYSTEM_NAME Linux)
-SET(CMAKE_SYSTEM_PROCESSOR arm)
-SET(CMAKE_SYSTEM_VERSION 1)
-set(CMAKE_CROSSCOMPILING TRUE)
-
-find_program(CC_GCC arm-none-linux-gnueabihf-gcc REQUIRED)
-
-set(CMAKE_FIND_ROOT_PATH /usr/arm-linux-gnueabihf)
-
-# Cross compiler
-SET(CMAKE_C_COMPILER arm-none-linux-gnueabihf-gcc)
-SET(CMAKE_CXX_COMPILER arm-none-linux-gnueabihf-g++)
-set(CMAKE_LIBRARY_ARCHITECTURE arm-none-linux-gnueabihf)
-
-# Search for programs in the build host directories
-SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
-
-# Libraries and headers in the target directories
-set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
-set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
-set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
-
-set(THREADS_PTHREAD_ARG "0" CACHE STRING "Result from TRY_RUN" FORCE)
-
-get_filename_component(TOOLCHAIN_DIR "${CC_GCC}" DIRECTORY)
-get_filename_component(TOOLCHAIN_DIR "${TOOLCHAIN_DIR}" DIRECTORY)
-set(TOOLCHAIN_SO_DIR "${TOOLCHAIN_DIR}/arm-none-linux-gnueabihf/libc/")
-
-#/home/jpmag/local/arm/gcc-arm-9.2-2019.12-x86_64-arm-none-linux-gnueabihf
-set(CMAKE_CROSSCOMPILING_EMULATOR qemu-arm -L ${TOOLCHAIN_SO_DIR})
-
-return()
-
-
-set(CMAKE_SYSTEM_NAME Generic)
-set(CMAKE_SYSTEM_PROCESSOR arm)
-set(CMAKE_SYSTEM_VERSION 1)
-set(CMAKE_CROSSCOMPILING 1)
-
-set(CMAKE_C_COMPILER "arm-none-eabi-gcc")
-set(CMAKE_CXX_COMPILER "arm-none-eabi-g++")
-
-
-set(CMAKE_FIND_ROOT_PATH /usr/arm-none-eabi)
-set(CMAKE_EXE_LINKER_FLAGS "--specs=nosys.specs" CACHE INTERNAL "")
-
-set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
-set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
-set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
-set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
-
-set(COMPILER_FLAGS "-marm -mfpu=neon -mfloat-abi=hard -mcpu=cortex-a9 -D_GNU_SOURCE")
-
-message(STATUS)
-message(STATUS)
-message(STATUS)
-
-if(NOT DEFINED CMAKE_C_FLAGS)
- set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${COMPILER_FLAGS}" CACHE STRING "")
-else()
- set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${COMPILER_FLAGS}")
-endif()
-
-message(STATUS)
-message(STATUS)
-message(STATUS)
-message(STATUS)
-
-if(NOT DEFINED CMAKE_CXX_FLAGS)
- set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${COMPILER_FLAGS}" CACHE STRING "")
-else()
- set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${COMPILER_FLAGS}")
-endif()
diff --git a/thirdparty/ryml/ext/c4core/cmake/Toolchain-PS4.cmake b/thirdparty/ryml/ext/c4core/cmake/Toolchain-PS4.cmake
deleted file mode 100644
index 260b9b078..000000000
--- a/thirdparty/ryml/ext/c4core/cmake/Toolchain-PS4.cmake
+++ /dev/null
@@ -1,73 +0,0 @@
-# Copyright 2017 Autodesk Inc. http://www.autodesk.com
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you
-# may not use this file except in compliance with the License. You may
-# obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-# implied. See the License for the specific language governing
-# permissions and limitations under the License.
-
-# This module is shared; use include blocker.
-if( _PS4_TOOLCHAIN_ )
- return()
-endif()
-set(_PS4_TOOLCHAIN_ 1)
-
-# PS4 SCE version requirement
-set(REQUIRED_PS4_VERSION "4.000")
-
-# Get PS4 SCE environment
-if( EXISTS "$ENV{SCE_ROOT_DIR}" AND IS_DIRECTORY "$ENV{SCE_ROOT_DIR}" )
- string(REGEX REPLACE "\\\\" "/" PS4_ROOT $ENV{SCE_ROOT_DIR})
- string(REGEX REPLACE "//" "/" PS4_ROOT ${PS4_ROOT})
- if( EXISTS "$ENV{SCE_ORBIS_SDK_DIR}" AND IS_DIRECTORY "$ENV{SCE_ORBIS_SDK_DIR}" )
- string(REGEX REPLACE "\\\\" "/" PS4_SDK $ENV{SCE_ORBIS_SDK_DIR})
- string(REGEX REPLACE "//" "/" PS4_SDK ${PS4_SDK})
- get_filename_component(SCE_VERSION "${PS4_SDK}" NAME)
- endif()
-endif()
-
-# Report and check version if it exist
-if( NOT "${SCE_VERSION}" STREQUAL "" )
- message(STATUS "PS4 SCE version found: ${SCE_VERSION}")
- if( NOT "${SCE_VERSION}" MATCHES "${REQUIRED_PS4_VERSION}+" )
- message(WARNING "Expected PS4 SCE version: ${REQUIRED_PS4_VERSION}")
- if( PLATFORM_TOOLCHAIN_ENVIRONMENT_ONLY )
- set(PS4_ROOT)
- set(PS4_SDK)
- endif()
- endif()
-endif()
-
-# If we only want the environment values, exit now
-if( PLATFORM_TOOLCHAIN_ENVIRONMENT_ONLY )
- return()
-endif()
-
-# We are building PS4 platform, fail if PS4 SCE not found
-if( NOT PS4_ROOT OR NOT PS4_SDK )
- message(FATAL_ERROR "Engine requires PS4 SCE SDK to be installed in order to build PS4 platform.")
-endif()
-
-# Tell CMake we are cross-compiling to PS4 (Orbis)
-set(CMAKE_SYSTEM_NAME Orbis)
-set(PS4 True)
-
-# Set CMake system root search path
-set(CMAKE_SYSROOT "${PS4_ROOT}")
-
-# Set compilers to the ones found in PS4 SCE SDK directory
-set(CMAKE_C_COMPILER "${PS4_SDK}/host_tools/bin/orbis-clang.exe")
-set(CMAKE_CXX_COMPILER "${PS4_SDK}/host_tools/bin/orbis-clang++.exe")
-set(CMAKE_ASM_COMPILER "${PS4_SDK}/host_tools/bin/orbis-as.exe")
-
-# Only search the PS4 SCE SDK, not the remainder of the host file system
-set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
-set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
-set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
-set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
diff --git a/thirdparty/ryml/ext/c4core/cmake/Toolchain-XBoxOne.cmake b/thirdparty/ryml/ext/c4core/cmake/Toolchain-XBoxOne.cmake
deleted file mode 100644
index 2ed9fad73..000000000
--- a/thirdparty/ryml/ext/c4core/cmake/Toolchain-XBoxOne.cmake
+++ /dev/null
@@ -1,93 +0,0 @@
-# Copyright 2017 Autodesk Inc. http://www.autodesk.com
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you
-# may not use this file except in compliance with the License. You may
-# obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-# implied. See the License for the specific language governing
-# permissions and limitations under the License.
-
-# This module is shared; use include blocker.
-if( _XB1_TOOLCHAIN_ )
- return()
-endif()
-set(_XB1_TOOLCHAIN_ 1)
-
-# XB1 XDK version requirement
-set(REQUIRED_XB1_TOOLCHAIN_VERSION "160305")
-
-# Get XDK environment
-if( EXISTS "$ENV{DurangoXDK}" AND IS_DIRECTORY "$ENV{DurangoXDK}" )
- string(REGEX REPLACE "\\\\" "/" XDK_ROOT $ENV{DurangoXDK})
- string(REGEX REPLACE "//" "/" XDK_ROOT ${XDK_ROOT})
-endif()
-
-# Fail if XDK not found
-if( NOT XDK_ROOT )
- if( PLATFORM_TOOLCHAIN_ENVIRONMENT_ONLY )
- return()
- endif()
- message(FATAL_ERROR "Engine requires XB1 XDK to be installed in order to build XB1 platform.")
-endif()
-
-# Get toolchain version
-get_filename_component(XDK_TOOLCHAIN_VERSION "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\Microsoft\\Durango XDK\\${REQUIRED_XB1_TOOLCHAIN_VERSION};EditionVersion]" NAME)
-
-if( XDK_TOOLCHAIN_VERSION STREQUAL REQUIRED_XB1_TOOLCHAIN_VERSION )
- message(STATUS "Found required XDK toolchain version (${XDK_TOOLCHAIN_VERSION})")
-else()
- get_filename_component(XDK_TOOLCHAIN_VERSION "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\Microsoft\\Durango XDK;Latest]" NAME)
- message(WARNING "Could not find required XDK toolchain version (${REQUIRED_XB1_TOOLCHAIN_VERSION}), using latest version instead (${XDK_TOOLCHAIN_VERSION})")
-endif()
-
-# If we only want the environment values, exit now
-if( PLATFORM_TOOLCHAIN_ENVIRONMENT_ONLY )
- return()
-endif()
-
-# Find XDK compiler directory
-if( CMAKE_GENERATOR STREQUAL "Visual Studio 11 2012" )
- set(XDK_COMPILER_DIR "${XDK_ROOT}/${XDK_TOOLCHAIN_VERSION}/Compilers/dev11.1")
-elseif( CMAKE_GENERATOR STREQUAL "Visual Studio 14 2015" )
- get_filename_component(XDK_COMPILER_DIR "[HKEY_CURRENT_USER\\Software\\Microsoft\\VisualStudio\\14.0_Config\\Setup\\VC;ProductDir]" DIRECTORY)
- if( DEFINED XDK_COMPILER_DIR )
- string(REGEX REPLACE "\\\\" "/" XDK_COMPILER_DIR ${XDK_COMPILER_DIR})
- string(REGEX REPLACE "//" "/" XDK_COMPILER_DIR ${XDK_COMPILER_DIR})
- endif()
- if( NOT XDK_COMPILER_DIR )
- message(FATAL_ERROR "Can't find Visual Studio 2015 installation path.")
- endif()
-else()
- message(FATAL_ERROR "Unsupported Visual Studio version!")
-endif()
-
-# Tell CMake we are cross-compiling to XBoxOne (Durango)
-set(CMAKE_SYSTEM_NAME Durango)
-set(XBOXONE True)
-
-# Set CMake system root search path
-set(CMAKE_SYSROOT "${XDK_COMPILER_DIR}")
-
-# Set the compilers to the ones found in XboxOne XDK directory
-set(CMAKE_C_COMPILER "${XDK_COMPILER_DIR}/vc/bin/amd64/cl.exe")
-set(CMAKE_CXX_COMPILER "${XDK_COMPILER_DIR}/vc/bin/amd64/cl.exe")
-set(CMAKE_ASM_COMPILER "${XDK_COMPILER_DIR}/vc/bin/amd64/ml64.exe")
-
-# Force compilers to skip detecting compiler ABI info and compile features
-set(CMAKE_C_COMPILER_FORCED True)
-set(CMAKE_CXX_COMPILER_FORCED True)
-set(CMAKE_ASM_COMPILER_FORCED True)
-
-# Only search the XBoxOne XDK, not the remainder of the host file system
-set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
-set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
-set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
-set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
-
-# Global variables
-set(XBOXONE_SDK_REFERENCES "Xbox Services API, Version=8.0;Xbox GameChat API, Version=8.0")
diff --git a/thirdparty/ryml/ext/c4core/cmake/amalgamate_utils.py b/thirdparty/ryml/ext/c4core/cmake/amalgamate_utils.py
deleted file mode 100644
index d4115c974..000000000
--- a/thirdparty/ryml/ext/c4core/cmake/amalgamate_utils.py
+++ /dev/null
@@ -1,219 +0,0 @@
-import re
-import os
-
-
-class cmtfile:
- """commented file"""
- def __init__(self, filename):
- self.filename = filename
- def __str__(self):
- return self.filename
-
-
-class cmttext:
- """commented text"""
- def __init__(self, text):
- self.text = text
- def __str__(self):
- return self.text
-
-
-class ignfile:
- """ignore file"""
- def __init__(self, filename):
- self.filename = filename
- def __str__(self):
- return self.filename
-
-
-class hdrfile:
- """header file, with custom include guard"""
- def __init__(self, filename, incpattern, include_guard=None):
- self.filename = filename
- self.incpattern = incpattern
- self.include_guard = include_guard
- def __str__(self):
- return self.filename
-
-
-class injfile:
- """header file, to be injected at the first include point"""
- def __init__(self, filename, incpattern):
- self.filename = filename
- self.incpattern = incpattern
- def __str__(self):
- return self.filename
-
-
-class injcode:
- """direct code to inject"""
- def __init__(self, code):
- self.code = code
- def __str__(self):
- return self.code
-
-
-class onlyif:
- def __init__(self, condition, obj):
- self.condition = condition
- self.obj = obj
-
-
-def catfiles(filenames, rootdir,
- include_regexes,
- definition_macro,
- repo,
- result_incguard):
- file_re = re.compile('[-./]')
- sepb = "//" + ("**" * 40)
- sepf = "//" + ("--" * 40)
- to_inject = {}
- custom_include_guards = {}
- def banner(s):
- return f"\n\n\n{sepb}\n{sepf}\n// {s}\n// {repo}/{s}\n{sepf}\n{sepb}\n\n"
- def footer(s):
- return f"\n\n// (end {repo}/{s})\n"
- def incguard(filename):
- return custom_include_guards.get(filename,
- f"{file_re.sub('_', filename).upper()}_")
- def replace_include(rx, match, line, guard):
- line = line.rstrip()
- incl = match.group(1)
- if to_inject.get(incl) is None:
- if guard is None:
- guard = incguard(incl)
- return f"""// amalgamate: removed include of
-// {repo}/src/{incl}
-//{line}
-#if !defined({guard}) && !defined(_{guard})
-#error "amalgamate: file {incl} must have been included at this point"
-#endif /* {guard} */\n
-"""
- else:
- entry = to_inject[incl]
- del to_inject[incl]
- return append_file(entry.filename)
- def append_file(filename, guard=None):
- s = ""
- with open(filename, encoding="utf8") as f:
- for line in f.readlines():
- for rx in include_regexes:
- match = rx.match(line)
- if match:
- line = replace_include(rx, match, line, guard)
- s += line
- return s
- def append_cpp(filename):
- return f"""#ifdef {definition_macro}
-{append_file(filename)}
-#endif /* {definition_macro} */
-"""
- def is_src(filename):
- return filename.endswith(".cpp") or filename.endswith(".c")
- def cmtline(line, more=""):
- if len(line.strip()) > 0:
- return f"// {line}{more}"
- else:
- return "//\n"
- out = ""
- for entry in filenames:
- if isinstance(entry, onlyif):
- if entry.condition:
- entry = entry.obj
- else:
- continue
- if isinstance(entry, ignfile):
- pass
- elif isinstance(entry, cmttext):
- for line in entry.text.split("\n"):
- out += cmtline(line, "\n")
- elif isinstance(entry, cmtfile):
- filename = f"{rootdir}/{entry.filename}"
- out += banner(entry.filename)
- with open(filename, encoding="utf8") as file:
- for line in file.readlines():
- out += cmtline(line)
- elif isinstance(entry, injcode):
- out += f"\n{entry.code}\n"
- elif isinstance(entry, injfile):
- entry.filename = f"{rootdir}/{entry.filename}"
- to_inject[entry.incpattern] = entry
- else:
- filename = f"{rootdir}/{entry}"
- out += banner(entry)
- if isinstance(entry, hdrfile):
- if entry.include_guard is not None:
- custom_include_guards[entry.incpattern] = entry.include_guard
- out += append_file(filename, entry.include_guard)
- else:
- assert isinstance(entry, str)
- if is_src(filename):
- out += append_cpp(filename)
- else:
- out += append_file(filename)
- out += footer(entry)
- return f"""#ifndef {result_incguard}
-#define {result_incguard}
-
-{out}
-#endif /* {result_incguard} */
-"""
-
-def include_only_first(file_contents: str):
- rx = [
- re.compile(r'^\s*#\s*include "(.*?)".*'),
- re.compile(r'^\s*#\s*include <(.*?)>.*'),
- ]
- already_included = {}
- out = ""
- for line in file_contents.split("\n"):
- for expr in rx:
- match = expr.match(line)
- if match:
- incl = match.group(1)
- if already_included.get(incl) is None:
- already_included[incl] = line
- if incl.endswith(".h"):
- cpp_version = f"c{incl[:-2]}"
- already_included[cpp_version] = line
- elif incl.startswith("c") and not (incl.endswith(".h") or incl.endswith(".hpp")):
- c_version = f"{incl[1:]}.h"
- already_included[c_version] = line
- else:
- line = f"//included above:\n//{line}"
- break
- out += line
- out += "\n"
- return out
-
-
-def mkparser(**bool_args):
- import argparse
- parser = argparse.ArgumentParser()
- parser.add_argument("output", default=None, nargs='?', help="output file. defaults to stdout")
- for k, (default, help) in bool_args.items():
- # https://stackoverflow.com/questions/15008758/parsing-boolean-values-with-argparse
- feature = parser.add_mutually_exclusive_group(required=False)
- yes = '--' + k
- no = '--no-' + k
- if default:
- yes_default = "this is the default"
- no_default = f"the default is {yes}"
- else:
- yes_default = f"the default is {no}"
- no_default = "this is the default"
- feature.add_argument(yes, dest=k, action='store_true', help=f"{help}. {yes_default}.")
- feature.add_argument(no, dest=k, action='store_false', help=f"{help}. {no_default}.")
- parser.set_defaults(**{k: default})
- return parser
-
-
-def file_put_contents(filename: str, contents: str):
- if filename is None:
- print(contents)
- else:
- dirname = os.path.dirname(filename)
- if dirname:
- os.makedirs(dirname, exist_ok=True)
- with open(filename, "w", encoding="utf8") as output:
- output.write(contents)
diff --git a/thirdparty/ryml/ext/c4core/cmake/bm-xp/.gitignore b/thirdparty/ryml/ext/c4core/cmake/bm-xp/.gitignore
deleted file mode 100644
index ccf5d016e..000000000
--- a/thirdparty/ryml/ext/c4core/cmake/bm-xp/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-static/* \ No newline at end of file
diff --git a/thirdparty/ryml/ext/c4core/cmake/bm-xp/README.md b/thirdparty/ryml/ext/c4core/cmake/bm-xp/README.md
deleted file mode 100644
index 485cd4edb..000000000
--- a/thirdparty/ryml/ext/c4core/cmake/bm-xp/README.md
+++ /dev/null
@@ -1,7 +0,0 @@
-# Benchmark explorer
-
-You need to start a http server on this folder:
-
-```shellsession
-$ python bm.py serve .
-```
diff --git a/thirdparty/ryml/ext/c4core/cmake/bm-xp/bm.js b/thirdparty/ryml/ext/c4core/cmake/bm-xp/bm.js
deleted file mode 100644
index 402d6120f..000000000
--- a/thirdparty/ryml/ext/c4core/cmake/bm-xp/bm.js
+++ /dev/null
@@ -1,475 +0,0 @@
-
-/* https://stackoverflow.com/questions/9050345/selecting-last-element-in-javascript-array */
-function last(arr)
-{
- return arr[arr.length - 1];
-};
-
-function dbg()
-{
- /* pass ?dbg=1 to enable debug logs */
- /*if(!getParam('dbg', 0)){
- return;
- }*/
- elm = $("#dbg");
- var s = "";
- for (var i = 0; i < arguments.length; i++) {
- if(i > 0) s += ' ';
- s += arguments[i].toString();
- }
- console.log(s);
- s+= "\n";
- elm.append(document.createTextNode(s));
-}
-
-
-function iterArr(arr, fn) {
- for (var key in arr) {
- if (arr.hasOwnProperty(key)) {
- fn(key, arr[key]);
- }
- }
-}
-
-
-function fileContents(file, onComplete)
-{
- dbg(`${file}: requesting...`);
- var data;
- $.get(file, function(d) {
- dbg(`${file}: got response! ${d.length}B...`);
- if(onComplete) {
- onComplete(d);
- }
- }, "text");
-}
-
-
-
-/* https://stackoverflow.com/questions/7394748/whats-the-right-way-to-decode-a-string-that-has-special-html-entities-in-it/7394787 */
-function decodeHtmlEntities(str)
-{
- return str
- .replace("&amp;", "&")
- .replace("&lt;", "<")
- .replace("&gt;", ">")
- .replace("&quot;", "\"")
- .replace(/&#(\d+);/g, function(match, dec) {
- return String.fromCharCode(dec);
- });
-}
-/* https://stackoverflow.com/questions/6234773/can-i-escape-html-special-chars-in-javascript */
-function escapeHtml(unsafe)
-{
- return unsafe
- .replace(/&/g, "&amp;")
- .replace(/</g, "&lt;")
- .replace(/>/g, "&gt;")
- .replace(/"/g, "&quot;")
- .replace(/'/g, "&#039;");
-}
-
-
-/* URL params ----------------------------------------------------------------- */
-
-var _curr_url_params = null;
-function parseUrlParams()
-{
- var keyvals = [];
- var keys = document.location.search.substring(1).split('&');
- dbg("keys=", keys)
- for(var i = 0; i < keys.length; i++) {
- var key = keys[i].split('=');
- dbg("i=", i, " key=", key);
- keyvals.push(key[0]);
- keyvals[key[0]] = key[1];
- }
- _curr_url_params = keyvals;
-}
-
-function dbgParams() {
- iterArr(_curr_url_params, function(key, val){ dbg("url params:", key, "=", val); })
-
-}
-function getParam(name, fallback)
-{
- if(_curr_url_params === null) { parseUrlParams(); }
- if(name in _curr_url_params) {
- return _curr_url_params[name];
- }
- return fallback;
-}
-
-function setParam(name, value) {
- if(_curr_url_params === null) { parseUrlParams(); }
- _curr_url_params[name] = value;
- // https://stackoverflow.com/questions/486896/adding-a-parameter-to-the-url-with-javascript
- document.location.search = joinParams();
-}
-
-function joinParams() {
- if(_curr_url_params === null) { parseUrlParams(); }
- var s = "";
- iterArr(_curr_url_params, function(key, val){
- if(s != ""){ s += '&'; }
- s += `${key}=${val}`;
- });
- return s;
-}
-
-
-/* ----------------------------------------------------------------------------- */
-
-function colMax(data, col)
-{
- var max = -1.e30;
- data.forEach(function(item, index){
- max = item[col] > max ? item[col] : max;
- });
- return max;
-}
-
-function colMin(data, col)
-{
- var min = 1.e30;
- data.forEach(function(item, index){
- min = item[col] < min ? item[col] : min;
- });
- return min;
-}
-
-/* https://stackoverflow.com/questions/2283566/how-can-i-round-a-number-in-javascript-tofixed-returns-a-string */
-function toFixedNumber(num, digits, base)
-{
- var pow = Math.pow(base||10, digits);
- return Math.round(num*pow) / pow;
-}
-
-function humanReadable(sz, base=1024, precision=3)
-{
- var i = -1;
- var units;
- if(base == 1000)
- {
- units = ['k', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y'];
- }
- else if(base == 1024)
- {
- units = ['ki', 'Mi', 'Gi', 'Ti', 'Pi', 'Ei', 'Zi', 'Yi'];
- }
- do
- {
- sz /= base;
- i++;
- } while (sz > base);
- return sz.toFixed(precision) + units[i];
-};
-
-
-/* ----------------------------------------------------------------------------- */
-
-class BmResults
-{
- constructor(dict={})
- {
- Object.assign(this, dict);
- for(var i = 0; i < this.benchmarks.length; ++i) {
- var bm = this.benchmarks[i];
- bm.name = decodeHtmlEntities(bm.name);
- bm.run_name = decodeHtmlEntities(bm.run_name);
- }
- }
-}
-
-var bmSpecs;
-function iterBms(fn)
-{
- iterArr(bmSpecs.bm, fn);
-}
-
-function loadSpecs(specs)
-{
- dbg("loading specs ....");
- iterArr(specs, function(k, v){dbg("k=", k, 'v=', v); });
- $("#heading-title").html(`Benchmarks: <a href="${specs.url}">${specs.projname}</a>`);
- bmSpecs = specs;
- var toc = $("#toc");
- /*toc.append(`<li><a href="#" onclick="setParam('bm', 'all');">Load all</a></li>`);*/
- iterBms(function(key, bm) {
- toc.append(`<li><a href="#${key}" onclick="setParam('bm', '${key}');">${key}</a>: ${bm.specs.desc}</li>`)
- bm.name = key;
- });
- // load if required
- currBm = getParam("bm", "");
- dbg("params=", _curr_url_params, currBm);
- if(currBm != "") {
- dbg("loading BM from URL:", currBm)
- loadBm(currBm);
- }
-}
-
-function normalizeBy(results, column_name, best_fn)
-{
- var best = best_fn(results.benchmarks, column_name);
- results.benchmarks.forEach(function(item, index){
- item[`${column_name}_normalized`] = item[column_name] / best;
- });
-}
-
-
-function loadAll()
-{
- var id = "#bm-results";
- $(id).empty();
- var i = 0;
- iterBms(function(key, bm){
- if(i++ > 0) $(id).append("<div class='bm-sep'><hr/></div>");
- appendBm(key);
- });
-}
-
-
-function loadBm(key)
-{
- dbg("loading-.....", key);
- /*if(key == "all") {
- loadAll();
- }*/
- $("#bm-results").empty();
- var bm = bmSpecs.bm[key];
- if(bm.src != "") {
- fileContents(bm.src, function(data){
- dbg(`${key}: got src data!`)
- bm.src_data = data;
- });
- }
- var latestRun = last(bm.entries);
- var bmfile = `${latestRun}/${key}.json`;
- dbg("bmfile=", bmfile);
- fileContents("bm/"+bmfile, function(data){
- dbg(`${key}: got bm data!`)
- bm.results_data = new BmResults(JSON.parse(data));
- bm.results_data.benchmarks.forEach(function(item, index){
- item.id = index;
- });
- normalizeBy(bm.results_data, 'iterations', colMin);
- normalizeBy(bm.results_data, 'real_time', colMin, );
- normalizeBy(bm.results_data, 'cpu_time', colMin);
- normalizeBy(bm.results_data, 'bytes_per_second', colMin);
- normalizeBy(bm.results_data, 'items_per_second', colMin);
- appendBm(latestRun, key, bm);
- });
-}
-
-
-function appendBm(run_id, id, bm)
-{
- if($(document).find(`bm-results-${id}`).length == 0)
- {
- $("#bm-results").append(`
-<div id="bm-results-${id}">
- <h2 id="bm-title-${id}">${id}</h2>
-
- <h3 id="heading-details-table-${id}">Run details</h3><table id="table-details-${id}" class="datatable" width="800px"></table>
-
- <h3 id="heading-table-${id}">Result tables</h3>
- <h4 id="heading-table-${id}_pretty">Results</h4><table id="table-${id}_pretty" class="datatable" width="800px"></table>
- <h4 id="heading-table-${id}_normalized">Normalized by column min</h4><table id="table-${id}_normalized" class="datatable" width="800px"></table>
-
- <h3 id="heading-chart-${id}">Chart</h2>
- <div id="chart-container-${id}"></div>
-
- <h3 id="heading-code-${id}">Code</h2>
- <pre><code id="code-${id}" class="lang-c++"></code></pre>
-</div>
-`);
- }
- var results = bm.results_data;
- var code = bm.src_data;
- loadDetailsTable(run_id, id, bm, results);
- loadTable(id, bm, results);
- loadChart(id, bm, results);
- loadCode(id, bm, code);
-}
-
-
-function loadCode(elmId, bm, code)
-{
- var elm = $(`#code-${elmId}`);
- elm.text(code);
- /* hljs.highlightBlock(elm); // this doesn't work */
- /* ... and this is very inefficient: */
- document.querySelectorAll('pre code').forEach((block) => {
- hljs.highlightBlock(block);
- });
-}
-
-function parseRunId(run_id)
-{
- // example:
- // commit id / cpu id - system id - build id
- // git20201204_202919-b3f7fa7/x86_64_b9db3176-linux_4e9326b4-64bit_Debug_gcc10.2.0_10c5d03c
- // git20201203_193348-2974fb0/x86_64_16ac0500-win32_59f3579c-64bit_MinSizeRel_msvc19.28.29304.1_32f6fc66
- // to tune the regex: https://regex101.com/r/rdkPi8/1
- // commit / cpu - system - build
- var rx = /^(.+?)-([0-9a-f]{7})\/(.+?)_([0-9a-f]{8})-(.+?)_([0-9a-f]{8})-(.+?)_([0-9a-f]{8})$/gim;
- var tag = rx.exec(run_id);
- dbg("fdx: run_id=", run_id);
- dbg("fdx: tag=", tag);
- dbg("fdx: len=", tag.length);
- return {
- commit_id: `${tag[2]}: ${tag[1]}`,
- cpu_id: `${tag[4]}: ${tag[3]} `,
- system_id: `${tag[6]}: ${tag[5]}`,
- build_id: `${tag[8]}: ${tag[7]}`,
- };
-}
-
-function getBuildId(run_id)
-{
- return parseRunId(run_id).build_id;
-}
-
-function loadDetailsTable(run_id, id, bm, results)
-{
- var url = bmSpecs.url;
- var run = bmSpecs.runs[run_id];
- var commit = bmSpecs.commit[run.commit].specs;
- var cpu = bmSpecs.cpu[run.cpu].specs;
- var system = bmSpecs.system[run.system].specs;
-
- let other_commit_entries = bmSpecs.commit[run.commit].entries.filter(
- entry_run => entry_run != run_id
- ).map(entry_run => getBuildId(entry_run)).join('<br>');
-
- /* https://datatables.net/ */
- $(`#table-details-${id}`).DataTable({
- data: results.benchmarks,
- info: false,
- paging: false,
- searching: false,
- retrieve: false,
- order: [],
- columns: [
- {title: "", data: "desc"},
- {title: "", data: "contents"},
- ],
- data: [
- {desc: "benchmark id" , contents: id},
- {desc: "commit" , contents: ahref(`${url}/commit/${commit.sha1}`, commit.sha1)},
- {desc: "commit date" , contents: ahref(`${url}/commit/${commit.sha1}`, commit.committed_datetime)},
- {desc: "commit summary", contents: ahref(`${url}/commit/${commit.sha1}`, commit.summary)},
- {desc: "source tree" , contents: ahref(`${url}/tree/${commit.sha1}`, `tree @ ${commit.sha1}`)},
- {desc: "benchmark" , contents: ahref(`${url}/tree/${commit.sha1}/${bm.specs.src}`, `source @ ${commit.sha1}`)},
- {desc: "cpu used" , contents: `${cpu.arch} ${cpu.brand_raw}`},
- {desc: "system used" , contents: `${system.uname.system} ${system.uname.release}`},
- {desc: "this build" , contents: `<pre>${getBuildId(run_id)}</pre>`},
- {desc: "commit builds" , contents: `<pre>${other_commit_entries}</pre>`},
- ]
- });
- function ahref(url, txt) { return `<a href="${url}" target="_blank">${txt}</a>`; }
-}
-
-
-function loadTable(id, bm, results)
-{
- function render_int(data, type, row, meta) { return toFixedNumber(data, 0); }
- function render_megas(data, type, row, meta) { return toFixedNumber(data / 1.e6, 3); }
- function render_fixed(data, type, row, meta) { return toFixedNumber(data, 3); }
- function render_human(data, type, row, meta) { return humanReadable(data, 1000, 3); }
-
- addTable("_pretty" , "" , {ns: render_int, iters: render_megas, rates: render_megas});
- addTable("_normalized", "_normalized", {ns: render_fixed, iters: render_fixed, rates: render_fixed});
-
- function addTable(suffix, data_suffix, renderers) {
- /* https://datatables.net/ */
- var searching = (results.benchmarks.count > 20);
- var ratePrefix = renderers.rates == render_megas ? "M" : "";
- var iterPrefix = renderers.iters == render_megas ? "M" : "";
- var clockSuffix = data_suffix == "_normalized" ? "" : "(ns)";
- $(`#table-${id}${suffix}`).DataTable( {
- data: results.benchmarks,
- info: false,
- paging: false,
- searching: searching,
- retrieve: searching,
- /* https://datatables.net/reference/option/columns.type */
- columns: [
- {title: "ID", data: "id", type: "num"},
- {title: "Name", data: "name", render: function(data, type, row, meta) { return escapeHtml(data); }},
- {title: `${ratePrefix}B/s` , data: `bytes_per_second${data_suffix}`, type: "num", className: "text-right", render: renderers.rates},
- {title: `${ratePrefix}items/s` , data: `items_per_second${data_suffix}`, type: "num", className: "text-right", render: renderers.rates},
- {title: `Clock${clockSuffix}` , data: `real_time${data_suffix}` , type: "num", className: "text-right", render: renderers.ns},
- {title: `CPU${clockSuffix}` , data: `cpu_time${data_suffix}` , type: "num", className: "text-right", render: renderers.ns},
- {title: `${ratePrefix}Iterations`, data: `iterations${data_suffix}` , type: "num", className: "text-right", render: renderers.iters},
- ]});
- }
-}
-
-function loadChart(id, bm, results)
-{
-
- addChartFromColumn('bytes_per_second_normalized', "B/s", "(more is better)");
- addChartFromColumn('items_per_second_normalized', "items/s", "(more is better)");
- addChartFromColumn('iterations_normalized', "Iterations", "(more is better)");
- addChartFromColumn('real_time_normalized', "Clock time", "(less is better)");
- addChartFromColumn('cpu_time_normalized', "CPU time", "(less is better)");
-
- function addChartFromColumn(column, column_name, obs) {
- var elmId = `chart-${id}-${column}`;
- var canvas = `${elmId}-canvas`;
-
- $(`#chart-container-${id}`).append(`
-<div id="${elmId}" class="chart">
- <canvas id="${canvas}"></canvas>
-</div>
-`);
-
- var chart = new CanvasJS.Chart(elmId, {
- animationEnabled: false,
- title:{
- fontSize: 24,
- /* text: `${id}: ${column_name}\n${obs}` */
- text: `${column_name}\n${obs}`
- },
- axisX: {
- labelFontSize: 12,
- },
- data: [{
- type: "bar",
- axisYType: "secondary",
- color: "#eb7434",/*"#014D65",*/
- dataPoints: results.benchmarks.map(function(item){
- return {
- indexLabelFormatter: function(e) { return e.dataPoint.indexLabel; },
- indexLabelFontSize: 16,
- indexLabel: item.name,
- /* label: item.name, */
- y: item[column],
- /* save the result here: the tooltip will show the full thing */
- benchmark_results: item
- };
- }),
- }],
- toolTip: {
- /*content: "{indexLabel}: {y}",*/
- contentFormatter: function(e){
- function hr(val) { return humanReadable(val, 1000, 3); }
- function fx(val) { return toFixedNumber(val, 3); }
- function fxi(val) { return toFixedNumber(val, 0); }
- function getRow(name, abs, rel) { return `<tr><td>${name}</td><td>${abs}</td><td>${rel}x min</td></tr>`; }
- var r = e.entries[0].dataPoint.benchmark_results;
- var hdrRow = `<tr><th></th><th>Absolute</th><th>Normalized</th></tr>`;
- var bpsRow = getRow("B/s", hr(r.bytes_per_second), fx(r.bytes_per_second_normalized));
- var ipsRow = getRow("items/s", hr(r.items_per_second), fx(r.items_per_second_normalized));
- var cpuRow = getRow("CPU", fxi(r.cpu_time) + "ns", fx(r.cpu_time_normalized));
- var clockRow = getRow("Clock", fxi(r.real_time) + "ns", fx(r.real_time_normalized));
- var itersRow = getRow("Iterations", hr(r.iterations), fx(r.iterations_normalized));
- var table = `<table>${hdrRow}${bpsRow}${ipsRow}${cpuRow}${clockRow}${itersRow}</table>`;
- return `<h4>${escapeHtml(r.name)}</h4>${table}`;
- }
- }
- });
- chart.render();
- }
-}
diff --git a/thirdparty/ryml/ext/c4core/cmake/bm-xp/bm_plot.py b/thirdparty/ryml/ext/c4core/cmake/bm-xp/bm_plot.py
deleted file mode 100644
index 3bcab5f4d..000000000
--- a/thirdparty/ryml/ext/c4core/cmake/bm-xp/bm_plot.py
+++ /dev/null
@@ -1,746 +0,0 @@
-import os
-import sys
-import copy
-import re
-import itertools
-import typing
-import enum
-
-# https://stackoverflow.com/questions/11351032/named-tuple-and-default-values-for-optional-keyword-arguments
-from dataclasses import dataclass
-
-from munch import Munch, munchify
-
-import bokeh.io as bki
-import bokeh.models as bkm
-import bokeh.plotting as bkp
-import bokeh.transform as bkt
-import bokeh.layouts as bkl
-from bokeh.models.markers import marker_types as bk_markers
-# https://docs.bokeh.org/en/latest/docs/reference/palettes.html
-from bokeh.palettes import d3 as bk_palette_d3
-bk_palette = bk_palette_d3['Category20c'][20]
-
-# saving bokeh to png is not working, so we save png using matplotlib
-import matplotlib.pyplot as plt
-import matplotlib.ticker as plttck
-plt_markers = [c for c in ".,ov^<>1234spP*hH+xXDdl"]
-
-from bm_util import _enum
-from bm_util import *
-from bm_run import BenchmarkRun, BenchmarkPanel
-
-
-# ------------------------------------------------------------------------------
-# ------------------------------------------------------------------------------
-# ------------------------------------------------------------------------------
-
-
-# https://stackoverflow.com/questions/11351032/named-tuple-and-default-values-for-optional-keyword-arguments
-@dataclass
-class BarChartSpecs:
- horizontal: bool = True
- bar_width: float = 0.9
-
-
-@dataclass
-class LineChartSpecs:
- width: int = 1000
- xlog: bool = False
- ylog: bool = False
- xlabel: str = ""
- ylabel: str = ""
-
-
-def _plt_save_png(name):
- log(name)
- plt.savefig(name, bbox_inches='tight', dpi=100)
-
-
-def _plt_clear():
- plt.clf()
-
-
-def _bokeh_save_html(name, p):
- log(name)
- bki.save(p, name)
-
-
-def _bokeh_adjust_figure_props(p):
- p.toolbar.autohide = True
- #p.toolbar.active_inspect = [hover_tool, crosshair_tool]
- p.toolbar.active_drag = "auto"
- p.toolbar.active_scroll = "auto"
- p.legend
- p.legend.click_policy = "hide"
- p.legend.label_text_font_size = "10px"
-
-
-def bokeh_plot_many(plots, name: str, ncols: int = 2):
- layout = bkl.gridplot(plots, ncols=ncols)
- _bokeh_save_html(name, layout)
- #bkp.show(layout)
-
-
-def plot_benchmark_run_as_bars(bm: BenchmarkRun, title: str,
- bar_names, bar_values, bar_label,
- **kwargs):
- kwargs = BarChartSpecs(**kwargs)
- #
- palette = itertools.cycle(bk_palette)
- colors = [next(palette) for _ in bar_names]
- #
- fig_args_bokeh = {
- "title": title,
- #"toolbar_location": None,
- #"tools": ""
- }
- if kwargs.horizontal:
- #
- # plot with bokeh (interactive, but cannot export png)
- rnames = list(reversed(bar_names))
- rvalues = list(reversed(bar_values))
- rcolors = list(reversed(colors))
- p = bkp.figure(y_range=rnames, **fig_args_bokeh)
- p.hbar(y=rnames, right=rvalues, fill_color=rcolors,
- line_color=rcolors, height=kwargs.bar_width)
- p.ygrid.grid_line_color = None
- p.x_range.start = 0
- p.xaxis.axis_label = bar_label
- #
- # plot with matplotlib (to export png)
- p_ = plt.barh(y=rnames, width=rvalues, color=rcolors,
- height=kwargs.bar_width)
- plt.gca().xaxis.grid(True)
- plt.gca().xaxis.set_minor_locator(plttck.AutoMinorLocator())
- plt.xlabel(bar_label, fontsize='small')
- plt.yticks(fontsize='x-small')
- plt.title(title)
- else:
- #
- # plot with bokeh (interactive, but cannot export png)
- p = bkp.figure(x_range=bar_names, **fig_args_bokeh)
- p.vbar(x=bar_names, top=bar_values, fill_color=colors,
- line_color=colors, width=kwargs.bar_width)
- p.xaxis.major_label_orientation = 1
- p.xgrid.grid_line_color = None
- p.y_range.start = 0
- p.yaxis.axis_label = bar_label
- #
- # plot with matplotlib (to export png)
- p_ = plt.bar(x=bar_names, height=bar_values, color=colors,
- width=kwargs.bar_width)
- plt.gca().yaxis.grid(True)
- plt.gca().yaxis.set_minor_locator(plttck.AutoMinorLocator())
- plt.ylabel(bar_label, fontsize='small')
- plt.xticks(fontsize='x-small')
- plt.title(title)
- _bokeh_adjust_figure_props(p)
- return p, p_
-
-
-def plot_benchmark_panel_as_lines(bm_panel: BenchmarkPanel, title: str,
- xget, yget, nameget,
- **kwargs):
- kwargs = LineChartSpecs(**kwargs)
- #
- colors = itertools.cycle(bk_palette)
- markers = itertools.cycle(bk_markers)
- markers_ = itertools.cycle(plt_markers)
- #
- # plot with bokeh (interactive, but cannot export png)
- p = bkp.figure(title=title,
- x_axis_type="log" if kwargs.xlog else "linear",
- y_axis_type="log" if kwargs.ylog else "linear",
- #background_fill_color="#fafafa",
- x_axis_label=kwargs.xlabel,
- y_axis_label=kwargs.ylabel,
- plot_width=kwargs.width,
- )
- # plot with matplotlib (to export png)
- plt.title(title)
- for bm in bm_panel.runs:
- x = xget(bm)
- y = yget(bm)
- line_name = nameget(bm)
- color = next(colors)
- marker = next(markers)
- marker_ = next(markers_)
- # plot with bokeh (interactive, but cannot export png)
- #legends.append(LegendItem(name=c, label=line_name))
- p.scatter(x, y, marker=marker, size=8, color=color,
- legend_label=line_name)
- p.line(x, y, color=color, alpha=0.9,
- #muted_color=c, muted_alpha=0.05,
- legend_label=line_name)
- #
- # plot with matplotlib (to export png)
- plt.plot(x, y, f'-{marker_}', color=color, label=line_name)
- plt.gca().xaxis.grid(True)
- plt.gca().yaxis.grid(True)
- plt.xscale("log" if kwargs.xlog else "linear")
- plt.yscale("log" if kwargs.ylog else "linear")
- plt.xlabel(kwargs.xlabel, fontsize='small')
- plt.ylabel(kwargs.ylabel, fontsize='small')
- plt.gca().legend(loc='center left', bbox_to_anchor=(1, 0.5), fontsize='x-small')
- _bokeh_adjust_figure_props(p)
- return p
-
-
-# -----------------------------------------------------------------------------
-# -----------------------------------------------------------------------------
-# -----------------------------------------------------------------------------
-
-####### old code: to remove and tidy up
-
-@dataclass
-class CharconvMeta: # also for atox
- title: str
- subject: str
- function: str
- data_type: FundamentalTypes
-
- @classmethod
- def make(cls, bm_title: str):
- # eg:
- # xtoa_c4_write_dec<uint8_t>
- # xtoa_c4_utoa<uint8_t>
- # xtoa_c4_xtoa<uint8_t>
- # xtoa_c4_to_chars<uint8_t>
- # xtoa_std_to_chars<uint8_t>
- # xtoa_std_to_string<uint8_t>
- # xtoa_sprintf<uint8_t>
- # xtoa_sstream_reuse<uint8_t>
- # xtoa_sstream<uint8_t>
- rx = re.compile(r'(atox|xtoa|xtoahex|xtoaoct|xtoabin)_(.*?)<(u?int\d+_t)>')
- if not rx.fullmatch(bm_title):
- raise Exception(f"cannot understand bm title: {bm_title}")
- subject = rx.sub(r'\1', bm_title)
- function = rx.sub(r'\2', bm_title)
- data_type = rx.sub(r'\3', bm_title)
- return cls(
- title=bm_title,
- subject=subject,
- function=function.replace("c4_", "c4::").replace("std_", "std::"),
- data_type=FundamentalTypes.make(data_type)
- )
-
- def checkbox_groups(self):
- return {
- 'data_type': [t for t in FundamentalTypes],
- }
-
- @property
- def shortname(self):
- return self.function
-
- @property
- def shortparams(self):
- return str(self.data_type.short)
-
- @property
- def shorttitle(self):
- return f"{self.shortname}<{self.shortparams}>"
-
-
-@dataclass
-class CharconvThreadsMeta:
- function: str
- num_threads: int
-
- @classmethod
- def make(cls, bm_title: str):
- # eg:
- # c4_itoa/real_time/threads:4
- rx = re.compile(r'(.*?)/real_time/threads:(\d+)')
- if not rx.fullmatch(bm_title):
- raise Exception(f"cannot understand bm title: {bm_title}")
- function = rx.sub(r'\1', bm_title)
- num_threads = int(rx.sub(r'\2', bm_title))
- return cls(
- function=function.replace("c4_", "c4::").replace("std_", "std::"),
- num_threads=num_threads
- )
-
- def checkbox_groups(self):
- return {}
-
- @property
- def shortname(self):
- return self.function
-
- @property
- def shorttitle(self):
- return self.shortname
-
-
-def plot_charconv_bars(bm_panel: BenchmarkPanel, panel_title_human: str, outputfile_prefix: str):
- assert os.path.isabs(outputfile_prefix), outputfile_prefix
- for prop in ("mega_bytes_per_second", "cpu_time_ms"):
- ps, ps_ = [], []
- pd = bm_panel.first_run.property_plot_data(prop)
- bar_label = f"{pd.human_name_short}{pd.what_is_better}"
- outfilename = f"{outputfile_prefix}-{prop}"
- for bm in bm_panel.runs:
- bar_names = [m.shorttitle for m in bm.meta]
- bar_values = list(getattr(bm, prop))
- data_type = first(bm.meta).data_type
- # to save each bokeh plot separately and also
- # a grid plot with all of them, we have to plot
- # twice because bokeh does not allow saving twice
- # the same plot from multiple pictures.
- plotit = lambda: plot_benchmark_run_as_bars(bm, title=f"{panel_title_human}: {data_type}\n{bar_label}",
- bar_names=bar_names, bar_values=bar_values, bar_label=bar_label)
- # make one plot to save:
- p, p_ = plotit()
- _bokeh_save_html(f"{outfilename}-{data_type.short}.html", p)
- _plt_save_png_and_clear(f"{outfilename}-{data_type.short}.png")
- # and another to gather:
- p, p_ = plotit()
- ps.append(p)
- ps_.append(p_)
- layout = bkl.gridplot(ps, ncols=2)
- _bokeh_save_html(f"{outfilename}.html", layout)
- # now show
- #bkp.show(layout)
-
-
-def plot_charconv_threads_(bm_panel: BenchmarkPanel, panel_title_human: str, outputfile_prefix: str):
- assert os.path.isabs(outputfile_prefix), outputfile_prefix
- orig = lambda yprop: lambda bm: list(bm.extract_plot_series(yprop))
- divnt = lambda yprop: lambda bm: [v / n for v, n in bm.extract_plot_series_with_threads(yprop)]
- mulnt = lambda yprop: lambda bm: [v * n for v, n in bm.extract_plot_series_with_threads(yprop)]
- xprop = "threads"
- xpd = bm_panel.first_run.property_plot_data(xprop)
- xlabel = f"{xpd.human_name_short}"
- for yprop, ylog, yget in (
- #("mega_items_per_second", False, orig),
- ("mega_bytes_per_second", False, orig),
- #("iterations", False, divnt),
- #("real_time_ms", True, mulnt),
- ("cpu_time_ms", True, orig),):
- ypd = bm_panel.first_run.property_plot_data(yprop)
- ylabel = f"{ypd.human_name_short}{ypd.what_is_better}"
- p = plot_benchmark_panel_as_lines(
- bm_panel, f"{panel_title_human}\n{ylabel}",
- xget=orig("threads"),
- yget=yget(yprop),
- nameget=lambda bm: first(bm.meta).function,
- ylog=ylog,
- xlabel=xlabel,
- ylabel=ylabel
- )
- name = f"{outputfile_prefix}-lines-{yprop}"
- # save png using matplotlib
- _plt_save_png_and_clear(f"{name}.png")
- # save html using bokeh
- _bokeh_save_html(f"{name}.html", p)
- #bkp.show(p)
- return p
-
-
-def plot_charconv_threads(json_files, case: str = ""):
- case = f" [{case}]" if case else ""
- dir_ = os.path.dirname(first(json_files))
- panel = BenchmarkPanel(json_files, CharconvThreadsMeta)
- plot_charconv_threads_(panel,
- f"itoa benchmark: convert 2M 32b integers to string{case}",
- f"{dir_}/c4core-bm-charconv_threads")
-
-
-def plot_charconv_xtoa(json_files, case: str = ""):
- case = f" [{case}]" if case else ""
- dir_ = os.path.dirname(first(json_files))
- panel = BenchmarkPanel(json_files, CharconvMeta)
- plot_charconv_bars(panel,
- f"xtoa benchmark: convert 2M numbers to strings{case}",
- f"{dir_}/c4core-bm-charconv-xtoa")
-
-
-def plot_charconv_atox(json_files, case: str = ""):
- case = f" [{case}]" if case else ""
- dir_ = os.path.dirname(first(json_files))
- panel = BenchmarkPanel(json_files, CharconvMeta)
- plot_charconv_bars(panel,
- f"atox benchmark: convert 2M strings to numbers{case}",
- f"{dir_}/c4core-bm-charconv-atox")
-
-
-def threads_data(dir_: str):
- assert os.path.exists(dir_), dir_
- return [
- f"{dir_}/c4core-bm-charconv_threads-c4_write_dec.json",
- f"{dir_}/c4core-bm-charconv_threads-c4_itoa.json",
- f"{dir_}/c4core-bm-charconv_threads-c4_xtoa.json",
- f"{dir_}/c4core-bm-charconv_threads-c4_to_chars.json",
- f"{dir_}/c4core-bm-charconv_threads-fmtlib_format_to.json",
- f"{dir_}/c4core-bm-charconv_threads-std_to_chars.json",
- f"{dir_}/c4core-bm-charconv_threads-snprintf.json",
- f"{dir_}/c4core-bm-charconv_threads-stb_snprintf.json",
- f"{dir_}/c4core-bm-charconv_threads-sstream.json",
- f"{dir_}/c4core-bm-charconv_threads-sstream_naive_reuse.json",
- f"{dir_}/c4core-bm-charconv_threads-sstream_naive.json",
- ]
-
-
-def xtoa_data(dir_: str):
- assert os.path.exists(dir_), dir_
- return [
- f"{dir_}/c4core-bm-charconv-xtoa-int8.json",
- f"{dir_}/c4core-bm-charconv-xtoa-uint8.json",
- f"{dir_}/c4core-bm-charconv-xtoa-int16.json",
- f"{dir_}/c4core-bm-charconv-xtoa-uint16.json",
- f"{dir_}/c4core-bm-charconv-xtoa-int32.json",
- f"{dir_}/c4core-bm-charconv-xtoa-uint32.json",
- f"{dir_}/c4core-bm-charconv-xtoa-int64.json",
- f"{dir_}/c4core-bm-charconv-xtoa-uint64.json",
- ]
-
-
-def atox_data(dir_: str):
- assert os.path.exists(dir_), dir_
- return [
- f"{dir_}/c4core-bm-charconv-atox-int8.json",
- f"{dir_}/c4core-bm-charconv-atox-uint8.json",
- f"{dir_}/c4core-bm-charconv-atox-int16.json",
- f"{dir_}/c4core-bm-charconv-atox-uint16.json",
- f"{dir_}/c4core-bm-charconv-atox-int32.json",
- f"{dir_}/c4core-bm-charconv-atox-uint32.json",
- f"{dir_}/c4core-bm-charconv-atox-int64.json",
- f"{dir_}/c4core-bm-charconv-atox-uint64.json",
- ]
-
-
-def examples_dir():
- this_dir = os.path.dirname(os.path.abspath(__file__))
- exdir = f"{this_dir}/examples"
- assert os.path.exists(exdir), exdir
- return exdir
-
-
-if __name__ == '__main__':
- xdir = examples_dir()
- #
- plot_charconv_threads(threads_data(f"{xdir}/lines/gcc11.2"), "gcc11.2")
- plot_charconv_threads(threads_data(f"{xdir}/lines/vs2022"), "vs2022")
- #
- plot_charconv_xtoa(xtoa_data(f"{xdir}/bars/xtoa/gcc11.2"), "gcc11.2")
- plot_charconv_xtoa(xtoa_data(f"{xdir}/bars/xtoa/vs2022"), "vs2022")
- #
- plot_charconv_atox(atox_data(f"{xdir}/bars/atox/gcc11.2"), "gcc11.2")
- plot_charconv_atox(atox_data(f"{xdir}/bars/atox/vs2022"), "vs2022")
- #
- exit()
-
-
-# ------------------------------------------------------------------------------
-# ------------------------------------------------------------------------------
-# ------------------------------------------------------------------------------
-
-
-def plot_benchmarks_as_lines(title, *bm, transform=None,
- line_title_transform=None,
- logx=True, logy=True):
- import bokeh
- from bokeh.plotting import figure, output_file, show
- from bokeh.palettes import Dark2_5 as palette
- from bokeh.layouts import row, column
- from bokeh.models import (Legend, LegendItem, CheckboxGroup, CustomJS, Div,
- RadioGroup, Toggle,
- ColumnDataSource, DataTable, TableColumn)
- from bokeh.models.markers import marker_types
- #
- ids = entry_ids(*bm, transform=transform)
- colors = itertools.cycle(palette)
- markers = itertools.cycle(marker_types)
- p = figure(title=title,
- x_axis_type="log" if logx else "linear",
- y_axis_type="log" if logy else "linear",
- #background_fill_color="#fafafa",
- plot_width=1000,
- x_axis_label="Number of pixels",
- y_axis_label="Throughput (MB/s)",
- )
- p.toolbar.autohide = True
- #p.toolbar.active_inspect = [hover_tool, crosshair_tool]
- p.toolbar.active_drag = "auto"
- p.toolbar.active_scroll = "auto"
- #
- def dft(v): return v if v else (lambda n: n)
- tr = dft(transform)
- lttr = dft(line_title_transform)
- #
- for results in bm:
- x = [ids[name] for name in results.names]
- y = [bps/1e6 for bps in results.bytes_per_second]
- c = next(colors)
- marker = next(markers)
- next(markers) # advance two
- line_name = lttr(results.first)
- #legends.append(LegendItem(name=c, label=line_name))
- p.scatter(x, y, marker=marker, size=8, color=c, legend_label=line_name)
- p.line(x, y,
- color=c, alpha=0.9,
- #muted_color=c, muted_alpha=0.05,
- legend_label=line_name)
- p.legend.click_policy = "hide"
- p.legend.label_text_font_size = "10px"
- #
- def input_title(title):
- return Div(text=f"<h3>{title}</h3>")
- inputs = []
- first = bm[0].first.meta
- for k, g in first.checkbox_groups().items():
- cb = CheckboxGroup(labels=[str(v) for v in g],
- active=[i for i in range(len(g))],
- inline=True)
- inputs.append(input_title(k))
- inputs.append(cb)
- #
- # https://github.com/bokeh/bokeh/blob/branch-2.3/examples/app/export_csv/main.py
- x_axis_values = [f"{m.num_pixels}px" for m in bm[0].meta]
- table_sources = []
- for i, px in enumerate(x_axis_values):
- c = ColumnDataSource(data={
- 'name': [nth(results.filtered_names, i) for results in bm],
- 'bytes_per_second': [nth(results.bytes_per_second, i) for results in bm],
- 'items_per_second': [nth(results.items_per_second, i) for results in bm],
- 'cpu_time': [nth(results.real_time, i) for results in bm],
- 'real_time': [nth(results.real_time, i) for results in bm],
- 'iterations': [nth(results.iterations, i) for results in bm],
- 'threads': [nth(results.threads, i) for results in bm],
- })
- table_sources.append(c)
- selected_x_index = 8 # FIXME (currently 2000 pixels)
- table_source = copy.deepcopy(table_sources[selected_x_index])
- relvalues = Toggle(label="Table: Relative values")
- px_title = input_title("Table: number of pixels")
- px_radiogroup = RadioGroup(labels=x_axis_values, active=selected_x_index)
- table_inputs = [relvalues, px_title, px_radiogroup]
- #
- table_cols = [
- TableColumn(field='name', title='Name'),
- TableColumn(field='bytes_per_second', title='Bytes/second'),
- TableColumn(field='items_per_second', title='Items/second'),
- TableColumn(field='cpu_time', title='CPU time'),
- TableColumn(field='real_time', title='Real time'),
- TableColumn(field='iterations', title='Iterations'),
- TableColumn(field='threads', title='Threads'),
- ]
- data_table = DataTable(source=table_source, columns=table_cols, width=1200)
- callback = CustomJS(args=dict(
- radiogroup=px_radiogroup,
- source=table_source,
- table=table_sources
- ), code="""
- console.log(`active=${radiogroup.active}`);
- /*source.data=table[radiogroup.active];*/
- var nrows = source.data['name'].length;
- var ts = table[radiogroup.active].data;
- var names = ["name", "bytes_per_second", "items_per_second", "cpu_time", "real_time", "iterations", "threads"];
- var ncols = names.length;
- console.log(`names=${names} nrows=${nrows} ncols=${ncols}`);
- for(var i = 0; i < nrows; i++) {
- for(var j = 0; j < ncols; ++j) {
- var name = names[j];
- /*console.log(`i=${i} j=${j} name=${name}`);*/
- source.data[name][i] = ts[name][i];
- }
- }
- source.change.emit();
- """)
- px_radiogroup.js_on_change('active', callback)
- # lambda attr, old, new: log(f"attr={attr} old={old} new={new} active={px_radiogroup.active}"))
- #
- layout = column(
- row(column(*inputs), p),
- row(column(*table_inputs), data_table))
- show(layout)
-
-
-def entry_ids(*bm, transform=None):
- ids = {}
- curr = 0
- for results in bm:
- log(os.path.basename(results.filename), "------------------------------")
- for entry in results.entries:
- log(entry.name)
- if transform is not None:
- ids[entry.name] = transform(entry)
- else:
- if ids.get(entry.name) is None:
- ids[entry.name] = curr
- curr += 1
- return ids
-
-
-class MatrixOrder(_enum):
- row_major = "row_major"
- col_major = "col_major"
- @property
- def short(self):
- return "rm" if self is MatrixOrder.row_major else "cm"
- @classmethod
- def make(cls, s):
- try:
- return {"rm": cls.row_major, "cm": cls.col_major}[s]
- except:
- cls.err_unknown(s)
-
-
-class MatrixLayout(_enum):
- compact = "compact"
- strided = "strided"
- @classmethod
- def make(cls, s):
- try:
- return cls[s]
- except:
- cls.err_unknown(s)
-
-
-class DimensionBinding(_enum):
- compile_time = "compile_time"
- run_time = "run_time"
- @property
- def short(self):
- return "ct" if self is DimensionBinding.compile_time else "rt"
- @classmethod
- def make(cls, s):
- try:
- return {"ct": cls.compile_time, "rt": cls.run_time}[s]
- except:
- cls.err_unknown(s)
-
-
-class MultType(_enum):
- naive = "naive"
- avx2 = "avx2"
- avx2_unroll2 = "avx2_unroll2"
- avx2_unroll4 = "avx2_unroll4"
- avx2_unroll8 = "avx2_unroll8"
- @classmethod
- def make(cls, s):
- try:
- s = s.replace("dotprod_", "").replace("_naive", "")
- return cls[s]
- except:
- cls.err_unknown(s)
-
-
-class MatrixMult(typing.NamedTuple):
- title: str
- num_pixels: int
- num_channels: int
- num_features: int
- mult_type: MultType
- layout: MatrixLayout
- dim_binding: DimensionBinding
- ret_order: MatrixOrder
- lhs_order: MatrixOrder
- rhs_order: MatrixOrder
-
- @classmethod
- def make(cls, bm_title: str):
- # eg:
- # mult_naive_strided_ct_rm_cmcm<250, 8, 16>
- # mult_naive_compact_rt_rm_rmrm/4000/8/16
- rxline = r'mult_(.*)[</](\d+)(?:/|, )(\d+)(?:/|, )(\d+).*'
- rxcase = r"(.*)_(compact|strided)_(ct|rt)_(rm|cm)_(rm|cm)(rm|cm)"
- case = re.sub(rxline, r'\1', bm_title)
- return cls(
- title=case,
- num_pixels=int(re.sub(rxline, r'\2', bm_title)),
- num_channels=int(re.sub(rxline, r'\3', bm_title)),
- num_features=int(re.sub(rxline, r'\4', bm_title)),
- mult_type=MultType.make(re.sub(rxcase, r'\1', case)),
- layout=MatrixLayout.make(re.sub(rxcase, r'\2', case)),
- dim_binding=DimensionBinding.make(re.sub(rxcase, r'\3', case)),
- ret_order=MatrixOrder.make(re.sub(rxcase, r'\4', case)),
- lhs_order=MatrixOrder.make(re.sub(rxcase, r'\5', case)),
- rhs_order=MatrixOrder.make(re.sub(rxcase, r'\6', case))
- )
-
- def comparison_axes(self):
- return ('num_pixels', 'num_channels', 'num_features')
-
- def checkbox_groups(self):
- return {
- 'multiplication method': [t for t in MultType],
- 'layout': [t for t in MatrixLayout],
- 'dimension': [d for d in DimensionBinding],
- 'return matrix ordering': [o for o in MatrixOrder],
- 'lhs matrix ordering': [o for o in MatrixOrder],
- 'rhs matrix ordering': [o for o in MatrixOrder],
- }
-
- @property
- def matrix_size(self):
- return self.num_pixels * self.num_channels
-
- @property
- def classifier_size(self):
- return self.num_channels * self.num_features
-
- @property
- def shortname(self):
- m = self
- return f"{m.mult_type}/{m.layout}/{m.dim_binding.short}_{m.ret_order.short}_{m.lhs_order.short}{m.rhs_order.short}"
-
- @property
- def shortparams(self):
- m = self
- return f"{m.num_pixels:04d}px{m.num_channels:02d}ch{m.num_features:02d}ft"
-
- @property
- def shorttitle(self):
- return f"{self.shortname}/{self.shortparams}"
-
-
-def _test():
- def expect(v_, attr, val):
- var = getattr(v_, attr)
- if var != val:
- raise Exception(f"{attr}: expected={val} actual={var}")
- #
- v = MatrixMult.make("mult_naive_strided_ct_rm_cmcm<250, 8, 16>")
- expect(v, 'title', 'naive_strided_ct_rm_cmcm')
- expect(v, 'num_pixels', 250)
- expect(v, 'num_channels', 8)
- expect(v, 'num_features', 16)
- expect(v, 'mult_type', MultType.naive)
- expect(v, 'layout', MatrixLayout.strided)
- expect(v, 'dim_binding', DimensionBinding.compile_time)
- expect(v, 'ret_order', MatrixOrder.row_major)
- expect(v, 'lhs_order', MatrixOrder.col_major)
- expect(v, 'rhs_order', MatrixOrder.col_major)
- v = MatrixMult.make("mult_dotprod_avx2_compact_rt_cm_rmcm/4000/16/8")
- expect(v, 'title', 'dotprod_avx2_compact_rt_cm_rmcm')
- expect(v, 'num_pixels', 4000)
- expect(v, 'num_channels', 16)
- expect(v, 'num_features', 8)
- expect(v, 'mult_type', MultType.avx2)
- expect(v, 'layout', MatrixLayout.compact)
- expect(v, 'dim_binding', DimensionBinding.run_time)
- expect(v, 'ret_order', MatrixOrder.col_major)
- expect(v, 'lhs_order', MatrixOrder.row_major)
- expect(v, 'rhs_order', MatrixOrder.col_major)
-
-_test()
-
-
-
-def formatMBps(value):
- return value / 1e6
-
-
-
-if __name__ == '__main__':
- bms = sorted(sys.argv[2:])
- log(bms)
- bms = BenchmarkPanel(bms, bm_meta_cls=MatrixMult.make)
- fm = bms.runs[0].first.meta
- title = f"Classifier multiplication, {fm.num_channels} channels, {fm.num_features} features: throughput (MB/s)"
- bms.plot_all_lines(title)
- exit()
- main()
diff --git a/thirdparty/ryml/ext/c4core/cmake/bm-xp/bm_run.py b/thirdparty/ryml/ext/c4core/cmake/bm-xp/bm_run.py
deleted file mode 100644
index 812b64abe..000000000
--- a/thirdparty/ryml/ext/c4core/cmake/bm-xp/bm_run.py
+++ /dev/null
@@ -1,248 +0,0 @@
-import copy
-import os.path
-
-# https://stackoverflow.com/questions/11351032/named-tuple-and-default-values-for-optional-keyword-arguments
-from dataclasses import dataclass
-
-from munch import Munch
-
-from bm_util import load_json, first, _enum
-
-
-# ------------------------------------------------------------------------------
-# ------------------------------------------------------------------------------
-# ------------------------------------------------------------------------------
-
-class QuantityType(_enum):
- neutral = ""
- more_is_better = "more is better"
- less_is_better = "less is better"
-
- @property
- def comment(self):
- return f" ({self.value})" if self.name else ""
-
-
-_more = QuantityType.more_is_better
-_less = QuantityType.less_is_better
-
-
-@dataclass
-class BenchmarkPropertyPlotData:
- human_name: str = ""
- human_name_short: str = ""
- qty_type: QuantityType = QuantityType.neutral
-
-
-class BenchmarkRun(Munch):
- """results of an individual run"""
-
- def __init__(self, json_file: str, meta_class):
- """
- meta_class is a class to extract property values from the benchmark run
- """
- self._filename = json_file
- props = load_json(json_file)
- assert hasattr(props, "context")
- assert hasattr(props, "benchmarks")
- super().__init__(**props)
- setattr(self, 'property_names', list(__class__._properties.keys()))
- for bm in self.benchmarks:
- if meta_class is not None:
- setattr(bm, 'meta', meta_class.make(bm.name))
- else:
- setattr(bm, 'meta', None)
-
- _properties = {
- 'filename': None,
- 'basename': None,
- 'dirname': None,
- 'meta': None,
- 'shorttitle': None,
- 'name': None,
- 'run_name': None,
- 'run_type': None,
- 'repetitions': None,
- 'repetition_index': None,
- 'threads': BenchmarkPropertyPlotData('number of threads', 'threads'),
- 'iterations': BenchmarkPropertyPlotData('number of iterations', 'iterations', _more),
- 'real_time': BenchmarkPropertyPlotData('real time', 'real time', _less),
- 'cpu_time': BenchmarkPropertyPlotData('CPU time', 'cpu time', _less),
- 'real_time_ms': BenchmarkPropertyPlotData('real time', 'real time', _less),
- 'cpu_time_ms': BenchmarkPropertyPlotData('CPU time', 'cpu time', _less),
- 'time_unit': None,
- 'bytes_per_second': BenchmarkPropertyPlotData('Bytes/s', 'B/s', _more),
- 'items_per_second': BenchmarkPropertyPlotData('items/s', 'items/s', _more),
- 'mega_bytes_per_second': BenchmarkPropertyPlotData('MBytes/s', 'MB/s', _more),
- 'mega_items_per_second': BenchmarkPropertyPlotData('Mega items/s', 'Mega items/s', _more),
- 'counters': None,
- }
-
- def property_plot_data(self, property_name: str):
- pd = copy.deepcopy(__class__._properties.get(property_name, BenchmarkPropertyPlotData()))
- if property_name.endswith('_time'):
- time_unit = first(self.entries).time_unit
- pd.human_name += f' ({time_unit})'
- pd.human_name_short += f' ({time_unit})'
- elif property_name.endswith('_time_ms'):
- pd.human_name += ' (ms)'
- pd.human_name_short += ' (ms)'
- return pd
-
- def extract_plot_series(self, property_name_or_getter,
- relative_to_entry = None,
- percent_of_entry = None,
- ):
- if isinstance(property_name_or_getter, str):
- series = getattr(self, property_name_or_getter)
- else:
- series = property_name_or_getter(self)
- series = list(series)
- def getrefval(ref):
- assert ref in self.entries, ref.name
- pos = self.pos(ref)
- assert pos in range(len(series)), (pos, len(series))
- return series[pos]
- if relative_to_entry:
- refval = getrefval(relative_to_entry)
- for v in series:
- yield v / refval
- elif percent_of_entry:
- refval = getrefval(percent_of_entry)
- for v in series:
- yield 100.0 * ((v - refval) / refval)
- else:
- for v in series:
- yield v
-
- def extract_plot_series_with_threads(self, property_name_or_getter,
- relative_to: str = None,
- percent_of: str = None,
- ):
- series = self.extract_plot_series(property_name_or_getter, relative_to=relative_to, percent_of=percent_of)
- for y, n in zip(series, self.threads):
- yield y, n
-
- def pos(self, entry):
- for i, e in enumerate(self.entries):
- if e == entry:
- return i
- raise Exception("entry not found")
-
- @property
- def filename(self):
- return self._filename
-
- @property
- def basename(self):
- return os.path.basename(self._filename)
-
- @property
- def dirname(self):
- return os.path.dirname(self._filename)
-
- @property
- def entries(self):
- for entry in self.benchmarks:
- yield entry
-
- @property
- def meta(self):
- for entry in self.benchmarks:
- yield entry.meta
-
- @property
- def names(self):
- for entry in self.benchmarks:
- yield entry.name
-
- @property
- def run_names(self):
- for entry in self.benchmarks:
- yield entry.run_name
-
- @property
- def run_types(self):
- for entry in self.benchmarks:
- yield entry.run_type
-
- @property
- def repetitions(self):
- for entry in self.benchmarks:
- yield entry.repetitions
-
- @property
- def repetition_indices(self):
- for entry in self.benchmarks:
- yield entry.repetition_index
-
- @property
- def threads(self):
- for entry in self.benchmarks:
- yield entry.threads
-
- @property
- def iterations(self):
- for entry in self.benchmarks:
- yield entry.iterations
-
- @property
- def real_time(self):
- for entry in self.benchmarks:
- yield entry.real_time
-
- @property
- def cpu_time(self):
- for entry in self.benchmarks:
- yield entry.cpu_time
-
- @property
- def real_time_ms(self):
- for entry in self.benchmarks:
- assert entry.time_unit == "ns"
- yield entry.real_time / 1e6
-
- @property
- def cpu_time_ms(self):
- for entry in self.benchmarks:
- assert entry.time_unit == "ns"
- yield entry.cpu_time / 1e6
-
- @property
- def time_unit(self):
- for entry in self.benchmarks:
- yield entry.time_unit
-
- @property
- def bytes_per_second(self):
- for entry in self.benchmarks:
- yield entry.bytes_per_second
-
- @property
- def items_per_second(self):
- for entry in self.benchmarks:
- yield entry.items_per_second
-
- @property
- def mega_bytes_per_second(self):
- for entry in self.benchmarks:
- yield entry.bytes_per_second / 1e6
-
- @property
- def mega_items_per_second(self):
- for entry in self.benchmarks:
- yield entry.items_per_second / 1e6
-
-
-# ------------------------------------------------------------------------------
-# ------------------------------------------------------------------------------
-# ------------------------------------------------------------------------------
-
-class BenchmarkPanel:
-
- def __init__(self, runs, bm_meta_cls=None):
- self.runs = [BenchmarkRun(a, bm_meta_cls) for a in runs]
-
- @property
- def first_run(self):
- return first(self.runs)
diff --git a/thirdparty/ryml/ext/c4core/cmake/bm-xp/bm_serve.py b/thirdparty/ryml/ext/c4core/cmake/bm-xp/bm_serve.py
deleted file mode 100644
index 6fc683b84..000000000
--- a/thirdparty/ryml/ext/c4core/cmake/bm-xp/bm_serve.py
+++ /dev/null
@@ -1,502 +0,0 @@
-import os
-import sys
-import argparse
-import copy
-import requests
-import flask
-import json
-import re
-import yaml
-import shutil
-import mmh3
-import itertools
-import typing
-import enum
-
-# https://stackoverflow.com/questions/11351032/named-tuple-and-default-values-for-optional-keyword-arguments
-from dataclasses import dataclass
-
-from munch import Munch, munchify
-from flask import render_template, redirect, url_for, send_from_directory
-from markupsafe import escape
-
-from bm_util import *
-
-
-# ------------------------------------------------------------------------------
-# ------------------------------------------------------------------------------
-# ------------------------------------------------------------------------------
-
-class BenchmarkCollection:
-
- @staticmethod
- def create_new(args):
- dir = args.target
- filename = os.path.join(dir, "bm.yml")
- manifest = os.path.join(dir, "manifest.yml")
- if not os.path.exists(dir):
- os.makedirs(dir)
- shutil.copyfile(args.filename, filename)
- dump_yml(load_yml("""{runs: {}, bm: {}}"""), manifest)
- return __class__(dir)
-
- def __init__(self, dir):
- if not os.path.exists(dir):
- raise Exception(f"not found: {dir}")
- self.dir = os.path.abspath(dir)
- self.runs_dir = os.path.join(self.dir, "runs")
- self.manifest = os.path.join(self.dir, "manifest.yml")
- self.filename = os.path.join(self.dir, "bm.yml")
- self.specs = munchify(load_yml_file(self.filename))
- self.manif = munchify(load_yml_file(self.manifest))
-
- def add(self, results_dir):
- results_dir = os.path.abspath(results_dir)
- dst_dir, meta = self._read_run(results_dir)
- self._add_run(results_dir, dst_dir, meta)
- dump_yml(self.manif, self.manifest)
-
- def _read_run(self, results_dir):
- log("adding run...")
- id = f"{len(self.manif.runs.keys()):05d}"
- log(f"adding run: id={id}")
- meta = ResultMeta.load(results_dir)
- dst_dir = os.path.join(self.runs_dir, meta.name)
- return dst_dir, meta
-
- def _add_run(self, results_dir, dst_dir, meta):
- cats = self._add_meta_categories(meta)
- for filename in ("meta.yml",
- "CMakeCCompiler.cmake",
- "CMakeCXXCompiler.cmake",
- "CMakeSystem.cmake",
- "compile_commands.json"):
- filename = os.path.join(results_dir, filename)
- if os.path.exists(filename):
- copy_file_to_dir(filename, dst_dir)
- else:
- if not filename.endswith("compile_commands.json"):
- raise Exception(f"wtf???? {filename}")
- for name, specs in self.specs.bm.items():
- if not hasattr(specs, 'variants'):
- filename = chk(f"{results_dir}/{name}.json")
- dst = copy_file_to_dir(filename, dst_dir)
- self._add_bm_run(name, specs, meta)
- else:
- for t in specs.variants:
- tname = f"{name}-{t}"
- filename = chk(f"{results_dir}/{tname}.json")
- dst = copy_file_to_dir(filename, dst_dir)
- self._add_bm_run(tname, specs, meta)
-
- def _add_bm_run(self, name, specs, meta):
- if name not in self.manif.bm.keys():
- self.manif.bm[name] = Munch(specs=specs, entries=[])
- entry = self.manif.bm[name]
- entry.specs = specs
- if meta.name not in entry.entries:
- entry.entries.append(meta.name)
-
- def _add_meta_categories(self, meta):
- run = Munch()
- for catname in ('commit', 'cpu', 'system', 'build'):
- meta_item = getattr(meta, catname)
- self._add_item_to_category(meta.name, catname, meta_item)
- run[catname] = meta_item.storage_id
- # build specs are too verbose; remove them
- self.manif.build[meta.build.storage_id].specs = Munch()
- self.manif.runs[meta.name] = run
-
- def _add_item_to_category(self, run, category_name, item):
- if not hasattr(self.manif, category_name):
- setattr(self.manif, category_name, Munch())
- category = getattr(self.manif, category_name)
- if item.storage_id not in category.keys():
- category[item.storage_id] = Munch(specs=item, entries=[])
- entry = category[item.storage_id]
- entry.specs = item
- if run not in entry.entries:
- entry.entries.append(run)
-
-
-# -----------------------------------------------------------------------------
-# -----------------------------------------------------------------------------
-# -----------------------------------------------------------------------------
-
-class ResultMeta(Munch):
-
- def __init__(self, results_dir, cmakecache, build_type):
- super().__init__(self)
- self.date = __class__.get_date()
- self.commit = __class__.get_commit(results_dir)
- self.cpu = __class__.get_cpu_info()
- self.system = __class__.get_sys_info()
- self.build = __class__.get_build_info(cmakecache, build_type)
- self.name = self._get_name()
-
- @staticmethod
- def load(results_dir):
- results_dir = os.path.join(os.path.abspath(results_dir), "meta.yml")
- data = load_yml_file(results_dir)
- return munchify(data)
-
- def save(self, results_dir):
- out = os.path.join(results_dir, "meta.yml")
- log("saving meta:", out)
- dump_yml(self, out)
- self.build.save(results_dir)
-
- @staticmethod
- def get_date():
- import datetime
- now = datetime.datetime.now()
- return now.strftime("%Y%m%d-%H%M%S")
-
- def _get_name(self):
- commit = self.commit.storage_name
- cpu = self.cpu.storage_name
- sys = self.system.storage_name
- build = self.build.storage_name
- name = f"{commit}/{cpu}-{sys}-{build}"
- return name
-
- @staticmethod
- def get_commit(results_dir):
- import git
- repo = git.Repo(results_dir, search_parent_directories=True)
- commit = repo.head.commit
- commit = {p: str(getattr(commit, p))
- for p in ('message', 'summary', 'name_rev',
- 'author',
- 'authored_datetime',
- 'committer',
- 'committed_datetime',)}
- commit = Munch(commit)
- commit.message = commit.message.strip()
- commit.sha1 = commit.name_rev[:7]
- spl = commit.authored_datetime.split(" ")
- date = re.sub(r'-', '', spl[0])
- time = re.sub(r'(\d+):(\d+):(\d+).*', r'\1\2\3', spl[1])
- commit.storage_id = commit.sha1
- commit.storage_name = f"git{date}_{time}-{commit.sha1}"
- return commit
-
- @staticmethod
- def get_cpu_info():
- import cpuinfo
- nfo = cpuinfo.get_cpu_info()
- nfo = Munch(nfo)
- for a in ('cpu_version', 'cpu_version_string', 'python_version'):
- if hasattr(nfo, a):
- delattr(nfo, a)
- for a in ('arch_string_raw', 'brand_raw', 'hardware_raw', 'vendor_id_raw'):
- if not hasattr(nfo, a):
- setattr(nfo, a, '')
- nfo.storage_id = myhash(
- nfo.arch_string_raw, nfo.brand_raw, nfo.hardware_raw, nfo.vendor_id_raw,
- nfo.arch, nfo.bits, nfo.count, nfo.family, nfo.model, nfo.stepping,
- ",".join(nfo.flags), nfo.hz_advertised_friendly,
- nfo.l2_cache_associativity,
- nfo.l2_cache_line_size,
- nfo.l2_cache_size,
- nfo.l3_cache_size,
- *optionals('l1_data_cache_size', 'l1_instruction_cache_size')
- )
- nfo.storage_name = f"{nfo.arch.lower()}_{nfo.storage_id}"
- return nfo
-
- @staticmethod
- def get_sys_info():
- import platform
- uname = platform.uname()
- nfo = Munch(
- sys_platform=sys.platform,
- sys=platform.system(),
- uname=Munch(
- machine=uname.machine,
- node=uname.node,
- release=uname.release,
- system=uname.system,
- version=uname.version,
- )
- )
- nfo.storage_id = myhash(
- nfo.sys_platform,
- nfo.uname.machine,
- )
- nfo.storage_name = f"{nfo.sys_platform}_{nfo.storage_id}"
- return nfo
-
- @staticmethod
- def get_build_info(cmakecache_txt, buildtype):
- nfo = CMakeCache(cmakecache_txt)
- def _btflags(name):
- return (getattr(nfo, name), getattr(nfo, f"{name}_{buildtype.upper()}"))
- nfo.storage_id = myhash(
- buildtype,
- nfo.CMAKE_CXX_COMPILER_ID,
- nfo.CMAKE_CXX_COMPILER_VERSION,
- nfo.CMAKE_CXX_COMPILER_VERSION_INTERNAL,
- nfo.CMAKE_CXX_COMPILER_ABI,
- nfo.CMAKE_CXX_SIZEOF_DATA_PTR,
- nfo.CMAKE_C_COMPILER_ID,
- nfo.CMAKE_C_COMPILER_VERSION,
- nfo.CMAKE_C_COMPILER_VERSION_INTERNAL,
- nfo.CMAKE_C_COMPILER_ABI,
- nfo.CMAKE_C_SIZEOF_DATA_PTR,
- *_btflags("CMAKE_CXX_FLAGS"),
- *_btflags("CMAKE_C_FLAGS"),
- *_btflags("CMAKE_STATIC_LINKER_FLAGS"),
- *_btflags("CMAKE_SHARED_LINKER_FLAGS"),
- )
- #
- ccname = nfo.CMAKE_CXX_COMPILER_ID.lower()
- if ccname == "gnu":
- ccname = "gcc"
- ccname += nfo.CMAKE_CXX_COMPILER_VERSION.lower()
- #
- if nfo.CMAKE_C_SIZEOF_DATA_PTR == "4":
- bits = "32bit"
- elif nfo.CMAKE_C_SIZEOF_DATA_PTR == "8":
- bits = "64bit"
- else:
- raise Exception("unknown architecture")
- #
- nfo.storage_name = f"{bits}_{buildtype}_{ccname}_{nfo.storage_id}"
- return nfo
-
-
-# -----------------------------------------------------------------------------
-# -----------------------------------------------------------------------------
-# -----------------------------------------------------------------------------
-
-class CMakeCache(Munch):
-
- def __init__(self, cmakecache_txt):
- import glob
- for line in iter_cmake_lines(cmakecache_txt):
- spl = line.split("=")
- if len(spl) < 2:
- continue
- k, ty = spl[0].split(":")
- v = "=".join(spl[1:]).strip()
- setattr(self, k, v)
- bdir = os.path.dirname(os.path.abspath(cmakecache_txt))
- self._c_compiler_file = sorted(glob.glob(f"{bdir}/CMakeFiles/*/CMakeCCompiler.cmake"))[-1] # get the last
- self._cxx_compiler_file = sorted(glob.glob(f"{bdir}/CMakeFiles/*/CMakeCXXCompiler.cmake"))[-1] # get the last
- self._system_file = sorted(glob.glob(f"{bdir}/CMakeFiles/*/CMakeSystem.cmake"))[-1] # get the last
- self._load_cmake_file(self._c_compiler_file)
- self._load_cmake_file(self._cxx_compiler_file)
- ccomfile = f"{bdir}/compile_commands.json"
- self._compile_commands_file = ccomfile if os.path.exists(ccomfile) else None
-
- def _load_cmake_file(self, filename):
- for line in iter_cmake_lines(filename):
- if not line.startswith("set("):
- continue
- k = re.sub(r"set\((.*)\ +(.*)\)", r"\1", line)
- v = re.sub(r"set\((.*)\ +(.*)\)", r"\2", line)
- v = v.strip('"').strip("'").strip()
- setattr(self, k, v)
-
- def save(self, results_dir):
- copy_file_to_dir(self._c_compiler_file, results_dir)
- copy_file_to_dir(self._cxx_compiler_file, results_dir)
- copy_file_to_dir(self._system_file, results_dir)
- if self._compile_commands_file is not None:
- copy_file_to_dir(self._compile_commands_file, results_dir)
-
-
-def iter_cmake_lines(filename):
- with open(filename) as f:
- for line in f.readlines():
- line = line.strip()
- if line.startswith("#") or line.startswith("//") or len(line) == 0:
- continue
- yield line
-
-
-# --------------------------------------------------------
-
-
-def get_manifest(args):
- bmdir = os.path.abspath(args.bmdir)
- if not args.manifest:
- manifest_yml = os.path.join(bmdir, "manifest.yml")
- else:
- if not os.path.isabs(args.manifest):
- manifest_yml = os.path.join(os.getcwd(), args.manifest)
- manifest_json = os.path.join(os.path.dirname(manifest.yml), "manifest.json")
- manifest = load_yml_file(manifest_yml)
- dump_json(manifest, manifest_json)
- return manifest
-
-
-def add_results(args):
- log("adding results:", args.results)
- col = BenchmarkCollection(args.target)
- col.add(args.results)
-
-
-def add_meta(args):
- log("adding bm run metadata to results dir:", args.results)
- meta = ResultMeta(results_dir=args.results,
- cmakecache=args.cmakecache,
- build_type=args.build_type)
- meta.save(args.results)
- log("adding bm run metadata to results dir: success!")
-
-
-# ------------------------------------------------------------------------------
-# ------------------------------------------------------------------------------
-# ------------------------------------------------------------------------------
-
-app = flask.Flask(__name__, template_folder='template')
-
-def _setup_app(args):
- def _s(prop, val):
- assert not hasattr(app, prop), prop
- setattr(app, prop, val)
- _s('args', args)
- _s('manifest', get_manifest(args))
- if args.debug:
- app.config["DEBUG"] = True
-
-
-def freeze(args):
- "https://pythonhosted.org/Frozen-Flask/"
- from flask_frozen import Freezer
- _setup_app(args)
- freezer = Freezer(app)
- freezer.freeze(debug=args.debug)
-
-
-def serve(args):
- _setup_app(args)
- app.run(host=args.host, port=args.port, debug=args.debug)
-
-
-def home():
- log("requested home")
- return render_template("index.html")
-
-
-def other_(path):
- path = escape(path)
- d = app.args.bmdir
- log("requested other path:", path, "---", os.path.join(d, path))
- return send_from_directory(d, path)
-
-
[email protected]("/static/<path>")
-def static_(path):
- path = escape(path)
- d = os.path.join(app.args.bmdir, "static")
- log("requested static path:", path, "---", os.path.join(d, path))
- return send_from_directory(d, path, cache_timeout=1) # timeout in seconds
-
-
[email protected]("/bm/<commit>/<run>/<resultjson>")
-def bm_(commit, run, resultjson):
- commit = escape(commit)
- run = escape(run)
- resultjson = escape(resultjson)
- d = os.path.join(app.args.bmdir, "runs", commit, run)
- log("requested result:", os.path.join(d, resultjson))
- return send_from_directory(d, resultjson, cache_timeout=1) # timeout in seconds
-
-
-# ------------------------------------------------------------------------------
-# ------------------------------------------------------------------------------
-# ------------------------------------------------------------------------------
-
-def download_deps():
- deps = [
- "https://code.jquery.com/jquery-3.3.1.js",
- "https://code.jquery.com/jquery-3.3.1.js",
- "https://code.jquery.com/ui/1.12.1/jquery-ui.js",
- "https://cdn.datatables.net/1.10.20/js/jquery.dataTables.js",
- "https://cdn.datatables.net/1.10.20/js/jquery.dataTables.min.js",
- "https://cdn.datatables.net/1.10.20/css/jquery.dataTables.css",
- "https://cdn.datatables.net/1.10.20/css/jquery.dataTables.min.css",
- "https://www.chartjs.org/dist/2.9.1/Chart.min.js",
- #("https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.3.2/styles/github.css", "highlight.github.css"),
- ("https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.3.2/styles/github.min.css", "highlight.github.min.css"),
- #"https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.3.2/highlight.js",
- "https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.3.2/highlight.min.js",
- ]
- for src in deps:
- if type(src) == str:
- base = os.path.basename(src)
- else:
- src, base = src
- dst = f"{os.getcwd()}/static/{base}"
- download_url(src, dst)
-
-
-def download_url(url, dst):
- log("download url:", url, "--->", dst)
- req = requests.get(url, stream=True)
- if req.status_code == 200:
- sz = 0
- with open(dst, 'wb') as f:
- for chunk in req:
- f.write(chunk)
- sz += len(chunk)
- log(f"........ finished: {sz}B")
- else:
- log(f" error:", req.status_code, url)
-
-
-
-def main():
- def _common_args(parser):
- parser.add_argument("-m", "--manifest", type=str, default="", help="enable debug mode")
- parser.add_argument("--debug", action="store_true", help="enable debug mode")
- #
- parser = argparse.ArgumentParser(description="Browse benchmark results", prog="bm")
- _common_args(parser)
- subparsers = parser.add_subparsers()
- #
- sp = subparsers.add_parser("create", help="create benchmark collection")
- _common_args(sp)
- sp.add_argument("--debug", action="store_true", help="enable debug mode")
- sp.add_argument("filename", type=str, help="the YAML file with the benchmark specs")
- sp.add_argument("target", type=str, help="the directory to store the results")
- #
- sp = subparsers.add_parser("meta", help="get the required meta-information: cpu info, commit data")
- _common_args(sp)
- sp.add_argument("--debug", action="store_true", help="enable debug mode")
- sp.add_argument("results", type=str, help="the directory with the results")
- sp.add_argument("cmakecache", type=str, help="the path to the CMakeCache.txt file used to build the benchmark binaries")
- sp.add_argument("build_type", type=str, help="the build type, eg Release Debug MinSizeRel RelWithDebInfo")
- #
- sp = subparsers.add_parser("add", help="add benchmark results")
- _common_args(sp)
- sp.add_argument("--debug", action="store_true", help="enable debug mode")
- sp.add_argument("results", type=str, help="the directory with the results")
- sp.add_argument("target", type=str, help="the directory to store the results")
- #
- sp = subparsers.add_parser("serve", help="serve benchmark results")
- _common_args(sp)
- sp.add_argument("--debug", action="store_true", help="enable debug mode")
- sp.add_argument("bmdir", type=os.path.abspath, default=os.getcwd(), help="the directory with the results. default=.")
- sp.add_argument("-H", "--host", type=str, default="localhost", help="host. default=%(default)s")
- sp.add_argument("-p", "--port", type=int, default=8000, help="port. default=%(default)s")
- #
- sp = subparsers.add_parser("export", help="export static html")
- sp.set_defaults(func=freeze)
- sp.add_argument("bmdir", type=os.path.abspath, default=os.getcwd(), help="the directory with the results. default=.")
- _common_args(sp)
- #
- sp = subparsers.add_parser("deps", help="install server dependencies")
- sp.set_defaults(func=lambda _: download_deps())
- sp.add_argument("--debug", action="store_true", help="enable debug mode")
- _common_args(sp)
- #
- args = parser.parse_args(sys.argv[1:] if len(sys.argv) > 1 else ["serve"])
- if args.debug:
- log(args)
- args.func(args)
diff --git a/thirdparty/ryml/ext/c4core/cmake/bm-xp/bm_util.py b/thirdparty/ryml/ext/c4core/cmake/bm-xp/bm_util.py
deleted file mode 100644
index 7c7c2891e..000000000
--- a/thirdparty/ryml/ext/c4core/cmake/bm-xp/bm_util.py
+++ /dev/null
@@ -1,147 +0,0 @@
-import os
-import json
-import yaml
-import shutil
-import mmh3
-import itertools
-import munch
-import enum
-
-
-# --------------------------------------------------------
-
-class _enum(enum.Enum):
- def __str__(self):
- return str(self.name)
-
- @property
- def short(self):
- return self.name
-
- @classmethod
- def make(cls, s):
- try:
- return cls[s]
- except:
- cls.err_unknown(s)
-
- @classmethod
- def err_unknown(cls, s):
- raise Exception(f"unknown {__class__.__name__}: {s}")
-
-
-class FundamentalTypes(_enum):
- float = "float"
- double = "double"
- int8_t = "int8_t"
- uint8_t = "uint8_t"
- int16_t = "int16_t"
- uint16_t = "uint16_t"
- int32_t = "int32_t"
- uint32_t = "uint32_t"
- int64_t = "int64_t"
- uint64_t = "uint64_t"
- @property
- def short(self):
- return self.name.replace("uint", "u").replace("int", "i").replace("_t", "")
-
-
-# --------------------------------------------------------
-
-def log(*args, **kwargs):
- print(*args, **kwargs, flush=True)
-
-
-def myhash_combine(curr, value):
- return curr ^ (value + 0x9e3779b9 + (curr << 6) + (curr >> 2))
-
-
-def first(iterable):
- """Returns the first item"""
- if isinstance(iterable, list):
- return iterable[0]
- return next(iterable)
-
-
-def chain(*iterables):
- for it in iterables:
- for elm in it:
- yield elm
-
-
-def nth(iterable, n, default=None):
- """Returns the nth item or a default value"""
- return next(itertools.islice(iterable, n, None), default)
-
-
-def optionals(obj, *attrs):
- ret = []
- for attr in attrs:
- if not hasattr(obj, attr):
- log("attr not present:", attr)
- continue
- ret.append(getattr(obj, attr))
- return ret
-
-
-def myhash(*args):
- h = 137597
- for a in args:
- if isinstance(a, str):
- if a == "":
- continue
- b = bytes(a, "utf8")
- else:
- b = bytes(a)
- hb = mmh3.hash(b, signed=False)
- h = myhash_combine(h, hb)
- s = hex(h)
- return s[2:min(10, len(s))]
-
-
-def copy_file_to_dir(file, dir):
- dir = os.path.abspath(dir)
- src = os.path.abspath(file)
- dst = f"{dir}/{os.path.basename(src)}"
- if not os.path.exists(dir):
- os.makedirs(dir)
- if os.path.exists(dst):
- os.remove(dst)
- log("copy:", src, "-->", dst)
- shutil.copy(src, dst)
- return dst
-
-
-def chk(f):
- log("looking for file:", f)
- assert os.path.exists(f), f
- return f
-
-
-def load_yml_file(filename):
- if not os.path.exists(filename):
- raise Exception(f"not found: {filename}")
- with open(filename) as f:
- return load_yml(f.read())
-
-
-def dump_yml(data, filename):
- with open(filename, "w") as f:
- yaml.safe_dump(data, f)
-
-
-def load_yml(yml):
- return munch.munchify(yaml.safe_load(yml))
-
-
-def dump_json(data, filename):
- with open(filename, "w") as f:
- f.write(json.dumps(data, indent=2, sort_keys=True))
-
-
-def load_json(filename):
- with open(filename, "r") as f:
- try:
- return munch.munchify(json.load(f))
- except Exception as exc:
- raise Exception(f"could not load file: {filename}: {exc}")
diff --git a/thirdparty/ryml/ext/c4core/cmake/bm-xp/example_c4core.py b/thirdparty/ryml/ext/c4core/cmake/bm-xp/example_c4core.py
deleted file mode 100644
index 3db4175cb..000000000
--- a/thirdparty/ryml/ext/c4core/cmake/bm-xp/example_c4core.py
+++ /dev/null
@@ -1,1061 +0,0 @@
-import os
-import sys
-import argparse
-import copy
-import requests
-import flask
-import json
-import re
-import yaml
-import shutil
-import mmh3
-from itertools import islice
-
-from munch import Munch, munchify
-from flask import render_template, redirect, url_for, send_from_directory
-from markupsafe import escape
-
-
-def log(*args, **kwargs):
- print(*args, **kwargs, flush=True)
-
-
-def myhash_combine(curr, value):
- return curr ^ (value + 0x9e3779b9 + (curr<<6) + (curr>>2))
-
-
-def nth(iterable, n, default=None):
- "Returns the nth item or a default value"
- return next(islice(iterable, n, None), default)
-
-
-def optionals(obj, *attrs):
- ret = []
- for attr in attrs:
- if not hasattr(obj, attr):
- log("attr not present:", attr)
- continue
- ret.append(getattr(obj, attr))
- return ret
-
-
-def myhash(*args):
- h = 137597
- for a in args:
- if isinstance(a, str):
- if a == "":
- continue
- b = bytes(a, "utf8")
- else:
- b = bytes(a)
- hb = mmh3.hash(b, signed=False)
- h = myhash_combine(h, hb)
- s = hex(h)
- return s[2:min(10, len(s))]
-
-
-def copy_file_to_dir(file, dir):
- dir = os.path.abspath(dir)
- src = os.path.abspath(file)
- dst = f"{dir}/{os.path.basename(src)}"
- if not os.path.exists(dir):
- os.makedirs(dir)
- if os.path.exists(dst):
- os.remove(dst)
- log("copy:", src, "-->", dst)
- shutil.copy(src, dst)
- return dst
-
-
-def chk(f):
- log(f"looking for file:", f)
- assert os.path.exists(f), f
- return f
-
-
-def load_yml_file(filename):
- if not os.path.exists(filename):
- raise Exception(f"not found: {filename}")
- with open(filename) as f:
- return load_yml(f.read())
-
-
-def dump_yml(data, filename):
- with open(filename, "w") as f:
- yaml.safe_dump(data, f)
-
-
-def load_yml(yml):
- return munchify(yaml.safe_load(yml))
-
-
-def dump_json(data, filename):
- with open(filename, "w") as f:
- f.write(json.dumps(data, indent=2, sort_keys=True))
-
-
-def load_json(filename):
- with open(filename, "r") as f:
- try:
- return munchify(json.load(f))
- except Exception as exc:
- raise Exception(f"could not load file: {filename}: {exc}")
-
-
-def main():
- def _common_args(parser):
- parser.add_argument("-m", "--manifest", type=str, default="", help="enable debug mode")
- parser.add_argument("--debug", action="store_true", help="enable debug mode")
- #
- parser = argparse.ArgumentParser(description="Browse benchmark results", prog="bm")
- _common_args(parser)
- subparsers = parser.add_subparsers()
- #
- sp = subparsers.add_parser("create", help="create benchmark collection")
- _common_args(sp)
- sp.add_argument("--debug", action="store_true", help="enable debug mode")
- sp.add_argument("filename", type=str, help="the YAML file with the benchmark specs")
- sp.add_argument("target", type=str, help="the directory to store the results")
- #
- sp = subparsers.add_parser("meta", help="get the required meta-information: cpu info, commit data")
- _common_args(sp)
- sp.add_argument("--debug", action="store_true", help="enable debug mode")
- sp.add_argument("results", type=str, help="the directory with the results")
- sp.add_argument("cmakecache", type=str, help="the path to the CMakeCache.txt file used to build the benchmark binaries")
- sp.add_argument("build_type", type=str, help="the build type, eg Release Debug MinSizeRel RelWithDebInfo")
- #
- sp = subparsers.add_parser("add", help="add benchmark results")
- _common_args(sp)
- sp.add_argument("--debug", action="store_true", help="enable debug mode")
- sp.add_argument("results", type=str, help="the directory with the results")
- sp.add_argument("target", type=str, help="the directory to store the results")
- #
- sp = subparsers.add_parser("serve", help="serve benchmark results")
- _common_args(sp)
- sp.add_argument("--debug", action="store_true", help="enable debug mode")
- sp.add_argument("bmdir", type=os.path.abspath, default=os.getcwd(), help="the directory with the results. default=.")
- sp.add_argument("-H", "--host", type=str, default="localhost", help="host. default=%(default)s")
- sp.add_argument("-p", "--port", type=int, default=8000, help="port. default=%(default)s")
- #
- sp = subparsers.add_parser("export", help="export static html")
- sp.set_defaults(func=freeze)
- sp.add_argument("bmdir", type=os.path.abspath, default=os.getcwd(), help="the directory with the results. default=.")
- _common_args(sp)
- #
- sp = subparsers.add_parser("deps", help="install server dependencies")
- sp.set_defaults(func=lambda _: download_deps())
- sp.add_argument("--debug", action="store_true", help="enable debug mode")
- _common_args(sp)
- #
- args = parser.parse_args(sys.argv[1:] if len(sys.argv) > 1 else ["serve"])
- if args.debug:
- log(args)
- args.func(args)
-
-
-def get_manifest(args):
- bmdir = os.path.abspath(args.bmdir)
- if not args.manifest:
- manifest_yml = os.path.join(bmdir, "manifest.yml")
- else:
- if not os.path.isabs(args.manifest):
- manifest_yml = os.path.join(os.getcwd(), args.manifest)
- manifest_json = os.path.join(os.path.dirname(manifest.yml), "manifest.json")
- manifest = load_yml_file(manifest_yml)
- dump_json(manifest, manifest_json)
- return manifest
-
-
-# ------------------------------------------------------------------------------
-# ------------------------------------------------------------------------------
-# ------------------------------------------------------------------------------
-
-app = flask.Flask(__name__,
- template_folder='template')
-
-
-def _setup_app(args):
- def _s(prop, val):
- assert not hasattr(app, prop), prop
- setattr(app, prop, val)
- _s('args', args)
- _s('manifest', get_manifest(args))
- if args.debug:
- app.config["DEBUG"] = True
-
-
-def freeze(args):
- "https://pythonhosted.org/Frozen-Flask/"
- from flask_frozen import Freezer
- _setup_app(args)
- freezer = Freezer(app)
- freezer.freeze(debug=args.debug)
-
-
-def serve(args):
- _setup_app(args)
- app.run(host=args.host, port=args.port, debug=args.debug)
-
-
-def home():
- log("requested home")
- return render_template("index.html")
-
-
-def other_(path):
- path = escape(path)
- d = app.args.bmdir
- log("requested other path:", path, "---", os.path.join(d, path))
- return send_from_directory(d, path)
-
-
[email protected]("/static/<path>")
-def static_(path):
- path = escape(path)
- d = os.path.join(app.args.bmdir, "static")
- log("requested static path:", path, "---", os.path.join(d, path))
- return send_from_directory(d, path, cache_timeout=1) # timeout in seconds
-
-
[email protected]("/bm/<commit>/<run>/<resultjson>")
-def bm_(commit, run, resultjson):
- commit = escape(commit)
- run = escape(run)
- resultjson = escape(resultjson)
- d = os.path.join(app.args.bmdir, "runs", commit, run)
- log("requested result:", os.path.join(d, resultjson))
- return send_from_directory(d, resultjson, cache_timeout=1) # timeout in seconds
-
-
-# ------------------------------------------------------------------------------
-# ------------------------------------------------------------------------------
-# ------------------------------------------------------------------------------
-
-def download_deps():
- deps = [
- "https://code.jquery.com/jquery-3.3.1.js",
- "https://code.jquery.com/jquery-3.3.1.js",
- "https://code.jquery.com/ui/1.12.1/jquery-ui.js",
- "https://cdn.datatables.net/1.10.20/js/jquery.dataTables.js",
- "https://cdn.datatables.net/1.10.20/js/jquery.dataTables.min.js",
- "https://cdn.datatables.net/1.10.20/css/jquery.dataTables.css",
- "https://cdn.datatables.net/1.10.20/css/jquery.dataTables.min.css",
- "https://www.chartjs.org/dist/2.9.1/Chart.min.js",
- #("https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.3.2/styles/github.css", "highlight.github.css"),
- ("https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.3.2/styles/github.min.css", "highlight.github.min.css"),
- #"https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.3.2/highlight.js",
- "https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.3.2/highlight.min.js",
- ]
- for src in deps:
- if type(src) == str:
- base = os.path.basename(src)
- else:
- src, base = src
- dst = f"{os.getcwd()}/static/{base}"
- download_url(src, dst)
-
-
-def download_url(url, dst):
- log("download url:", url, "--->", dst)
- req = requests.get(url, stream=True)
- if req.status_code == 200:
- sz = 0
- with open(dst, 'wb') as f:
- for chunk in req:
- f.write(chunk)
- sz += len(chunk)
- log(f"........ finished: {sz}B")
- else:
- log(f" error:", req.status_code, url)
-
-
-# ------------------------------------------------------------------------------
-# ------------------------------------------------------------------------------
-# ------------------------------------------------------------------------------
-
-class BenchmarkCollection:
-
- @staticmethod
- def create_new(args):
- dir = args.target
- filename = os.path.join(dir, "bm.yml")
- manifest = os.path.join(dir, "manifest.yml")
- if not os.path.exists(dir):
- os.makedirs(dir)
- shutil.copyfile(args.filename, filename)
- dump_yml(load_yml("""{runs: {}, bm: {}}"""), manifest)
- return __class__(dir)
-
- def __init__(self, dir):
- if not os.path.exists(dir):
- raise Exception(f"not found: {dir}")
- self.dir = os.path.abspath(dir)
- self.runs_dir = os.path.join(self.dir, "runs")
- self.manifest = os.path.join(self.dir, "manifest.yml")
- self.filename = os.path.join(self.dir, "bm.yml")
- self.specs = munchify(load_yml_file(self.filename))
- self.manif = munchify(load_yml_file(self.manifest))
-
- def add(self, results_dir):
- results_dir = os.path.abspath(results_dir)
- dst_dir, meta = self._read_run(results_dir)
- self._add_run(results_dir, dst_dir, meta)
- dump_yml(self.manif, self.manifest)
-
- def _read_run(self, results_dir):
- log("adding run...")
- id = f"{len(self.manif.runs.keys()):05d}"
- log(f"adding run: id={id}")
- meta = ResultMeta.load(results_dir)
- dst_dir = os.path.join(self.runs_dir, meta.name)
- return dst_dir, meta
-
- def _add_run(self, results_dir, dst_dir, meta):
- cats = self._add_meta_categories(meta)
- for filename in ("meta.yml",
- "CMakeCCompiler.cmake",
- "CMakeCXXCompiler.cmake",
- "CMakeSystem.cmake",
- "compile_commands.json"):
- filename = os.path.join(results_dir, filename)
- if os.path.exists(filename):
- copy_file_to_dir(filename, dst_dir)
- else:
- if not filename.endswith("compile_commands.json"):
- raise Exception(f"wtf???? {filename}")
- for name, specs in self.specs.bm.items():
- if not hasattr(specs, 'variants'):
- filename = chk(f"{results_dir}/{name}.json")
- dst = copy_file_to_dir(filename, dst_dir)
- self._add_bm_run(name, specs, meta)
- else:
- for t in specs.variants:
- tname = f"{name}-{t}"
- filename = chk(f"{results_dir}/{tname}.json")
- dst = copy_file_to_dir(filename, dst_dir)
- self._add_bm_run(tname, specs, meta)
-
- def _add_bm_run(self, name, specs, meta):
- if name not in self.manif.bm.keys():
- self.manif.bm[name] = Munch(specs=specs, entries=[])
- entry = self.manif.bm[name]
- entry.specs = specs
- if meta.name not in entry.entries:
- entry.entries.append(meta.name)
-
- def _add_meta_categories(self, meta):
- run = Munch()
- for catname in ('commit', 'cpu', 'system', 'build'):
- meta_item = getattr(meta, catname)
- self._add_item_to_category(meta.name, catname, meta_item)
- run[catname] = meta_item.storage_id
- # build specs are too verbose; remove them
- self.manif.build[meta.build.storage_id].specs = Munch()
- self.manif.runs[meta.name] = run
-
- def _add_item_to_category(self, run, category_name, item):
- if not hasattr(self.manif, category_name):
- setattr(self.manif, category_name, Munch())
- category = getattr(self.manif, category_name)
- if item.storage_id not in category.keys():
- category[item.storage_id] = Munch(specs=item, entries=[])
- entry = category[item.storage_id]
- entry.specs = item
- if run not in entry.entries:
- entry.entries.append(run)
-
-
-# -----------------------------------------------------------------------------
-# -----------------------------------------------------------------------------
-# -----------------------------------------------------------------------------
-
-class ResultMeta(Munch):
-
- def __init__(self, results_dir, cmakecache, build_type):
- super().__init__(self)
- self.date = __class__.get_date()
- self.commit = __class__.get_commit(results_dir)
- self.cpu = __class__.get_cpu_info()
- self.system = __class__.get_sys_info()
- self.build = __class__.get_build_info(cmakecache, build_type)
- self.name = self._get_name()
-
- @staticmethod
- def load(results_dir):
- results_dir = os.path.join(os.path.abspath(results_dir), "meta.yml")
- data = load_yml_file(results_dir)
- return munchify(data)
-
- def save(self, results_dir):
- out = os.path.join(results_dir, "meta.yml")
- log("saving meta:", out)
- dump_yml(self, out)
- self.build.save(results_dir)
-
- @staticmethod
- def get_date():
- import datetime
- now = datetime.datetime.now()
- return now.strftime("%Y%m%d-%H%M%S")
-
- def _get_name(self):
- commit = self.commit.storage_name
- cpu = self.cpu.storage_name
- sys = self.system.storage_name
- build = self.build.storage_name
- name = f"{commit}/{cpu}-{sys}-{build}"
- return name
-
- @staticmethod
- def get_commit(results_dir):
- import git
- repo = git.Repo(results_dir, search_parent_directories=True)
- commit = repo.head.commit
- commit = {p: str(getattr(commit, p))
- for p in ('message', 'summary', 'name_rev',
- 'author',
- 'authored_datetime',
- 'committer',
- 'committed_datetime',)}
- commit = Munch(commit)
- commit.message = commit.message.strip()
- commit.sha1 = commit.name_rev[:7]
- spl = commit.authored_datetime.split(" ")
- date = re.sub(r'-', '', spl[0])
- time = re.sub(r'(\d+):(\d+):(\d+).*', r'\1\2\3', spl[1])
- commit.storage_id = commit.sha1
- commit.storage_name = f"git{date}_{time}-{commit.sha1}"
- return commit
-
- @staticmethod
- def get_cpu_info():
- import cpuinfo
- nfo = cpuinfo.get_cpu_info()
- nfo = Munch(nfo)
- for a in ('cpu_version', 'cpu_version_string', 'python_version'):
- if hasattr(nfo, a):
- delattr(nfo, a)
- for a in ('arch_string_raw', 'brand_raw', 'hardware_raw', 'vendor_id_raw'):
- if not hasattr(nfo, a):
- setattr(nfo, a, '')
- nfo.storage_id = myhash(
- nfo.arch_string_raw, nfo.brand_raw, nfo.hardware_raw, nfo.vendor_id_raw,
- nfo.arch, nfo.bits, nfo.count, nfo.family, nfo.model, nfo.stepping,
- ",".join(nfo.flags), nfo.hz_advertised_friendly,
- nfo.l2_cache_associativity,
- nfo.l2_cache_line_size,
- nfo.l2_cache_size,
- nfo.l3_cache_size,
- *optionals('l1_data_cache_size', 'l1_instruction_cache_size')
- )
- nfo.storage_name = f"{nfo.arch.lower()}_{nfo.storage_id}"
- return nfo
-
- @staticmethod
- def get_sys_info():
- import platform
- uname = platform.uname()
- nfo = Munch(
- sys_platform=sys.platform,
- sys=platform.system(),
- uname=Munch(
- machine=uname.machine,
- node=uname.node,
- release=uname.release,
- system=uname.system,
- version=uname.version,
- )
- )
- nfo.storage_id = myhash(
- nfo.sys_platform,
- nfo.uname.machine,
- )
- nfo.storage_name = f"{nfo.sys_platform}_{nfo.storage_id}"
- return nfo
-
- @staticmethod
- def get_build_info(cmakecache_txt, buildtype):
- nfo = CMakeCache(cmakecache_txt)
- def _btflags(name):
- return (getattr(nfo, name), getattr(nfo, f"{name}_{buildtype.upper()}"))
- nfo.storage_id = myhash(
- buildtype,
- nfo.CMAKE_CXX_COMPILER_ID,
- nfo.CMAKE_CXX_COMPILER_VERSION,
- nfo.CMAKE_CXX_COMPILER_VERSION_INTERNAL,
- nfo.CMAKE_CXX_COMPILER_ABI,
- nfo.CMAKE_CXX_SIZEOF_DATA_PTR,
- nfo.CMAKE_C_COMPILER_ID,
- nfo.CMAKE_C_COMPILER_VERSION,
- nfo.CMAKE_C_COMPILER_VERSION_INTERNAL,
- nfo.CMAKE_C_COMPILER_ABI,
- nfo.CMAKE_C_SIZEOF_DATA_PTR,
- *_btflags("CMAKE_CXX_FLAGS"),
- *_btflags("CMAKE_C_FLAGS"),
- *_btflags("CMAKE_STATIC_LINKER_FLAGS"),
- *_btflags("CMAKE_SHARED_LINKER_FLAGS"),
- )
- #
- ccname = nfo.CMAKE_CXX_COMPILER_ID.lower()
- if ccname == "gnu":
- ccname = "gcc"
- ccname += nfo.CMAKE_CXX_COMPILER_VERSION.lower()
- #
- if nfo.CMAKE_C_SIZEOF_DATA_PTR == "4":
- bits = "32bit"
- elif nfo.CMAKE_C_SIZEOF_DATA_PTR == "8":
- bits = "64bit"
- else:
- raise Exception("unknown architecture")
- #
- nfo.storage_name = f"{bits}_{buildtype}_{ccname}_{nfo.storage_id}"
- return nfo
-
-
-# -----------------------------------------------------------------------------
-# -----------------------------------------------------------------------------
-# -----------------------------------------------------------------------------
-
-class CMakeCache(Munch):
-
- def __init__(self, cmakecache_txt):
- import glob
- for line in iter_cmake_lines(cmakecache_txt):
- spl = line.split("=")
- if len(spl) < 2:
- continue
- k, ty = spl[0].split(":")
- v = "=".join(spl[1:]).strip()
- setattr(self, k, v)
- bdir = os.path.dirname(os.path.abspath(cmakecache_txt))
- self._c_compiler_file = sorted(glob.glob(f"{bdir}/CMakeFiles/*/CMakeCCompiler.cmake"))[-1] # get the last
- self._cxx_compiler_file = sorted(glob.glob(f"{bdir}/CMakeFiles/*/CMakeCXXCompiler.cmake"))[-1] # get the last
- self._system_file = sorted(glob.glob(f"{bdir}/CMakeFiles/*/CMakeSystem.cmake"))[-1] # get the last
- self._load_cmake_file(self._c_compiler_file)
- self._load_cmake_file(self._cxx_compiler_file)
- ccomfile = f"{bdir}/compile_commands.json"
- self._compile_commands_file = ccomfile if os.path.exists(ccomfile) else None
-
- def _load_cmake_file(self, filename):
- for line in iter_cmake_lines(filename):
- if not line.startswith("set("):
- continue
- k = re.sub(r"set\((.*)\ +(.*)\)", r"\1", line)
- v = re.sub(r"set\((.*)\ +(.*)\)", r"\2", line)
- v = v.strip('"').strip("'").strip()
- setattr(self, k, v)
-
- def save(self, results_dir):
- copy_file_to_dir(self._c_compiler_file, results_dir)
- copy_file_to_dir(self._cxx_compiler_file, results_dir)
- copy_file_to_dir(self._system_file, results_dir)
- if self._compile_commands_file is not None:
- copy_file_to_dir(self._compile_commands_file, results_dir)
-
-
-def iter_cmake_lines(filename):
- with open(filename) as f:
- for line in f.readlines():
- line = line.strip()
- if line.startswith("#") or line.startswith("//") or len(line) == 0:
- continue
- yield line
-
-
-# ------------------------------------------------------------------------------
-# ------------------------------------------------------------------------------
-# ------------------------------------------------------------------------------
-
-class BenchmarkRun(Munch):
- "results of an individual run"
-
- def __init__(self, json_file, meta_class):
- props = load_json(json_file)
- setattr(self, "filename", json_file)
- assert hasattr(props, "context")
- assert hasattr(props, "benchmarks")
- super().__init__(**props)
- for e in self.benchmarks:
- setattr(e, 'meta', meta_class(e.name))
- setattr(self, 'property_names', (
- 'meta',
- 'shorttitle',
- 'name',
- 'run_name',
- 'run_type',
- 'repetitions',
- 'repetition_index',
- 'repetition_index',
- 'threads',
- 'iterations',
- 'real_time',
- 'cpu_time',
- 'time_unit',
- 'bytes_per_second',
- 'items_per_second',
- 'counters',
- ))
-
- @property
- def first(self):
- return self.benchmarks[0]
-
- @property
- def entries(self):
- for entry in self.benchmarks:
- yield entry
-
- @property
- def meta(self):
- for entry in self.benchmarks:
- yield entry.meta
-
- @property
- def filtered_names(self):
- for entry in self.benchmarks:
- yield entry.meta.shorttitle
-
- @property
- def names(self):
- for entry in self.benchmarks:
- yield entry.name
-
- @property
- def run_names(self):
- for entry in self.benchmarks:
- yield entry.run_name
-
- @property
- def run_types(self):
- for entry in self.benchmarks:
- yield entry.run_type
-
- @property
- def repetitions(self):
- for entry in self.benchmarks:
- yield entry.repetitions
-
- @property
- def repetition_indices(self):
- for entry in self.benchmarks:
- yield entry.repetition_index
-
- @property
- def threads(self):
- for entry in self.benchmarks:
- yield entry.threads
-
- @property
- def iterations(self):
- for entry in self.benchmarks:
- yield entry.iterations
-
- @property
- def real_time(self):
- for entry in self.benchmarks:
- yield entry.real_time
-
- @property
- def cpu_time(self):
- for entry in self.benchmarks:
- yield entry.cpu_time
-
- @property
- def time_unit(self):
- for entry in self.benchmarks:
- yield entry.time_unit
-
- @property
- def bytes_per_second(self):
- for entry in self.benchmarks:
- yield entry.bytes_per_second
-
- @property
- def items_per_second(self):
- for entry in self.benchmarks:
- yield entry.items_per_second
-
-
-# ------------------------------------------------------------------------------
-# ------------------------------------------------------------------------------
-# ------------------------------------------------------------------------------
-
-class BenchmarkPanel:
-
- def __init__(self, runs, bm_meta_cls=None):
- self.runs = [BenchmarkRun(a, bm_meta_cls) for a in runs]
-
- def plot_bars(self, title):
- plot_benchmarks_as_lines(title, *self.runs)
-
-
- def plot_all_lines(self, title):
- plot_benchmarks_as_lines(title, *self.runs,
- transform=lambda r: r.meta.num_pixels,
- line_title_transform=lambda r: r.meta.shortname)
-
-
-# ------------------------------------------------------------------------------
-# ------------------------------------------------------------------------------
-# ------------------------------------------------------------------------------
-
-
-def plot_benchmarks_as_bars(title, *bm, transform=None):
- from bokeh.models import ColumnDataSource, FactorRange
- from bokeh.plotting import figure, show
- from bokeh.transform import factor_cmap
- pass
-
-
-
-
-def plot_benchmarks_as_lines(title, *bm, transform=None,
- line_title_transform=None,
- logx=True, logy=True):
- import bokeh
- from bokeh.plotting import figure, output_file, show
- from bokeh.palettes import Dark2_5 as palette
- from bokeh.layouts import row, column
- from bokeh.models import (Legend, LegendItem, CheckboxGroup, CustomJS, Div,
- RadioGroup, Toggle,
- ColumnDataSource, DataTable, TableColumn)
- from bokeh.models.markers import marker_types
- import itertools
- #
- ids = entry_ids(*bm, transform=transform)
- colors = itertools.cycle(palette)
- markers = itertools.cycle(marker_types)
- p = figure(title=title,
- x_axis_type="log" if logx else "linear",
- y_axis_type="log" if logy else "linear",
- #background_fill_color="#fafafa",
- plot_width=1000,
- x_axis_label="Number of pixels",
- y_axis_label="Throughput (MB/s)",
- )
- p.toolbar.autohide = True
- #p.toolbar.active_inspect = [hover_tool, crosshair_tool]
- p.toolbar.active_drag = "auto"
- p.toolbar.active_scroll = "auto"
- #
- def dft(v): return v if v else (lambda n: n)
- tr = dft(transform)
- lttr = dft(line_title_transform)
- #
- for results in bm:
- x = [ids[name] for name in results.names]
- y = [bps/1e6 for bps in results.bytes_per_second]
- c = next(colors)
- marker = next(markers)
- next(markers) # advance two
- line_name = lttr(results.first)
- #legends.append(LegendItem(name=c, label=line_name))
- p.scatter(x, y, marker=marker, size=8, color=c, legend_label=line_name)
- p.line(x, y,
- color=c, alpha=0.9,
- #muted_color=c, muted_alpha=0.05,
- legend_label=line_name)
- p.legend.click_policy = "hide"
- p.legend.label_text_font_size = "10px"
- #
- def input_title(title):
- return Div(text=f"<h3>{title}</h3>")
- inputs = []
- first = bm[0].first.meta
- for k, g in first.checkbox_groups().items():
- cb = CheckboxGroup(labels=[str(v) for v in g],
- active=[i for i in range(len(g))],
- inline=True)
- inputs.append(input_title(k))
- inputs.append(cb)
- #
- # https://github.com/bokeh/bokeh/blob/branch-2.3/examples/app/export_csv/main.py
- x_axis_values = [f"{m.num_pixels}px" for m in bm[0].meta]
- table_sources = []
- for i, px in enumerate(x_axis_values):
- c = ColumnDataSource(data={
- 'name': [nth(results.filtered_names, i) for results in bm],
- 'bytes_per_second': [nth(results.bytes_per_second, i) for results in bm],
- 'items_per_second': [nth(results.items_per_second, i) for results in bm],
- 'cpu_time': [nth(results.real_time, i) for results in bm],
- 'real_time': [nth(results.real_time, i) for results in bm],
- 'iterations': [nth(results.iterations, i) for results in bm],
- 'threads': [nth(results.threads, i) for results in bm],
- })
- table_sources.append(c)
- selected_x_index = 8 # FIXME (currently 2000 pixels)
- table_source = copy.deepcopy(table_sources[selected_x_index])
- relvalues = Toggle(label="Table: Relative values")
- px_title = input_title("Table: number of pixels")
- px_radiogroup = RadioGroup(labels=x_axis_values, active=selected_x_index)
- table_inputs = [relvalues, px_title, px_radiogroup]
- #
- table_cols = [
- TableColumn(field='name', title='Name'),
- TableColumn(field='bytes_per_second', title='Bytes/second'),
- TableColumn(field='items_per_second', title='Items/second'),
- TableColumn(field='cpu_time', title='CPU time'),
- TableColumn(field='real_time', title='Real time'),
- TableColumn(field='iterations', title='Iterations'),
- TableColumn(field='threads', title='Threads'),
- ]
- data_table = DataTable(source=table_source, columns=table_cols, width=1200)
- callback = CustomJS(args=dict(
- radiogroup=px_radiogroup,
- source=table_source,
- table=table_sources
- ), code="""
- console.log(`active=${radiogroup.active}`);
- /*source.data=table[radiogroup.active];*/
- var nrows = source.data['name'].length;
- var ts = table[radiogroup.active].data;
- var names = ["name", "bytes_per_second", "items_per_second", "cpu_time", "real_time", "iterations", "threads"];
- var ncols = names.length;
- console.log(`names=${names} nrows=${nrows} ncols=${ncols}`);
- for(var i = 0; i < nrows; i++) {
- for(var j = 0; j < ncols; ++j) {
- var name = names[j];
- /*console.log(`i=${i} j=${j} name=${name}`);*/
- source.data[name][i] = ts[name][i];
- }
- }
- source.change.emit();
- """)
- px_radiogroup.js_on_change('active', callback)
- # lambda attr, old, new: log(f"attr={attr} old={old} new={new} active={px_radiogroup.active}"))
- #
- layout = column(
- row(column(*inputs), p),
- row(column(*table_inputs), data_table))
- show(layout)
-
-
-def chain(*iterables):
- for it in iterables:
- for elm in it:
- yield elm
-
-
-def entry_ids(*bm, transform=None):
- ids = {}
- curr = 0
- for results in bm:
- log(os.path.basename(results.filename), "------------------------------")
- for entry in results.entries:
- log(entry.name)
- if transform is not None:
- ids[entry.name] = transform(entry)
- else:
- if ids.get(entry.name) is None:
- ids[entry.name] = curr
- curr += 1
- return ids
-
-
-# ------------------------------------------------------------------------------
-# ------------------------------------------------------------------------------
-# ------------------------------------------------------------------------------
-
-def add_results(args):
- log("adding results:", args.results)
- col = BenchmarkCollection(args.target)
- col.add(args.results)
-
-
-def add_meta(args):
- log("adding bm run metadata to results dir:", args.results)
- meta = ResultMeta(results_dir=args.results,
- cmakecache=args.cmakecache,
- build_type=args.build_type)
- meta.save(args.results)
- log("adding bm run metadata to results dir: success!")
-
-
-# ------------------------------------------------------------------------------
-# ------------------------------------------------------------------------------
-# ------------------------------------------------------------------------------
-
-import typing
-import enum
-
-
-class _enum(enum.Enum):
- def __str__(self):
- return str(self.name)
- @classmethod
- def err_unknown(cls, s):
- raise Exception(f"unknown {__class__.__name__}: {s}")
-
-
-class MatrixOrder(_enum):
- row_major = "row_major"
- col_major = "col_major"
- @property
- def short(self):
- return "rm" if self is MatrixOrder.row_major else "cm"
- @classmethod
- def make(cls, s):
- try:
- return {"rm": cls.row_major, "cm": cls.col_major}[s]
- except:
- cls.err_unknown(s)
-
-
-class MatrixLayout(_enum):
- compact = "compact"
- strided = "strided"
- @classmethod
- def make(cls, s):
- try:
- return cls[s]
- except:
- cls.err_unknown(s)
-
-
-class DimensionBinding(_enum):
- compile_time = "compile_time"
- run_time = "run_time"
- @property
- def short(self):
- return "ct" if self is DimensionBinding.compile_time else "rt"
- @classmethod
- def make(cls, s):
- try:
- return {"ct": cls.compile_time, "rt": cls.run_time}[s]
- except:
- cls.err_unknown(s)
-
-
-class MultType(_enum):
- naive = "naive"
- avx2 = "avx2"
- avx2_unroll2 = "avx2_unroll2"
- avx2_unroll4 = "avx2_unroll4"
- avx2_unroll8 = "avx2_unroll8"
- @classmethod
- def make(cls, s):
- try:
- s = s.replace("dotprod_", "").replace("_naive", "")
- return cls[s]
- except:
- cls.err_unknown(s)
-
-
-class MatrixMult(typing.NamedTuple):
- title: str
- num_pixels: int
- num_channels: int
- num_features: int
- mult_type: MultType
- layout: MatrixLayout
- dim_binding: DimensionBinding
- ret_order: MatrixOrder
- lhs_order: MatrixOrder
- rhs_order: MatrixOrder
-
- @classmethod
- def make(cls, bm_title: str):
- # eg:
- # mult_naive_strided_ct_rm_cmcm<250, 8, 16>
- # mult_naive_compact_rt_rm_rmrm/4000/8/16
- rxline = r'mult_(.*)[</](\d+)(?:/|, )(\d+)(?:/|, )(\d+).*'
- rxcase = r"(.*)_(compact|strided)_(ct|rt)_(rm|cm)_(rm|cm)(rm|cm)"
- case = re.sub(rxline, r'\1', bm_title)
- return cls(
- title=case,
- num_pixels=int(re.sub(rxline, r'\2', bm_title)),
- num_channels=int(re.sub(rxline, r'\3', bm_title)),
- num_features=int(re.sub(rxline, r'\4', bm_title)),
- mult_type=MultType.make(re.sub(rxcase, r'\1', case)),
- layout=MatrixLayout.make(re.sub(rxcase, r'\2', case)),
- dim_binding=DimensionBinding.make(re.sub(rxcase, r'\3', case)),
- ret_order=MatrixOrder.make(re.sub(rxcase, r'\4', case)),
- lhs_order=MatrixOrder.make(re.sub(rxcase, r'\5', case)),
- rhs_order=MatrixOrder.make(re.sub(rxcase, r'\6', case))
- )
-
- def comparison_axes(self):
- return ('num_pixels', 'num_channels', 'num_features')
-
- def checkbox_groups(self):
- return {
- 'multiplication method': [t for t in MultType],
- 'layout': [t for t in MatrixLayout],
- 'dimension': [d for d in DimensionBinding],
- 'return matrix ordering': [o for o in MatrixOrder],
- 'lhs matrix ordering': [o for o in MatrixOrder],
- 'rhs matrix ordering': [o for o in MatrixOrder],
- }
-
- @property
- def matrix_size(self):
- return self.num_pixels * self.num_channels
-
- @property
- def classifier_size(self):
- return self.num_channels * self.num_features
-
- @property
- def shortname(self):
- m = self
- return f"{m.mult_type}/{m.layout}/{m.dim_binding.short}_{m.ret_order.short}_{m.lhs_order.short}{m.rhs_order.short}"
-
- @property
- def shortparams(self):
- m = self
- return f"{m.num_pixels:04d}px{m.num_channels:02d}ch{m.num_features:02d}ft"
-
- @property
- def shorttitle(self):
- return f"{self.shortname}/{self.shortparams}"
-
-
-def _test():
- def expect(v_, attr, val):
- var = getattr(v_, attr)
- if var != val:
- raise Exception(f"{attr}: expected={val} actual={var}")
- #
- v = MatrixMult.make("mult_naive_strided_ct_rm_cmcm<250, 8, 16>")
- expect(v, 'title', 'naive_strided_ct_rm_cmcm')
- expect(v, 'num_pixels', 250)
- expect(v, 'num_channels', 8)
- expect(v, 'num_features', 16)
- expect(v, 'mult_type', MultType.naive)
- expect(v, 'layout', MatrixLayout.strided)
- expect(v, 'dim_binding', DimensionBinding.compile_time)
- expect(v, 'ret_order', MatrixOrder.row_major)
- expect(v, 'lhs_order', MatrixOrder.col_major)
- expect(v, 'rhs_order', MatrixOrder.col_major)
- v = MatrixMult.make("mult_dotprod_avx2_compact_rt_cm_rmcm/4000/16/8")
- expect(v, 'title', 'dotprod_avx2_compact_rt_cm_rmcm')
- expect(v, 'num_pixels', 4000)
- expect(v, 'num_channels', 16)
- expect(v, 'num_features', 8)
- expect(v, 'mult_type', MultType.avx2)
- expect(v, 'layout', MatrixLayout.compact)
- expect(v, 'dim_binding', DimensionBinding.run_time)
- expect(v, 'ret_order', MatrixOrder.col_major)
- expect(v, 'lhs_order', MatrixOrder.row_major)
- expect(v, 'rhs_order', MatrixOrder.col_major)
-
-_test()
-
-
-
-def formatMBps(value):
- return value / 1e6
-
-
-
-if __name__ == '__main__':
- bms = sorted(sys.argv[2:])
- log(bms)
- bms = BenchmarkPanel(bms, bm_meta_cls=MatrixMult.make)
- fm = bms.runs[0].first.meta
- title = f"Classifier multiplication, {fm.num_channels} channels, {fm.num_features} features: throughput (MB/s)"
- bms.plot_all_lines(title)
- exit()
- main()
diff --git a/thirdparty/ryml/ext/c4core/cmake/bm-xp/example_mintm.py b/thirdparty/ryml/ext/c4core/cmake/bm-xp/example_mintm.py
deleted file mode 100644
index 3db4175cb..000000000
--- a/thirdparty/ryml/ext/c4core/cmake/bm-xp/example_mintm.py
+++ /dev/null
@@ -1,1061 +0,0 @@
-import os
-import sys
-import argparse
-import copy
-import requests
-import flask
-import json
-import re
-import yaml
-import shutil
-import mmh3
-from itertools import islice
-
-from munch import Munch, munchify
-from flask import render_template, redirect, url_for, send_from_directory
-from markupsafe import escape
-
-
-def log(*args, **kwargs):
- print(*args, **kwargs, flush=True)
-
-
-def myhash_combine(curr, value):
- return curr ^ (value + 0x9e3779b9 + (curr<<6) + (curr>>2))
-
-
-def nth(iterable, n, default=None):
- "Returns the nth item or a default value"
- return next(islice(iterable, n, None), default)
-
-
-def optionals(obj, *attrs):
- ret = []
- for attr in attrs:
- if not hasattr(obj, attr):
- log("attr not present:", attr)
- continue
- ret.append(getattr(obj, attr))
- return ret
-
-
-def myhash(*args):
- h = 137597
- for a in args:
- if isinstance(a, str):
- if a == "":
- continue
- b = bytes(a, "utf8")
- else:
- b = bytes(a)
- hb = mmh3.hash(b, signed=False)
- h = myhash_combine(h, hb)
- s = hex(h)
- return s[2:min(10, len(s))]
-
-
-def copy_file_to_dir(file, dir):
- dir = os.path.abspath(dir)
- src = os.path.abspath(file)
- dst = f"{dir}/{os.path.basename(src)}"
- if not os.path.exists(dir):
- os.makedirs(dir)
- if os.path.exists(dst):
- os.remove(dst)
- log("copy:", src, "-->", dst)
- shutil.copy(src, dst)
- return dst
-
-
-def chk(f):
- log(f"looking for file:", f)
- assert os.path.exists(f), f
- return f
-
-
-def load_yml_file(filename):
- if not os.path.exists(filename):
- raise Exception(f"not found: {filename}")
- with open(filename) as f:
- return load_yml(f.read())
-
-
-def dump_yml(data, filename):
- with open(filename, "w") as f:
- yaml.safe_dump(data, f)
-
-
-def load_yml(yml):
- return munchify(yaml.safe_load(yml))
-
-
-def dump_json(data, filename):
- with open(filename, "w") as f:
- f.write(json.dumps(data, indent=2, sort_keys=True))
-
-
-def load_json(filename):
- with open(filename, "r") as f:
- try:
- return munchify(json.load(f))
- except Exception as exc:
- raise Exception(f"could not load file: {filename}: {exc}")
-
-
-def main():
- def _common_args(parser):
- parser.add_argument("-m", "--manifest", type=str, default="", help="enable debug mode")
- parser.add_argument("--debug", action="store_true", help="enable debug mode")
- #
- parser = argparse.ArgumentParser(description="Browse benchmark results", prog="bm")
- _common_args(parser)
- subparsers = parser.add_subparsers()
- #
- sp = subparsers.add_parser("create", help="create benchmark collection")
- _common_args(sp)
- sp.add_argument("--debug", action="store_true", help="enable debug mode")
- sp.add_argument("filename", type=str, help="the YAML file with the benchmark specs")
- sp.add_argument("target", type=str, help="the directory to store the results")
- #
- sp = subparsers.add_parser("meta", help="get the required meta-information: cpu info, commit data")
- _common_args(sp)
- sp.add_argument("--debug", action="store_true", help="enable debug mode")
- sp.add_argument("results", type=str, help="the directory with the results")
- sp.add_argument("cmakecache", type=str, help="the path to the CMakeCache.txt file used to build the benchmark binaries")
- sp.add_argument("build_type", type=str, help="the build type, eg Release Debug MinSizeRel RelWithDebInfo")
- #
- sp = subparsers.add_parser("add", help="add benchmark results")
- _common_args(sp)
- sp.add_argument("--debug", action="store_true", help="enable debug mode")
- sp.add_argument("results", type=str, help="the directory with the results")
- sp.add_argument("target", type=str, help="the directory to store the results")
- #
- sp = subparsers.add_parser("serve", help="serve benchmark results")
- _common_args(sp)
- sp.add_argument("--debug", action="store_true", help="enable debug mode")
- sp.add_argument("bmdir", type=os.path.abspath, default=os.getcwd(), help="the directory with the results. default=.")
- sp.add_argument("-H", "--host", type=str, default="localhost", help="host. default=%(default)s")
- sp.add_argument("-p", "--port", type=int, default=8000, help="port. default=%(default)s")
- #
- sp = subparsers.add_parser("export", help="export static html")
- sp.set_defaults(func=freeze)
- sp.add_argument("bmdir", type=os.path.abspath, default=os.getcwd(), help="the directory with the results. default=.")
- _common_args(sp)
- #
- sp = subparsers.add_parser("deps", help="install server dependencies")
- sp.set_defaults(func=lambda _: download_deps())
- sp.add_argument("--debug", action="store_true", help="enable debug mode")
- _common_args(sp)
- #
- args = parser.parse_args(sys.argv[1:] if len(sys.argv) > 1 else ["serve"])
- if args.debug:
- log(args)
- args.func(args)
-
-
-def get_manifest(args):
- bmdir = os.path.abspath(args.bmdir)
- if not args.manifest:
- manifest_yml = os.path.join(bmdir, "manifest.yml")
- else:
- if not os.path.isabs(args.manifest):
- manifest_yml = os.path.join(os.getcwd(), args.manifest)
- manifest_json = os.path.join(os.path.dirname(manifest.yml), "manifest.json")
- manifest = load_yml_file(manifest_yml)
- dump_json(manifest, manifest_json)
- return manifest
-
-
-# ------------------------------------------------------------------------------
-# ------------------------------------------------------------------------------
-# ------------------------------------------------------------------------------
-
-app = flask.Flask(__name__,
- template_folder='template')
-
-
-def _setup_app(args):
- def _s(prop, val):
- assert not hasattr(app, prop), prop
- setattr(app, prop, val)
- _s('args', args)
- _s('manifest', get_manifest(args))
- if args.debug:
- app.config["DEBUG"] = True
-
-
-def freeze(args):
- "https://pythonhosted.org/Frozen-Flask/"
- from flask_frozen import Freezer
- _setup_app(args)
- freezer = Freezer(app)
- freezer.freeze(debug=args.debug)
-
-
-def serve(args):
- _setup_app(args)
- app.run(host=args.host, port=args.port, debug=args.debug)
-
-
-def home():
- log("requested home")
- return render_template("index.html")
-
-
-def other_(path):
- path = escape(path)
- d = app.args.bmdir
- log("requested other path:", path, "---", os.path.join(d, path))
- return send_from_directory(d, path)
-
-
[email protected]("/static/<path>")
-def static_(path):
- path = escape(path)
- d = os.path.join(app.args.bmdir, "static")
- log("requested static path:", path, "---", os.path.join(d, path))
- return send_from_directory(d, path, cache_timeout=1) # timeout in seconds
-
-
[email protected]("/bm/<commit>/<run>/<resultjson>")
-def bm_(commit, run, resultjson):
- commit = escape(commit)
- run = escape(run)
- resultjson = escape(resultjson)
- d = os.path.join(app.args.bmdir, "runs", commit, run)
- log("requested result:", os.path.join(d, resultjson))
- return send_from_directory(d, resultjson, cache_timeout=1) # timeout in seconds
-
-
-# ------------------------------------------------------------------------------
-# ------------------------------------------------------------------------------
-# ------------------------------------------------------------------------------
-
-def download_deps():
- deps = [
- "https://code.jquery.com/jquery-3.3.1.js",
- "https://code.jquery.com/jquery-3.3.1.js",
- "https://code.jquery.com/ui/1.12.1/jquery-ui.js",
- "https://cdn.datatables.net/1.10.20/js/jquery.dataTables.js",
- "https://cdn.datatables.net/1.10.20/js/jquery.dataTables.min.js",
- "https://cdn.datatables.net/1.10.20/css/jquery.dataTables.css",
- "https://cdn.datatables.net/1.10.20/css/jquery.dataTables.min.css",
- "https://www.chartjs.org/dist/2.9.1/Chart.min.js",
- #("https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.3.2/styles/github.css", "highlight.github.css"),
- ("https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.3.2/styles/github.min.css", "highlight.github.min.css"),
- #"https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.3.2/highlight.js",
- "https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.3.2/highlight.min.js",
- ]
- for src in deps:
- if type(src) == str:
- base = os.path.basename(src)
- else:
- src, base = src
- dst = f"{os.getcwd()}/static/{base}"
- download_url(src, dst)
-
-
-def download_url(url, dst):
- log("download url:", url, "--->", dst)
- req = requests.get(url, stream=True)
- if req.status_code == 200:
- sz = 0
- with open(dst, 'wb') as f:
- for chunk in req:
- f.write(chunk)
- sz += len(chunk)
- log(f"........ finished: {sz}B")
- else:
- log(f" error:", req.status_code, url)
-
-
-# ------------------------------------------------------------------------------
-# ------------------------------------------------------------------------------
-# ------------------------------------------------------------------------------
-
-class BenchmarkCollection:
-
- @staticmethod
- def create_new(args):
- dir = args.target
- filename = os.path.join(dir, "bm.yml")
- manifest = os.path.join(dir, "manifest.yml")
- if not os.path.exists(dir):
- os.makedirs(dir)
- shutil.copyfile(args.filename, filename)
- dump_yml(load_yml("""{runs: {}, bm: {}}"""), manifest)
- return __class__(dir)
-
- def __init__(self, dir):
- if not os.path.exists(dir):
- raise Exception(f"not found: {dir}")
- self.dir = os.path.abspath(dir)
- self.runs_dir = os.path.join(self.dir, "runs")
- self.manifest = os.path.join(self.dir, "manifest.yml")
- self.filename = os.path.join(self.dir, "bm.yml")
- self.specs = munchify(load_yml_file(self.filename))
- self.manif = munchify(load_yml_file(self.manifest))
-
- def add(self, results_dir):
- results_dir = os.path.abspath(results_dir)
- dst_dir, meta = self._read_run(results_dir)
- self._add_run(results_dir, dst_dir, meta)
- dump_yml(self.manif, self.manifest)
-
- def _read_run(self, results_dir):
- log("adding run...")
- id = f"{len(self.manif.runs.keys()):05d}"
- log(f"adding run: id={id}")
- meta = ResultMeta.load(results_dir)
- dst_dir = os.path.join(self.runs_dir, meta.name)
- return dst_dir, meta
-
- def _add_run(self, results_dir, dst_dir, meta):
- cats = self._add_meta_categories(meta)
- for filename in ("meta.yml",
- "CMakeCCompiler.cmake",
- "CMakeCXXCompiler.cmake",
- "CMakeSystem.cmake",
- "compile_commands.json"):
- filename = os.path.join(results_dir, filename)
- if os.path.exists(filename):
- copy_file_to_dir(filename, dst_dir)
- else:
- if not filename.endswith("compile_commands.json"):
- raise Exception(f"wtf???? {filename}")
- for name, specs in self.specs.bm.items():
- if not hasattr(specs, 'variants'):
- filename = chk(f"{results_dir}/{name}.json")
- dst = copy_file_to_dir(filename, dst_dir)
- self._add_bm_run(name, specs, meta)
- else:
- for t in specs.variants:
- tname = f"{name}-{t}"
- filename = chk(f"{results_dir}/{tname}.json")
- dst = copy_file_to_dir(filename, dst_dir)
- self._add_bm_run(tname, specs, meta)
-
- def _add_bm_run(self, name, specs, meta):
- if name not in self.manif.bm.keys():
- self.manif.bm[name] = Munch(specs=specs, entries=[])
- entry = self.manif.bm[name]
- entry.specs = specs
- if meta.name not in entry.entries:
- entry.entries.append(meta.name)
-
- def _add_meta_categories(self, meta):
- run = Munch()
- for catname in ('commit', 'cpu', 'system', 'build'):
- meta_item = getattr(meta, catname)
- self._add_item_to_category(meta.name, catname, meta_item)
- run[catname] = meta_item.storage_id
- # build specs are too verbose; remove them
- self.manif.build[meta.build.storage_id].specs = Munch()
- self.manif.runs[meta.name] = run
-
- def _add_item_to_category(self, run, category_name, item):
- if not hasattr(self.manif, category_name):
- setattr(self.manif, category_name, Munch())
- category = getattr(self.manif, category_name)
- if item.storage_id not in category.keys():
- category[item.storage_id] = Munch(specs=item, entries=[])
- entry = category[item.storage_id]
- entry.specs = item
- if run not in entry.entries:
- entry.entries.append(run)
-
-
-# -----------------------------------------------------------------------------
-# -----------------------------------------------------------------------------
-# -----------------------------------------------------------------------------
-
-class ResultMeta(Munch):
-
- def __init__(self, results_dir, cmakecache, build_type):
- super().__init__(self)
- self.date = __class__.get_date()
- self.commit = __class__.get_commit(results_dir)
- self.cpu = __class__.get_cpu_info()
- self.system = __class__.get_sys_info()
- self.build = __class__.get_build_info(cmakecache, build_type)
- self.name = self._get_name()
-
- @staticmethod
- def load(results_dir):
- results_dir = os.path.join(os.path.abspath(results_dir), "meta.yml")
- data = load_yml_file(results_dir)
- return munchify(data)
-
- def save(self, results_dir):
- out = os.path.join(results_dir, "meta.yml")
- log("saving meta:", out)
- dump_yml(self, out)
- self.build.save(results_dir)
-
- @staticmethod
- def get_date():
- import datetime
- now = datetime.datetime.now()
- return now.strftime("%Y%m%d-%H%M%S")
-
- def _get_name(self):
- commit = self.commit.storage_name
- cpu = self.cpu.storage_name
- sys = self.system.storage_name
- build = self.build.storage_name
- name = f"{commit}/{cpu}-{sys}-{build}"
- return name
-
- @staticmethod
- def get_commit(results_dir):
- import git
- repo = git.Repo(results_dir, search_parent_directories=True)
- commit = repo.head.commit
- commit = {p: str(getattr(commit, p))
- for p in ('message', 'summary', 'name_rev',
- 'author',
- 'authored_datetime',
- 'committer',
- 'committed_datetime',)}
- commit = Munch(commit)
- commit.message = commit.message.strip()
- commit.sha1 = commit.name_rev[:7]
- spl = commit.authored_datetime.split(" ")
- date = re.sub(r'-', '', spl[0])
- time = re.sub(r'(\d+):(\d+):(\d+).*', r'\1\2\3', spl[1])
- commit.storage_id = commit.sha1
- commit.storage_name = f"git{date}_{time}-{commit.sha1}"
- return commit
-
- @staticmethod
- def get_cpu_info():
- import cpuinfo
- nfo = cpuinfo.get_cpu_info()
- nfo = Munch(nfo)
- for a in ('cpu_version', 'cpu_version_string', 'python_version'):
- if hasattr(nfo, a):
- delattr(nfo, a)
- for a in ('arch_string_raw', 'brand_raw', 'hardware_raw', 'vendor_id_raw'):
- if not hasattr(nfo, a):
- setattr(nfo, a, '')
- nfo.storage_id = myhash(
- nfo.arch_string_raw, nfo.brand_raw, nfo.hardware_raw, nfo.vendor_id_raw,
- nfo.arch, nfo.bits, nfo.count, nfo.family, nfo.model, nfo.stepping,
- ",".join(nfo.flags), nfo.hz_advertised_friendly,
- nfo.l2_cache_associativity,
- nfo.l2_cache_line_size,
- nfo.l2_cache_size,
- nfo.l3_cache_size,
- *optionals('l1_data_cache_size', 'l1_instruction_cache_size')
- )
- nfo.storage_name = f"{nfo.arch.lower()}_{nfo.storage_id}"
- return nfo
-
- @staticmethod
- def get_sys_info():
- import platform
- uname = platform.uname()
- nfo = Munch(
- sys_platform=sys.platform,
- sys=platform.system(),
- uname=Munch(
- machine=uname.machine,
- node=uname.node,
- release=uname.release,
- system=uname.system,
- version=uname.version,
- )
- )
- nfo.storage_id = myhash(
- nfo.sys_platform,
- nfo.uname.machine,
- )
- nfo.storage_name = f"{nfo.sys_platform}_{nfo.storage_id}"
- return nfo
-
- @staticmethod
- def get_build_info(cmakecache_txt, buildtype):
- nfo = CMakeCache(cmakecache_txt)
- def _btflags(name):
- return (getattr(nfo, name), getattr(nfo, f"{name}_{buildtype.upper()}"))
- nfo.storage_id = myhash(
- buildtype,
- nfo.CMAKE_CXX_COMPILER_ID,
- nfo.CMAKE_CXX_COMPILER_VERSION,
- nfo.CMAKE_CXX_COMPILER_VERSION_INTERNAL,
- nfo.CMAKE_CXX_COMPILER_ABI,
- nfo.CMAKE_CXX_SIZEOF_DATA_PTR,
- nfo.CMAKE_C_COMPILER_ID,
- nfo.CMAKE_C_COMPILER_VERSION,
- nfo.CMAKE_C_COMPILER_VERSION_INTERNAL,
- nfo.CMAKE_C_COMPILER_ABI,
- nfo.CMAKE_C_SIZEOF_DATA_PTR,
- *_btflags("CMAKE_CXX_FLAGS"),
- *_btflags("CMAKE_C_FLAGS"),
- *_btflags("CMAKE_STATIC_LINKER_FLAGS"),
- *_btflags("CMAKE_SHARED_LINKER_FLAGS"),
- )
- #
- ccname = nfo.CMAKE_CXX_COMPILER_ID.lower()
- if ccname == "gnu":
- ccname = "gcc"
- ccname += nfo.CMAKE_CXX_COMPILER_VERSION.lower()
- #
- if nfo.CMAKE_C_SIZEOF_DATA_PTR == "4":
- bits = "32bit"
- elif nfo.CMAKE_C_SIZEOF_DATA_PTR == "8":
- bits = "64bit"
- else:
- raise Exception("unknown architecture")
- #
- nfo.storage_name = f"{bits}_{buildtype}_{ccname}_{nfo.storage_id}"
- return nfo
-
-
-# -----------------------------------------------------------------------------
-# -----------------------------------------------------------------------------
-# -----------------------------------------------------------------------------
-
-class CMakeCache(Munch):
-
- def __init__(self, cmakecache_txt):
- import glob
- for line in iter_cmake_lines(cmakecache_txt):
- spl = line.split("=")
- if len(spl) < 2:
- continue
- k, ty = spl[0].split(":")
- v = "=".join(spl[1:]).strip()
- setattr(self, k, v)
- bdir = os.path.dirname(os.path.abspath(cmakecache_txt))
- self._c_compiler_file = sorted(glob.glob(f"{bdir}/CMakeFiles/*/CMakeCCompiler.cmake"))[-1] # get the last
- self._cxx_compiler_file = sorted(glob.glob(f"{bdir}/CMakeFiles/*/CMakeCXXCompiler.cmake"))[-1] # get the last
- self._system_file = sorted(glob.glob(f"{bdir}/CMakeFiles/*/CMakeSystem.cmake"))[-1] # get the last
- self._load_cmake_file(self._c_compiler_file)
- self._load_cmake_file(self._cxx_compiler_file)
- ccomfile = f"{bdir}/compile_commands.json"
- self._compile_commands_file = ccomfile if os.path.exists(ccomfile) else None
-
- def _load_cmake_file(self, filename):
- for line in iter_cmake_lines(filename):
- if not line.startswith("set("):
- continue
- k = re.sub(r"set\((.*)\ +(.*)\)", r"\1", line)
- v = re.sub(r"set\((.*)\ +(.*)\)", r"\2", line)
- v = v.strip('"').strip("'").strip()
- setattr(self, k, v)
-
- def save(self, results_dir):
- copy_file_to_dir(self._c_compiler_file, results_dir)
- copy_file_to_dir(self._cxx_compiler_file, results_dir)
- copy_file_to_dir(self._system_file, results_dir)
- if self._compile_commands_file is not None:
- copy_file_to_dir(self._compile_commands_file, results_dir)
-
-
-def iter_cmake_lines(filename):
- with open(filename) as f:
- for line in f.readlines():
- line = line.strip()
- if line.startswith("#") or line.startswith("//") or len(line) == 0:
- continue
- yield line
-
-
-# ------------------------------------------------------------------------------
-# ------------------------------------------------------------------------------
-# ------------------------------------------------------------------------------
-
-class BenchmarkRun(Munch):
- "results of an individual run"
-
- def __init__(self, json_file, meta_class):
- props = load_json(json_file)
- setattr(self, "filename", json_file)
- assert hasattr(props, "context")
- assert hasattr(props, "benchmarks")
- super().__init__(**props)
- for e in self.benchmarks:
- setattr(e, 'meta', meta_class(e.name))
- setattr(self, 'property_names', (
- 'meta',
- 'shorttitle',
- 'name',
- 'run_name',
- 'run_type',
- 'repetitions',
- 'repetition_index',
- 'repetition_index',
- 'threads',
- 'iterations',
- 'real_time',
- 'cpu_time',
- 'time_unit',
- 'bytes_per_second',
- 'items_per_second',
- 'counters',
- ))
-
- @property
- def first(self):
- return self.benchmarks[0]
-
- @property
- def entries(self):
- for entry in self.benchmarks:
- yield entry
-
- @property
- def meta(self):
- for entry in self.benchmarks:
- yield entry.meta
-
- @property
- def filtered_names(self):
- for entry in self.benchmarks:
- yield entry.meta.shorttitle
-
- @property
- def names(self):
- for entry in self.benchmarks:
- yield entry.name
-
- @property
- def run_names(self):
- for entry in self.benchmarks:
- yield entry.run_name
-
- @property
- def run_types(self):
- for entry in self.benchmarks:
- yield entry.run_type
-
- @property
- def repetitions(self):
- for entry in self.benchmarks:
- yield entry.repetitions
-
- @property
- def repetition_indices(self):
- for entry in self.benchmarks:
- yield entry.repetition_index
-
- @property
- def threads(self):
- for entry in self.benchmarks:
- yield entry.threads
-
- @property
- def iterations(self):
- for entry in self.benchmarks:
- yield entry.iterations
-
- @property
- def real_time(self):
- for entry in self.benchmarks:
- yield entry.real_time
-
- @property
- def cpu_time(self):
- for entry in self.benchmarks:
- yield entry.cpu_time
-
- @property
- def time_unit(self):
- for entry in self.benchmarks:
- yield entry.time_unit
-
- @property
- def bytes_per_second(self):
- for entry in self.benchmarks:
- yield entry.bytes_per_second
-
- @property
- def items_per_second(self):
- for entry in self.benchmarks:
- yield entry.items_per_second
-
-
-# ------------------------------------------------------------------------------
-# ------------------------------------------------------------------------------
-# ------------------------------------------------------------------------------
-
-class BenchmarkPanel:
-
- def __init__(self, runs, bm_meta_cls=None):
- self.runs = [BenchmarkRun(a, bm_meta_cls) for a in runs]
-
- def plot_bars(self, title):
- plot_benchmarks_as_lines(title, *self.runs)
-
-
- def plot_all_lines(self, title):
- plot_benchmarks_as_lines(title, *self.runs,
- transform=lambda r: r.meta.num_pixels,
- line_title_transform=lambda r: r.meta.shortname)
-
-
-# ------------------------------------------------------------------------------
-# ------------------------------------------------------------------------------
-# ------------------------------------------------------------------------------
-
-
-def plot_benchmarks_as_bars(title, *bm, transform=None):
- from bokeh.models import ColumnDataSource, FactorRange
- from bokeh.plotting import figure, show
- from bokeh.transform import factor_cmap
- pass
-
-
-
-
-def plot_benchmarks_as_lines(title, *bm, transform=None,
- line_title_transform=None,
- logx=True, logy=True):
- import bokeh
- from bokeh.plotting import figure, output_file, show
- from bokeh.palettes import Dark2_5 as palette
- from bokeh.layouts import row, column
- from bokeh.models import (Legend, LegendItem, CheckboxGroup, CustomJS, Div,
- RadioGroup, Toggle,
- ColumnDataSource, DataTable, TableColumn)
- from bokeh.models.markers import marker_types
- import itertools
- #
- ids = entry_ids(*bm, transform=transform)
- colors = itertools.cycle(palette)
- markers = itertools.cycle(marker_types)
- p = figure(title=title,
- x_axis_type="log" if logx else "linear",
- y_axis_type="log" if logy else "linear",
- #background_fill_color="#fafafa",
- plot_width=1000,
- x_axis_label="Number of pixels",
- y_axis_label="Throughput (MB/s)",
- )
- p.toolbar.autohide = True
- #p.toolbar.active_inspect = [hover_tool, crosshair_tool]
- p.toolbar.active_drag = "auto"
- p.toolbar.active_scroll = "auto"
- #
- def dft(v): return v if v else (lambda n: n)
- tr = dft(transform)
- lttr = dft(line_title_transform)
- #
- for results in bm:
- x = [ids[name] for name in results.names]
- y = [bps/1e6 for bps in results.bytes_per_second]
- c = next(colors)
- marker = next(markers)
- next(markers) # advance two
- line_name = lttr(results.first)
- #legends.append(LegendItem(name=c, label=line_name))
- p.scatter(x, y, marker=marker, size=8, color=c, legend_label=line_name)
- p.line(x, y,
- color=c, alpha=0.9,
- #muted_color=c, muted_alpha=0.05,
- legend_label=line_name)
- p.legend.click_policy = "hide"
- p.legend.label_text_font_size = "10px"
- #
- def input_title(title):
- return Div(text=f"<h3>{title}</h3>")
- inputs = []
- first = bm[0].first.meta
- for k, g in first.checkbox_groups().items():
- cb = CheckboxGroup(labels=[str(v) for v in g],
- active=[i for i in range(len(g))],
- inline=True)
- inputs.append(input_title(k))
- inputs.append(cb)
- #
- # https://github.com/bokeh/bokeh/blob/branch-2.3/examples/app/export_csv/main.py
- x_axis_values = [f"{m.num_pixels}px" for m in bm[0].meta]
- table_sources = []
- for i, px in enumerate(x_axis_values):
- c = ColumnDataSource(data={
- 'name': [nth(results.filtered_names, i) for results in bm],
- 'bytes_per_second': [nth(results.bytes_per_second, i) for results in bm],
- 'items_per_second': [nth(results.items_per_second, i) for results in bm],
- 'cpu_time': [nth(results.real_time, i) for results in bm],
- 'real_time': [nth(results.real_time, i) for results in bm],
- 'iterations': [nth(results.iterations, i) for results in bm],
- 'threads': [nth(results.threads, i) for results in bm],
- })
- table_sources.append(c)
- selected_x_index = 8 # FIXME (currently 2000 pixels)
- table_source = copy.deepcopy(table_sources[selected_x_index])
- relvalues = Toggle(label="Table: Relative values")
- px_title = input_title("Table: number of pixels")
- px_radiogroup = RadioGroup(labels=x_axis_values, active=selected_x_index)
- table_inputs = [relvalues, px_title, px_radiogroup]
- #
- table_cols = [
- TableColumn(field='name', title='Name'),
- TableColumn(field='bytes_per_second', title='Bytes/second'),
- TableColumn(field='items_per_second', title='Items/second'),
- TableColumn(field='cpu_time', title='CPU time'),
- TableColumn(field='real_time', title='Real time'),
- TableColumn(field='iterations', title='Iterations'),
- TableColumn(field='threads', title='Threads'),
- ]
- data_table = DataTable(source=table_source, columns=table_cols, width=1200)
- callback = CustomJS(args=dict(
- radiogroup=px_radiogroup,
- source=table_source,
- table=table_sources
- ), code="""
- console.log(`active=${radiogroup.active}`);
- /*source.data=table[radiogroup.active];*/
- var nrows = source.data['name'].length;
- var ts = table[radiogroup.active].data;
- var names = ["name", "bytes_per_second", "items_per_second", "cpu_time", "real_time", "iterations", "threads"];
- var ncols = names.length;
- console.log(`names=${names} nrows=${nrows} ncols=${ncols}`);
- for(var i = 0; i < nrows; i++) {
- for(var j = 0; j < ncols; ++j) {
- var name = names[j];
- /*console.log(`i=${i} j=${j} name=${name}`);*/
- source.data[name][i] = ts[name][i];
- }
- }
- source.change.emit();
- """)
- px_radiogroup.js_on_change('active', callback)
- # lambda attr, old, new: log(f"attr={attr} old={old} new={new} active={px_radiogroup.active}"))
- #
- layout = column(
- row(column(*inputs), p),
- row(column(*table_inputs), data_table))
- show(layout)
-
-
-def chain(*iterables):
- for it in iterables:
- for elm in it:
- yield elm
-
-
-def entry_ids(*bm, transform=None):
- ids = {}
- curr = 0
- for results in bm:
- log(os.path.basename(results.filename), "------------------------------")
- for entry in results.entries:
- log(entry.name)
- if transform is not None:
- ids[entry.name] = transform(entry)
- else:
- if ids.get(entry.name) is None:
- ids[entry.name] = curr
- curr += 1
- return ids
-
-
-# ------------------------------------------------------------------------------
-# ------------------------------------------------------------------------------
-# ------------------------------------------------------------------------------
-
-def add_results(args):
- log("adding results:", args.results)
- col = BenchmarkCollection(args.target)
- col.add(args.results)
-
-
-def add_meta(args):
- log("adding bm run metadata to results dir:", args.results)
- meta = ResultMeta(results_dir=args.results,
- cmakecache=args.cmakecache,
- build_type=args.build_type)
- meta.save(args.results)
- log("adding bm run metadata to results dir: success!")
-
-
-# ------------------------------------------------------------------------------
-# ------------------------------------------------------------------------------
-# ------------------------------------------------------------------------------
-
-import typing
-import enum
-
-
-class _enum(enum.Enum):
- def __str__(self):
- return str(self.name)
- @classmethod
- def err_unknown(cls, s):
- raise Exception(f"unknown {__class__.__name__}: {s}")
-
-
-class MatrixOrder(_enum):
- row_major = "row_major"
- col_major = "col_major"
- @property
- def short(self):
- return "rm" if self is MatrixOrder.row_major else "cm"
- @classmethod
- def make(cls, s):
- try:
- return {"rm": cls.row_major, "cm": cls.col_major}[s]
- except:
- cls.err_unknown(s)
-
-
-class MatrixLayout(_enum):
- compact = "compact"
- strided = "strided"
- @classmethod
- def make(cls, s):
- try:
- return cls[s]
- except:
- cls.err_unknown(s)
-
-
-class DimensionBinding(_enum):
- compile_time = "compile_time"
- run_time = "run_time"
- @property
- def short(self):
- return "ct" if self is DimensionBinding.compile_time else "rt"
- @classmethod
- def make(cls, s):
- try:
- return {"ct": cls.compile_time, "rt": cls.run_time}[s]
- except:
- cls.err_unknown(s)
-
-
-class MultType(_enum):
- naive = "naive"
- avx2 = "avx2"
- avx2_unroll2 = "avx2_unroll2"
- avx2_unroll4 = "avx2_unroll4"
- avx2_unroll8 = "avx2_unroll8"
- @classmethod
- def make(cls, s):
- try:
- s = s.replace("dotprod_", "").replace("_naive", "")
- return cls[s]
- except:
- cls.err_unknown(s)
-
-
-class MatrixMult(typing.NamedTuple):
- title: str
- num_pixels: int
- num_channels: int
- num_features: int
- mult_type: MultType
- layout: MatrixLayout
- dim_binding: DimensionBinding
- ret_order: MatrixOrder
- lhs_order: MatrixOrder
- rhs_order: MatrixOrder
-
- @classmethod
- def make(cls, bm_title: str):
- # eg:
- # mult_naive_strided_ct_rm_cmcm<250, 8, 16>
- # mult_naive_compact_rt_rm_rmrm/4000/8/16
- rxline = r'mult_(.*)[</](\d+)(?:/|, )(\d+)(?:/|, )(\d+).*'
- rxcase = r"(.*)_(compact|strided)_(ct|rt)_(rm|cm)_(rm|cm)(rm|cm)"
- case = re.sub(rxline, r'\1', bm_title)
- return cls(
- title=case,
- num_pixels=int(re.sub(rxline, r'\2', bm_title)),
- num_channels=int(re.sub(rxline, r'\3', bm_title)),
- num_features=int(re.sub(rxline, r'\4', bm_title)),
- mult_type=MultType.make(re.sub(rxcase, r'\1', case)),
- layout=MatrixLayout.make(re.sub(rxcase, r'\2', case)),
- dim_binding=DimensionBinding.make(re.sub(rxcase, r'\3', case)),
- ret_order=MatrixOrder.make(re.sub(rxcase, r'\4', case)),
- lhs_order=MatrixOrder.make(re.sub(rxcase, r'\5', case)),
- rhs_order=MatrixOrder.make(re.sub(rxcase, r'\6', case))
- )
-
- def comparison_axes(self):
- return ('num_pixels', 'num_channels', 'num_features')
-
- def checkbox_groups(self):
- return {
- 'multiplication method': [t for t in MultType],
- 'layout': [t for t in MatrixLayout],
- 'dimension': [d for d in DimensionBinding],
- 'return matrix ordering': [o for o in MatrixOrder],
- 'lhs matrix ordering': [o for o in MatrixOrder],
- 'rhs matrix ordering': [o for o in MatrixOrder],
- }
-
- @property
- def matrix_size(self):
- return self.num_pixels * self.num_channels
-
- @property
- def classifier_size(self):
- return self.num_channels * self.num_features
-
- @property
- def shortname(self):
- m = self
- return f"{m.mult_type}/{m.layout}/{m.dim_binding.short}_{m.ret_order.short}_{m.lhs_order.short}{m.rhs_order.short}"
-
- @property
- def shortparams(self):
- m = self
- return f"{m.num_pixels:04d}px{m.num_channels:02d}ch{m.num_features:02d}ft"
-
- @property
- def shorttitle(self):
- return f"{self.shortname}/{self.shortparams}"
-
-
-def _test():
- def expect(v_, attr, val):
- var = getattr(v_, attr)
- if var != val:
- raise Exception(f"{attr}: expected={val} actual={var}")
- #
- v = MatrixMult.make("mult_naive_strided_ct_rm_cmcm<250, 8, 16>")
- expect(v, 'title', 'naive_strided_ct_rm_cmcm')
- expect(v, 'num_pixels', 250)
- expect(v, 'num_channels', 8)
- expect(v, 'num_features', 16)
- expect(v, 'mult_type', MultType.naive)
- expect(v, 'layout', MatrixLayout.strided)
- expect(v, 'dim_binding', DimensionBinding.compile_time)
- expect(v, 'ret_order', MatrixOrder.row_major)
- expect(v, 'lhs_order', MatrixOrder.col_major)
- expect(v, 'rhs_order', MatrixOrder.col_major)
- v = MatrixMult.make("mult_dotprod_avx2_compact_rt_cm_rmcm/4000/16/8")
- expect(v, 'title', 'dotprod_avx2_compact_rt_cm_rmcm')
- expect(v, 'num_pixels', 4000)
- expect(v, 'num_channels', 16)
- expect(v, 'num_features', 8)
- expect(v, 'mult_type', MultType.avx2)
- expect(v, 'layout', MatrixLayout.compact)
- expect(v, 'dim_binding', DimensionBinding.run_time)
- expect(v, 'ret_order', MatrixOrder.col_major)
- expect(v, 'lhs_order', MatrixOrder.row_major)
- expect(v, 'rhs_order', MatrixOrder.col_major)
-
-_test()
-
-
-
-def formatMBps(value):
- return value / 1e6
-
-
-
-if __name__ == '__main__':
- bms = sorted(sys.argv[2:])
- log(bms)
- bms = BenchmarkPanel(bms, bm_meta_cls=MatrixMult.make)
- fm = bms.runs[0].first.meta
- title = f"Classifier multiplication, {fm.num_channels} channels, {fm.num_features} features: throughput (MB/s)"
- bms.plot_all_lines(title)
- exit()
- main()
diff --git a/thirdparty/ryml/ext/c4core/cmake/bm-xp/requirements.txt b/thirdparty/ryml/ext/c4core/cmake/bm-xp/requirements.txt
deleted file mode 100644
index 5a1b395ef..000000000
--- a/thirdparty/ryml/ext/c4core/cmake/bm-xp/requirements.txt
+++ /dev/null
@@ -1,14 +0,0 @@
-munch
-pyyaml
-py-cpuinfo
-psutil
-gitpython
-flask
-markupsafe
-Frozen-Flask
-requests
-mmh3
-bokeh<3.0
-selenium
-matplotlib
-prettytable
diff --git a/thirdparty/ryml/ext/c4core/cmake/bm-xp/template/index.html b/thirdparty/ryml/ext/c4core/cmake/bm-xp/template/index.html
deleted file mode 100644
index fb52b8ba0..000000000
--- a/thirdparty/ryml/ext/c4core/cmake/bm-xp/template/index.html
+++ /dev/null
@@ -1,45 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-
- <head>
- <meta charset="UTF-8">
- <link rel="shortcut icon" href="#">
- <link rel="stylesheet" type="text/css" href="/static/jquery-ui.min.css"/>
- <link rel="stylesheet" type="text/css" href="/static/jquery.dataTables.min.css"/>
- <link rel="stylesheet" type="text/css" href="/static/highlight.github.min.css"/>
- <style>
- body {
- font-family: "Trebuchet MS", sans-serif;
- margin: 50px;
- }
- .chart {
- height: 700px; max-width: 920px; margin: 0px auto;
- }
- </style>
- </head>
-
- <body>
- <h1 id="heading-title">Title</h1>
- <div>
- Available benchmarks:
- <ul id="toc"></ul>
- </div>
- <div id="bm-results"></div>
- <div><pre id="dbg"></pre></div>
- <!-- scripts -->
- <script type="text/javascript" src="/static/jquery-3.3.1.min.js"></script>
- <script type="text/javascript" src="/static/jquery-ui.js"></script>
- <script type="text/javascript" src="/static/jquery.canvasjs.min.js"></script>
- <script type="text/javascript" src="/static/Chart.min.js"></script>
- <script type="text/javascript" src="/static/jquery.dataTables.min.js"></script>
- <script type="text/javascript" src="/static/highlight.min.js"></script>
- <script type="text/javascript" src="/bm.js"></script>
- <script type="text/javascript">
- $(document).ready(function() {
- $.getJSON('/manifest.json', function(specs){
- loadSpecs(specs);
- })
- });
- </script>
- </body>
-</html>
diff --git a/thirdparty/ryml/ext/c4core/cmake/c4CatSources.cmake b/thirdparty/ryml/ext/c4core/cmake/c4CatSources.cmake
deleted file mode 100644
index 1633989af..000000000
--- a/thirdparty/ryml/ext/c4core/cmake/c4CatSources.cmake
+++ /dev/null
@@ -1,105 +0,0 @@
-if(NOT _c4CatSourcesIncluded)
-set(_c4CatSourcesIncluded ON)
-
-
-#------------------------------------------------------------------------------
-# concatenate the source files to an output file, adding preprocessor adjustment
-# for correct file/line reporting
-function(c4_cat_sources files output umbrella_target)
- _c4_cat_sources_create_cat(cat)
- c4_to_full_path("${files}" full_files) # we must work with full paths
- c4_separate_list("${full_files}" sepfiles) # and use a string instead of a list
- c4_dbg("${_c4_prefix}: catting sources to ${output}")
- if(NOT EXISTS "${output}")
- # the cat command is executed at build time, but we need the output
- # file to exist to be able to create the target. so to bootstrap, just
- # run the command now
- c4_dbg("${_c4_prefix}: creating ${output} for the first time")
- execute_process(
- COMMAND ${cat} "${sepfiles}" "${output}"
- WORKING_DIRECTORY "${CMAKE_BINARY_DIR}"
- )
- else()
- c4_dbg("output exists: ${output}")
- endif()
- # add a custom command invoking our cat script for the input files
- add_custom_command(OUTPUT ${output}
- COMMAND ${cat} "${sepfiles}" "${output}"
- DEPENDS ${files}
- WORKING_DIRECTORY "${CMAKE_BINARY_DIR}"
- COMMENT "concatenating sources to ${output}")
- if(NOT TARGET ${umbrella_target})
- add_custom_target(${umbrella_target} DEPENDS ${output} ${files})
- endif()
-endfunction(c4_cat_sources)
-
-
-#------------------------------------------------------------------------------
-# get a cat script
-function(_c4_cat_sources_create_cat catfile)
- # create a script to concatenate the sources
- if(WIN32)
- set(cat ${CMAKE_BINARY_DIR}/_c4catfiles.bat)
- set(cattmp ${CMAKE_BINARY_DIR}/${CMAKE_FILES_DIRECTORY}/_c4catfiles.bat)
- else()
- set(cat ${CMAKE_BINARY_DIR}/_c4catfiles.sh)
- set(cattmp ${CMAKE_BINARY_DIR}/${CMAKE_FILES_DIRECTORY}/_c4catfiles.sh)
- endif()
- set(${catfile} ${cat} PARENT_SCOPE)
- if(NOT EXISTS ${cat})
- if(WIN32)
- file(WRITE ${cattmp} "
-setlocal EnableDelayedExpansion
-set \"src_files=%1\"
-set \"out_file=%2\"
-echo.>\"out_file%\"
-for %%f in (%src_files%) do (
- echo.>>\"%out_file%\"
- echo.>>\"%out_file%\"
- echo \"/*BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB*/\".>>\"%out_file%\"
- echo \"/*BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB*/\".>>\"%out_file%\"
- echo \"/*BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB*/\".>>\"%out_file%\"
- echo \"#line 1 \\\"%%f\\\" // reset __LINE__ and __FILE__ to the correct value\".>>\"%out_file%\"
- type %%f>>\"%out_file%\"
-)
-")
- else()
- file(WRITE ${cattmp} "#!/bin/sh
-
-src_files=$1
-out_file=$2
-#echo \"src_files $src_files\"
-#echo \"out_file $out_file\"
-
-cat > $out_file << EOF
-// DO NOT EDIT.
-// this is an auto-generated file, and will be overwritten
-EOF
-for f in $src_files ; do
- cat >> $out_file <<EOF
-
-
-/*BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB*/
-/*BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB*/
-/*BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB*/
-#line 1 \"$f\"
-EOF
- cat $f >> $out_file
-done
-
-echo \"Wrote output to $out_file\"
-")
- endif()
- # add execute permissions
- get_filename_component(catdir ${cat} DIRECTORY)
- file(COPY ${cattmp} DESTINATION ${catdir}
- FILE_PERMISSIONS
- OWNER_READ OWNER_WRITE OWNER_EXECUTE
- GROUP_READ GROUP_EXECUTE
- WORLD_READ WORLD_EXECUTE
- )
- endif()
-endfunction()
-
-
-endif(NOT _c4CatSourcesIncluded)
diff --git a/thirdparty/ryml/ext/c4core/cmake/c4Doxygen.cmake b/thirdparty/ryml/ext/c4core/cmake/c4Doxygen.cmake
deleted file mode 100644
index b5e018872..000000000
--- a/thirdparty/ryml/ext/c4core/cmake/c4Doxygen.cmake
+++ /dev/null
@@ -1,121 +0,0 @@
-# (C) 2019 Joao Paulo Magalhaes <[email protected]>
-if(NOT _c4_doxygen_included)
-set(_c4_doxygen_included ON)
-
-
-#------------------------------------------------------------------------------
-# TODO use customizations from https://cmake.org/cmake/help/v3.9/module/FindDoxygen.html
-function(c4_setup_doxygen umbrella_option)
- cmake_dependent_option(${_c4_uprefix}BUILD_DOCS "Enable targets to build documentation for ${prefix}" ON "${umbrella_option}" OFF)
- if(${_c4_uprefix}BUILD_DOCS)
- find_package(Doxygen QUIET)
- if(DOXYGEN_FOUND)
- c4_log("enabling documentation targets")
- else()
- c4_dbg("doxygen not found")
- endif()
- endif()
-endfunction()
-
-#------------------------------------------------------------------------------
-function(c4_add_doxygen doc_name)
- if(NOT ${_c4_uprefix}BUILD_DOCS)
- return()
- endif()
- #
- set(opt0
- )
- set(opt1
- DOXYFILE DOXYFILE_IN
- PROJ
- PROJ_BRIEF
- VERSION
- OUTPUT_DIR
- CLANG_DATABASE_PATH
- )
- set(optN
- INPUT
- FILE_PATTERNS
- EXCLUDE
- EXCLUDE_PATTERNS
- EXCLUDE_SYMBOLS
- STRIP_FROM_PATH
- STRIP_FROM_INC_PATH
- EXAMPLE_PATH
- )
- cmake_parse_arguments("" "${opt0}" "${opt1}" "${optN}" ${ARGN})
- #
- if(NOT _PROJ)
- set(_PROJ ${_c4_ucprefix})
- endif()
- if(NOT _DOXYFILE AND NOT _DOXYFILE_IN)
- set(_DOXYFILE_IN ${CMAKE_CURRENT_LIST_DIR}/Doxyfile.in)
- endif()
- if(NOT _OUTPUT_DIR)
- if("${doc_name}" MATCHES "^[Dd]oc")
- set(_OUTPUT_DIR ${CMAKE_CURRENT_BINARY_DIR}/${doc_name})
- else()
- set(_OUTPUT_DIR ${CMAKE_CURRENT_BINARY_DIR}/doc/${doc_name})
- endif()
- endif()
- #
- _c4_doxy_fwd_to_cmd(_PROJ OFF)
- _c4_doxy_fwd_to_cmd(_PROJ_BRIEF OFF)
- _c4_doxy_fwd_to_cmd(_VERSION OFF)
- _c4_doxy_fwd_to_cmd(_OUTPUT_DIR OFF)
- _c4_doxy_fwd_to_cmd(_CLANG_DATABASE_PATH OFF)
- _c4_doxy_fwd_to_cmd(_INPUT ON)
- _c4_doxy_fwd_to_cmd(_FILE_PATTERNS ON)
- _c4_doxy_fwd_to_cmd(_EXCLUDE ON)
- _c4_doxy_fwd_to_cmd(_EXCLUDE_PATTERNS ON)
- _c4_doxy_fwd_to_cmd(_EXCLUDE_SYMBOLS ON)
- _c4_doxy_fwd_to_cmd(_STRIP_FROM_PATH ON)
- _c4_doxy_fwd_to_cmd(_STRIP_FROM_INC_PATH ON)
- _c4_doxy_fwd_to_cmd(_EXAMPLE_PATH ON)
- #
- if("${doc_name}" MATCHES "^[Dd]oc")
- set(tgt ${_c4_lcprefix}-${doc_name})
- else()
- set(tgt ${_c4_lcprefix}-doc-${doc_name})
- endif()
- #
- if(_DOXYFILE)
- set(doxyfile_out ${_DOXYFILE})
- elseif(_DOXYFILE_IN)
- set(doxyfile_out ${_OUTPUT_DIR}/Doxyfile)
- set(config_script ${_c4_project_dir}/c4DoxygenConfig.cmake)
- add_custom_command(OUTPUT ${doxyfile_out}
- COMMAND ${CMAKE_COMMAND} -E remove -f ${doxyfile_out}
- COMMAND ${CMAKE_COMMAND} -DDOXYFILE_IN=${_DOXYFILE_IN} -DDOXYFILE_OUT=${doxyfile_out} ${defs} '-DALLVARS=${allvars}' '-DLISTVARS=${listvars}' -P ${config_script}
- DEPENDS ${_DOXYFILE_IN} ${config_script}
- COMMENT "${tgt}: generating ${doxyfile_out}"
- WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
- endif()
- #
- add_custom_target(${tgt}
- COMMAND ${DOXYGEN_EXECUTABLE} ${doxyfile_out}
- DEPENDS ${doxyfile_out}
- WORKING_DIRECTORY ${_OUTPUT_DIR}
- COMMENT "${tgt}: docs will be placed in ${_OUTPUT_DIR}"
- VERBATIM)
- _c4_set_target_folder(${tgt} doc)
-endfunction()
-
-
-macro(_c4_doxy_fwd_to_cmd varname is_list)
- if(NOT ("${${varname}}" STREQUAL ""))
- if("${defs}" STREQUAL "")
- set(li "-D${varname}=${${varname}}")
- else()
- set(li ${defs})
- list(APPEND li "-D${varname}='${${varname}}'")
- endif()
- set(defs ${li})
- endif()
- set(allvars "${allvars};${varname}")
- if(${is_list})
- set(listvars "${listvars};${varname}")
- endif()
-endmacro()
-
-endif(NOT _c4_doxygen_included)
diff --git a/thirdparty/ryml/ext/c4core/cmake/c4DoxygenConfig.cmake b/thirdparty/ryml/ext/c4core/cmake/c4DoxygenConfig.cmake
deleted file mode 100644
index b472cab88..000000000
--- a/thirdparty/ryml/ext/c4core/cmake/c4DoxygenConfig.cmake
+++ /dev/null
@@ -1,24 +0,0 @@
-function(_c4_doxy_list_to_str var)
- set(il)
- foreach(i ${${var}})
- if("${il}" STREQUAL "")
- set(il "${i}")
- else()
- set(il "${il} ${i}")
- endif()
- endforeach()
- set(${var} "${il}" PARENT_SCOPE)
-endfunction()
-
-string(REPLACE " " ";" ALLVARS ${ALLVARS})
-string(REPLACE " " ";" LISTVARS ${LISTVARS})
-
-foreach(var ${LISTVARS})
- _c4_doxy_list_to_str(${var})
-endforeach()
-
-foreach(var ${ALLVARS})
- message(STATUS "${var}='${${var}}'")
-endforeach()
-
-configure_file(${DOXYFILE_IN} ${DOXYFILE_OUT} @ONLY)
diff --git a/thirdparty/ryml/ext/c4core/cmake/c4GetTargetPropertyRecursive.cmake b/thirdparty/ryml/ext/c4core/cmake/c4GetTargetPropertyRecursive.cmake
deleted file mode 100644
index 45a74aa9e..000000000
--- a/thirdparty/ryml/ext/c4core/cmake/c4GetTargetPropertyRecursive.cmake
+++ /dev/null
@@ -1,186 +0,0 @@
-if(NOT _c4_GTPR_included)
-set(_c4_GTPR_included ON)
-
-function(c4_get_target_property_recursive outputvar target property)
- #
- # helps for debugging
- if(_stack)
- set(_stack "${_stack}/${target}")
- else()
- set(_stack "${property}:${target}")
- endif()
- #
- # what type of target is this?
- get_target_property(_rec_target_type ${target} TYPE)
- c4_dbg("${_stack} [type=${_rec_target_type}]: get property ${property}")
- #
- # adjust the property names for interface targets
- set(_ept_prop_ll LINK_LIBRARIES)
- if(_rec_target_type STREQUAL "INTERFACE_LIBRARY")
- set(_ept_prop_ll INTERFACE_LINK_LIBRARIES)
- if(property STREQUAL "INCLUDE_DIRECTORIES")
- c4_dbg("${_stack} [type=${_rec_target_type}]: property ${property} ---> INTERFACE_INCLUDE_DIRECTORIES")
- set(property INTERFACE_INCLUDE_DIRECTORIES)
- elseif(property STREQUAL "LINK_LIBRARIES")
- c4_dbg("${_stack} [type=${_rec_target_type}]: property ${property} ---> INTERFACE_LINK_LIBRARIES")
- set(property INTERFACE_LINK_LIBRARIES)
- endif()
- endif()
- #
- get_target_property(_ept_li ${target} ${property})
- c4_dbg("${_stack} [type=${_rec_target_type}]: property ${property}=${_ept_li}")
- if(NOT _ept_li) # the property may not be set (ie foo-NOTFOUND)
- set(_ept_li) # so clear it in that case
- endif()
- #
- # now descend and append the property for each of the linked libraries
- get_target_property(_ept_deps ${target} ${_ept_prop_ll})
- if(_ept_deps)
- foreach(_ept_ll ${_ept_deps})
- if(TARGET ${_ept_ll})
- c4_get_target_property_recursive(_ept_out ${_ept_ll} ${property})
- list(APPEND _ept_li ${_ept_out})
- endif()
- endforeach()
- endif()
- #
- foreach(le_ ${_ept_li})
- string(STRIP "${le_}" le)
- if(NOT le)
- elseif("${le}" STREQUAL "")
- else()
- list(APPEND _ept_li_f ${le})
- endif()
- endforeach()
- c4_dbg("${_stack} [type=${_rec_target_type}]: final=${_ept_li_f}")
- set(${outputvar} ${_ept_li_f} PARENT_SCOPE)
-endfunction()
-
-
-#------------------------------------------------------------------------------
-#------------------------------------------------------------------------------
-#------------------------------------------------------------------------------
-
-
-function(c4_set_transitive_property target prop_name prop_value)
- set_target_properties(${target} PROPERTIES "${prop_name}" "${prop_value}")
-endfunction()
-
-
-function(c4_append_transitive_property target prop_name prop_value)
- get_target_property(curr_value ${target} "${prop_name}")
- if(curr_value)
- list(APPEND curr_value "${prop_value}")
- else()
- set(curr_value "${prop_value}")
- endif()
- c4_set_transitive_property(${target} "${prop_name}" "${curr_value}")
-endfunction()
-
-
-# TODO: maybe we can use c4_get_target_property_recursive()?
-function(c4_get_transitive_property target prop_name out)
- if(NOT TARGET ${target})
- return()
- endif()
- # these will be the names of the variables we'll use to cache the result
- set(_trval _C4_TRANSITIVE_${prop_name})
- set(_trmark _C4_TRANSITIVE_${prop_name}_DONE)
- #
- get_target_property(cached ${target} ${_trmark}) # is it cached already
- if(cached)
- get_target_property(p ${target} _C4_TRANSITIVE_${prop_name})
- set(${out} ${p} PARENT_SCOPE)
- #c4_dbg("${target}: c4_get_transitive_property ${target} ${prop_name}: cached='${p}'")
- else()
- #c4_dbg("${target}: gathering transitive property: ${prop_name}...")
- set(interleaved)
- get_target_property(lv ${target} ${prop_name})
- if(lv)
- list(APPEND interleaved ${lv})
- endif()
- c4_get_transitive_libraries(${target} LINK_LIBRARIES libs)
- c4_get_transitive_libraries(${target} INTERFACE_LINK_LIBRARIES ilibs)
- list(APPEND libs ${ilibs})
- foreach(lib ${libs})
- #c4_dbg("${target}: considering ${lib}...")
- if(NOT lib)
- #c4_dbg("${target}: considering ${lib}: not found, skipping...")
- continue()
- endif()
- if(NOT TARGET ${lib})
- #c4_dbg("${target}: considering ${lib}: not a target, skipping...")
- continue()
- endif()
- get_target_property(lv ${lib} ${prop_name})
- if(lv)
- list(APPEND interleaved ${lv})
- endif()
- c4_get_transitive_property(${lib} ${prop_name} v)
- if(v)
- list(APPEND interleaved ${v})
- endif()
- #c4_dbg("${target}: considering ${lib}---${interleaved}")
- endforeach()
- #c4_dbg("${target}: gathering transitive property: ${prop_name}: ${interleaved}")
- set(${out} ${interleaved} PARENT_SCOPE)
- get_target_property(aliased_target ${target} ALIASED_TARGET)
- if(NOT aliased_target)
- set_target_properties(${target} PROPERTIES
- ${_trmark} ON
- ${_trval} "${interleaved}")
- endif()
- endif()
-endfunction()
-
-
-function(c4_get_transitive_libraries target prop_name out)
- if(NOT TARGET ${target})
- return()
- endif()
- # these will be the names of the variables we'll use to cache the result
- set(_trval _C4_TRANSITIVE_${prop_name})
- set(_trmark _C4_TRANSITIVE_${prop_name}_DONE)
- #
- get_target_property(cached ${target} ${_trmark})
- if(cached)
- get_target_property(p ${target} ${_trval})
- set(${out} ${p} PARENT_SCOPE)
- #c4_dbg("${target}: c4_get_transitive_libraries ${target} ${prop_name}: cached='${p}'")
- else()
- #c4_dbg("${target}: gathering transitive libraries: ${prop_name}...")
- get_target_property(target_type ${target} TYPE)
- set(interleaved)
- if(NOT ("${target_type}" STREQUAL "INTERFACE_LIBRARY")
- AND ("${prop_name}" STREQUAL LINK_LIBRARIES))
- get_target_property(l ${target} ${prop_name})
- foreach(ll ${l})
- #c4_dbg("${target}: considering ${ll}...")
- if(NOT ll)
- #c4_dbg("${target}: considering ${ll}: not found, skipping...")
- continue()
- endif()
- if(NOT ll)
- #c4_dbg("${target}: considering ${ll}: not a target, skipping...")
- continue()
- endif()
- list(APPEND interleaved ${ll})
- c4_get_transitive_libraries(${ll} ${prop_name} v)
- if(v)
- list(APPEND interleaved ${v})
- endif()
- #c4_dbg("${target}: considering ${ll}---${interleaved}")
- endforeach()
- endif()
- #c4_dbg("${target}: gathering transitive libraries: ${prop_name}: result='${interleaved}'")
- set(${out} ${interleaved} PARENT_SCOPE)
- get_target_property(aliased_target ${target} ALIASED_TARGET)
- if(NOT aliased_target)
- set_target_properties(${target} PROPERTIES
- ${_trmark} ON
- ${_trval} "${interleaved}")
- endif()
- endif()
-endfunction()
-
-endif(NOT _c4_GTPR_included)
diff --git a/thirdparty/ryml/ext/c4core/cmake/c4Project.cmake b/thirdparty/ryml/ext/c4core/cmake/c4Project.cmake
deleted file mode 100644
index 60c8717fe..000000000
--- a/thirdparty/ryml/ext/c4core/cmake/c4Project.cmake
+++ /dev/null
@@ -1,3691 +0,0 @@
-if(NOT _c4_project_included)
-set(_c4_project_included ON)
-set(_c4_project_file ${CMAKE_CURRENT_LIST_FILE})
-set(_c4_project_dir ${CMAKE_CURRENT_LIST_DIR})
-
-
-# "I didn't have time to write a short letter, so I wrote a long one
-# instead." -- Mark Twain
-#
-# ... Eg, hopefully this code will be cleaned up. There's a lot of
-# code here that can be streamlined into a more intuitive arrangement.
-
-
-cmake_minimum_required(VERSION 3.12 FATAL_ERROR)
-
-list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR})
-set_property(GLOBAL PROPERTY USE_FOLDERS ON)
-
-include(ConfigurationTypes)
-include(CreateSourceGroup)
-include(c4SanitizeTarget)
-include(c4StaticAnalysis)
-include(PrintVar)
-include(c4CatSources)
-include(c4Doxygen)
-include(PatchUtils)
-
-
-#------------------------------------------------------------------------------
-#------------------------------------------------------------------------------
-#------------------------------------------------------------------------------
-# define c4 project settings
-
-set(C4_EXTERN_DIR "$ENV{C4_EXTERN_DIR}" CACHE PATH "the directory where imported projects should be looked for (or cloned in when not found)")
-set(C4_DBG_ENABLED OFF CACHE BOOL "enable detailed cmake logs in c4Project code")
-set(C4_LIBRARY_TYPE "" CACHE STRING "default library type: either \"\"(defer to BUILD_SHARED_LIBS),INTERFACE,STATIC,SHARED,MODULE")
-set(C4_SOURCE_TRANSFORM NONE CACHE STRING "global source transform method")
-set(C4_HDR_EXTS "h;hpp;hh;h++;hxx" CACHE STRING "list of header extensions for determining which files are headers")
-set(C4_SRC_EXTS "c;cpp;cc;c++;cxx;cu;" CACHE STRING "list of compilation unit extensions for determining which files are sources")
-set(C4_ADD_EXTS "natvis" CACHE STRING "list of additional file extensions that might be added as sources to targets")
-set(C4_GEN_SRC_EXT "cpp" CACHE STRING "the extension of the output source files resulting from concatenation")
-set(C4_GEN_HDR_EXT "hpp" CACHE STRING "the extension of the output header files resulting from concatenation")
-set(C4_CXX_STANDARDS "20;17;14;11" CACHE STRING "list of CXX standards")
-set(C4_CXX_STANDARD_DEFAULT "11" CACHE STRING "the default CXX standard for projects not specifying one")
-
-
-#------------------------------------------------------------------------------
-#------------------------------------------------------------------------------
-#------------------------------------------------------------------------------
-
-macro(c4_log)
- message(STATUS "${_c4_prefix}: ${ARGN}")
-endmacro()
-
-
-macro(c4_err)
- message(FATAL_ERROR "${_c4_prefix}: ${ARGN}")
-endmacro()
-
-
-macro(c4_dbg)
- if(C4_DBG_ENABLED)
- message(STATUS "${_c4_prefix}: ${ARGN}")
- endif()
-endmacro()
-
-
-macro(c4_log_var varname)
- c4_log("${varname}=${${varname}} ${ARGN}")
-endmacro()
-macro(c4_log_vars)
- set(____s____)
- foreach(varname ${ARGN})
- set(____s____ "${____s____}${varname}=${${varname}} ")
- endforeach()
- c4_log("${____s____}")
-endmacro()
-macro(c4_dbg_var varname)
- c4_dbg("${varname}=${${varname}} ${ARGN}")
-endmacro()
-macro(c4_log_var_if varname)
- if(${varname})
- c4_log("${varname}=${${varname}} ${ARGN}")
- endif()
-endmacro()
-macro(c4_dbg_var_if varname)
- if(${varname})
- c4_dbg("${varname}=${${varname}} ${ARGN}")
- endif()
-endmacro()
-
-
-macro(_c4_show_pfx_vars)
- if(NOT ("${ARGN}" STREQUAL ""))
- c4_log("prefix vars: ${ARGN}")
- endif()
- print_var(_c4_prefix)
- print_var(_c4_ocprefix)
- print_var(_c4_ucprefix)
- print_var(_c4_lcprefix)
- print_var(_c4_oprefix)
- print_var(_c4_uprefix)
- print_var(_c4_lprefix)
-endmacro()
-
-
-function(c4_zero_pad padded size str)
- string(LENGTH "${str}" len)
- math(EXPR numchars "${size} - ${len}")
- if(numchars EQUAL 0)
- set(${padded} "${str}" PARENT_SCOPE)
- else()
- set(out "${str}")
- math(EXPR ncm1 "${numchars} - 1")
- foreach(z RANGE ${ncm1})
- set(out "0${out}")
- endforeach()
- set(${padded} "${out}" PARENT_SCOPE)
- endif()
-endfunction()
-
-
-#------------------------------------------------------------------------------
-#------------------------------------------------------------------------------
-#------------------------------------------------------------------------------
-
-# handy macro for dealing with arguments in one single statement.
-# look for example usage cases below.
-macro(_c4_handle_args)
- set(opt0arg
- )
- set(opt1arg
- _PREFIX
- )
- set(optNarg
- _ARGS0
- _ARGS1
- _ARGSN
- _ARGS
- _DEPRECATE
- )
- # parse the arguments to this macro to find out the required arguments
- cmake_parse_arguments("__c4ha" "${opt0arg}" "${opt1arg}" "${optNarg}" ${ARGN})
- # now parse the required arguments
- cmake_parse_arguments("${__c4ha__PREFIX}" "${__c4ha__ARGS0}" "${__c4ha__ARGS1}" "${__c4ha__ARGSN}" ${__c4ha__ARGS})
- # raise an error on deprecated arguments
- foreach(a ${__c4ha__DEPRECATE})
- list(FIND __c4ha__ARGS ${a} contains)
- if(NOT (${contains} EQUAL -1))
- c4err("${a} is deprecated")
- endif()
- endforeach()
-endmacro()
-
-# fallback to provided default(s) if argument is not set
-macro(_c4_handle_arg argname)
- if("${_${argname}}" STREQUAL "")
- set(_${argname} "${ARGN}")
- else()
- set(_${argname} "${_${argname}}")
- endif()
-endmacro()
-macro(_c4_handle_arg_no_pfx argname)
- if("${${argname}}" STREQUAL "")
- set(${argname} "${ARGN}")
- else()
- set(${argname} "${${argname}}")
- endif()
-endmacro()
-
-
-# if ${_${argname}} is non empty, return it
-# otherwise, fallback to ${_c4_uprefix}${argname}
-# otherwise, fallback to C4_${argname}
-# otherwise, fallback to provided default through ${ARGN}
-macro(_c4_handle_arg_or_fallback argname)
- if(NOT ("${_${argname}}" STREQUAL ""))
- c4_dbg("handle arg ${argname}: picking explicit value _${argname}=${_${argname}}")
- else()
- foreach(_c4haf_varname "${_c4_uprefix}${argname}" "C4_${argname}" "${argname}" "CMAKE_${argname}")
- set(v ${${_c4haf_varname}})
- if("${v}" STREQUAL "")
- c4_dbg("handle arg ${argname}: ${_c4haf_varname}: empty, continuing")
- else()
- c4_dbg("handle arg ${argname}: ${_c4haf_varname}=${v} not empty!")
- c4_setg(_${argname} "${v}")
- break()
- endif()
- endforeach()
- if("${_${argname}}" STREQUAL "")
- c4_dbg("handle arg ${argname}: picking default: ${ARGN}")
- c4_setg(_${argname} "${ARGN}")
- endif()
- endif()
-endmacro()
-
-
-#------------------------------------------------------------------------------
-#------------------------------------------------------------------------------
-#------------------------------------------------------------------------------
-
-function(c4_get_config var name)
- c4_dbg("get_config: ${var} ${name}")
- c4_get_from_first_of(config ${ARGN} VARS ${_c4_uprefix}${name} C4_${name} ${name})
- c4_dbg("get_config: ${var} ${name}=${config}")
- set(${var} ${config} PARENT_SCOPE)
-endfunction()
-
-
-function(c4_get_from_first_of var)
- _c4_handle_args(_ARGS ${ARGN}
- _ARGS0
- REQUIRED # raise an error if no set variable was found
- ENV # if none of the provided vars is given,
- # then search next on environment variables
- # of the same name, using the same sequence
- _ARGS1
- DEFAULT
- _ARGSN
- VARS
- )
- c4_dbg("get_from_first_of(): searching ${var}")
- foreach(_var ${_VARS})
- set(val ${${_var}})
- c4_dbg("${var}: searching ${_var}=${val}")
- if(NOT ("${val}" STREQUAL ""))
- set(${var} "${val}" PARENT_SCOPE)
- return()
- endif()
- endforeach()
- if(_ENV)
- foreach(_envvar ${_VARS})
- set(val $ENV{${_envvar}})
- c4_dbg("${var}: searching environment variable ${_envvar}=${val}")
- if(NOT ("${val}" STREQUAL ""))
- c4_dbg("${var}: picking ${val} from ${_envvar}")
- set(${var} "${val}" PARENT_SCOPE)
- return()
- endif()
- endforeach()
- endif()
- if(_REQUIRED)
- c4_err("could not find a value for the variable ${var}")
- endif()
- set(${var} ${_DEFAULT} PARENT_SCOPE)
-endfunction()
-
-
-#------------------------------------------------------------------------------
-#------------------------------------------------------------------------------
-#------------------------------------------------------------------------------
-
-# assumes a prior call to project()
-function(c4_project)
- _c4_handle_args(_ARGS ${ARGN}
- _ARGS0 # zero-value macro arguments
- STANDALONE # Declare that targets from this project MAY be
- # compiled in standalone mode. In this mode, any
- # designated libraries on which a target depends
- # will be incorporated into the target instead of
- # being linked with it. The effect is to "flatten"
- # those libraries into the requesting library, with
- # their sources now becoming part of the requesting
- # library; their dependencies are transitively handled.
- # Note that requesting targets must explicitly
- # opt-in to this behavior via the INCORPORATE
- # argument to c4_add_library() or
- # c4_add_executable(). Note also that this behavior
- # is only enabled if this project's option
- # ${prefix}_STANDALONE or C4_STANDALONE is set to ON.
- _ARGS1 # one-value macro arguments
- AUTHOR # specify author(s); used in cpack
- VERSION # cmake does not accept semantic versioning so we provide
- # that here (see https://gitlab.kitware.com/cmake/cmake/-/issues/16716)
- CXX_STANDARD # one of latest;${C4_VALID_CXX_STANDARDS}
- # if this is not provided, falls back on
- # ${uprefix}CXX_STANDARD, then C4_CXX_STANDARD,
- # then CXX_STANDARD. if none are provided,
- # defaults to 11
- _ARGSN # multi-value macro arguments
- )
- # get the prefix from the call to project()
- set(prefix ${PROJECT_NAME})
- string(TOUPPER "${prefix}" ucprefix) # ucprefix := upper case prefix
- string(TOLOWER "${prefix}" lcprefix) # lcprefix := lower case prefix
- if(NOT _c4_prefix)
- c4_setg(_c4_is_root_proj ON)
- c4_setg(_c4_root_proj ${prefix})
- c4_setg(_c4_root_uproj ${ucprefix})
- c4_setg(_c4_root_lproj ${lcprefix})
- c4_setg(_c4_curr_path "")
- else()
- c4_setg(_c4_is_root_proj OFF)
- if(_c4_curr_path)
- c4_setg(_c4_curr_path "${_c4_curr_path}/${prefix}")
- else()
- c4_setg(_c4_curr_path "${prefix}")
- endif()
- endif()
- c4_setg(_c4_curr_subproject ${prefix})
- # get the several prefix flavors
- c4_setg(_c4_ucprefix ${ucprefix})
- c4_setg(_c4_lcprefix ${lcprefix})
- c4_setg(_c4_ocprefix ${prefix}) # ocprefix := original case prefix
- c4_setg(_c4_prefix ${prefix}) # prefix := original prefix
- c4_setg(_c4_oprefix ${prefix}) # oprefix := original prefix
- c4_setg(_c4_uprefix ${_c4_ucprefix}) # upper prefix: for variables
- c4_setg(_c4_lprefix ${_c4_lcprefix}) # lower prefix: for targets
- if(_c4_oprefix)
- c4_setg(_c4_oprefix "${_c4_oprefix}_")
- endif()
- if(_c4_uprefix)
- c4_setg(_c4_uprefix "${_c4_uprefix}_")
- endif()
- if(_c4_lprefix)
- c4_setg(_c4_lprefix "${_c4_lprefix}-")
- endif()
- #
- if(_STANDALONE)
- option(${_c4_uprefix}STANDALONE
- "Enable compilation of opting-in targets from ${_c4_lcprefix} in standalone mode (ie, incorporate subprojects as specified in the INCORPORATE clause to c4_add_library/c4_add_target)"
- ${_c4_is_root_proj})
- c4_setg(_c4_root_proj_standalone ${_c4_uprefix}STANDALONE)
- endif()
- _c4_handle_arg_or_fallback(CXX_STANDARD ${C4_CXX_STANDARD_DEFAULT})
- _c4_handle_arg(VERSION 0.0.0-pre0)
- _c4_handle_arg(AUTHOR "")
- _c4_handle_semantic_version(${_VERSION})
- #
- # make sure project-wide settings are defined -- see cmake's
- # documentation for project(), which defines these and other
- # variables
- if("${PROJECT_DESCRIPTION}" STREQUAL "")
- c4_setg(PROJECT_DESCRIPTION "${prefix}")
- c4_setg(${prefix}_DESCRIPTION "${prefix}")
- endif()
- if("${PROJECT_HOMEPAGE_URL}" STREQUAL "")
- c4_setg(PROJECT_HOMEPAGE_URL "")
- c4_setg(${prefix}_HOMEPAGE_URL "")
- endif()
- # other specific c4_project properties
- c4_setg(PROJECT_AUTHOR "${_AUTHOR}")
- c4_setg(${prefix}_AUTHOR "${_AUTHOR}")
-
- # CXX standard
- if("${_CXX_STANDARD}" STREQUAL "latest")
- _c4_find_latest_supported_cxx_standard(_CXX_STANDARD)
- endif()
- c4_log("using C++ standard: C++${_CXX_STANDARD}")
- c4_set_proj_prop(CXX_STANDARD "${_CXX_STANDARD}")
- c4_setg(${_c4_uprefix}CXX_STANDARD "${_CXX_STANDARD}")
- if(${_CXX_STANDARD})
- c4_set_cxx(${_CXX_STANDARD})
- endif()
-
- # we are opinionated with respect to directory structure
- c4_setg(${_c4_uprefix}SRC_DIR ${CMAKE_CURRENT_LIST_DIR}/src)
- c4_setg(${_c4_uprefix}EXT_DIR ${CMAKE_CURRENT_LIST_DIR}/ext)
- c4_setg(${_c4_uprefix}API_DIR ${CMAKE_CURRENT_LIST_DIR}/api)
- # opionionated also for directory test
- # opionionated also for directory bm (benchmarks)
-
- if("${C4_DEV}" STREQUAL "")
- option(C4_DEV "enable development targets for all c4 projects" OFF)
- endif()
- option(${_c4_uprefix}DEV "enable development targets: tests, benchmarks, sanitize, static analysis, coverage" ${C4_DEV})
-
- if(EXISTS "${CMAKE_CURRENT_LIST_DIR}/test")
- cmake_dependent_option(${_c4_uprefix}BUILD_TESTS "build unit tests" ON ${_c4_uprefix}DEV OFF)
- else()
- c4_dbg("no tests: directory does not exist: ${CMAKE_CURRENT_LIST_DIR}/test")
- endif()
- if(EXISTS "${CMAKE_CURRENT_LIST_DIR}/bm")
- cmake_dependent_option(${_c4_uprefix}BUILD_BENCHMARKS "build benchmarks" ON ${_c4_uprefix}DEV OFF)
- else()
- c4_dbg("no benchmarks: directory does not exist: ${CMAKE_CURRENT_LIST_DIR}/bm")
- endif()
- if(EXISTS "${CMAKE_CURRENT_LIST_DIR}/api")
- cmake_dependent_option(${_c4_uprefix}BUILD_API "build API" OFF ${_c4_uprefix}DEV OFF)
- else()
- c4_dbg("no API generation: directory does not exist: ${CMAKE_CURRENT_LIST_DIR}/api")
- endif()
- if(_c4_is_root_proj)
- c4_setup_coverage()
- endif()
- c4_setup_valgrind(${_c4_uprefix}DEV)
- c4_setup_sanitize(${_c4_uprefix}DEV)
- c4_setup_static_analysis(${_c4_uprefix}DEV)
- c4_setup_doxygen(${_c4_uprefix}DEV)
-
- # option to use libc++
- option(${_c4_uprefix}USE_LIBCXX "use libc++ instead of the default standard library" OFF)
- if(${_c4_uprefix}USE_LIBCXX)
- if(CMAKE_CXX_COMPILER_ID MATCHES ".*Clang")
- c4_log("using libc++")
- list(APPEND CMAKE_CXX_FLAGS -stdlib=libc++)
- list(APPEND CMAKE_EXE_LINKER_FLAGS -lc++)
- list(APPEND CMAKE_MODULE_LINKER_FLAGS -lc++)
- list(APPEND CMAKE_SHARED_LINKER_FLAGS -lc++)
- list(APPEND CMAKE_STATIC_LINKER_FLAGS -lc++)
- else()
- c4_err("libc++ can only be used with clang")
- endif()
- endif()
-
- # default compilation flags
- set(${_c4_uprefix}CXX_FLAGS "${${_c4_uprefix}CXX_FLAGS_FWD}" CACHE STRING "compilation flags for ${_c4_prefix} targets")
- set(${_c4_uprefix}CXX_LINKER_FLAGS "${${_c4_uprefix}CXX_LINKER_FLAGS_FWD}" CACHE STRING "linker flags for ${_c4_prefix} targets")
- c4_dbg_var_if(${_c4_uprefix}CXX_LINKER_FLAGS_FWD)
- c4_dbg_var_if(${_c4_uprefix}CXX_FLAGS_FWD)
- c4_dbg_var_if(${_c4_uprefix}CXX_LINKER_FLAGS)
- c4_dbg_var_if(${_c4_uprefix}CXX_FLAGS)
-
- # Dev compilation flags, appended to the project's flags. They
- # are enabled when in dev mode, but provided as a (default-disabled)
- # option when not in dev mode
- c4_dbg_var_if(${_c4_uprefix}CXX_FLAGS_OPT_FWD)
- c4_setg(${_c4_uprefix}CXX_FLAGS_OPT "${${_c4_uprefix}CXX_FLAGS_OPT_FWD}")
- c4_optional_compile_flags_dev(WERROR "Compile with warnings as errors"
- GCC_CLANG -Werror -pedantic-errors
- MSVC /WX
- )
- c4_optional_compile_flags_dev(STRICT_ALIASING "Enable strict aliasing"
- GCC_CLANG -fstrict-aliasing
- MSVC # does it have this?
- )
- c4_optional_compile_flags_dev(PEDANTIC "Compile in pedantic mode"
- GCC ${_C4_PEDANTIC_FLAGS_GCC}
- CLANG ${_C4_PEDANTIC_FLAGS_CLANG}
- MSVC ${_C4_PEDANTIC_FLAGS_MSVC}
- )
- c4_dbg_var_if(${_c4_uprefix}CXX_FLAGS_OPT)
-endfunction(c4_project)
-
-
-# cmake: VERSION argument in project() does not accept semantic versioning
-# see: https://gitlab.kitware.com/cmake/cmake/-/issues/16716
-macro(_c4_handle_semantic_version version)
- # https://stackoverflow.com/questions/18658233/split-string-to-3-variables-in-cmake
- string(REPLACE "." ";" version_list ${version})
- list(GET version_list 0 _major)
- list(GET version_list 1 _minor)
- list(GET version_list 2 _patch)
- if("${_patch}" STREQUAL "")
- set(_patch 1)
- set(_tweak)
- else()
- string(REGEX REPLACE "([0-9]+)[-_.]?(.*)" "\\2" _tweak ${_patch}) # do this first
- string(REGEX REPLACE "([0-9]+)[-_.]?(.*)" "\\1" _patch ${_patch}) # ... because this replaces _patch
- endif()
- # because cmake handles only numeric tweak fields, make sure to skip our
- # semantic tweak field if it is not numeric
- if(${_tweak} MATCHES "^[0-9]+$")
- set(_safe_tweak ${_tweak})
- set(_safe_version ${_major}.${_minor}.${_patch}.${_tweak})
- else()
- set(_safe_tweak)
- set(_safe_version ${_major}.${_minor}.${_patch})
- endif()
- c4_setg(PROJECT_VERSION_FULL ${version})
- c4_setg(PROJECT_VERSION ${_safe_version})
- c4_setg(PROJECT_VERSION_MAJOR ${_major})
- c4_setg(PROJECT_VERSION_MINOR ${_minor})
- c4_setg(PROJECT_VERSION_PATCH ${_patch})
- c4_setg(PROJECT_VERSION_TWEAK "${_safe_tweak}")
- c4_setg(PROJECT_VERSION_TWEAK_FULL "${_tweak}")
- c4_setg(${prefix}_VERSION_FULL ${version})
- c4_setg(${prefix}_VERSION ${_safe_version})
- c4_setg(${prefix}_VERSION_MAJOR ${_major})
- c4_setg(${prefix}_VERSION_MINOR ${_minor})
- c4_setg(${prefix}_VERSION_PATCH ${_patch})
- c4_setg(${prefix}_VERSION_TWEAK "${_safe_tweak}")
- c4_setg(${prefix}_VERSION_TWEAK_FULL "${_tweak}")
-endmacro()
-
-
-# Add targets for testing (dir=./test), benchmark (dir=./bm) and API (dir=./api).
-# Call this macro towards the end of the project's main CMakeLists.txt.
-# Experimental feature: docs.
-function(c4_add_dev_targets)
- if(NOT CMAKE_CURRENT_LIST_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR)
- c4_err("this macro needs to be called on the project's main CMakeLists.txt file")
- endif()
- #
- if(${_c4_uprefix}BUILD_TESTS)
- if(EXISTS "${CMAKE_CURRENT_LIST_DIR}/test")
- c4_dbg("adding tests: ${CMAKE_CURRENT_LIST_DIR}/test")
- enable_testing() # this must be done here (and not inside the
- # test dir) so that the cmake-generated test
- # targets are available at the top level
- add_subdirectory(test)
- endif()
- endif()
- #
- if(${_c4_uprefix}BUILD_BENCHMARKS)
- if(EXISTS "${CMAKE_CURRENT_LIST_DIR}/bm")
- c4_dbg("adding benchmarks: ${CMAKE_CURRENT_LIST_DIR}/bm")
- add_subdirectory(bm)
- endif()
- endif()
- #
- if(${_c4_uprefix}BUILD_API)
- if(EXISTS "${CMAKE_CURRENT_LIST_DIR}/api")
- c4_dbg("adding API: ${d}")
- add_subdirectory(api)
- endif()
- endif()
- #
- # FIXME
- c4_add_doxygen(doc DOXYFILE_IN ${_c4_project_dir}/Doxyfile.in
- PROJ c4core
- INPUT ${${_c4_uprefix}SRC_DIR}
- EXCLUDE ${${_c4_uprefix}EXT_DIR} ${${_c4_uprefix}SRC_DIR}/c4/ext
- STRIP_FROM_PATH ${${_c4_uprefix}SRC_DIR}
- STRIP_FROM_INC_PATH ${${_c4_uprefix}SRC_DIR}
- CLANG_DATABASE_PATH ${CMAKE_BINARY_DIR}
- )
- c4_add_doxygen(doc-full DOXYFILE_IN ${_c4_project_dir}/Doxyfile.full.in
- PROJ c4core
- INPUT ${${_c4_uprefix}SRC_DIR}
- EXCLUDE ${${_c4_uprefix}EXT_DIR} ${${_c4_uprefix}SRC_DIR}/c4/ext
- STRIP_FROM_PATH ${${_c4_uprefix}SRC_DIR}
- STRIP_FROM_INC_PATH ${${_c4_uprefix}SRC_DIR}
- CLANG_DATABASE_PATH ${CMAKE_BINARY_DIR}
- )
-endfunction()
-
-
-function(_c4_get_san_targets target result)
- _c4_get_tgt_prop(san_targets ${target} C4_SAN_TARGETS)
- if(NOT san_targets)
- #c4_err("${target} must have at least itself in its sanitized target list")
- set(${result} ${target} PARENT_SCOPE)
- else()
- set(${result} ${san_targets} PARENT_SCOPE)
- endif()
-endfunction()
-
-
-# -----------------------------------------------------------------------------
-# -----------------------------------------------------------------------------
-# -----------------------------------------------------------------------------
-
-# utilities for compilation flags and defines
-
-# flags enabled only on dev mode
-macro(c4_optional_compile_flags_dev tag desc)
- _c4_handle_args(_ARGS ${ARGN}
- _ARGS0
- _ARGS1
- _ARGSN
- MSVC # flags for Visual Studio compilers
- GCC # flags for gcc compilers
- CLANG # flags for clang compilers
- GCC_CLANG # flags common to gcc and clang
- _DEPRECATE
- )
- cmake_dependent_option(${_c4_uprefix}${tag} "${desc}" ON ${_c4_uprefix}DEV OFF)
- set(optname ${_c4_uprefix}${tag})
- if(${optname})
- c4_dbg("${optname} is enabled. Adding flags...")
- if(MSVC)
- set(flags ${_MSVC})
- elseif(CMAKE_CXX_COMPILER_ID MATCHES ".*Clang")
- set(flags ${_GCC_CLANG};${_CLANG})
- elseif(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
- set(flags ${_GCC_CLANG};${_GCC})
- elseif(CMAKE_CXX_COMPILER_ID STREQUAL "Intel")
- set(flags ${_ALL};${_GCC_CLANG};${_GCC}) # FIXME
- elseif(CMAKE_CXX_COMPILER_ID STREQUAL "IntelLLVM")
- set(flags ${_ALL};${_GCC_CLANG};${_CLANG}) # FIXME
- else()
- c4_err("unknown compiler")
- endif()
- else()
- c4_dbg("${optname} is disabled.")
- endif()
- if(flags)
- c4_log("${tag} flags [${desc}]: ${flags}")
- c4_setg(${_c4_uprefix}CXX_FLAGS_OPT "${${_c4_uprefix}CXX_FLAGS_OPT};${flags}")
- endif()
-endmacro()
-
-
-function(c4_target_compile_flags target)
- _c4_handle_args(_ARGS ${ARGN}
- _ARGS0
- PUBLIC
- PRIVATE
- INTERFACE
- AFTER # this is the default
- BEFORE
- _ARGS1
- _ARGSN
- ALL # flags for all compilers
- MSVC # flags for Visual Studio compilers
- GCC # flags for gcc compilers
- CLANG # flags for clang compilers
- GCC_CLANG # flags common to gcc and clang
- _DEPRECATE
- )
- if(MSVC)
- set(flags ${_ALL};${_MSVC})
- elseif(CMAKE_CXX_COMPILER_ID MATCHES ".*Clang")
- set(flags ${_ALL};${_GCC_CLANG};${_CLANG})
- elseif(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
- set(flags ${_ALL};${_GCC_CLANG};${_GCC})
- elseif(CMAKE_CXX_COMPILER_ID STREQUAL "Intel")
- set(flags ${_ALL};${_GCC_CLANG};${_GCC}) # FIXME
- elseif(CMAKE_CXX_COMPILER_ID STREQUAL "IntelLLVM")
- set(flags ${_ALL};${_GCC_CLANG};${_CLANG}) # FIXME
- else()
- c4_err("unknown compiler")
- endif()
- if(NOT flags)
- c4_dbg("no compile flags to be set")
- return()
- endif()
- if(_AFTER OR (NOT _BEFORE))
- set(mode)
- c4_log("${target}: adding compile flags AFTER: ${flags}")
- elseif(_BEFORE)
- set(mode BEFORE)
- c4_log("${target}: adding compile flags BEFORE: ${flags}")
- endif()
- _c4_get_san_targets(${target} san_targets)
- foreach(st ${san_targets})
- if(_PUBLIC)
- target_compile_options(${st} ${mode} PUBLIC ${flags})
- elseif(_PRIVATE)
- target_compile_options(${st} ${mode} PRIVATE ${flags})
- elseif(_INTERFACE)
- target_compile_options(${st} ${mode} INTERFACE ${flags})
- else()
- c4_err("${target}: must have one of PUBLIC, PRIVATE or INTERFACE")
- endif()
- endforeach()
-endfunction()
-
-
-function(c4_target_definitions target)
- _c4_handle_args(_ARGS ${ARGN}
- _ARGS0
- PUBLIC
- PRIVATE
- INTERFACE
- _ARGS1
- _ARGSN
- ALL # defines for all compilers
- MSVC # defines for Visual Studio compilers
- GCC # defines for gcc compilers
- CLANG # defines for clang compilers
- GCC_CLANG # defines common to gcc and clang
- _DEPRECATE
- )
- if(MSVC)
- set(flags ${_ALL};${_MSVC})
- elseif(CMAKE_CXX_COMPILER_ID MATCHES ".*Clang")
- set(flags ${_ALL};${_GCC_CLANG};${_CLANG})
- elseif(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
- set(flags ${_ALL};${_GCC_CLANG};${_GCC})
- else()
- c4_err("unknown compiler")
- endif()
- if(NOT flags)
- c4_dbg("no compile flags to be set")
- return()
- endif()
- if(_AFTER OR (NOT _BEFORE))
- set(mode)
- c4_log("${target}: adding definitions AFTER: ${flags}")
- elseif(_BEFORE)
- set(mode BEFORE)
- c4_log("${target}: adding definitions BEFORE: ${flags}")
- endif()
- _c4_get_san_targets(${target} san_targets)
- foreach(st ${san_targets})
- if(_PUBLIC)
- target_compile_definitions(${st} ${mode} PUBLIC ${flags})
- elseif(_PRIVATE)
- target_compile_definitions(${st} ${mode} PRIVATE ${flags})
- elseif(_INTERFACE)
- target_compile_definitions(${st} ${mode} INTERFACE ${flags})
- else()
- c4_err("${target}: must have one of PUBLIC, PRIVATE or INTERFACE")
- endif()
- endforeach()
-endfunction()
-
-
-function(c4_target_remove_compile_flags target)
- _c4_handle_args(_ARGS ${ARGN}
- _ARGS0
- PUBLIC # remove only from public compile options
- INTERFACE # remove only from interface compile options
- _ARGS1
- _ARGSN
- MSVC # flags for Visual Studio compilers
- GCC # flags for gcc compilers
- CLANG # flags for clang compilers
- GCC_CLANG # flags common to gcc and clang
- _DEPRECATE
- )
- if(MSVC)
- set(flags ${_MSVC})
- elseif(CMAKE_CXX_COMPILER_ID MATCHES ".*Clang")
- set(flags ${_GCC_CLANG};${_CLANG})
- elseif(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
- set(flags ${_GCC_CLANG};${_GCC})
- else()
- c4_err("unknown compiler")
- endif()
- if(NOT flags)
- return()
- endif()
- _c4_get_san_targets(${target} san_targets)
- foreach(st ${san_targets})
- if(_PUBLIC OR (NOT _INTERFACE))
- get_target_property(co ${st} COMPILE_OPTIONS)
- if(co)
- _c4_remove_entries_from_list("${flags}" co)
- set_target_properties(${st} PROPERTIES COMPILE_OPTIONS "${co}")
- endif()
- endif()
- if(_INTERFACE OR (NOT _PUBLIC))
- get_target_property(ico ${st} INTERFACE_COMPILE_OPTIONS)
- if(ico)
- _c4_remove_entries_from_list("${flags}" ico)
- set_target_properties(${st} PROPERTIES INTERFACE_COMPILE_OPTIONS "${ico}")
- endif()
- endif()
- endforeach()
-endfunction()
-
-
-function(_c4_remove_entries_from_list entries_to_remove list)
- set(str ${${list}})
- string(REPLACE ";" "==?==" str "${str}")
- foreach(entry ${entries_to_remove})
- string(REPLACE "${entry}" "" str "${str}")
- endforeach()
- string(REPLACE "==?==" ";" str "${str}")
- string(REPLACE ";;" ";" str "${str}")
- set(${list} "${str}" PARENT_SCOPE)
-endfunction()
-
-
-
-# pedantic flags...
-# default pedantic flags taken from:
-# https://github.com/lefticus/cpp_starter_project/blob/master/cmake/CompilerWarnings.cmake
-set(_C4_PEDANTIC_FLAGS_MSVC
- /W4 # Baseline reasonable warnings
- /w14242 # 'identifier': conversion from 'type1' to 'type1', possible loss of data
- /w14254 # 'operator': conversion from 'type1:field_bits' to 'type2:field_bits', possible loss of data
- /w14263 # 'function': member function does not override any base class virtual member function
- /w14265 # 'classname': class has virtual functions, but destructor is not virtual instances of this class may not
- # be destructed correctly
- /w14287 # 'operator': unsigned/negative constant mismatch
- /we4289 # nonstandard extension used: 'variable': loop control variable declared in the for-loop is used outside
- # the for-loop scope
- /w14296 # 'operator': expression is always 'boolean_value'
- /w14311 # 'variable': pointer truncation from 'type1' to 'type2'
- /w14545 # expression before comma evaluates to a function which is missing an argument list
- /w14546 # function call before comma missing argument list
- /w14547 # 'operator': operator before comma has no effect; expected operator with side-effect
- /w14549 # 'operator': operator before comma has no effect; did you intend 'operator'?
- /w14555 # expression has no effect; expected expression with side- effect
- /w14619 # pragma warning: there is no warning number 'number'
- /w14640 # Enable warning on thread un-safe static member initialization
- /w14826 # Conversion from 'type1' to 'type_2' is sign-extended. This may cause unexpected runtime behavior.
- /w14905 # wide string literal cast to 'LPSTR'
- /w14906 # string literal cast to 'LPWSTR'
- /w14928 # illegal copy-initialization; more than one user-defined conversion has been implicitly applied
- $<$<VERSION_GREATER:${MSVC_VERSION},1900>:/permissive-> # standards conformance mode for MSVC compiler (only vs2017+)
- )
-
-set(_C4_PEDANTIC_FLAGS_CLANG
- -Wall
- -Wextra
- -pedantic
- -Wshadow # warn the user if a variable declaration shadows one from a parent context
- -Wnon-virtual-dtor # warn the user if a class with virtual functions has a non-virtual destructor. This helps
- # catch hard to track down memory errors
- #-Wold-style-cast # warn for c-style casts
- -Wcast-align # warn for potential performance problem casts
- -Wunused # warn on anything being unused
- -Woverloaded-virtual # warn if you overload (not override) a virtual function
- -Wpedantic # warn if non-standard C++ is used
- -Wconversion # warn on type conversions that may lose data
- -Wsign-conversion # warn on sign conversions
- -Wdouble-promotion # warn if float is implicit promoted to double
- -Wfloat-equal # warn if comparing floats
- -Wformat=2 # warn on security issues around functions that format output (ie printf)
- )
-
-set(_C4_PEDANTIC_FLAGS_GCC ${_C4_PEDANTIC_FLAGS_CLANG}
- -Wlogical-op # where logical operations are used where bitwise were probably wanted
- -Wuseless-cast # where you perform a cast to the same type
- )
-
-if((CMAKE_CXX_COMPILER_ID STREQUAL "GNU") AND (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 6.0))
- list(APPEND _C4_PEDANTIC_FLAGS_GCC
- -Wnull-dereference # warn if a null dereference is detected
- -Wmisleading-indentation # where indentation implies blocks where blocks do not exist
- -Wduplicated-cond # where if-else chain has duplicated conditions
- )
-endif()
-
-if((CMAKE_CXX_COMPILER_ID STREQUAL "GNU") AND (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 7.0))
- list(APPEND _C4_PEDANTIC_FLAGS_GCC
- -Wduplicated-branches # where if-else branches have duplicated code
- )
-endif()
-
-
-#------------------------------------------------------------------------------
-#------------------------------------------------------------------------------
-#------------------------------------------------------------------------------
-
-function(c4_pack_project)
- # if this is the top-level project... pack it.
- if(CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME)
- c4_log("packing the project: ${ARGN}")
- c4_set_default_pack_properties(${ARGN})
- include(CPack)
- endif()
-endfunction()
-
-
-# [WIP] set convenient defaults for the properties used by CPack
-function(c4_set_default_pack_properties)
- _c4_handle_args(_ARGS ${ARGN}
- _ARGS0 # zero-value macro arguments
- _ARGS1 # one-value macro arguments
- TYPE # one of LIBRARY, EXECUTABLE
- _ARGSN # multi-value macro arguments
- )
- set(pd "${PROJECT_SOURCE_DIR}")
- _c4_handle_arg(TYPE EXECUTABLE) # default to EXECUTABLE
- #
- _c4_get_platform_tag(platform_tag)
- if("${_TYPE}" STREQUAL "LIBRARY")
- if(BUILD_SHARED_LIBS)
- set(build_tag "-shared")
- else()
- set(build_tag "-static")
- endif()
- get_property(multi_config GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
- if(multi_config)
- # doesn't work because generators are not evaluated: set(build_tag "${build_tag}-$<CONFIG>")
- # doesn't work because generators are not evaluated: set(build_tag "${build_tag}$<$<CONFIG:Debug>:-Debug>$<$<CONFIG:MinSizeRel>:-MinSizeRel>$<$<CONFIG:Release>:-Release>$<$<CONFIG:RelWithDebInfo>:-RelWithDebInfo>")
- # see also https://stackoverflow.com/questions/44153730/how-to-change-cpack-package-file-name-based-on-configuration
- if(CMAKE_BUILD_TYPE) # in the off-chance it was explicitly set
- set(build_tag "${build_tag}-${CMAKE_BUILD_TYPE}")
- endif()
- else()
- set(build_tag "${build_tag}-${CMAKE_BUILD_TYPE}")
- endif()
- elseif("${_TYPE}" STREQUAL "EXECUTABLE")
- set(build_tag)
- elseif()
- c4_err("unknown TYPE: ${_TYPE}")
- endif()
- #
- c4_setg(CPACK_VERBATIM_VARIABLES true)
- c4_setg(CPACK_PACKAGE_VENDOR "${${_c4_prefix}_HOMEPAGE_URL}")
- c4_setg(CPACK_PACKAGE_CONTACT "${${_c4_prefix}_AUTHOR}")
- c4_setg(CPACK_PACKAGE_DESCRIPTION_SUMMARY "${${_c4_prefix}_DESCRIPTION}")
- if(EXISTS "${pd}/README.md")
- c4_setg(CPACK_PACKAGE_DESCRIPTION_FILE "${pd}/README.md")
- c4_setg(CPACK_PACKAGE_DESCRIPTION_README "${pd}/README.md")
- c4_setg(CPACK_PACKAGE_DESCRIPTION_WELCOME "${pd}/README.md")
- elseif(EXISTS "${pd}/README.txt")
- c4_setg(CPACK_PACKAGE_DESCRIPTION_FILE "${pd}/README.txt")
- c4_setg(CPACK_PACKAGE_DESCRIPTION_README "${pd}/README.txt")
- c4_setg(CPACK_PACKAGE_DESCRIPTION_WELCOME "${pd}/README.txt")
- endif()
- if(EXISTS "${pd}/LICENSE.md")
- c4_setg(CPACK_RESOURCE_FILE_LICENSE "${pd}/LICENSE.md")
- elseif(EXISTS "${pd}/LICENSE.txt")
- c4_setg(CPACK_RESOURCE_FILE_LICENSE "${pd}/LICENSE.txt")
- endif()
- c4_proj_get_version("${pd}" version_tag full major minor patch tweak)
- c4_setg(CPACK_PACKAGE_VERSION "${full}")
- c4_setg(CPACK_PACKAGE_VERSION_MAJOR "${major}")
- c4_setg(CPACK_PACKAGE_VERSION_MINOR "${minor}")
- c4_setg(CPACK_PACKAGE_VERSION_PATCH "${patch}")
- c4_setg(CPACK_PACKAGE_VERSION_TWEAK "${tweak}")
- c4_setg(CPACK_PACKAGE_INSTALL_DIRECTORY "${_c4_prefix}-${version_tag}")
- c4_setg(CPACK_PACKAGE_FILE_NAME "${_c4_prefix}-${version_tag}-${platform_tag}${build_tag}")
- if(WIN32 AND NOT UNIX)
- # There is a bug in NSI that does not handle full UNIX paths properly.
- # Make sure there is at least one set of four backlashes.
- #c4_setg(CPACK_PACKAGE_ICON "${CMake_SOURCE_DIR}/Utilities/Release\\\\InstallIcon.bmp")
- #c4_setg(CPACK_NSIS_INSTALLED_ICON_NAME "bin\\\\MyExecutable.exe")
- c4_setg(CPACK_NSIS_DISPLAY_NAME "${_c4_prefix} ${version_tag}")
- c4_setg(CPACK_NSIS_HELP_LINK "${${_c4_prefix}_HOMEPAGE_URL}")
- c4_setg(CPACK_NSIS_URL_INFO_ABOUT "${${_c4_prefix}_HOMEPAGE_URL}")
- c4_setg(CPACK_NSIS_CONTACT "${${_c4_prefix}_AUTHOR}")
- c4_setg(CPACK_NSIS_MODIFY_PATH ON)
- else()
- #c4_setg(CPACK_STRIP_FILES "bin/MyExecutable")
- #c4_setg(CPACK_SOURCE_STRIP_FILES "")
- c4_setg(CPACK_DEBIAN_PACKAGE_MAINTAINER "${${_c4_prefix}_AUTHOR}")
- endif()
- #c4_setg(CPACK_PACKAGE_EXECUTABLES "MyExecutable" "My Executable")
-endfunction()
-
-
-function(_c4_get_platform_tag tag_)
- if(WIN32 AND NOT UNIX)
- set(tag win)
- elseif(APPLE)
- set(tag apple)
- elseif(UNIX)
- set(tag unix)
- else()
- set(tag ${CMAKE_SYSTEM_NAME})
- endif()
- if(CMAKE_SIZEOF_VOID_P EQUAL 8) # 64 bits
- set(tag ${tag}64)
- elseif(CMAKE_SIZEOF_VOID_P EQUAL 4) # 32 bits
- set(tag ${tag}32)
- else()
- c4_err("not implemented")
- endif()
- set(${tag_} ${tag} PARENT_SCOPE)
-endfunction()
-
-
-function(_c4_extract_version_tag tag_)
- # git describe --tags <commit-id> for unannotated tags
- # git describe --contains <commit>
-endfunction()
-
-
-#------------------------------------------------------------------------------
-#------------------------------------------------------------------------------
-#------------------------------------------------------------------------------
-
-# set project-wide property
-function(c4_set_proj_prop prop value)
- c4_dbg("set ${prop}=${value}")
- set(C4PROJ_${_c4_prefix}_${prop} ${value})
-endfunction()
-
-# set project-wide property
-function(c4_get_proj_prop prop var)
- c4_dbg("get ${prop}=${C4PROJ_${_c4_prefix}_${prop}}")
- set(${var} ${C4PROJ_${_c4_prefix}_${prop}} PARENT_SCOPE)
-endfunction()
-
-
-#------------------------------------------------------------------------------
-#------------------------------------------------------------------------------
-#------------------------------------------------------------------------------
-
-# set target-wide c4 property
-function(c4_set_target_prop target prop value)
- _c4_set_tgt_prop(${target} C4_TGT_${prop} "${value}")
-endfunction()
-function(c4_append_target_prop target prop value)
- _c4_append_tgt_prop(${target} C4_TGT_${prop} "${value}")
-endfunction()
-
-# get target-wide c4 property
-function(c4_get_target_prop target prop var)
- _c4_get_tgt_prop(val ${target} C4_TGT_${prop})
- set(${var} ${val} PARENT_SCOPE)
-endfunction()
-
-
-# get target-wide property
-function(_c4_get_tgt_prop out tgt prop)
- get_target_property(target_type ${target} TYPE)
- if(target_type STREQUAL "INTERFACE_LIBRARY")
- get_property(val GLOBAL PROPERTY C4_TGT_${tgt}_${prop})
- else()
- get_target_property(val ${tgt} ${prop})
- endif()
- c4_dbg("target ${tgt}: get ${prop}=${val}")
- set(${out} "${val}" PARENT_SCOPE)
-endfunction()
-
-# set target-wide property
-function(_c4_set_tgt_prop tgt prop propval)
- c4_dbg("target ${tgt}: set ${prop}=${propval}")
- get_target_property(target_type ${target} TYPE)
- if(target_type STREQUAL "INTERFACE_LIBRARY")
- set_property(GLOBAL PROPERTY C4_TGT_${tgt}_${prop} "${propval}")
- else()
- set_target_properties(${tgt} PROPERTIES ${prop} "${propval}")
- endif()
-endfunction()
-function(_c4_append_tgt_prop tgt prop propval)
- c4_dbg("target ${tgt}: appending ${prop}=${propval}")
- _c4_get_tgt_prop(curr ${tgt} ${prop})
- if(curr)
- list(APPEND curr "${propval}")
- else()
- set(curr "${propval}")
- endif()
- _c4_set_tgt_prop(${tgt} ${prop} "${curr}")
-endfunction()
-
-
-#------------------------------------------------------------------------------
-#------------------------------------------------------------------------------
-#------------------------------------------------------------------------------
-
-function(c4_set_var_tmp var value)
- c4_dbg("tmp-setting ${var} to ${value} (was ${${value}})")
- set(_c4_old_val_${var} ${${var}})
- set(${var} ${value} PARENT_SCOPE)
-endfunction()
-
-function(c4_clean_var_tmp var)
- c4_dbg("cleaning ${var} to ${_c4_old_val_${var}} (tmp was ${${var}})")
- set(${var} ${_c4_old_val_${var}} PARENT_SCOPE)
-endfunction()
-
-macro(c4_override opt val)
- set(${opt} ${val} CACHE BOOL "" FORCE)
-endmacro()
-
-
-macro(c4_setg var val)
- set(${var} ${val})
- set(${var} ${val} PARENT_SCOPE)
-endmacro()
-
-
-#------------------------------------------------------------------------------
-#------------------------------------------------------------------------------
-#------------------------------------------------------------------------------
-
-function(c4_proj_get_version dir tag_o full_o major_o minor_o patch_o tweak_o)
- if("${dir}" STREQUAL "")
- set(dir ${CMAKE_CURRENT_LIST_DIR})
- endif()
- find_program(GIT git REQUIRED)
- function(_c4pgv_get_cmd outputvar)
- execute_process(COMMAND ${ARGN}
- WORKING_DIRECTORY ${dir}
- ERROR_VARIABLE error
- ERROR_STRIP_TRAILING_WHITESPACE
- OUTPUT_VARIABLE output
- OUTPUT_STRIP_TRAILING_WHITESPACE)
- c4_dbg("output of ${ARGN}: ${outputvar}=${output} [@${dir}]")
- set(${outputvar} ${output} PARENT_SCOPE)
- endfunction()
- # do we have any tags yet?
- _c4pgv_get_cmd(head_desc ${GIT} describe HEAD)
- _c4pgv_get_cmd(branch ${GIT} rev-parse --abbrev-ref HEAD)
- if(NOT head_desc)
- c4_dbg("the repo does not have any tags yet")
- _c4pgv_get_cmd(commit_hash ${GIT} rev-parse --short HEAD)
- set(otag "${commit_hash}-${branch}")
- else()
- c4_dbg("there are tags!")
- # is the current commit tagged?
- _c4pgv_get_cmd(commit_hash_full ${GIT} rev-parse HEAD)
- _c4pgv_get_cmd(commit_desc ${GIT} describe --exact-match ${commit_hash_full})
- if(commit_desc)
- c4_dbg("current commit is tagged")
- # is the tag a version tag?
- _c4_parse_version_tag(${commit_desc} is_version major minor patch tweak more)
- if(is_version)
- c4_dbg("current commit's tag is a version tag")
- # is the tag the current version tag?
- if("${is_version}" VERSION_EQUAL "${${_c4_prefix}_VERSION_FULL}")
- c4_dbg("this is the official version commit")
- else()
- c4_dbg("this is a different version")
- endif()
- set(otag "${commit_desc}")
- else()
- c4_dbg("this is a non-version tag")
- set(otag "${commit_desc}-${branch}")
- endif()
- else(commit_desc)
- # is the latest tag in the head_desc a version tag?
- string(REGEX REPLACE "(.*)-[0-9]+-[0-9a-f]+" "\\1" latest_tag "${head_desc}")
- c4_dbg("current commit is NOT tagged. latest tag=${latest_tag}")
- _c4_parse_version_tag(${latest_tag} latest_tag_is_a_version major minor patch tweak more)
- if(latest_tag_is_a_version)
- c4_dbg("latest tag is a version. stick to the head description")
- set(otag "${head_desc}-${branch}")
- set(full "${latest_tag_is_a_version}")
- else()
- c4_dbg("latest tag is NOT a version. Use the current project version from cmake + the output of git describe")
- set(otag "v${full}-${head_desc}-${branch}")
- set(full "${${_c4_prefix}_VERSION_FULL}")
- set(major "${${_c4_prefix}_VERSION_MAJOR}")
- set(minor "${${_c4_prefix}_VERSION_MINOR}")
- set(patch "${${_c4_prefix}_VERSION_PATCH}")
- set(tweak "${${_c4_prefix}_VERSION_TWEAK}")
- endif()
- endif(commit_desc)
- endif(NOT head_desc)
- c4_log("cpack tag: ${otag}")
- set(${tag_o} "${otag}" PARENT_SCOPE)
- set(${full_o} "${full}" PARENT_SCOPE)
- set(${major_o} "${major}" PARENT_SCOPE)
- set(${minor_o} "${minor}" PARENT_SCOPE)
- set(${patch_o} "${patch}" PARENT_SCOPE)
- set(${tweak_o} "${tweak}" PARENT_SCOPE)
- # also: dirty index?
- # https://stackoverflow.com/questions/2657935/checking-for-a-dirty-index-or-untracked-files-with-git
-endfunction()
-
-
-function(_c4_parse_version_tag tag is_version major minor patch tweak more)
- # does the tag match a four-part version?
- string(REGEX MATCH "v?([0-9]+)([\._][0-9]+)([\._][0-9]+)([\._][0-9]+)(.*)" match "${tag}")
- function(_triml arg out) # trim the leading [\._] from the left
- if("${arg}" STREQUAL "")
- set(${out} "" PARENT_SCOPE)
- else()
- string(REGEX REPLACE "[\._](.*)" "\\1" ret "${arg}")
- set("${out}" "${ret}" PARENT_SCOPE)
- endif()
- endfunction()
- if(match)
- set(${is_version} ${tag} PARENT_SCOPE)
- _triml("${CMAKE_MATCH_1}" major_v)
- _triml("${CMAKE_MATCH_2}" minor_v)
- _triml("${CMAKE_MATCH_3}" patch_v)
- _triml("${CMAKE_MATCH_4}" tweak_v)
- _triml("${CMAKE_MATCH_5}" more_v)
- else()
- # does the tag match a three-part version?
- string(REGEX MATCH "v?([0-9]+)([\._][0-9]+)([\._][0-9]+)(.*)" match "${tag}")
- if(match)
- set(${is_version} ${tag} PARENT_SCOPE)
- _triml("${CMAKE_MATCH_1}" major_v)
- _triml("${CMAKE_MATCH_2}" minor_v)
- _triml("${CMAKE_MATCH_3}" patch_v)
- _triml("${CMAKE_MATCH_4}" more_v)
- else()
- # does the tag match a two-part version?
- string(REGEX MATCH "v?([0-9]+)([\._][0-9]+)(.*)" match "${tag}")
- if(match)
- set(${is_version} ${tag} PARENT_SCOPE)
- _triml("${CMAKE_MATCH_1}" major_v)
- _triml("${CMAKE_MATCH_2}" minor_v)
- _triml("${CMAKE_MATCH_3}" more_v)
- else()
- # not a version!
- set(${is_version} FALSE PARENT_SCOPE)
- endif()
- endif()
- endif()
- set(${major} "${major_v}" PARENT_SCOPE)
- set(${minor} "${minor_v}" PARENT_SCOPE)
- set(${patch} "${patch_v}" PARENT_SCOPE)
- set(${tweak} "${tweak_v}" PARENT_SCOPE)
- set(${more} "${more_v}" PARENT_SCOPE)
-endfunction()
-
-
-#function(testvtag)
-# set(err FALSE)
-# function(cmp value expected)
-# if(NOT ("${${value}}" STREQUAL "${expected}"))
-# c4_log("${tag}: error: expected ${value}=='${expected}': '${${value}}'=='${expected}'")
-# set(err TRUE PARENT_SCOPE)
-# else()
-# c4_log("${tag}: ok: expected ${value}=='${expected}': '${${value}}'=='${expected}'")
-# endif()
-# endfunction()
-# function(verify tag is_version_e major_e minor_e patch_e tweak_e more_e)
-# _c4_parse_version_tag(${tag} is_version major minor patch tweak more)
-# cmp(is_version ${is_version_e})
-# cmp(major "${major_e}")
-# cmp(minor "${minor_e}")
-# cmp(patch "${patch_e}")
-# cmp(tweak "${tweak_e}")
-# cmp(more "${more_e}")
-# set(err ${err} PARENT_SCOPE)
-# endfunction()
-# verify(v12.34.567.89-rcfoo TRUE 12 34 567 89 -rcfoo)
-# verify(v12_34_567_89-rcfoo TRUE 12 34 567 89 -rcfoo)
-# verify(v12.34.567.89 TRUE 12 34 567 89 "")
-# verify(v12_34_567_89 TRUE 12 34 567 89 "")
-# verify(v12.34.567-rcfoo TRUE 12 34 567 "" -rcfoo)
-# verify(v12_34_567-rcfoo TRUE 12 34 567 "" -rcfoo)
-# verify(v12.34.567 TRUE 12 34 567 "" "")
-# verify(v12_34_567 TRUE 12 34 567 "" "")
-# verify(v12_34 TRUE 12 34 "" "" "")
-# verify(v12.34 TRUE 12 34 "" "" "")
-# if(err)
-# c4_err("test failed")
-# endif()
-#endfunction()
-#testvtag()
-
-
-#------------------------------------------------------------------------------
-#------------------------------------------------------------------------------
-#------------------------------------------------------------------------------
-
-
-macro(_c4_handle_cxx_standard_args)
- # EXTENSIONS:
- # enable compiler extensions eg, prefer gnu++11 to c++11
- if(EXTENSIONS IN_LIST ARGN)
- set(_EXTENSIONS ON)
- else()
- c4_get_from_first_of(_EXTENSIONS
- ENV
- DEFAULT OFF
- VARS ${_c4_uprefix}CXX_EXTENSIONS C4_CXX_EXTENSIONS CMAKE_CXX_EXTENSIONS)
- endif()
- #
- # OPTIONAL
- if(OPTIONAL IN_LIST ARGN)
- set(_REQUIRED OFF)
- else()
- c4_get_from_first_of(_REQUIRED
- ENV
- DEFAULT ON
- VARS ${_c4_uprefix}CXX_STANDARD_REQUIRED C4_CXX_STANDARD_REQUIRED CMAKE_CXX_STANDARD_REQUIRED)
- endif()
-endmacro()
-
-
-# set the global cxx standard for the project.
-#
-# examples:
-# c4_set_cxx(latest) # find the latest standard supported by the compiler, and use that
-# c4_set_cxx(11) # required, no extensions (eg c++11)
-# c4_set_cxx(14) # required, no extensions (eg c++14)
-# c4_set_cxx(11 EXTENSIONS) # opt-in to extensions (eg, gnu++11)
-# c4_set_cxx(14 EXTENSIONS) # opt-in to extensions (eg, gnu++14)
-# c4_set_cxx(11 OPTIONAL) # not REQUIRED. no extensions
-# c4_set_cxx(11 OPTIONAL EXTENSIONS) # not REQUIRED. with extensions.
-macro(c4_set_cxx standard)
- _c4_handle_cxx_standard_args(${ARGN})
- if(NOT DEFINED CMAKE_CXX_STANDARD)
- c4_log("setting C++ standard: ${standard}")
- c4_setg(CMAKE_CXX_STANDARD ${standard})
- endif()
- if(NOT DEFINED CMAKE_CXX_STANDARD_REQUIRED)
- c4_log("setting C++ standard required: ${_REQUIRED}")
- c4_setg(CMAKE_CXX_STANDARD_REQUIRED ${_REQUIRED})
- endif()
- if(NOT DEFINED CMAKE_CXX_STANDARD_REQUIRED)
- c4_log("setting C++ standard extensions: ${_EXTENSIONS}")
- c4_setg(CMAKE_CXX_EXTENSIONS ${_EXTENSIONS})
- endif()
-endmacro()
-
-
-# set the cxx standard for a target.
-#
-# examples:
-# c4_target_set_cxx(target latest) # find the latest standard supported by the compiler, and use that
-# c4_target_set_cxx(target 11) # required, no extensions (eg c++11)
-# c4_target_set_cxx(target 14) # required, no extensions (eg c++14)
-# c4_target_set_cxx(target 11 EXTENSIONS) # opt-in to extensions (eg, gnu++11)
-# c4_target_set_cxx(target 14 EXTENSIONS) # opt-in to extensions (eg, gnu++14)
-# c4_target_set_cxx(target 11 OPTIONAL) # not REQUIRED. no extensions
-# c4_target_set_cxx(target 11 OPTIONAL EXTENSIONS)
-function(c4_target_set_cxx target standard)
- c4_dbg("setting C++ standard for target ${target}: ${standard}")
- _c4_handle_cxx_standard_args(${ARGN})
- set_target_properties(${target} PROPERTIES
- CXX_STANDARD ${standard}
- CXX_STANDARD_REQUIRED ${_REQUIRED}
- CXX_EXTENSIONS ${_EXTENSIONS})
- target_compile_features(${target} PUBLIC cxx_std_${standard})
-endfunction()
-
-
-# set the cxx standard for a target based on the global project settings
-function(c4_target_inherit_cxx_standard target)
- c4_dbg("inheriting C++ standard for target ${target}: ${CMAKE_CXX_STANDARD}")
- set_target_properties(${target} PROPERTIES
- CXX_STANDARD "${CMAKE_CXX_STANDARD}"
- CXX_STANDARD_REQUIRED "${CMAKE_CXX_STANDARD_REQUIRED}"
- CXX_EXTENSIONS "${CMAKE_CXX_EXTENSIONS}")
- target_compile_features(${target} PUBLIC cxx_std_${CMAKE_CXX_STANDARD})
-endfunction()
-
-
-function(_c4_find_latest_supported_cxx_standard out)
- if(NOT c4_latest_supported_cxx_standard)
- include(CheckCXXCompilerFlag)
- # make sure CMAKE_CXX_FLAGS is clean here
- # see https://cmake.org/cmake/help/v3.16/module/CheckCXXCompilerFlag.html
- # Note: since this is a function, we don't need to reset CMAKE_CXX_FLAGS
- # back to its previous value
- set(CMAKE_CXX_FLAGS)
- set(standard 11) # default to C++11 if everything fails
- foreach(s ${C4_CXX_STANDARDS})
- if(MSVC)
- set(flag /std:c++${s})
- else()
- # assume GNU-style compiler
- set(flag -std=c++${s})
- endif()
- c4_log("checking CXX standard: C++${s} flag=${flag}")
- check_cxx_compiler_flag(${flag} has${s})
- if(has${s})
- c4_log("checking CXX standard: C++${s} is supported! flag=${flag}")
- set(standard ${s})
- break()
- else()
- c4_log("checking CXX standard: C++${s}: no support for flag=${flag} no")
- endif()
- endforeach()
- set(c4_latest_supported_cxx_standard ${standard} CACHE INTERNAL "")
- endif()
- set(${out} ${c4_latest_supported_cxx_standard} PARENT_SCOPE)
-endfunction()
-
-
-#------------------------------------------------------------------------------
-#------------------------------------------------------------------------------
-#------------------------------------------------------------------------------
-# examples:
-#
-# # require subproject c4core, as a subdirectory. c4core will be used
-# # as a separate library
-# c4_require_subproject(c4core SUBDIRECTORY ${C4OPT_EXT_DIR}/c4core)
-#
-# # require subproject c4core, as a remote proj
-# c4_require_subproject(c4core REMOTE
-# GIT_REPOSITORY https://github.com/biojppm/c4core
-# GIT_TAG master
-# )
-function(c4_require_subproject subproj)
- _c4_handle_args(_ARGS ${ARGN}
- _ARGS0
- INCORPORATE
- EXCLUDE_FROM_ALL
- _ARGS1
- SUBDIRECTORY # the subproject is located in the given directory name and
- # will be added via add_subdirectory()
- _ARGSN
- REMOTE # the subproject is located in a remote repo/url
- # and will be added via c4_import_remote_proj(),
- # forwarding all the arguments in here.
- OVERRIDE # a list of variable name+value pairs
- # these variables will be set with c4_override()
- # before calling add_subdirectory()
- SET_FOLDER_TARGETS # Set the folder of the given targets using
- # c4_set_folder_remote_project_targets().
- # The first expected argument is the folder,
- # and the remaining arguments are the targets
- # which we want to set the folder.
- _DEPRECATE
- INTERFACE
- )
- list(APPEND _${_c4_uprefix}_deps ${subproj})
- c4_setg(_${_c4_uprefix}_deps ${_${_c4_uprefix}_deps})
- c4_dbg("-----------------------------------------------")
- c4_dbg("requires subproject ${subproj}!")
- if(_INCORPORATE)
- c4_dbg("requires subproject ${subproj} in INCORPORATE mode!")
- c4_dbg_var(${_c4_root_uproj}_STANDALONE)
- if(${_c4_root_uproj}_STANDALONE)
- c4_dbg("${_c4_root_uproj} is STANDALONE: honoring INCORPORATE mode...")
- else()
- c4_dbg("${_c4_root_uproj} is not STANDALONE: ignoring INCORPORATE mode...")
- set(_INCORPORATE OFF)
- endif()
- endif()
- #
- _c4_get_subproject_property(${subproj} AVAILABLE _available)
- if(_available)
- c4_dbg("required subproject ${subproj} was already imported:")
- c4_dbg_subproject(${subproj})
- # TODO check version compatibility
- else() #elseif(NOT _${subproj}_available)
- c4_dbg("required subproject ${subproj} is unknown. Importing...")
- if(_EXCLUDE_FROM_ALL)
- set(excl EXCLUDE_FROM_ALL)
- endif()
- # forward c4 compile flags
- string(TOUPPER ${subproj} usubproj)
- c4_setg(${usubproj}_CXX_FLAGS_FWD "${${_c4_uprefix}CXX_FLAGS}")
- c4_setg(${usubproj}_CXX_FLAGS_OPT_FWD "${${_c4_uprefix}CXX_FLAGS_OPT}")
- c4_setg(${usubproj}_CXX_LINKER_FLAGS_FWD "${${_c4_uprefix}CXX_LINKER_FLAGS}")
- # root dir
- set(_r ${CMAKE_CURRENT_BINARY_DIR}/subprojects/${subproj})
- if(_REMOTE)
- c4_log("importing subproject ${subproj} (REMOTE)... ${_REMOTE}")
- _c4_mark_subproject_imported(${subproj} ${_r}/src ${_r}/build ${_INCORPORATE})
- c4_import_remote_proj(${subproj} ${_r} REMOTE ${_REMOTE} OVERRIDE ${_OVERRIDE} ${excl})
- _c4_get_subproject_property(${subproj} SRC_DIR _srcdir)
- c4_dbg("finished importing subproject ${subproj} (REMOTE, SRC_DIR=${_srcdir}).")
- elseif(_SUBDIRECTORY)
- c4_log("importing subproject ${subproj} (SUBDIRECTORY)... ${_SUBDIRECTORY}")
- _c4_mark_subproject_imported(${subproj} ${_SUBDIRECTORY} ${_r}/build ${_INCORPORATE})
- c4_add_subproj(${subproj} ${_SUBDIRECTORY} ${_r}/build OVERRIDE ${_OVERRIDE} ${excl})
- set(_srcdir ${_SUBDIRECTORY})
- c4_dbg("finished importing subproject ${subproj} (SUBDIRECTORY=${_SUBDIRECTORY}).")
- else()
- c4_err("subproject type must be either REMOTE or SUBDIRECTORY")
- endif()
- endif()
- #
- if(_SET_FOLDER_TARGETS)
- c4_set_folder_remote_project_targets(${_SET_FOLDER_TARGETS})
- endif()
-endfunction(c4_require_subproject)
-
-
-function(c4_add_subproj proj dir bindir)
- _c4_handle_args(_ARGS ${ARGN}
- _ARGS0
- EXCLUDE_FROM_ALL # forward to add_subdirectory()
- _ARGS1
- _ARGSN
- OVERRIDE # a list of variable name+value pairs
- # these variables will be set with c4_override()
- # before calling add_subdirectory()
- )
- # push the subproj into the current path
- set(prev_subproject ${_c4_curr_subproject})
- set(prev_path ${_c4_curr_path})
- set(_c4_curr_subproject ${proj})
- string(REGEX MATCH ".*/${proj}\$" pos "${_c4_curr_path}")
- if(pos EQUAL -1)
- string(REGEX MATCH "^${proj}\$" pos "${_c4_curr_path}")
- if(pos EQUAL -1)
- set(_c4_curr_path ${_c4_curr_path}/${proj})
- endif()
- endif()
- #
- while(_OVERRIDE)
- list(POP_FRONT _OVERRIDE varname)
- list(POP_FRONT _OVERRIDE varvalue)
- c4_override(${varname} ${varvalue})
- endwhile()
- #
- if(_EXCLUDE_FROM_ALL)
- set(excl EXCLUDE_FROM_ALL)
- endif()
- #
- c4_dbg("adding subproj: ${prev_subproject}->${_c4_curr_subproject}. path=${_c4_curr_path}")
- add_subdirectory(${dir} ${bindir} ${excl})
- # pop the subproj from the current path
- set(_c4_curr_subproject ${prev_subproject})
- set(_c4_curr_path ${prev_path})
-endfunction()
-
-
-function(_c4_mark_subproject_imported subproject_name subproject_src_dir subproject_bin_dir incorporate)
- c4_dbg("marking subproject imported: ${subproject_name} (imported by ${_c4_prefix}). src=${subproject_src_dir}")
- _c4_append_subproject_property(${_c4_prefix} DEPENDENCIES ${subproject_name})
- _c4_get_folder(folder ${_c4_prefix} ${subproject_name})
- _c4_set_subproject_property(${subproject_name} AVAILABLE ON)
- _c4_set_subproject_property(${subproject_name} IMPORTER "${_c4_prefix}")
- _c4_set_subproject_property(${subproject_name} SRC_DIR "${subproject_src_dir}")
- _c4_set_subproject_property(${subproject_name} BIN_DIR "${subproject_bin_dir}")
- _c4_set_subproject_property(${subproject_name} FOLDER "${folder}")
- _c4_set_subproject_property(${subproject_name} INCORPORATE "${incorporate}")
-endfunction()
-
-
-function(_c4_get_subproject_property subproject property var)
- get_property(v GLOBAL PROPERTY _c4_subproject-${subproject}-${property})
- set(${var} "${v}" PARENT_SCOPE)
-endfunction()
-
-
-function(_c4_set_subproject_property subproject property value)
- c4_dbg("setting subproj prop: ${subproject}: ${property}=${value}")
- set_property(GLOBAL PROPERTY _c4_subproject-${subproject}-${property} "${value}")
-endfunction()
-function(_c4_append_subproject_property subproject property value)
- _c4_get_subproject_property(${subproject} ${property} cval)
- if(cval)
- list(APPEND cval ${value})
- else()
- set(cval ${value})
- endif()
- _c4_set_subproject_property(${subproject} ${property} ${cval})
-endfunction()
-
-
-function(_c4_is_incorporated subproj out)
- if("${subproj}" STREQUAL "${_c4_root_proj}")
- c4_dbg("${subproj} is incorporated? root proj, no")
- set(${out} OFF PARENT_SCOPE)
- else()
- _c4_get_subproject_property(${subproj} INCORPORATE inc)
- c4_dbg("${subproj} is incorporated? not root proj, incorporate=${inc}")
- set(${out} ${inc} PARENT_SCOPE)
- endif()
-endfunction()
-
-
-function(c4_dbg_subproject subproject)
- set(props AVAILABLE IMPORTER SRC_DIR BIN_DIR DEPENDENCIES FOLDER INCORPORATE)
- foreach(p ${props})
- _c4_get_subproject_property(${subproject} ${p} pv)
- c4_dbg("${subproject}: ${p}=${pv}")
- endforeach()
-endfunction()
-
-
-#------------------------------------------------------------------------------
-#------------------------------------------------------------------------------
-#------------------------------------------------------------------------------
-
-#
-#
-function(c4_import_remote_proj name dir)
- _c4_handle_args(_ARGS ${ARGN}
- _ARGS0
- EXCLUDE_FROM_ALL
- _ARGS1
- SUBDIR # path to the subdirectory where the CMakeLists file is to be found.
- _ARGSN
- OVERRIDE # a list of variable name+value pairs
- # these variables will be set with c4_override()
- # before calling add_subdirectory()
- REMOTE # to specify url, repo, tag, or branch,
- # pass the needed arguments after dir.
- # These arguments will be forwarded to ExternalProject_Add()
- SET_FOLDER_TARGETS # Set the folder of the given targets using
- # c4_set_folder_remote_project_targets().
- # The first expected argument is the folder,
- # and the remaining arguments are the targets
- # which we want to set the folder.
- )
- set(srcdir_in_out "${dir}")
- c4_download_remote_proj(${name} srcdir_in_out ${_REMOTE})
- if(_SUBDIR)
- set(srcdir_in_out "${srcdir_in_out}/${_SUBDIR}")
- endif()
- _c4_set_subproject_property(${name} SRC_DIR "${srcdir_in_out}")
- if(_EXCLUDE_FROM_ALL)
- set(excl EXCLUDE_FROM_ALL)
- endif()
- c4_add_subproj(${name} "${srcdir_in_out}" "${dir}/build" OVERRIDE ${_OVERRIDE} ${excl})
- #
- if(_SET_FOLDER_TARGETS)
- c4_set_folder_remote_project_targets(${_SET_FOLDER_TARGETS})
- endif()
-endfunction()
-
-
-# download remote projects while running cmake
-# to specify url, repo, tag, or branch,
-# pass the needed arguments after dir.
-# These arguments will be forwarded to ExternalProject_Add()
-function(c4_download_remote_proj name candidate_dir)
- # https://crascit.com/2015/07/25/cmake-gtest/
- # (via https://stackoverflow.com/questions/15175318/cmake-how-to-build-external-projects-and-include-their-targets)
- set(dir ${${candidate_dir}})
- if("${dir}" STREQUAL "")
- set(dir "${CMAKE_BINARY_DIR}/extern/${name}")
- endif()
- set(cvar _${_c4_uprefix}_DOWNLOAD_${name}_LOCATION)
- set(cval ${${cvar}})
- #
- # was it already downloaded in this project?
- if(NOT ("${cval}" STREQUAL ""))
- if(EXISTS "${cval}")
- c4_log("${name} was previously imported into this project - found at \"${cval}\"!")
- set(${candidate_dir} "${cval}" PARENT_SCOPE)
- return()
- else()
- c4_log("${name} was previously imported into this project - but was NOT found at \"${cval}\"!")
- endif()
- endif()
- #
- # try to find an existing version (downloaded by some other project)
- set(out "${dir}")
- _c4_find_cached_proj(${name} out)
- if(NOT ("${out}" STREQUAL "${dir}"))
- c4_log("using ${name} from \"${out}\"...")
- set(${cvar} "${out}" CACHE INTERNAL "")
- set(${candidate_dir} "${out}" PARENT_SCOPE)
- return()
- endif()
- #
- # no version was found; need to download.
- c4_log("downloading ${name}: not in cache...")
- # check for a global place to download into
- set(srcdir)
- _c4_get_cached_srcdir_global_extern(${name} srcdir)
- if("${srcdir}" STREQUAL "")
- # none found; default to the given dir
- set(srcdir "${dir}/src")
- endif()
- #
- # do it
- #if((EXISTS ${dir}/dl) AND (EXISTS ${dir}/dl/CMakeLists.txt))
- # return()
- #endif()
- c4_log("downloading remote project: ${name} -> \"${srcdir}\" (dir=${dir})...")
- #
- file(WRITE ${dir}/dl/CMakeLists.txt "
-cmake_minimum_required(VERSION 2.8.2)
-project(${_c4_lcprefix}-download-${name} NONE)
-
-# this project only downloads ${name}
-# (ie, no configure, build or install step)
-include(ExternalProject)
-
-ExternalProject_Add(${name}-dl
- ${ARGN}
- SOURCE_DIR \"${srcdir}\"
- BINARY_DIR \"${dir}/build\"
- CONFIGURE_COMMAND \"\"
- BUILD_COMMAND \"\"
- INSTALL_COMMAND \"\"
- TEST_COMMAND \"\"
-)
-")
- execute_process(COMMAND ${CMAKE_COMMAND} -G "${CMAKE_GENERATOR}" .
- WORKING_DIRECTORY ${dir}/dl)
- execute_process(COMMAND ${CMAKE_COMMAND} --build .
- WORKING_DIRECTORY ${dir}/dl)
- #
- set(${candidate_dir} "${srcdir}" PARENT_SCOPE)
- set(_${_c4_uprefix}_DOWNLOAD_${name}_LOCATION "${srcdir}" CACHE INTERNAL "")
-endfunction()
-
-
-# checks if the project was already downloaded. If it was, then dir_in_out is
-# changed to the directory where the project was found at.
-function(_c4_find_cached_proj name dir_in_out)
- c4_log("downloading ${name}: searching cached project...")
- #
- # 1. search in the per-import variable, eg RYML_CACHE_DOWNLOAD_GTEST
- string(TOUPPER ${name} uname)
- set(var ${_c4_uprefix}CACHE_DOWNLOAD_${uname})
- set(val "${${var}}")
- if(NOT ("${val}" STREQUAL ""))
- c4_log("downloading ${name}: searching in ${var}=${val}")
- if(EXISTS "${val}")
- c4_log("downloading ${name}: picked ${sav} instead of ${${dir_in_out}}")
- set(${dir_in_out} ${sav} PARENT_SCOPE)
- endif()
- endif()
- #
- # 2. search in the global directory (if there is one)
- _c4_get_cached_srcdir_global_extern(${name} sav)
- if(NOT ("${sav}" STREQUAL ""))
- c4_log("downloading ${name}: searching in C4_EXTERN_DIR: ${sav}")
- if(EXISTS "${sav}")
- c4_log("downloading ${name}: picked ${sav} instead of ${${dir_in_out}}")
- set(${dir_in_out} ${sav} PARENT_SCOPE)
- endif()
- endif()
-endfunction()
-
-
-function(_c4_get_cached_srcdir_global_extern name out)
- set(${out} "" PARENT_SCOPE)
- if("${C4_EXTERN_DIR}" STREQUAL "")
- set(C4_EXTERN_DIR "$ENV{C4_EXTERN_DIR}")
- endif()
- if(NOT ("${C4_EXTERN_DIR}" STREQUAL ""))
- set(${out} "${C4_EXTERN_DIR}/${name}" PARENT_SCOPE)
- endif()
-endfunction()
-
-
-#------------------------------------------------------------------------------
-#------------------------------------------------------------------------------
-#------------------------------------------------------------------------------
-
-function(_c4_get_folder output importer_subproject subproject_name)
- _c4_get_subproject_property(${importer_subproject} FOLDER importer_folder)
- if("${importer_folder}" STREQUAL "")
- set(folder ${importer_subproject})
- else()
- set(folder "${importer_folder}/deps/${subproject_name}")
- endif()
- set(${output} ${folder} PARENT_SCOPE)
-endfunction()
-
-
-function(_c4_set_target_folder target subfolder)
- string(FIND "${subfolder}" "/" pos)
- if(pos EQUAL 0)
- if("${_c4_curr_path}" STREQUAL "")
- string(SUBSTRING "${subfolder}" 1 -1 sf)
- set_target_properties(${target} PROPERTIES
- FOLDER "${sf}")
- else()
- set_target_properties(${target} PROPERTIES
- FOLDER "${subfolder}")
- endif()
- elseif("${subfolder}" STREQUAL "")
- set_target_properties(${target} PROPERTIES
- FOLDER "${_c4_curr_path}")
- else()
- if("${_c4_curr_path}" STREQUAL "")
- set_target_properties(${target} PROPERTIES
- FOLDER "${subfolder}")
- else()
- set_target_properties(${target} PROPERTIES
- FOLDER "${_c4_curr_path}/${subfolder}")
- endif()
- endif()
-endfunction()
-
-
-function(c4_set_folder_remote_project_targets subfolder)
- foreach(target ${ARGN})
- if(TARGET ${target})
- _c4_set_target_folder(${target} "${subfolder}")
- endif()
- endforeach()
-endfunction()
-
-
-#------------------------------------------------------------------------------
-#------------------------------------------------------------------------------
-#------------------------------------------------------------------------------
-
-# a convenience alias to c4_add_target()
-function(c4_add_executable target)
- c4_add_target(${target} EXECUTABLE ${ARGN})
-endfunction(c4_add_executable)
-
-
-# a convenience alias to c4_add_target()
-function(c4_add_library target)
- c4_add_target(${target} LIBRARY ${ARGN})
-endfunction(c4_add_library)
-
-
-# example: c4_add_target(ryml LIBRARY SOURCES ${SRC})
-function(c4_add_target target)
- c4_dbg("adding target: ${target}: ${ARGN}")
- set(opt0arg
- LIBRARY # the target is a library
- EXECUTABLE # the target is an executable
- WIN32 # the executable is WIN32
- SANITIZE # deprecated
- )
- set(opt1arg
- LIBRARY_TYPE # override global setting for C4_LIBRARY_TYPE
- SHARED_MACRO # the name of the macro to turn on export/import symbols
- # for compiling the library as a windows DLL.
- # defaults to ${_c4_uprefix}SHARED.
- SHARED_EXPORTS # the name of the macro to turn on export of symbols
- # for compiling the library as a windows DLL.
- # defaults to ${_c4_uprefix}EXPORTS.
- SOURCE_ROOT # the directory where relative source paths
- # should be resolved. when empty,
- # use CMAKE_CURRENT_SOURCE_DIR
- FOLDER # IDE folder to group the target in
- SANITIZERS # outputs the list of sanitize targets in this var
- SOURCE_TRANSFORM # WIP
- )
- set(optnarg
- INCORPORATE # incorporate these libraries into this target,
- # subject to ${_c4_uprefix}STANDALONE and C4_STANDALONE
- SOURCES PUBLIC_SOURCES INTERFACE_SOURCES PRIVATE_SOURCES
- HEADERS PUBLIC_HEADERS INTERFACE_HEADERS PRIVATE_HEADERS
- INC_DIRS PUBLIC_INC_DIRS INTERFACE_INC_DIRS PRIVATE_INC_DIRS
- LIBS PUBLIC_LIBS INTERFACE_LIBS PRIVATE_LIBS
- DEFS PUBLIC_DEFS INTERFACE_DEFS PRIVATE_DEFS # defines
- CFLAGS PUBLIC_CFLAGS INTERFACE_CFLAGS PRIVATE_CFLAGS # compiler flags. TODO: linker flags
- DLLS # DLLs required by this target
- MORE_ARGS
- )
- cmake_parse_arguments("" "${opt0arg}" "${opt1arg}" "${optnarg}" ${ARGN})
- #
- if(_SANITIZE)
- c4_err("SANITIZE is deprecated")
- endif()
-
- if(${_LIBRARY})
- set(_what LIBRARY)
- elseif(${_EXECUTABLE})
- set(_what EXECUTABLE)
- else()
- c4_err("must be either LIBRARY or EXECUTABLE")
- endif()
-
- _c4_handle_arg(SHARED_MACRO ${_c4_uprefix}MACRO)
- _c4_handle_arg(SHARED_EXPORTS ${_c4_uprefix}EXPORTS)
- _c4_handle_arg_or_fallback(SOURCE_ROOT "${CMAKE_CURRENT_SOURCE_DIR}")
- function(_c4_transform_to_full_path list all)
- set(l)
- foreach(f ${${list}})
- if(NOT IS_ABSOLUTE "${f}")
- set(f "${_SOURCE_ROOT}/${f}")
- endif()
- list(APPEND l "${f}")
- endforeach()
- set(${list} "${l}" PARENT_SCOPE)
- set(cp ${${all}})
- list(APPEND cp ${l})
- set(${all} ${cp} PARENT_SCOPE)
- endfunction()
- _c4_transform_to_full_path( _SOURCES allsrc)
- _c4_transform_to_full_path( _HEADERS allsrc)
- _c4_transform_to_full_path( _PUBLIC_SOURCES allsrc)
- _c4_transform_to_full_path(_INTERFACE_SOURCES allsrc)
- _c4_transform_to_full_path( _PRIVATE_SOURCES allsrc)
- _c4_transform_to_full_path( _PUBLIC_HEADERS allsrc)
- _c4_transform_to_full_path(_INTERFACE_HEADERS allsrc)
- _c4_transform_to_full_path( _PRIVATE_HEADERS allsrc)
- create_source_group("" "${_SOURCE_ROOT}" "${allsrc}")
- # is the target name prefixed with the project prefix?
- string(REGEX MATCH "${_c4_prefix}::.*" target_is_prefixed "${target}")
- if(NOT ${_c4_uprefix}SANITIZE_ONLY)
- if(${_EXECUTABLE})
- c4_dbg("adding executable: ${target}")
- if(WIN32)
- if(${_WIN32})
- list(APPEND _MORE_ARGS WIN32)
- endif()
- endif()
- add_executable(${target} ${_MORE_ARGS})
- if(NOT target_is_prefixed)
- add_executable(${_c4_prefix}::${target} ALIAS ${target})
- endif()
- set(src_mode PRIVATE)
- set(tgt_type PUBLIC)
- set(compiled_target ON)
- set_target_properties(${target} PROPERTIES VERSION ${${_c4_prefix}_VERSION})
- elseif(${_LIBRARY})
- c4_dbg("adding library: ${target}")
- set(_blt ${C4_LIBRARY_TYPE}) # build library type
- if(NOT "${_LIBRARY_TYPE}" STREQUAL "")
- set(_blt ${_LIBRARY_TYPE})
- endif()
- if("${_blt}" STREQUAL "")
- endif()
- #
- if("${_blt}" STREQUAL "INTERFACE")
- c4_dbg("adding interface library ${target}")
- add_library(${target} INTERFACE)
- set(src_mode INTERFACE)
- set(tgt_type INTERFACE)
- set(compiled_target OFF)
- else()
- if("${_blt}" STREQUAL "")
- # obey BUILD_SHARED_LIBS (ie, either static or shared library)
- c4_dbg("adding library ${target} (defer to BUILD_SHARED_LIBS=${BUILD_SHARED_LIBS}) --- ${_MORE_ARGS}")
- add_library(${target} ${_MORE_ARGS})
- if(BUILD_SHARED_LIBS)
- set(_blt SHARED)
- else()
- set(_blt STATIC)
- endif()
- else()
- c4_dbg("adding library ${target} with type ${_blt}")
- add_library(${target} ${_blt} ${_MORE_ARGS})
- endif()
- # libraries
- set(src_mode PRIVATE)
- set(tgt_type PUBLIC)
- set(compiled_target ON)
- set_target_properties(${target} PROPERTIES VERSION ${${_c4_prefix}_VERSION})
- if("${_blt}" STREQUAL SHARED)
- set_target_properties(${target} PROPERTIES SOVERSION ${${_c4_prefix}_VERSION})
- endif()
- # exports for shared libraries
- if(WIN32)
- if("${_blt}" STREQUAL SHARED)
- set_target_properties(${target} PROPERTIES WINDOWS_EXPORT_ALL_SYMBOLS ON)
- target_compile_definitions(${target} PUBLIC ${_SHARED_MACRO})
- target_compile_definitions(${target} PRIVATE $<BUILD_INTERFACE:${_SHARED_EXPORTS}>)
- # save the name of the macro for later use when(if) incorporating this library
- c4_set_target_prop(${target} SHARED_EXPORTS ${_SHARED_EXPORTS})
- endif() # shared lib
- endif() # win32
- endif() # interface or lib
- if(NOT target_is_prefixed)
- add_library(${_c4_prefix}::${target} ALIAS ${target})
- endif()
- endif(${_EXECUTABLE})
-
- if(src_mode STREQUAL "PUBLIC")
- c4_add_target_sources(${target}
- PUBLIC "${_SOURCES};${_HEADERS};${_PUBLIC_SOURCES};${_PUBLIC_HEADERS}"
- INTERFACE "${_INTERFACE_SOURCES};${_INTERFACE_HEADERS}"
- PRIVATE "${_PRIVATE_SOURCES};${_PRIVATE_HEADERS}")
- elseif(src_mode STREQUAL "INTERFACE")
- c4_add_target_sources(${target}
- PUBLIC "${_PUBLIC_SOURCES};${_PUBLIC_HEADERS}"
- INTERFACE "${_SOURCES};${_HEADERS};${_INTERFACE_SOURCES};${_INTERFACE_HEADERS}"
- PRIVATE "${_PRIVATE_SOURCES};${_PRIVATE_HEADERS}")
- elseif(src_mode STREQUAL "PRIVATE")
- c4_add_target_sources(${target}
- PUBLIC "${_PUBLIC_SOURCES};${_PUBLIC_HEADERS}"
- INTERFACE "${_INTERFACE_SOURCES};${_INTERFACE_HEADERS}"
- PRIVATE "${_SOURCES};${_HEADERS};${_PRIVATE_SOURCES};${_PRIVATE_HEADERS}")
- elseif()
- c4_err("${target}: adding sources: invalid source mode")
- endif()
- _c4_set_tgt_prop(${target} C4_SOURCE_ROOT "${_SOURCE_ROOT}")
-
- if(_INC_DIRS)
- c4_dbg("${target}: adding include dirs ${_INC_DIRS} [from target: ${tgt_type}]")
- target_include_directories(${target} "${tgt_type}" ${_INC_DIRS})
- endif()
- if(_PUBLIC_INC_DIRS)
- c4_dbg("${target}: adding PUBLIC include dirs ${_PUBLIC_INC_DIRS}")
- target_include_directories(${target} PUBLIC ${_PUBLIC_INC_DIRS})
- endif()
- if(_INTERFACE_INC_DIRS)
- c4_dbg("${target}: adding INTERFACE include dirs ${_INTERFACE_INC_DIRS}")
- target_include_directories(${target} INTERFACE ${_INTERFACE_INC_DIRS})
- endif()
- if(_PRIVATE_INC_DIRS)
- c4_dbg("${target}: adding PRIVATE include dirs ${_PRIVATE_INC_DIRS}")
- target_include_directories(${target} PRIVATE ${_PRIVATE_INC_DIRS})
- endif()
-
- if(_LIBS)
- _c4_link_with_libs(${target} "${tgt_type}" "${_LIBS}" "${_INCORPORATE}")
- endif()
- if(_PUBLIC_LIBS)
- _c4_link_with_libs(${target} PUBLIC "${_PUBLIC_LIBS}" "${_INCORPORATE}")
- endif()
- if(_INTERFACE_LIBS)
- _c4_link_with_libs(${target} INTERFACE "${_INTERFACE_LIBS}" "${_INCORPORATE}")
- endif()
- if(_PRIVATE_LIBS)
- _c4_link_with_libs(${target} PRIVATE "${_PRIVATE_LIBS}" "${_INCORPORATE}")
- endif()
-
- if(compiled_target)
- if(_FOLDER)
- _c4_set_target_folder(${target} "${_FOLDER}")
- else()
- _c4_set_target_folder(${target} "")
- endif()
- # cxx standard
- c4_target_inherit_cxx_standard(${target})
- # compile flags
- set(_more_flags
- ${${_c4_uprefix}CXX_FLAGS}
- ${${_c4_uprefix}C_FLAGS}
- ${${_c4_uprefix}CXX_FLAGS_OPT})
- if(_more_flags)
- get_target_property(_flags ${target} COMPILE_OPTIONS)
- if(_flags)
- set(_more_flags ${_flags};${_more_flags})
- endif()
- c4_dbg("${target}: COMPILE_FLAGS=${_more_flags}")
- target_compile_options(${target} PRIVATE "${_more_flags}")
- endif()
- # linker flags
- set(_link_flags ${${_c4_uprefix}CXX_LINKER_FLAGS})
- if(_link_flags)
- get_target_property(_flags ${target} LINK_OPTIONS)
- if(_flags)
- set(_link_flags ${_flags};${_more_flags})
- endif()
- c4_dbg("${target}: LINKER_FLAGS=${_link_flags}")
- target_link_options(${target} PUBLIC "${_link_flags}")
- endif()
- # static analysis
- if(${_c4_uprefix}LINT)
- c4_static_analysis_target(${target} "${_FOLDER}" lint_targets)
- endif()
- endif(compiled_target)
-
- if(_DEFS)
- target_compile_definitions(${target} "${tgt_type}" ${_DEFS})
- endif()
- if(_PUBLIC_DEFS)
- target_compile_definitions(${target} PUBLIC ${_PUBLIC_DEFS})
- endif()
- if(_INTERFACE_DEFS)
- target_compile_definitions(${target} INTERFACE ${_INTERFACE_DEFS})
- endif()
- if(_PRIVATE_DEFS)
- target_compile_definitions(${target} PRIVATE ${_PRIVATE_DEFS})
- endif()
-
- if(_CFLAGS)
- target_compile_options(${target} "${tgt_type}" ${_CFLAGS})
- endif()
- if(_PUBLIC_CFLAGS)
- target_compile_options(${target} PUBLIC ${_PUBLIC_CFLAGS})
- endif()
- if(_INTERFACE_CFLAGS)
- target_compile_options(${target} INTERFACE ${_INTERFACE_CFLAGS})
- endif()
- if(_PRIVATE_CFLAGS)
- target_compile_options(${target} PRIVATE ${_PRIVATE_CFLAGS})
- endif()
-
- if((CMAKE_CXX_COMPILER_ID STREQUAL "GNU") AND
- (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 4.8) AND
- (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.0))
- c4_dbg("${target}: adding compat include path")
- target_include_directories(${target} PUBLIC $<BUILD_INTERFACE:${_c4_project_dir}/compat>)
- endif()
-
- endif(NOT ${_c4_uprefix}SANITIZE_ONLY)
-
- if(compiled_target)
- if(${_c4_uprefix}SANITIZE)
- c4_sanitize_target(${target}
- ${_what} # LIBRARY or EXECUTABLE
- SOURCES ${allsrc}
- INC_DIRS ${_INC_DIRS} ${_PUBLIC_INC_DIRS} ${_INTERFACE_INC_DIRS} ${_PRIVATE_INC_DIRS}
- LIBS ${_LIBS} ${_PUBLIC_LIBS} ${_INTERFACE_LIBS} ${_PRIVATE_LIBS}
- DEFS ${_DEFS} ${_PUBLIC_DEFS} ${_INTERFACE_DEFS} ${_PRIVATE_DEFS}
- CFLAGS ${_CFLAGS} ${_PUBLIC_CFLAGS} ${_INTERFACE_CFLAGS} ${_PRIVATE_CFLAGS}
- OUTPUT_TARGET_NAMES san_targets
- FOLDER "${_FOLDER}"
- )
- endif()
-
- if(NOT ${_c4_uprefix}SANITIZE_ONLY)
- list(INSERT san_targets 0 ${target})
- endif()
-
- if(_SANITIZERS)
- set(${_SANITIZERS} ${san_targets} PARENT_SCOPE)
- endif()
-
- _c4_set_tgt_prop(${target} C4_SAN_TARGETS "${san_targets}")
- else()
- _c4_set_tgt_prop(${target} C4_SAN_TARGETS "${target}")
- endif()
-
- # gather dlls so that they can be automatically copied to the target directory
- if(_DLLS)
- c4_append_transitive_property(${target} _C4_DLLS "${_DLLS}")
- endif()
-
- if(${_EXECUTABLE})
- if(WIN32)
- c4_get_transitive_property(${target} _C4_DLLS transitive_dlls)
- list(REMOVE_DUPLICATES transitive_dlls)
- foreach(_dll ${transitive_dlls})
- if(_dll)
- c4_dbg("enable copy of dll to target file dir: ${_dll} ---> $<TARGET_FILE_DIR:${target}>")
- add_custom_command(TARGET ${target} POST_BUILD
- COMMAND ${CMAKE_COMMAND} -E copy_if_different "${_dll}" "$<TARGET_FILE_DIR:${target}>"
- )
- else()
- message(WARNING "dll required by ${_c4_prefix}/${target} was not found, so cannot copy: ${_dll}")
- endif()
- endforeach()
- endif()
- endif()
-endfunction() # add_target
-
-
-function(_c4_link_with_libs target link_type libs incorporate)
- foreach(lib ${libs})
- # add targets that are DLLs
- if(WIN32)
- if(TARGET ${lib})
- get_target_property(lib_type ${lib} TYPE)
- if(lib_type STREQUAL SHARED_LIBRARY)
- c4_append_transitive_property(${target} _C4_DLLS "$<TARGET_FILE:${lib}>")
- endif()
- endif()
- endif()
- _c4_lib_is_incorporated(${lib} isinc)
- if(isinc OR (incorporate AND ${_c4_uprefix}STANDALONE))
- c4_log("-----> target ${target} ${link_type} incorporating lib ${lib}")
- _c4_incorporate_lib(${target} ${link_type} ${lib})
- else()
- c4_dbg("${target} ${link_type} linking with lib ${lib}")
- target_link_libraries(${target} ${link_type} ${lib})
- endif()
- endforeach()
-endfunction()
-
-
-function(_c4_lib_is_incorporated lib ret)
- c4_dbg("${lib}: is incorporated?")
- if(NOT TARGET ${lib})
- c4_dbg("${lib}: no, not a target")
- set(${ret} OFF PARENT_SCOPE)
- else()
- c4_get_target_prop(${lib} INCORPORATING_TARGETS inc)
- if(inc)
- c4_dbg("${lib}: is incorporated!")
- set(${ret} ON PARENT_SCOPE)
- else()
- c4_dbg("${lib}: is not incorporated!")
- set(${ret} OFF PARENT_SCOPE)
- endif()
- endif()
-endfunction()
-
-
-function(_c4_incorporate_lib target link_type lib)
- c4_dbg("target ${target}: incorporating lib ${lib} [${link_type}]")
- _c4_get_tgt_prop(srcroot ${lib} C4_SOURCE_ROOT)
- #
- c4_append_target_prop(${lib} INCORPORATING_TARGETS ${target})
- c4_append_target_prop(${target} INCORPORATED_TARGETS ${lib})
- #
- _c4_get_tgt_prop(lib_src ${lib} SOURCES)
- if(lib_src)
- create_source_group("${lib}" "${srcroot}" "${lib_src}")
- c4_add_target_sources(${target} INCORPORATED_FROM ${lib} PRIVATE ${lib_src})
- endif()
- #
- _c4_get_tgt_prop(lib_isrc ${lib} INTERFACE_SOURCES)
- if(lib_isrc)
- create_source_group("${lib}" "${srcroot}" "${lib_isrc}")
- c4_add_target_sources(${target} INCORPORATED_FROM ${lib} INTERFACE ${lib_isrc})
- endif()
- #
- _c4_get_tgt_prop(lib_psrc ${lib} PRIVATE_SOURCES)
- if(lib_psrc)
- create_source_group("${lib}" "${srcroot}" "${lib_psrc}")
- c4_add_target_sources(${target} INCORPORATED_FROM ${lib} INTERFACE ${lib_psrc})
- endif()
- #
- #
- _c4_get_tgt_prop(lib_incs ${lib} INCLUDE_DIRECTORIES)
- if(lib_incs)
- target_include_directories(${target} PUBLIC ${lib_incs})
- endif()
- #
- _c4_get_tgt_prop(lib_iincs ${lib} INTERFACE_INCLUDE_DIRECTORIES)
- if(lib_iincs)
- target_include_directories(${target} INTERFACE ${lib_iincs})
- endif()
- #
- #
- _c4_get_tgt_prop(lib_lib ${lib} LINK_LIBRARIES)
- if(lib_lib)
- target_link_libraries(${target} PUBLIC ${lib_lib})
- endif()
- _c4_get_tgt_prop(lib_ilib ${lib} INTERFACE_LIBRARY)
- if(lib_ilib)
- target_link_libraries(${target} INTERFACE ${lib_ilib})
- endif()
- #
- #
- c4_get_target_prop(${lib} SHARED_EXPORTS lib_exports)
- if(lib_exports)
- target_compile_definitions(${target} PRIVATE $<BUILD_INTERFACE:${lib_exports}>)
- endif()
-endfunction()
-
-
-#------------------------------------------------------------------------------
-#------------------------------------------------------------------------------
-#------------------------------------------------------------------------------
-#
-#
-function(c4_add_target_sources target)
- # https://steveire.wordpress.com/2016/08/09/opt-in-header-only-libraries-with-cmake/
- _c4_handle_args(_ARGS ${ARGN}
- _ARGS1 # one-value macro arguments
- INCORPORATED_FROM
- TRANSFORM # Transform types:
- # * NONE - do not transform the sources
- # * UNITY
- # * UNITY_HDR
- # * SINGLE_HDR
- # * SINGLE_UNIT
- _ARGSN # multi-value macro arguments
- PUBLIC
- INTERFACE
- PRIVATE
- )
- if(("${_TRANSFORM}" STREQUAL "GLOBAL") OR ("${_TRANSFORM}" STREQUAL ""))
- set(_TRANSFORM ${C4_SOURCE_TRANSFORM})
- endif()
- if("${_TRANSFORM}" STREQUAL "")
- set(_TRANSFORM NONE)
- endif()
- #
- # is this target an interface?
- set(_is_iface FALSE)
- _c4_get_tgt_prop(target_type ${target} TYPE)
- if("${target_type}" STREQUAL "INTERFACE_LIBRARY")
- set(_is_iface TRUE)
- elseif("${prop_name}" STREQUAL "LINK_LIBRARIES")
- set(_is_iface FALSE)
- endif()
- #
- set(out)
- set(umbrella ${_c4_lprefix}transform-src)
- #
- if("${_TRANSFORM}" STREQUAL "NONE")
- c4_dbg("target ${target}: source transform: NONE!")
- #
- # do not transform the sources
- #
- if(_PUBLIC)
- c4_dbg("target=${target} PUBLIC sources: ${_PUBLIC}")
- c4_append_target_prop(${target} PUBLIC_SRC "${_PUBLIC}")
- if(_INCORPORATED_FROM)
- c4_append_target_prop(${target} PUBLIC_SRC_${_INCORPORATED_FROM} "${_PUBLIC}")
- else()
- c4_append_target_prop(${target} PUBLIC_SRC_${target} "${_PUBLIC}")
- endif()
- target_sources(${target} PUBLIC "${_PUBLIC}")
- endif()
- if(_INTERFACE)
- c4_dbg("target=${target} INTERFACE sources: ${_INTERFACE}")
- c4_append_target_prop(${target} INTERFACE_SRC "${_INTERFACE}")
- if(_INCORPORATED_FROM)
- c4_append_target_prop(${target} INTERFACE_SRC_${_INCORPORATED_FROM} "${_INTERFACE}")
- else()
- c4_append_target_prop(${target} INTERFACE_SRC_${target} "${_INTERFACE}")
- endif()
- target_sources(${target} INTERFACE "${_INTERFACE}")
- endif()
- if(_PRIVATE)
- c4_dbg("target=${target} PRIVATE sources: ${_PRIVATE}")
- c4_append_target_prop(${target} PRIVATE_SRC "${_PRIVATE}")
- if(_INCORPORATED_FROM)
- c4_append_target_prop(${target} PRIVATE_SRC_${_INCORPORATED_FROM} "${_PRIVATE}")
- else()
- c4_append_target_prop(${target} PRIVATE_SRC_${target} "${_PRIVATE}")
- endif()
- target_sources(${target} PRIVATE "${_PRIVATE}")
- endif()
- #
- elseif("${_TRANSFORM}" STREQUAL "UNITY")
- c4_dbg("target ${target}: source transform: UNITY!")
- c4_err("source transformation not implemented")
- #
- # concatenate all compilation unit files (excluding interface)
- # into a single compilation unit
- #
- _c4cat_filter_srcs("${_PUBLIC}" cpublic)
- _c4cat_filter_hdrs("${_PUBLIC}" hpublic)
- _c4cat_filter_srcs("${_INTERFACE}" cinterface)
- _c4cat_filter_hdrs("${_INTERFACE}" hinterface)
- _c4cat_filter_srcs("${_PRIVATE}" cprivate)
- _c4cat_filter_hdrs("${_PRIVATE}" hprivate)
- if(cpublic OR cinterface OR cprivate)
- _c4cat_get_outname(${target} "src" ${C4_GEN_SRC_EXT} out)
- c4_dbg("${target}: output unit: ${out}")
- c4_cat_sources("${cpublic};${cinterface};${cprivate}" "${out}" ${umbrella})
- add_dependencies(${target} ${out})
- endif()
- if(_PUBLIC)
- c4_append_target_prop(${target} PUBLIC_SRC
- $<BUILD_INTERFACE:${hpublic};${out}>
- $<INSTALL_INTERFACE:${hpublic};${out}>)
- target_sources(${target} PUBLIC
- $<BUILD_INTERFACE:${hpublic};${out}>
- $<INSTALL_INTERFACE:${hpublic};${out}>)
- endif()
- if(_INTERFACE)
- c4_append_target_prop(${target} INTERFACE_SRC
- $<BUILD_INTERFACE:${hinterface}>
- $<INSTALL_INTERFACE:${hinterface}>)
- target_sources(${target} INTERFACE
- $<BUILD_INTERFACE:${hinterface}>
- $<INSTALL_INTERFACE:${hinterface}>)
- endif()
- if(_PRIVATE)
- c4_append_target_prop(${target} PRIVATE_SRC
- $<BUILD_INTERFACE:${hprivate}>
- $<INSTALL_INTERFACE:${hprivate}>)
- target_sources(${target} PRIVATE
- $<BUILD_INTERFACE:${hprivate}>
- $<INSTALL_INTERFACE:${hprivate}>)
- endif()
- elseif("${_TRANSFORM}" STREQUAL "UNITY_HDR")
- c4_dbg("target ${target}: source transform: UNITY_HDR!")
- c4_err("target ${target}: source transformation not implemented")
- #
- # like unity, but concatenate compilation units into
- # a header file, leaving other header files untouched
- #
- _c4cat_filter_srcs("${_PUBLIC}" cpublic)
- _c4cat_filter_hdrs("${_PUBLIC}" hpublic)
- _c4cat_filter_srcs("${_INTERFACE}" cinterface)
- _c4cat_filter_hdrs("${_INTERFACE}" hinterface)
- _c4cat_filter_srcs("${_PRIVATE}" cprivate)
- _c4cat_filter_hdrs("${_PRIVATE}" hprivate)
- if(c)
- _c4cat_get_outname(${target} "src" ${C4_GEN_HDR_EXT} out)
- c4_dbg("${target}: output hdr: ${out}")
- _c4cat_filter_srcs_hdrs("${_PUBLIC}" c_h)
- c4_cat_sources("${c}" "${out}" ${umbrella})
- add_dependencies(${target} ${out})
- add_dependencies(${target} ${_c4_lprefix}cat)
- endif()
- set(${src} ${out} PARENT_SCOPE)
- set(${hdr} ${h} PARENT_SCOPE)
- #
- elseif("${_TRANSFORM}" STREQUAL "SINGLE_HDR")
- c4_dbg("target ${target}: source transform: SINGLE_HDR!")
- c4_err("target ${target}: source transformation not implemented")
- #
- # concatenate everything into a single header file
- #
- _c4cat_get_outname(${target} "all" ${C4_GEN_HDR_EXT} out)
- _c4cat_filter_srcs_hdrs("${_c4al_SOURCES}" ch)
- c4_cat_sources("${ch}" "${out}" ${umbrella})
- #
- elseif("${_TRANSFORM}" STREQUAL "SINGLE_UNIT")
- c4_dbg("target ${target}: source transform: SINGLE_UNIT!")
- c4_err("target ${target}: source transformation not implemented")
- #
- # concatenate:
- # * all compilation units into a single compilation unit
- # * all headers into a single header
- #
- _c4cat_get_outname(${target} "src" ${C4_GEN_SRC_EXT} out)
- _c4cat_get_outname(${target} "hdr" ${C4_GEN_SRC_EXT} out)
- _c4cat_filter_srcs_hdrs("${_c4al_SOURCES}" ch)
- c4_cat_sources("${ch}" "${out}" ${umbrella})
- else()
- c4_err("unknown transform type: ${transform_type}. Must be one of GLOBAL;NONE;UNITY;TO_HEADERS;SINGLE_HEADER")
- endif()
-endfunction()
-
-
-# -----------------------------------------------------------------------------
-# -----------------------------------------------------------------------------
-# -----------------------------------------------------------------------------
-# WIP, under construction (still incomplete)
-# see: https://github.com/pr0g/cmake-examples
-# see: https://cliutils.gitlab.io/modern-cmake/
-
-
-function(c4_install_target target)
- _c4_handle_args(_ARGS ${ARGN}
- _ARGS1 # one-value macro arguments
- EXPORT # the name of the export target. default: see below.
- )
- _c4_handle_arg(EXPORT "${_c4_prefix}-export")
- #
- c4_dbg("installing target: ${target} ${ARGN}")
- #_c4_is_incorporated(${_c4_prefix} inc)
- #if(inc)
- # c4_dbg("this project is INCORPORATEd. skipping install of targets")
- # return()
- #endif()
- #
- _c4_setup_install_vars()
- install(TARGETS ${target}
- EXPORT ${_EXPORT}
- RUNTIME DESTINATION ${_RUNTIME_INSTALL_DIR} #COMPONENT runtime
- BUNDLE DESTINATION ${_RUNTIME_INSTALL_DIR} #COMPONENT runtime
- LIBRARY DESTINATION ${_LIBRARY_INSTALL_DIR} #COMPONENT runtime
- ARCHIVE DESTINATION ${_ARCHIVE_INSTALL_DIR} #COMPONENT development
- OBJECTS DESTINATION ${_OBJECTS_INSTALL_DIR} #COMPONENT development
- INCLUDES DESTINATION ${_INCLUDE_INSTALL_DIR} #COMPONENT development
- PUBLIC_HEADER DESTINATION ${_INCLUDE_INSTALL_DIR} #COMPONENT development
- )
- c4_install_sources(${target} include)
- #
- # on windows, install also required DLLs
- if(WIN32)
- get_target_property(target_type ${target} TYPE)
- if("${target_type}" STREQUAL "EXECUTABLE")
- c4_get_transitive_property(${target} _C4_DLLS transitive_dlls)
- if(transitive_dlls)
- c4_dbg("${target}: installing dlls: ${transitive_dlls} to ${_RUNTIME_INSTALL_DIR}")
- list(REMOVE_DUPLICATES transitive_dlls)
- install(FILES ${transitive_dlls}
- DESTINATION ${_RUNTIME_INSTALL_DIR} # shouldn't it be _LIBRARY_INSTALL_DIR?
- #COMPONENT runtime
- )
- endif()
- endif()
- endif()
- #
- set(l ${${_c4_prefix}_TARGETS})
- list(APPEND l ${target})
- set(${_c4_prefix}_TARGETS ${l} PARENT_SCOPE)
- #
-# # pkgconfig (WIP)
-# set(pc ${CMAKE_CURRENT_BINARY_DIR}/pkgconfig/${target}.pc)
-# file(WRITE ${pc} "# pkg-config: ${target}
-#
-#prefix=\"${CMAKE_INSTALL_PREFIX}\"
-#exec_prefix=\"\${_c4_prefix}\"
-#libdir=\"\${_c4_prefix}/${CMAKE_INSTALL_LIBDIR}\"
-#includedir=\"\${_c4_prefix}/include\"
-#
-#Name: ${target}
-#Description: A library for xyzzying frobnixes
-#URL: https://github.com/me/mylibrary
-#Version: 0.0.0
-#Requires: @PKGCONF_REQ_PUB@
-#Requires.private: @PKGCONF_REQ_PRIV@
-#Cflags: -I\"${includedir}\"
-#Libs: -L\"${libdir}\" -lmylibrary
-#Libs.private: -L\"${libdir}\" -lmylibrary @PKGCONF_LIBS_PRIV@
-#")
-# _c4_setup_install_vars()
-# install(FILES ${pc} DESTINATION "${_ARCHIVE_INSTALL_DIR}/pkgconfig/")
-endfunction()
-
-
-function(c4_install_sources target destination)
- c4_dbg("target ${target}: installing sources to ${destination}")
- # executables have no sources requiring install
- _c4_get_tgt_prop(target_type ${target} TYPE)
- if(target_type STREQUAL "EXECUTABLE")
- c4_dbg("target ${target}: is executable, skipping source install")
- return()
- endif()
- # install source from the target and incorporated targets
- c4_get_target_prop(${target} INCORPORATED_TARGETS inctargets)
- if(inctargets)
- set(targets "${inctargets};${target}")
- else()
- set(targets "${target}")
- endif()
- foreach(t ${targets})
- _c4_get_tgt_prop(srcroot ${t} C4_SOURCE_ROOT)
- # get the sources from the target
- #
- c4_get_target_prop(${t} PUBLIC_SRC_${t} src)
- if(src)
- _c4cat_filter_hdrs("${src}" srcf)
- _c4cat_filter_additional_exts("${src}" add)
- c4_install_files("${srcf}" "${destination}" "${srcroot}")
- c4_install_files("${add}" "${destination}" "${srcroot}")
- endif()
- #
- c4_get_target_prop(${t} PRIVATE_SRC_${t} psrc)
- if(psrc)
- _c4cat_filter_hdrs("${psrc}" psrcf)
- _c4cat_filter_additional_exts("${psrc}" add)
- c4_install_files("${psrcf}" "${destination}" "${srcroot}")
- c4_install_files("${add}" "${destination}" "${srcroot}")
- endif()
- #
- c4_get_target_prop(${t} INTERFACE_SRC_${t} isrc)
- if(isrc)
- _c4cat_filter_srcs_hdrs("${isrc}" isrcf)
- _c4cat_filter_additional_exts("${isrc}" add)
- c4_install_files("${isrcf}" "${destination}" "${srcroot}")
- c4_install_files("${add}" "${destination}" "${srcroot}")
- endif()
- #
- c4_get_target_prop(${t} ADDFILES addfiles)
- if(addfiles)
- foreach(af ${addfiles})
- string(REGEX REPLACE "(.*)!!(.*)!!(.*)" "\\1;\\2;\\3" li "${af}")
- list(GET li 0 files)
- list(GET li 1 dst)
- list(GET li 2 relative_to)
- string(REPLACE "%%%" ";" files "${files}")
- c4_install_files("${files}" "${dst}" "${relative_to}")
- endforeach()
- endif()
- #
- c4_get_target_prop(${t} ADDDIRS adddirs)
- if(adddirs)
- foreach(af ${adddirs})
- string(REGEX REPLACE "(.*)!!(.*)!!(.*)" "\\1;\\2;\\3" li "${af}")
- list(GET li 0 dirs)
- list(GET li 1 dst)
- list(GET li 2 relative_to)
- string(REPLACE "%%%" ";" dirs "${files}")
- c4_install_dirs("${dirs}" "${dst}" "${relative_to}")
- endforeach()
- endif()
- endforeach()
-endfunction()
-
-
-function(c4_install_target_add_files target files destination relative_to)
- c4_dbg("installing additional files for target ${target}, destination=${destination}: ${files}")
- string(REPLACE ";" "%%%" rfiles "${files}")
- c4_append_target_prop(${target} ADDFILES "${rfiles}!!${destination}!!${relative_to}")
- #
- _c4_is_incorporated(${_c4_prefix} inc)
- if(inc)
- c4_dbg("this project is INCORPORATEd. skipping install of targets")
- return()
- endif()
- c4_install_files("${files}" "${destination}" "${relative_to}")
-endfunction()
-
-
-function(c4_install_target_add_dirs target dirs destination relative_to)
- c4_dbg("installing additional dirs for target ${target}, destination=${destination}: ${dirs}")
- string(REPLACE ";" "%%%" rdirs "${dirs}")
- c4_append_target_prop(${target} ADDDIRS "${rdirs}!!${destination}!!${relative_to}")
- #
- _c4_is_incorporated(${_c4_prefix} inc)
- if(inc)
- c4_dbg("this project is INCORPORATEd. skipping install of targets")
- return()
- endif()
- c4_install_dirs("${dirs}" "${destination}" "${relative_to}")
-endfunction()
-
-
-function(c4_install_files files destination relative_to)
- c4_dbg("adding files to install list, destination ${destination}: ${files}")
- foreach(f ${files})
- file(RELATIVE_PATH rf "${relative_to}" ${f})
- get_filename_component(rd "${rf}" DIRECTORY)
- install(FILES ${f} DESTINATION "${destination}/${rd}" ${ARGN})
- endforeach()
-endfunction()
-
-
-function(c4_install_directories directories destination relative_to)
- c4_dbg("adding directories to install list, destination ${destination}: ${directories}")
- foreach(d ${directories})
- file(RELATIVE_PATH rf "${relative_to}" ${d})
- get_filename_component(rd "${rf}" DIRECTORY)
- install(DIRECTORY ${d} DESTINATION "${destination}/${rd}" ${ARGN})
- endforeach()
-endfunction()
-
-
-function(c4_install_exports)
- _c4_handle_args(_ARGS ${ARGN}
- _ARGS1 # one-value macro arguments
- PREFIX # override the c4 project-wide prefix. This will be used in the cmake
- TARGET # the name of the exports target
- NAMESPACE # the namespace for the targets
- _ARGSN # multi-value macro arguments
- DEPENDENCIES
- )
- #
- _c4_handle_arg(PREFIX "${_c4_prefix}")
- _c4_handle_arg(TARGET "${_c4_prefix}-export")
- _c4_handle_arg(NAMESPACE "${_c4_prefix}::")
- #
- c4_dbg("installing exports: ${ARGN}")
- #_c4_is_incorporated(${_c4_prefix} inc)
- #if(inc)
- # c4_dbg("this project is INCORPORATEd. skipping install of exports")
- # return()
- #endif()
- #
- _c4_setup_install_vars()
- #
- list(GET ${_c4_prefix}_TARGETS 0 target)
- set(exported_target "${_NAMESPACE}${target}")
- set(targets_file "${_PREFIX}Targets.cmake")
- #
- set(deps)
- if(_DEPENDENCIES)
- set(deps "#-----------------------------
-include(CMakeFindDependencyMacro)
-")
- foreach(d ${_DEPENDENCIES})
- _c4_is_incorporated(${d} inc)
- if(inc)
- c4_dbg("install: dependency ${d} is INCORPORATEd, skipping check")
- continue()
- endif()
- c4_dbg("install: adding dependency check for ${d}")
- set(deps "${deps}find_dependency(${d} REQUIRED)
-")
- endforeach()
- set(deps "${deps}#-----------------------------")
- endif()
- #
- # cfg_dst is the path relative to install root where the export
- # should be installed; cfg_dst_rel is the path from there to
- # the install root
- macro(__c4_install_exports cfg_dst cfg_dst_rel)
- # make sure that different exports are staged in different directories
- set(case ${CMAKE_CURRENT_BINARY_DIR}/export_cases/${cfg_dst})
- file(MAKE_DIRECTORY ${case})
- #
- install(EXPORT "${_TARGET}"
- FILE "${targets_file}"
- NAMESPACE "${_NAMESPACE}"
- DESTINATION "${cfg_dst}")
- export(EXPORT ${_TARGET}
- FILE "${targets_file}"
- NAMESPACE "${_NAMESPACE}")
- #
- # Config files
- # the module below has nice docs in it; do read them
- # to understand the macro calls below
- include(CMakePackageConfigHelpers)
- set(cfg ${case}/${_PREFIX}Config.cmake)
- set(cfg_ver ${case}/${_PREFIX}ConfigVersion.cmake)
- #
- file(WRITE ${cfg}.in "${deps}
-set(${_c4_uprefix}VERSION ${${_c4_uprefix}VERSION})
-
-@PACKAGE_INIT@
-
-if(NOT TARGET ${exported_target})
- include(\${PACKAGE_PREFIX_DIR}/${targets_file})
-endif()
-
-# HACK: PACKAGE_PREFIX_DIR is obtained from the PACKAGE_INIT macro above;
-# When used below in the calls to set_and_check(),
-# it points at the location of this file. So point it instead
-# to the CMAKE_INSTALL_PREFIX, in relative terms
-get_filename_component(PACKAGE_PREFIX_DIR
- \"\${PACKAGE_PREFIX_DIR}/${cfg_dst_rel}\" ABSOLUTE)
-
-set_and_check(${_c4_uprefix}INCLUDE_DIR \"@PACKAGE__INCLUDE_INSTALL_DIR@\")
-set_and_check(${_c4_uprefix}LIB_DIR \"@PACKAGE__LIBRARY_INSTALL_DIR@\")
-#set_and_check(${_c4_uprefix}SYSCONFIG_DIR \"@PACKAGE__SYSCONFIG_INSTALL_DIR@\")
-
-check_required_components(${_c4_lcprefix})
-")
- configure_package_config_file(${cfg}.in ${cfg}
- INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}" # defaults to CMAKE_INSTALL_PREFIX
- INSTALL_DESTINATION "${CMAKE_INSTALL_PREFIX}"
- PATH_VARS
- _INCLUDE_INSTALL_DIR
- _LIBRARY_INSTALL_DIR
- _SYSCONFIG_INSTALL_DIR
- #NO_SET_AND_CHECK_MACRO
- #NO_CHECK_REQUIRED_COMPONENTS_MACRO
- )
- write_basic_package_version_file(
- ${cfg_ver}
- VERSION ${${_c4_uprefix}VERSION}
- COMPATIBILITY AnyNewerVersion
- )
- install(FILES ${cfg} ${cfg_ver} DESTINATION ${cfg_dst})
- endmacro(__c4_install_exports)
- #
- # To install the exports:
- #
- # Windows:
- # <prefix>/
- # <prefix>/(cmake|CMake)/
- # <prefix>/<name>*/
- # <prefix>/<name>*/(cmake|CMake)/
- #
- # Unix:
- # <prefix>/(lib/<arch>|lib|share)/cmake/<name>*/
- # <prefix>/(lib/<arch>|lib|share)/<name>*/
- # <prefix>/(lib/<arch>|lib|share)/<name>*/(cmake|CMake)/
- #
- # Apple:
- # <prefix>/<name>.framework/Resources/
- # <prefix>/<name>.framework/Resources/CMake/
- # <prefix>/<name>.framework/Versions/*/Resources/
- # <prefix>/<name>.framework/Versions/*/Resources/CMake/
- # <prefix>/<name>.app/Contents/Resources/
- # <prefix>/<name>.app/Contents/Resources/CMake/
- #
- # (This was taken from the find_package() documentation)
- if(WIN32)
- __c4_install_exports(cmake/ "..")
- elseif(APPLE)
- __c4_install_exports(${_ARCHIVE_INSTALL_DIR}/cmake/${_c4_prefix} "../../..")
- #__c4_install_exports(${_ARCHIVE_INSTALL_DIR}/${_c4_prefix}.framework/Resources/ "../../..")
- elseif(UNIX OR (CMAKE_SYSTEM_NAME STREQUAL UNIX) OR (CMAKE_SYSTEM_NAME STREQUAL Linux) OR (CMAKE_SYSTEM_NAME STREQUAL Generic))
- __c4_install_exports(${_ARCHIVE_INSTALL_DIR}/cmake/${_c4_prefix} "../../..")
- else()
- c4_err("unknown platform. CMAKE_SYSTEM_NAME=${CMAKE_SYSTEM_NAME} CMAKE_SYSTEM_PROCESSOR=${CMAKE_SYSTEM_PROCESSOR}")
- endif()
-endfunction()
-
-
-macro(_c4_setup_install_vars)
- set(_RUNTIME_INSTALL_DIR bin/)
- set(_ARCHIVE_INSTALL_DIR lib/)
- set(_LIBRARY_INSTALL_DIR lib/) # TODO on Windows, ARCHIVE and LIBRARY dirs must be different to prevent name clashes
- set(_INCLUDE_INSTALL_DIR include/)
- set(_OBJECTS_INSTALL_DIR obj/)
- set(_SYSCONFIG_INSTALL_DIR etc/${_c4_lcprefix}/)
-endmacro()
-
-
-function(c4_get_target_installed_headers target out)
- c4_get_target_prop(${target} INCORPORATED_TARGETS inctargets)
- if(inctargets)
- set(targets "${inctargets};${target}")
- else()
- set(targets "${target}")
- endif()
- set(hdrs)
- foreach(t ${targets})
- _c4_get_tgt_prop(srcroot ${t} C4_SOURCE_ROOT)
- #
- c4_get_target_prop(${t} PUBLIC_SRC_${t} src)
- if(src)
- _c4cat_filter_hdrs("${src}" srcf)
- if(thdrs)
- set(thdrs "${thdrs};${srcf}")
- else()
- set(thdrs "${srcf}")
- endif()
- endif()
- #
- c4_get_target_prop(${t} PRIVATE_SRC_${t} psrc)
- if(src)
- _c4cat_filter_hdrs("${psrc}" psrcf)
- if(thdrs)
- set(thdrs "${thdrs};${psrcf}")
- else()
- set(thdrs "${psrcf}")
- endif()
- endif()
- #
- c4_get_target_prop(${t} INTERFACE_SRC_${t} isrc)
- if(src)
- _c4cat_filter_hdrs("${isrc}" isrcf)
- if(thdrs)
- set(thdrs "${thdrs};${isrcf}")
- else()
- set(thdrs "${isrcf}")
- endif()
- endif()
- #
- foreach(h ${thdrs})
- file(RELATIVE_PATH rf "${srcroot}" "${h}")
- list(APPEND hdrs "${rf}")
- endforeach()
- endforeach()
- set(${out} ${hdrs} PARENT_SCOPE)
-endfunction()
-
-
-#------------------------------------------------------------------------------
-#------------------------------------------------------------------------------
-#------------------------------------------------------------------------------
-function(c4_setup_testing)
- _c4_handle_args(_ARGS ${ARGN}
- _ARGS0
- GTEST # download and import googletest
- DOCTEST # download and import doctest
- _ARGS1
- _ARGSN
- )
- #include(GoogleTest) # this module requires at least cmake 3.9
- c4_dbg("enabling tests")
- # umbrella target for building test binaries
- add_custom_target(${_c4_lprefix}test-build)
- _c4_set_target_folder(${_c4_lprefix}test-build test)
- # umbrella targets for running tests
- if(NOT TARGET test-build)
- add_custom_target(test-build)
- add_custom_target(test-verbose)
- _c4_set_target_folder(test-build "/test")
- _c4_set_target_folder(test-verbose "/test")
- endif()
- if(NOT TARGET test)
- # add a test target. To prevent a warning, we need to set up a policy,
- # and also suppress the resulting warning from suppressing the warning.
- set(_depr_old_val ${CMAKE_WARN_DEPRECATED})
- set(CMAKE_WARN_DEPRECATED OFF CACHE BOOL "" FORCE) # https://stackoverflow.com/questions/67432538/cannot-set-cmake-warn-deprecated-inside-the-cmakelists-txt
- cmake_policy(PUSH)
- cmake_policy(SET CMP0037 OLD) # target name "test" is reserved for CTesting
- add_custom_target(test)
- _c4_set_target_folder(test "/test")
- cmake_policy(POP)
- set(CMAKE_WARN_DEPRECATED OFF CACHE BOOL "${_depr_old_val}" FORCE)
- unset(_depr_old_val)
- endif()
- function(_def_runner runner)
- set(echo "
-CWD=${CMAKE_CURRENT_BINARY_DIR}
-----------------------------------
-${ARGN}
-----------------------------------
-")
- add_custom_target(${runner}
- #${CMAKE_COMMAND} -E echo "${echo}"
- COMMAND ${ARGN}
- WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
- DEPENDS ${_c4_lprefix}test-build
- )
- _c4_set_target_folder(${runner} test)
- endfunction()
- _def_runner(${_c4_lprefix}test-run ${CMAKE_CTEST_COMMAND} --output-on-failure ${${_c4_uprefix}CTEST_OPTIONS} -C $<CONFIG>)
- _def_runner(${_c4_lprefix}test-run-verbose ${CMAKE_CTEST_COMMAND} -VV ${${_c4_uprefix}CTEST_OPTIONS} -C $<CONFIG>)
- add_dependencies(test ${_c4_lprefix}test-run)
- add_dependencies(test-verbose ${_c4_lprefix}test-run-verbose)
- add_dependencies(test-build ${_c4_lprefix}test-build)
- #
- # import required libraries
- if(_GTEST)
- c4_log("testing requires googletest")
- if(NOT TARGET gtest)
- c4_import_remote_proj(gtest ${CMAKE_CURRENT_BINARY_DIR}/ext/gtest
- REMOTE
- GIT_REPOSITORY https://github.com/google/googletest.git
- GIT_TAG release-1.11.0 #GIT_SHALLOW ON
- OVERRIDE
- BUILD_GTEST ON
- BUILD_GMOCK OFF
- gtest_force_shared_crt ON
- gtest_build_samples OFF
- gtest_build_tests OFF
- SET_FOLDER_TARGETS ext gtest gtest_main
- EXCLUDE_FROM_ALL
- )
- # old gcc-4.8 support
- if((CMAKE_CXX_COMPILER_ID STREQUAL "GNU") AND
- (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 4.8) AND
- (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.0))
- _c4_get_subproject_property(gtest SRC_DIR _gtest_patch_src_dir)
- apply_patch("${_c4_project_dir}/compat/gtest_gcc-4.8.patch"
- "${_gtest_patch_src_dir}"
- "${_gtest_patch_src_dir}/.gtest_gcc-4.8.patch")
- unset(_gtest_patch_src_dir)
- target_compile_options(gtest PUBLIC -include ${_c4_project_dir}/compat/c4/gcc-4.8.hpp)
- endif()
- endif()
- endif()
- if(_DOCTEST)
- c4_log("testing requires doctest")
- if(NOT TARGET doctest)
- c4_import_remote_proj(doctest ${CMAKE_CURRENT_BINARY_DIR}/ext/doctest
- REMOTE
- GIT_REPOSITORY https://github.com/onqtam/doctest.git
- GIT_TAG 2.4.6 #GIT_SHALLOW ON
- OVERRIDE
- DOCTEST_WITH_TESTS OFF
- DOCTEST_WITH_MAIN_IN_STATIC_LIB ON
- SET_FOLDER_TARGETS ext doctest_with_main
- EXCLUDE_FROM_ALL
- )
- endif()
- endif()
-endfunction(c4_setup_testing)
-
-
-function(c4_add_test target)
- _c4_handle_args(_ARGS ${ARGN}
- _ARGS0 # zero-value macro arguments
- _ARGS1 # one-value macro arguments
- WORKING_DIRECTORY
- _ARGSN # multi-value macro arguments
- ARGS
- )
- #
- if(_WORKING_DIRECTORY)
- set(_WORKING_DIRECTORY WORKING_DIRECTORY ${_WORKING_DIRECTORY})
- endif()
- set(cmd_pfx)
- if(CMAKE_CROSSCOMPILING)
- set(cmd_pfx ${CMAKE_CROSSCOMPILING_EMULATOR})
- endif()
- if(NOT ${uprefix}SANITIZE_ONLY)
- if(${CMAKE_VERSION} VERSION_LESS "3.16.0")
- add_test(NAME ${target}
- COMMAND ${cmd_pfx} "$<TARGET_FILE:${target}>" ${_ARGS}
- ${_WORKING_DIRECTORY})
- else()
- add_test(NAME ${target}
- COMMAND ${cmd_pfx} "$<TARGET_FILE:${target}>" ${_ARGS}
- ${_WORKING_DIRECTORY}
- COMMAND_EXPAND_LISTS)
- endif()
- endif()
- #
- if("${CMAKE_BUILD_TYPE}" STREQUAL "Coverage")
- add_dependencies(${_c4_lprefix}test-build ${target})
- return()
- endif()
- #
- set(sanitized_targets)
- foreach(s asan msan tsan ubsan)
- set(t ${target}-${s})
- if(TARGET ${t})
- list(APPEND sanitized_targets ${s})
- endif()
- endforeach()
- if(sanitized_targets)
- add_custom_target(${target}-all)
- add_dependencies(${target}-all ${target})
- add_dependencies(${_c4_lprefix}test-build ${target}-all)
- _c4_set_target_folder(${target}-all test/${target})
- else()
- add_dependencies(${_c4_lprefix}test-build ${target})
- endif()
- if(sanitized_targets)
- foreach(s asan msan tsan ubsan)
- set(t ${target}-${s})
- if(TARGET ${t})
- add_dependencies(${target}-all ${t})
- c4_sanitize_get_target_command("${cmd_pfx};$<TARGET_FILE:${t}>" ${s} cmd)
- #c4_log("adding test: ${t}")
- add_test(NAME ${t}
- COMMAND ${cmd} ${_ARGS}
- ${_WORKING_DIRECTORY}
- COMMAND_EXPAND_LISTS)
- endif()
- endforeach()
- endif()
- if(NOT CMAKE_CROSSCOMPILING)
- if(NOT ${_c4_uprefix}SANITIZE_ONLY)
- c4_add_valgrind(${target} ${ARGN})
- endif()
- endif()
- if(${_c4_uprefix}LINT)
- c4_static_analysis_add_tests(${target}) # this will not actually run the executable
- endif()
-endfunction(c4_add_test)
-
-
-# every excess argument is passed on to set_target_properties()
-function(c4_add_test_fail_build name srccontent_or_srcfilename)
- #
- set(sdir ${CMAKE_CURRENT_BINARY_DIR}/test_fail_build)
- set(src ${srccontent_or_srcfilename})
- if("${src}" STREQUAL "")
- c4_err("must be given an existing source file name or a non-empty string")
- endif()
- #
- if(EXISTS ${src})
- set(fn ${src})
- else()
- if(NOT EXISTS ${sdir})
- file(MAKE_DIRECTORY ${sdir})
- endif()
- set(fn ${sdir}/${name}.cpp)
- file(WRITE ${fn} "${src}")
- endif()
- #
- # https://stackoverflow.com/questions/30155619/expected-build-failure-tests-in-cmake
- add_executable(${name} ${fn})
- # don't build this target
- set_target_properties(${name} PROPERTIES
- EXCLUDE_FROM_ALL TRUE
- EXCLUDE_FROM_DEFAULT_BUILD TRUE
- # and pass on further properties given by the caller
- ${ARGN})
- add_test(NAME ${name}
- COMMAND ${CMAKE_COMMAND} --build . --target ${name} --config $<CONFIGURATION>
- WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
- set_tests_properties(${name} PROPERTIES WILL_FAIL TRUE)
-endfunction()
-
-
-# add a test ensuring that a target linking and using code from a library
-# successfully compiles and runs against the installed library
-function(c4_add_install_link_test library namespace exe_source_code)
- if(CMAKE_CROSSCOMPILING)
- c4_log("cross-compiling: skip install link test")
- return()
- endif()
- if("${library}" STREQUAL "${_c4_prefix}")
- set(testname ${_c4_lprefix}test-install-link)
- else()
- set(testname ${_c4_lprefix}test-install-link-${library})
- endif()
- _c4_add_library_client_test(${library} "${namespace}" "${testname}" "${exe_source_code}")
-endfunction()
-
-
-# add a test ensuring that a target consuming every header in a library
-# successfully compiles and runs against the installed library
-function(c4_add_install_include_test library namespace)
- if(CMAKE_CROSSCOMPILING)
- c4_log("cross-compiling: skip install include test")
- return()
- endif()
- c4_get_target_installed_headers(${library} incfiles)
- set(incblock)
- foreach(i ${incfiles})
- set(incblock "${incblock}
-#include <${i}>")
- endforeach()
- set(src "${incblock}
-
-int main()
-{
- return 0;
-}
-")
- if("${library}" STREQUAL "${_c4_prefix}")
- set(testname ${_c4_lprefix}test-install-include)
- else()
- set(testname ${_c4_lprefix}test-install-include-${library})
- endif()
- _c4_add_library_client_test(${library} "${namespace}" "${testname}" "${src}")
-endfunction()
-
-
-function(_c4_add_library_client_test library namespace pname source_code)
- if("${CMAKE_BUILD_TYPE}" STREQUAL Coverage)
- add_test(NAME ${pname}
- COMMAND ${CMAKE_COMMAND} -E echo "skipping this test in coverage builds"
- )
- return()
- endif()
- set(pdir "${CMAKE_CURRENT_BINARY_DIR}/${pname}")
- set(bdir "${pdir}/build")
- if(NOT EXISTS "${pdir}")
- file(MAKE_DIRECTORY "${pdir}")
- endif()
- if(NOT EXISTS "${bdir}/build")
- file(MAKE_DIRECTORY "${bdir}/build")
- endif()
- set(psrc "${pdir}/${pname}.cpp")
- set(tsrc "${pdir}/${pname}-run.cmake")
- set(tout "${pdir}/${pname}-run-out")
- # generate the source file
- file(WRITE "${psrc}" "${source_code}")
- # generate the cmake project consuming this library
- file(WRITE "${pdir}/CMakeLists.txt" "
-cmake_minimum_required(VERSION 3.12)
-project(${pname} LANGUAGES CXX)
-
-find_package(${library} REQUIRED)
-
-message(STATUS \"
-found ${library}:
- ${_c4_uprefix}INCLUDE_DIR=\${${_c4_uprefix}INCLUDE_DIR}
- ${_c4_uprefix}LIB_DIR=\${${_c4_uprefix}LIB_DIR}
-\")
-
-add_executable(${pname} ${pname}.cpp)
-# this must be the only required setup to link with ${library}
-target_link_libraries(${pname} PUBLIC ${namespace}${library})
-
-get_target_property(lib_type ${namespace}${library} TYPE)
-if(WIN32 AND (lib_type STREQUAL SHARED_LIBRARY))
- # add the directory containing the DLL to the path
- get_target_property(imported_configs ${namespace}${library} IMPORTED_CONFIGURATIONS)
- message(STATUS \"${namespace}${library}: it's a shared library. imported configs: \${imported_configs}\")
- foreach(cfg \${imported_configs})
- get_target_property(implib ${namespace}${library} IMPORTED_IMPLIB_\${cfg})
- get_target_property(location ${namespace}${library} IMPORTED_LOCATION_\${cfg})
- message(STATUS \"${namespace}${library}: implib_\${cfg}=\${implib}\")
- message(STATUS \"${namespace}${library}: location_\${cfg}=\${location}\")
- break()
- endforeach()
- get_filename_component(dlldir \"\${location}\" DIRECTORY)
- message(STATUS \"${namespace}${library}: dlldir=\${dlldir}\")
- add_custom_target(${pname}-run
- COMMAND \${CMAKE_COMMAND} -E echo \"cd \${dlldir} && \$<TARGET_FILE:${pname}>\"
- COMMAND \$<TARGET_FILE:${pname}>
- DEPENDS ${pname}
- WORKING_DIRECTORY \${dlldir})
-else()
- add_custom_target(${pname}-run
- COMMAND \$<TARGET_FILE:${pname}>
- DEPENDS ${pname})
-endif()
-")
- # The test consists in running the script generated below.
- # We force evaluation of the configuration generator expression
- # by receiving its result via the command line.
- add_test(NAME ${pname}
- COMMAND ${CMAKE_COMMAND} -DCFG_IN=$<CONFIG> -P "${tsrc}"
- )
- # NOTE: in the cmake configure command, be sure to NOT use quotes
- # in -DCMAKE_PREFIX_PATH=\"${CMAKE_INSTALL_PREFIX}\". Use
- # -DCMAKE_PREFIX_PATH=${CMAKE_INSTALL_PREFIX} instead.
- # So here we add a check to make sure the install path has no spaces
- string(FIND "${CMAKE_INSTALL_PREFIX}" " " has_spaces)
- if(NOT (has_spaces EQUAL -1))
- c4_err("install tests will fail if the install path has spaces: '${CMAKE_INSTALL_PREFIX}' : ... ${has_spaces}")
- endif()
- # make sure the test project uses the same architecture
- # CMAKE_VS_PLATFORM_NAME is available only since cmake 3.9
- # see https://cmake.org/cmake/help/v3.9/variable/CMAKE_GENERATOR_PLATFORM.html
- if(WIN32)
- set(cfg_opt "--config \${cfg}")
- if(CMAKE_GENERATOR_PLATFORM OR CMAKE_VS_PLATFORM_NAME)
- set(arch "-DCMAKE_GENERATOR_PLATFORM=${CMAKE_GENERATOR_PLATFORM}" "-DCMAKE_VS_PLATFORM_NAME=${CMAKE_VS_PLATFORM_NAME}")
- else()
- if(CMAKE_SIZEOF_VOID_P EQUAL 8)
- set(arch -A x64)
- elseif(CMAKE_SIZEOF_VOID_P EQUAL 4)
- set(arch -A Win32)
- else()
- c4_err("not implemented")
- endif()
- endif()
- elseif(ANDROID OR IOS OR WINCE OR WINDOWS_PHONE)
- c4_err("not implemented")
- elseif(IOS)
- c4_err("not implemented")
- elseif(UNIX)
- if(CMAKE_GENERATOR_PLATFORM OR CMAKE_VS_PLATFORM_NAME)
- set(arch "-DCMAKE_GENERATOR_PLATFORM=${CMAKE_GENERATOR_PLATFORM}" "-DCMAKE_VS_PLATFORM_NAME=${CMAKE_VS_PLATFORM_NAME}")
- else()
- if(CMAKE_SYSTEM_PROCESSOR STREQUAL aarch64)
- else()
- if(CMAKE_SIZEOF_VOID_P EQUAL 8)
- set(arch "-DCMAKE_CXX_FLAGS=-m64")
- elseif(CMAKE_SIZEOF_VOID_P EQUAL 4)
- set(arch "-DCMAKE_CXX_FLAGS=-m32")
- else()
- c4_err("not implemented")
- endif()
- endif()
- endif()
- endif()
- # generate the cmake script with the test content
- file(WRITE "${tsrc}" "
-# run a command and check its return status
-function(runcmd id)
- set(cmdout \"${tout}-\${id}.log\")
- message(STATUS \"Running command: \${ARGN}\")
- message(STATUS \"Running command: output goes to \${cmdout}\")
- execute_process(
- COMMAND \${ARGN}
- RESULT_VARIABLE retval
- OUTPUT_FILE \"\${cmdout}\"
- ERROR_FILE \"\${cmdout}\"
- # COMMAND_ECHO STDOUT # only available from cmake-3.15
- )
- message(STATUS \"Running command: exit status was \${retval}\")
- file(READ \"\${cmdout}\" output)
- if(\"\${cmdout}\" STREQUAL \"\")
- message(STATUS \"Running command: no output\")
- else()
- message(STATUS \"Running command: output:
---------------------
-\${output}--------------------\")
- endif()
- if(NOT (\${retval} EQUAL 0))
- message(FATAL_ERROR \"Command failed with exit status \${retval}: \${ARGN}\")
- endif()
-endfunction()
-
-set(cmk \"${CMAKE_COMMAND}\")
-set(pfx \"${CMAKE_INSTALL_PREFIX}\")
-set(idir \"${CMAKE_BINARY_DIR}\")
-set(pdir \"${pdir}\")
-set(bdir \"${bdir}\")
-
-# force evaluation of the configuration generator expression
-# by receiving its result via the command line
-set(cfg \${CFG_IN})
-
-# remove any existing library install
-if(EXISTS \"\${pfx}\")
- runcmd(0_rmdir \"\${cmk}\" -E remove_directory \"\${pfx}\")
-else()
- message(STATUS \"does not exist: \${pfx}\")
-endif()
-
-# install the library
-#runcmd(1_install_lib \"\${cmk}\" --install \"\${idir}\" ${cfg_opt}) # requires cmake>3.13 (at least)
-runcmd(1_install_lib \"\${cmk}\" --build \"\${idir}\" ${cfg_opt} --target install)
-
-# configure the client project
-runcmd(2_config \"\${cmk}\" -S \"\${pdir}\" -B \"\${bdir}\" \"-DCMAKE_PREFIX_PATH=\${pfx}\" \"-DCMAKE_GENERATOR=${CMAKE_GENERATOR}\" ${arch} \"-DCMAKE_C_COMPILER=${CMAKE_C_COMPILER}\" \"-DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}\")
-
-# build the client project
-runcmd(3_build \"\${cmk}\" --build \"\${bdir}\" ${cfg_opt})
-
-# run the client executable
-runcmd(4_install \"\${cmk}\" --build \"\${bdir}\" --target \"${pname}-run\" ${cfg_opt})
-")
-endfunction()
-
-
-#------------------------------------------------------------------------------
-#------------------------------------------------------------------------------
-#------------------------------------------------------------------------------
-function(c4_setup_valgrind umbrella_option)
- if(UNIX AND (NOT "${CMAKE_BUILD_TYPE}" STREQUAL "Coverage"))
- if("${C4_VALGRIND}" STREQUAL "")
- option(C4_VALGRIND "enable valgrind tests (all subprojects)" ON)
- endif()
- if("${C4_VALGRIND_SGCHECK}" STREQUAL "")
- option(C4_VALGRIND_SGCHECK "enable valgrind tests with the exp-sgcheck tool (all subprojects)" OFF)
- endif()
- cmake_dependent_option(${_c4_uprefix}VALGRIND "enable valgrind tests" ${C4_VALGRIND} ${umbrella_option} OFF)
- cmake_dependent_option(${_c4_uprefix}VALGRIND_SGCHECK "enable valgrind tests with the exp-sgcheck tool" ${C4_VALGRIND_SGCHECK} ${umbrella_option} OFF)
- set(${_c4_uprefix}VALGRIND_OPTIONS "--gen-suppressions=all --error-exitcode=10101" CACHE STRING "options for valgrind tests")
- endif()
-endfunction(c4_setup_valgrind)
-
-
-function(c4_add_valgrind target_name)
- _c4_handle_args(_ARGS ${ARGN}
- _ARGS0 # zero-value macro arguments
- _ARGS1 # one-value macro arguments
- WORKING_DIRECTORY
- _ARGSN # multi-value macro arguments
- ARGS
- )
- #
- if(_WORKING_DIRECTORY)
- set(_WORKING_DIRECTORY WORKING_DIRECTORY ${_WORKING_DIRECTORY})
- endif()
- # @todo: consider doing this for valgrind:
- # http://stackoverflow.com/questions/40325957/how-do-i-add-valgrind-tests-to-my-cmake-test-target
- # for now we explicitly run it:
- if(${_c4_uprefix}VALGRIND)
- separate_arguments(_vg_opts UNIX_COMMAND "${${_c4_uprefix}VALGRIND_OPTIONS}")
- add_test(NAME ${target_name}-valgrind
- COMMAND valgrind ${_vg_opts} $<TARGET_FILE:${target_name}> ${_ARGS}
- ${_WORKING_DIRECTORY}
- COMMAND_EXPAND_LISTS)
- endif()
- if(${_c4_uprefix}VALGRIND_SGCHECK)
- # stack and global array overrun detector
- # http://valgrind.org/docs/manual/sg-manual.html
- separate_arguments(_sg_opts UNIX_COMMAND "--tool=exp-sgcheck ${${_c4_uprefix}VALGRIND_OPTIONS}")
- add_test(NAME ${target_name}-sgcheck
- COMMAND valgrind ${_sg_opts} $<TARGET_FILE:${target_name}> ${_ARGS}
- ${_WORKING_DIRECTORY}
- COMMAND_EXPAND_LISTS)
- endif()
-endfunction(c4_add_valgrind)
-
-
-#------------------------------------------------------------------------------
-#------------------------------------------------------------------------------
-#------------------------------------------------------------------------------
-
-function(c4_setup_coverage)
- if(NOT ("${CMAKE_BUILD_TYPE}" STREQUAL "Coverage"))
- return()
- endif()
- #
- _c4_handle_args(_ARGS ${ARGN}
- _ARGS0 # zero-value macro arguments
- _ARGS1 # one-value macro arguments
- _ARGSN # multi-value macro arguments
- COVFLAGS # coverage compilation flags
- INCLUDE # patterns to include in the coverage, relative to CMAKE_SOURCE_DIR
- EXCLUDE # patterns to exclude in the coverage, relative to CMAKE_SOURCE_DIR
- EXCLUDE_ABS # absolute paths to exclude in the coverage
- GENHTML_ARGS # options to pass to genhtml
- )
- # defaults for the macro arguments
- set(_genhtml_args "--title ${_c4_lcprefix} --demangle-cpp --sort --function-coverage --branch-coverage --prefix '${CMAKE_SOURCE_DIR}' --prefix '${CMAKE_BINARY_DIR}'")
- set(covflags "-g -O0 --coverage") #set(covflags "-g -O0 -fprofile-arcs -ftest-coverage")
- if(CMAKE_CXX_COMPILER_ID MATCHES "GNU")
- set(covflags "${covflags} -fprofile-arcs -ftest-coverage -fno-inline -fno-inline-small-functions -fno-default-inline")
- endif()
- set(${_c4_uprefix}COVERAGE_FLAGS "${covflags}" CACHE STRING "coverage compilation flags")
- set(${_c4_uprefix}COVERAGE_GENHTML_ARGS "${_genhtml_args}" CACHE STRING "arguments to pass to genhtml")
- set(${_c4_uprefix}COVERAGE_INCLUDE src CACHE STRING "relative paths to include in the coverage, relative to CMAKE_SOURCE_DIR")
- set(${_c4_uprefix}COVERAGE_EXCLUDE bm;build;extern;ext;src/c4/ext;test CACHE STRING "relative paths to exclude from the coverage, relative to CMAKE_SOURCE_DIR")
- set(${_c4_uprefix}COVERAGE_EXCLUDE_ABS /usr CACHE STRING "absolute paths to exclude from the coverage")
- _c4_handle_arg(COVFLAGS ${${_c4_uprefix}COVERAGE_FLAGS})
- _c4_handle_arg(INCLUDE ${${_c4_uprefix}COVERAGE_INCLUDE})
- _c4_handle_arg(EXCLUDE ${${_c4_uprefix}COVERAGE_EXCLUDE})
- _c4_handle_arg(EXCLUDE_ABS ${${_c4_uprefix}COVERAGE_EXCLUDE_ABS} "${CMAKE_BINARY_DIR}")
- _c4_handle_arg(GENHTML_ARGS ${${_c4_uprefix}COVERAGE_GENHTML_ARGS})
- #
- function(_c4cov_transform_filters var reldir)
- set(_filters)
- foreach(pat ${${var}})
- list(APPEND _filters "'${reldir}${pat}/*'")
- endforeach()
- set(${var} ${_filters} PARENT_SCOPE)
- endfunction()
- _c4cov_transform_filters(_INCLUDE "${CMAKE_SOURCE_DIR}/")
- _c4cov_transform_filters(_EXCLUDE "${CMAKE_SOURCE_DIR}/")
- _c4cov_transform_filters(_EXCLUDE_ABS "")
- #
- if("${CMAKE_CXX_COMPILER_ID}" MATCHES "(Apple)?[Cc]lang")
- if("${CMAKE_CXX_COMPILER_VERSION}" VERSION_LESS 3)
- c4_err("coverage: clang version must be 3.0.0 or greater")
- endif()
- elseif(NOT CMAKE_COMPILER_IS_GNUCXX)
- c4_err("coverage: compiler is not GNUCXX")
- endif()
- #
- find_program(GCOV gcov)
- find_program(LCOV lcov)
- find_program(GENHTML genhtml)
- find_program(CTEST ctest)
- if(NOT (GCOV AND LCOV AND GENHTML AND CTEST))
- c4_err("Coverage tools not available:
- gcov: ${GCOV}
- lcov: ${LCOV}
- genhtml: ${GENHTML}
- ctest: ${CTEST}
- --coverage flags: ${_COVFLAGS}")
- endif()
- #
- add_configuration_type(Coverage
- DEFAULT_FROM DEBUG
- C_FLAGS ${_COVFLAGS}
- CXX_FLAGS ${_COVFLAGS}
- )
- #
- option(${_c4_uprefix}COVERAGE_CODECOV "enable target to submit coverage to codecov.io" OFF)
- option(${_c4_uprefix}COVERAGE_COVERALLS "enable target to submit coverage to coveralls.io" OFF)
- #
- c4_dbg("adding coverage targets")
- #
- set(sd "${CMAKE_SOURCE_DIR}")
- set(bd "${CMAKE_BINARY_DIR}")
- set(coverage_result ${bd}/lcov/index.html)
- set(lcov_result ${bd}/coverage3-final_filtered.lcov)
- separate_arguments(_GENHTML_ARGS NATIVE_COMMAND ${_GENHTML_ARGS})
- add_custom_command(OUTPUT ${coverage_result} ${lcov_result}
- COMMAND echo "cd ${CMAKE_BINARY_DIR}"
- COMMAND ${LCOV} -q --zerocounters --directory .
- COMMAND ${LCOV} -q --no-external --capture --base-directory "${sd}" --directory . --output-file ${bd}/coverage0-before.lcov --initial
- COMMAND ${CMAKE_COMMAND} --build . --target ${_c4_lprefix}test-run || echo "Failed running the tests. Proceeding with coverage, but results may be affected or even empty."
- COMMAND ${LCOV} -q --no-external --capture --base-directory "${sd}" --directory . --output-file ${bd}/coverage1-after.lcov
- COMMAND ${LCOV} -q --add-tracefile ${bd}/coverage0-before.lcov --add-tracefile ${bd}/coverage1-after.lcov --output-file ${bd}/coverage2-final.lcov
- COMMAND ${LCOV} -q --remove ${bd}/coverage2-final.lcov ${_EXCLUDE} ${EXCLUDE_ABS} --output-file ${bd}/coverage3-final_filtered.lcov
- COMMAND ${GENHTML} ${bd}/coverage3-final_filtered.lcov -o ${bd}/lcov ${_GENHTML_ARGS}
- COMMAND echo "Coverage report: ${coverage_result}"
- DEPENDS ${_c4_lprefix}test-build
- WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
- COMMENT "${_c4_prefix} coverage: LCOV report at ${coverage_result}"
- #VERBATIM
- )
- add_custom_target(${_c4_lprefix}coverage SOURCES ${coverage_result} ${lcov_result})
- #
- if(${_c4_uprefix}COVERAGE_CODECOV)
- set(_subm ${_c4_lprefix}coverage-submit-codecov)
- _c4cov_get_service_token(codecov _token)
- if(NOT ("${_token}" STREQUAL ""))
- set(_token -t "${_token}")
- endif()
- set(_silent_codecov)
- if(${_c4_uprefix}COVERAGE_CODECOV_SILENT)
- set(_silent_codecov >${CMAKE_BINARY_DIR}/codecov.log 2>&1)
- endif()
- #
- c4_log("coverage: enabling submission of results to https://codecov.io: ${_subm}")
- set(submitcc "${CMAKE_BINARY_DIR}/submit_codecov.sh")
- c4_download_file("https://codecov.io/bash" "${submitcc}")
- set(submit_cmd bash ${submitcc} -Z ${_token} -X gcov -X gcovout -p ${CMAKE_SOURCE_DIR} -f ${lcov_result} ${_silent_codecov})
- string(REPLACE ";" " " submit_cmd_str "${submit_cmd}")
- add_custom_target(${_subm}
- SOURCES ${lcov_result}
- WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
- COMMAND echo "cd ${CMAKE_BINARY_DIR} && ${submit_cmd_str}"
- COMMAND ${submit_cmd}
- VERBATIM
- COMMENT "${_c4_lcprefix} coverage: submit to codecov"
- )
- c4_add_umbrella_target(coverage-submit-codecov coverage-submit) # uses the current prefix
- endif()
- #
- if(${_c4_uprefix}COVERAGE_COVERALLS)
- set(_subm ${_c4_lprefix}coverage-submit-coveralls)
- _c4cov_get_service_token(coveralls _token)
- if(NOT ("${_token}" STREQUAL ""))
- set(_token --repo-token "${_token}")
- endif()
- set(_silent_coveralls)
- if(${_c4_uprefix}COVERAGE_COVERALLS_SILENT)
- set(_silent_coveralls >${CMAKE_BINARY_DIR}/coveralls.log 2>&1)
- endif()
- #
- c4_log("coverage: enabling submission of results to https://coveralls.io: ${_subm}")
- set(submit_cmd coveralls ${_token} --build-root ${CMAKE_BINARY_DIR} --root ${CMAKE_SOURCE_DIR} --no-gcov --lcov-file ${lcov_result} ${_silent_coveralls})
- string(REPLACE ";" " " submit_cmd_str "${submit_cmd}")
- add_custom_target(${_subm}
- SOURCES ${lcov_result}
- WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
- COMMAND echo "cd ${CMAKE_BINARY_DIR} && ${submit_cmd_str}"
- COMMAND ${submit_cmd}
- VERBATIM
- COMMENT "${_c4_lcprefix} coverage: submit to coveralls"
- )
- c4_add_umbrella_target(coverage-submit-coveralls coverage-submit) # uses the current prefix
- endif()
-endfunction(c4_setup_coverage)
-
-
-# 1. try cmake or environment variables
-# 2. try local file
-function(_c4cov_get_service_token service out)
- # try cmake var
- string(TOUPPER ${service} uservice)
- c4_get_from_first_of(token COVERAGE_${uservice}_TOKEN ENV)
- if(NOT ("${token}" STREQUAL ""))
- c4_dbg("${service}: found token from variable: ${token}")
- else()
- # try local file
- set(service_token_file ${CMAKE_SOURCE_DIR}/.ci/${service}.token)
- if(EXISTS ${service_token_file})
- file(READ ${service_token_file} token)
- c4_dbg("found token file for ${service} coverage report: ${service_token_file}")
- else()
- c4_dbg("could not find token for ${service} coverage report")
- endif()
- endif()
- set(${out} ${token} PARENT_SCOPE)
-endfunction()
-
-
-#------------------------------------------------------------------------------
-#------------------------------------------------------------------------------
-#------------------------------------------------------------------------------
-
-function(c4_add_umbrella_target target umbrella_target)
- _c4_handle_args(_ARGS ${ARGN}
- # zero-value macro arguments
- _ARGS0
- ALWAYS # Add the umbrella target even if this is the only one under it.
- # The default behavior is to add the umbrella target only if
- # there is more than one target under it.
- # one-value macro arguments
- _ARGS1
- PREFIX # The project prefix. Defaults to ${_c4_lprefix}
- # multi-value macro arguments
- _ARGSN
- ARGS # more args to add_custom_target()
- )
- if(NOT _PREFIX)
- set(_PREFIX "${_c4_lprefix}")
- endif()
- set(t ${_PREFIX}${target})
- set(ut ${_PREFIX}${umbrella_target})
- # if the umbrella target already exists, just add the dependency
- if(TARGET ${ut})
- add_dependencies(${ut} ${t})
- else()
- if(_ALWAYS)
- add_custom_target(${ut} ${_ARGS})
- add_dependencies(${ut} ${t})
- else()
- # check if there is more than one under the same umbrella
- c4_get_proj_prop(${ut}_subtargets sub)
- if(sub)
- add_custom_target(${ut} ${_ARGS})
- add_dependencies(${ut} ${sub})
- add_dependencies(${ut} ${t})
- else()
- c4_set_proj_prop(${ut}_subtargets ${t})
- endif()
- endif()
- endif()
-endfunction()
-
-
-
-function(c4_download_file url dstpath)
- c4_dbg("downloading file: ${url} ---> ${dstpath}")
- get_filename_component(abspath ${dstpath} ABSOLUTE)
- if(NOT EXISTS ${abspath})
- c4_dbg("downloading file: does not exist: ${dstpath}")
- file(DOWNLOAD ${url} ${abspath} LOG dl_log STATUS status ${ARGN})
- if((NOT (status EQUAL 0)) OR (NOT EXISTS ${abspath}))
- c4_err("error downloading file: ${url} -> ${abspath}:\n${dl_log}")
- endif()
- endif()
-endfunction()
-
-
-#------------------------------------------------------------------------------
-#------------------------------------------------------------------------------
-#------------------------------------------------------------------------------
-function(c4_setup_benchmarking)
- c4_log("enabling benchmarks: to build, ${_c4_lprefix}bm-build")
- c4_log("enabling benchmarks: to run, ${_c4_lprefix}bm-run")
- # umbrella target for building test binaries
- add_custom_target(${_c4_lprefix}bm-build)
- # umbrella target for running benchmarks
- add_custom_target(${_c4_lprefix}bm-run
- ${CMAKE_COMMAND} -E echo CWD=${CMAKE_CURRENT_BINARY_DIR}
- DEPENDS ${_c4_lprefix}bm-build
- )
- if(NOT TARGET bm-run)
- add_custom_target(bm-run)
- add_custom_target(bm-build)
- endif()
- add_dependencies(bm-run ${_c4_lprefix}bm-run)
- add_dependencies(bm-build ${_c4_lprefix}bm-build)
- _c4_set_target_folder(${_c4_lprefix}bm-run bm)
- _c4_set_target_folder(${_c4_lprefix}bm-build bm)
- _c4_set_target_folder(bm-build "/bm")
- _c4_set_target_folder(bm-run "/bm")
- # download google benchmark
- if(NOT TARGET benchmark)
- c4_import_remote_proj(googlebenchmark ${CMAKE_CURRENT_BINARY_DIR}/ext/googlebenchmark
- REMOTE
- GIT_REPOSITORY https://github.com/google/benchmark.git
- GIT_TAG main GIT_SHALLOW ON
- OVERRIDE
- BENCHMARK_ENABLE_TESTING OFF
- BENCHMARK_ENABLE_EXCEPTIONS OFF
- BENCHMARK_ENABLE_LTO OFF
- SET_FOLDER_TARGETS ext benchmark benchmark_main
- EXCLUDE_FROM_ALL
- )
- #
- if((CMAKE_CXX_COMPILER_ID STREQUAL GNU) OR (CMAKE_COMPILER_IS_GNUCC))
- target_compile_options(benchmark PRIVATE -Wno-deprecated-declarations)
- target_compile_options(benchmark PRIVATE -Wno-restrict)
- endif()
- #
- if(NOT WIN32)
- option(${_c4_uprefix}BENCHMARK_CPUPOWER
- "set the cpu mode to performance before / powersave after the benchmark" OFF)
- if(${_c4_uprefix}BENCHMARK_CPUPOWER)
- find_program(C4_SUDO sudo)
- find_program(C4_CPUPOWER cpupower)
- endif()
- endif()
- endif()
-endfunction()
-
-
-function(c4_add_benchmark_cmd casename)
- add_custom_target(${casename}
- COMMAND ${ARGN}
- VERBATIM
- COMMENT "${_c4_prefix}: running benchmark ${casename}: ${ARGN}")
- add_dependencies(${_c4_lprefix}bm-build ${casename})
- _c4_set_target_folder(${casename} bm)
-endfunction()
-
-
-# assumes this is a googlebenchmark target, and that multiple
-# benchmarks are defined from it
-function(c4_add_target_benchmark target casename)
- set(opt0arg
- )
- set(opt1arg
- WORKDIR # working directory
- FILTER # benchmark patterns to filter
- UMBRELLA_TARGET
- RESULTS_FILE
- )
- set(optnarg
- ARGS
- )
- cmake_parse_arguments("" "${opt0arg}" "${opt1arg}" "${optnarg}" ${ARGN})
- #
- set(name "${target}-${casename}")
- set(rdir "${CMAKE_CURRENT_BINARY_DIR}/bm-results")
- set(rfile "${rdir}/${name}.json")
- if(_RESULTS_FILE)
- set(${_RESULTS_FILE} "${rfile}" PARENT_SCOPE)
- endif()
- if(NOT EXISTS "${rdir}")
- file(MAKE_DIRECTORY "${rdir}")
- endif()
- set(filter)
- if(NOT ("${_FILTER}" STREQUAL ""))
- set(filter "--benchmark_filter=${_FILTER}")
- endif()
- set(args_fwd ${filter} --benchmark_out_format=json --benchmark_out=${rfile} ${_ARGS})
- c4_add_benchmark(${target}
- "${name}"
- "${_WORKDIR}"
- "saving results in ${rfile}"
- ${args_fwd}
- OUTPUT_FILE ${rfile})
- if(_UMBRELLA_TARGET)
- add_dependencies(${_UMBRELLA_TARGET} "${name}")
- endif()
-endfunction()
-
-
-function(c4_add_benchmark target casename work_dir comment)
- set(opt0arg
- )
- set(opt1arg
- OUTPUT_FILE
- )
- set(optnarg
- )
- cmake_parse_arguments("" "${opt0arg}" "${opt1arg}" "${optnarg}" ${ARGN})
- if(NOT TARGET ${target})
- c4_err("target ${target} does not exist...")
- endif()
- if(NOT ("${work_dir}" STREQUAL ""))
- if(NOT EXISTS "${work_dir}")
- file(MAKE_DIRECTORY "${work_dir}")
- endif()
- endif()
- set(exe $<TARGET_FILE:${target}>)
- if(${_c4_uprefix}BENCHMARK_CPUPOWER)
- if(C4_BM_SUDO AND C4_BM_CPUPOWER)
- set(c ${C4_SUDO} ${C4_CPUPOWER} frequency-set --governor performance)
- set(cpupow_before
- COMMAND echo ${c}
- COMMAND ${c})
- set(c ${C4_SUDO} ${C4_CPUPOWER} frequency-set --governor powersave)
- set(cpupow_after
- COMMAND echo ${c}
- COMMAND ${c})
- endif()
- endif()
- if(_OUTPUT_FILE)
- set(_OUTPUT_FILE BYPRODUCTS ${_OUTPUT_FILE})
- set(_OUTPUT_FILE) # otherwise the benchmarks run everytime when building depending targets
- endif()
- add_custom_target(${casename}
- ${cpupow_before}
- # this is useful to show the target file (you cannot echo generator variables)
- #COMMAND ${CMAKE_COMMAND} -E echo "target file = $<TARGET_FILE:${target}>"
- COMMAND ${CMAKE_COMMAND} -E echo "${exe} ${ARGN}"
- COMMAND "${exe}" ${ARGN}
- ${cpupow_after}
- VERBATIM
- ${_OUTPUT_FILE}
- WORKING_DIRECTORY "${work_dir}"
- DEPENDS ${target}
- COMMENT "${_c4_lcprefix}: running benchmark ${target}, case ${casename}: ${comment}"
- )
- add_dependencies(${_c4_lprefix}bm-build ${target})
- add_dependencies(${_c4_lprefix}bm-run ${casename})
- _c4_set_target_folder(${casename} bm/run)
-endfunction()
-
-
-#------------------------------------------------------------------------------
-#------------------------------------------------------------------------------
-#------------------------------------------------------------------------------
-
-function(_c4cat_get_outname target id ext out)
- if("${_c4_lcprefix}" STREQUAL "${target}")
- set(p "${target}")
- else()
- set(p "${_c4_lcprefix}.${target}")
- endif()
- set(${out} "${CMAKE_CURRENT_BINARY_DIR}/${p}.${id}.${ext}" PARENT_SCOPE)
-endfunction()
-
-function(_c4cat_filter_srcs in out)
- _c4cat_filter_extensions("${in}" "${C4_SRC_EXTS}" l)
- set(${out} ${l} PARENT_SCOPE)
-endfunction()
-
-function(_c4cat_filter_hdrs in out)
- _c4cat_filter_extensions("${in}" "${C4_HDR_EXTS}" l)
- set(${out} ${l} PARENT_SCOPE)
-endfunction()
-
-function(_c4cat_filter_srcs_hdrs in out)
- _c4cat_filter_extensions("${in}" "${C4_HDR_EXTS};${C4_SRC_EXTS}" l)
- set(${out} ${l} PARENT_SCOPE)
-endfunction()
-
-function(_c4cat_filter_additional_exts in out)
- _c4cat_filter_extensions("${in}" "${C4_ADD_EXTS}" l)
- set(${out} ${l} PARENT_SCOPE)
-endfunction()
-
-function(_c4cat_filter_extensions in filter out)
- set(l)
- foreach(fn ${in}) # don't quote the list here
- _c4cat_get_file_ext("${fn}" ext)
- _c4cat_one_of("${ext}" "${filter}" yes)
- if(${yes})
- list(APPEND l "${fn}")
- endif()
- endforeach()
- set(${out} "${l}" PARENT_SCOPE)
-endfunction()
-
-function(_c4cat_get_file_ext in out)
- # https://stackoverflow.com/questions/30049180/strip-filename-shortest-extension-by-cmake-get-filename-removing-the-last-ext
- string(REGEX MATCH "^.*\\.([^.]*)$" dummy ${in})
- set(${out} ${CMAKE_MATCH_1} PARENT_SCOPE)
-endfunction()
-
-function(_c4cat_one_of ext candidates out)
- foreach(e ${candidates})
- if("${ext}" STREQUAL "${e}")
- set(${out} TRUE PARENT_SCOPE)
- return()
- endif()
- endforeach()
- set(${out} FALSE PARENT_SCOPE)
-endfunction()
-
-
-#------------------------------------------------------------------------------
-#------------------------------------------------------------------------------
-#------------------------------------------------------------------------------
-
-# given a list of source files, return a list with full paths
-function(c4_to_full_path source_list source_list_with_full_paths)
- set(l)
- foreach(f ${source_list})
- if(IS_ABSOLUTE "${f}")
- list(APPEND l "${f}")
- else()
- list(APPEND l "${CMAKE_CURRENT_SOURCE_DIR}/${f}")
- endif()
- endforeach()
- set(${source_list_with_full_paths} ${l} PARENT_SCOPE)
-endfunction()
-
-
-# convert a list to a string separated with spaces
-function(c4_separate_list input_list output_string)
- set(s)
- foreach(e ${input_list})
- set(s "${s} ${e}")
- endforeach()
- set(${output_string} ${s} PARENT_SCOPE)
-endfunction()
-
-
-
-#------------------------------------------------------------------------------
-#------------------------------------------------------------------------------
-#------------------------------------------------------------------------------
-endif(NOT _c4_project_included)
diff --git a/thirdparty/ryml/ext/c4core/cmake/c4SanitizeTarget.cmake b/thirdparty/ryml/ext/c4core/cmake/c4SanitizeTarget.cmake
deleted file mode 100644
index a064f91ee..000000000
--- a/thirdparty/ryml/ext/c4core/cmake/c4SanitizeTarget.cmake
+++ /dev/null
@@ -1,292 +0,0 @@
-# (C) 2017 Joao Paulo Magalhaes <[email protected]>
-if(NOT _c4_sanitize_target_included)
-set(_c4_sanitize_target_included ON)
-
-include(CMakeDependentOption)
-include(PrintVar)
-
-function(_c4_default_if_not_set var dft)
- if("${${var}}" STREQUAL "")
- option(${var} "" ${dft})
- endif()
-endfunction()
-
-
-#------------------------------------------------------------------------------
-function(c4_setup_sanitize umbrella_option)
- if("${CMAKE_BUILD_TYPE}" STREQUAL "Coverage")
- return()
- endif()
- if(NOT ((CMAKE_CXX_COMPILER_ID MATCHES ".*Clang") OR (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")))
- return()
- endif()
-
- _c4_default_if_not_set(C4_SANITIZE ON)
- _c4_default_if_not_set(C4_SANITIZE_ONLY OFF)
- _c4_default_if_not_set(C4_ASAN ON)
- _c4_default_if_not_set(C4_TSAN ON)
- _c4_default_if_not_set(C4_MSAN ON)
- _c4_default_if_not_set(C4_UBSAN ON)
-
- cmake_dependent_option(${_c4_uprefix}SANITIZE "turn on clang sanitizer targets" ${C4_SANITIZE} ${umbrella_option} OFF)
- cmake_dependent_option(${_c4_uprefix}SANITIZE_ONLY "compile only sanitize targets (not the regular unsanitized targets)" ${C4_SANITIZE_ONLY} ${umbrella_option} OFF)
-
- # options for individual sanitizers - contingent on sanitize on/off
- cmake_dependent_option(${_c4_uprefix}ASAN "" ${C4_ASAN} "${_c4_uprefix}SANITIZE" OFF)
- cmake_dependent_option(${_c4_uprefix}TSAN "" ${C4_TSAN} "${_c4_uprefix}SANITIZE" OFF)
- cmake_dependent_option(${_c4_uprefix}MSAN "" ${C4_MSAN} "${_c4_uprefix}SANITIZE" OFF)
- cmake_dependent_option(${_c4_uprefix}UBSAN "" ${C4_UBSAN} "${_c4_uprefix}SANITIZE" OFF)
-
- if(${_c4_uprefix}SANITIZE)
- string(REGEX REPLACE "([0-9]+\\.[0-9]+).*" "\\1" LLVM_VERSION "${CMAKE_CXX_COMPILER_VERSION}")
- find_program(LLVM_SYMBOLIZER llvm-symbolizer
- NAMES llvm-symbolizer-${LLVM_VERSION} llvm-symbolizer
- DOC "symbolizer to use in sanitize tools")
- if(NOT LLVM_SYMBOLIZER)
- string(REGEX REPLACE "([0-9]+)\\.[0-9]+.*" "\\1" LLVM_VERSION "${CMAKE_CXX_COMPILER_VERSION}")
- find_program(LLVM_SYMBOLIZER llvm-symbolizer
- NAMES llvm-symbolizer-${LLVM_VERSION} llvm-symbolizer
- DOC "symbolizer to use in sanitize tools")
- if(NOT LLVM_SYMBOLIZER)
- message(FATAL_ERROR "could not find symbolizer. LLVM_VERSION=${LLVM_VERSION}")
- endif()
- endif()
-
- set(ss) # string to report enabled sanitizers
-
- if(${_c4_uprefix}ASAN)
- set(ss "asan")
- set(${_c4_uprefix}ASAN_CFLAGS "-O1 -g -fsanitize=address -fno-omit-frame-pointer -fno-optimize-sibling-calls" CACHE STRING "compile flags for clang address sanitizer: https://clang.llvm.org/docs/AddressSanitizer.html")
- set(${_c4_uprefix}ASAN_LFLAGS "-g -fsanitize=address" CACHE STRING "linker flags for clang address sanitizer: https://clang.llvm.org/docs/AddressSanitizer.html")
- set(${_c4_uprefix}ASAN_RENV "env ASAN_SYMBOLIZER_PATH=${LLVM_SYMBOLIZER} ASAN_OPTIONS=symbolize=1" CACHE STRING "run environment for clang address sanitizer: https://clang.llvm.org/docs/AddressSanitizer.html")
- # the flags are strings; we need to separate them into a list
- # to prevent cmake from quoting them when passing to the targets
- separate_arguments(${_c4_uprefix}ASAN_CFLAGS_SEP UNIX_COMMAND ${${_c4_uprefix}ASAN_CFLAGS})
- separate_arguments(${_c4_uprefix}ASAN_LFLAGS_SEP UNIX_COMMAND ${${_c4_uprefix}ASAN_LFLAGS})
- endif()
-
- if(${_c4_uprefix}TSAN)
- set(ss "${ss} tsan")
- set(${_c4_uprefix}TSAN_CFLAGS "-O1 -g -fsanitize=thread -fno-omit-frame-pointer" CACHE STRING "compile flags for clang thread sanitizer: https://clang.llvm.org/docs/ThreadSanitizer.html")
- set(${_c4_uprefix}TSAN_LFLAGS "-g -fsanitize=thread" CACHE STRING "linker flags for clang thread sanitizer: https://clang.llvm.org/docs/ThreadSanitizer.html")
- set(${_c4_uprefix}TSAN_RENV "env TSAN_SYMBOLIZER_PATH=${LLVM_SYMBOLIZER} TSAN_OPTIONS=symbolize=1" CACHE STRING "run environment for clang thread sanitizer: https://clang.llvm.org/docs/ThreadSanitizer.html")
- separate_arguments(${_c4_uprefix}TSAN_CFLAGS_SEP UNIX_COMMAND ${${_c4_uprefix}TSAN_CFLAGS})
- separate_arguments(${_c4_uprefix}TSAN_LFLAGS_SEP UNIX_COMMAND ${${_c4_uprefix}TSAN_LFLAGS})
- endif()
-
- if(${_c4_uprefix}MSAN)
- set(ss "${ss} msan")
- set(${_c4_uprefix}MSAN_CFLAGS "-O1 -g -fsanitize=memory -fsanitize-memory-track-origins -fno-omit-frame-pointer -fno-optimize-sibling-calls" CACHE STRING "compile flags for clang memory sanitizer: https://clang.llvm.org/docs/MemorySanitizer.html")
- set(${_c4_uprefix}MSAN_LFLAGS "-g -fsanitize=memory" CACHE STRING "linker flags for clang memory sanitizer: https://clang.llvm.org/docs/MemorySanitizer.html")
- set(${_c4_uprefix}MSAN_RENV "env MSAN_SYMBOLIZER_PATH=${LLVM_SYMBOLIZER} MSAN_OPTIONS=symbolize=1" CACHE STRING "run environment for clang memory sanitizer: https://clang.llvm.org/docs/MemorySanitizer.html")
- separate_arguments(${_c4_uprefix}MSAN_CFLAGS_SEP UNIX_COMMAND ${${_c4_uprefix}MSAN_CFLAGS})
- separate_arguments(${_c4_uprefix}MSAN_LFLAGS_SEP UNIX_COMMAND ${${_c4_uprefix}MSAN_LFLAGS})
- endif()
-
- if(${_c4_uprefix}UBSAN)
- set(ss "${ss} ubsan")
- set(${_c4_uprefix}UBSAN_CFLAGS "-g -fsanitize=undefined" CACHE STRING "compile flags for clang undefined behaviour sanitizer: https://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html")
- set(${_c4_uprefix}UBSAN_LFLAGS "-g -fsanitize=undefined" CACHE STRING "linker flags for clang undefined behaviour sanitizer: https://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html")
- set(${_c4_uprefix}UBSAN_RENV "env UBSAN_SYMBOLIZER_PATH=${LLVM_SYMBOLIZER} UBSAN_OPTIONS='symbolize=1 print_stacktrace=1'" CACHE STRING "run environment for clang undefined behaviour sanitizer: https://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html")
- separate_arguments(${_c4_uprefix}UBSAN_CFLAGS_SEP UNIX_COMMAND ${${_c4_uprefix}UBSAN_CFLAGS})
- separate_arguments(${_c4_uprefix}UBSAN_LFLAGS_SEP UNIX_COMMAND ${${_c4_uprefix}UBSAN_LFLAGS})
- endif()
-
- c4_dbg("enabled clang sanitizers: ${ss}")
- endif() # ${_c4_uprefix}SANITIZE
-
-endfunction()
-
-
-#------------------------------------------------------------------------------
-function(c4_sanitize_get_target_command name which_sanitizer_ output)
- string(TOUPPER ${which_sanitizer_} which_sanitizer)
- if("${which_sanitizer}" STREQUAL ASAN)
- elseif("${which_sanitizer}" STREQUAL TSAN)
- elseif("${which_sanitizer}" STREQUAL MSAN)
- elseif("${which_sanitizer}" STREQUAL UBSAN)
- else()
- message(FATAL_ERROR "the sanitizer must be one of: ASAN, TSAN, MSAN, UBSAN")
- endif()
- separate_arguments(cmd UNIX_COMMAND "${${_c4_uprefix}${which_sanitizer}_RENV} ${name}")
- set(${output} ${cmd} PARENT_SCOPE)
-endfunction()
-
-function(_sanitize_set_target_folder tgt folder)
- if(folder)
- set_target_properties(${tgt} PROPERTIES FOLDER "${folder}")
- endif()
-endfunction()
-
-
-#------------------------------------------------------------------------------
-function(c4_sanitize_target name)
- set(opt0arg
- LIBRARY
- EXECUTABLE
- )
- set(opt1arg
- OUTPUT_TARGET_NAMES
- FOLDER
- )
- set(optnarg
- SOURCES
- INC_DIRS # TODO public, interface, private
- LIBS # TODO public, interface, private
- LIB_DIRS # TODO public, interface, private
- DEFS # TODO public, interface, private
- CFLAGS # TODO public, interface, private
- )
- cmake_parse_arguments("" "${opt0arg}" "${opt1arg}" "${optnarg}" ${ARGN})
-
- if((NOT _LIBRARY) AND (NOT _EXECUTABLE))
- c4_err("either LIBRARY or EXECUTABLE must be specified")
- endif()
-
- if(${_c4_uprefix}SANITIZE AND NOT TARGET ${_c4_lprefix}sanitize)
- add_custom_target(${_c4_lprefix}sanitize)
- _sanitize_set_target_folder(${_c4_lprefix}sanitize "${_FOLDER}")
- endif()
- if(${_c4_uprefix}ASAN AND NOT TARGET ${_c4_lprefix}asan-all)
- add_custom_target(${_c4_lprefix}asan-all)
- add_dependencies(${_c4_lprefix}sanitize ${_c4_lprefix}asan-all)
- _sanitize_set_target_folder(${_c4_lprefix}asan-all "${_FOLDER}")
- endif()
- if(${_c4_uprefix}MSAN AND NOT TARGET ${_c4_lprefix}msan-all)
- add_custom_target(${_c4_lprefix}msan-all)
- add_dependencies(${_c4_lprefix}sanitize ${_c4_lprefix}msan-all)
- _sanitize_set_target_folder(${_c4_lprefix}msan-all "${_FOLDER}")
- endif()
- if(${_c4_uprefix}TSAN AND NOT TARGET ${_c4_lprefix}tsan-all)
- add_custom_target(${_c4_lprefix}tsan-all)
- add_dependencies(${_c4_lprefix}sanitize ${_c4_lprefix}tsan-all)
- _sanitize_set_target_folder(${_c4_lprefix}tsan-all "${_FOLDER}")
- endif()
- if(${_c4_uprefix}UBSAN AND NOT TARGET ${_c4_lprefix}ubsan-all)
- add_custom_target(${_c4_lprefix}ubsan-all)
- add_dependencies(${_c4_lprefix}sanitize ${_c4_lprefix}ubsan-all)
- _sanitize_set_target_folder(${_c4_lprefix}ubsan-all "${_FOLDER}")
- endif()
-
- if(${_c4_uprefix}ASAN OR ${_c4_uprefix}MSAN OR ${_c4_uprefix}TSAN OR ${_c4_uprefix}UBSAN)
- add_custom_target(${name}-sanitize-all)
- _sanitize_set_target_folder(${name}-sanitize-all "${_FOLDER}")
- endif()
-
- set(targets)
-
- # https://clang.llvm.org/docs/AddressSanitizer.html
- if(${_c4_uprefix}ASAN)
- if(${_LIBRARY})
- add_library(${name}-asan EXCLUDE_FROM_ALL ${_SOURCES})
- elseif(${_EXECUTABLE})
- add_executable(${name}-asan EXCLUDE_FROM_ALL ${_SOURCES})
- endif()
- _sanitize_set_target_folder(${name}-asan "${_FOLDER}")
- list(APPEND targets ${name}-asan)
- target_include_directories(${name}-asan PUBLIC ${_INC_DIRS})
- set(_real_libs)
- foreach(_l ${_LIBS})
- if(TARGET ${_l}-asan)
- list(APPEND _real_libs ${_l}-asan)
- else()
- list(APPEND _real_libs ${_l})
- endif()
- endforeach()
- target_link_libraries(${name}-asan PUBLIC ${_real_libs})
- target_compile_definitions(${name}-asan PUBLIC ${_DEFS})
- target_compile_options(${name}-asan PUBLIC ${_CFLAGS} ${${_c4_uprefix}ASAN_CFLAGS_SEP})
- # http://stackoverflow.com/questions/25043458/does-cmake-have-something-like-target-link-options
- target_link_libraries(${name}-asan PUBLIC ${${_c4_uprefix}ASAN_LFLAGS_SEP})
- add_dependencies(${_c4_lprefix}asan-all ${name}-asan)
- add_dependencies(${name}-sanitize-all ${name}-asan)
- endif()
-
- # https://clang.llvm.org/docs/ThreadSanitizer.html
- if(${_c4_uprefix}TSAN)
- if(${_LIBRARY})
- add_library(${name}-tsan EXCLUDE_FROM_ALL ${_SOURCES})
- elseif(${_EXECUTABLE})
- add_executable(${name}-tsan EXCLUDE_FROM_ALL ${_SOURCES})
- endif()
- _sanitize_set_target_folder(${name}-tsan "${_FOLDER}")
- list(APPEND targets ${name}-tsan)
- target_include_directories(${name}-tsan PUBLIC ${_INC_DIRS})
- set(_real_libs)
- foreach(_l ${_LIBS})
- if(TARGET ${_l}-tsan)
- list(APPEND _real_libs ${_l}-tsan)
- else()
- list(APPEND _real_libs ${_l})
- endif()
- endforeach()
- target_link_libraries(${name}-tsan PUBLIC ${_real_libs})
- target_compile_definitions(${name}-tsan PUBLIC ${_DEFS})
- target_compile_options(${name}-tsan PUBLIC ${_CFLAGS} ${${_c4_uprefix}TSAN_CFLAGS_SEP})
- # http://stackoverflow.com/questions/25043458/does-cmake-have-something-like-target-link-options
- target_link_libraries(${name}-tsan PUBLIC ${${_c4_uprefix}TSAN_LFLAGS_SEP})
- add_dependencies(${_c4_lprefix}tsan-all ${name}-tsan)
- add_dependencies(${name}-sanitize-all ${name}-tsan)
- endif()
-
- # https://clang.llvm.org/docs/MemorySanitizer.html
- if(${_c4_uprefix}MSAN)
- if(${_LIBRARY})
- add_library(${name}-msan EXCLUDE_FROM_ALL ${_SOURCES})
- elseif(${_EXECUTABLE})
- add_executable(${name}-msan EXCLUDE_FROM_ALL ${_SOURCES})
- endif()
- _sanitize_set_target_folder(${name}-msan "${_FOLDER}")
- list(APPEND targets ${name}-msan)
- target_include_directories(${name}-msan PUBLIC ${_INC_DIRS})
- set(_real_libs)
- foreach(_l ${_LIBS})
- if(TARGET ${_l}-msan)
- list(APPEND _real_libs ${_l}-msan)
- else()
- list(APPEND _real_libs ${_l})
- endif()
- endforeach()
- target_link_libraries(${name}-msan PUBLIC ${_real_libs})
- target_compile_definitions(${name}-msan PUBLIC ${_DEFS})
- target_compile_options(${name}-msan PUBLIC ${_CFLAGS} ${${_c4_uprefix}MSAN_CFLAGS_SEP})
- # http://stackoverflow.com/questions/25043458/does-cmake-have-something-like-target-link-options
- target_link_libraries(${name}-msan PUBLIC ${${_c4_uprefix}MSAN_LFLAGS_SEP})
- add_dependencies(${_c4_lprefix}msan-all ${name}-msan)
- add_dependencies(${name}-sanitize-all ${name}-msan)
- endif()
-
- # https://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html
- if(${_c4_uprefix}UBSAN)
- if(${_LIBRARY})
- add_library(${name}-ubsan EXCLUDE_FROM_ALL ${_SOURCES})
- elseif(${_EXECUTABLE})
- add_executable(${name}-ubsan EXCLUDE_FROM_ALL ${_SOURCES})
- endif()
- _sanitize_set_target_folder(${name}-ubsan "${_FOLDER}")
- list(APPEND targets ${name}-ubsan)
- target_include_directories(${name}-ubsan PUBLIC ${_INC_DIRS})
- set(_real_libs)
- foreach(_l ${_LIBS})
- if(TARGET ${_l}-ubsan)
- list(APPEND _real_libs ${_l}-ubsan)
- else()
- list(APPEND _real_libs ${_l})
- endif()
- endforeach()
- target_link_libraries(${name}-ubsan PUBLIC ${_real_libs})
- target_compile_definitions(${name}-ubsan PUBLIC ${_DEFS})
- target_compile_options(${name}-ubsan PUBLIC ${_CFLAGS} ${${_c4_uprefix}UBSAN_CFLAGS_SEP})
- # http://stackoverflow.com/questions/25043458/does-cmake-have-something-like-target-link-options
- target_link_libraries(${name}-ubsan PUBLIC ${${_c4_uprefix}UBSAN_LFLAGS_SEP})
- add_dependencies(${_c4_lprefix}ubsan-all ${name}-ubsan)
- add_dependencies(${name}-sanitize-all ${name}-ubsan)
- endif()
-
- if(_OUTPUT_TARGET_NAMES)
- set(${_OUTPUT_TARGET_NAMES} ${targets} PARENT_SCOPE)
- endif()
-endfunction()
-
-
-endif(NOT _c4_sanitize_target_included)
diff --git a/thirdparty/ryml/ext/c4core/cmake/c4StaticAnalysis.cmake b/thirdparty/ryml/ext/c4core/cmake/c4StaticAnalysis.cmake
deleted file mode 100644
index 06de5ca2f..000000000
--- a/thirdparty/ryml/ext/c4core/cmake/c4StaticAnalysis.cmake
+++ /dev/null
@@ -1,154 +0,0 @@
-include(PVS-Studio)
-include(GetFlags)
-include(c4GetTargetPropertyRecursive)
-
-
-function(_c4sta_default_if_not_set var dft)
- if("${${var}}" STREQUAL "")
- set(${var} "${dft}" PARENT_SCOPE)
- endif()
-endfunction()
-
-
-function(c4_setup_static_analysis umbrella_option)
- if(WIN32)
- c4_dbg("no static analyzer available in WIN32")
- return()
- endif()
- if("${CMAKE_BUILD_TYPE}" STREQUAL "Coverage")
- c4_dbg("Coverage build: disabling static analyzers")
- return()
- endif()
- _c4sta_default_if_not_set(C4_LINT ${umbrella_option})
- _c4sta_default_if_not_set(C4_LINT_TESTS ${umbrella_option})
- _c4sta_default_if_not_set(C4_LINT_CLANG_TIDY ${umbrella_option})
- _c4sta_default_if_not_set(C4_LINT_PVS_STUDIO OFF)
- # option to turn lints on/off
- cmake_dependent_option(${_c4_uprefix}LINT "add static analyzer targets" ${C4_LINT} ${umbrella_option} OFF)
- cmake_dependent_option(${_c4_uprefix}LINT_TESTS "add tests to run static analyzer targets" ${C4_LINT_TESTS} ${umbrella_option} OFF)
- # options for individual lints - contingent on linting on/off
- cmake_dependent_option(${_c4_uprefix}LINT_CLANG_TIDY "use the clang-tidy static analyzer" ${C4_LINT_CLANG_TIDY} "${_c4_uprefix}LINT" ON)
- cmake_dependent_option(${_c4_uprefix}LINT_PVS_STUDIO "use the PVS-Studio static analyzer https://www.viva64.com/en/b/0457/" ${C4_LINT_PVS_STUDIO} "${_c4_uprefix}LINT" OFF)
- if(${_c4_uprefix}LINT_CLANG_TIDY)
- find_program(CLANG_TIDY clang-tidy)
- endif()
- if(${_c4_uprefix}LINT_PVS_STUDIO)
- set(${_c4_uprefix}LINT_PVS_STUDIO_FORMAT "errorfile" CACHE STRING "PVS-Studio output format. Choices: xml,csv,errorfile(like gcc/clang),tasklist(qtcreator)")
- endif()
- #
- set(sa)
- if(${_c4_uprefix}LINT_CLANG_TIDY)
- set(sa "clang_tidy")
- endif()
- if(${_c4_uprefix}LINT_PVS_STUDIO)
- set(sa "${sa} PVS-Studio")
- endif()
- if(sa)
- c4_dbg("enabled static analyzers: ${sa}")
- endif()
-endfunction()
-
-
-function(c4_static_analysis_target target_name folder generated_targets)
- set(any_linter OFF)
- if(${_c4_uprefix}LINT_CLANG_TIDY OR ${_c4_uprefix}LINT_PVS_STUDIO)
- set(any_linter ON)
- endif()
- if(${_c4_uprefix}LINT AND any_linter)
- # umbrella target for running all linters for this particular target
- if(any_linter AND NOT TARGET ${_c4_lprefix}lint-all)
- add_custom_target(${_c4_lprefix}lint-all)
- if(folder)
- #message(STATUS "${target_name}: folder=${folder}")
- set_target_properties(${_c4_lprefix}lint-all PROPERTIES FOLDER "${folder}")
- endif()
- endif()
- if(${_c4_uprefix}LINT_CLANG_TIDY)
- c4_static_analysis_clang_tidy(${target_name}
- ${target_name}-lint-clang_tidy
- ${_c4_lprefix}lint-all-clang_tidy
- "${folder}")
- list(APPEND ${generated_targets} ${_c4_lprefix}lint-clang_tidy)
- add_dependencies(${_c4_lprefix}lint-all ${_c4_lprefix}lint-all-clang_tidy)
- endif()
- if(${_c4_uprefix}LINT_PVS_STUDIO)
- c4_static_analysis_pvs_studio(${target_name}
- ${target_name}-lint-pvs_studio
- ${_c4_lprefix}lint-all-pvs_studio
- "${folder}")
- list(APPEND ${generated_targets} ${_c4_lprefix}lint-pvs_studio)
- add_dependencies(${_c4_lprefix}lint-all ${_c4_lprefix}lint-all-pvs_studio)
- endif()
- endif()
-endfunction()
-
-
-function(c4_static_analysis_add_tests target_name)
- if(${_c4_uprefix}LINT_CLANG_TIDY AND ${_c4_uprefix}LINT_TESTS)
- add_test(NAME ${target_name}-lint-clang_tidy-run
- COMMAND
- ${CMAKE_COMMAND} --build ${CMAKE_CURRENT_BINARY_DIR} --target ${target_name}-lint-clang_tidy)
- endif()
- if(${_c4_uprefix}LINT_PVS_STUDIO AND ${_c4_uprefix}LINT_TESTS)
- add_test(NAME ${target_name}-lint-pvs_studio-run
- COMMAND
- ${CMAKE_COMMAND} --build ${CMAKE_CURRENT_BINARY_DIR} --target ${target_name}-lint-pvs_studio)
- endif()
-endfunction()
-
-
-#------------------------------------------------------------------------------
-function(c4_static_analysis_clang_tidy subj_target lint_target umbrella_target folder)
- c4_static_analysis_clang_tidy_get_cmd(${subj_target} ${lint_target} cmd)
- string(REPLACE ";" " " cmd_str "${cmd}")
- add_custom_target(${lint_target}
- COMMAND ${CMAKE_COMMAND} -E echo "cd ${CMAKE_CURRENT_SOURCE_DIR} ; ${cmd_str}"
- COMMAND ${cmd}
- VERBATIM
- COMMENT "clang-tidy: analyzing sources of ${subj_target}"
- WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
- if(folder)
- set_target_properties(${lint_target} PROPERTIES FOLDER "${folder}")
- endif()
- if(NOT TARGET ${umbrella_target})
- add_custom_target(${umbrella_target})
- endif()
- add_dependencies(${umbrella_target} ${lint_target})
-endfunction()
-
-function(c4_static_analysis_clang_tidy_get_cmd subj_target lint_target cmd)
- get_target_property(_clt_all_srcs ${subj_target} SOURCES)
- _c4cat_filter_srcs_hdrs("${_clt_all_srcs}" _clt_srcs)
- set(result "${CLANG_TIDY}" -p ${CMAKE_BINARY_DIR} --header-filter=.* ${_clt_srcs})
- set(${cmd} ${result} PARENT_SCOPE)
-endfunction()
-
-
-#------------------------------------------------------------------------------
-function(c4_static_analysis_pvs_studio subj_target lint_target umbrella_target folder)
- c4_get_target_property_recursive(_c4al_pvs_incs ${subj_target} INCLUDE_DIRECTORIES)
- c4_get_include_flags(_c4al_pvs_incs ${_c4al_pvs_incs})
- separate_arguments(_c4al_cxx_flags_sep UNIX_COMMAND "${CMAKE_CXX_FLAGS} ${_c4al_pvs_incs}")
- separate_arguments(_c4al_c_flags_sep UNIX_COMMAND "${CMAKE_C_FLAGS} ${_c4al_pvs_incs}")
- pvs_studio_add_target(TARGET ${lint_target}
- ALL # indicates that the analysis starts when you build the project
- #PREPROCESSOR ${_c4al_preproc}
- FORMAT tasklist
- LOG "${CMAKE_CURRENT_BINARY_DIR}/${subj_target}.pvs-analysis.tasks"
- ANALYZE ${name} #main_target subtarget:path/to/subtarget
- CXX_FLAGS ${_c4al_cxx_flags_sep}
- C_FLAGS ${_c4al_c_flags_sep}
- #CONFIG "/path/to/PVS-Studio.cfg"
- )
- if(folder)
- set_target_properties(${lint_target} PROPERTIES FOLDER "${folder}")
- endif()
- if(NOT TARGET ${umbrella_target})
- add_custom_target(${umbrella_target})
- endif()
- add_dependencies(${umbrella_target} ${lint_target})
-endfunction()
-
-function(c4_static_analysis_pvs_studio_get_cmd subj_target lint_target cmd)
- set(${cmd} $<RULE_LAUNCH_CUSTOM:${subj_target}> PARENT_SCOPE)
-endfunction()
diff --git a/thirdparty/ryml/ext/c4core/cmake/c4stlAddTarget.cmake b/thirdparty/ryml/ext/c4core/cmake/c4stlAddTarget.cmake
deleted file mode 100644
index 07835977b..000000000
--- a/thirdparty/ryml/ext/c4core/cmake/c4stlAddTarget.cmake
+++ /dev/null
@@ -1,5 +0,0 @@
-include(c4project)
-
-function(c4stl_add_target name)
- c4_add_target(c4stl ${name} ${ARGN})
-endfunction() # c4stl_add_target
diff --git a/thirdparty/ryml/ext/c4core/cmake/compat/c4/gcc-4.8.hpp b/thirdparty/ryml/ext/c4core/cmake/compat/c4/gcc-4.8.hpp
deleted file mode 100644
index 83cad6256..000000000
--- a/thirdparty/ryml/ext/c4core/cmake/compat/c4/gcc-4.8.hpp
+++ /dev/null
@@ -1,69 +0,0 @@
-#ifndef _C4_COMPAT_GCC_4_8_HPP_
-#define _C4_COMPAT_GCC_4_8_HPP_
-
-#if __GNUC__ == 4 && __GNUC_MINOR__ >= 8
-/* STL polyfills for old GNU compilers */
-
-_Pragma("GCC diagnostic ignored \"-Wshadow\"")
-_Pragma("GCC diagnostic ignored \"-Wmissing-field-initializers\"")
-
-#if __cplusplus
-#include <cstdint>
-#include <type_traits>
-
-namespace std {
-
-template<typename _Tp>
-struct is_trivially_copyable : public integral_constant<bool,
- is_destructible<_Tp>::value && __has_trivial_destructor(_Tp) &&
- (__has_trivial_constructor(_Tp) || __has_trivial_copy(_Tp) || __has_trivial_assign(_Tp))>
-{ };
-
-template<typename _Tp>
-using is_trivially_copy_constructible = has_trivial_copy_constructor<_Tp>;
-
-template<typename _Tp>
-using is_trivially_default_constructible = has_trivial_default_constructor<_Tp>;
-
-template<typename _Tp>
-using is_trivially_copy_assignable = has_trivial_copy_assign<_Tp>;
-
-/* not supported */
-template<typename _Tp>
-struct is_trivially_move_constructible : false_type
-{ };
-
-/* not supported */
-template<typename _Tp>
-struct is_trivially_move_assignable : false_type
-{ };
-
-inline void *align(size_t __align, size_t __size, void*& __ptr, size_t& __space) noexcept
-{
- if (__space < __size)
- return nullptr;
- const auto __intptr = reinterpret_cast<uintptr_t>(__ptr);
- const auto __aligned = (__intptr - 1u + __align) & -__align;
- const auto __diff = __aligned - __intptr;
- if (__diff > (__space - __size))
- return nullptr;
- else
- {
- __space -= __diff;
- return __ptr = reinterpret_cast<void*>(__aligned);
- }
-}
-typedef long double max_align_t ;
-
-}
-#else // __cplusplus
-
-#include <string.h>
-// see https://sourceware.org/bugzilla/show_bug.cgi?id=25399 (ubuntu gcc-4.8)
-#define memset(s, c, count) __builtin_memset(s, c, count)
-
-#endif // __cplusplus
-
-#endif // __GNUC__ == 4 && __GNUC_MINOR__ >= 8
-
-#endif // _C4_COMPAT_GCC_4_8_HPP_
diff --git a/thirdparty/ryml/ext/c4core/cmake/compat/gtest_gcc-4.8.patch b/thirdparty/ryml/ext/c4core/cmake/compat/gtest_gcc-4.8.patch
deleted file mode 100644
index 07f0ca577..000000000
--- a/thirdparty/ryml/ext/c4core/cmake/compat/gtest_gcc-4.8.patch
+++ /dev/null
@@ -1,97 +0,0 @@
-Multi-line macros support is not guaranteed with gcc-4.8.
-
-This uses temporary objects to work-arround this limitation, main drawback is
-that compared code is not displayed in message anymore (only "val" placeholders).
-
---- googletest/include/gtest/gtest.h
-+++ googletest/include/gtest/gtest.h
-@@ -2040,6 +2040,80 @@ class TestWithParam : public Test, publi
- // ASSERT_LT(i, array_size);
- // ASSERT_GT(records.size(), 0) << "There is no record left.";
-
-+#if __GNUC__ == 4 && __GNUC_MINOR__ >= 8
-+/*
-+ * multi-line macros support is not guaranteed with gcc-4.8.
-+ * This uses temporary objects to work-arround this limitation, main drawback is
-+ * that compared code is not displayed in message anymore (only "val" placeholders)
-+ */
-+
-+enum class CompatExpectSelector { EQ, NE, LE, LT, GE, GT };
-+
-+template <CompatExpectSelector T>
-+struct CompatExpect
-+{
-+ const char *file;
-+ int line;
-+ ::testing::AssertionResult gtest_ar = AssertionSuccess();
-+ ::testing::Message msg;
-+
-+ CompatExpect(const char *file, int line) : file(file), line(line) {}
-+ ~CompatExpect() {
-+ if (!gtest_ar)
-+ GTEST_MESSAGE_AT_(file, line, gtest_ar.failure_message(), ::testing::TestPartResult::kNonFatalFailure) << msg;
-+ }
-+
-+ template <typename T1, typename T2, CompatExpectSelector SEL = T, typename std::enable_if<SEL == CompatExpectSelector::EQ, int>::type = 0>
-+ CompatExpect<T> &operator ()(const T1 &val1, const T2 &val2) {
-+ gtest_ar = ::testing::internal::EqHelper::Compare("val1", "val2", val1, val2);
-+ return *this;
-+ }
-+
-+ template <typename T1, typename T2, CompatExpectSelector SEL = T, typename std::enable_if<SEL == CompatExpectSelector::NE, int>::type = 0>
-+ CompatExpect<T> &operator ()(const T1 &val1, const T2 &val2) {
-+ gtest_ar = ::testing::internal::CmpHelperNE("val1", "val2", val1, val2);
-+ return *this;
-+ }
-+
-+ template <typename T1, typename T2, CompatExpectSelector SEL = T, typename std::enable_if<SEL == CompatExpectSelector::LE, int>::type = 0>
-+ CompatExpect<T> &operator ()(const T1 &val1, const T2 &val2) {
-+ gtest_ar = ::testing::internal::CmpHelperLE("val1", "val2", val1, val2);
-+ return *this;
-+ }
-+
-+ template <typename T1, typename T2, CompatExpectSelector SEL = T, typename std::enable_if<SEL == CompatExpectSelector::LT, int>::type = 0>
-+ CompatExpect<T> &operator ()(const T1 &val1, const T2 &val2) {
-+ gtest_ar = ::testing::internal::CmpHelperLT("val1", "val2", val1, val2);
-+ return *this;
-+ }
-+
-+ template <typename T1, typename T2, CompatExpectSelector SEL = T, typename std::enable_if<SEL == CompatExpectSelector::GE, int>::type = 0>
-+ CompatExpect<T> &operator ()(const T1 &val1, const T2 &val2) {
-+ gtest_ar = ::testing::internal::CmpHelperGE("val1", "val2", val1, val2);
-+ return *this;
-+ }
-+
-+ template <typename T1, typename T2, CompatExpectSelector SEL = T, typename std::enable_if<SEL == CompatExpectSelector::GT, int>::type = 0>
-+ CompatExpect<T> &operator ()(const T1 &val1, const T2 &val2) {
-+ gtest_ar = ::testing::internal::CmpHelperGT("val1", "val2", val1, val2);
-+ return *this;
-+ }
-+
-+ template <typename T1>
-+ CompatExpect &operator << (const T1 &t) {
-+ msg << t;
-+ return *this;
-+ }
-+};
-+#define EXPECT_EQ ::testing::CompatExpect<::testing::CompatExpectSelector::EQ>{__FILE__,__LINE__}
-+#define EXPECT_NE ::testing::CompatExpect<::testing::CompatExpectSelector::NE>{__FILE__,__LINE__}
-+#define EXPECT_LE ::testing::CompatExpect<::testing::CompatExpectSelector::LE>{__FILE__,__LINE__}
-+#define EXPECT_LT ::testing::CompatExpect<::testing::CompatExpectSelector::LT>{__FILE__,__LINE__}
-+#define EXPECT_GE ::testing::CompatExpect<::testing::CompatExpectSelector::GE>{__FILE__,__LINE__}
-+#define EXPECT_GT ::testing::CompatExpect<::testing::CompatExpectSelector::GT>{__FILE__,__LINE__}
-+
-+#else
-+
- #define EXPECT_EQ(val1, val2) \
- EXPECT_PRED_FORMAT2(::testing::internal::EqHelper::Compare, val1, val2)
- #define EXPECT_NE(val1, val2) \
-@@ -2053,6 +2127,8 @@ class TestWithParam : public Test, publi
- #define EXPECT_GT(val1, val2) \
- EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperGT, val1, val2)
-
-+#endif
-+
- #define GTEST_ASSERT_EQ(val1, val2) \
- ASSERT_PRED_FORMAT2(::testing::internal::EqHelper::Compare, val1, val2)
- #define GTEST_ASSERT_NE(val1, val2) \
diff --git a/thirdparty/ryml/ext/c4core/cmake/requirements_doc.txt b/thirdparty/ryml/ext/c4core/cmake/requirements_doc.txt
deleted file mode 100644
index baeb2ce4f..000000000
--- a/thirdparty/ryml/ext/c4core/cmake/requirements_doc.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-sphinx
-sphinx_rtd_theme
-breathe