From 41aea129417e2d34b2f066870bb33d4ac80e3031 Mon Sep 17 00:00:00 2001 From: Benjamin Buch Date: Sat, 5 Jul 2025 00:04:17 -0400 Subject: [PATCH] Do not define CMAKE_PARENT_LIST_FILE in CMakeLists.txt Add policy `CMP0198` for compatibility. Issue: #25026 --- Help/manual/cmake-policies.7.rst | 8 ++++ Help/policy/CMP0198.rst | 23 +++++++++++ Help/release/dev/cmake-parent-fix.rst | 5 +++ Help/variable/CMAKE_PARENT_LIST_FILE.rst | 3 +- Source/cmMakefile.cxx | 39 ++++++++++++++++++- Source/cmMakefile.h | 3 ++ Source/cmPolicies.h | 3 ++ .../include/CMP0198-NEW-root-stdout.txt | 6 +++ .../include/CMP0198-NEW-subdir-stdout.txt | 7 ++++ .../RunCMake/include/CMP0198-NEW-subdir.cmake | 2 + .../include/CMP0198-OLD-root-stdout.txt | 6 +++ .../include/CMP0198-OLD-subdir-stdout.txt | 7 ++++ .../RunCMake/include/CMP0198-OLD-subdir.cmake | 2 + .../include/CMP0198-WARN-root-stdout.txt | 6 +++ .../include/CMP0198-WARN-subdir-stdout.txt | 7 ++++ .../include/CMP0198-WARN-subdir.cmake | 3 ++ .../CMP0198-implicit-NEW-root-stdout.txt | 6 +++ Tests/RunCMake/include/CMakeLists.txt | 24 +++++++++++- .../include/ParentVariableRoot-stdout.txt | 1 + Tests/RunCMake/include/RunCMakeTest.cmake | 18 +++++++++ 20 files changed, 175 insertions(+), 4 deletions(-) create mode 100644 Help/policy/CMP0198.rst create mode 100644 Help/release/dev/cmake-parent-fix.rst create mode 100644 Tests/RunCMake/include/CMP0198-NEW-root-stdout.txt create mode 100644 Tests/RunCMake/include/CMP0198-NEW-subdir-stdout.txt create mode 100644 Tests/RunCMake/include/CMP0198-NEW-subdir.cmake create mode 100644 Tests/RunCMake/include/CMP0198-OLD-root-stdout.txt create mode 100644 Tests/RunCMake/include/CMP0198-OLD-subdir-stdout.txt create mode 100644 Tests/RunCMake/include/CMP0198-OLD-subdir.cmake create mode 100644 Tests/RunCMake/include/CMP0198-WARN-root-stdout.txt create mode 100644 Tests/RunCMake/include/CMP0198-WARN-subdir-stdout.txt create mode 100644 Tests/RunCMake/include/CMP0198-WARN-subdir.cmake create mode 100644 Tests/RunCMake/include/CMP0198-implicit-NEW-root-stdout.txt diff --git a/Help/manual/cmake-policies.7.rst b/Help/manual/cmake-policies.7.rst index 21cc92ab97..e183bd03de 100644 --- a/Help/manual/cmake-policies.7.rst +++ b/Help/manual/cmake-policies.7.rst @@ -92,6 +92,14 @@ Supported Policies The following policies are supported. +Policies Introduced by CMake 4.2 +-------------------------------- + +.. toctree:: + :maxdepth: 1 + + CMP0198: CMAKE_PARENT_LIST_FILE is not defined in CMakeLists.txt. + Policies Introduced by CMake 4.1 -------------------------------- diff --git a/Help/policy/CMP0198.rst b/Help/policy/CMP0198.rst new file mode 100644 index 0000000000..4e32e1ce43 --- /dev/null +++ b/Help/policy/CMP0198.rst @@ -0,0 +1,23 @@ +CMP0198 +------- + +.. versionadded:: 4.2 + +:variable:`CMAKE_PARENT_LIST_FILE` is not defined in ``CMakeLists.txt``. + +CMake 4.1 and below defined ``CMAKE_PARENT_LIST_FILE`` when processing +a ``CMakeLists.txt`` even though there is no parent file. CMake 4.2 +and above prefer to not define ``CMAKE_PARENT_LIST_FILE``. This policy +provides compatibility for projects that accidentally relied on the +old behavior. + +The ``OLD`` behavior for this policy is to set +:variable:`CMAKE_PARENT_LIST_FILE` to :variable:`CMAKE_CURRENT_LIST_FILE` +when processing a ``CMakeLists.txt``. The ``NEW`` behavior for this policy +is to not set :variable:`CMAKE_PARENT_LIST_FILE`. + +.. |INTRODUCED_IN_CMAKE_VERSION| replace:: 4.2 +.. |WARNS_OR_DOES_NOT_WARN| replace:: does *not* warn +.. include:: include/STANDARD_ADVICE.rst + +.. include:: include/DEPRECATED.rst diff --git a/Help/release/dev/cmake-parent-fix.rst b/Help/release/dev/cmake-parent-fix.rst new file mode 100644 index 0000000000..99fdcc7cfe --- /dev/null +++ b/Help/release/dev/cmake-parent-fix.rst @@ -0,0 +1,5 @@ +cmake-parent-fix +---------------- + +* :variable:`CMAKE_PARENT_LIST_FILE` is no longer defined when processing + a ``CMakeLists.txt`` file. See policy :policy:`CMP0198`. diff --git a/Help/variable/CMAKE_PARENT_LIST_FILE.rst b/Help/variable/CMAKE_PARENT_LIST_FILE.rst index 7e71efa901..c0c646993e 100644 --- a/Help/variable/CMAKE_PARENT_LIST_FILE.rst +++ b/Help/variable/CMAKE_PARENT_LIST_FILE.rst @@ -8,7 +8,8 @@ While processing a CMake file loaded by :command:`include` or including it. While processing a ``CMakeLists.txt`` file, even in subdirectories, -this variable has the same value as :variable:`CMAKE_CURRENT_LIST_FILE`. +this variable is not defined. See policy :policy:`CMP0198`. + While processing a :option:`cmake -P` script, this variable is not defined in the outermost script. diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx index 2b60760e3a..5bf8d16198 100644 --- a/Source/cmMakefile.cxx +++ b/Source/cmMakefile.cxx @@ -1553,7 +1553,23 @@ void cmMakefile::Configure() cmSystemTools::MakeDirectory(filesDir); assert(cmSystemTools::FileExists(currentStart, true)); - this->AddDefinition(kCMAKE_PARENT_LIST_FILE, currentStart); + + // In the top-most directory, cmake_minimum_required() may not have been + // called yet, so ApplyPolicyVersion() may not have handled the default + // policy value. Check them here. + if (this->GetPolicyStatus(cmPolicies::CMP0198) == cmPolicies::WARN) { + if (cmValue defaultValue = + this->GetDefinition("CMAKE_POLICY_DEFAULT_CMP0198")) { + if (*defaultValue == "NEW") { + this->SetPolicy(cmPolicies::CMP0198, cmPolicies::NEW); + } else if (*defaultValue == "OLD") { + this->SetPolicy(cmPolicies::CMP0198, cmPolicies::OLD); + } + } + } + + // Set CMAKE_PARENT_LIST_FILE for CMakeLists.txt based on CMP0198 policy + this->UpdateParentListFileVariable(); #ifdef CMake_ENABLE_DEBUGGER if (this->GetCMakeInstance()->GetDebugAdapter()) { @@ -4092,6 +4108,12 @@ bool cmMakefile::SetPolicy(cmPolicies::PolicyID id, } this->StateSnapshot.SetPolicy(id, status); + + // Handle CMAKE_PARENT_LIST_FILE for CMP0198 policy changes + if (id == cmPolicies::CMP0198) { + this->UpdateParentListFileVariable(); + } + return true; } @@ -4144,6 +4166,21 @@ bool cmMakefile::SetPolicyVersion(std::string const& version_min, cmPolicies::WarnCompat::On); } +void cmMakefile::UpdateParentListFileVariable() +{ + // CMP0198 determines CMAKE_PARENT_LIST_FILE behavior in CMakeLists.txt + if (this->GetPolicyStatus(cmPolicies::CMP0198) == cmPolicies::NEW) { + this->RemoveDefinition(kCMAKE_PARENT_LIST_FILE); + } else { + std::string currentSourceDir = + this->StateSnapshot.GetDirectory().GetCurrentSource(); + std::string currentStart = + this->GetCMakeInstance()->GetCMakeListFile(currentSourceDir); + + this->AddDefinition(kCMAKE_PARENT_LIST_FILE, currentStart); + } +} + cmMakefile::VariablePushPop::VariablePushPop(cmMakefile* m) : Makefile(m) { diff --git a/Source/cmMakefile.h b/Source/cmMakefile.h index 89b3c2b681..ab0c75f4f9 100644 --- a/Source/cmMakefile.h +++ b/Source/cmMakefile.h @@ -391,6 +391,9 @@ public: void RecordPolicies(cmPolicies::PolicyMap& pm) const; //@} + /** Update CMAKE_PARENT_LIST_FILE based on CMP0198 policy status. */ + void UpdateParentListFileVariable(); + /** Helper class to push and pop policies automatically. */ class PolicyPushPop { diff --git a/Source/cmPolicies.h b/Source/cmPolicies.h index b6ef05e102..6b9fff9000 100644 --- a/Source/cmPolicies.h +++ b/Source/cmPolicies.h @@ -589,6 +589,9 @@ class cmMakefile; "The CMakeDetermineVSServicePack module is removed.", 4, 1, 0, WARN) \ SELECT(POLICY, CMP0197, \ "MSVC link -machine: flag is not in CMAKE_*_LINKER_FLAGS.", 4, 1, 0, \ + WARN) \ + SELECT(POLICY, CMP0198, \ + "CMAKE_PARENT_LIST_FILE is not defined in CMakeLists.txt.", 4, 2, 0, \ WARN) #define CM_SELECT_ID(F, A1, A2, A3, A4, A5, A6) F(A1) diff --git a/Tests/RunCMake/include/CMP0198-NEW-root-stdout.txt b/Tests/RunCMake/include/CMP0198-NEW-root-stdout.txt new file mode 100644 index 0000000000..420a047a11 --- /dev/null +++ b/Tests/RunCMake/include/CMP0198-NEW-root-stdout.txt @@ -0,0 +1,6 @@ +-- CMakeLists\.txt: ''.* +-- CMakeLists\.txt: '' +-- ParentVariableRoot/include1\.cmake: '[^']*/Tests/RunCMake/include/CMakeLists\.txt' +-- ParentVariableRoot/include2\.cmake: '[^']*/Tests/RunCMake/include/ParentVariableRoot/include1\.cmake' +-- ParentVariableRoot/include1\.cmake: '[^']*/Tests/RunCMake/include/CMakeLists\.txt' +-- CMakeLists\.txt: '' diff --git a/Tests/RunCMake/include/CMP0198-NEW-subdir-stdout.txt b/Tests/RunCMake/include/CMP0198-NEW-subdir-stdout.txt new file mode 100644 index 0000000000..f8bfb1666d --- /dev/null +++ b/Tests/RunCMake/include/CMP0198-NEW-subdir-stdout.txt @@ -0,0 +1,7 @@ +-- ParentVariableSubDir/CMakeLists\.txt: '' +-- ParentVariableSubDir/include1\.cmake: '[^']*/Tests/RunCMake/include/ParentVariableSubDir/CMakeLists\.txt' +-- ParentVariableSubDir/Inc/include2.cmake: '[^']*/Tests/RunCMake/include/ParentVariableSubDir/include1\.cmake' +-- ParentVariableSubDir/include1\.cmake: '[^']*/Tests/RunCMake/include/ParentVariableSubDir/CMakeLists\.txt' +-- ParentVariableSubDir/Inc/CMakeLists\.txt: '[^']*/Tests/RunCMake/include/ParentVariableSubDir/include1\.cmake' +-- ParentVariableSubDir/include1\.cmake: '[^']*/Tests/RunCMake/include/ParentVariableSubDir/CMakeLists\.txt' +-- ParentVariableSubDir/CMakeLists\.txt: '' diff --git a/Tests/RunCMake/include/CMP0198-NEW-subdir.cmake b/Tests/RunCMake/include/CMP0198-NEW-subdir.cmake new file mode 100644 index 0000000000..4c5deff773 --- /dev/null +++ b/Tests/RunCMake/include/CMP0198-NEW-subdir.cmake @@ -0,0 +1,2 @@ +cmake_policy(SET CMP0198 NEW) +add_subdirectory(ParentVariableSubDir) diff --git a/Tests/RunCMake/include/CMP0198-OLD-root-stdout.txt b/Tests/RunCMake/include/CMP0198-OLD-root-stdout.txt new file mode 100644 index 0000000000..8f8ba92f40 --- /dev/null +++ b/Tests/RunCMake/include/CMP0198-OLD-root-stdout.txt @@ -0,0 +1,6 @@ +-- CMakeLists\.txt: '[^']*/Tests/RunCMake/include/CMakeLists\.txt'.* +-- CMakeLists\.txt: '[^']*/Tests/RunCMake/include/CMakeLists\.txt' +-- ParentVariableRoot/include1\.cmake: '[^']*/Tests/RunCMake/include/CMakeLists\.txt' +-- ParentVariableRoot/include2\.cmake: '[^']*/Tests/RunCMake/include/ParentVariableRoot/include1\.cmake' +-- ParentVariableRoot/include1\.cmake: '[^']*/Tests/RunCMake/include/CMakeLists\.txt' +-- CMakeLists\.txt: '[^']*/Tests/RunCMake/include/CMakeLists\.txt' diff --git a/Tests/RunCMake/include/CMP0198-OLD-subdir-stdout.txt b/Tests/RunCMake/include/CMP0198-OLD-subdir-stdout.txt new file mode 100644 index 0000000000..2f785eef04 --- /dev/null +++ b/Tests/RunCMake/include/CMP0198-OLD-subdir-stdout.txt @@ -0,0 +1,7 @@ +-- ParentVariableSubDir/CMakeLists\.txt: '[^']*/Tests/RunCMake/include/ParentVariableSubDir/CMakeLists\.txt' +-- ParentVariableSubDir/include1\.cmake: '[^']*/Tests/RunCMake/include/ParentVariableSubDir/CMakeLists\.txt' +-- ParentVariableSubDir/Inc/include2.cmake: '[^']*/Tests/RunCMake/include/ParentVariableSubDir/include1\.cmake' +-- ParentVariableSubDir/include1\.cmake: '[^']*/Tests/RunCMake/include/ParentVariableSubDir/CMakeLists\.txt' +-- ParentVariableSubDir/Inc/CMakeLists\.txt: '[^']*/Tests/RunCMake/include/ParentVariableSubDir/include1\.cmake' +-- ParentVariableSubDir/include1\.cmake: '[^']*/Tests/RunCMake/include/ParentVariableSubDir/CMakeLists\.txt' +-- ParentVariableSubDir/CMakeLists\.txt: '[^']*/Tests/RunCMake/include/ParentVariableSubDir/CMakeLists\.txt' diff --git a/Tests/RunCMake/include/CMP0198-OLD-subdir.cmake b/Tests/RunCMake/include/CMP0198-OLD-subdir.cmake new file mode 100644 index 0000000000..52a211e58b --- /dev/null +++ b/Tests/RunCMake/include/CMP0198-OLD-subdir.cmake @@ -0,0 +1,2 @@ +cmake_policy(SET CMP0198 OLD) +add_subdirectory(ParentVariableSubDir) diff --git a/Tests/RunCMake/include/CMP0198-WARN-root-stdout.txt b/Tests/RunCMake/include/CMP0198-WARN-root-stdout.txt new file mode 100644 index 0000000000..8f8ba92f40 --- /dev/null +++ b/Tests/RunCMake/include/CMP0198-WARN-root-stdout.txt @@ -0,0 +1,6 @@ +-- CMakeLists\.txt: '[^']*/Tests/RunCMake/include/CMakeLists\.txt'.* +-- CMakeLists\.txt: '[^']*/Tests/RunCMake/include/CMakeLists\.txt' +-- ParentVariableRoot/include1\.cmake: '[^']*/Tests/RunCMake/include/CMakeLists\.txt' +-- ParentVariableRoot/include2\.cmake: '[^']*/Tests/RunCMake/include/ParentVariableRoot/include1\.cmake' +-- ParentVariableRoot/include1\.cmake: '[^']*/Tests/RunCMake/include/CMakeLists\.txt' +-- CMakeLists\.txt: '[^']*/Tests/RunCMake/include/CMakeLists\.txt' diff --git a/Tests/RunCMake/include/CMP0198-WARN-subdir-stdout.txt b/Tests/RunCMake/include/CMP0198-WARN-subdir-stdout.txt new file mode 100644 index 0000000000..2f785eef04 --- /dev/null +++ b/Tests/RunCMake/include/CMP0198-WARN-subdir-stdout.txt @@ -0,0 +1,7 @@ +-- ParentVariableSubDir/CMakeLists\.txt: '[^']*/Tests/RunCMake/include/ParentVariableSubDir/CMakeLists\.txt' +-- ParentVariableSubDir/include1\.cmake: '[^']*/Tests/RunCMake/include/ParentVariableSubDir/CMakeLists\.txt' +-- ParentVariableSubDir/Inc/include2.cmake: '[^']*/Tests/RunCMake/include/ParentVariableSubDir/include1\.cmake' +-- ParentVariableSubDir/include1\.cmake: '[^']*/Tests/RunCMake/include/ParentVariableSubDir/CMakeLists\.txt' +-- ParentVariableSubDir/Inc/CMakeLists\.txt: '[^']*/Tests/RunCMake/include/ParentVariableSubDir/include1\.cmake' +-- ParentVariableSubDir/include1\.cmake: '[^']*/Tests/RunCMake/include/ParentVariableSubDir/CMakeLists\.txt' +-- ParentVariableSubDir/CMakeLists\.txt: '[^']*/Tests/RunCMake/include/ParentVariableSubDir/CMakeLists\.txt' diff --git a/Tests/RunCMake/include/CMP0198-WARN-subdir.cmake b/Tests/RunCMake/include/CMP0198-WARN-subdir.cmake new file mode 100644 index 0000000000..3b8ef0c9ec --- /dev/null +++ b/Tests/RunCMake/include/CMP0198-WARN-subdir.cmake @@ -0,0 +1,3 @@ +# Test CMP0198 WARN behavior with subdirectory: should behave like OLD (no warning issued) +# Do not set CMP0198 policy explicitly +add_subdirectory(ParentVariableSubDir) diff --git a/Tests/RunCMake/include/CMP0198-implicit-NEW-root-stdout.txt b/Tests/RunCMake/include/CMP0198-implicit-NEW-root-stdout.txt new file mode 100644 index 0000000000..417fb3014f --- /dev/null +++ b/Tests/RunCMake/include/CMP0198-implicit-NEW-root-stdout.txt @@ -0,0 +1,6 @@ +-- CMakeLists\.txt: '[^']*/Tests/RunCMake/include/CMakeLists\.txt'.* +-- CMakeLists\.txt: '' +-- ParentVariableRoot/include1\.cmake: '[^']*/Tests/RunCMake/include/CMakeLists\.txt' +-- ParentVariableRoot/include2\.cmake: '[^']*/Tests/RunCMake/include/ParentVariableRoot/include1\.cmake' +-- ParentVariableRoot/include1\.cmake: '[^']*/Tests/RunCMake/include/CMakeLists\.txt' +-- CMakeLists\.txt: '' diff --git a/Tests/RunCMake/include/CMakeLists.txt b/Tests/RunCMake/include/CMakeLists.txt index 3dd7323fb6..b03a9d9f3b 100644 --- a/Tests/RunCMake/include/CMakeLists.txt +++ b/Tests/RunCMake/include/CMakeLists.txt @@ -1,9 +1,29 @@ -cmake_minimum_required(VERSION 3.10) +set(root_test OFF) +if(RunCMake_TEST STREQUAL "ParentVariableRoot" OR + RunCMake_TEST STREQUAL "CMP0198-NEW-root" OR + RunCMake_TEST STREQUAL "CMP0198-implicit-NEW-root" OR + RunCMake_TEST STREQUAL "CMP0198-OLD-root" OR + RunCMake_TEST STREQUAL "CMP0198-WARN-root") + set(root_test ON) +endif() + +if(root_test) + message(STATUS "CMakeLists.txt: '${CMAKE_PARENT_LIST_FILE}'") +endif() + +if(RunCMake_TEST STREQUAL "CMP0198-implicit-NEW-root") + cmake_minimum_required(VERSION 4.1...4.2) +else() + cmake_minimum_required(VERSION 3.10) +endif() + project(${RunCMake_TEST} NONE) -if(RunCMake_TEST STREQUAL "ParentVariableRoot") + +if(root_test) message(STATUS "CMakeLists.txt: '${CMAKE_PARENT_LIST_FILE}'") include(ParentVariableRoot/include1.cmake) message(STATUS "CMakeLists.txt: '${CMAKE_PARENT_LIST_FILE}'") return() endif() + include(${RunCMake_TEST}.cmake) diff --git a/Tests/RunCMake/include/ParentVariableRoot-stdout.txt b/Tests/RunCMake/include/ParentVariableRoot-stdout.txt index 0460905871..8f8ba92f40 100644 --- a/Tests/RunCMake/include/ParentVariableRoot-stdout.txt +++ b/Tests/RunCMake/include/ParentVariableRoot-stdout.txt @@ -1,3 +1,4 @@ +-- CMakeLists\.txt: '[^']*/Tests/RunCMake/include/CMakeLists\.txt'.* -- CMakeLists\.txt: '[^']*/Tests/RunCMake/include/CMakeLists\.txt' -- ParentVariableRoot/include1\.cmake: '[^']*/Tests/RunCMake/include/CMakeLists\.txt' -- ParentVariableRoot/include2\.cmake: '[^']*/Tests/RunCMake/include/ParentVariableRoot/include1\.cmake' diff --git a/Tests/RunCMake/include/RunCMakeTest.cmake b/Tests/RunCMake/include/RunCMakeTest.cmake index 1b0c808e06..cd5eedbe56 100644 --- a/Tests/RunCMake/include/RunCMakeTest.cmake +++ b/Tests/RunCMake/include/RunCMakeTest.cmake @@ -43,3 +43,21 @@ run_cmake(CMP0196-OLD) run_cmake(CMP0196-WARN) run_cmake(CMP0196-NEW-name) run_cmake(CMP0196-NEW-path) + +# Warn should silently behave like OLD +# Test old with implicit and explicit policy setting +run_cmake(CMP0198-OLD-root) +run_cmake(CMP0198-WARN-root) +set(RunCMake_TEST_OPTIONS "-DCMAKE_POLICY_DEFAULT_CMP0198=OLD") +run_cmake(CMP0198-OLD-root) +set(RunCMake_TEST_OPTIONS "-DCMAKE_POLICY_DEFAULT_CMP0198=NEW") +run_cmake(CMP0198-NEW-root) +unset(RunCMake_TEST_OPTIONS) +run_cmake(CMP0198-implicit-NEW-root) +run_cmake(CMP0198-OLD-subdir) +run_cmake(CMP0198-WARN-subdir) +set(RunCMake_TEST_OPTIONS "-DCMAKE_POLICY_DEFAULT_CMP0198=OLD") +run_cmake(CMP0198-OLD-subdir) +set(RunCMake_TEST_OPTIONS "-DCMAKE_POLICY_DEFAULT_CMP0198=NEW") +run_cmake(CMP0198-NEW-subdir) +unset(RunCMake_TEST_OPTIONS)