summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Auxiliary/vim/syntax/cmake.vim1
-rw-r--r--Help/manual/cmake-generator-expressions.7.rst17
-rw-r--r--Help/manual/cmake-policies.7.rst3
-rw-r--r--Help/manual/cmake-properties.7.rst1
-rw-r--r--Help/policy/CMP0099.rst19
-rw-r--r--Help/policy/CMP0166.rst40
-rw-r--r--Help/prop_tgt/VS_FILTER_PROPS.rst10
-rw-r--r--Help/release/dev/FindOpenMP-runtime-msvc.rst5
-rw-r--r--Help/release/dev/genex-link-properties.rst8
-rw-r--r--Help/release/dev/vs-filter-props.rst6
-rw-r--r--Modules/FindICU.cmake113
-rw-r--r--Modules/FindOpenMP.cmake24
-rw-r--r--Modules/FindPackageHandleStandardArgs.cmake3
-rw-r--r--Source/CMakeVersion.cmake2
-rw-r--r--Source/cmCommonTargetGenerator.cxx3
-rw-r--r--Source/cmComputeLinkDepends.cxx21
-rw-r--r--Source/cmExportTryCompileFileGenerator.cxx18
-rw-r--r--Source/cmGeneratorExpression.cxx2
-rw-r--r--Source/cmGeneratorExpressionDAGChecker.cxx58
-rw-r--r--Source/cmGeneratorExpressionDAGChecker.h40
-rw-r--r--Source/cmGeneratorExpressionNode.cxx48
-rw-r--r--Source/cmGeneratorTarget.cxx150
-rw-r--r--Source/cmGeneratorTarget.h20
-rw-r--r--Source/cmPolicies.h10
-rw-r--r--Source/cmQtAutoGenInitializer.cxx5
-rw-r--r--Source/cmVisualStudio10TargetGenerator.cxx37
-rw-r--r--Source/cmVisualStudio10TargetGenerator.h1
-rw-r--r--Tests/FindOpenMP/Test/CMakeLists.txt13
-rw-r--r--Tests/RunCMake/FPHSA/BadFoundVar-stderr.txt6
-rw-r--r--Tests/RunCMake/FPHSA/BeforeProject-Error-result.txt1
-rw-r--r--Tests/RunCMake/FPHSA/BeforeProject-Error-stderr.txt12
-rw-r--r--Tests/RunCMake/FPHSA/BeforeProject-Error.cmake2
-rw-r--r--Tests/RunCMake/FPHSA/BeforeProject-Missing-stdout.txt2
-rw-r--r--Tests/RunCMake/FPHSA/BeforeProject-Missing.cmake2
-rw-r--r--Tests/RunCMake/FPHSA/CMakeLists.txt5
-rw-r--r--Tests/RunCMake/FPHSA/FindBeforeProject.cmake3
-rw-r--r--Tests/RunCMake/FPHSA/NameMismatch-stderr.txt12
-rw-r--r--Tests/RunCMake/FPHSA/RunCMakeTest.cmake2
-rw-r--r--Tests/RunCMake/GenEx-TARGET_PROPERTY/CMakeLists.txt4
-rw-r--r--Tests/RunCMake/GenEx-TARGET_PROPERTY/RunCMakeTest.cmake3
-rw-r--r--Tests/RunCMake/GenEx-TARGET_PROPERTY/TransitiveBuild-check.cmake25
-rw-r--r--Tests/RunCMake/GenEx-TARGET_PROPERTY/TransitiveBuild.cmake66
-rw-r--r--Tests/RunCMake/GenEx-TARGET_PROPERTY/TransitiveLink-CMP0166-NEW-check.cmake8
-rw-r--r--Tests/RunCMake/GenEx-TARGET_PROPERTY/TransitiveLink-CMP0166-NEW.cmake2
-rw-r--r--Tests/RunCMake/GenEx-TARGET_PROPERTY/TransitiveLink-CMP0166-OLD-check.cmake8
-rw-r--r--Tests/RunCMake/GenEx-TARGET_PROPERTY/TransitiveLink-CMP0166-OLD.cmake2
-rw-r--r--Tests/RunCMake/GenEx-TARGET_PROPERTY/TransitiveLink-check-common.cmake12
-rw-r--r--Tests/RunCMake/GenEx-TARGET_PROPERTY/TransitiveLink-common.cmake42
-rw-r--r--Tests/RunCMake/GenEx-TARGET_PROPERTY/empty.h0
-rw-r--r--Tests/RunCMake/GenEx-TARGET_PROPERTY/empty1.c0
-rw-r--r--Tests/RunCMake/GenEx-TARGET_PROPERTY/empty1.h0
-rw-r--r--Tests/RunCMake/GenEx-TARGET_PROPERTY/empty2.h0
-rw-r--r--Tests/RunCMake/GenEx-TARGET_PROPERTY/empty3.h0
-rw-r--r--Tests/RunCMake/GenEx-TARGET_PROPERTY/main.c4
-rw-r--r--Tests/RunCMake/VS10Project/VsCustomProps-check.cmake45
-rw-r--r--Tests/RunCMake/VS10Project/VsCustomProps.cmake3
-rw-r--r--Utilities/Sphinx/conf.py.in1
57 files changed, 639 insertions, 311 deletions
diff --git a/Auxiliary/vim/syntax/cmake.vim b/Auxiliary/vim/syntax/cmake.vim
index 5629356..5d412c2 100644
--- a/Auxiliary/vim/syntax/cmake.vim
+++ b/Auxiliary/vim/syntax/cmake.vim
@@ -450,6 +450,7 @@ syn keyword cmakeProperty contained
\ VS_STARTUP_PROJECT
\ VS_TOOL_OVERRIDE
\ VS_USER_PROPS
+ \ VS_FILTER_PROPS
\ VS_WINDOWS_TARGET_PLATFORM_MIN_VERSION
\ VS_WINRT_COMPONENT
\ VS_WINRT_EXTENSIONS
diff --git a/Help/manual/cmake-generator-expressions.7.rst b/Help/manual/cmake-generator-expressions.7.rst
index 38fa6f9..31f0573 100644
--- a/Help/manual/cmake-generator-expressions.7.rst
+++ b/Help/manual/cmake-generator-expressions.7.rst
@@ -1282,7 +1282,7 @@ Compile Context
.. versionadded:: 3.27
Content of ``...``, when collecting
- :ref:`usage requirements <Target Usage Requirements>`,
+ :ref:`transitive build properties <Transitive Build Properties>`,
otherwise it is the empty string. This is intended for use in an
:prop_tgt:`INTERFACE_LINK_LIBRARIES` and :prop_tgt:`LINK_LIBRARIES` target
properties, typically populated via the :command:`target_link_libraries` command.
@@ -1670,8 +1670,8 @@ Link Context
.. versionadded:: 3.1
- Content of ``...``, except while collecting
- :ref:`usage requirements <Target Usage Requirements>`,
+ Content of ``...``, except while collecting usage requirements from
+ :ref:`transitive build properties <Transitive Build Properties>`,
in which case it is the empty string. This is intended for use in an
:prop_tgt:`INTERFACE_LINK_LIBRARIES` target property, typically populated
via the :command:`target_link_libraries` command, to specify private link
@@ -1788,7 +1788,16 @@ The expressions have special evaluation rules for some properties:
of the value on the target itself with the values of the same properties on
targets named by the target's :prop_tgt:`INTERFACE_LINK_LIBRARIES`.
Evaluation is transitive over the closure of the target's
- :prop_tgt:`INTERFACE_LINK_LIBRARIES`.
+ :prop_tgt:`INTERFACE_LINK_LIBRARIES`:
+
+ * For :ref:`Transitive Build Properties`, the transitive closure
+ *excludes* entries of :prop_tgt:`INTERFACE_LINK_LIBRARIES` guarded
+ by the :genex:`LINK_ONLY` generator expression.
+
+ * For :ref:`Transitive Link Properties`, the transitive closure is
+ *includes* entries of :prop_tgt:`INTERFACE_LINK_LIBRARIES` guarded
+ by the :genex:`LINK_ONLY` generator expression.
+ See policy :policy:`CMP0166`.
Evaluation of :prop_tgt:`INTERFACE_LINK_LIBRARIES` itself is not transitive.
diff --git a/Help/manual/cmake-policies.7.rst b/Help/manual/cmake-policies.7.rst
index e46e88e..826790d 100644
--- a/Help/manual/cmake-policies.7.rst
+++ b/Help/manual/cmake-policies.7.rst
@@ -57,6 +57,7 @@ Policies Introduced by CMake 3.30
.. toctree::
:maxdepth: 1
+ CMP0166: TARGET_PROPERTY evaluates link properties transitively over private dependencies of static libraries. </policy/CMP0166>
CMP0165: enable_language() must not be called before project(). </policy/CMP0165>
CMP0164: add_library() rejects SHARED libraries when not supported by the platform. </policy/CMP0164>
CMP0163: The GENERATED source file property is now visible in all directories. </policy/CMP0163>
@@ -214,7 +215,7 @@ Policies Introduced by CMake 3.17
CMP0102: mark_as_advanced() does nothing if a cache entry does not exist. </policy/CMP0102>
CMP0101: target_compile_options honors BEFORE keyword in all scopes. </policy/CMP0101>
CMP0100: Let AUTOMOC and AUTOUIC process .hh header files. </policy/CMP0100>
- CMP0099: Link properties are transitive over private dependency on static libraries. </policy/CMP0099>
+ CMP0099: Link properties are transitive over private dependencies of static libraries. </policy/CMP0099>
CMP0098: FindFLEX runs flex in CMAKE_CURRENT_BINARY_DIR when executing. </policy/CMP0098>
Policies Introduced by CMake 3.16
diff --git a/Help/manual/cmake-properties.7.rst b/Help/manual/cmake-properties.7.rst
index 6ccc23e..7e640df 100644
--- a/Help/manual/cmake-properties.7.rst
+++ b/Help/manual/cmake-properties.7.rst
@@ -448,6 +448,7 @@ Properties on Targets
/prop_tgt/VS_SOURCE_SETTINGS_tool
/prop_tgt/VS_USE_DEBUG_LIBRARIES
/prop_tgt/VS_USER_PROPS
+ /prop_tgt/VS_FILTER_PROPS
/prop_tgt/VS_WINDOWS_TARGET_PLATFORM_MIN_VERSION
/prop_tgt/VS_WINRT_COMPONENT
/prop_tgt/VS_WINRT_REFERENCES
diff --git a/Help/policy/CMP0099.rst b/Help/policy/CMP0099.rst
index c0db99d..0a2b786 100644
--- a/Help/policy/CMP0099.rst
+++ b/Help/policy/CMP0099.rst
@@ -3,13 +3,16 @@ CMP0099
.. versionadded:: 3.17
-Target link properties :prop_tgt:`INTERFACE_LINK_OPTIONS`,
-:prop_tgt:`INTERFACE_LINK_DIRECTORIES` and :prop_tgt:`INTERFACE_LINK_DEPENDS`
-are now transitive over private dependencies of static libraries.
+Link properties are transitive over private dependencies of static libraries.
-In CMake 3.16 and below the interface link properties attached to libraries
-are not propagated for private dependencies of static libraries.
+In CMake 3.16 and below, evaluation of target properties
+:prop_tgt:`INTERFACE_LINK_OPTIONS`, :prop_tgt:`INTERFACE_LINK_DIRECTORIES`,
+and :prop_tgt:`INTERFACE_LINK_DEPENDS` during buildsystem generation does not
+follow private dependencies of static libraries, which appear in their
+:prop_tgt:`INTERFACE_LINK_LIBRARIES` guarded by :genex:`LINK_ONLY` generator
+expressions.
Only the libraries themselves are propagated to link the dependent binary.
+
CMake 3.17 and later prefer to propagate all interface link properties.
This policy provides compatibility for projects that have not been updated
to expect the new behavior.
@@ -18,6 +21,12 @@ The ``OLD`` behavior for this policy is to not propagate interface link
properties. The ``NEW`` behavior of this policy is to propagate interface link
properties.
+.. versionadded:: 3.30
+
+ Policy :policy:`CMP0166` makes :genex:`TARGET_PROPERTY` evaluation of
+ these three transitive link properties follow private dependencies of
+ static libraries too.
+
.. |INTRODUCED_IN_CMAKE_VERSION| replace:: 3.17
.. |WARNS_OR_DOES_NOT_WARN| replace:: does *not* warn
.. include:: STANDARD_ADVICE.txt
diff --git a/Help/policy/CMP0166.rst b/Help/policy/CMP0166.rst
new file mode 100644
index 0000000..5c67880
--- /dev/null
+++ b/Help/policy/CMP0166.rst
@@ -0,0 +1,40 @@
+CMP0166
+-------
+
+.. versionadded:: 3.30
+
+:genex:`TARGET_PROPERTY` evaluates link properties transitively over private
+dependencies of static libraries.
+
+In CMake 3.29 and below, the :genex:`TARGET_PROPERTY` generator expression
+evaluates properties :prop_tgt:`INTERFACE_LINK_OPTIONS`,
+:prop_tgt:`INTERFACE_LINK_DIRECTORIES`, and :prop_tgt:`INTERFACE_LINK_DEPENDS`
+as if they were :ref:`Transitive Build Properties` rather than
+:ref:`Transitive Link Properties`, even when policy :policy:`CMP0099` is
+set to ``NEW``. Private dependencies of static libraries, which appear in
+their :prop_tgt:`INTERFACE_LINK_LIBRARIES` guarded by :genex:`LINK_ONLY`
+generator expressions, are not followed. This is inconsistent with
+evaluation of the same target properties during buildsystem generation.
+
+CMake 3.30 and above prefer that :genex:`TARGET_PROPERTY` evaluates
+properties :prop_tgt:`INTERFACE_LINK_OPTIONS`,
+:prop_tgt:`INTERFACE_LINK_DIRECTORIES`, and :prop_tgt:`INTERFACE_LINK_DEPENDS`
+as :ref:`Transitive Link Properties` such that private dependencies of static
+libraries, which appear in their :prop_tgt:`INTERFACE_LINK_LIBRARIES` guarded
+by :genex:`LINK_ONLY` generator expressions, are followed.
+This policy provides compatibility for projects that have not been updated
+to expect the new behavior.
+
+The ``OLD`` behavior for this policy is for :genex:`TARGET_PROPERTY` to
+evaluate properties :prop_tgt:`INTERFACE_LINK_OPTIONS`,
+:prop_tgt:`INTERFACE_LINK_DIRECTORIES`, and :prop_tgt:`INTERFACE_LINK_DEPENDS`
+as if they were :ref:`Transitive Build Properties` by not following private
+dependencies of static libraries. The ``NEW`` behavior for this policy is
+to evaluate them as :ref:`Transitive Link Properties` by following private
+dependencies of static libraries.
+
+.. |INTRODUCED_IN_CMAKE_VERSION| replace:: 3.30
+.. |WARNS_OR_DOES_NOT_WARN| replace:: does *not* warn
+.. include:: STANDARD_ADVICE.txt
+
+.. include:: DEPRECATED.txt
diff --git a/Help/prop_tgt/VS_FILTER_PROPS.rst b/Help/prop_tgt/VS_FILTER_PROPS.rst
new file mode 100644
index 0000000..3de0a16
--- /dev/null
+++ b/Help/prop_tgt/VS_FILTER_PROPS.rst
@@ -0,0 +1,10 @@
+VS_FILTER_PROPS
+---------------
+
+.. versionadded:: 3.30
+
+Sets the filter props file to be included in the visual studio
+C++ project filter file.
+
+The ``*.filter.props`` files can be used for Visual Studio wide
+configuration which is independent from cmake.
diff --git a/Help/release/dev/FindOpenMP-runtime-msvc.rst b/Help/release/dev/FindOpenMP-runtime-msvc.rst
new file mode 100644
index 0000000..76df237
--- /dev/null
+++ b/Help/release/dev/FindOpenMP-runtime-msvc.rst
@@ -0,0 +1,5 @@
+FindOpenMP-runtime-msvc
+-----------------------
+
+* The :module:`FindOpenMP` module gained a ``OpenMP_RUNTIME_MSVC``
+ option to control the OpenMP runtime used with MSVC.
diff --git a/Help/release/dev/genex-link-properties.rst b/Help/release/dev/genex-link-properties.rst
new file mode 100644
index 0000000..e1e84e0
--- /dev/null
+++ b/Help/release/dev/genex-link-properties.rst
@@ -0,0 +1,8 @@
+genex-link-properties
+---------------------
+
+* The :genex:`TARGET_PROPERTY` generator expression now evaluates target
+ properties :prop_tgt:`INTERFACE_LINK_OPTIONS`,
+ :prop_tgt:`INTERFACE_LINK_DIRECTORIES`, and
+ :prop_tgt:`INTERFACE_LINK_DEPENDS` correctly by following private
+ dependencies of static libraries. See policy :policy:`CMP0166`.
diff --git a/Help/release/dev/vs-filter-props.rst b/Help/release/dev/vs-filter-props.rst
new file mode 100644
index 0000000..5a09511
--- /dev/null
+++ b/Help/release/dev/vs-filter-props.rst
@@ -0,0 +1,6 @@
+vs-filter-props
+---------------
+
+* A :prop_tgt:`VS_FILTER_PROPS` target property was added to tell
+ :ref:`Visual Studio Generators` for VS 2010 and above to use a
+ custom MSBuild filter ``.props`` file.
diff --git a/Modules/FindICU.cmake b/Modules/FindICU.cmake
index 4708aff..63c2576 100644
--- a/Modules/FindICU.cmake
+++ b/Modules/FindICU.cmake
@@ -24,10 +24,10 @@ platform-specific library name will be automatically selected.
This module reports information about the ICU installation in
several variables. General variables::
- ICU_VERSION - ICU release version
ICU_FOUND - true if the main programs and libraries were found
- ICU_LIBRARIES - component libraries to be linked
ICU_INCLUDE_DIRS - the directories containing the ICU headers
+ ICU_LIBRARIES - component libraries to be linked
+ ICU_VERSION - ICU release version
Imported targets::
@@ -83,15 +83,10 @@ The following cache variables may also be set::
In most cases none of the above variables will require setting,
unless multiple ICU versions are available and a specific version
is required.
-
-Other variables one may set to control this module are::
-
- ICU_DEBUG - Set to ON to enable debug output from FindICU.
#]=======================================================================]
cmake_policy(PUSH)
cmake_policy(SET CMP0159 NEW) # file(STRINGS) with REGEX updates CMAKE_MATCH_<n>
-
# Written by Roger Leigh <rleigh@codelibre.net>
set(icu_programs
@@ -182,7 +177,6 @@ function(_ICU_FIND)
# Find all ICU libraries
list(APPEND icu_library_suffixes "${_lib64}" "lib")
- set(ICU_REQUIRED_LIBS_FOUND ON)
set(static_prefix )
# static icu libraries compiled with MSVC have the prefix 's'
if(MSVC)
@@ -193,8 +187,9 @@ function(_ICU_FIND)
set(component_cache "ICU_${component_upcase}_LIBRARY")
set(component_cache_release "${component_cache}_RELEASE")
set(component_cache_debug "${component_cache}_DEBUG")
- set(component_found "ICU_${component_upcase}_FOUND")
+ set(component_found "ICU_${component}_FOUND")
set(component_found_compat "${component_upcase}_FOUND")
+ set(component_found_compat2 "ICU_${component_upcase}_FOUND")
set(component_libnames "icu${component}")
set(component_debug_libnames "icu${component}d")
@@ -257,27 +252,17 @@ function(_ICU_FIND)
if(${component_cache})
set("${component_found}" ON)
set("${component_found_compat}" ON)
+ set("${component_found_compat2}" ON)
list(APPEND ICU_LIBRARY "${${component_cache}}")
- if (ICU_FIND_REQUIRED_${component})
- list(APPEND ICU_LIBS_FOUND "${component} (required): ${${component_cache}}")
- else()
- list(APPEND ICU_LIBS_FOUND "${component} (optional): ${${component_cache}}")
- endif()
- else()
- if (ICU_FIND_REQUIRED_${component})
- set(ICU_REQUIRED_LIBS_FOUND OFF)
- list(APPEND ICU_LIBS_NOTFOUND "${component} (required)")
- else()
- list(APPEND ICU_LIBS_NOTFOUND "${component} (optional)")
- endif()
endif()
mark_as_advanced("${component_found}")
mark_as_advanced("${component_found_compat}")
+ mark_as_advanced("${component_found_compat2}")
set("${component_cache}" "${${component_cache}}" PARENT_SCOPE)
set("${component_found}" "${${component_found}}" PARENT_SCOPE)
set("${component_found_compat}" "${${component_found_compat}}" PARENT_SCOPE)
+ set("${component_found_compat2}" "${${component_found_compat2}}" PARENT_SCOPE)
endforeach()
- set(_ICU_REQUIRED_LIBS_FOUND "${ICU_REQUIRED_LIBS_FOUND}" PARENT_SCOPE)
set(ICU_LIBRARY "${ICU_LIBRARY}" PARENT_SCOPE)
# Find all ICU data files
@@ -306,43 +291,21 @@ function(_ICU_FIND)
mark_as_advanced("${cache_var}")
set("${data_var}" "${${cache_var}}" PARENT_SCOPE)
endforeach()
-
- if(NOT ICU_FIND_QUIETLY)
- if(ICU_LIBS_FOUND)
- message(STATUS "Found the following ICU libraries:")
- foreach(found ${ICU_LIBS_FOUND})
- message(STATUS " ${found}")
- endforeach()
- endif()
- if(ICU_LIBS_NOTFOUND)
- message(STATUS "The following ICU libraries were not found:")
- foreach(notfound ${ICU_LIBS_NOTFOUND})
- message(STATUS " ${notfound}")
- endforeach()
- endif()
- endif()
-
- if(ICU_DEBUG)
- message(STATUS "--------FindICU.cmake search debug--------")
- message(STATUS "ICU binary path search order: ${icu_roots}")
- message(STATUS "ICU include path search order: ${icu_roots}")
- message(STATUS "ICU library path search order: ${icu_roots}")
- message(STATUS "----------------")
- endif()
endfunction()
_ICU_FIND()
include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
-FIND_PACKAGE_HANDLE_STANDARD_ARGS(ICU
- FOUND_VAR ICU_FOUND
- REQUIRED_VARS ICU_INCLUDE_DIR
- ICU_LIBRARY
- _ICU_REQUIRED_LIBS_FOUND
- VERSION_VAR ICU_VERSION
- FAIL_MESSAGE "Failed to find all ICU components")
-
-unset(_ICU_REQUIRED_LIBS_FOUND)
+find_package_handle_standard_args(ICU
+ REQUIRED_VARS
+ ICU_INCLUDE_DIR
+ ICU_LIBRARY
+ VERSION_VAR
+ ICU_VERSION
+ HANDLE_COMPONENTS
+ FAIL_MESSAGE
+ "Failed to find all ICU components"
+)
if(ICU_FOUND)
set(ICU_INCLUDE_DIRS "${ICU_INCLUDE_DIR}")
@@ -396,47 +359,5 @@ if(ICU_FOUND)
endforeach()
endif()
-if(ICU_DEBUG)
- message(STATUS "--------FindICU.cmake results debug--------")
- message(STATUS "ICU found: ${ICU_FOUND}")
- message(STATUS "ICU_VERSION number: ${ICU_VERSION}")
- message(STATUS "ICU_ROOT directory: ${ICU_ROOT}")
- message(STATUS "ICU_INCLUDE_DIR directory: ${ICU_INCLUDE_DIR}")
- message(STATUS "ICU_LIBRARIES: ${ICU_LIBRARIES}")
-
- foreach(program IN LISTS icu_programs)
- string(TOUPPER "${program}" program_upcase)
- set(program_lib "ICU_${program_upcase}_EXECUTABLE")
- message(STATUS "${program} program: ${program_lib}=${${program_lib}}")
- unset(program_upcase)
- unset(program_lib)
- endforeach()
-
- foreach(data IN LISTS icu_data)
- string(TOUPPER "${data}" data_upcase)
- string(REPLACE "." "_" data_upcase "${data_upcase}")
- set(data_lib "ICU_${data_upcase}")
- message(STATUS "${data} data: ${data_lib}=${${data_lib}}")
- unset(data_upcase)
- unset(data_lib)
- endforeach()
-
- foreach(component IN LISTS ICU_FIND_COMPONENTS)
- string(TOUPPER "${component}" component_upcase)
- set(component_lib "ICU_${component_upcase}_LIBRARIES")
- set(component_found "ICU_${component_upcase}_FOUND")
- set(component_found_compat "${component_upcase}_FOUND")
- message(STATUS "${component} library found: ${component_found}=${${component_found}}")
- message(STATUS "${component} library found (compat name): ${component_found_compat}=${${component_found_compat}}")
- message(STATUS "${component} library: ${component_lib}=${${component_lib}}")
- unset(component_upcase)
- unset(component_lib)
- unset(component_found)
- unset(component_found_compat)
- endforeach()
- message(STATUS "----------------")
-endif()
-
unset(icu_programs)
-
cmake_policy(POP)
diff --git a/Modules/FindOpenMP.cmake b/Modules/FindOpenMP.cmake
index 077a239..f88e43c 100644
--- a/Modules/FindOpenMP.cmake
+++ b/Modules/FindOpenMP.cmake
@@ -16,8 +16,22 @@ flag to support OpenMP.
.. versionadded:: 3.5
Clang support.
-Variables
-^^^^^^^^^
+Input Variables
+^^^^^^^^^^^^^^^
+
+The following variables may be set to influence this module's behavior:
+
+``OpenMP_RUNTIME_MSVC``
+ .. versionadded:: 3.30
+
+ Specify the `OpenMP Runtime <msvc-openmp_>`_ when compiling with MSVC.
+ If set to a non-empty value, such as ``experimental`` or ``llvm``, it
+ will be passed as the value of the ``-openmp:`` flag.
+
+.. _`msvc-openmp`: https://learn.microsoft.com/en-us/cpp/build/reference/openmp-enable-openmp-2-0-support
+
+Result Variables
+^^^^^^^^^^^^^^^^
.. versionadded:: 3.10
The module exposes the components ``C``, ``CXX``, and ``Fortran``.
@@ -121,7 +135,11 @@ function(_OPENMP_FLAG_CANDIDATES LANG)
else()
set(OMP_FLAG_IntelLLVM "-fiopenmp")
endif()
- set(OMP_FLAG_MSVC "-openmp")
+ if(OpenMP_RUNTIME_MSVC)
+ set(OMP_FLAG_MSVC "-openmp:${OpenMP_RUNTIME_MSVC}")
+ else()
+ set(OMP_FLAG_MSVC "-openmp")
+ endif()
set(OMP_FLAG_PathScale "-openmp")
set(OMP_FLAG_NAG "-openmp")
set(OMP_FLAG_Absoft "-openmp")
diff --git a/Modules/FindPackageHandleStandardArgs.cmake b/Modules/FindPackageHandleStandardArgs.cmake
index 63b2bf2..c6db433 100644
--- a/Modules/FindPackageHandleStandardArgs.cmake
+++ b/Modules/FindPackageHandleStandardArgs.cmake
@@ -225,6 +225,9 @@ macro(_FPHSA_FAILURE_MESSAGE _msg)
set (__msg "${_msg}")
if (FPHSA_REASON_FAILURE_MESSAGE)
string(APPEND __msg "\n Reason given by package: ${FPHSA_REASON_FAILURE_MESSAGE}\n")
+ elseif(NOT DEFINED PROJECT_NAME)
+ string(APPEND __msg "\n"
+ "Hint: The project() command has not yet been called. It sets up system-specific search paths.")
endif()
if (${_NAME}_FIND_REQUIRED)
message(FATAL_ERROR "${__msg}")
diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake
index 7170842..203e214 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 20240501)
+set(CMake_VERSION_PATCH 20240502)
#set(CMake_VERSION_RC 0)
set(CMake_VERSION_IS_DIRTY 0)
diff --git a/Source/cmCommonTargetGenerator.cxx b/Source/cmCommonTargetGenerator.cxx
index 677bb48..fbf39e2 100644
--- a/Source/cmCommonTargetGenerator.cxx
+++ b/Source/cmCommonTargetGenerator.cxx
@@ -501,7 +501,8 @@ std::string cmCommonTargetGenerator::GetLinkerLauncher(
cmValue launcherProp = this->GeneratorTarget->GetProperty(propName);
if (cmNonempty(launcherProp)) {
cmGeneratorExpressionDAGChecker dagChecker(this->GeneratorTarget, propName,
- nullptr, nullptr);
+ nullptr, nullptr,
+ this->LocalCommonGenerator);
std::string evaluatedLinklauncher = cmGeneratorExpression::Evaluate(
*launcherProp, this->LocalCommonGenerator, config, this->GeneratorTarget,
&dagChecker, this->GeneratorTarget, lang);
diff --git a/Source/cmComputeLinkDepends.cxx b/Source/cmComputeLinkDepends.cxx
index f4b26f3..f6ff71a 100644
--- a/Source/cmComputeLinkDepends.cxx
+++ b/Source/cmComputeLinkDepends.cxx
@@ -451,10 +451,14 @@ cmComputeLinkDepends::cmComputeLinkDepends(const cmGeneratorTarget* target,
if (cmValue feature = this->Target->GetProperty(key)) {
if (!feature->empty() && key.length() > lloPrefix.length()) {
auto item = key.substr(lloPrefix.length());
- cmGeneratorExpressionDAGChecker dag{ this->Target->GetBacktrace(),
- this->Target,
- "LINK_LIBRARY_OVERRIDE",
- nullptr, nullptr };
+ cmGeneratorExpressionDAGChecker dag{
+ this->Target->GetBacktrace(),
+ this->Target,
+ "LINK_LIBRARY_OVERRIDE",
+ nullptr,
+ nullptr,
+ this->Target->GetLocalGenerator()
+ };
auto overrideFeature = cmGeneratorExpression::Evaluate(
*feature, this->Target->GetLocalGenerator(), config,
this->Target, &dag, this->Target, linkLanguage);
@@ -466,9 +470,12 @@ cmComputeLinkDepends::cmComputeLinkDepends(const cmGeneratorTarget* target,
// global override property
if (cmValue linkLibraryOverride =
this->Target->GetProperty("LINK_LIBRARY_OVERRIDE")) {
- cmGeneratorExpressionDAGChecker dag{ target->GetBacktrace(), target,
- "LINK_LIBRARY_OVERRIDE", nullptr,
- nullptr };
+ cmGeneratorExpressionDAGChecker dag{ target->GetBacktrace(),
+ target,
+ "LINK_LIBRARY_OVERRIDE",
+ nullptr,
+ nullptr,
+ target->GetLocalGenerator() };
auto overrideValue = cmGeneratorExpression::Evaluate(
*linkLibraryOverride, target->GetLocalGenerator(), config, target, &dag,
target, linkLanguage);
diff --git a/Source/cmExportTryCompileFileGenerator.cxx b/Source/cmExportTryCompileFileGenerator.cxx
index 00c9173..4c41ff5 100644
--- a/Source/cmExportTryCompileFileGenerator.cxx
+++ b/Source/cmExportTryCompileFileGenerator.cxx
@@ -2,9 +2,11 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmExportTryCompileFileGenerator.h"
+#include <map>
#include <utility>
#include <cm/memory>
+#include <cm/string_view>
#include "cmFileSet.h"
#include "cmGeneratorExpression.h"
@@ -44,12 +46,10 @@ bool cmExportTryCompileFileGenerator::GenerateMainFile(std::ostream& os)
ImportPropertyMap properties;
for (std::string const& lang : this->Languages) {
-#define FIND_TARGETS(PROPERTY) \
- this->FindTargets("INTERFACE_" #PROPERTY, te, lang, emittedDeps);
-
- CM_FOR_EACH_TRANSITIVE_PROPERTY_NAME(FIND_TARGETS)
-
-#undef FIND_TARGETS
+ for (auto i : cmGeneratorTarget::BuiltinTransitiveProperties) {
+ this->FindTargets(std::string(i.second.InterfaceName), te, lang,
+ emittedDeps);
+ }
}
this->PopulateProperties(te, properties, emittedDeps);
@@ -76,10 +76,10 @@ std::string cmExportTryCompileFileGenerator::FindTargets(
// To please constraint checks of DAGChecker, this property must have
// LINK_OPTIONS property as parent
parentDagChecker = cm::make_unique<cmGeneratorExpressionDAGChecker>(
- tgt, "LINK_OPTIONS", nullptr, nullptr);
+ tgt, "LINK_OPTIONS", nullptr, nullptr, tgt->GetLocalGenerator());
}
- cmGeneratorExpressionDAGChecker dagChecker(tgt, propName, nullptr,
- parentDagChecker.get());
+ cmGeneratorExpressionDAGChecker dagChecker(
+ tgt, propName, nullptr, parentDagChecker.get(), tgt->GetLocalGenerator());
std::unique_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(*prop);
diff --git a/Source/cmGeneratorExpression.cxx b/Source/cmGeneratorExpression.cxx
index 0b96c3f..0583fd5 100644
--- a/Source/cmGeneratorExpression.cxx
+++ b/Source/cmGeneratorExpression.cxx
@@ -425,7 +425,7 @@ const std::string& cmGeneratorExpressionInterpreter::Evaluate(
cmGeneratorExpressionDAGChecker dagChecker(
this->HeadTarget,
property == "COMPILE_FLAGS" ? "COMPILE_OPTIONS" : property, nullptr,
- nullptr);
+ nullptr, this->LocalGenerator);
return this->CompiledGeneratorExpression->Evaluate(
this->LocalGenerator, this->Config, this->HeadTarget, &dagChecker, nullptr,
diff --git a/Source/cmGeneratorExpressionDAGChecker.cxx b/Source/cmGeneratorExpressionDAGChecker.cxx
index fda7ec3..bb1f4b4 100644
--- a/Source/cmGeneratorExpressionDAGChecker.cxx
+++ b/Source/cmGeneratorExpressionDAGChecker.cxx
@@ -2,10 +2,10 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmGeneratorExpressionDAGChecker.h"
-#include <cstring>
#include <sstream>
#include <utility>
+#include <cm/optional>
#include <cm/string_view>
#include <cmext/string_view>
@@ -20,16 +20,17 @@
cmGeneratorExpressionDAGChecker::cmGeneratorExpressionDAGChecker(
cmGeneratorTarget const* target, std::string property,
const GeneratorExpressionContent* content,
- cmGeneratorExpressionDAGChecker* parent)
+ cmGeneratorExpressionDAGChecker* parent, cmLocalGenerator const* contextLG)
: cmGeneratorExpressionDAGChecker(cmListFileBacktrace(), target,
- std::move(property), content, parent)
+ std::move(property), content, parent,
+ contextLG)
{
}
cmGeneratorExpressionDAGChecker::cmGeneratorExpressionDAGChecker(
cmListFileBacktrace backtrace, cmGeneratorTarget const* target,
std::string property, const GeneratorExpressionContent* content,
- cmGeneratorExpressionDAGChecker* parent)
+ cmGeneratorExpressionDAGChecker* parent, cmLocalGenerator const* contextLG)
: Parent(parent)
, Top(parent ? parent->Top : this)
, Target(target)
@@ -40,10 +41,9 @@ cmGeneratorExpressionDAGChecker::cmGeneratorExpressionDAGChecker(
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->TopIsTransitiveProperty =
+ this->Target->IsTransitiveProperty(this->Property, contextLG)
+ .has_value();
}
this->CheckResult = this->CheckGraph();
@@ -169,6 +169,12 @@ bool cmGeneratorExpressionDAGChecker::EvaluatingCompileExpression() const
property == "COMPILE_DEFINITIONS"_s || property == "COMPILE_OPTIONS"_s;
}
+bool cmGeneratorExpressionDAGChecker::EvaluatingSources() const
+{
+ return this->Property == "SOURCES"_s ||
+ this->Property == "INTERFACE_SOURCES"_s;
+}
+
bool cmGeneratorExpressionDAGChecker::EvaluatingLinkExpression() const
{
cm::string_view property(this->Top->Property);
@@ -222,39 +228,3 @@ cmGeneratorTarget const* cmGeneratorExpressionDAGChecker::TopTarget() const
{
return this->Top->Target;
}
-
-enum class TransitiveProperty
-{
-#define DEFINE_ENUM_ENTRY(NAME) NAME,
- CM_FOR_EACH_TRANSITIVE_PROPERTY_NAME(DEFINE_ENUM_ENTRY)
-#undef DEFINE_ENUM_ENTRY
- Terminal
-};
-
-template <TransitiveProperty>
-bool additionalTest(const char* const /*unused*/)
-{
- return false;
-}
-
-template <>
-bool additionalTest<TransitiveProperty::COMPILE_DEFINITIONS>(
- const char* const prop)
-{
- return cmHasLiteralPrefix(prop, "COMPILE_DEFINITIONS_");
-}
-
-#define DEFINE_TRANSITIVE_PROPERTY_METHOD(METHOD, PROPERTY) \
- bool cmGeneratorExpressionDAGChecker::METHOD() const \
- { \
- const char* const prop = this->Property.c_str(); \
- if (strcmp(prop, #PROPERTY) == 0 || \
- strcmp(prop, "INTERFACE_" #PROPERTY) == 0) { \
- return true; \
- } \
- return additionalTest<TransitiveProperty::PROPERTY>(prop); \
- }
-
-CM_FOR_EACH_TRANSITIVE_PROPERTY(DEFINE_TRANSITIVE_PROPERTY_METHOD)
-
-#undef DEFINE_TRANSITIVE_PROPERTY_METHOD
diff --git a/Source/cmGeneratorExpressionDAGChecker.h b/Source/cmGeneratorExpressionDAGChecker.h
index 068ba6b..b230188 100644
--- a/Source/cmGeneratorExpressionDAGChecker.h
+++ b/Source/cmGeneratorExpressionDAGChecker.h
@@ -13,33 +13,7 @@
struct GeneratorExpressionContent;
struct cmGeneratorExpressionContext;
class cmGeneratorTarget;
-
-#define CM_SELECT_BOTH(F, A1, A2) F(A1, A2)
-#define CM_SELECT_FIRST(F, A1, A2) F(A1)
-#define CM_SELECT_SECOND(F, A1, A2) F(A2)
-
-#define CM_FOR_EACH_TRANSITIVE_PROPERTY_IMPL(F, SELECT) \
- SELECT(F, EvaluatingIncludeDirectories, INCLUDE_DIRECTORIES) \
- SELECT(F, EvaluatingSystemIncludeDirectories, SYSTEM_INCLUDE_DIRECTORIES) \
- SELECT(F, EvaluatingCompileDefinitions, COMPILE_DEFINITIONS) \
- SELECT(F, EvaluatingCompileOptions, COMPILE_OPTIONS) \
- SELECT(F, EvaluatingAutoMocMacroNames, AUTOMOC_MACRO_NAMES) \
- SELECT(F, EvaluatingAutoUicOptions, AUTOUIC_OPTIONS) \
- SELECT(F, EvaluatingSources, SOURCES) \
- SELECT(F, EvaluatingCompileFeatures, COMPILE_FEATURES) \
- SELECT(F, EvaluatingLinkOptions, LINK_OPTIONS) \
- SELECT(F, EvaluatingLinkDirectories, LINK_DIRECTORIES) \
- SELECT(F, EvaluatingLinkDepends, LINK_DEPENDS) \
- SELECT(F, EvaluatingPrecompileHeaders, PRECOMPILE_HEADERS)
-
-#define CM_FOR_EACH_TRANSITIVE_PROPERTY(F) \
- CM_FOR_EACH_TRANSITIVE_PROPERTY_IMPL(F, CM_SELECT_BOTH)
-
-#define CM_FOR_EACH_TRANSITIVE_PROPERTY_METHOD(F) \
- CM_FOR_EACH_TRANSITIVE_PROPERTY_IMPL(F, CM_SELECT_FIRST)
-
-#define CM_FOR_EACH_TRANSITIVE_PROPERTY_NAME(F) \
- CM_FOR_EACH_TRANSITIVE_PROPERTY_IMPL(F, CM_SELECT_SECOND)
+class cmLocalGenerator;
struct cmGeneratorExpressionDAGChecker
{
@@ -47,11 +21,13 @@ struct cmGeneratorExpressionDAGChecker
cmGeneratorTarget const* target,
std::string property,
const GeneratorExpressionContent* content,
- cmGeneratorExpressionDAGChecker* parent);
+ cmGeneratorExpressionDAGChecker* parent,
+ cmLocalGenerator const* contextLG);
cmGeneratorExpressionDAGChecker(cmGeneratorTarget const* target,
std::string property,
const GeneratorExpressionContent* content,
- cmGeneratorExpressionDAGChecker* parent);
+ cmGeneratorExpressionDAGChecker* parent,
+ cmLocalGenerator const* contextLG);
enum Result
{
@@ -83,11 +59,7 @@ struct cmGeneratorExpressionDAGChecker
bool EvaluatingLinkLibraries(cmGeneratorTarget const* tgt = nullptr,
ForGenex genex = ForGenex::ANY) const;
-#define DECLARE_TRANSITIVE_PROPERTY_METHOD(METHOD) bool METHOD() const;
-
- CM_FOR_EACH_TRANSITIVE_PROPERTY_METHOD(DECLARE_TRANSITIVE_PROPERTY_METHOD)
-
-#undef DECLARE_TRANSITIVE_PROPERTY_METHOD
+ bool EvaluatingSources() const;
bool GetTransitivePropertiesOnly() const;
void SetTransitivePropertiesOnly() { this->TransitivePropertiesOnly = true; }
diff --git a/Source/cmGeneratorExpressionNode.cxx b/Source/cmGeneratorExpressionNode.cxx
index 0df086b..b9feb87 100644
--- a/Source/cmGeneratorExpressionNode.cxx
+++ b/Source/cmGeneratorExpressionNode.cxx
@@ -487,7 +487,8 @@ protected:
if (context->HeadTarget) {
cmGeneratorExpressionDAGChecker dagChecker(
context->Backtrace, context->HeadTarget,
- genexOperator + ":" + expression, content, dagCheckerParent);
+ genexOperator + ":" + expression, content, dagCheckerParent,
+ context->LG);
switch (dagChecker.Check()) {
case cmGeneratorExpressionDAGChecker::SELF_REFERENCE:
case cmGeneratorExpressionDAGChecker::CYCLIC_REFERENCE: {
@@ -2700,7 +2701,8 @@ static const struct DeviceLinkNode : public cmGeneratorExpressionNode
static std::string getLinkedTargetsContent(
cmGeneratorTarget const* target, std::string const& prop,
cmGeneratorExpressionContext* context,
- cmGeneratorExpressionDAGChecker* dagChecker)
+ cmGeneratorExpressionDAGChecker* dagChecker,
+ cmGeneratorTarget::LinkInterfaceFor interfaceFor)
{
std::string result;
if (cmLinkImplementationLibraries const* impl =
@@ -2716,8 +2718,7 @@ static std::string getLinkedTargetsContent(
target, context->EvaluateForBuildsystem, lib.Backtrace,
context->Language);
std::string libResult = lib.Target->EvaluateInterfaceProperty(
- prop, &libContext, dagChecker,
- cmGeneratorTarget::LinkInterfaceFor::Usage);
+ prop, &libContext, dagChecker, interfaceFor);
if (!libResult.empty()) {
if (result.empty()) {
result = std::move(libResult);
@@ -2875,25 +2876,15 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode
std::string interfacePropertyName;
bool isInterfaceProperty = false;
+ cmGeneratorTarget::LinkInterfaceFor interfaceFor =
+ cmGeneratorTarget::LinkInterfaceFor::Usage;
-#define POPULATE_INTERFACE_PROPERTY_NAME(prop) \
- if (propertyName == #prop) { \
- interfacePropertyName = "INTERFACE_" #prop; \
- } else if (propertyName == "INTERFACE_" #prop) { \
- interfacePropertyName = "INTERFACE_" #prop; \
- isInterfaceProperty = true; \
- } else
-
- CM_FOR_EACH_TRANSITIVE_PROPERTY_NAME(POPULATE_INTERFACE_PROPERTY_NAME)
- // Note that the above macro terminates with an else
- /* else */ if (cmHasLiteralPrefix(propertyName, "COMPILE_DEFINITIONS_")) {
- cmPolicies::PolicyStatus polSt =
- context->LG->GetPolicyStatus(cmPolicies::CMP0043);
- if (polSt == cmPolicies::WARN || polSt == cmPolicies::OLD) {
- interfacePropertyName = "INTERFACE_COMPILE_DEFINITIONS";
- }
+ if (cm::optional<cmGeneratorTarget::TransitiveProperty> transitiveProp =
+ target->IsTransitiveProperty(propertyName, context->LG)) {
+ interfacePropertyName = std::string(transitiveProp->InterfaceName);
+ isInterfaceProperty = transitiveProp->InterfaceName == propertyName;
+ interfaceFor = transitiveProp->InterfaceFor;
}
-#undef POPULATE_INTERFACE_PROPERTY_NAME
bool evaluatingLinkLibraries = false;
@@ -2916,20 +2907,19 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode
return std::string();
}
} else {
- assert(dagCheckerParent
- ->EvaluatingTransitiveProperty()); // NOLINT(clang-tidy)
+ assert(dagCheckerParent->EvaluatingTransitiveProperty());
}
}
if (isInterfaceProperty) {
return cmGeneratorExpression::StripEmptyListElements(
- target->EvaluateInterfaceProperty(
- propertyName, context, dagCheckerParent,
- cmGeneratorTarget::LinkInterfaceFor::Usage));
+ target->EvaluateInterfaceProperty(propertyName, context,
+ dagCheckerParent, interfaceFor));
}
- cmGeneratorExpressionDAGChecker dagChecker(
- context->Backtrace, target, propertyName, content, dagCheckerParent);
+ cmGeneratorExpressionDAGChecker dagChecker(context->Backtrace, target,
+ propertyName, content,
+ dagCheckerParent, context->LG);
switch (dagChecker.Check()) {
case cmGeneratorExpressionDAGChecker::SELF_REFERENCE:
@@ -3011,7 +3001,7 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode
this->EvaluateDependentExpression(result, context->LG, context, target,
&dagChecker, target));
std::string linkedTargetsContent = getLinkedTargetsContent(
- target, interfacePropertyName, context, &dagChecker);
+ target, interfacePropertyName, context, &dagChecker, interfaceFor);
if (!linkedTargetsContent.empty()) {
result += (result.empty() ? "" : ";") + linkedTargetsContent;
}
diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx
index 5861dc5..75f3b6d 100644
--- a/Source/cmGeneratorTarget.cxx
+++ b/Source/cmGeneratorTarget.cxx
@@ -65,6 +65,7 @@
namespace {
using LinkInterfaceFor = cmGeneratorTarget::LinkInterfaceFor;
+using TransitiveProperty = cmGeneratorTarget::TransitiveProperty;
const std::string kINTERFACE_LINK_LIBRARIES = "INTERFACE_LINK_LIBRARIES";
const std::string kINTERFACE_LINK_LIBRARIES_DIRECT =
@@ -73,6 +74,33 @@ const std::string kINTERFACE_LINK_LIBRARIES_DIRECT_EXCLUDE =
"INTERFACE_LINK_LIBRARIES_DIRECT_EXCLUDE";
}
+const std::map<cm::string_view, TransitiveProperty>
+ cmGeneratorTarget::BuiltinTransitiveProperties = {
+ { "AUTOMOC_MACRO_NAMES"_s,
+ { "INTERFACE_AUTOMOC_MACRO_NAMES"_s, LinkInterfaceFor::Usage } },
+ { "AUTOUIC_OPTIONS"_s,
+ { "INTERFACE_AUTOUIC_OPTIONS"_s, LinkInterfaceFor::Usage } },
+ { "COMPILE_DEFINITIONS"_s,
+ { "INTERFACE_COMPILE_DEFINITIONS"_s, LinkInterfaceFor::Usage } },
+ { "COMPILE_FEATURES"_s,
+ { "INTERFACE_COMPILE_FEATURES"_s, LinkInterfaceFor::Usage } },
+ { "COMPILE_OPTIONS"_s,
+ { "INTERFACE_COMPILE_OPTIONS"_s, LinkInterfaceFor::Usage } },
+ { "INCLUDE_DIRECTORIES"_s,
+ { "INTERFACE_INCLUDE_DIRECTORIES"_s, LinkInterfaceFor::Usage } },
+ { "LINK_DEPENDS"_s,
+ { "INTERFACE_LINK_DEPENDS"_s, LinkInterfaceFor::Link } },
+ { "LINK_DIRECTORIES"_s,
+ { "INTERFACE_LINK_DIRECTORIES"_s, LinkInterfaceFor::Link } },
+ { "LINK_OPTIONS"_s,
+ { "INTERFACE_LINK_OPTIONS"_s, LinkInterfaceFor::Link } },
+ { "PRECOMPILE_HEADERS"_s,
+ { "INTERFACE_PRECOMPILE_HEADERS"_s, LinkInterfaceFor::Usage } },
+ { "SOURCES"_s, { "INTERFACE_SOURCES"_s, LinkInterfaceFor::Usage } },
+ { "SYSTEM_INCLUDE_DIRECTORIES"_s,
+ { "INTERFACE_SYSTEM_INCLUDE_DIRECTORIES"_s, LinkInterfaceFor::Usage } },
+ };
+
template <>
cmValue cmTargetPropertyComputer::GetSources<cmGeneratorTarget>(
cmGeneratorTarget const* tgt, cmMakefile const& /* mf */)
@@ -887,7 +915,7 @@ std::string cmGeneratorTarget::GetLinkerTypeProperty(
auto linkerType = this->GetProperty(propName);
if (!linkerType.IsEmpty()) {
cmGeneratorExpressionDAGChecker dagChecker(this, propName, nullptr,
- nullptr);
+ nullptr, this->LocalGenerator);
auto ltype =
cmGeneratorExpression::Evaluate(*linkerType, this->GetLocalGenerator(),
config, this, &dagChecker, this, lang);
@@ -1352,7 +1380,8 @@ bool cmGeneratorTarget::IsSystemIncludeDirectory(
if (iter == this->SystemIncludesCache.end()) {
cmGeneratorExpressionDAGChecker dagChecker(
- this, "SYSTEM_INCLUDE_DIRECTORIES", nullptr, nullptr);
+ this, "SYSTEM_INCLUDE_DIRECTORIES", nullptr, nullptr,
+ this->LocalGenerator);
bool excludeImported = this->GetPropertyAsBool("NO_SYSTEM_FROM_IMPORTED");
@@ -1460,7 +1489,8 @@ std::string cmGeneratorTarget::EvaluateInterfaceProperty(
// a subset of TargetPropertyNode::Evaluate without stringify/parse steps
// but sufficient for transitive interface properties.
cmGeneratorExpressionDAGChecker dagChecker(context->Backtrace, this, prop,
- nullptr, dagCheckerParent);
+ nullptr, dagCheckerParent,
+ this->LocalGenerator);
switch (dagChecker.Check()) {
case cmGeneratorExpressionDAGChecker::SELF_REFERENCE:
dagChecker.ReportError(
@@ -1525,6 +1555,38 @@ std::string cmGeneratorTarget::EvaluateInterfaceProperty(
return result;
}
+cm::optional<cmGeneratorTarget::TransitiveProperty>
+cmGeneratorTarget::IsTransitiveProperty(cm::string_view prop,
+ cmLocalGenerator const* lg) const
+{
+ cm::optional<TransitiveProperty> result;
+ static const cm::string_view kINTERFACE_ = "INTERFACE_"_s;
+ if (cmHasPrefix(prop, kINTERFACE_)) {
+ prop = prop.substr(kINTERFACE_.length());
+ }
+ auto i = BuiltinTransitiveProperties.find(prop);
+ if (i != BuiltinTransitiveProperties.end()) {
+ result = i->second;
+ if (result->InterfaceFor != cmGeneratorTarget::LinkInterfaceFor::Usage) {
+ cmPolicies::PolicyStatus cmp0166 =
+ lg->GetPolicyStatus(cmPolicies::CMP0166);
+ if ((cmp0166 == cmPolicies::WARN || cmp0166 == cmPolicies::OLD) &&
+ (prop == "LINK_DIRECTORIES"_s || prop == "LINK_DEPENDS"_s ||
+ prop == "LINK_OPTIONS"_s)) {
+ result->InterfaceFor = cmGeneratorTarget::LinkInterfaceFor::Usage;
+ }
+ }
+ } else if (cmHasLiteralPrefix(prop, "COMPILE_DEFINITIONS_")) {
+ cmPolicies::PolicyStatus cmp0043 =
+ lg->GetPolicyStatus(cmPolicies::CMP0043);
+ if (cmp0043 == cmPolicies::WARN || cmp0043 == cmPolicies::OLD) {
+ result = TransitiveProperty{ "INTERFACE_COMPILE_DEFINITIONS"_s,
+ LinkInterfaceFor::Usage };
+ }
+ }
+ return result;
+}
+
namespace {
enum class IncludeDirectoryFallBack
@@ -1539,8 +1601,10 @@ std::string AddLangSpecificInterfaceIncludeDirectories(
const std::string& propertyName, IncludeDirectoryFallBack mode,
cmGeneratorExpressionDAGChecker* context)
{
- cmGeneratorExpressionDAGChecker dag{ target->GetBacktrace(), target,
- propertyName, nullptr, context };
+ cmGeneratorExpressionDAGChecker dag{
+ target->GetBacktrace(), target, propertyName, nullptr, context,
+ target->GetLocalGenerator()
+ };
switch (dag.Check()) {
case cmGeneratorExpressionDAGChecker::SELF_REFERENCE:
dag.ReportError(
@@ -1590,8 +1654,10 @@ void AddLangSpecificImplicitIncludeDirectories(
{
if (const auto* libraries = target->GetLinkImplementationLibraries(
config, LinkInterfaceFor::Usage)) {
- cmGeneratorExpressionDAGChecker dag{ target->GetBacktrace(), target,
- propertyName, nullptr, nullptr };
+ cmGeneratorExpressionDAGChecker dag{
+ target->GetBacktrace(), target, propertyName, nullptr, nullptr,
+ target->GetLocalGenerator()
+ };
for (const cmLinkImplItem& library : libraries->Libraries) {
if (const cmGeneratorTarget* dependency = library.Target) {
@@ -1843,8 +1909,8 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetSourceFilePaths(
this->DebugSourcesDone = true;
}
- cmGeneratorExpressionDAGChecker dagChecker(this, "SOURCES", nullptr,
- nullptr);
+ cmGeneratorExpressionDAGChecker dagChecker(this, "SOURCES", nullptr, nullptr,
+ this->LocalGenerator);
EvaluatedTargetPropertyEntries entries = EvaluateTargetPropertyEntries(
this, config, std::string(), &dagChecker, this->SourceEntries);
@@ -3058,7 +3124,7 @@ void cmGeneratorTarget::GetAutoUicOptions(std::vector<std::string>& result,
}
cmGeneratorExpressionDAGChecker dagChecker(this, "AUTOUIC_OPTIONS", nullptr,
- nullptr);
+ nullptr, this->LocalGenerator);
cmExpandList(cmGeneratorExpression::Evaluate(prop, this->LocalGenerator,
config, this, &dagChecker),
result);
@@ -3858,8 +3924,8 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetIncludeDirectories(
std::vector<BT<std::string>> includes;
std::unordered_set<std::string> uniqueIncludes;
- cmGeneratorExpressionDAGChecker dagChecker(this, "INCLUDE_DIRECTORIES",
- nullptr, nullptr);
+ cmGeneratorExpressionDAGChecker dagChecker(
+ this, "INCLUDE_DIRECTORIES", nullptr, nullptr, this->LocalGenerator);
cmList debugProperties{ this->Makefile->GetDefinition(
"CMAKE_DEBUG_TARGET_PROPERTIES") };
@@ -4123,7 +4189,7 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetCompileOptions(
std::unordered_set<std::string> uniqueOptions;
cmGeneratorExpressionDAGChecker dagChecker(this, "COMPILE_OPTIONS", nullptr,
- nullptr);
+ nullptr, this->LocalGenerator);
cmList debugProperties{ this->Makefile->GetDefinition(
"CMAKE_DEBUG_TARGET_PROPERTIES") };
@@ -4164,7 +4230,7 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetCompileFeatures(
std::unordered_set<std::string> uniqueFeatures;
cmGeneratorExpressionDAGChecker dagChecker(this, "COMPILE_FEATURES", nullptr,
- nullptr);
+ nullptr, this->LocalGenerator);
cmList debugProperties{ this->Makefile->GetDefinition(
"CMAKE_DEBUG_TARGET_PROPERTIES") };
@@ -4213,8 +4279,8 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetCompileDefinitions(
std::vector<BT<std::string>> list;
std::unordered_set<std::string> uniqueOptions;
- cmGeneratorExpressionDAGChecker dagChecker(this, "COMPILE_DEFINITIONS",
- nullptr, nullptr);
+ cmGeneratorExpressionDAGChecker dagChecker(
+ this, "COMPILE_DEFINITIONS", nullptr, nullptr, this->LocalGenerator);
cmList debugProperties{ this->Makefile->GetDefinition(
"CMAKE_DEBUG_TARGET_PROPERTIES") };
@@ -4277,8 +4343,8 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetPrecompileHeaders(
}
std::unordered_set<std::string> uniqueOptions;
- cmGeneratorExpressionDAGChecker dagChecker(this, "PRECOMPILE_HEADERS",
- nullptr, nullptr);
+ cmGeneratorExpressionDAGChecker dagChecker(
+ this, "PRECOMPILE_HEADERS", nullptr, nullptr, this->LocalGenerator);
cmList debugProperties{ this->Makefile->GetDefinition(
"CMAKE_DEBUG_TARGET_PROPERTIES") };
@@ -4681,7 +4747,7 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetLinkOptions(
std::unordered_set<std::string> uniqueOptions;
cmGeneratorExpressionDAGChecker dagChecker(this, "LINK_OPTIONS", nullptr,
- nullptr);
+ nullptr, this->LocalGenerator);
cmList debugProperties{ this->Makefile->GetDefinition(
"CMAKE_DEBUG_TARGET_PROPERTIES") };
@@ -4849,8 +4915,8 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetStaticLibraryLinkOptions(
std::vector<BT<std::string>> result;
std::unordered_set<std::string> uniqueOptions;
- cmGeneratorExpressionDAGChecker dagChecker(this, "STATIC_LIBRARY_OPTIONS",
- nullptr, nullptr);
+ cmGeneratorExpressionDAGChecker dagChecker(
+ this, "STATIC_LIBRARY_OPTIONS", nullptr, nullptr, this->LocalGenerator);
EvaluatedTargetPropertyEntries entries;
if (cmValue linkOptions = this->GetProperty("STATIC_LIBRARY_OPTIONS")) {
@@ -4963,7 +5029,7 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetLinkDirectories(
std::unordered_set<std::string> uniqueDirectories;
cmGeneratorExpressionDAGChecker dagChecker(this, "LINK_DIRECTORIES", nullptr,
- nullptr);
+ nullptr, this->LocalGenerator);
cmList debugProperties{ this->Makefile->GetDefinition(
"CMAKE_DEBUG_TARGET_PROPERTIES") };
@@ -5007,7 +5073,7 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetLinkDepends(
std::vector<BT<std::string>> result;
std::unordered_set<std::string> uniqueOptions;
cmGeneratorExpressionDAGChecker dagChecker(this, "LINK_DEPENDS", nullptr,
- nullptr);
+ nullptr, this->LocalGenerator);
EvaluatedTargetPropertyEntries entries;
if (cmValue linkDepends = this->GetProperty("LINK_DEPENDS")) {
@@ -6993,7 +7059,8 @@ void cmGeneratorTarget::ExpandLinkItems(
return;
}
// Keep this logic in sync with ComputeLinkImplementationLibraries.
- cmGeneratorExpressionDAGChecker dagChecker(this, prop, nullptr, nullptr);
+ cmGeneratorExpressionDAGChecker dagChecker(this, prop, nullptr, nullptr,
+ this->LocalGenerator);
// The $<LINK_ONLY> expression may be in a link interface to specify
// private link dependencies that are otherwise excluded from usage
// requirements.
@@ -8668,7 +8735,7 @@ void cmGeneratorTarget::ComputeLinkImplementationLibraries(
for (auto const& entry : entryRange) {
// Keep this logic in sync with ExpandLinkItems.
cmGeneratorExpressionDAGChecker dagChecker(this, "LINK_LIBRARIES", nullptr,
- nullptr);
+ nullptr, this->LocalGenerator);
// The $<LINK_ONLY> expression may be used to specify link dependencies
// that are otherwise excluded from usage requirements.
if (implFor == LinkInterfaceFor::Usage) {
@@ -9640,11 +9707,25 @@ bool cmGeneratorTarget::NeedDyndepForSource(std::string const& lang,
return true;
}
+ auto targetDyndep = this->NeedCxxDyndep(config);
+ if (targetDyndep == CxxModuleSupport::Unavailable) {
+ return false;
+ }
+ auto const sfProp = sf->GetProperty("CXX_SCAN_FOR_MODULES");
+ if (sfProp.IsSet()) {
+ return sfProp.IsOn();
+ }
+ return targetDyndep == CxxModuleSupport::Enabled;
+}
+
+cmGeneratorTarget::CxxModuleSupport cmGeneratorTarget::NeedCxxDyndep(
+ std::string const& config) const
+{
bool haveRule = false;
switch (this->HaveCxxModuleSupport(config)) {
case Cxx20SupportLevel::MissingCxx:
case Cxx20SupportLevel::NoCxx20:
- return false;
+ return CxxModuleSupport::Unavailable;
case Cxx20SupportLevel::MissingRule:
break;
case Cxx20SupportLevel::Supported:
@@ -9654,28 +9735,29 @@ bool cmGeneratorTarget::NeedDyndepForSource(std::string const& lang,
bool haveGeneratorSupport =
this->GetGlobalGenerator()->CheckCxxModuleSupport(
cmGlobalGenerator::CxxModuleSupportQuery::Inspect);
- auto const sfProp = sf->GetProperty("CXX_SCAN_FOR_MODULES");
- if (sfProp.IsSet()) {
- return sfProp.IsOn();
- }
auto const tgtProp = this->GetProperty("CXX_SCAN_FOR_MODULES");
if (tgtProp.IsSet()) {
- return tgtProp.IsOn();
+ return tgtProp.IsOn() ? CxxModuleSupport::Enabled
+ : CxxModuleSupport::Disabled;
}
- bool policyAnswer = false;
+ CxxModuleSupport policyAnswer = CxxModuleSupport::Unavailable;
switch (this->GetPolicyStatusCMP0155()) {
case cmPolicies::WARN:
case cmPolicies::OLD:
// The OLD behavior is to not scan the source.
- policyAnswer = false;
+ policyAnswer = CxxModuleSupport::Disabled;
break;
case cmPolicies::REQUIRED_ALWAYS:
case cmPolicies::REQUIRED_IF_USED:
case cmPolicies::NEW:
// The NEW behavior is to scan the source if the compiler supports
// scanning and the generator supports it.
- policyAnswer = haveRule && haveGeneratorSupport;
+ if (haveRule && haveGeneratorSupport) {
+ policyAnswer = CxxModuleSupport::Enabled;
+ } else {
+ policyAnswer = CxxModuleSupport::Disabled;
+ }
break;
}
return policyAnswer;
diff --git a/Source/cmGeneratorTarget.h b/Source/cmGeneratorTarget.h
index 9e5cef0..5c7201d 100644
--- a/Source/cmGeneratorTarget.h
+++ b/Source/cmGeneratorTarget.h
@@ -15,6 +15,7 @@
#include <vector>
#include <cm/optional>
+#include <cm/string_view>
#include "cmAlgorithms.h"
#include "cmComputeLinkInformation.h"
@@ -888,6 +889,18 @@ public:
cmGeneratorExpressionDAGChecker* dagCheckerParent,
LinkInterfaceFor interfaceFor) const;
+ struct TransitiveProperty
+ {
+ cm::string_view InterfaceName;
+ LinkInterfaceFor InterfaceFor;
+ };
+
+ static const std::map<cm::string_view, TransitiveProperty>
+ BuiltinTransitiveProperties;
+
+ cm::optional<TransitiveProperty> IsTransitiveProperty(
+ cm::string_view prop, cmLocalGenerator const* lg) const;
+
bool HaveInstallTreeRPATH(const std::string& config) const;
bool GetBuildRPATH(const std::string& config, std::string& rpath) const;
@@ -1344,6 +1357,13 @@ public:
cmSourceFile const* sf) const;
bool NeedDyndepForSource(std::string const& lang, std::string const& config,
cmSourceFile const* sf) const;
+ enum class CxxModuleSupport
+ {
+ Unavailable,
+ Enabled,
+ Disabled,
+ };
+ CxxModuleSupport NeedCxxDyndep(std::string const& config) const;
private:
void BuildFileSetInfoCache(std::string const& config) const;
diff --git a/Source/cmPolicies.h b/Source/cmPolicies.h
index ada87dd..eb9f031 100644
--- a/Source/cmPolicies.h
+++ b/Source/cmPolicies.h
@@ -294,8 +294,8 @@ class cmMakefile;
"FindFLEX runs flex in CMAKE_CURRENT_BINARY_DIR when executing.", 3, \
17, 0, cmPolicies::WARN) \
SELECT(POLICY, CMP0099, \
- "Link properties are transitive over private dependency on static " \
- "libraries.", \
+ "Link properties are transitive over private dependencies of " \
+ "static libraries.", \
3, 17, 0, cmPolicies::WARN) \
SELECT(POLICY, CMP0100, "Let AUTOMOC and AUTOUIC process .hh files.", 3, \
17, 0, cmPolicies::WARN) \
@@ -508,7 +508,11 @@ class cmMakefile;
3, 30, 0, cmPolicies::WARN) \
SELECT(POLICY, CMP0165, \
"enable_language() must not be called before project().", 3, 30, 0, \
- cmPolicies::WARN)
+ cmPolicies::WARN) \
+ SELECT(POLICY, CMP0166, \
+ "TARGET_PROPERTY evaluates link properties transitively over " \
+ "private dependencies of static libraries.", \
+ 3, 30, 0, cmPolicies::WARN)
#define CM_SELECT_ID(F, A1, A2, A3, A4, A5, A6) F(A1)
#define CM_FOR_EACH_POLICY_ID(POLICY) \
diff --git a/Source/cmQtAutoGenInitializer.cxx b/Source/cmQtAutoGenInitializer.cxx
index 0ccebfd..34a47cc 100644
--- a/Source/cmQtAutoGenInitializer.cxx
+++ b/Source/cmQtAutoGenInitializer.cxx
@@ -1918,8 +1918,9 @@ bool cmQtAutoGenInitializer::SetupWriteAutogenInfo()
info.SetBool("MOC_RELAXED_MODE", this->Moc.RelaxedMode);
info.SetBool("MOC_PATH_PREFIX", this->Moc.PathPrefix);
- cmGeneratorExpressionDAGChecker dagChecker(
- this->GenTarget, "AUTOMOC_MACRO_NAMES", nullptr, nullptr);
+ cmGeneratorExpressionDAGChecker dagChecker(this->GenTarget,
+ "AUTOMOC_MACRO_NAMES", nullptr,
+ nullptr, this->LocalGen);
EvaluatedTargetPropertyEntries InterfaceAutoMocMacroNamesEntries;
if (this->MultiConfig) {
diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx
index bca4719..0fb8bae 100644
--- a/Source/cmVisualStudio10TargetGenerator.cxx
+++ b/Source/cmVisualStudio10TargetGenerator.cxx
@@ -281,6 +281,16 @@ cmVisualStudio10TargetGenerator::cmVisualStudio10TargetGenerator(
this->Makefile->GetGeneratorConfigs(cmMakefile::ExcludeEmptyConfig);
this->NsightTegra = gg->IsNsightTegra();
this->Android = gg->TargetsAndroid();
+ auto scanProp = target->GetProperty("CXX_SCAN_FOR_MODULES");
+ for (auto const& config : this->Configurations) {
+ if (scanProp.IsSet()) {
+ this->ScanSourceForModuleDependencies[config] = scanProp.IsOn();
+ } else {
+ this->ScanSourceForModuleDependencies[config] =
+ target->NeedCxxDyndep(config) ==
+ cmGeneratorTarget::CxxModuleSupport::Enabled;
+ }
+ }
for (unsigned int& version : this->NsightTegraVersion) {
version = 0;
}
@@ -2074,6 +2084,18 @@ void cmVisualStudio10TargetGenerator::WriteGroups()
"gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms");
}
}
+ {
+ if (cmValue p = this->GeneratorTarget->GetProperty("VS_FILTER_PROPS")) {
+ auto props = *p;
+ if (!props.empty()) {
+ ConvertToWindowsSlash(props);
+ Elem(e0, "Import")
+ .Attribute("Project", props)
+ .Attribute("Condition", cmStrCat("exists('", props, "')"))
+ .Attribute("Label", "LocalAppDataPlatform");
+ }
+ }
+ }
}
fout << '\n';
@@ -2860,7 +2882,9 @@ void cmVisualStudio10TargetGenerator::OutputSourceSpecificFlags(
// use them
if (!flags.empty() || !options.empty() || !configDefines.empty() ||
!includes.empty() || compileAsPerConfig || noWinRT ||
- !options.empty() || needsPCHFlags || shouldScanForModules) {
+ !options.empty() || needsPCHFlags ||
+ (shouldScanForModules !=
+ this->ScanSourceForModuleDependencies[config])) {
cmGlobalVisualStudio10Generator* gg = this->GlobalGenerator;
cmIDEFlagTable const* flagtable = nullptr;
const std::string& srclang = source->GetLanguage();
@@ -2888,8 +2912,10 @@ void cmVisualStudio10TargetGenerator::OutputSourceSpecificFlags(
if (compileAsPerConfig) {
clOptions.AddFlag("CompileAs", compileAsPerConfig);
}
- if (shouldScanForModules) {
- clOptions.AddFlag("ScanSourceForModuleDependencies", "true");
+ if (shouldScanForModules !=
+ this->ScanSourceForModuleDependencies[config]) {
+ clOptions.AddFlag("ScanSourceForModuleDependencies",
+ shouldScanForModules ? "true" : "false");
}
if (noWinRT) {
clOptions.AddFlag("CompileAsWinRT", "false");
@@ -3629,8 +3655,9 @@ void cmVisualStudio10TargetGenerator::WriteClOptions(
}
}
- // Disable C++ source scanning by default.
- e2.Element("ScanSourceForModuleDependencies", "false");
+ e2.Element("ScanSourceForModuleDependencies",
+ this->ScanSourceForModuleDependencies[configName] ? "true"
+ : "false");
}
bool cmVisualStudio10TargetGenerator::ComputeRcOptions()
diff --git a/Source/cmVisualStudio10TargetGenerator.h b/Source/cmVisualStudio10TargetGenerator.h
index bafd5e9..056f426 100644
--- a/Source/cmVisualStudio10TargetGenerator.h
+++ b/Source/cmVisualStudio10TargetGenerator.h
@@ -240,6 +240,7 @@ private:
bool NsightTegra;
bool Android;
bool HaveCustomCommandDepfile = false;
+ std::map<std::string, bool> ScanSourceForModuleDependencies;
unsigned int NsightTegraVersion[4];
bool TargetCompileAsWinRT;
std::set<std::string> IPOEnabledConfigurations;
diff --git a/Tests/FindOpenMP/Test/CMakeLists.txt b/Tests/FindOpenMP/Test/CMakeLists.txt
index ebdb6b8..7ead835 100644
--- a/Tests/FindOpenMP/Test/CMakeLists.txt
+++ b/Tests/FindOpenMP/Test/CMakeLists.txt
@@ -26,8 +26,21 @@ foreach(c C CXX Fortran)
endif()
endforeach()
+if(CMAKE_C_COMPILER_ID STREQUAL "MSVC"
+ AND CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 19.30
+ AND NOT CMAKE_C_COMPILER_ARCHITECTURE_ID STREQUAL "ARM64")
+ set(test_msvc_runtime 1)
+ set(OpenMP_RUNTIME_MSVC "llvm")
+endif()
+
find_package(OpenMP REQUIRED)
+if(test_msvc_runtime)
+ if(NOT OpenMP_C_FLAGS STREQUAL "-openmp:llvm")
+ message(FATAL_ERROR "OpenMP_RUNTIME_MSVC='${OpenMP_RUNTIME_MSVC}' not honored: '${OpenMP_C_FLAGS}'")
+ endif()
+endif()
+
foreach(c C CXX Fortran)
if(NOT "${OpenMP_TEST_${c}}")
continue()
diff --git a/Tests/RunCMake/FPHSA/BadFoundVar-stderr.txt b/Tests/RunCMake/FPHSA/BadFoundVar-stderr.txt
index 4c739d8..3ae1ba7 100644
--- a/Tests/RunCMake/FPHSA/BadFoundVar-stderr.txt
+++ b/Tests/RunCMake/FPHSA/BadFoundVar-stderr.txt
@@ -2,6 +2,6 @@ CMake Error at .*/Modules/FindPackageHandleStandardArgs.cmake:[0-9]+ \(message\)
The argument for FOUND_VAR is "badfoundvar_FOUND", but only
"BadFoundVar_FOUND" and "BADFOUNDVAR_FOUND" are valid names.
Call Stack \(most recent call first\):
- FindBadFoundVar.cmake:5 \(find_package_handle_standard_args\)
- BadFoundVar.cmake:3 \(find_package\)
- CMakeLists.txt:3 \(include\)
+ FindBadFoundVar.cmake:[0-9]+ \(find_package_handle_standard_args\)
+ BadFoundVar.cmake:[0-9]+ \(find_package\)
+ CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/FPHSA/BeforeProject-Error-result.txt b/Tests/RunCMake/FPHSA/BeforeProject-Error-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/FPHSA/BeforeProject-Error-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/FPHSA/BeforeProject-Error-stderr.txt b/Tests/RunCMake/FPHSA/BeforeProject-Error-stderr.txt
new file mode 100644
index 0000000..c8e53fc
--- /dev/null
+++ b/Tests/RunCMake/FPHSA/BeforeProject-Error-stderr.txt
@@ -0,0 +1,12 @@
+^CMake Error at [^
+]*/Modules/FindPackageHandleStandardArgs\.cmake:[0-9]+ \(message\):
+ Could NOT find BeforeProject \(missing: SOME_VAR\)
+
+ Hint: The project\(\) command has not yet been called\. It sets up
+ system-specific search paths\.
+Call Stack \(most recent call first\):
+ [^
+]*/Modules/FindPackageHandleStandardArgs\.cmake:[0-9]+ \(_FPHSA_FAILURE_MESSAGE\)
+ FindBeforeProject\.cmake:[0-9]+ \(find_package_handle_standard_args\)
+ BeforeProject-Error\.cmake:[0-9]+ \(find_package\)
+ CMakeLists\.txt:[0-9]+ \(include\)$
diff --git a/Tests/RunCMake/FPHSA/BeforeProject-Error.cmake b/Tests/RunCMake/FPHSA/BeforeProject-Error.cmake
new file mode 100644
index 0000000..53a8073
--- /dev/null
+++ b/Tests/RunCMake/FPHSA/BeforeProject-Error.cmake
@@ -0,0 +1,2 @@
+set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}")
+find_package(BeforeProject REQUIRED)
diff --git a/Tests/RunCMake/FPHSA/BeforeProject-Missing-stdout.txt b/Tests/RunCMake/FPHSA/BeforeProject-Missing-stdout.txt
new file mode 100644
index 0000000..05df0b0
--- /dev/null
+++ b/Tests/RunCMake/FPHSA/BeforeProject-Missing-stdout.txt
@@ -0,0 +1,2 @@
+-- Could NOT find BeforeProject \(missing: SOME_VAR\)[ ]*
+Hint: The project\(\) command has not yet been called\. It sets up system-specific search paths\.
diff --git a/Tests/RunCMake/FPHSA/BeforeProject-Missing.cmake b/Tests/RunCMake/FPHSA/BeforeProject-Missing.cmake
new file mode 100644
index 0000000..8d44ca9
--- /dev/null
+++ b/Tests/RunCMake/FPHSA/BeforeProject-Missing.cmake
@@ -0,0 +1,2 @@
+set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}")
+find_package(BeforeProject)
diff --git a/Tests/RunCMake/FPHSA/CMakeLists.txt b/Tests/RunCMake/FPHSA/CMakeLists.txt
index 93ee9df..dc34259 100644
--- a/Tests/RunCMake/FPHSA/CMakeLists.txt
+++ b/Tests/RunCMake/FPHSA/CMakeLists.txt
@@ -1,3 +1,8 @@
cmake_minimum_required(VERSION 3.5)
+if(RunCMake_TEST MATCHES "^BeforeProject")
+ include(${RunCMake_TEST}.cmake)
+ project(${RunCMake_TEST} NONE)
+ return()
+endif()
project(${RunCMake_TEST} NONE)
include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/FPHSA/FindBeforeProject.cmake b/Tests/RunCMake/FPHSA/FindBeforeProject.cmake
new file mode 100644
index 0000000..6bf49f1
--- /dev/null
+++ b/Tests/RunCMake/FPHSA/FindBeforeProject.cmake
@@ -0,0 +1,3 @@
+set(SOME_VAR FALSE)
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(BeforeProject REQUIRED_VARS SOME_VAR)
diff --git a/Tests/RunCMake/FPHSA/NameMismatch-stderr.txt b/Tests/RunCMake/FPHSA/NameMismatch-stderr.txt
index 722b50b..8ee6ec1 100644
--- a/Tests/RunCMake/FPHSA/NameMismatch-stderr.txt
+++ b/Tests/RunCMake/FPHSA/NameMismatch-stderr.txt
@@ -5,9 +5,9 @@ CMake Warning \(dev\) at .*/Modules/FindPackageHandleStandardArgs.cmake:[0-9]+ \
`find_package` result variables \(e.g., `_FOUND`\) to follow a certain
pattern.
Call Stack \(most recent call first\):
- FindNameMismatch.cmake:3 \(find_package_handle_standard_args\)
- NameMismatch.cmake:3 \(find_package\)
- CMakeLists.txt:3 \(include\)
+ FindNameMismatch.cmake:[0-9]+ \(find_package_handle_standard_args\)
+ NameMismatch.cmake:[0-9]+ \(find_package\)
+ CMakeLists.txt:[0-9]+ \(include\)
This warning is for project developers. Use -Wno-dev to suppress it.
CMake Warning \(dev\) at .*/Modules/FindPackageHandleStandardArgs.cmake:[0-9]+ \(message\):
@@ -17,7 +17,7 @@ CMake Warning \(dev\) at .*/Modules/FindPackageHandleStandardArgs.cmake:[0-9]+ \
`find_package` result variables \(e.g., `_FOUND`\) to follow a certain
pattern.
Call Stack \(most recent call first\):
- FindNameMismatchOld.cmake:3 \(find_package_handle_standard_args\)
- NameMismatch.cmake:4 \(find_package\)
- CMakeLists.txt:3 \(include\)
+ FindNameMismatchOld.cmake:[0-9]+ \(find_package_handle_standard_args\)
+ NameMismatch.cmake:[0-9]+ \(find_package\)
+ CMakeLists.txt:[0-9]+ \(include\)
This warning is for project developers. Use -Wno-dev to suppress it.
diff --git a/Tests/RunCMake/FPHSA/RunCMakeTest.cmake b/Tests/RunCMake/FPHSA/RunCMakeTest.cmake
index 3b095a6..be9b127 100644
--- a/Tests/RunCMake/FPHSA/RunCMakeTest.cmake
+++ b/Tests/RunCMake/FPHSA/RunCMakeTest.cmake
@@ -1,6 +1,8 @@
include(RunCMake)
run_cmake(BadFoundVar)
+run_cmake(BeforeProject-Error)
+run_cmake(BeforeProject-Missing)
run_cmake(NameMismatch)
# The pseudo module will "find" a package with the given version. Check if the
diff --git a/Tests/RunCMake/GenEx-TARGET_PROPERTY/CMakeLists.txt b/Tests/RunCMake/GenEx-TARGET_PROPERTY/CMakeLists.txt
index 32d92d8..5791993 100644
--- a/Tests/RunCMake/GenEx-TARGET_PROPERTY/CMakeLists.txt
+++ b/Tests/RunCMake/GenEx-TARGET_PROPERTY/CMakeLists.txt
@@ -1,6 +1,6 @@
-cmake_minimum_required(VERSION 3.10)
+cmake_minimum_required(VERSION 3.17)
if(RunCMake_TEST STREQUAL "LOCATION")
cmake_minimum_required(VERSION 2.8.12) # Leave CMP0026 unset.
endif()
project(${RunCMake_TEST} NONE)
-include(${RunCMake_TEST}.cmake)
+include(${RunCMake_TEST}.cmake NO_POLICY_SCOPE)
diff --git a/Tests/RunCMake/GenEx-TARGET_PROPERTY/RunCMakeTest.cmake b/Tests/RunCMake/GenEx-TARGET_PROPERTY/RunCMakeTest.cmake
index b613ad1..07052eb 100644
--- a/Tests/RunCMake/GenEx-TARGET_PROPERTY/RunCMakeTest.cmake
+++ b/Tests/RunCMake/GenEx-TARGET_PROPERTY/RunCMakeTest.cmake
@@ -13,6 +13,9 @@ run_cmake(LinkImplementationCycle5)
run_cmake(LinkImplementationCycle6)
run_cmake(LOCATION)
run_cmake(SOURCES)
+run_cmake(TransitiveBuild)
+run_cmake(TransitiveLink-CMP0166-OLD)
+run_cmake(TransitiveLink-CMP0166-NEW)
block()
run_cmake(Scope)
diff --git a/Tests/RunCMake/GenEx-TARGET_PROPERTY/TransitiveBuild-check.cmake b/Tests/RunCMake/GenEx-TARGET_PROPERTY/TransitiveBuild-check.cmake
new file mode 100644
index 0000000..65adfaf
--- /dev/null
+++ b/Tests/RunCMake/GenEx-TARGET_PROPERTY/TransitiveBuild-check.cmake
@@ -0,0 +1,25 @@
+set(expect [[
+# file\(GENERATE\) produced:
+main INCLUDE_DIRECTORIES: '[^';]*/Tests/RunCMake/GenEx-TARGET_PROPERTY/dirM;[^';]*/Tests/RunCMake/GenEx-TARGET_PROPERTY/dir1'
+main SYSTEM_INCLUDE_DIRECTORIES: '[^';]*/Tests/RunCMake/GenEx-TARGET_PROPERTY/sys1'
+main COMPILE_DEFINITIONS: 'DEFM;DEF1'
+main COMPILE_FEATURES: 'cxx_std_20;cxx_std_11'
+main COMPILE_OPTIONS: '-optM;-opt1'
+main PRECOMPILE_HEADERS: '[^';]*/Tests/RunCMake/GenEx-TARGET_PROPERTY/empty.h;[^';]*/Tests/RunCMake/GenEx-TARGET_PROPERTY/empty1.h'
+main SOURCES: 'main.c;[^';]*/Tests/RunCMake/GenEx-TARGET_PROPERTY/empty1.c'
+main AUTOMOC_MACRO_NAMES: 'MOCM;MOC1'
+main AUTOUIC_OPTIONS: '-uicM;-uic1'
+]])
+
+string(REGEX REPLACE "\r\n" "\n" expect "${expect}")
+string(REGEX REPLACE "\n+$" "" expect "${expect}")
+
+file(READ "${RunCMake_TEST_BINARY_DIR}/out.txt" actual)
+string(REGEX REPLACE "\r\n" "\n" actual "${actual}")
+string(REGEX REPLACE "\n+$" "" actual "${actual}")
+
+if(NOT actual MATCHES "^${expect}$")
+ string(REPLACE "\n" "\n expect> " expect " expect> ${expect}")
+ string(REPLACE "\n" "\n actual> " actual " actual> ${actual}")
+ message(FATAL_ERROR "Expected file(GENERATE) output:\n${expect}\ndoes not match actual output:\n${actual}")
+endif()
diff --git a/Tests/RunCMake/GenEx-TARGET_PROPERTY/TransitiveBuild.cmake b/Tests/RunCMake/GenEx-TARGET_PROPERTY/TransitiveBuild.cmake
new file mode 100644
index 0000000..8f8eb96
--- /dev/null
+++ b/Tests/RunCMake/GenEx-TARGET_PROPERTY/TransitiveBuild.cmake
@@ -0,0 +1,66 @@
+enable_language(C)
+set(CMAKE_PCH_EXTENSION "") # suppress cmake_pch from SOURCES
+
+add_library(foo1 STATIC empty.c)
+target_link_libraries(foo1 PRIVATE foo2 foo3)
+target_include_directories(foo1 INTERFACE dir1)
+target_compile_definitions(foo1 INTERFACE DEF1)
+target_compile_features(foo1 INTERFACE cxx_std_11)
+target_compile_options(foo1 INTERFACE -opt1)
+target_precompile_headers(foo1 INTERFACE "${CMAKE_CURRENT_SOURCE_DIR}/empty1.h")
+target_sources(foo1 INTERFACE "${CMAKE_CURRENT_SOURCE_DIR}/empty1.c")
+set_target_properties(foo1 PROPERTIES
+ INTERFACE_SYSTEM_INCLUDE_DIRECTORIES "${CMAKE_CURRENT_SOURCE_DIR}/sys1"
+ INTERFACE_AUTOMOC_MACRO_NAMES "MOC1"
+ INTERFACE_AUTOUIC_OPTIONS "-uic1"
+ )
+
+add_library(foo2 STATIC empty.c)
+target_include_directories(foo2 INTERFACE dir2)
+target_compile_definitions(foo2 INTERFACE DEF2)
+target_compile_features(foo2 INTERFACE cxx_std_14)
+target_compile_options(foo2 INTERFACE -opt2)
+target_precompile_headers(foo2 INTERFACE "${CMAKE_CURRENT_SOURCE_DIR}/empty2.h")
+target_sources(foo2 INTERFACE "${CMAKE_CURRENT_SOURCE_DIR}/empty2.c")
+set_target_properties(foo2 PROPERTIES
+ INTERFACE_SYSTEM_INCLUDE_DIRECTORIES "${CMAKE_CURRENT_SOURCE_DIR}/sys2"
+ INTERFACE_AUTOMOC_MACRO_NAMES "MOC2"
+ INTERFACE_AUTOUIC_OPTIONS "-uic2"
+ )
+
+add_library(foo3 STATIC empty.c)
+target_include_directories(foo3 PRIVATE dir3)
+target_compile_definitions(foo3 PRIVATE DEF3)
+target_compile_features(foo3 PRIVATE cxx_std_17)
+target_compile_options(foo3 PRIVATE -opt3)
+target_precompile_headers(foo3 PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/empty3.h")
+target_sources(foo3 PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/empty3.c")
+set_target_properties(foo3 PROPERTIES
+ SYSTEM_INCLUDE_DIRECTORIES "${CMAKE_CURRENT_SOURCE_DIR}/sys3"
+ AUTOMOC_MACRO_NAMES "MOC3"
+ AUTOUIC_OPTIONS "-uic3"
+ )
+
+add_executable(main main.c)
+target_link_libraries(main PRIVATE foo1)
+target_include_directories(main PRIVATE dirM)
+target_compile_definitions(main PRIVATE DEFM)
+target_compile_features(main PRIVATE cxx_std_20)
+target_compile_options(main PRIVATE -optM)
+target_precompile_headers(main PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/empty.h")
+set_target_properties(main PROPERTIES
+ AUTOMOC_MACRO_NAMES "MOCM"
+ AUTOUIC_OPTIONS "-uicM"
+ )
+
+file(GENERATE OUTPUT out.txt CONTENT "# file(GENERATE) produced:
+main INCLUDE_DIRECTORIES: '$<TARGET_PROPERTY:main,INCLUDE_DIRECTORIES>'
+main SYSTEM_INCLUDE_DIRECTORIES: '$<TARGET_PROPERTY:main,SYSTEM_INCLUDE_DIRECTORIES>'
+main COMPILE_DEFINITIONS: '$<TARGET_PROPERTY:main,COMPILE_DEFINITIONS>'
+main COMPILE_FEATURES: '$<TARGET_PROPERTY:main,COMPILE_FEATURES>'
+main COMPILE_OPTIONS: '$<TARGET_PROPERTY:main,COMPILE_OPTIONS>'
+main PRECOMPILE_HEADERS: '$<TARGET_PROPERTY:main,PRECOMPILE_HEADERS>'
+main SOURCES: '$<TARGET_PROPERTY:main,SOURCES>'
+main AUTOMOC_MACRO_NAMES: '$<TARGET_PROPERTY:main,AUTOMOC_MACRO_NAMES>'
+main AUTOUIC_OPTIONS: '$<TARGET_PROPERTY:main,AUTOUIC_OPTIONS>'
+")
diff --git a/Tests/RunCMake/GenEx-TARGET_PROPERTY/TransitiveLink-CMP0166-NEW-check.cmake b/Tests/RunCMake/GenEx-TARGET_PROPERTY/TransitiveLink-CMP0166-NEW-check.cmake
new file mode 100644
index 0000000..7ea95b8
--- /dev/null
+++ b/Tests/RunCMake/GenEx-TARGET_PROPERTY/TransitiveLink-CMP0166-NEW-check.cmake
@@ -0,0 +1,8 @@
+set(expect [[
+# file\(GENERATE\) produced:
+main LINK_LIBRARIES: 'foo1' # not transitive
+main LINK_DIRECTORIES: '[^';]*/Tests/RunCMake/GenEx-TARGET_PROPERTY/dirM;[^';]*/Tests/RunCMake/GenEx-TARGET_PROPERTY/dir1;[^';]*/Tests/RunCMake/GenEx-TARGET_PROPERTY/dir2'
+main LINK_OPTIONS: '-optM;-opt1;-opt2'
+main LINK_DEPENDS: '[^';]*/Tests/RunCMake/GenEx-TARGET_PROPERTY/TransitiveLink-CMP0166-NEW-build/depM;[^';]*/Tests/RunCMake/GenEx-TARGET_PROPERTY/TransitiveLink-CMP0166-NEW-build/dep1;[^';]*/Tests/RunCMake/GenEx-TARGET_PROPERTY/TransitiveLink-CMP0166-NEW-build/dep2'
+]])
+include(${CMAKE_CURRENT_LIST_DIR}/TransitiveLink-check-common.cmake)
diff --git a/Tests/RunCMake/GenEx-TARGET_PROPERTY/TransitiveLink-CMP0166-NEW.cmake b/Tests/RunCMake/GenEx-TARGET_PROPERTY/TransitiveLink-CMP0166-NEW.cmake
new file mode 100644
index 0000000..658dd84
--- /dev/null
+++ b/Tests/RunCMake/GenEx-TARGET_PROPERTY/TransitiveLink-CMP0166-NEW.cmake
@@ -0,0 +1,2 @@
+cmake_policy(SET CMP0166 NEW)
+include(TransitiveLink-common.cmake)
diff --git a/Tests/RunCMake/GenEx-TARGET_PROPERTY/TransitiveLink-CMP0166-OLD-check.cmake b/Tests/RunCMake/GenEx-TARGET_PROPERTY/TransitiveLink-CMP0166-OLD-check.cmake
new file mode 100644
index 0000000..2d430c2
--- /dev/null
+++ b/Tests/RunCMake/GenEx-TARGET_PROPERTY/TransitiveLink-CMP0166-OLD-check.cmake
@@ -0,0 +1,8 @@
+set(expect [[
+# file\(GENERATE\) produced:
+main LINK_LIBRARIES: 'foo1' # not transitive
+main LINK_DIRECTORIES: '[^';]*/Tests/RunCMake/GenEx-TARGET_PROPERTY/dirM;[^';]*/Tests/RunCMake/GenEx-TARGET_PROPERTY/dir1'
+main LINK_OPTIONS: '-optM;-opt1'
+main LINK_DEPENDS: '[^';]*/Tests/RunCMake/GenEx-TARGET_PROPERTY/TransitiveLink-CMP0166-OLD-build/depM;[^';]*/Tests/RunCMake/GenEx-TARGET_PROPERTY/TransitiveLink-CMP0166-OLD-build/dep1'
+]])
+include(${CMAKE_CURRENT_LIST_DIR}/TransitiveLink-check-common.cmake)
diff --git a/Tests/RunCMake/GenEx-TARGET_PROPERTY/TransitiveLink-CMP0166-OLD.cmake b/Tests/RunCMake/GenEx-TARGET_PROPERTY/TransitiveLink-CMP0166-OLD.cmake
new file mode 100644
index 0000000..a4a4599
--- /dev/null
+++ b/Tests/RunCMake/GenEx-TARGET_PROPERTY/TransitiveLink-CMP0166-OLD.cmake
@@ -0,0 +1,2 @@
+cmake_policy(SET CMP0166 OLD)
+include(TransitiveLink-common.cmake)
diff --git a/Tests/RunCMake/GenEx-TARGET_PROPERTY/TransitiveLink-check-common.cmake b/Tests/RunCMake/GenEx-TARGET_PROPERTY/TransitiveLink-check-common.cmake
new file mode 100644
index 0000000..42e63bc
--- /dev/null
+++ b/Tests/RunCMake/GenEx-TARGET_PROPERTY/TransitiveLink-check-common.cmake
@@ -0,0 +1,12 @@
+string(REGEX REPLACE "\r\n" "\n" expect "${expect}")
+string(REGEX REPLACE "\n+$" "" expect "${expect}")
+
+file(READ "${RunCMake_TEST_BINARY_DIR}/out.txt" actual)
+string(REGEX REPLACE "\r\n" "\n" actual "${actual}")
+string(REGEX REPLACE "\n+$" "" actual "${actual}")
+
+if(NOT actual MATCHES "^${expect}$")
+ string(REPLACE "\n" "\n expect> " expect " expect> ${expect}")
+ string(REPLACE "\n" "\n actual> " actual " actual> ${actual}")
+ message(FATAL_ERROR "Expected file(GENERATE) output:\n${expect}\ndoes not match actual output:\n${actual}")
+endif()
diff --git a/Tests/RunCMake/GenEx-TARGET_PROPERTY/TransitiveLink-common.cmake b/Tests/RunCMake/GenEx-TARGET_PROPERTY/TransitiveLink-common.cmake
new file mode 100644
index 0000000..c120366
--- /dev/null
+++ b/Tests/RunCMake/GenEx-TARGET_PROPERTY/TransitiveLink-common.cmake
@@ -0,0 +1,42 @@
+enable_language(C)
+
+add_library(foo1 STATIC empty.c)
+target_link_libraries(foo1 PRIVATE foo2 foo3)
+target_link_directories(foo1 INTERFACE dir1)
+target_link_options(foo1 INTERFACE -opt1)
+set_target_properties(foo1 PROPERTIES
+ INTERFACE_LINK_DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/dep1"
+ )
+file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/dep1" "")
+
+add_library(foo2 STATIC empty.c)
+target_link_directories(foo2 INTERFACE dir2)
+target_link_options(foo2 INTERFACE -opt2)
+set_target_properties(foo2 PROPERTIES
+ INTERFACE_LINK_DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/dep2"
+ )
+file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/dep2" "")
+
+add_library(foo3 STATIC empty.c)
+target_link_directories(foo3 PRIVATE dir3)
+target_link_options(foo3 PRIVATE -opt3)
+set_target_properties(foo3 PROPERTIES
+ LINK_DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/dep3"
+ )
+file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/dep3" "")
+
+add_executable(main main.c)
+target_link_libraries(main PRIVATE foo1)
+target_link_directories(main PRIVATE dirM)
+target_link_options(main PRIVATE -optM)
+set_target_properties(main PROPERTIES
+ LINK_DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/depM"
+ )
+file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/depM" "")
+
+file(GENERATE OUTPUT out.txt CONTENT "# file(GENERATE) produced:
+main LINK_LIBRARIES: '$<TARGET_PROPERTY:main,LINK_LIBRARIES>' # not transitive
+main LINK_DIRECTORIES: '$<TARGET_PROPERTY:main,LINK_DIRECTORIES>'
+main LINK_OPTIONS: '$<TARGET_PROPERTY:main,LINK_OPTIONS>'
+main LINK_DEPENDS: '$<TARGET_PROPERTY:main,LINK_DEPENDS>'
+")
diff --git a/Tests/RunCMake/GenEx-TARGET_PROPERTY/empty.h b/Tests/RunCMake/GenEx-TARGET_PROPERTY/empty.h
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/Tests/RunCMake/GenEx-TARGET_PROPERTY/empty.h
diff --git a/Tests/RunCMake/GenEx-TARGET_PROPERTY/empty1.c b/Tests/RunCMake/GenEx-TARGET_PROPERTY/empty1.c
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/Tests/RunCMake/GenEx-TARGET_PROPERTY/empty1.c
diff --git a/Tests/RunCMake/GenEx-TARGET_PROPERTY/empty1.h b/Tests/RunCMake/GenEx-TARGET_PROPERTY/empty1.h
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/Tests/RunCMake/GenEx-TARGET_PROPERTY/empty1.h
diff --git a/Tests/RunCMake/GenEx-TARGET_PROPERTY/empty2.h b/Tests/RunCMake/GenEx-TARGET_PROPERTY/empty2.h
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/Tests/RunCMake/GenEx-TARGET_PROPERTY/empty2.h
diff --git a/Tests/RunCMake/GenEx-TARGET_PROPERTY/empty3.h b/Tests/RunCMake/GenEx-TARGET_PROPERTY/empty3.h
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/Tests/RunCMake/GenEx-TARGET_PROPERTY/empty3.h
diff --git a/Tests/RunCMake/GenEx-TARGET_PROPERTY/main.c b/Tests/RunCMake/GenEx-TARGET_PROPERTY/main.c
new file mode 100644
index 0000000..8488f4e
--- /dev/null
+++ b/Tests/RunCMake/GenEx-TARGET_PROPERTY/main.c
@@ -0,0 +1,4 @@
+int main(void)
+{
+ return 0;
+}
diff --git a/Tests/RunCMake/VS10Project/VsCustomProps-check.cmake b/Tests/RunCMake/VS10Project/VsCustomProps-check.cmake
index 22a3df0..ad585d5 100644
--- a/Tests/RunCMake/VS10Project/VsCustomProps-check.cmake
+++ b/Tests/RunCMake/VS10Project/VsCustomProps-check.cmake
@@ -1,25 +1,30 @@
-set(vcProjectFile "${RunCMake_TEST_BINARY_DIR}/foo.vcxproj")
-if(NOT EXISTS "${vcProjectFile}")
- set(RunCMake_TEST_FAILED "Project file ${vcProjectFile} does not exist.")
- return()
-endif()
+macro(check_custom_prop suffix)
+ set(vcProjectFile "${RunCMake_TEST_BINARY_DIR}/foo.vcxproj${suffix}")
+ if(NOT EXISTS "${vcProjectFile}")
+ set(RunCMake_TEST_FAILED "Project file ${vcProjectFile} does not exist.")
+ return()
+ endif()
-set(importFound FALSE)
+ set(importFound FALSE)
-set(props_file "${RunCMake_SOURCE_DIR}/my.props")
-file(TO_NATIVE_PATH "${props_file}" check_file)
-file(STRINGS "${vcProjectFile}" lines)
-foreach(line IN LISTS lines)
- if(line MATCHES "^ *<Import Project=\"([^\"]+)\".*Label=\"([^\"]+)\".*$")
- if("${CMAKE_MATCH_1}" STREQUAL "${check_file}" AND
- "${CMAKE_MATCH_2}" STREQUAL "LocalAppDataPlatform")
- message(STATUS "foo.vcxproj is importing ${check_file}")
- set(importFound TRUE)
+ set(props_file "${RunCMake_SOURCE_DIR}/my.props")
+ file(TO_NATIVE_PATH "${props_file}" check_file)
+ file(STRINGS "${vcProjectFile}" lines)
+ foreach(line IN LISTS lines)
+ if(line MATCHES "^ *<Import Project=\"([^\"]+)\".*Label=\"([^\"]+)\".*$")
+ if("${CMAKE_MATCH_1}" STREQUAL "${check_file}" AND
+ "${CMAKE_MATCH_2}" STREQUAL "LocalAppDataPlatform")
+ message(STATUS "foo.vcxproj${suffix} is importing ${check_file}")
+ set(importFound TRUE)
+ endif()
endif()
+ endforeach()
+
+ if(NOT importFound)
+ set(RunCMake_TEST_FAILED "Import of custom .props file not found.")
+ return()
endif()
-endforeach()
+endmacro()
-if(NOT importFound)
- set(RunCMake_TEST_FAILED "Import of custom .props file not found.")
- return()
-endif()
+check_custom_prop("")
+check_custom_prop(".filters")
diff --git a/Tests/RunCMake/VS10Project/VsCustomProps.cmake b/Tests/RunCMake/VS10Project/VsCustomProps.cmake
index fbbcfcf..d6c905f 100644
--- a/Tests/RunCMake/VS10Project/VsCustomProps.cmake
+++ b/Tests/RunCMake/VS10Project/VsCustomProps.cmake
@@ -4,4 +4,5 @@ add_library(foo foo.cpp)
set(props_file "${CMAKE_CURRENT_SOURCE_DIR}/my.props")
set_target_properties(foo PROPERTIES
- VS_USER_PROPS "${props_file}")
+ VS_USER_PROPS "${props_file}"
+ VS_FILTER_PROPS "${props_file}")
diff --git a/Utilities/Sphinx/conf.py.in b/Utilities/Sphinx/conf.py.in
index 20e1340..09a7d5a 100644
--- a/Utilities/Sphinx/conf.py.in
+++ b/Utilities/Sphinx/conf.py.in
@@ -98,6 +98,7 @@ linkcheck_allowed_redirects = {
r'https://cdash\.org': r'https://www\.cdash\.org/',
r'https://cmake.org/get-involved/': r'https://cmake.org/documentation/',
r'https://docs\.nvidia\.com/cuda/': r'https://docs\.nvidia\.com/cuda/index\.html',
+ r'https://learn\.microsoft\.com/en-us/cpp/build/reference/openmp-enable-openmp-2-0-support': r'https://learn\.microsoft\.com/en-us/cpp/build/reference/openmp-enable-openmp-2-0-support\?.*',
r'https://learn\.microsoft\.com/en-us/cpp/c-language/parsing-c-command-line-arguments': r'https://learn\.microsoft\.com/en-us/cpp/c-language/parsing-c-command-line-arguments\?.*',
r'https://openjdk\.java\.net/jeps/313': r'https://openjdk\.org:443/jeps/313',
r'https://www\.sphinx-doc\.org': r'https://www\.sphinx-doc\.org/en/master/',