From 627b2eba6c2e8790ba7091f5123e114e9363726d Mon Sep 17 00:00:00 2001
From: Brad King <brad.king@kitware.com>
Date: Fri, 22 Apr 2022 09:21:06 -0400
Subject: Help: Make TARGET_BUNDLE[_CONTENT]_DIR examples more precise

The `TARGET_BUNDLE_DIR` and `TARGET_BUNDLE_CONTENT_DIR` generator
expressions produce absolute paths.  Show them in the examples.

Suggested-by: Ben Leadbetter <ben.leadbetter@native-instruments.com>
---
 Help/manual/cmake-generator-expressions.7.rst | 14 ++++++++------
 1 file changed, 8 insertions(+), 6 deletions(-)

diff --git a/Help/manual/cmake-generator-expressions.7.rst b/Help/manual/cmake-generator-expressions.7.rst
index 3389968..c83eb87 100644
--- a/Help/manual/cmake-generator-expressions.7.rst
+++ b/Help/manual/cmake-generator-expressions.7.rst
@@ -1019,8 +1019,9 @@ which is just the string ``tgt``.
 
   .. versionadded:: 3.9
 
-  Full path to the bundle directory (``my.app``, ``my.framework``, or
-  ``my.bundle``) where ``tgt`` is the name of a target.
+  Full path to the bundle directory (``/path/to/my.app``,
+  ``/path/to/my.framework``, or ``/path/to/my.bundle``),
+  where ``tgt`` is the name of a target.
 
   Note that ``tgt`` is not added as a dependency of the target this
   expression is evaluated on (see policy :policy:`CMP0112`).
@@ -1030,10 +1031,11 @@ which is just the string ``tgt``.
   .. versionadded:: 3.9
 
   Full path to the bundle content directory where ``tgt`` is the name of a
-  target. For the macOS SDK it leads to ``my.app/Contents``, ``my.framework``,
-  or ``my.bundle/Contents``. For all other SDKs (e.g. iOS) it leads to
-  ``my.app``, ``my.framework``, or ``my.bundle`` due to the flat bundle
-  structure.
+  target.  For the macOS SDK it leads to ``/path/to/my.app/Contents``,
+  ``/path/to/my.framework``, or ``/path/to/my.bundle/Contents``.
+  For all other SDKs (e.g. iOS) it leads to ``/path/to/my.app``,
+  ``/path/to/my.framework``, or ``/path/to/my.bundle`` due to the flat
+  bundle structure.
 
   Note that ``tgt`` is not added as a dependency of the target this
   expression is evaluated on (see policy :policy:`CMP0112`).
-- 
cgit v0.12


From 997af2e1a6b8f2d644dfe1734653398633cafe52 Mon Sep 17 00:00:00 2001
From: Ben Leadbetter <ben.leadbetter@native-instruments.com>
Date: Thu, 14 Apr 2022 15:44:49 +0200
Subject: Genex: Add TARGET_BUNDLE_DIR_NAME

Evaluate to the name of the bundle directory for a given bundle target.

Fixes: #23409
---
 Auxiliary/vim/syntax/cmake.vim                     |  1 +
 Help/manual/cmake-generator-expressions.7.rst      | 10 ++++++
 Help/policy/CMP0112.rst                            |  1 +
 Help/release/dev/target-bundle-dir-name-genex.rst  |  6 ++++
 Source/cmGeneratorExpressionNode.cxx               | 40 +++++++++++++++++++++-
 ...mportedTarget-TARGET_BUNDLE_DIR_NAME-result.txt |  1 +
 ...mportedTarget-TARGET_BUNDLE_DIR_NAME-stderr.txt |  8 +++++
 .../ImportedTarget-TARGET_BUNDLE_DIR_NAME.cmake    |  2 ++
 ...onValidTarget-TARGET_BUNDLE_DIR_NAME-result.txt |  1 +
 ...onValidTarget-TARGET_BUNDLE_DIR_NAME-stderr.txt |  8 +++++
 .../NonValidTarget-TARGET_BUNDLE_DIR_NAME.cmake    |  9 +++++
 .../RunCMake/GenEx-TARGET_FILE/RunCMakeTest.cmake  |  2 ++
 12 files changed, 88 insertions(+), 1 deletion(-)
 create mode 100644 Help/release/dev/target-bundle-dir-name-genex.rst
 create mode 100644 Tests/RunCMake/GenEx-TARGET_FILE/ImportedTarget-TARGET_BUNDLE_DIR_NAME-result.txt
 create mode 100644 Tests/RunCMake/GenEx-TARGET_FILE/ImportedTarget-TARGET_BUNDLE_DIR_NAME-stderr.txt
 create mode 100644 Tests/RunCMake/GenEx-TARGET_FILE/ImportedTarget-TARGET_BUNDLE_DIR_NAME.cmake
 create mode 100644 Tests/RunCMake/GenEx-TARGET_FILE/NonValidTarget-TARGET_BUNDLE_DIR_NAME-result.txt
 create mode 100644 Tests/RunCMake/GenEx-TARGET_FILE/NonValidTarget-TARGET_BUNDLE_DIR_NAME-stderr.txt
 create mode 100644 Tests/RunCMake/GenEx-TARGET_FILE/NonValidTarget-TARGET_BUNDLE_DIR_NAME.cmake

