Add generator-agnostic DEBUGGER_WORKING_DIRECTORY target property

Generalize the `VS_DEBUGGER_WORKING_DIRECTORY` property.

Issue: #16478
diff --git a/Auxiliary/vim/syntax/cmake.vim b/Auxiliary/vim/syntax/cmake.vim
index d09bbfc..2c0d74f 100644
--- a/Auxiliary/vim/syntax/cmake.vim
+++ b/Auxiliary/vim/syntax/cmake.vim
@@ -155,6 +155,7 @@
             \ C_STANDARD_REQUIRED
             \ DEBUG_CONFIGURATIONS
             \ DEBUG_POSTFIX
+            \ DEBUGGER_WORKING_DIRECTORY
             \ DEFINE_SYMBOL
             \ DEFINITIONS
             \ DEPENDS
@@ -1140,6 +1141,7 @@
             \ CMAKE_C_VISIBILITY_PRESET
             \ CMAKE_DEBUG_POSTFIX
             \ CMAKE_DEBUG_TARGET_PROPERTIES
+            \ CMAKE_DEBUGGER_WORKING_DIRECTORY
             \ CMAKE_DEFAULT_BUILD_TYPE
             \ CMAKE_DEFAULT_CONFIGS
             \ CMAKE_DEPENDS_IN_PROJECT_ONLY
diff --git a/Help/manual/cmake-properties.7.rst b/Help/manual/cmake-properties.7.rst
index 4d20d98..c49aa89 100644
--- a/Help/manual/cmake-properties.7.rst
+++ b/Help/manual/cmake-properties.7.rst
@@ -204,6 +204,7 @@
    /prop_tgt/CXX_STANDARD
    /prop_tgt/CXX_STANDARD_REQUIRED
    /prop_tgt/DEBUG_POSTFIX
+   /prop_tgt/DEBUGGER_WORKING_DIRECTORY
    /prop_tgt/DEFINE_SYMBOL
    /prop_tgt/DEPLOYMENT_ADDITIONAL_FILES
    /prop_tgt/DEPLOYMENT_REMOTE_DIRECTORY
diff --git a/Help/manual/cmake-variables.7.rst b/Help/manual/cmake-variables.7.rst
index 24ff9bc..9b4f13c 100644
--- a/Help/manual/cmake-variables.7.rst
+++ b/Help/manual/cmake-variables.7.rst
@@ -434,6 +434,7 @@
    /variable/CMAKE_CXX_MODULE_STD
    /variable/CMAKE_CXX_SCAN_FOR_MODULES
    /variable/CMAKE_DEBUG_POSTFIX
+   /variable/CMAKE_DEBUGGER_WORKING_DIRECTORY
    /variable/CMAKE_DEFAULT_BUILD_TYPE
    /variable/CMAKE_DEFAULT_CONFIGS
    /variable/CMAKE_DEPENDS_USE_COMPILER
diff --git a/Help/prop_tgt/DEBUGGER_WORKING_DIRECTORY.rst b/Help/prop_tgt/DEBUGGER_WORKING_DIRECTORY.rst
new file mode 100644
index 0000000..135e304
--- /dev/null
+++ b/Help/prop_tgt/DEBUGGER_WORKING_DIRECTORY.rst
@@ -0,0 +1,11 @@
+DEBUGGER_WORKING_DIRECTORY
+--------------------------
+
+.. versionadded:: 3.32
+
+  Sets the local debugger working directory for C++ targets.
+  The property value may use
+  :manual:`generator expressions <cmake-generator-expressions(7)>`.
+  This property is initialized by the value of the variable
+  :variable:`CMAKE_DEBUGGER_WORKING_DIRECTORY` if it is set when a target is
+  created.
diff --git a/Help/release/dev/debugger-working-directory.rst b/Help/release/dev/debugger-working-directory.rst
new file mode 100644
index 0000000..314a021
--- /dev/null
+++ b/Help/release/dev/debugger-working-directory.rst
@@ -0,0 +1,9 @@
+debugger-working-directory
+--------------------------
+
+* The :variable:`CMAKE_DEBUGGER_WORKING_DIRECTORY` was added to
+  initialize the corresponding target property.
+
+* The :prop_tgt:`DEBUGGER_WORKING_DIRECTORY` target property was added
+  to tell generators what debugger working directory should be set for
+  the target.
diff --git a/Help/variable/CMAKE_DEBUGGER_WORKING_DIRECTORY.rst b/Help/variable/CMAKE_DEBUGGER_WORKING_DIRECTORY.rst
new file mode 100644
index 0000000..bc1e564
--- /dev/null
+++ b/Help/variable/CMAKE_DEBUGGER_WORKING_DIRECTORY.rst
@@ -0,0 +1,8 @@
+CMAKE_DEBUGGER_WORKING_DIRECTORY
+--------------------------------
+
+.. versionadded:: 3.32
+
+This variable is used to initialize the :prop_tgt:`DEBUGGER_WORKING_DIRECTORY`
+property on each target as it is created.  See that target property
+for additional information.
diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx
index 1d1d932..f2ff927 100644
--- a/Source/cmGlobalGenerator.cxx
+++ b/Source/cmGlobalGenerator.cxx
@@ -3499,6 +3499,12 @@
   // configuration.
 }
 
