From d3acd22380663bd4061abf07384d507c589d3286 Mon Sep 17 00:00:00 2001
From: Juan Ramos <cmake@jpr.mozmail.com>
Date: Sun, 6 Nov 2022 15:52:42 -0700
Subject: USE_FOLDERS: Treat as on by default

Add a policy to treat the `USE_FOLDERS` global property as ON by default
if it is not set.

Fixes: #21695
---
 Help/manual/cmake-policies.7.rst                   |  7 +++++
 Help/policy/CMP0143.rst                            | 30 ++++++++++++++++++++++
 Help/prop_gbl/USE_FOLDERS.rst                      | 15 ++++++++---
 Help/release/dev/use-folder-on-by-default.rst      |  5 ++++
 Source/cmGlobalGenerator.cxx                       | 13 +++++-----
 Source/cmPolicies.h                                |  5 +++-
 Tests/RunCMake/VSSolution/CMP0143-NEW-check.cmake  |  6 +++++
 Tests/RunCMake/VSSolution/CMP0143-NEW.cmake        |  1 +
 Tests/RunCMake/VSSolution/CMP0143-OLD-check.cmake  |  6 +++++
 Tests/RunCMake/VSSolution/CMP0143-OLD.cmake        |  1 +
 Tests/RunCMake/VSSolution/CMP0143-WARN-check.cmake |  6 +++++
 Tests/RunCMake/VSSolution/CMP0143-WARN.cmake       |  1 +
 Tests/RunCMake/VSSolution/RunCMakeTest.cmake       |  3 +++
 13 files changed, 88 insertions(+), 11 deletions(-)
 create mode 100644 Help/policy/CMP0143.rst
 create mode 100644 Help/release/dev/use-folder-on-by-default.rst
 create mode 100644 Tests/RunCMake/VSSolution/CMP0143-NEW-check.cmake
 create mode 100644 Tests/RunCMake/VSSolution/CMP0143-NEW.cmake
 create mode 100644 Tests/RunCMake/VSSolution/CMP0143-OLD-check.cmake
 create mode 100644 Tests/RunCMake/VSSolution/CMP0143-OLD.cmake
 create mode 100644 Tests/RunCMake/VSSolution/CMP0143-WARN-check.cmake
 create mode 100644 Tests/RunCMake/VSSolution/CMP0143-WARN.cmake

diff --git a/Help/manual/cmake-policies.7.rst b/Help/manual/cmake-policies.7.rst
index d6a30ff..22e9eb2 100644
--- a/Help/manual/cmake-policies.7.rst
+++ b/Help/manual/cmake-policies.7.rst
@@ -51,6 +51,13 @@ The :variable:`CMAKE_MINIMUM_REQUIRED_VERSION` variable may also be used
 to determine whether to report an error on use of deprecated macros or
 functions.
 
+Policies Introduced by CMake 3.26
+=================================
+
+.. toctree::
+   :maxdepth: 1
+
+   CMP0143: USE_FOLDERS global property is treated as ON by default. </policy/CMP0143>
 
 Policies Introduced by CMake 3.25
 =================================
diff --git a/Help/policy/CMP0143.rst b/Help/policy/CMP0143.rst
new file mode 100644
index 0000000..7a7aee7
--- /dev/null
+++ b/Help/policy/CMP0143.rst
@@ -0,0 +1,30 @@
+CMP0143
+-------
+
+.. versionadded:: 3.26
+
+:prop_gbl:`USE_FOLDERS` global property is treated as ``ON`` by default.
+
+When using CMake 3.25 and below, :prop_gbl:`USE_FOLDERS` is treated
+as ``OFF`` by default unless projects enable the feature.  For example:
+
+.. code-block:: cmake
+
+  cmake_minimum_required(VERSION 3.25)
+  project(foobar LANGUAGES CXX)
+  set_property(GLOBAL PROPERTY USE_FOLDERS ON)
+
+CMake 3.26 and later prefer to enable the feature by default.
+
+This policy provides compatibility with projects that have not been updated
+to expect enabling of folders.  Enabling folders causes projects to appear
+differently in IDEs.
+
+This policy was introduced in CMake version 3.26.  Use the
+:command:`cmake_policy` command to set it to ``OLD`` or ``NEW`` explicitly.
+Unlike many policies, CMake version |release| does *not* warn
+when this policy is not set and simply uses ``OLD`` behavior.
+The policy setting must be in scope at the end of the top-level
+``CMakeLists.txt`` file of the project and has global effect.
+
+.. include:: DEPRECATED.txt
diff --git a/Help/prop_gbl/USE_FOLDERS.rst b/Help/prop_gbl/USE_FOLDERS.rst
index 5919723..965b5d6 100644
--- a/Help/prop_gbl/USE_FOLDERS.rst
+++ b/Help/prop_gbl/USE_FOLDERS.rst
@@ -4,7 +4,16 @@ USE_FOLDERS
 Use the :prop_tgt:`FOLDER` target property to organize targets into
 folders.
 
