Kaynağa Gözat

GenEx: Add POSTFIX option to $<TARGET_PDB_FILE_BASE_NAME>

Extend commit 0b055a8893 (GenEx: add POSTFIX option to
$<TARGET_FILE_BASE_NAME>, 2025-09-07) to cover PDB names too.
Marc Chevrier 1 ay önce
ebeveyn
işleme
7a154bf4fd

+ 20 - 7
Help/manual/cmake-generator-expressions.7.rst

@@ -2687,24 +2687,37 @@ In the following, the phrase "the ``tgt`` filename" means the name of the
   target properties and their configuration specific variants
   :prop_tgt:`PDB_NAME_<CONFIG>` and :prop_tgt:`PDB_OUTPUT_DIRECTORY_<CONFIG>`.
 
-.. genex:: $<TARGET_PDB_FILE_BASE_NAME:tgt>
+.. genex:: $<TARGET_PDB_FILE_BASE_NAME:tgt[,POSTFIX:(INCLUDE|EXCLUDE)]>
 
   .. versionadded:: 3.15
 
   Base name of the linker generated program database file (.pdb)
   where ``tgt`` is the name of a target.
 
+  .. versionadded:: 4.2
+    The option ``POSTFIX``, which can be used to control the inclusion or not
+    of the :prop_tgt:`<CONFIG>_POSTFIX` target property value as part of the
+    base name. The default is ``POSTFIX:INCLUDE``.
+
   .. versionchanged:: 4.2
     The postfix, as specified by :prop_tgt:`DEBUG_POSTFIX` or
     :prop_tgt:`<CONFIG>_POSTFIX` target properties, is always included in the
-    ``PDB`` base name. See the policy :policy:`CMP0202`.
+    ``PDB`` base name, except if option ``POSTFIX`` has value ``EXCLUDE``.
+    See the policy :policy:`CMP0202`.
 
   The base name corresponds to the target PDB file name (see
-  ``$<TARGET_PDB_FILE_NAME:tgt>``) without prefix and suffix. For example,
-  if target file name is ``base.pdb``, the base name is ``base``.
-
-  See also the :prop_tgt:`PDB_NAME` target property, and its
-  configuration-specific variant :prop_tgt:`PDB_NAME_<CONFIG>`.
+  ``$<TARGET_PDB_FILE_NAME:tgt>``) without prefix and suffix, and, optionally,
+  postfix. For example, if target file name is ``base_postfix.pdb``, the base
+  name is
+
+    * ``base_postfix`` for ``$<TARGET_PDB_FILE_BASE_NAME:tgt>`` or
+      ``$<TARGET_PDB_FILE_BASE_NAME:tgt,POSTFIX:INCLUDE>``.
+    * ``base`` for ``$<TARGET_PDB_FILE_BASE_NAME:tgt,POSTFIX:EXCLUDE>``.
+
+  See also the :prop_tgt:`OUTPUT_NAME`, :prop_tgt:`PDB_NAME` target properties,
+  and their configuration-specific variants :prop_tgt:`OUTPUT_NAME_<CONFIG>`
+  and :prop_tgt:`PDB_NAME_<CONFIG>`, and the :prop_tgt:`<CONFIG>_POSTFIX` and
+  :prop_tgt:`DEBUG_POSTFIX` target properties.
 
   Note that ``tgt`` is not added as a dependency of the target this
   expression is evaluated on.

+ 2 - 1
Help/release/dev/GenEx-TARGET_FILE_BASE_NAME-POSTFIX.rst

@@ -4,7 +4,8 @@ GenEx-TARGET_FILE_BASE_NAME-POSTFIX
 * The :genex:`TARGET_FILE_BASE_NAME`, :genex:`TARGET_IMPORT_FILE_BASE_NAME`,
   :genex:`TARGET_LINKER_FILE_BASE_NAME`,
   :genex:`TARGET_LINKER_LIBRARY_FILE_BASE_NAME`,
