Merge topic 'findgtk2-fix'
7e49b98219 FindGTK2: Find arch-specific headers via pkg-config
Acked-by: Kitware Robot <kwrobot@kitware.com>
Merge-request: !9417
diff --git a/.gitlab/ci/configure_fedora39_makefiles.cmake b/.gitlab/ci/configure_fedora39_makefiles.cmake
index 39fe642..4e18c83 100644
--- a/.gitlab/ci/configure_fedora39_makefiles.cmake
+++ b/.gitlab/ci/configure_fedora39_makefiles.cmake
@@ -48,6 +48,7 @@
set(CMake_TEST_FindICU "ON" CACHE BOOL "")
set(CMake_TEST_FindImageMagick "ON" CACHE BOOL "")
set(CMake_TEST_FindIntl "ON" CACHE BOOL "")
+set(CMake_TEST_FindJasper "ON" CACHE BOOL "")
set(CMake_TEST_FindJNI "ON" CACHE BOOL "")
set(CMake_TEST_FindJPEG "ON" CACHE BOOL "")
set(CMake_TEST_FindJsonCpp "ON" CACHE BOOL "")
diff --git a/.gitlab/ci/configure_windows_msvc_cxx_modules_common.cmake b/.gitlab/ci/configure_windows_msvc_cxx_modules_common.cmake
index e378d62..207f2a5 100644
--- a/.gitlab/ci/configure_windows_msvc_cxx_modules_common.cmake
+++ b/.gitlab/ci/configure_windows_msvc_cxx_modules_common.cmake
@@ -1 +1 @@
-set(CMake_TEST_MODULE_COMPILATION "named,compile_commands,collation,partitions,internal_partitions,shared,export_bmi,install_bmi,bmionly" CACHE STRING "")
+set(CMake_TEST_MODULE_COMPILATION "named,compile_commands,collation,partitions,internal_partitions,shared,export_bmi,install_bmi,bmionly,import_std23" CACHE STRING "")
diff --git a/.gitlab/ci/docker/fedora39/deps_packages.lst b/.gitlab/ci/docker/fedora39/deps_packages.lst
index e51a985..1459894 100644
--- a/.gitlab/ci/docker/fedora39/deps_packages.lst
+++ b/.gitlab/ci/docker/fedora39/deps_packages.lst
@@ -90,6 +90,7 @@
hdf5-mpich-devel
hdf5-openmpi-devel
ImageMagick-c++-devel
+jasper-devel
java-11-openjdk-devel
jsoncpp-devel
lapack-devel
diff --git a/.gitlab/os-linux.yml b/.gitlab/os-linux.yml
index e6e9773..dc32016 100644
--- a/.gitlab/os-linux.yml
+++ b/.gitlab/os-linux.yml
@@ -69,7 +69,7 @@
### Fedora
.fedora39:
- image: "kitware/cmake:ci-fedora39-x86_64-2024-03-04"
+ image: "kitware/cmake:ci-fedora39-x86_64-2024-04-10"
variables:
GIT_CLONE_PATH: "$CI_BUILDS_DIR/cmake ci/long file name for testing purposes"
diff --git a/Auxiliary/cmake-mode.el b/Auxiliary/cmake-mode.el
index b5e5ff4..cfa0173 100644
--- a/Auxiliary/cmake-mode.el
+++ b/Auxiliary/cmake-mode.el
@@ -1,4 +1,4 @@
-;;; cmake-mode.el --- major-mode for editing CMake sources
+;;; cmake-mode.el --- major-mode for editing CMake sources -*- lexical-binding: t; -*-
;; Package-Requires: ((emacs "24.1"))
@@ -480,7 +480,8 @@
;;;###autoload
(defun cmake-help ()
- "Queries for any of the four available help topics and prints out the appropriate page."
+ "Queries for any of the four available help topics and prints out the
+appropriate page."
(interactive)
(let* ((default-entry (cmake-symbol-at-point))
(command-list (cmake-get-list "command"))
diff --git a/Help/command/string.rst b/Help/command/string.rst
index 2f01653..6bd56a1 100644
--- a/Help/command/string.rst
+++ b/Help/command/string.rst
@@ -136,15 +136,16 @@
or ``\\`` for a literal backslash ``\``. Escaping a non-special
character is unnecessary but allowed, e.g. ``\a`` matches ``a``.
``[ ]``
- Matches any character(s) inside the brackets
+ Matches any character(s) inside the brackets.
+ To match a literal ``]``, make it the first character, e.g., ``[]ab]``.
``[^ ]``
- Matches any character(s) not inside the brackets
+ Matches any character(s) not inside the brackets.
+ To not match a literal ``]``, make it the first character, e.g., ``[^]ab]``.
``-``
- Inside brackets, specifies an inclusive range between
- characters on either side e.g. ``[a-f]`` is ``[abcdef]``
- To match a literal ``-`` using brackets, make it the first
- or the last character e.g. ``[+*/-]`` matches basic
- mathematical operators.
+ Inside brackets, specifies an inclusive range between characters on
+ either side, e.g., ``[a-f]`` is ``[abcdef]``.
+ To match a literal ``-`` using brackets, make it the first or the last
+ character, e.g., ``[+*/-]`` matches basic mathematical operators.
``*``
Matches preceding pattern zero or more times
``+``
diff --git a/Help/dev/experimental.rst b/Help/dev/experimental.rst
index fc4ac8b..93298c5 100644
--- a/Help/dev/experimental.rst
+++ b/Help/dev/experimental.rst
@@ -38,3 +38,24 @@
* The package name associated with specific targets may be specified
using the ``CMAKE_EXPORT_FIND_PACKAGE_NAME`` variable and/or
``EXPORT_FIND_PACKAGE_NAME`` target property.
+
+C++ ``import std`` support
+==========================
+
+In order to activate support for ``import std`` in C++23 and newer targets,
+set
+
+* variable ``CMAKE_EXPERIMENTAL_CXX_IMPORT_STD`` to
+* value ``0e5b6991-d74f-4b3d-a41c-cf096e0b2508``.
+
+This UUID may change in future versions of CMake. Be sure to use the value
+documented here by the source tree of the version of CMake with which you are
+experimenting.
+
+When activated, this experimental feature provides the following:
+
+* The :prop_tgt:`CXX_MODULE_STD` target property and its initializing variable
+ :variable:`CMAKE_CXX_MODULE_STD`.
+
+* Targets with the property set to a true value and at least ``cxx_std_23``
+ may use ``import std;`` in any scanned C++ source file.
diff --git a/Help/manual/cmake-cxxmodules.7.rst b/Help/manual/cmake-cxxmodules.7.rst
index 3ee6645..8f4ff44 100644
--- a/Help/manual/cmake-cxxmodules.7.rst
+++ b/Help/manual/cmake-cxxmodules.7.rst
@@ -12,6 +12,49 @@
scanning results to infer ordering constraints, and tells the build tool
how to dynamically update the build graph.
+Compilation Strategy
+====================
+
+With C++ modules, compiling a set of C++ sources is no longer embarrassingly
+parallel. That is, any given source may first require the compilation of
+another source file first in order to provide a "CMI" (compiled module
+interface) or "BMI" (binary module interface) that C++ compilers use to
+satisfy ``import`` statements in other sources. With headers, sources could
+share their declarations so that any consumers could compile independently.
+With modules, declarations are now generated into these BMI files by the
+compiler during compilation based on the contents of the source file and its
+``export`` statements.
+
+The order necessary for compilation requires build-time resolution of the
+ordering because the order is controlled by the contents of the sources. This
+means that the ordering needs extracted from the source during the build to
+avoid regenerating the build graph via a configure and generate phase for
+every source change to get a correct build.
+
+The general strategy is to use a "scanner" to extract the ordering dependency
+information and update the build graph with new edges between existing edges
+by taking the per-source scan results (represented by `P1689R5`_ files) and
+"collating" the dependencies within a target and to modules produced by
+targets visible to the target. The primary task is to generate "module map"
+files to pass to each compile rule with the paths to the BMIs needed to
+satisfy ``import`` statements. The collator also has tasks to use the
+build-time information to fill out information including ``install`` rules for
+the module interface units, their BMIs, and properties for any exported
+targets with C++ modules.
+
+.. _`P1689R5`: https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2022/p1689r5.html
+
+.. note:
+
+ CMake is focusing on correct builds before looking at performance
+ improvements. There are known tactics within the chosen strategy which may
+ offer build performance improvements. However, they are being deferred
+ until we have a working model against which to compare them. It is also
+ important to note that a tactic useful in one situation (e.g., clean
+ builds) may not be performant in a different situation (e.g., incremental
+ builds). Finding a balance and offering controls to select the tactics is
+ future work.
+
Scanning Control
================
@@ -43,6 +86,22 @@
* LLVM/Clang 16.0 and newer
* GCC 14 (for the in-development branch, after 2023-09-20) and newer
+``import std`` Support
+======================
+
+Support for ``import std`` is limited to the following toolchain and standard
+library combinations:
+
+* Clang 18.1.2 and newer with ``-stdlib=libc++``
+* MSVC toolset 14.36 and newer (provided with Visual Studio 17.6 Preview 2 and
+ newer)
+
+.. note ::
+
+ This support is provided only when experimental support for
+ ``import std;`` has been enabled by the
+ ``CMAKE_EXPERIMENTAL_CXX_IMPORT_STD`` gate.
+
Generator Support
=================
@@ -73,6 +132,7 @@
- Only Visual Studio 2022 and MSVC toolsets 14.34 (Visual Studio
17.4) and newer.
- No support for exporting or installing BMI or module information.
-- No support for compiling BMIs from ``IMPORTED`` targets with C++ modules.
+- No support for compiling BMIs from ``IMPORTED`` targets with C++ modules
+ (including ``import std``).
- No diagnosis of using modules provided by ``PRIVATE`` sources from
``PUBLIC`` module sources.
diff --git a/Help/manual/cmake-properties.7.rst b/Help/manual/cmake-properties.7.rst
index 8d2d202..6ccc23e 100644
--- a/Help/manual/cmake-properties.7.rst
+++ b/Help/manual/cmake-properties.7.rst
@@ -194,6 +194,7 @@
/prop_tgt/CXX_MODULE_SET
/prop_tgt/CXX_MODULE_SET_NAME
/prop_tgt/CXX_MODULE_SETS
+ /prop_tgt/CXX_MODULE_STD
/prop_tgt/CXX_SCAN_FOR_MODULES
/prop_tgt/CXX_STANDARD
/prop_tgt/CXX_STANDARD_REQUIRED
diff --git a/Help/manual/cmake-variables.7.rst b/Help/manual/cmake-variables.7.rst
index 4bb0ec8..6ae7d1c 100644
--- a/Help/manual/cmake-variables.7.rst
+++ b/Help/manual/cmake-variables.7.rst
@@ -424,6 +424,7 @@
/variable/CMAKE_CUDA_RESOLVE_DEVICE_SYMBOLS
/variable/CMAKE_CUDA_RUNTIME_LIBRARY
/variable/CMAKE_CUDA_SEPARABLE_COMPILATION
+ /variable/CMAKE_CXX_MODULE_STD
/variable/CMAKE_CXX_SCAN_FOR_MODULES
/variable/CMAKE_DEBUG_POSTFIX
/variable/CMAKE_DEFAULT_BUILD_TYPE
diff --git a/Help/prop_tgt/CXX_MODULE_STD.rst b/Help/prop_tgt/CXX_MODULE_STD.rst
new file mode 100644
index 0000000..d42699d
--- /dev/null
+++ b/Help/prop_tgt/CXX_MODULE_STD.rst
@@ -0,0 +1,41 @@
+CXX_MODULE_STD
+--------------
+
+.. versionadded:: 3.30
+
+``CXX_MODULE_STD`` is a boolean specifying whether the target may use
+``import std;`` its C++ sources or not.
+
+.. note ::
+
+ This setting is meaningful only when experimental support for ``import
+ std;`` has been enabled by the ``CMAKE_EXPERIMENTAL_CXX_IMPORT_STD`` gate.
+
+When this property is explicitly set to ``ON``, CMake will add a dependency to
+a target which provides the C++ standard library's modules for the C++
+standard applied to the target. This target is only applicable within the
+current build and will not appear in the exported interfaces of the targets.
+When consumed, these targets will be reapplied as necessary.
+
+.. note:
+
+ Similar to the introduction of :prop:`CXX_SCAN_FOR_MODULES`, this property
+ defaults to _not_ adding ``import std`` support to targets using
+ ``cxx_std_23`` without an explicit request in order to preserve existing
+ behavior for projects using C++23 without ``import std``. A future policy
+ to change the default behavior is expected once the feature sees wider
+ usage.
+
+This property's value is not relevant for targets which disable scanning (see
+:prop_tgt:`CXX_SCAN_FOR_MODULES`). Additionally, this property only applies to
+targets utilizing C++23 (``cxx_std_23``) or newer.
+
+The property supports
+:manual:`generator expressions <cmake-generator-expressions(7)>`, however
+expressions that depend upon the configuration, the consuming target, or the
+linker language are not allowed. Whether a target uses ``import std`` should
+not depend upon such things as it is a static property of the target's source
+code.
+
+Targets which are exported with C++ module sources will have this property's
+resolved value exported.
diff --git a/Help/release/3.29.rst b/Help/release/3.29.rst
index 36827cd..302bdf4 100644
--- a/Help/release/3.29.rst
+++ b/Help/release/3.29.rst
@@ -211,3 +211,10 @@
* The :variable:`CMAKE_LINKER_TYPE` variable and corresponding
:prop_tgt:`LINKER_TYPE` target property now work with compilers
for the ``Swift`` language.
+
+3.29.2
+------
+
+* This version made no changes to documented features or interfaces.
+ Some implementation updates were made to support ecosystem changes
+ and/or fix regressions.
diff --git a/Help/release/dev/CXX_MODULE_STD-property.rst b/Help/release/dev/CXX_MODULE_STD-property.rst
new file mode 100644
index 0000000..50febf4
--- /dev/null
+++ b/Help/release/dev/CXX_MODULE_STD-property.rst
@@ -0,0 +1,5 @@
+CXX_MODULE_STD-property
+-----------------------
+
+* The :prop_tgt:`CXX_MODULE_STD` property may be used to control
+ ``import std;`` support for targets.
diff --git a/Help/variable/CMAKE_CXX_MODULE_STD.rst b/Help/variable/CMAKE_CXX_MODULE_STD.rst
new file mode 100644
index 0000000..e2b27a0
--- /dev/null
+++ b/Help/variable/CMAKE_CXX_MODULE_STD.rst
@@ -0,0 +1,15 @@
+CMAKE_CXX_MODULE_STD
+--------------------
+
+.. versionadded:: 3.30
+
+Whether to add utility targets as dependencies to targets with at least
+``cxx_std_23`` or not.
+
+.. note ::
+
+ This setting is meaningful only when experimental support for ``import
+ std;`` has been enabled by the ``CMAKE_EXPERIMENTAL_CXX_IMPORT_STD`` gate.
+
+This variable is used to initialize the :prop_tgt:`CXX_MODULE_STD` property on
+all targets. See that target property for additional information.
diff --git a/Modules/CMakeCXXCompiler.cmake.in b/Modules/CMakeCXXCompiler.cmake.in
index d18e1c8..e0c5f8b 100644
--- a/Modules/CMakeCXXCompiler.cmake.in
+++ b/Modules/CMakeCXXCompiler.cmake.in
@@ -91,3 +91,5 @@
set(CMAKE_CXX_IMPLICIT_LINK_DIRECTORIES "@CMAKE_CXX_IMPLICIT_LINK_DIRECTORIES@")
set(CMAKE_CXX_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES "@CMAKE_CXX_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES@")
set(CMAKE_CXX_COMPILER_CLANG_RESOURCE_DIR "@CMAKE_CXX_COMPILER_CLANG_RESOURCE_DIR@")
+
+@CMAKE_CXX_IMPORT_STD@
diff --git a/Modules/CMakeDetermineCompilerId.cmake b/Modules/CMakeDetermineCompilerId.cmake
index e75018b..7fcfbdc 100644
--- a/Modules/CMakeDetermineCompilerId.cmake
+++ b/Modules/CMakeDetermineCompilerId.cmake
@@ -312,6 +312,29 @@
endif ()
endif ()
+ set(CMAKE_${lang}_STANDARD_LIBRARY "")
+ if ("x${lang}" STREQUAL "xCXX" AND
+ EXISTS "${CMAKE_CURRENT_FUNCTION_LIST_DIR}/${lang}-DetectStdlib.h" AND
+ "x${CMAKE_${lang}_COMPILER_ID}" STREQUAL "xClang" AND
+ "x${CMAKE_${lang}_COMPILER_FRONTEND_VARIANT}" STREQUAL "xGNU")
+ # See #20851 for a proper abstraction for this.
+ execute_process(
+ COMMAND "${CMAKE_${lang}_COMPILER}"
+ ${CMAKE_${lang}_COMPILER_ID_ARG1}
+ ${CMAKE_CXX_COMPILER_ID_FLAGS_LIST}
+ -E
+ -x c++-header
+ "${CMAKE_CURRENT_FUNCTION_LIST_DIR}/${lang}-DetectStdlib.h"
+ -o - # Write to stdout.
+ OUTPUT_VARIABLE _lang_stdlib_out
+ ERROR_VARIABLE _lang_stdlib_err
+ RESULT_VARIABLE _lang_stdlib_res
+ ERROR_STRIP_TRAILING_WHITESPACE)
+ if (_lang_stdlib_res EQUAL 0)
+ string(REGEX REPLACE ".*CMAKE-STDLIB-DETECT: (.+)\n.*" "\\1" "CMAKE_${lang}_STANDARD_LIBRARY" "${_lang_stdlib_out}")
+ endif ()
+ endif ()
+
# Display the final identification result.
if(CMAKE_${lang}_COMPILER_ID)
if(CMAKE_${lang}_COMPILER_VERSION)
@@ -355,6 +378,7 @@
set(CMAKE_${lang}_COMPILER_PRODUCED_OUTPUT "${COMPILER_${lang}_PRODUCED_OUTPUT}" PARENT_SCOPE)
set(CMAKE_${lang}_COMPILER_PRODUCED_FILES "${COMPILER_${lang}_PRODUCED_FILES}" PARENT_SCOPE)
set(CMAKE_${lang}_COMPILER_CLANG_RESOURCE_DIR "${CMAKE_${lang}_COMPILER_CLANG_RESOURCE_DIR}" PARENT_SCOPE)
+ set(CMAKE_${lang}_STANDARD_LIBRARY "${CMAKE_${lang}_STANDARD_LIBRARY}" PARENT_SCOPE)
endfunction()
include(CMakeCompilerIdDetection)
diff --git a/Modules/CMakeDetermineCompilerSupport.cmake b/Modules/CMakeDetermineCompilerSupport.cmake
index 746f04e..d561e7b 100644
--- a/Modules/CMakeDetermineCompilerSupport.cmake
+++ b/Modules/CMakeDetermineCompilerSupport.cmake
@@ -105,6 +105,19 @@
)
endif()
+ # Create targets for use with `import std;` here.
+ set(CMAKE_CXX_IMPORT_STD "")
+ foreach (_cmake_import_std_version IN ITEMS 23 26)
+ if (CMAKE_CXX${_cmake_import_std_version}_COMPILE_FEATURES)
+ set(_cmake_cxx_import_std "")
+ cmake_create_cxx_import_std("${_cmake_import_std_version}" _cmake_cxx_import_std)
+ if (_cmake_cxx_import_std)
+ string(APPEND CMAKE_CXX_IMPORT_STD "### Imported target for C++${_cmake_import_std_version} standard library\n")
+ string(APPEND CMAKE_CXX_IMPORT_STD "${_cmake_cxx_import_std}\n\n")
+ endif ()
+ endif ()
+ endforeach ()
+
set(CMAKE_CXX_COMPILE_FEATURES ${CMAKE_CXX_COMPILE_FEATURES} PARENT_SCOPE)
set(CMAKE_CXX98_COMPILE_FEATURES ${CMAKE_CXX98_COMPILE_FEATURES} PARENT_SCOPE)
set(CMAKE_CXX11_COMPILE_FEATURES ${CMAKE_CXX11_COMPILE_FEATURES} PARENT_SCOPE)
@@ -113,6 +126,7 @@
set(CMAKE_CXX20_COMPILE_FEATURES ${CMAKE_CXX20_COMPILE_FEATURES} PARENT_SCOPE)
set(CMAKE_CXX23_COMPILE_FEATURES ${CMAKE_CXX23_COMPILE_FEATURES} PARENT_SCOPE)
set(CMAKE_CXX26_COMPILE_FEATURES ${CMAKE_CXX26_COMPILE_FEATURES} PARENT_SCOPE)
+ set(CMAKE_CXX_IMPORT_STD ${CMAKE_CXX_IMPORT_STD} PARENT_SCOPE)
message(CHECK_PASS "done")
diff --git a/Modules/CMakePackageConfigHelpers.cmake b/Modules/CMakePackageConfigHelpers.cmake
index 8bd643e..dfe1ec7 100644
--- a/Modules/CMakePackageConfigHelpers.cmake
+++ b/Modules/CMakePackageConfigHelpers.cmake
@@ -377,24 +377,6 @@
write_basic_config_version_file(${ARGN})
endmacro()
-function(__CMAKE_get_config_file_package_prefix outvar)
- get_property(counter GLOBAL PROPERTY CMAKE_CONFIGURE_PACKAGE_CONFIG_FILE_COUNTER)
- if(NOT counter)
- set(counter 1)
- set_property(GLOBAL PROPERTY CMAKE_CONFIGURE_PACKAGE_CONFIG_FILE_COUNTER ${counter})
- endif()
- set(${outvar} "PACKAGE_\${CMAKE_FIND_PACKAGE_NAME}_COUNTER_${counter}" PARENT_SCOPE)
-endfunction()
-
-function(__CMAKE_increment_config_file_counter)
- get_property(counter GLOBAL PROPERTY CMAKE_CONFIGURE_PACKAGE_CONFIG_FILE_COUNTER)
- if(NOT counter)
- message(FATAL_ERROR "Internal error: global counter unexpectedly not set")
- endif()
- math(EXPR counter "${counter} + 1")
- set_property(GLOBAL PROPERTY CMAKE_CONFIGURE_PACKAGE_CONFIG_FILE_COUNTER ${counter})
-endfunction()
-
function(CONFIGURE_PACKAGE_CONFIG_FILE _inputFile _outputFile)
set(options NO_SET_AND_CHECK_MACRO NO_CHECK_REQUIRED_COMPONENTS_MACRO)
set(oneValueArgs INSTALL_DESTINATION INSTALL_PREFIX)
@@ -430,17 +412,15 @@
file(RELATIVE_PATH PACKAGE_RELATIVE_PATH "${absInstallDir}" "${installPrefix}" )
- __CMAKE_get_config_file_package_prefix(prefix_dir)
-
foreach(var ${CCF_PATH_VARS})
if(NOT DEFINED ${var})
message(FATAL_ERROR "Variable ${var} does not exist")
else()
if(IS_ABSOLUTE "${${var}}")
- string(REPLACE "${installPrefix}" "\${${prefix_dir}}"
+ string(REPLACE "${installPrefix}" "\${PACKAGE_PREFIX_DIR}"
PACKAGE_${var} "${${var}}")
else()
- set(PACKAGE_${var} "\${${prefix_dir}}/${${var}}")
+ set(PACKAGE_${var} "\${PACKAGE_PREFIX_DIR}/${${var}}")
endif()
endif()
endforeach()
@@ -452,7 +432,7 @@
####### Any changes to this file will be overwritten by the next CMake run ####
####### The input file was ${inputFileName} ########
-get_filename_component(${prefix_dir} \"\${CMAKE_CURRENT_LIST_DIR}/${PACKAGE_RELATIVE_PATH}\" ABSOLUTE)
+get_filename_component(PACKAGE_PREFIX_DIR \"\${CMAKE_CURRENT_LIST_DIR}/${PACKAGE_RELATIVE_PATH}\" ABSOLUTE)
")
if("${absInstallDir}" MATCHES "^(/usr)?/lib(64)?/.+")
@@ -463,7 +443,7 @@
get_filename_component(_realCurr \"\${CMAKE_CURRENT_LIST_DIR}\" REALPATH)
get_filename_component(_realOrig \"${absInstallDir}\" REALPATH)
if(_realCurr STREQUAL _realOrig)
- set(${prefix_dir} \"${installPrefix}\")
+ set(PACKAGE_PREFIX_DIR \"${installPrefix}\")
endif()
unset(_realOrig)
unset(_realCurr)
@@ -501,10 +481,6 @@
configure_file("${_inputFile}" "${_outputFile}" @ONLY)
- # We're done writing the file. Make sure the next one has a unique prefix dir
- # variable name (we may have multiple config files for the one package)
- __CMAKE_increment_config_file_counter()
-
endfunction()
function(generate_apple_platform_selection_file _output_file)
@@ -545,14 +521,12 @@
set(_branch_INIT "")
endif()
- __CMAKE_get_config_file_package_prefix(prefix_dir)
-
set(_else ELSE)
foreach(_opt IN LISTS _config_file_options _else)
if(_gpsf_${_opt})
set(_config_file "${_gpsf_${_opt}}")
if(NOT IS_ABSOLUTE "${_config_file}")
- string(PREPEND _config_file "\${${prefix_dir}}/")
+ string(PREPEND _config_file [[${PACKAGE_PREFIX_DIR}/]])
endif()
set(_branch_${_opt} "include(\"${_config_file}\")")
elseif(_gpsf_ERROR_VARIABLE)
@@ -626,13 +600,11 @@
"endif()\n"
)
- __CMAKE_get_config_file_package_prefix(prefix_dir)
-
foreach(pair IN ZIP_LISTS _gasf_SINGLE_ARCHITECTURES _gasf_SINGLE_ARCHITECTURE_INCLUDE_FILES)
set(arch "${pair_0}")
set(config_file "${pair_1}")
if(NOT IS_ABSOLUTE "${config_file}")
- string(PREPEND config_file "\${${prefix_dir}}/")
+ string(PREPEND config_file [[${PACKAGE_PREFIX_DIR}/]])
endif()
string(APPEND _branch_code
"\n"
@@ -647,7 +619,7 @@
string(JOIN " " universal_archs "${_gasf_UNIVERSAL_ARCHITECTURES}")
set(config_file "${_gasf_UNIVERSAL_INCLUDE_FILE}")
if(NOT IS_ABSOLUTE "${config_file}")
- string(PREPEND config_file "\${${prefix_dir}}/")
+ string(PREPEND config_file [[${PACKAGE_PREFIX_DIR}/]])
endif()
string(APPEND _branch_code
"\n"
diff --git a/Modules/CMakeSwiftInformation.cmake b/Modules/CMakeSwiftInformation.cmake
index 34ae751..60df6a2 100644
--- a/Modules/CMakeSwiftInformation.cmake
+++ b/Modules/CMakeSwiftInformation.cmake
@@ -138,7 +138,7 @@
endif()
if(NOT CMAKE_Swift_CREATE_SHARED_MODULE)
- set(CMAKE_Swift_CREATE_SHARED_MODULE ${CMAKE_Swift_CREATE_SHARED_LIBRARY})
+ set(CMAKE_Swift_CREATE_SHARED_MODULE "${CMAKE_Swift_CREATE_SHARED_LIBRARY} <CMAKE_SHARED_MODULE_CREATE_Swift_FLAGS>")
endif()
if(NOT CMAKE_Swift_LINK_EXECUTABLE)
@@ -162,7 +162,7 @@
endif()
if(NOT CMAKE_Swift_CREATE_SHARED_MODULE)
- set(CMAKE_Swift_CREATE_SHARED_MODULE ${CMAKE_Swift_CREATE_SHARED_LIBRARY})
+ set(CMAKE_Swift_CREATE_SHARED_MODULE "${CMAKE_Swift_CREATE_SHARED_LIBRARY} <CMAKE_SHARED_MODULE_CREATE_Swift_FLAGS>")
endif()
if(NOT CMAKE_Swift_LINK_EXECUTABLE)
diff --git a/Modules/CXX-DetectStdlib.h b/Modules/CXX-DetectStdlib.h
new file mode 100644
index 0000000..0214dee
--- /dev/null
+++ b/Modules/CXX-DetectStdlib.h
@@ -0,0 +1,10 @@
+#include <version>
+// clang-format off
+#if defined(_LIBCPP_VERSION)
+CMAKE-STDLIB-DETECT: libc++
+#elif defined(__GLIBCXX__)
+CMAKE-STDLIB-DETECT: libstdc++
+#else
+CMAKE-STDLIB-DETECT: UNKNOWN
+#endif
+ // clang-format on
diff --git a/Modules/Compiler/CMakeCommonCompilerMacros.cmake b/Modules/Compiler/CMakeCommonCompilerMacros.cmake
index 02c2b18..0b5df0d 100644
--- a/Modules/Compiler/CMakeCommonCompilerMacros.cmake
+++ b/Modules/Compiler/CMakeCommonCompilerMacros.cmake
@@ -201,3 +201,49 @@
_has_compiler_features_hip(11)
_has_compiler_features_hip(98)
endmacro()
+
+function(cmake_create_cxx_import_std std variable)
+ set(_cmake_supported_import_std_features
+ # Compilers support `import std` in C++20 as an extension. Skip
+ # for now.
+ # 20
+ 23
+ 26)
+ list(FIND _cmake_supported_import_std_features "${std}" _cmake_supported_import_std_idx)
+ if (_cmake_supported_import_std_idx EQUAL "-1")
+ return ()
+ endif ()
+ # If the target exists, skip. A toolchain file may have provided it.
+ if (TARGET "__CMAKE::CXX${std}")
+ return ()
+ endif ()
+ # The generator must support imported C++ modules.
+ if (NOT CMAKE_GENERATOR MATCHES "Ninja")
+ return ()
+ endif ()
+ # Check if the compiler understands how to `import std;`.
+ include("${CMAKE_ROOT}/Modules/Compiler/${CMAKE_CXX_COMPILER_ID}-CXX-CXXImportStd.cmake" OPTIONAL RESULT_VARIABLE _cmake_import_std_res)
+ if (NOT _cmake_import_std_res)
+ return ()
+ endif ()
+ if (NOT COMMAND _cmake_cxx_import_std)
+ return ()
+ endif ()
+
+ # Check the experimental flag. Check it here to avoid triggering warnings in
+ # situations that don't support the feature anyways.
+ set(_cmake_supported_import_std_experimental "")
+ cmake_language(GET_EXPERIMENTAL_FEATURE_ENABLED
+ "CxxImportStd"
+ _cmake_supported_import_std_experimental)
+ if (NOT _cmake_supported_import_std_experimental)
+ return ()
+ endif ()
+
+ _cmake_cxx_import_std("${std}" target_definition)
+ string(CONCAT guarded_target_definition
+ "if (NOT TARGET \"__CMAKE::CXX${std}\")\n"
+ "${target_definition}"
+ "endif ()\n")
+ set("${variable}" "${guarded_target_definition}" PARENT_SCOPE)
+endfunction()
diff --git a/Modules/Compiler/Clang-CXX-CXXImportStd.cmake b/Modules/Compiler/Clang-CXX-CXXImportStd.cmake
new file mode 100644
index 0000000..3934db9
--- /dev/null
+++ b/Modules/Compiler/Clang-CXX-CXXImportStd.cmake
@@ -0,0 +1,153 @@
+function (_cmake_cxx_import_std std variable)
+ if (NOT CMAKE_CXX_STANDARD_LIBRARY STREQUAL "libc++")
+ return ()
+ endif ()
+
+ execute_process(
+ COMMAND
+ "${CMAKE_CXX_COMPILER}"
+ ${CMAKE_CXX_COMPILER_ID_ARG1}
+ -print-file-name=libc++.modules.json
+ OUTPUT_VARIABLE _clang_libcxx_modules_json_file
+ ERROR_VARIABLE _clang_libcxx_modules_json_file_err
+ RESULT_VARIABLE _clang_libcxx_modules_json_file_res
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+ ERROR_STRIP_TRAILING_WHITESPACE)
+ if (_clang_libcxx_modules_json_file_res)
+ return ()
+ endif ()
+
+ # Without this file, we do not have modules installed.
+ if (NOT EXISTS "${_clang_libcxx_modules_json_file}")
+ return ()
+ endif ()
+
+ if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS "18.1.2")
+ # The original PR had a key spelling mismatch internally. Do not support it
+ # and instead require a release known to have the fix.
+ # https://github.com/llvm/llvm-project/pull/83036
+ return ()
+ endif ()
+
+ file(READ "${_clang_libcxx_modules_json_file}" _clang_libcxx_modules_json)
+ string(JSON _clang_modules_json_version GET "${_clang_libcxx_modules_json}" "version")
+ string(JSON _clang_modules_json_revision GET "${_clang_libcxx_modules_json}" "revision")
+ # Require version 1.
+ if (NOT _clang_modules_json_version EQUAL "1")
+ return ()
+ endif ()
+
+ string(JSON _clang_modules_json_nmodules LENGTH "${_clang_libcxx_modules_json}" "modules")
+ # Don't declare the target without any modules.
+ if (NOT _clang_modules_json_nmodules)
+ return ()
+ endif ()
+
+ # Declare the target.
+ set(_clang_libcxx_target "")
+ # Clang 18 does not provide the module initializer for the `std` modules.
+ # Create a static library to hold these. Hope that Clang 19 can provide this,
+ # but never run the code.
+ string(APPEND _clang_libcxx_target
+ "add_library(__cmake_cxx${std} STATIC)\n")
+ string(APPEND _clang_libcxx_target
+ "target_sources(__cmake_cxx${std} INTERFACE \"$<$<STREQUAL:$<TARGET_PROPERTY:TYPE>,STATIC_LIBRARY>:$<TARGET_OBJECTS:__cmake_cxx${std}>>\")\n")
+ string(APPEND _clang_libcxx_target
+ "set_property(TARGET __cmake_cxx${std} PROPERTY EXCLUDE_FROM_ALL 1)\n")
+ string(APPEND _clang_libcxx_target
+ "set_property(TARGET __cmake_cxx${std} PROPERTY CXX_SCAN_FOR_MODULES 1)\n")
+ string(APPEND _clang_libcxx_target
+ "set_property(TARGET __cmake_cxx${std} PROPERTY CXX_MODULE_STD 0)\n")
+ string(APPEND _clang_libcxx_target
+ "target_compile_features(__cmake_cxx${std} PUBLIC cxx_std_${std})\n")
+
+ set(_clang_modules_is_stdlib 0)
+ set(_clang_modules_include_dirs_list "")
+ set(_clang_modules_module_paths "")
+ get_filename_component(_clang_modules_dir "${_clang_libcxx_modules_json_file}" DIRECTORY)
+
+ # Add module sources.
+ math(EXPR _clang_modules_json_nmodules_range "${_clang_modules_json_nmodules} - 1")
+ foreach (_clang_modules_json_modules_idx RANGE 0 "${_clang_modules_json_nmodules_range}")
+ string(JSON _clang_modules_json_module GET "${_clang_libcxx_modules_json}" "modules" "${_clang_modules_json_modules_idx}")
+
+ string(JSON _clang_modules_json_module_source GET "${_clang_modules_json_module}" "source-path")
+ string(JSON _clang_modules_json_module_is_stdlib GET "${_clang_modules_json_module}" "is-std-library")
+ string(JSON _clang_modules_json_module_local_arguments GET "${_clang_modules_json_module}" "local-arguments")
+ string(JSON _clang_modules_json_module_nsystem_include_directories LENGTH "${_clang_modules_json_module_local_arguments}" "system-include-directories")
+
+ if (NOT IS_ABSOLUTE "${_clang_modules_json_module_source}")
+ string(PREPEND _clang_modules_json_module_source "${_clang_modules_dir}/")
+ endif ()
+ list(APPEND _clang_modules_module_paths
+ "${_clang_modules_json_module_source}")
+
+ if (_clang_modules_json_module_is_stdlib)
+ set(_clang_modules_is_stdlib 1)
+ endif ()
+
+ math(EXPR _clang_modules_json_module_nsystem_include_directories_range "${_clang_modules_json_module_nsystem_include_directories} - 1")
+ foreach (_clang_modules_json_modules_system_include_directories_idx RANGE 0 "${_clang_modules_json_module_nsystem_include_directories_range}")
+ string(JSON _clang_modules_json_module_system_include_directory GET "${_clang_modules_json_module_local_arguments}" "system-include-directories" "${_clang_modules_json_modules_system_include_directories_idx}")
+
+ if (NOT IS_ABSOLUTE "${_clang_modules_json_module_system_include_directory}")
+ string(PREPEND _clang_modules_json_module_system_include_directory "${_clang_modules_dir}/")
+ endif ()
+ list(APPEND _clang_modules_include_dirs_list
+ "${_clang_modules_json_module_system_include_directory}")
+ endforeach ()
+ endforeach ()
+
+ # Split the paths into basedirs and module paths.
+ set(_clang_modules_base_dirs_list "")
+ set(_clang_modules_files "")
+ foreach (_clang_modules_module_path IN LISTS _clang_modules_module_paths)
+ get_filename_component(_clang_module_dir "${_clang_modules_module_path}" DIRECTORY)
+
+ list(APPEND _clang_modules_base_dirs_list
+ "${_clang_module_dir}")
+ string(APPEND _clang_modules_files
+ " \"${_clang_modules_module_path}\"")
+ endforeach ()
+ list(REMOVE_DUPLICATES _clang_modules_base_dirs_list)
+ set(_clang_modules_base_dirs "")
+ foreach (_clang_modules_base_dir IN LISTS _clang_modules_base_dirs_list)
+ string(APPEND _clang_modules_base_dirs
+ " \"${_clang_modules_base_dir}\"")
+ endforeach ()
+
+ # If we have a standard library module, suppress warnings about reserved
+ # module names.
+ if (_clang_modules_is_stdlib)
+ string(APPEND _clang_libcxx_target
+ "target_compile_options(__cmake_cxx${std} PRIVATE -Wno-reserved-module-identifier)\n")
+ endif ()
+
+ # Set up include directories.
+ list(REMOVE_DUPLICATES _clang_modules_include_dirs_list)
+ set(_clang_modules_include_dirs "")
+ foreach (_clang_modules_include_dir IN LISTS _clang_modules_include_dirs_list)
+ string(APPEND _clang_modules_include_dirs
+ " \"${_clang_modules_include_dir}\"")
+ endforeach ()
+ string(APPEND _clang_libcxx_target
+ "target_include_directories(__cmake_cxx${std} PRIVATE ${_clang_modules_include_dirs})\n")
+
+ # Create the file set for the modules.
+ string(APPEND _clang_libcxx_target
+ "target_sources(__cmake_cxx${std}
+ PUBLIC
+ FILE_SET std TYPE CXX_MODULES
+ BASE_DIRS ${_clang_modules_base_dirs}
+ FILES ${_clang_modules_files})\n")
+
+ # Wrap the `__cmake_cxx${std}` target in a check.
+ string(PREPEND _clang_libcxx_target
+ "if (NOT TARGET \"__cmake_cxx${std}\")\n")
+ string(APPEND _clang_libcxx_target
+ "endif ()\n")
+ string(APPEND _clang_libcxx_target
+ "add_library(__CMAKE::CXX${std} ALIAS __cmake_cxx${std})\n")
+
+ set("${variable}" "${_clang_libcxx_target}" PARENT_SCOPE)
+endfunction ()
diff --git a/Modules/Compiler/MSVC-CXX-CXXImportStd.cmake b/Modules/Compiler/MSVC-CXX-CXXImportStd.cmake
new file mode 100644
index 0000000..9966b9b
--- /dev/null
+++ b/Modules/Compiler/MSVC-CXX-CXXImportStd.cmake
@@ -0,0 +1,102 @@
+function (_cmake_cxx_import_std std variable)
+ find_file(_msvc_modules_json_file
+ NAME modules.json
+ HINTS
+ "$ENV{VCToolsInstallDir}/modules"
+ PATHS
+ "$ENV{INCLUDE}"
+ "${CMAKE_CXX_COMPILER}/../../.."
+ PATH_SUFFIXES
+ ../modules
+ NO_CACHE)
+ # Without this file, we do not have modules installed.
+ if (NOT EXISTS "${_msvc_modules_json_file}")
+ return ()
+ endif ()
+
+ file(READ "${_msvc_modules_json_file}" _msvc_modules_json)
+ string(JSON _msvc_json_version GET "${_msvc_modules_json}" "version")
+ string(JSON _msvc_json_revision GET "${_msvc_modules_json}" "revision")
+ # Require version 1.
+ if (NOT _msvc_json_version EQUAL "1")
+ return ()
+ endif ()
+
+ string(JSON _msvc_json_library GET "${_msvc_modules_json}" "library")
+ # Bail if we don't understand the library.
+ if (NOT _msvc_json_library STREQUAL "microsoft/STL")
+ return ()
+ endif ()
+
+ string(JSON _msvc_json_nmodules LENGTH "${_msvc_modules_json}" "module-sources")
+ # Don't declare the target without any modules.
+ if (NOT _msvc_json_nmodules)
+ return ()
+ endif ()
+
+ # Declare the target.
+ set(_msvc_std_target "")
+ string(APPEND _msvc_std_target
+ "add_library(__cmake_cxx${std} STATIC)\n")
+ string(APPEND _msvc_std_target
+ "target_sources(__cmake_cxx${std} INTERFACE \"$<$<STREQUAL:$<TARGET_PROPERTY:TYPE>,STATIC_LIBRARY>:$<TARGET_OBJECTS:__cmake_cxx${std}>>\")\n")
+ string(APPEND _msvc_std_target
+ "set_property(TARGET __cmake_cxx${std} PROPERTY EXCLUDE_FROM_ALL 1)\n")
+ string(APPEND _msvc_std_target
+ "set_property(TARGET __cmake_cxx${std} PROPERTY CXX_SCAN_FOR_MODULES 1)\n")
+ string(APPEND _msvc_std_target
+ "set_property(TARGET __cmake_cxx${std} PROPERTY CXX_MODULE_STD 0)\n")
+ string(APPEND _msvc_std_target
+ "target_compile_features(__cmake_cxx${std} PUBLIC cxx_std_${std})\n")
+
+ set(_msvc_modules_module_paths "")
+ get_filename_component(_msvc_modules_dir "${_msvc_modules_json_file}" DIRECTORY)
+
+ # Add module sources.
+ math(EXPR _msvc_modules_json_nmodules_range "${_msvc_json_nmodules} - 1")
+ foreach (_msvc_modules_json_modules_idx RANGE 0 "${_msvc_modules_json_nmodules_range}")
+ string(JSON _msvc_modules_json_module_source GET "${_msvc_modules_json}" "module-sources" "${_msvc_modules_json_modules_idx}")
+
+ if (NOT IS_ABSOLUTE "${_msvc_modules_json_module_source}")
+ string(PREPEND _msvc_modules_json_module_source "${_msvc_modules_dir}/")
+ endif ()
+ list(APPEND _msvc_modules_module_paths
+ "${_msvc_modules_json_module_source}")
+ endforeach ()
+
+ # Split the paths into basedirs and module paths.
+ set(_msvc_modules_base_dirs_list "")
+ set(_msvc_modules_files "")
+ foreach (_msvc_modules_module_path IN LISTS _msvc_modules_module_paths)
+ get_filename_component(_msvc_module_dir "${_msvc_modules_module_path}" DIRECTORY)
+
+ list(APPEND _msvc_modules_base_dirs_list
+ "${_msvc_module_dir}")
+ string(APPEND _msvc_modules_files
+ " \"${_msvc_modules_module_path}\"")
+ endforeach ()
+ list(REMOVE_DUPLICATES _msvc_modules_base_dirs_list)
+ set(_msvc_modules_base_dirs "")
+ foreach (_msvc_modules_base_dir IN LISTS _msvc_modules_base_dirs_list)
+ string(APPEND _msvc_modules_base_dirs
+ " \"${_msvc_modules_base_dir}\"")
+ endforeach ()
+
+ # Create the file set for the modules.
+ string(APPEND _msvc_std_target
+ "target_sources(__cmake_cxx${std}
+ PUBLIC
+ FILE_SET std TYPE CXX_MODULES
+ BASE_DIRS ${_msvc_modules_base_dirs}
+ FILES ${_msvc_modules_files})\n")
+
+ # Wrap the `__cmake_cxx${std}` target in a check.
+ string(PREPEND _msvc_std_target
+ "if (NOT TARGET \"__cmake_cxx${std}\")\n")
+ string(APPEND _msvc_std_target
+ "endif ()\n")
+ string(APPEND _msvc_std_target
+ "add_library(__CMAKE::CXX${std} ALIAS __cmake_cxx${std})\n")
+
+ set("${variable}" "${_msvc_std_target}" PARENT_SCOPE)
+endfunction ()
diff --git a/Modules/FindJasper.cmake b/Modules/FindJasper.cmake
index 981bedc..79afcd5 100644
--- a/Modules/FindJasper.cmake
+++ b/Modules/FindJasper.cmake
@@ -77,14 +77,14 @@
endif()
if(EXISTS "${JASPER_LIBRARY_RELEASE}")
set_property(TARGET Jasper::Jasper APPEND PROPERTY
- IMPORTED CONFIGURATION RELEASE)
+ IMPORTED_CONFIGURATIONS RELEASE)
set_target_properties(Jasper::Jasper PROPERTIES
IMPORTED_LINK_INTERFACE_LANGUAGES_RELEASE "C"
IMPORTED_LOCATION "${JASPER_LIBRARY_RELEASE}")
endif()
if(EXISTS "${JASPER_LIBRARY_DEBUG}")
set_property(TARGET Jasper::Jasper APPEND PROPERTY
- IMPORTED CONFIGURATION DEBUG)
+ IMPORTED_CONFIGURATIONS DEBUG)
set_target_properties(Jasper::Jasper PROPERTIES
IMPORTED_LINK_INTERFACE_LANGUAGES_DEBUG "C"
IMPORTED_LOCATION "${JASPER_LIBRARY_DEBUG}")
diff --git a/Modules/Platform/AIX/ExportImportList b/Modules/Platform/AIX/ExportImportList
index 5e16fcb..7c269fd 100755
--- a/Modules/Platform/AIX/ExportImportList
+++ b/Modules/Platform/AIX/ExportImportList
@@ -63,7 +63,7 @@
V["EXPORTED"]=" export"
V["PROTECTED"]=" protected"
}
- /^\[[0-9]+\]\tm +[^ ]+ +\.(text|data|bss) +[^ ]+ +(extern|weak) +(EXPORTED|PROTECTED| ) / {
+ /^\[[0-9]+\]\tm +[^ ]+ +\.(text|data|tdata|bss) +[^ ]+ +(extern|weak) +(EXPORTED|PROTECTED| ) / {
if (!match($NF,/^(\.|__sinit|__sterm|__[0-9]+__)/)) {
print $NF V[$(NF-1)]
}
diff --git a/Modules/Platform/Apple-Apple-Swift.cmake b/Modules/Platform/Apple-Apple-Swift.cmake
index 237f6e4..9f27efa 100644
--- a/Modules/Platform/Apple-Apple-Swift.cmake
+++ b/Modules/Platform/Apple-Apple-Swift.cmake
@@ -7,8 +7,11 @@
set(CMAKE_Swift_USING_LINKER_APPLE_CLASSIC "-fuse-ld=ld" "LINKER:-ld_classic")
set(CMAKE_Swift_USING_LINKER_LLD "-fuse-ld=lld")
set(CMAKE_Swift_USING_LINKER_SYSTEM "-fuse-ld=ld")
+ set(CMAKE_SHARED_MODULE_LOADER_Swift_FLAG "-Wl,-bundle_loader,")
else()
set(CMAKE_Swift_USING_LINKER_APPLE_CLASSIC "-use-ld=ld" "LINKER:-ld_classic")
set(CMAKE_Swift_USING_LINKER_LLD "-use-ld=lld")
set(CMAKE_Swift_USING_LINKER_SYSTEM "-use-ld=ld")
+ set(CMAKE_SHARED_MODULE_LOADER_Swift_FLAG "-Xclang-linker -Wl,-bundle_loader,")
+ set(CMAKE_SHARED_MODULE_CREATE_Swift_FLAGS "-Xlinker -bundle")
endif()
diff --git a/Modules/Platform/Linux-Apple-Swift.cmake b/Modules/Platform/Linux-Apple-Swift.cmake
index 22f0554..248d2de 100644
--- a/Modules/Platform/Linux-Apple-Swift.cmake
+++ b/Modules/Platform/Linux-Apple-Swift.cmake
@@ -1,3 +1,5 @@
+set(CMAKE_EXE_EXPORTS_Swift_FLAG "-Xclang-linker -Wl,--export-dynamic")
+
# Linker Selection
# BFD is known to mislink Swift objects resulting in missing type info
set(CMAKE_Swift_USING_LINKER_SYSTEM "")
diff --git a/Modules/exportheader.cmake.in b/Modules/exportheader.cmake.in
index c518b3d..7659958 100644
--- a/Modules/exportheader.cmake.in
+++ b/Modules/exportheader.cmake.in
@@ -33,6 +33,7 @@
# define @DEPRECATED_MACRO_NAME@_NO_EXPORT @NO_EXPORT_MACRO_NAME@ @DEPRECATED_MACRO_NAME@
#endif
+/* NOLINTNEXTLINE(readability-avoid-unconditional-preprocessor-if) */
#if @DEFINE_NO_DEPRECATED@ /* DEFINE_NO_DEPRECATED */
# ifndef @NO_DEPRECATED_MACRO_NAME@
# define @NO_DEPRECATED_MACRO_NAME@
diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake
index 32497bd..226f3a0 100644
--- a/Source/CMakeVersion.cmake
+++ b/Source/CMakeVersion.cmake
@@ -1,7 +1,7 @@
# CMake version number components.
set(CMake_VERSION_MAJOR 3)
set(CMake_VERSION_MINOR 29)
-set(CMake_VERSION_PATCH 20240410)
+set(CMake_VERSION_PATCH 20240416)
#set(CMake_VERSION_RC 0)
set(CMake_VERSION_IS_DIRTY 0)
diff --git a/Source/Checks/cm_cxx_features.cmake b/Source/Checks/cm_cxx_features.cmake
index 0262746..02ebaa6 100644
--- a/Source/Checks/cm_cxx_features.cmake
+++ b/Source/Checks/cm_cxx_features.cmake
@@ -43,7 +43,7 @@
# Filter out MSVC output that looks like a command-line warning.
string(REGEX REPLACE "[^\n]*warning D[0-9][0-9][0-9][0-9][^\n]*" "" check_output "${check_output}")
# Filter out warnings caused by user flags.
- string(REGEX REPLACE "[^\n]*warning:[^\n]*-Winvalid-command-line-argument[^\n]*" "" check_output "${check_output}")
+ string(REGEX REPLACE "[^\n]*warning:[^\n]*-W(invalid|unused)-command-line-argument[^\n]*" "" check_output "${check_output}")
# Filter out warnings caused by local configuration.
string(REGEX REPLACE "[^\n]*warning:[^\n]*directory not found for option[^\n]*" "" check_output "${check_output}")
string(REGEX REPLACE "[^\n]*warning:[^\n]*object file compiled with -mlong-branch which is no longer needed[^\n]*" "" check_output "${check_output}")
diff --git a/Source/cmArgumentParserTypes.h b/Source/cmArgumentParserTypes.h
index 7daae09..3e0fae4 100644
--- a/Source/cmArgumentParserTypes.h
+++ b/Source/cmArgumentParserTypes.h
@@ -4,7 +4,7 @@
#include "cmConfigure.h" // IWYU pragma: keep
-#if defined(__SUNPRO_CC)
+#if defined(__SUNPRO_CC) || defined(__EDG__)
# include <string>
# include <vector>
diff --git a/Source/cmBinUtilsMacOSMachOLinker.cxx b/Source/cmBinUtilsMacOSMachOLinker.cxx
index 90e0891..7db7cb0 100644
--- a/Source/cmBinUtilsMacOSMachOLinker.cxx
+++ b/Source/cmBinUtilsMacOSMachOLinker.cxx
@@ -126,10 +126,16 @@
this->Archive->AddResolvedPath(filename, path, unique,
dep_file_info->rpaths);
- if (unique &&
- !this->ScanDependencies(path, dep_file_info->libs,
- dep_file_info->rpaths, executablePath)) {
- return false;
+ if (unique) {
+ std::vector<std::string> combinedParentRpaths =
+ dep_file_info->rpaths;
+ combinedParentRpaths.insert(combinedParentRpaths.end(),
+ rpaths.begin(), rpaths.end());
+ if (!this->ScanDependencies(path, dep_file_info->libs,
+ combinedParentRpaths,
+ executablePath)) {
+ return false;
+ }
}
}
} else {
diff --git a/Source/cmCMakeLanguageCommand.cxx b/Source/cmCMakeLanguageCommand.cxx
index 9ffc363..fe9257e 100644
--- a/Source/cmCMakeLanguageCommand.cxx
+++ b/Source/cmCMakeLanguageCommand.cxx
@@ -345,27 +345,18 @@
auto const& featureName = expandedArgs[1];
auto const& variableName = expandedArgs[2];
- auto feature = cmExperimental::Feature::Sentinel;
- for (std::size_t i = 0;
- i < static_cast<std::size_t>(cmExperimental::Feature::Sentinel); i++) {
- if (cmExperimental::DataForFeature(static_cast<cmExperimental::Feature>(i))
- .Name == featureName) {
- feature = static_cast<cmExperimental::Feature>(i);
- break;
+ if (auto feature = cmExperimental::FeatureByName(featureName)) {
+ if (cmExperimental::HasSupportEnabled(makefile, *feature)) {
+ makefile.AddDefinition(variableName, "TRUE");
+ } else {
+ makefile.AddDefinition(variableName, "FALSE");
}
- }
- if (feature == cmExperimental::Feature::Sentinel) {
+ } else {
return FatalError(status,
cmStrCat("Experimental feature name \"", featureName,
"\" does not exist."));
}
- if (cmExperimental::HasSupportEnabled(makefile, feature)) {
- makefile.AddDefinition(variableName, "TRUE");
- } else {
- makefile.AddDefinition(variableName, "FALSE");
- }
-
return true;
}
}
diff --git a/Source/cmExperimental.cxx b/Source/cmExperimental.cxx
index fb21f53..a2e6e70 100644
--- a/Source/cmExperimental.cxx
+++ b/Source/cmExperimental.cxx
@@ -37,6 +37,15 @@
{},
cmExperimental::TryCompileCondition::Always,
false },
+ // CxxImportStd
+ { "CxxImportStd",
+ "0e5b6991-d74f-4b3d-a41c-cf096e0b2508",
+ "CMAKE_EXPERIMENTAL_CXX_IMPORT_STD",
+ "CMake's support for `import std;` in C++23 and newer is experimental. It "
+ "is meant only for experimentation and feedback to CMake developers.",
+ {},
+ cmExperimental::TryCompileCondition::Always,
+ false },
};
static_assert(sizeof(LookupTable) / sizeof(LookupTable[0]) ==
static_cast<size_t>(cmExperimental::Feature::Sentinel),
@@ -54,6 +63,20 @@
return ::DataForFeature(f);
}
+cm::optional<cmExperimental::Feature> cmExperimental::FeatureByName(
+ std::string const& name)
+{
+ size_t idx = 0;
+ for (auto const& feature : LookupTable) {
+ if (feature.Name == name) {
+ return static_cast<Feature>(idx);
+ }
+ ++idx;
+ }
+
+ return {};
+}
+
bool cmExperimental::HasSupportEnabled(cmMakefile const& mf, Feature f)
{
bool enabled = false;
diff --git a/Source/cmExperimental.h b/Source/cmExperimental.h
index 5593c85..05764f9 100644
--- a/Source/cmExperimental.h
+++ b/Source/cmExperimental.h
@@ -8,6 +8,8 @@
#include <string>
#include <vector>
+#include <cm/optional>
+
class cmMakefile;
class cmExperimental
@@ -17,6 +19,7 @@
{
ExportPackageDependencies,
WindowsKernelModeDriver,
+ CxxImportStd,
Sentinel,
};
@@ -40,5 +43,6 @@
};
static const FeatureData& DataForFeature(Feature f);
+ static cm::optional<Feature> FeatureByName(std::string const& name);
static bool HasSupportEnabled(cmMakefile const& mf, Feature f);
};
diff --git a/Source/cmExportFileGenerator.cxx b/Source/cmExportFileGenerator.cxx
index 7867a8e..9bd7f49 100644
--- a/Source/cmExportFileGenerator.cxx
+++ b/Source/cmExportFileGenerator.cxx
@@ -1388,6 +1388,12 @@
os << ")\n\n";
}
+enum class ExportWhen
+{
+ Defined,
+ Always,
+};
+
enum class PropertyType
{
Strings,
@@ -1409,6 +1415,12 @@
}
}
+struct ModuleTargetPropertyTable
+{
+ cm::static_string_view Name;
+ ExportWhen Cond;
+};
+
struct ModulePropertyTable
{
cm::static_string_view Name;
@@ -1424,18 +1436,29 @@
return true;
}
- const cm::static_string_view exportedDirectModuleProperties[] = {
- "CXX_EXTENSIONS"_s,
+ const ModuleTargetPropertyTable exportedDirectModuleProperties[] = {
+ { "CXX_EXTENSIONS"_s, ExportWhen::Defined },
+ // Always define this property as it is an intrinsic property of the target
+ // and should not be inherited from the in-scope `CMAKE_CXX_MODULE_STD`
+ // variable.
+ //
+ // TODO(cxxmodules): A future policy may make this "ON" based on the target
+ // policies if unset. Add a new `ExportWhen` condition to handle it when
+ // this happens.
+ { "CXX_MODULE_STD"_s, ExportWhen::Always },
};
- for (auto const& propName : exportedDirectModuleProperties) {
- auto const propNameStr = std::string(propName);
- cmValue prop = gte->Target->GetComputedProperty(
+ for (auto const& prop : exportedDirectModuleProperties) {
+ auto const propNameStr = std::string(prop.Name);
+ cmValue propValue = gte->Target->GetComputedProperty(
propNameStr, *gte->Target->GetMakefile());
- if (!prop) {
- prop = gte->Target->GetProperty(propNameStr);
+ if (!propValue) {
+ propValue = gte->Target->GetProperty(propNameStr);
}
- if (prop) {
- properties[propNameStr] = cmGeneratorExpression::Preprocess(*prop, ctx);
+ if (propValue) {
+ properties[propNameStr] =
+ cmGeneratorExpression::Preprocess(*propValue, ctx);
+ } else if (prop.Cond == ExportWhen::Always) {
+ properties[propNameStr] = "";
}
}
diff --git a/Source/cmFileAPICodemodel.cxx b/Source/cmFileAPICodemodel.cxx
index e9302da..869b94a 100644
--- a/Source/cmFileAPICodemodel.cxx
+++ b/Source/cmFileAPICodemodel.cxx
@@ -685,6 +685,11 @@
continue;
}
+ // Ignore targets starting with `__cmake_` as they are internal.
+ if (cmHasLiteralPrefix(gt->GetName(), "__cmake_")) {
+ continue;
+ }
+
targets.append(this->DumpTarget(gt, targets.size()));
}
diff --git a/Source/cmGeneratorExpression.cxx b/Source/cmGeneratorExpression.cxx
index 04decd2..0b96c3f 100644
--- a/Source/cmGeneratorExpression.cxx
+++ b/Source/cmGeneratorExpression.cxx
@@ -70,13 +70,6 @@
currentTarget ? currentTarget : headTarget, this->EvaluateForBuildsystem,
this->Backtrace, language);
- return this->EvaluateWithContext(context, dagChecker);
-}
-
-const std::string& cmCompiledGeneratorExpression::EvaluateWithContext(
- cmGeneratorExpressionContext& context,
- cmGeneratorExpressionDAGChecker* dagChecker) const
-{
if (!this->NeedsEvaluation) {
return this->Input;
}
diff --git a/Source/cmGeneratorExpression.h b/Source/cmGeneratorExpression.h
index e22b8ab..71855c9 100644
--- a/Source/cmGeneratorExpression.h
+++ b/Source/cmGeneratorExpression.h
@@ -17,7 +17,6 @@
class cmake;
class cmCompiledGeneratorExpression;
class cmGeneratorTarget;
-struct cmGeneratorExpressionContext;
struct cmGeneratorExpressionDAGChecker;
struct cmGeneratorExpressionEvaluator;
@@ -151,10 +150,6 @@
std::map<std::string, std::string>& mapping);
private:
- const std::string& EvaluateWithContext(
- cmGeneratorExpressionContext& context,
- cmGeneratorExpressionDAGChecker* dagChecker) const;
-
cmCompiledGeneratorExpression(cmake& cmakeInstance,
cmListFileBacktrace backtrace,
std::string input);
diff --git a/Source/cmGeneratorExpressionDAGChecker.cxx b/Source/cmGeneratorExpressionDAGChecker.cxx
index da5785e..fda7ec3 100644
--- a/Source/cmGeneratorExpressionDAGChecker.cxx
+++ b/Source/cmGeneratorExpressionDAGChecker.cxx
@@ -37,16 +37,19 @@
, Content(content)
, Backtrace(std::move(backtrace))
{
- const auto* top = this->Top;
+ if (parent) {
+ this->TopIsTransitiveProperty = parent->TopIsTransitiveProperty;
+ } else {
+#define TEST_TRANSITIVE_PROPERTY_METHOD(METHOD) this->METHOD() ||
+ this->TopIsTransitiveProperty = (CM_FOR_EACH_TRANSITIVE_PROPERTY_METHOD(
+ TEST_TRANSITIVE_PROPERTY_METHOD) false); // NOLINT(*)
+#undef TEST_TRANSITIVE_PROPERTY_METHOD
+ }
+
this->CheckResult = this->CheckGraph();
-#define TEST_TRANSITIVE_PROPERTY_METHOD(METHOD) top->METHOD() ||
-
- if (this->CheckResult == DAG &&
- (CM_FOR_EACH_TRANSITIVE_PROPERTY_METHOD(
- TEST_TRANSITIVE_PROPERTY_METHOD) false)) // NOLINT(*)
-#undef TEST_TRANSITIVE_PROPERTY_METHOD
- {
+ if (this->CheckResult == DAG && this->EvaluatingTransitiveProperty()) {
+ const auto* top = this->Top;
auto it = top->Seen.find(this->Target);
if (it != top->Seen.end()) {
const std::set<std::string>& propSet = it->second;
@@ -139,14 +142,22 @@
return this->Top->CMP0131;
}
+bool cmGeneratorExpressionDAGChecker::EvaluatingTransitiveProperty() const
+{
+ return this->TopIsTransitiveProperty;
+}
+
bool cmGeneratorExpressionDAGChecker::EvaluatingGenexExpression() const
{
+ // Corresponds to GenexEvaluator::EvaluateExpression.
return cmHasLiteralPrefix(this->Property, "TARGET_GENEX_EVAL:") ||
cmHasLiteralPrefix(this->Property, "GENEX_EVAL:");
}
bool cmGeneratorExpressionDAGChecker::EvaluatingPICExpression() const
{
+ // Corresponds to checkInterfacePropertyCompatibility's special case
+ // that evaluates the value of POSITION_INDEPENDENT_CODE as a genex.
return this->Top->Property == "INTERFACE_POSITION_INDEPENDENT_CODE";
}
diff --git a/Source/cmGeneratorExpressionDAGChecker.h b/Source/cmGeneratorExpressionDAGChecker.h
index 2f88386..068ba6b 100644
--- a/Source/cmGeneratorExpressionDAGChecker.h
+++ b/Source/cmGeneratorExpressionDAGChecker.h
@@ -66,6 +66,7 @@
void ReportError(cmGeneratorExpressionContext* context,
const std::string& expr);
+ bool EvaluatingTransitiveProperty() const;
bool EvaluatingGenexExpression() const;
bool EvaluatingPICExpression() const;
bool EvaluatingCompileExpression() const;
@@ -109,4 +110,5 @@
Result CheckResult;
bool TransitivePropertiesOnly = false;
bool CMP0131 = false;
+ bool TopIsTransitiveProperty = false;
};
diff --git a/Source/cmGeneratorExpressionNode.cxx b/Source/cmGeneratorExpressionNode.cxx
index 4274448..0df086b 100644
--- a/Source/cmGeneratorExpressionNode.cxx
+++ b/Source/cmGeneratorExpressionNode.cxx
@@ -547,6 +547,7 @@
return expression;
}
+ // Replace the surrounding context with the named target.
cmGeneratorExpressionContext targetContext(
context->LG, context->Config, context->Quiet, target, target,
context->EvaluateForBuildsystem, context->Backtrace, context->Language);
@@ -2714,8 +2715,9 @@
target->GetLocalGenerator(), context->Config, context->Quiet, target,
target, context->EvaluateForBuildsystem, lib.Backtrace,
context->Language);
- std::string libResult =
- lib.Target->EvaluateInterfaceProperty(prop, &libContext, dagChecker);
+ std::string libResult = lib.Target->EvaluateInterfaceProperty(
+ prop, &libContext, dagChecker,
+ cmGeneratorTarget::LinkInterfaceFor::Usage);
if (!libResult.empty()) {
if (result.empty()) {
result = std::move(libResult);
@@ -2896,6 +2898,9 @@
bool evaluatingLinkLibraries = false;
if (dagCheckerParent) {
+ // This $<TARGET_PROPERTY:...> node has been reached while evaluating
+ // another target property value. Check that the outermost evaluation
+ // expects such nested evaluations.
if (dagCheckerParent->EvaluatingGenexExpression() ||
dagCheckerParent->EvaluatingPICExpression() ||
dagCheckerParent->EvaluatingLinkerLauncher()) {
@@ -2911,17 +2916,16 @@
return std::string();
}
} else {
-#define ASSERT_TRANSITIVE_PROPERTY_METHOD(METHOD) dagCheckerParent->METHOD() ||
- assert(CM_FOR_EACH_TRANSITIVE_PROPERTY_METHOD(
- ASSERT_TRANSITIVE_PROPERTY_METHOD) false); // NOLINT(clang-tidy)
-#undef ASSERT_TRANSITIVE_PROPERTY_METHOD
+ assert(dagCheckerParent
+ ->EvaluatingTransitiveProperty()); // NOLINT(clang-tidy)
}
}
if (isInterfaceProperty) {
return cmGeneratorExpression::StripEmptyListElements(
- target->EvaluateInterfaceProperty(propertyName, context,
- dagCheckerParent));
+ target->EvaluateInterfaceProperty(
+ propertyName, context, dagCheckerParent,
+ cmGeneratorTarget::LinkInterfaceFor::Usage));
}
cmGeneratorExpressionDAGChecker dagChecker(
@@ -2950,8 +2954,20 @@
return std::string();
}
- if (!haveProp && !target->IsImported() &&
- target->GetType() != cmStateEnums::INTERFACE_LIBRARY) {
+ // Properties named by COMPATIBLE_INTERFACE_ properties combine over
+ // the transitive link closure as a single order-independent value.
+ // Imported targets do not themselves have a defined value for these
+ // properties, but they can contribute to the value of a non-imported
+ // dependent.
+ //
+ // For COMPATIBLE_INTERFACE_{BOOL,STRING}:
+ // * If set on this target, use the value directly. It is checked
+ // elsewhere for consistency over the transitive link closure.
+ // * If not set on this target, compute the value from the closure.
+ //
+ // For COMPATIBLE_INTERFACE_NUMBER_{MAX,MIN} we always compute the value
+ // from this target and the transitive link closure to get the max or min.
+ if (!haveProp && !target->IsImported()) {
if (target->IsLinkInterfaceDependentBoolProperty(propertyName,
context->Config)) {
context->HadContextSensitiveCondition = true;
@@ -2968,6 +2984,8 @@
context->Config);
return propContent ? propContent : "";
}
+ }
+ if (!evaluatingLinkLibraries && !target->IsImported()) {
if (target->IsLinkInterfaceDependentNumberMinProperty(propertyName,
context->Config)) {
context->HadContextSensitiveCondition = true;
@@ -2986,26 +3004,8 @@
}
}
- if (!target->IsImported() && dagCheckerParent &&
- !dagCheckerParent->EvaluatingLinkLibraries()) {
- if (target->IsLinkInterfaceDependentNumberMinProperty(propertyName,
- context->Config)) {
- context->HadContextSensitiveCondition = true;
- const char* propContent =
- target->GetLinkInterfaceDependentNumberMinProperty(propertyName,
- context->Config);
- return propContent ? propContent : "";
- }
- if (target->IsLinkInterfaceDependentNumberMaxProperty(propertyName,
- context->Config)) {
- context->HadContextSensitiveCondition = true;
- const char* propContent =
- target->GetLinkInterfaceDependentNumberMaxProperty(propertyName,
- context->Config);
- return propContent ? propContent : "";
- }
- }
-
+ // Some properties, such as usage requirements, combine over the
+ // transitive link closure as an ordered list.
if (!interfacePropertyName.empty()) {
result = cmGeneratorExpression::StripEmptyListElements(
this->EvaluateDependentExpression(result, context->LG, context, target,
diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx
index 2ec1a29..d6560d0 100644
--- a/Source/cmGeneratorTarget.cxx
+++ b/Source/cmGeneratorTarget.cxx
@@ -32,6 +32,7 @@
#include "cmCustomCommandGenerator.h"
#include "cmCxxModuleUsageEffects.h"
#include "cmEvaluatedTargetProperty.h"
+#include "cmExperimental.h"
#include "cmFileSet.h"
#include "cmFileTimes.h"
#include "cmGeneratedFileStream.h"
@@ -6375,6 +6376,7 @@
std::string interfaceProperty = "INTERFACE_" + p;
std::unique_ptr<cmGeneratorExpressionInterpreter> genexInterpreter;
if (p == "POSITION_INDEPENDENT_CODE") {
+ // Corresponds to EvaluatingPICExpression.
genexInterpreter = cm::make_unique<cmGeneratorExpressionInterpreter>(
tgt->GetLocalGenerator(), config, tgt);
}
@@ -8411,9 +8413,119 @@
}
}
+bool cmGeneratorTarget::ApplyCXXStdTargets()
+{
+ cmStandardLevelResolver standardResolver(this->Makefile);
+ cmStandardLevel const cxxStd23 =
+ *standardResolver.LanguageStandardLevel("CXX", "23");
+ std::vector<std::string> const& configs =
+ this->Makefile->GetGeneratorConfigs(cmMakefile::IncludeEmptyConfig);
+ auto std_prop = this->GetProperty("CXX_MODULE_STD");
+ if (!std_prop) {
+ // TODO(cxxmodules): Add a target policy to flip the default here. Set
+ // `std_prop` based on it.
+ return true;
+ }
+
+ std::string std_prop_value;
+ if (std_prop) {
+ // Evaluate generator expressions.
+ cmGeneratorExpression ge(*this->LocalGenerator->GetCMakeInstance());
+ auto cge = ge.Parse(*std_prop);
+ if (!cge) {
+ this->Makefile->IssueMessage(
+ MessageType::FATAL_ERROR,
+ cmStrCat(R"(The "CXX_MODULE_STD" property on the target ")",
+ this->GetName(), "\" is not a valid generator expression."));
+ return false;
+ }
+ // But do not allow context-sensitive queries. Whether a target uses
+ // `import std` should not depend on configuration or properties of the
+ // consumer (head target). The link language also shouldn't matter, so ban
+ // it as well.
+ if (cge->GetHadHeadSensitiveCondition()) {
+ // Not reachable; all target-sensitive genexes actually fail to parse.
+ this->Makefile->IssueMessage(
+ MessageType::FATAL_ERROR,
+ cmStrCat(R"(The "CXX_MODULE_STD" property on the target ")",
+ this->GetName(),
+ "\" contains a condition that queries the "
+ "consuming target which is not supported."));
+ return false;
+ }
+ if (cge->GetHadLinkLanguageSensitiveCondition()) {
+ // Not reachable; all link language genexes actually fail to parse.
+ this->Makefile->IssueMessage(
+ MessageType::FATAL_ERROR,
+ cmStrCat(R"(The "CXX_MODULE_STD" property on the target ")",
+ this->GetName(),
+ "\" contains a condition that queries the "
+ "link language which is not supported."));
+ return false;
+ }
+ std_prop_value = cge->Evaluate(this->LocalGenerator, "");
+ if (cge->GetHadContextSensitiveCondition()) {
+ this->Makefile->IssueMessage(
+ MessageType::FATAL_ERROR,
+ cmStrCat(R"(The "CXX_MODULE_STD" property on the target ")",
+ this->GetName(),
+ "\" contains a context-sensitive condition "
+ "that is not supported."));
+ return false;
+ }
+ }
+ auto use_std = cmIsOn(std_prop_value);
+
+ // If we have a value and it is not true, there's nothing to do.
+ if (std_prop && !use_std) {
+ return true;
+ }
+
+ for (auto const& config : configs) {
+ if (this->HaveCxxModuleSupport(config) != Cxx20SupportLevel::Supported) {
+ continue;
+ }
+
+ cm::optional<cmStandardLevel> explicitLevel =
+ this->GetExplicitStandardLevel("CXX", config);
+ if (!explicitLevel || *explicitLevel < cxxStd23) {
+ continue;
+ }
+
+ auto const targetName = cmStrCat(
+ "__CMAKE::CXX", standardResolver.GetLevelString("CXX", *explicitLevel));
+ if (!this->Makefile->FindTargetToUse(targetName)) {
+ this->Makefile->IssueMessage(
+ MessageType::FATAL_ERROR,
+ cmStrCat(
+ R"(The "CXX_MODULE_STD" property on the target ")", this->GetName(),
+ "\" requires that the \"", targetName,
+ "\" target exist, but it was not provided by the toolchain."));
+ break;
+ }
+
+ // Check the experimental feature here as well. A toolchain may have
+ // provided the target and skipped the check in the toolchain preparation
+ // logic.
+ if (!cmExperimental::HasSupportEnabled(
+ *this->Makefile, cmExperimental::Feature::CxxImportStd)) {
+ break;
+ }
+
+ this->Target->AppendProperty(
+ "LINK_LIBRARIES",
+ cmStrCat("$<BUILD_LOCAL_INTERFACE:$<$<CONFIG:", config, ">:", targetName,
+ ">>"));
+ }
+
+ return true;
+}
+
bool cmGeneratorTarget::DiscoverSyntheticTargets(cmSyntheticTargetCache& cache,
std::string const& config)
{
+ std::vector<std::string> allConfigs =
+ this->Makefile->GetGeneratorConfigs(cmMakefile::IncludeEmptyConfig);
cmOptionalLinkImplementation impl;
this->ComputeLinkImplementationLibraries(config, impl, this,
LinkInterfaceFor::Link);
@@ -8488,9 +8600,22 @@
// Create the generator target and attach it to the local generator.
auto gtp = cm::make_unique<cmGeneratorTarget>(tgt, lg);
+
synthDep = gtp.get();
cache.CxxModuleTargets[targetName] = synthDep;
+
+ // See `localGen->ComputeTargetCompileFeatures()` call in
+ // `cmGlobalGenerator::Compute` for where non-synthetic targets resolve
+ // this.
+ for (auto const& innerConfig : allConfigs) {
+ gtp->ComputeCompileFeatures(innerConfig);
+ }
+ // See `cmGlobalGenerator::ApplyCXXStdTargets` in
+ // `cmGlobalGenerator::Compute` for non-synthetic target resolutions.
+ gtp->ApplyCXXStdTargets();
+
gtp->DiscoverSyntheticTargets(cache, config);
+
lg->AddGeneratorTarget(std::move(gtp));
} else {
synthDep = cached->second;
diff --git a/Source/cmGeneratorTarget.h b/Source/cmGeneratorTarget.h
index fd4b2ec..fbc71e5 100644
--- a/Source/cmGeneratorTarget.h
+++ b/Source/cmGeneratorTarget.h
@@ -883,7 +883,7 @@
std::string EvaluateInterfaceProperty(
std::string const& prop, cmGeneratorExpressionContext* context,
cmGeneratorExpressionDAGChecker* dagCheckerParent,
- LinkInterfaceFor interfaceFor = LinkInterfaceFor::Usage) const;
+ LinkInterfaceFor interfaceFor) const;
bool HaveInstallTreeRPATH(const std::string& config) const;
@@ -961,6 +961,7 @@
std::string GetImportedXcFrameworkPath(const std::string& config) const;
+ bool ApplyCXXStdTargets();
bool DiscoverSyntheticTargets(cmSyntheticTargetCache& cache,
std::string const& config);
diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx
index 818b1a0..e397fa2 100644
--- a/Source/cmGlobalGenerator.cxx
+++ b/Source/cmGlobalGenerator.cxx
@@ -28,6 +28,7 @@
#include "cm_codecvt_Encoding.hxx"
#include "cmAlgorithms.h"
+#include "cmCMakePath.h"
#include "cmCPackPropertiesGenerator.h"
#include "cmComputeTargetDepends.h"
#include "cmCryptoHash.h"
@@ -270,17 +271,14 @@
std::string changeVars;
if (cname && !optional) {
- std::string cnameString;
+ cmCMakePath cachedPath;
if (!cmSystemTools::FileIsFullPath(*cname)) {
- cnameString = cmSystemTools::FindProgram(*cname);
+ cachedPath = cmSystemTools::FindProgram(*cname);
} else {
- cnameString = *cname;
+ cachedPath = *cname;
}
- std::string pathString = path;
- // get rid of potentially multiple slashes:
- cmSystemTools::ConvertToUnixSlashes(cnameString);
- cmSystemTools::ConvertToUnixSlashes(pathString);
- if (cnameString != pathString) {
+ cmCMakePath foundPath = path;
+ if (foundPath.Normal() != cachedPath.Normal()) {
cmValue cvars = this->GetCMakeInstance()->GetState()->GetGlobalProperty(
"__CMAKE_DELETE_CACHE_CHANGE_VARS_");
if (cvars) {
@@ -1583,6 +1581,29 @@
}
#endif
+ // Perform up-front computation in order to handle errors (such as unknown
+ // features) at this point. While processing the compile features we also
+ // calculate and cache the language standard required by the compile
+ // features.
+ //
+ // Synthetic targets performed this inside of
+ // `cmLocalGenerator::DiscoverSyntheticTargets`
+ for (const auto& localGen : this->LocalGenerators) {
+ if (!localGen->ComputeTargetCompileFeatures()) {
+ return false;
+ }
+ }
+
+ // We now have all targets set up and std levels constructed. Add
+ // `__CMAKE::CXX*` targets as link dependencies to all targets which need
+ // them.
+ //
+ // Synthetic targets performed this inside of
+ // `cmLocalGenerator::DiscoverSyntheticTargets`
+ if (!this->ApplyCXXStdTargets()) {
+ return false;
+ }
+
// Iterate through all targets and set up C++20 module targets.
// Create target templates for each imported target with C++20 modules.
// INTERFACE library with BMI-generating rules and a collation step?
@@ -1590,6 +1611,9 @@
// Make `add_dependencies(imported_target
// $<$<TARGET_NAME_IF_EXISTS:uses_imported>:synth1>
// $<$<TARGET_NAME_IF_EXISTS:other_uses_imported>:synth2>)`
+ //
+ // Note that synthetic target creation performs the above marked
+ // steps on the created targets.
if (!this->DiscoverSyntheticTargets()) {
return false;
}
@@ -1599,16 +1623,6 @@
localGen->AddHelperCommands();
}
- // Perform up-front computation in order to handle errors (such as unknown
- // features) at this point. While processing the compile features we also
- // calculate and cache the language standard required by the compile
- // features.
- for (const auto& localGen : this->LocalGenerators) {
- if (!localGen->ComputeTargetCompileFeatures()) {
- return false;
- }
- }
-
// Add automatically generated sources (e.g. unity build).
// Add unity sources after computing compile features. Unity sources do
// not change the set of languages or features, but we need to know them
@@ -1826,6 +1840,19 @@
entry->second = index++;
}
+bool cmGlobalGenerator::ApplyCXXStdTargets()
+{
+ for (auto const& gen : this->LocalGenerators) {
+ for (auto const& tgt : gen->GetGeneratorTargets()) {
+ if (!tgt->ApplyCXXStdTargets()) {
+ return false;
+ }
+ }
+ }
+
+ return true;
+}
+
bool cmGlobalGenerator::DiscoverSyntheticTargets()
{
cmSyntheticTargetCache cache;
diff --git a/Source/cmGlobalGenerator.h b/Source/cmGlobalGenerator.h
index ba39768..1ca02d9 100644
--- a/Source/cmGlobalGenerator.h
+++ b/Source/cmGlobalGenerator.h
@@ -674,6 +674,7 @@
virtual bool CheckALLOW_DUPLICATE_CUSTOM_TARGETS() const;
+ bool ApplyCXXStdTargets();
bool DiscoverSyntheticTargets();
bool AddHeaderSetVerification();
diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx
index 8462a1a..7dd5ffa 100644
--- a/Source/cmGlobalXCodeGenerator.cxx
+++ b/Source/cmGlobalXCodeGenerator.cxx
@@ -3115,8 +3115,12 @@
"shellScript", this->CreateString("# shell script goes here\nexit 0"));
shellBuildPhase->AddAttribute("showEnvVarsInLog", this->CreateString("0"));
- cmXCodeObject* target =
- this->CreateObject(cmXCodeObject::PBXAggregateTarget);
+ std::string targetBinaryPath = cmStrCat(
+ gtgt->Makefile->GetCurrentBinaryDirectory(), '/', gtgt->GetName());
+
+ cmXCodeObject* target = this->CreateObject(
+ cmXCodeObject::PBXAggregateTarget,
+ cmStrCat("PBXAggregateTarget:", gtgt->GetName(), ":", targetBinaryPath));
target->SetComment(gtgt->GetName());
cmXCodeObject* buildPhases = this->CreateObject(cmXCodeObject::OBJECT_LIST);
std::vector<cmXCodeObject*> emptyContentVector;
@@ -3340,7 +3344,14 @@
if (!gtgt->IsInBuildSystem()) {
return nullptr;
}
- cmXCodeObject* target = this->CreateObject(cmXCodeObject::PBXNativeTarget);
+
+ std::string targetBinaryPath = this->RelativeToRootBinary(cmStrCat(
+ gtgt->Makefile->GetCurrentBinaryDirectory(), '/', gtgt->GetName()));
+
+ cmXCodeObject* target = this->CreateObject(
+ cmXCodeObject::PBXNativeTarget,
+ cmStrCat("PBXNativeTarget:", gtgt->GetName(), ":", targetBinaryPath));
+
target->AddAttribute("buildPhases", buildPhases);
cmXCodeObject* buildRules = this->CreateObject(cmXCodeObject::OBJECT_LIST);
target->AddAttribute("buildRules", buildRules);
@@ -5130,6 +5141,17 @@
return p;
}
+std::string cmGlobalXCodeGenerator::RelativeToRootBinary(const std::string& p)
+{
+ std::string binaryDirectory =
+ this->CurrentRootGenerator->GetCurrentBinaryDirectory();
+ if (cmSystemTools::IsSubDirectory(p, binaryDirectory)) {
+ binaryDirectory = cmSystemTools::ForceToRelativePath(binaryDirectory, p);
+ }
+
+ return binaryDirectory;
+}
+
std::string cmGlobalXCodeGenerator::RelativeToBinary(const std::string& p)
{
return this->CurrentRootGenerator->MaybeRelativeToCurBinDir(p);
diff --git a/Source/cmGlobalXCodeGenerator.h b/Source/cmGlobalXCodeGenerator.h
index 12a5cad..2375e95 100644
--- a/Source/cmGlobalXCodeGenerator.h
+++ b/Source/cmGlobalXCodeGenerator.h
@@ -161,6 +161,7 @@
bool CreateGroups(std::vector<cmLocalGenerator*>& generators);
std::string XCodeEscapePath(const std::string& p);
std::string RelativeToSource(const std::string& p);
+ std::string RelativeToRootBinary(const std::string& p);
std::string RelativeToBinary(const std::string& p);
std::string ConvertToRelativeForMake(std::string const& p);
void CreateCustomCommands(
diff --git a/Source/cmGraphVizWriter.cxx b/Source/cmGraphVizWriter.cxx
index a8a7abb..6c3afef 100644
--- a/Source/cmGraphVizWriter.cxx
+++ b/Source/cmGraphVizWriter.cxx
@@ -284,7 +284,8 @@
// Reserved targets have inconsistent names across platforms (e.g. 'all'
// vs. 'ALL_BUILD'), which can disrupt the traversal ordering.
// We don't need or want them anyway.
- if (!cmGlobalGenerator::IsReservedTarget(gt->GetName())) {
+ if (!cmGlobalGenerator::IsReservedTarget(gt->GetName()) &&
+ !cmHasLiteralPrefix(gt->GetName(), "__cmake_")) {
sortedGeneratorTargets.insert(gt.get());
}
}
diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx
index d8f56d1..c943591 100644
--- a/Source/cmLocalGenerator.cxx
+++ b/Source/cmLocalGenerator.cxx
@@ -1478,7 +1478,7 @@
CM_FALLTHROUGH;
case cmStateEnums::SHARED_LIBRARY: {
std::string sharedLibFlags;
- if (linkLanguage != "Swift") {
+ if (this->IsSplitSwiftBuild() || linkLanguage != "Swift") {
sharedLibFlags = cmStrCat(
this->Makefile->GetSafeDefinition(libraryLinkVariable), ' ');
if (!configUpper.empty()) {
@@ -1521,6 +1521,13 @@
} break;
case cmStateEnums::EXECUTABLE: {
std::string exeFlags;
+ if (linkLanguage.empty()) {
+ cmSystemTools::Error(
+ "CMake can not determine linker language for target: " +
+ target->GetName());
+ return;
+ }
+
if (linkLanguage != "Swift") {
exeFlags = this->Makefile->GetSafeDefinition("CMAKE_EXE_LINKER_FLAGS");
exeFlags += " ";
@@ -1529,28 +1536,22 @@
cmStrCat("CMAKE_EXE_LINKER_FLAGS_", configUpper));
exeFlags += " ";
}
- if (linkLanguage.empty()) {
- cmSystemTools::Error(
- "CMake can not determine linker language for target: " +
- target->GetName());
- return;
- }
+ }
- if (target->IsWin32Executable(config)) {
- exeFlags += this->Makefile->GetSafeDefinition(
- cmStrCat("CMAKE_", linkLanguage, "_CREATE_WIN32_EXE"));
- exeFlags += " ";
- } else {
- exeFlags += this->Makefile->GetSafeDefinition(
- cmStrCat("CMAKE_", linkLanguage, "_CREATE_CONSOLE_EXE"));
- exeFlags += " ";
- }
+ if (target->IsWin32Executable(config)) {
+ exeFlags += this->Makefile->GetSafeDefinition(
+ cmStrCat("CMAKE_", linkLanguage, "_CREATE_WIN32_EXE"));
+ exeFlags += " ";
+ } else {
+ exeFlags += this->Makefile->GetSafeDefinition(
+ cmStrCat("CMAKE_", linkLanguage, "_CREATE_CONSOLE_EXE"));
+ exeFlags += " ";
+ }
- if (target->IsExecutableWithExports()) {
- exeFlags += this->Makefile->GetSafeDefinition(
- cmStrCat("CMAKE_EXE_EXPORTS_", linkLanguage, "_FLAG"));
- exeFlags += " ";
- }
+ if (target->IsExecutableWithExports()) {
+ exeFlags += this->Makefile->GetSafeDefinition(
+ cmStrCat("CMAKE_EXE_EXPORTS_", linkLanguage, "_FLAG"));
+ exeFlags += " ";
}
this->AddLanguageFlagsForLinking(flags, target, linkLanguage, config);
diff --git a/Source/cmStandardLevelResolver.cxx b/Source/cmStandardLevelResolver.cxx
index c9ed380..44c4ae1 100644
--- a/Source/cmStandardLevelResolver.cxx
+++ b/Source/cmStandardLevelResolver.cxx
@@ -541,6 +541,21 @@
return mapping->second.GetEffectiveStandard(this->Makefile, target, config);
}
+std::string cmStandardLevelResolver::GetLevelString(
+ std::string const& lang, cmStandardLevel const& level) const
+{
+ auto mapping = StandardComputerMapping.find(lang);
+ if (mapping == StandardComputerMapping.end()) {
+ return {};
+ }
+
+ if (mapping->second.LevelsAsStrings.size() <= level.Index()) {
+ return {};
+ }
+
+ return mapping->second.LevelsAsStrings[level.Index()];
+}
+
bool cmStandardLevelResolver::AddRequiredTargetFeature(
cmTarget* target, const std::string& feature, std::string* error) const
{
diff --git a/Source/cmStandardLevelResolver.h b/Source/cmStandardLevelResolver.h
index 29cab55..523aa73 100644
--- a/Source/cmStandardLevelResolver.h
+++ b/Source/cmStandardLevelResolver.h
@@ -29,6 +29,9 @@
std::string const& lang,
std::string const& config) const;
+ std::string GetLevelString(std::string const& lang,
+ cmStandardLevel const& level) const;
+
bool AddRequiredTargetFeature(cmTarget* target, const std::string& feature,
std::string* error = nullptr) const;
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index 3f7e29b..1284130 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -412,6 +412,7 @@
COMMON_LANGUAGE_PROPERTIES(C),
// ---- C++
COMMON_LANGUAGE_PROPERTIES(CXX),
+ { "CXX_MODULE_STD"_s, IC::CanCompileSources },
// ---- CSharp
{ "DOTNET_SDK"_s, IC::NonImportedTarget },
{ "DOTNET_TARGET_FRAMEWORK"_s, IC::TargetWithCommands },
@@ -1842,6 +1843,7 @@
"CXX_STANDARD_REQUIRED",
"CXX_EXTENSIONS",
"CXX_VISIBILITY_PRESET",
+ "CXX_MODULE_STD",
// Static analysis
"CXX_CLANG_TIDY",
diff --git a/Tests/CompatibleInterface/CMakeLists.txt b/Tests/CompatibleInterface/CMakeLists.txt
index 668a97b..5d57ce4 100644
--- a/Tests/CompatibleInterface/CMakeLists.txt
+++ b/Tests/CompatibleInterface/CMakeLists.txt
@@ -13,12 +13,14 @@
BOOL_PROP2
BOOL_PROP3
BOOL_PROP4
+ BOOL_PROP5
)
set_property(TARGET iface1 APPEND PROPERTY
COMPATIBLE_INTERFACE_STRING
STRING_PROP1
STRING_PROP2
STRING_PROP3
+ STRING_PROP4
)
set_property(TARGET iface1 APPEND PROPERTY
COMPATIBLE_INTERFACE_NUMBER_MIN
@@ -26,30 +28,40 @@
NUMBER_MIN_PROP2
NUMBER_MIN_PROP3
NUMBER_MIN_PROP4
+ NUMBER_MIN_PROP5
+ NUMBER_MIN_PROP6
)
set_property(TARGET iface1 APPEND PROPERTY
COMPATIBLE_INTERFACE_NUMBER_MAX
NUMBER_MAX_PROP1
NUMBER_MAX_PROP2
+ NUMBER_MAX_PROP3
+ NUMBER_MAX_PROP4
)
set(CMAKE_DEBUG_TARGET_PROPERTIES
- BOOL_PROP1 BOOL_PROP2 BOOL_PROP3 BOOL_PROP4
- STRING_PROP1 STRING_PROP2 STRING_PROP3
- NUMBER_MIN_PROP1 NUMBER_MIN_PROP2 NUMBER_MIN_PROP3 NUMBER_MIN_PROP4
- NUMBER_MAX_PROP1 NUMBER_MAX_PROP2
+ BOOL_PROP1 BOOL_PROP2 BOOL_PROP3 BOOL_PROP4 BOOL_PROP5
+ STRING_PROP1 STRING_PROP2 STRING_PROP3 STRING_PROP4
+ NUMBER_MIN_PROP1 NUMBER_MIN_PROP2 NUMBER_MIN_PROP3 NUMBER_MIN_PROP4 NUMBER_MIN_PROP5 NUMBER_MIN_PROP6
+ NUMBER_MAX_PROP1 NUMBER_MAX_PROP2 NUMBER_MAX_PROP3 NUMBER_MAX_PROP4
)
set_property(TARGET iface1 PROPERTY INTERFACE_BOOL_PROP1 ON)
set_property(TARGET iface1 PROPERTY INTERFACE_BOOL_PROP2 ON)
+set_property(TARGET iface1 PROPERTY INTERFACE_BOOL_PROP5 ON)
set_property(TARGET iface1 PROPERTY INTERFACE_STRING_PROP1 prop1)
set_property(TARGET iface1 PROPERTY INTERFACE_STRING_PROP2 prop2)
+set_property(TARGET iface1 PROPERTY INTERFACE_STRING_PROP4 prop4)
set_property(TARGET iface1 PROPERTY INTERFACE_NUMBER_MIN_PROP1 100)
set_property(TARGET iface1 PROPERTY INTERFACE_NUMBER_MIN_PROP2 200)
set_property(TARGET iface1 PROPERTY INTERFACE_NUMBER_MIN_PROP3 0x10)
set_property(TARGET iface1 PROPERTY INTERFACE_NUMBER_MIN_PROP4 0x10)
+set_property(TARGET iface1 PROPERTY INTERFACE_NUMBER_MIN_PROP5 5)
+set_property(TARGET iface1 PROPERTY INTERFACE_NUMBER_MIN_PROP6 6)
set_property(TARGET iface1 PROPERTY INTERFACE_NUMBER_MAX_PROP1 100)
set_property(TARGET iface1 PROPERTY INTERFACE_NUMBER_MAX_PROP2 200)
+set_property(TARGET iface1 PROPERTY INTERFACE_NUMBER_MAX_PROP3 3)
+set_property(TARGET iface1 PROPERTY INTERFACE_NUMBER_MAX_PROP4 4)
add_executable(CompatibleInterface main.cpp)
target_link_libraries(CompatibleInterface iface1)
@@ -86,8 +98,48 @@
$<$<STREQUAL:$<TARGET_PROPERTY:NUMBER_MIN_PROP2>,200>:NUMBER_MIN_PROP2=200>
$<$<EQUAL:$<TARGET_PROPERTY:NUMBER_MIN_PROP3>,0xA>:NUMBER_MIN_PROP3=0xA>
$<$<STREQUAL:$<TARGET_PROPERTY:NUMBER_MIN_PROP4>,0x10>:NUMBER_MIN_PROP4=0x10>
+ $<$<STREQUAL:$<TARGET_PROPERTY:NUMBER_MIN_PROP5>,5>:NUMBER_MIN_PROP5=5>
$<$<STREQUAL:$<TARGET_PROPERTY:NUMBER_MAX_PROP1>,100>:NUMBER_MAX_PROP1=100>
$<$<STREQUAL:$<TARGET_PROPERTY:NUMBER_MAX_PROP2>,250>:NUMBER_MAX_PROP2=250>
+ $<$<STREQUAL:$<TARGET_PROPERTY:NUMBER_MAX_PROP3>,3>:NUMBER_MAX_PROP3=3>
+
+ # Static libraries compute COMPATIBLE_INTERFACE_ properties transitively.
+ $<$<BOOL:$<TARGET_PROPERTY:static1,BOOL_PROP1>>:STATIC1_BOOL_PROP1>
+ $<$<STREQUAL:$<TARGET_PROPERTY:static1,STRING_PROP1>,prop1>:STATIC1_STRING_PROP1>
+ $<$<EQUAL:$<TARGET_PROPERTY:static1,NUMBER_MAX_PROP3>,3>:STATIC1_NUMBER_MAX_PROP3>
+ $<$<EQUAL:$<TARGET_PROPERTY:static1,NUMBER_MIN_PROP5>,5>:STATIC1_NUMBER_MIN_PROP5>
+
+ # Object libraries do not compute COMPATIBLE_INTERFACE_ properties transitively.
+ $<$<NOT:$<STREQUAL:$<TARGET_PROPERTY:object1,BOOL_PROP1>,>>:OBJECT1_BOOL_PROP1>
+ $<$<NOT:$<STREQUAL:$<TARGET_PROPERTY:object1,STRING_PROP1>,>>:OBJECT1_STRING_PROP1>
+ $<$<NOT:$<STREQUAL:$<TARGET_PROPERTY:object1,NUMBER_MAX_PROP3>,>>:OBJECT1_NUMBER_MAX_PROP3>
+ $<$<NOT:$<STREQUAL:$<TARGET_PROPERTY:object1,NUMBER_MIN_PROP5>,>>:OBJECT1_NUMBER_MIN_PROP5>
+
+ # Interface libraries do not compute COMPATIBLE_INTERFACE_ properties transitively.
+ $<$<NOT:$<STREQUAL:$<TARGET_PROPERTY:iface3,BOOL_PROP1>,>>:IFACE3_BOOL_PROP1>
+ $<$<NOT:$<STREQUAL:$<TARGET_PROPERTY:iface3,STRING_PROP1>,>>:IFACE3_STRING_PROP1>
+ $<$<NOT:$<STREQUAL:$<TARGET_PROPERTY:iface3,NUMBER_MAX_PROP3>,>>:IFACE3_NUMBER_MAX_PROP3>
+ $<$<NOT:$<STREQUAL:$<TARGET_PROPERTY:iface3,NUMBER_MIN_PROP5>,>>:IFACE3_NUMBER_MIN_PROP5>
+
+ # Static libraries compute COMPATIBLE_INTERFACE_ properties transitively.
+ $<$<BOOL:$<TARGET_PROPERTY:static1,BOOL_PROP5>>:STATIC1_BOOL_PROP5>
+ $<$<STREQUAL:$<TARGET_PROPERTY:static1,STRING_PROP4>,prop4>:STATIC1_STRING_PROP4>
+ $<$<EQUAL:$<TARGET_PROPERTY:static1,NUMBER_MIN_PROP6>,6>:STATIC1_NUMBER_MIN_PROP6>
+ $<$<EQUAL:$<TARGET_PROPERTY:static1,NUMBER_MAX_PROP4>,4>:STATIC1_NUMBER_MAX_PROP4>
+
+ # Object libraries do not compute COMPATIBLE_INTERFACE_ properties transitively,
+ # but can have properties set on them.
+ $<$<BOOL:$<TARGET_PROPERTY:object1,BOOL_PROP5>>:OBJECT1_BOOL_PROP5>
+ $<$<STREQUAL:$<TARGET_PROPERTY:object1,STRING_PROP4>,prop4>:OBJECT1_STRING_PROP4>
+ $<$<EQUAL:$<TARGET_PROPERTY:object1,NUMBER_MIN_PROP6>,7>:OBJECT1_NUMBER_MIN_PROP6>
+ $<$<EQUAL:$<TARGET_PROPERTY:object1,NUMBER_MAX_PROP4>,1>:OBJECT1_NUMBER_MAX_PROP4>
+
+ # Interface libraries do not compute COMPATIBLE_INTERFACE_ properties transitively,
+ # but can have properties set on them.
+ $<$<BOOL:$<TARGET_PROPERTY:iface3,BOOL_PROP5>>:IFACE3_BOOL_PROP5>
+ $<$<STREQUAL:$<TARGET_PROPERTY:iface3,STRING_PROP4>,prop4>:IFACE3_STRING_PROP4>
+ $<$<EQUAL:$<TARGET_PROPERTY:iface3,NUMBER_MIN_PROP6>,7>:IFACE3_NUMBER_MIN_PROP6>
+ $<$<EQUAL:$<TARGET_PROPERTY:iface3,NUMBER_MAX_PROP4>,1>:IFACE3_NUMBER_MAX_PROP4>
)
@@ -128,3 +180,64 @@
COMPATIBLE_INTERFACE_BOOL
NON_RELEVANT_PROP
)
+
+add_library(static1 STATIC foo.cpp)
+set_property(TARGET static1 PROPERTY BOOL_PROP5 ON)
+set_property(TARGET static1 PROPERTY STRING_PROP4 prop4)
+set_property(TARGET static1 PROPERTY NUMBER_MIN_PROP6 7)
+set_property(TARGET static1 PROPERTY NUMBER_MAX_PROP4 1)
+target_link_libraries(static1 PUBLIC iface1)
+
+add_library(object1 OBJECT foo.cpp)
+set_property(TARGET object1 PROPERTY BOOL_PROP5 ON)
+set_property(TARGET object1 PROPERTY STRING_PROP4 prop4)
+set_property(TARGET object1 PROPERTY NUMBER_MIN_PROP6 7)
+set_property(TARGET object1 PROPERTY NUMBER_MAX_PROP4 1)
+target_link_libraries(object1 PUBLIC iface1)
+
+add_library(iface3 INTERFACE)
+set_property(TARGET iface3 PROPERTY BOOL_PROP5 ON)
+set_property(TARGET iface3 PROPERTY STRING_PROP4 prop4)
+set_property(TARGET iface3 PROPERTY NUMBER_MIN_PROP6 7)
+set_property(TARGET iface3 PROPERTY NUMBER_MAX_PROP4 1)
+target_link_libraries(iface3 INTERFACE iface1)
+
+# Test COMPATIBLE_INTERFACE_* property evaluation outside of usage requirements.
+add_custom_target(check ALL VERBATIM
+ COMMAND CompatibleInterface
+ # expect actual
+ "1" "$<TARGET_PROPERTY:CompatibleInterface,BOOL_PROP1>"
+ "prop1" "$<TARGET_PROPERTY:CompatibleInterface,STRING_PROP1>"
+ "3" "$<TARGET_PROPERTY:CompatibleInterface,NUMBER_MAX_PROP3>"
+ "5" "$<TARGET_PROPERTY:CompatibleInterface,NUMBER_MIN_PROP5>"
+
+ "1" "$<TARGET_PROPERTY:static1,BOOL_PROP1>"
+ "prop1" "$<TARGET_PROPERTY:static1,STRING_PROP1>"
+ "3" "$<TARGET_PROPERTY:static1,NUMBER_MAX_PROP3>"
+ "5" "$<TARGET_PROPERTY:static1,NUMBER_MIN_PROP5>"
+
+ "" "$<TARGET_PROPERTY:object1,BOOL_PROP1>"
+ "" "$<TARGET_PROPERTY:object1,STRING_PROP1>"
+ "" "$<TARGET_PROPERTY:object1,NUMBER_MAX_PROP3>"
+ "" "$<TARGET_PROPERTY:object1,NUMBER_MIN_PROP5>"
+
+ "" "$<TARGET_PROPERTY:iface3,BOOL_PROP1>"
+ "" "$<TARGET_PROPERTY:iface3,STRING_PROP1>"
+ "" "$<TARGET_PROPERTY:iface3,NUMBER_MAX_PROP3>"
+ "" "$<TARGET_PROPERTY:iface3,NUMBER_MIN_PROP5>"
+
+ "ON" "$<TARGET_PROPERTY:static1,BOOL_PROP5>"
+ "prop4" "$<TARGET_PROPERTY:static1,STRING_PROP4>"
+ "6" "$<TARGET_PROPERTY:static1,NUMBER_MIN_PROP6>"
+ "4" "$<TARGET_PROPERTY:static1,NUMBER_MAX_PROP4>"
+
+ "ON" "$<TARGET_PROPERTY:object1,BOOL_PROP5>"
+ "prop4" "$<TARGET_PROPERTY:object1,STRING_PROP4>"
+ "7" "$<TARGET_PROPERTY:object1,NUMBER_MIN_PROP6>"
+ "1" "$<TARGET_PROPERTY:object1,NUMBER_MAX_PROP4>"
+
+ "ON" "$<TARGET_PROPERTY:iface3,BOOL_PROP5>"
+ "prop4" "$<TARGET_PROPERTY:iface3,STRING_PROP4>"
+ "7" "$<TARGET_PROPERTY:iface3,NUMBER_MIN_PROP6>"
+ "1" "$<TARGET_PROPERTY:iface3,NUMBER_MAX_PROP4>"
+ )
diff --git a/Tests/CompatibleInterface/main.cpp b/Tests/CompatibleInterface/main.cpp
index 0bccb82..1205cca 100644
--- a/Tests/CompatibleInterface/main.cpp
+++ b/Tests/CompatibleInterface/main.cpp
@@ -1,3 +1,5 @@
+#include <stdio.h>
+#include <string.h>
#ifndef BOOL_PROP1
# error Expected BOOL_PROP1
@@ -23,6 +25,102 @@
# error Expected STRING_PROP3
#endif
+#ifndef STATIC1_BOOL_PROP1
+# error Expected STATIC1_BOOL_PROP1
+#endif
+
+#ifndef STATIC1_STRING_PROP1
+# error Expected STATIC1_STRING_PROP1
+#endif
+
+#ifndef STATIC1_NUMBER_MAX_PROP3
+# error Expected STATIC1_NUMBER_MAX_PROP3
+#endif
+
+#ifndef STATIC1_NUMBER_MIN_PROP5
+# error Expected STATIC1_NUMBER_MIN_PROP5
+#endif
+
+#ifdef OBJECT1_BOOL_PROP1
+# error Unexpected OBJECT1_BOOL_PROP1
+#endif
+
+#ifdef OBJECT1_STRING_PROP1
+# error Unexpected OBJECT1_STRING_PROP1
+#endif
+
+#ifdef OBJECT1_NUMBER_MAX_PROP3
+# error Unexpected OBJECT1_NUMBER_MAX_PROP3
+#endif
+
+#ifdef OBJECT1_NUMBER_MIN_PROP5
+# error Unexpected OBJECT1_NUMBER_MIN_PROP5
+#endif
+
+#ifdef IFACE3_BOOL_PROP1
+# error Unexpected IFACE3_BOOL_PROP1
+#endif
+
+#ifdef IFACE3_STRING_PROP1
+# error Unexpected IFACE3_STRING_PROP1
+#endif
+
+#ifdef IFACE3_NUMBER_MAX_PROP3
+# error Unexpected IFACE3_NUMBER_MAX_PROP3
+#endif
+
+#ifdef IFACE3_NUMBER_MIN_PROP5
+# error Unexpected IFACE3_NUMBER_MIN_PROP5
+#endif
+
+#ifndef STATIC1_BOOL_PROP5
+# error Expected STATIC1_BOOL_PROP5
+#endif
+
+#ifndef STATIC1_STRING_PROP4
+# error Expected STATIC1_STRING_PROP4
+#endif
+
+#ifndef STATIC1_NUMBER_MIN_PROP6
+# error Expected STATIC1_NUMBER_MIN_PROP6
+#endif
+
+#ifndef STATIC1_NUMBER_MAX_PROP4
+# error Expected STATIC1_NUMBER_MAX_PROP4
+#endif
+
+#ifndef OBJECT1_BOOL_PROP5
+# error Expected OBJECT1_BOOL_PROP5
+#endif
+
+#ifndef OBJECT1_STRING_PROP4
+# error Expected OBJECT1_STRING_PROP4
+#endif
+
+#ifndef OBJECT1_NUMBER_MIN_PROP6
+# error Expected OBJECT1_NUMBER_MIN_PROP6
+#endif
+
+#ifndef OBJECT1_NUMBER_MAX_PROP4
+# error Expected OBJECT1_NUMBER_MAX_PROP4
+#endif
+
+#ifndef IFACE3_BOOL_PROP5
+# error Expected IFACE3_BOOL_PROP5
+#endif
+
+#ifndef IFACE3_STRING_PROP4
+# error Expected IFACE3_STRING_PROP4
+#endif
+
+#ifndef IFACE3_NUMBER_MIN_PROP6
+# error Expected IFACE3_NUMBER_MIN_PROP6
+#endif
+
+#ifndef IFACE3_NUMBER_MAX_PROP4
+# error Expected IFACE3_NUMBER_MAX_PROP4
+#endif
+
template <bool test>
struct CMakeStaticAssert;
@@ -35,10 +133,12 @@
{
NumericMaxTest1 = sizeof(CMakeStaticAssert<NUMBER_MAX_PROP1 == 100>),
NumericMaxTest2 = sizeof(CMakeStaticAssert<NUMBER_MAX_PROP2 == 250>),
+ NumericMaxTest3 = sizeof(CMakeStaticAssert<NUMBER_MAX_PROP3 == 3>),
NumericMinTest1 = sizeof(CMakeStaticAssert<NUMBER_MIN_PROP1 == 50>),
NumericMinTest2 = sizeof(CMakeStaticAssert<NUMBER_MIN_PROP2 == 200>),
NumericMinTest3 = sizeof(CMakeStaticAssert<NUMBER_MIN_PROP3 == 0xA>),
- NumericMinTest4 = sizeof(CMakeStaticAssert<NUMBER_MIN_PROP4 == 0x10>)
+ NumericMinTest4 = sizeof(CMakeStaticAssert<NUMBER_MIN_PROP4 == 0x10>),
+ NumericMinTest5 = sizeof(CMakeStaticAssert<NUMBER_MIN_PROP5 == 5>)
};
#include "iface2.h"
@@ -51,6 +151,14 @@
int main(int argc, char** argv)
{
+ int result = 0;
+ for (int i = 2; i < argc; i += 2) {
+ if (strcmp(argv[i - 1], argv[i]) != 0) {
+ fprintf(stderr, "Argument %d expected '%s' but got '%s'.\n", i,
+ argv[i - 1], argv[i]);
+ result = 1;
+ }
+ }
Iface2 if2;
- return if2.foo() + foo() + bar();
+ return result + if2.foo() + foo() + bar();
}
diff --git a/Tests/FindJasper/Test/CMakeLists.txt b/Tests/FindJasper/Test/CMakeLists.txt
index 1e9467d..93873bf 100644
--- a/Tests/FindJasper/Test/CMakeLists.txt
+++ b/Tests/FindJasper/Test/CMakeLists.txt
@@ -4,7 +4,7 @@
find_package(Jasper)
-add_definitions(-DCMAKE_EXPECTED_JASPER_VERSION=${JASPER_VERSION_STRING})
+add_definitions(-DCMAKE_EXPECTED_JASPER_VERSION="${JASPER_VERSION_STRING}")
add_executable(test_jasper_tgt main.c)
target_link_libraries(test_jasper_tgt Jasper::Jasper)
diff --git a/Tests/FindJasper/Test/main.c b/Tests/FindJasper/Test/main.c
index 242ff7d..b9dbe1e 100644
--- a/Tests/FindJasper/Test/main.c
+++ b/Tests/FindJasper/Test/main.c
@@ -1,17 +1,11 @@
-#include <assert.h>
-// clang-format off
-#include <stdio.h>
#include <jasper/jasper.h>
-// clang-format on
+#include <string.h>
int main(void)
{
- /* Without any JPEG file to open, test that the call fails as
- expected. This tests that linking worked. */
- jas_init();
- jas_image_t* img = jas_image_create0();
- jas_image_destroy(img);
- jas_cleanup();
-
- return (JAS_VERSION != CMAKE_EXPECTED_JASPER_VERSION);
+ jas_conf_clear();
+ jas_conf_set_max_mem_usage(0x100000);
+ jas_init_library();
+ jas_cleanup_library();
+ return strcmp(JAS_VERSION, CMAKE_EXPECTED_JASPER_VERSION);
}
diff --git a/Tests/RunCMake/CMakeLists.txt b/Tests/RunCMake/CMakeLists.txt
index a82c79f..9e85179 100644
--- a/Tests/RunCMake/CMakeLists.txt
+++ b/Tests/RunCMake/CMakeLists.txt
@@ -1087,11 +1087,22 @@
DEB.CUSTOM_NAMES
DEB.DEB_PACKAGE_VERSION_BACK_COMPATIBILITY
DEB.PROJECT_META DEB.DEPENDENCIES
+ DEB.EXTRA
+ DEB.GENERATE_SHLIBS_LDCONFIG
+ DEB.LONG_FILENAMES
+ DEB.MD5SUMS
+ DEB.EMPTY_DIR
+ DEB.DEFAULT_PERMISSIONS
+ DEB.VERSION
+ DEB.TIMESTAMPS
RPM.PARTIALLY_RELOCATABLE_WARNING
RPM.PER_COMPONENT_FIELDS
RPM.USER_FILELIST
RPM.DIST
RPM.AUTO_SUFFIXES
+ 7Z
+ TXZ
+ TBZ2
TGZ
ZIP
STGZ
diff --git a/Tests/RunCMake/CMakePackage/ApplePlatformGenSubdir-stdout.txt b/Tests/RunCMake/CMakePackage/ApplePlatformGenSubdir-stdout.txt
deleted file mode 100644
index 8821dad..0000000
--- a/Tests/RunCMake/CMakePackage/ApplePlatformGenSubdir-stdout.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-(-- )?Hello from platform switch
-(-- )?Hello from arch switch
-(-- )?Hello from pkg_a
diff --git a/Tests/RunCMake/CMakePackage/ApplePlatformGenSubdir.cmake b/Tests/RunCMake/CMakePackage/ApplePlatformGenSubdir.cmake
deleted file mode 100644
index a8a3168..0000000
--- a/Tests/RunCMake/CMakePackage/ApplePlatformGenSubdir.cmake
+++ /dev/null
@@ -1,50 +0,0 @@
-set(CMAKE_INSTALL_DATADIR share)
-set(SWITCH_DIR platform/cmake)
-
-include(CMakePackageConfigHelpers)
-
-file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/pkg_a-config.cmake.in [[
-@PACKAGE_INIT@
-include("@PACKAGE_SWITCH_DIR@/platform-switch.cmake")
-include("@PACKAGE_CMAKE_INSTALL_DATADIR@/pkg_a_included.cmake")
-]])
-configure_package_config_file(
- ${CMAKE_CURRENT_BINARY_DIR}/pkg_a-config.cmake.in
- ${CMAKE_CURRENT_BINARY_DIR}/install/pkg_a-config.cmake
- INSTALL_DESTINATION .
- PATH_VARS CMAKE_INSTALL_DATADIR SWITCH_DIR
-)
-file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/install/${CMAKE_INSTALL_DATADIR}/pkg_a_included.cmake
- [[message(STATUS "Hello from pkg_a")]]
-)
-
-# To expose re-using the same package prefix variable, we need to use a
-# different install prefix but still with the same package name. This is
-# really contrived and not representative of what a package should do.
-generate_apple_platform_selection_file(
- ${CMAKE_CURRENT_BINARY_DIR}/install/platform/cmake/platform-switch.cmake
- INSTALL_PREFIX ${CMAKE_INSTALL_PREFIX}/platform
- INSTALL_DESTINATION cmake
- MACOS_INCLUDE_FILE cmake/switch_included.cmake # relative to install prefix
-)
-file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/install/platform/cmake/switch_included.cmake
-[[
-message(STATUS "Hello from platform switch")
-include("${CMAKE_CURRENT_LIST_DIR}/../arch/cmake/arch-switch.cmake")
-]]
-)
-
-generate_apple_architecture_selection_file(
- ${CMAKE_CURRENT_BINARY_DIR}/install/platform/arch/cmake/arch-switch.cmake
- INSTALL_PREFIX ${CMAKE_INSTALL_PREFIX}/platform/arch
- INSTALL_DESTINATION cmake
- UNIVERSAL_ARCHITECTURES i386 x86_64 arm64 $(ARCHS_STANDARD)
- UNIVERSAL_INCLUDE_FILE cmake/switch_included.cmake # relative to install prefix
-)
-file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/install/platform/arch/cmake/switch_included.cmake
- [[message(STATUS "Hello from arch switch")]]
-)
-
-find_package(pkg_a REQUIRED NO_DEFAULT_PATH
- PATHS ${CMAKE_CURRENT_BINARY_DIR}/install
-)
diff --git a/Tests/RunCMake/CMakePackage/NestedConfigFile-stdout.txt b/Tests/RunCMake/CMakePackage/NestedConfigFile-stdout.txt
deleted file mode 100644
index a95ef87..0000000
--- a/Tests/RunCMake/CMakePackage/NestedConfigFile-stdout.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-(-- )?Hello from pkg_a
-(-- )?Hello from pkg_b
diff --git a/Tests/RunCMake/CMakePackage/NestedConfigFile.cmake b/Tests/RunCMake/CMakePackage/NestedConfigFile.cmake
deleted file mode 100644
index e62c46b..0000000
--- a/Tests/RunCMake/CMakePackage/NestedConfigFile.cmake
+++ /dev/null
@@ -1,39 +0,0 @@
-set(CMAKE_INSTALL_DATADIR share)
-
-include(CMakePackageConfigHelpers)
-
-file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/pkg_a-config.cmake.in [[
-@PACKAGE_INIT@
-include("@PACKAGE_CMAKE_INSTALL_DATADIR@/pkg_a_included.cmake")
-]])
-configure_package_config_file(
- ${CMAKE_CURRENT_BINARY_DIR}/pkg_a-config.cmake.in
- ${CMAKE_CURRENT_BINARY_DIR}/install_pkg_a/pkg_a-config.cmake
- INSTALL_DESTINATION .
- PATH_VARS CMAKE_INSTALL_DATADIR
-)
-file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/install_pkg_a/share/pkg_a_included.cmake
- [[message(STATUS "Hello from pkg_a")]]
-)
-
-file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/pkg_b-config.cmake.in [[
-@PACKAGE_INIT@
-include(CMakeFindDependencyMacro)
-find_dependency(pkg_a NO_DEFAULT_PATH
- PATHS "@CMAKE_CURRENT_BINARY_DIR@/install_pkg_a"
-)
-include("@PACKAGE_CMAKE_INSTALL_DATADIR@/pkg_b_included.cmake")
-]])
-configure_package_config_file(
- ${CMAKE_CURRENT_BINARY_DIR}/pkg_b-config.cmake.in
- ${CMAKE_CURRENT_BINARY_DIR}/install_pkg_b/pkg_b-config.cmake
- INSTALL_DESTINATION .
- PATH_VARS CMAKE_INSTALL_DATADIR
-)
-file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/install_pkg_b/share/pkg_b_included.cmake
- [[message(STATUS "Hello from pkg_b")]]
-)
-
-find_package(pkg_b REQUIRED NO_DEFAULT_PATH
- PATHS ${CMAKE_CURRENT_BINARY_DIR}/install_pkg_b
-)
diff --git a/Tests/RunCMake/CMakePackage/RunCMakeTest.cmake b/Tests/RunCMake/CMakePackage/RunCMakeTest.cmake
index 6663f38..1551b55 100644
--- a/Tests/RunCMake/CMakePackage/RunCMakeTest.cmake
+++ b/Tests/RunCMake/CMakePackage/RunCMakeTest.cmake
@@ -4,8 +4,6 @@
set(maybe_CMAKE_BUILD_TYPE -DCMAKE_BUILD_TYPE=Release)
endif()
-run_cmake_with_options(NestedConfigFile ${maybe_CMAKE_BUILD_TYPE})
-
function(apple_export platform system_name archs sysroot)
set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/apple-export-${platform}-build)
string(REPLACE ";" "\\;" archs "${archs}")
@@ -80,12 +78,6 @@
set(enable_visionos 1)
endif()
- string(REPLACE ";" "\\;" macos_archs_for_cmd "${macos_archs}")
- run_cmake_with_options(ApplePlatformGenSubdir
- "-DCMAKE_OSX_ARCHITECTURES=${macos_archs_for_cmd}"
- ${maybe_CMAKE_BUILD_TYPE}
- )
-
apple_export(macos Darwin "${macos_archs}" macosx)
apple_export(ios iOS "arm64" iphoneos)
apple_export(tvos tvOS "arm64" appletvos)
diff --git a/Tests/RunCMake/CXXModules/CMP0155-NEW.cmake b/Tests/RunCMake/CXXModules/CMP0155-NEW.cmake
index d68775a..c754930 100644
--- a/Tests/RunCMake/CXXModules/CMP0155-NEW.cmake
+++ b/Tests/RunCMake/CXXModules/CMP0155-NEW.cmake
@@ -1,3 +1,6 @@
+# Block making C++ `import std` targets.
+add_library(__CMAKE::CXX23 IMPORTED INTERFACE)
+
enable_language(CXX)
unset(CMAKE_CXX_SCANDEP_SOURCE)
diff --git a/Tests/RunCMake/CXXModules/CMP0155-OLD.cmake b/Tests/RunCMake/CXXModules/CMP0155-OLD.cmake
index 201598e..a994266 100644
--- a/Tests/RunCMake/CXXModules/CMP0155-OLD.cmake
+++ b/Tests/RunCMake/CXXModules/CMP0155-OLD.cmake
@@ -1,3 +1,6 @@
+# Block making C++ `import std` targets.
+add_library(__CMAKE::CXX23 IMPORTED INTERFACE)
+
enable_language(CXX)
unset(CMAKE_CXX_SCANDEP_SOURCE)
diff --git a/Tests/RunCMake/CXXModules/CXXImportStdConfig-result.txt b/Tests/RunCMake/CXXModules/CXXImportStdConfig-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/CXXImportStdConfig-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CXXModules/CXXImportStdConfig-stderr.txt b/Tests/RunCMake/CXXModules/CXXImportStdConfig-stderr.txt
new file mode 100644
index 0000000..268099f
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/CXXImportStdConfig-stderr.txt
@@ -0,0 +1,3 @@
+CMake Error in CMakeLists.txt:
+ The "CXX_MODULE_STD" property on the target "nocxx23target" contains a
+ context-sensitive condition that is not supported.
diff --git a/Tests/RunCMake/CXXModules/CXXImportStdConfig.cmake b/Tests/RunCMake/CXXModules/CXXImportStdConfig.cmake
new file mode 100644
index 0000000..0867082
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/CXXImportStdConfig.cmake
@@ -0,0 +1,10 @@
+enable_language(CXX)
+
+set(CMAKE_CXX_MODULE_STD "$<CONFIG:Release>")
+
+add_library(nocxx23target)
+target_sources(nocxx23target
+ PRIVATE
+ FILE_SET fs TYPE CXX_MODULES FILES
+ sources/module.cxx)
+target_compile_features(nocxx23target PRIVATE cxx_std_23)
diff --git a/Tests/RunCMake/CXXModules/CXXImportStdHeadTarget-result.txt b/Tests/RunCMake/CXXModules/CXXImportStdHeadTarget-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/CXXImportStdHeadTarget-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CXXModules/CXXImportStdHeadTarget-stderr.txt b/Tests/RunCMake/CXXModules/CXXImportStdHeadTarget-stderr.txt
new file mode 100644
index 0000000..a2cdb63
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/CXXImportStdHeadTarget-stderr.txt
@@ -0,0 +1,9 @@
+CMake Error:
+ Error evaluating generator expression:
+
+ \$<TARGET_PROPERTY:use_std_in_consumed>
+
+ \$<TARGET_PROPERTY:prop> may only be used with binary targets. It may not
+ be used with add_custom_command or add_custom_target. Specify the target
+ to read a property from using the \$<TARGET_PROPERTY:tgt,prop> signature
+ instead.
diff --git a/Tests/RunCMake/CXXModules/CXXImportStdHeadTarget.cmake b/Tests/RunCMake/CXXModules/CXXImportStdHeadTarget.cmake
new file mode 100644
index 0000000..3eb2c68
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/CXXImportStdHeadTarget.cmake
@@ -0,0 +1,10 @@
+enable_language(CXX)
+
+set(CMAKE_CXX_MODULE_STD "$<TARGET_PROPERTY:use_std_in_consumed>")
+
+add_library(nocxx23target)
+target_sources(nocxx23target
+ PRIVATE
+ FILE_SET fs TYPE CXX_MODULES FILES
+ sources/module.cxx)
+target_compile_features(nocxx23target PRIVATE cxx_std_23)
diff --git a/Tests/RunCMake/CXXModules/CXXImportStdInvalidGenex.cmake b/Tests/RunCMake/CXXModules/CXXImportStdInvalidGenex.cmake
new file mode 100644
index 0000000..86230a4
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/CXXImportStdInvalidGenex.cmake
@@ -0,0 +1,11 @@
+enable_language(CXX)
+set(CMAKE_CXX_SCANDEP_SOURCE "echo")
+
+set(CMAKE_CXX_MODULE_STD "$<STREQUAL:")
+
+add_library(nocxx23target)
+target_sources(nocxx23target
+ PRIVATE
+ FILE_SET fs TYPE CXX_MODULES FILES
+ sources/module.cxx)
+target_compile_features(nocxx23target PRIVATE cxx_std_23)
diff --git a/Tests/RunCMake/CXXModules/CXXImportStdLinkLanguage-result.txt b/Tests/RunCMake/CXXModules/CXXImportStdLinkLanguage-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/CXXImportStdLinkLanguage-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CXXModules/CXXImportStdLinkLanguage-stderr.txt b/Tests/RunCMake/CXXModules/CXXImportStdLinkLanguage-stderr.txt
new file mode 100644
index 0000000..21148a2
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/CXXImportStdLinkLanguage-stderr.txt
@@ -0,0 +1,7 @@
+CMake Error:
+ Error evaluating generator expression:
+
+ \$<LINK_LANGUAGE:CXX>
+
+ \$<LINK_LANGUAGE:...> may only be used with binary targets to specify link
+ libraries, link directories, link options and link depends.
diff --git a/Tests/RunCMake/CXXModules/CXXImportStdLinkLanguage.cmake b/Tests/RunCMake/CXXModules/CXXImportStdLinkLanguage.cmake
new file mode 100644
index 0000000..e9b20c7
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/CXXImportStdLinkLanguage.cmake
@@ -0,0 +1,10 @@
+enable_language(CXX)
+
+set(CMAKE_CXX_MODULE_STD "$<LINK_LANGUAGE:CXX>")
+
+add_library(nocxx23target)
+target_sources(nocxx23target
+ PRIVATE
+ FILE_SET fs TYPE CXX_MODULES FILES
+ sources/module.cxx)
+target_compile_features(nocxx23target PRIVATE cxx_std_23)
diff --git a/Tests/RunCMake/CXXModules/ImplicitCXX20.cmake b/Tests/RunCMake/CXXModules/ImplicitCXX20.cmake
index cac1777..64d69f3 100644
--- a/Tests/RunCMake/CXXModules/ImplicitCXX20.cmake
+++ b/Tests/RunCMake/CXXModules/ImplicitCXX20.cmake
@@ -1,6 +1,9 @@
# Enable scanning by default for targets that explicitly use C++ 20.
cmake_policy(SET CMP0155 NEW)
+# Block making C++ `import std` targets.
+add_library(__CMAKE::CXX23 IMPORTED INTERFACE)
+
# Force CMAKE_CXX_STANDARD_DEFAULT to be C++ 20.
set(ENV{CXXFLAGS} "$ENV{CXXFLAGS} ${CMAKE_CXX20_STANDARD_COMPILE_OPTION}")
enable_language(CXX)
diff --git a/Tests/RunCMake/CXXModules/Inspect.cmake b/Tests/RunCMake/CXXModules/Inspect.cmake
index 612b01b..1597bd8 100644
--- a/Tests/RunCMake/CXXModules/Inspect.cmake
+++ b/Tests/RunCMake/CXXModules/Inspect.cmake
@@ -15,11 +15,17 @@
set(forced_cxx_standard 1)
endif ()
+set(have_cxx23_import_std 0)
+if (TARGET "__CMAKE::CXX23")
+ set(have_cxx23_import_std 1)
+endif ()
+
# Forward information about the C++ compile features.
string(APPEND info "\
set(CMAKE_CXX_COMPILE_FEATURES \"${CMAKE_CXX_COMPILE_FEATURES}\")
set(CMAKE_MAKE_PROGRAM \"${CMAKE_MAKE_PROGRAM}\")
set(forced_cxx_standard \"${forced_cxx_standard}\")
+set(have_cxx23_import_std \"${have_cxx23_import_std}\")
set(CMAKE_CXX_COMPILER_VERSION \"${CMAKE_CXX_COMPILER_VERSION}\")
set(CMAKE_CXX_OUTPUT_EXTENSION \"${CMAKE_CXX_OUTPUT_EXTENSION}\")
set(CXXModules_default_build_type \"${CMAKE_BUILD_TYPE}\")
diff --git a/Tests/RunCMake/CXXModules/NoCXX20.cmake b/Tests/RunCMake/CXXModules/NoCXX20.cmake
index b7372e8..9710728 100644
--- a/Tests/RunCMake/CXXModules/NoCXX20.cmake
+++ b/Tests/RunCMake/CXXModules/NoCXX20.cmake
@@ -1,3 +1,6 @@
+# Block making C++ `import std` targets.
+add_library(__CMAKE::CXX23 IMPORTED INTERFACE)
+
enable_language(CXX)
add_library(nocxx20)
diff --git a/Tests/RunCMake/CXXModules/NoCXX23TargetNotRequired.cmake b/Tests/RunCMake/CXXModules/NoCXX23TargetNotRequired.cmake
new file mode 100644
index 0000000..2d9bffa
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/NoCXX23TargetNotRequired.cmake
@@ -0,0 +1,11 @@
+enable_language(CXX)
+set(CMAKE_CXX_SCANDEP_SOURCE "echo")
+
+set(CMAKE_CXX_MODULE_STD 0)
+
+add_library(nocxx23target)
+target_sources(nocxx23target
+ PRIVATE
+ FILE_SET fs TYPE CXX_MODULES FILES
+ sources/module.cxx)
+target_compile_features(nocxx23target PRIVATE cxx_std_23)
diff --git a/Tests/RunCMake/CXXModules/NoCXX23TargetRequired-result.txt b/Tests/RunCMake/CXXModules/NoCXX23TargetRequired-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/NoCXX23TargetRequired-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CXXModules/NoCXX23TargetRequired-stderr.txt b/Tests/RunCMake/CXXModules/NoCXX23TargetRequired-stderr.txt
new file mode 100644
index 0000000..56468d0
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/NoCXX23TargetRequired-stderr.txt
@@ -0,0 +1,4 @@
+CMake Error in CMakeLists.txt:
+ The "CXX_MODULE_STD" property on the target "nocxx23target" requires that
+ the "__CMAKE::CXX23" target exist, but it was not provided by the
+ toolchain.
diff --git a/Tests/RunCMake/CXXModules/NoCXX23TargetRequired.cmake b/Tests/RunCMake/CXXModules/NoCXX23TargetRequired.cmake
new file mode 100644
index 0000000..fac05e2
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/NoCXX23TargetRequired.cmake
@@ -0,0 +1,11 @@
+enable_language(CXX)
+set(CMAKE_CXX_SCANDEP_SOURCE "echo")
+
+set(CMAKE_CXX_MODULE_STD 1)
+
+add_library(nocxx23target)
+target_sources(nocxx23target
+ PRIVATE
+ FILE_SET fs TYPE CXX_MODULES FILES
+ sources/module.cxx)
+target_compile_features(nocxx23target PRIVATE cxx_std_23)
diff --git a/Tests/RunCMake/CXXModules/NoCXX23TargetUnset.cmake b/Tests/RunCMake/CXXModules/NoCXX23TargetUnset.cmake
new file mode 100644
index 0000000..8f6a656
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/NoCXX23TargetUnset.cmake
@@ -0,0 +1,13 @@
+enable_language(CXX)
+set(CMAKE_CXX_SCANDEP_SOURCE "echo")
+
+# TODO(cxxmodules): Add instances of this test which test the policy
+# of the property's unset behavior.
+# set(CMAKE_CXX_MODULE_STD …)
+
+add_library(nocxx23target)
+target_sources(nocxx23target
+ PRIVATE
+ FILE_SET fs TYPE CXX_MODULES FILES
+ sources/module.cxx)
+target_compile_features(nocxx23target PRIVATE cxx_std_23)
diff --git a/Tests/RunCMake/CXXModules/NoScanningVariable.cmake b/Tests/RunCMake/CXXModules/NoScanningVariable.cmake
index 4bb6a70..950f1f3 100644
--- a/Tests/RunCMake/CXXModules/NoScanningVariable.cmake
+++ b/Tests/RunCMake/CXXModules/NoScanningVariable.cmake
@@ -1,6 +1,9 @@
# Enable scanning by default for targets that explicitly use C++ 20.
cmake_policy(SET CMP0155 NEW)
+# Block making C++ `import std` targets.
+add_library(__CMAKE::CXX23 IMPORTED INTERFACE)
+
enable_language(CXX)
# Hide any real scanning rule that may be available.
diff --git a/Tests/RunCMake/CXXModules/RunCMakeTest.cmake b/Tests/RunCMake/CXXModules/RunCMakeTest.cmake
index 14829a1..94e380d 100644
--- a/Tests/RunCMake/CXXModules/RunCMakeTest.cmake
+++ b/Tests/RunCMake/CXXModules/RunCMakeTest.cmake
@@ -83,6 +83,20 @@
run_cmake("NotCXXSource${fileset_type}")
endforeach ()
+if ("cxx_std_23" IN_LIST CMAKE_CXX_COMPILE_FEATURES)
+ run_cmake(CXXImportStdConfig)
+ run_cmake(CXXImportStdHeadTarget)
+ run_cmake(CXXImportStdLinkLanguage)
+ run_cmake(CXXImportStdInvalidGenex)
+endif ()
+
+if ("cxx_std_23" IN_LIST CMAKE_CXX_COMPILE_FEATURES AND
+ NOT have_cxx23_import_std)
+ run_cmake(NoCXX23TargetUnset)
+ run_cmake(NoCXX23TargetNotRequired)
+ run_cmake(NoCXX23TargetRequired)
+endif ()
+
run_cmake(InstallBMI)
run_cmake(InstallBMIGenericArgs)
run_cmake(InstallBMIIgnore)
@@ -175,6 +189,7 @@
# - `partitions`: module partitions are supported
# - `internal_partitions`: internal module partitions are supported
# - `bmionly`: the compiler supports BMI-only builds
+# - `import_std23`: the compiler supports `import std` for C++23
#
# Generator-based:
# - `compile_commands`: the generator supports `compile_commands.json`
@@ -221,6 +236,31 @@
run_cxx_module_test(same-src-name)
run_cxx_module_test(scan_properties)
run_cxx_module_test(target-objects)
+
+ if ("cxx_std_23" IN_LIST CMAKE_CXX_COMPILE_FEATURES AND
+ "import_std23" IN_LIST CMake_TEST_MODULE_COMPILATION)
+ run_cxx_module_test(import-std)
+ set(RunCMake_CXXModules_NO_TEST 1)
+ run_cxx_module_test(import-std-no-std-property)
+ unset(RunCMake_CXXModules_NO_TEST)
+ run_cxx_module_test(import-std-export-no-std-build)
+ set(RunCMake_CXXModules_INSTALL 1)
+ run_cxx_module_test(import-std-export-no-std-install)
+ unset(RunCMake_CXXModules_INSTALL)
+
+ if ("collation" IN_LIST CMake_TEST_MODULE_COMPILATION)
+ run_cxx_module_test(import-std-not-in-export-build)
+ run_cxx_module_test(import-std-transitive import-std-transitive-not-in-export-build "-DCMAKE_PREFIX_PATH=${RunCMake_BINARY_DIR}/examples/import-std-not-in-export-build-build")
+
+ set(RunCMake_CXXModules_INSTALL 1)
+ run_cxx_module_test(import-std-not-in-export-install)
+ unset(RunCMake_CXXModules_INSTALL)
+ run_cxx_module_test(import-std-transitive import-std-transitive-not-in-export-install "-DCMAKE_PREFIX_PATH=${RunCMake_BINARY_DIR}/examples/import-std-not-in-export-install-install")
+
+ run_cxx_module_test(import-std-transitive import-std-transitive-export-no-std-build "-DCMAKE_PREFIX_PATH=${RunCMake_BINARY_DIR}/examples/import-std-export-no-std-build-build" -DEXPORT_NO_STD=1)
+ run_cxx_module_test(import-std-transitive import-std-transitive-export-no-std-install "-DCMAKE_PREFIX_PATH=${RunCMake_BINARY_DIR}/examples/import-std-export-no-std-install-install" -DEXPORT_NO_STD=1)
+ endif ()
+ endif ()
endif ()
# Tests which require compile commands support.
diff --git a/Tests/RunCMake/CXXModules/examples/import-std-export-no-std-build-stderr.txt b/Tests/RunCMake/CXXModules/examples/import-std-export-no-std-build-stderr.txt
new file mode 100644
index 0000000..3589448
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/examples/import-std-export-no-std-build-stderr.txt
@@ -0,0 +1,8 @@
+CMake Warning \(dev\) at .*/Modules/Compiler/CMakeCommonCompilerMacros.cmake:[0-9]* \(cmake_language\):
+ CMake's support for `import std;` in C\+\+23 and newer is experimental. It
+ is meant only for experimentation and feedback to CMake developers.
+Call Stack \(most recent call first\):
+ .*/Modules/CMakeDetermineCompilerSupport.cmake:[0-9]* \(cmake_create_cxx_import_std\)
+ .*/Modules/CMakeTestCXXCompiler.cmake:[0-9]* \(CMAKE_DETERMINE_COMPILER_SUPPORT\)
+ CMakeLists.txt:[0-9]* \(project\)
+This warning is for project developers. Use -Wno-dev to suppress it.
diff --git a/Tests/RunCMake/CXXModules/examples/import-std-export-no-std-build/CMakeLists.txt b/Tests/RunCMake/CXXModules/examples/import-std-export-no-std-build/CMakeLists.txt
new file mode 100644
index 0000000..89350ef
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/examples/import-std-export-no-std-build/CMakeLists.txt
@@ -0,0 +1,59 @@
+set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD
+ "0e5b6991-d74f-4b3d-a41c-cf096e0b2508")
+
+cmake_minimum_required(VERSION 3.29)
+project(cxx_modules_import_std_export_no_std CXX)
+
+include("${CMAKE_SOURCE_DIR}/../cxx-modules-rules.cmake")
+
+set(CMAKE_NO_STD 1)
+
+add_library(import_std_export_no_std)
+target_sources(import_std_export_no_std
+ PRIVATE
+ uses-std.cxx
+ PUBLIC
+ FILE_SET use_std TYPE CXX_MODULES FILES
+ impl-uses-std.cxx)
+target_compile_features(import_std_export_no_std PUBLIC cxx_std_23)
+set_property(TARGET import_std_export_no_std
+ PROPERTY
+ CXX_MODULE_STD "$<BOOL:$<BUILD_LOCAL_INTERFACE:1>>")
+
+add_executable(main
+ main.cxx)
+target_link_libraries(main PRIVATE import_std_export_no_std)
+
+install(TARGETS import_std_export_no_std
+ EXPORT export
+ ARCHIVE DESTINATION "lib"
+ FILE_SET use_std DESTINATION "lib/cxx/miu")
+export(EXPORT export
+ NAMESPACE CXXModules::
+ FILE "${CMAKE_CURRENT_BINARY_DIR}/import_std_export_no_std-targets.cmake")
+file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/import_std_export_no_std-config.cmake"
+ "include(\"\${CMAKE_CURRENT_LIST_DIR}/import_std_export_no_std-targets.cmake\")
+set(\${CMAKE_FIND_PACKAGE_NAME}_FOUND 1)
+")
+
+add_test(NAME main COMMAND main)
+
+set(generator
+ -G "${CMAKE_GENERATOR}")
+if (CMAKE_GENERATOR_TOOLSET)
+ list(APPEND generator
+ -T "${CMAKE_GENERATOR_TOOLSET}")
+endif ()
+if (CMAKE_GENERATOR_PLATFORM)
+ list(APPEND generator
+ -A "${CMAKE_GENERATOR_PLATFORM}")
+endif ()
+
+add_test(NAME import_std_export_no_std_build
+ COMMAND
+ "${CMAKE_COMMAND}"
+ "-Dexpected_dir=${CMAKE_CURRENT_SOURCE_DIR}"
+ "-Dimport_std_export_no_std_DIR=${CMAKE_CURRENT_BINARY_DIR}"
+ ${generator}
+ -S "${CMAKE_CURRENT_SOURCE_DIR}/test"
+ -B "${CMAKE_CURRENT_BINARY_DIR}/test")
diff --git a/Tests/RunCMake/CXXModules/examples/import-std-export-no-std-build/impl-uses-std.cxx b/Tests/RunCMake/CXXModules/examples/import-std-export-no-std-build/impl-uses-std.cxx
new file mode 100644
index 0000000..ee19332
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/examples/import-std-export-no-std-build/impl-uses-std.cxx
@@ -0,0 +1,3 @@
+export module uses_std;
+
+export int f();
diff --git a/Tests/RunCMake/CXXModules/examples/import-std-export-no-std-build/main.cxx b/Tests/RunCMake/CXXModules/examples/import-std-export-no-std-build/main.cxx
new file mode 100644
index 0000000..a6dd8d8
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/examples/import-std-export-no-std-build/main.cxx
@@ -0,0 +1,6 @@
+import uses_std;
+
+int main(int argc, char* argv[])
+{
+ return f();
+}
diff --git a/Tests/RunCMake/CXXModules/examples/import-std-export-no-std-build/test/CMakeLists.txt b/Tests/RunCMake/CXXModules/examples/import-std-export-no-std-build/test/CMakeLists.txt
new file mode 100644
index 0000000..e37f174
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/examples/import-std-export-no-std-build/test/CMakeLists.txt
@@ -0,0 +1,45 @@
+cmake_minimum_required(VERSION 3.29)
+project(cxx_modules_library NONE)
+
+find_package(import_std_export_no_std REQUIRED)
+
+if (NOT TARGET CXXModules::import_std_export_no_std)
+ message(FATAL_ERROR
+ "Missing imported target")
+endif ()
+
+function (check_property expected property)
+ get_property(actual TARGET CXXModules::import_std_export_no_std
+ PROPERTY "${property}")
+ if (NOT DEFINED actual)
+ if (NOT expected STREQUAL "<UNDEF>")
+ message(SEND_ERROR
+ "Mismatch for ${property}:\n expected: ${expected}\n actual: NOT-DEFINED")
+ endif ()
+ elseif (NOT actual STREQUAL expected)
+ message(SEND_ERROR
+ "Mismatch for ${property}:\n expected: ${expected}\n actual: ${actual}")
+ endif ()
+endfunction ()
+
+check_property("<UNDEF>" "IMPORTED_CXX_MODULES_INCLUDE_DIRECTORIES")
+check_property("<UNDEF>" "IMPORTED_CXX_MODULES_COMPILE_DEFINITIONS")
+check_property("cxx_std_23" "IMPORTED_CXX_MODULES_COMPILE_FEATURES")
+check_property("" "IMPORTED_CXX_MODULES_LINK_LIBRARIES")
+check_property("<UNDEF>" "INTERFACE_LINK_LIBRARIES")
+check_property("$<BOOL:>" "CXX_MODULE_STD")
+
+# Extract the export-dependent targets from the export file.
+file(STRINGS "${import_std_export_no_std_DIR}/import_std_export_no_std-targets.cmake" usage_dependent_targets
+ REGEX "foreach._target ")
+# Rudimentary argument splitting.
+string(REPLACE " " ";" usage_dependent_targets "${usage_dependent_targets}")
+# Remove exported "target" names.
+list(FILTER usage_dependent_targets EXCLUDE REGEX "CXXModules::")
+# Strip quotes.
+string(REPLACE "\"" "" usage_dependent_targets "${usage_dependent_targets}")
+
+if ("__CMAKE::CXX23" IN_LIST usage_dependent_targets)
+ message(SEND_ERROR
+ "The main export requires the '__CMAKE::CXX23' target")
+endif ()
diff --git a/Tests/RunCMake/CXXModules/examples/import-std-export-no-std-build/uses-std.cxx b/Tests/RunCMake/CXXModules/examples/import-std-export-no-std-build/uses-std.cxx
new file mode 100644
index 0000000..bd91093
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/examples/import-std-export-no-std-build/uses-std.cxx
@@ -0,0 +1,8 @@
+module uses_std;
+
+import std;
+
+int f()
+{
+ return 0;
+}
diff --git a/Tests/RunCMake/CXXModules/examples/import-std-export-no-std-install-stderr.txt b/Tests/RunCMake/CXXModules/examples/import-std-export-no-std-install-stderr.txt
new file mode 100644
index 0000000..3589448
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/examples/import-std-export-no-std-install-stderr.txt
@@ -0,0 +1,8 @@
+CMake Warning \(dev\) at .*/Modules/Compiler/CMakeCommonCompilerMacros.cmake:[0-9]* \(cmake_language\):
+ CMake's support for `import std;` in C\+\+23 and newer is experimental. It
+ is meant only for experimentation and feedback to CMake developers.
+Call Stack \(most recent call first\):
+ .*/Modules/CMakeDetermineCompilerSupport.cmake:[0-9]* \(cmake_create_cxx_import_std\)
+ .*/Modules/CMakeTestCXXCompiler.cmake:[0-9]* \(CMAKE_DETERMINE_COMPILER_SUPPORT\)
+ CMakeLists.txt:[0-9]* \(project\)
+This warning is for project developers. Use -Wno-dev to suppress it.
diff --git a/Tests/RunCMake/CXXModules/examples/import-std-export-no-std-install/CMakeLists.txt b/Tests/RunCMake/CXXModules/examples/import-std-export-no-std-install/CMakeLists.txt
new file mode 100644
index 0000000..62d9d91
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/examples/import-std-export-no-std-install/CMakeLists.txt
@@ -0,0 +1,61 @@
+set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD
+ "0e5b6991-d74f-4b3d-a41c-cf096e0b2508")
+
+cmake_minimum_required(VERSION 3.29)
+project(cxx_modules_import_std_export_no_std CXX)
+
+include("${CMAKE_SOURCE_DIR}/../cxx-modules-rules.cmake")
+
+add_library(import_std_export_no_std)
+target_sources(import_std_export_no_std
+ PRIVATE
+ uses-std.cxx
+ PUBLIC
+ FILE_SET use_std TYPE CXX_MODULES FILES
+ impl-uses-std.cxx)
+target_compile_features(import_std_export_no_std PUBLIC cxx_std_23)
+set_property(TARGET import_std_export_no_std
+ PROPERTY
+ CXX_MODULE_STD "$<BOOL:$<BUILD_LOCAL_INTERFACE:1>>")
+
+add_executable(main
+ main.cxx)
+target_link_libraries(main PRIVATE import_std_export_no_std)
+
+install(TARGETS import_std_export_no_std
+ EXPORT export
+ ARCHIVE DESTINATION "lib"
+ FILE_SET use_std DESTINATION "lib/cxx/miu")
+install(
+ EXPORT export
+ NAMESPACE CXXModules::
+ DESTINATION "lib/cmake/import_std_export_no_std"
+ FILE "import_std_export_no_std-targets.cmake")
+file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/import_std_export_no_std-config.cmake"
+ "include(\"\${CMAKE_CURRENT_LIST_DIR}/import_std_export_no_std-targets.cmake\")
+set(\${CMAKE_FIND_PACKAGE_NAME}_FOUND 1)
+")
+install(FILES "${CMAKE_CURRENT_BINARY_DIR}/import_std_export_no_std-config.cmake"
+ DESTINATION "lib/cmake/import_std_export_no_std")
+
+add_test(NAME main COMMAND main)
+
+set(generator
+ -G "${CMAKE_GENERATOR}")
+if (CMAKE_GENERATOR_TOOLSET)
+ list(APPEND generator
+ -T "${CMAKE_GENERATOR_TOOLSET}")
+endif ()
+if (CMAKE_GENERATOR_PLATFORM)
+ list(APPEND generator
+ -A "${CMAKE_GENERATOR_PLATFORM}")
+endif ()
+
+add_test(NAME import_std_export_no_std_build
+ COMMAND
+ "${CMAKE_COMMAND}"
+ "-Dexpected_dir=${CMAKE_INSTALL_PREFIX}/lib/cxx/miu"
+ "-Dimport_std_export_no_std_DIR=${CMAKE_INSTALL_PREFIX}/lib/cmake/import_std_export_no_std"
+ ${generator}
+ -S "${CMAKE_CURRENT_SOURCE_DIR}/test"
+ -B "${CMAKE_CURRENT_BINARY_DIR}/test")
diff --git a/Tests/RunCMake/CXXModules/examples/import-std-export-no-std-install/impl-uses-std.cxx b/Tests/RunCMake/CXXModules/examples/import-std-export-no-std-install/impl-uses-std.cxx
new file mode 100644
index 0000000..ee19332
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/examples/import-std-export-no-std-install/impl-uses-std.cxx
@@ -0,0 +1,3 @@
+export module uses_std;
+
+export int f();
diff --git a/Tests/RunCMake/CXXModules/examples/import-std-export-no-std-install/main.cxx b/Tests/RunCMake/CXXModules/examples/import-std-export-no-std-install/main.cxx
new file mode 100644
index 0000000..a6dd8d8
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/examples/import-std-export-no-std-install/main.cxx
@@ -0,0 +1,6 @@
+import uses_std;
+
+int main(int argc, char* argv[])
+{
+ return f();
+}
diff --git a/Tests/RunCMake/CXXModules/examples/import-std-export-no-std-install/test/CMakeLists.txt b/Tests/RunCMake/CXXModules/examples/import-std-export-no-std-install/test/CMakeLists.txt
new file mode 100644
index 0000000..e37f174
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/examples/import-std-export-no-std-install/test/CMakeLists.txt
@@ -0,0 +1,45 @@
+cmake_minimum_required(VERSION 3.29)
+project(cxx_modules_library NONE)
+
+find_package(import_std_export_no_std REQUIRED)
+
+if (NOT TARGET CXXModules::import_std_export_no_std)
+ message(FATAL_ERROR
+ "Missing imported target")
+endif ()
+
+function (check_property expected property)
+ get_property(actual TARGET CXXModules::import_std_export_no_std
+ PROPERTY "${property}")
+ if (NOT DEFINED actual)
+ if (NOT expected STREQUAL "<UNDEF>")
+ message(SEND_ERROR
+ "Mismatch for ${property}:\n expected: ${expected}\n actual: NOT-DEFINED")
+ endif ()
+ elseif (NOT actual STREQUAL expected)
+ message(SEND_ERROR
+ "Mismatch for ${property}:\n expected: ${expected}\n actual: ${actual}")
+ endif ()
+endfunction ()
+
+check_property("<UNDEF>" "IMPORTED_CXX_MODULES_INCLUDE_DIRECTORIES")
+check_property("<UNDEF>" "IMPORTED_CXX_MODULES_COMPILE_DEFINITIONS")
+check_property("cxx_std_23" "IMPORTED_CXX_MODULES_COMPILE_FEATURES")
+check_property("" "IMPORTED_CXX_MODULES_LINK_LIBRARIES")
+check_property("<UNDEF>" "INTERFACE_LINK_LIBRARIES")
+check_property("$<BOOL:>" "CXX_MODULE_STD")
+
+# Extract the export-dependent targets from the export file.
+file(STRINGS "${import_std_export_no_std_DIR}/import_std_export_no_std-targets.cmake" usage_dependent_targets
+ REGEX "foreach._target ")
+# Rudimentary argument splitting.
+string(REPLACE " " ";" usage_dependent_targets "${usage_dependent_targets}")
+# Remove exported "target" names.
+list(FILTER usage_dependent_targets EXCLUDE REGEX "CXXModules::")
+# Strip quotes.
+string(REPLACE "\"" "" usage_dependent_targets "${usage_dependent_targets}")
+
+if ("__CMAKE::CXX23" IN_LIST usage_dependent_targets)
+ message(SEND_ERROR
+ "The main export requires the '__CMAKE::CXX23' target")
+endif ()
diff --git a/Tests/RunCMake/CXXModules/examples/import-std-export-no-std-install/uses-std.cxx b/Tests/RunCMake/CXXModules/examples/import-std-export-no-std-install/uses-std.cxx
new file mode 100644
index 0000000..6b7e814
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/examples/import-std-export-no-std-install/uses-std.cxx
@@ -0,0 +1,9 @@
+module uses_std;
+import std;
+
+int f()
+{
+ std::string str = "hello!";
+ std::cout << "program: " << str << std::endl;
+ return 0;
+}
diff --git a/Tests/RunCMake/CXXModules/examples/import-std-no-std-property-build-result.txt b/Tests/RunCMake/CXXModules/examples/import-std-no-std-property-build-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/examples/import-std-no-std-property-build-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CXXModules/examples/import-std-no-std-property-build-stdout.txt b/Tests/RunCMake/CXXModules/examples/import-std-no-std-property-build-stdout.txt
new file mode 100644
index 0000000..d473333
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/examples/import-std-no-std-property-build-stdout.txt
@@ -0,0 +1 @@
+((Clang)?module 'std' not found|(MSVC)?could not find module 'std')
diff --git a/Tests/RunCMake/CXXModules/examples/import-std-no-std-property-stderr.txt b/Tests/RunCMake/CXXModules/examples/import-std-no-std-property-stderr.txt
new file mode 100644
index 0000000..3589448
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/examples/import-std-no-std-property-stderr.txt
@@ -0,0 +1,8 @@
+CMake Warning \(dev\) at .*/Modules/Compiler/CMakeCommonCompilerMacros.cmake:[0-9]* \(cmake_language\):
+ CMake's support for `import std;` in C\+\+23 and newer is experimental. It
+ is meant only for experimentation and feedback to CMake developers.
+Call Stack \(most recent call first\):
+ .*/Modules/CMakeDetermineCompilerSupport.cmake:[0-9]* \(cmake_create_cxx_import_std\)
+ .*/Modules/CMakeTestCXXCompiler.cmake:[0-9]* \(CMAKE_DETERMINE_COMPILER_SUPPORT\)
+ CMakeLists.txt:[0-9]* \(project\)
+This warning is for project developers. Use -Wno-dev to suppress it.
diff --git a/Tests/RunCMake/CXXModules/examples/import-std-no-std-property/CMakeLists.txt b/Tests/RunCMake/CXXModules/examples/import-std-no-std-property/CMakeLists.txt
new file mode 100644
index 0000000..a605e95
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/examples/import-std-no-std-property/CMakeLists.txt
@@ -0,0 +1,13 @@
+set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD
+ "0e5b6991-d74f-4b3d-a41c-cf096e0b2508")
+
+cmake_minimum_required(VERSION 3.29)
+project(cxx_modules_import_std_no_std_property CXX)
+
+include("${CMAKE_SOURCE_DIR}/../cxx-modules-rules.cmake")
+
+set(CMAKE_CXX_MODULE_STD 0)
+
+add_executable(main
+ main.cxx)
+target_compile_features(main PRIVATE cxx_std_23)
diff --git a/Tests/RunCMake/CXXModules/examples/import-std-no-std-property/main.cxx b/Tests/RunCMake/CXXModules/examples/import-std-no-std-property/main.cxx
new file mode 100644
index 0000000..fee84f1
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/examples/import-std-no-std-property/main.cxx
@@ -0,0 +1,6 @@
+import std;
+
+int main(int argc, char* argv[])
+{
+ return 0;
+}
diff --git a/Tests/RunCMake/CXXModules/examples/import-std-not-in-export-build-stderr.txt b/Tests/RunCMake/CXXModules/examples/import-std-not-in-export-build-stderr.txt
new file mode 100644
index 0000000..3589448
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/examples/import-std-not-in-export-build-stderr.txt
@@ -0,0 +1,8 @@
+CMake Warning \(dev\) at .*/Modules/Compiler/CMakeCommonCompilerMacros.cmake:[0-9]* \(cmake_language\):
+ CMake's support for `import std;` in C\+\+23 and newer is experimental. It
+ is meant only for experimentation and feedback to CMake developers.
+Call Stack \(most recent call first\):
+ .*/Modules/CMakeDetermineCompilerSupport.cmake:[0-9]* \(cmake_create_cxx_import_std\)
+ .*/Modules/CMakeTestCXXCompiler.cmake:[0-9]* \(CMAKE_DETERMINE_COMPILER_SUPPORT\)
+ CMakeLists.txt:[0-9]* \(project\)
+This warning is for project developers. Use -Wno-dev to suppress it.
diff --git a/Tests/RunCMake/CXXModules/examples/import-std-not-in-export-build/CMakeLists.txt b/Tests/RunCMake/CXXModules/examples/import-std-not-in-export-build/CMakeLists.txt
new file mode 100644
index 0000000..3112002
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/examples/import-std-not-in-export-build/CMakeLists.txt
@@ -0,0 +1,54 @@
+set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD
+ "0e5b6991-d74f-4b3d-a41c-cf096e0b2508")
+
+cmake_minimum_required(VERSION 3.29)
+project(cxx_modules_import_std_not_in_export CXX)
+
+include("${CMAKE_SOURCE_DIR}/../cxx-modules-rules.cmake")
+
+set(CMAKE_CXX_MODULE_STD 1)
+
+add_library(import_std_not_in_export)
+target_sources(import_std_not_in_export
+ PUBLIC
+ FILE_SET use_std TYPE CXX_MODULES FILES
+ uses-std.cxx)
+target_compile_features(import_std_not_in_export PUBLIC cxx_std_23)
+
+add_executable(main
+ main.cxx)
+target_link_libraries(main PRIVATE import_std_not_in_export)
+
+install(TARGETS import_std_not_in_export
+ EXPORT export
+ ARCHIVE DESTINATION "lib"
+ FILE_SET use_std DESTINATION "lib/cxx/miu")
+export(EXPORT export
+ NAMESPACE CXXModules::
+ FILE "${CMAKE_CURRENT_BINARY_DIR}/import_std_not_in_export-targets.cmake")
+file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/import_std_not_in_export-config.cmake"
+ "include(\"\${CMAKE_CURRENT_LIST_DIR}/import_std_not_in_export-targets.cmake\")
+set(\${CMAKE_FIND_PACKAGE_NAME}_FOUND 1)
+")
+
+add_test(NAME main COMMAND main)
+
+set(generator
+ -G "${CMAKE_GENERATOR}")
+if (CMAKE_GENERATOR_TOOLSET)
+ list(APPEND generator
+ -T "${CMAKE_GENERATOR_TOOLSET}")
+endif ()
+if (CMAKE_GENERATOR_PLATFORM)
+ list(APPEND generator
+ -A "${CMAKE_GENERATOR_PLATFORM}")
+endif ()
+
+add_test(NAME import_std_not_in_export_build
+ COMMAND
+ "${CMAKE_COMMAND}"
+ "-Dexpected_dir=${CMAKE_CURRENT_SOURCE_DIR}"
+ "-Dimport_std_not_in_export_DIR=${CMAKE_CURRENT_BINARY_DIR}"
+ ${generator}
+ -S "${CMAKE_CURRENT_SOURCE_DIR}/test"
+ -B "${CMAKE_CURRENT_BINARY_DIR}/test")
diff --git a/Tests/RunCMake/CXXModules/examples/import-std-not-in-export-build/main.cxx b/Tests/RunCMake/CXXModules/examples/import-std-not-in-export-build/main.cxx
new file mode 100644
index 0000000..a6dd8d8
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/examples/import-std-not-in-export-build/main.cxx
@@ -0,0 +1,6 @@
+import uses_std;
+
+int main(int argc, char* argv[])
+{
+ return f();
+}
diff --git a/Tests/RunCMake/CXXModules/examples/import-std-not-in-export-build/test/CMakeLists.txt b/Tests/RunCMake/CXXModules/examples/import-std-not-in-export-build/test/CMakeLists.txt
new file mode 100644
index 0000000..4e994d2
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/examples/import-std-not-in-export-build/test/CMakeLists.txt
@@ -0,0 +1,45 @@
+cmake_minimum_required(VERSION 3.29)
+project(cxx_modules_library NONE)
+
+find_package(import_std_not_in_export REQUIRED)
+
+if (NOT TARGET CXXModules::import_std_not_in_export)
+ message(FATAL_ERROR
+ "Missing imported target")
+endif ()
+
+function (check_property expected property)
+ get_property(actual TARGET CXXModules::import_std_not_in_export
+ PROPERTY "${property}")
+ if (NOT DEFINED actual)
+ if (NOT expected STREQUAL "<UNDEF>")
+ message(SEND_ERROR
+ "Mismatch for ${property}:\n expected: ${expected}\n actual: NOT-DEFINED")
+ endif ()
+ elseif (NOT actual STREQUAL expected)
+ message(SEND_ERROR
+ "Mismatch for ${property}:\n expected: ${expected}\n actual: ${actual}")
+ endif ()
+endfunction ()
+
+check_property("<UNDEF>" "IMPORTED_CXX_MODULES_INCLUDE_DIRECTORIES")
+check_property("<UNDEF>" "IMPORTED_CXX_MODULES_COMPILE_DEFINITIONS")
+check_property("cxx_std_23" "IMPORTED_CXX_MODULES_COMPILE_FEATURES")
+check_property("" "IMPORTED_CXX_MODULES_LINK_LIBRARIES")
+check_property("<UNDEF>" "INTERFACE_LINK_LIBRARIES")
+check_property("1" "CXX_MODULE_STD")
+
+# Extract the export-dependent targets from the export file.
+file(STRINGS "${import_std_not_in_export_DIR}/import_std_not_in_export-targets.cmake" usage_dependent_targets
+ REGEX "foreach._target ")
+# Rudimentary argument splitting.
+string(REPLACE " " ";" usage_dependent_targets "${usage_dependent_targets}")
+# Remove exported "target" names.
+list(FILTER usage_dependent_targets EXCLUDE REGEX "CXXModules::")
+# Strip quotes.
+string(REPLACE "\"" "" usage_dependent_targets "${usage_dependent_targets}")
+
+if ("__CMAKE::CXX23" IN_LIST usage_dependent_targets)
+ message(SEND_ERROR
+ "The main export requires the '__CMAKE::CXX23' target")
+endif ()
diff --git a/Tests/RunCMake/CXXModules/examples/import-std-not-in-export-build/uses-std.cxx b/Tests/RunCMake/CXXModules/examples/import-std-not-in-export-build/uses-std.cxx
new file mode 100644
index 0000000..aa45dd1
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/examples/import-std-not-in-export-build/uses-std.cxx
@@ -0,0 +1,7 @@
+export module uses_std;
+import std;
+
+export int f()
+{
+ return 0;
+}
diff --git a/Tests/RunCMake/CXXModules/examples/import-std-not-in-export-install-stderr.txt b/Tests/RunCMake/CXXModules/examples/import-std-not-in-export-install-stderr.txt
new file mode 100644
index 0000000..3589448
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/examples/import-std-not-in-export-install-stderr.txt
@@ -0,0 +1,8 @@
+CMake Warning \(dev\) at .*/Modules/Compiler/CMakeCommonCompilerMacros.cmake:[0-9]* \(cmake_language\):
+ CMake's support for `import std;` in C\+\+23 and newer is experimental. It
+ is meant only for experimentation and feedback to CMake developers.
+Call Stack \(most recent call first\):
+ .*/Modules/CMakeDetermineCompilerSupport.cmake:[0-9]* \(cmake_create_cxx_import_std\)
+ .*/Modules/CMakeTestCXXCompiler.cmake:[0-9]* \(CMAKE_DETERMINE_COMPILER_SUPPORT\)
+ CMakeLists.txt:[0-9]* \(project\)
+This warning is for project developers. Use -Wno-dev to suppress it.
diff --git a/Tests/RunCMake/CXXModules/examples/import-std-not-in-export-install/CMakeLists.txt b/Tests/RunCMake/CXXModules/examples/import-std-not-in-export-install/CMakeLists.txt
new file mode 100644
index 0000000..788ea84
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/examples/import-std-not-in-export-install/CMakeLists.txt
@@ -0,0 +1,58 @@
+set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD
+ "0e5b6991-d74f-4b3d-a41c-cf096e0b2508")
+
+cmake_minimum_required(VERSION 3.29)
+project(cxx_modules_import_std_not_in_export CXX)
+
+include("${CMAKE_SOURCE_DIR}/../cxx-modules-rules.cmake")
+
+set(CMAKE_CXX_MODULE_STD 1)
+
+add_library(import_std_not_in_export)
+target_sources(import_std_not_in_export
+ PUBLIC
+ FILE_SET use_std TYPE CXX_MODULES FILES
+ uses-std.cxx)
+target_compile_features(import_std_not_in_export PUBLIC cxx_std_23)
+
+add_executable(main
+ main.cxx)
+target_link_libraries(main PRIVATE import_std_not_in_export)
+
+install(TARGETS import_std_not_in_export
+ EXPORT export
+ ARCHIVE DESTINATION "lib"
+ FILE_SET use_std DESTINATION "lib/cxx/miu")
+install(
+ EXPORT export
+ NAMESPACE CXXModules::
+ DESTINATION "lib/cmake/import_std_not_in_export"
+ FILE "import_std_not_in_export-targets.cmake")
+file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/import_std_not_in_export-config.cmake"
+ "include(\"\${CMAKE_CURRENT_LIST_DIR}/import_std_not_in_export-targets.cmake\")
+set(\${CMAKE_FIND_PACKAGE_NAME}_FOUND 1)
+")
+install(FILES "${CMAKE_CURRENT_BINARY_DIR}/import_std_not_in_export-config.cmake"
+ DESTINATION "lib/cmake/import_std_not_in_export")
+
+add_test(NAME main COMMAND main)
+
+set(generator
+ -G "${CMAKE_GENERATOR}")
+if (CMAKE_GENERATOR_TOOLSET)
+ list(APPEND generator
+ -T "${CMAKE_GENERATOR_TOOLSET}")
+endif ()
+if (CMAKE_GENERATOR_PLATFORM)
+ list(APPEND generator
+ -A "${CMAKE_GENERATOR_PLATFORM}")
+endif ()
+
+add_test(NAME import_std_not_in_export_build
+ COMMAND
+ "${CMAKE_COMMAND}"
+ "-Dexpected_dir=${CMAKE_INSTALL_PREFIX}/lib/cxx/miu"
+ "-Dimport_std_not_in_export_DIR=${CMAKE_INSTALL_PREFIX}/lib/cmake/import_std_not_in_export"
+ ${generator}
+ -S "${CMAKE_CURRENT_SOURCE_DIR}/test"
+ -B "${CMAKE_CURRENT_BINARY_DIR}/test")
diff --git a/Tests/RunCMake/CXXModules/examples/import-std-not-in-export-install/main.cxx b/Tests/RunCMake/CXXModules/examples/import-std-not-in-export-install/main.cxx
new file mode 100644
index 0000000..a6dd8d8
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/examples/import-std-not-in-export-install/main.cxx
@@ -0,0 +1,6 @@
+import uses_std;
+
+int main(int argc, char* argv[])
+{
+ return f();
+}
diff --git a/Tests/RunCMake/CXXModules/examples/import-std-not-in-export-install/test/CMakeLists.txt b/Tests/RunCMake/CXXModules/examples/import-std-not-in-export-install/test/CMakeLists.txt
new file mode 100644
index 0000000..4e994d2
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/examples/import-std-not-in-export-install/test/CMakeLists.txt
@@ -0,0 +1,45 @@
+cmake_minimum_required(VERSION 3.29)
+project(cxx_modules_library NONE)
+
+find_package(import_std_not_in_export REQUIRED)
+
+if (NOT TARGET CXXModules::import_std_not_in_export)
+ message(FATAL_ERROR
+ "Missing imported target")
+endif ()
+
+function (check_property expected property)
+ get_property(actual TARGET CXXModules::import_std_not_in_export
+ PROPERTY "${property}")
+ if (NOT DEFINED actual)
+ if (NOT expected STREQUAL "<UNDEF>")
+ message(SEND_ERROR
+ "Mismatch for ${property}:\n expected: ${expected}\n actual: NOT-DEFINED")
+ endif ()
+ elseif (NOT actual STREQUAL expected)
+ message(SEND_ERROR
+ "Mismatch for ${property}:\n expected: ${expected}\n actual: ${actual}")
+ endif ()
+endfunction ()
+
+check_property("<UNDEF>" "IMPORTED_CXX_MODULES_INCLUDE_DIRECTORIES")
+check_property("<UNDEF>" "IMPORTED_CXX_MODULES_COMPILE_DEFINITIONS")
+check_property("cxx_std_23" "IMPORTED_CXX_MODULES_COMPILE_FEATURES")
+check_property("" "IMPORTED_CXX_MODULES_LINK_LIBRARIES")
+check_property("<UNDEF>" "INTERFACE_LINK_LIBRARIES")
+check_property("1" "CXX_MODULE_STD")
+
+# Extract the export-dependent targets from the export file.
+file(STRINGS "${import_std_not_in_export_DIR}/import_std_not_in_export-targets.cmake" usage_dependent_targets
+ REGEX "foreach._target ")
+# Rudimentary argument splitting.
+string(REPLACE " " ";" usage_dependent_targets "${usage_dependent_targets}")
+# Remove exported "target" names.
+list(FILTER usage_dependent_targets EXCLUDE REGEX "CXXModules::")
+# Strip quotes.
+string(REPLACE "\"" "" usage_dependent_targets "${usage_dependent_targets}")
+
+if ("__CMAKE::CXX23" IN_LIST usage_dependent_targets)
+ message(SEND_ERROR
+ "The main export requires the '__CMAKE::CXX23' target")
+endif ()
diff --git a/Tests/RunCMake/CXXModules/examples/import-std-not-in-export-install/uses-std.cxx b/Tests/RunCMake/CXXModules/examples/import-std-not-in-export-install/uses-std.cxx
new file mode 100644
index 0000000..aa45dd1
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/examples/import-std-not-in-export-install/uses-std.cxx
@@ -0,0 +1,7 @@
+export module uses_std;
+import std;
+
+export int f()
+{
+ return 0;
+}
diff --git a/Tests/RunCMake/CXXModules/examples/import-std-stderr.txt b/Tests/RunCMake/CXXModules/examples/import-std-stderr.txt
new file mode 100644
index 0000000..3589448
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/examples/import-std-stderr.txt
@@ -0,0 +1,8 @@
+CMake Warning \(dev\) at .*/Modules/Compiler/CMakeCommonCompilerMacros.cmake:[0-9]* \(cmake_language\):
+ CMake's support for `import std;` in C\+\+23 and newer is experimental. It
+ is meant only for experimentation and feedback to CMake developers.
+Call Stack \(most recent call first\):
+ .*/Modules/CMakeDetermineCompilerSupport.cmake:[0-9]* \(cmake_create_cxx_import_std\)
+ .*/Modules/CMakeTestCXXCompiler.cmake:[0-9]* \(CMAKE_DETERMINE_COMPILER_SUPPORT\)
+ CMakeLists.txt:[0-9]* \(project\)
+This warning is for project developers. Use -Wno-dev to suppress it.
diff --git a/Tests/RunCMake/CXXModules/examples/import-std-transitive-not-in-export-build-stderr.txt b/Tests/RunCMake/CXXModules/examples/import-std-transitive-not-in-export-build-stderr.txt
new file mode 100644
index 0000000..3589448
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/examples/import-std-transitive-not-in-export-build-stderr.txt
@@ -0,0 +1,8 @@
+CMake Warning \(dev\) at .*/Modules/Compiler/CMakeCommonCompilerMacros.cmake:[0-9]* \(cmake_language\):
+ CMake's support for `import std;` in C\+\+23 and newer is experimental. It
+ is meant only for experimentation and feedback to CMake developers.
+Call Stack \(most recent call first\):
+ .*/Modules/CMakeDetermineCompilerSupport.cmake:[0-9]* \(cmake_create_cxx_import_std\)
+ .*/Modules/CMakeTestCXXCompiler.cmake:[0-9]* \(CMAKE_DETERMINE_COMPILER_SUPPORT\)
+ CMakeLists.txt:[0-9]* \(project\)
+This warning is for project developers. Use -Wno-dev to suppress it.
diff --git a/Tests/RunCMake/CXXModules/examples/import-std-transitive-not-in-export-install-stderr.txt b/Tests/RunCMake/CXXModules/examples/import-std-transitive-not-in-export-install-stderr.txt
new file mode 100644
index 0000000..3589448
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/examples/import-std-transitive-not-in-export-install-stderr.txt
@@ -0,0 +1,8 @@
+CMake Warning \(dev\) at .*/Modules/Compiler/CMakeCommonCompilerMacros.cmake:[0-9]* \(cmake_language\):
+ CMake's support for `import std;` in C\+\+23 and newer is experimental. It
+ is meant only for experimentation and feedback to CMake developers.
+Call Stack \(most recent call first\):
+ .*/Modules/CMakeDetermineCompilerSupport.cmake:[0-9]* \(cmake_create_cxx_import_std\)
+ .*/Modules/CMakeTestCXXCompiler.cmake:[0-9]* \(CMAKE_DETERMINE_COMPILER_SUPPORT\)
+ CMakeLists.txt:[0-9]* \(project\)
+This warning is for project developers. Use -Wno-dev to suppress it.
diff --git a/Tests/RunCMake/CXXModules/examples/import-std-transitive/CMakeLists.txt b/Tests/RunCMake/CXXModules/examples/import-std-transitive/CMakeLists.txt
new file mode 100644
index 0000000..2894d67
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/examples/import-std-transitive/CMakeLists.txt
@@ -0,0 +1,28 @@
+set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD
+ "0e5b6991-d74f-4b3d-a41c-cf096e0b2508")
+
+cmake_minimum_required(VERSION 3.29)
+
+if (EXPORT_NO_STD)
+ # Block making C++ `import std` targets.
+ add_library(__CMAKE::CXX23 IMPORTED INTERFACE)
+endif ()
+
+project(cxx_modules_import_std_transitive CXX)
+
+include("${CMAKE_SOURCE_DIR}/../cxx-modules-rules.cmake")
+
+if (EXPORT_NO_STD)
+ set(package "import_std_export_no_std")
+else ()
+ set(package "import_std_not_in_export")
+endif ()
+find_package("${package}" REQUIRED)
+
+set(CMAKE_CXX_MODULE_STD 0)
+
+add_executable(main
+ main.cxx)
+target_link_libraries(main PRIVATE "CXXModules::${package}")
+
+add_test(NAME main COMMAND main)
diff --git a/Tests/RunCMake/CXXModules/examples/import-std-transitive/main.cxx b/Tests/RunCMake/CXXModules/examples/import-std-transitive/main.cxx
new file mode 100644
index 0000000..a6dd8d8
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/examples/import-std-transitive/main.cxx
@@ -0,0 +1,6 @@
+import uses_std;
+
+int main(int argc, char* argv[])
+{
+ return f();
+}
diff --git a/Tests/RunCMake/CXXModules/examples/import-std/CMakeLists.txt b/Tests/RunCMake/CXXModules/examples/import-std/CMakeLists.txt
new file mode 100644
index 0000000..bffcd66
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/examples/import-std/CMakeLists.txt
@@ -0,0 +1,15 @@
+set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD
+ "0e5b6991-d74f-4b3d-a41c-cf096e0b2508")
+
+cmake_minimum_required(VERSION 3.29)
+project(cxx_modules_import_std CXX)
+
+include("${CMAKE_SOURCE_DIR}/../cxx-modules-rules.cmake")
+
+set(CMAKE_CXX_MODULE_STD 1)
+
+add_executable(main
+ main.cxx)
+target_compile_features(main PRIVATE cxx_std_23)
+
+add_test(NAME main COMMAND main)
diff --git a/Tests/RunCMake/CXXModules/examples/import-std/main.cxx b/Tests/RunCMake/CXXModules/examples/import-std/main.cxx
new file mode 100644
index 0000000..6dafd01
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/examples/import-std/main.cxx
@@ -0,0 +1,10 @@
+import std;
+
+int main(int argc, char* argv[])
+{
+ if (argc > 0 && argv[0]) {
+ std::string argv0 = argv[0];
+ std::cout << "program: " << argv0 << std::endl;
+ }
+ return 0;
+}
diff --git a/Tests/RunCMake/CXXModules/examples/vs-without-flags/CMakeLists.txt b/Tests/RunCMake/CXXModules/examples/vs-without-flags/CMakeLists.txt
index 0d18a66..c5958df 100644
--- a/Tests/RunCMake/CXXModules/examples/vs-without-flags/CMakeLists.txt
+++ b/Tests/RunCMake/CXXModules/examples/vs-without-flags/CMakeLists.txt
@@ -3,7 +3,7 @@
include("${CMAKE_SOURCE_DIR}/../cxx-modules-rules.cmake")
-set(CMAKE_CXX_STANDARD 23)
+set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
set(CMAKE_CXX_SCAN_FOR_MODULES ON)
diff --git a/Tests/RunCMake/CompilerChange/CompilerPath-stdout.txt b/Tests/RunCMake/CompilerChange/CompilerPath-stdout.txt
new file mode 100644
index 0000000..bf7e220
--- /dev/null
+++ b/Tests/RunCMake/CompilerChange/CompilerPath-stdout.txt
@@ -0,0 +1,2 @@
+-- CMAKE_C_COMPILER is '[^']*/Tests/RunCMake/CompilerChange/cc1.sh'
+-- CACHE_ENTRY='cached'
diff --git a/Tests/RunCMake/CompilerChange/CompilerPath.cmake b/Tests/RunCMake/CompilerChange/CompilerPath.cmake
new file mode 100644
index 0000000..26cb63d
--- /dev/null
+++ b/Tests/RunCMake/CompilerChange/CompilerPath.cmake
@@ -0,0 +1,3 @@
+enable_language(C)
+message(STATUS "CMAKE_C_COMPILER is '${CMAKE_C_COMPILER}'")
+message(STATUS "CACHE_ENTRY='${CACHE_ENTRY}'")
diff --git a/Tests/RunCMake/CompilerChange/EmptyCompiler-override.cmake b/Tests/RunCMake/CompilerChange/EmptyCompiler-override.cmake
index 28d29e0..c715d4a 100644
--- a/Tests/RunCMake/CompilerChange/EmptyCompiler-override.cmake
+++ b/Tests/RunCMake/CompilerChange/EmptyCompiler-override.cmake
@@ -1,2 +1 @@
-message(STATUS "CMAKE_C_COMPILER is \"${CMAKE_C_COMPILER}\"")
-file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/cc.cmake" "set(CMAKE_C_COMPILER \"${CMAKE_C_COMPILER}\")\n")
+message(STATUS "CMAKE_C_COMPILER is '${CMAKE_C_COMPILER}'")
diff --git a/Tests/RunCMake/CompilerChange/EmptyCompiler-stdout.txt b/Tests/RunCMake/CompilerChange/EmptyCompiler-stdout.txt
new file mode 100644
index 0000000..caf6b07
--- /dev/null
+++ b/Tests/RunCMake/CompilerChange/EmptyCompiler-stdout.txt
@@ -0,0 +1,3 @@
+-- CMAKE_C_COMPILER is '[^']*/Tests/RunCMake/CompilerChange/cc2.sh'
+.*
+-- CMAKE_C_COMPILER is 'CMAKE_C_COMPILER-NOTFOUND'
diff --git a/Tests/RunCMake/CompilerChange/FirstCompiler-stdout.txt b/Tests/RunCMake/CompilerChange/FirstCompiler-stdout.txt
index 17621b7..137b1d0 100644
--- a/Tests/RunCMake/CompilerChange/FirstCompiler-stdout.txt
+++ b/Tests/RunCMake/CompilerChange/FirstCompiler-stdout.txt
@@ -1 +1 @@
--- CMAKE_C_COMPILER is ".*/Tests/RunCMake/CompilerChange/cc1.sh"
+-- CMAKE_C_COMPILER is '[^']*/Tests/RunCMake/CompilerChange/cc1.sh'
diff --git a/Tests/RunCMake/CompilerChange/FirstCompiler.cmake b/Tests/RunCMake/CompilerChange/FirstCompiler.cmake
index c87ec49..df20bdc 100644
--- a/Tests/RunCMake/CompilerChange/FirstCompiler.cmake
+++ b/Tests/RunCMake/CompilerChange/FirstCompiler.cmake
@@ -1,3 +1,2 @@
enable_language(C)
-message(STATUS "CMAKE_C_COMPILER is \"${CMAKE_C_COMPILER}\"")
-file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/cc.cmake" "set(CMAKE_C_COMPILER \"${CMAKE_C_COMPILER}\")\n")
+message(STATUS "CMAKE_C_COMPILER is '${CMAKE_C_COMPILER}'")
diff --git a/Tests/RunCMake/CompilerChange/RunCMakeTest.cmake b/Tests/RunCMake/CompilerChange/RunCMakeTest.cmake
index 5bb2821..4178de9 100644
--- a/Tests/RunCMake/CompilerChange/RunCMakeTest.cmake
+++ b/Tests/RunCMake/CompilerChange/RunCMakeTest.cmake
@@ -25,34 +25,23 @@
configure_file(${ccIn} ${cc1} @ONLY)
configure_file(${ccIn} ${cc2} @ONLY)
-# Use a single build tree for remaining tests without cleaning.
-set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/ChangeCompiler-build)
-set(RunCMake_TEST_NO_CLEAN 1)
-file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}")
+block()
+ set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/ChangeCompiler-build)
+ set(ENV{RunCMake_TEST} "FirstCompiler")
+ run_cmake_with_options(FirstCompiler -DCMAKE_C_COMPILER=${cc1})
+ set(RunCMake_TEST_NO_CLEAN 1)
+ set(ENV{RunCMake_TEST} "SecondCompiler")
+ run_cmake_with_options(SecondCompiler -DCMAKE_C_COMPILER=${cc2})
+ set(ENV{RunCMake_TEST} "EmptyCompiler")
+ run_cmake_with_options(EmptyCompiler -DCMAKE_C_COMPILER=)
+endblock()
-# Check build with compiler wrapper 1.
-set(RunCMake_TEST_OPTIONS -DCMAKE_C_COMPILER=${cc1})
-set(ENV{RunCMake_TEST} "FirstCompiler")
-run_cmake(FirstCompiler)
-include(${RunCMake_TEST_BINARY_DIR}/cc.cmake)
-if(NOT "${CMAKE_C_COMPILER}" STREQUAL "${cc1}")
- message(FATAL_ERROR "FirstCompiler built with compiler:\n ${CMAKE_C_COMPILER}\nand not with:\n ${cc1}")
-endif()
-
-# Check rebuild with compiler wrapper 2.
-set(RunCMake_TEST_OPTIONS -DCMAKE_C_COMPILER=${cc2})
-set(ENV{RunCMake_TEST} "SecondCompiler")
-run_cmake(SecondCompiler)
-include(${RunCMake_TEST_BINARY_DIR}/cc.cmake)
-if(NOT "${CMAKE_C_COMPILER}" STREQUAL "${cc2}")
- message(FATAL_ERROR "SecondCompiler built with compiler:\n ${CMAKE_C_COMPILER}\nand not with:\n ${cc2}")
-endif()
-
-# Check failure with an empty compiler string.
-set(RunCMake_TEST_OPTIONS -DCMAKE_C_COMPILER=)
-set(ENV{RunCMake_TEST} "EmptyCompiler")
-run_cmake(EmptyCompiler)
-include(${RunCMake_TEST_BINARY_DIR}/cc.cmake)
-if(NOT "${CMAKE_C_COMPILER}" STREQUAL "${cc3}")
- message(FATAL_ERROR "Empty built with compiler:\n ${CMAKE_C_COMPILER}\nand not with:\n ${cc3}")
-endif()
+block()
+ set(cc1_dot ${RunCMake_BINARY_DIR}/./cc1.sh)
+ set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/CompilerPath-build)
+ set(RunCMake_TEST_VARIANT_DESCRIPTION "-step1")
+ run_cmake_with_options(CompilerPath "-DCMAKE_C_COMPILER=${cc1_dot}" -DCACHE_ENTRY=cached)
+ set(RunCMake_TEST_NO_CLEAN 1)
+ set(RunCMake_TEST_VARIANT_DESCRIPTION "-step2")
+ run_cmake_with_options(CompilerPath "-DCMAKE_C_COMPILER=${cc1_dot}")
+endblock()
diff --git a/Tests/RunCMake/CompilerChange/SecondCompiler-stdout.txt b/Tests/RunCMake/CompilerChange/SecondCompiler-stdout.txt
index 26ca964..7f90526 100644
--- a/Tests/RunCMake/CompilerChange/SecondCompiler-stdout.txt
+++ b/Tests/RunCMake/CompilerChange/SecondCompiler-stdout.txt
@@ -1 +1,3 @@
--- CMAKE_C_COMPILER is ".*/Tests/RunCMake/CompilerChange/cc2.sh"
+-- CMAKE_C_COMPILER is '[^']*/Tests/RunCMake/CompilerChange/cc1.sh'
+.*
+-- CMAKE_C_COMPILER is '[^']*/Tests/RunCMake/CompilerChange/cc2.sh'
diff --git a/Tests/RunCMake/CompilerChange/SecondCompiler.cmake b/Tests/RunCMake/CompilerChange/SecondCompiler.cmake
index c87ec49..df20bdc 100644
--- a/Tests/RunCMake/CompilerChange/SecondCompiler.cmake
+++ b/Tests/RunCMake/CompilerChange/SecondCompiler.cmake
@@ -1,3 +1,2 @@
enable_language(C)
-message(STATUS "CMAKE_C_COMPILER is \"${CMAKE_C_COMPILER}\"")
-file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/cc.cmake" "set(CMAKE_C_COMPILER \"${CMAKE_C_COMPILER}\")\n")
+message(STATUS "CMAKE_C_COMPILER is '${CMAKE_C_COMPILER}'")
diff --git a/Tests/RunCMake/GenerateExportHeader/reference/Cygwin/libshared_export.h b/Tests/RunCMake/GenerateExportHeader/reference/Cygwin/libshared_export.h
index dac4fda..e0e423d 100644
--- a/Tests/RunCMake/GenerateExportHeader/reference/Cygwin/libshared_export.h
+++ b/Tests/RunCMake/GenerateExportHeader/reference/Cygwin/libshared_export.h
@@ -33,6 +33,7 @@
# define LIBSHARED_DEPRECATED_NO_EXPORT LIBSHARED_NO_EXPORT LIBSHARED_DEPRECATED
#endif
+/* NOLINTNEXTLINE(readability-avoid-unconditional-preprocessor-if) */
#if 0 /* DEFINE_NO_DEPRECATED */
# ifndef LIBSHARED_NO_DEPRECATED
# define LIBSHARED_NO_DEPRECATED
diff --git a/Tests/RunCMake/GenerateExportHeader/reference/Cygwin/libstatic_export.h b/Tests/RunCMake/GenerateExportHeader/reference/Cygwin/libstatic_export.h
index b6e2a4a..cfc1187 100644
--- a/Tests/RunCMake/GenerateExportHeader/reference/Cygwin/libstatic_export.h
+++ b/Tests/RunCMake/GenerateExportHeader/reference/Cygwin/libstatic_export.h
@@ -33,6 +33,7 @@
# define LIBSTATIC_DEPRECATED_NO_EXPORT LIBSTATIC_NO_EXPORT LIBSTATIC_DEPRECATED
#endif
+/* NOLINTNEXTLINE(readability-avoid-unconditional-preprocessor-if) */
#if 0 /* DEFINE_NO_DEPRECATED */
# ifndef LIBSTATIC_NO_DEPRECATED
# define LIBSTATIC_NO_DEPRECATED
diff --git a/Tests/RunCMake/GenerateExportHeader/reference/Empty/libshared_export.h b/Tests/RunCMake/GenerateExportHeader/reference/Empty/libshared_export.h
index 0b1dcba..e2c132d 100644
--- a/Tests/RunCMake/GenerateExportHeader/reference/Empty/libshared_export.h
+++ b/Tests/RunCMake/GenerateExportHeader/reference/Empty/libshared_export.h
@@ -33,6 +33,7 @@
# define LIBSHARED_DEPRECATED_NO_EXPORT LIBSHARED_NO_EXPORT LIBSHARED_DEPRECATED
#endif
+/* NOLINTNEXTLINE(readability-avoid-unconditional-preprocessor-if) */
#if 0 /* DEFINE_NO_DEPRECATED */
# ifndef LIBSHARED_NO_DEPRECATED
# define LIBSHARED_NO_DEPRECATED
diff --git a/Tests/RunCMake/GenerateExportHeader/reference/Empty/libstatic_export.h b/Tests/RunCMake/GenerateExportHeader/reference/Empty/libstatic_export.h
index 5e3ac9f..b54eef5 100644
--- a/Tests/RunCMake/GenerateExportHeader/reference/Empty/libstatic_export.h
+++ b/Tests/RunCMake/GenerateExportHeader/reference/Empty/libstatic_export.h
@@ -33,6 +33,7 @@
# define LIBSTATIC_DEPRECATED_NO_EXPORT LIBSTATIC_NO_EXPORT LIBSTATIC_DEPRECATED
#endif
+/* NOLINTNEXTLINE(readability-avoid-unconditional-preprocessor-if) */
#if 0 /* DEFINE_NO_DEPRECATED */
# ifndef LIBSTATIC_NO_DEPRECATED
# define LIBSTATIC_NO_DEPRECATED
diff --git a/Tests/RunCMake/GenerateExportHeader/reference/MinGW/libshared_export.h b/Tests/RunCMake/GenerateExportHeader/reference/MinGW/libshared_export.h
index 3ba2d2e..6013dcd 100644
--- a/Tests/RunCMake/GenerateExportHeader/reference/MinGW/libshared_export.h
+++ b/Tests/RunCMake/GenerateExportHeader/reference/MinGW/libshared_export.h
@@ -33,6 +33,7 @@
# define LIBSHARED_DEPRECATED_NO_EXPORT LIBSHARED_NO_EXPORT LIBSHARED_DEPRECATED
#endif
+/* NOLINTNEXTLINE(readability-avoid-unconditional-preprocessor-if) */
#if 0 /* DEFINE_NO_DEPRECATED */
# ifndef LIBSHARED_NO_DEPRECATED
# define LIBSHARED_NO_DEPRECATED
diff --git a/Tests/RunCMake/GenerateExportHeader/reference/MinGW/libstatic_export.h b/Tests/RunCMake/GenerateExportHeader/reference/MinGW/libstatic_export.h
index 3c7e093..7a5a573 100644
--- a/Tests/RunCMake/GenerateExportHeader/reference/MinGW/libstatic_export.h
+++ b/Tests/RunCMake/GenerateExportHeader/reference/MinGW/libstatic_export.h
@@ -33,6 +33,7 @@
# define LIBSTATIC_DEPRECATED_NO_EXPORT LIBSTATIC_NO_EXPORT LIBSTATIC_DEPRECATED
#endif
+/* NOLINTNEXTLINE(readability-avoid-unconditional-preprocessor-if) */
#if 0 /* DEFINE_NO_DEPRECATED */
# ifndef LIBSTATIC_NO_DEPRECATED
# define LIBSTATIC_NO_DEPRECATED
diff --git a/Tests/RunCMake/GenerateExportHeader/reference/UNIX/libshared_export.h b/Tests/RunCMake/GenerateExportHeader/reference/UNIX/libshared_export.h
index 11f8042..388dbc9 100644
--- a/Tests/RunCMake/GenerateExportHeader/reference/UNIX/libshared_export.h
+++ b/Tests/RunCMake/GenerateExportHeader/reference/UNIX/libshared_export.h
@@ -33,6 +33,7 @@
# define LIBSHARED_DEPRECATED_NO_EXPORT LIBSHARED_NO_EXPORT LIBSHARED_DEPRECATED
#endif
+/* NOLINTNEXTLINE(readability-avoid-unconditional-preprocessor-if) */
#if 0 /* DEFINE_NO_DEPRECATED */
# ifndef LIBSHARED_NO_DEPRECATED
# define LIBSHARED_NO_DEPRECATED
diff --git a/Tests/RunCMake/GenerateExportHeader/reference/UNIX/libstatic_export.h b/Tests/RunCMake/GenerateExportHeader/reference/UNIX/libstatic_export.h
index b6e2a4a..cfc1187 100644
--- a/Tests/RunCMake/GenerateExportHeader/reference/UNIX/libstatic_export.h
+++ b/Tests/RunCMake/GenerateExportHeader/reference/UNIX/libstatic_export.h
@@ -33,6 +33,7 @@
# define LIBSTATIC_DEPRECATED_NO_EXPORT LIBSTATIC_NO_EXPORT LIBSTATIC_DEPRECATED
#endif
+/* NOLINTNEXTLINE(readability-avoid-unconditional-preprocessor-if) */
#if 0 /* DEFINE_NO_DEPRECATED */
# ifndef LIBSTATIC_NO_DEPRECATED
# define LIBSTATIC_NO_DEPRECATED
diff --git a/Tests/RunCMake/GenerateExportHeader/reference/UNIX_DeprecatedOnly/libshared_export.h b/Tests/RunCMake/GenerateExportHeader/reference/UNIX_DeprecatedOnly/libshared_export.h
index 1481acd..97b988d 100644
--- a/Tests/RunCMake/GenerateExportHeader/reference/UNIX_DeprecatedOnly/libshared_export.h
+++ b/Tests/RunCMake/GenerateExportHeader/reference/UNIX_DeprecatedOnly/libshared_export.h
@@ -33,6 +33,7 @@
# define LIBSHARED_DEPRECATED_NO_EXPORT LIBSHARED_NO_EXPORT LIBSHARED_DEPRECATED
#endif
+/* NOLINTNEXTLINE(readability-avoid-unconditional-preprocessor-if) */
#if 0 /* DEFINE_NO_DEPRECATED */
# ifndef LIBSHARED_NO_DEPRECATED
# define LIBSHARED_NO_DEPRECATED
diff --git a/Tests/RunCMake/GenerateExportHeader/reference/UNIX_DeprecatedOnly/libstatic_export.h b/Tests/RunCMake/GenerateExportHeader/reference/UNIX_DeprecatedOnly/libstatic_export.h
index b6e2a4a..cfc1187 100644
--- a/Tests/RunCMake/GenerateExportHeader/reference/UNIX_DeprecatedOnly/libstatic_export.h
+++ b/Tests/RunCMake/GenerateExportHeader/reference/UNIX_DeprecatedOnly/libstatic_export.h
@@ -33,6 +33,7 @@
# define LIBSTATIC_DEPRECATED_NO_EXPORT LIBSTATIC_NO_EXPORT LIBSTATIC_DEPRECATED
#endif
+/* NOLINTNEXTLINE(readability-avoid-unconditional-preprocessor-if) */
#if 0 /* DEFINE_NO_DEPRECATED */
# ifndef LIBSTATIC_NO_DEPRECATED
# define LIBSTATIC_NO_DEPRECATED
diff --git a/Tests/RunCMake/GenerateExportHeader/reference/Win32-Clang/libshared_export.h b/Tests/RunCMake/GenerateExportHeader/reference/Win32-Clang/libshared_export.h
index 3ba2d2e..6013dcd 100644
--- a/Tests/RunCMake/GenerateExportHeader/reference/Win32-Clang/libshared_export.h
+++ b/Tests/RunCMake/GenerateExportHeader/reference/Win32-Clang/libshared_export.h
@@ -33,6 +33,7 @@
# define LIBSHARED_DEPRECATED_NO_EXPORT LIBSHARED_NO_EXPORT LIBSHARED_DEPRECATED
#endif
+/* NOLINTNEXTLINE(readability-avoid-unconditional-preprocessor-if) */
#if 0 /* DEFINE_NO_DEPRECATED */
# ifndef LIBSHARED_NO_DEPRECATED
# define LIBSHARED_NO_DEPRECATED
diff --git a/Tests/RunCMake/GenerateExportHeader/reference/Win32-Clang/libstatic_export.h b/Tests/RunCMake/GenerateExportHeader/reference/Win32-Clang/libstatic_export.h
index 3c7e093..7a5a573 100644
--- a/Tests/RunCMake/GenerateExportHeader/reference/Win32-Clang/libstatic_export.h
+++ b/Tests/RunCMake/GenerateExportHeader/reference/Win32-Clang/libstatic_export.h
@@ -33,6 +33,7 @@
# define LIBSTATIC_DEPRECATED_NO_EXPORT LIBSTATIC_NO_EXPORT LIBSTATIC_DEPRECATED
#endif
+/* NOLINTNEXTLINE(readability-avoid-unconditional-preprocessor-if) */
#if 0 /* DEFINE_NO_DEPRECATED */
# ifndef LIBSTATIC_NO_DEPRECATED
# define LIBSTATIC_NO_DEPRECATED
diff --git a/Tests/RunCMake/GenerateExportHeader/reference/Win32/libshared_export.h b/Tests/RunCMake/GenerateExportHeader/reference/Win32/libshared_export.h
index 3ba2d2e..6013dcd 100644
--- a/Tests/RunCMake/GenerateExportHeader/reference/Win32/libshared_export.h
+++ b/Tests/RunCMake/GenerateExportHeader/reference/Win32/libshared_export.h
@@ -33,6 +33,7 @@
# define LIBSHARED_DEPRECATED_NO_EXPORT LIBSHARED_NO_EXPORT LIBSHARED_DEPRECATED
#endif
+/* NOLINTNEXTLINE(readability-avoid-unconditional-preprocessor-if) */
#if 0 /* DEFINE_NO_DEPRECATED */
# ifndef LIBSHARED_NO_DEPRECATED
# define LIBSHARED_NO_DEPRECATED
diff --git a/Tests/RunCMake/GenerateExportHeader/reference/Win32/libstatic_export.h b/Tests/RunCMake/GenerateExportHeader/reference/Win32/libstatic_export.h
index 3c7e093..7a5a573 100644
--- a/Tests/RunCMake/GenerateExportHeader/reference/Win32/libstatic_export.h
+++ b/Tests/RunCMake/GenerateExportHeader/reference/Win32/libstatic_export.h
@@ -33,6 +33,7 @@
# define LIBSTATIC_DEPRECATED_NO_EXPORT LIBSTATIC_NO_EXPORT LIBSTATIC_DEPRECATED
#endif
+/* NOLINTNEXTLINE(readability-avoid-unconditional-preprocessor-if) */
#if 0 /* DEFINE_NO_DEPRECATED */
# ifndef LIBSTATIC_NO_DEPRECATED
# define LIBSTATIC_NO_DEPRECATED
diff --git a/Tests/RunCMake/GenerateExportHeader/reference/WinEmpty/libshared_export.h b/Tests/RunCMake/GenerateExportHeader/reference/WinEmpty/libshared_export.h
index bf9163e..e64c45f 100644
--- a/Tests/RunCMake/GenerateExportHeader/reference/WinEmpty/libshared_export.h
+++ b/Tests/RunCMake/GenerateExportHeader/reference/WinEmpty/libshared_export.h
@@ -33,6 +33,7 @@
# define LIBSHARED_DEPRECATED_NO_EXPORT LIBSHARED_NO_EXPORT LIBSHARED_DEPRECATED
#endif
+/* NOLINTNEXTLINE(readability-avoid-unconditional-preprocessor-if) */
#if 0 /* DEFINE_NO_DEPRECATED */
# ifndef LIBSHARED_NO_DEPRECATED
# define LIBSHARED_NO_DEPRECATED
diff --git a/Tests/RunCMake/GenerateExportHeader/reference/WinEmpty/libstatic_export.h b/Tests/RunCMake/GenerateExportHeader/reference/WinEmpty/libstatic_export.h
index 5e3ac9f..b54eef5 100644
--- a/Tests/RunCMake/GenerateExportHeader/reference/WinEmpty/libstatic_export.h
+++ b/Tests/RunCMake/GenerateExportHeader/reference/WinEmpty/libstatic_export.h
@@ -33,6 +33,7 @@
# define LIBSTATIC_DEPRECATED_NO_EXPORT LIBSTATIC_NO_EXPORT LIBSTATIC_DEPRECATED
#endif
+/* NOLINTNEXTLINE(readability-avoid-unconditional-preprocessor-if) */
#if 0 /* DEFINE_NO_DEPRECATED */
# ifndef LIBSTATIC_NO_DEPRECATED
# define LIBSTATIC_NO_DEPRECATED
diff --git a/Tests/RunCMake/cmake_language/Experimental/CxxImportStd-set-stderr.txt b/Tests/RunCMake/cmake_language/Experimental/CxxImportStd-set-stderr.txt
new file mode 100644
index 0000000..bddd3ab
--- /dev/null
+++ b/Tests/RunCMake/cmake_language/Experimental/CxxImportStd-set-stderr.txt
@@ -0,0 +1,6 @@
+CMake Warning \(dev\) at Experimental/CxxImportStd-set.cmake:4 \(cmake_language\):
+ CMake's support for `import std;` in C\+\+23 and newer is experimental. It
+ is meant only for experimentation and feedback to CMake developers.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
+This warning is for project developers. Use -Wno-dev to suppress it.
diff --git a/Tests/RunCMake/cmake_language/Experimental/CxxImportStd-set.cmake b/Tests/RunCMake/cmake_language/Experimental/CxxImportStd-set.cmake
new file mode 100644
index 0000000..a002297
--- /dev/null
+++ b/Tests/RunCMake/cmake_language/Experimental/CxxImportStd-set.cmake
@@ -0,0 +1,11 @@
+set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD
+ "0e5b6991-d74f-4b3d-a41c-cf096e0b2508")
+
+cmake_language(GET_EXPERIMENTAL_FEATURE_ENABLED
+ "CxxImportStd"
+ feature_present)
+
+if (NOT feature_present STREQUAL "TRUE")
+ message(FATAL_ERROR
+ "Expected the `CxxImportStd` feature to be enabled.")
+endif ()
diff --git a/Tests/RunCMake/cmake_language/Experimental/CxxImportStd-unset.cmake b/Tests/RunCMake/cmake_language/Experimental/CxxImportStd-unset.cmake
new file mode 100644
index 0000000..be758c2
--- /dev/null
+++ b/Tests/RunCMake/cmake_language/Experimental/CxxImportStd-unset.cmake
@@ -0,0 +1,8 @@
+cmake_language(GET_EXPERIMENTAL_FEATURE_ENABLED
+ "CxxImportStd"
+ feature_present)
+
+if (NOT feature_present STREQUAL "FALSE")
+ message(FATAL_ERROR
+ "Expected the `CxxImportStd` feature to be disabled.")
+endif ()
diff --git a/Tests/RunCMake/cmake_language/Experimental/ExportPackageDependencies-set-stderr.txt b/Tests/RunCMake/cmake_language/Experimental/ExportPackageDependencies-set-stderr.txt
new file mode 100644
index 0000000..0207835
--- /dev/null
+++ b/Tests/RunCMake/cmake_language/Experimental/ExportPackageDependencies-set-stderr.txt
@@ -0,0 +1,6 @@
+CMake Warning \(dev\) at Experimental/ExportPackageDependencies-set.cmake:4 \(cmake_language\):
+ CMake's EXPORT_PACKAGE_DEPENDENCIES support is experimental. It is meant
+ only for experimentation and feedback to CMake developers.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
+This warning is for project developers. Use -Wno-dev to suppress it.
diff --git a/Tests/RunCMake/cmake_language/Experimental/ExportPackageDependencies-set.cmake b/Tests/RunCMake/cmake_language/Experimental/ExportPackageDependencies-set.cmake
new file mode 100644
index 0000000..74b3f93
--- /dev/null
+++ b/Tests/RunCMake/cmake_language/Experimental/ExportPackageDependencies-set.cmake
@@ -0,0 +1,11 @@
+set(CMAKE_EXPERIMENTAL_EXPORT_PACKAGE_DEPENDENCIES
+ "1942b4fa-b2c5-4546-9385-83f254070067")
+
+cmake_language(GET_EXPERIMENTAL_FEATURE_ENABLED
+ "ExportPackageDependencies"
+ feature_present)
+
+if (NOT feature_present STREQUAL "TRUE")
+ message(FATAL_ERROR
+ "Expected the `ExportPackageDependencies` feature to be enabled.")
+endif ()
diff --git a/Tests/RunCMake/cmake_language/Experimental/ExportPackageDependencies-unset.cmake b/Tests/RunCMake/cmake_language/Experimental/ExportPackageDependencies-unset.cmake
new file mode 100644
index 0000000..c60595f
--- /dev/null
+++ b/Tests/RunCMake/cmake_language/Experimental/ExportPackageDependencies-unset.cmake
@@ -0,0 +1,8 @@
+cmake_language(GET_EXPERIMENTAL_FEATURE_ENABLED
+ "ExportPackageDependencies"
+ feature_present)
+
+if (NOT feature_present STREQUAL "FALSE")
+ message(FATAL_ERROR
+ "Expected the `ExportPackageDependencies` feature to be disabled.")
+endif ()
diff --git a/Tests/RunCMake/cmake_language/Experimental/Unknown-result.txt b/Tests/RunCMake/cmake_language/Experimental/Unknown-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/cmake_language/Experimental/Unknown-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/cmake_language/Experimental/Unknown-stderr.txt b/Tests/RunCMake/cmake_language/Experimental/Unknown-stderr.txt
new file mode 100644
index 0000000..ca7c058
--- /dev/null
+++ b/Tests/RunCMake/cmake_language/Experimental/Unknown-stderr.txt
@@ -0,0 +1,4 @@
+CMake Error at Experimental/Unknown.cmake:1 \(cmake_language\):
+ cmake_language Experimental feature name "Unknown" does not exist.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/cmake_language/Experimental/Unknown.cmake b/Tests/RunCMake/cmake_language/Experimental/Unknown.cmake
new file mode 100644
index 0000000..d5e3047
--- /dev/null
+++ b/Tests/RunCMake/cmake_language/Experimental/Unknown.cmake
@@ -0,0 +1,8 @@
+cmake_language(GET_EXPERIMENTAL_FEATURE_ENABLED
+ "Unknown"
+ feature_present)
+
+if (NOT feature_present STREQUAL "")
+ message(FATAL_ERROR
+ "Got a result for the `Unknown` experimental feature.")
+endif ()
diff --git a/Tests/RunCMake/cmake_language/Experimental/WindowsKernelModeDriver-set-stderr.txt b/Tests/RunCMake/cmake_language/Experimental/WindowsKernelModeDriver-set-stderr.txt
new file mode 100644
index 0000000..d6f8788
--- /dev/null
+++ b/Tests/RunCMake/cmake_language/Experimental/WindowsKernelModeDriver-set-stderr.txt
@@ -0,0 +1,6 @@
+CMake Warning \(dev\) at Experimental/WindowsKernelModeDriver-set.cmake:4 \(cmake_language\):
+ CMake's Windows kernel-mode driver support is experimental. It is meant
+ only for experimentation and feedback to CMake developers.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
+This warning is for project developers. Use -Wno-dev to suppress it.
diff --git a/Tests/RunCMake/cmake_language/Experimental/WindowsKernelModeDriver-set.cmake b/Tests/RunCMake/cmake_language/Experimental/WindowsKernelModeDriver-set.cmake
new file mode 100644
index 0000000..f942d95
--- /dev/null
+++ b/Tests/RunCMake/cmake_language/Experimental/WindowsKernelModeDriver-set.cmake
@@ -0,0 +1,11 @@
+set(CMAKE_EXPERIMENTAL_WINDOWS_KERNEL_MODE_DRIVER
+ "5c2d848d-4efa-4529-a768-efd57171bf68")
+
+cmake_language(GET_EXPERIMENTAL_FEATURE_ENABLED
+ "WindowsKernelModeDriver"
+ feature_present)
+
+if (NOT feature_present STREQUAL "TRUE")
+ message(FATAL_ERROR
+ "Expected the `WindowsKernelModeDriver` feature to be enabled.")
+endif ()
diff --git a/Tests/RunCMake/cmake_language/Experimental/WindowsKernelModeDriver-unset.cmake b/Tests/RunCMake/cmake_language/Experimental/WindowsKernelModeDriver-unset.cmake
new file mode 100644
index 0000000..7aee0d3
--- /dev/null
+++ b/Tests/RunCMake/cmake_language/Experimental/WindowsKernelModeDriver-unset.cmake
@@ -0,0 +1,8 @@
+cmake_language(GET_EXPERIMENTAL_FEATURE_ENABLED
+ "WindowsKernelModeDriver"
+ feature_present)
+
+if (NOT feature_present STREQUAL "FALSE")
+ message(FATAL_ERROR
+ "Expected the `WindowsKernelModeDriver` feature to be disabled.")
+endif ()
diff --git a/Tests/RunCMake/cmake_language/RunCMakeTest.cmake b/Tests/RunCMake/cmake_language/RunCMakeTest.cmake
index 5fb2de6..fe3da79 100644
--- a/Tests/RunCMake/cmake_language/RunCMakeTest.cmake
+++ b/Tests/RunCMake/cmake_language/RunCMakeTest.cmake
@@ -156,3 +156,11 @@
-DCMAKE_MESSAGE_LOG_LEVEL=TRACE
-P ${RunCMake_SOURCE_DIR}/get_message_log_level.cmake
)
+
+run_cmake(Experimental/CxxImportStd-set)
+run_cmake(Experimental/CxxImportStd-unset)
+run_cmake(Experimental/ExportPackageDependencies-set)
+run_cmake(Experimental/ExportPackageDependencies-unset)
+run_cmake(Experimental/WindowsKernelModeDriver-set)
+run_cmake(Experimental/WindowsKernelModeDriver-unset)
+run_cmake(Experimental/Unknown)
diff --git a/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/RunCMakeTest.cmake b/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/RunCMakeTest.cmake
index a68607e..f7ede51 100644
--- a/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/RunCMakeTest.cmake
+++ b/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/RunCMakeTest.cmake
@@ -42,6 +42,7 @@
run_install_test(macos-unresolved)
run_install_test(macos-conflict)
run_install_test(macos-notfile)
+ run_install_test(macos-parent-rpath-propagation)
run_install_test(file-filter)
endif()
run_cmake(project)
diff --git a/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/macos-parent-rpath-propagation.cmake b/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/macos-parent-rpath-propagation.cmake
new file mode 100644
index 0000000..43df621
--- /dev/null
+++ b/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/macos-parent-rpath-propagation.cmake
@@ -0,0 +1,44 @@
+enable_language(C)
+
+# bin/exe (RPATH = "lib1:lib2:lib3")
+# ^
+# |
+# lib1/libone.dylib (RPATH erased)
+# ^
+# |
+# lib2/libtwo.dylib (RPATH erased)
+# ^
+# |
+# lib3/libthree.dylib (RPATH erased)
+# GET_RUNTIME_DEPENDENCIES(bin/exe) should resolve all three libraries
+
+set(TEST_SOURCE_DIR "macos/parent-rpath-propagation")
+
+add_library(three SHARED "${TEST_SOURCE_DIR}/three.c")
+
+add_library(two SHARED "${TEST_SOURCE_DIR}/two.c")
+target_link_libraries(two PRIVATE three)
+
+add_library(one SHARED "${TEST_SOURCE_DIR}/one.c")
+target_link_libraries(one PRIVATE two)
+
+add_executable(exe "${TEST_SOURCE_DIR}/main.c")
+target_link_libraries(exe PUBLIC one)
+
+set_property(TARGET exe PROPERTY INSTALL_RPATH
+ @loader_path/../lib1
+ @loader_path/../lib2
+ @loader_path/../lib3
+)
+
+install(TARGETS exe DESTINATION bin)
+install(TARGETS one DESTINATION lib1)
+install(TARGETS two DESTINATION lib2)
+install(TARGETS three DESTINATION lib3)
+
+install(CODE [[
+ file(GET_RUNTIME_DEPENDENCIES
+ EXECUTABLES
+ "${CMAKE_INSTALL_PREFIX}/bin/$<TARGET_FILE_NAME:exe>"
+ )
+ ]])
diff --git a/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/macos/parent-rpath-propagation/main.c b/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/macos/parent-rpath-propagation/main.c
new file mode 100644
index 0000000..fc02afa
--- /dev/null
+++ b/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/macos/parent-rpath-propagation/main.c
@@ -0,0 +1,8 @@
+extern void one(void);
+
+int main(void)
+{
+ one();
+
+ return 0;
+}
diff --git a/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/macos/parent-rpath-propagation/one.c b/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/macos/parent-rpath-propagation/one.c
new file mode 100644
index 0000000..0c480cc
--- /dev/null
+++ b/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/macos/parent-rpath-propagation/one.c
@@ -0,0 +1,6 @@
+extern void two(void);
+
+void one(void)
+{
+ two();
+}
diff --git a/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/macos/parent-rpath-propagation/three.c b/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/macos/parent-rpath-propagation/three.c
new file mode 100644
index 0000000..0be5f47
--- /dev/null
+++ b/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/macos/parent-rpath-propagation/three.c
@@ -0,0 +1,3 @@
+void three(void)
+{
+}
diff --git a/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/macos/parent-rpath-propagation/two.c b/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/macos/parent-rpath-propagation/two.c
new file mode 100644
index 0000000..370baf7
--- /dev/null
+++ b/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/macos/parent-rpath-propagation/two.c
@@ -0,0 +1,6 @@
+extern void three(void);
+
+void two(void)
+{
+ three();
+}
diff --git a/Tests/RunCMake/property_init/CompileSources.cmake b/Tests/RunCMake/property_init/CompileSources.cmake
index e8c5554..22b8f3f 100644
--- a/Tests/RunCMake/property_init/CompileSources.cmake
+++ b/Tests/RunCMake/property_init/CompileSources.cmake
@@ -100,6 +100,7 @@
"C_LINKER_LAUNCHER" "ccache" "<SAME>"
### C++
"CXX_LINKER_LAUNCHER" "ccache" "<SAME>"
+ "CXX_MODULE_STD" "ON" "<SAME>"
### CUDA
"CUDA_RESOLVE_DEVICE_SYMBOLS" "ON" "<SAME>"
"CUDA_RUNTIME_LIBRARY" "Static" "<SAME>"
diff --git a/Tests/RunCMake/separate_arguments/ProgramCommand.cmake b/Tests/RunCMake/separate_arguments/ProgramCommand.cmake
index bdf5810..cbd44bf 100644
--- a/Tests/RunCMake/separate_arguments/ProgramCommand.cmake
+++ b/Tests/RunCMake/separate_arguments/ProgramCommand.cmake
@@ -4,12 +4,11 @@
message (SEND_ERROR "unexpected result with nonexistent program")
endif()
-set (TEST_EXE_DIR "${CMAKE_CURRENT_BINARY_DIR}/TestExe")
-file(MAKE_DIRECTORY "${TEST_EXE_DIR}")
-file(COPY "${CMAKE_COMMAND}" DESTINATION "${TEST_EXE_DIR}")
-cmake_path (GET CMAKE_COMMAND FILENAME cmake_exe)
+get_filename_component(cmake_command "${CMAKE_COMMAND}" ABSOLUTE)
+cmake_path (GET cmake_command FILENAME cmake_exe)
+cmake_path (GET cmake_command PARENT_PATH cmake_dir)
-set (ENV{PATH} "${TEST_EXE_DIR}")
+set (ENV{PATH} "${cmake_dir}")
separate_arguments (out UNIX_COMMAND PROGRAM "${cmake_exe}")
@@ -22,8 +21,8 @@
endif()
list(GET out 0 cmake)
list(GET out 1 args)
-if (NOT cmake STREQUAL "${TEST_EXE_DIR}/${cmake_exe}")
- message (SEND_ERROR "bad path for program: '${cmake}' instead of '${TEST_EXE_DIR}/${cmake_exe}'")
+if (NOT cmake STREQUAL "${cmake_dir}/${cmake_exe}")
+ message (SEND_ERROR "bad path for program: '${cmake}' instead of '${cmake_dir}/${cmake_exe}'")
endif()
if (NOT args STREQUAL "")
message (SEND_ERROR "bad value for args: '${args}' instead of ''")
@@ -40,8 +39,8 @@
endif()
list(GET out 0 cmake)
list(GET out 1 args)
-if (NOT cmake STREQUAL "${TEST_EXE_DIR}/${cmake_exe}")
- message (SEND_ERROR "bad path for program: '${cmake}' instead of '${TEST_EXE_DIR}/${cmake_exe}'")
+if (NOT cmake STREQUAL "${cmake_dir}/${cmake_exe}")
+ message (SEND_ERROR "bad path for program: '${cmake}' instead of '${cmake_dir}/${cmake_exe}'")
endif()
if (NOT args STREQUAL " a b c")
message (SEND_ERROR "bad value for args: '${args}' instead of ' a b c'")
diff --git a/Tests/RunCMake/separate_arguments/ProgramCommandWithSeparateArgs.cmake b/Tests/RunCMake/separate_arguments/ProgramCommandWithSeparateArgs.cmake
index 2826cc9..b93b42c 100644
--- a/Tests/RunCMake/separate_arguments/ProgramCommandWithSeparateArgs.cmake
+++ b/Tests/RunCMake/separate_arguments/ProgramCommandWithSeparateArgs.cmake
@@ -4,12 +4,11 @@
message (SEND_ERROR "unexpected result with nonexistent program")
endif()
-set (TEST_EXE_DIR "${CMAKE_CURRENT_BINARY_DIR}/TestExe")
-file(MAKE_DIRECTORY "${TEST_EXE_DIR}")
-file(COPY "${CMAKE_COMMAND}" DESTINATION "${TEST_EXE_DIR}")
-cmake_path (GET CMAKE_COMMAND FILENAME cmake_exe)
+get_filename_component(cmake_command "${CMAKE_COMMAND}" ABSOLUTE)
+cmake_path (GET cmake_command FILENAME cmake_exe)
+cmake_path (GET cmake_command PARENT_PATH cmake_dir)
-set (ENV{PATH} "${TEST_EXE_DIR}")
+set (ENV{PATH} "${cmake_dir}")
separate_arguments (out UNIX_COMMAND PROGRAM SEPARATE_ARGS "${cmake_exe} a b c")
list (LENGTH out length)
@@ -20,8 +19,8 @@
message(FATAL_ERROR "unexpected arguments")
endif()
list(POP_FRONT out cmake)
-if (NOT cmake STREQUAL "${TEST_EXE_DIR}/${cmake_exe}")
- message (SEND_ERROR "bad path for program: '${cmake}' instead of '${TEST_EXE_DIR}/${cmake_exe}'")
+if (NOT cmake STREQUAL "${cmake_dir}/${cmake_exe}")
+ message (SEND_ERROR "bad path for program: '${cmake}' instead of '${cmake_dir}/${cmake_exe}'")
endif()
if (NOT out STREQUAL "a;b;c")
message (SEND_ERROR "bad path for args: '${out}' instead of 'a;b;c'")
diff --git a/Tests/SwiftOnly/CMakeLists.txt b/Tests/SwiftOnly/CMakeLists.txt
index db7caf9..de4c82f 100644
--- a/Tests/SwiftOnly/CMakeLists.txt
+++ b/Tests/SwiftOnly/CMakeLists.txt
@@ -57,16 +57,7 @@
add_library(SwiftIface INTERFACE)
target_link_libraries(SwiftOnly PRIVATE SwiftIface)
-# @_alwaysEmitIntoClient ensures that the function body is inserted into the
-# swiftmodule instead of as a symbol in the binary itself. I'm doing this to
-# avoid having to link the executable. There are some flags required in order to
-# link an executable into a library that I didn't see CMake emitting for Swift
-# on macOS. AEIC is the easiest workaround that still tests this functionality.
-# Unfortunately, AEIC was only added recently (~Swift 5.2), so we need to check
-# that it is available before using it.
-if(CMAKE_Swift_COMPILER_VERSION VERSION_GREATER_EQUAL 5.2)
- add_subdirectory("SwiftPlugin")
-endif()
+add_subdirectory("SwiftPlugin")
function(test_cmp0157_default mode)
if(POLICY CMP0157)
diff --git a/Tests/SwiftOnly/SwiftPlugin/CMakeLists.txt b/Tests/SwiftOnly/SwiftPlugin/CMakeLists.txt
index 4069f16..2bfbc8a 100644
--- a/Tests/SwiftOnly/SwiftPlugin/CMakeLists.txt
+++ b/Tests/SwiftOnly/SwiftPlugin/CMakeLists.txt
@@ -1,5 +1,5 @@
add_executable(main main.swift)
set_target_properties(main PROPERTIES ENABLE_EXPORTS TRUE)
-add_library(plugin plugin.swift)
+add_library(plugin MODULE plugin.swift)
target_link_libraries(plugin PRIVATE main)
diff --git a/Tests/SwiftOnly/SwiftPlugin/main.swift b/Tests/SwiftOnly/SwiftPlugin/main.swift
index f5aac51..caba1fb 100644
--- a/Tests/SwiftOnly/SwiftPlugin/main.swift
+++ b/Tests/SwiftOnly/SwiftPlugin/main.swift
@@ -1,4 +1,3 @@
-@_alwaysEmitIntoClient
-public func exported() -> Int { 32 }
+public func exported() -> Int { return 32 }
print(exported())
diff --git a/Tests/SwiftOnly/SwiftPlugin/plugin.swift b/Tests/SwiftOnly/SwiftPlugin/plugin.swift
index e84f248..d00ca33 100644
--- a/Tests/SwiftOnly/SwiftPlugin/plugin.swift
+++ b/Tests/SwiftOnly/SwiftPlugin/plugin.swift
@@ -1,3 +1,3 @@
import main
-public func importing() -> Int { main.exported() + 1 }
+public func importing() -> Int { return main.exported() + 1 }