-If not set, CMake treats this property as ``OFF`` by default.  CMake
-generators that are capable of organizing into a hierarchy of folders
+.. versionchanged:: 3.26
+
+  CMake treats this property as ``ON`` by default.
+  See policy :policy:`CMP0143`.
+
+CMake generators that are capable of organizing into a hierarchy of folders
 use the values of the :prop_tgt:`FOLDER` target property to name those
-folders. See also the documentation for the :prop_tgt:`FOLDER` target property.
+folders. (i.e.: Visual Studio / XCode)
+
+IDE's can also take advantage of this property to organize CMake targets.
+Regardless of generator support.
+
+See also the documentation for the :prop_tgt:`FOLDER` target property.
diff --git a/Help/release/dev/use-folder-on-by-default.rst b/Help/release/dev/use-folder-on-by-default.rst
new file mode 100644
index 0000000..4e91c2e
--- /dev/null
+++ b/Help/release/dev/use-folder-on-by-default.rst
@@ -0,0 +1,5 @@
+use-folder-on-by-default
+------------------------
+
+* Global property :prop_gbl:`USE_FOLDERS` is treated as ``ON`` by default.
+  See policy :policy:`CMP0143`.
diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx
index c2bf888..a539d33 100644
--- a/Source/cmGlobalGenerator.cxx
+++ b/Source/cmGlobalGenerator.cxx
@@ -2943,19 +2943,18 @@ std::string cmGlobalGenerator::GetPredefinedTargetsFolder() const
 
 bool cmGlobalGenerator::UseFolderProperty() const
 {
-  cmValue prop =
+  const cmValue prop =
     this->GetCMakeInstance()->GetState()->GetGlobalProperty("USE_FOLDERS");
 
-  // If this property is defined, let the setter turn this on or off...
-  //
+  // If this property is defined, let the setter turn this on or off.
   if (prop) {
     return cmIsOn(*prop);
   }
 
-  // By default, this feature is OFF, since it is not supported in the
-  // Visual Studio Express editions until VS11:
-  //
-  return false;
+  // If CMP0143 is NEW `treat` "USE_FOLDERS" as ON. Otherwise `treat` it as OFF
+  assert(!this->Makefiles.empty());
+  return (this->Makefiles[0]->GetPolicyStatus(cmPolicies::CMP0143) ==
+          cmPolicies::NEW);
 }
 
 void cmGlobalGenerator::CreateGlobalTarget(GlobalTargetInfo const& gti,
diff --git a/Source/cmPolicies.h b/Source/cmPolicies.h
index 4643868..fa24f57 100644
--- a/Source/cmPolicies.h
+++ b/Source/cmPolicies.h
@@ -431,7 +431,10 @@ class cmMakefile;
   SELECT(POLICY, CMP0142,                                                     \
          "The Xcode generator does not append per-config suffixes to "        \
          "library search paths.",                                             \
-         3, 25, 0, cmPolicies::WARN)
+         3, 25, 0, cmPolicies::WARN)                                          \
+  SELECT(POLICY, CMP0143,                                                     \
+         "Global property USE_FOLDERS treated as ON by default", 3, 26, 0,    \
+         cmPolicies::WARN)
 
 #define CM_SELECT_ID(F, A1, A2, A3, A4, A5, A6) F(A1)
 #define CM_FOR_EACH_POLICY_ID(POLICY)                                         \