diff --git a/Auxiliary/vim/syntax/cmake.vim b/Auxiliary/vim/syntax/cmake.vim
index 8773446..60be937 100644
--- a/Auxiliary/vim/syntax/cmake.vim
+++ b/Auxiliary/vim/syntax/cmake.vim
@@ -3780,6 +3780,7 @@ syn keyword cmakeGeneratorExpressions contained
             \ STREQUAL
             \ TARGET_BUNDLE_CONTENT_DIR
             \ TARGET_BUNDLE_DIR
+            \ TARGET_BUNDLE_DIR_NAME
             \ TARGET_EXISTS
             \ TARGET_FILE
             \ TARGET_FILE_BASE_NAME
diff --git a/Help/manual/cmake-generator-expressions.7.rst b/Help/manual/cmake-generator-expressions.7.rst
index c83eb87..1ef1ec8 100644
--- a/Help/manual/cmake-generator-expressions.7.rst
+++ b/Help/manual/cmake-generator-expressions.7.rst
@@ -1026,6 +1026,16 @@ which is just the string ``tgt``.
   Note that ``tgt`` is not added as a dependency of the target this
   expression is evaluated on (see policy :policy:`CMP0112`).
 
+.. genex:: $<TARGET_BUNDLE_DIR_NAME:tgt>
+
+  .. versionadded:: 3.24
+
+  Name of the bundle directory (``my.app``, ``my.framework``, or
+  ``my.bundle``), where ``tgt`` is the name of a target.
+
+  Note that ``tgt`` is not added as a dependency of the target this
+  expression is evaluated on (see policy :policy:`CMP0112`).
+
 .. genex:: $<TARGET_BUNDLE_CONTENT_DIR:tgt>
 
   .. versionadded:: 3.9
diff --git a/Help/policy/CMP0112.rst b/Help/policy/CMP0112.rst
index 5b00d07..25c3896 100644
--- a/Help/policy/CMP0112.rst
+++ b/Help/policy/CMP0112.rst
@@ -18,6 +18,7 @@ file name components no longer add a dependency on the evaluated target.
     - ``TARGET_PDB_FILE_NAME``
     - ``TARGET_PDB_FILE_DIR``
     - ``TARGET_BUNDLE_DIR``
+    - ``TARGET_BUNDLE_DIR_NAME``
     - ``TARGET_BUNDLE_CONTENT_DIR``
 
 
diff --git a/Help/release/dev/target-bundle-dir-name-genex.rst b/Help/release/dev/target-bundle-dir-name-genex.rst
new file mode 100644
index 0000000..0ae835a
--- /dev/null
+++ b/Help/release/dev/target-bundle-dir-name-genex.rst
@@ -0,0 +1,6 @@
+target-bundle-dir-name-genex
+----------------------------
+
+* Added the new :genex:`TARGET_BUNDLE_DIR_NAME` generator expression
+  which evaluates to the name of the bundle directory for a given bundle
+  target.
diff --git a/Source/cmGeneratorExpressionNode.cxx b/Source/cmGeneratorExpressionNode.cxx
index a9bc435..26ffd4b 100644
--- a/Source/cmGeneratorExpressionNode.cxx
+++ b/Source/cmGeneratorExpressionNode.cxx
@@ -2098,6 +2098,7 @@ class ArtifactPathTag;
 class ArtifactPdbTag;
 class ArtifactSonameTag;
 class ArtifactBundleDirTag;
+class ArtifactBundleDirNameTag;
 class ArtifactBundleContentDirTag;
 
 template <typename ArtifactT, typename ComponentT>
@@ -2158,6 +2159,12 @@ struct TargetFilesystemArtifactDependency<ArtifactBundleDirTag,
 {
 };
 template <>