-  and :genex:`TARGET_LINKER_IMPORT_FILE_BASE_NAME`
+  :genex:`TARGET_LINKER_IMPORT_FILE_BASE_NAME`, and
+  :genex:`TARGET_PDB_FILE_BASE_NAME`
   generator expressions gained the option ``POSTFIX`` to control the inclusion
   or not of the :prop_tgt:`<CONFIG>_POSTFIX` target property as part of the
   base name of the target.

+ 28 - 19
Source/cmGeneratorExpressionNode.cxx

@@ -4166,6 +4166,7 @@ static TargetFilesystemArtifact<ArtifactBundleContentDirTag,
 //
 enum class Postfix
 {
+  Unspecified,
   Exclude,
   Include
 };
@@ -4189,7 +4190,7 @@ struct TargetOutputNameArtifactResultGetter<ArtifactNameTag>
   {
     auto output = target->GetOutputName(eval->Context.Config,
                                         cmStateEnums::RuntimeBinaryArtifact);
-    return postfix == Postfix::Include
+    return postfix != Postfix::Exclude
       ? cmStrCat(output, target->GetFilePostfix(eval->Context.Config))
       : output;
   }
@@ -4206,7 +4207,7 @@ struct TargetOutputNameArtifactResultGetter<ArtifactImportTag>
     if (target->HasImportLibrary(eval->Context.Config)) {
       auto output = target->GetOutputName(eval->Context.Config,
                                           cmStateEnums::ImportLibraryArtifact);
-      return postfix == Postfix::Include
+      return postfix != Postfix::Exclude
         ? cmStrCat(output, target->GetFilePostfix(eval->Context.Config))
         : output;
     }
@@ -4235,7 +4236,7 @@ struct TargetOutputNameArtifactResultGetter<ArtifactLinkerTag>
       ? cmStateEnums::ImportLibraryArtifact
       : cmStateEnums::RuntimeBinaryArtifact;
     auto output = target->GetOutputName(eval->Context.Config, artifact);
-    return postfix == Postfix::Include
+    return postfix != Postfix::Exclude
       ? cmStrCat(output, target->GetFilePostfix(eval->Context.Config))
       : output;
   }
@@ -4262,7 +4263,7 @@ struct TargetOutputNameArtifactResultGetter<ArtifactLinkerLibraryTag>
         target->GetType() == cmStateEnums::STATIC_LIBRARY) {
       auto output = target->GetOutputName(eval->Context.Config,
                                           cmStateEnums::ImportLibraryArtifact);
-      return postfix == Postfix::Include
+      return postfix != Postfix::Exclude
         ? cmStrCat(output, target->GetFilePostfix(eval->Context.Config))
         : output;
     }
@@ -4289,7 +4290,7 @@ struct TargetOutputNameArtifactResultGetter<ArtifactLinkerImportTag>
     if (target->HasImportLibrary(eval->Context.Config)) {
       auto output = target->GetOutputName(eval->Context.Config,
                                           cmStateEnums::ImportLibraryArtifact);
-      return postfix == Postfix::Include
+      return postfix != Postfix::Exclude
         ? cmStrCat(output, target->GetFilePostfix(eval->Context.Config))
         : output;
     }
@@ -4303,7 +4304,7 @@ struct TargetOutputNameArtifactResultGetter<ArtifactPdbTag>
   static std::string Get(cmGeneratorTarget* target,
                          cm::GenEx::Evaluation* eval,
                          GeneratorExpressionContent const* content,
-                         Postfix /* unused */)
+                         Postfix postfix)
   {
     if (target->IsImported()) {
       ::reportError(
@@ -4336,9 +4337,24 @@ struct TargetOutputNameArtifactResultGetter<ArtifactPdbTag>
 
     auto output = target->GetPDBOutputName(eval->Context.Config);
 
-    return target->GetPolicyStatusCMP0202() == cmPolicies::NEW
-      ? cmStrCat(output, target->GetFilePostfix(eval->Context.Config))
-      : output;
+    if (target->GetPolicyStatusCMP0202() == cmPolicies::NEW) {
+      return postfix != Postfix::Exclude
+        ? cmStrCat(output, target->GetFilePostfix(eval->Context.Config))
+        : output;
+    }
+
+    if (target->GetPolicyStatusCMP0202() == cmPolicies::WARN &&
+        postfix != Postfix::Unspecified) {
+      eval->Context.LG->GetCMakeInstance()->IssueMessage(
+        MessageType::AUTHOR_WARNING,
+        cmStrCat(cmPolicies::GetPolicyWarning(cmPolicies::CMP0202), '\n',
+                 "\"POSTFIX\" option is recognized only when the policy is "
+                 "set to NEW. Since the policy is not set, the OLD behavior "
+                 "will be used."),
+        eval->Backtrace);
+    }
+
+    return output;
   }
 };
 
@@ -4366,7 +4382,7 @@ struct TargetFileBaseNameArtifact : public TargetArtifactBase
       return std::string();
     }
 