diff --git a/Tests/RunCMake/VSSolution/CMP0143-NEW-check.cmake b/Tests/RunCMake/VSSolution/CMP0143-NEW-check.cmake
new file mode 100644
index 0000000..6dd042b
--- /dev/null
+++ b/Tests/RunCMake/VSSolution/CMP0143-NEW-check.cmake
@@ -0,0 +1,6 @@
+getProjectNames(projects)
+
+list(FIND projects "CMakePredefinedTargets" found)
+  if(found EQUAL "-1")
+    error("CMakePredefinedTargets should be defined when CMP0143 is NEW!")
+endif()
diff --git a/Tests/RunCMake/VSSolution/CMP0143-NEW.cmake b/Tests/RunCMake/VSSolution/CMP0143-NEW.cmake
new file mode 100644
index 0000000..dd67b16
--- /dev/null
+++ b/Tests/RunCMake/VSSolution/CMP0143-NEW.cmake
@@ -0,0 +1 @@
+add_custom_target(TestStartup)
diff --git a/Tests/RunCMake/VSSolution/CMP0143-OLD-check.cmake b/Tests/RunCMake/VSSolution/CMP0143-OLD-check.cmake
new file mode 100644
index 0000000..2d9829c
--- /dev/null
+++ b/Tests/RunCMake/VSSolution/CMP0143-OLD-check.cmake
@@ -0,0 +1,6 @@
+getProjectNames(projects)
+
+list(FIND projects "CMakePredefinedTargets" found)
+  if(NOT (found EQUAL "-1"))
+    error("CMakePredefinedTargets should not be defined when CMP0143 is OLD!")
+endif()
diff --git a/Tests/RunCMake/VSSolution/CMP0143-OLD.cmake b/Tests/RunCMake/VSSolution/CMP0143-OLD.cmake
new file mode 100644
index 0000000..dd67b16
--- /dev/null
+++ b/Tests/RunCMake/VSSolution/CMP0143-OLD.cmake
@@ -0,0 +1 @@
+add_custom_target(TestStartup)
diff --git a/Tests/RunCMake/VSSolution/CMP0143-WARN-check.cmake b/Tests/RunCMake/VSSolution/CMP0143-WARN-check.cmake
new file mode 100644
index 0000000..2d9829c
--- /dev/null
+++ b/Tests/RunCMake/VSSolution/CMP0143-WARN-check.cmake
@@ -0,0 +1,6 @@
+getProjectNames(projects)
+
+list(FIND projects "CMakePredefinedTargets" found)
+  if(NOT (found EQUAL "-1"))
+    error("CMakePredefinedTargets should not be defined when CMP0143 is OLD!")
+endif()
diff --git a/Tests/RunCMake/VSSolution/CMP0143-WARN.cmake b/Tests/RunCMake/VSSolution/CMP0143-WARN.cmake
new file mode 100644
index 0000000..dd67b16
--- /dev/null
+++ b/Tests/RunCMake/VSSolution/CMP0143-WARN.cmake
@@ -0,0 +1 @@
+add_custom_target(TestStartup)
diff --git a/Tests/RunCMake/VSSolution/RunCMakeTest.cmake b/Tests/RunCMake/VSSolution/RunCMakeTest.cmake
index c25833d..134821d 100644
--- a/Tests/RunCMake/VSSolution/RunCMakeTest.cmake
+++ b/Tests/RunCMake/VSSolution/RunCMakeTest.cmake
@@ -15,4 +15,7 @@ run_cmake(AddPackageToDefault)
 
 if(NOT NO_USE_FOLDERS)
   run_cmake(StartupProjectUseFolders)
+  run_cmake(CMP0143-WARN)
+  run_cmake_with_options(CMP0143-OLD "-DCMAKE_POLICY_DEFAULT_CMP0143=OLD")
+  run_cmake_with_options(CMP0143-NEW "-DCMAKE_POLICY_DEFAULT_CMP0143=NEW")
 endif()
-- 
cgit v0.12