This became available as of VS 16.10 (toolchain version 14.29.30037).
* The :cpack_gen:`CPack NSIS Generator` now requires NSIS 3.03 or later.
+
+3.22.1
+------
+
+This version made no changes to documented features or interfaces.
+Some implementation updates were made to support ecosystem changes
+and/or fix regressions.
+
+3.22.2
+------
+
+* The ``OLD`` behavior of :policy:`CMP0128` was fixed to add flags even when
+ the specified standard matches the compiler default.
const char* info_language_extensions_default = "INFO" ":" "extensions_default["
/* !defined(_MSC_VER) to exclude Clang's MSVC compatibility mode. */
-#if (defined(__clang__) || defined(__GNUC__) || \
+#if (defined(__clang__) || defined(__GNUC__) || defined(__xlC__) || \
defined(__TI_COMPILER_VERSION__)) && \
!defined(__STRICT_ANSI__) && !defined(_MSC_VER)
"ON"
const char* info_language_extensions_default = "INFO" ":" "extensions_default["
/* !defined(_MSC_VER) to exclude Clang's MSVC compatibility mode. */
-#if (defined(__clang__) || defined(__GNUC__) || \
+#if (defined(__clang__) || defined(__GNUC__) || defined(__xlC__) || \
defined(__TI_COMPILER_VERSION__)) && \
!defined(__STRICT_ANSI__) && !defined(_MSC_VER)
"ON"
list(APPEND CMAKE_ASM${ASM_DIALECT}_COMPILER_ID_VENDORS ARMCC)
set(CMAKE_ASM${ASM_DIALECT}_COMPILER_ID_VENDOR_FLAGS_ARMCC )
- set(CMAKE_ASM${ASM_DIALECT}_COMPILER_ID_VENDOR_REGEX_ARMCC "(ARM Compiler)|(ARM Assembler)")
+ set(CMAKE_ASM${ASM_DIALECT}_COMPILER_ID_VENDOR_REGEX_ARMCC "(ARM Compiler)|(ARM Assembler)|(Arm Compiler)")
list(APPEND CMAKE_ASM${ASM_DIALECT}_COMPILER_ID_VENDORS NASM)
set(CMAKE_ASM${ASM_DIALECT}_COMPILER_ID_VENDOR_FLAGS_NASM "-v")
set(id_cl "$(CLToolExe)")
elseif(CMAKE_VS_PLATFORM_TOOLSET MATCHES "v[0-9]+_clang_.*")
set(id_cl clang.exe)
- # Executable names have been chosen according documentation
- # URL: (https://software.intel.com/content/www/us/en/develop/documentation/get-started-with-dpcpp-compiler/top.html#top_GUID-A9B4C91D-97AC-450D-9742-9D895BC8AEE1)
elseif(CMAKE_VS_PLATFORM_TOOLSET MATCHES "Intel")
if(CMAKE_VS_PLATFORM_TOOLSET MATCHES "DPC\\+\\+ Compiler")
set(id_cl dpcpp.exe)
- elseif(CMAKE_VS_PLATFORM_TOOLSET MATCHES "C\\+\\+ Compiler 2021")
- set(id_cl icx.exe)
- elseif(CMAKE_VS_PLATFORM_TOOLSET MATCHES "C\\+\\+ Compiler")
+ elseif(CMAKE_VS_PLATFORM_TOOLSET MATCHES "C\\+\\+ Compiler ([8-9]\\.|1[0-9]\\.|XE)")
set(id_cl icl.exe)
+ elseif(CMAKE_VS_PLATFORM_TOOLSET MATCHES "C\\+\\+ Compiler")
+ set(id_cl icx.exe)
endif()
else()
set(id_cl cl.exe)
# The `/external:I` flag was made non-experimental in 19.29.30036.3.
if (CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 19.29.30036.3)
- set(CMAKE_INCLUDE_SYSTEM_FLAG_C "-external:I ")
+ set(CMAKE_INCLUDE_SYSTEM_FLAG_C "-external:I")
set(_CMAKE_INCLUDE_SYSTEM_FLAG_C_WARNING "-external:W0 ")
endif ()
# The `/external:I` flag was made non-experimental in 19.29.30036.3.
if (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 19.29.30036.3)
- set(CMAKE_INCLUDE_SYSTEM_FLAG_CXX "-external:I ")
+ set(CMAKE_INCLUDE_SYSTEM_FLAG_CXX "-external:I")
set(_CMAKE_INCLUDE_SYSTEM_FLAG_CXX_WARNING "-external:W0 ")
endif ()
function(_boost_get_existing_target component target_var)
set(names "${component}")
- if(component MATCHES "^([a-z_]*)(python|numpy)([1-9])\\.?([0-9])?$")
+ if(component MATCHES "^([a-z_]*)(python|numpy)([1-9])\\.?([0-9]+)?$")
# handle pythonXY and numpyXY versioned components and also python X.Y, mpi_python etc.
list(APPEND names
"${CMAKE_MATCH_1}${CMAKE_MATCH_2}" # python
if(TARGET "${prefix}::${name}")
# The target may be an INTERFACE library that wraps around a single other
# target for compatibility. Unwrap this layer so we can extract real info.
- if("${name}" MATCHES "^(python|numpy|mpi_python)([1-9])([0-9])$")
+ if("${name}" MATCHES "^(python|numpy|mpi_python)([1-9])([0-9]+)$")
set(name_nv "${CMAKE_MATCH_1}")
if(TARGET "${prefix}::${name_nv}")
get_property(type TARGET "${prefix}::${name}" PROPERTY TYPE)
function(_boost_get_canonical_target_name component target_var)
string(TOLOWER "${component}" component)
- if(component MATCHES "^([a-z_]*)(python|numpy)([1-9])\\.?([0-9])?$")
+ if(component MATCHES "^([a-z_]*)(python|numpy)([1-9])\\.?([0-9]+)?$")
# handle pythonXY and numpyXY versioned components and also python X.Y, mpi_python etc.
set(${target_var} "Boost::${CMAKE_MATCH_1}${CMAKE_MATCH_2}" PARENT_SCOPE)
else()
# against the new release.
# Handle Python version suffixes
- if(component MATCHES "^(python|mpi_python|numpy)([0-9][0-9]?|[0-9]\\.[0-9])\$")
+ if(component MATCHES "^(python|mpi_python|numpy)([0-9][0-9]?|[0-9]\\.[0-9]+)\$")
set(component "${CMAKE_MATCH_1}")
set(component_python_version "${CMAKE_MATCH_2}")
endif()
set(_Boost_TIMER_DEPENDENCIES chrono)
set(_Boost_WAVE_DEPENDENCIES filesystem serialization thread chrono date_time atomic)
set(_Boost_WSERIALIZATION_DEPENDENCIES serialization)
- else()
+ elseif(Boost_VERSION_STRING VERSION_LESS 1.78.0)
set(_Boost_CONTRACT_DEPENDENCIES thread chrono)
set(_Boost_COROUTINE_DEPENDENCIES context)
set(_Boost_FIBER_DEPENDENCIES context)
set(_Boost_TIMER_DEPENDENCIES chrono)
set(_Boost_WAVE_DEPENDENCIES filesystem serialization thread chrono atomic)
set(_Boost_WSERIALIZATION_DEPENDENCIES serialization)
- if(Boost_VERSION_STRING VERSION_GREATER_EQUAL 1.78.0 AND NOT Boost_NO_WARN_NEW_VERSIONS)
+ else()
+ set(_Boost_CONTRACT_DEPENDENCIES thread chrono)
+ set(_Boost_COROUTINE_DEPENDENCIES context)
+ set(_Boost_FIBER_DEPENDENCIES context)
+ set(_Boost_IOSTREAMS_DEPENDENCIES regex)
+ set(_Boost_JSON_DEPENDENCIES container)
+ set(_Boost_LOG_DEPENDENCIES log_setup filesystem thread regex chrono atomic)
+ set(_Boost_MATH_DEPENDENCIES math_c99 math_c99f math_c99l math_tr1 math_tr1f math_tr1l)
+ set(_Boost_MPI_DEPENDENCIES serialization)
+ set(_Boost_MPI_PYTHON_DEPENDENCIES python${component_python_version} mpi serialization)
+ set(_Boost_NUMPY_DEPENDENCIES python${component_python_version})
+ set(_Boost_THREAD_DEPENDENCIES chrono atomic)
+ set(_Boost_TIMER_DEPENDENCIES chrono)
+ set(_Boost_WAVE_DEPENDENCIES filesystem serialization thread chrono atomic)
+ set(_Boost_WSERIALIZATION_DEPENDENCIES serialization)
+ if(Boost_VERSION_STRING VERSION_GREATER_EQUAL 1.79.0 AND NOT Boost_NO_WARN_NEW_VERSIONS)
message(WARNING "New Boost version may have incorrect or missing dependencies and imported targets")
endif()
endif()
#
function(_Boost_COMPONENT_HEADERS component _hdrs)
# Handle Python version suffixes
- if(component MATCHES "^(python|mpi_python|numpy)([0-9][0-9]?|[0-9]\\.[0-9])\$")
+ if(component MATCHES "^(python|mpi_python|numpy)([0-9]+|[0-9]\\.[0-9]+)\$")
set(component "${CMAKE_MATCH_1}")
set(component_python_version "${CMAKE_MATCH_2}")
endif()
# _Boost_COMPONENT_HEADERS. See the instructions at the top of
# _Boost_COMPONENT_DEPENDENCIES.
set(_Boost_KNOWN_VERSIONS ${Boost_ADDITIONAL_VERSIONS}
- "1.77.0" "1.77" "1.76.0" "1.76" "1.75.0" "1.75" "1.74.0" "1.74"
+ "1.78.0" "1.78" "1.77.0" "1.77" "1.76.0" "1.76" "1.75.0" "1.75" "1.74.0" "1.74"
"1.73.0" "1.73" "1.72.0" "1.72" "1.71.0" "1.71" "1.70.0" "1.70" "1.69.0" "1.69"
"1.68.0" "1.68" "1.67.0" "1.67" "1.66.0" "1.66" "1.65.1" "1.65.0" "1.65"
"1.64.0" "1.64" "1.63.0" "1.63" "1.62.0" "1.62" "1.61.0" "1.61" "1.60.0" "1.60"
if(${COMPONENT} MATCHES "^(python|mpi_python|numpy)([0-9])\$")
set(COMPONENT_UNVERSIONED "${CMAKE_MATCH_1}")
set(COMPONENT_PYTHON_VERSION_MAJOR "${CMAKE_MATCH_2}")
- elseif(${COMPONENT} MATCHES "^(python|mpi_python|numpy)([0-9])\\.?([0-9])\$")
+ elseif(${COMPONENT} MATCHES "^(python|mpi_python|numpy)([0-9])\\.?([0-9]+)\$")
set(COMPONENT_UNVERSIONED "${CMAKE_MATCH_1}")
set(COMPONENT_PYTHON_VERSION_MAJOR "${CMAKE_MATCH_2}")
set(COMPONENT_PYTHON_VERSION_MINOR "${CMAKE_MATCH_3}")
if(PKG_CONFIG_FOUND)
pkg_check_modules(GLUT glut)
if(GLUT_FOUND)
+ # In the non-pkg-config code path we only provide GLUT_INCLUDE_DIR.
+ set(GLUT_INCLUDE_DIR "${GLUT_INCLUDE_DIRS}")
_add_glut_target_simple()
FIND_PACKAGE_HANDLE_STANDARD_ARGS(GLUT REQUIRED_VARS GLUT_FOUND)
return()
message (FATAL_ERROR "FindPython: INTERNAL ERROR")
endif()
if (_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR EQUAL "3")
- set(_${_PYTHON_PREFIX}_VERSIONS 3.10 3.9 3.8 3.7 3.6 3.5 3.4 3.3 3.2 3.1 3.0)
+ set(_${_PYTHON_PREFIX}_VERSIONS 3.11 3.10 3.9 3.8 3.7 3.6 3.5 3.4 3.3 3.2 3.1 3.0)
elseif (_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR EQUAL "2")
set(_${_PYTHON_PREFIX}_VERSIONS 2.7 2.6 2.5 2.4 2.3 2.2 2.1 2.0)
else()
set(_PYTHON1_VERSIONS 1.6 1.5)
set(_PYTHON2_VERSIONS 2.7 2.6 2.5 2.4 2.3 2.2 2.1 2.0)
-set(_PYTHON3_VERSIONS 3.10 3.9 3.8 3.7 3.6 3.5 3.4 3.3 3.2 3.1 3.0)
+set(_PYTHON3_VERSIONS 3.11 3.10 3.9 3.8 3.7 3.6 3.5 3.4 3.3 3.2 3.1 3.0)
if(PythonInterp_FIND_VERSION)
if(PythonInterp_FIND_VERSION_COUNT GREATER 1)
set(_PYTHON1_VERSIONS 1.6 1.5)
set(_PYTHON2_VERSIONS 2.7 2.6 2.5 2.4 2.3 2.2 2.1 2.0)
-set(_PYTHON3_VERSIONS 3.10 3.9 3.8 3.7 3.6 3.5 3.4 3.3 3.2 3.1 3.0)
+set(_PYTHON3_VERSIONS 3.11 3.10 3.9 3.8 3.7 3.6 3.5 3.4 3.3 3.2 3.1 3.0)
if(PythonLibs_FIND_VERSION)
if(PythonLibs_FIND_VERSION_COUNT GREATER 1)
add_executable(FortranCInterface main.F call_sub.f ${call_mod})
target_link_libraries(FortranCInterface PUBLIC symbols)
+# If IPO is enabled here, GCC gfortran >= 12.0 will obfuscate
+# the strings of the return values in the compiled executable,
+# which we use to regex match against later.
+# The static libraries must be build with IPO and non-IPO objects,
+# as that will ensure the verify step will operate on IPO objects,
+# if requested by the system compiler flags.
+if(CMAKE_Fortran_COMPILER_ID STREQUAL "GNU" AND
+ CMAKE_Fortran_COMPILER_VERSION VERSION_GREATER_EQUAL 12)
+ target_compile_options(FortranCInterface PRIVATE "-fno-lto")
+ target_compile_options(myfort PRIVATE "-flto=auto" "-ffat-lto-objects")
+ target_compile_options(symbols PRIVATE "-flto=auto" "-ffat-lto-objects")
+endif()
+
file(GENERATE OUTPUT exe-$<CONFIG>.cmake CONTENT [[
set(FortranCInterface_EXE "$<TARGET_FILE:FortranCInterface>")
]])
if(_ANDROID_STL_EXCEPTIONS OR _ANDROID_STL_RTTI)
string(APPEND CMAKE_${lang}_STANDARD_LIBRARIES " -lc++abi")
if(CMAKE_SYSTEM_VERSION LESS 21)
- list(APPEND CMAKE_${lang}_STANDARD_LIBRARIES "-landroid_support")
+ string(APPEND CMAKE_${lang}_STANDARD_LIBRARIES " -landroid_support")
endif()
endif()
endmacro()
# CMake version number components.
set(CMake_VERSION_MAJOR 3)
set(CMake_VERSION_MINOR 22)
-set(CMake_VERSION_PATCH 1)
+set(CMake_VERSION_PATCH 2)
#set(CMake_VERSION_RC 0)
set(CMake_VERSION_IS_DIRTY 0)
if(NOT CMake_VERSION_NO_GIT)
# If this source was exported by 'git archive', use its commit info.
- set(git_info [==[aa6a33fe54 CMake 3.22.1]==])
+ set(git_info [==[8428e39ed9 CMake 3.22.2]==])
# Otherwise, try to identify the current development source version.
if(NOT git_info MATCHES "^([0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]?[0-9a-f]?)[0-9a-f]* "
cmELF elf(fileNameArg.c_str());
if (!elf) {
- status.SetError(cmStrCat("READ_ELF given FILE \"", fileNameArg,
- "\" that is not a valid ELF file."));
- return false;
+ if (arguments.Error.empty()) {
+ status.SetError(cmStrCat("READ_ELF given FILE:\n ", fileNameArg,
+ "\nthat is not a valid ELF file."));
+ return false;
+ }
+ status.GetMakefile().AddDefinition(arguments.Error,
+ "not a valid ELF file");
+ return true;
}
if (!arguments.RPath.empty()) {
// If the standard requested is older than the compiler's default or the
// extension mode doesn't match then we need to use a flag.
- if (stdIt < defaultStdIt ||
- (cmp0128 == cmPolicies::NEW && ext != defaultExt)) {
+ if ((cmp0128 != cmPolicies::NEW && stdIt <= defaultStdIt) ||
+ (cmp0128 == cmPolicies::NEW &&
+ (stdIt < defaultStdIt || ext != defaultExt))) {
auto offset = std::distance(cm::cbegin(stds), stdIt);
return cmStrCat("CMAKE_", this->Language, stdsStrings[offset], "_", type,
"_COMPILE_OPTION");
"flags": []
},
{
- "name": "LinkControlFlowGuard",
- "switch": "guard:cf",
- "comment": "Control Flow Guard",
- "value": "true",
- "flags": []
- },
- {
"name": "LinkGuardEHContMetadata",
"switch": "guard:ehcont",
"comment": "Enable EH Continuation Metadata",
add_test(NAME testglut_tgt COMMAND testglut_tgt)
add_executable(testglut_var main.c)
-target_include_directories(testglut_var PRIVATE ${GLUT_INCLUDE_DIRS})
+target_include_directories(testglut_var PRIVATE ${GLUT_INCLUDE_DIR})
target_link_libraries(testglut_var PRIVATE ${GLUT_LIBRARIES})
add_test(NAME testglut_var COMMAND testglut_var)
string(REPLACE "${CMAKE_START_TEMP_FILE}" "" CMAKE_@lang@_COMPILE_OBJECT "${CMAKE_@lang@_COMPILE_OBJECT}")
string(REPLACE "${CMAKE_END_TEMP_FILE}" "" CMAKE_@lang@_COMPILE_OBJECT "${CMAKE_@lang@_COMPILE_OBJECT}")
-set(CMAKE_@lang@_EXTENSIONS @extensions_opposite@)
add_library(foo "@RunCMake_SOURCE_DIR@/empty.@ext@")
--- /dev/null
+set(CMAKE_@lang@_EXTENSIONS @extensions_opposite@)
+set(CMAKE_@lang@_STANDARD @standard_default@)
--- /dev/null
+set(CMAKE_@lang@_EXTENSIONS @extensions_opposite@)
--- /dev/null
+set(CMAKE_@lang@_EXTENSIONS @extensions_default@)
+set(CMAKE_@lang@_STANDARD @standard_default@)
--- /dev/null
+foreach(flag @flags@)
+ string(FIND "${actual_stdout}" "${flag}" position)
+
+ if(NOT position EQUAL -1)
+ set(found TRUE)
+ break()
+ endif()
+endforeach()
+
+if(NOT found)
+ set(RunCMake_TEST_FAILED "No compile flags from \"@flags@\" found for LANG_STANDARD=default.")
+endif()
--- /dev/null
+set(CMAKE_@lang@_STANDARD @standard_default@)
-enable_language(@lang@)
cmake_policy(SET CMP0128 OLD)
set(CMAKE_POLICY_WARNING_CMP0128 ON)
set(CMAKE_@lang@_EXTENSIONS @extensions_default@)
set(CMAKE_@lang@_STANDARD @standard_default@)
-add_library(foo "@RunCMake_SOURCE_DIR@/empty.@ext@")
-enable_language(@lang@)
cmake_policy(SET CMP0128 OLD)
set(CMAKE_POLICY_WARNING_CMP0128 ON)
set(CMAKE_@lang@_EXTENSIONS @extensions_opposite@)
-add_library(foo "@RunCMake_SOURCE_DIR@/empty.@ext@")
+++ /dev/null
-enable_language(@lang@)
-
-# Make sure the compile command is not hidden.
-string(REPLACE "${CMAKE_START_TEMP_FILE}" "" CMAKE_@lang@_COMPILE_OBJECT "${CMAKE_@lang@_COMPILE_OBJECT}")
-string(REPLACE "${CMAKE_END_TEMP_FILE}" "" CMAKE_@lang@_COMPILE_OBJECT "${CMAKE_@lang@_COMPILE_OBJECT}")
-
-set(CMAKE_@lang@_EXTENSIONS @extensions_opposite@)
-set(CMAKE_@lang@_STANDARD @standard_default@)
-add_library(foo "@RunCMake_SOURCE_DIR@/empty.@ext@")
+++ /dev/null
-enable_language(@lang@)
-
-# Make sure the compile command is not hidden.
-string(REPLACE "${CMAKE_START_TEMP_FILE}" "" CMAKE_@lang@_COMPILE_OBJECT "${CMAKE_@lang@_COMPILE_OBJECT}")
-string(REPLACE "${CMAKE_END_TEMP_FILE}" "" CMAKE_@lang@_COMPILE_OBJECT "${CMAKE_@lang@_COMPILE_OBJECT}")
-
-set(CMAKE_@lang@_EXTENSIONS @extensions_default@)
-set(CMAKE_@lang@_STANDARD @standard_default@)
-add_library(foo "@RunCMake_SOURCE_DIR@/empty.@ext@")
endif()
configure_file("${RunCMake_SOURCE_DIR}/CMakeLists.txt" "${RunCMake_BINARY_DIR}/CMakeLists.txt" COPYONLY)
+file(READ "${RunCMake_SOURCE_DIR}/CMP0128Common.cmake" cmp0128_common)
function(test_build)
set(test ${name}-${lang})
- configure_file("${RunCMake_SOURCE_DIR}/${name}.cmake" "${RunCMake_BINARY_DIR}/${test}.cmake" @ONLY)
+ file(READ "${RunCMake_SOURCE_DIR}/${name}.cmake" cmake)
+ file(CONFIGURE OUTPUT "${RunCMake_BINARY_DIR}/${test}.cmake" CONTENT "${cmake}${cmp0128_common}" @ONLY)
if(EXISTS "${RunCMake_SOURCE_DIR}/${name}-build-check.cmake")
configure_file("${RunCMake_SOURCE_DIR}/${name}-build-check.cmake" "${RunCMake_BINARY_DIR}/${test}-build-check.cmake" @ONLY)
endif()
list(APPEND flags "${result}")
endmacro()
-function(test_extensions_opposite)
+function(test_cmp0128_old_same_standard)
+ if(extensions_default)
+ set(flag_ext "_EXT")
+ endif()
+
+ set(flag "${${lang}${${lang}_STANDARD_DEFAULT}${flag_ext}_FLAG}")
+
+ if(NOT flag)
+ return()
+ endif()
+
+ mangle_flags(flag)
+
+ set(name CMP0128OldSameStandard)
+ test_build(--verbose)
+endfunction()
+
+function(test_cmp0128_new_extensions_opposite)
if(extensions_opposite)
set(flag_ext "_EXT")
endif()
# Make sure we enable/disable extensions when:
# 1. LANG_STANDARD is unset.
- set(name ExtensionsStandardUnset)
+ set(name CMP0128NewExtensionsStandardUnset)
set(RunCMake_TEST_OPTIONS -DCMAKE_POLICY_DEFAULT_CMP0128=NEW)
test_build(--verbose)
# 2. LANG_STANDARD matches CMAKE_LANG_STANDARD_DEFAULT.
- set(name ExtensionsStandardDefault)
+ set(name CMP0128NewExtensionsStandardDefault)
test_build(--verbose)
endfunction()
-function(test_no_unnecessary_flag)
+function(test_cmp0128_new_no_unnecessary_flag)
set(standard_flag "${${lang}${${lang}_STANDARD_DEFAULT}_FLAG}")
set(extension_flag "${${lang}${${lang}_STANDARD_DEFAULT}_EXT_FLAG}")
mangle_flags(standard_flag)
mangle_flags(extension_flag)
- set(name NoUnnecessaryFlag)
+ set(name CMP0128NewNoUnnecessaryFlag)
set(RunCMake_TEST_OPTIONS -DCMAKE_POLICY_DEFAULT_CMP0128=NEW)
test_build(--verbose)
endfunction()
set(extensions_opposite ON)
endif()
- test_extensions_opposite()
- test_no_unnecessary_flag()
+ test_cmp0128_new_extensions_opposite()
+ test_cmp0128_new_no_unnecessary_flag()
+ test_cmp0128_old_same_standard()
test_cmp0128_warn_match()
test_cmp0128_warn_unset()
endfunction()
run_cmake(VsSettings)
run_cmake(VsSourceSettingsTool)
run_cmake(VsPlatformToolset)
+run_cmake(VsControlFlowGuardLinkSetting)
run_cmake(VsWinRTByDefault)
--- /dev/null
+set(vcProjectFile "${RunCMake_TEST_BINARY_DIR}/ControlFlowGuardProject.vcxproj")
+if(NOT EXISTS "${vcProjectFile}")
+ set(RunCMake_TEST_FAILED "Project file ControlFlowGuardProject.vcxproj does not exist.")
+ return()
+endif()
+
+set(Is_in_link_section 0)
+set(HAS_ControlFlowGuardSetting 0)
+
+file(STRINGS "${vcProjectFile}" lines)
+foreach(line IN LISTS lines)
+ if(line MATCHES "^ *<LinkControlFlowGuard>([^<>]+)</LinkControlFlowGuard>")
+ set(RunCMake_TEST_FAILED "Project file ControlFlowGuardProject.vcxproj contains the invalid <LinkControlFlowGuard> link property.")
+ return()
+ break()
+ endif()
+ if(line MATCHES "^ *<Link>")
+ # The start of the link section of the vcxproj file
+ set(Is_in_link_section 1)
+ continue()
+ endif()
+ if(line MATCHES "^ *</Link>")
+ # The end of the link section of the vcxproj file
+ set(Is_in_link_section 0)
+ continue()
+ endif()
+ if(Is_in_link_section)
+ if(line MATCHES "^ *<AdditionalOptions>([^<>]+)</AdditionalOptions>")
+ if("${CMAKE_MATCH_1}" MATCHES ".*/guard:cf.*")
+ set(HAS_ControlFlowGuardSetting 1)
+ break()
+ endif()
+ endif()
+ endif()
+endforeach()
+
+if(NOT HAS_ControlFlowGuardSetting)
+ set(RunCMake_TEST_FAILED "Project file ControlFlowGuardProject.vcxproj does not have '/guard:cf' specified in the <AdditionalOptions> property.")
+ return()
+endif()
--- /dev/null
+enable_language(CXX)
+
+# Add the Control Flow Guard compiler and linker option
+add_compile_options("/guard:cf")
+string(APPEND CMAKE_SHARED_LINKER_FLAGS " /guard:cf")
+
+add_library(ControlFlowGuardProject SHARED foo.cpp)
-.*file READ_ELF must be called with at least three additional arguments\.
-.*file READ_ELF given FILE "XXX" that does not exist\.
+^CMake Error at READ_ELF.cmake:1 \(file\):
+ file READ_ELF must be called with at least three additional arguments\.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:[0-9]+ \(include\)
++
+CMake Error at READ_ELF.cmake:2 \(file\):
+ file READ_ELF given FILE "XXX" that does not exist\.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:[0-9]+ \(include\)
++
+CMake Error at READ_ELF.cmake:4 \(file\):
+ file READ_ELF given FILE:
+
+ [^
+]*/Tests/RunCMake/file/READ_ELF.cmake
+
+ that is not a valid ELF file\.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:[0-9]+ \(include\)$
file(READ_ELF XXX)
file(READ_ELF XXX RPATH YYY)
+file(READ_ELF ${CMAKE_CURRENT_LIST_FILE} RPATH YYY CAPTURE_ERROR err)
+file(READ_ELF ${CMAKE_CURRENT_LIST_FILE} RPATH YYY)