get_filename_component(_vtkModule_dir "${CMAKE_CURRENT_LIST_FILE}" DIRECTORY) #[==[.rst: ********* vtkModule ********* #]==] #[==[.rst: .. cmake:command:: _vtk_module_debug Conditionally output debug statements |module-internal| The :cmake:command:`_vtk_module_debug` function is provided to assist in debugging. It is controlled by the `_vtk_module_log` variable which contains a list of "domains" to debug. .. code-block:: cmake _vtk_module_debug( ) If the `domain` is enabled for debugging, the `format` argument is configured and printed. It should contain `@` variable expansions to replace rather than it being done outside. This helps to avoid the cost of generating large strings when debugging is disabled. #]==] function (_vtk_module_debug domain format) if (NOT _vtk_module_log STREQUAL "ALL" AND NOT domain IN_LIST _vtk_module_log) return () endif () string(CONFIGURE "${format}" _vtk_module_debug_msg) if (_vtk_module_debug_msg) message(STATUS "VTK module debug ${domain}: ${_vtk_module_debug_msg}") endif () endfunction () # TODO: Support finding `vtk.module` and `vtk.kit` contents in the # `CMakeLists.txt` files for the module via a comment header. #[==[.rst: .. cmake:command:: vtk_module_find_kits Find `vtk.kit` files in a set of directories |module| .. code-block:: cmake vtk_module_find_kits( [...]) This scans the given directories recursively for `vtk.kit` files and put the paths into the output variable. #]==] function (vtk_module_find_kits output) set(_vtk_find_kits_all) foreach (_vtk_find_kits_directory IN LISTS ARGN) file(GLOB_RECURSE _vtk_find_kits_kits "${_vtk_find_kits_directory}/vtk.kit") list(APPEND _vtk_find_kits_all ${_vtk_find_kits_kits}) endforeach () set("${output}" ${_vtk_find_kits_all} PARENT_SCOPE) endfunction () #[==[.rst: .. cmake:command:: vtk_module_find_modules Find `vtk.module` files in a set of directories |module| .. code-block:: cmake vtk_module_find_modules( [...]) This scans the given directories recursively for ``vtk.module`` files and put the paths into the output variable. Note that module files are assumed to live next to the ``CMakeLists.txt`` file which will build the module. #]==] function (vtk_module_find_modules output) set(_vtk_find_modules_all) foreach (_vtk_find_modules_directory IN LISTS ARGN) file(GLOB_RECURSE _vtk_find_modules_modules "${_vtk_find_modules_directory}/vtk.module") list(APPEND _vtk_find_modules_all ${_vtk_find_modules_modules}) endforeach () set("${output}" ${_vtk_find_modules_all} PARENT_SCOPE) endfunction () #[==[.rst: .. cmake:command:: _vtk_module_split_module_name Split a module name into a namespace and target component |module-internal| Module names may include a namespace. This function splits the name into a namespace and target name part. .. code-block:: cmake _vtk_module_split_module_name( ) The ``_NAMESPACE`` and ``_TARGET_NAME`` variables will be set in the calling scope. #]==] function (_vtk_module_split_module_name name prefix) string(FIND "${name}" "::" namespace_pos) if (namespace_pos EQUAL -1) set(namespace "") set(target_name "${name}") else () string(SUBSTRING "${name}" 0 "${namespace_pos}" namespace) math(EXPR name_pos "${namespace_pos} + 2") string(SUBSTRING "${name}" "${name_pos}" -1 target_name) endif () set("${prefix}_NAMESPACE" "${namespace}" PARENT_SCOPE) set("${prefix}_TARGET_NAME" "${target_name}" PARENT_SCOPE) endfunction () #[==[.rst: .. cmake:command:: _vtk_module_optional_dependency_exists Detect whether an optional dependency exists or not. |module-internal| Optional dependencies need to be detected namespace and target name part. .. code-block:: cmake _vtk_module_optional_dependency_exists( SATISFIED_VAR ) The result will be returned in the variable specified by ``SATISFIED_VAR``. #]==] function (_vtk_module_optional_dependency_exists dependency) cmake_parse_arguments(_vtk_optional_dep "" "SATISFIED_VAR;PACKAGE" "" ${ARGN}) if (_vtk_optional_dep_UNPARSED_ARGUMENTS) message(FATAL_ERROR "Unparsed arguments for `_vtk_module_optional_dependency_exists`: " "${_vtk_optional_dep_UNPARSED_ARGUMENTS}") endif () if (NOT _vtk_optional_dep_SATISFIED_VAR) message(FATAL_ERROR "The `SATISFIED_VAR` argument is required.") endif () set(_vtk_optional_dep_satisfied 0) if (TARGET "${dependency}") # If the target is imported, we check its `_FOUND` variable. If it is not # imported, we assume it is set up properly as a normal target (or an # `ALIAS`). get_property(_vtk_optional_dep_is_imported TARGET "${dependency}" PROPERTY IMPORTED) if (_vtk_optional_dep_is_imported) _vtk_module_split_module_name("${dependency}" _vtk_optional_dep_parse) set(_vtk_optional_dep_found_var "${_vtk_optional_dep_parse_NAMESPACE}_${_vtk_optional_dep_parse_TARGET_NAME}_FOUND") if (DEFINED "${_vtk_optional_dep_found_var}" AND ${_vtk_optional_dep_found_var}) set(_vtk_optional_dep_satisfied 1) endif () else () set(_vtk_optional_dep_satisfied 1) endif () endif () set("${_vtk_optional_dep_SATISFIED_VAR}" "${_vtk_optional_dep_satisfied}" PARENT_SCOPE) endfunction () #[==[.rst: .. _module-parse-module: vtk.module file contents ======================== The `vtk.module` file is parsed and used as arguments to a CMake function which stores information about the module for use when building it. Note that no variable expansion is allowed and it is not CMake code, so no control flow is allowed. Comments are supported and any content after a `#` on a line is treated as a comment. Due to the breakdown of the content, quotes are not meaningful within the files. Example: .. code-block:: cmake NAME VTK::CommonCore LIBRARY_NAME vtkCommonCore DESCRIPTION The base VTK library. LICENSE_FILES Copyright.txt SPDX_COPYRIGHT_TEXT Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen SPDX_LICENSE_IDENTIFIER BSD-3-Clause GROUPS StandAlone DEPENDS VTK::kwiml PRIVATE_DEPENDS VTK::vtksys VTK::utf8 All values are optional unless otherwise noted. The following arguments are supported: * ``NAME``: (Required) The name of the module. * ``LIBRARY_NAME``: The base name of the library file. It defaults to the module name, but any namespaces are removed. For example, a ``NS::Foo`` module will have a default ``LIBRARY_NAME`` of ``Foo``. * ``DESCRIPTION``: (Recommended) Short text describing what the module is for. * ``KIT``: The name of the kit the module belongs to (see ``Kits files`` for more information). * ``IMPLEMENTABLE``: If present, the module contains logic which supports the autoinit functionality. * ``GROUPS``: Modules may belong to "groups" which is exposed as a build option. This allows for enabling a set of modules with a single build option. * ``CONDITION``: Arguments to CMake's ``if`` command which may be used to hide the module for certain platforms or other reasons. If the expression is false, the module is completely ignored. * ``DEPENDS``: A list of modules which are required by this module and modules using this module. * ``PRIVATE_DEPENDS``: A list of modules which are required by this module, but not by those using this module. * ``OPTIONAL_DEPENDS``: A list of modules which are used by this module if enabled; these are treated as ``PRIVATE_DEPENDS`` if they exist. * ``ORDER_DEPENDS``: Dependencies which only matter for ordering. This does not mean that the module will be enabled, just guaranteed to build before this module. * ``IMPLEMENTS``: A list of modules for which this module needs to register with. * ``TEST_DEPENDS``: Modules required by the test suite for this module. * ``TEST_OPTIONAL_DEPENDS``: Modules used by the test suite for this module if available. * ``TEST_LABELS``: Labels to apply to the tests of this module. By default, the module name is applied as a label. * ``EXCLUDE_WRAP``: If present, this module should not be wrapped in any language. * ``INCLUDE_MARSHAL``: If present, this module opts into automatic code generation of (de)serializers. This option requires that the module is not excluded from wrapping with `EXCLUDE_WRAP`. * ``THIRD_PARTY``: If present, this module is a third party module. * ``LICENSE_FILES``: A list of license files to install for the module. * ``SPDX_LICENSE_IDENTIFIER``: A license identifier for SPDX file generation. * ``SPDX_DOWNLOAD_LOCATION``: A download location for the SPDX file generation. * ``SPDX_COPYRIGHT_TEXT``: A copyright text for the SPDX file generation. * ``SPDX_CUSTOM_LICENSE_FILE``: A relative path to a single custom license file to include in generated SPDX file. * ``SPDX_CUSTOM_LICENSE_NAME``: The name of the single custom license, without the ``LicenseRef-`` #]==] #[==[.rst: .. cmake:command:: _vtk_module_parse_module_args Parse ``vtk.module`` file contents |module-impl| This macro places all ``vtk.module`` keyword "arguments" into the caller's scope prefixed with the value of ``name_output`` which is set to the ``NAME`` of the module. .. code-block:: cmake _vtk_module_parse_module_args(name_output ) For example, this ``vtk.module`` file: .. code-block:: cmake NAME Namespace::Target LIBRARY_NAME nsTarget called with ``_vtk_module_parse_module_args(name ...)`` will set the following variables in the calling scope: - ``name``: ``Namespace::Target`` - ``Namespace::Target_LIBRARY_NAME``: ``nsTarget`` With namespace support for module names, the variable should instead be referenced via ``${${name}_LIBRARY_NAME}`` instead. #]==] macro (_vtk_module_parse_module_args name_output) cmake_parse_arguments("_name" "" "NAME" "" ${ARGN}) if (NOT _name_NAME) message(FATAL_ERROR "A VTK module requires a name (from ${_vtk_scan_module_file}).") endif () set("${name_output}" "${_name_NAME}") cmake_parse_arguments("${_name_NAME}" "IMPLEMENTABLE;EXCLUDE_WRAP;THIRD_PARTY;INCLUDE_MARSHAL" "LIBRARY_NAME;NAME;KIT;SPDX_DOWNLOAD_LOCATION;SPDX_CUSTOM_LICENSE_FILE;SPDX_CUSTOM_LICENSE_NAME" "GROUPS;DEPENDS;PRIVATE_DEPENDS;OPTIONAL_DEPENDS;ORDER_DEPENDS;TEST_DEPENDS;TEST_OPTIONAL_DEPENDS;TEST_LABELS;DESCRIPTION;CONDITION;IMPLEMENTS;LICENSE_FILES;SPDX_LICENSE_IDENTIFIER;SPDX_COPYRIGHT_TEXT" ${ARGN}) if (${_name_NAME}_UNPARSED_ARGUMENTS) message(FATAL_ERROR "Unparsed arguments for ${_name_NAME}: " "${${_name_NAME}_UNPARSED_ARGUMENTS}") endif () if (NOT ${_name_NAME}_DESCRIPTION AND _vtk_module_warnings) message(WARNING "The ${_name_NAME} module should have a description") endif () string(REPLACE ";" " " "${_name_NAME}_DESCRIPTION" "${${_name_NAME}_DESCRIPTION}") _vtk_module_split_module_name("${_name_NAME}" "${_name_NAME}") if (NOT DEFINED "${_name_NAME}_LIBRARY_NAME") set("${_name_NAME}_LIBRARY_NAME" "${${_name_NAME}_TARGET_NAME}") endif () if (NOT ${_name_NAME}_LIBRARY_NAME) message(FATAL_ERROR "The ${_name_NAME} module must have a non-empty `LIBRARY_NAME`.") endif () list(APPEND "${_name_NAME}_TEST_LABELS" "${${_name_NAME}_NAME}" "${${_name_NAME}_LIBRARY_NAME}") endmacro () #[==[.rst: .. _module-parse-kit: vtk.kit file contents ===================== The `vtk.kit` file is parsed similarly to `vtk.module` files. Kits are intended to bring together related modules into a single library in order to reduce the number of objects that linkers need to deal with. Example: .. code-block:: cmake NAME VTK::Common LIBRARY_NAME vtkCommon DESCRIPTION Core utilities for VTK. All values are optional unless otherwise noted. The following arguments are supported: * ``NAME``: (Required) The name of the kit. * ``LIBRARY_NAME``: The base name of the library file. It defaults to the module name, but any namespaces are removed. For example, a ``NS::Foo`` module will have a default ``LIBRARY_NAME`` of ``Foo``. * ``DESCRIPTION``: (Recommended) Short text describing what the kit contains. #]==] #[==[.rst: .. cmake:command:: _vtk_module_parse_kit_args Parse `vtk.kit` file contents |module-impl| Just like :cmake:command:`_vtk_module_parse_module_args`, but for kits. #]==] macro (_vtk_module_parse_kit_args name_output) cmake_parse_arguments("_name" "" "NAME" "" ${ARGN}) if (NOT _name_NAME) message(FATAL_ERROR "A VTK kit requires a name (from ${_vtk_scan_kit_file}).") endif () set("${name_output}" "${_name_NAME}") cmake_parse_arguments("${_name_NAME}" "" "NAME;LIBRARY_NAME" "DESCRIPTION" ${ARGN}) if (${_name_NAME}_UNPARSED_ARGUMENTS) message(FATAL_ERROR "Unparsed arguments for ${_name_NAME}: " "${${_name_NAME}_UNPARSED_ARGUMENTS}") endif () _vtk_module_split_module_name("${_name_NAME}" "${_name_NAME}") if (NOT DEFINED "${_name_NAME}_LIBRARY_NAME") set("${_name_NAME}_LIBRARY_NAME" "${${_name_NAME}_TARGET_NAME}") endif () if (NOT ${_name_NAME}_LIBRARY_NAME) message(FATAL_ERROR "The ${_name_NAME} module must have a non-empty `LIBRARY_NAME`.") endif () if (NOT ${_name_NAME}_DESCRIPTION AND _vtk_module_warnings) message(WARNING "The ${_name_NAME} kit should have a description") endif () string(REPLACE ";" " " "${_name_NAME}_DESCRIPTION" "${${_name_NAME}_DESCRIPTION}") endmacro () #[==[.rst: .. _module-enable-status: Enable status values ==================== Modules and groups are enable and disable preferences are specified using a 5-way flag setting: - ``YES``: The module or group must be built. - ``NO``: The module or group must not be built. - ``WANT``: The module or group should be built if possible. - ``DONT_WANT``: The module or group should only be built if required (e.g., via a dependency). - ``DEFAULT``: Acts as either ``WANT`` or ``DONT_WANT`` based on the group settings for the module or ``WANT_BY_DEFAULT`` option to :cmake:command:`vtk_module_scan` if no other preference is specified. This is usually handled via another setting in the main project. If a ``YES`` module preference requires a module with a ``NO`` preference, an error is raised. A module with a setting of ``DEFAULT`` will look for its first non-``DEFAULT`` group setting and only if all of those are set to ``DEFAULT`` is the ``WANT_BY_DEFAULT`` setting used. #]==] #[==[.rst: .. cmake:command:: _vtk_module_verify_enable_value Verify enable values |module-impl| Verifies that the variable named as the first parameter is a valid `enable status` value. .. code-block:: cmake _vtk_module_verify_enable_value(var) #]==] function (_vtk_module_verify_enable_value var) if (NOT (${var} STREQUAL "YES" OR ${var} STREQUAL "WANT" OR ${var} STREQUAL "DONT_WANT" OR ${var} STREQUAL "NO" OR ${var} STREQUAL "DEFAULT")) message(FATAL_ERROR "The `${var}` variable must be one of `YES`, `WANT`, `DONT_WANT`, `NO`, " "or `DEFAULT`. Found `${${var}}`.") endif () endfunction () include("${CMAKE_CURRENT_LIST_DIR}/vtkTopologicalSort.cmake") #[==[.rst: .. cmake:command:: vtk_module_scan Scan modules and kits |module| Once all of the modules and kits files have been found, they are "scanned" to determine what modules are enabled or required. .. code-block:: cmake vtk_module_scan( MODULE_FILES ... [KIT_FILES ...] PROVIDES_MODULES [PROVIDES_KITS ] [REQUIRES_MODULES ] [REQUEST_MODULES ...] [REJECT_MODULES ...] [UNRECOGNIZED_MODULES ] [WANT_BY_DEFAULT ] [HIDE_MODULES_FROM_CACHE ] [ENABLE_TESTS ]) The ``MODULE_FILES`` and ``PROVIDES_MODULES`` arguments are required. Modules which refer to kits must be scanned at the same time as their kits. This is so that modules may not add themselves to kits declared prior. The arguments are as follows: * ``MODULE_FILES``: (Required) The list of module files to scan. * ``KIT_FILES``: The list of kit files to scan. * ``PROVIDES_MODULES``: (Required) This variable will contain the list of modules which are enabled due to this scan. * ``PROVIDES_KITS``: (Required if ``KIT_FILES`` are provided) This variable will contain the list of kits which are enabled due to this scan. * ``REQUIRES_MODULES``: This variable will contain the list of modules required by the enabled modules that were not scanned. * ``REQUEST_MODULES``: The list of modules required by previous scans. * ``REJECT_MODULES``: The list of modules to exclude from the scan. If any of these modules are required, an error will be raised. * ``UNRECOGNIZED_MODULES``: This variable will contain the list of requested modules that were not scanned. * ``WANT_BY_DEFAULT``: (Defaults to ``OFF``) Whether modules should default to being built or not. * ``HIDE_MODULES_FROM_CACHE``: (Defaults to ``OFF``) Whether or not to hide the control variables from the cache or not. If enabled, modules will not be built unless they are required elsewhere. * ``ENABLE_TESTS``: (Defaults to ``DEFAULT``) Whether or not modules required by the tests for the scanned modules should be enabled or not. - ``ON``: Modules listed as ``TEST_DEPENDS`` will be required. - ``OFF``: Test modules will not be considered. - ``WANT``: Test dependencies will enable modules if possible. Note that this has known issues where modules required only via testing may not have their dependencies enabled. - ``DEFAULT``: Test modules will be enabled if their required dependencies are satisfied and skipped otherwise. To make error messages clearer, modules passed to ``REQUIRES_MODULES`` and ``REJECT_MODULES`` may have a ``_vtk_module_reason_`` variable set to the reason for the module appearing in either argument. For example, if the ``Package::Frobnitz`` module is required due to a ``ENABLE_FROBNITZ`` cache variable: .. code-block:: cmake set("_vtk_module_reason_Package::Frobnitz" "via the `ENABLE_FROBNITZ` setting") Additionally, the reason for the ``WANT_BY_DEFAULT`` value may be provided via the ``_vtk_module_reason_WANT_BY_DEFAULT`` variable. .. _module-scanning-multiple: Scanning multiple groups of modules =================================== When scanning complicated projects, multiple scans may be required to get defaults set properly. The ``REQUIRES_MODULES``, ``REQUEST_MODULES``, and ``UNRECOGNIZED_MODULES`` arguments are meant to deal with this case. As an example, imagine a project with its source code, third party dependencies, as well as some utility modules which should only be built as necessary. Here, the project would perform three scans, one for each "grouping" of modules: .. code-block:: cmake # Scan our modules first because we need to know what of the other groups we # need. vtk_module_find_modules(our_modules "${CMAKE_CURRENT_SOURCE_DIR}/src") vtk_module_scan( MODULE_FILES ${our_modules} PROVIDES_MODULES our_enabled_modules REQUIRES_MODULES required_modules) # Scan the third party modules, requesting only those that are necessary, but # allowing them to be toggled during the build. vtk_module_find_modules(third_party_modules "${CMAKE_CURRENT_SOURCE_DIR}/third-party") vtk_module_scan( MODULE_FILES ${third_party_modules} PROVIDES_MODULES third_party_enabled_modules # These modules were requested by an earlier scan. REQUEST_MODULES ${required_modules} REQUIRES_MODULES required_modules UNRECOGNIZED_MODULES unrecognized_modules) # These modules are internal and should only be built if necessary. There is no # need to support them being enabled independently, so hide them from the # cache. vtk_module_find_modules(utility_modules "${CMAKE_CURRENT_SOURCE_DIR}/utilities") vtk_module_scan( MODULE_FILES ${utility_modules} PROVIDES_MODULES utility_enabled_modules # These modules were either requested or unrecognized by an earlier scan. REQUEST_MODULES ${required_modules} ${unrecognized_modules} REQUIRES_MODULES required_modules UNRECOGNIZED_MODULES unrecognized_modules HIDE_MODULES_FROM_CACHE ON) if (required_modules OR unrecognized_modules) # Not all of the modules we required were found. This should probably error out. endif () #]==] function (vtk_module_scan) cmake_parse_arguments(PARSE_ARGV 0 _vtk_scan "" "WANT_BY_DEFAULT;HIDE_MODULES_FROM_CACHE;PROVIDES_MODULES;REQUIRES_MODULES;UNRECOGNIZED_MODULES;ENABLE_TESTS;PROVIDES_KITS" "MODULE_FILES;KIT_FILES;REQUEST_MODULES;REJECT_MODULES") if (_vtk_scan_UNPARSED_ARGUMENTS) message(FATAL_ERROR "Unparsed arguments for vtk_module_scan: " "${_vtk_scan_UNPARSED_ARGUMENTS}") endif () if (NOT DEFINED _vtk_scan_WANT_BY_DEFAULT) set(_vtk_scan_WANT_BY_DEFAULT OFF) endif () if (NOT DEFINED _vtk_scan_HIDE_MODULES_FROM_CACHE) set(_vtk_scan_HIDE_MODULES_FROM_CACHE OFF) endif () if (NOT DEFINED _vtk_scan_PROVIDES_MODULES) message(FATAL_ERROR "The `PROVIDES_MODULES` argument is required.") endif () if (NOT DEFINED _vtk_scan_PROVIDES_KITS AND _vtk_scan_KIT_FILES) message(FATAL_ERROR "The `PROVIDES_KITS` argument is required.") endif () if (NOT DEFINED _vtk_scan_ENABLE_TESTS) set(_vtk_scan_ENABLE_TESTS "DEFAULT") endif () if (NOT (_vtk_scan_ENABLE_TESTS STREQUAL "ON" OR _vtk_scan_ENABLE_TESTS STREQUAL "OFF" OR _vtk_scan_ENABLE_TESTS STREQUAL "WANT" OR _vtk_scan_ENABLE_TESTS STREQUAL "DEFAULT")) message(FATAL_ERROR "The `ENABLE_TESTS` argument must be one of `ON`, `OFF`, `WANT`, or " "`DEFAULT`. " "Received `${_vtk_scan_ENABLE_TESTS}`.") endif () if (NOT _vtk_scan_MODULE_FILES) message(FATAL_ERROR "No module files given to scan.") endif () set(_vtk_scan_option_default_type STRING) if (_vtk_scan_HIDE_MODULES_FROM_CACHE) set(_vtk_scan_option_default_type INTERNAL) endif () set(_vtk_scan_all_kits) foreach (_vtk_scan_kit_file IN LISTS _vtk_scan_KIT_FILES) if (NOT IS_ABSOLUTE "${_vtk_scan_kit_file}") string(PREPEND _vtk_scan_kit_file "${CMAKE_CURRENT_SOURCE_DIR}/") endif () set_property(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS "${_vtk_scan_kit_file}") file(READ "${_vtk_scan_kit_file}" _vtk_scan_kit_args) # Replace comments. string(REGEX REPLACE "#[^\n]*\n" "\n" _vtk_scan_kit_args "${_vtk_scan_kit_args}") # Use argument splitting. string(REGEX REPLACE "( |\n)+" ";" _vtk_scan_kit_args "${_vtk_scan_kit_args}") _vtk_module_parse_kit_args(_vtk_scan_kit_name ${_vtk_scan_kit_args}) _vtk_module_debug(kit "@_vtk_scan_kit_name@ declared by @_vtk_scan_kit_file@") list(APPEND _vtk_scan_all_kits "${_vtk_scan_kit_name}") # Set properties for building. set_property(GLOBAL PROPERTY "_vtk_kit_${_vtk_scan_kit_name}_namespace" "${${_vtk_scan_kit_name}_NAMESPACE}") set_property(GLOBAL PROPERTY "_vtk_kit_${_vtk_scan_kit_name}_target_name" "${${_vtk_scan_kit_name}_TARGET_NAME}") set_property(GLOBAL PROPERTY "_vtk_kit_${_vtk_scan_kit_name}_library_name" "${${_vtk_scan_kit_name}_LIBRARY_NAME}") endforeach () set(_vtk_scan_all_modules) set(_vtk_scan_all_groups) set(_vtk_scan_rejected_modules) # Read all of the module files passed in. foreach (_vtk_scan_module_file IN LISTS _vtk_scan_MODULE_FILES) if (NOT IS_ABSOLUTE "${_vtk_scan_module_file}") string(PREPEND _vtk_scan_module_file "${CMAKE_CURRENT_SOURCE_DIR}/") endif () set_property(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS "${_vtk_scan_module_file}") file(READ "${_vtk_scan_module_file}" _vtk_scan_module_args) # Replace comments. string(REGEX REPLACE "#[^\n]*\n" "\n" _vtk_scan_module_args "${_vtk_scan_module_args}") # Use argument splitting. string(REGEX REPLACE "( |\n)+" ";" _vtk_scan_module_args "${_vtk_scan_module_args}") _vtk_module_parse_module_args(_vtk_scan_module_name ${_vtk_scan_module_args}) _vtk_module_debug(module "@_vtk_scan_module_name@ declared by @_vtk_scan_module_file@") string(REPLACE "::" "_" _vtk_scan_module_name_safe "${_vtk_scan_module_name}") if (${_vtk_scan_module_name}_THIRD_PARTY) if (_vtk_module_warnings) if (${_vtk_scan_module_name}_EXCLUDE_WRAP) message(WARNING "The third party ${_vtk_scan_module_name} module does not need to " "declare `EXCLUDE_WRAP` also.") endif () endif () if (${_vtk_scan_module_name}_INCLUDE_MARSHAL) message(FATAL_ERROR "The third party ${_vtk_scan_module_name} module may not opt-in to " "`INCLUDE_MARSHAL`.") endif () if (${_vtk_scan_module_name}_IMPLEMENTABLE) message(FATAL_ERROR "The third party ${_vtk_scan_module_name} module may not be " "`IMPLEMENTABLE`.") endif () if (${_vtk_scan_module_name}_IMPLEMENTS) message(FATAL_ERROR "The third party ${_vtk_scan_module_name} module may not " "`IMPLEMENTS` another module.") endif () if (${_vtk_scan_module_name}_KIT) message(FATAL_ERROR "The third party ${_vtk_scan_module_name} module may not be part of " "a kit (${${_vtk_scan_module_name}_KIT}).") endif () endif () # Throw error when mutually exclusive options are present. # When a module opts into marshalling, it requires the hierarchy if (${_vtk_scan_module_name}_EXCLUDE_WRAP AND ${_vtk_scan_module_name}_INCLUDE_MARSHAL) message(FATAL_ERROR "The ${_vtk_scan_module_name} module can not declare `EXCLUDE_WRAP` and `INCLUDE_MARSHAL` at the same time.") endif () if (${_vtk_scan_module_name}_KIT) if (NOT ${_vtk_scan_module_name}_KIT IN_LIST _vtk_scan_all_kits) message(FATAL_ERROR "The ${_vtk_scan_module_name} belongs to the " "${${_vtk_scan_module_name}_KIT} kit, but it has not been scanned.") endif () endif () # Check if the module is visible. Modules which have a failing condition # are basically invisible. if (DEFINED ${_vtk_scan_module_name}_CONDITION) if (NOT (${${_vtk_scan_module_name}_CONDITION})) if (DEFINED "VTK_MODULE_ENABLE_${_vtk_scan_module_name_safe}") set_property(CACHE "VTK_MODULE_ENABLE_${_vtk_scan_module_name_safe}" PROPERTY TYPE INTERNAL) endif () _vtk_module_debug(module "@_vtk_scan_module_name@ hidden by its `CONDITION`") continue () endif () endif () # Determine whether we should provide a user-visible option for this # module. set(_vtk_build_use_option 1) if (DEFINED _vtk_scan_REQUEST_MODULE) if (_vtk_scan_module_name IN_LIST _vtk_scan_REQUEST_MODULE) set("_vtk_scan_enable_${_vtk_scan_module_name}" YES) set(_vtk_build_use_option 0) endif () endif () if (DEFINED _vtk_scan_REJECT_MODULES) if (_vtk_scan_module_name IN_LIST _vtk_scan_REJECT_MODULES) if (NOT _vtk_build_use_option) message(FATAL_ERROR "The ${_vtk_scan_module_name} module has been requested and rejected.") endif () # Rejected modules should not have a build option. set(_vtk_build_use_option 0) list(APPEND _vtk_scan_rejected_modules "${_vtk_scan_module_name}") endif () endif () # Handle cache entries and determine the enabled state of the module from # the relevant cache variables. if (_vtk_build_use_option) set("VTK_MODULE_ENABLE_${_vtk_scan_module_name_safe}" "DEFAULT" CACHE STRING "Enable the ${_vtk_scan_module_name} module. ${${_vtk_scan_module_name}_DESCRIPTION}") mark_as_advanced("VTK_MODULE_ENABLE_${_vtk_scan_module_name_safe}") set_property(CACHE "VTK_MODULE_ENABLE_${_vtk_scan_module_name_safe}" PROPERTY STRINGS "YES;WANT;DONT_WANT;NO;DEFAULT") _vtk_module_verify_enable_value("VTK_MODULE_ENABLE_${_vtk_scan_module_name_safe}") if (NOT VTK_MODULE_ENABLE_${_vtk_scan_module_name_safe} STREQUAL "DEFAULT") set("_vtk_scan_enable_${_vtk_scan_module_name}" "${VTK_MODULE_ENABLE_${_vtk_scan_module_name_safe}}") set("_vtk_scan_enable_reason_${_vtk_scan_module_name}" "via `VTK_MODULE_ENABLE_${_vtk_scan_module_name_safe}`") _vtk_module_debug(enable "@_vtk_scan_module_name@ is `${_vtk_scan_enable_${_vtk_scan_module_name}}` by cache value") endif () # Check the state of any groups the module belongs to. foreach (_vtk_scan_group IN LISTS "${_vtk_scan_module_name}_GROUPS") if (NOT DEFINED "VTK_GROUP_ENABLE_${_vtk_scan_group}") set(_vtk_scan_group_default "DEFAULT") if (DEFINED "_vtk_module_group_default_${_vtk_scan_group}") set(_vtk_scan_group_default "${_vtk_module_group_default_${_vtk_scan_group}}") endif () set("VTK_GROUP_ENABLE_${_vtk_scan_group}" "${_vtk_scan_group_default}" CACHE STRING "Enable the ${_vtk_scan_group} group modules.") set_property(CACHE "VTK_GROUP_ENABLE_${_vtk_scan_group}" PROPERTY STRINGS "YES;WANT;DONT_WANT;NO;DEFAULT") set_property(CACHE "VTK_GROUP_ENABLE_${_vtk_scan_group}" PROPERTY TYPE "${_vtk_scan_option_default_type}") endif () _vtk_module_verify_enable_value("VTK_GROUP_ENABLE_${_vtk_scan_group}") if (NOT VTK_MODULE_ENABLE_${_vtk_scan_module_name_safe} STREQUAL "DEFAULT") continue () endif () # Determine the state of the group. set(_vtk_scan_group_enable "${VTK_GROUP_ENABLE_${_vtk_scan_group}}") if (NOT _vtk_scan_group_enable STREQUAL "DEFAULT") set("_vtk_scan_enable_${_vtk_scan_module_name}" "${_vtk_scan_group_enable}") set("_vtk_scan_enable_reason_${_vtk_scan_module_name}" "via `VTK_GROUP_ENABLE_${_vtk_scan_group}`") _vtk_module_debug(enable "@_vtk_scan_module_name@ is DEFAULT, using group `@_vtk_scan_group@` setting: @_vtk_scan_group_enable@") endif () endforeach () set_property(CACHE "VTK_MODULE_ENABLE_${_vtk_scan_module_name_safe}" PROPERTY TYPE "${_vtk_scan_option_default_type}") endif () if (NOT DEFINED "_vtk_scan_enable_${_vtk_scan_module_name}" AND VTK_MODULE_ENABLE_${_vtk_scan_module_name_safe} STREQUAL "DEFAULT") if (_vtk_scan_WANT_BY_DEFAULT) set("_vtk_scan_enable_${_vtk_scan_module_name}" "WANT") else () set("_vtk_scan_enable_${_vtk_scan_module_name}" "DONT_WANT") endif () if (DEFINED _vtk_module_reason_WANT_BY_DEFAULT) set("_vtk_scan_enable_reason_${_vtk_scan_module_name}" "${_vtk_module_reason_WANT_BY_DEFAULT}") else () set("_vtk_scan_enable_reason_${_vtk_scan_module_name}" "via `WANT_BY_DEFAULT=${_vtk_scan_WANT_BY_DEFAULT}`") endif () _vtk_module_debug(enable "@_vtk_scan_module_name@ is DEFAULT, using `WANT_BY_DEFAULT`: ${_vtk_scan_enable_reason_${_vtk_scan_module_name}}") endif () list(APPEND _vtk_scan_all_modules "${_vtk_scan_module_name}") set("_vtk_scan_${_vtk_scan_module_name}_all_depends" ${${_vtk_scan_module_name}_DEPENDS} ${${_vtk_scan_module_name}_PRIVATE_DEPENDS}) if (${_vtk_scan_module_name}_THIRD_PARTY) set("${_vtk_scan_module_name}_INCLUDE_MARSHAL" FALSE) set("${_vtk_scan_module_name}_EXCLUDE_WRAP" TRUE) set("${_vtk_scan_module_name}_IMPLEMENTABLE" FALSE) set("${_vtk_scan_module_name}_IMPLEMENTS") endif () if (${_vtk_scan_module_name}_KIT) _vtk_module_debug(kit "@_vtk_scan_module_name@ belongs to the ${${_vtk_scan_module_name}_KIT} kit") endif () # Set properties for building. set_property(GLOBAL PROPERTY "_vtk_module_${_vtk_scan_module_name}_file" "${_vtk_scan_module_file}") set_property(GLOBAL PROPERTY "_vtk_module_${_vtk_scan_module_name}_namespace" "${${_vtk_scan_module_name}_NAMESPACE}") set_property(GLOBAL PROPERTY "_vtk_module_${_vtk_scan_module_name}_target_name" "${${_vtk_scan_module_name}_TARGET_NAME}") set_property(GLOBAL PROPERTY "_vtk_module_${_vtk_scan_module_name}_library_name" "${${_vtk_scan_module_name}_LIBRARY_NAME}") set_property(GLOBAL PROPERTY "_vtk_module_${_vtk_scan_module_name}_third_party" "${${_vtk_scan_module_name}_THIRD_PARTY}") set_property(GLOBAL PROPERTY "_vtk_module_${_vtk_scan_module_name}_exclude_wrap" "${${_vtk_scan_module_name}_EXCLUDE_WRAP}") set_property(GLOBAL PROPERTY "_vtk_module_${_vtk_scan_module_name}_kit" "${${_vtk_scan_module_name}_KIT}") set_property(GLOBAL PROPERTY "_vtk_module_${_vtk_scan_module_name}_depends" "${${_vtk_scan_module_name}_DEPENDS}") set_property(GLOBAL PROPERTY "_vtk_module_${_vtk_scan_module_name}_order_depends" "${${_vtk_scan_module_name}_ORDER_DEPENDS}") set_property(GLOBAL PROPERTY "_vtk_module_${_vtk_scan_module_name}_private_depends" "${${_vtk_scan_module_name}_PRIVATE_DEPENDS}") set_property(GLOBAL PROPERTY "_vtk_module_${_vtk_scan_module_name}_optional_depends" "${${_vtk_scan_module_name}_OPTIONAL_DEPENDS}") set_property(GLOBAL PROPERTY "_vtk_module_${_vtk_scan_module_name}_test_depends" "${${_vtk_scan_module_name}_TEST_DEPENDS}") set_property(GLOBAL PROPERTY "_vtk_module_${_vtk_scan_module_name}_test_optional_depends" "${${_vtk_scan_module_name}_TEST_OPTIONAL_DEPENDS}") set_property(GLOBAL PROPERTY "_vtk_module_${_vtk_scan_module_name}_test_labels" "${${_vtk_scan_module_name}_TEST_LABELS}") set_property(GLOBAL PROPERTY "_vtk_module_${_vtk_scan_module_name}_implements" "${${_vtk_scan_module_name}_IMPLEMENTS}") set_property(GLOBAL PROPERTY "_vtk_module_${_vtk_scan_module_name}_implementable" "${${_vtk_scan_module_name}_IMPLEMENTABLE}") set_property(GLOBAL PROPERTY "_vtk_module_${_vtk_scan_module_name}_include_marshal" "${${_vtk_scan_module_name}_INCLUDE_MARSHAL}") # create absolute path for license files set(_license_files) foreach (_license_file IN LISTS ${_vtk_scan_module_name}_LICENSE_FILES) if (NOT IS_ABSOLUTE "${_license_file}") get_filename_component(_vtk_scan_module_dir "${_vtk_scan_module_file}" DIRECTORY) string(PREPEND _license_file "${_vtk_scan_module_dir}/") endif () list(APPEND _license_files "${_license_file}") endforeach () set_property(GLOBAL PROPERTY "_vtk_module_${_vtk_scan_module_name}_license_files" "${_license_files}") # Revert argument splitting done in vtk_module_scan() just before calling _vtk_module_parse_module_args() # For example, it converts # "MIT;AND;(LGPL-2.1-or-later;OR;BSD-3-Clause)" # back to # "MIT AND (LGPL-2.1-or-later OR BSD-3-Clause)" string(REGEX REPLACE ";" " " _spdx_license_identifier "${${_vtk_scan_module_name}_SPDX_LICENSE_IDENTIFIER}") set_property(GLOBAL PROPERTY "_vtk_module_${_vtk_scan_module_name}_spdx_license_identifier" "${_spdx_license_identifier}") # Revert argument splitting done in vtk_module_scan() just before calling _vtk_module_parse_module_args() # For example, it converts # "Copyright;(c);Ken;Martin,;Will;Schroeder,;Bill;Lorensen" # back to # "Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen" string(REGEX REPLACE ";" " " _spdx_copyright_text "${${_vtk_scan_module_name}_SPDX_COPYRIGHT_TEXT}") set_property(GLOBAL PROPERTY "_vtk_module_${_vtk_scan_module_name}_spdx_copyright_text" "${_spdx_copyright_text}") set_property(GLOBAL PROPERTY "_vtk_module_${_vtk_scan_module_name}_spdx_download_location" "${${_vtk_scan_module_name}_SPDX_DOWNLOAD_LOCATION}") set_property(GLOBAL PROPERTY "_vtk_module_${_vtk_scan_module_name}_spdx_custom_license_file" "${${_vtk_scan_module_name}_SPDX_CUSTOM_LICENSE_FILE}") set_property(GLOBAL PROPERTY "_vtk_module_${_vtk_scan_module_name}_spdx_custom_license_name" "${${_vtk_scan_module_name}_SPDX_CUSTOM_LICENSE_NAME}") if (_vtk_scan_ENABLE_TESTS STREQUAL "WANT") set_property(GLOBAL PROPERTY "_vtk_module_${_vtk_scan_module_name}_enable_tests_by_want" "1") endif () endforeach () set(_vtk_scan_current_modules "${_vtk_scan_all_modules}") vtk_topological_sort(_vtk_scan_all_modules "_vtk_scan_" "_all_depends") set(_vtk_scan_provided_modules) set(_vtk_scan_required_modules) set(_vtk_scan_disabled_modules) # Seed the `_vtk_scan_provide_` variables with modules requested and rejected # as arguments. foreach (_vtk_scan_request_module IN LISTS _vtk_scan_REQUEST_MODULES) set("_vtk_scan_provide_${_vtk_scan_request_module}" ON) if (DEFINED "_vtk_module_reason_${_vtk_scan_request_module}") set("_vtk_scan_provide_reason_${_vtk_scan_request_module}" "${_vtk_module_reason_${_vtk_scan_request_module}}") else () set("_vtk_scan_provide_reason_${_vtk_scan_request_module}" "via `REQUEST_MODULES`") endif () _vtk_module_debug(provide "@_vtk_scan_request_module@ is provided ${_vtk_scan_provide_reason_${_vtk_scan_request_module}}") endforeach () foreach (_vtk_scan_reject_module IN LISTS _vtk_scan_REJECT_MODULES) set("_vtk_scan_provide_${_vtk_scan_reject_module}" OFF) if (DEFINED "_vtk_module_reason_${_vtk_scan_reject_module}") set("_vtk_scan_provide_reason_${_vtk_scan_reject_module}" "${_vtk_module_reason_${_vtk_scan_reject_module}}") else () set("_vtk_scan_provide_reason_${_vtk_scan_reject_module}" "via `REJECT_MODULES`") endif () _vtk_module_debug(provide "@_vtk_scan_reject_module@ is not provided ${_vtk_scan_provide_reason_${_vtk_scan_reject_module}}") endforeach () # Traverse the graph classifying the quad-state for enabling modules into a # boolean stored in the `_vtk_scan_provide_` variables. foreach (_vtk_scan_module IN LISTS _vtk_scan_all_modules) if (NOT _vtk_scan_module IN_LIST _vtk_scan_current_modules) _vtk_module_debug(provide "@_vtk_scan_module@ is ignored because it is not in the current scan set") continue () endif () if (DEFINED "_vtk_scan_provide_${_vtk_scan_module}") # Already done. elseif (_vtk_scan_enable_${_vtk_scan_module} STREQUAL "YES") # Mark enabled modules as to-be-provided. Any errors with requiring a # disabled module will be dealt with later. set("_vtk_scan_provide_${_vtk_scan_module}" ON) set("_vtk_scan_provide_reason_${_vtk_scan_module}" "via a `YES` setting (${_vtk_scan_enable_reason_${_vtk_scan_module}})") _vtk_module_debug(provide "@_vtk_scan_module@ is provided due to `YES` setting") elseif (_vtk_scan_enable_${_vtk_scan_module} STREQUAL "WANT") # Check to see if we can provide this module by checking of any of its # dependencies have been disabled. set(_vtk_scan_test_depends) if (NOT ${_vtk_scan_module}_THIRD_PARTY AND _vtk_scan_ENABLE_TESTS STREQUAL "ON") # If the tests have to be on, we also need the test dependencies. set(_vtk_scan_test_depends "${${_vtk_scan_module}_TEST_DEPENDS}") endif () set("_vtk_scan_provide_${_vtk_scan_module}" ON) set("_vtk_scan_provide_reason_${_vtk_scan_module}" "via a `WANT` setting (${_vtk_scan_enable_reason_${_vtk_scan_module}})") _vtk_module_debug(provide "@_vtk_scan_module@ is provided due to `WANT` setting") foreach (_vtk_scan_module_depend IN LISTS "${_vtk_scan_module}_DEPENDS" "${_vtk_scan_module}_PRIVATE_DEPENDS" _vtk_scan_test_depends) if (DEFINED "_vtk_scan_provide_${_vtk_scan_module_depend}" AND NOT _vtk_scan_provide_${_vtk_scan_module_depend}) set("_vtk_scan_provide_${_vtk_scan_module}" OFF) set("_vtk_scan_provide_reason_${_vtk_scan_module}" "due to the ${_vtk_scan_module_depend} module not being available") if (DEFINED "_vtk_scan_provide_reason_${_vtk_scan_module_depend}") string(APPEND "_vtk_scan_provide_reason_${_vtk_scan_module}" " (${_vtk_scan_provide_reason_${_vtk_scan_module_depend}})") endif () _vtk_module_debug(provide "@_vtk_scan_module@ is not provided due to not provided dependency @_vtk_scan_module_depend@") break () endif () endforeach () elseif (_vtk_scan_enable_${_vtk_scan_module} STREQUAL "DONT_WANT") # Check for disabled dependencies and disable if so. foreach (_vtk_scan_module_depend IN LISTS "${_vtk_scan_module}_DEPENDS" "${_vtk_scan_module}_PRIVATE_DEPENDS" _vtk_scan_test_depends) if (DEFINED "_vtk_scan_provide_${_vtk_scan_module_depend}" AND NOT _vtk_scan_provide_${_vtk_scan_module_depend}) set("_vtk_scan_provide_${_vtk_scan_module}" OFF) set("_vtk_scan_provide_reason_${_vtk_scan_module}" "due to the ${_vtk_scan_module_depend} module not being available") if (DEFINED "_vtk_scan_provide_reason_${_vtk_scan_module_depend}") string(APPEND "_vtk_scan_provide_reason_${_vtk_scan_module}" " (${_vtk_scan_provide_reason_${_vtk_scan_module_depend}})") endif () _vtk_module_debug(provide "@_vtk_scan_module@ is not provided due to not provided dependency @_vtk_scan_module_depend@") break () endif () endforeach () elseif (_vtk_scan_enable_${_vtk_scan_module} STREQUAL "NO") # Disable the module. set("_vtk_scan_provide_${_vtk_scan_module}" OFF) set("_vtk_scan_provide_reason_${_vtk_scan_module}" "via a `NO` setting (${_vtk_scan_enable_reason_${_vtk_scan_module}})") _vtk_module_debug(provide "@_vtk_scan_module@ is not provided due to `NO` setting") endif () # Collect disabled modules into a list. if (DEFINED "_vtk_scan_provide_${_vtk_scan_module}" AND NOT _vtk_scan_provide_${_vtk_scan_module}) list(APPEND _vtk_scan_disabled_modules "${_vtk_scan_module}") endif () if (NOT DEFINED "_vtk_scan_provide_${_vtk_scan_module}") _vtk_module_debug(provide "@_vtk_scan_module@ is indeterminate (${_vtk_scan_enable_${_vtk_scan_module}})") endif () endforeach () # Scan all modules from the top of tree to the bottom. list(REVERSE _vtk_scan_all_modules) foreach (_vtk_scan_module IN LISTS _vtk_scan_all_modules) if (NOT _vtk_scan_module IN_LIST _vtk_scan_current_modules) continue () endif () # If we're providing this module... if (_vtk_scan_provide_${_vtk_scan_module}) list(APPEND _vtk_scan_provided_modules "${_vtk_scan_module}") # Grab any test dependencies that are required. set(_vtk_scan_test_depends) set(_vtk_scan_test_wants) if (_vtk_scan_ENABLE_TESTS STREQUAL "ON") set_property(GLOBAL APPEND PROPERTY "_vtk_module_test_modules" "${_vtk_scan_module}") set(_vtk_scan_test_depends "${${_vtk_scan_module}_TEST_DEPENDS}") elseif (_vtk_scan_ENABLE_TESTS STREQUAL "WANT") set_property(GLOBAL APPEND PROPERTY "_vtk_module_test_modules" "${_vtk_scan_module}") set(_vtk_scan_test_wants _vtk_scan_wants_marker ${${_vtk_scan_module}_TEST_DEPENDS}) elseif (_vtk_scan_ENABLE_TESTS STREQUAL "DEFAULT") set_property(GLOBAL APPEND PROPERTY "_vtk_module_test_modules" "${_vtk_scan_module}") elseif (_vtk_scan_ENABLE_TESTS STREQUAL "OFF") # Nothing to do. else () message(FATAL_ERROR "Unrecognized option for ENABLE_TESTS: ${_vtk_module_ENABLE_TESTS}.") endif () # Add all dependent modules to the list of required or provided modules. set(_vtk_scan_is_wanting 0) foreach (_vtk_scan_module_depend IN LISTS "${_vtk_scan_module}_DEPENDS" "${_vtk_scan_module}_PRIVATE_DEPENDS" _vtk_scan_test_depends _vtk_scan_test_wants) if (_vtk_scan_module_depend STREQUAL "_vtk_scan_wants_marker") set(_vtk_scan_is_wanting 1) continue () endif () # Though we need to error if this would cause a disabled module to be # provided. if (_vtk_scan_module_depend IN_LIST _vtk_scan_disabled_modules) if (_vtk_scan_is_wanting) continue () else () message(FATAL_ERROR "The ${_vtk_scan_module} module (enabled " "${_vtk_scan_provide_reason_${_vtk_scan_module}}) requires the " "disabled module ${_vtk_scan_module_depend} (disabled " "${_vtk_scan_provide_reason_${_vtk_scan_module_depend}}).") endif () endif () if (DEFINED "_vtk_scan_provide_${_vtk_scan_module_depend}") if (NOT _vtk_scan_provide_${_vtk_scan_module_depend}) message(FATAL_ERROR "The ${_vtk_scan_module_depend} module (disabled " "${_vtk_scan_provide_reason_${_vtk_scan_module_depend}}) should " "be provided because it is required by ${_vtk_scan_module} " "(${_vtk_scan_provide_reason_${_vtk_scan_module}})") endif () continue () endif () set("_vtk_scan_provide_reason_${_vtk_scan_module_depend}" "via dependency from ${_vtk_scan_module}") if (DEFINED "_vtk_scan_provide_reason_${_vtk_scan_module}") string(APPEND "_vtk_scan_provide_reason_${_vtk_scan_module_depend}" " (${_vtk_scan_provide_reason_${_vtk_scan_module}})") endif () set("_vtk_scan_provide_${_vtk_scan_module_depend}" ON) if (NOT _vtk_scan_module_depend IN_LIST _vtk_scan_current_modules) if (NOT TARGET "${_vtk_scan_module_depend}") _vtk_module_debug(provide "@_vtk_scan_module_depend@ is external and required due to dependency from @_vtk_scan_module@") endif () list(APPEND _vtk_scan_required_modules "${_vtk_scan_module_depend}") else () _vtk_module_debug(provide "@_vtk_scan_module_depend@ is provided due to dependency from @_vtk_scan_module@") list(APPEND _vtk_scan_provided_modules "${_vtk_scan_module_depend}") endif () endforeach () endif () endforeach () if (_vtk_scan_provided_modules) list(REMOVE_DUPLICATES _vtk_scan_provided_modules) endif () set(_vtk_scan_provided_kits) # Build a list of kits which contain the provided modules. foreach (_vtk_scan_provided_module IN LISTS _vtk_scan_provided_modules) if (${_vtk_scan_provided_module}_KIT) list(APPEND _vtk_scan_provided_kits "${${_vtk_scan_provided_module}_KIT}") set_property(GLOBAL APPEND PROPERTY "_vtk_kit_${${_vtk_scan_provided_module}_KIT}_kit_modules" "${_vtk_scan_provided_module}") endif () endforeach () if (_vtk_scan_provided_kits) list(REMOVE_DUPLICATES _vtk_scan_provided_kits) endif () if (_vtk_scan_required_modules) list(REMOVE_DUPLICATES _vtk_scan_required_modules) endif () set(_vtk_scan_unrecognized_modules ${_vtk_scan_REQUEST_MODULES} ${_vtk_scan_REJECT_MODULES}) if (_vtk_scan_unrecognized_modules AND (_vtk_scan_provided_modules OR _vtk_scan_rejected_modules)) list(REMOVE_ITEM _vtk_scan_unrecognized_modules ${_vtk_scan_provided_modules} ${_vtk_scan_rejected_modules}) endif () set("${_vtk_scan_PROVIDES_MODULES}" ${_vtk_scan_provided_modules} PARENT_SCOPE) if (DEFINED _vtk_scan_REQUIRES_MODULES) set("${_vtk_scan_REQUIRES_MODULES}" ${_vtk_scan_required_modules} PARENT_SCOPE) endif () if (DEFINED _vtk_scan_UNRECOGNIZED_MODULES) set("${_vtk_scan_UNRECOGNIZED_MODULES}" ${_vtk_scan_unrecognized_modules} PARENT_SCOPE) endif () if (DEFINED _vtk_scan_PROVIDES_KITS) set("${_vtk_scan_PROVIDES_KITS}" ${_vtk_scan_provided_kits} PARENT_SCOPE) endif () endfunction () #[==[.rst: .. _module-target-functions: Module-as-target functions ========================== Due to the nature of VTK modules supporting being built as kits, the module name might not be usable as a target to CMake's `target_` family of commands. Instead, there are various wrappers around them which take the module name as an argument. These handle the forwarding of relevant information to the kit library as well where necessary. * :cmake:command:`vtk_module_set_properties` * :cmake:command:`vtk_module_set_property` * :cmake:command:`vtk_module_get_property` * :cmake:command:`vtk_module_depend` * :cmake:command:`vtk_module_include` * :cmake:command:`vtk_module_definitions` * :cmake:command:`vtk_module_compile_options` * :cmake:command:`vtk_module_compile_features` * :cmake:command:`vtk_module_link` * :cmake:command:`vtk_module_link_options` #]==] #[==[.rst: .. _module-target-internals: Module target internals ======================= When manipulating modules as targets, there are a few functions provided for use in wrapping code to more easily access them. * :cmake:command:`_vtk_module_real_target` * :cmake:command:`_vtk_module_real_target_kit` #]==] #[==[.rst: .. cmake:command:: _vtk_module_real_target The real target for a module |module-internal| .. code-block:: cmake _vtk_module_real_target( ) Sometimes the actual, core target for a module is required (e.g., setting CMake-level target properties or install rules). This function returns the real target for a module. #]==] function (_vtk_module_real_target var module) if (ARGN) message(FATAL_ERROR "Unparsed arguments for _vtk_module_real_target: ${ARGN}.") endif () set(_vtk_real_target_res "") if (TARGET "${module}") get_property(_vtk_real_target_imported TARGET "${module}" PROPERTY IMPORTED) if (_vtk_real_target_imported) set(_vtk_real_target_res "${module}") endif () endif () if (NOT _vtk_real_target_res) get_property(_vtk_real_target_res GLOBAL PROPERTY "_vtk_module_${module}_target_name") # Querying during the build. if (DEFINED _vtk_build_BUILD_WITH_KITS AND _vtk_build_BUILD_WITH_KITS) get_property(_vtk_real_target_kit GLOBAL PROPERTY "_vtk_module_${module}_kit") if (_vtk_real_target_kit) string(APPEND _vtk_real_target_res "-objects") endif () # A query for after the module is built. elseif (TARGET "${_vtk_real_target_res}-objects") string(APPEND _vtk_real_target_res "-objects") endif () endif () if (NOT _vtk_real_target_res) set(_vtk_real_target_msg "") if (NOT TARGET "${module}") if (DEFINED _vtk_build_module) set(_vtk_real_target_msg " Is a module dependency missing?") elseif (TARGET "${module}") set(_vtk_real_target_msg " It's a target, but is it a VTK module?") else () set(_vtk_real_target_msg " The module name is not a CMake target. Is there a typo? Is it missing a `Package::` prefix? Is a `find_package` missing a required component?") endif () endif () message(FATAL_ERROR "Failed to determine the real target for the `${module}` " "module.${_vtk_real_target_msg}") endif () set("${var}" "${_vtk_real_target_res}" PARENT_SCOPE) endfunction () #[==[.rst: .. cmake:command:: _vtk_module_real_target_kit The real target for a kit |module-internal| .. code-block:: cmake _vtk_module_real_target_kit( ) Sometimes the actual, core target for a module is required (e.g., setting CMake-level target properties or install rules). This function returns the real target for a kit. #]==] function (_vtk_module_real_target_kit var kit) if (ARGN) message(FATAL_ERROR "Unparsed arguments for _vtk_module_real_target_kit: ${ARGN}.") endif () set(_vtk_real_target_res "") if (TARGET "${kit}") get_property(_vtk_real_target_imported TARGET "${kit}" PROPERTY IMPORTED) if (_vtk_real_target_imported) set(_vtk_real_target_res "${kit}") endif () endif () if (NOT _vtk_real_target_res) get_property(_vtk_real_target_res GLOBAL PROPERTY "_vtk_kit_${kit}_target_name") endif () if (NOT _vtk_real_target_res) message(FATAL_ERROR "Failed to determine the real target for the `${kit}` kit.") endif () set("${var}" "${_vtk_real_target_res}" PARENT_SCOPE) endfunction () #[==[.rst: .. cmake:command:: vtk_module_set_properties Set multiple properties on a module |module| A wrapper around `set_target_properties` that works for modules. .. code-block:: cmake vtk_module_set_properties( [ ]...) #]==] function (vtk_module_set_properties module) _vtk_module_real_target(_vtk_set_properties_target "${module}") set_target_properties("${_vtk_set_properties_target}" PROPERTIES ${ARGN}) endfunction () #[==[.rst: .. cmake:command:: vtk_module_set_property Set a property on a module. |module| A wrapper around ``set_property(TARGET)`` that works for modules. .. code-block:: cmake vtk_module_set_property( [APPEND] [APPEND_STRING] PROPERTY VALUE ...) #]==] function (vtk_module_set_property module) cmake_parse_arguments(PARSE_ARGV 1 _vtk_property "APPEND;APPEND_STRING" "PROPERTY" "VALUE") if (_vtk_property_UNPARSED_ARGUMENTS) message(FATAL_ERROR "Unparsed arguments for vtk_module_set_property: " "${_vtk_property_UNPARSED_ARGUMENTS}.") endif () if (NOT DEFINED _vtk_property_PROPERTY) message(FATAL_ERROR "The `PROPERTY` argument is required.") endif () if (NOT DEFINED _vtk_property_VALUE) message(FATAL_ERROR "The `VALUE` argument is required.") endif () if (_vtk_property_APPEND AND _vtk_property_APPEND_STRING) message(FATAL_ERROR "`APPEND` and `APPEND_STRING` may not be used at the same time.") endif () set(_vtk_property_args) if (_vtk_property_APPEND) list(APPEND _vtk_property_args APPEND) endif () if (_vtk_property_APPEND_STRING) list(APPEND _vtk_property_args APPEND_STRING) endif () _vtk_module_real_target(_vtk_property_target "${module}") set_property(TARGET "${_vtk_property_target}" ${_vtk_property_args} PROPERTY "${_vtk_property_PROPERTY}" "${_vtk_property_VALUE}") endfunction () #[==[.rst: .. cmake:command:: vtk_module_get_property Get a property from a module |module| A wrapper around `get_property(TARGET)` that works for modules. .. code-block:: cmake vtk_module_get_property( PROPERTY VARIABLE ) The variable name passed to the ``VARIABLE`` argument will be unset if the property is not set (rather than the empty string). #]==] function (vtk_module_get_property module) cmake_parse_arguments(PARSE_ARGV 1 _vtk_property "" "PROPERTY;VARIABLE" "") if (_vtk_property_UNPARSED_ARGUMENTS) message(FATAL_ERROR "Unparsed arguments for vtk_module_get_property: " "${_vtk_property_UNPARSED_ARGUMENTS}.") endif () if (NOT DEFINED _vtk_property_PROPERTY) message(FATAL_ERROR "The `PROPERTY` argument is required.") endif () if (NOT DEFINED _vtk_property_VARIABLE) message(FATAL_ERROR "The `VARIABLE` argument is required.") endif () _vtk_module_real_target(_vtk_property_target "${module}") get_property(_vtk_property_is_set TARGET "${_vtk_property_target}" PROPERTY "${_vtk_property_PROPERTY}" SET) if (_vtk_property_is_set) get_property(_vtk_property_value TARGET "${_vtk_property_target}" PROPERTY "${_vtk_property_PROPERTY}") set("${_vtk_property_VARIABLE}" "${_vtk_property_value}" PARENT_SCOPE) else () unset("${_vtk_property_VARIABLE}" PARENT_SCOPE) endif () endfunction () #[==[.rst: .. cmake:command:: _vtk_module_target_function Generate arguments for target function wrappers |module-impl| Create the ``INTERFACE``, ``PUBLIC``, and ``PRIVATE`` arguments for a function wrapping CMake's ``target_`` functions to call the wrapped function. This is necessary because not all of the functions support empty lists given a keyword. #]==] function (_vtk_module_target_function prefix) foreach (visibility IN ITEMS INTERFACE PUBLIC PRIVATE) if (${prefix}_${visibility}) set("${prefix}_${visibility}_args" "${visibility}" ${${prefix}_${visibility}} PARENT_SCOPE) endif () endforeach () endfunction () #[==[.rst: .. cmake:command:: vtk_module_depend Add dependencies to a module |module| A wrapper around ``add_dependencies`` that works for modules. .. code-block:: cmake vtk_module_depend( ...) #]==] function (vtk_module_depend module) _vtk_module_real_target(_vtk_depend_target "${module}") add_dependencies("${_vtk_depend_target}" ${ARGN}) endfunction () #[==[.rst: .. cmake:command:: vtk_module_sources Add source files to a module. |module| A wrapper around `target_sources` that works for modules. .. code-block:: cmake vtk_module_sources( [PUBLIC ...] [PRIVATE ...] [INTERFACE ...]) #]==] function (vtk_module_sources module) cmake_parse_arguments(PARSE_ARGV 1 _vtk_sources "" "" "INTERFACE;PUBLIC;PRIVATE") if (_vtk_sources_UNPARSED_ARGUMENTS) message(FATAL_ERROR "Unparsed arguments for vtk_module_sources: " "${_vtk_sources_UNPARSED_ARGUMENTS}.") endif () _vtk_module_real_target(_vtk_sources_target "${module}") _vtk_module_target_function(_vtk_sources) if (NOT _vtk_sources_INTERFACE_args AND NOT _vtk_sources_PUBLIC_args AND NOT _vtk_sources_PRIVATE_args) return () endif () target_sources("${_vtk_sources_target}" ${_vtk_sources_INTERFACE_args} ${_vtk_sources_PUBLIC_args} ${_vtk_sources_PRIVATE_args}) endfunction () #[==[.rst: .. cmake:command:: vtk_module_include Add include directories to a module |module| A wrapper around `target_include_directories` that works for modules. .. code-block:: cmake vtk_module_include( [SYSTEM] [PUBLIC ...] [PRIVATE ...] [INTERFACE ...]) #]==] function (vtk_module_include module) cmake_parse_arguments(PARSE_ARGV 1 _vtk_include "SYSTEM" "" "INTERFACE;PUBLIC;PRIVATE") if (_vtk_include_UNPARSED_ARGUMENTS) message(FATAL_ERROR "Unparsed arguments for vtk_module_include: " "${_vtk_include_UNPARSED_ARGUMENTS}.") endif () _vtk_module_real_target(_vtk_include_target "${module}") _vtk_module_target_function(_vtk_include) set(_vtk_include_system_arg) if (_vtk_include_SYSTEM) set(_vtk_include_system_arg SYSTEM) endif () if (NOT _vtk_include_INTERFACE_args AND NOT _vtk_include_PUBLIC_args AND NOT _vtk_include_PRIVATE_args) return () endif () target_include_directories("${_vtk_include_target}" ${_vtk_include_system_arg} ${_vtk_include_INTERFACE_args} ${_vtk_include_PUBLIC_args} ${_vtk_include_PRIVATE_args}) endfunction () #[==[.rst: .. cmake:command:: vtk_module_definitions Add compile definitions to a module. |module| A wrapper around ``target_compile_definitions`` that works for modules. .. code-block:: cmake vtk_module_definitions( [PUBLIC ...] [PRIVATE ...] [INTERFACE ...]) #]==] function (vtk_module_definitions module) cmake_parse_arguments(PARSE_ARGV 1 _vtk_definitions "" "" "INTERFACE;PUBLIC;PRIVATE") if (_vtk_definitions_UNPARSED_ARGUMENTS) message(FATAL_ERROR "Unparsed arguments for vtk_module_definitions: " "${_vtk_definitions_UNPARSED_ARGUMENTS}.") endif () _vtk_module_real_target(_vtk_definitions_target "${module}") _vtk_module_target_function(_vtk_definitions) if (NOT _vtk_definitions_INTERFACE_args AND NOT _vtk_definitions_PUBLIC_args AND NOT _vtk_definitions_PRIVATE_args) return () endif () target_compile_definitions("${_vtk_definitions_target}" ${_vtk_definitions_INTERFACE_args} ${_vtk_definitions_PUBLIC_args} ${_vtk_definitions_PRIVATE_args}) endfunction () #[==[.rst: .. cmake:command:: vtk_module_compile_options Add compile options to a module. |module| A wrapper around ``target_compile_options`` that works for modules. .. code-block:: cmake vtk_module_compile_options( [PUBLIC