Merge branch 'release-4.2'
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index f71b283..269b044 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -110,7 +110,7 @@
# NOTE See BUG https://github.com/crate-ci/typos/issues/390
- repo: https://github.com/adhtruong/mirrors-typos
- rev: v1.36.1
+ rev: v1.38.1
hooks:
- id: typos
# NOTE Override hook's default args to prevent automatic
diff --git a/.typos.toml b/.typos.toml
index 42cf331..db890af 100644
--- a/.typos.toml
+++ b/.typos.toml
@@ -20,6 +20,12 @@
# script accordingly.
#extend-ignore-identifiers-re=["\\b[0-9a-f]{8,12}\\b"]
+[default.extend-identifiers]
+_tru64 = "_tru64"
+__tru64 = "__tru64"
+__TRU64__ = "__TRU64__"
+Tru64 = "Tru64"
+
# Add repo-wide false positives here in the form of `word = "word"`.
# Check the manual for details.
[default.extend-words]
@@ -83,6 +89,9 @@
[type.py.extend-identifiers]
typ = "typ"
+[type.sh.extend-identifiers]
+xTRUEx = "xTRUEx"
+
[type.rst]
extend-ignore-re = [
# NOTE Allow to mark block of text to exclude from spellchecking as RST comments
diff --git a/Help/command/remove_definitions.rst b/Help/command/remove_definitions.rst
index faad16d..74730e5 100644
--- a/Help/command/remove_definitions.rst
+++ b/Help/command/remove_definitions.rst
@@ -1,11 +1,32 @@
remove_definitions
------------------
-Remove -D define flags added by :command:`add_definitions`.
+Removes compile definitions added by :command:`add_compile_definitions`, or
+:command:`add_definitions`:
.. code-block:: cmake
- remove_definitions(-DFOO -DBAR ...)
+ remove_definitions([<definitions>...])
-Removes flags (added by :command:`add_definitions`) from the compiler
-command line for sources in the current directory and below.
+The arguments are:
+
+``<definitions>...``
+ Zero or more compile definitions.
+
+This command can be also used to remove any flags added by
+:command:`add_definitions`, but it is intended to remove preprocessor
+definitions passed with ``-D``, or ``/D``.
+
+Examples
+^^^^^^^^
+
+In the following example targets of the current directory scope will have
+only ``BAZ`` and ``QUUX`` compile definitions:
+
+.. code-block:: cmake
+
+ add_compile_definitions(FOO BAR BAZ -DQUUX)
+
+ # ...
+
+ remove_definitions(-DFOO -DBAR)
diff --git a/Help/dev/source.rst b/Help/dev/source.rst
index d8de4e1..c36f334 100644
--- a/Help/dev/source.rst
+++ b/Help/dev/source.rst
@@ -111,7 +111,8 @@
``cm::shared_lock``
* ``<cm/type_traits>``:
- ``cm::enable_if_t``
+ ``cm::conditional_t``, ``cm::decay_t``, ``cm::enable_if_t``,
+ ``cm::remove_cv_t``, ``cm::remove_reference_t``
* ``<cm/unordered_map>``:
``cm::cbegin``, ``cm::cend``, ``cm::rbegin``, ``cm::rend``,
@@ -169,7 +170,7 @@
* ``<cm/type_traits>``:
``cm::bool_constant``, ``cm::invoke_result_t``, ``cm::invoke_result``,
- ``cm::void_t``
+ ``cm::is_same_v``, ``cm::void_t``
* ``<cm/unordered_map>``:
``cm::size``, ``cm::empty``, ``cm::data``
diff --git a/Help/manual/cmake-policies.7.rst b/Help/manual/cmake-policies.7.rst
index a477897..fd01048 100644
--- a/Help/manual/cmake-policies.7.rst
+++ b/Help/manual/cmake-policies.7.rst
@@ -34,10 +34,10 @@
.. code-block:: cmake
- cmake_minimum_required(VERSION 3.10...4.1)
+ cmake_minimum_required(VERSION 3.10...4.2)
This uses the ``<min>...<max>`` syntax to enable the ``NEW`` behaviors
-of policies introduced in CMake 4.1 and earlier while only requiring a
+of policies introduced in CMake 4.2 and earlier while only requiring a
minimum version of CMake 3.10. The project is expected to work with
both the ``OLD`` and ``NEW`` behaviors of policies introduced between
those versions.
diff --git a/Help/release/dev/0-sample-topic.rst b/Help/release/dev/0-sample-topic.rst
new file mode 100644
index 0000000..e4cc01e
--- /dev/null
+++ b/Help/release/dev/0-sample-topic.rst
@@ -0,0 +1,7 @@
+0-sample-topic
+--------------
+
+* This is a sample release note for the change in a topic.
+ Developers should add similar notes for each topic branch
+ making a noteworthy change. Each document should be named
+ and titled to match the topic name to avoid merge conflicts.
diff --git a/Help/release/dev/UseJava-include-modules.rst b/Help/release/dev/UseJava-include-modules.rst
new file mode 100644
index 0000000..a26e8ee
--- /dev/null
+++ b/Help/release/dev/UseJava-include-modules.rst
@@ -0,0 +1,7 @@
+UseJava-include-modules
+-----------------------
+
+* The :module:`UseJava` module's :command:`add_jar` command now accepts a new
+ option `INCLUDE_MODULES` that adds its arguments to the `--module-path`
+ argument to the Java compiler. This allows building JAR files that use JPMS
+ modules in their build.
diff --git a/Help/release/index.rst b/Help/release/index.rst
index 54190ee..edeab50 100644
--- a/Help/release/index.rst
+++ b/Help/release/index.rst
@@ -7,6 +7,8 @@
This file should include the adjacent "dev.txt" file
in development versions but not in release versions.
+.. include:: dev.txt
+
Releases
========
diff --git a/Modules/CPackIFW.cmake b/Modules/CPackIFW.cmake
index b114430..8826064 100644
--- a/Modules/CPackIFW.cmake
+++ b/Modules/CPackIFW.cmake
@@ -645,7 +645,7 @@
endmacro()
# Resolve full path to license file
-macro(_cpack_ifw_resolve_lisenses _variable)
+macro(_cpack_ifw_resolve_licenses _variable)
if(${_variable})
set(_ifw_license_file FALSE)
set(_ifw_licenses_fix)
@@ -689,7 +689,7 @@
cmake_parse_arguments(CPACK_IFW_COMPONENT_${_CPACK_IFWCOMP_UNAME} "${_IFW_OPT}" "${_IFW_ARGS}" "${_IFW_MULTI_ARGS}" ${ARGN})
_cpack_ifw_resolve_script(CPACK_IFW_COMPONENT_${_CPACK_IFWCOMP_UNAME}_SCRIPT)
- _cpack_ifw_resolve_lisenses(CPACK_IFW_COMPONENT_${_CPACK_IFWCOMP_UNAME}_LICENSES)
+ _cpack_ifw_resolve_licenses(CPACK_IFW_COMPONENT_${_CPACK_IFWCOMP_UNAME}_LICENSES)
_cpack_ifw_resolve_file_list(CPACK_IFW_COMPONENT_${_CPACK_IFWCOMP_UNAME}_USER_INTERFACES)
_cpack_ifw_resolve_file_list(CPACK_IFW_COMPONENT_${_CPACK_IFWCOMP_UNAME}_TRANSLATIONS)
@@ -730,7 +730,7 @@
cmake_parse_arguments(CPACK_IFW_COMPONENT_GROUP_${_CPACK_IFWGRP_UNAME} "${_IFW_OPT}" "${_IFW_ARGS}" "${_IFW_MULTI_ARGS}" ${ARGN})
_cpack_ifw_resolve_script(CPACK_IFW_COMPONENT_GROUP_${_CPACK_IFWGRP_UNAME}_SCRIPT)
- _cpack_ifw_resolve_lisenses(CPACK_IFW_COMPONENT_GROUP_${_CPACK_IFWGRP_UNAME}_LICENSES)
+ _cpack_ifw_resolve_licenses(CPACK_IFW_COMPONENT_GROUP_${_CPACK_IFWGRP_UNAME}_LICENSES)
_cpack_ifw_resolve_file_list(CPACK_IFW_COMPONENT_GROUP_${_CPACK_IFWGRP_UNAME}_USER_INTERFACES)
_cpack_ifw_resolve_file_list(CPACK_IFW_COMPONENT_GROUP_${_CPACK_IFWGRP_UNAME}_TRANSLATIONS)
diff --git a/Modules/CPackIFWConfigureFile.cmake b/Modules/CPackIFWConfigureFile.cmake
index f92fc10..bed78f9 100644
--- a/Modules/CPackIFWConfigureFile.cmake
+++ b/Modules/CPackIFWConfigureFile.cmake
@@ -7,8 +7,8 @@
.. versionadded:: 3.8
-This module defines :command:`configure_file` similar command to
-configure file templates prepared in QtIFW/SDK/Creator style.
+This module provides a command similar to :command:`configure_file` for
+configuring file templates prepared in QtIFW/SDK/Creator style.
Load this module in a CMake project with:
@@ -19,21 +19,100 @@
Commands
^^^^^^^^
-The module defines the following commands:
+This module provides the following command:
.. command:: cpack_ifw_configure_file
- Copy a file to another location and modify its contents.
+ Copies a file template to output file and substitutes variable values
+ referenced as ``%{VAR}`` or ``%VAR%`` from the input file template
+ content:
.. code-block:: cmake
cpack_ifw_configure_file(<input> <output>)
- Copies an ``<input>`` file to an ``<output>`` file and substitutes variable
- values referenced as ``%{VAR}`` or ``%VAR%`` in the input file content.
+ ``<input>``
+ Input file template. If given as a relative path, it is interpreted as
+ relative to the current source directory
+ (:variable:`CMAKE_CURRENT_SOURCE_DIR`).
+
+ ``<output>``
+ Output file. If given as a relative path, it is interpreted as relative
+ to the current binary directory (:variable:`CMAKE_CURRENT_BINARY_DIR`).
+
+ Qt Installer Framework (QtIFW) uses ``@`` characters for embedding
+ predefined variables (``TargetDir``, ``StartMenuDir``, etc.) in Qt
+ installer scripts:
+
+ .. code-block:: javascript
+ :caption: ``example.qs``
+
+ component.addOperation(
+ "CreateShortcut",
+ "@TargetDir@/example.com.html",
+ "@StartMenuDir@/Example Web Site.lnk"
+ );
+
+ The purpose of this command is to preserve the QtIFW predefined variables
+ containing the ``@`` characters (``@VAR@``), and instead use the ``%``
+ characters for template placeholders (``%VAR%``, ``%{VAR}``) in
+ Qt/IFW/SDK/Creator templates. The :command:`configure_file` command
+ would otherwise replace all variable references containing the ``@``
+ characters.
+
Each variable reference will be replaced with the current value of the
variable, or the empty string if the variable is not defined.
+Examples
+^^^^^^^^
+
+In the following example this module is used to create an IFW component
+script from a given template file ``qt.tools.foo.qs.in``, where
+``%FOO_DOC_DIR%`` variable reference will be replaced by the values of
+the ``FOO_DOC_DIR`` CMake variable.
+
+.. code-block:: cmake
+ :caption: ``CMakeLists.txt``
+
+ cmake_minimum_required(VERSION 3.8)
+
+ project(Foo)
+
+ # ...
+
+ include(CPackIFWConfigureFile)
+
+ set(FOO_DOC_DIR "doc/foo")
+
+ cpack_ifw_configure_file(qt.tools.foo.qs.in qt.tools.foo.qs)
+
+.. code-block:: javascript
+ :caption: ``qt.tools.foo.qs.in``
+
+ function Component()
+ {
+ }
+
+ Component.prototype.createOperations = function()
+ {
+ if (installer.value("os") === "win") {
+ component.addOperation(
+ "CreateShortcut",
+ "@TargetDir@/%FOO_DOC_DIR%/example.com.html",
+ "@StartMenuDir@/Example Web Site.lnk"
+ );
+ }
+
+ component.createOperations();
+ }
+
+ // ...
+
+See Also
+^^^^^^^^
+
+* The :cpack_gen:`CPack IFW Generator`.
+* The :module:`CPackIFW` module.
#]=======================================================================]
if(NOT DEFINED CPackIFWConfigureFile_CMake_INCLUDED)
diff --git a/Modules/FindMatlab.cmake b/Modules/FindMatlab.cmake
index 8acc6f3..231700a 100644
--- a/Modules/FindMatlab.cmake
+++ b/Modules/FindMatlab.cmake
@@ -5,308 +5,767 @@
FindMatlab
----------
-Finds Matlab or Matlab Compiler Runtime (MCR) and provides Matlab tools,
+Finds MATLAB or MATLAB Compiler Runtime (MCR) and provides its tools,
libraries and compilers to CMake:
.. code-block:: cmake
- find_package(Matlab [<version>] [COMPONENTS <components>...] [...])
+ find_package(Matlab [<version>] [COMPONENTS <components>...] [REGISTRY_VIEW <view>] [...])
-This package primary purpose is to find the libraries associated with Matlab
-or the MCR in order to be able to build Matlab extensions (mex files). It
-can also be used:
+The primary purpose of this module is to find the libraries associated with
+MATLAB or the MCR in order to be able to build MATLAB extensions (MEX files).
+It can also be used:
-* to run specific commands in Matlab in case Matlab is available
-* for declaring Matlab unit test
-* to retrieve various information from Matlab (mex extensions, versions and
+* to run specific commands in MATLAB in case MATLAB is available
+* for declaring MATLAB unit tests
+* to retrieve various information from MATLAB (MEX extensions, versions and
release queries, ...)
.. versionadded:: 3.12
- Added Matlab Compiler Runtime (MCR) support.
-
-The module supports the following components:
-
-* ``ENG_LIBRARY`` and ``MAT_LIBRARY``: respectively the ``ENG`` and ``MAT``
- libraries of Matlab
-* ``MAIN_PROGRAM`` the Matlab binary program. Note that this component is not
- available on the MCR version, and will yield an error if the MCR is found
- instead of the regular Matlab installation.
-* ``MEX_COMPILER`` the MEX compiler.
-* ``MCC_COMPILER`` the MCC compiler, included with the Matlab Compiler add-on.
-* ``SIMULINK`` the Simulink environment.
-
-.. versionadded:: 3.7
- Added the ``MAT_LIBRARY`` component.
-
-.. versionadded:: 3.13
- Added the ``ENGINE_LIBRARY``, ``DATAARRAY_LIBRARY`` and ``MCC_COMPILER``
- components.
-
-.. versionchanged:: 3.14
- Removed the ``MX_LIBRARY``, ``ENGINE_LIBRARY`` and ``DATAARRAY_LIBRARY``
- components. These libraries are found unconditionally.
+ MATLAB Compiler Runtime (MCR) support.
.. versionadded:: 3.30
- Added support for specifying a version range to :command:`find_package` and
- added support for specifying ``REGISTRY_VIEW`` to :command:`find_package`,
+ Support for specifying a version range to :command:`find_package`,
+ support for specifying ``REGISTRY_VIEW`` argument to
+ :command:`find_package`,
:command:`matlab_extract_all_installed_versions_from_registry` and
- :command:`matlab_get_all_valid_matlab_roots_from_registry`. The default
- behavior remained unchanged, by using the registry view ``TARGET``.
+ :command:`matlab_get_all_valid_matlab_roots_from_registry` commands.
+ The default behavior remained unchanged, by using the registry view
+ ``TARGET``.
.. note::
- The version given to the :command:`find_package` directive is the Matlab
- **version**, which should not be confused with the Matlab *release* name
- (e.g. `R2023b`).
- The :command:`matlab_get_version_from_release_name` and
- :command:`matlab_get_release_name_from_version` provide a mapping
- between the release name and the version.
+ The version given to the :command:`find_package` argument is the MATLAB
+ *version*, which should not be confused with the MATLAB *release name*
+ (e.g. ``R2023b``). The :command:`matlab_get_version_from_release_name`
+ and :command:`matlab_get_release_name_from_version` commands provide a
+ mapping between the release name and the version.
-The variable :variable:`Matlab_ROOT_DIR` may be specified in order to give
-the path of the desired Matlab version. Otherwise, the behavior is platform
-specific:
+Components
+^^^^^^^^^^
-* Windows: The installed versions of Matlab/MCR are retrieved from the
- Windows registry. The ``REGISTRY_VIEW`` argument may optionally be specified
- to manually control whether 32bit or 64bit versions shall be searched for.
-* macOS: The installed versions of Matlab/MCR are given by the MATLAB
- default installation paths under ``$HOME/Applications`` and ``/Applications``.
- If no such application is found, it falls back to the one that might be
- accessible from the ``PATH``.
-* Unix: The desired Matlab should be accessible from the ``PATH``. This does
- not work for MCR installation and :variable:`Matlab_ROOT_DIR` should be
- specified on this platform.
+This module supports optional components which can be specified using the
+:command:`find_package` command:
-Additional information is provided when :variable:`MATLAB_FIND_DEBUG` is set.
-When a Matlab/MCR installation is found automatically and the ``MATLAB_VERSION``
-is not given, the version is queried from Matlab directly (on Windows this
-may pop up a Matlab window) or from the MCR installation.
+.. code-block:: cmake
-The mapping of the release names and the version of Matlab is performed by
-defining pairs (name, version). The variable
-:variable:`MATLAB_ADDITIONAL_VERSIONS` may be provided before the call to
-the :command:`find_package` in order to handle additional versions.
+ find_package(Matlab [COMPONENTS <components>...])
-A Matlab scripts can be added to the set of tests using the
-:command:`matlab_add_unit_test`. By default, the Matlab unit test framework
-will be used (>= 2013a) to run this script, but regular ``.m`` files
-returning an exit code can be used as well (0 indicating a success).
+Supported components include:
-Module Input Variables
-^^^^^^^^^^^^^^^^^^^^^^
+``ENG_LIBRARY``
+ .. versionadded:: 3.3
-Users or projects may set the following variables to configure the module
-behavior:
+ Finds the ``ENG`` library of MATLAB.
-:variable:`Matlab_ROOT <<PackageName>_ROOT>`
- .. versionadded:: 3.25
+``MAT_LIBRARY``
+ .. versionadded:: 3.7
- Default value for :variable:`Matlab_ROOT_DIR`, the root of the Matlab
- installation.
+ Finds the ``MAT`` library of MATLAB.
-:variable:`Matlab_ROOT_DIR`
- The root of the Matlab installation.
+``MAIN_PROGRAM``
+ .. versionadded:: 3.3
-:variable:`MATLAB_FIND_DEBUG`
- outputs debug information
+ Finds the MATLAB binary program. Note that this component is not
+ available on the MCR version, and will yield an error if the MCR is found
+ instead of the regular MATLAB installation.
-:variable:`MATLAB_ADDITIONAL_VERSIONS`
- additional versions of Matlab for the automatic retrieval of the installed
- versions.
+``MEX_COMPILER``
+ .. versionadded:: 3.3
+
+ Finds the MEX compiler.
+
+``MCC_COMPILER``
+ .. versionadded:: 3.13
+
+ Finds the MCC compiler, included with the MATLAB Compiler add-on.
+
+``SIMULINK``
+ .. versionadded:: 3.3
+
+ Finds the Simulink environment.
+
+Implicitly Found Components
+"""""""""""""""""""""""""""
+
+The following components are always found unconditionally, without needing
+to be specified explicitly:
+
+``MX_LIBRARY``
+ .. versionchanged:: 3.14
+ This component has been removed and is now always found unconditionally.
+
+ .. versionadded:: 3.3
+
+ Finds the MATLAB mx library.
+
+``ENGINE_LIBRARY``
+ .. versionchanged:: 3.14
+ This component has been removed and is now always found unconditionally.
+
+ .. versionadded:: 3.13
+
+ Finds the MATLAB engine library.
+
+``DATAARRAY_LIBRARY``
+ .. versionchanged:: 3.14
+ This component has been removed and is now always found unconditionally.
+
+ .. versionadded:: 3.13
+
+ Finds the C++ MATLAB data array library.
+
+If no components are specified, the module looks for the ``MX_LIBRARY``,
+``ENGINE_LIBRARY``, and ``DATAARRAY_LIBRARY`` by default.
Imported Targets
^^^^^^^^^^^^^^^^
-.. versionadded:: 3.22
-
-This module defines the following :prop_tgt:`IMPORTED` targets:
+This module provides the following :ref:`Imported Targets`:
``Matlab::mex``
- The ``mex`` library, always available for MATLAB installations. Available for
- MCR installations if provided by MCR.
+ .. versionadded:: 3.22
+
+ Target encapsulating the ``mex`` library usage requirements, always
+ available for MATLAB installations. Available for MCR installations if
+ provided by MCR.
``Matlab::mx``
- The mx library of Matlab (arrays), always available for MATLAB installations.
- Available for MCR installations if provided by MCR.
+ .. versionadded:: 3.22
+
+ Target encapsulating the usage requirements of the mx library of MATLAB
+ (arrays), always available for MATLAB installations. Available for MCR
+ installations if provided by MCR.
``Matlab::eng``
- Matlab engine library. Available only if the ``ENG_LIBRARY`` component
- is requested.
+ .. versionadded:: 3.22
+
+ Target encapsulating the MATLAB engine library usage requirements.
+ Available only if the ``ENG_LIBRARY`` component is requested.
``Matlab::mat``
- Matlab matrix library. Available only if the ``MAT_LIBRARY`` component
- is requested.
+ .. versionadded:: 3.22
+
+ Target encapsulating the MATLAB matrix library usage requirements.
+ Available only if the ``MAT_LIBRARY`` component is requested.
``Matlab::MatlabEngine``
- Matlab C++ engine library, always available for MATLAB R2018a and newer.
- Available for MCR installations if provided by MCR.
+ .. versionadded:: 3.22
+
+ Target encapsulating the MATLAB C++ engine library usage requirements,
+ always available for MATLAB R2018a and newer. Available for MCR
+ installations if provided by MCR.
``Matlab::MatlabDataArray``
- Matlab C++ data array library, always available for MATLAB R2018a and newer.
- Available for MCR installations if provided by MCR.
+ .. versionadded:: 3.22
-Variables defined by the module
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ Target encapsulating the MATLAB C++ data array library usage requirements,
+ always available for MATLAB R2018a and newer. Available for MCR
+ installations if provided by MCR.
-Result variables
-""""""""""""""""
+Result Variables
+^^^^^^^^^^^^^^^^
+
+This module defines the following variables:
``Matlab_FOUND``
.. versionadded:: 3.3
- Boolean indicating whether the (requested version of) Matlab installation
- was found. All variables below are defined if Matlab is found.
+ Boolean indicating whether the (requested version of) MATLAB installation
+ was found. All variables below are defined if MATLAB is found.
``Matlab_VERSION``
.. versionadded:: 3.27
- the numerical version (e.g. 23.2.0) of Matlab found. Not to be confused with
- Matlab release name (e.g. R2023b) that can be obtained with
- :command:`matlab_get_release_name_from_version`.
+ The numerical version (e.g. ``23.2.0``) of MATLAB found. Not to be
+ confused with MATLAB release name (e.g. ``R2023b``) that can be obtained
+ with :command:`matlab_get_release_name_from_version`.
+
+ When a MATLAB/MCR installation is found automatically and the
+ ``Matlab_VERSION`` is not given, the version is queried from MATLAB
+ directly (on Windows this may pop up a MATLAB window) or from the MCR
+ installation.
+
``Matlab_ROOT_DIR``
- the final root of the Matlab installation determined by the FindMatlab
- module.
+ .. versionadded:: 3.3
+
+ The final root of the MATLAB installation determined by this module.
+
``Matlab_MAIN_PROGRAM``
- the Matlab binary program. Available only if the component ``MAIN_PROGRAM``
- is given in the :command:`find_package` directive.
+ .. versionadded:: 3.3
+
+ The MATLAB binary program. Available only if the component ``MAIN_PROGRAM``
+ is given in the :command:`find_package` argument.
+
``Matlab_INCLUDE_DIRS``
- the path of the Matlab libraries headers
+ .. versionadded:: 3.3
+
+ The path of the MATLAB libraries headers.
+
``Matlab_MEX_LIBRARY``
- library for mex, always available for MATLAB installations. Available for MCR
- installations if provided by MCR.
+ Library for MEX, always available for MATLAB installations. Available
+ for MCR installations if provided by MCR.
+
``Matlab_MX_LIBRARY``
- mx library of Matlab (arrays), always available for MATLAB installations.
- Available for MCR installations if provided by MCR.
+ The mx library of MATLAB (arrays), always available for MATLAB
+ installations. Available for MCR installations if provided by MCR.
+
``Matlab_ENG_LIBRARY``
- Matlab engine library. Available only if the component ``ENG_LIBRARY``
+ MATLAB engine library. Available only if the component ``ENG_LIBRARY``
is requested.
+
``Matlab_MAT_LIBRARY``
- Matlab matrix library. Available only if the component ``MAT_LIBRARY``
+ .. versionadded:: 3.7
+
+ Matlab matrix library. Available only if the component ``MAT_LIBRARY``
is requested.
+
``Matlab_ENGINE_LIBRARY``
.. versionadded:: 3.13
Matlab C++ engine library, always available for MATLAB R2018a and newer.
Available for MCR installations if provided by MCR.
+
``Matlab_DATAARRAY_LIBRARY``
.. versionadded:: 3.13
- Matlab C++ data array library, always available for MATLAB R2018a and newer.
- Available for MCR installations if provided by MCR.
+ Matlab C++ data array library, always available for MATLAB R2018a and
+ newer. Available for MCR installations if provided by MCR.
+
``Matlab_LIBRARIES``
- the whole set of libraries of Matlab
+ The whole set of libraries of MATLAB.
+
``Matlab_MEX_COMPILER``
- the mex compiler of Matlab. Currently not used.
- Available only if the component ``MEX_COMPILER`` is requested.
+ .. versionadded:: 3.3
+
+ The MEX compiler of MATLAB. Currently not used. Available only if the
+ component ``MEX_COMPILER`` is requested.
+
``Matlab_MCC_COMPILER``
.. versionadded:: 3.13
- the mcc compiler of Matlab. Included with the Matlab Compiler add-on.
+ The mcc compiler of MATLAB. Included with the MATLAB Compiler add-on.
Available only if the component ``MCC_COMPILER`` is requested.
-Cached variables
-""""""""""""""""
+Cache Variables
+^^^^^^^^^^^^^^^
+
+The following cache variables may also be set:
``Matlab_MEX_EXTENSION``
- the extension of the mex files for the current platform (given by Matlab).
+ .. versionadded:: 3.3
+
+ The extension of the MEX files for the current platform (given by MATLAB).
+
``Matlab_ROOT_DIR``
- the location of the root of the Matlab installation found. If this value
+ .. versionadded:: 3.3
+
+ The location of the root of the MATLAB installation found. If this value
is changed by the user, the result variables are recomputed.
-Provided commands
-^^^^^^^^^^^^^^^^^
+Input Variables
+^^^^^^^^^^^^^^^
-:command:`matlab_get_version_from_release_name`
- returns the version from the Matlab release name
-:command:`matlab_get_release_name_from_version`
- returns the release name from the Matlab version
-:command:`matlab_add_mex`
- adds a target compiling a MEX file.
-:command:`matlab_add_unit_test`
- adds a Matlab unit test file as a test to the project.
-:command:`matlab_extract_all_installed_versions_from_registry`
- parses the registry for all Matlab versions. Available on Windows only.
- The part of the registry parsed is dependent on the host processor
-:command:`matlab_get_all_valid_matlab_roots_from_registry`
- returns all the possible Matlab or MCR paths, according to a previously
- given list. Only the existing/accessible paths are kept. This is mainly
- useful for the searching all possible Matlab installation.
-:command:`matlab_get_mex_suffix`
- returns the suffix to be used for the mex files
- (platform/architecture dependent)
-:command:`matlab_get_version_from_matlab_run`
- returns the version of Matlab/MCR, given the full directory of the Matlab/MCR
- installation path.
+Users or projects may set the following variables to configure the module
+behavior before calling ``find_package(Matlab)``:
+:variable:`Matlab_ROOT <<PackageName>_ROOT>`
+ .. versionadded:: 3.25
-Known issues
-^^^^^^^^^^^^
+ Default value for the ``Matlab_ROOT_DIR`` variable, the root of the
+ MATLAB installation.
-**Symbol clash in a MEX target**
- By default, every symbols inside a MEX
- file defined with the command :command:`matlab_add_mex` have hidden
- visibility, except for the entry point. This is the default behavior of
- the MEX compiler, which lowers the risk of symbol collision between the
- libraries shipped with Matlab, and the libraries to which the MEX file is
- linking to. This is also the default on Windows platforms.
+``Matlab_ROOT_DIR``
+ .. versionadded:: 3.3
- However, this is not sufficient in certain case, where for instance your
- MEX file is linking against libraries that are already loaded by Matlab,
- even if those libraries have different SONAMES.
- A possible solution is to hide the symbols of the libraries to which the
- MEX target is linking to. This can be achieved in GNU GCC compilers with
- the linker option ``-Wl,--exclude-libs,ALL``.
+ The root folder of the MATLAB installation. If set before the call to
+ :command:`find_package`, the module will look for the components in that
+ path. If not set, then an automatic search of MATLAB will be performed.
+ If set, it should point to a valid version of MATLAB.
-**Tests using GPU resources**
- in case your MEX file is using the GPU and
- in order to be able to run unit tests on this MEX file, the GPU resources
- should be properly released by Matlab. A possible solution is to make
- Matlab aware of the use of the GPU resources in the session, which can be
- performed by a command such as ``D = gpuDevice()`` at the beginning of
- the test script (or via a fixture).
+ This variable may be specified in order to give the path of the desired
+ MATLAB version. Otherwise, the behavior is platform specific:
+ * Windows: The installed versions of MATLAB/MCR are retrieved from the
+ Windows registry. The ``REGISTRY_VIEW`` argument may optionally be
+ specified to manually control whether 32bit or 64bit versions shall be
+ searched for.
+ * macOS: The installed versions of MATLAB/MCR are given by the MATLAB
+ default installation paths under ``$HOME/Applications`` and
+ ``/Applications``. If no such application is found, it falls back to
+ the one that might be accessible from the ``PATH``.
+ * Unix: The desired MATLAB should be accessible from the ``PATH``. This
+ does not work for MCR installation and ``Matlab_ROOT_DIR`` should be
+ specified on this platform.
-Reference
-^^^^^^^^^
+``MATLAB_FIND_DEBUG``
+ .. versionadded:: 3.3
-.. variable:: Matlab_ROOT_DIR
+ If set to a boolean true, additional debug information is outputted to
+ the console, such as the lookup of MATLAB and the intermediate
+ configuration steps.
- The root folder of the Matlab installation. If set before the call to
- :command:`find_package`, the module will look for the components in that
- path. If not set, then an automatic search of Matlab
- will be performed. If set, it should point to a valid version of Matlab.
+``MATLAB_ADDITIONAL_VERSIONS``
+ .. versionadded:: 3.3
-.. variable:: MATLAB_FIND_DEBUG
+ If set, it specifies additional versions of MATLAB for the automatic
+ retrieval of the installed versions that may be handled and looked for.
- If set, the lookup of Matlab and the intermediate configuration steps are
- outputted to the console.
-
-.. variable:: MATLAB_ADDITIONAL_VERSIONS
-
- If set, specifies additional versions of Matlab that may be looked for.
- The variable should be a list of strings, organized by pairs of release
- name and versions, such as follows:
+ The mapping of the release names and the version of MATLAB is performed
+ by defining pairs (name, version). The variable should be a list of
+ strings, organized by pairs of release name and versions, such as
+ follows:
.. code-block:: cmake
- set(MATLAB_ADDITIONAL_VERSIONS
+ set(
+ MATLAB_ADDITIONAL_VERSIONS
"release_name1=corresponding_version1"
"release_name2=corresponding_version2"
- ...
- )
+ # ...
+ )
+
+ find_package(Matlab)
Example:
.. code-block:: cmake
- set(MATLAB_ADDITIONAL_VERSIONS
+ set(
+ MATLAB_ADDITIONAL_VERSIONS
"R2013b=8.2"
"R2013a=8.1"
- "R2012b=8.0")
+ "R2012b=8.0"
+ # ...
+ )
- The order of entries in this list matters when several versions of
- Matlab are installed. The priority is set according to the ordering in
- this list.
+ find_package(Matlab)
+
+ The order of entries in this list matters when several versions of MATLAB
+ are installed. The priority is set according to the ordering in this
+ list.
+
+Commands
+^^^^^^^^
+
+This module provides the following commands:
+
+* :command:`matlab_get_version_from_release_name`
+* :command:`matlab_get_release_name_from_version`
+* :command:`matlab_get_version_from_matlab_run`
+* :command:`matlab_extract_all_installed_versions_from_registry`
+* :command:`matlab_get_all_valid_matlab_roots_from_registry`
+* :command:`matlab_add_mex`
+* :command:`matlab_get_mex_suffix`
+* :command:`matlab_add_unit_test`
+
+.. command:: matlab_get_version_from_release_name
+
+ .. versionadded:: 3.3
+
+ Returns the version of MATLAB from a release name:
+
+ .. code-block:: cmake
+
+ matlab_get_version_from_release_name(<release-name> <version-var>)
+
+ The arguments are:
+
+ ``<release-name>``
+ Input release name string (e.g. ``R2023b``).
+
+ ``<version-var>``
+ The name of the variable in which to store the version of MATLAB. The
+ output result is e.g. ``23.2.0``.
+
+ .. note::
+
+ This command provides correct versions mappings for MATLAB but not MCR.
+
+.. command:: matlab_get_release_name_from_version
+
+ .. versionadded:: 3.3
+
+ Returns the release name from the version of MATLAB:
+
+ .. code-block:: cmake
+
+ matlab_get_release_name_from_version(<version> <release-name-var>)
+
+ The arguments are:
+
+ ``<version>``
+ Input MATLAB version string (e.g. ``23.2.0``).
+
+ ``<release-name-var>``
+ The name of the variable in which to store the MATLAB release name. The
+ output result is e.g. ``R2023b``.
+
+ .. note::
+
+ This command provides correct version mappings for MATLAB but not MCR.
+
+.. command:: matlab_get_version_from_matlab_run
+
+ .. versionadded:: 3.3
+
+ Runs the specified MATLAB program and extracts the version of MATLAB/MCR,
+ given the full directory of the MATLAB/MCR installation path:
+
+ .. code-block:: cmake
+
+ matlab_get_version_from_matlab_run(<matlab-binary> <matlab-versions-var>)
+
+ The arguments are:
+
+ ``<matlab-binary>``
+ The path to the ``matlab`` binary executable.
+
+ ``<matlab-versions-var>``
+ The name of the variable in which a list of extracted MATLAB versions
+ are stored.
+
+ If the path provided for the MATLAB installation points to an MCR
+ installation, the version is extracted from the installed files.
+
+.. command:: matlab_extract_all_installed_versions_from_registry
+
+ .. versionadded:: 3.3
+
+ Parses the Windows registry and finds all installed MATLAB versions:
+
+ .. signature::
+ matlab_extract_all_installed_versions_from_registry(<versions-var>
+ [REGISTRY_VIEW <view>])
+ :target: matlab_extract_all_installed_versions_from_registry-keyword
+
+ The arguments are:
+
+ ``<versions-var>``
+ The name of the variable in which to store the list of all MATLAB
+ versions found.
+
+ ``REGISTRY_VIEW <view>``
+ .. versionadded:: 3.30
+
+ Optional registry view argument that provides a more precise interface
+ on how to interact with the Windows Registry. The argument is passed
+ (or omitted) to :command:`cmake_host_system_information` without
+ further checks or modification. For example, ``<view>`` value can be
+ one of ``64``, ``32``, ``64_32``, ``32_64``, ``HOST``, ``TARGET``,
+ ``BOTH``.
+
+ The old signature is:
+
+ .. signature::
+ matlab_extract_all_installed_versions_from_registry(<win64> <versions-var>)
+ :target: matlab_extract_all_installed_versions_from_registry-positional
+
+ The arguments are:
+
+ ``<win64>``
+ Boolean whether to search for the 64-bit version of MATLAB. If set
+ to boolean true, 64-bit registry view will be searched. If set to
+ boolean false, 32-bit registry view will be searched. For finer
+ control, use the above signature.
+
+ ``<versions-var>``
+ The name of the variable in which to store the list of all MATLAB
+ versions found.
+
+ This command is available on Windows only. The part of the registry
+ parsed is dependent on the host processor.
+
+ The returned list contains all versions under
+ ``HKLM\SOFTWARE\Mathworks\MATLAB``,
+ ``HKLM\SOFTWARE\Mathworks\MATLAB Runtime`` and
+ ``HKLM\SOFTWARE\Mathworks\MATLAB Compiler Runtime`` or an empty list in
+ case an error occurred (or nothing found).
+
+ .. note::
+
+ Only the versions are provided. No check is made over the existence of
+ the installation referenced in the registry.
+
+.. command:: matlab_get_all_valid_matlab_roots_from_registry
+
+ .. versionadded:: 3.3
+
+ Returns all the possible MATLAB or MCR paths, according to a previously
+ given list:
+
+ .. code-block:: cmake
+
+ matlab_get_all_valid_matlab_roots_from_registry(
+ <matlab-versions>
+ <matlab-roots-var>
+ [REGISTRY_VIEW <view>]
+ )
+
+ This command populates the MATLAB root with valid versions of MATLAB or
+ MATLAB Runtime (MCR) and is mainly useful for the searching of all
+ possible MATLAB installations. Only the existing/accessible paths are
+ kept.
+
+ The arguments are:
+
+ ``<matlab-versions>``
+ A :ref:`semicolon-separated list <CMake Language Lists>` of each of the
+ MATLAB or MCR installations. Specify it as a single string value.
+
+ ``<matlab-roots-var>``
+ The name of the variable in which to store a list of locations of each
+ of the MATLAB or MCR installations.
+
+ The value of this variable is organized in triplets
+ ``(type,version_number,matlab_root_path)``, where ``type`` indicates
+ either ``MATLAB`` or ``MCR``.
+
+ ``REGISTRY_VIEW <view>``
+ .. versionadded:: 3.30
+
+ Optional registry view argument that provides a more precise interface
+ on how to interact with the Windows Registry. The argument is passed
+ (or omitted) to :command:`cmake_host_system_information` without
+ further checks or modification. For example, ``<view>`` value can be
+ one of ``64``, ``32``, ``64_32``, ``32_64``, ``HOST``, ``TARGET``,
+ ``BOTH``.
+
+.. command:: matlab_add_mex
+
+ .. versionadded:: 3.3
+
+ Adds a target that compiles MATLAB MEX target file:
+
+ .. code-block:: cmake
+
+ matlab_add_mex(
+ NAME <name>
+ [EXECUTABLE | MODULE | SHARED]
+ SRC <sources>...
+ [OUTPUT_NAME <output-name>]
+ [DOCUMENTATION <file>]
+ [LINK_TO <targets>...]
+ [R2017b | R2018a]
+ [EXCLUDE_FROM_ALL]
+ [NO_IMPLICIT_LINK_TO_MATLAB_LIBRARIES]
+ [...]
+ )
+
+ This commands compiles the given sources with the current tool-chain in
+ order to produce a MEX file. The final name of the produced output may
+ be specified, as well as additional link libraries, and a documentation
+ entry for the MEX file. Remaining arguments of the call are passed to
+ the :command:`add_library` or :command:`add_executable` command.
+
+ The arguments are:
+
+ ``NAME <name>``
+ The name of the target.
+
+ ``SRC <sources>...``
+ One or more source files to be compiled.
+
+ ``LINK_TO <targets>...``
+ A list of additional link dependencies. The target links to ``libmex``
+ and ``libmx`` by default, unless the
+ ``NO_IMPLICIT_LINK_TO_MATLAB_LIBRARIES`` option is passed.
+
+ ``OUTPUT_NAME <output-name>``
+ If given, overrides the default name. The default name is the name of
+ the target without any prefix and with ``Matlab_MEX_EXTENSION`` suffix.
+
+ ``DOCUMENTATION <file>``
+ If given, the ``<file>`` will be considered as being the documentation
+ file for the MEX file. This file is copied into the same folder without
+ any processing, with the same name as the final MEX file, and with
+ extension ``.m``. In that case, typing ``help <name>`` in MATLAB
+ prints the documentation contained in this file.
+
+ The documentation file is not processed and should be in the following
+ format:
+
+ .. code-block:: matlab
+
+ % This is the documentation
+ function ret = mex_target_output_name(input1)
+
+ ``R2017b`` or ``R2018a``
+ .. versionadded:: 3.14
+
+ May be given to specify the version of the C API
+ to use: ``R2017b`` specifies the traditional (separate complex) C API,
+ and corresponds to the ``-R2017b`` flag for the ``mex`` command.
+ ``R2018a`` specifies the new interleaved complex C API, and corresponds
+ to the ``-R2018a`` flag for the ``mex`` command. Ignored for MATLAB
+ versions prior to R2018a. Defaults to ``R2017b``.
+
+ ``MODULE`` or ``SHARED``
+ .. versionadded:: 3.7
+
+ May be given to specify the type of library to be created.
+
+ ``EXECUTABLE``
+ .. versionadded:: 3.7
+
+ May be given to create an executable instead of a library. If no type
+ is given explicitly, the default type is ``SHARED``.
+
+ ``EXCLUDE_FROM_ALL``
+ This option has the same meaning as the :prop_tgt:`EXCLUDE_FROM_ALL`
+ target property and is forwarded to the :command:`add_library`, or
+ :command:`add_executable` command.
+
+ ``NO_IMPLICIT_LINK_TO_MATLAB_LIBRARIES``
+ .. versionadded:: 3.24
+
+ This option permits to disable the automatic linking of MATLAB
+ libraries, so that only the libraries that are actually required can be
+ linked via the ``LINK_TO`` option.
+
+.. command:: matlab_get_mex_suffix
+
+ .. versionadded:: 3.3
+
+ Returns the extension to be used for the MEX files (the suffix):
+
+ .. code-block:: cmake
+
+ matlab_get_mex_suffix(<matlab-root> <mex-suffix-var>)
+
+ The arguments are:
+
+ ``<matlab-root>``
+ The root of MATLAB/MCR installation. For example, the value of the
+ ``Matlab_ROOT_DIR`` variable.
+
+ ``<mex-suffix-var>``
+ The name of the variable in which the suffix will be returned.
+
+ This command is platform and architecture dependent. It should not be
+ called before the appropriate MATLAB root has been found.
+
+.. command:: matlab_add_unit_test
+
+ .. versionadded:: 3.3
+
+ Adds a MATLAB unit test file to the project's test set of CMake/CTest:
+
+ .. code-block:: cmake
+
+ matlab_add_unit_test(
+ NAME <name>
+ UNITTEST_FILE <matlab-file-containing-unittest.m>
+ [CUSTOM_TEST_COMMAND <matlab-command-to-run-as-test>]
+ [UNITTEST_PRECOMMAND <matlab-command-to-run>]
+ [TIMEOUT <timeout>]
+ [ADDITIONAL_PATH <paths>...]
+ [MATLAB_ADDITIONAL_STARTUP_OPTIONS <options>...]
+ [TEST_ARGS <args>...]
+ [NO_UNITTEST_FRAMEWORK]
+ [WORKING_DIRECTORY <dir>]
+ )
+
+ By default, the MATLAB unit test framework will be used (>= 2013a) to run
+ the added MATLAB script, but regular ``.m`` files returning an exit code
+ can be used as well (0 indicating a success).
+
+ This command requires the component ``MAIN_PROGRAM`` and hence is not
+ available for an MCR installation.
+
+ The unit test uses the MATLAB unittest framework (default, available
+ starting MATLAB 2013b+) except if the option ``NO_UNITTEST_FRAMEWORK``
+ is given.
+
+ The command expects one MATLAB test script file to be given.
+ In the case ``NO_UNITTEST_FRAMEWORK`` is given, the unittest script file
+ should contain the script to be run, plus an exit command with the exit
+ value. This exit value will be passed to the ctest framework (0 success,
+ non 0 failure). Additional arguments accepted by :command:`add_test` can
+ be passed through ``TEST_ARGS`` (e.g. ``CONFIGURATIONS <config> ...``).
+
+ The arguments are:
+
+ ``NAME <name>``
+ The name of the unittest in ctest.
+
+ ``UNITTEST_FILE <matlab-file-containing-unittest.m>``
+ The MATLAB unittest file. Its path will be automatically added to the
+ MATLAB path.
+
+ ``CUSTOM_TEST_COMMAND <matlab-command-to-run-as-test>``
+ MATLAB script command to run as the test.
+ If this is not set, then the following is run:
+ ``runtests('matlab_file_name'), exit(max([ans(1,:).Failed]))`` where
+ ``matlab_file_name`` is the ``UNITTEST_FILE`` without the extension.
+
+ ``UNITTEST_PRECOMMAND <matlab-command-to-run>``
+ MATLAB script command to be ran before the file
+ containing the test (e.g. GPU device initialization based on CMake
+ variables).
+
+ ``TIMEOUT <timeout>``
+ The test timeout in seconds. Defaults to 180 seconds as the
+ MATLAB unit test may hang.
+
+ ``ADDITIONAL_PATH <paths>...``
+ A list of paths to add to the MATLAB path prior to running the unit
+ test.
+
+ ``MATLAB_ADDITIONAL_STARTUP_OPTIONS <options>``
+ A list of additional option in order to run MATLAB from the command
+ line. The ``-nosplash``, ``-nodesktop``, and ``-nodisplay`` options
+ are always added automatically.
+
+ ``TEST_ARGS <args>...``
+ Additional options provided to the add_test command. These
+ options are added to the default options (e.g. ``CONFIGURATIONS Release``).
+
+ ``NO_UNITTEST_FRAMEWORK``
+ When set, indicates that the test should not
+ use the unittest framework of MATLAB (available for versions >= R2013a).
+
+ ``WORKING_DIRECTORY <dir>``
+ This will be the working directory for the test. If specified it will
+ also be the output directory used for the log file of the test run.
+ If not specified the temporary directory ``${CMAKE_BINARY_DIR}/Matlab``
+ will be used as the working directory and the log location.
+
+Known Issues
+^^^^^^^^^^^^
+
+**Symbol clash in a MEX target**
+ By default, every symbol inside a MEX
+ file defined with the command :command:`matlab_add_mex` have hidden
+ visibility, except for the entry point. This is the default behavior of
+ the MEX compiler, which lowers the risk of symbol collision between the
+ libraries shipped with MATLAB, and the libraries to which the MEX file is
+ linking to. This is also the default on Windows platforms.
+
+ However, this is not sufficient in certain case, where for instance the
+ MEX file is linking against libraries that are already loaded by MATLAB,
+ even if those libraries have different SONAMES.
+ A possible solution is to hide the symbols of the libraries to which the
+ MEX target is linking to. This can be achieved in GNU GCC compilers with
+ the linker option ``-Wl,--exclude-libs,ALL``.
+
+**Tests using GPU resources**
+ In case the MEX file is using the GPU and in order to be able to run unit
+ tests on this MEX file, the GPU resources should be properly released by
+ MATLAB. A possible solution is to make MATLAB aware of the use of the
+ GPU resources in the session, which can be performed by a command, such
+ as ``D = gpuDevice()``, at the beginning of the test script (or via a
+ fixture).
+
+Examples
+^^^^^^^^
+
+Finding MATLAB and linking imported target to a project target:
+
+.. code-block:: cmake
+
+ find_package(Matlab)
+ target_link_libraries(example PRIVATE Matlab::mx)
#]=======================================================================]
cmake_policy(PUSH)
@@ -370,23 +829,7 @@
file(MAKE_DIRECTORY "${_matlab_temporary_folder}")
-#[=======================================================================[.rst:
-.. command:: matlab_get_version_from_release_name
-
- .. code-block:: cmake
-
- matlab_get_version_from_release_name(release version)
-
- * Input: ``release`` is the release name (e.g. R2023b)
- * Output: ``version`` is the version of Matlab (e.g. 23.2.0)
-
- Returns the version of Matlab from a release name
-
- .. note::
-
- This command provides correct versions mappings for Matlab but not MCR.
-
-#]=======================================================================]
+# Public.
macro(matlab_get_version_from_release_name release_name version_name)
string(REGEX MATCHALL "${release_name}=([0-9]+\\.[0-9]+)" _matched ${MATLAB_VERSIONS_MAPPING})
@@ -401,24 +844,7 @@
endmacro()
-
-#[=======================================================================[.rst:
-.. command:: matlab_get_release_name_from_version
-
- .. code-block:: cmake
-
- matlab_get_release_name_from_version(version release_name)
-
- * Input: ``version`` is the version of Matlab (e.g. 23.2.0)
- * Output: ``release_name`` is the release name (R2023b)
-
- Returns the release name from the version of Matlab
-
- .. note::
-
- This command provides correct version mappings for Matlab but not MCR.
-
-#]=======================================================================]
+# Public.
function(matlab_get_release_name_from_version version release_name)
# only the major.minor version is used
@@ -435,7 +861,6 @@
endfunction()
-
# extracts all the supported release names (R2022b...) of Matlab
# internal use
macro(matlab_get_supported_releases list_releases)
@@ -451,8 +876,6 @@
unset(_var)
endmacro()
-
-
# extracts all the supported versions of Matlab
# internal use
macro(matlab_get_supported_versions list_versions)
@@ -468,47 +891,7 @@
unset(_var)
endmacro()
-
-#[=======================================================================[.rst:
-.. command:: matlab_extract_all_installed_versions_from_registry
-
- This function parses the Windows registry and finds the Matlab versions that
- are installed. The found versions are stored in a given ``<versions-var>``.
-
- .. signature::
- matlab_extract_all_installed_versions_from_registry(<versions-var>
- [REGISTRY_VIEW view])
- :target: matlab_extract_all_installed_versions_from_registry-keyword
-
- .. versionadded:: 3.30
-
- * Output: ``<versions-var>`` is a list of all the versions of Matlab found
- * Input: ``REGISTRY_VIEW`` Optional registry view to use for registry
- interaction. The argument is passed (or omitted) to
- :command:`cmake_host_system_information` without further checks or
- modification.
-
- .. signature::
- matlab_extract_all_installed_versions_from_registry(<win64> <versions-var>)
- :target: matlab_extract_all_installed_versions_from_registry-positional
-
- * Input: ``win64`` is a boolean to search for the 64 bit version of
- Matlab. Set to ``ON`` to use the 64bit registry view or ``OFF`` to use the
- 32bit registry view. If finer control is needed, see signature above.
- * Output: ``<versions-var>`` is a list of all the versions of Matlab found
-
- The returned list contains all versions under
- ``HKLM\SOFTWARE\Mathworks\MATLAB``,
- ``HKLM\SOFTWARE\Mathworks\MATLAB Runtime`` and
- ``HKLM\SOFTWARE\Mathworks\MATLAB Compiler Runtime`` or an empty list in
- case an error occurred (or nothing found).
-
- .. note::
-
- Only the versions are provided. No check is made over the existence of the
- installation referenced in the registry,
-
-#]=======================================================================]
+# Public.
function(matlab_extract_all_installed_versions_from_registry win64_or_matlab_versions)
if(NOT CMAKE_HOST_WIN32)
@@ -562,8 +945,6 @@
endfunction()
-
-
# (internal)
macro(extract_matlab_versions_from_registry_brute_force matlab_versions)
# get the supported versions
@@ -579,32 +960,7 @@
set(${matlab_versions} ${matlab_supported_versions})
endmacro()
-
-#[=======================================================================[.rst:
-.. command:: matlab_get_all_valid_matlab_roots_from_registry
-
- Populates the Matlab root with valid versions of Matlab or
- Matlab Runtime (MCR).
- The returned matlab_roots is organized in triplets
- ``(type,version_number,matlab_root_path)``, where ``type``
- indicates either ``MATLAB`` or ``MCR``.
-
- .. code-block:: cmake
-
- matlab_get_all_valid_matlab_roots_from_registry(matlab_versions matlab_roots [REGISTRY_VIEW view])
-
- * Input: ``matlab_versions`` of each of the Matlab or MCR installations
- * Output: ``matlab_roots`` location of each of the Matlab or MCR installations
- * Input: ``REGISTRY_VIEW`` Optional registry view to use for registry
- interaction. The argument is passed (or omitted) to
- :command:`cmake_host_system_information` without further checks or
- modification.
-
- .. versionadded:: 3.30
- The optional ``REGISTRY_VIEW`` argument was added to provide a more precise
- interface on how to interact with the Windows Registry.
-
-#]=======================================================================]
+# Public.
function(matlab_get_all_valid_matlab_roots_from_registry matlab_versions matlab_roots)
# The matlab_versions comes either from
@@ -672,20 +1028,7 @@
set(${matlab_roots} ${_matlab_roots_list} PARENT_SCOPE)
endfunction()
-#[=======================================================================[.rst:
-.. command:: matlab_get_mex_suffix
-
- Returns the extension of the mex files (the suffixes).
- This function should not be called before the appropriate Matlab root has
- been found.
-
- .. code-block:: cmake
-
- matlab_get_mex_suffix(matlab_root mex_suffix)
-
- * Input: ``matlab_root`` root of Matlab/MCR install e.g. ``Matlab_ROOT_DIR``
- * Output: ``mex_suffix`` variable name in which the suffix will be returned.
-#]=======================================================================]
+# Public.
function(matlab_get_mex_suffix matlab_root mex_suffix)
# find_program does not consider script suffix .bat for Matlab mexext.bat on Windows
@@ -761,21 +1104,7 @@
set(${mex_suffix} ${_matlab_mex_extension} PARENT_SCOPE)
endfunction()
-
-#[=======================================================================[.rst:
-.. command:: matlab_get_version_from_matlab_run
-
- This function runs Matlab program specified on arguments and extracts its
- version. If the path provided for the Matlab installation points to an MCR
- installation, the version is extracted from the installed files.
-
- .. code-block:: cmake
-
- matlab_get_version_from_matlab_run(matlab_binary_path matlab_list_versions)
-
- * Input: ``matlab_binary_path`` path of the `matlab` binary executable
- * Output: ``matlab_list_versions`` the version extracted from Matlab
-#]=======================================================================]
+# Public.
function(matlab_get_version_from_matlab_run matlab_binary_program matlab_list_versions)
set(${matlab_list_versions} "" PARENT_SCOPE)
@@ -926,77 +1255,7 @@
endfunction()
-#[=======================================================================[.rst:
-.. command:: matlab_add_unit_test
-
- Adds a Matlab unit test to the test set of cmake/ctest.
- This command requires the component ``MAIN_PROGRAM`` and hence is not
- available for an MCR installation.
-
- The unit test uses the Matlab unittest framework (default, available
- starting Matlab 2013b+) except if the option ``NO_UNITTEST_FRAMEWORK``
- is given.
-
- The function expects one Matlab test script file to be given.
- In the case ``NO_UNITTEST_FRAMEWORK`` is given, the unittest script file
- should contain the script to be run, plus an exit command with the exit
- value. This exit value will be passed to the ctest framework (0 success,
- non 0 failure). Additional arguments accepted by :command:`add_test` can be
- passed through ``TEST_ARGS`` (eg. ``CONFIGURATION <config> ...``).
-
- .. code-block:: cmake
-
- matlab_add_unit_test(
- NAME <name>
- UNITTEST_FILE matlab_file_containing_unittest.m
- [CUSTOM_TEST_COMMAND matlab_command_to_run_as_test]
- [UNITTEST_PRECOMMAND matlab_command_to_run]
- [TIMEOUT timeout]
- [ADDITIONAL_PATH path1 [path2 ...]]
- [MATLAB_ADDITIONAL_STARTUP_OPTIONS option1 [option2 ...]]
- [TEST_ARGS arg1 [arg2 ...]]
- [NO_UNITTEST_FRAMEWORK]
- )
-
- Function Parameters:
-
- ``NAME``
- name of the unittest in ctest.
- ``UNITTEST_FILE``
- the matlab unittest file. Its path will be automatically
- added to the Matlab path.
- ``CUSTOM_TEST_COMMAND``
- Matlab script command to run as the test.
- If this is not set, then the following is run:
- ``runtests('matlab_file_name'), exit(max([ans(1,:).Failed]))``
- where ``matlab_file_name`` is the ``UNITTEST_FILE`` without the extension.
- ``UNITTEST_PRECOMMAND``
- Matlab script command to be ran before the file
- containing the test (eg. GPU device initialization based on CMake
- variables).
- ``TIMEOUT``
- the test timeout in seconds. Defaults to 180 seconds as the
- Matlab unit test may hang.
- ``ADDITIONAL_PATH``
- a list of paths to add to the Matlab path prior to
- running the unit test.
- ``MATLAB_ADDITIONAL_STARTUP_OPTIONS``
- a list of additional option in order
- to run Matlab from the command line.
- ``-nosplash -nodesktop -nodisplay`` are always added.
- ``TEST_ARGS``
- Additional options provided to the add_test command. These
- options are added to the default options (eg. "CONFIGURATIONS Release")
- ``NO_UNITTEST_FRAMEWORK``
- when set, indicates that the test should not
- use the unittest framework of Matlab (available for versions >= R2013a).
- ``WORKING_DIRECTORY``
- This will be the working directory for the test. If specified it will
- also be the output directory used for the log file of the test run.
- If not specified the temporary directory ``${CMAKE_BINARY_DIR}/Matlab`` will
- be used as the working directory and the log location.
-
-#]=======================================================================]
+# Public.
function(matlab_add_unit_test)
if(NOT Matlab_MAIN_PROGRAM)
@@ -1049,93 +1308,7 @@
)
endfunction()
-
-#[=======================================================================[.rst:
-.. command:: matlab_add_mex
-
- Adds a Matlab MEX target.
- This commands compiles the given sources with the current tool-chain in
- order to produce a MEX file. The final name of the produced output may be
- specified, as well as additional link libraries, and a documentation entry
- for the MEX file. Remaining arguments of the call are passed to the
- :command:`add_library` or :command:`add_executable` command.
-
- .. code-block:: cmake
-
- matlab_add_mex(
- NAME <name>
- [EXECUTABLE | MODULE | SHARED]
- SRC src1 [src2 ...]
- [OUTPUT_NAME output_name]
- [DOCUMENTATION file.txt]
- [LINK_TO target1 target2 ...]
- [R2017b | R2018a]
- [EXCLUDE_FROM_ALL]
- [NO_IMPLICIT_LINK_TO_MATLAB_LIBRARIES]
- [...]
- )
-
- Function Parameters:
-
- ``NAME``
- name of the target.
- ``SRC``
- list of source files.
- ``LINK_TO``
- a list of additional link dependencies. The target links to ``libmex``
- and ``libmx`` by default, unless the
- ``NO_IMPLICIT_LINK_TO_MATLAB_LIBRARIES`` option is passed.
- ``OUTPUT_NAME``
- if given, overrides the default name. The default name is
- the name of the target without any prefix and
- with ``Matlab_MEX_EXTENSION`` suffix.
- ``DOCUMENTATION``
- if given, the file ``file.txt`` will be considered as
- being the documentation file for the MEX file. This file is copied into
- the same folder without any processing, with the same name as the final
- mex file, and with extension `.m`. In that case, typing ``help <name>``
- in Matlab prints the documentation contained in this file.
- ``R2017b`` or ``R2018a``
- .. versionadded:: 3.14
-
- May be given to specify the version of the C API
- to use: ``R2017b`` specifies the traditional (separate complex) C API,
- and corresponds to the ``-R2017b`` flag for the `mex` command. ``R2018a``
- specifies the new interleaved complex C API, and corresponds to the
- ``-R2018a`` flag for the `mex` command. Ignored if MATLAB version prior
- to R2018a. Defaults to ``R2017b``.
-
- ``MODULE`` or ``SHARED``
- .. versionadded:: 3.7
-
- May be given to specify the type of library to be
- created.
-
- ``EXECUTABLE``
- .. versionadded:: 3.7
-
- May be given to create an executable instead of
- a library. If no type is given explicitly, the type is ``SHARED``.
- ``EXCLUDE_FROM_ALL``
- This option has the same meaning as for :prop_tgt:`EXCLUDE_FROM_ALL` and
- is forwarded to :command:`add_library` or :command:`add_executable`
- commands.
- ``NO_IMPLICIT_LINK_TO_MATLAB_LIBRARIES``
- .. versionadded:: 3.24
-
- This option permits to disable the automatic linking of MATLAB
- libraries, so that only the libraries that are actually required can be
- linked via the ``LINK_TO`` option.
-
- The documentation file is not processed and should be in the following
- format:
-
- ::
-
- % This is the documentation
- function ret = mex_target_output_name(input1)
-
-#]=======================================================================]
+# Public.
function(matlab_add_mex)
set(options EXECUTABLE MODULE SHARED R2017b R2018a EXCLUDE_FROM_ALL NO_IMPLICIT_LINK_TO_MATLAB_LIBRARIES)
@@ -1331,7 +1504,6 @@
endfunction()
-
# (internal)
# Used to get the version of matlab, using caching. This basically transforms the
# output of the root list, with possible unknown version, to a version
@@ -1477,7 +1649,6 @@
endfunction()
-
function(_Matlab_VersionInfoXML matlab_root _version)
set(_ver "unknown")
@@ -1496,7 +1667,6 @@
endfunction()
-
# Utility function for finding Matlab or MCR on Win32
function(_Matlab_find_instances_win32 matlab_roots)
# On WIN32, we look for Matlab installation in the registry
@@ -1819,7 +1989,6 @@
endif()
-
set(MATLAB_INCLUDE_DIR_TO_LOOK ${Matlab_ROOT_DIR}/extern/include)
if(CMAKE_SIZEOF_VOID_P EQUAL 4)
set(_matlab_current_suffix ${_matlab_bin_suffix_32bits})
@@ -1851,8 +2020,6 @@
message(STATUS "[MATLAB] _matlab_lib_prefix_for_search = ${_matlab_lib_prefix_for_search} | _matlab_lib_dir_for_search = ${_matlab_lib_dir_for_search}")
endif()
-
-
# internal
# This small stub around find_library is to prevent any pollution of CMAKE_FIND_LIBRARY_PREFIXES in the global scope.
# This is the function to be used below instead of the find_library directives.
diff --git a/Modules/GoogleTest.cmake b/Modules/GoogleTest.cmake
index 2fded3f..5f4eaf8 100644
--- a/Modules/GoogleTest.cmake
+++ b/Modules/GoogleTest.cmake
@@ -332,7 +332,7 @@
# Save project's policies
block(SCOPE_FOR POLICIES)
-cmake_policy(VERSION 3.30)
+cmake_policy(VERSION 4.2)
#------------------------------------------------------------------------------
function(gtest_add_tests)
diff --git a/Modules/GoogleTestAddTests.cmake b/Modules/GoogleTestAddTests.cmake
index ceaba3e..8622424 100644
--- a/Modules/GoogleTestAddTests.cmake
+++ b/Modules/GoogleTestAddTests.cmake
@@ -1,8 +1,7 @@
# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
# file LICENSE.rst or https://cmake.org/licensing for details.
-cmake_minimum_required(VERSION 3.30)
-cmake_policy(SET CMP0174 NEW) # TODO: Remove this when we can update the above to 3.31
+cmake_minimum_required(VERSION 4.2)
function(add_command name test_name)
set(args "")
diff --git a/Modules/Internal/CPack/CPackRPM.cmake b/Modules/Internal/CPack/CPackRPM.cmake
index b733cfe..d0454e1 100644
--- a/Modules/Internal/CPack/CPackRPM.cmake
+++ b/Modules/Internal/CPack/CPackRPM.cmake
@@ -445,13 +445,13 @@
endfunction()
function(cpack_rpm_symlink_add_for_relocation_script PACKAGE_PREFIXES SYMLINK SYMLINK_RELOCATION_PATHS POINT POINT_RELOCATION_PATHS)
- list(LENGTH SYMLINK_RELOCATION_PATHS SYMLINK_PATHS_COUTN)
+ list(LENGTH SYMLINK_RELOCATION_PATHS SYMLINK_PATHS_COUNT)
list(LENGTH POINT_RELOCATION_PATHS POINT_PATHS_COUNT)
list(APPEND _RPM_RELOCATION_SCRIPT_PAIRS "${SYMLINK}:${POINT}")
list(LENGTH _RPM_RELOCATION_SCRIPT_PAIRS PAIR_NO)
- if(SYMLINK_PATHS_COUTN)
+ if(SYMLINK_PATHS_COUNT)
foreach(SYMLINK_RELOC_PATH IN LISTS SYMLINK_RELOCATION_PATHS)
list(FIND PACKAGE_PREFIXES "${SYMLINK_RELOC_PATH}" SYMLINK_INDEX)
diff --git a/Modules/UseJava.cmake b/Modules/UseJava.cmake
index b79d8d2..4192169 100644
--- a/Modules/UseJava.cmake
+++ b/Modules/UseJava.cmake
@@ -53,6 +53,7 @@
[SOURCES] <source1> [<source2>...] [<resource1>...]
[RESOURCES NAMESPACE <ns1> <resource1>... [NAMESPACE <nsX> <resourceX>...]... ]
[INCLUDE_JARS <jar1> [<jar2>...]]
+ [INCLUDE_MODULES <jar1> [<jar2>...]]
[ENTRY_POINT <entry>]
[VERSION <version>]
[MANIFEST <manifest>]
@@ -109,6 +110,13 @@
jar files listed as sources are ignored (as they have been since the first
version of this module).
+ ``INCLUDE_MODULES``
+ .. versionadded:: 4.3
+
+ The list of jars are added to the module path when building the java sources
+ and also to the dependencies of the target. ``INCLUDE_MODULES`` also
+ accepts other target names created by ``add_jar()``.
+
``ENTRY_POINT``
Defines an entry point in the jar file.
@@ -568,6 +576,9 @@
generated docs. Same behavior as option ``-version`` of ``javadoc`` tool.
#]=======================================================================]
+block(SCOPE_FOR POLICIES)
+cmake_policy(SET CMP0140 NEW) # For return(PROPAGATE ...)
+
function (__java_copy_file src dest comment)
add_custom_command(
OUTPUT ${dest}
@@ -665,11 +676,42 @@
set(_UseJava_PATH_SEP ":")
endif()
+function(__java_resolve_jar outvar_path path_or_tgt)
+ if (TARGET "${path_or_tgt}")
+ # Check if this is a target created by add_jar
+ get_target_property(jarpath "${path_or_tgt}" JAR_FILE)
+ set("${outvar_path}" "${jarpath}")
+ if (NOT jarpath) # Some other target that we do not know how to use as a JAR
+ message(SEND_ERROR "target ${path_or_tgt} is not a jar")
+ endif ()
+ else () # Interpreted as the path to an external JAR
+ set("${outvar_path}" "${path_or_tgt}")
+ endif ()
+ return(PROPAGATE "${outvar_path}")
+endfunction()
+
+# Helper that processes a list of add_jar-created targets or paths to external
+# JAR files and:
+# - appends each item (target name or JAR path) to the list in outvar_depsraw.
+# - appends the resolved JAR path to the list in outvar_depsresolved.
+# If any item cannot be resolved, because it is a target name that was not
+# created by add_jar, a SEND_ERROR message is raised.
+function(__java_build_deplists outvar_depsraw outvar_depsresolved jars_or_targets_lst)
+ foreach(item IN LISTS "${jars_or_targets_lst}")
+ __java_resolve_jar(res_path "${item}")
+ if (res_path) # We would get a falsy value in the error case
+ list(APPEND "${outvar_depsraw}" "${item}") # Keep the original name (possibly a target) here
+ list(APPEND "${outvar_depsresolved}" "${res_path}")
+ endif ()
+ endforeach()
+ return(PROPAGATE "${outvar_depsraw}" "${outvar_depsresolved}")
+endfunction()
+
function(add_jar _TARGET_NAME)
set(options) # currently there are no zero value args (aka: options)
set(oneValueArgs "ENTRY_POINT;MANIFEST;OUTPUT_DIR;;OUTPUT_NAME;VERSION" )
- set(multiValueArgs "GENERATE_NATIVE_HEADERS;INCLUDE_JARS;RESOURCES;SOURCES" )
+ set(multiValueArgs "GENERATE_NATIVE_HEADERS;INCLUDE_JARS;INCLUDE_MODULES;RESOURCES;SOURCES" )
cmake_parse_arguments(PARSE_ARGV 1 _add_jar
"${options}"
@@ -803,6 +845,7 @@
set(_JAVA_COMPILE_FILELISTS)
set(_JAVA_DEPENDS)
set(_JAVA_COMPILE_DEPENDS)
+ set(_JAVA_COMPILE_MODDEPENDS)
set(_JAVA_RESOURCE_FILES)
set(_JAVA_RESOURCE_FILES_RELATIVE)
foreach(_JAVA_SOURCE_FILE IN LISTS _JAVA_SOURCE_FILES)
@@ -838,7 +881,8 @@
# Ignored for backward compatibility
elseif (_JAVA_EXT STREQUAL "")
- list(APPEND CMAKE_JAVA_INCLUDE_PATH ${JAVA_JAR_TARGET_${_JAVA_SOURCE_FILE}} ${JAVA_JAR_TARGET_${_JAVA_SOURCE_FILE}_CLASSPATH})
+ # XXX: this was not being used after setting!
+ # list(APPEND CMAKE_JAVA_INCLUDE_PATH ${JAVA_JAR_TARGET_${_JAVA_SOURCE_FILE}} ${JAVA_JAR_TARGET_${_JAVA_SOURCE_FILE}_CLASSPATH})
list(APPEND _JAVA_DEPENDS ${JAVA_JAR_TARGET_${_JAVA_SOURCE_FILE}})
else ()
@@ -857,24 +901,21 @@
_JAVA_RESOURCE_FILES_RELATIVE)
endif()
- foreach(_JAVA_INCLUDE_JAR IN LISTS _add_jar_INCLUDE_JARS)
- if (TARGET ${_JAVA_INCLUDE_JAR})
- get_target_property(_JAVA_JAR_PATH ${_JAVA_INCLUDE_JAR} JAR_FILE)
- if (_JAVA_JAR_PATH)
- string(APPEND CMAKE_JAVA_INCLUDE_PATH_FINAL "${_UseJava_PATH_SEP}${_JAVA_JAR_PATH}")
- list(APPEND CMAKE_JAVA_INCLUDE_PATH ${_JAVA_JAR_PATH})
- list(APPEND _JAVA_DEPENDS ${_JAVA_INCLUDE_JAR})
- list(APPEND _JAVA_COMPILE_DEPENDS ${_JAVA_JAR_PATH})
- else ()
- message(SEND_ERROR "add_jar: INCLUDE_JARS target ${_JAVA_INCLUDE_JAR} is not a jar")
- endif ()
- else ()
- string(APPEND CMAKE_JAVA_INCLUDE_PATH_FINAL "${_UseJava_PATH_SEP}${_JAVA_INCLUDE_JAR}")
- list(APPEND CMAKE_JAVA_INCLUDE_PATH "${_JAVA_INCLUDE_JAR}")
- list(APPEND _JAVA_DEPENDS "${_JAVA_INCLUDE_JAR}")
- list(APPEND _JAVA_COMPILE_DEPENDS "${_JAVA_INCLUDE_JAR}")
- endif ()
- endforeach()
+ # Build dependency lists and arguments for JARs in the classpath
+ __java_build_deplists(_JAVA_DEPENDS _JAVA_COMPILE_DEPENDS _add_jar_INCLUDE_JARS)
+ foreach (resolved_cp_item IN LISTS _JAVA_COMPILE_DEPENDS)
+ string(APPEND CMAKE_JAVA_INCLUDE_PATH_FINAL "${_UseJava_PATH_SEP}${resolved_cp_item}")
+ endforeach ()
+ # Build dependency lists and arguments for JARs in the modulepath
+ set(javac_mp_args)
+ if (_add_jar_INCLUDE_MODULES)
+ if (Java_VERSION VERSION_LESS 9)
+ message(SEND_ERROR "INCLUDE_MODULES requires Java 9+")
+ endif()
+ __java_build_deplists(_JAVA_DEPENDS _JAVA_COMPILE_MODDEPENDS _add_jar_INCLUDE_MODULES)
+ list(JOIN _JAVA_COMPILE_MODDEPENDS "${_UseJava_PATH_SEP}" javac_mp_args)
+ set(javac_mp_args "--module-path [[${javac_mp_args}]]")
+ endif()
if (_JAVA_COMPILE_FILES OR _JAVA_COMPILE_FILELISTS)
set (_JAVA_SOURCES_FILELISTS)
@@ -899,33 +940,41 @@
cmake_language(GET_MESSAGE_LOG_LEVEL _LOG_LEVEL)
# Compile the java files and create a list of class files
- add_custom_command(
- # NOTE: this command generates an artificial dependency file
- OUTPUT ${CMAKE_JAVA_CLASS_OUTPUT_PATH}/java_compiled_${_TARGET_NAME}
+ # NOTE: this command generates an artificial dependency file
+ set(stamp_file "${CMAKE_JAVA_CLASS_OUTPUT_PATH}/java_compiled_${_TARGET_NAME}")
+ add_custom_command(OUTPUT "${stamp_file}"
COMMAND ${CMAKE_COMMAND}
-DCMAKE_JAVA_CLASS_OUTPUT_PATH=${CMAKE_JAVA_CLASS_OUTPUT_PATH}
-DCMAKE_JAR_CLASSES_PREFIX=${CMAKE_JAR_CLASSES_PREFIX}
-P ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/UseJava/ClearClassFiles.cmake
--log-level ${_LOG_LEVEL}
- COMMAND ${Java_JAVAC_EXECUTABLE}
- ${CMAKE_JAVA_COMPILE_FLAGS}
- -classpath "${CMAKE_JAVA_INCLUDE_PATH_FINAL}"
- -d ${CMAKE_JAVA_CLASS_OUTPUT_PATH}
- ${_GENERATE_NATIVE_HEADERS}
- ${_JAVA_SOURCES_FILELISTS}
- COMMAND ${CMAKE_COMMAND} -E touch ${CMAKE_JAVA_CLASS_OUTPUT_PATH}/java_compiled_${_TARGET_NAME}
- DEPENDS ${_JAVA_COMPILE_FILES} ${_JAVA_COMPILE_FILELISTS} ${_JAVA_COMPILE_DEPENDS} ${_JAVA_SOURCES_FILE}
+ DEPENDS ${_JAVA_COMPILE_FILES} ${_JAVA_COMPILE_FILELISTS} ${_JAVA_COMPILE_DEPENDS} ${_JAVA_COMPILE_MODDEPENDS} ${_JAVA_SOURCES_FILE}
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
COMMENT "Building Java objects for ${_TARGET_NAME}.jar"
VERBATIM
)
+ cmake_language(EVAL CODE "
+ add_custom_command(OUTPUT [[${stamp_file}]]
+ APPEND COMMAND [[${Java_JAVAC_EXECUTABLE}]]
+ \${CMAKE_JAVA_COMPILE_FLAGS}
+ -classpath [[${CMAKE_JAVA_INCLUDE_PATH_FINAL}]]
+ ${javac_mp_args}
+ -d [[${CMAKE_JAVA_CLASS_OUTPUT_PATH}]]
+ \${_GENERATE_NATIVE_HEADERS}
+ \${_JAVA_SOURCES_FILELISTS}
+ )
+ ")
+ add_custom_command(OUTPUT "${stamp_file}"
+ APPEND COMMAND ${CMAKE_COMMAND} -E touch "${stamp_file}"
+ )
+
add_custom_command(
OUTPUT ${CMAKE_JAVA_CLASS_OUTPUT_PATH}/java_class_filelist
COMMAND ${CMAKE_COMMAND}
-DCMAKE_JAVA_CLASS_OUTPUT_PATH=${CMAKE_JAVA_CLASS_OUTPUT_PATH}
-DCMAKE_JAR_CLASSES_PREFIX=${CMAKE_JAR_CLASSES_PREFIX}
-P ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/UseJava/ClassFilelist.cmake
- DEPENDS ${CMAKE_JAVA_CLASS_OUTPUT_PATH}/java_compiled_${_TARGET_NAME}
+ DEPENDS "${stamp_file}"
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
VERBATIM
)
@@ -1725,3 +1774,5 @@
DESTINATION ${_install_jar_exports_DESTINATION}
${_COMPONENT})
endfunction()
+
+endblock()
diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt
index 44f87db..c76eee4 100644
--- a/Source/CMakeLists.txt
+++ b/Source/CMakeLists.txt
@@ -701,6 +701,8 @@
cmRemoveDefinitionsCommand.h
cmReturnCommand.cxx
cmReturnCommand.h
+ cmSbomObject.h
+ cmSbomSerializer.h
cmSearchPath.cxx
cmSearchPath.h
cmSeparateArgumentsCommand.cxx
@@ -721,9 +723,10 @@
cmSiteNameCommand.h
cmSourceGroupCommand.cxx
cmSourceGroupCommand.h
- cmSPDXSerializer.cxx
- cmSPDXSerializer.h
- cmSPDXTypes.def
+ cmSpdx.cxx
+ cmSpdx.h
+ cmSpdxSerializer.cxx
+ cmSpdxSerializer.h
cmString.cxx
cmString.hxx
cmStringReplaceHelper.cxx
diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake
index fd83e70..be0a659 100644
--- a/Source/CMakeVersion.cmake
+++ b/Source/CMakeVersion.cmake
@@ -1,8 +1,8 @@
# CMake version number components.
set(CMake_VERSION_MAJOR 4)
set(CMake_VERSION_MINOR 2)
-set(CMake_VERSION_PATCH 0)
-set(CMake_VERSION_RC 1)
+set(CMake_VERSION_PATCH 20251028)
+#set(CMake_VERSION_RC 0)
set(CMake_VERSION_IS_DIRTY 0)
# Start with the full version number used in tags. It has no dev info.
diff --git a/Source/cmNinjaTargetGenerator.cxx b/Source/cmNinjaTargetGenerator.cxx
index c9cec0d..842130a 100644
--- a/Source/cmNinjaTargetGenerator.cxx
+++ b/Source/cmNinjaTargetGenerator.cxx
@@ -1698,10 +1698,10 @@
if (ispcSuffixes.size() > 1) {
std::string rootObjectDir =
this->GeneratorTarget->GetObjectDirectory(config);
- auto ispcSideEfffectObjects = detail::ComputeISPCExtraObjects(
+ auto ispcSideEffectObjects = detail::ComputeISPCExtraObjects(
objectName, rootObjectDir, ispcSuffixes);
- for (auto sideEffect : ispcSideEfffectObjects) {
+ for (auto sideEffect : ispcSideEffectObjects) {
sideEffect = this->ConvertToNinjaPath(sideEffect);
objBuild.ImplicitOuts.emplace_back(sideEffect);
this->GetGlobalGenerator()->AddAdditionalCleanFile(sideEffect, config);
diff --git a/Source/cmSPDXSerializer.cxx b/Source/cmSPDXSerializer.cxx
deleted file mode 100644
index 7d22103..0000000
--- a/Source/cmSPDXSerializer.cxx
+++ /dev/null
@@ -1,1375 +0,0 @@
-/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
- file LICENSE.rst or https://cmake.org/licensing for details. */
-#include "cmSPDXSerializer.h"
-
-#include <new>
-#include <string>
-
-#include <cm/optional>
-
-#include <cm3p/json/value.h>
-
-// Serialization Utilities
-
-template <typename T>
-void addVectorSPDXValue(Json::Value& obj, std::string const& key,
- std::vector<T> const& vec)
-{
- auto& list = obj[key];
- list = Json::Value(Json::arrayValue);
- for (auto const& val : vec) {
- list.append(val.toJsonLD());
- }
-}
-
-template <>
-void addVectorSPDXValue(Json::Value& obj, std::string const& key,
- std::vector<std::string> const& vec)
-{
- auto& list = obj[key];
- list = Json::Value(Json::arrayValue);
- for (auto const& val : vec) {
- list.append(val);
- }
-}
-
-template <typename T>
-void addOptionalSPDXValue(Json::Value& obj, std::string const& key,
- cm::optional<std::vector<T>> const& opt)
-{
- if (opt) {
- addVectorSPDXValue(obj, key, *opt);
- }
-}
-
-template <typename T>
-void addOptionalSPDXValue(Json::Value& obj, std::string const& key,
- cm::optional<T> const& opt)
-{
- if (opt) {
- obj[key] = opt->toJsonLD();
- }
-}
-
-template <>
-void addOptionalSPDXValue(Json::Value& obj, std::string const& key,
- cm::optional<std::string> const& opt)
-{
- if (opt) {
- obj[key] = *opt;
- }
-}
-
-// Base Class
-
-cmSPDXSerializationBase::SPDXTypeId cmSPDXSerializationBase::getTypeId() const
-{
- return TypeId;
-}
-
-cmSPDXSerializationBase::cmSPDXSerializationBase(SPDXTypeId id)
- : TypeId(id)
-{
-}
-
-cmSPDXSerializationBase::cmSPDXSerializationBase(SPDXTypeId id,
- std::string nodeId)
- : NodeId(std::move(nodeId))
- , TypeId(id)
-{
-}
-
-// Convenience Classes
-
-cmSPDXIdentifierReference::cmSPDXIdentifierReference()
- : cmSPDXSerializationBase(CM_IDENTIFIER_REFERENCE)
-{
-}
-cmSPDXIdentifierReference::cmSPDXIdentifierReference(
- cmSPDXSerializationBase const& ref)
- : cmSPDXSerializationBase(CM_IDENTIFIER_REFERENCE, ref.NodeId)
-{
-}
-cmSPDXIdentifierReference::cmSPDXIdentifierReference(std::string const& ref)
- : cmSPDXSerializationBase(CM_IDENTIFIER_REFERENCE, ref)
-{
-}
-
-Json::Value cmSPDXIdentifierReference::toJsonLD() const
-{
- return NodeId;
-}
-
-cmSPDXNonElementBase::cmSPDXNonElementBase(SPDXTypeId id)
- : cmSPDXSerializationBase(id)
-{
-}
-
-Json::Value cmSPDXNonElementBase::toJsonLD() const
-{
- Json::Value obj(Json::objectValue);
- obj["@id"] = NodeId;
- return obj;
-}
-
-// SPDX Core Enums
-
-cmSPDXAnnotationType::cmSPDXAnnotationType(cmSPDXAnnotationTypeId typeId)
- : TypeId(typeId)
-{
-}
-
-Json::Value cmSPDXAnnotationType::toJsonLD() const
-{
- switch (TypeId) {
- case OTHER:
- return "other";
- case REVIEW:
- return "review";
- default:
- return "INVALID_ANNOTATION_TYPE_ID";
- }
-}
-
-cmSPDXExternalIdentifierType::cmSPDXExternalIdentifierType(
- cmSPDXExternalIdentifierTypeId typeId)
- : TypeId(typeId)
-{
-}
-
-Json::Value cmSPDXExternalIdentifierType::toJsonLD() const
-{
- switch (TypeId) {
- case CPE22:
- return "cpe22";
- case CPE23:
- return "cpe23";
- case CVE:
- return "cve";
- case EMAIL:
- return "email";
- case GITOID:
- return "gitoid";
- case OTHER:
- return "other";
- case PACKAGE_URL:
- return "packageUrl";
- case SECURITY_OTHER:
- return "securityOther";
- case SWHID:
- return "swhid";
- case SWID:
- return "swid";
- case URL_SCHEME:
- return "urlScheme";
- default:
- return "INVALID_EXTERNAL_IDENTIFIER_TYPE_ID";
- }
-}
-
-cmSPDXExternalRefType::cmSPDXExternalRefType(cmSPDXExternalRefTypeId typeId)
- : TypeId(typeId)
-{
-}
-
-Json::Value cmSPDXExternalRefType::toJsonLD() const
-{
- switch (TypeId) {
- case ALT_DOWNLOAD_LOCATION:
- return "altDownloadLocation:";
- case ALT_WEB_PAGE:
- return "altWebPage";
- case BINARY_ARTIFACT:
- return "binaryArtifact";
- case BOWER:
- return "bower";
- case BUILD_META:
- return "buildMeta";
- case BUILD_SYSTEM:
- return "buildSystem";
- case CERTIFICATION_REPORT:
- return "certificationReport";
- case CHAT:
- return "chat";
- case COMPONENT_ANALYSIS_REPORT:
- return "componentAnalysisReport";
- case CWE:
- return "cwe";
- case DOCUMENTATION:
- return "documentation";
- case DYNAMIC_ANALYSIS_REPORT:
- return "dynamicAnalysisReport";
- case EOL_NOTICE:
- return "eolNotice";
- case EXPORT_CONTROL_ASSESSMENT:
- return "exportControlAssessment";
- case FUNDING:
- return "funding";
- case ISSUE_TRACKER:
- return "issueTracker";
- case LICENSE:
- return "license";
- case MAILING_LIST:
- return "mailingList";
- case MAVEN_CENTRAL:
- return "mavenCentral";
- case METRICS:
- return "metrics";
- case NPM:
- return "npm";
- case NUGET:
- return "nuget";
- case OTHER:
- return "other";
- case PRIVACY_ASSESSMENT:
- return "privacyAssessment";
- case PRODUCT_METADATA:
- return "productMetadata";
- case PURCHASE_ORDER:
- return "purchaseOrder";
- case QUALITY_ASSESSMENT_REPORT:
- return "qualityAssessmentReport";
- case RELEASE_HISTORY:
- return "releaseHistory";
- case RELEASE_NOTES:
- return "releaseNotes";
- case RISK_ASSESSMENT:
- return "riskAssessment";
- case RUNTIME_ANALYSIS_REPORT:
- return "runtimeAnalysisReport";
- case SECURE_SOFTWARE_ATTESTATION:
- return "secureSoftwareAttestation";
- case SECURITY_ADVERSARY_MODEL:
- return "securityAdversaryModel";
- case SECURITY_ADVISORY:
- return "securityAdvisory";
- case SECURITY_FIX:
- return "securityFix";
- case SECURITY_OTHER:
- return "securityOther";
- case SECURITY_PEN_TEST_REPORT:
- return "securityPenTestReport";
- case SECURITY_POLICY:
- return "securityPolicy";
- case SECURITY_THREAT_MODEL:
- return "securityThreatModel";
- case SOCIAL_MEDIA:
- return "socialMedia";
- case SOURCE_ARTIFACT:
- return "sourceArtifact";
- case STATIC_ANALYSIS_REPORT:
- return "staticAnalysisReport";
- case SUPPORT:
- return "support";
- case VCS:
- return "vcs";
- case VULNERABILITY_DISCLOSURE_REPORT:
- return "vulnerabilityDisclosureReport";
- case VULNERABILITY_EXPLOITABILITY_ASSESSMENT:
- return "vulnerabilityExploitabilityAssessment";
- default:
- return "INVALID_EXTERNAL_REF_TYPE_ID";
- }
-}
-
-cmSPDXHashAlgorithm::cmSPDXHashAlgorithm(cmSPDXHashAlgorithmId typeId)
- : TypeId(typeId)
-{
-}
-
-Json::Value cmSPDXHashAlgorithm::toJsonLD() const
-{
- switch (TypeId) {
- case ADLER32:
- return "adler32";
- case BLAKE2B256:
- return "blake2b256";
- case BLAKE2B384:
- return "blake2b384";
- case BLAKE2B512:
- return "blake2b512";
- case BLAKE3:
- return "blake3";
- case CRYSTALS_DILITHIUM:
- return "crystalsDilithium";
- case CRYSTALS_KYBER:
- return "crystalsLyber";
- case FALCON:
- return "falcon";
- case MD2:
- return "md2";
- case MD4:
- return "md4";
- case MD5:
- return "md5";
- case MD6:
- return "md6";
- case OTHER:
- return "other";
- case SHA1:
- return "sha1";
- case SHA224:
- return "sha224";
- case SHA256:
- return "sha256";
- case SHA384:
- return "sha384";
- case SHA3_224:
- return "sha3_224";
- case SHA3_256:
- return "sha3_256";
- case SHA3_384:
- return "sha3_384";
- case SHA3_512:
- return "sha3_512";
- case SHA512:
- return "sha512";
- default:
- return "INVALID_HASH_TYPE_ID";
- }
-}
-
-cmSPDXLifecycleScopeType::cmSPDXLifecycleScopeType(
- cmSPDXLifecycleScopeTypeId typeId)
- : TypeId(typeId)
-{
-}
-
-Json::Value cmSPDXLifecycleScopeType::toJsonLD() const
-{
- switch (TypeId) {
- case BUILD:
- return "build";
- case DESIGN:
- return "design";
- case DEVELOPMENT:
- return "development";
- case OTHER:
- return "other";
- case RUNTIME:
- return "runtime";
- case TEST:
- return "test";
- default:
- return "INVALID_LIFECYCLE_SCOPE_TYPE_ID";
- }
-}
-
-cmSPDXProfileIdentifierType::cmSPDXProfileIdentifierType(
- cmSPDXProfileIdentifierTypeId typeId)
- : TypeId(typeId)
-{
-}
-
-Json::Value cmSPDXProfileIdentifierType::toJsonLD() const
-{
- switch (TypeId) {
- case AI:
- return "ai";
- case BUILD:
- return "build";
- case CORE:
- return "code";
- case DATASET:
- return "dataset";
- case EXPANDED_LICENSING:
- return "expandedLicensing";
- case EXTENSION:
- return "extension";
- case LITE:
- return "lite";
- case SECURITY:
- return "security";
- case SIMPLE_LICENSING:
- return "simpleLicensing";
- case SOFTWARE:
- return "software";
- default:
- return "INVALID_PROFILE_IDENTIFIER_TYPE_ID";
- }
-}
-
-cmSPDXRelationshipCompletenessType::cmSPDXRelationshipCompletenessType(
- cmSPDXRelationshipCompletenessTypeId typeId)
- : TypeId(typeId)
-{
-}
-
-Json::Value cmSPDXRelationshipCompletenessType::toJsonLD() const
-{
- switch (TypeId) {
- case COMPLETE:
- return "complete";
- case INCOMPLETE:
- return "incomplete";
- case NO_ASSERTION:
- return "noAssertion";
- default:
- return "INVALID_RELATIONSHIP_COMPLETENESS_TYPE_ID";
- }
-}
-
-cmSPDXRelationshipType::cmSPDXRelationshipType(cmSPDXRelationshipTypeId typeId)
- : TypeId(typeId)
-{
-}
-
-Json::Value cmSPDXRelationshipType::toJsonLD() const
-{
- switch (TypeId) {
- case AFFECTS:
- return "affects";
- case AMENDED_BY:
- return "amendedBy";
- case ANCESTOR_OF:
- return "ancestorOf";
- case AVAILABLE_FROM:
- return "availableFrom";
- case CONFIGURES:
- return "configures";
- case CONTAINS:
- return "contains";
- case COORDINATED_BY:
- return "coordinatedBy";
- case COPIED_TO:
- return "copiedTo";
- case DELEGATED_TO:
- return "delegatedTo";
- case DEPENDS_ON:
- return "dependsOn";
- case DESCENDANT_OF:
- return "descendantOf";
- case DESCRIBES:
- return "describes";
- case DOES_NOT_AFFECT:
- return "doesNotAffect";
- case EXPANDS_TO:
- return "expandsTo";
- case EXPLOIT_CREATED_BY:
- return "exploitCreatedBy";
- case FIXED_BY:
- return "fixedBy";
- case FIXED_IN:
- return "fixedIn";
- case FOUND_BY:
- return "foundBy";
- case GENERATES:
- return "generates";
- case HAS_ADDED_FILE:
- return "hasAddedFile";
- case HAS_ASSESSMENT_FOR:
- return "hasAssessmentFor";
- case HAS_ASSOCIATED_VULNERABILITY:
- return "hasAssociatedVulnerability";
- case HAS_CONCLUDED_LICENSE:
- return "hasConcludedLicense";
- case HAS_DATA_FILE:
- return "hasDataFile";
- case HAS_DECLARED_LICENSE:
- return "hasDeclaredLicense";
- case HAS_DELETED_FILE:
- return "hasDeletedFile";
- case HAS_DEPENDENCY_MANIFEST:
- return "hasDependencyManifest";
- case HAS_DISTRIBUTION_ARTIFACT:
- return "hasDistributionArtifact";
- case HAS_DOCUMENTATION:
- return "hasDocumentation";
- case HAS_DYNAMIC_LINK:
- return "hasDynamicLink";
- case HAS_EVIDENCE:
- return "hasEvidence";
- case HAS_EXAMPLE:
- return "hasExample";
- case HAS_HOST:
- return "hasHost";
- case HAS_INPUT:
- return "hasInput";
- case HAS_METADATA:
- return "hasMetadata";
- case HAS_OPTIONAL_COMPONENT:
- return "hasOptionalComponent";
- case HAS_OPTIONAL_DEPENDENCY:
- return "hasOptionalDependency";
- case HAS_OUTPUT:
- return "hasOutput";
- case HAS_PREREQUISITE:
- return "hasPrerequisite";
- case HAS_PROVIDED_DEPENDENCY:
- return "hasProvidedDependency";
- case HAS_REQUIREMENT:
- return "hasRequirement";
- case HAS_SPECIFICATION:
- return "hasSpecification";
- case HAS_STATIC_LINK:
- return "hasStaticLink";
- case HAS_TEST:
- return "hasTest";
- case HAS_TEST_CASE:
- return "hasTestCase";
- case HAS_VARIANT:
- return "hasVariant";
- case INVOKED_BY:
- return "invokedBy";
- case MODIFIED_BY:
- return "modifiedBy";
- case OTHER:
- return "other";
- case PACKAGED_BY:
- return "packagedBy";
- case PATCHED_BY:
- return "patchedBy";
- case PUBLISHED_BY:
- return "publishedBy";
- case REPORTED_BY:
- return "reportedBy";
- case REPUBLISHED_BY:
- return "republishedBy";
- case SERIALIZED_IN_ARTIFACT:
- return "serializedInArtifact";
- case TESTED_ON:
- return "testedOn";
- case TRAINED_ON:
- return "trainedOn";
- case UNDER_INVESTIGATION_FOR:
- return "underInvestigationFor";
- case USES_TOOL:
- return "usesTool";
- default:
- return "INVALID_RELATIONSHIP_TYPE_ID";
- }
-}
-
-cmSPDXSupportType::cmSPDXSupportType(cmSPDXSupportTypeId typeId)
- : TypeId(typeId)
-{
-}
-
-Json::Value cmSPDXSupportType::toJsonLD() const
-{
- switch (TypeId) {
- case DEPLOYED:
- return "deployed";
- case DEVELOPMENT:
- return "development";
- case END_OF_SUPPORT:
- return "endOfSupport";
- case LIMITED_SUPPORT:
- return "limitedSupport";
- case NO_ASSERTION:
- return "noAssertion";
- case NO_SUPPORT:
- return "noSupport";
- case SUPPORT:
- return "support";
- default:
- return "INVALID_SUPPORT_TYPE_ID";
- }
-}
-
-// SPDX Core NonElement Classes, Abstract
-
-cmSPDXIntegrityMethod::cmSPDXIntegrityMethod(SPDXTypeId id)
- : cmSPDXNonElementBase(id)
-{
-}
-
-Json::Value cmSPDXIntegrityMethod::toJsonLD() const
-{
- auto obj = cmSPDXNonElementBase::toJsonLD();
- addOptionalSPDXValue(obj, "comment", Comment);
- return obj;
-}
-
-// SPDX Core NonElement Classes, Concrete
-
-cmSPDXCreationInfo::cmSPDXCreationInfo()
- : cmSPDXNonElementBase(CORE_CREATION_INFO)
-{
-}
-
-Json::Value cmSPDXCreationInfo::toJsonLD() const
-{
- auto obj = cmSPDXNonElementBase::toJsonLD();
- obj["type"] = "CreationInfo";
- addOptionalSPDXValue(obj, "Comment", Comment);
- obj["created"] = Created;
- addVectorSPDXValue(obj, "createdBy", CreatedBy);
- addOptionalSPDXValue(obj, "createdUsing", CreatedUsing);
- return obj;
-}
-
-cmSPDXDictionaryEntry::cmSPDXDictionaryEntry()
- : cmSPDXNonElementBase(CORE_DICTIONARY_ENTRY)
-{
-}
-cmSPDXDictionaryEntry::cmSPDXDictionaryEntry(std::string key)
- : cmSPDXNonElementBase(CORE_DICTIONARY_ENTRY)
- , Key(std::move(key))
-{
-}
-cmSPDXDictionaryEntry::cmSPDXDictionaryEntry(std::string key, std::string val)
- : cmSPDXNonElementBase(CORE_DICTIONARY_ENTRY)
- , Key(std::move(key))
- , Value(std::move(val))
-{
-}
-
-Json::Value cmSPDXDictionaryEntry::toJsonLD() const
-{
- auto obj = cmSPDXNonElementBase::toJsonLD();
- obj["type"] = "DictionaryEntry";
- obj["key"] = Key;
- addOptionalSPDXValue(obj, "value", Value);
- return obj;
-}
-
-cmSPDXExternalIdentifier::cmSPDXExternalIdentifier()
- : cmSPDXNonElementBase(CORE_EXTERNAL_IDENTIFIER)
-{
-}
-
-Json::Value cmSPDXExternalIdentifier::toJsonLD() const
-{
- auto obj = cmSPDXNonElementBase::toJsonLD();
- obj["type"] = "ExternalIdentifier";
- addOptionalSPDXValue(obj, "comment", Comment);
- obj["externalIdentifierType"] = ExternalIdentifierType.toJsonLD();
- obj["identifier"] = Identifier;
- addOptionalSPDXValue(obj, "identifierLocator", IdentifierLocator);
- addOptionalSPDXValue(obj, "issuingAuthority", IssuingAuthority);
- return obj;
-}
-
-cmSPDXExternalMap::cmSPDXExternalMap()
- : cmSPDXNonElementBase(CORE_EXTERNAL_MAP)
-{
-}
-
-Json::Value cmSPDXExternalMap::toJsonLD() const
-{
- auto obj = cmSPDXNonElementBase::toJsonLD();
- obj["type"] = "ExternalMap";
- addOptionalSPDXValue(obj, "definingArtifact", DefiningArtifact);
- obj["externalSpdxId"] = ExternalSpdxId;
- addOptionalSPDXValue(obj, "locationHint", LocationHint);
- addOptionalSPDXValue(obj, "integrityMethod", IntegrityMethod);
- return obj;
-}
-
-cmSPDXExternalRef::cmSPDXExternalRef()
- : cmSPDXNonElementBase(CORE_EXTERNAL_REF)
-{
-}
-
-Json::Value cmSPDXExternalRef::toJsonLD() const
-{
- auto obj = cmSPDXNonElementBase::toJsonLD();
- obj["type"] = "ExternalRef";
- addOptionalSPDXValue(obj, "comment", Comment);
- addOptionalSPDXValue(obj, "contentType", ContentType);
- addOptionalSPDXValue(obj, "externalRefType", ExternalRefType);
- addOptionalSPDXValue(obj, "locator", Locator);
- return obj;
-}
-
-cmSPDXHash::cmSPDXHash()
- : cmSPDXIntegrityMethod(CORE_HASH)
-{
-}
-
-Json::Value cmSPDXHash::toJsonLD() const
-{
- auto obj = cmSPDXIntegrityMethod::toJsonLD();
- obj["type"] = "Hash";
- obj["algorithm"] = Algorithm.toJsonLD();
- obj["hashValue"] = HashValue;
- return obj;
-}
-
-cmSPDXNamespaceMap::cmSPDXNamespaceMap()
- : cmSPDXNonElementBase(CORE_NAMESPACE_MAP)
-{
-}
-
-Json::Value cmSPDXNamespaceMap::toJsonLD() const
-{
- auto obj = cmSPDXNonElementBase::toJsonLD();
- obj["type"] = "NamespaceMap";
- obj["namespace"] = Namespace;
- obj["prefix"] = Namespace;
- return obj;
-}
-
-cmSPDXPackageVerificationCode::cmSPDXPackageVerificationCode()
- : cmSPDXIntegrityMethod(CORE_PACKAGE_VERIFICATION_CODE)
-{
-}
-
-Json::Value cmSPDXPackageVerificationCode::toJsonLD() const
-{
- auto obj = cmSPDXIntegrityMethod::toJsonLD();
- obj["type"] = "PackageVerificationCode";
- obj["algorithm"] = Algorithm.toJsonLD();
- obj["hashValue"] = HashValue;
- return obj;
-}
-
-cmSPDXPositiveIntegerRange::cmSPDXPositiveIntegerRange(
- unsigned int beingIntegerRange, unsigned int endIntegerRange)
- : cmSPDXNonElementBase(CORE_POSITIVE_INTEGER_RANGE)
- , BeginIntegerRange(beingIntegerRange)
- , EndIntegerRange(endIntegerRange)
-{
-}
-
-Json::Value cmSPDXPositiveIntegerRange::toJsonLD() const
-{
- auto obj = cmSPDXNonElementBase::toJsonLD();
- obj["type"] = "PositiveIntegerRange";
- obj["beginIntegerRange"] = BeginIntegerRange;
- obj["endIntegerRange"] = EndIntegerRange;
- return obj;
-}
-
-// SPDX Core Element Classes, Abstract
-
-cmSPDXElement::cmSPDXElement(SPDXTypeId id,
- cmSPDXCreationInfo const& creationInfo)
- : cmSPDXSerializationBase(id)
- , CreationInfo(creationInfo)
-{
-}
-
-Json::Value cmSPDXElement::toJsonLD() const
-{
- Json::Value obj(Json::objectValue);
- addOptionalSPDXValue(obj, "comment", Comment);
- obj["creationInfo"] = CreationInfo.toJsonLD();
- addOptionalSPDXValue(obj, "description", Description);
- addOptionalSPDXValue(obj, "extension", Extension);
- addOptionalSPDXValue(obj, "externalIdentifier", ExternalIdentifier);
- addOptionalSPDXValue(obj, "externalRef", ExternalRef);
- addOptionalSPDXValue(obj, "name", Name);
- obj["spdxId"] = NodeId;
- addOptionalSPDXValue(obj, "summary", Summary);
- addOptionalSPDXValue(obj, "verifiedUsing", VerifiedUsing);
- return obj;
-}
-
-cmSPDXArtifact::cmSPDXArtifact(SPDXTypeId id,
- cmSPDXCreationInfo const& creationInfo)
- : cmSPDXElement(id, creationInfo)
-{
-}
-
-Json::Value cmSPDXArtifact::toJsonLD() const
-{
- auto obj = cmSPDXElement::toJsonLD();
- addOptionalSPDXValue(obj, "builtTime", BuiltTime);
- addOptionalSPDXValue(obj, "originateBy", OriginatedBy);
- addOptionalSPDXValue(obj, "releaseTime", ReleaseTime);
- addOptionalSPDXValue(obj, "standardName", StandardName);
- addOptionalSPDXValue(obj, "suppliedBy", SuppliedBy);
- addOptionalSPDXValue(obj, "supportType", SupportType);
- addOptionalSPDXValue(obj, "validUntilTime", ValidUntilTime);
- return obj;
-}
-
-cmSPDXElementCollection::cmSPDXElementCollection(
- SPDXTypeId id, cmSPDXCreationInfo const& creationInfo)
- : cmSPDXElement(id, creationInfo)
-{
-}
-
-Json::Value cmSPDXElementCollection::toJsonLD() const
-{
- auto obj = cmSPDXElement::toJsonLD();
- addOptionalSPDXValue(obj, "element", Element);
- addOptionalSPDXValue(obj, "profileConformance", ProfileConformance);
- addOptionalSPDXValue(obj, "rootElement", RootElement);
- return obj;
-}
-
-// SPDX Implicit Core Element Classes, Abstract
-
-// Nominally an inheritable class, but adds nothing to Element
-using cmSPDXAgentAbstract = cmSPDXElement;
-
-cmSPDXBundleAbstract::cmSPDXBundleAbstract(
- SPDXTypeId id, cmSPDXCreationInfo const& creationInfo)
- : cmSPDXElementCollection(id, creationInfo)
-{
-}
-
-Json::Value cmSPDXBundleAbstract::toJsonLD() const
-{
- auto obj = cmSPDXElementCollection::toJsonLD();
- obj["context"] = Context;
- return obj;
-}
-
-// Nominally an inheritable class, but adds nothing to Bundle
-using cmSPDXBomAbstract = cmSPDXBundleAbstract;
-
-cmSPDXRelationshipAbstract::cmSPDXRelationshipAbstract(
- SPDXTypeId id, cmSPDXCreationInfo const& creationInfo)
- : cmSPDXElement(id, creationInfo)
-{
-}
-
-Json::Value cmSPDXRelationshipAbstract::toJsonLD() const
-{
- auto obj = cmSPDXElement::toJsonLD();
- addOptionalSPDXValue(obj, "completeness", Completeness);
- addOptionalSPDXValue(obj, "endTime", EndTime);
- obj["from"] = From.toJsonLD();
- obj["relationshipType"] = RelationshipType.toJsonLD();
- addOptionalSPDXValue(obj, "startTime", StartTime);
- addVectorSPDXValue(obj, "to", To);
- return obj;
-}
-
-// SPDX Core Element Classes, Concrete
-
-cmSPDXAgent::cmSPDXAgent(cmSPDXCreationInfo const& creationInfo)
- : cmSPDXAgentAbstract(CORE_AGENT, creationInfo)
-{
-}
-
-Json::Value cmSPDXAgent::toJsonLD() const
-{
- auto obj = cmSPDXAgentAbstract::toJsonLD();
- obj["type"] = "Agent";
- return obj;
-}
-
-cmSPDXAnnotation::cmSPDXAnnotation(cmSPDXCreationInfo const& creationInfo,
- cmSPDXIdentifierReference subject)
- : cmSPDXElement(CORE_ANNOTATION, creationInfo)
- , Subject(std::move(subject))
-{
-}
-
-Json::Value cmSPDXAnnotation::toJsonLD() const
-{
- auto obj = cmSPDXElement::toJsonLD();
- obj["type"] = "Annotation";
- obj["annotationType"] = AnnotationType.toJsonLD();
- addOptionalSPDXValue(obj, "contentType", ContentType);
- addOptionalSPDXValue(obj, "statement", Statement);
- obj["subject"] = Subject.toJsonLD();
- return obj;
-}
-
-cmSPDXBom::cmSPDXBom(cmSPDXCreationInfo const& creationInfo)
- : cmSPDXBomAbstract(CORE_BOM, creationInfo)
-{
-}
-
-Json::Value cmSPDXBom::toJsonLD() const
-{
- auto obj = cmSPDXBomAbstract::toJsonLD();
- obj["type"] = "Bom";
- return obj;
-}
-
-cmSPDXBundle::cmSPDXBundle(cmSPDXCreationInfo const& creationInfo)
- : cmSPDXBundleAbstract(CORE_BUNDLE, creationInfo)
-{
-}
-
-Json::Value cmSPDXBundle::toJsonLD() const
-{
- auto obj = cmSPDXBundleAbstract::toJsonLD();
- obj["type"] = "Bundle";
- return obj;
-}
-
-cmSPDXIndividualElement::cmSPDXIndividualElement(
- cmSPDXCreationInfo const& creationInfo)
- : cmSPDXElement(CORE_INDIVIDUAL_ELEMENT, creationInfo)
-{
-}
-
-Json::Value cmSPDXIndividualElement::toJsonLD() const
-{
- auto obj = cmSPDXElement::toJsonLD();
- obj["type"] = "IndividualElement";
- return obj;
-}
-
-cmSPDXLifecycleScopedRelationship::cmSPDXLifecycleScopedRelationship(
- cmSPDXCreationInfo const& creationInfo)
- : cmSPDXRelationshipAbstract(CORE_LIFECYCLE_SCOPED_RELATIONSHIP,
- creationInfo)
-{
-}
-
-Json::Value cmSPDXLifecycleScopedRelationship::toJsonLD() const
-{
- auto obj = cmSPDXRelationshipAbstract::toJsonLD();
- obj["type"] = "LifecycleScopedRelationship";
- addOptionalSPDXValue(obj, "scope", Scope);
- return obj;
-}
-
-cmSPDXOrganization::cmSPDXOrganization(cmSPDXCreationInfo const& creationInfo)
- : cmSPDXAgentAbstract(CORE_ORGANIZATION, creationInfo)
-{
-}
-
-Json::Value cmSPDXOrganization::toJsonLD() const
-{
- auto obj = cmSPDXAgentAbstract::toJsonLD();
- obj["type"] = "Organization";
- return obj;
-}
-
-cmSPDXPerson::cmSPDXPerson(cmSPDXCreationInfo const& creationInfo)
- : cmSPDXAgentAbstract(CORE_PERSON, creationInfo)
-{
-}
-
-Json::Value cmSPDXPerson::toJsonLD() const
-{
- auto obj = cmSPDXAgentAbstract::toJsonLD();
- obj["type"] = "Person";
- return obj;
-}
-
-cmSPDXRelationship::cmSPDXRelationship(cmSPDXCreationInfo const& creationInfo)
- : cmSPDXRelationshipAbstract(CORE_RELATIONSHIP, creationInfo)
-{
-}
-
-Json::Value cmSPDXRelationship::toJsonLD() const
-{
- auto obj = cmSPDXRelationshipAbstract::toJsonLD();
- obj["type"] = "Relationship";
- return obj;
-}
-
-cmSPDXSoftwareAgent::cmSPDXSoftwareAgent(
- cmSPDXCreationInfo const& creationInfo)
- : cmSPDXAgentAbstract(CORE_SOFTWARE_AGENT, creationInfo)
-{
-}
-
-Json::Value cmSPDXSoftwareAgent::toJsonLD() const
-{
- auto obj = cmSPDXAgentAbstract::toJsonLD();
- obj["type"] = "SoftwareAgent";
- return obj;
-}
-
-cmSPDXSpdxDocument::cmSPDXSpdxDocument(cmSPDXCreationInfo const& creationInfo)
- : cmSPDXElementCollection(CORE_SPDX_DOCUMENT, creationInfo)
-{
-}
-
-Json::Value cmSPDXSpdxDocument::toJsonLD() const
-{
- auto obj = cmSPDXElementCollection::toJsonLD();
- obj["type"] = "SpdxDocument";
- addOptionalSPDXValue(obj, "dataLicense", DataLicense);
- addOptionalSPDXValue(obj, "externalMap", ExternalMap);
- addOptionalSPDXValue(obj, "namespaceMap", NamespaceMap);
- return obj;
-}
-
-cmSPDXTool::cmSPDXTool(cmSPDXCreationInfo const& creationInfo)
- : cmSPDXElement(CORE_TOOL, creationInfo)
-{
-}
-
-Json::Value cmSPDXTool::toJsonLD() const
-{
- auto obj = cmSPDXElement::toJsonLD();
- obj["type"] = "Tool";
- return obj;
-}
-
-// SPDX Software Enums
-
-cmSPDXContentIdentifierType::cmSPDXContentIdentifierType(
- cmSPDXContentIdentifierTypeId typeId)
- : TypeId(typeId)
-{
-}
-
-Json::Value cmSPDXContentIdentifierType::toJsonLD() const
-{
- switch (TypeId) {
- case GITOID:
- return "gitoid";
- case SWHID:
- return "swhid";
- default:
- return "INVALID_CONTENT_IDENTIFIER_TYPE_ID";
- }
-}
-
-cmSPDXFileKindType::cmSPDXFileKindType(cmSPDXFileKindTypeId typeId)
- : TypeId(typeId)
-{
-}
-
-Json::Value cmSPDXFileKindType::toJsonLD() const
-{
- switch (TypeId) {
- case DIRECTORY:
- return "directory";
- case FILE:
- return "file";
- default:
- return "INVALID_FILE_KIND_TYPE_ID";
- }
-}
-
-cmSPDXSbomType::cmSPDXSbomType(cmSPDXSbomTypeId typeId)
- : TypeId(typeId)
-{
-}
-
-Json::Value cmSPDXSbomType::toJsonLD() const
-{
- switch (TypeId) {
- case ANALYZED:
- return "analyzed";
- case BUILD:
- return "build";
- case DEPLOYED:
- return "deployed";
- case DESIGN:
- return "design";
- case RUNTIME:
- return "runtime";
- case SOURCE:
- return "source";
- default:
- return "INVALID_SBOM_TYPE_ID";
- }
-}
-
-cmSPDXSoftwarePurpose::cmSPDXSoftwarePurpose(cmSPDXSoftwarePurposeId typeId)
- : TypeId(typeId)
-{
-}
-
-Json::Value cmSPDXSoftwarePurpose::toJsonLD() const
-{
- switch (TypeId) {
- case APPLICATION:
- return "application";
- case ARCHIVE:
- return "archive";
- case BOM:
- return "bom";
- case CONFIGURATION:
- return "configuration";
- case CONTAINER:
- return "container";
- case DATA:
- return "data";
- case DEVICE:
- return "device";
- case DEVICE_DRIVER:
- return "deviceDriver";
- case DISK_IMAGE:
- return "diskImage";
- case DOCUMENTATION:
- return "documentation";
- case EVIDENCE:
- return "evidence";
- case EXECUTABLE:
- return "executable";
- case FILE:
- return "file";
- case FILESYSTEM_IMAGE:
- return "filesystemImage";
- case FIRMWARE:
- return "firmware";
- case FRAMEWORK:
- return "framework";
- case INSTALL:
- return "install";
- case LIBRARY:
- return "library";
- case MANIFEST:
- return "manifest";
- case MODEL:
- return "model";
- case MODULE:
- return "module";
- case OPERATING_SYSTEM:
- return "operatingSystem";
- case OTHER:
- return "other";
- case PATCH:
- return "patch";
- case PLATFORM:
- return "platform";
- case REQUIREMENT:
- return "requirement";
- case SOURCE:
- return "source";
- case SPECIFICATION:
- return "specification";
- case TEST:
- return "test";
- default:
- return "INVALID_SOFTWARE_PURPOSE_ID";
- }
-}
-
-// SPDX Software NonElement Classes, Concrete
-
-cmSPDXContentIdentifier::cmSPDXContentIdentifier()
- : cmSPDXIntegrityMethod(SOFTWARE_CONTENT_IDENTIFIER)
-{
-}
-
-Json::Value cmSPDXContentIdentifier::toJsonLD() const
-{
- auto obj = cmSPDXIntegrityMethod::toJsonLD();
- obj["type"] = "ContentIdentifier";
- obj["contentIdentifierType"] = ContentIdentifierType.toJsonLD();
- obj["contentIdentifierValue"] = ContentIdentifierValue;
- return obj;
-}
-
-// SPDX Software Element Classes, Abstract
-
-cmSPDXSoftwareArtifact::cmSPDXSoftwareArtifact(
- SPDXTypeId id, cmSPDXCreationInfo const& creationInfo)
- : cmSPDXArtifact(id, creationInfo)
-{
-}
-
-Json::Value cmSPDXSoftwareArtifact::toJsonLD() const
-{
- auto obj = cmSPDXArtifact::toJsonLD();
- addOptionalSPDXValue(obj, "additionalPurpose", AdditionalPurpose);
- addOptionalSPDXValue(obj, "attributionText", AttributionText);
- addOptionalSPDXValue(obj, "contentIdentifier", ContentIdentifier);
- addOptionalSPDXValue(obj, "copyrightText", CopyrightText);
- addOptionalSPDXValue(obj, "primaryPurpose", PrimaryPurpose);
- return obj;
-}
-
-// SPDX Software Element Classes, Concrete
-
-cmSPDXFile::cmSPDXFile(cmSPDXCreationInfo const& creationInfo)
- : cmSPDXSoftwareArtifact(SOFTWARE_FILE, creationInfo)
-{
-}
-
-Json::Value cmSPDXFile::toJsonLD() const
-{
- auto obj = cmSPDXSoftwareArtifact::toJsonLD();
- obj["type"] = "File";
- addOptionalSPDXValue(obj, "contentType", ContentType);
- addOptionalSPDXValue(obj, "fileKind", FileKind);
- return obj;
-}
-
-cmSPDXPackage::cmSPDXPackage(cmSPDXCreationInfo const& creationInfo)
- : cmSPDXSoftwareArtifact(SOFTWARE_PACKAGE, creationInfo)
-{
-}
-
-Json::Value cmSPDXPackage::toJsonLD() const
-{
- auto obj = cmSPDXSoftwareArtifact::toJsonLD();
- obj["type"] = "Package";
- addOptionalSPDXValue(obj, "downloadLocation", DownloadLocation);
- addOptionalSPDXValue(obj, "homePage", HomePage);
- addOptionalSPDXValue(obj, "packageUrl", PackageUrl);
- addOptionalSPDXValue(obj, "packageVersion", PackageVersion);
- addOptionalSPDXValue(obj, "sourceInfo", SourceInfo);
- return obj;
-}
-
-cmSPDXSbom::cmSPDXSbom(cmSPDXCreationInfo const& creationInfo)
- : cmSPDXBomAbstract(SOFTWARE_SBOM, creationInfo)
-{
-}
-
-Json::Value cmSPDXSbom::toJsonLD() const
-{
- auto obj = cmSPDXBomAbstract::toJsonLD();
- obj["type"] = "Sbom";
- addOptionalSPDXValue(obj, "sbomType", SbomType);
- return obj;
-}
-
-cmSPDXSnippet::cmSPDXSnippet(cmSPDXCreationInfo const& creationInfo)
- : cmSPDXSoftwareArtifact(SOFTWARE_SNIPPET, creationInfo)
-{
-}
-
-Json::Value cmSPDXSnippet::toJsonLD() const
-{
- auto obj = cmSPDXSoftwareArtifact::toJsonLD();
- obj["type"] = "Snippet";
- addOptionalSPDXValue(obj, "byteRange", ByteRange);
- addOptionalSPDXValue(obj, "lineRange", LineRange);
- obj["snippetFromFile"] = SnippetFromFile.toJsonLD();
- return obj;
-}
-
-// SPDX SimpleLicensing Element Classes, Concrete
-
-cmSPDXLicenseExpression::cmSPDXLicenseExpression(
- cmSPDXCreationInfo const& creationInfo)
- : cmSPDXAnyLicenseInfo(SIMPLE_LICENSING_LICENSE_EXPRESSION, creationInfo)
-{
-}
-
-Json::Value cmSPDXLicenseExpression::toJsonLD() const
-{
- auto obj = cmSPDXAnyLicenseInfo::toJsonLD();
- obj["type"] = "LicenseExpression";
- addOptionalSPDXValue(obj, "customIdToUri", CustomIdToUri);
- obj["licenseExpression"] = LicenseExpression;
- addOptionalSPDXValue(obj, "licenseListVersion", LicenseListVersion);
- return obj;
-}
-
-cmSPDXSimpleLicensingText::cmSPDXSimpleLicensingText(
- cmSPDXCreationInfo const& creationInfo)
- : cmSPDXElement(SIMPLE_LICENSING_SIMPLE_LICENSING_TEXT, creationInfo)
-{
-}
-
-Json::Value cmSPDXSimpleLicensingText::toJsonLD() const
-{
- auto obj = cmSPDXElement::toJsonLD();
- obj["type"] = "SimpleLicensingText";
- obj["licenseText"] = LicenseText;
- return obj;
-}
-
-// Graph Manipulation
-
-#define X_SPDX(classtype, enumid, member, camel) \
- template <> \
- cmSPDXSerializationBase::SPDXTypeId cmSPDXGetTypeId<classtype>() \
- { \
- return cmSPDXSerializationBase::enumid; \
- } \
- \
- template <> \
- std::string cmSPDXGetTypeName<classtype>() \
- { \
- return #camel; \
- } \
- \
- cmSPDXObject::cmSPDXObject(classtype val) \
- : member(std::move(val)) {}; \
- \
- void cmSPDXObject::get(classtype** ptr) \
- { \
- *ptr = SerializationBase.getTypeId() == cmSPDXSerializationBase::enumid \
- ? &member \
- : nullptr; \
- }
-#include "cmSPDXTypes.def"
-
-cmSPDXObject::cmSPDXObject()
- : IdentifierReference("UNINITIALIZED_SPDX_OBJECT")
-{
-}
-
-cmSPDXObject::cmSPDXObject(cmSPDXObject const& other)
-{
- switch (other.SerializationBase.getTypeId()) {
-#define X_SPDX(classtype, enumid, member, camel) \
- case cmSPDXSerializationBase::enumid: \
- new (&member) classtype(other.member); \
- break;
-#include "cmSPDXTypes.def"
- default:
- new (&IdentifierReference)
- cmSPDXIdentifierReference("UNINITIALIZED_SPDX_OBJECT");
- }
-}
-
-cmSPDXObject::cmSPDXObject(cmSPDXObject&& other) noexcept
-{
- switch (other.SerializationBase.getTypeId()) {
-#define X_SPDX(classtype, enumid, member, camel) \
- case cmSPDXSerializationBase::enumid: \
- new (&member) classtype(std::move(other.member)); \
- break;
-#include "cmSPDXTypes.def"
- default:
- new (&IdentifierReference)
- cmSPDXIdentifierReference("UNINITIALIZED_SPDX_OBJECT");
- }
-}
-
-cmSPDXObject& cmSPDXObject::operator=(cmSPDXObject const& other)
-{
- this->~cmSPDXObject();
- new (this) cmSPDXObject(other);
- return *this;
-}
-
-cmSPDXObject& cmSPDXObject::operator=(cmSPDXObject&& other) noexcept
-{
- this->~cmSPDXObject();
- new (this) cmSPDXObject(std::move(other));
- return *this;
-}
-
-cmSPDXObject::~cmSPDXObject()
-{
- switch (SerializationBase.getTypeId()) {
-#define X_SPDX(classtype, enumid, member, camel) \
- case cmSPDXSerializationBase::enumid: \
- member.~classtype(); \
- break;
-#include "cmSPDXTypes.def"
- default:
- break;
- }
-}
-
-Json::Value cmSPDXObject::toJsonLD() const
-{
- switch (SerializationBase.getTypeId()) {
-#define X_SPDX(classtype, enumid, member, camel) \
- case cmSPDXSerializationBase::enumid: \
- return member.toJsonLD();
-#include "cmSPDXTypes.def"
- default:
- return "INVALID_SPDX_OBJECT_TYPE_ID";
- }
-}
-
-cmSPDXSimpleGraph::cmSPDXSimpleGraph(std::string iriBase,
- cmSPDXCreationInfo creationInfo)
- : IRIBase(std::move(iriBase))
- , CreationInfo(&insert<cmSPDXCreationInfo>(std::move(creationInfo)))
-{
-}
-
-cmSPDXCreationInfo& cmSPDXSimpleGraph::getCreationInfo()
-{
- return *CreationInfo;
-}
-
-Json::Value cmSPDXSimpleGraph::toJsonLD()
-{
- Json::Value obj(Json::objectValue);
- obj["@context"] = "https://spdx.org/rdf/3.0.1/spdx-context.jsonld";
-
- auto& graph = obj["@graph"];
- for (auto const& it : Graph) {
- graph.append(it.second.toJsonLD());
- }
-
- return obj;
-}
diff --git a/Source/cmSPDXSerializer.h b/Source/cmSPDXSerializer.h
deleted file mode 100644
index 65bf214..0000000
--- a/Source/cmSPDXSerializer.h
+++ /dev/null
@@ -1,1008 +0,0 @@
-/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
- file LICENSE.rst or https://cmake.org/licensing for details. */
-#pragma once
-
-#include <array>
-#include <cstddef>
-#include <map>
-#include <new>
-#include <string>
-#include <tuple>
-#include <utility>
-#include <vector>
-
-#include <cm/optional>
-#include <cm/type_traits>
-
-#include <cm3p/json/value.h>
-
-#include "cmStringAlgorithms.h"
-
-// Base Class
-
-struct cmSPDXSerializationBase
-{
- enum SPDXTypeId
- {
- INVALID = -1,
- NULL_ID = 0,
-
-#define X_SPDX(classtype, enumid, title, camel) enumid,
-#include "cmSPDXTypes.def"
-
- SPDX_TYPE_ID_MAX,
- };
-
- SPDXTypeId getTypeId() const;
-
- std::string NodeId;
-
-protected:
- cmSPDXSerializationBase(SPDXTypeId id);
- cmSPDXSerializationBase(SPDXTypeId id, std::string nodeId);
-
-private:
- SPDXTypeId TypeId;
-};
-
-// Convenience Classes
-
-struct cmSPDXIdentifierReference : cmSPDXSerializationBase
-{
- cmSPDXIdentifierReference();
- cmSPDXIdentifierReference(cmSPDXSerializationBase const& ref);
- cmSPDXIdentifierReference(std::string const& ref);
-
- Json::Value toJsonLD() const;
-};
-
-struct cmSPDXNonElementBase : cmSPDXSerializationBase
-{
-protected:
- cmSPDXNonElementBase(SPDXTypeId id);
-
- Json::Value toJsonLD() const;
-};
-
-// SPDX Core Data Types
-
-// Nominally these are supposed to be validated strings
-using cmSPDXDateTime = std::string;
-using cmSPDXMediaType = std::string;
-using cmSPDXSemVer = std::string;
-
-// SPDX Core Enums
-
-struct cmSPDXAnnotationType
-{
- enum cmSPDXAnnotationTypeId
- {
- INVALID = -1,
- NULL_ID = 0,
- OTHER,
- REVIEW,
- };
-
- cmSPDXAnnotationTypeId TypeId;
-
- cmSPDXAnnotationType(cmSPDXAnnotationTypeId typeId = NULL_ID);
-
- Json::Value toJsonLD() const;
-};
-
-struct cmSPDXExternalIdentifierType
-{
- enum cmSPDXExternalIdentifierTypeId
- {
- INVALID = -1,
- NULL_ID = 0,
- CPE22,
- CPE23,
- CVE,
- EMAIL,
- GITOID,
- OTHER,
- PACKAGE_URL,
- SECURITY_OTHER,
- SWHID,
- SWID,
- URL_SCHEME,
- };
-
- cmSPDXExternalIdentifierTypeId TypeId;
-
- cmSPDXExternalIdentifierType(
- cmSPDXExternalIdentifierTypeId typeId = NULL_ID);
-
- Json::Value toJsonLD() const;
-};
-
-struct cmSPDXExternalRefType
-{
- enum cmSPDXExternalRefTypeId
- {
- INVALID = -1,
- NULL_ID = 0,
- ALT_DOWNLOAD_LOCATION,
- ALT_WEB_PAGE,
- BINARY_ARTIFACT,
- BOWER,
- BUILD_META,
- BUILD_SYSTEM,
- CERTIFICATION_REPORT,
- CHAT,
- COMPONENT_ANALYSIS_REPORT,
- CWE,
- DOCUMENTATION,
- DYNAMIC_ANALYSIS_REPORT,
- EOL_NOTICE,
- EXPORT_CONTROL_ASSESSMENT,
- FUNDING,
- ISSUE_TRACKER,
- LICENSE,
- MAILING_LIST,
- MAVEN_CENTRAL,
- METRICS,
- NPM,
- NUGET,
- OTHER,
- PRIVACY_ASSESSMENT,
- PRODUCT_METADATA,
- PURCHASE_ORDER,
- QUALITY_ASSESSMENT_REPORT,
- RELEASE_HISTORY,
- RELEASE_NOTES,
- RISK_ASSESSMENT,
- RUNTIME_ANALYSIS_REPORT,
- SECURE_SOFTWARE_ATTESTATION,
- SECURITY_ADVERSARY_MODEL,
- SECURITY_ADVISORY,
- SECURITY_FIX,
- SECURITY_OTHER,
- SECURITY_PEN_TEST_REPORT,
- SECURITY_POLICY,
- SECURITY_THREAT_MODEL,
- SOCIAL_MEDIA,
- SOURCE_ARTIFACT,
- STATIC_ANALYSIS_REPORT,
- SUPPORT,
- VCS,
- VULNERABILITY_DISCLOSURE_REPORT,
- VULNERABILITY_EXPLOITABILITY_ASSESSMENT,
- };
-
- cmSPDXExternalRefTypeId TypeId;
-
- cmSPDXExternalRefType(cmSPDXExternalRefTypeId typeId = NULL_ID);
-
- Json::Value toJsonLD() const;
-};
-
-struct cmSPDXHashAlgorithm
-{
- enum cmSPDXHashAlgorithmId
- {
- INVALID = -1,
- NULL_ID = 0,
- ADLER32,
- BLAKE2B256,
- BLAKE2B384,
- BLAKE2B512,
- BLAKE3,
- CRYSTALS_DILITHIUM,
- CRYSTALS_KYBER,
- FALCON,
- MD2,
- MD4,
- MD5,
- MD6,
- OTHER,
- SHA1,
- SHA224,
- SHA256,
- SHA384,
- SHA3_224,
- SHA3_256,
- SHA3_384,
- SHA3_512,
- SHA512,
- };
-
- cmSPDXHashAlgorithmId TypeId;
-
- cmSPDXHashAlgorithm(cmSPDXHashAlgorithmId typeId = NULL_ID);
-
- Json::Value toJsonLD() const;
-};
-
-struct cmSPDXLifecycleScopeType
-{
- enum cmSPDXLifecycleScopeTypeId
- {
- INVALID = -1,
- NULL_ID = 0,
- BUILD,
- DESIGN,
- DEVELOPMENT,
- OTHER,
- RUNTIME,
- TEST,
- };
-
- cmSPDXLifecycleScopeTypeId TypeId;
-
- cmSPDXLifecycleScopeType(cmSPDXLifecycleScopeTypeId typeId = NULL_ID);
-
- Json::Value toJsonLD() const;
-};
-
-struct cmSPDXProfileIdentifierType
-{
- enum cmSPDXProfileIdentifierTypeId
- {
- INVALID = -1,
- NULL_ID = 0,
- AI,
- BUILD,
- CORE,
- DATASET,
- EXPANDED_LICENSING,
- EXTENSION,
- LITE,
- SECURITY,
- SIMPLE_LICENSING,
- SOFTWARE,
- };
-
- cmSPDXProfileIdentifierTypeId TypeId;
-
- cmSPDXProfileIdentifierType(cmSPDXProfileIdentifierTypeId typeId = NULL_ID);
-
- Json::Value toJsonLD() const;
-};
-
-struct cmSPDXRelationshipCompletenessType
-{
- enum cmSPDXRelationshipCompletenessTypeId
- {
- INVALID = -1,
- NULL_ID = 0,
- COMPLETE,
- INCOMPLETE,
- NO_ASSERTION,
- };
-
- cmSPDXRelationshipCompletenessTypeId TypeId;
-
- cmSPDXRelationshipCompletenessType(
- cmSPDXRelationshipCompletenessTypeId typeId = NULL_ID);
-
- Json::Value toJsonLD() const;
-};
-
-struct cmSPDXRelationshipType
-{
- enum cmSPDXRelationshipTypeId
- {
- INVALID = -1,
- NULL_ID = 0,
- AFFECTS,
- AMENDED_BY,
- ANCESTOR_OF,
- AVAILABLE_FROM,
- CONFIGURES,
- CONTAINS,
- COORDINATED_BY,
- COPIED_TO,
- DELEGATED_TO,
- DEPENDS_ON,
- DESCENDANT_OF,
- DESCRIBES,
- DOES_NOT_AFFECT,
- EXPANDS_TO,
- EXPLOIT_CREATED_BY,
- FIXED_BY,
- FIXED_IN,
- FOUND_BY,
- GENERATES,
- HAS_ADDED_FILE,
- HAS_ASSESSMENT_FOR,
- HAS_ASSOCIATED_VULNERABILITY,
- HAS_CONCLUDED_LICENSE,
- HAS_DATA_FILE,
- HAS_DECLARED_LICENSE,
- HAS_DELETED_FILE,
- HAS_DEPENDENCY_MANIFEST,
- HAS_DISTRIBUTION_ARTIFACT,
- HAS_DOCUMENTATION,
- HAS_DYNAMIC_LINK,
- HAS_EVIDENCE,
- HAS_EXAMPLE,
- HAS_HOST,
- HAS_INPUT,
- HAS_METADATA,
- HAS_OPTIONAL_COMPONENT,
- HAS_OPTIONAL_DEPENDENCY,
- HAS_OUTPUT,
- HAS_PREREQUISITE,
- HAS_PROVIDED_DEPENDENCY,
- HAS_REQUIREMENT,
- HAS_SPECIFICATION,
- HAS_STATIC_LINK,
- HAS_TEST,
- HAS_TEST_CASE,
- HAS_VARIANT,
- INVOKED_BY,
- MODIFIED_BY,
- OTHER,
- PACKAGED_BY,
- PATCHED_BY,
- PUBLISHED_BY,
- REPORTED_BY,
- REPUBLISHED_BY,
- SERIALIZED_IN_ARTIFACT,
- TESTED_ON,
- TRAINED_ON,
- UNDER_INVESTIGATION_FOR,
- USES_TOOL,
- };
-
- cmSPDXRelationshipTypeId TypeId;
-
- cmSPDXRelationshipType(cmSPDXRelationshipTypeId typeId = NULL_ID);
-
- Json::Value toJsonLD() const;
-};
-
-struct cmSPDXSupportType
-{
- enum cmSPDXSupportTypeId
- {
- INVALID = -1,
- NULL_ID = 0,
- DEPLOYED,
- DEVELOPMENT,
- END_OF_SUPPORT,
- LIMITED_SUPPORT,
- NO_ASSERTION,
- NO_SUPPORT,
- SUPPORT,
- };
-
- cmSPDXSupportTypeId TypeId;
-
- cmSPDXSupportType(cmSPDXSupportTypeId typeId = NULL_ID);
-
- Json::Value toJsonLD() const;
-};
-
-// SPDX Core NonElement Classes, Abstract
-
-struct cmSPDXIntegrityMethod : cmSPDXNonElementBase
-{
-
- cm::optional<std::string> Comment;
-
-protected:
- cmSPDXIntegrityMethod(SPDXTypeId id);
-
- Json::Value toJsonLD() const;
-};
-
-// SPDX Core NonElement Classes, Concrete
-
-struct cmSPDXCreationInfo : cmSPDXNonElementBase
-{
- cm::optional<std::string> Comment;
- cmSPDXDateTime Created;
- std::vector<cmSPDXIdentifierReference> CreatedBy;
- cm::optional<std::vector<cmSPDXIdentifierReference>> CreatedUsing;
-
- cmSPDXCreationInfo();
-
- Json::Value toJsonLD() const;
-};
-
-struct cmSPDXDictionaryEntry : cmSPDXNonElementBase
-{
- std::string Key;
- cm::optional<std::string> Value;
-
- cmSPDXDictionaryEntry();
- cmSPDXDictionaryEntry(std::string key);
- cmSPDXDictionaryEntry(std::string key, std::string val);
-
- Json::Value toJsonLD() const;
-};
-
-struct cmSPDXExternalIdentifier : cmSPDXNonElementBase
-{
- cm::optional<std::string> Comment;
- cmSPDXExternalIdentifierType ExternalIdentifierType;
- std::string Identifier;
- cm::optional<std::vector<std::string>> IdentifierLocator;
- cm::optional<std::string> IssuingAuthority;
-
- cmSPDXExternalIdentifier();
-
- Json::Value toJsonLD() const;
-};
-
-struct cmSPDXExternalMap : cmSPDXNonElementBase
-{
- cm::optional<cmSPDXIdentifierReference> DefiningArtifact;
- std::string ExternalSpdxId;
- cm::optional<std::string> LocationHint;
- cm::optional<std::vector<cmSPDXIdentifierReference>> IntegrityMethod;
-
- cmSPDXExternalMap();
-
- Json::Value toJsonLD() const;
-};
-
-struct cmSPDXExternalRef : cmSPDXNonElementBase
-{
- cm::optional<std::string> Comment;
- cm::optional<cmSPDXMediaType> ContentType;
- cm::optional<cmSPDXExternalRefType> ExternalRefType;
- cm::optional<std::vector<std::string>> Locator;
-
- cmSPDXExternalRef();
-
- Json::Value toJsonLD() const;
-};
-
-struct cmSPDXHash : cmSPDXIntegrityMethod
-{
- cmSPDXHashAlgorithm Algorithm;
- std::string HashValue;
-
- cmSPDXHash();
-
- Json::Value toJsonLD() const;
-};
-
-struct cmSPDXNamespaceMap : cmSPDXNonElementBase
-{
- std::string Namespace;
- std::string Prefix;
-
- cmSPDXNamespaceMap();
-
- Json::Value toJsonLD() const;
-};
-
-struct cmSPDXPackageVerificationCode : cmSPDXIntegrityMethod
-{
- cmSPDXHashAlgorithm Algorithm;
- std::string HashValue;
- cm::optional<std::vector<std::string>> PackageVerificationCodeExcludedFile;
-
- cmSPDXPackageVerificationCode();
-
- Json::Value toJsonLD() const;
-};
-
-struct cmSPDXPositiveIntegerRange : cmSPDXNonElementBase
-{
- unsigned int BeginIntegerRange;
- unsigned int EndIntegerRange;
-
- cmSPDXPositiveIntegerRange(unsigned int beingIntegerRange = 0,
- unsigned int endIntegerRange = 0);
-
- Json::Value toJsonLD() const;
-};
-
-// SPDX Core Element Classes, Abstract
-
-struct cmSPDXElement : cmSPDXSerializationBase
-{
- cm::optional<std::string> Comment;
- cmSPDXIdentifierReference CreationInfo;
- cm::optional<std::string> Description;
- cm::optional<std::vector<cmSPDXIdentifierReference>> Extension;
- cm::optional<std::vector<cmSPDXIdentifierReference>> ExternalIdentifier;
- cm::optional<std::vector<cmSPDXIdentifierReference>> ExternalRef;
- cm::optional<std::string> Name;
- // SpdxId is the NodeId
- cm::optional<std::string> Summary;
- cm::optional<std::vector<cmSPDXIdentifierReference>> VerifiedUsing;
-
-protected:
- cmSPDXElement(SPDXTypeId id, cmSPDXCreationInfo const& creationInfo);
-
- Json::Value toJsonLD() const;
-};
-
-struct cmSPDXArtifact : cmSPDXElement
-{
- cm::optional<cmSPDXDateTime> BuiltTime;
- cm::optional<std::vector<cmSPDXIdentifierReference>> OriginatedBy;
- cm::optional<cmSPDXDateTime> ReleaseTime;
- cm::optional<std::vector<std::string>> StandardName;
- cm::optional<cmSPDXIdentifierReference> SuppliedBy;
- cm::optional<std::vector<cmSPDXSupportType>> SupportType;
- cm::optional<cmSPDXDateTime> ValidUntilTime;
-
-protected:
- cmSPDXArtifact(SPDXTypeId id, cmSPDXCreationInfo const& creationInfo);
-
- Json::Value toJsonLD() const;
-};
-
-struct cmSPDXElementCollection : cmSPDXElement
-{
- cm::optional<std::vector<cmSPDXIdentifierReference>> Element;
- cm::optional<std::vector<cmSPDXProfileIdentifierType>> ProfileConformance;
- cm::optional<std::vector<cmSPDXIdentifierReference>> RootElement;
-
-protected:
- cmSPDXElementCollection(SPDXTypeId id,
- cmSPDXCreationInfo const& creationInfo);
-
- Json::Value toJsonLD() const;
-};
-
-// SPDX Implicit Core Element Classes, Abstract
-
-// Nominally an inheritable class, but adds nothing to Element
-using cmSPDXAgentAbstract = cmSPDXElement;
-
-struct cmSPDXBundleAbstract : cmSPDXElementCollection
-{
- std::string Context;
-
-protected:
- cmSPDXBundleAbstract(SPDXTypeId id, cmSPDXCreationInfo const& creationInfo);
-
- Json::Value toJsonLD() const;
-};
-
-// Nominally an inheritable class, but adds nothing to Bundle
-using cmSPDXBomAbstract = cmSPDXBundleAbstract;
-
-struct cmSPDXRelationshipAbstract : cmSPDXElement
-{
- cm::optional<cmSPDXRelationshipCompletenessType> Completeness;
- cm::optional<cmSPDXDateTime> EndTime;
- cmSPDXIdentifierReference From;
- cmSPDXRelationshipType RelationshipType;
- cm::optional<cmSPDXDateTime> StartTime;
- std::vector<cmSPDXIdentifierReference> To;
-
-protected:
- cmSPDXRelationshipAbstract(SPDXTypeId id,
- cmSPDXCreationInfo const& creationInfo);
-
- Json::Value toJsonLD() const;
-};
-
-// SPDX Core Element Classes, Concrete
-
-struct cmSPDXAgent : cmSPDXAgentAbstract
-{
- cmSPDXAgent(cmSPDXCreationInfo const& creationInfo);
-
- Json::Value toJsonLD() const;
-};
-
-struct cmSPDXAnnotation : cmSPDXElement
-{
- cmSPDXAnnotationType AnnotationType;
- cm::optional<cmSPDXMediaType> ContentType;
- cm::optional<std::string> Statement;
- cmSPDXIdentifierReference Subject;
-
- cmSPDXAnnotation(cmSPDXCreationInfo const& creationInfo,
- cmSPDXIdentifierReference subject = {});
-
- Json::Value toJsonLD() const;
-};
-
-struct cmSPDXBom : cmSPDXBomAbstract
-{
- cmSPDXBom(cmSPDXCreationInfo const& creationInfo);
-
- Json::Value toJsonLD() const;
-};
-
-struct cmSPDXBundle : cmSPDXBundleAbstract
-{
- cmSPDXBundle(cmSPDXCreationInfo const& creationInfo);
-
- Json::Value toJsonLD() const;
-};
-
-struct cmSPDXIndividualElement : cmSPDXElement
-{
- cmSPDXIndividualElement(cmSPDXCreationInfo const& creationInfo);
-
- Json::Value toJsonLD() const;
-};
-
-struct cmSPDXLifecycleScopedRelationship : cmSPDXRelationshipAbstract
-{
- cm::optional<cmSPDXLifecycleScopeType> Scope;
-
- cmSPDXLifecycleScopedRelationship(cmSPDXCreationInfo const& creationInfo);
-
- Json::Value toJsonLD() const;
-};
-
-struct cmSPDXOrganization : cmSPDXAgentAbstract
-{
- cmSPDXOrganization(cmSPDXCreationInfo const& creationInfo);
-
- Json::Value toJsonLD() const;
-};
-
-struct cmSPDXPerson : cmSPDXAgentAbstract
-{
- cmSPDXPerson(cmSPDXCreationInfo const& creationInfo);
-
- Json::Value toJsonLD() const;
-};
-
-struct cmSPDXRelationship : cmSPDXRelationshipAbstract
-{
- cmSPDXRelationship(cmSPDXCreationInfo const& creationInfo);
-
- Json::Value toJsonLD() const;
-};
-
-struct cmSPDXSoftwareAgent : cmSPDXAgentAbstract
-{
- cmSPDXSoftwareAgent(cmSPDXCreationInfo const& creationInfo);
-
- Json::Value toJsonLD() const;
-};
-
-struct cmSPDXSpdxDocument : cmSPDXElementCollection
-{
- cm::optional<cmSPDXIdentifierReference> DataLicense;
- cm::optional<cmSPDXIdentifierReference> ExternalMap;
- cm::optional<cmSPDXIdentifierReference> NamespaceMap;
-
- cmSPDXSpdxDocument(cmSPDXCreationInfo const& creationInfo);
-
- Json::Value toJsonLD() const;
-};
-
-struct cmSPDXTool : cmSPDXElement
-{
- cmSPDXTool(cmSPDXCreationInfo const& creationInfo);
-
- Json::Value toJsonLD() const;
-};
-
-// SPDX Software Enums
-
-struct cmSPDXContentIdentifierType
-{
- enum cmSPDXContentIdentifierTypeId
- {
- INVALID = -1,
- NULL_ID = 0,
- GITOID,
- SWHID,
- };
-
- cmSPDXContentIdentifierTypeId TypeId;
-
- cmSPDXContentIdentifierType(cmSPDXContentIdentifierTypeId typeId = NULL_ID);
-
- Json::Value toJsonLD() const;
-};
-
-struct cmSPDXFileKindType
-{
- enum cmSPDXFileKindTypeId
- {
- INVALID = -1,
- NULL_ID = 0,
- DIRECTORY,
- FILE,
- };
-
- cmSPDXFileKindTypeId TypeId;
-
- cmSPDXFileKindType(cmSPDXFileKindTypeId typeId = NULL_ID);
-
- Json::Value toJsonLD() const;
-};
-
-struct cmSPDXSbomType
-{
- enum cmSPDXSbomTypeId
- {
- INVALID = -1,
- NULL_ID = 0,
- ANALYZED,
- BUILD,
- DEPLOYED,
- DESIGN,
- RUNTIME,
- SOURCE,
- };
-
- cmSPDXSbomTypeId TypeId;
-
- cmSPDXSbomType(cmSPDXSbomTypeId typeId = NULL_ID);
-
- Json::Value toJsonLD() const;
-};
-
-struct cmSPDXSoftwarePurpose
-{
- enum cmSPDXSoftwarePurposeId
- {
- INVALID = -1,
- NULL_ID = 0,
- APPLICATION,
- ARCHIVE,
- BOM,
- CONFIGURATION,
- CONTAINER,
- DATA,
- DEVICE,
- DEVICE_DRIVER,
- DISK_IMAGE,
- DOCUMENTATION,
- EVIDENCE,
- EXECUTABLE,
- FILE,
- FILESYSTEM_IMAGE,
- FIRMWARE,
- FRAMEWORK,
- INSTALL,
- LIBRARY,
- MANIFEST,
- MODEL,
- MODULE,
- OPERATING_SYSTEM,
- OTHER,
- PATCH,
- PLATFORM,
- REQUIREMENT,
- SOURCE,
- SPECIFICATION,
- TEST,
- };
-
- cmSPDXSoftwarePurposeId TypeId;
-
- cmSPDXSoftwarePurpose(cmSPDXSoftwarePurposeId typeId = NULL_ID);
-
- Json::Value toJsonLD() const;
-};
-
-// SPDX Software NonElement Classes, Concrete
-
-struct cmSPDXContentIdentifier : cmSPDXIntegrityMethod
-{
- cmSPDXContentIdentifierType ContentIdentifierType;
- std::string ContentIdentifierValue;
-
- cmSPDXContentIdentifier();
-
- Json::Value toJsonLD() const;
-};
-
-// SPDX Software Element Classes, Abstract
-
-struct cmSPDXSoftwareArtifact : cmSPDXArtifact
-{
- cm::optional<std::vector<cmSPDXSoftwarePurpose>> AdditionalPurpose;
- cm::optional<std::string> AttributionText;
- cm::optional<cmSPDXIdentifierReference> ContentIdentifier;
- cm::optional<std::string> CopyrightText;
- cm::optional<cmSPDXSoftwarePurpose> PrimaryPurpose;
-
-protected:
- cmSPDXSoftwareArtifact(SPDXTypeId id,
- cmSPDXCreationInfo const& creationInfo);
-
- Json::Value toJsonLD() const;
-};
-
-// SPDX Software Element Classes, Concrete
-
-struct cmSPDXFile : cmSPDXSoftwareArtifact
-{
- cm::optional<cmSPDXMediaType> ContentType;
- cm::optional<cmSPDXFileKindType> FileKind;
-
- cmSPDXFile(cmSPDXCreationInfo const& creationInfo);
-
- Json::Value toJsonLD() const;
-};
-
-struct cmSPDXPackage : cmSPDXSoftwareArtifact
-{
- cm::optional<std::string> DownloadLocation;
- cm::optional<std::string> HomePage;
- cm::optional<std::string> PackageUrl;
- cm::optional<std::string> PackageVersion;
- cm::optional<std::string> SourceInfo;
-
- cmSPDXPackage(cmSPDXCreationInfo const& creationInfo);
-
- Json::Value toJsonLD() const;
-};
-
-struct cmSPDXSbom : cmSPDXBomAbstract
-{
- cm::optional<std::vector<cmSPDXSbomType>> SbomType;
-
- cmSPDXSbom(cmSPDXCreationInfo const& creationInfo);
-
- Json::Value toJsonLD() const;
-};
-
-struct cmSPDXSnippet : cmSPDXSoftwareArtifact
-{
- cm::optional<cmSPDXIdentifierReference> ByteRange;
- cm::optional<cmSPDXIdentifierReference> LineRange;
- cmSPDXIdentifierReference SnippetFromFile;
-
- cmSPDXSnippet(cmSPDXCreationInfo const& creationInfo);
-
- Json::Value toJsonLD() const;
-};
-
-// SPDX SimpleLicensing Element Classes, Abstract
-
-// Nominally an inheritable class, but adds nothing to Element
-using cmSPDXAnyLicenseInfo = cmSPDXElement;
-
-// SPDX SimpleLicensing Element Classes, Concrete
-
-struct cmSPDXLicenseExpression : cmSPDXAnyLicenseInfo
-{
- cm::optional<std::vector<cmSPDXIdentifierReference>> CustomIdToUri;
- std::string LicenseExpression;
- cm::optional<cmSPDXSemVer> LicenseListVersion;
-
- cmSPDXLicenseExpression(cmSPDXCreationInfo const& CreationInfo);
-
- Json::Value toJsonLD() const;
-};
-
-struct cmSPDXSimpleLicensingText : cmSPDXElement
-{
- std::string LicenseText;
-
- cmSPDXSimpleLicensingText(cmSPDXCreationInfo const& CreationInfo);
-
- Json::Value toJsonLD() const;
-};
-
-// Graph Manipulation
-
-template <typename T>
-cmSPDXSerializationBase::SPDXTypeId cmSPDXGetTypeId();
-
-template <typename T>
-std::string cmSPDXGetTypeName();
-
-#define X_SPDX(classtype, enumid, member, camel) \
- template <> \
- cmSPDXSerializationBase::SPDXTypeId cmSPDXGetTypeId<classtype>(); \
- \
- template <> \
- std::string cmSPDXGetTypeName<classtype>();
-#include "cmSPDXTypes.def"
-
-template <class T>
-struct cmSPDXTag
-{
- using type = T;
-};
-
-union cmSPDXObject
-{
-
- cmSPDXSerializationBase SerializationBase;
-
- cmSPDXObject();
- cmSPDXObject(cmSPDXObject const& other);
- cmSPDXObject(cmSPDXObject&& other) noexcept;
-
-#define X_SPDX(classtype, enumid, member, camel) \
- classtype member; \
- cmSPDXObject(classtype val); \
- \
- template <typename... Args> \
- cmSPDXObject(cmSPDXTag<classtype>, Args&&... args) \
- { \
- new (&member) classtype(std::forward<Args>(args)...); \
- }
-#include "cmSPDXTypes.def"
-
- cmSPDXObject& operator=(cmSPDXObject const& other);
- cmSPDXObject& operator=(cmSPDXObject&& other) noexcept;
-
- ~cmSPDXObject();
-
- template <typename T>
- T* get()
- {
- T* ptr;
- get(&ptr);
- return ptr;
- }
-
- Json::Value toJsonLD() const;
-
-private:
-#define X_SPDX(classtype, enumid, member, camel) void get(classtype** ptr);
-#include "cmSPDXTypes.def"
-};
-
-struct cmSPDXSimpleGraph
-{
- cmSPDXSimpleGraph(std::string iriBase, cmSPDXCreationInfo creationInfo = {});
-
- template <typename T, typename... Args>
- cm::enable_if_t<std::is_base_of<cmSPDXElement, T>::value, T>& insert(
- Args&&... args)
- {
- std::string nodeId = cmStrCat(IRIBase, IRICount++);
- auto const& it =
- Graph.emplace(std::piecewise_construct, std::forward_as_tuple(nodeId),
- std::forward_as_tuple(cmSPDXTag<T>{}, *CreationInfo,
- std::forward<Args>(args)...));
- auto& node = *it.first->second.template get<T>();
- node.NodeId = std::move(nodeId);
- return node;
- }
-
- cmSPDXCreationInfo& getCreationInfo();
-
- template <typename T, typename... Args>
- cm::enable_if_t<std::is_base_of<cmSPDXNonElementBase, T>::value, T>& insert(
- Args&&... args)
- {
- std::size_t nodeCount = BlankCounts[cmSPDXGetTypeId<T>()]++;
- std::string nodeId =
- cmStrCat("_:", cmSPDXGetTypeName<T>(), "_", nodeCount);
- auto const& it = Graph.emplace(
- std::piecewise_construct, std::forward_as_tuple(nodeId),
- std::forward_as_tuple(cmSPDXTag<T>{}, std::forward<Args>(args)...));
- auto& node = *it.first->second.template get<T>();
- node.NodeId = std::move(nodeId);
- return node;
- }
-
- template <typename T>
- T* get(std::string const& key)
- {
- auto it = Graph.find(key);
- if (it == Graph.end()) {
- return nullptr;
- }
- return it->second.get<T>();
- }
-
- template <typename T>
- T* get(cmSPDXIdentifierReference const& key)
- {
- auto it = Graph.find(key.NodeId);
- if (it == Graph.end()) {
- return nullptr;
- }
- return it->second.get<T>();
- }
-
- Json::Value toJsonLD();
-
-private:
- std::string IRIBase;
- std::size_t IRICount{ 0 };
- std::array<std::size_t, cmSPDXSerializationBase::SPDX_TYPE_ID_MAX>
- BlankCounts{};
-
- std::map<std::string, cmSPDXObject> Graph;
- cmSPDXCreationInfo* CreationInfo;
-};
diff --git a/Source/cmSPDXTypes.def b/Source/cmSPDXTypes.def
deleted file mode 100644
index 88d8043..0000000
--- a/Source/cmSPDXTypes.def
+++ /dev/null
@@ -1,54 +0,0 @@
-/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
- file LICENSE.rst or https://cmake.org/licensing for details. */
-#ifndef X_SPDX
-# define X_SPDX(classtype, enumid, member, camel)
-#endif
-
-// Convenience
-X_SPDX(cmSPDXIdentifierReference, CM_IDENTIFIER_REFERENCE, IdentifierReference,
- identifierReference)
-
-// Core
-X_SPDX(cmSPDXAgent, CORE_AGENT, Agent, agent)
-X_SPDX(cmSPDXAnnotation, CORE_ANNOTATION, Annotation, annotation)
-X_SPDX(cmSPDXBom, CORE_BOM, Bom, bom)
-X_SPDX(cmSPDXBundle, CORE_BUNDLE, Bundle, bundle)
-X_SPDX(cmSPDXCreationInfo, CORE_CREATION_INFO, CreationInfo, creationInfo)
-X_SPDX(cmSPDXDictionaryEntry, CORE_DICTIONARY_ENTRY, DictionaryEntry,
- dictionaryEntry)
-X_SPDX(cmSPDXExternalIdentifier, CORE_EXTERNAL_IDENTIFIER, ExternalIdentifier,
- externalIdentifier)
-X_SPDX(cmSPDXExternalMap, CORE_EXTERNAL_MAP, ExternalMap, externalMap)
-X_SPDX(cmSPDXExternalRef, CORE_EXTERNAL_REF, ExternalRef, externalRef)
-X_SPDX(cmSPDXHash, CORE_HASH, Hash, hash)
-X_SPDX(cmSPDXIndividualElement, CORE_INDIVIDUAL_ELEMENT, IndividualElement,
- individualElement)
-X_SPDX(cmSPDXLifecycleScopedRelationship, CORE_LIFECYCLE_SCOPED_RELATIONSHIP,
- LifecycleScopedRelationship, lifecycleScopedRelationship)
-X_SPDX(cmSPDXNamespaceMap, CORE_NAMESPACE_MAP, NamespaceMap, namespaceMap)
-X_SPDX(cmSPDXOrganization, CORE_ORGANIZATION, Organization, organization)
-X_SPDX(cmSPDXPackageVerificationCode, CORE_PACKAGE_VERIFICATION_CODE,
- PackageVerificationCode, packageVerificationCode)
-X_SPDX(cmSPDXPerson, CORE_PERSON, Person, person)
-X_SPDX(cmSPDXPositiveIntegerRange, CORE_POSITIVE_INTEGER_RANGE,
- PositiveIntegerRange, positiveIntegerRange)
-X_SPDX(cmSPDXRelationship, CORE_RELATIONSHIP, Relationship, relationship)
-X_SPDX(cmSPDXSoftwareAgent, CORE_SOFTWARE_AGENT, SoftwareAgent, softwareAgent)
-X_SPDX(cmSPDXSpdxDocument, CORE_SPDX_DOCUMENT, SpdxDocument, spdxDocument)
-X_SPDX(cmSPDXTool, CORE_TOOL, Tool, tool)
-
-// Software
-X_SPDX(cmSPDXContentIdentifier, SOFTWARE_CONTENT_IDENTIFIER, ContentIdentifier,
- contentIdentifier)
-X_SPDX(cmSPDXFile, SOFTWARE_FILE, File, file)
-X_SPDX(cmSPDXPackage, SOFTWARE_PACKAGE, Package, package)
-X_SPDX(cmSPDXSbom, SOFTWARE_SBOM, Sbom, sbom)
-X_SPDX(cmSPDXSnippet, SOFTWARE_SNIPPET, Snippet, snippet)
-
-// SimpleLicensing
-X_SPDX(cmSPDXLicenseExpression, SIMPLE_LICENSING_LICENSE_EXPRESSION,
- LicenseExpression, licenseExpression)
-X_SPDX(cmSPDXSimpleLicensingText, SIMPLE_LICENSING_SIMPLE_LICENSING_TEXT,
- SimpleLicensingText, simpleLicensingText)
-
-#undef X_SPDX
diff --git a/Source/cmSbomObject.h b/Source/cmSbomObject.h
new file mode 100644
index 0000000..3f42cfb
--- /dev/null
+++ b/Source/cmSbomObject.h
@@ -0,0 +1,270 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file LICENSE.rst or https://cmake.org/licensing for details. */
+#pragma once
+
+#include <cstddef>
+#include <memory>
+#include <string>
+#include <vector>
+
+#include <cm/type_traits>
+
+#include "cmSbomSerializer.h"
+
+class cmSbomObject;
+
+template <typename T>
+inline void SerializeDispatch(T const& t, cmSbomSerializer& serializer)
+{
+ serializer.BeginObject();
+ t.Serialize(serializer);
+ serializer.EndObject();
+}
+
+template <typename T>
+inline void SerializeDispatch(T* p, cmSbomSerializer& serializer)
+{
+ if (p->SpdxId) {
+ serializer.AddReference(*p->SpdxId);
+ }
+}
+
+inline void SerializeDispatch(std::nullptr_t, cmSbomSerializer&)
+{
+}
+
+struct ObjectInterface
+{
+ virtual ObjectInterface* Copy(void* storage) const = 0;
+ virtual ObjectInterface* Move(void* storage) = 0;
+ virtual void* Addr() noexcept = 0;
+ virtual void const* Addr() const noexcept = 0;
+ virtual void SerializeImpl(cmSbomSerializer& os) const = 0;
+ virtual ~ObjectInterface() = default;
+
+ ObjectInterface() = default;
+ ObjectInterface(ObjectInterface const&) = default;
+ ObjectInterface& operator=(ObjectInterface const&) = default;
+ ObjectInterface(ObjectInterface&&) noexcept = default;
+ ObjectInterface& operator=(ObjectInterface&&) noexcept = default;
+};
+
+namespace impl {
+
+#if defined(__GLIBCXX__) && __GLIBCXX__ <= 20150623
+using max_align_t = ::max_align_t;
+#else
+using max_align_t = std::max_align_t;
+#endif
+
+enum class StorageKind
+{
+ Stack,
+ Heap
+};
+
+template <typename, StorageKind>
+struct Storage
+{
+};
+
+template <typename T>
+struct Storage<T, StorageKind::Stack> : ObjectInterface
+{
+ using ValueType = cm::decay_t<T>;
+
+ explicit Storage(T x)
+ : Value(std::move(x))
+ {
+ }
+
+ Storage(Storage&&) noexcept(
+ std::is_nothrow_move_constructible<ValueType>::value) = default;
+ ~Storage() override = default;
+
+ void* Addr() noexcept override { return std::addressof(Value); }
+ void const* Addr() const noexcept override { return std::addressof(Value); }
+
+ ValueType& get() { return Value; }
+ ValueType const& get() const { return Value; }
+
+private:
+ ValueType Value;
+};
+
+template <typename T>
+struct Storage<T, StorageKind::Heap> : ObjectInterface
+{
+ using ValueType = cm::decay_t<T>;
+
+ explicit Storage(T x)
+ : Ptr(new T(std::move(x)))
+ {
+ }
+
+ Storage(Storage&&) noexcept = default;
+ ~Storage() override = default;
+
+ void* Addr() noexcept override { return Ptr.get(); }
+ void const* Addr() const noexcept override { return Ptr.get(); }
+
+ ValueType& get() { return *Ptr; }
+ ValueType const& get() const { return *Ptr; }
+
+private:
+ std::unique_ptr<ValueType> Ptr;
+};
+
+template <>
+struct Storage<std::nullptr_t, StorageKind::Stack> : ObjectInterface
+{
+ explicit Storage(std::nullptr_t) {}
+
+ Storage(Storage&&) noexcept = default;
+ ~Storage() override = default;
+
+ void* Addr() noexcept override { return nullptr; }
+ void const* Addr() const noexcept override { return nullptr; }
+
+ void SerializeImpl(cmSbomSerializer&) const override {}
+
+ std::nullptr_t get() { return nullptr; }
+ std::nullptr_t get() const { return nullptr; }
+};
+
+}
+
+struct ObjectStorage
+{
+ template <typename T>
+ using Stack = impl::Storage<T, impl::StorageKind::Stack>;
+ template <typename T>
+ using Heap = impl::Storage<T, impl::StorageKind::Heap>;
+
+ static constexpr std::size_t BufferSize = 128u;
+
+ static constexpr std::size_t Size = sizeof(Heap<std::nullptr_t>) > BufferSize
+ ? sizeof(Heap<std::nullptr_t>)
+ : BufferSize;
+ static constexpr std::size_t Align = alignof(impl::max_align_t);
+
+ struct Buffer
+ {
+ alignas(Align) unsigned char Data[Size];
+ };
+
+ template <typename Concrete>
+ using Model = cm::conditional_t<sizeof(Stack<Concrete>) <= Size &&
+ alignof(Stack<Concrete>) <= Align,
+ Stack<Concrete>, Heap<Concrete>>;
+};
+
+class cmSbomObject
+{
+public:
+ template <typename T>
+ struct Instance : ObjectStorage::Model<T>
+ {
+ using Base = ObjectStorage::Model<T>;
+ using Base::Base;
+ Instance(Instance&&) noexcept = default;
+
+ ObjectInterface* Copy(void* storage) const override
+ {
+ return ::new (storage) Instance(this->get());
+ }
+
+ ObjectInterface* Move(void* storage) override
+ {
+ return ::new (storage) Instance(std::move(*this));
+ }
+
+ void SerializeImpl(cmSbomSerializer& os) const override
+ {
+ SerializeDispatch(this->get(), os);
+ }
+ };
+
+ cmSbomObject() { ::new (Storage()) Instance<std::nullptr_t>(nullptr); }
+ cmSbomObject(std::nullptr_t)
+ : cmSbomObject()
+ {
+ }
+
+ template <
+ typename T, typename Decayed = cm::remove_cv_t<cm::remove_reference_t<T>>,
+ typename = cm::enable_if_t<!std::is_same<Decayed, cmSbomObject>::value>>
+ cmSbomObject(T&& x)
+ {
+ ::new (Storage()) Instance<Decayed>(std::forward<T>(x));
+ }
+
+ cmSbomObject(cmSbomObject const& other)
+ {
+ other.Interface().Copy(Storage());
+ }
+ cmSbomObject(cmSbomObject&& other) noexcept
+ {
+ other.Interface().Move(Storage());
+ }
+
+ ~cmSbomObject() noexcept { Interface().~ObjectInterface(); }
+
+ cmSbomObject& operator=(cmSbomObject rhs)
+ {
+ Interface().~ObjectInterface();
+ rhs.Interface().Move(Storage());
+ return *this;
+ }
+
+ bool IsNull() const noexcept { return Interface().Addr() == nullptr; }
+ explicit operator bool() const noexcept { return !IsNull(); }
+
+ void Serialize(cmSbomSerializer& os) const { Interface().SerializeImpl(os); }
+
+ template <typename T>
+ T& CastUnchecked()
+ {
+ return *static_cast<T*>(Interface().Addr());
+ }
+
+ template <typename T>
+ T const& CastUnchecked() const
+ {
+ return *static_cast<T const*>(Interface().Addr());
+ }
+
+ ObjectInterface& Interface()
+ {
+ return *static_cast<ObjectInterface*>(Storage());
+ }
+ ObjectInterface const& Interface() const
+ {
+ return *static_cast<ObjectInterface const*>(Storage());
+ }
+
+ void* Storage() { return &Data.Data; }
+ void const* Storage() const { return &Data.Data; }
+
+ template <typename U>
+ U* ptr() noexcept
+ {
+ return std::addressof(this->template CastUnchecked<U>());
+ }
+
+ template <typename U>
+ U const* ptr() const noexcept
+ {
+ return std::addressof(this->template CastUnchecked<U>());
+ }
+
+private:
+ ObjectStorage::Buffer Data{};
+};
+
+template <typename T, typename U = cm::decay_t<T>>
+U* insert_back(std::vector<cmSbomObject>& vec, T&& obj) noexcept
+{
+ vec.emplace_back(std::forward<U>(obj));
+ return std::addressof(vec.back().CastUnchecked<U>());
+}
diff --git a/Source/cmSbomSerializer.h b/Source/cmSbomSerializer.h
new file mode 100644
index 0000000..019a1c7
--- /dev/null
+++ b/Source/cmSbomSerializer.h
@@ -0,0 +1,38 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file LICENSE.rst or https://cmake.org/licensing for details. */
+#pragma once
+
+#include <string>
+#include <vector>
+
+#include <cm/optional>
+
+class cmSbomObject;
+class cmSbomSerializer
+{
+public:
+ cmSbomSerializer() = default;
+ cmSbomSerializer(cmSbomSerializer const&) = default;
+ cmSbomSerializer(cmSbomSerializer&&) = default;
+ cmSbomSerializer& operator=(cmSbomSerializer const&) = default;
+ cmSbomSerializer& operator=(cmSbomSerializer&&) = default;
+
+ virtual void BeginObject() {}
+ virtual void EndObject() {}
+ virtual void BeginArray() {}
+ virtual void EndArray() {}
+
+ virtual void AddReference(std::string const& id) = 0;
+
+ virtual void AddString(std::string const& key, std::string const& value) = 0;
+ virtual void AddVisitable(std::string const& key,
+ cmSbomObject const& visitable) = 0;
+
+ virtual void AddVectorIfPresent(std::string const& key,
+ std::vector<cmSbomObject> const& vec) = 0;
+ virtual void AddVectorIfPresent(std::string const& key,
+ std::vector<std::string> const& vec) = 0;
+
+ virtual bool WriteSbom(std::ostream& os, cmSbomObject const& document) = 0;
+ virtual ~cmSbomSerializer() = default;
+};
diff --git a/Source/cmSpdx.cxx b/Source/cmSpdx.cxx
new file mode 100644
index 0000000..6bd37ce
--- /dev/null
+++ b/Source/cmSpdx.cxx
@@ -0,0 +1,520 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file LICENSE.rst or https://cmake.org/licensing for details. */
+#include "cmSpdx.h"
+
+#include <stdexcept>
+#include <string>
+
+#include "cmSbomSerializer.h"
+
+inline void SerializeIfPresent(cmSbomSerializer& s, std::string const& key,
+ cm::optional<std::string> const& v)
+{
+ if (v) {
+ s.AddString(key, *v);
+ }
+}
+
+std::string to_string(cmSpdxIntegrityMethod::HashAlgorithmId id)
+{
+ switch (id) {
+ case cmSpdxIntegrityMethod::HashAlgorithmId::ADLER32:
+ return "ADLER32";
+ case cmSpdxIntegrityMethod::HashAlgorithmId::BLAKE2B256:
+ return "BLAKE2B256";
+ case cmSpdxIntegrityMethod::HashAlgorithmId::BLAKE2B384:
+ return "BLAKE2B384";
+ case cmSpdxIntegrityMethod::HashAlgorithmId::BLAKE2B512:
+ return "BLAKE2B512";
+ case cmSpdxIntegrityMethod::HashAlgorithmId::BLAKE3:
+ return "BLAKE3";
+ case cmSpdxIntegrityMethod::HashAlgorithmId::MD2:
+ return "MD2";
+ case cmSpdxIntegrityMethod::HashAlgorithmId::MD4:
+ return "MD4";
+ case cmSpdxIntegrityMethod::HashAlgorithmId::MD5:
+ return "MD5";
+ case cmSpdxIntegrityMethod::HashAlgorithmId::MD6:
+ return "MD6";
+ case cmSpdxIntegrityMethod::HashAlgorithmId::SHA1:
+ return "SHA1";
+ case cmSpdxIntegrityMethod::HashAlgorithmId::SHA224:
+ return "SHA224";
+ case cmSpdxIntegrityMethod::HashAlgorithmId::SHA256:
+ return "SHA256";
+ case cmSpdxIntegrityMethod::HashAlgorithmId::SHA384:
+ return "SHA384";
+ case cmSpdxIntegrityMethod::HashAlgorithmId::SHA512:
+ return "SHA512";
+ case cmSpdxIntegrityMethod::HashAlgorithmId::SHA3_256:
+ return "SHA3_256";
+ case cmSpdxIntegrityMethod::HashAlgorithmId::SHA3_384:
+ return "SHA3_384";
+ case cmSpdxIntegrityMethod::HashAlgorithmId::SHA3_512:
+ return "SHA3_512";
+ }
+ throw std::invalid_argument("Unknown HashAlgorithmId");
+}
+
+std::string to_string(cmSpdxSoftwareArtifact::PurposeId id)
+{
+ switch (id) {
+ case cmSpdxSoftwareArtifact::PurposeId::APPLICATION:
+ return "APPLICATION";
+ case cmSpdxSoftwareArtifact::PurposeId::ARCHIVE:
+ return "ARCHIVE";
+ case cmSpdxSoftwareArtifact::PurposeId::CONTAINER:
+ return "CONTAINER";
+ case cmSpdxSoftwareArtifact::PurposeId::DATA:
+ return "DATA";
+ case cmSpdxSoftwareArtifact::PurposeId::DEVICE:
+ return "DEVICE";
+ case cmSpdxSoftwareArtifact::PurposeId::FIRMWARE:
+ return "FIRMWARE";
+ case cmSpdxSoftwareArtifact::PurposeId::FILE:
+ return "FILE";
+ case cmSpdxSoftwareArtifact::PurposeId::INSTALL:
+ return "INSTALL";
+ case cmSpdxSoftwareArtifact::PurposeId::LIBRARY:
+ return "LIBRARY";
+ case cmSpdxSoftwareArtifact::PurposeId::MODULE:
+ return "MODULE";
+ case cmSpdxSoftwareArtifact::PurposeId::OPERATING_SYSTEM:
+ return "OPERATING_SYSTEM";
+ case cmSpdxSoftwareArtifact::PurposeId::SOURCE:
+ return "SOURCE";
+ }
+ throw std::invalid_argument("Unknown PurposeId");
+}
+
+std::string to_string(cmSpdxSbom::TypeId id)
+{
+ switch (id) {
+ case cmSpdxSbom::TypeId::ANALYZED:
+ return "ANALYZED";
+ case cmSpdxSbom::TypeId::BUILD:
+ return "BUILD";
+ case cmSpdxSbom::TypeId::DEPLOYED:
+ return "DEPLOYED";
+ case cmSpdxSbom::TypeId::DESIGN:
+ return "DESIGN";
+ case cmSpdxSbom::TypeId::RUNTIME:
+ return "RUNTIME";
+ case cmSpdxSbom::TypeId::SOURCE:
+ return "SOURCE";
+ case cmSpdxSbom::TypeId::TEST:
+ return "TEST";
+ }
+ throw std::invalid_argument("Unknown Sbom::TypeId");
+}
+
+std::string to_string(cmSpdxFile::FileKindId id)
+{
+ switch (id) {
+ case cmSpdxFile::FileKindId::DIRECTORY:
+ return "DIRECTORY";
+ case cmSpdxFile::FileKindId::FILE:
+ return "FILE";
+ }
+ throw std::invalid_argument("Unknown File::FileKindId");
+}
+
+std::string to_string(cmSpdxRelationship::RelationshipTypeId id)
+{
+ switch (id) {
+ case cmSpdxRelationship::RelationshipTypeId::DESCRIBES:
+ return "DESCRIBES";
+ case cmSpdxRelationship::RelationshipTypeId::CONTAINS:
+ return "CONTAINS";
+ case cmSpdxRelationship::RelationshipTypeId::DEPENDS_ON:
+ return "DEPENDS_ON";
+ case cmSpdxRelationship::RelationshipTypeId::OTHER:
+ return "OTHER";
+ }
+ throw std::invalid_argument("Unknown RelationshipTypeId");
+}
+
+std::string to_string(cmSpdxLifecycleScopedRelationship::ScopeId id)
+{
+ switch (id) {
+ case cmSpdxLifecycleScopedRelationship::ScopeId::BUILD:
+ return "BUILD";
+ case cmSpdxLifecycleScopedRelationship::ScopeId::DESIGN:
+ return "DESIGN";
+ case cmSpdxLifecycleScopedRelationship::ScopeId::RUNTIME:
+ return "RUNTIME";
+ case cmSpdxLifecycleScopedRelationship::ScopeId::TEST:
+ return "TEST";
+ }
+ throw std::invalid_argument("Unknown Lifecycle ScopeId");
+}
+
+std::string to_string(cmSpdxAnnotation::AnnotationTypeId id)
+{
+ switch (id) {
+ case cmSpdxAnnotation::AnnotationTypeId::REVIEW:
+ return "REVIEW";
+ case cmSpdxAnnotation::AnnotationTypeId::OTHER:
+ return "OTHER";
+ }
+ throw std::invalid_argument("Unknown AnnotationTypeId");
+}
+
+std::string to_string(cmSpdxArtifact::SupportTypeId id)
+{
+ switch (id) {
+ case cmSpdxArtifact::SupportTypeId::COMMUNITY:
+ return "COMMUNITY";
+ case cmSpdxArtifact::SupportTypeId::COMMERCIAL:
+ return "COMMERCIAL";
+ case cmSpdxArtifact::SupportTypeId::NONE:
+ return "NONE";
+ }
+ throw std::invalid_argument("Unknown SupportTypeId");
+}
+
+void cmSpdxExternalIdentifier::Serialize(cmSbomSerializer& serializer) const
+{
+ serializer.AddString("type", "ExternalIdentifier");
+ SerializeIfPresent(serializer, "externalIdentifierType",
+ ExternalIdentifierType);
+ SerializeIfPresent(serializer, "identifier", Identifier);
+ SerializeIfPresent(serializer, "comment", Comment);
+ SerializeIfPresent(serializer, "identifierLocation", IdentifierLocation);
+ SerializeIfPresent(serializer, "issuingAuthority", IssuingAuthority);
+}
+
+void cmSpdxExternalRef::Serialize(cmSbomSerializer& serializer) const
+{
+ serializer.AddString("type", "ExternalRef");
+ SerializeIfPresent(serializer, "externalRefType", ExternalRefType);
+ SerializeIfPresent(serializer, "locator", Locator);
+ SerializeIfPresent(serializer, "contentType", ContentType);
+ SerializeIfPresent(serializer, "comment", Comment);
+}
+
+void cmSpdxChecksum::Serialize(cmSbomSerializer& serializer) const
+{
+ serializer.AddString("type", "Checksum");
+ serializer.AddString("algorithm", to_string(Algorithm));
+ serializer.AddString("checksumValue", ChecksumValue);
+}
+
+void cmSpdxCreationInfo::Serialize(cmSbomSerializer& serializer) const
+{
+ serializer.AddString("type", "CreationInfo");
+ SerializeIfPresent(serializer, "@id", SpdxId);
+ if (SpecVersion) {
+ serializer.AddString("specVersion", *SpecVersion);
+ }
+ SerializeIfPresent(serializer, "comment", Comment);
+ SerializeIfPresent(serializer, "created", Created);
+ if (!CreatedBy.empty()) {
+ serializer.AddVectorIfPresent("createdBy", CreatedBy);
+ }
+ if (!CreatedUsing.empty()) {
+ serializer.AddVectorIfPresent("createdUsing", CreatedUsing);
+ }
+}
+
+void cmSpdxIntegrityMethod::Serialize(cmSbomSerializer& serializer) const
+{
+ serializer.AddString("type", "IntegrityMethod");
+ SerializeIfPresent(serializer, "comment", Comment);
+}
+
+void cmSpdxElement::Serialize(cmSbomSerializer& serializer) const
+{
+ serializer.AddString("type", "Element");
+ SerializeIfPresent(serializer, "@id", SpdxId);
+ SerializeIfPresent(serializer, "name", Name);
+ SerializeIfPresent(serializer, "summary", Summary);
+ SerializeIfPresent(serializer, "description", Description);
+ SerializeIfPresent(serializer, "comment", Comment);
+ if (CreationInfo) {
+ serializer.AddVisitable("creationInfo", *CreationInfo);
+ }
+ if (VerifiedUsing) {
+ serializer.AddVisitable("verifiedUsing", *VerifiedUsing);
+ }
+ if (!ExternalRef.empty()) {
+ serializer.AddVectorIfPresent("externalRef", ExternalRef);
+ }
+ if (!ExternalIdentifier.empty()) {
+ serializer.AddVectorIfPresent("externalIdentifier", ExternalIdentifier);
+ }
+ if (Extension) {
+ serializer.AddVisitable("extension", *Extension);
+ }
+}
+
+void cmSpdxTool::Serialize(cmSbomSerializer& serializer) const
+{
+ cmSpdxElement::Serialize(serializer);
+ serializer.AddString("type", "Tool");
+}
+
+void cmSpdxAgent::Serialize(cmSbomSerializer& serializer) const
+{
+ cmSpdxElement::Serialize(serializer);
+ serializer.AddString("type", "Agent");
+}
+
+void cmSpdxOrganization::Serialize(cmSbomSerializer& serializer) const
+{
+ cmSpdxAgent::Serialize(serializer);
+ serializer.AddString("type", "Organization");
+}
+
+void cmSpdxPerson::Serialize(cmSbomSerializer& serializer) const
+{
+ cmSpdxAgent::Serialize(serializer);
+ serializer.AddString("type", "Person");
+}
+
+void cmSpdxSoftwareAgent::Serialize(cmSbomSerializer& serializer) const
+{
+ cmSpdxAgent::Serialize(serializer);
+ serializer.AddString("type", "SoftwareAgent");
+}
+
+void cmSpdxPositiveIntegerRange::Serialize(cmSbomSerializer& serializer) const
+{
+ serializer.AddString("type", "PositiveIntegerRange");
+ SerializeIfPresent(serializer, "beginIntegerRange", BeginIntegerRange);
+ SerializeIfPresent(serializer, "endIntegerRange", EndIntegerRange);
+}
+
+void cmSpdxRelationship::Serialize(cmSbomSerializer& serializer) const
+{
+ cmSpdxElement::Serialize(serializer);
+ serializer.AddString("type", "Relationship");
+ if (From) {
+ serializer.AddVisitable("from", *From);
+ }
+ if (!To.empty()) {
+ serializer.AddVectorIfPresent("to", To);
+ }
+ if (RelationshipType) {
+ serializer.AddString("relationshipType", to_string(*RelationshipType));
+ }
+ SerializeIfPresent(serializer, "startTime", StartTime);
+ SerializeIfPresent(serializer, "endTime", EndTime);
+}
+
+void cmSpdxLifecycleScopedRelationship::Serialize(
+ cmSbomSerializer& serializer) const
+{
+ cmSpdxRelationship::Serialize(serializer);
+ serializer.AddString("type", "LifecycleScopedRelationship");
+ if (Scope) {
+ serializer.AddString("scope", to_string(*Scope));
+ }
+}
+
+void cmSpdxArtifact::Serialize(cmSbomSerializer& serializer) const
+{
+ cmSpdxElement::Serialize(serializer);
+ serializer.AddString("type", "Artifact");
+ if (!OriginatedBy.empty()) {
+ serializer.AddVectorIfPresent("originatedBy", OriginatedBy);
+ }
+ if (SuppliedBy) {
+ serializer.AddVisitable("suppliedBy", *SuppliedBy);
+ }
+ SerializeIfPresent(serializer, "builtTime", BuiltTime);
+ SerializeIfPresent(serializer, "releaseTime", ReleaseTime);
+ SerializeIfPresent(serializer, "validUntilTime", ValidUntilTime);
+ SerializeIfPresent(serializer, "standardName", StandardName);
+ if (Support) {
+ serializer.AddString("support", to_string(*Support));
+ }
+}
+
+void cmSpdxIndividualElement::Serialize(cmSbomSerializer& serializer) const
+{
+ cmSpdxElement::Serialize(serializer);
+ serializer.AddString("type", "IndividualElement");
+}
+
+void cmSpdxAnnotation::Serialize(cmSbomSerializer& serializer) const
+{
+ cmSpdxElement::Serialize(serializer);
+ serializer.AddString("type", "Annotation");
+ if (AnnotationType) {
+ serializer.AddString("annotationType", to_string(*AnnotationType));
+ }
+ SerializeIfPresent(serializer, "contentType", ContentType);
+ SerializeIfPresent(serializer, "statement", Statement);
+ if (Element) {
+ serializer.AddVisitable("element", *Element);
+ }
+}
+
+void cmSpdxExternalMap::Serialize(cmSbomSerializer& serializer) const
+{
+ serializer.AddString("type", "ExternalMap");
+ SerializeIfPresent(serializer, "externalSpdxId", ExternalSpdxId);
+ if (VerifiedUsing) {
+ serializer.AddVisitable("verifiedUsing", *VerifiedUsing);
+ }
+ SerializeIfPresent(serializer, "locationHistory", LocationHistory);
+ if (DefiningArtifact) {
+ serializer.AddVisitable("definingArtifact", *DefiningArtifact);
+ }
+}
+
+void cmSpdxNamespaceMap::Serialize(cmSbomSerializer& serializer) const
+{
+ serializer.AddString("type", "NamespaceMap");
+ SerializeIfPresent(serializer, "prefix", Prefix);
+ SerializeIfPresent(serializer, "namespace", Namespace);
+}
+
+void cmSpdxElementCollection::Serialize(cmSbomSerializer& serializer) const
+{
+ cmSpdxElement::Serialize(serializer);
+ serializer.AddString("type", "ElementCollection");
+ if (!Elements.empty()) {
+ serializer.AddVectorIfPresent("element", Elements);
+ }
+ if (!RootElements.empty()) {
+ serializer.AddVectorIfPresent("rootElement", RootElements);
+ }
+ if (!ProfileConformance.empty()) {
+ serializer.AddVectorIfPresent("profileConformance", ProfileConformance);
+ }
+}
+
+void cmSpdxPackageVerificationCode::Serialize(
+ cmSbomSerializer& serializer) const
+{
+ serializer.AddString("type", "PackageVerificationCode");
+ if (Algorithm) {
+ serializer.AddString("algorithm", to_string(*Algorithm));
+ }
+ SerializeIfPresent(serializer, "hashValue", HashValue);
+ SerializeIfPresent(serializer, "packageVerificationCodeExcludedFile",
+ PackageVerificationCodeExcludedFile);
+}
+
+void cmSpdxHash::Serialize(cmSbomSerializer& serializer) const
+{
+ serializer.AddString("type", "Hash");
+ serializer.AddString("hashAlgorithm", to_string(HashAlgorithm));
+ serializer.AddString("hashValue", HashValue);
+}
+
+void cmSpdxBundle::Serialize(cmSbomSerializer& serializer) const
+{
+ cmSpdxElementCollection::Serialize(serializer);
+ serializer.AddString("type", "Bundle");
+ SerializeIfPresent(serializer, "context", Context);
+}
+
+void cmSpdxBom::Serialize(cmSbomSerializer& serializer) const
+{
+ cmSpdxBundle::Serialize(serializer);
+ serializer.AddString("type", "Bom");
+}
+
+void cmSpdxSbom::Serialize(cmSbomSerializer& serializer) const
+{
+ cmSpdxBom::Serialize(serializer);
+ serializer.AddString("type", "software_Sbom");
+ if (Types) {
+ for (auto const& t : *Types) {
+ serializer.AddString("sbomType", to_string(t));
+ }
+ }
+ if (LifecycleScope) {
+ serializer.AddString("lifecycleScope", to_string(*LifecycleScope));
+ }
+}
+
+void cmSpdxSoftwareArtifact::Serialize(cmSbomSerializer& serializer) const
+{
+ cmSpdxArtifact::Serialize(serializer);
+ serializer.AddString("type", "software_SoftwareArtifact");
+ if (PrimaryPurpose) {
+ serializer.AddString("primaryPurpose", to_string(*PrimaryPurpose));
+ }
+ if (AdditionalPurpose) {
+ for (auto const& p : *AdditionalPurpose) {
+ serializer.AddString("additionalPurpose", to_string(p));
+ }
+ }
+ SerializeIfPresent(serializer, "copyrightText", CopyrightText);
+ SerializeIfPresent(serializer, "attributionText", AttributionText);
+ if (ContentIdentifier) {
+ serializer.AddVisitable("contentIdentifier", *ContentIdentifier);
+ }
+ SerializeIfPresent(serializer, "artifactSize", ArtifactSize);
+}
+
+void cmSpdxPackage::Serialize(cmSbomSerializer& serializer) const
+{
+ cmSpdxSoftwareArtifact::Serialize(serializer);
+ serializer.AddString("type", "software_Package");
+ SerializeIfPresent(serializer, "downloadLocation", DownloadLocation);
+ SerializeIfPresent(serializer, "homePage", Homepage);
+ SerializeIfPresent(serializer, "packageVersion", PackageVersion);
+ SerializeIfPresent(serializer, "packageUrl", PackageUrl);
+ SerializeIfPresent(serializer, "sourceInfo", SourceInfo);
+}
+
+void cmSpdxFile::Serialize(cmSbomSerializer& serializer) const
+{
+ cmSpdxArtifact::Serialize(serializer);
+ serializer.AddString("type", "software_File");
+ if (ContentType) {
+ serializer.AddString("contentType", *ContentType);
+ }
+ if (FileType) {
+ serializer.AddString("fileType", to_string(*FileType));
+ }
+}
+
+void cmSpdxContentIdentifier::Serialize(cmSbomSerializer& serializer) const
+{
+ cmSpdxIntegrityMethod::Serialize(serializer);
+ serializer.AddString("type", "software_ContentIdentifier");
+ SerializeIfPresent(serializer, "contentIdentifierType",
+ ContentIdentifierType);
+ SerializeIfPresent(serializer, "contentValue", ContentValue);
+}
+
+void cmSpdxSnippet::Serialize(cmSbomSerializer& serializer) const
+{
+ cmSpdxSoftwareArtifact::Serialize(serializer);
+ serializer.AddString("type", "software_Snippet");
+ SerializeIfPresent(serializer, "byteRange", ByteRange);
+ SerializeIfPresent(serializer, "lineRange", LineRange);
+ if (SnippetFromFile) {
+ serializer.AddVisitable("snippetFromFile", *SnippetFromFile);
+ }
+}
+
+void cmSpdxDocument::Serialize(cmSbomSerializer& serializer) const
+{
+ cmSpdxElementCollection::Serialize(serializer);
+
+ serializer.AddString("type", "SpdxDocument");
+ if (ExternalMap) {
+ serializer.AddVisitable("externalMap", *ExternalMap);
+ }
+ if (NamespaceMap) {
+ serializer.AddVisitable("namespaceMap", *NamespaceMap);
+ }
+ SerializeIfPresent(serializer, "dataLicense", DataLicense);
+}
+
+void cmSbomDocument::Serialize(cmSbomSerializer& serializer) const
+{
+ serializer.AddString(
+ "@context",
+ Context.value_or("https://spdx.org/rdf/3.0.1/spdx-context.jsonld"));
+ if (!Graph.empty()) {
+ serializer.AddVectorIfPresent("@graph", Graph);
+ }
+}
diff --git a/Source/cmSpdx.h b/Source/cmSpdx.h
new file mode 100644
index 0000000..9b37828
--- /dev/null
+++ b/Source/cmSpdx.h
@@ -0,0 +1,390 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file LICENSE.rst or https://cmake.org/licensing for details. */
+#pragma once
+#include <string>
+#include <vector>
+
+#include <cm/optional>
+
+#include "cmSbomObject.h"
+
+class cmSbomSerializer;
+
+using Datetime = std::string;
+using MediaType = std::string;
+using SemVer = std::string;
+
+struct cmSpdxExternalIdentifier
+{
+ cm::optional<std::string> SpdxId;
+ cm::optional<std::string> ExternalIdentifierType;
+ cm::optional<std::string> Identifier;
+ cm::optional<std::string> Comment;
+ cm::optional<std::string> IdentifierLocation;
+ cm::optional<std::string> IssuingAuthority;
+
+ void Serialize(cmSbomSerializer&) const;
+};
+
+struct cmSpdxExternalRef
+{
+ cm::optional<std::string> SpdxId;
+ cm::optional<std::string> ExternalRefType;
+ cm::optional<std::string> Locator;
+ cm::optional<std::string> ContentType;
+ cm::optional<std::string> Comment;
+
+ void Serialize(cmSbomSerializer&) const;
+};
+
+struct cmSpdxCreationInfo
+{
+ cm::optional<std::string> SpdxId;
+ cm::optional<SemVer> SpecVersion;
+ cm::optional<std::string> Comment;
+ cm::optional<Datetime> Created;
+ std::vector<cmSbomObject> CreatedBy;
+ std::vector<cmSbomObject> CreatedUsing;
+
+ void Serialize(cmSbomSerializer&) const;
+};
+
+struct cmSpdxIntegrityMethod
+{
+ cm::optional<std::string> SpdxId;
+ cm::optional<std::string> Comment;
+
+ enum HashAlgorithmId
+ {
+ ADLER32,
+ BLAKE2B256,
+ BLAKE2B384,
+ BLAKE2B512,
+ BLAKE3,
+ MD2,
+ MD4,
+ MD5,
+ MD6,
+ SHA1,
+ SHA224,
+ SHA256,
+ SHA384,
+ SHA512,
+ SHA3_256,
+ SHA3_384,
+ SHA3_512,
+ };
+
+ cmSpdxIntegrityMethod() = default;
+ cmSpdxIntegrityMethod(cmSpdxIntegrityMethod const&) = default;
+ cmSpdxIntegrityMethod(cmSpdxIntegrityMethod&&) = default;
+ cmSpdxIntegrityMethod& operator=(cmSpdxIntegrityMethod const&) = default;
+ cmSpdxIntegrityMethod& operator=(cmSpdxIntegrityMethod&&) = default;
+
+ virtual void Serialize(cmSbomSerializer&) const;
+ virtual ~cmSpdxIntegrityMethod() = default;
+};
+
+struct cmSpdxChecksum
+{
+ cm::optional<std::string> SpdxId;
+ cmSpdxIntegrityMethod::HashAlgorithmId Algorithm;
+ std::string ChecksumValue;
+
+ void Serialize(cmSbomSerializer&) const;
+};
+
+struct cmSpdxElement
+{
+ cm::optional<std::string> SpdxId;
+ cm::optional<std::string> Name;
+ cm::optional<std::string> Summary;
+ cm::optional<std::string> Description;
+ cm::optional<std::string> Comment;
+ cm::optional<cmSbomObject> CreationInfo;
+ cm::optional<cmSbomObject> VerifiedUsing;
+ std::vector<cmSbomObject> ExternalRef;
+ std::vector<cmSbomObject> ExternalIdentifier;
+ cm::optional<cmSbomObject> Extension;
+
+ cmSpdxElement() = default;
+ cmSpdxElement(cmSpdxElement const&) = default;
+ cmSpdxElement(cmSpdxElement&&) = default;
+ cmSpdxElement& operator=(cmSpdxElement const&) = default;
+ cmSpdxElement& operator=(cmSpdxElement&&) = default;
+
+ virtual ~cmSpdxElement() = default;
+ virtual void Serialize(cmSbomSerializer&) const;
+};
+
+struct cmSpdxTool final : cmSpdxElement
+{
+ void Serialize(cmSbomSerializer&) const override;
+};
+
+struct cmSpdxAgent : cmSpdxElement
+{
+ void Serialize(cmSbomSerializer&) const override;
+};
+
+struct cmSpdxOrganization final : cmSpdxAgent
+{
+ void Serialize(cmSbomSerializer&) const override;
+};
+
+struct cmSpdxPerson final : cmSpdxAgent
+{
+ void Serialize(cmSbomSerializer&) const override;
+};
+
+struct cmSpdxSoftwareAgent final : cmSpdxAgent
+{
+ void Serialize(cmSbomSerializer&) const override;
+};
+
+struct cmSpdxPositiveIntegerRange
+{
+ cm::optional<std::string> SpdxId;
+ cm::optional<std::string> BeginIntegerRange;
+ cm::optional<std::string> EndIntegerRange;
+
+ void Serialize(cmSbomSerializer&) const;
+};
+
+struct cmSpdxRelationship : cmSpdxElement
+{
+ enum RelationshipTypeId
+ {
+ DESCRIBES,
+ CONTAINS,
+ DEPENDS_ON,
+ OTHER
+ };
+
+ cm::optional<cmSbomObject> From;
+ std::vector<cmSbomObject> To;
+ cm::optional<RelationshipTypeId> RelationshipType;
+ cm::optional<Datetime> StartTime;
+ cm::optional<Datetime> EndTime;
+
+ void Serialize(cmSbomSerializer&) const override;
+};
+
+struct cmSpdxLifecycleScopedRelationship final : cmSpdxRelationship
+{
+ enum ScopeId
+ {
+ BUILD,
+ DESIGN,
+ RUNTIME,
+ TEST
+ };
+
+ cm::optional<ScopeId> Scope;
+
+ void Serialize(cmSbomSerializer&) const override;
+};
+
+struct cmSpdxArtifact : cmSpdxElement
+{
+ enum SupportTypeId
+ {
+ COMMUNITY,
+ COMMERCIAL,
+ NONE
+ };
+
+ std::vector<cmSbomObject> OriginatedBy;
+ cm::optional<cmSbomObject> SuppliedBy;
+ cm::optional<Datetime> BuiltTime;
+ cm::optional<Datetime> ReleaseTime;
+ cm::optional<Datetime> ValidUntilTime;
+ cm::optional<std::string> StandardName;
+ cm::optional<SupportTypeId> Support;
+
+ void Serialize(cmSbomSerializer&) const override;
+};
+
+struct cmSpdxIndividualElement final : cmSpdxElement
+{
+ void Serialize(cmSbomSerializer&) const override;
+};
+
+struct cmSpdxAnnotation final : cmSpdxElement
+{
+ enum AnnotationTypeId
+ {
+ REVIEW,
+ OTHER
+ };
+
+ cm::optional<AnnotationTypeId> AnnotationType;
+ cm::optional<MediaType> ContentType;
+ cm::optional<std::string> Statement;
+ cm::optional<cmSbomObject> Element;
+
+ void Serialize(cmSbomSerializer&) const override;
+};
+
+struct cmSpdxExternalMap
+{
+ cm::optional<std::string> SpdxId;
+ cm::optional<std::string> ExternalSpdxId;
+ cm::optional<cmSbomObject> VerifiedUsing;
+ cm::optional<std::string> LocationHistory;
+ cm::optional<cmSbomObject> DefiningArtifact;
+
+ void Serialize(cmSbomSerializer&) const;
+};
+
+struct cmSpdxNamespaceMap
+{
+ cm::optional<std::string> SpdxId;
+ cm::optional<std::string> Prefix;
+ cm::optional<std::string> Namespace;
+
+ void Serialize(cmSbomSerializer&) const;
+};
+
+struct cmSpdxElementCollection : cmSpdxElement
+{
+ std::vector<cmSbomObject> Elements;
+ std::vector<cmSbomObject> RootElements;
+ std::vector<std::string> ProfileConformance;
+
+ void Serialize(cmSbomSerializer&) const override;
+};
+
+struct cmSpdxPackageVerificationCode final : cmSpdxIntegrityMethod
+{
+ cm::optional<HashAlgorithmId> Algorithm;
+ cm::optional<std::string> HashValue;
+ cm::optional<std::string> PackageVerificationCodeExcludedFile;
+
+ void Serialize(cmSbomSerializer&) const override;
+};
+
+struct cmSpdxHash final : cmSpdxIntegrityMethod
+{
+ HashAlgorithmId HashAlgorithm;
+ std::string HashValue;
+
+ void Serialize(cmSbomSerializer&) const override;
+};
+
+struct cmSpdxBundle : cmSpdxElementCollection
+{
+ cm::optional<std::string> Context;
+
+ void Serialize(cmSbomSerializer&) const override;
+};
+
+struct cmSpdxBom : cmSpdxBundle
+{
+ void Serialize(cmSbomSerializer&) const override;
+};
+
+struct cmSpdxSbom final : cmSpdxBom
+{
+ enum TypeId
+ {
+ ANALYZED,
+ BUILD,
+ DEPLOYED,
+ DESIGN,
+ RUNTIME,
+ SOURCE,
+ TEST
+ };
+
+ cm::optional<std::vector<TypeId>> Types;
+ cm::optional<TypeId> LifecycleScope;
+
+ void Serialize(cmSbomSerializer&) const override;
+};
+
+struct cmSpdxSoftwareArtifact : cmSpdxArtifact
+{
+ enum PurposeId
+ {
+ APPLICATION,
+ ARCHIVE,
+ CONTAINER,
+ DATA,
+ DEVICE,
+ FIRMWARE,
+ FILE,
+ INSTALL,
+ LIBRARY,
+ MODULE,
+ OPERATING_SYSTEM,
+ SOURCE
+ };
+
+ cm::optional<PurposeId> PrimaryPurpose;
+ cm::optional<std::vector<PurposeId>> AdditionalPurpose;
+ cm::optional<std::string> CopyrightText;
+ cm::optional<std::string> AttributionText;
+ cm::optional<cmSbomObject> ContentIdentifier;
+ cm::optional<std::string> ArtifactSize;
+
+ void Serialize(cmSbomSerializer&) const override;
+};
+
+struct cmSpdxPackage final : cmSpdxSoftwareArtifact
+{
+ cm::optional<std::string> DownloadLocation;
+ cm::optional<std::string> Homepage;
+ cm::optional<std::string> PackageVersion;
+ cm::optional<std::string> PackageUrl;
+ cm::optional<std::string> SourceInfo;
+
+ void Serialize(cmSbomSerializer&) const override;
+};
+
+struct cmSpdxDocument final : cmSpdxElementCollection
+{
+ cm::optional<cmSbomObject> ExternalMap;
+ cm::optional<cmSbomObject> NamespaceMap;
+ std::string DataLicense;
+
+ void Serialize(cmSbomSerializer& serializer) const override;
+};
+
+struct cmSpdxContentIdentifier final : cmSpdxIntegrityMethod
+{
+ cm::optional<std::string> ContentIdentifierType;
+ cm::optional<std::string> ContentValue;
+
+ void Serialize(cmSbomSerializer&) const override;
+};
+
+struct cmSpdxFile final : cmSpdxArtifact
+{
+ enum FileKindId
+ {
+ DIRECTORY,
+ FILE
+ };
+ cm::optional<MediaType> ContentType;
+ cm::optional<FileKindId> FileType;
+
+ void Serialize(cmSbomSerializer&) const override;
+};
+
+struct cmSpdxSnippet final : cmSpdxSoftwareArtifact
+{
+ cm::optional<std::string> ByteRange;
+ cm::optional<std::string> LineRange;
+ cm::optional<cmSbomObject> SnippetFromFile;
+
+ void Serialize(cmSbomSerializer&) const override;
+};
+
+struct cmSbomDocument
+{
+ cm::optional<std::string> Context;
+ std::vector<cmSbomObject> Graph;
+
+ void Serialize(cmSbomSerializer&) const;
+};
diff --git a/Source/cmSpdxSerializer.cxx b/Source/cmSpdxSerializer.cxx
new file mode 100644
index 0000000..47c22fd
--- /dev/null
+++ b/Source/cmSpdxSerializer.cxx
@@ -0,0 +1,119 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file LICENSE.rst or https://cmake.org/licensing for details. */
+#include "cmSpdxSerializer.h"
+
+#include <utility>
+
+#include <cm3p/json/writer.h>
+
+#include "cmSbomObject.h"
+
+cmSpdxSerializer::cmSpdxSerializer()
+{
+ Json::StreamWriterBuilder builder = Json::StreamWriterBuilder();
+ builder["indentation"] = " ";
+ Writer.reset(builder.newStreamWriter());
+}
+
+void cmSpdxSerializer::BeginObject()
+{
+ CurrentValue = Json::objectValue;
+}
+
+void cmSpdxSerializer::BeginArray()
+{
+ CurrentValue = Json::arrayValue;
+}
+
+void cmSpdxSerializer::EndObject()
+{
+}
+
+void cmSpdxSerializer::EndArray()
+{
+}
+
+void cmSpdxSerializer::AddReference(std::string const& id)
+{
+ CurrentValue = id;
+}
+
+void cmSpdxSerializer::AddString(std::string const& key,
+ std::string const& value)
+{
+ if (!value.empty()) {
+ CurrentValue[key] = value;
+ }
+}
+
+void cmSpdxSerializer::AddVisitable(std::string const& key,
+ cmSbomObject const& visitable)
+{
+ if (visitable.IsNull()) {
+ return;
+ }
+
+ Json::Value parentValue = std::move(CurrentValue);
+ visitable.Serialize(*this);
+ Json::Value childValue = std::move(CurrentValue);
+
+ CurrentValue = std::move(parentValue);
+ CurrentValue[key] = std::move(childValue);
+}
+
+void cmSpdxSerializer::AddVectorIfPresent(std::string const& key,
+ std::vector<cmSbomObject> const& vec)
+{
+ if (vec.empty()) {
+ return;
+ }
+ Json::Value parentValue = std::move(CurrentValue);
+ Json::Value childValue(Json::arrayValue);
+
+ for (auto const& item : vec) {
+ if (item.IsNull()) {
+ continue;
+ }
+
+ item.Serialize(*this);
+
+ if (!CurrentValue.isNull()) {
+ childValue.append(std::move(CurrentValue));
+ }
+ }
+
+ CurrentValue = std::move(parentValue);
+ CurrentValue[key] = std::move(childValue);
+}
+
+void cmSpdxSerializer::AddVectorIfPresent(std::string const& key,
+ std::vector<std::string> const& vec)
+{
+ if (vec.empty()) {
+ return;
+ }
+ Json::Value parentValue = std::move(CurrentValue);
+ Json::Value childValue(Json::arrayValue);
+
+ for (auto const& item : vec) {
+ if (item.empty()) {
+ continue;
+ }
+ childValue.append(item);
+ }
+
+ CurrentValue = std::move(parentValue);
+ CurrentValue[key] = std::move(childValue);
+}
+
+bool cmSpdxSerializer::WriteSbom(std::ostream& os,
+ cmSbomObject const& document)
+{
+ if (document.IsNull()) {
+ return false;
+ }
+
+ document.Serialize(*this);
+ Writer->write(CurrentValue, &os);
+ return os.good();
+}
diff --git a/Source/cmSpdxSerializer.h b/Source/cmSpdxSerializer.h
new file mode 100644
index 0000000..50ece9a
--- /dev/null
+++ b/Source/cmSpdxSerializer.h
@@ -0,0 +1,52 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file LICENSE.rst or https://cmake.org/licensing for details. */
+#pragma once
+
+#include <memory>
+#include <ostream>
+#include <string>
+#include <vector>
+
+#include <cm3p/json/value.h>
+#include <cm3p/json/writer.h>
+
+#include "cmSbomSerializer.h"
+
+class cmSbomObject;
+
+struct cmSpdxSerializer final : cmSbomSerializer
+{
+ cmSpdxSerializer();
+
+ ~cmSpdxSerializer() override = default;
+
+ void BeginObject() override;
+
+ void BeginArray() override;
+
+ void EndObject() override;
+
+ void EndArray() override;
+
+ void AddReference(std::string const& id) override;
+
+ void AddString(std::string const& key, std::string const& value) override;
+
+ void AddVisitable(std::string const& key,
+ cmSbomObject const& visitable) override;
+
+ void AddVectorIfPresent(std::string const& key,
+ std::vector<cmSbomObject> const& vec) override;
+
+ void AddVectorIfPresent(std::string const& key,
+ std::vector<std::string> const& vec) override;
+
+ bool WriteSbom(std::ostream& os, cmSbomObject const& document) override;
+
+ Json::Value GetJson() { return CurrentValue; }
+
+private:
+ Json::Value CurrentValue;
+ std::string CurrentKey;
+ std::unique_ptr<Json::StreamWriter> Writer;
+};
diff --git a/Source/cmSystemTools.cxx b/Source/cmSystemTools.cxx
index 85aba24..c362689 100644
--- a/Source/cmSystemTools.cxx
+++ b/Source/cmSystemTools.cxx
@@ -2034,7 +2034,7 @@
if (in == top) {
out = ".";
} else if (cmSystemTools::IsSubDirectory(in, top)) {
- out = in.substr(top.size() + 1);
+ out = in.substr(top.size() + (top.back() == '/' ? 0 : 1));
} else {
out = in;
}
diff --git a/Source/cmake.cxx b/Source/cmake.cxx
index c15e288..b3a1f79 100644
--- a/Source/cmake.cxx
+++ b/Source/cmake.cxx
@@ -4509,10 +4509,14 @@
std::string cmake::GetCMakeListFile(std::string const& dir) const
{
- std::string listFile = cmStrCat(dir, '/', this->CMakeListName);
- if (this->CMakeListName.empty() ||
- !cmSystemTools::FileExists(listFile, true)) {
- return cmStrCat(dir, "/CMakeLists.txt");
+ cm::string_view const slash =
+ dir.empty() || dir.back() != '/' ? "/"_s : ""_s;
+ std::string listFile;
+ if (!this->CMakeListName.empty()) {
+ listFile = cmStrCat(dir, slash, this->CMakeListName);
+ }
+ if (listFile.empty() || !cmSystemTools::FileExists(listFile, true)) {
+ listFile = cmStrCat(dir, slash, "CMakeLists.txt");
}
return listFile;
}
diff --git a/Source/kwsys/SystemInformation.cxx b/Source/kwsys/SystemInformation.cxx
index a11487d..5f67f16 100644
--- a/Source/kwsys/SystemInformation.cxx
+++ b/Source/kwsys/SystemInformation.cxx
@@ -4131,6 +4131,10 @@
this->TotalPhysicalMemory = tp >> 10 >> 10;
this->AvailableVirtualMemory = av >> 10 >> 10;
this->AvailablePhysicalMemory = ap >> 10 >> 10;
+
+ // The virtual WinAPI memory contains both physical memory and page file.
+ this->TotalVirtualMemory -= this->TotalPhysicalMemory;
+ this->AvailableVirtualMemory -= this->AvailablePhysicalMemory;
return true;
#else
return false;
diff --git a/Tests/CMakeLib/CMakeLists.txt b/Tests/CMakeLib/CMakeLists.txt
index a50936e..dee4731 100644
--- a/Tests/CMakeLib/CMakeLists.txt
+++ b/Tests/CMakeLib/CMakeLists.txt
@@ -25,7 +25,7 @@
testRange.cxx
testOptional.cxx
testPathResolver.cxx
- testSPDXSerializer.cxx
+ testSpdxSerializer.cxx
testStdIo.cxx
testString.cxx
testStringAlgorithms.cxx
diff --git a/Tests/CMakeLib/testSPDXSerializer.cxx b/Tests/CMakeLib/testSPDXSerializer.cxx
deleted file mode 100644
index b8ab923..0000000
--- a/Tests/CMakeLib/testSPDXSerializer.cxx
+++ /dev/null
@@ -1,649 +0,0 @@
-/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
- file LICENSE.rst or https://cmake.org/licensing for details. */
-#include <iostream>
-#include <string>
-#include <vector>
-
-#include <cm/optional>
-#include <cm/type_traits>
-
-#include <cm3p/json/reader.h>
-#include <cm3p/json/value.h>
-
-#include "cmSPDXSerializer.h"
-
-namespace {
-
-std::string const nonOptional(R"================({
- "@context": "https://spdx.org/rdf/3.0.1/spdx-context.jsonld",
- "@graph": [
- {
- "@id": "_:contentIdentifier_0",
- "contentIdentifierType": "INVALID_CONTENT_IDENTIFIER_TYPE_ID",
- "contentIdentifierValue": "",
- "type": "ContentIdentifier"
- },
- {
- "@id": "_:creationInfo_0",
- "created": "",
- "createdBy": [],
- "type": "CreationInfo"
- },
- {
- "@id": "_:creationInfo_1",
- "created": "",
- "createdBy": [],
- "type": "CreationInfo"
- },
- {
- "@id": "_:dictionaryEntry_0",
- "key": "",
- "type": "DictionaryEntry"
- },
- {
- "@id": "_:externalIdentifier_0",
- "externalIdentifierType": "INVALID_EXTERNAL_IDENTIFIER_TYPE_ID",
- "identifier": "",
- "type": "ExternalIdentifier"
- },
- {
- "@id": "_:externalMap_0",
- "externalSpdxId": "",
- "type": "ExternalMap"
- },
- {
- "@id": "_:externalRef_0",
- "type": "ExternalRef"
- },
- {
- "@id": "_:hash_0",
- "algorithm": "INVALID_HASH_TYPE_ID",
- "hashValue": "",
- "type": "Hash"
- },
- {
- "@id": "_:namespaceMap_0",
- "namespace": "",
- "prefix": "",
- "type": "NamespaceMap"
- },
- {
- "@id": "_:packageVerificationCode_0",
- "algorithm": "INVALID_HASH_TYPE_ID",
- "hashValue": "",
- "type": "PackageVerificationCode"
- },
- {
- "@id": "_:positiveIntegerRange_0",
- "beginIntegerRange": 0,
- "endIntegerRange": 0,
- "type": "PositiveIntegerRange"
- },
- {
- "creationInfo": "_:creationInfo_0",
- "spdxId": "https://cmake.org/testSPDXSerialization-gnrtd0",
- "type": "Agent"
- },
- {
- "annotationType": "INVALID_ANNOTATION_TYPE_ID",
- "creationInfo": "_:creationInfo_0",
- "spdxId": "https://cmake.org/testSPDXSerialization-gnrtd1",
- "subject": "",
- "type": "Annotation"
- },
- {
- "creationInfo": "_:creationInfo_0",
- "spdxId": "https://cmake.org/testSPDXSerialization-gnrtd10",
- "type": "SpdxDocument"
- },
- {
- "creationInfo": "_:creationInfo_0",
- "spdxId": "https://cmake.org/testSPDXSerialization-gnrtd11",
- "type": "Tool"
- },
- {
- "creationInfo": "_:creationInfo_0",
- "spdxId": "https://cmake.org/testSPDXSerialization-gnrtd12",
- "type": "File"
- },
- {
- "creationInfo": "_:creationInfo_0",
- "spdxId": "https://cmake.org/testSPDXSerialization-gnrtd13",
- "type": "Package"
- },
- {
- "context": "",
- "creationInfo": "_:creationInfo_0",
- "spdxId": "https://cmake.org/testSPDXSerialization-gnrtd14",
- "type": "Sbom"
- },
- {
- "creationInfo": "_:creationInfo_0",
- "snippetFromFile": "",
- "spdxId": "https://cmake.org/testSPDXSerialization-gnrtd15",
- "type": "Snippet"
- },
- {
- "creationInfo": "_:creationInfo_0",
- "licenseExpression": "",
- "spdxId": "https://cmake.org/testSPDXSerialization-gnrtd16",
- "type": "LicenseExpression"
- },
- {
- "creationInfo": "_:creationInfo_0",
- "licenseText": "",
- "spdxId": "https://cmake.org/testSPDXSerialization-gnrtd17",
- "type": "SimpleLicensingText"
- },
- {
- "context": "",
- "creationInfo": "_:creationInfo_0",
- "spdxId": "https://cmake.org/testSPDXSerialization-gnrtd2",
- "type": "Bom"
- },
- {
- "context": "",
- "creationInfo": "_:creationInfo_0",
- "spdxId": "https://cmake.org/testSPDXSerialization-gnrtd3",
- "type": "Bundle"
- },
- {
- "creationInfo": "_:creationInfo_0",
- "spdxId": "https://cmake.org/testSPDXSerialization-gnrtd4",
- "type": "IndividualElement"
- },
- {
- "creationInfo": "_:creationInfo_0",
- "from": "",
- "relationshipType": "INVALID_RELATIONSHIP_TYPE_ID",
- "spdxId": "https://cmake.org/testSPDXSerialization-gnrtd5",
- "to": [],
- "type": "LifecycleScopedRelationship"
- },
- {
- "creationInfo": "_:creationInfo_0",
- "spdxId": "https://cmake.org/testSPDXSerialization-gnrtd6",
- "type": "Organization"
- },
- {
- "creationInfo": "_:creationInfo_0",
- "spdxId": "https://cmake.org/testSPDXSerialization-gnrtd7",
- "type": "Person"
- },
- {
- "creationInfo": "_:creationInfo_0",
- "from": "",
- "relationshipType": "INVALID_RELATIONSHIP_TYPE_ID",
- "spdxId": "https://cmake.org/testSPDXSerialization-gnrtd8",
- "to": [],
- "type": "Relationship"
- },
- {
- "creationInfo": "_:creationInfo_0",
- "spdxId": "https://cmake.org/testSPDXSerialization-gnrtd9",
- "type": "SoftwareAgent"
- }
- ]
-})================");
-
-std::string const Optional(R"================({
- "@context": "https://spdx.org/rdf/3.0.1/spdx-context.jsonld",
- "@graph": [
- {
- "@id": "_:contentIdentifier_0",
- "contentIdentifierType": "gitoid",
- "contentIdentifierValue": "ContentIdentifierValue",
- "type": "ContentIdentifier"
- },
- {
- "@id": "_:creationInfo_0",
- "created": "",
- "createdBy": [],
- "type": "CreationInfo"
- },
- {
- "@id": "_:creationInfo_1",
- "Comment": "Comment",
- "created": "Created",
- "createdBy": [
- "testRef"
- ],
- "createdUsing": [
- "testRef"
- ],
- "type": "CreationInfo"
- },
- {
- "@id": "_:dictionaryEntry_0",
- "key": "Key",
- "type": "DictionaryEntry",
- "value": "Value"
- },
- {
- "@id": "_:externalIdentifier_0",
- "comment": "Comment",
- "externalIdentifierType": "other",
- "identifier": "Identifier",
- "identifierLocator": [
- "IdentifierLocator"
- ],
- "issuingAuthority": "IssuingAuthority",
- "type": "ExternalIdentifier"
- },
- {
- "@id": "_:externalMap_0",
- "definingArtifact": "testRef",
- "externalSpdxId": "ExternalSpdxId",
- "integrityMethod": [
- "testRef"
- ],
- "locationHint": "LocationHint",
- "type": "ExternalMap"
- },
- {
- "@id": "_:externalRef_0",
- "comment": "Comment",
- "contentType": "ContentType",
- "externalRefType": "other",
- "locator": [
- "Locator"
- ],
- "type": "ExternalRef"
- },
- {
- "@id": "_:hash_0",
- "algorithm": "other",
- "hashValue": "HashValue",
- "type": "Hash"
- },
- {
- "@id": "_:namespaceMap_0",
- "namespace": "Namespace",
- "prefix": "Namespace",
- "type": "NamespaceMap"
- },
- {
- "@id": "_:packageVerificationCode_0",
- "algorithm": "other",
- "hashValue": "HashValue",
- "type": "PackageVerificationCode"
- },
- {
- "@id": "_:positiveIntegerRange_0",
- "beginIntegerRange": 1,
- "endIntegerRange": 2,
- "type": "PositiveIntegerRange"
- },
- {
- "comment": "Comment",
- "creationInfo": "_:creationInfo_0",
- "description": "Description",
- "extension": [
- "testRef"
- ],
- "externalIdentifier": [
- "testRef"
- ],
- "externalRef": [
- "testRef"
- ],
- "name": "Name",
- "spdxId": "https://cmake.org/testSPDXSerialization-gnrtd0",
- "summary": "Summary",
- "type": "Agent",
- "verifiedUsing": [
- "testRef"
- ]
- },
- {
- "annotationType": "other",
- "contentType": "ContentType",
- "creationInfo": "_:creationInfo_0",
- "spdxId": "https://cmake.org/testSPDXSerialization-gnrtd1",
- "statement": "Statement",
- "subject": "testRef",
- "type": "Annotation"
- },
- {
- "creationInfo": "_:creationInfo_0",
- "dataLicense": "testRef",
- "externalMap": "testRef",
- "namespaceMap": "testRef",
- "spdxId": "https://cmake.org/testSPDXSerialization-gnrtd10",
- "type": "SpdxDocument"
- },
- {
- "creationInfo": "_:creationInfo_0",
- "spdxId": "https://cmake.org/testSPDXSerialization-gnrtd11",
- "type": "Tool"
- },
- {
- "additionalPurpose": [
- "other"
- ],
- "attributionText": "AttributionText",
- "contentIdentifier": "testRef",
- "contentType": "ContentType",
- "copyrightText": "CopyrightText",
- "creationInfo": "_:creationInfo_0",
- "fileKind": "file",
- "primaryPurpose": "file",
- "spdxId": "https://cmake.org/testSPDXSerialization-gnrtd12",
- "type": "File"
- },
- {
- "creationInfo": "_:creationInfo_0",
- "downloadLocation": "DownloadLocation",
- "homePage": "HomePage",
- "packageUrl": "PackageUrl",
- "packageVersion": "PackageVersion",
- "sourceInfo": "SourceInfo",
- "spdxId": "https://cmake.org/testSPDXSerialization-gnrtd13",
- "type": "Package"
- },
- {
- "context": "",
- "creationInfo": "_:creationInfo_0",
- "sbomType": [
- "build"
- ],
- "spdxId": "https://cmake.org/testSPDXSerialization-gnrtd14",
- "type": "Sbom"
- },
- {
- "byteRange": "testRef",
- "creationInfo": "_:creationInfo_0",
- "lineRange": "testRef",
- "snippetFromFile": "testRef",
- "spdxId": "https://cmake.org/testSPDXSerialization-gnrtd15",
- "type": "Snippet"
- },
- {
- "creationInfo": "_:creationInfo_0",
- "customIdToUri": [
- "testRef"
- ],
- "licenseExpression": "LicenseExpression",
- "licenseListVersion": "LicenseListVersion",
- "spdxId": "https://cmake.org/testSPDXSerialization-gnrtd16",
- "type": "LicenseExpression"
- },
- {
- "creationInfo": "_:creationInfo_0",
- "licenseText": "LicenseText",
- "spdxId": "https://cmake.org/testSPDXSerialization-gnrtd17",
- "type": "SimpleLicensingText"
- },
- {
- "context": "Context",
- "creationInfo": "_:creationInfo_0",
- "spdxId": "https://cmake.org/testSPDXSerialization-gnrtd2",
- "type": "Bom"
- },
- {
- "context": "",
- "creationInfo": "_:creationInfo_0",
- "spdxId": "https://cmake.org/testSPDXSerialization-gnrtd3",
- "type": "Bundle"
- },
- {
- "creationInfo": "_:creationInfo_0",
- "spdxId": "https://cmake.org/testSPDXSerialization-gnrtd4",
- "type": "IndividualElement"
- },
- {
- "completeness": "noAssertion",
- "creationInfo": "_:creationInfo_0",
- "endTime": "EndTime",
- "from": "testRef",
- "relationshipType": "other",
- "scope": "other",
- "spdxId": "https://cmake.org/testSPDXSerialization-gnrtd5",
- "startTime": "StartTime",
- "to": [
- "testRef"
- ],
- "type": "LifecycleScopedRelationship"
- },
- {
- "creationInfo": "_:creationInfo_0",
- "spdxId": "https://cmake.org/testSPDXSerialization-gnrtd6",
- "type": "Organization"
- },
- {
- "creationInfo": "_:creationInfo_0",
- "spdxId": "https://cmake.org/testSPDXSerialization-gnrtd7",
- "type": "Person"
- },
- {
- "creationInfo": "_:creationInfo_0",
- "from": "",
- "relationshipType": "INVALID_RELATIONSHIP_TYPE_ID",
- "spdxId": "https://cmake.org/testSPDXSerialization-gnrtd8",
- "to": [],
- "type": "Relationship"
- },
- {
- "creationInfo": "_:creationInfo_0",
- "spdxId": "https://cmake.org/testSPDXSerialization-gnrtd9",
- "type": "SoftwareAgent"
- }
- ]
-})================");
-}
-
-int testNonOptional()
-{
- cmSPDXSimpleGraph graph("https://cmake.org/testSPDXSerialization-gnrtd");
-
- // Core
- graph.insert<cmSPDXAgent>();
- graph.insert<cmSPDXAnnotation>();
- graph.insert<cmSPDXBom>();
- graph.insert<cmSPDXBundle>();
- graph.insert<cmSPDXCreationInfo>();
- graph.insert<cmSPDXDictionaryEntry>();
- graph.insert<cmSPDXExternalIdentifier>();
- graph.insert<cmSPDXExternalMap>();
- graph.insert<cmSPDXExternalRef>();
- graph.insert<cmSPDXHash>();
- graph.insert<cmSPDXIndividualElement>();
- graph.insert<cmSPDXLifecycleScopedRelationship>();
- graph.insert<cmSPDXNamespaceMap>();
- graph.insert<cmSPDXOrganization>();
- graph.insert<cmSPDXPackageVerificationCode>();
- graph.insert<cmSPDXPerson>();
- graph.insert<cmSPDXPositiveIntegerRange>();
- graph.insert<cmSPDXRelationship>();
- graph.insert<cmSPDXSoftwareAgent>();
- graph.insert<cmSPDXSpdxDocument>();
- graph.insert<cmSPDXTool>();
-
- // Software
- graph.insert<cmSPDXContentIdentifier>();
- graph.insert<cmSPDXFile>();
- graph.insert<cmSPDXPackage>();
- graph.insert<cmSPDXSbom>();
- graph.insert<cmSPDXSnippet>();
-
- // SimpleLicensing
- graph.insert<cmSPDXLicenseExpression>();
- graph.insert<cmSPDXSimpleLicensingText>();
-
- Json::Value root;
- Json::Reader().parse(nonOptional.c_str(), root);
-
- std::cout << "NonOptional SPDX:";
- std::cout << "\nConstructed Graph: " << graph.toJsonLD().toStyledString();
- std::cout << "\nComparison Graph:" << root.toStyledString() << "\n";
-
- // Convert to string to disregard differences in number signedness
- return root.toStyledString() == graph.toJsonLD().toStyledString();
-};
-
-int testOptional()
-{
- cmSPDXSimpleGraph graph("https://cmake.org/testSPDXSerialization-gnrtd");
-
- cmSPDXIdentifierReference ident("testRef");
-
- // Core
- auto& agent = graph.insert<cmSPDXAgent>();
- agent.Comment = "Comment";
- agent.Description = "Description";
- agent.Extension.emplace().push_back(ident);
- agent.ExternalIdentifier.emplace().push_back(ident);
- agent.ExternalRef.emplace().push_back(ident);
- agent.Name = "Name";
- agent.Summary = "Summary";
- agent.VerifiedUsing.emplace().push_back(ident);
-
- auto& annotation = graph.insert<cmSPDXAnnotation>();
- annotation.AnnotationType = cmSPDXAnnotationType::OTHER;
- annotation.ContentType = "ContentType";
- annotation.Statement = "Statement";
- annotation.Subject = ident;
-
- auto& bom = graph.insert<cmSPDXBom>();
- bom.Context = "Context";
-
- graph.insert<cmSPDXBundle>();
-
- auto& creationInfo = graph.insert<cmSPDXCreationInfo>();
- creationInfo.Comment = "Comment";
- creationInfo.Created = "Created";
- creationInfo.CreatedBy.push_back(ident);
- creationInfo.CreatedUsing.emplace().push_back(ident);
-
- auto& dictionaryEntry = graph.insert<cmSPDXDictionaryEntry>();
- dictionaryEntry.Key = "Key";
- dictionaryEntry.Value = "Value";
-
- auto& externalIdentifier = graph.insert<cmSPDXExternalIdentifier>();
- externalIdentifier.Comment = "Comment";
- externalIdentifier.ExternalIdentifierType =
- cmSPDXExternalIdentifierType::OTHER;
- externalIdentifier.Identifier = "Identifier";
- externalIdentifier.IdentifierLocator.emplace().push_back(
- "IdentifierLocator");
- externalIdentifier.IssuingAuthority = "IssuingAuthority";
-
- auto& externalMap = graph.insert<cmSPDXExternalMap>();
- externalMap.DefiningArtifact = ident;
- externalMap.ExternalSpdxId = "ExternalSpdxId";
- externalMap.LocationHint = "LocationHint";
- externalMap.IntegrityMethod.emplace().push_back(ident);
-
- auto& externalRef = graph.insert<cmSPDXExternalRef>();
- externalRef.Comment = "Comment";
- externalRef.ContentType = "ContentType";
- externalRef.ExternalRefType = cmSPDXExternalRefType::OTHER;
- externalRef.Locator.emplace().push_back("Locator");
-
- auto& hash = graph.insert<cmSPDXHash>();
- hash.Algorithm = cmSPDXHashAlgorithm::OTHER;
- hash.HashValue = "HashValue";
-
- graph.insert<cmSPDXIndividualElement>();
-
- auto& lifecycleScopedRelationship =
- graph.insert<cmSPDXLifecycleScopedRelationship>();
- lifecycleScopedRelationship.Completeness =
- cmSPDXRelationshipCompletenessType::NO_ASSERTION;
- lifecycleScopedRelationship.EndTime = "EndTime";
- lifecycleScopedRelationship.From = ident;
- lifecycleScopedRelationship.RelationshipType = cmSPDXRelationshipType::OTHER;
- lifecycleScopedRelationship.StartTime = "StartTime";
- lifecycleScopedRelationship.To.push_back(ident);
- lifecycleScopedRelationship.Scope = cmSPDXLifecycleScopeType::OTHER;
-
- auto& namespaceMap = graph.insert<cmSPDXNamespaceMap>();
- namespaceMap.Namespace = "Namespace";
- namespaceMap.Prefix = "Prefix";
-
- graph.insert<cmSPDXOrganization>();
-
- auto& packageVerificationCode =
- graph.insert<cmSPDXPackageVerificationCode>();
- packageVerificationCode.Algorithm = cmSPDXHashAlgorithm::OTHER;
- packageVerificationCode.HashValue = "HashValue";
- packageVerificationCode.PackageVerificationCodeExcludedFile.emplace()
- .push_back("PacakgeVerificationCodeExcludeFile");
-
- graph.insert<cmSPDXPerson>();
-
- auto& positiveIntegerRange = graph.insert<cmSPDXPositiveIntegerRange>();
- positiveIntegerRange.BeginIntegerRange = 1;
- positiveIntegerRange.EndIntegerRange = 2;
-
- graph.insert<cmSPDXRelationship>();
-
- graph.insert<cmSPDXSoftwareAgent>();
-
- auto& spdxDocument = graph.insert<cmSPDXSpdxDocument>();
- spdxDocument.DataLicense = ident;
- spdxDocument.ExternalMap = ident;
- spdxDocument.NamespaceMap = ident;
-
- graph.insert<cmSPDXTool>();
-
- // Software
- auto& contentIdentifier = graph.insert<cmSPDXContentIdentifier>();
- contentIdentifier.ContentIdentifierType =
- cmSPDXContentIdentifierType::GITOID;
- contentIdentifier.ContentIdentifierValue = "ContentIdentifierValue";
-
- auto& file = graph.insert<cmSPDXFile>();
- file.AdditionalPurpose.emplace().push_back(cmSPDXSoftwarePurpose::OTHER);
- file.AttributionText = "AttributionText";
- file.ContentIdentifier = ident;
- file.CopyrightText = "CopyrightText";
- file.PrimaryPurpose = cmSPDXSoftwarePurpose::FILE;
- file.ContentType = "ContentType";
- file.FileKind = cmSPDXFileKindType::FILE;
-
- auto& package = graph.insert<cmSPDXPackage>();
- package.DownloadLocation = "DownloadLocation";
- package.HomePage = "HomePage";
- package.PackageUrl = "PackageUrl";
- package.PackageVersion = "PackageVersion";
- package.SourceInfo = "SourceInfo";
-
- auto& sbom = graph.insert<cmSPDXSbom>();
- sbom.SbomType.emplace().push_back(cmSPDXSbomType::BUILD);
-
- auto& snippet = graph.insert<cmSPDXSnippet>();
- snippet.ByteRange = ident;
- snippet.LineRange = ident;
- snippet.SnippetFromFile = ident;
-
- // SimpleLicensing
- auto& licenseExpression = graph.insert<cmSPDXLicenseExpression>();
- licenseExpression.CustomIdToUri.emplace().push_back(ident);
- licenseExpression.LicenseExpression = "LicenseExpression";
- licenseExpression.LicenseListVersion = "LicenseListVersion";
-
- auto& simpleLicensingText = graph.insert<cmSPDXSimpleLicensingText>();
- simpleLicensingText.LicenseText = "LicenseText";
-
- Json::Value root;
- Json::Reader().parse(Optional.c_str(), root);
-
- std::cout << "Optional SPDX:";
- std::cout << "\nConstructed Graph: " << graph.toJsonLD().toStyledString();
- std::cout << "\nComparison Graph:" << root.toStyledString() << "\n";
-
- // Convert to string to disregard differences in number signedness
- return root.toStyledString() == graph.toJsonLD().toStyledString();
-};
-
-int testSPDXSerializer(int /* argc */, char* /* argv */[])
-{
- if (!testNonOptional())
- return -1;
-
- if (!testOptional())
- return -1;
-
- return 0;
-}
diff --git a/Tests/CMakeLib/testSpdxSerializer.cxx b/Tests/CMakeLib/testSpdxSerializer.cxx
new file mode 100644
index 0000000..ab394cb
--- /dev/null
+++ b/Tests/CMakeLib/testSpdxSerializer.cxx
@@ -0,0 +1,84 @@
+
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file LICENSE.rst or https://cmake.org/licensing for details. */
+
+#include <string>
+#include <utility>
+#include <vector>
+
+#include <cm/optional>
+
+#include <cm3p/json/value.h>
+
+#include "cmSbomObject.h"
+#include "cmSpdx.h"
+#include "cmSpdxSerializer.h"
+
+#include "testCommon.h"
+
+namespace {
+
+bool testSerializeSpdxJson()
+{
+
+ auto constexpr contextUrl = "https://spdx.org/rdf/3.0.1/spdx-context.jsonld";
+
+ cmSbomDocument doc;
+ doc.Context = contextUrl;
+
+ cmSpdxDocument spdxValue;
+ spdxValue.SpdxId = "_:SPDXRef-Document";
+ spdxValue.DataLicense = "CC0-1.0";
+ auto spdx = insert_back(doc.Graph, std::move(spdxValue));
+
+ {
+ cmSpdxCreationInfo ci;
+ ci.SpdxId = "_:SPDXRef-CreationInfo";
+ ci.SpecVersion = "3.0.1";
+ spdx->CreationInfo = std::move(ci);
+ }
+
+ {
+ cmSpdxPackage pkg;
+ pkg.Name = "sample-package";
+ pkg.SpdxId = "_:SPDXRef-Package";
+
+ spdx->RootElements.emplace_back(std::move(pkg));
+ }
+
+ {
+ cmSpdxSerializer serializer;
+ doc.Serialize(serializer);
+ auto value = serializer.GetJson();
+
+ ASSERT_TRUE(value.isObject());
+
+ Json::Value const& context = value["@context"];
+ ASSERT_EQUAL(context.asString(), contextUrl);
+
+ Json::Value const& graph = value["@graph"];
+ ASSERT_TRUE(graph.isArray());
+
+ Json::Value const& docValue = graph[0];
+ ASSERT_TRUE(docValue.isObject());
+ ASSERT_EQUAL(docValue["type"].asString(), "SpdxDocument");
+ ASSERT_EQUAL(docValue["@id"].asString(), "_:SPDXRef-Document");
+
+ auto const& creationInfo = docValue["creationInfo"];
+ ASSERT_EQUAL(creationInfo["@id"].asString(), "_:SPDXRef-CreationInfo");
+ ASSERT_EQUAL(creationInfo["type"].asString(), "CreationInfo");
+
+ auto const& package = docValue["rootElement"][0];
+ ASSERT_EQUAL(package["type"].asString(), "software_Package");
+ ASSERT_EQUAL(package["@id"].asString(), "_:SPDXRef-Package");
+ }
+
+ return true;
+}
+
+} // namespace
+
+int testSpdxSerializer(int /*unused*/, char* /*unused*/[])
+{
+ return runTests({ testSerializeSpdxJson });
+}
diff --git a/Tests/CMakeLib/testSystemTools.cxx b/Tests/CMakeLib/testSystemTools.cxx
index 3581474..d34f710 100644
--- a/Tests/CMakeLib/testSystemTools.cxx
+++ b/Tests/CMakeLib/testSystemTools.cxx
@@ -96,6 +96,50 @@
return true;
}
+static bool testRelativeIfUnder()
+{
+ std::cout << "testRelativeIfUnder()\n";
+
+ std::string result = cmSystemTools::RelativeIfUnder("/a/b", "/a/b");
+ if (result != ".") {
+ std::cout << "cmSystemTools::RelativeIfUnder failed on /a/b, /a/b: "
+ << result << "\n";
+ return false;
+ }
+ result = cmSystemTools::RelativeIfUnder("/a/b", "/a/b/c/d");
+ if (result != "c/d") {
+ std::cout << "cmSystemTools::RelativeIfUnder failed on /a/b, /a/b/c/d: "
+ << result << "\n";
+ return false;
+ }
+ result = cmSystemTools::RelativeIfUnder("/d/f/", "/a/b/c/d");
+ if (result != "/a/b/c/d") {
+ std::cout << "cmSystemTools::RelativeIfUnder failed on /d/f/, /a/b/c/d: "
+ << result << "\n";
+ return false;
+ }
+ result = cmSystemTools::RelativeIfUnder("/", "/a/b");
+ if (result != "a/b") {
+ std::cout << "cmSystemTools::RelativeIfUnder failed on /, /a/b: " << result
+ << "\n";
+ return false;
+ }
+ result = cmSystemTools::RelativeIfUnder("I:/", "I:/CMakeLists.txt");
+ if (result != "CMakeLists.txt") {
+ std::cout
+ << "cmSystemTools::RelativeIfUnder failed on I:/, I:/CMakeLists.txt: "
+ << result << "\n";
+ return false;
+ }
+ result = cmSystemTools::RelativeIfUnder("", "/a/b");
+ if (result != "/a/b") {
+ std::cout << "cmSystemTools::RelativeIfUnder failed on \"\", /a/b: "
+ << result << "\n";
+ return false;
+ }
+ return true;
+}
+
static bool testMakeTempDirectory()
{
std::cout << "testMakeTempDirectory()\n";
@@ -124,6 +168,7 @@
testUpperCase,
testVersionCompare,
testStrVersCmp,
+ testRelativeIfUnder,
testMakeTempDirectory,
});
}
diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt
index 2ead810..22b99ba 100644
--- a/Tests/CMakeLists.txt
+++ b/Tests/CMakeLists.txt
@@ -3283,6 +3283,11 @@
set(JavaExportImport_BUILD_OPTIONS -DCMake_TEST_NESTED_MAKE_PROGRAM:FILEPATH=${CMake_TEST_EXPLICIT_MAKE_PROGRAM})
ADD_TEST_MACRO(JavaExportImport JavaExportImport)
+ if("${Java_VERSION}" VERSION_GREATER_EQUAL 9)
+ set(JavaModExportImport_BUILD_OPTIONS -DCMake_TEST_NESTED_MAKE_PROGRAM:FILEPATH=${CMake_TEST_EXPLICIT_MAKE_PROGRAM})
+ ADD_TEST_MACRO(JavaModExportImport JavaModExportImport)
+ endif()
+
get_filename_component(JAVACPATH ${Java_JAVAC_EXECUTABLE} REALPATH)
get_filename_component(JNIPATH ${JAVACPATH} PATH)
find_file(JNI_H jni.h
diff --git a/Tests/JavaModExportImport/BuildExport/CMakeLists.txt b/Tests/JavaModExportImport/BuildExport/CMakeLists.txt
new file mode 100644
index 0000000..f818f44
--- /dev/null
+++ b/Tests/JavaModExportImport/BuildExport/CMakeLists.txt
@@ -0,0 +1,13 @@
+project(foo Java)
+
+cmake_minimum_required(VERSION 3.10)
+set(CMAKE_VERBOSE_MAKEFILE 1)
+
+find_package(Java COMPONENTS Development)
+include(UseJava)
+
+add_jar(${PROJECT_NAME} Foo.java module-info.java)
+export_jars(
+ TARGETS ${PROJECT_NAME}
+ NAMESPACE foo::
+ FILE JavaBuildExportTestConfig.cmake)
diff --git a/Tests/JavaModExportImport/BuildExport/Foo.java b/Tests/JavaModExportImport/BuildExport/Foo.java
new file mode 100644
index 0000000..c0e2a1a
--- /dev/null
+++ b/Tests/JavaModExportImport/BuildExport/Foo.java
@@ -0,0 +1,13 @@
+package org.foo;
+
+public class Foo
+{
+ public Foo()
+ {
+ }
+
+ public void printName()
+ {
+ System.out.println("Foo");
+ }
+}
diff --git a/Tests/JavaModExportImport/BuildExport/module-info.java b/Tests/JavaModExportImport/BuildExport/module-info.java
new file mode 100644
index 0000000..aeb0e17
--- /dev/null
+++ b/Tests/JavaModExportImport/BuildExport/module-info.java
@@ -0,0 +1,3 @@
+module mod_foo {
+ exports org.foo;
+}
diff --git a/Tests/JavaModExportImport/CMakeLists.txt b/Tests/JavaModExportImport/CMakeLists.txt
new file mode 100644
index 0000000..5326457
--- /dev/null
+++ b/Tests/JavaModExportImport/CMakeLists.txt
@@ -0,0 +1,105 @@
+cmake_minimum_required(VERSION 3.10)
+project(JavaModExportImport)
+if(NOT DEFINED CMake_TEST_NESTED_MAKE_PROGRAM AND NOT CMAKE_GENERATOR MATCHES "Visual Studio")
+ set(CMake_TEST_NESTED_MAKE_PROGRAM "${CMAKE_MAKE_PROGRAM}")
+endif()
+
+find_package(Java COMPONENTS Development)
+
+# Wipe out the install tree to make sure the exporter works.
+add_custom_command(
+ OUTPUT ${JavaModExportImport_BINARY_DIR}/CleanupProject
+ COMMAND ${CMAKE_COMMAND} -E rm -rf ${JavaModExportImport_BINARY_DIR}/Root
+ )
+add_custom_target(CleanupTarget ALL DEPENDS ${JavaModExportImport_BINARY_DIR}/CleanupProject)
+set_property(
+ SOURCE ${JavaModExportImport_BINARY_DIR}/CleanupProject
+ PROPERTY SYMBOLIC 1
+ )
+
+get_property(_isMultiConfig GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
+if(_isMultiConfig)
+ set(NESTED_CONFIG_TYPE -C "${CMAKE_CFG_INTDIR}")
+else()
+ if(CMAKE_BUILD_TYPE)
+ set(NESTED_CONFIG_TYPE -C "${CMAKE_BUILD_TYPE}")
+ else()
+ set(NESTED_CONFIG_TYPE)
+ endif()
+endif()
+
+configure_file(${JavaModExportImport_SOURCE_DIR}/InitialCache.cmake.in
+ ${JavaModExportImport_BINARY_DIR}/InitialCache.cmake @ONLY)
+
+# Build the build exporter.
+add_custom_command(
+ OUTPUT ${JavaModExportImport_BINARY_DIR}/BuildExportProject
+ COMMAND ${CMAKE_CTEST_COMMAND} ${NESTED_CONFIG_TYPE}
+ --build-and-test
+ ${JavaModExportImport_SOURCE_DIR}/BuildExport
+ ${JavaModExportImport_BINARY_DIR}/BuildExport
+ --build-noclean
+ --build-project BuildExport
+ --build-generator ${CMAKE_GENERATOR}
+ --build-generator-platform "${CMAKE_GENERATOR_PLATFORM}"
+ --build-generator-toolset "${CMAKE_GENERATOR_TOOLSET}"
+ --build-options -C${JavaModExportImport_BINARY_DIR}/InitialCache.cmake
+ VERBATIM
+ )
+add_custom_target(BuildExportTarget ALL DEPENDS ${JavaModExportImport_BINARY_DIR}/BuildExportProject)
+add_dependencies(BuildExportTarget CleanupTarget)
+set_property(
+ SOURCE ${JavaModExportImport_BINARY_DIR}/BuildExportProject
+ PROPERTY SYMBOLIC 1
+ )
+
+# Build and install the install exporter.
+add_custom_command(
+ OUTPUT ${JavaModExportImport_BINARY_DIR}/InstallExportProject
+ COMMAND ${CMAKE_CTEST_COMMAND} ${NESTED_CONFIG_TYPE}
+ --build-and-test
+ ${JavaModExportImport_SOURCE_DIR}/InstallExport
+ ${JavaModExportImport_BINARY_DIR}/InstallExport
+ --build-noclean
+ --build-project InstallExport
+ --build-target install
+ --build-generator ${CMAKE_GENERATOR}
+ --build-generator-platform "${CMAKE_GENERATOR_PLATFORM}"
+ --build-generator-toolset "${CMAKE_GENERATOR_TOOLSET}"
+ --build-options -C${JavaModExportImport_BINARY_DIR}/InitialCache.cmake
+ VERBATIM
+ )
+add_custom_target(InstallExportTarget ALL DEPENDS ${JavaModExportImport_BINARY_DIR}/InstallExportProject)
+add_dependencies(InstallExportTarget CleanupTarget)
+set_property(
+ SOURCE ${JavaModExportImport_BINARY_DIR}/InstallExportProject
+ PROPERTY SYMBOLIC 1
+ )
+
+# Build and install the importer.
+add_custom_command(
+ OUTPUT ${JavaModExportImport_BINARY_DIR}/ImportProject
+ COMMAND ${CMAKE_CTEST_COMMAND} ${NESTED_CONFIG_TYPE}
+ --build-and-test
+ ${JavaModExportImport_SOURCE_DIR}/Import
+ ${JavaModExportImport_BINARY_DIR}/Import
+ --build-noclean
+ --build-project Import
+ --build-generator ${CMAKE_GENERATOR}
+ --build-generator-platform "${CMAKE_GENERATOR_PLATFORM}"
+ --build-generator-toolset "${CMAKE_GENERATOR_TOOLSET}"
+ --build-options
+ -C${JavaModExportImport_BINARY_DIR}/InitialCache.cmake
+ -DJavaBuildExportTest_DIR:PATH=${JavaModExportImport_BINARY_DIR}/BuildExport
+ -DJavaInstallExportTest_DIR:PATH=${JavaModExportImport_BINARY_DIR}/Root/share/cmake
+ VERBATIM
+ )
+add_custom_target(ImportTarget ALL DEPENDS ${JavaModExportImport_BINARY_DIR}/ImportProject)
+add_dependencies(ImportTarget BuildExportTarget InstallExportTarget)
+set_property(
+ SOURCE ${JavaModExportImport_BINARY_DIR}/ImportProject
+ PROPERTY SYMBOLIC 1
+ )
+
+add_executable(JavaModExportImport main.c)
+add_dependencies(JavaModExportImport ImportTarget)
diff --git a/Tests/JavaModExportImport/Import/CMakeLists.txt b/Tests/JavaModExportImport/Import/CMakeLists.txt
new file mode 100644
index 0000000..f8f773a
--- /dev/null
+++ b/Tests/JavaModExportImport/Import/CMakeLists.txt
@@ -0,0 +1,14 @@
+project(import Java)
+
+cmake_minimum_required(VERSION 3.10)
+set(CMAKE_VERBOSE_MAKEFILE 1)
+
+find_package(Java COMPONENTS Development)
+include(UseJava)
+
+find_package(JavaBuildExportTest REQUIRED)
+find_package(JavaInstallExportTest REQUIRED)
+
+add_jar(${PROJECT_NAME}
+ SOURCES Import.java module-info.java
+ INCLUDE_MODULES foo::foo bar::bar)
diff --git a/Tests/JavaModExportImport/Import/Import.java b/Tests/JavaModExportImport/Import/Import.java
new file mode 100644
index 0000000..46b1e9a
--- /dev/null
+++ b/Tests/JavaModExportImport/Import/Import.java
@@ -0,0 +1,13 @@
+import org.foo.Foo;
+import com.bar.Bar;
+
+class Import
+{
+ public static void main(String args[])
+ {
+ Foo foo = new Foo();
+ Bar bar = new Bar();
+ foo.printName();
+ bar.printName();
+ }
+}
diff --git a/Tests/JavaModExportImport/Import/module-info.java b/Tests/JavaModExportImport/Import/module-info.java
new file mode 100644
index 0000000..9d719cd
--- /dev/null
+++ b/Tests/JavaModExportImport/Import/module-info.java
@@ -0,0 +1,4 @@
+module client {
+ requires mod_foo;
+ requires mod_bar;
+}
diff --git a/Tests/JavaModExportImport/InitialCache.cmake.in b/Tests/JavaModExportImport/InitialCache.cmake.in
new file mode 100644
index 0000000..cc7871e
--- /dev/null
+++ b/Tests/JavaModExportImport/InitialCache.cmake.in
@@ -0,0 +1,5 @@
+set(CMAKE_MAKE_PROGRAM "@CMake_TEST_NESTED_MAKE_PROGRAM@" CACHE FILEPATH "Make Program")
+set(Java_JAVA_EXECUTABLE "@Java_JAVA_EXECUTABLE@" CACHE STRING "Java Interpreter")
+set(Java_JAVAC_EXECUTABLE "@Java_JAVAC_EXECUTABLE@" CACHE STRING "Java Compiler")
+set(Java_JAR_EXECUTABLE "@Java_JAR_EXECUTABLE@" CACHE STRING "Java Archive Tool")
+set(CMAKE_INSTALL_PREFIX "@JavaModExportImport_BINARY_DIR@/Root" CACHE STRING "Installation Prefix")
diff --git a/Tests/JavaModExportImport/InstallExport/Bar.java b/Tests/JavaModExportImport/InstallExport/Bar.java
new file mode 100644
index 0000000..dfa941c
--- /dev/null
+++ b/Tests/JavaModExportImport/InstallExport/Bar.java
@@ -0,0 +1,13 @@
+package com.bar;
+
+public class Bar
+{
+ public Bar()
+ {
+ }
+
+ public void printName()
+ {
+ System.out.println("Bar");
+ }
+}
diff --git a/Tests/JavaModExportImport/InstallExport/CMakeLists.txt b/Tests/JavaModExportImport/InstallExport/CMakeLists.txt
new file mode 100644
index 0000000..5997bdc
--- /dev/null
+++ b/Tests/JavaModExportImport/InstallExport/CMakeLists.txt
@@ -0,0 +1,15 @@
+project(bar Java)
+
+cmake_minimum_required(VERSION 3.10)
+set(CMAKE_VERBOSE_MAKEFILE 1)
+
+find_package(Java COMPONENTS Development)
+include(UseJava)
+
+add_jar(${PROJECT_NAME} Bar.java module-info.java)
+install_jar(${PROJECT_NAME} DESTINATION share/java)
+install_jar_exports(
+ TARGETS ${PROJECT_NAME}
+ NAMESPACE bar::
+ FILE JavaInstallExportTestConfig.cmake
+ DESTINATION share/cmake)
diff --git a/Tests/JavaModExportImport/InstallExport/module-info.java b/Tests/JavaModExportImport/InstallExport/module-info.java
new file mode 100644
index 0000000..7c8b62d
--- /dev/null
+++ b/Tests/JavaModExportImport/InstallExport/module-info.java
@@ -0,0 +1,3 @@
+module mod_bar {
+ exports com.bar;
+}
diff --git a/Tests/JavaModExportImport/main.c b/Tests/JavaModExportImport/main.c
new file mode 100644
index 0000000..8488f4e
--- /dev/null
+++ b/Tests/JavaModExportImport/main.c
@@ -0,0 +1,4 @@
+int main(void)
+{
+ return 0;
+}
diff --git a/Utilities/std/cm/type_traits b/Utilities/std/cm/type_traits
index 6bb6b5c..6126e71 100644
--- a/Utilities/std/cm/type_traits
+++ b/Utilities/std/cm/type_traits
@@ -11,27 +11,39 @@
#if __cplusplus >= 201402L || (defined(_MSVC_LANG) && _MSVC_LANG >= 201402L)
-// Miscellaneous transformations
template <bool B, typename T = void>
using enable_if_t = std::enable_if_t<B, T>;
+using std::conditional_t;
+using std::decay_t;
+using std::remove_cv_t;
+using std::remove_reference_t;
+
#else
-// Miscellaneous transformations
template <bool B, typename T = void>
using enable_if_t = typename std::enable_if<B, T>::type;
-#endif
+template <bool B, typename T, typename F>
+using conditional_t = typename std::conditional<B, T, F>::type;
+
+template <typename T>
+using decay_t = typename std::decay<T>::type;
+
+template <typename T>
+using remove_cv_t = typename std::remove_cv<T>::type;
+
+template <typename T>
+using remove_reference_t = typename std::remove_reference<T>::type;
+
+#endif // C++14 (_t aliases)
#if __cplusplus >= 201703L || (defined(_MSVC_LANG) && _MSVC_LANG >= 201703L)
-// Helper classes
using std::bool_constant;
-// Miscellaneous transformations
using std::invoke_result;
using std::invoke_result_t;
-
using std::void_t;
#else
@@ -44,7 +56,7 @@
template <typename F, typename... ArgTypes>
using invoke_result = std::result_of<F(ArgTypes...)>;
-template <class F, typename... ArgTypes>
+template <typename F, typename... ArgTypes>
using invoke_result_t = typename invoke_result<F, ArgTypes...>::type;
template <typename... ArgTypes>
@@ -77,13 +89,13 @@
!std::is_convertible<T, typename std::underlying_type<T>::type>::value>
{
};
-}
+} // namespace internals
template <typename T>
struct is_scoped_enum : public internals::is_scoped_enum_helper<T>
{
};
-#endif
+#endif // is_scoped_enum
} // namespace cm