diff --git a/Help/release/3.28.rst b/Help/release/3.28.rst index 77f03f63f..b7a1435cd 100644 --- a/Help/release/3.28.rst +++ b/Help/release/3.28.rst @@ -219,3 +219,10 @@ Changes made since CMake 3.28.0 include the following. * This version made no changes to documented features or interfaces. Some implementation updates were made to C++ modules support. + +3.28.6 +------ + +* This version made no changes to documented features or interfaces. + Some implementation updates were made to support ecosystem changes + and/or fix regressions. diff --git a/Help/release/3.29.rst b/Help/release/3.29.rst index 35f6d396e..3903c91b1 100644 --- a/Help/release/3.29.rst +++ b/Help/release/3.29.rst @@ -212,8 +212,8 @@ Changes made since CMake 3.29.0 include the following. :prop_tgt:`LINKER_TYPE` target property now work with compilers for the ``Swift`` language. -3.29.2, 3.29.3 --------------- +3.29.2, 3.29.3, 3.29.4 +---------------------- * These versions made no changes to documented features or interfaces. Some implementation updates were made to support ecosystem changes diff --git a/Help/variable/MSVC_VERSION.rst b/Help/variable/MSVC_VERSION.rst index cbb3a3c38..400217b83 100644 --- a/Help/variable/MSVC_VERSION.rst +++ b/Help/variable/MSVC_VERSION.rst @@ -19,7 +19,7 @@ Known version numbers are:: 1900 = VS 14.0 (v140 toolset) 1910-1919 = VS 15.0 (v141 toolset) 1920-1929 = VS 16.0 (v142 toolset) - 1930-1939 = VS 17.0 (v143 toolset) + 1930-1949 = VS 17.0 (v143 toolset) See also the :variable:`CMAKE__COMPILER_VERSION` and :variable:`MSVC_TOOLSET_VERSION` variable. diff --git a/Modules/CMakeDetermineCompilerId.cmake b/Modules/CMakeDetermineCompilerId.cmake index 7d063ed59..08de0f93f 100644 --- a/Modules/CMakeDetermineCompilerId.cmake +++ b/Modules/CMakeDetermineCompilerId.cmake @@ -567,7 +567,7 @@ Id flags: ${testflags} ${CMAKE_${lang}_COMPILER_ID_FLAGS_ALWAYS} if(CMAKE_VS_PLATFORM_NAME STREQUAL x64) set(cuda_target "64") endif() - set(id_ItemDefinitionGroup_entry "${cuda_target}%(AdditionalOptions)-v") + set(id_ItemDefinitionGroup_entry "${cuda_target}%(AdditionalOptions)-v -allow-unsupported-compiler") set(id_PostBuildEvent_Command [[echo CMAKE_CUDA_COMPILER=$(CudaToolkitBinDir)\nvcc.exe]]) if(CMAKE_VS_PLATFORM_TOOLSET_CUDA_CUSTOM_DIR) # check for legacy cuda custom toolkit folder structure diff --git a/Modules/ExternalProject.cmake b/Modules/ExternalProject.cmake index 965b25c99..5dab044e7 100644 --- a/Modules/ExternalProject.cmake +++ b/Modules/ExternalProject.cmake @@ -2224,7 +2224,16 @@ function(_ep_get_configuration_subdir_genex suffix_var) set(suffix "") get_property(_isMultiConfig GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG) if(_isMultiConfig) - set(suffix "/$") + if(CMAKE_GENERATOR STREQUAL "Xcode") + # The Xcode generator does not support per-config sources, + # so use the underlying build system's placeholder instead. + # FIXME(#23652): We have no test for the use case requiring + # CMAKE_CFG_INTDIR for XCODE_EMIT_EFFECTIVE_PLATFORM_NAME, + # but $ does not work. + set(suffix "/${CMAKE_CFG_INTDIR}") + else() + set(suffix "/$") + endif() endif() set(${suffix_var} "${suffix}" PARENT_SCOPE) endfunction() diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake index 6cacae7b9..06ffde96f 100644 --- a/Source/CMakeVersion.cmake +++ b/Source/CMakeVersion.cmake @@ -1,7 +1,7 @@ # CMake version number components. set(CMake_VERSION_MAJOR 3) set(CMake_VERSION_MINOR 29) -set(CMake_VERSION_PATCH 3) +set(CMake_VERSION_PATCH 4) #set(CMake_VERSION_RC 0) set(CMake_VERSION_IS_DIRTY 0) @@ -21,7 +21,7 @@ endif() if(NOT CMake_VERSION_NO_GIT) # If this source was exported by 'git archive', use its commit info. - set(git_info [==[b39fb31bf4 CMake 3.29.3]==]) + set(git_info [==[efaa9efece CMake 3.29.4]==]) # 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]* " diff --git a/Source/cmCxxModuleMapper.cxx b/Source/cmCxxModuleMapper.cxx index b6b95404e..4b2aec7c5 100644 --- a/Source/cmCxxModuleMapper.cxx +++ b/Source/cmCxxModuleMapper.cxx @@ -434,3 +434,17 @@ std::string CxxModuleMapContent(CxxModuleMapFormat format, assert(false); return {}; } + +CxxModuleMapMode CxxModuleMapOpenMode(CxxModuleMapFormat format) +{ + switch (format) { + case CxxModuleMapFormat::Gcc: + return CxxModuleMapMode::Binary; + case CxxModuleMapFormat::Clang: + case CxxModuleMapFormat::Msvc: + return CxxModuleMapMode::Default; + } + + assert(false); + return CxxModuleMapMode::Default; +} diff --git a/Source/cmCxxModuleMapper.h b/Source/cmCxxModuleMapper.h index c7850994f..898396cfa 100644 --- a/Source/cmCxxModuleMapper.h +++ b/Source/cmCxxModuleMapper.h @@ -83,6 +83,14 @@ struct CxxModuleUsage LookupMethod method); }; +enum class CxxModuleMapMode +{ + Text, + Binary, + + Default = Text, +}; + // Return the extension to use for a given modulemap format. cm::static_string_view CxxModuleMapExtension( cm::optional format); @@ -101,3 +109,6 @@ std::string CxxModuleMapContent(CxxModuleMapFormat format, CxxModuleLocations const& loc, cmScanDepInfo const& obj, CxxModuleUsage const& usages); + +// Return the open mode required for the modmap file format. +CxxModuleMapMode CxxModuleMapOpenMode(CxxModuleMapFormat format); diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx index 1606eec57..b2ee306f8 100644 --- a/Source/cmGlobalGenerator.cxx +++ b/Source/cmGlobalGenerator.cxx @@ -2730,6 +2730,7 @@ cmGlobalGenerator::SplitFrameworkPath(const std::string& path, } static bool RaiseCMP0037Message(cmake* cm, cmTarget* tgt, + std::string const& targetNameAsWritten, std::string const& reason) { MessageType messageType = MessageType::AUTHOR_WARNING; @@ -2750,8 +2751,8 @@ static bool RaiseCMP0037Message(cmake* cm, cmTarget* tgt, break; } if (issueMessage) { - e << "The target name \"" << tgt->GetName() << "\" is reserved " << reason - << "."; + e << "The target name \"" << targetNameAsWritten << "\" is reserved " + << reason << "."; if (messageType == MessageType::AUTHOR_WARNING) { e << " It may result in undefined behavior."; } @@ -2770,7 +2771,8 @@ bool cmGlobalGenerator::CheckCMP0037(std::string const& targetName, if (!tgt) { return true; } - return RaiseCMP0037Message(this->GetCMakeInstance(), tgt, reason); + return RaiseCMP0037Message(this->GetCMakeInstance(), tgt, targetName, + reason); } void cmGlobalGenerator::CreateDefaultGlobalTargets( diff --git a/Source/cmGlobalNinjaGenerator.cxx b/Source/cmGlobalNinjaGenerator.cxx index 612af4f49..250546fc8 100644 --- a/Source/cmGlobalNinjaGenerator.cxx +++ b/Source/cmGlobalNinjaGenerator.cxx @@ -2806,7 +2806,10 @@ bool cmGlobalNinjaGenerator::WriteDyndepFile( // `cmNinjaTargetGenerator::WriteObjectBuildStatements` and // `cmNinjaTargetGenerator::ExportObjectCompileCommand` to generate the // corresponding file path. - cmGeneratedFileStream mmf(cmStrCat(object.PrimaryOutput, ".modmap")); + cmGeneratedFileStream mmf; + mmf.Open(cmStrCat(object.PrimaryOutput, ".modmap"), false, + CxxModuleMapOpenMode(*modmap_fmt) == + CxxModuleMapMode::Binary); mmf.SetCopyIfDifferent(true); mmf << mm; } diff --git a/Source/kwsys/testConsoleBuf.cxx b/Source/kwsys/testConsoleBuf.cxx index f9b826d21..64c61e2ff 100644 --- a/Source/kwsys/testConsoleBuf.cxx +++ b/Source/kwsys/testConsoleBuf.cxx @@ -476,6 +476,22 @@ static int testFile() # define _WIN32_WINNT_VISTA 0x0600 # endif +static bool consoleIsConhost() +{ + wchar_t consoleClassNameBuf[64]; + int const consoleClassNameLen = GetClassNameW( + GetConsoleWindow(), &consoleClassNameBuf[0], sizeof(consoleClassNameBuf)); + // Windows Console Host: ConsoleWindowClass + // Windows Terminal / ConPTY: PseudoConsoleWindow (undocumented) + return (consoleClassNameLen > 0 && + wcscmp(consoleClassNameBuf, L"ConsoleWindowClass") == 0); +} + +static bool charIsNUL(wchar_t c) +{ + return c == 0; +} + static int testConsole() { int didFail = 1; @@ -691,7 +707,15 @@ static int testConsole() throw std::runtime_error("ReadConsoleOutputCharacter failed!"); } std::wstring wideTestString = kwsys::Encoding::ToWide(encodedTestString); - std::replace(wideTestString.begin(), wideTestString.end(), '\0', ' '); + if (consoleIsConhost()) { + // Windows Console Host converts NUL bytes to spaces. + std::replace(wideTestString.begin(), wideTestString.end(), '\0', ' '); + } else { + // Windows Terminal / ConPTY removes NUL bytes. + wideTestString.erase(std::remove_if(wideTestString.begin(), + wideTestString.end(), charIsNUL), + wideTestString.end()); + } std::wstring wideInputTestString = kwsys::Encoding::ToWide(encodedInputTestString); if (memcmp(outputBuffer, wideTestString.c_str(), diff --git a/Tests/RunCMake/CMP0037/RunCMakeTest.cmake b/Tests/RunCMake/CMP0037/RunCMakeTest.cmake index 558fba3bf..89beb5963 100644 --- a/Tests/RunCMake/CMP0037/RunCMakeTest.cmake +++ b/Tests/RunCMake/CMP0037/RunCMakeTest.cmake @@ -45,6 +45,10 @@ run_cmake(WARN-cond) run_cmake(WARN-cond-test) run_cmake(WARN-cond-package) +run_cmake(alias-test-NEW) +run_cmake(alias-test-OLD) +run_cmake(alias-test-WARN) + if(RunCMake_GENERATOR MATCHES "Make|Ninja") run_cmake(NEW-cond-package_source) run_cmake(OLD-cond-package_source) diff --git a/Tests/RunCMake/CMP0037/alias-test-NEW-result.txt b/Tests/RunCMake/CMP0037/alias-test-NEW-result.txt new file mode 100644 index 000000000..d00491fd7 --- /dev/null +++ b/Tests/RunCMake/CMP0037/alias-test-NEW-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/CMP0037/alias-test-NEW-stderr.txt b/Tests/RunCMake/CMP0037/alias-test-NEW-stderr.txt new file mode 100644 index 000000000..68a36ccd1 --- /dev/null +++ b/Tests/RunCMake/CMP0037/alias-test-NEW-stderr.txt @@ -0,0 +1,5 @@ +^CMake Error at alias-test-common\.cmake:[0-9]+ \(add_library\): + The target name "test" is reserved when CTest testing is enabled\. +Call Stack \(most recent call first\): + alias-test-NEW\.cmake:[0-9]+ \(include\) + CMakeLists\.txt:[0-9]+ \(include\)$ diff --git a/Tests/RunCMake/CMP0037/alias-test-NEW.cmake b/Tests/RunCMake/CMP0037/alias-test-NEW.cmake new file mode 100644 index 000000000..32569b547 --- /dev/null +++ b/Tests/RunCMake/CMP0037/alias-test-NEW.cmake @@ -0,0 +1,2 @@ +cmake_policy(SET CMP0037 NEW) +include(alias-test-common.cmake) diff --git a/Tests/RunCMake/CMP0037/alias-test-OLD-stderr.txt b/Tests/RunCMake/CMP0037/alias-test-OLD-stderr.txt new file mode 100644 index 000000000..bf177e2db --- /dev/null +++ b/Tests/RunCMake/CMP0037/alias-test-OLD-stderr.txt @@ -0,0 +1,10 @@ +^CMake Deprecation Warning at alias-test-OLD\.cmake:[0-9]+ \(cmake_policy\): + The OLD behavior for policy CMP0037 will be removed from a future version + of CMake\. + + The cmake-policies\(7\) manual explains that the OLD behaviors of all + policies are deprecated and that a policy should be set to OLD only under + specific short-term circumstances\. Projects should be ported to the NEW + behavior and not rely on setting a policy to OLD\. +Call Stack \(most recent call first\): + CMakeLists\.txt:[0-9]+ \(include\)$ diff --git a/Tests/RunCMake/CMP0037/alias-test-OLD.cmake b/Tests/RunCMake/CMP0037/alias-test-OLD.cmake new file mode 100644 index 000000000..1f3e77087 --- /dev/null +++ b/Tests/RunCMake/CMP0037/alias-test-OLD.cmake @@ -0,0 +1,2 @@ +cmake_policy(SET CMP0037 OLD) +include(alias-test-common.cmake) diff --git a/Tests/RunCMake/CMP0037/alias-test-WARN-stderr.txt b/Tests/RunCMake/CMP0037/alias-test-WARN-stderr.txt new file mode 100644 index 000000000..43bf98b8c --- /dev/null +++ b/Tests/RunCMake/CMP0037/alias-test-WARN-stderr.txt @@ -0,0 +1,11 @@ +^CMake Warning \(dev\) at alias-test-common\.cmake:[0-9]+ \(add_library\): + Policy CMP0037 is not set: Target names should not be reserved and should + match a validity pattern\. Run "cmake --help-policy CMP0037" for policy + details\. Use the cmake_policy command to set the policy and suppress this + warning\. + + The target name "test" is reserved when CTest testing is enabled\. It may + result in undefined behavior\. +Call Stack \(most recent call first\): + alias-test-WARN\.cmake:[0-9]+ \(include\) + CMakeLists\.txt:[0-9]+ \(include\) diff --git a/Tests/RunCMake/CMP0037/alias-test-WARN.cmake b/Tests/RunCMake/CMP0037/alias-test-WARN.cmake new file mode 100644 index 000000000..688cb95f3 --- /dev/null +++ b/Tests/RunCMake/CMP0037/alias-test-WARN.cmake @@ -0,0 +1,2 @@ +# leave CMP0037 unset +include(alias-test-common.cmake) diff --git a/Tests/RunCMake/CMP0037/alias-test-common.cmake b/Tests/RunCMake/CMP0037/alias-test-common.cmake new file mode 100644 index 000000000..f6e5000ea --- /dev/null +++ b/Tests/RunCMake/CMP0037/alias-test-common.cmake @@ -0,0 +1,3 @@ +enable_testing() +add_library(iface INTERFACE) +add_library(test ALIAS iface) diff --git a/Tests/RunCMake/CMakeLists.txt b/Tests/RunCMake/CMakeLists.txt index f10e72d05..a9fe571b5 100644 --- a/Tests/RunCMake/CMakeLists.txt +++ b/Tests/RunCMake/CMakeLists.txt @@ -513,6 +513,10 @@ set(execute_process_ARGS if(NOT CMake_TEST_EXTERNAL_CMAKE) list(APPEND execute_process_ARGS -DTEST_ENCODING_EXE=$) endif() +if(WIN32) + add_executable(testStartupInfo testStartupInfo.c) + list(APPEND execute_process_ARGS -DTEST_STARTUPINFO_EXE=$) +endif() add_RunCMake_test(execute_process) add_RunCMake_test(export) if(CMake_TEST_MSYSTEM_PREFIX) diff --git a/Tests/RunCMake/execute_process/RunCMakeTest.cmake b/Tests/RunCMake/execute_process/RunCMakeTest.cmake index a3a3a9aee..cd5e41bf9 100644 --- a/Tests/RunCMake/execute_process/RunCMakeTest.cmake +++ b/Tests/RunCMake/execute_process/RunCMakeTest.cmake @@ -53,3 +53,7 @@ if(WIN32 OR CYGWIN) set(RunCMake_TEST_NO_CLEAN 1) run_cmake_command(WindowsNoExtension-build ${CMAKE_COMMAND} --build . --config Debug --target RunScript) endif() + +if(TEST_STARTUPINFO_EXE) + run_cmake_script(StartupInfo -DTEST_STARTUPINFO_EXE=${TEST_STARTUPINFO_EXE}) +endif() diff --git a/Tests/RunCMake/execute_process/StartupInfo.cmake b/Tests/RunCMake/execute_process/StartupInfo.cmake new file mode 100644 index 000000000..54b9ad40a --- /dev/null +++ b/Tests/RunCMake/execute_process/StartupInfo.cmake @@ -0,0 +1 @@ +execute_process(COMMAND "${TEST_STARTUPINFO_EXE}" COMMAND_ERROR_IS_FATAL ANY) diff --git a/Tests/RunCMake/testStartupInfo.c b/Tests/RunCMake/testStartupInfo.c new file mode 100644 index 000000000..d626fb99c --- /dev/null +++ b/Tests/RunCMake/testStartupInfo.c @@ -0,0 +1,25 @@ +#ifndef _CRT_SECURE_NO_WARNINGS +# define _CRT_SECURE_NO_WARNINGS +#endif + +#if defined(_MSC_VER) && _MSC_VER >= 1928 +# pragma warning(disable : 5105) /* macro expansion warning in windows.h */ +#endif + +#include + +#include +#include + +int main(void) +{ + STARTUPINFOW si; + memset(&si, 0, sizeof(si)); + GetStartupInfoW(&si); + if (si.cbReserved2 != 0 || si.lpReserved2 != NULL) { + fprintf(stderr, "si.cbReserved2: %u\n", si.cbReserved2); + fprintf(stderr, "si.lpReserved2: %p\n", si.lpReserved2); + return 1; + } + return 0; +} diff --git a/Utilities/cmlibuv/src/win/process.c b/Utilities/cmlibuv/src/win/process.c index 11cf5b283..5cf9fb806 100644 --- a/Utilities/cmlibuv/src/win/process.c +++ b/Utilities/cmlibuv/src/win/process.c @@ -1083,8 +1083,15 @@ int uv_spawn(uv_loop_t* loop, startup.lpTitle = NULL; startup.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW; +#if 1 + /* cmake does not need libuv's support for passing file descriptors >= 3 + to the MSVC C run-time in the child. Avoid using reserved members. */ + startup.cbReserved2 = 0; + startup.lpReserved2 = NULL; +#else startup.cbReserved2 = uv__stdio_size(process->child_stdio_buffer); startup.lpReserved2 = (BYTE*) process->child_stdio_buffer; +#endif startup.hStdInput = uv__stdio_handle(process->child_stdio_buffer, 0); startup.hStdOutput = uv__stdio_handle(process->child_stdio_buffer, 1);