From b1a804d6167c8e2dc82efad72e98be58ce5eb6a5 Mon Sep 17 00:00:00 2001 From: Brad King Date: Fri, 21 Jun 2024 09:34:08 -0400 Subject: [PATCH] Ninja Multi-Config: Fix crash if config list is changed in subdirectory Look up the value of `CMAKE_CONFIGURATION_TYPES` only in the top level directory. Fixes: #26064 --- Source/cmLocalCommonGenerator.cxx | 14 ++++++++++---- .../add_subdirectory/ChangeConfigMulti.cmake | 1 + .../ChangeConfigMulti/CMakeLists.txt | 1 + Tests/RunCMake/add_subdirectory/RunCMakeTest.cmake | 4 ++++ 4 files changed, 16 insertions(+), 4 deletions(-) create mode 100644 Tests/RunCMake/add_subdirectory/ChangeConfigMulti.cmake create mode 100644 Tests/RunCMake/add_subdirectory/ChangeConfigMulti/CMakeLists.txt diff --git a/Source/cmLocalCommonGenerator.cxx b/Source/cmLocalCommonGenerator.cxx index aa953f469d..14b3040243 100644 --- a/Source/cmLocalCommonGenerator.cxx +++ b/Source/cmLocalCommonGenerator.cxx @@ -2,10 +2,12 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmLocalCommonGenerator.h" +#include #include #include #include "cmGeneratorTarget.h" +#include "cmGlobalGenerator.h" #include "cmMakefile.h" #include "cmOutputConverter.h" #include "cmStateDirectory.h" @@ -13,14 +15,18 @@ #include "cmStringAlgorithms.h" #include "cmValue.h" -class cmGlobalGenerator; - cmLocalCommonGenerator::cmLocalCommonGenerator(cmGlobalGenerator* gg, cmMakefile* mf) : cmLocalGenerator(gg, mf) { - this->ConfigNames = - this->Makefile->GetGeneratorConfigs(cmMakefile::IncludeEmptyConfig); + // Multi-config generators define one set of configurations at the top. + // Single-config generators nominally define one configuration at the top, + // but the implementation has never been strict about that, so look up the + // per-directory config to preserve behavior. + this->ConfigNames = (gg->IsMultiConfig() && !gg->GetMakefiles().empty() + ? gg->GetMakefiles().front().get() + : this->Makefile) + ->GetGeneratorConfigs(cmMakefile::IncludeEmptyConfig); } cmLocalCommonGenerator::~cmLocalCommonGenerator() = default; diff --git a/Tests/RunCMake/add_subdirectory/ChangeConfigMulti.cmake b/Tests/RunCMake/add_subdirectory/ChangeConfigMulti.cmake new file mode 100644 index 0000000000..449c5c8ae2 --- /dev/null +++ b/Tests/RunCMake/add_subdirectory/ChangeConfigMulti.cmake @@ -0,0 +1 @@ +add_subdirectory(ChangeConfigMulti) diff --git a/Tests/RunCMake/add_subdirectory/ChangeConfigMulti/CMakeLists.txt b/Tests/RunCMake/add_subdirectory/ChangeConfigMulti/CMakeLists.txt new file mode 100644 index 0000000000..3ea7fc56a7 --- /dev/null +++ b/Tests/RunCMake/add_subdirectory/ChangeConfigMulti/CMakeLists.txt @@ -0,0 +1 @@ +set(CMAKE_CONFIGURATION_TYPES NotDebug NotRelease) diff --git a/Tests/RunCMake/add_subdirectory/RunCMakeTest.cmake b/Tests/RunCMake/add_subdirectory/RunCMakeTest.cmake index 3c70d072f6..801abaeb9b 100644 --- a/Tests/RunCMake/add_subdirectory/RunCMakeTest.cmake +++ b/Tests/RunCMake/add_subdirectory/RunCMakeTest.cmake @@ -7,6 +7,10 @@ set(RunCMake_TEST_OPTIONS -DCMAKE_Fortran_COMPILER=${CMAKE_Fortran_COMPILER}) run_cmake(System) unset(RunCMake_TEST_OPTIONS) +if(RunCMake_GENERATOR_IS_MULTI_CONFIG) + run_cmake_with_options(ChangeConfigMulti "-DCMAKE_CONFIGURATION_TYPES=Debug\\;Release") +endif() + macro(run_cmake_install case) set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/${case}-build) set(RunCMake_TEST_NO_CLEAN 1)