-    Postfix postfix = Postfix::Include;
+    Postfix postfix = Postfix::Unspecified;
     if (parameters.size() == 2) {
       if (parameters[1] == "POSTFIX:INCLUDE") {
         postfix = Postfix::Include;
@@ -4388,14 +4404,6 @@ struct TargetFileBaseNameArtifact : public TargetArtifactBase
   }
 };
 
-struct TargetPdbFileBaseNameArtifact
-  : public TargetFileBaseNameArtifact<ArtifactPdbTag>
-{
-  TargetPdbFileBaseNameArtifact() {} // NOLINT(modernize-use-equals-default)
-
-  int NumExpectedParameters() const override { return 1; }
-};
-
 static TargetFileBaseNameArtifact<ArtifactNameTag> const
   targetFileBaseNameNode;
 static TargetFileBaseNameArtifact<ArtifactImportTag> const
@@ -4406,7 +4414,8 @@ static TargetFileBaseNameArtifact<ArtifactLinkerLibraryTag> const
   targetLinkerLibraryFileBaseNameNode;
 static TargetFileBaseNameArtifact<ArtifactLinkerImportTag> const
   targetLinkerImportFileBaseNameNode;
-static TargetPdbFileBaseNameArtifact const targetPdbFileBaseNameNode;
+static TargetFileBaseNameArtifact<ArtifactPdbTag> const
+  targetPdbFileBaseNameNode;
 
 class ArtifactFilePrefixTag;
 class ArtifactImportFilePrefixTag;

+ 10 - 0
Tests/RunCMake/GenEx-TARGET_FILE/CMP0202-WARN-TARGET_PDB_FILE_BASE_NAME-stderr.txt

@@ -0,0 +1,10 @@
+^CMake Warning \(dev\) at CMP0202-WARN-TARGET_PDB_FILE_BASE_NAME\.cmake:[0-9]+ \(file\):
+  Policy CMP0202 is not set: PDB file names always include their target's
+  per-config POSTFIX\.  Run "cmake --help-policy CMP0202" for policy details\.
+  Use the cmake_policy command to set the policy and suppress this warning\.
+
+  "POSTFIX" option is recognized only when the policy is set to NEW.  Since
+  the policy is not set, the OLD behavior will be used\.
+Call Stack \(most recent call first\):
+  CMakeLists\.txt:[0-9]+ \(include\)
+This warning is for project developers.  Use -Wno-dev to suppress it.

+ 11 - 0
Tests/RunCMake/GenEx-TARGET_FILE/CMP0202-WARN-TARGET_PDB_FILE_BASE_NAME.cmake

@@ -0,0 +1,11 @@
+
+cmake_minimum_required(VERSION 4.0)
+
+enable_language(C)
+
+add_library(empty SHARED empty.c)
+
+file(GENERATE
+  OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/test.txt"
+  CONTENT "[$<TARGET_PDB_FILE_BASE_NAME:empty,POSTFIX:INCLUDE>]"
+)

+ 1 - 0
Tests/RunCMake/GenEx-TARGET_FILE/RunCMakeTest.cmake