+struct TargetFilesystemArtifactDependency<ArtifactBundleDirNameTag,
+                                          ArtifactPathTag>
+  : TargetFilesystemArtifactDependencyCMP0112
+{
+};
+template <>
 struct TargetFilesystemArtifactDependency<ArtifactBundleContentDirTag,
                                           ArtifactPathTag>
   : TargetFilesystemArtifactDependencyCMP0112
@@ -2285,6 +2292,31 @@ struct TargetFilesystemArtifactResultCreator<ArtifactBundleDirTag>
 };
 
 template <>
+struct TargetFilesystemArtifactResultCreator<ArtifactBundleDirNameTag>
+{
+  static std::string Create(cmGeneratorTarget* target,
+                            cmGeneratorExpressionContext* context,
+                            const GeneratorExpressionContent* content)
+  {
+    if (target->IsImported()) {
+      ::reportError(
+        context, content->GetOriginalExpression(),
+        "TARGET_BUNDLE_DIR_NAME not allowed for IMPORTED targets.");
+      return std::string();
+    }
+    if (!target->IsBundleOnApple()) {
+      ::reportError(
+        context, content->GetOriginalExpression(),
+        "TARGET_BUNDLE_DIR_NAME is allowed only for Bundle targets.");
+      return std::string();
+    }
+
+    return target->GetAppBundleDirectory(context->Config,
+                                         cmGeneratorTarget::BundleDirLevel);
+  }
+};
+
+template <>
 struct TargetFilesystemArtifactResultCreator<ArtifactBundleContentDirTag>
 {
   static std::string Create(cmGeneratorTarget* target,
@@ -2417,7 +2449,8 @@ struct TargetFilesystemArtifact : public TargetArtifactBase
       return std::string();
     }
     // Not a dependent target if we are querying for ArtifactDirTag,
-    // ArtifactNameTag, ArtifactBundleDirTag, and ArtifactBundleContentDirTag
+    // ArtifactNameTag, ArtifactBundleDirTag, ArtifactBundleDirNameTag,
+    // and ArtifactBundleContentDirTag
     TargetFilesystemArtifactDependency<ArtifactT, ComponentT>::AddDependency(
       target, context);
 
@@ -2458,6 +2491,10 @@ static const TargetFilesystemArtifactNodeGroup<ArtifactPdbTag>
 static const TargetFilesystemArtifact<ArtifactBundleDirTag, ArtifactPathTag>
   targetBundleDirNode;
 
+static const TargetFilesystemArtifact<ArtifactBundleDirNameTag,
+                                      ArtifactNameTag>
+  targetBundleDirNameNode;
+
 static const TargetFilesystemArtifact<ArtifactBundleContentDirTag,
                                       ArtifactPathTag>
   targetBundleContentDirNode;
@@ -2783,6 +2820,7 @@ const cmGeneratorExpressionNode* cmGeneratorExpressionNode::GetNode(
     { "TARGET_SONAME_FILE_DIR", &targetSoNameNodeGroup.FileDir },
     { "TARGET_PDB_FILE_DIR", &targetPdbNodeGroup.FileDir },
     { "TARGET_BUNDLE_DIR", &targetBundleDirNode },
+    { "TARGET_BUNDLE_DIR_NAME", &targetBundleDirNameNode },
     { "TARGET_BUNDLE_CONTENT_DIR", &targetBundleContentDirNode },
     { "STREQUAL", &strEqualNode },
     { "EQUAL", &equalNode },
diff --git a/Tests/RunCMake/GenEx-TARGET_FILE/ImportedTarget-TARGET_BUNDLE_DIR_NAME-result.txt b/Tests/RunCMake/GenEx-TARGET_FILE/ImportedTarget-TARGET_BUNDLE_DIR_NAME-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/GenEx-TARGET_FILE/ImportedTarget-TARGET_BUNDLE_DIR_NAME-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/GenEx-TARGET_FILE/ImportedTarget-TARGET_BUNDLE_DIR_NAME-stderr.txt b/Tests/RunCMake/GenEx-TARGET_FILE/ImportedTarget-TARGET_BUNDLE_DIR_NAME-stderr.txt
new file mode 100644
index 0000000..f6e2df5
--- /dev/null
+++ b/Tests/RunCMake/GenEx-TARGET_FILE/ImportedTarget-TARGET_BUNDLE_DIR_NAME-stderr.txt
@@ -0,0 +1,8 @@
+CMake Error at ImportedTarget-TARGET_BUNDLE_DIR_NAME.cmake:[0-9]* \(add_custom_target\):
+  Error evaluating generator expression:
+
+    \$<TARGET_BUNDLE_DIR_NAME:empty>
+
+  TARGET_BUNDLE_DIR_NAME not allowed for IMPORTED targets.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:[0-9]* \(include\)
diff --git a/Tests/RunCMake/GenEx-TARGET_FILE/ImportedTarget-TARGET_BUNDLE_DIR_NAME.cmake b/Tests/RunCMake/GenEx-TARGET_FILE/ImportedTarget-TARGET_BUNDLE_DIR_NAME.cmake
new file mode 100644
index 0000000..f926f75
--- /dev/null
+++ b/Tests/RunCMake/GenEx-TARGET_FILE/ImportedTarget-TARGET_BUNDLE_DIR_NAME.cmake
@@ -0,0 +1,2 @@
+add_library(empty UNKNOWN IMPORTED)
+add_custom_target(custom COMMAND echo $<TARGET_BUNDLE_DIR_NAME:empty>)
diff --git a/Tests/RunCMake/GenEx-TARGET_FILE/NonValidTarget-TARGET_BUNDLE_DIR_NAME-result.txt b/Tests/RunCMake/GenEx-TARGET_FILE/NonValidTarget-TARGET_BUNDLE_DIR_NAME-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/GenEx-TARGET_FILE/NonValidTarget-TARGET_BUNDLE_DIR_NAME-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/GenEx-TARGET_FILE/NonValidTarget-TARGET_BUNDLE_DIR_NAME-stderr.txt b/Tests/RunCMake/GenEx-TARGET_FILE/NonValidTarget-TARGET_BUNDLE_DIR_NAME-stderr.txt
new file mode 100644
index 0000000..dbbf63c
--- /dev/null
+++ b/Tests/RunCMake/GenEx-TARGET_FILE/NonValidTarget-TARGET_BUNDLE_DIR_NAME-stderr.txt
@@ -0,0 +1,8 @@
+CMake Error at NonValidTarget-TARGET_BUNDLE_DIR_NAME.cmake:[0-9]* \(file\):
+  Error evaluating generator expression:
+
+    \$<TARGET_BUNDLE_DIR_NAME:empty>
+
+  TARGET_BUNDLE_DIR_NAME is allowed only for Bundle targets.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:[0-9]* \(include\)
diff --git a/Tests/RunCMake/GenEx-TARGET_FILE/NonValidTarget-TARGET_BUNDLE_DIR_NAME.cmake b/Tests/RunCMake/GenEx-TARGET_FILE/NonValidTarget-TARGET_BUNDLE_DIR_NAME.cmake
new file mode 100644
index 0000000..05b8e18
--- /dev/null
+++ b/Tests/RunCMake/GenEx-TARGET_FILE/NonValidTarget-TARGET_BUNDLE_DIR_NAME.cmake
@@ -0,0 +1,9 @@
+
+enable_language(C)
+
+add_library(empty STATIC empty.c)
+
+file(GENERATE
+  OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/test.txt"
+  CONTENT "[$<TARGET_BUNDLE_DIR_NAME:empty>]"
+)
diff --git a/Tests/RunCMake/GenEx-TARGET_FILE/RunCMakeTest.cmake b/Tests/RunCMake/GenEx-TARGET_FILE/RunCMakeTest.cmake
index 55b0f9b..148baac 100644
--- a/Tests/RunCMake/GenEx-TARGET_FILE/RunCMakeTest.cmake
+++ b/Tests/RunCMake/GenEx-TARGET_FILE/RunCMakeTest.cmake
@@ -17,8 +17,10 @@ run_cmake_with_options(TARGET_FILE_BASE_NAME-imported-target -DCMAKE_BUILD_TYPE:
 run_cmake(TARGET_FILE_BASE_NAME-non-valid-target)
 run_cmake(TARGET_LINKER_FILE_BASE_NAME-non-valid-target)
 run_cmake(NonValidTarget-TARGET_BUNDLE_DIR)
+run_cmake(NonValidTarget-TARGET_BUNDLE_DIR_NAME)
 run_cmake(NonValidTarget-TARGET_BUNDLE_CONTENT_DIR)
 run_cmake(ImportedTarget-TARGET_BUNDLE_DIR)
+run_cmake(ImportedTarget-TARGET_BUNDLE_DIR_NAME)
 run_cmake(ImportedTarget-TARGET_BUNDLE_CONTENT_DIR)
 run_cmake(ImportedTarget-TARGET_PDB_FILE)
 run_cmake(ImportedTarget-TARGET_PDB_FILE_BASE_NAME)
-- 
cgit v0.12