+cmValue cmGlobalGenerator::GetDebuggerWorkingDirectory(
+  cmGeneratorTarget* gt) const
+{
+  return gt->GetProperty("DEBUGGER_WORKING_DIRECTORY");
+}
+
 cmGlobalGenerator::TargetDependSet const&
 cmGlobalGenerator::GetTargetDirectDepends(cmGeneratorTarget const* target)
 {
diff --git a/Source/cmGlobalGenerator.h b/Source/cmGlobalGenerator.h
index 6b97a50..7f07c1c 100644
--- a/Source/cmGlobalGenerator.h
+++ b/Source/cmGlobalGenerator.h
@@ -513,6 +513,8 @@
   // Default config to use for cmake --build
   virtual std::string GetDefaultBuildConfig() const { return "Debug"; }
 
+  virtual cmValue GetDebuggerWorkingDirectory(cmGeneratorTarget* gt) const;
+
   // Class to track a set of dependencies.
   using TargetDependSet = cmTargetDependSet;
 
diff --git a/Source/cmGlobalVisualStudioGenerator.cxx b/Source/cmGlobalVisualStudioGenerator.cxx
index 5ff9506..784d6cd 100644
--- a/Source/cmGlobalVisualStudioGenerator.cxx
+++ b/Source/cmGlobalVisualStudioGenerator.cxx
@@ -93,6 +93,16 @@
   return true;
 }
 
+cmValue cmGlobalVisualStudioGenerator::GetDebuggerWorkingDirectory(
+  cmGeneratorTarget* gt) const
+{
+  if (cmValue ret = gt->GetProperty("VS_DEBUGGER_WORKING_DIRECTORY")) {
+    return ret;
+  } else {
+    return cmGlobalGenerator::GetDebuggerWorkingDirectory(gt);
+  }
+}
+
 std::string const& cmGlobalVisualStudioGenerator::GetPlatformName() const
 {
   if (!this->GeneratorPlatform.empty()) {
diff --git a/Source/cmGlobalVisualStudioGenerator.h b/Source/cmGlobalVisualStudioGenerator.h
index a53b3bd..96b8d0c 100644
--- a/Source/cmGlobalVisualStudioGenerator.h
+++ b/Source/cmGlobalVisualStudioGenerator.h
@@ -78,6 +78,8 @@
    */
   virtual std::string GetUserMacrosRegKeyBase();
 
+  cmValue GetDebuggerWorkingDirectory(cmGeneratorTarget* gt) const override;
+
   enum MacroName
   {
     MacroReload,
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index 30eef70..5267c78 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -373,6 +373,8 @@
 
 TargetProperty const StaticTargetProperties[] = {
   /* clang-format off */
+  // -- Debugger Properties
+  { "DEBUGGER_WORKING_DIRECTORY"_s, IC::ExecutableTarget },
   // Compilation properties
   { "COMPILE_WARNING_AS_ERROR"_s, IC::CanCompileSources },
   { "INTERPROCEDURAL_OPTIMIZATION"_s, IC::CanCompileSources },
diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx
index fce248c..0147cef 100644
--- a/Source/cmVisualStudio10TargetGenerator.cxx
+++ b/Source/cmVisualStudio10TargetGenerator.cxx
@@ -3167,8 +3167,9 @@
     }
 
     if (ttype <= cmStateEnums::UTILITY) {
-      if (cmValue workingDir = this->GeneratorTarget->GetProperty(
-            "VS_DEBUGGER_WORKING_DIRECTORY")) {
+      if (cmValue workingDir =
+            this->GlobalGenerator->GetDebuggerWorkingDirectory(
+              this->GeneratorTarget)) {
         std::string genWorkingDir = cmGeneratorExpression::Evaluate(
           *workingDir, this->LocalGenerator, config);
         e1.WritePlatformConfigTag("LocalDebuggerWorkingDirectory", cond,