@@ -41,6 +41,7 @@ if(LINKER_SUPPORTS_PDB)
   run_cmake(ValidTarget-TARGET_PDB_FILE)
   run_cmake(NonValidTarget-TARGET_PDB_FILE_BASE_NAME)
   run_cmake(ValidTarget-TARGET_PDB_FILE_BASE_NAME)
+  run_cmake(CMP0202-WARN-TARGET_PDB_FILE_BASE_NAME)
 else()
   run_cmake(NonValidCompiler-TARGET_PDB_FILE)
   run_cmake(NonValidCompiler-TARGET_PDB_FILE_BASE_NAME)

+ 11 - 5
Tests/RunCMake/GenEx-TARGET_FILE/TARGET_FILE_BASE_NAME.cmake

@@ -117,23 +117,23 @@ string (APPEND GENERATE_CONTENT [[
 
 check_value ("TARGET_FILE_BASE_NAME executable all properties + postfix" "$<TARGET_FILE_BASE_NAME:exec4>" "exec4_runtime_postfix")
 check_value ("TARGET_FILE_BASE_NAME executable all properties + postfix" "$<TARGET_FILE_BASE_NAME:exec4,POSTFIX:INCLUDE>" "exec4_runtime_postfix")
-check_value ("TARGET_FILE_BASE_NAME executable all properties without postfix" "$<TARGET_FILE_BASE_NAME:exec4,POSTFIX:EXCLUDE>" "exec4_runtime")
+check_value ("TARGET_FILE_BASE_NAME executable all properties + postfix (excluded)" "$<TARGET_FILE_BASE_NAME:exec4,POSTFIX:EXCLUDE>" "exec4_runtime")
 
 check_value ("TARGET_FILE_BASE_NAME shared all properties + postfix" "$<TARGET_FILE_BASE_NAME:shared4>" "$<IF:$<IN_LIST:$<PLATFORM_ID>,Windows$<SEMICOLON>CYGWIN$<SEMICOLON>MSYS>,shared4_runtime,shared4_library>_postfix")
 check_value ("TARGET_FILE_BASE_NAME shared all properties + postfix" "$<TARGET_FILE_BASE_NAME:shared4,POSTFIX:INCLUDE>" "$<IF:$<IN_LIST:$<PLATFORM_ID>,Windows$<SEMICOLON>CYGWIN$<SEMICOLON>MSYS>,shared4_runtime,shared4_library>_postfix")
-check_value ("TARGET_FILE_BASE_NAME shared all properties without postfix" "$<TARGET_FILE_BASE_NAME:shared4,POSTFIX:EXCLUDE>" "$<IF:$<IN_LIST:$<PLATFORM_ID>,Windows$<SEMICOLON>CYGWIN$<SEMICOLON>MSYS>,shared4_runtime,shared4_library>")
+check_value ("TARGET_FILE_BASE_NAME shared all properties + postfix (excluded)" "$<TARGET_FILE_BASE_NAME:shared4,POSTFIX:EXCLUDE>" "$<IF:$<IN_LIST:$<PLATFORM_ID>,Windows$<SEMICOLON>CYGWIN$<SEMICOLON>MSYS>,shared4_runtime,shared4_library>")
 
 check_value ("TARGET_LINKER_FILE_BASE_NAME shared linker all properties + postfix" "$<TARGET_LINKER_FILE_BASE_NAME:shared4>" "$<IF:$<IN_LIST:$<PLATFORM_ID>,Windows$<SEMICOLON>CYGWIN$<SEMICOLON>MSYS>,shared4_archive,shared4_library>_postfix")
 check_value ("TARGET_LINKER_FILE_BASE_NAME shared linker all properties + postfix" "$<TARGET_LINKER_FILE_BASE_NAME:shared4,POSTFIX:INCLUDE>" "$<IF:$<IN_LIST:$<PLATFORM_ID>,Windows$<SEMICOLON>CYGWIN$<SEMICOLON>MSYS>,shared4_archive,shared4_library>_postfix")
-check_value ("TARGET_LINKER_FILE_BASE_NAME shared linker all properties without postfix" "$<TARGET_LINKER_FILE_BASE_NAME:shared4,POSTFIX:EXCLUDE>" "$<IF:$<IN_LIST:$<PLATFORM_ID>,Windows$<SEMICOLON>CYGWIN$<SEMICOLON>MSYS>,shared4_archive,shared4_library>")
+check_value ("TARGET_LINKER_FILE_BASE_NAME shared linker all properties + postfix (excluded)" "$<TARGET_LINKER_FILE_BASE_NAME:shared4,POSTFIX:EXCLUDE>" "$<IF:$<IN_LIST:$<PLATFORM_ID>,Windows$<SEMICOLON>CYGWIN$<SEMICOLON>MSYS>,shared4_archive,shared4_library>")
 
 check_value ("TARGET_FILE_BASE_NAME static all properties + postfix" "$<TARGET_FILE_BASE_NAME:static4>" "static4_archive_postfix")
 check_value ("TARGET_FILE_BASE_NAME static all properties + postfix" "$<TARGET_FILE_BASE_NAME:static4,POSTFIX:INCLUDE>" "static4_archive_postfix")
-check_value ("TARGET_FILE_BASE_NAME static all properties without postfix" "$<TARGET_FILE_BASE_NAME:static4,POSTFIX:EXCLUDE>" "static4_archive")
+check_value ("TARGET_FILE_BASE_NAME static all properties + postfix (excluded)" "$<TARGET_FILE_BASE_NAME:static4,POSTFIX:EXCLUDE>" "static4_archive")
 
 check_value ("TARGET_LINKER_FILE_BASE_NAME static linker all properties + postfix" "$<TARGET_LINKER_FILE_BASE_NAME:static4>" "static4_archive_postfix")
 check_value ("TARGET_LINKER_FILE_BASE_NAME static linker all properties + postfix" "$<TARGET_LINKER_FILE_BASE_NAME:static4,POSTFIX:INCLUDE>" "static4_archive_postfix")
-check_value ("TARGET_LINKER_FILE_BASE_NAME static linker all properties without postfix" "$<TARGET_LINKER_FILE_BASE_NAME:static4,POSTFIX:EXCLUDE>" "static4_archive")
+check_value ("TARGET_LINKER_FILE_BASE_NAME static linker all properties + postfix (excluded)" "$<TARGET_LINKER_FILE_BASE_NAME:static4,POSTFIX:EXCLUDE>" "static4_archive")
 ]])
 if (CMAKE_C_LINKER_SUPPORTS_PDB)
   string (APPEND GENERATE_CONTENT [[
@@ -158,6 +158,12 @@ if (CMAKE_C_LINKER_SUPPORTS_PDB)
   string (APPEND GENERATE_CONTENT [[
 check_value ("TARGET_PDB_FILE_BASE_NAME executable PDB all properties + postfix" "$<TARGET_PDB_FILE_BASE_NAME:exec5>" "exec5_pdb_postfix")
 check_value ("TARGET_PDB_FILE_BASE_NAME shared PDB all properties + postfix" "$<TARGET_PDB_FILE_BASE_NAME:shared5>" "shared5_pdb_postfix")
+
+check_value ("TARGET_PDB_FILE_BASE_NAME executable PDB all properties + postfix" "$<TARGET_PDB_FILE_BASE_NAME:exec5,POSTFIX:INCLUDE>" "exec5_pdb_postfix")
+check_value ("TARGET_PDB_FILE_BASE_NAME shared PDB all properties + postfix" "$<TARGET_PDB_FILE_BASE_NAME:shared5,POSTFIX:INCLUDE>" "shared5_pdb_postfix")
+
+check_value ("TARGET_PDB_FILE_BASE_NAME executable PDB all properties + postfix (excluded)" "$<TARGET_PDB_FILE_BASE_NAME:exec5,POSTFIX:EXCLUDE>" "exec5_pdb")
+check_value ("TARGET_PDB_FILE_BASE_NAME shared PDB all properties + postfix (excluded)" "$<TARGET_PDB_FILE_BASE_NAME:shared5,POSTFIX:EXCLUDE>" "shared5_pdb")
 ]])
 endif()