summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Help/manual/cmake-compile-features.7.rst10
-rw-r--r--Help/manual/cmake-generator-expressions.7.rst3
-rw-r--r--Help/prop_gbl/CMAKE_CXX_KNOWN_FEATURES.rst3
-rw-r--r--Help/prop_tgt/CXX_STANDARD.rst2
-rw-r--r--Help/release/dev/features-c++20.rst6
-rw-r--r--Help/release/dev/features-msvc-c.rst5
-rw-r--r--Help/release/dev/genex-TARGET_NAME_IF_EXISTS.rst6
-rw-r--r--Modules/CMakeCUDACompilerId.cu.in4
-rw-r--r--Modules/CMakeCXXCompiler.cmake.in1
-rw-r--r--Modules/CMakeCXXCompilerId.cpp.in4
-rw-r--r--Modules/CMakeDetermineCompileFeatures.cmake6
-rw-r--r--Modules/Compiler/CMakeCommonCompilerMacros.cmake3
-rw-r--r--Modules/Compiler/Clang-CXX.cmake12
-rw-r--r--Modules/Compiler/GNU-CXX.cmake10
-rw-r--r--Modules/Compiler/MSVC-C-FeatureTests.cmake8
-rw-r--r--Modules/Compiler/MSVC-C.cmake25
-rw-r--r--Modules/Compiler/MSVC-CXX.cmake13
-rw-r--r--Modules/FindCUDA.cmake24
-rw-r--r--Source/CMakeVersion.cmake2
-rw-r--r--Source/CTest/cmCTestCoverageHandler.cxx3
-rw-r--r--Source/CTest/cmCTestSVN.h4
-rw-r--r--Source/cmCMakeMinimumRequired.cxx45
-rw-r--r--Source/cmCMakeMinimumRequired.h2
-rw-r--r--Source/cmComputeLinkInformation.cxx40
-rw-r--r--Source/cmComputeLinkInformation.h28
-rw-r--r--Source/cmGeneratorExpressionNode.cxx35
-rw-r--r--Source/cmLocalGenerator.cxx12
-rw-r--r--Source/cmLocalVisualStudio7Generator.cxx33
-rw-r--r--Source/cmLocalVisualStudio7Generator.h15
-rw-r--r--Source/cmMakefile.cxx23
-rw-r--r--Source/cmMakefile.h2
-rw-r--r--Source/cmSystemTools.cxx13
-rw-r--r--Source/cmTarget.cxx7
-rw-r--r--Source/cmVisualStudio10TargetGenerator.cxx107
-rw-r--r--Source/cmVisualStudio10TargetGenerator.h7
-rw-r--r--Source/cmVisualStudioGeneratorOptions.cxx62
-rw-r--r--Source/cmVisualStudioGeneratorOptions.h20
-rw-r--r--Source/cmake.h1
-rw-r--r--Source/kwsys/SystemTools.cxx15
-rw-r--r--Source/kwsys/Terminal.c1
-rw-r--r--Source/kwsys/testSystemTools.cxx28
-rw-r--r--Tests/CMakeCommands/target_compile_features/CMakeLists.txt6
-rw-r--r--Tests/CompileFeatures/CMakeLists.txt19
-rw-r--r--Tests/CompileFeatures/default_dialect.cpp6
-rw-r--r--Tests/CompileFeatures/genex_test.c12
-rw-r--r--Tests/RunCMake/CTest/CTestTestfile.cmake.in1
-rw-r--r--Tests/RunCMake/CTest/NotOn-check.cmake8
-rw-r--r--Tests/RunCMake/CTest/NotOn.cmake3
-rw-r--r--Tests/RunCMake/CTest/RunCMakeTest.cmake2
-rw-r--r--Tests/RunCMake/GeneratorExpression/RunCMakeTest.cmake4
-rw-r--r--Tests/RunCMake/GeneratorExpression/TARGET_NAME_IF_EXISTS-check.cmake6
-rw-r--r--Tests/RunCMake/GeneratorExpression/TARGET_NAME_IF_EXISTS-empty-arg-result.txt1
-rw-r--r--Tests/RunCMake/GeneratorExpression/TARGET_NAME_IF_EXISTS-empty-arg-stderr.txt9
-rw-r--r--Tests/RunCMake/GeneratorExpression/TARGET_NAME_IF_EXISTS-empty-arg.cmake2
-rw-r--r--Tests/RunCMake/GeneratorExpression/TARGET_NAME_IF_EXISTS-no-arg-result.txt1
-rw-r--r--Tests/RunCMake/GeneratorExpression/TARGET_NAME_IF_EXISTS-no-arg-stderr.txt8
-rw-r--r--Tests/RunCMake/GeneratorExpression/TARGET_NAME_IF_EXISTS-no-arg.cmake2
-rw-r--r--Tests/RunCMake/GeneratorExpression/TARGET_NAME_IF_EXISTS-not-a-target-check.cmake5
-rw-r--r--Tests/RunCMake/GeneratorExpression/TARGET_NAME_IF_EXISTS-not-a-target.cmake2
-rw-r--r--Tests/RunCMake/GeneratorExpression/TARGET_NAME_IF_EXISTS.cmake3
-rw-r--r--Tests/RunCMake/cmake_minimum_required/Future.cmake1
-rw-r--r--Tests/RunCMake/cmake_minimum_required/RunCMakeTest.cmake2
-rw-r--r--Tests/RunCMake/cmake_minimum_required/Unknown-result.txt1
-rw-r--r--Tests/RunCMake/cmake_minimum_required/Unknown-stderr.txt4
-rw-r--r--Tests/RunCMake/cmake_minimum_required/Unknown.cmake1
65 files changed, 508 insertions, 251 deletions
diff --git a/Help/manual/cmake-compile-features.7.rst b/Help/manual/cmake-compile-features.7.rst
index e9495c6..634da10 100644
--- a/Help/manual/cmake-compile-features.7.rst
+++ b/Help/manual/cmake-compile-features.7.rst
@@ -331,9 +331,9 @@ and :prop_gbl:`compile features <CMAKE_CXX_KNOWN_FEATURES>` available from
the following :variable:`compiler ids <CMAKE_<LANG>_COMPILER_ID>` as of the
versions specified for each:
-* ``AppleClang``: Apple Clang for Xcode versions 4.4 though 6.2.
-* ``Clang``: Clang compiler versions 2.9 through 3.4.
-* ``GNU``: GNU compiler versions 4.4 through 5.0.
+* ``AppleClang``: Apple Clang for Xcode versions 4.4 though 9.2.
+* ``Clang``: Clang compiler versions 2.9 through 6.0.
+* ``GNU``: GNU compiler versions 4.4 through 8.0.
* ``MSVC``: Microsoft Visual Studio versions 2010 through 2017.
* ``SunPro``: Oracle SolarisStudio versions 12.4 through 12.6.
* ``Intel``: Intel compiler versions 12.1 through 17.0.
@@ -344,7 +344,7 @@ the following :variable:`compiler ids <CMAKE_<LANG>_COMPILER_ID>` as of the
versions specified for each:
* all compilers and versions listed above for C++.
-* ``GNU``: GNU compiler versions 3.4 through 5.0.
+* ``GNU``: GNU compiler versions 3.4 through 8.0.
CMake is currently aware of the :prop_tgt:`C++ standards <CXX_STANDARD>` and
their associated meta-features (e.g. ``cxx_std_11``) available from the
@@ -366,4 +366,4 @@ CMake is currently aware of the :prop_tgt:`CUDA standards <CUDA_STANDARD>`
from the following :variable:`compiler ids <CMAKE_<LANG>_COMPILER_ID>` as of the
versions specified for each:
-* ``NVIDIA``: NVIDIA nvcc compiler 7.5 though 8.0.
+* ``NVIDIA``: NVIDIA nvcc compiler 7.5 though 9.1.
diff --git a/Help/manual/cmake-generator-expressions.7.rst b/Help/manual/cmake-generator-expressions.7.rst
index d3514ab..0e73bd2 100644
--- a/Help/manual/cmake-generator-expressions.7.rst
+++ b/Help/manual/cmake-generator-expressions.7.rst
@@ -274,6 +274,9 @@ Available output expressions are:
Marks ``...`` as being the name of a target. This is required if exporting
targets to multiple dependent export sets. The ``...`` must be a literal
name of a target- it may not contain generator expressions.
+``$<TARGET_NAME_IF_EXISTS:...>``
+ Expands to the ``...`` if the given target exists, an empty string
+ otherwise.
``$<LINK_ONLY:...>``
Content of ``...`` except when evaluated in a link interface while
propagating :ref:`Target Usage Requirements`, in which case it is the
diff --git a/Help/prop_gbl/CMAKE_CXX_KNOWN_FEATURES.rst b/Help/prop_gbl/CMAKE_CXX_KNOWN_FEATURES.rst
index 2ad8157..262a67c 100644
--- a/Help/prop_gbl/CMAKE_CXX_KNOWN_FEATURES.rst
+++ b/Help/prop_gbl/CMAKE_CXX_KNOWN_FEATURES.rst
@@ -26,6 +26,9 @@ The features known to this version of CMake are:
``cxx_std_17``
Compiler mode is aware of C++ 17.
+``cxx_std_20``
+ Compiler mode is aware of C++ 20.
+
``cxx_aggregate_default_initializers``
Aggregate default initializers, as defined in N3605_.
diff --git a/Help/prop_tgt/CXX_STANDARD.rst b/Help/prop_tgt/CXX_STANDARD.rst
index 0762033..ccc0147 100644
--- a/Help/prop_tgt/CXX_STANDARD.rst
+++ b/Help/prop_tgt/CXX_STANDARD.rst
@@ -9,7 +9,7 @@ flag such as ``-std=gnu++11`` to the compile line. For compilers that
have no notion of a standard level, such as Microsoft Visual C++ before
2015 Update 3, this has no effect.
-Supported values are ``98``, ``11``, ``14``, and ``17``.
+Supported values are ``98``, ``11``, ``14``, ``17``, and ``20``.
If the value requested does not result in a compile flag being added for
the compiler in use, a previous standard flag will be added instead. This
diff --git a/Help/release/dev/features-c++20.rst b/Help/release/dev/features-c++20.rst
new file mode 100644
index 0000000..f7d050b
--- /dev/null
+++ b/Help/release/dev/features-c++20.rst
@@ -0,0 +1,6 @@
+features-c++20
+--------------
+
+* The :manual:`Compile Features <cmake-compile-features(7)>` functionality
+ is now aware of C++ 20. No specific features are yet enumerated besides
+ the ``cxx_std_20`` meta-feature.
diff --git a/Help/release/dev/features-msvc-c.rst b/Help/release/dev/features-msvc-c.rst
new file mode 100644
index 0000000..0c55544
--- /dev/null
+++ b/Help/release/dev/features-msvc-c.rst
@@ -0,0 +1,5 @@
+features-msvc-c
+---------------
+
+* The :manual:`Compile Features <cmake-compile-features(7)>` functionality
+ is now aware of the availability of C features in MSVC since VS 2010.
diff --git a/Help/release/dev/genex-TARGET_NAME_IF_EXISTS.rst b/Help/release/dev/genex-TARGET_NAME_IF_EXISTS.rst
new file mode 100644
index 0000000..416e812
--- /dev/null
+++ b/Help/release/dev/genex-TARGET_NAME_IF_EXISTS.rst
@@ -0,0 +1,6 @@
+genex-TARGET_NAME_IF_EXISTS
+---------------------------
+
+* A new ``$<TARGET_NAME_IF_EXISTS:...>``
+ :manual:`generator expression <cmake-generator-expressions(7)>`
+ has been added.
diff --git a/Modules/CMakeCUDACompilerId.cu.in b/Modules/CMakeCUDACompilerId.cu.in
index 018bab7..6eda924 100644
--- a/Modules/CMakeCUDACompilerId.cu.in
+++ b/Modules/CMakeCUDACompilerId.cu.in
@@ -17,7 +17,9 @@ char const* info_simulate = "INFO" ":" "simulate[" SIMULATE_ID "]";
@CMAKE_CUDA_COMPILER_ID_ERROR_FOR_TEST@
const char* info_language_dialect_default = "INFO" ":" "dialect_default["
-#if __cplusplus > 201402L
+#if __cplusplus > 201703L
+ "20"
+#elif __cplusplus >= 201703L
"17"
#elif __cplusplus >= 201402L
"14"
diff --git a/Modules/CMakeCXXCompiler.cmake.in b/Modules/CMakeCXXCompiler.cmake.in
index df57a4f..974886d 100644
--- a/Modules/CMakeCXXCompiler.cmake.in
+++ b/Modules/CMakeCXXCompiler.cmake.in
@@ -10,6 +10,7 @@ set(CMAKE_CXX98_COMPILE_FEATURES "@CMAKE_CXX98_COMPILE_FEATURES@")
set(CMAKE_CXX11_COMPILE_FEATURES "@CMAKE_CXX11_COMPILE_FEATURES@")
set(CMAKE_CXX14_COMPILE_FEATURES "@CMAKE_CXX14_COMPILE_FEATURES@")
set(CMAKE_CXX17_COMPILE_FEATURES "@CMAKE_CXX17_COMPILE_FEATURES@")
+set(CMAKE_CXX20_COMPILE_FEATURES "@CMAKE_CXX20_COMPILE_FEATURES@")
set(CMAKE_CXX_PLATFORM_ID "@CMAKE_CXX_PLATFORM_ID@")
set(CMAKE_CXX_SIMULATE_ID "@CMAKE_CXX_SIMULATE_ID@")
diff --git a/Modules/CMakeCXXCompilerId.cpp.in b/Modules/CMakeCXXCompilerId.cpp.in
index 4cb2267..34639b4 100644
--- a/Modules/CMakeCXXCompilerId.cpp.in
+++ b/Modules/CMakeCXXCompilerId.cpp.in
@@ -34,7 +34,9 @@ char const *info_cray = "INFO" ":" "compiler_wrapper[CrayPrgEnv]";
#endif
const char* info_language_dialect_default = "INFO" ":" "dialect_default["
-#if CXX_STD > 201402L
+#if CXX_STD > 201703L
+ "20"
+#elif CXX_STD >= 201703L
"17"
#elif CXX_STD >= 201402L
"14"
diff --git a/Modules/CMakeDetermineCompileFeatures.cmake b/Modules/CMakeDetermineCompileFeatures.cmake
index 3ed92be..01a81a1 100644
--- a/Modules/CMakeDetermineCompileFeatures.cmake
+++ b/Modules/CMakeDetermineCompileFeatures.cmake
@@ -49,6 +49,7 @@ function(cmake_determine_compile_features lang)
set(CMAKE_CXX11_COMPILE_FEATURES)
set(CMAKE_CXX14_COMPILE_FEATURES)
set(CMAKE_CXX17_COMPILE_FEATURES)
+ set(CMAKE_CXX20_COMPILE_FEATURES)
include("${CMAKE_ROOT}/Modules/Internal/FeatureTesting.cmake")
@@ -59,6 +60,9 @@ function(cmake_determine_compile_features lang)
return()
endif()
+ if (CMAKE_CXX17_COMPILE_FEATURES AND CMAKE_CXX20_COMPILE_FEATURES)
+ list(REMOVE_ITEM CMAKE_CXX20_COMPILE_FEATURES ${CMAKE_CXX17_COMPILE_FEATURES})
+ endif()
if (CMAKE_CXX14_COMPILE_FEATURES AND CMAKE_CXX17_COMPILE_FEATURES)
list(REMOVE_ITEM CMAKE_CXX17_COMPILE_FEATURES ${CMAKE_CXX14_COMPILE_FEATURES})
endif()
@@ -75,6 +79,7 @@ function(cmake_determine_compile_features lang)
${CMAKE_CXX11_COMPILE_FEATURES}
${CMAKE_CXX14_COMPILE_FEATURES}
${CMAKE_CXX17_COMPILE_FEATURES}
+ ${CMAKE_CXX20_COMPILE_FEATURES}
)
endif()
@@ -83,6 +88,7 @@ function(cmake_determine_compile_features lang)
set(CMAKE_CXX11_COMPILE_FEATURES ${CMAKE_CXX11_COMPILE_FEATURES} PARENT_SCOPE)
set(CMAKE_CXX14_COMPILE_FEATURES ${CMAKE_CXX14_COMPILE_FEATURES} PARENT_SCOPE)
set(CMAKE_CXX17_COMPILE_FEATURES ${CMAKE_CXX17_COMPILE_FEATURES} PARENT_SCOPE)
+ set(CMAKE_CXX20_COMPILE_FEATURES ${CMAKE_CXX20_COMPILE_FEATURES} PARENT_SCOPE)
message(STATUS "Detecting ${lang} compile features - done")
endif()
diff --git a/Modules/Compiler/CMakeCommonCompilerMacros.cmake b/Modules/Compiler/CMakeCommonCompilerMacros.cmake
index 684fd30..ad464c7 100644
--- a/Modules/Compiler/CMakeCommonCompilerMacros.cmake
+++ b/Modules/Compiler/CMakeCommonCompilerMacros.cmake
@@ -78,6 +78,9 @@ endmacro()
# Define to allow compile features to be automatically determined
macro(cmake_record_cxx_compile_features)
set(_result 0)
+ if(_result EQUAL 0 AND DEFINED CMAKE_CXX20_STANDARD_COMPILE_OPTION)
+ _record_compiler_features_cxx(20)
+ endif()
if(_result EQUAL 0 AND DEFINED CMAKE_CXX17_STANDARD_COMPILE_OPTION)
_record_compiler_features_cxx(17)
endif()
diff --git a/Modules/Compiler/Clang-CXX.cmake b/Modules/Compiler/Clang-CXX.cmake
index efc68b3..321ddf6 100644
--- a/Modules/Compiler/Clang-CXX.cmake
+++ b/Modules/Compiler/Clang-CXX.cmake
@@ -32,10 +32,18 @@ if(NOT "x${CMAKE_CXX_SIMULATE_ID}" STREQUAL "xMSVC")
set(CMAKE_CXX14_EXTENSION_COMPILE_OPTION "-std=gnu++1y")
endif()
- if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 3.5)
+ if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.0)
+ set(CMAKE_CXX17_STANDARD_COMPILE_OPTION "-std=c++17")
+ set(CMAKE_CXX17_EXTENSION_COMPILE_OPTION "-std=gnu++17")
+ elseif (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 3.5)
set(CMAKE_CXX17_STANDARD_COMPILE_OPTION "-std=c++1z")
set(CMAKE_CXX17_EXTENSION_COMPILE_OPTION "-std=gnu++1z")
endif()
+
+ if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.0)
+ set(CMAKE_CXX20_STANDARD_COMPILE_OPTION "-std=c++2a")
+ set(CMAKE_CXX20_EXTENSION_COMPILE_OPTION "-std=gnu++2a")
+ endif()
else()
# clang-cl does not know these options because it behaves like cl.exe
set(CMAKE_CXX98_STANDARD_COMPILE_OPTION "")
@@ -46,6 +54,8 @@ else()
set(CMAKE_CXX14_EXTENSION_COMPILE_OPTION "")
set(CMAKE_CXX17_STANDARD_COMPILE_OPTION "")
set(CMAKE_CXX17_EXTENSION_COMPILE_OPTION "")
+ set(CMAKE_CXX20_STANDARD_COMPILE_OPTION "")
+ set(CMAKE_CXX20_EXTENSION_COMPILE_OPTION "")
endif()
if(NOT "x${CMAKE_CXX_SIMULATE_ID}" STREQUAL "xMSVC")
diff --git a/Modules/Compiler/GNU-CXX.cmake b/Modules/Compiler/GNU-CXX.cmake
index 4f1f30e..0058223 100644
--- a/Modules/Compiler/GNU-CXX.cmake
+++ b/Modules/Compiler/GNU-CXX.cmake
@@ -33,9 +33,17 @@ elseif (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.8)
set(CMAKE_CXX14_EXTENSION_COMPILE_OPTION "-std=gnu++1y")
endif()
-if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.1)
+if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 8.0)
+ set(CMAKE_CXX17_STANDARD_COMPILE_OPTION "-std=c++17")
+ set(CMAKE_CXX17_EXTENSION_COMPILE_OPTION "-std=gnu++17")
+elseif (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.1)
set(CMAKE_CXX17_STANDARD_COMPILE_OPTION "-std=c++1z")
set(CMAKE_CXX17_EXTENSION_COMPILE_OPTION "-std=gnu++1z")
endif()
+if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 8.0)
+ set(CMAKE_CXX20_STANDARD_COMPILE_OPTION "-std=c++2a")
+ set(CMAKE_CXX20_EXTENSION_COMPILE_OPTION "-std=gnu++2a")
+endif()
+
__compiler_check_default_language_standard(CXX 3.4 98 6.0 14)
diff --git a/Modules/Compiler/MSVC-C-FeatureTests.cmake b/Modules/Compiler/MSVC-C-FeatureTests.cmake
new file mode 100644
index 0000000..3f09be2
--- /dev/null
+++ b/Modules/Compiler/MSVC-C-FeatureTests.cmake
@@ -0,0 +1,8 @@
+set(_cmake_oldestSupported "_MSC_VER >= 1600")
+
+# Not yet supported:
+#set(_cmake_feature_test_c_static_assert "")
+#set(_cmake_feature_test_c_restrict "")
+
+set(_cmake_feature_test_c_variadic_macros "${_cmake_oldestSupported}")
+set(_cmake_feature_test_c_function_prototypes "${_cmake_oldestSupported}")
diff --git a/Modules/Compiler/MSVC-C.cmake b/Modules/Compiler/MSVC-C.cmake
new file mode 100644
index 0000000..22c34f8
--- /dev/null
+++ b/Modules/Compiler/MSVC-C.cmake
@@ -0,0 +1,25 @@
+# MSVC has no specific options to set C language standards, but set them as
+# empty strings anyways so the feature test infrastructure can at least check
+# to see if they are defined.
+set(CMAKE_C90_STANDARD_COMPILE_OPTION "")
+set(CMAKE_C90_EXTENSION_COMPILE_OPTION "")
+set(CMAKE_C99_STANDARD_COMPILE_OPTION "")
+set(CMAKE_C99_EXTENSION_COMPILE_OPTION "")
+set(CMAKE_C11_STANDARD_COMPILE_OPTION "")
+set(CMAKE_C11_EXTENSION_COMPILE_OPTION "")
+
+# There is no meaningful default for this
+set(CMAKE_C_STANDARD_DEFAULT "")
+
+# There are no C compiler modes so we only need to test features once.
+# Override the default macro for this special case. Pretend that
+# all language standards are available so that at least compilation
+# can be attempted.
+macro(cmake_record_c_compile_features)
+ list(APPEND CMAKE_C_COMPILE_FEATURES
+ c_std_90
+ c_std_99
+ c_std_11
+ )
+ _record_compiler_features(C "" CMAKE_C_COMPILE_FEATURES)
+endmacro()
diff --git a/Modules/Compiler/MSVC-CXX.cmake b/Modules/Compiler/MSVC-CXX.cmake
index 789fff5..be259ff 100644
--- a/Modules/Compiler/MSVC-CXX.cmake
+++ b/Modules/Compiler/MSVC-CXX.cmake
@@ -22,6 +22,10 @@ if ((CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 19.0.24215.1 AND
set(CMAKE_CXX17_STANDARD_COMPILE_OPTION "-std:c++latest")
set(CMAKE_CXX17_EXTENSION_COMPILE_OPTION "-std:c++latest")
endif()
+ if (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 19.12.25835)
+ set(CMAKE_CXX20_STANDARD_COMPILE_OPTION "-std:c++latest")
+ set(CMAKE_CXX20_EXTENSION_COMPILE_OPTION "-std:c++latest")
+ endif()
__compiler_check_default_language_standard(CXX 19.0 14)
@@ -29,6 +33,12 @@ if ((CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 19.0.24215.1 AND
# for meta-features for C++14 and above. Override the default macro
# to avoid doing unnecessary work.
macro(cmake_record_cxx_compile_features)
+ if (DEFINED CMAKE_CXX20_STANDARD_COMPILE_OPTION)
+ list(APPEND CMAKE_CXX20_COMPILE_FEATURES cxx_std_20)
+ endif()
+ # The main cmake_record_cxx_compile_features macro makes all
+ # these conditional on CMAKE_CXX##_STANDARD_COMPILE_OPTION,
+ # but we can skip the conditions because we set them above.
list(APPEND CMAKE_CXX17_COMPILE_FEATURES cxx_std_17)
list(APPEND CMAKE_CXX14_COMPILE_FEATURES cxx_std_14)
list(APPEND CMAKE_CXX98_COMPILE_FEATURES cxx_std_11) # no flag needed for 11
@@ -46,6 +56,8 @@ elseif (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 16.0)
set(CMAKE_CXX14_EXTENSION_COMPILE_OPTION "")
set(CMAKE_CXX17_STANDARD_COMPILE_OPTION "")
set(CMAKE_CXX17_EXTENSION_COMPILE_OPTION "")
+ set(CMAKE_CXX20_STANDARD_COMPILE_OPTION "")
+ set(CMAKE_CXX20_EXTENSION_COMPILE_OPTION "")
# There is no meaningful default for this
set(CMAKE_CXX_STANDARD_DEFAULT "")
@@ -60,6 +72,7 @@ elseif (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 16.0)
cxx_std_11
cxx_std_14
cxx_std_17
+ cxx_std_20
)
_record_compiler_features(CXX "" CMAKE_CXX_COMPILE_FEATURES)
endmacro()
diff --git a/Modules/FindCUDA.cmake b/Modules/FindCUDA.cmake
index 119fc13..6f6f349 100644
--- a/Modules/FindCUDA.cmake
+++ b/Modules/FindCUDA.cmake
@@ -733,16 +733,20 @@ endif()
# CUDA_NVCC_EXECUTABLE
-cuda_find_host_program(CUDA_NVCC_EXECUTABLE
- NAMES nvcc
- PATHS "${CUDA_TOOLKIT_ROOT_DIR}"
- ENV CUDA_PATH
- ENV CUDA_BIN_PATH
- PATH_SUFFIXES bin bin64
- NO_DEFAULT_PATH
- )
-# Search default search paths, after we search our own set of paths.
-cuda_find_host_program(CUDA_NVCC_EXECUTABLE nvcc)
+if(DEFINED ENV{CUDA_NVCC_EXECUTABLE})
+ set(CUDA_NVCC_EXECUTABLE "$ENV{CUDA_NVCC_EXECUTABLE}" CACHE FILEPATH "The CUDA compiler")
+else()
+ cuda_find_host_program(CUDA_NVCC_EXECUTABLE
+ NAMES nvcc
+ PATHS "${CUDA_TOOLKIT_ROOT_DIR}"
+ ENV CUDA_PATH
+ ENV CUDA_BIN_PATH
+ PATH_SUFFIXES bin bin64
+ NO_DEFAULT_PATH
+ )
+ # Search default search paths, after we search our own set of paths.
+ cuda_find_host_program(CUDA_NVCC_EXECUTABLE nvcc)
+endif()
mark_as_advanced(CUDA_NVCC_EXECUTABLE)
if(CUDA_NVCC_EXECUTABLE AND NOT CUDA_VERSION)
diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake
index 0686b72..df5dbc2 100644
--- a/Source/CMakeVersion.cmake
+++ b/Source/CMakeVersion.cmake
@@ -1,5 +1,5 @@
# CMake version number components.
set(CMake_VERSION_MAJOR 3)
set(CMake_VERSION_MINOR 11)
-set(CMake_VERSION_PATCH 20180326)
+set(CMake_VERSION_PATCH 20180402)
#set(CMake_VERSION_RC 1)
diff --git a/Source/CTest/cmCTestCoverageHandler.cxx b/Source/CTest/cmCTestCoverageHandler.cxx
index 6cf0ac2..bafbe9a 100644
--- a/Source/CTest/cmCTestCoverageHandler.cxx
+++ b/Source/CTest/cmCTestCoverageHandler.cxx
@@ -928,7 +928,8 @@ int cmCTestCoverageHandler::HandleGCovCoverage(
std::string gcovCommand =
this->CTest->GetCTestConfiguration("CoverageCommand");
if (gcovCommand.empty()) {
- cmCTestLog(this->CTest, WARNING, "Could not find gcov." << std::endl);
+ cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
+ "Could not find gcov." << std::endl, this->Quiet);
return 0;
}
std::string gcovExtraFlags =
diff --git a/Source/CTest/cmCTestSVN.h b/Source/CTest/cmCTestSVN.h
index dbc7fde..a467ede 100644
--- a/Source/CTest/cmCTestSVN.h
+++ b/Source/CTest/cmCTestSVN.h
@@ -8,6 +8,7 @@
#include "cmCTestGlobalVC.h"
#include <iosfwd>
+#include <list>
#include <string>
#include <vector>
@@ -70,7 +71,8 @@ private:
friend struct Revision;
// Info of all the repositories (root, externals and nested ones).
- std::vector<SVNInfo> Repositories;
+ // Use std::list so the elements don't move in memory.
+ std::list<SVNInfo> Repositories;
// Pointer to the infos of the root repository.
SVNInfo* RootInfo;
diff --git a/Source/cmCMakeMinimumRequired.cxx b/Source/cmCMakeMinimumRequired.cxx
index c4834a8..2b51976 100644
--- a/Source/cmCMakeMinimumRequired.cxx
+++ b/Source/cmCMakeMinimumRequired.cxx
@@ -42,7 +42,7 @@ bool cmCMakeMinimumRequired::InitialPass(std::vector<std::string> const& args,
// Make sure there was a version to check.
if (version_string.empty()) {
- return this->EnforceUnknownArguments();
+ return this->EnforceUnknownArguments(std::string());
}
// Separate the <min> version and any trailing ...<max> component.
@@ -102,7 +102,7 @@ bool cmCMakeMinimumRequired::InitialPass(std::vector<std::string> const& args,
}
// The version is not from the future, so enforce unknown arguments.
- if (!this->EnforceUnknownArguments()) {
+ if (!this->EnforceUnknownArguments(version_max)) {
return false;
}
@@ -118,14 +118,39 @@ bool cmCMakeMinimumRequired::InitialPass(std::vector<std::string> const& args,
return true;
}
-bool cmCMakeMinimumRequired::EnforceUnknownArguments()
+bool cmCMakeMinimumRequired::EnforceUnknownArguments(
+ std::string const& version_max)
{
- if (!this->UnknownArguments.empty()) {
- std::ostringstream e;
- e << "called with unknown argument \"" << this->UnknownArguments[0]
- << "\".";
- this->SetError(e.str());
- return false;
+ if (this->UnknownArguments.empty()) {
+ return true;
}
- return true;
+
+ // Consider the max version if at least two components were given.
+ unsigned int max_major = 0;
+ unsigned int max_minor = 0;
+ unsigned int max_patch = 0;
+ unsigned int max_tweak = 0;
+ if (sscanf(version_max.c_str(), "%u.%u.%u.%u", &max_major, &max_minor,
+ &max_patch, &max_tweak) >= 2) {
+ unsigned int current_major = cmVersion::GetMajorVersion();
+ unsigned int current_minor = cmVersion::GetMinorVersion();
+ unsigned int current_patch = cmVersion::GetPatchVersion();
+ unsigned int current_tweak = cmVersion::GetTweakVersion();
+
+ if ((current_major < max_major) ||
+ (current_major == max_major && current_minor < max_minor) ||
+ (current_major == max_major && current_minor == max_minor &&
+ current_patch < max_patch) ||
+ (current_major == max_major && current_minor == max_minor &&
+ current_patch == max_patch && current_tweak < max_tweak)) {
+ // A ...<max> version was given that is larger than the current
+ // version of CMake, so tolerate unknown arguments.
+ return true;
+ }
+ }
+
+ std::ostringstream e;
+ e << "called with unknown argument \"" << this->UnknownArguments[0] << "\".";
+ this->SetError(e.str());
+ return false;
}
diff --git a/Source/cmCMakeMinimumRequired.h b/Source/cmCMakeMinimumRequired.h
index 18d9460..f9b61e1 100644
--- a/Source/cmCMakeMinimumRequired.h
+++ b/Source/cmCMakeMinimumRequired.h
@@ -34,7 +34,7 @@ public:
private:
std::vector<std::string> UnknownArguments;
- bool EnforceUnknownArguments();
+ bool EnforceUnknownArguments(std::string const& version_max);
};
#endif
diff --git a/Source/cmComputeLinkInformation.cxx b/Source/cmComputeLinkInformation.cxx
index b82fc43..6e6e0be 100644
--- a/Source/cmComputeLinkInformation.cxx
+++ b/Source/cmComputeLinkInformation.cxx
@@ -240,21 +240,19 @@ because this need be done only for shared libraries without soname-s.
cmComputeLinkInformation::cmComputeLinkInformation(
const cmGeneratorTarget* target, const std::string& config)
-{
// Store context information.
- this->Target = target;
- this->Makefile = this->Target->Target->GetMakefile();
- this->GlobalGenerator =
- this->Target->GetLocalGenerator()->GetGlobalGenerator();
- this->CMakeInstance = this->GlobalGenerator->GetCMakeInstance();
-
+ : Target(target),
+ Makefile(target->Target->GetMakefile()),
+ GlobalGenerator(target->GetLocalGenerator()->GetGlobalGenerator()),
+ CMakeInstance(this->GlobalGenerator->GetCMakeInstance())
+ // The configuration being linked.
+ ,
+ Config(config)
+{
// Check whether to recognize OpenBSD-style library versioned names.
this->OpenBSD = this->Makefile->GetState()->GetGlobalPropertyAsBool(
"FIND_LIBRARY_USE_OPENBSD_VERSIONING");
- // The configuration being linked.
- this->Config = config;
-
// Allocate internals.
this->OrderLinkerSearchPath = new cmOrderDirectories(
this->GlobalGenerator, target, "linker search path");
@@ -412,11 +410,12 @@ cmComputeLinkInformation::GetItems() const
}
std::vector<std::string> const& cmComputeLinkInformation::GetDirectories()
+ const
{
return this->OrderLinkerSearchPath->GetOrderedDirectories();
}
-std::string cmComputeLinkInformation::GetRPathLinkString()
+std::string cmComputeLinkInformation::GetRPathLinkString() const
{
// If there is no separate linker runtime search flag (-rpath-link)
// there is no reason to compute a string.
@@ -428,18 +427,19 @@ std::string cmComputeLinkInformation::GetRPathLinkString()
return cmJoin(this->OrderDependentRPath->GetOrderedDirectories(), ":");
}
-std::vector<std::string> const& cmComputeLinkInformation::GetDepends()
+std::vector<std::string> const& cmComputeLinkInformation::GetDepends() const
{
return this->Depends;
}
std::vector<std::string> const& cmComputeLinkInformation::GetFrameworkPaths()
+ const
{
return this->FrameworkPaths;
}
const std::set<const cmGeneratorTarget*>&
-cmComputeLinkInformation::GetSharedLibrariesLinked()
+cmComputeLinkInformation::GetSharedLibrariesLinked() const
{
return this->SharedLibrariesLinked;
}
@@ -1026,7 +1026,7 @@ void cmComputeLinkInformation::AddFullItem(std::string const& item)
(generator.find("Visual Studio") != std::string::npos ||
generator.find("Xcode") != std::string::npos)) {
std::string file = cmSystemTools::GetFilenameName(item);
- if (!this->ExtractAnyLibraryName.find(file.c_str())) {
+ if (!this->ExtractAnyLibraryName.find(file)) {
this->HandleBadFullItem(item, file);
return;
}
@@ -1233,7 +1233,7 @@ void cmComputeLinkInformation::AddUserItem(std::string const& item,
void cmComputeLinkInformation::AddFrameworkItem(std::string const& item)
{
// Try to separate the framework name and path.
- if (!this->SplitFramework.find(item.c_str())) {
+ if (!this->SplitFramework.find(item)) {
std::ostringstream e;
e << "Could not parse framework path \"" << item << "\" "
<< "linked by target " << this->Target->GetName() << ".";
@@ -1572,7 +1572,7 @@ void cmComputeLinkInformation::LoadImplicitLinkInfo()
}
std::vector<std::string> const&
-cmComputeLinkInformation::GetRuntimeSearchPath()
+cmComputeLinkInformation::GetRuntimeSearchPath() const
{
return this->OrderRuntimeSearchPath->GetOrderedDirectories();
}
@@ -1638,7 +1638,7 @@ void cmComputeLinkInformation::AddLibraryRuntimeInfo(
if (!is_shared_library) {
// On some platforms (AIX) a shared library may look static.
if (this->ArchivesMayBeShared) {
- if (this->ExtractStaticLibraryName.find(file.c_str())) {
+ if (this->ExtractStaticLibraryName.find(file)) {
// This is the name of a shared library or archive.
is_shared_library = true;
}
@@ -1683,7 +1683,7 @@ static void cmCLI_ExpandListUnique(const char* str,
}
void cmComputeLinkInformation::GetRPath(std::vector<std::string>& runtimeDirs,
- bool for_install)
+ bool for_install) const
{
// Select whether to generate runtime search directories.
bool outputRuntime =
@@ -1797,7 +1797,7 @@ void cmComputeLinkInformation::GetRPath(std::vector<std::string>& runtimeDirs,
cmCLI_ExpandListUnique(this->RuntimeAlways.c_str(), runtimeDirs, emitted);
}
-std::string cmComputeLinkInformation::GetRPathString(bool for_install)
+std::string cmComputeLinkInformation::GetRPathString(bool for_install) const
{
// Get the directories to use.
std::vector<std::string> runtimeDirs;
@@ -1825,7 +1825,7 @@ std::string cmComputeLinkInformation::GetRPathString(bool for_install)
return rpath;
}
-std::string cmComputeLinkInformation::GetChrpathString()
+std::string cmComputeLinkInformation::GetChrpathString() const
{
if (!this->RuntimeUseChrpath) {
return "";
diff --git a/Source/cmComputeLinkInformation.h b/Source/cmComputeLinkInformation.h
index 6c67fb4..65c12da 100644
--- a/Source/cmComputeLinkInformation.h
+++ b/Source/cmComputeLinkInformation.h
@@ -49,20 +49,20 @@ public:
};
typedef std::vector<Item> ItemVector;
ItemVector const& GetItems() const;
- std::vector<std::string> const& GetDirectories();
- std::vector<std::string> const& GetDepends();
- std::vector<std::string> const& GetFrameworkPaths();
+ std::vector<std::string> const& GetDirectories() const;
+ std::vector<std::string> const& GetDepends() const;
+ std::vector<std::string> const& GetFrameworkPaths() const;
std::string GetLinkLanguage() const { return this->LinkLanguage; }
- std::vector<std::string> const& GetRuntimeSearchPath();
+ std::vector<std::string> const& GetRuntimeSearchPath() const;
std::string const& GetRuntimeFlag() const { return this->RuntimeFlag; }
std::string const& GetRuntimeSep() const { return this->RuntimeSep; }
- void GetRPath(std::vector<std::string>& runtimeDirs, bool for_install);
- std::string GetRPathString(bool for_install);
- std::string GetChrpathString();
- std::set<cmGeneratorTarget const*> const& GetSharedLibrariesLinked();
+ void GetRPath(std::vector<std::string>& runtimeDirs, bool for_install) const;
+ std::string GetRPathString(bool for_install) const;
+ std::string GetChrpathString() const;
+ std::set<cmGeneratorTarget const*> const& GetSharedLibrariesLinked() const;
std::string const& GetRPathLinkFlag() const { return this->RPathLinkFlag; }
- std::string GetRPathLinkString();
+ std::string GetRPathLinkString() const;
std::string GetConfig() const { return this->Config; }
private:
@@ -78,13 +78,13 @@ private:
std::set<cmGeneratorTarget const*> SharedLibrariesLinked;
// Context information.
- cmGeneratorTarget const* Target;
- cmMakefile* Makefile;
- cmGlobalGenerator* GlobalGenerator;
- cmake* CMakeInstance;
+ cmGeneratorTarget const* const Target;
+ cmMakefile* const Makefile;
+ cmGlobalGenerator* const GlobalGenerator;
+ cmake* const CMakeInstance;
// Configuration information.
- std::string Config;
+ std::string const Config;
std::string LinkLanguage;
// Modes for dealing with dependent shared libraries.
diff --git a/Source/cmGeneratorExpressionNode.cxx b/Source/cmGeneratorExpressionNode.cxx
index f444113..09b7faf 100644
--- a/Source/cmGeneratorExpressionNode.cxx
+++ b/Source/cmGeneratorExpressionNode.cxx
@@ -331,6 +331,40 @@ static const struct TargetExistsNode : public cmGeneratorExpressionNode
}
} targetExistsNode;
+static const struct TargetNameIfExistsNode : public cmGeneratorExpressionNode
+{
+ TargetNameIfExistsNode() {}
+
+ int NumExpectedParameters() const override { return 1; }
+
+ std::string Evaluate(
+ const std::vector<std::string>& parameters,
+ cmGeneratorExpressionContext* context,
+ const GeneratorExpressionContent* content,
+ cmGeneratorExpressionDAGChecker* /*dagChecker*/) const override
+ {
+ if (parameters.size() != 1) {
+ reportError(context, content->GetOriginalExpression(),
+ "$<TARGET_NAME_IF_EXISTS:...> expression requires one "
+ "parameter");
+ return std::string();
+ }
+
+ std::string targetName = parameters.front();
+ if (targetName.empty() ||
+ !cmGeneratorExpression::IsValidTargetName(targetName)) {
+ reportError(context, content->GetOriginalExpression(),
+ "$<TARGET_NAME_IF_EXISTS:tgt> expression requires a "
+ "non-empty valid target name.");
+ return std::string();
+ }
+
+ return context->LG->GetMakefile()->FindTargetToUse(targetName)
+ ? targetName
+ : std::string();
+ }
+} targetNameIfExistsNode;
+
static const struct LowerCaseNode : public cmGeneratorExpressionNode
{
LowerCaseNode() {}
@@ -1897,6 +1931,7 @@ const cmGeneratorExpressionNode* cmGeneratorExpressionNode::GetNode(
nodeMap["TARGET_OBJECTS"] = &targetObjectsNode;
nodeMap["TARGET_POLICY"] = &targetPolicyNode;
nodeMap["TARGET_EXISTS"] = &targetExistsNode;
+ nodeMap["TARGET_NAME_IF_EXISTS"] = &targetNameIfExistsNode;
nodeMap["BUILD_INTERFACE"] = &buildInterfaceNode;
nodeMap["INSTALL_INTERFACE"] = &installInterfaceNode;
nodeMap["INSTALL_PREFIX"] = &installPrefixNode;
diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx
index cee540b..629d54a 100644
--- a/Source/cmLocalGenerator.cxx
+++ b/Source/cmLocalGenerator.cxx
@@ -224,14 +224,7 @@ void cmLocalGenerator::TraceDependencies()
void cmLocalGenerator::GenerateTestFiles()
{
- std::string file = this->StateSnapshot.GetDirectory().GetCurrentBinary();
- file += "/";
- file += "CTestTestfile.cmake";
-
if (!this->Makefile->IsOn("CMAKE_TESTING_ENABLED")) {
- if (cmSystemTools::FileExists(file)) {
- cmSystemTools::RemoveFile(file);
- }
return;
}
@@ -240,6 +233,10 @@ void cmLocalGenerator::GenerateTestFiles()
const std::string& config =
this->Makefile->GetConfigurations(configurationTypes, false);
+ std::string file = this->StateSnapshot.GetDirectory().GetCurrentBinary();
+ file += "/";
+ file += "CTestTestfile.cmake";
+
cmGeneratedFileStream fout(file.c_str());
fout.SetCopyIfDifferent(true);
@@ -1564,6 +1561,7 @@ void cmLocalGenerator::AddCompilerRequirementFlag(
static std::map<std::string, std::vector<std::string>> langStdMap;
if (langStdMap.empty()) {
// Maintain sorted order, most recent first.
+ langStdMap["CXX"].push_back("20");
langStdMap["CXX"].push_back("17");
langStdMap["CXX"].push_back("14");
langStdMap["CXX"].push_back("11");
diff --git a/Source/cmLocalVisualStudio7Generator.cxx b/Source/cmLocalVisualStudio7Generator.cxx
index 500a0aa..91ee09f 100644
--- a/Source/cmLocalVisualStudio7Generator.cxx
+++ b/Source/cmLocalVisualStudio7Generator.cxx
@@ -792,10 +792,9 @@ void cmLocalVisualStudio7Generator::WriteConfiguration(
<< "\\$(ConfigurationName)\"\n";
}
targetOptions.OutputAdditionalIncludeDirectories(
- fout, "\t\t\t\t", "\n",
- this->FortranProject ? "Fortran" : langForClCompile);
+ fout, "\t\t\t\t", this->FortranProject ? "Fortran" : langForClCompile);
targetOptions.OutputFlagMap(fout, "\t\t\t\t");
- targetOptions.OutputPreprocessorDefinitions(fout, "\t\t\t\t", "\n",
+ targetOptions.OutputPreprocessorDefinitions(fout, "\t\t\t\t",
langForClCompile);
fout << "\t\t\t\tObjectFile=\"$(IntDir)\\\"\n";
if (target->GetType() <= cmStateEnums::OBJECT_LIBRARY) {
@@ -815,11 +814,10 @@ void cmLocalVisualStudio7Generator::WriteConfiguration(
"\t\t\t\tName=\"MASM\"\n"
;
/* clang-format on */
- targetOptions.OutputAdditionalIncludeDirectories(fout, "\t\t\t\t", "\n",
+ targetOptions.OutputAdditionalIncludeDirectories(fout, "\t\t\t\t",
"ASM_MASM");
// Use same preprocessor definitions as VCCLCompilerTool.
- targetOptions.OutputPreprocessorDefinitions(fout, "\t\t\t\t", "\n",
- "ASM_MASM");
+ targetOptions.OutputPreprocessorDefinitions(fout, "\t\t\t\t", "ASM_MASM");
masmOptions.OutputFlagMap(fout, "\t\t\t\t");
/* clang-format off */
fout <<
@@ -837,18 +835,16 @@ void cmLocalVisualStudio7Generator::WriteConfiguration(
tool = "VFResourceCompilerTool";
}
fout << "\t\t\t<Tool\n\t\t\t\tName=\"" << tool << "\"\n";
- targetOptions.OutputAdditionalIncludeDirectories(fout, "\n\t\t\t\t", "",
- "RC");
+ targetOptions.OutputAdditionalIncludeDirectories(fout, "\t\t\t\t", "RC");
// add the -D flags to the RC tool
- targetOptions.OutputPreprocessorDefinitions(fout, "\n\t\t\t\t", "", "RC");
- fout << "/>\n";
+ targetOptions.OutputPreprocessorDefinitions(fout, "\t\t\t\t", "RC");
+ fout << "\t\t\t/>\n";
tool = "VCMIDLTool";
if (this->FortranProject) {
tool = "VFMIDLTool";
}
fout << "\t\t\t<Tool\n\t\t\t\tName=\"" << tool << "\"\n";
- targetOptions.OutputAdditionalIncludeDirectories(fout, "\n\t\t\t\t", "",
- "MIDL");
+ targetOptions.OutputAdditionalIncludeDirectories(fout, "\t\t\t\t", "MIDL");
fout << "\t\t\t\tMkTypLibCompatible=\"false\"\n";
if (gg->GetPlatformName() == "x64") {
fout << "\t\t\t\tTargetEnvironment=\"3\"\n";
@@ -1686,9 +1682,9 @@ bool cmLocalVisualStudio7Generator::WriteGroup(
fileOptions.AddIncludes(includes);
fileOptions.OutputFlagMap(fout, "\t\t\t\t\t");
fileOptions.OutputAdditionalIncludeDirectories(
- fout, "\t\t\t\t\t", "\n",
+ fout, "\t\t\t\t\t",
ppLang == "CXX" && this->FortranProject ? "Fortran" : ppLang);
- fileOptions.OutputPreprocessorDefinitions(fout, "\t\t\t\t\t", "\n",
+ fileOptions.OutputPreprocessorDefinitions(fout, "\t\t\t\t\t",
ppLang);
}
if (!fc.AdditionalDeps.empty()) {
@@ -2065,6 +2061,15 @@ std::string cmLocalVisualStudio7Generator::ConvertToXMLOutputPathSingle(
return ret;
}
+void cmVS7GeneratorOptions::OutputFlag(std::ostream& fout, const char* indent,
+ const char* tag,
+ const std::string& content)
+{
+ fout << indent << tag << "=\"";
+ fout << cmLocalVisualStudio7GeneratorEscapeForXML(content);
+ fout << "\"\n";
+}
+
// This class is used to parse an existing vs 7 project
// and extract the GUID
class cmVS7XMLParser : public cmXMLParser
diff --git a/Source/cmLocalVisualStudio7Generator.h b/Source/cmLocalVisualStudio7Generator.h
index 02e6931..22b4264 100644
--- a/Source/cmLocalVisualStudio7Generator.h
+++ b/Source/cmLocalVisualStudio7Generator.h
@@ -21,6 +21,19 @@ class cmMakefile;
class cmSourceFile;
class cmSourceGroup;
+class cmVS7GeneratorOptions : public cmVisualStudioGeneratorOptions
+{
+public:
+ cmVS7GeneratorOptions(cmLocalVisualStudioGenerator* lg, Tool tool,
+ cmVS7FlagTable const* table = nullptr,
+ cmVS7FlagTable const* extraTable = nullptr)
+ : cmVisualStudioGeneratorOptions(lg, tool, table, extraTable)
+ {
+ }
+ void OutputFlag(std::ostream& fout, const char* indent, const char* tag,
+ const std::string& content) override;
+};
+
/** \class cmLocalVisualStudio7Generator
* \brief Write Visual Studio .NET project files.
*
@@ -70,7 +83,7 @@ protected:
void CreateSingleVCProj(const std::string& lname, cmGeneratorTarget* tgt);
private:
- typedef cmVisualStudioGeneratorOptions Options;
+ typedef cmVS7GeneratorOptions Options;
typedef cmLocalVisualStudio7GeneratorFCInfo FCInfo;
std::string GetBuildTypeLinkerFlags(std::string rootLinkerFlags,
const std::string& configName);
diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx
index c270629..3ecd7eb 100644
--- a/Source/cmMakefile.cxx
+++ b/Source/cmMakefile.cxx
@@ -4223,7 +4223,7 @@ static const char* const CXX_FEATURES[] = { nullptr FOR_EACH_CXX_FEATURE(
#undef FEATURE_STRING
static const char* const C_STANDARDS[] = { "90", "99", "11" };
-static const char* const CXX_STANDARDS[] = { "98", "11", "14", "17" };
+static const char* const CXX_STANDARDS[] = { "98", "11", "14", "17", "20" };
bool cmMakefile::AddRequiredTargetFeature(cmTarget* target,
const std::string& feature,
@@ -4473,8 +4473,9 @@ bool cmMakefile::HaveCxxStandardAvailable(cmTarget const* target,
bool needCxx11 = false;
bool needCxx14 = false;
bool needCxx17 = false;
+ bool needCxx20 = false;
this->CheckNeededCxxLanguage(feature, needCxx98, needCxx11, needCxx14,
- needCxx17);
+ needCxx17, needCxx20);
const char* existingCxxStandard = target->GetProperty("CXX_STANDARD");
if (!existingCxxStandard) {
@@ -4494,7 +4495,8 @@ bool cmMakefile::HaveCxxStandardAvailable(cmTarget const* target,
/* clang-format off */
const char* const* needCxxLevel =
- needCxx17 ? &CXX_STANDARDS[3]
+ needCxx20 ? &CXX_STANDARDS[4]
+ : needCxx17 ? &CXX_STANDARDS[3]
: needCxx14 ? &CXX_STANDARDS[2]
: needCxx11 ? &CXX_STANDARDS[1]
: needCxx98 ? &CXX_STANDARDS[0]
@@ -4506,7 +4508,8 @@ bool cmMakefile::HaveCxxStandardAvailable(cmTarget const* target,
void cmMakefile::CheckNeededCxxLanguage(const std::string& feature,
bool& needCxx98, bool& needCxx11,
- bool& needCxx14, bool& needCxx17) const
+ bool& needCxx14, bool& needCxx17,
+ bool& needCxx20) const
{
if (const char* propCxx98 =
this->GetDefinition("CMAKE_CXX98_COMPILE_FEATURES")) {
@@ -4532,6 +4535,12 @@ void cmMakefile::CheckNeededCxxLanguage(const std::string& feature,
cmSystemTools::ExpandListArgument(propCxx17, props);
needCxx17 = std::find(props.begin(), props.end(), feature) != props.end();
}
+ if (const char* propCxx20 =
+ this->GetDefinition("CMAKE_CXX20_COMPILE_FEATURES")) {
+ std::vector<std::string> props;
+ cmSystemTools::ExpandListArgument(propCxx20, props);
+ needCxx20 = std::find(props.begin(), props.end(), feature) != props.end();
+ }
}
bool cmMakefile::AddRequiredTargetCxxFeature(cmTarget* target,
@@ -4542,9 +4551,10 @@ bool cmMakefile::AddRequiredTargetCxxFeature(cmTarget* target,
bool needCxx11 = false;
bool needCxx14 = false;
bool needCxx17 = false;
+ bool needCxx20 = false;
this->CheckNeededCxxLanguage(feature, needCxx98, needCxx11, needCxx14,
- needCxx17);
+ needCxx17, needCxx20);
const char* existingCxxStandard = target->GetProperty("CXX_STANDARD");
const char* const* existingCxxLevel = nullptr;
@@ -4589,7 +4599,8 @@ bool cmMakefile::AddRequiredTargetCxxFeature(cmTarget* target,
/* clang-format off */
const char* const* needCxxLevel =
- needCxx17 ? &CXX_STANDARDS[3]
+ needCxx20 ? &CXX_STANDARDS[4]
+ : needCxx17 ? &CXX_STANDARDS[3]
: needCxx14 ? &CXX_STANDARDS[2]
: needCxx11 ? &CXX_STANDARDS[1]
: needCxx98 ? &CXX_STANDARDS[0]
diff --git a/Source/cmMakefile.h b/Source/cmMakefile.h
index 419cb6e..d2626cd 100644
--- a/Source/cmMakefile.h
+++ b/Source/cmMakefile.h
@@ -991,7 +991,7 @@ private:
bool& needC99, bool& needC11) const;
void CheckNeededCxxLanguage(const std::string& feature, bool& needCxx98,
bool& needCxx11, bool& needCxx14,
- bool& needCxx17) const;
+ bool& needCxx17, bool& needCxx20) const;
bool HaveCStandardAvailable(cmTarget const* target,
const std::string& feature) const;
diff --git a/Source/cmSystemTools.cxx b/Source/cmSystemTools.cxx
index 88cfe81..eeb73c3 100644
--- a/Source/cmSystemTools.cxx
+++ b/Source/cmSystemTools.cxx
@@ -550,12 +550,13 @@ std::vector<std::string> cmSystemTools::ParseArguments(const char* command)
bool win_path = false;
- if ((command[0] != '/' && command[1] == ':' && command[2] == '\\') ||
- (command[0] == '\"' && command[1] != '/' && command[2] == ':' &&
- command[3] == '\\') ||
- (command[0] == '\'' && command[1] != '/' && command[2] == ':' &&
- command[3] == '\\') ||
- (command[0] == '\\' && command[1] == '\\')) {
+ if (command[0] && command[1] &&
+ ((command[0] != '/' && command[1] == ':' && command[2] == '\\') ||
+ (command[0] == '\"' && command[1] != '/' && command[2] == ':' &&
+ command[3] == '\\') ||
+ (command[0] == '\'' && command[1] != '/' && command[2] == ':' &&
+ command[3] == '\\') ||
+ (command[0] == '\\' && command[1] == '\\'))) {
win_path = true;
}
// Split the command into an argv array.
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index b88d517f..d17a85a 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -722,12 +722,7 @@ void cmTarget::AddLinkLibrary(cmMakefile& mf, const std::string& lib,
return;
}
- {
- cmTarget::LibraryID tmp;
- tmp.first = lib;
- tmp.second = llt;
- this->OriginalLinkLibraries.emplace_back(lib, llt);
- }
+ this->OriginalLinkLibraries.emplace_back(lib, llt);
// Add the explicit dependency information for libraries. This is
// simply a set of libraries separated by ";". There should always
diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx
index 7e6e803..4bd07ef 100644
--- a/Source/cmVisualStudio10TargetGenerator.cxx
+++ b/Source/cmVisualStudio10TargetGenerator.cxx
@@ -18,6 +18,16 @@
#include <iterator>
#include <memory> // IWYU pragma: keep
+static void ConvertToWindowsSlash(std::string& s);
+
+static std::string cmVS10EscapeXML(std::string arg)
+{
+ cmSystemTools::ReplaceString(arg, "&", "&amp;");
+ cmSystemTools::ReplaceString(arg, "<", "&lt;");
+ cmSystemTools::ReplaceString(arg, ">", "&gt;");
+ return arg;
+}
+
struct cmVisualStudio10TargetGenerator::Elem
{
cmGeneratedFileStream& S;
@@ -57,6 +67,37 @@ struct cmVisualStudio10TargetGenerator::Elem
}
};
+class cmVS10GeneratorOptions : public cmVisualStudioGeneratorOptions
+{
+public:
+ cmVS10GeneratorOptions(cmLocalVisualStudioGenerator* lg, Tool tool,
+ cmVS7FlagTable const* table,
+ cmVisualStudio10TargetGenerator* g = nullptr)
+ : cmVisualStudioGeneratorOptions(lg, tool, table)
+ , TargetGenerator(g)
+ {
+ }
+
+ void OutputFlag(std::ostream& fout, const char* indent, const char* tag,
+ const std::string& content) override
+ {
+ if (!this->GetConfiguration().empty()) {
+ // if there are configuration specific flags, then
+ // use the configuration specific tag for PreprocessorDefinitions
+ fout << indent;
+ this->TargetGenerator->WritePlatformConfigTag(
+ tag, this->GetConfiguration(), 0);
+ } else {
+ fout << indent << "<" << tag << ">";
+ }
+ fout << cmVS10EscapeXML(content);
+ fout << "</" << tag << ">\n";
+ }
+
+private:
+ cmVisualStudio10TargetGenerator* TargetGenerator;
+};
+
inline void cmVisualStudio10TargetGenerator::WriteElem(const char* tag,
const char* val,
int indentLevel)
@@ -73,16 +114,6 @@ inline void cmVisualStudio10TargetGenerator::WriteElem(const char* tag,
(*this->BuildFileStream) << tag << ">" << val << "</" << tag << ">\n";
}
-static void ConvertToWindowsSlash(std::string& s);
-
-static std::string cmVS10EscapeXML(std::string arg)
-{
- cmSystemTools::ReplaceString(arg, "&", "&amp;");
- cmSystemTools::ReplaceString(arg, "<", "&lt;");
- cmSystemTools::ReplaceString(arg, ">", "&gt;");
- return arg;
-}
-
inline void cmVisualStudio10TargetGenerator::WriteElemEscapeXML(
const char* tag, std::string const& val, int indentLevel)
{
@@ -187,12 +218,10 @@ cmVisualStudio10TargetGenerator::~cmVisualStudio10TargetGenerator()
void cmVisualStudio10TargetGenerator::WritePlatformConfigTag(
const char* tag, const std::string& config, int indentLevel,
- const char* attribute, const char* end, std::ostream* stream)
+ const char* attribute)
{
- if (!stream) {
- stream = this->BuildFileStream;
- }
+ std::ostream* stream = this->BuildFileStream;
stream->fill(' ');
stream->width(indentLevel * 2);
(*stream) << ""; // applies indentation
@@ -213,8 +242,8 @@ void cmVisualStudio10TargetGenerator::WritePlatformConfigTag(
}
// close the tag
(*stream) << ">";
- if (end) {
- (*stream) << end;
+ if (attribute) {
+ (*stream) << "\n";
}
}
@@ -941,7 +970,7 @@ void cmVisualStudio10TargetGenerator::WriteProjectConfigurationValues()
{
for (std::string const& c : this->Configurations) {
this->WritePlatformConfigTag("PropertyGroup", c, 1,
- " Label=\"Configuration\"", "\n");
+ " Label=\"Configuration\"");
if (this->ProjectType != csproj) {
std::string configType = "<ConfigurationType>";
@@ -1281,8 +1310,7 @@ void cmVisualStudio10TargetGenerator::WriteCustomRuleCSharp(
attributes << "\n Name=\"" << name << "\"";
attributes << "\n Inputs=\"" << inputs << "\"";
attributes << "\n Outputs=\"" << outputs << "\"";
- this->WritePlatformConfigTag("Target", config, 1, attributes.str().c_str(),
- "\n");
+ this->WritePlatformConfigTag("Target", config, 1, attributes.str().c_str());
if (!comment.empty()) {
this->WriteString("<Exec Command=\"", 2);
(*this->BuildFileStream) << "echo " << cmVS10EscapeXML(comment)
@@ -2048,9 +2076,9 @@ void cmVisualStudio10TargetGenerator::OutputSourceSpecificFlags(
cmGeneratorExpressionInterpreter genexInterpreter(
this->LocalGenerator, this->GeneratorTarget, config,
this->GeneratorTarget->GetName(), lang);
- cmVisualStudioGeneratorOptions clOptions(
+ cmVS10GeneratorOptions clOptions(
this->LocalGenerator, cmVisualStudioGeneratorOptions::Compiler,
- flagtable, 0, this);
+ flagtable, this);
if (compileAs) {
clOptions.AddFlag("CompileAs", compileAs);
}
@@ -2096,10 +2124,10 @@ void cmVisualStudio10TargetGenerator::OutputSourceSpecificFlags(
clOptions.SetConfiguration(config);
clOptions.PrependInheritedString("AdditionalOptions");
clOptions.OutputAdditionalIncludeDirectories(*this->BuildFileStream,
- " ", "\n", lang);
+ " ", lang);
clOptions.OutputFlagMap(*this->BuildFileStream, " ");
clOptions.OutputPreprocessorDefinitions(*this->BuildFileStream, " ",
- "\n", lang);
+ lang);
}
}
if (this->IsXamlSource(source->GetFullPath())) {
@@ -2455,10 +2483,10 @@ void cmVisualStudio10TargetGenerator::WriteClOptions(
this->WriteString("<ClCompile>\n", 2);
clOptions.PrependInheritedString("AdditionalOptions");
clOptions.OutputAdditionalIncludeDirectories(
- *this->BuildFileStream, " ", "\n", this->LangForClCompile);
+ *this->BuildFileStream, " ", this->LangForClCompile);
clOptions.OutputFlagMap(*this->BuildFileStream, " ");
clOptions.OutputPreprocessorDefinitions(*this->BuildFileStream, " ",
- "\n", this->LangForClCompile);
+ this->LangForClCompile);
if (this->NsightTegra) {
if (const char* processMax =
@@ -2544,9 +2572,9 @@ void cmVisualStudio10TargetGenerator::WriteRCOptions(
Options& rcOptions = *(this->RcOptions[configName]);
rcOptions.OutputPreprocessorDefinitions(*this->BuildFileStream, " ",
- "\n", "RC");
+ "RC");
rcOptions.OutputAdditionalIncludeDirectories(*this->BuildFileStream,
- " ", "\n", "RC");
+ " ", "RC");
rcOptions.PrependInheritedString("AdditionalOptions");
rcOptions.OutputFlagMap(*this->BuildFileStream, " ");
@@ -2680,9 +2708,9 @@ void cmVisualStudio10TargetGenerator::WriteCudaOptions(
Options& cudaOptions = *(this->CudaOptions[configName]);
cudaOptions.OutputAdditionalIncludeDirectories(*this->BuildFileStream,
- " ", "\n", "CUDA");
+ " ", "CUDA");
cudaOptions.OutputPreprocessorDefinitions(*this->BuildFileStream, " ",
- "\n", "CUDA");
+ "CUDA");
cudaOptions.PrependInheritedString("AdditionalOptions");
cudaOptions.OutputFlagMap(*this->BuildFileStream, " ");
@@ -2805,11 +2833,11 @@ void cmVisualStudio10TargetGenerator::WriteMasmOptions(
// Preprocessor definitions and includes are shared with clOptions.
Options& clOptions = *(this->ClOptions[configName]);
clOptions.OutputPreprocessorDefinitions(*this->BuildFileStream, " ",
- "\n", "ASM_MASM");
+ "ASM_MASM");
Options& masmOptions = *(this->MasmOptions[configName]);
masmOptions.OutputAdditionalIncludeDirectories(*this->BuildFileStream,
- " ", "\n", "ASM_MASM");
+ " ", "ASM_MASM");
masmOptions.PrependInheritedString("AdditionalOptions");
masmOptions.OutputFlagMap(*this->BuildFileStream, " ");
@@ -2866,16 +2894,16 @@ void cmVisualStudio10TargetGenerator::WriteNasmOptions(
this->GetIncludes(configName, "ASM_NASM");
Options& nasmOptions = *(this->NasmOptions[configName]);
nasmOptions.OutputAdditionalIncludeDirectories(*this->BuildFileStream,
- " ", "\n", "ASM_NASM");
+ " ", "ASM_NASM");
nasmOptions.OutputFlagMap(*this->BuildFileStream, " ");
nasmOptions.PrependInheritedString("AdditionalOptions");
nasmOptions.OutputPreprocessorDefinitions(*this->BuildFileStream, " ",
- "\n", "ASM_NASM");
+ "ASM_NASM");
// Preprocessor definitions and includes are shared with clOptions.
Options& clOptions = *(this->ClOptions[configName]);
clOptions.OutputPreprocessorDefinitions(*this->BuildFileStream, " ",
- "\n", "ASM_NASM");
+ "ASM_NASM");
this->WriteString("</NASM>\n", 2);
}
@@ -2893,9 +2921,9 @@ void cmVisualStudio10TargetGenerator::WriteLibOptions(
if (!libflags.empty()) {
this->WriteString("<Lib>\n", 2);
cmGlobalVisualStudio10Generator* gg = this->GlobalGenerator;
- cmVisualStudioGeneratorOptions libOptions(
- this->LocalGenerator, cmVisualStudioGeneratorOptions::Linker,
- gg->GetLibFlagTable(), 0, this);
+ cmVS10GeneratorOptions libOptions(this->LocalGenerator,
+ cmVisualStudioGeneratorOptions::Linker,
+ gg->GetLibFlagTable(), this);
libOptions.Parse(libflags.c_str());
libOptions.PrependInheritedString("AdditionalOptions");
libOptions.OutputFlagMap(*this->BuildFileStream, " ");
@@ -3063,9 +3091,8 @@ bool cmVisualStudio10TargetGenerator::ComputeLinkOptions(
std::string const& config)
{
cmGlobalVisualStudio10Generator* gg = this->GlobalGenerator;
- auto pOptions =
- cm::make_unique<Options>(this->LocalGenerator, Options::Linker,
- gg->GetLinkFlagTable(), nullptr, this);
+ auto pOptions = cm::make_unique<Options>(
+ this->LocalGenerator, Options::Linker, gg->GetLinkFlagTable(), this);
Options& linkOptions = *pOptions;
cmGeneratorTarget::LinkClosure const* linkClosure =
diff --git a/Source/cmVisualStudio10TargetGenerator.h b/Source/cmVisualStudio10TargetGenerator.h
index d557255..7106737 100644
--- a/Source/cmVisualStudio10TargetGenerator.h
+++ b/Source/cmVisualStudio10TargetGenerator.h
@@ -21,7 +21,7 @@ class cmLocalVisualStudio7Generator;
class cmMakefile;
class cmSourceFile;
class cmSourceGroup;
-class cmVisualStudioGeneratorOptions;
+class cmVS10GeneratorOptions;
class cmVisualStudio10TargetGenerator
{
@@ -34,8 +34,7 @@ public:
void Generate();
// used by cmVisualStudioGeneratorOptions
void WritePlatformConfigTag(const char* tag, const std::string& config,
- int indentLevel, const char* attribute = 0,
- const char* end = 0, std::ostream* strm = 0);
+ int indentLevel, const char* attribute = 0);
private:
struct ToolSource
@@ -176,7 +175,7 @@ private:
void GetCSharpSourceLink(cmSourceFile const* sf, std::string& link);
private:
- typedef cmVisualStudioGeneratorOptions Options;
+ typedef cmVS10GeneratorOptions Options;
typedef std::map<std::string, std::unique_ptr<Options>> OptionsMap;
OptionsMap ClOptions;
OptionsMap RcOptions;
diff --git a/Source/cmVisualStudioGeneratorOptions.cxx b/Source/cmVisualStudioGeneratorOptions.cxx
index 7d7000b..8b6f057 100644
--- a/Source/cmVisualStudioGeneratorOptions.cxx
+++ b/Source/cmVisualStudioGeneratorOptions.cxx
@@ -4,47 +4,19 @@
#include "cmLocalVisualStudioGenerator.h"
#include "cmOutputConverter.h"
#include "cmSystemTools.h"
-#include "cmVisualStudio10TargetGenerator.h"
static void cmVS10EscapeForMSBuild(std::string& ret)
{
cmSystemTools::ReplaceString(ret, ";", "%3B");
}
-static std::string cmVisualStudio10GeneratorOptionsEscapeForXML(
- std::string ret)
-{
- cmSystemTools::ReplaceString(ret, "&", "&amp;");
- cmSystemTools::ReplaceString(ret, "<", "&lt;");
- cmSystemTools::ReplaceString(ret, ">", "&gt;");
- return ret;
-}
-
-static std::string cmVisualStudioGeneratorOptionsEscapeForXML(std::string ret)
-{
- cmSystemTools::ReplaceString(ret, "&", "&amp;");
- cmSystemTools::ReplaceString(ret, "\"", "&quot;");
- cmSystemTools::ReplaceString(ret, "<", "&lt;");
- cmSystemTools::ReplaceString(ret, ">", "&gt;");
- cmSystemTools::ReplaceString(ret, "\n", "&#x0D;&#x0A;");
- return ret;
-}
-
-cmVisualStudioGeneratorOptions::cmVisualStudioGeneratorOptions(
- cmLocalVisualStudioGenerator* lg, Tool tool,
- cmVisualStudio10TargetGenerator* g)
- : cmVisualStudioGeneratorOptions(lg, tool, nullptr, nullptr, g)
-{
-}
-
cmVisualStudioGeneratorOptions::cmVisualStudioGeneratorOptions(
cmLocalVisualStudioGenerator* lg, Tool tool, cmVS7FlagTable const* table,
- cmVS7FlagTable const* extraTable, cmVisualStudio10TargetGenerator* g)
+ cmVS7FlagTable const* extraTable)
: cmIDEOptions()
, LocalGenerator(lg)
, Version(lg->GetVersion())
, CurrentTool(tool)
- , TargetGenerator(g)
{
// Store the given flag tables.
this->AddTable(table);
@@ -444,33 +416,13 @@ void cmVisualStudioGeneratorOptions::SetConfiguration(
this->Configuration = config;
}
-void cmVisualStudioGeneratorOptions::OutputFlag(std::ostream& fout,
- const char* indent,
- const char* tag,
- const std::string& content)
+const std::string& cmVisualStudioGeneratorOptions::GetConfiguration() const
{
- if (this->Version >= cmGlobalVisualStudioGenerator::VS10) {
- if (!this->Configuration.empty()) {
- // if there are configuration specific flags, then
- // use the configuration specific tag for PreprocessorDefinitions
- fout << indent;
- this->TargetGenerator->WritePlatformConfigTag(tag, this->Configuration,
- 0, 0, 0, &fout);
- } else {
- fout << indent << "<" << tag << ">";
- }
- fout << cmVisualStudio10GeneratorOptionsEscapeForXML(content);
- fout << "</" << tag << ">";
- } else {
- fout << indent << tag << "=\"";
- fout << cmVisualStudioGeneratorOptionsEscapeForXML(content);
- fout << "\"";
- }
+ return this->Configuration;
}
void cmVisualStudioGeneratorOptions::OutputPreprocessorDefinitions(
- std::ostream& fout, const char* prefix, const char* suffix,
- const std::string& lang)
+ std::ostream& fout, const char* prefix, const std::string& lang)
{
if (this->Defines.empty()) {
return;
@@ -509,12 +461,10 @@ void cmVisualStudioGeneratorOptions::OutputPreprocessorDefinitions(
}
this->OutputFlag(fout, prefix, tag, oss.str());
- fout << suffix;
}
void cmVisualStudioGeneratorOptions::OutputAdditionalIncludeDirectories(
- std::ostream& fout, const char* prefix, const char* suffix,
- const std::string& lang)
+ std::ostream& fout, const char* prefix, const std::string& lang)
{
if (this->Includes.empty()) {
return;
@@ -559,7 +509,6 @@ void cmVisualStudioGeneratorOptions::OutputAdditionalIncludeDirectories(
}
this->OutputFlag(fout, prefix, tag, oss.str());
- fout << suffix;
}
void cmVisualStudioGeneratorOptions::OutputFlagMap(std::ostream& fout,
@@ -577,6 +526,5 @@ void cmVisualStudioGeneratorOptions::OutputFlagMap(std::ostream& fout,
}
this->OutputFlag(fout, indent, m.first.c_str(), oss.str());
- fout << "\n";
}
}
diff --git a/Source/cmVisualStudioGeneratorOptions.h b/Source/cmVisualStudioGeneratorOptions.h
index 517760a..974ca62 100644
--- a/Source/cmVisualStudioGeneratorOptions.h
+++ b/Source/cmVisualStudioGeneratorOptions.h
@@ -16,8 +16,6 @@ class cmLocalVisualStudioGenerator;
typedef cmIDEFlagTable cmVS7FlagTable;
-class cmVisualStudio10TargetGenerator;
-
class cmVisualStudioGeneratorOptions : public cmIDEOptions
{
public:
@@ -34,12 +32,8 @@ public:
CSharpCompiler
};
cmVisualStudioGeneratorOptions(cmLocalVisualStudioGenerator* lg, Tool tool,
- cmVS7FlagTable const* table,
- cmVS7FlagTable const* extraTable = 0,
- cmVisualStudio10TargetGenerator* g = 0);
-
- cmVisualStudioGeneratorOptions(cmLocalVisualStudioGenerator* lg, Tool tool,
- cmVisualStudio10TargetGenerator* g = 0);
+ cmVS7FlagTable const* table = nullptr,
+ cmVS7FlagTable const* extraTable = nullptr);
// Add a table of flags.
void AddTable(cmVS7FlagTable const* table);
@@ -84,18 +78,17 @@ public:
bool IsManaged() const;
// Write options to output.
void OutputPreprocessorDefinitions(std::ostream& fout, const char* prefix,
- const char* suffix,
const std::string& lang);
void OutputAdditionalIncludeDirectories(std::ostream& fout,
const char* prefix,
- const char* suffix,
const std::string& lang);
void OutputFlagMap(std::ostream& fout, const char* indent);
void SetConfiguration(const std::string& config);
+ const std::string& GetConfiguration() const;
-private:
- void OutputFlag(std::ostream& fout, const char* indent, const char* tag,
- const std::string& content);
+protected:
+ virtual void OutputFlag(std::ostream& fout, const char* indent,
+ const char* tag, const std::string& content) = 0;
private:
cmLocalVisualStudioGenerator* LocalGenerator;
@@ -103,7 +96,6 @@ private:
std::string Configuration;
Tool CurrentTool;
- cmVisualStudio10TargetGenerator* TargetGenerator;
bool FortranRuntimeDebug;
bool FortranRuntimeDLL;
diff --git a/Source/cmake.h b/Source/cmake.h
index 1ac549b..cc56a07 100644
--- a/Source/cmake.h
+++ b/Source/cmake.h
@@ -574,6 +574,7 @@ private:
F(cxx_std_11) \
F(cxx_std_14) \
F(cxx_std_17) \
+ F(cxx_std_20) \
F(cxx_aggregate_default_initializers) \
F(cxx_alias_templates) \
F(cxx_alignas) \
diff --git a/Source/kwsys/SystemTools.cxx b/Source/kwsys/SystemTools.cxx
index 106afe5..52f509a 100644
--- a/Source/kwsys/SystemTools.cxx
+++ b/Source/kwsys/SystemTools.cxx
@@ -3344,15 +3344,20 @@ std::string SystemTools::RelativePath(const std::string& local,
static std::string GetCasePathName(std::string const& pathIn)
{
std::string casePath;
- std::vector<std::string> path_components;
- SystemTools::SplitPath(pathIn, path_components);
- if (path_components[0].empty()) // First component always exists.
- {
- // Relative paths cannot be converted.
+
+ // First check if the file is relative. We don't fix relative paths since the
+ // real case depends on the root directory and the given path fragment may
+ // have meaning elsewhere in the project.
+ if (!SystemTools::FileIsFullPath(pathIn)) {
+ // This looks unnecessary, but it allows for the return value optimization
+ // since all return paths return the same local variable.
casePath = pathIn;
return casePath;
}
+ std::vector<std::string> path_components;
+ SystemTools::SplitPath(pathIn, path_components);
+
// Start with root component.
std::vector<std::string>::size_type idx = 0;
casePath = path_components[idx++];
diff --git a/Source/kwsys/Terminal.c b/Source/kwsys/Terminal.c
index eaa5c7d..c9f9dc5 100644
--- a/Source/kwsys/Terminal.c
+++ b/Source/kwsys/Terminal.c
@@ -153,6 +153,7 @@ static const char* kwsysTerminalVT100Names[] = { "Eterm",
"xterm-88color",
"xterm-color",
"xterm-debian",
+ "xterm-kitty",
"xterm-termite",
0 };
diff --git a/Source/kwsys/testSystemTools.cxx b/Source/kwsys/testSystemTools.cxx
index e436a2b..a6d934b 100644
--- a/Source/kwsys/testSystemTools.cxx
+++ b/Source/kwsys/testSystemTools.cxx
@@ -738,29 +738,29 @@ static bool CheckGetPath()
#endif
const char* registryPath = "[HKEY_LOCAL_MACHINE\\SOFTWARE\\MyApp; MyKey]";
- std::vector<std::string> originalPathes;
- originalPathes.push_back(registryPath);
+ std::vector<std::string> originalPaths;
+ originalPaths.push_back(registryPath);
- std::vector<std::string> expectedPathes;
- expectedPathes.push_back(registryPath);
+ std::vector<std::string> expectedPaths;
+ expectedPaths.push_back(registryPath);
#ifdef _WIN32
- expectedPathes.push_back("C:/Somewhere/something");
- expectedPathes.push_back("D:/Temp");
+ expectedPaths.push_back("C:/Somewhere/something");
+ expectedPaths.push_back("D:/Temp");
#else
- expectedPathes.push_back("/Somewhere/something");
- expectedPathes.push_back("/tmp");
+ expectedPaths.push_back("/Somewhere/something");
+ expectedPaths.push_back("/tmp");
#endif
bool res = true;
res &= CheckPutEnv(std::string(envName) + "=" + envValue, envName, envValue);
- std::vector<std::string> pathes = originalPathes;
- kwsys::SystemTools::GetPath(pathes, envName);
+ std::vector<std::string> paths = originalPaths;
+ kwsys::SystemTools::GetPath(paths, envName);
- if (pathes != expectedPathes) {
- std::cerr << "GetPath(" << StringVectorToString(originalPathes) << ", "
- << envName << ") yielded " << StringVectorToString(pathes)
- << " instead of " << StringVectorToString(expectedPathes)
+ if (paths != expectedPaths) {
+ std::cerr << "GetPath(" << StringVectorToString(originalPaths) << ", "
+ << envName << ") yielded " << StringVectorToString(paths)
+ << " instead of " << StringVectorToString(expectedPaths)
<< std::endl;
res = false;
}
diff --git a/Tests/CMakeCommands/target_compile_features/CMakeLists.txt b/Tests/CMakeCommands/target_compile_features/CMakeLists.txt
index 5096a58..9664025 100644
--- a/Tests/CMakeCommands/target_compile_features/CMakeLists.txt
+++ b/Tests/CMakeCommands/target_compile_features/CMakeLists.txt
@@ -1,5 +1,4 @@
-cmake_minimum_required(VERSION 3.0)
-cmake_policy(SET CMP0057 NEW)
+cmake_minimum_required(VERSION 3.3)
project(target_compile_features)
set(CMAKE_VERBOSE_MAKEFILE ON)
@@ -19,7 +18,8 @@ if (c_restrict IN_LIST CMAKE_C_COMPILE_FEATURES)
target_link_libraries(c_restrict_user_specific c_lib_restrict_specific)
endif()
-if (c_std_99 IN_LIST CMAKE_C_COMPILE_FEATURES)
+if (c_std_99 IN_LIST CMAKE_C_COMPILE_FEATURES AND
+ NOT "${CMAKE_C_COMPILER_ID}" STREQUAL "MSVC")
add_executable(c_target_compile_features_meta main.c)
target_compile_features(c_target_compile_features_meta
PRIVATE c_std_99
diff --git a/Tests/CompileFeatures/CMakeLists.txt b/Tests/CompileFeatures/CMakeLists.txt
index b560acd..e94473f 100644
--- a/Tests/CompileFeatures/CMakeLists.txt
+++ b/Tests/CompileFeatures/CMakeLists.txt
@@ -227,43 +227,58 @@ if (C_expected_features)
if (CMAKE_C_COMPILER_ID STREQUAL "GNU")
if (NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 4.6)
list(APPEND expected_defs
+ EXPECT_C_RESTRICT=1
EXPECT_C_STATIC_ASSERT=1
)
else()
list(APPEND expected_defs
+ EXPECT_C_RESTRICT=1
EXPECT_C_STATIC_ASSERT=0
)
endif()
elseif(CMAKE_C_COMPILER_ID STREQUAL "Clang"
OR CMAKE_C_COMPILER_ID STREQUAL "AppleClang")
list(APPEND expected_defs
+ EXPECT_C_RESTRICT=1
EXPECT_C_STATIC_ASSERT=1
)
elseif (CMAKE_C_COMPILER_ID STREQUAL "Intel")
if (NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 15)
list(APPEND expected_defs
+ EXPECT_C_RESTRICT=1
EXPECT_C_STATIC_ASSERT=1
)
else()
list(APPEND expected_defs
+ EXPECT_C_RESTRICT=1
EXPECT_C_STATIC_ASSERT=0
)
endif()
+ elseif(CMAKE_C_COMPILER_ID STREQUAL "MSVC")
+ list(APPEND expected_defs
+ EXPECT_C_RESTRICT=0
+ EXPECT_C_STATIC_ASSERT=0
+ )
elseif (CMAKE_C_COMPILER_ID STREQUAL "SunPro")
if (NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 5.13)
list(APPEND expected_defs
+ EXPECT_C_RESTRICT=1
EXPECT_C_STATIC_ASSERT=1
)
else()
list(APPEND expected_defs
+ EXPECT_C_RESTRICT=1
EXPECT_C_STATIC_ASSERT=0
)
endif()
+ else()
+ list(APPEND expected_defs
+ EXPECT_C_RESTRICT=1
+ )
endif()
list(APPEND expected_defs
EXPECT_C_FUNCTION_PROTOTYPES=1
- EXPECT_C_RESTRICT=1
)
target_compile_definitions(CompileFeaturesGenex_C PRIVATE
@@ -280,6 +295,7 @@ if (CMAKE_CXX_COMPILE_FEATURES)
if (std_flag_idx EQUAL -1)
add_executable(default_dialect default_dialect.cpp)
target_compile_definitions(default_dialect PRIVATE
+ DEFAULT_CXX20=$<EQUAL:${CMAKE_CXX_STANDARD_DEFAULT},20>
DEFAULT_CXX17=$<EQUAL:${CMAKE_CXX_STANDARD_DEFAULT},17>
DEFAULT_CXX14=$<EQUAL:${CMAKE_CXX_STANDARD_DEFAULT},14>
DEFAULT_CXX11=$<EQUAL:${CMAKE_CXX_STANDARD_DEFAULT},11>
@@ -434,6 +450,7 @@ else()
HAVE_CXX_STD_11=$<COMPILE_FEATURES:cxx_std_11>
HAVE_CXX_STD_14=$<COMPILE_FEATURES:cxx_std_14>
HAVE_CXX_STD_17=$<COMPILE_FEATURES:cxx_std_17>
+ HAVE_CXX_STD_20=$<COMPILE_FEATURES:cxx_std_20>
)
endif()
diff --git a/Tests/CompileFeatures/default_dialect.cpp b/Tests/CompileFeatures/default_dialect.cpp
index 0de1125..7ddcfe7 100644
--- a/Tests/CompileFeatures/default_dialect.cpp
+++ b/Tests/CompileFeatures/default_dialect.cpp
@@ -8,7 +8,11 @@ struct Outputter;
#define CXX_STD __cplusplus
#endif
-#if DEFAULT_CXX17
+#if DEFAULT_CXX20
+#if CXX_STD <= 201703L
+Outputter<CXX_STD> o;
+#endif
+#elif DEFAULT_CXX17
#if CXX_STD <= 201402L
Outputter<CXX_STD> o;
#endif
diff --git a/Tests/CompileFeatures/genex_test.c b/Tests/CompileFeatures/genex_test.c
index 1d54840..e58d793 100644
--- a/Tests/CompileFeatures/genex_test.c
+++ b/Tests/CompileFeatures/genex_test.c
@@ -8,7 +8,7 @@
#error EXPECT_C_RESTRICT not defined
#endif
-#if !EXPECT_C_STATIC_ASSERT
+#if !HAVE_C_STATIC_ASSERT
#if EXPECT_C_STATIC_ASSERT
#error "Expect c_static_assert feature"
#endif
@@ -18,11 +18,17 @@
#endif
#endif
-#if !EXPECT_C_FUNCTION_PROTOTYPES
+#if !HAVE_C_FUNCTION_PROTOTYPES
+#if EXPECT_C_FUNCTION_PROTOTYPES
#error Expect c_function_prototypes support
#endif
+#else
+#if !EXPECT_C_FUNCTION_PROTOTYPES
+#error Expect no c_function_prototypes support
+#endif
+#endif
-#if !EXPECT_C_RESTRICT
+#if !HAVE_C_RESTRICT
#if EXPECT_C_RESTRICT
#error Expect c_restrict support
#endif
diff --git a/Tests/RunCMake/CTest/CTestTestfile.cmake.in b/Tests/RunCMake/CTest/CTestTestfile.cmake.in
new file mode 100644
index 0000000..0763244
--- /dev/null
+++ b/Tests/RunCMake/CTest/CTestTestfile.cmake.in
@@ -0,0 +1 @@
+# Created manually
diff --git a/Tests/RunCMake/CTest/NotOn-check.cmake b/Tests/RunCMake/CTest/NotOn-check.cmake
new file mode 100644
index 0000000..b68218a
--- /dev/null
+++ b/Tests/RunCMake/CTest/NotOn-check.cmake
@@ -0,0 +1,8 @@
+set(f "${RunCMake_TEST_BINARY_DIR}/CTestTestfile.cmake")
+if(NOT EXISTS "${f}")
+ set(RunCMake_TEST_FAILED "File does not exist:\n ${f}")
+endif()
+file(READ ${f} content)
+if(NOT "${content}" MATCHES "^# Created manually")
+ set(RunCMake_TEST_FAILED "File:\n ${f}\nhas unexpected content:\n ${content}")
+endif()
diff --git a/Tests/RunCMake/CTest/NotOn.cmake b/Tests/RunCMake/CTest/NotOn.cmake
new file mode 100644
index 0000000..7fba019
--- /dev/null
+++ b/Tests/RunCMake/CTest/NotOn.cmake
@@ -0,0 +1,3 @@
+set(BUILD_TESTING OFF CACHE BOOL "Build the testing tree.")
+include(CTest)
+configure_file(CTestTestfile.cmake.in CTestTestfile.cmake)
diff --git a/Tests/RunCMake/CTest/RunCMakeTest.cmake b/Tests/RunCMake/CTest/RunCMakeTest.cmake
index a6f6842..1392240 100644
--- a/Tests/RunCMake/CTest/RunCMakeTest.cmake
+++ b/Tests/RunCMake/CTest/RunCMakeTest.cmake
@@ -3,3 +3,5 @@ include(RunCMake)
set(RunCMake_TEST_OPTIONS -DNoProject=1)
run_cmake(BeforeProject)
unset(RunCMake_TEST_OPTIONS)
+
+run_cmake(NotOn)
diff --git a/Tests/RunCMake/GeneratorExpression/RunCMakeTest.cmake b/Tests/RunCMake/GeneratorExpression/RunCMakeTest.cmake
index f9a5cae..5636d00 100644
--- a/Tests/RunCMake/GeneratorExpression/RunCMakeTest.cmake
+++ b/Tests/RunCMake/GeneratorExpression/RunCMakeTest.cmake
@@ -38,6 +38,10 @@ run_cmake(TARGET_EXISTS-no-arg)
run_cmake(TARGET_EXISTS-empty-arg)
run_cmake(TARGET_EXISTS)
run_cmake(TARGET_EXISTS-not-a-target)
+run_cmake(TARGET_NAME_IF_EXISTS-no-arg)
+run_cmake(TARGET_NAME_IF_EXISTS-empty-arg)
+run_cmake(TARGET_NAME_IF_EXISTS)
+run_cmake(TARGET_NAME_IF_EXISTS-not-a-target)
run_cmake(ImportedTarget-TARGET_BUNDLE_DIR)
run_cmake(ImportedTarget-TARGET_BUNDLE_CONTENT_DIR)
diff --git a/Tests/RunCMake/GeneratorExpression/TARGET_NAME_IF_EXISTS-check.cmake b/Tests/RunCMake/GeneratorExpression/TARGET_NAME_IF_EXISTS-check.cmake
new file mode 100644
index 0000000..2f57430
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/TARGET_NAME_IF_EXISTS-check.cmake
@@ -0,0 +1,6 @@
+file(READ "${RunCMake_TEST_BINARY_DIR}/TARGET_NAME_IF_EXISTS-generated.txt" content)
+
+set(expected "foo")
+if(NOT content STREQUAL expected)
+ set(RunCMake_TEST_FAILED "actual content:\n [[${content}]]\nbut expected:\n [[${expected}]]")
+endif()
diff --git a/Tests/RunCMake/GeneratorExpression/TARGET_NAME_IF_EXISTS-empty-arg-result.txt b/Tests/RunCMake/GeneratorExpression/TARGET_NAME_IF_EXISTS-empty-arg-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/TARGET_NAME_IF_EXISTS-empty-arg-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/GeneratorExpression/TARGET_NAME_IF_EXISTS-empty-arg-stderr.txt b/Tests/RunCMake/GeneratorExpression/TARGET_NAME_IF_EXISTS-empty-arg-stderr.txt
new file mode 100644
index 0000000..5ee13b7
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/TARGET_NAME_IF_EXISTS-empty-arg-stderr.txt
@@ -0,0 +1,9 @@
+CMake Error at TARGET_NAME_IF_EXISTS-empty-arg.cmake:2 \(file\):
+ Error evaluating generator expression:
+
+ \$<TARGET_NAME_IF_EXISTS:>
+
+ \$<TARGET_NAME_IF_EXISTS:tgt> expression requires a non-empty valid target
+ name.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/GeneratorExpression/TARGET_NAME_IF_EXISTS-empty-arg.cmake b/Tests/RunCMake/GeneratorExpression/TARGET_NAME_IF_EXISTS-empty-arg.cmake
new file mode 100644
index 0000000..f5034f4
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/TARGET_NAME_IF_EXISTS-empty-arg.cmake
@@ -0,0 +1,2 @@
+cmake_policy(SET CMP0070 NEW)
+file(GENERATE OUTPUT TARGET_NAME_IF_EXISTS-generated.txt CONTENT "$<TARGET_NAME_IF_EXISTS:${empty}>")
diff --git a/Tests/RunCMake/GeneratorExpression/TARGET_NAME_IF_EXISTS-no-arg-result.txt b/Tests/RunCMake/GeneratorExpression/TARGET_NAME_IF_EXISTS-no-arg-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/TARGET_NAME_IF_EXISTS-no-arg-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/GeneratorExpression/TARGET_NAME_IF_EXISTS-no-arg-stderr.txt b/Tests/RunCMake/GeneratorExpression/TARGET_NAME_IF_EXISTS-no-arg-stderr.txt
new file mode 100644
index 0000000..4122425
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/TARGET_NAME_IF_EXISTS-no-arg-stderr.txt
@@ -0,0 +1,8 @@
+CMake Error at TARGET_NAME_IF_EXISTS-no-arg.cmake:2 \(file\):
+ Error evaluating generator expression:
+
+ \$<TARGET_NAME_IF_EXISTS>
+
+ \$<TARGET_NAME_IF_EXISTS> expression requires exactly one parameter.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/GeneratorExpression/TARGET_NAME_IF_EXISTS-no-arg.cmake b/Tests/RunCMake/GeneratorExpression/TARGET_NAME_IF_EXISTS-no-arg.cmake
new file mode 100644
index 0000000..3293094
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/TARGET_NAME_IF_EXISTS-no-arg.cmake
@@ -0,0 +1,2 @@
+cmake_policy(SET CMP0070 NEW)
+file(GENERATE OUTPUT TARGET_NAME_IF_EXISTS-generated.txt CONTENT "$<TARGET_NAME_IF_EXISTS>")
diff --git a/Tests/RunCMake/GeneratorExpression/TARGET_NAME_IF_EXISTS-not-a-target-check.cmake b/Tests/RunCMake/GeneratorExpression/TARGET_NAME_IF_EXISTS-not-a-target-check.cmake
new file mode 100644
index 0000000..2085c16
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/TARGET_NAME_IF_EXISTS-not-a-target-check.cmake
@@ -0,0 +1,5 @@
+file(READ "${RunCMake_TEST_BINARY_DIR}/TARGET_NAME_IF_EXISTS-not-a-target-generated.txt" content)
+
+if(content)
+ set(RunCMake_TEST_FAILED "actual content:\n [[${content}]]\nbut expected an empty string")
+endif()
diff --git a/Tests/RunCMake/GeneratorExpression/TARGET_NAME_IF_EXISTS-not-a-target.cmake b/Tests/RunCMake/GeneratorExpression/TARGET_NAME_IF_EXISTS-not-a-target.cmake
new file mode 100644
index 0000000..a054e6c
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/TARGET_NAME_IF_EXISTS-not-a-target.cmake
@@ -0,0 +1,2 @@
+cmake_policy(SET CMP0070 NEW)
+file(GENERATE OUTPUT TARGET_NAME_IF_EXISTS-not-a-target-generated.txt CONTENT "$<TARGET_NAME_IF_EXISTS:just-random-string>")
diff --git a/Tests/RunCMake/GeneratorExpression/TARGET_NAME_IF_EXISTS.cmake b/Tests/RunCMake/GeneratorExpression/TARGET_NAME_IF_EXISTS.cmake
new file mode 100644
index 0000000..0ce3b1d
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/TARGET_NAME_IF_EXISTS.cmake
@@ -0,0 +1,3 @@
+cmake_policy(SET CMP0070 NEW)
+add_custom_target(foo)
+file(GENERATE OUTPUT TARGET_NAME_IF_EXISTS-generated.txt CONTENT "$<TARGET_NAME_IF_EXISTS:foo>")
diff --git a/Tests/RunCMake/cmake_minimum_required/Future.cmake b/Tests/RunCMake/cmake_minimum_required/Future.cmake
new file mode 100644
index 0000000..2b5c445
--- /dev/null
+++ b/Tests/RunCMake/cmake_minimum_required/Future.cmake
@@ -0,0 +1 @@
+cmake_minimum_required(VERSION 3.11...99.0 SOME_FUTURE_OPTION)
diff --git a/Tests/RunCMake/cmake_minimum_required/RunCMakeTest.cmake b/Tests/RunCMake/cmake_minimum_required/RunCMakeTest.cmake
index 22aa5b7..1030211 100644
--- a/Tests/RunCMake/cmake_minimum_required/RunCMakeTest.cmake
+++ b/Tests/RunCMake/cmake_minimum_required/RunCMakeTest.cmake
@@ -2,6 +2,8 @@ include(RunCMake)
run_cmake(Before24)
run_cmake(CompatBefore24)
+run_cmake(Future)
run_cmake(PolicyBefore24)
run_cmake(Range)
run_cmake(RangeBad)
+run_cmake(Unknown)
diff --git a/Tests/RunCMake/cmake_minimum_required/Unknown-result.txt b/Tests/RunCMake/cmake_minimum_required/Unknown-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/cmake_minimum_required/Unknown-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/cmake_minimum_required/Unknown-stderr.txt b/Tests/RunCMake/cmake_minimum_required/Unknown-stderr.txt
new file mode 100644
index 0000000..d698642
--- /dev/null
+++ b/Tests/RunCMake/cmake_minimum_required/Unknown-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Error at Unknown.cmake:1 \(cmake_minimum_required\):
+ cmake_minimum_required called with unknown argument "SOME_UNKNOWN_OPTION".
+Call Stack \(most recent call first\):
+ CMakeLists.txt:[0-9]+ \(include\)$
diff --git a/Tests/RunCMake/cmake_minimum_required/Unknown.cmake b/Tests/RunCMake/cmake_minimum_required/Unknown.cmake
new file mode 100644
index 0000000..6c70f91
--- /dev/null
+++ b/Tests/RunCMake/cmake_minimum_required/Unknown.cmake
@@ -0,0 +1 @@
+cmake_minimum_required(VERSION 3.11 SOME_UNKNOWN_OPTION)