فهرست منبع

Refactor: Prepare Ninja generator for multi-config

Kyle Edwards 6 سال پیش
والد
کامیت
3bc63e99e4

+ 28 - 23
Source/cmCommonTargetGenerator.cxx

@@ -25,27 +25,29 @@ cmCommonTargetGenerator::cmCommonTargetGenerator(cmGeneratorTarget* gt)
       static_cast<cmLocalCommonGenerator*>(gt->LocalGenerator))
   , GlobalCommonGenerator(static_cast<cmGlobalCommonGenerator*>(
       gt->LocalGenerator->GetGlobalGenerator()))
-  , ConfigName(LocalCommonGenerator->GetConfigName())
+  , ConfigNames(LocalCommonGenerator->GetConfigNames())
 {
 }
 
 cmCommonTargetGenerator::~cmCommonTargetGenerator() = default;
 
-std::string const& cmCommonTargetGenerator::GetConfigName() const
+std::vector<std::string> const& cmCommonTargetGenerator::GetConfigNames() const
 {
-  return this->ConfigName;
+  return this->ConfigNames;
 }
 
-const char* cmCommonTargetGenerator::GetFeature(const std::string& feature)
+const char* cmCommonTargetGenerator::GetFeature(const std::string& feature,
+                                                const std::string& config)
 {
-  return this->GeneratorTarget->GetFeature(feature, this->ConfigName);
+  return this->GeneratorTarget->GetFeature(feature, config);
 }
 
 void cmCommonTargetGenerator::AddModuleDefinitionFlag(
-  cmLinkLineComputer* linkLineComputer, std::string& flags)
+  cmLinkLineComputer* linkLineComputer, std::string& flags,
+  const std::string& config)
 {
   cmGeneratorTarget::ModuleDefinitionInfo const* mdi =
-    this->GeneratorTarget->GetModuleDefinitionInfo(this->GetConfigName());
+    this->GeneratorTarget->GetModuleDefinitionInfo(config);
   if (!mdi || mdi->DefFile.empty()) {
     return;
   }
@@ -94,14 +96,15 @@ void cmCommonTargetGenerator::AppendFortranFormatFlags(
   }
 }
 
-std::string cmCommonTargetGenerator::GetFlags(const std::string& l)
+std::string cmCommonTargetGenerator::GetFlags(const std::string& l,
+                                              const std::string& config)
 {
   auto i = this->FlagsByLanguage.find(l);
   if (i == this->FlagsByLanguage.end()) {
     std::string flags;
 
-    this->LocalCommonGenerator->GetTargetCompileFlags(
-      this->GeneratorTarget, this->ConfigName, l, flags);
+    this->LocalCommonGenerator->GetTargetCompileFlags(this->GeneratorTarget,
+                                                      config, l, flags);
 
     ByLanguageMap::value_type entry(l, flags);
     i = this->FlagsByLanguage.insert(entry).first;
@@ -109,13 +112,14 @@ std::string cmCommonTargetGenerator::GetFlags(const std::string& l)
   return i->second;
 }
 
-std::string cmCommonTargetGenerator::GetDefines(const std::string& l)
+std::string cmCommonTargetGenerator::GetDefines(const std::string& l,
+                                                const std::string& config)
 {
   auto i = this->DefinesByLanguage.find(l);
   if (i == this->DefinesByLanguage.end()) {
     std::set<std::string> defines;
-    this->LocalCommonGenerator->GetTargetDefines(this->GeneratorTarget,
-                                                 this->ConfigName, l, defines);
+    this->LocalCommonGenerator->GetTargetDefines(this->GeneratorTarget, config,
+                                                 l, defines);
 
     std::string definesString;
     this->LocalCommonGenerator->JoinDefines(defines, definesString, l);
@@ -126,25 +130,26 @@ std::string cmCommonTargetGenerator::GetDefines(const std::string& l)
   return i->second;
 }
 
-std::string cmCommonTargetGenerator::GetIncludes(std::string const& l)
+std::string cmCommonTargetGenerator::GetIncludes(std::string const& l,
+                                                 const std::string& config)
 {
   auto i = this->IncludesByLanguage.find(l);
   if (i == this->IncludesByLanguage.end()) {
     std::string includes;
-    this->AddIncludeFlags(includes, l);
+    this->AddIncludeFlags(includes, l, config);
     ByLanguageMap::value_type entry(l, includes);
     i = this->IncludesByLanguage.insert(entry).first;
   }
   return i->second;
 }
 
-std::vector<std::string> cmCommonTargetGenerator::GetLinkedTargetDirectories()
-  const
+std::vector<std::string> cmCommonTargetGenerator::GetLinkedTargetDirectories(
+  const std::string& config) const
 {
   std::vector<std::string> dirs;
   std::set<cmGeneratorTarget const*> emitted;
   if (cmComputeLinkInformation* cli =
-        this->GeneratorTarget->GetLinkInformation(this->ConfigName)) {
+        this->GeneratorTarget->GetLinkInformation(config)) {
     cmComputeLinkInformation::ItemVector const& items = cli->GetItems();
     for (auto const& item : items) {
       cmGeneratorTarget const* linkee = item.Target;
@@ -165,15 +170,15 @@ std::vector<std::string> cmCommonTargetGenerator::GetLinkedTargetDirectories()
   return dirs;
 }
 
-std::string cmCommonTargetGenerator::ComputeTargetCompilePDB() const
+std::string cmCommonTargetGenerator::ComputeTargetCompilePDB(
+  const std::string& config) const
 {
   std::string compilePdbPath;
   if (this->GeneratorTarget->GetType() > cmStateEnums::OBJECT_LIBRARY) {
     return compilePdbPath;
   }
 
-  compilePdbPath =
-    this->GeneratorTarget->GetCompilePDBPath(this->GetConfigName());
+  compilePdbPath = this->GeneratorTarget->GetCompilePDBPath(config);
   if (compilePdbPath.empty()) {
     // Match VS default: `$(IntDir)vc$(PlatformToolsetVersion).pdb`.
     // A trailing slash tells the toolchain to add its default file name.
@@ -188,10 +193,10 @@ std::string cmCommonTargetGenerator::ComputeTargetCompilePDB() const
   return compilePdbPath;
 }
 
-std::string cmCommonTargetGenerator::GetManifests()
+std::string cmCommonTargetGenerator::GetManifests(const std::string& config)
 {
   std::vector<cmSourceFile const*> manifest_srcs;
-  this->GeneratorTarget->GetManifests(manifest_srcs, this->ConfigName);
+  this->GeneratorTarget->GetManifests(manifest_srcs, config);
 
   std::vector<std::string> manifests;
   manifests.reserve(manifest_srcs.size());

+ 14 - 12
Source/cmCommonTargetGenerator.h

@@ -25,42 +25,44 @@ public:
   cmCommonTargetGenerator(cmGeneratorTarget* gt);
   virtual ~cmCommonTargetGenerator();
 
-  std::string const& GetConfigName() const;
+  std::vector<std::string> const& GetConfigNames() const;
 
 protected:
   // Feature query methods.
-  const char* GetFeature(const std::string& feature);
+  const char* GetFeature(const std::string& feature,
+                         const std::string& config);
 
   // Helper to add flag for windows .def file.
   void AddModuleDefinitionFlag(cmLinkLineComputer* linkLineComputer,
-                               std::string& flags);
+                               std::string& flags, const std::string& config);
 
   cmGeneratorTarget* GeneratorTarget;
   cmMakefile* Makefile;
   cmLocalCommonGenerator* LocalCommonGenerator;
   cmGlobalCommonGenerator* GlobalCommonGenerator;
-  std::string ConfigName;
+  std::vector<std::string> ConfigNames;
 
   void AppendFortranFormatFlags(std::string& flags,
                                 cmSourceFile const& source);
 
-  virtual void AddIncludeFlags(std::string& flags,
-                               std::string const& lang) = 0;
+  virtual void AddIncludeFlags(std::string& flags, std::string const& lang,
+                               const std::string& config) = 0;
 
   void AppendOSXVerFlag(std::string& flags, const std::string& lang,
                         const char* name, bool so);
 
   using ByLanguageMap = std::map<std::string, std::string>;
-  std::string GetFlags(const std::string& l);
+  std::string GetFlags(const std::string& l, const std::string& config);
   ByLanguageMap FlagsByLanguage;
-  std::string GetDefines(const std::string& l);
+  std::string GetDefines(const std::string& l, const std::string& config);
   ByLanguageMap DefinesByLanguage;
-  std::string GetIncludes(std::string const& l);
+  std::string GetIncludes(std::string const& l, const std::string& config);
   ByLanguageMap IncludesByLanguage;
-  std::string GetManifests();
+  std::string GetManifests(const std::string& config);
 
-  std::vector<std::string> GetLinkedTargetDirectories() const;
-  std::string ComputeTargetCompilePDB() const;
+  std::vector<std::string> GetLinkedTargetDirectories(
+    const std::string& config) const;
+  std::string ComputeTargetCompilePDB(const std::string& config) const;
 };
 
 #endif

+ 35 - 20
Source/cmGlobalNinjaGenerator.cxx

@@ -916,11 +916,8 @@ std::string OrderDependsTargetForTarget(cmGeneratorTarget const* target)
 
 void cmGlobalNinjaGenerator::AppendTargetOutputs(
   cmGeneratorTarget const* target, cmNinjaDeps& outputs,
-  cmNinjaTargetDepends depends)
+  const std::string& config, cmNinjaTargetDepends depends)
 {
-  std::string configName =
-    target->Target->GetMakefile()->GetSafeDefinition("CMAKE_BUILD_TYPE");
-
   // for frameworks, we want the real name, not smple name
   // frameworks always appear versioned, and the build.ninja
   // will always attempt to manage symbolic links instead
@@ -939,7 +936,7 @@ void cmGlobalNinjaGenerator::AppendTargetOutputs(
     // FALLTHROUGH
     case cmStateEnums::EXECUTABLE: {
       outputs.push_back(this->ConvertToNinjaPath(target->GetFullPath(
-        configName, cmStateEnums::RuntimeBinaryArtifact, realname)));
+        config, cmStateEnums::RuntimeBinaryArtifact, realname)));
       break;
     }
     case cmStateEnums::OBJECT_LIBRARY: {
@@ -965,7 +962,7 @@ void cmGlobalNinjaGenerator::AppendTargetOutputs(
 
 void cmGlobalNinjaGenerator::AppendTargetDepends(
   cmGeneratorTarget const* target, cmNinjaDeps& outputs,
-  cmNinjaTargetDepends depends)
+  const std::string& config, cmNinjaTargetDepends depends)
 {
   if (target->GetType() == cmStateEnums::GLOBAL_TARGET) {
     // These depend only on other CMake-provided targets, e.g. "all".
@@ -982,7 +979,7 @@ void cmGlobalNinjaGenerator::AppendTargetDepends(
       if (targetDep->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
         continue;
       }
-      this->AppendTargetOutputs(targetDep, outs, depends);
+      this->AppendTargetOutputs(targetDep, outs, config, depends);
     }
     std::sort(outs.begin(), outs.end());
     cmAppend(outputs, outs);
@@ -990,15 +987,17 @@ void cmGlobalNinjaGenerator::AppendTargetDepends(
 }
 
 void cmGlobalNinjaGenerator::AppendTargetDependsClosure(
-  cmGeneratorTarget const* target, cmNinjaDeps& outputs)
+  cmGeneratorTarget const* target, cmNinjaDeps& outputs,
+  const std::string& config)
 {
   cmNinjaOuts outs;
-  this->AppendTargetDependsClosure(target, outs, true);
+  this->AppendTargetDependsClosure(target, outs, config, true);
   cmAppend(outputs, outs);
 }
 
 void cmGlobalNinjaGenerator::AppendTargetDependsClosure(
-  cmGeneratorTarget const* target, cmNinjaOuts& outputs, bool omit_self)
+  cmGeneratorTarget const* target, cmNinjaOuts& outputs,
+  const std::string& config, bool omit_self)
 {
 
   // try to locate the target in the cache
@@ -1019,7 +1018,7 @@ void cmGlobalNinjaGenerator::AppendTargetDependsClosure(
       }
 
       // Collect the dependent targets for _this_ target
-      this->AppendTargetDependsClosure(dep_target, this_outs, false);
+      this->AppendTargetDependsClosure(dep_target, this_outs, config, false);
     }
     find = this->TargetDependsClosures.emplace_hint(find, target,
                                                     std::move(this_outs));
@@ -1032,17 +1031,18 @@ void cmGlobalNinjaGenerator::AppendTargetDependsClosure(
   // finally generate the outputs of the target itself, if applicable
   cmNinjaDeps outs;
   if (!omit_self) {
-    this->AppendTargetOutputs(target, outs);
+    this->AppendTargetOutputs(target, outs, config);
   }
   outputs.insert(outs.begin(), outs.end());
 }
 
 void cmGlobalNinjaGenerator::AddTargetAlias(const std::string& alias,
-                                            cmGeneratorTarget* target)
+                                            cmGeneratorTarget* target,
+                                            const std::string& config)
 {
   std::string buildAlias = this->NinjaOutputPath(alias);
   cmNinjaDeps outputs;
-  this->AppendTargetOutputs(target, outputs);
+  this->AppendTargetOutputs(target, outputs, config);
   // Mark the target's outputs as ambiguous to ensure that no other target uses
   // the output as an alias.
   for (std::string const& output : outputs) {
@@ -1079,11 +1079,19 @@ void cmGlobalNinjaGenerator::WriteTargetAliases(std::ostream& os)
 
     // Outputs
     build.Outputs[0] = ta.first;
-    // Explicit depdendencies
-    build.ExplicitDeps.clear();
-    this->AppendTargetOutputs(ta.second, build.ExplicitDeps);
-    // Write
-    this->WriteBuild(os, build);
+
+    std::vector<std::string> configs;
+    ta.second->Makefile->GetConfigurations(configs);
+    if (configs.empty()) {
+      configs.emplace_back();
+    }
+    for (auto const& config : configs) {
+      // Explicit dependencies
+      build.ExplicitDeps.clear();
+      this->AppendTargetOutputs(ta.second, build.ExplicitDeps, config);
+      // Write
+      this->WriteBuild(os, build);
+    }
   }
 }
 
@@ -1107,7 +1115,14 @@ void cmGlobalNinjaGenerator::WriteFolderTargets(std::ostream& os)
       this->ConvertToNinjaPath(currentBinaryDir + "/all"));
     for (DirectoryTarget::Target const& t : dt.Targets) {
       if (!t.ExcludeFromAll) {
-        this->AppendTargetOutputs(t.GT, build.ExplicitDeps);
+        std::vector<std::string> configs;
+        dt.LG->GetMakefile()->GetConfigurations(configs, true);
+        if (configs.empty()) {
+          configs.emplace_back();
+        }
+        for (auto const& config : configs) {
+          this->AppendTargetOutputs(t.GT, build.ExplicitDeps, config);
+        }
       }
     }
     for (DirectoryTarget::Dir const& d : dt.Children) {

+ 8 - 3
Source/cmGlobalNinjaGenerator.h

@@ -287,18 +287,23 @@ public:
 
   void AppendTargetOutputs(
     cmGeneratorTarget const* target, cmNinjaDeps& outputs,
+    const std::string& config,
     cmNinjaTargetDepends depends = DependOnTargetArtifact);
   void AppendTargetDepends(
     cmGeneratorTarget const* target, cmNinjaDeps& outputs,
+    const std::string& config,
     cmNinjaTargetDepends depends = DependOnTargetArtifact);
   void AppendTargetDependsClosure(cmGeneratorTarget const* target,
-                                  cmNinjaDeps& outputs);
+                                  cmNinjaDeps& outputs,
+                                  const std::string& config);
   void AppendTargetDependsClosure(cmGeneratorTarget const* target,
-                                  cmNinjaOuts& outputs, bool omit_self);
+                                  cmNinjaOuts& outputs,
+                                  const std::string& config, bool omit_self);
 
   int GetRuleCmdLength(const std::string& name) { return RuleCmdLength[name]; }
 
-  void AddTargetAlias(const std::string& alias, cmGeneratorTarget* target);
+  void AddTargetAlias(const std::string& alias, cmGeneratorTarget* target,
+                      const std::string& config);
 
   void ComputeTargetObjectDirectory(cmGeneratorTarget* gt) const override;
 

+ 3 - 7
Source/cmLocalCommonGenerator.cxx

@@ -17,13 +17,9 @@ cmLocalCommonGenerator::cmLocalCommonGenerator(cmGlobalGenerator* gg,
   : cmLocalGenerator(gg, mf)
   , WorkingDirectory(std::move(wd))
 {
-  // Store the configuration name that will be generated.
-  if (const char* config = this->Makefile->GetDefinition("CMAKE_BUILD_TYPE")) {
-    // Use the build type given by the user.
-    this->ConfigName = config;
-  } else {
-    // No configuration type given.
-    this->ConfigName.clear();
+  this->Makefile->GetConfigurations(this->ConfigNames);
+  if (this->ConfigNames.empty()) {
+    this->ConfigNames.emplace_back();
   }
 }
 

+ 6 - 2
Source/cmLocalCommonGenerator.h

@@ -7,6 +7,7 @@
 
 #include <map>
 #include <string>
+#include <vector>
 
 #include "cmLocalGenerator.h"
 
@@ -25,7 +26,10 @@ public:
                          std::string wd);
   ~cmLocalCommonGenerator() override;
 
-  std::string const& GetConfigName() const { return this->ConfigName; }
+  std::vector<std::string> const& GetConfigNames() const
+  {
+    return this->ConfigNames;
+  }
 
   std::string GetWorkingDirectory() const { return this->WorkingDirectory; }
 
@@ -39,7 +43,7 @@ public:
 protected:
   std::string WorkingDirectory;
 
-  std::string ConfigName;
+  std::vector<std::string> ConfigNames;
 
   friend class cmCommonTargetGenerator;
 };

+ 31 - 21
Source/cmLocalNinjaGenerator.cxx

@@ -88,12 +88,16 @@ void cmLocalNinjaGenerator::Generate()
     }
     auto tg = cmNinjaTargetGenerator::New(target.get());
     if (tg) {
-      tg->Generate();
+      for (auto const& config : this->GetConfigNames()) {
+        tg->Generate(config);
+      }
     }
   }
 
-  this->WriteCustomCommandBuildStatements();
-  this->AdditionalCleanFiles();
+  for (auto const& config : this->GetConfigNames()) {
+    this->WriteCustomCommandBuildStatements(config);
+    this->AdditionalCleanFiles(config);
+  }
 }
 
 // TODO: Picked up from cmLocalUnixMakefileGenerator3.  Refactor it.
@@ -175,7 +179,8 @@ void cmLocalNinjaGenerator::WriteProjectHeader(std::ostream& os)
 {
   cmGlobalNinjaGenerator::WriteDivider(os);
   os << "# Project: " << this->GetProjectName() << std::endl
-     << "# Configuration: " << this->ConfigName << std::endl;
+     << "# Configurations: " << cmJoin(this->GetConfigNames(), ", ")
+     << std::endl;
   cmGlobalNinjaGenerator::WriteDivider(os);
 }
 
@@ -263,25 +268,29 @@ void cmLocalNinjaGenerator::WriteProcessedMakefile(std::ostream& os)
 }
 
 void cmLocalNinjaGenerator::AppendTargetOutputs(cmGeneratorTarget* target,
-                                                cmNinjaDeps& outputs)
+                                                cmNinjaDeps& outputs,
+                                                const std::string& config)
 {
-  this->GetGlobalNinjaGenerator()->AppendTargetOutputs(target, outputs);
+  this->GetGlobalNinjaGenerator()->AppendTargetOutputs(target, outputs,
+                                                       config);
 }
 
 void cmLocalNinjaGenerator::AppendTargetDepends(cmGeneratorTarget* target,
                                                 cmNinjaDeps& outputs,
+                                                const std::string& config,
                                                 cmNinjaTargetDepends depends)
 {
-  this->GetGlobalNinjaGenerator()->AppendTargetDepends(target, outputs,
+  this->GetGlobalNinjaGenerator()->AppendTargetDepends(target, outputs, config,
                                                        depends);
 }
 
 void cmLocalNinjaGenerator::AppendCustomCommandDeps(
-  cmCustomCommandGenerator const& ccg, cmNinjaDeps& ninjaDeps)
+  cmCustomCommandGenerator const& ccg, cmNinjaDeps& ninjaDeps,
+  const std::string& config)
 {
   for (std::string const& i : ccg.GetDepends()) {
     std::string dep;
-    if (this->GetRealDependency(i, this->GetConfigName(), dep)) {
+    if (this->GetRealDependency(i, config, dep)) {
       ninjaDeps.push_back(
         this->GetGlobalNinjaGenerator()->ConvertToNinjaPath(dep));
     }
@@ -446,14 +455,15 @@ void cmLocalNinjaGenerator::AppendCustomCommandLines(
 }
 
 void cmLocalNinjaGenerator::WriteCustomCommandBuildStatement(
-  cmCustomCommand const* cc, const cmNinjaDeps& orderOnlyDeps)
+  cmCustomCommand const* cc, const cmNinjaDeps& orderOnlyDeps,
+  const std::string& config)
 {
   cmGlobalNinjaGenerator* gg = this->GetGlobalNinjaGenerator();
   if (gg->SeenCustomCommand(cc)) {
     return;
   }
 
-  cmCustomCommandGenerator ccg(*cc, this->GetConfigName(), this);
+  cmCustomCommandGenerator ccg(*cc, config, this);
 
   const std::vector<std::string>& outputs = ccg.GetOutputs();
   const std::vector<std::string>& byproducts = ccg.GetByproducts();
@@ -484,7 +494,7 @@ void cmLocalNinjaGenerator::WriteCustomCommandBuildStatement(
   }
 
   cmNinjaDeps ninjaDeps;
-  this->AppendCustomCommandDeps(ccg, ninjaDeps);
+  this->AppendCustomCommandDeps(ccg, ninjaDeps, config);
 
   std::vector<std::string> cmdLines;
   this->AppendCustomCommandLines(ccg, cmdLines);
@@ -524,7 +534,8 @@ void cmLocalNinjaGenerator::AddCustomCommandTarget(cmCustomCommand const* cc,
   ins.first->second.insert(target);
 }
 
-void cmLocalNinjaGenerator::WriteCustomCommandBuildStatements()
+void cmLocalNinjaGenerator::WriteCustomCommandBuildStatements(
+  const std::string& config)
 {
   for (cmCustomCommand const* customCommand : this->CustomCommands) {
     auto i = this->CustomCommandTargets.find(customCommand);
@@ -542,15 +553,16 @@ void cmLocalNinjaGenerator::WriteCustomCommandBuildStatements()
     auto j = i->second.begin();
     assert(j != i->second.end());
     std::vector<std::string> ccTargetDeps;
-    this->GetGlobalNinjaGenerator()->AppendTargetDependsClosure(*j,
-                                                                ccTargetDeps);
+    this->GetGlobalNinjaGenerator()->AppendTargetDependsClosure(
+      *j, ccTargetDeps, config);
     std::sort(ccTargetDeps.begin(), ccTargetDeps.end());
     ++j;
 
     for (; j != i->second.end(); ++j) {
       std::vector<std::string> jDeps;
       std::vector<std::string> depsIntersection;
-      this->GetGlobalNinjaGenerator()->AppendTargetDependsClosure(*j, jDeps);
+      this->GetGlobalNinjaGenerator()->AppendTargetDependsClosure(*j, jDeps,
+                                                                  config);
       std::sort(jDeps.begin(), jDeps.end());
       std::set_intersection(ccTargetDeps.begin(), ccTargetDeps.end(),
                             jDeps.begin(), jDeps.end(),
@@ -558,7 +570,7 @@ void cmLocalNinjaGenerator::WriteCustomCommandBuildStatements()
       ccTargetDeps = depsIntersection;
     }
 
-    this->WriteCustomCommandBuildStatement(i->first, ccTargetDeps);
+    this->WriteCustomCommandBuildStatement(i->first, ccTargetDeps, config);
   }
 }
 
@@ -599,15 +611,13 @@ std::string cmLocalNinjaGenerator::MakeCustomLauncher(
   return launcher;
 }
 
-void cmLocalNinjaGenerator::AdditionalCleanFiles()
+void cmLocalNinjaGenerator::AdditionalCleanFiles(const std::string& config)
 {
   if (const char* prop_value =
         this->Makefile->GetProperty("ADDITIONAL_CLEAN_FILES")) {
     std::vector<std::string> cleanFiles;
     {
-      cmExpandList(cmGeneratorExpression::Evaluate(
-                     prop_value, this,
-                     this->Makefile->GetSafeDefinition("CMAKE_BUILD_TYPE")),
+      cmExpandList(cmGeneratorExpression::Evaluate(prop_value, this, config),
                    cleanFiles);
     }
     std::string const& binaryDir = this->GetCurrentBinaryDirectory();

+ 9 - 6
Source/cmLocalNinjaGenerator.h

@@ -64,9 +64,10 @@ public:
     std::string const& customStep = std::string(),
     cmGeneratorTarget const* target = nullptr) const;
 
-  void AppendTargetOutputs(cmGeneratorTarget* target, cmNinjaDeps& outputs);
+  void AppendTargetOutputs(cmGeneratorTarget* target, cmNinjaDeps& outputs,
+                           const std::string& config);
   void AppendTargetDepends(
-    cmGeneratorTarget* target, cmNinjaDeps& outputs,
+    cmGeneratorTarget* target, cmNinjaDeps& outputs, const std::string& config,
     cmNinjaTargetDepends depends = DependOnTargetArtifact);
 
   void AddCustomCommandTarget(cmCustomCommand const* cc,
@@ -74,7 +75,8 @@ public:
   void AppendCustomCommandLines(cmCustomCommandGenerator const& ccg,
                                 std::vector<std::string>& cmdLines);
   void AppendCustomCommandDeps(cmCustomCommandGenerator const& ccg,
-                               cmNinjaDeps& ninjaDeps);
+                               cmNinjaDeps& ninjaDeps,
+                               const std::string& config);
 
 protected:
   std::string ConvertToIncludeReference(
@@ -94,9 +96,10 @@ private:
   void WritePools(std::ostream& os);
 
   void WriteCustomCommandBuildStatement(cmCustomCommand const* cc,
-                                        const cmNinjaDeps& orderOnlyDeps);
+                                        const cmNinjaDeps& orderOnlyDeps,
+                                        const std::string& config);
 
-  void WriteCustomCommandBuildStatements();
+  void WriteCustomCommandBuildStatements(const std::string& config);
 
   std::string MakeCustomLauncher(cmCustomCommandGenerator const& ccg);
 
@@ -104,7 +107,7 @@ private:
                                  std::string const& customStep,
                                  cmGeneratorTarget const* target) const;
 
-  void AdditionalCleanFiles();
+  void AdditionalCleanFiles(const std::string& config);
 
   std::string HomeRelativeOutputPath;
 

+ 15 - 7
Source/cmLocalUnixMakefileGenerator3.cxx

@@ -3,6 +3,7 @@
 #include "cmLocalUnixMakefileGenerator3.h"
 
 #include <algorithm>
+#include <cassert>
 #include <cstdio>
 #include <sstream>
 #include <utility>
@@ -106,6 +107,13 @@ cmLocalUnixMakefileGenerator3::cmLocalUnixMakefileGenerator3(
 
 cmLocalUnixMakefileGenerator3::~cmLocalUnixMakefileGenerator3() = default;
 
+std::string cmLocalUnixMakefileGenerator3::GetConfigName() const
+{
+  auto const& configNames = this->GetConfigNames();
+  assert(configNames.size() == 1);
+  return configNames.front();
+}
+
 void cmLocalUnixMakefileGenerator3::Generate()
 {
   // Record whether some options are enabled to avoid checking many
@@ -162,7 +170,7 @@ void cmLocalUnixMakefileGenerator3::GetLocalObjectFiles(
       continue;
     }
     std::vector<cmSourceFile const*> objectSources;
-    gt->GetObjectSources(objectSources, this->ConfigName);
+    gt->GetObjectSources(objectSources, this->GetConfigName());
     // Compute full path to object file directory for this target.
     std::string dir = cmStrCat(gt->LocalGenerator->GetCurrentBinaryDirectory(),
                                '/', this->GetTargetDirectory(gt.get()), '/');
@@ -401,7 +409,7 @@ void cmLocalUnixMakefileGenerator3::WriteLocalMakefileTargets(
 
       // Add a local name for the rule to relink the target before
       // installation.
-      if (target->NeedRelinkBeforeInstall(this->ConfigName)) {
+      if (target->NeedRelinkBeforeInstall(this->GetConfigName())) {
         makeTargetName = cmStrCat(
           this->GetRelativeTargetDirectory(target.get()), "/preinstall");
         localName = cmStrCat(target->GetName(), "/preinstall");
@@ -858,7 +866,7 @@ void cmLocalUnixMakefileGenerator3::AppendCustomDepends(
   std::vector<std::string>& depends, const std::vector<cmCustomCommand>& ccs)
 {
   for (cmCustomCommand const& cc : ccs) {
-    cmCustomCommandGenerator ccg(cc, this->ConfigName, this);
+    cmCustomCommandGenerator ccg(cc, this->GetConfigName(), this);
     this->AppendCustomDepend(depends, ccg);
   }
 }
@@ -869,7 +877,7 @@ void cmLocalUnixMakefileGenerator3::AppendCustomDepend(
   for (std::string const& d : ccg.GetDepends()) {
     // Lookup the real name of the dependency in case it is a CMake target.
     std::string dep;
-    if (this->GetRealDependency(d, this->ConfigName, dep)) {
+    if (this->GetRealDependency(d, this->GetConfigName(), dep)) {
       depends.push_back(std::move(dep));
     }
   }
@@ -880,7 +888,7 @@ void cmLocalUnixMakefileGenerator3::AppendCustomCommands(
   cmGeneratorTarget* target, std::string const& relative)
 {
   for (cmCustomCommand const& cc : ccs) {
-    cmCustomCommandGenerator ccg(cc, this->ConfigName, this);
+    cmCustomCommandGenerator ccg(cc, this->GetConfigName(), this);
     this->AppendCustomCommand(commands, ccg, target, relative, true);
   }
 }
@@ -1839,7 +1847,7 @@ void cmLocalUnixMakefileGenerator3::WriteDependLanguageInfo(
 
     // Build a list of preprocessor definitions for the target.
     std::set<std::string> defines;
-    this->GetTargetDefines(target, this->ConfigName, implicitLang.first,
+    this->GetTargetDefines(target, this->GetConfigName(), implicitLang.first,
                            defines);
     if (!defines.empty()) {
       /* clang-format off */
@@ -1863,7 +1871,7 @@ void cmLocalUnixMakefileGenerator3::WriteDependLanguageInfo(
     std::vector<std::string> includes;
 
     this->GetIncludeDirectories(includes, target, implicitLang.first,
-                                this->ConfigName);
+                                this->GetConfigName());
     std::string binaryDir = this->GetState()->GetBinaryDirectory();
     if (this->Makefile->IsOn("CMAKE_DEPENDS_IN_PROJECT_ONLY")) {
       std::string const& sourceDir = this->GetState()->GetSourceDirectory();

+ 2 - 0
Source/cmLocalUnixMakefileGenerator3.h

@@ -33,6 +33,8 @@ public:
   cmLocalUnixMakefileGenerator3(cmGlobalGenerator* gg, cmMakefile* mf);
   ~cmLocalUnixMakefileGenerator3() override;
 
+  std::string GetConfigName() const;
+
   void ComputeHomeRelativeOutputPath() override;
 
   /**

+ 29 - 26
Source/cmMakefileExecutableTargetGenerator.cxx

@@ -35,10 +35,9 @@ cmMakefileExecutableTargetGenerator::cmMakefileExecutableTargetGenerator(
 {
   this->CustomCommandDriver = OnDepends;
   this->TargetNames =
-    this->GeneratorTarget->GetExecutableNames(this->ConfigName);
+    this->GeneratorTarget->GetExecutableNames(this->GetConfigName());
 
-  this->OSXBundleGenerator =
-    cm::make_unique<cmOSXBundleGenerator>(target, this->ConfigName);
+  this->OSXBundleGenerator = cm::make_unique<cmOSXBundleGenerator>(target);
   this->OSXBundleGenerator->SetMacContentFolders(&this->MacContentFolders);
 }
 
@@ -64,7 +63,7 @@ void cmMakefileExecutableTargetGenerator::WriteRuleFiles()
 
   // write the link rules
   this->WriteExecutableRule(false);
-  if (this->GeneratorTarget->NeedRelinkBeforeInstall(this->ConfigName)) {
+  if (this->GeneratorTarget->NeedRelinkBeforeInstall(this->GetConfigName())) {
     // Write rules to link an installable version of the target.
     this->WriteExecutableRule(true);
   }
@@ -85,7 +84,7 @@ void cmMakefileExecutableTargetGenerator::WriteDeviceExecutableRule(
 {
 #ifndef CMAKE_BOOTSTRAP
   const bool requiresDeviceLinking = requireDeviceLinking(
-    *this->GeneratorTarget, *this->LocalGenerator, this->ConfigName);
+    *this->GeneratorTarget, *this->LocalGenerator, this->GetConfigName());
   if (!requiresDeviceLinking) {
     return;
   }
@@ -141,10 +140,10 @@ void cmMakefileExecutableTargetGenerator::WriteDeviceExecutableRule(
 
   // Add language feature flags.
   this->LocalGenerator->AddLanguageFlagsForLinking(
-    flags, this->GeneratorTarget, linkLanguage, this->ConfigName);
+    flags, this->GeneratorTarget, linkLanguage, this->GetConfigName());
 
-  this->LocalGenerator->AddArchitectureFlags(flags, this->GeneratorTarget,
-                                             linkLanguage, this->ConfigName);
+  this->LocalGenerator->AddArchitectureFlags(
+    flags, this->GeneratorTarget, linkLanguage, this->GetConfigName());
 
   // Add target-specific linker flags.
   this->GetTargetLinkFlags(linkFlags, linkLanguage);
@@ -213,7 +212,8 @@ void cmMakefileExecutableTargetGenerator::WriteDeviceExecutableRule(
         this->LocalGenerator->GetCurrentBinaryDirectory(), targetOutputReal),
       output);
 
-    std::string targetFullPathCompilePDB = this->ComputeTargetCompilePDB();
+    std::string targetFullPathCompilePDB =
+      this->ComputeTargetCompilePDB(this->GetConfigName());
     std::string targetOutPathCompilePDB =
       this->LocalGenerator->ConvertToOutputFormat(targetFullPathCompilePDB,
                                                   cmOutputConverter::SHELL);
@@ -287,12 +287,14 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
 
   // Get the name of the executable to generate.
   cmGeneratorTarget::Names targetNames =
-    this->GeneratorTarget->GetExecutableNames(this->ConfigName);
+    this->GeneratorTarget->GetExecutableNames(this->GetConfigName());
 
   // Construct the full path version of the names.
-  std::string outpath = this->GeneratorTarget->GetDirectory(this->ConfigName);
+  std::string outpath =
+    this->GeneratorTarget->GetDirectory(this->GetConfigName());
   if (this->GeneratorTarget->IsAppBundleOnApple()) {
-    this->OSXBundleGenerator->CreateAppBundle(targetNames.Output, outpath);
+    this->OSXBundleGenerator->CreateAppBundle(targetNames.Output, outpath,
+                                              this->GetConfigName());
   }
   outpath += '/';
   std::string outpathImp;
@@ -308,18 +310,18 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
     cmSystemTools::MakeDirectory(outpath);
     if (!targetNames.ImportLibrary.empty()) {
       outpathImp = this->GeneratorTarget->GetDirectory(
-        this->ConfigName, cmStateEnums::ImportLibraryArtifact);
+        this->GetConfigName(), cmStateEnums::ImportLibraryArtifact);
       cmSystemTools::MakeDirectory(outpathImp);
       outpathImp += '/';
     }
   }
 
   std::string compilePdbOutputPath =
-    this->GeneratorTarget->GetCompilePDBDirectory(this->ConfigName);
+    this->GeneratorTarget->GetCompilePDBDirectory(this->GetConfigName());
   cmSystemTools::MakeDirectory(compilePdbOutputPath);
 
   std::string pdbOutputPath =
-    this->GeneratorTarget->GetPDBDirectory(this->ConfigName);
+    this->GeneratorTarget->GetPDBDirectory(this->GetConfigName());
   cmSystemTools::MakeDirectory(pdbOutputPath);
   pdbOutputPath += '/';
 
@@ -347,7 +349,7 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
 
   // Get the language to use for linking this executable.
   std::string linkLanguage =
-    this->GeneratorTarget->GetLinkerLanguage(this->ConfigName);
+    this->GeneratorTarget->GetLinkerLanguage(this->GetConfigName());
 
   // Make sure we have a link language.
   if (linkLanguage.empty()) {
@@ -380,7 +382,7 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
 
   // Add flags to create an executable.
   this->LocalGenerator->AddConfigVariableFlags(
-    linkFlags, "CMAKE_EXE_LINKER_FLAGS", this->ConfigName);
+    linkFlags, "CMAKE_EXE_LINKER_FLAGS", this->GetConfigName());
 
   if (this->GeneratorTarget->GetPropertyAsBool("WIN32_EXECUTABLE")) {
     this->LocalGenerator->AppendFlags(
@@ -409,10 +411,10 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
 
   // Add language feature flags.
   this->LocalGenerator->AddLanguageFlagsForLinking(
-    flags, this->GeneratorTarget, linkLanguage, this->ConfigName);
+    flags, this->GeneratorTarget, linkLanguage, this->GetConfigName());
 
-  this->LocalGenerator->AddArchitectureFlags(flags, this->GeneratorTarget,
-                                             linkLanguage, this->ConfigName);
+  this->LocalGenerator->AddArchitectureFlags(
+    flags, this->GeneratorTarget, linkLanguage, this->GetConfigName());
 
   // Add target-specific linker flags.
   this->GetTargetLinkFlags(linkFlags, linkLanguage);
@@ -423,11 +425,12 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
         this->LocalGenerator,
         this->LocalGenerator->GetStateSnapshot().GetDirectory()));
 
-    this->AddModuleDefinitionFlag(linkLineComputer.get(), linkFlags);
+    this->AddModuleDefinitionFlag(linkLineComputer.get(), linkFlags,
+                                  this->GetConfigName());
   }
 
-  this->LocalGenerator->AppendIPOLinkerFlags(linkFlags, this->GeneratorTarget,
-                                             this->ConfigName, linkLanguage);
+  this->LocalGenerator->AppendIPOLinkerFlags(
+    linkFlags, this->GeneratorTarget, this->GetConfigName(), linkLanguage);
 
   // Construct a list of files associated with this executable that
   // may need to be cleaned.
@@ -451,7 +454,7 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
       targetFullPathImport));
     std::string implib;
     if (this->GeneratorTarget->GetImplibGNUtoMS(
-          this->ConfigName, targetFullPathImport, implib)) {
+          this->GetConfigName(), targetFullPathImport, implib)) {
       exeCleanFiles.push_back(this->LocalGenerator->MaybeConvertToRelativePath(
         this->LocalGenerator->GetCurrentBinaryDirectory(), implib));
     }
@@ -479,7 +482,7 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
   // Construct the main link rule.
   std::vector<std::string> real_link_commands;
   std::string linkRuleVar = this->GeneratorTarget->GetCreateRuleVariable(
-    linkLanguage, this->ConfigName);
+    linkLanguage, this->GetConfigName());
   std::string linkRule = this->GetLinkRule(linkRuleVar);
   std::vector<std::string> commands1;
   cmExpandList(linkRule, real_link_commands);
@@ -536,7 +539,7 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
     // maybe create .def file from list of objects
     this->GenDefFile(real_link_commands);
 
-    std::string manifests = this->GetManifests();
+    std::string manifests = this->GetManifests(this->GetConfigName());
 
     cmRulePlaceholderExpander::RuleVariables vars;
     vars.CMTargetName = this->GeneratorTarget->GetName().c_str();

+ 48 - 44
Source/cmMakefileLibraryTargetGenerator.cxx

@@ -36,11 +36,10 @@ cmMakefileLibraryTargetGenerator::cmMakefileLibraryTargetGenerator(
   this->CustomCommandDriver = OnDepends;
   if (this->GeneratorTarget->GetType() != cmStateEnums::INTERFACE_LIBRARY) {
     this->TargetNames =
-      this->GeneratorTarget->GetLibraryNames(this->ConfigName);
+      this->GeneratorTarget->GetLibraryNames(this->GetConfigName());
   }
 
-  this->OSXBundleGenerator =
-    cm::make_unique<cmOSXBundleGenerator>(target, this->ConfigName);
+  this->OSXBundleGenerator = cm::make_unique<cmOSXBundleGenerator>(target);
   this->OSXBundleGenerator->SetMacContentFolders(&this->MacContentFolders);
 }
 
@@ -69,14 +68,16 @@ void cmMakefileLibraryTargetGenerator::WriteRuleFiles()
       break;
     case cmStateEnums::SHARED_LIBRARY:
       this->WriteSharedLibraryRules(false);
-      if (this->GeneratorTarget->NeedRelinkBeforeInstall(this->ConfigName)) {
+      if (this->GeneratorTarget->NeedRelinkBeforeInstall(
+            this->GetConfigName())) {
         // Write rules to link an installable version of the target.
         this->WriteSharedLibraryRules(true);
       }
       break;
     case cmStateEnums::MODULE_LIBRARY:
       this->WriteModuleLibraryRules(false);
-      if (this->GeneratorTarget->NeedRelinkBeforeInstall(this->ConfigName)) {
+      if (this->GeneratorTarget->NeedRelinkBeforeInstall(
+            this->GetConfigName())) {
         // Write rules to link an installable version of the target.
         this->WriteModuleLibraryRules(true);
       }
@@ -126,21 +127,21 @@ void cmMakefileLibraryTargetGenerator::WriteObjectLibraryRules()
 void cmMakefileLibraryTargetGenerator::WriteStaticLibraryRules()
 {
   const bool requiresDeviceLinking = requireDeviceLinking(
-    *this->GeneratorTarget, *this->LocalGenerator, this->ConfigName);
+    *this->GeneratorTarget, *this->LocalGenerator, this->GetConfigName());
   if (requiresDeviceLinking) {
     std::string linkRuleVar = "CMAKE_CUDA_DEVICE_LINK_LIBRARY";
     this->WriteDeviceLibraryRules(linkRuleVar, false);
   }
 
   std::string linkLanguage =
-    this->GeneratorTarget->GetLinkerLanguage(this->ConfigName);
+    this->GeneratorTarget->GetLinkerLanguage(this->GetConfigName());
 
   std::string linkRuleVar = this->GeneratorTarget->GetCreateRuleVariable(
-    linkLanguage, this->ConfigName);
+    linkLanguage, this->GetConfigName());
 
   std::string extraFlags;
   this->LocalGenerator->GetStaticLibraryFlags(
-    extraFlags, cmSystemTools::UpperCase(this->ConfigName), linkLanguage,
+    extraFlags, cmSystemTools::UpperCase(this->GetConfigName()), linkLanguage,
     this->GeneratorTarget);
   this->WriteLibraryRules(linkRuleVar, extraFlags, false);
 }
@@ -154,7 +155,7 @@ void cmMakefileLibraryTargetGenerator::WriteSharedLibraryRules(bool relink)
 
   if (!relink) {
     const bool requiresDeviceLinking = requireDeviceLinking(
-      *this->GeneratorTarget, *this->LocalGenerator, this->ConfigName);
+      *this->GeneratorTarget, *this->LocalGenerator, this->GetConfigName());
     if (requiresDeviceLinking) {
       std::string linkRuleVar = "CMAKE_CUDA_DEVICE_LINK_LIBRARY";
       this->WriteDeviceLibraryRules(linkRuleVar, relink);
@@ -162,21 +163,22 @@ void cmMakefileLibraryTargetGenerator::WriteSharedLibraryRules(bool relink)
   }
 
   std::string linkLanguage =
-    this->GeneratorTarget->GetLinkerLanguage(this->ConfigName);
+    this->GeneratorTarget->GetLinkerLanguage(this->GetConfigName());
   std::string linkRuleVar =
     cmStrCat("CMAKE_", linkLanguage, "_CREATE_SHARED_LIBRARY");
 
   std::string extraFlags;
   this->GetTargetLinkFlags(extraFlags, linkLanguage);
   this->LocalGenerator->AddConfigVariableFlags(
-    extraFlags, "CMAKE_SHARED_LINKER_FLAGS", this->ConfigName);
+    extraFlags, "CMAKE_SHARED_LINKER_FLAGS", this->GetConfigName());
 
   std::unique_ptr<cmLinkLineComputer> linkLineComputer(
     this->CreateLinkLineComputer(
       this->LocalGenerator,
       this->LocalGenerator->GetStateSnapshot().GetDirectory()));
 
-  this->AddModuleDefinitionFlag(linkLineComputer.get(), extraFlags);
+  this->AddModuleDefinitionFlag(linkLineComputer.get(), extraFlags,
+                                this->GetConfigName());
 
   if (this->GeneratorTarget->GetPropertyAsBool("LINK_WHAT_YOU_USE")) {
     this->LocalGenerator->AppendFlags(extraFlags, " -Wl,--no-as-needed");
@@ -188,7 +190,7 @@ void cmMakefileLibraryTargetGenerator::WriteModuleLibraryRules(bool relink)
 {
   if (!relink) {
     const bool requiresDeviceLinking = requireDeviceLinking(
-      *this->GeneratorTarget, *this->LocalGenerator, this->ConfigName);
+      *this->GeneratorTarget, *this->LocalGenerator, this->GetConfigName());
     if (requiresDeviceLinking) {
       std::string linkRuleVar = "CMAKE_CUDA_DEVICE_LINK_LIBRARY";
       this->WriteDeviceLibraryRules(linkRuleVar, relink);
@@ -196,21 +198,22 @@ void cmMakefileLibraryTargetGenerator::WriteModuleLibraryRules(bool relink)
   }
 
   std::string linkLanguage =
-    this->GeneratorTarget->GetLinkerLanguage(this->ConfigName);
+    this->GeneratorTarget->GetLinkerLanguage(this->GetConfigName());
   std::string linkRuleVar =
     cmStrCat("CMAKE_", linkLanguage, "_CREATE_SHARED_MODULE");
 
   std::string extraFlags;
   this->GetTargetLinkFlags(extraFlags, linkLanguage);
   this->LocalGenerator->AddConfigVariableFlags(
-    extraFlags, "CMAKE_MODULE_LINKER_FLAGS", this->ConfigName);
+    extraFlags, "CMAKE_MODULE_LINKER_FLAGS", this->GetConfigName());
 
   std::unique_ptr<cmLinkLineComputer> linkLineComputer(
     this->CreateLinkLineComputer(
       this->LocalGenerator,
       this->LocalGenerator->GetStateSnapshot().GetDirectory()));
 
-  this->AddModuleDefinitionFlag(linkLineComputer.get(), extraFlags);
+  this->AddModuleDefinitionFlag(linkLineComputer.get(), extraFlags,
+                                this->GetConfigName());
 
   this->WriteLibraryRules(linkRuleVar, extraFlags, relink);
 }
@@ -218,14 +221,14 @@ void cmMakefileLibraryTargetGenerator::WriteModuleLibraryRules(bool relink)
 void cmMakefileLibraryTargetGenerator::WriteFrameworkRules(bool relink)
 {
   std::string linkLanguage =
-    this->GeneratorTarget->GetLinkerLanguage(this->ConfigName);
+    this->GeneratorTarget->GetLinkerLanguage(this->GetConfigName());
   std::string linkRuleVar =
     cmStrCat("CMAKE_", linkLanguage, "_CREATE_MACOSX_FRAMEWORK");
 
   std::string extraFlags;
   this->GetTargetLinkFlags(extraFlags, linkLanguage);
   this->LocalGenerator->AddConfigVariableFlags(
-    extraFlags, "CMAKE_MACOSX_FRAMEWORK_LINKER_FLAGS", this->ConfigName);
+    extraFlags, "CMAKE_MACOSX_FRAMEWORK_LINKER_FLAGS", this->GetConfigName());
 
   this->WriteLibraryRules(linkRuleVar, extraFlags, relink);
 }
@@ -331,7 +334,8 @@ void cmMakefileLibraryTargetGenerator::WriteDeviceLibraryRules(
         this->LocalGenerator->GetCurrentBinaryDirectory(), targetOutputReal),
       output);
 
-    std::string targetFullPathCompilePDB = this->ComputeTargetCompilePDB();
+    std::string targetFullPathCompilePDB =
+      this->ComputeTargetCompilePDB(this->GetConfigName());
     std::string targetOutPathCompilePDB =
       this->LocalGenerator->ConvertToOutputFormat(targetFullPathCompilePDB,
                                                   cmOutputConverter::SHELL);
@@ -347,7 +351,7 @@ void cmMakefileLibraryTargetGenerator::WriteDeviceLibraryRules(
     // Add language-specific flags.
     std::string langFlags;
     this->LocalGenerator->AddLanguageFlagsForLinking(
-      langFlags, this->GeneratorTarget, linkLanguage, this->ConfigName);
+      langFlags, this->GeneratorTarget, linkLanguage, this->GetConfigName());
 
     vars.LanguageCompileFlags = langFlags.c_str();
 
@@ -420,7 +424,7 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules(
 
   // Get the language to use for linking this library.
   std::string linkLanguage =
-    this->GeneratorTarget->GetLinkerLanguage(this->ConfigName);
+    this->GeneratorTarget->GetLinkerLanguage(this->GetConfigName());
 
   // Make sure we have a link language.
   if (linkLanguage.empty()) {
@@ -439,8 +443,8 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules(
   // Create set of linking flags.
   std::string linkFlags;
   this->LocalGenerator->AppendFlags(linkFlags, extraFlags);
-  this->LocalGenerator->AppendIPOLinkerFlags(linkFlags, this->GeneratorTarget,
-                                             this->ConfigName, linkLanguage);
+  this->LocalGenerator->AppendIPOLinkerFlags(
+    linkFlags, this->GeneratorTarget, this->GetConfigName(), linkLanguage);
 
   // Add OSX version flags, if any.
   if (this->GeneratorTarget->GetType() == cmStateEnums::SHARED_LIBRARY ||
@@ -450,20 +454,20 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules(
   }
 
   // Construct the name of the library.
-  this->GeneratorTarget->GetLibraryNames(this->ConfigName);
+  this->GeneratorTarget->GetLibraryNames(this->GetConfigName());
 
   // Construct the full path version of the names.
   std::string outpath;
   std::string outpathImp;
   if (this->GeneratorTarget->IsFrameworkOnApple()) {
-    outpath = this->GeneratorTarget->GetDirectory(this->ConfigName);
+    outpath = this->GeneratorTarget->GetDirectory(this->GetConfigName());
     this->OSXBundleGenerator->CreateFramework(this->TargetNames.Output,
-                                              outpath);
+                                              outpath, this->GetConfigName());
     outpath += '/';
   } else if (this->GeneratorTarget->IsCFBundleOnApple()) {
-    outpath = this->GeneratorTarget->GetDirectory(this->ConfigName);
-    this->OSXBundleGenerator->CreateCFBundle(this->TargetNames.Output,
-                                             outpath);
+    outpath = this->GeneratorTarget->GetDirectory(this->GetConfigName());
+    this->OSXBundleGenerator->CreateCFBundle(this->TargetNames.Output, outpath,
+                                             this->GetConfigName());
     outpath += '/';
   } else if (relink) {
     outpath = cmStrCat(this->Makefile->GetCurrentBinaryDirectory(),
@@ -474,23 +478,23 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules(
       outpathImp = outpath;
     }
   } else {
-    outpath = this->GeneratorTarget->GetDirectory(this->ConfigName);
+    outpath = this->GeneratorTarget->GetDirectory(this->GetConfigName());
     cmSystemTools::MakeDirectory(outpath);
     outpath += '/';
     if (!this->TargetNames.ImportLibrary.empty()) {
       outpathImp = this->GeneratorTarget->GetDirectory(
-        this->ConfigName, cmStateEnums::ImportLibraryArtifact);
+        this->GetConfigName(), cmStateEnums::ImportLibraryArtifact);
       cmSystemTools::MakeDirectory(outpathImp);
       outpathImp += '/';
     }
   }
 
   std::string compilePdbOutputPath =
-    this->GeneratorTarget->GetCompilePDBDirectory(this->ConfigName);
+    this->GeneratorTarget->GetCompilePDBDirectory(this->GetConfigName());
   cmSystemTools::MakeDirectory(compilePdbOutputPath);
 
   std::string pdbOutputPath =
-    this->GeneratorTarget->GetPDBDirectory(this->ConfigName);
+    this->GeneratorTarget->GetPDBDirectory(this->GetConfigName());
   cmSystemTools::MakeDirectory(pdbOutputPath);
   pdbOutputPath += "/";
 
@@ -586,7 +590,7 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules(
       targetFullPathImport));
     std::string implib;
     if (this->GeneratorTarget->GetImplibGNUtoMS(
-          this->ConfigName, targetFullPathImport, implib)) {
+          this->GetConfigName(), targetFullPathImport, implib)) {
       libCleanFiles.insert(this->LocalGenerator->MaybeConvertToRelativePath(
         this->LocalGenerator->GetCurrentBinaryDirectory(), implib));
     }
@@ -638,7 +642,7 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules(
       cmStrCat("CMAKE_", linkLanguage, "_ARCHIVE_CREATE");
 
     arCreateVar = this->GeneratorTarget->GetFeatureSpecificLinkRuleVariable(
-      arCreateVar, linkLanguage, this->ConfigName);
+      arCreateVar, linkLanguage, this->GetConfigName());
 
     if (const char* rule = this->Makefile->GetDefinition(arCreateVar)) {
       cmExpandList(rule, archiveCreateCommands);
@@ -647,7 +651,7 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules(
       cmStrCat("CMAKE_", linkLanguage, "_ARCHIVE_APPEND");
 
     arAppendVar = this->GeneratorTarget->GetFeatureSpecificLinkRuleVariable(
-      arAppendVar, linkLanguage, this->ConfigName);
+      arAppendVar, linkLanguage, this->GetConfigName());
 
     if (const char* rule = this->Makefile->GetDefinition(arAppendVar)) {
       cmExpandList(rule, archiveAppendCommands);
@@ -656,7 +660,7 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules(
       cmStrCat("CMAKE_", linkLanguage, "_ARCHIVE_FINISH");
 
     arFinishVar = this->GeneratorTarget->GetFeatureSpecificLinkRuleVariable(
-      arFinishVar, linkLanguage, this->ConfigName);
+      arFinishVar, linkLanguage, this->GetConfigName());
 
     if (const char* rule = this->Makefile->GetDefinition(arFinishVar)) {
       cmExpandList(rule, archiveFinishCommands);
@@ -726,7 +730,7 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules(
     // maybe create .def file from list of objects
     this->GenDefFile(real_link_commands);
 
-    std::string manifests = this->GetManifests();
+    std::string manifests = this->GetManifests(this->GetConfigName());
 
     cmRulePlaceholderExpander::RuleVariables vars;
     vars.TargetPDB = targetOutPathPDB.c_str();
@@ -771,7 +775,7 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules(
     vars.Target = target.c_str();
     vars.LinkLibraries = linkLibs.c_str();
     vars.ObjectsQuoted = buildObjs.c_str();
-    if (this->GeneratorTarget->HasSOName(this->ConfigName)) {
+    if (this->GeneratorTarget->HasSOName(this->GetConfigName())) {
       vars.SONameFlag = this->Makefile->GetSONameFlag(linkLanguage);
       vars.TargetSOName = this->TargetNames.SharedObject.c_str();
     }
@@ -783,8 +787,8 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules(
     std::string install_name_dir;
     if (this->GeneratorTarget->GetType() == cmStateEnums::SHARED_LIBRARY) {
       // Get the install_name directory for the build tree.
-      install_name_dir =
-        this->GeneratorTarget->GetInstallNameDirForBuildTree(this->ConfigName);
+      install_name_dir = this->GeneratorTarget->GetInstallNameDirForBuildTree(
+        this->GetConfigName());
 
       // Set the rule variable replacement value.
       if (install_name_dir.empty()) {
@@ -800,10 +804,10 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules(
     // Add language-specific flags.
     std::string langFlags;
     this->LocalGenerator->AddLanguageFlagsForLinking(
-      langFlags, this->GeneratorTarget, linkLanguage, this->ConfigName);
+      langFlags, this->GeneratorTarget, linkLanguage, this->GetConfigName());
 
     this->LocalGenerator->AddArchitectureFlags(
-      langFlags, this->GeneratorTarget, linkLanguage, this->ConfigName);
+      langFlags, this->GeneratorTarget, linkLanguage, this->GetConfigName());
 
     vars.LanguageCompileFlags = langFlags.c_str();
 

+ 73 - 50
Source/cmMakefileTargetGenerator.cxx

@@ -2,6 +2,7 @@
    file Copyright.txt or https://cmake.org/licensing for details.  */
 #include "cmMakefileTargetGenerator.h"
 
+#include <cassert>
 #include <cstdio>
 #include <memory>
 #include <sstream>
@@ -85,6 +86,13 @@ cmMakefileTargetGenerator* cmMakefileTargetGenerator::New(
   return result;
 }
 
+std::string cmMakefileTargetGenerator::GetConfigName()
+{
+  auto const& configNames = this->LocalGenerator->GetConfigNames();
+  assert(configNames.size() == 1);
+  return configNames.front();
+}
+
 void cmMakefileTargetGenerator::GetTargetLinkFlags(
   std::string& flags, const std::string& linkLanguage)
 {
@@ -92,17 +100,18 @@ void cmMakefileTargetGenerator::GetTargetLinkFlags(
     flags, this->GeneratorTarget->GetSafeProperty("LINK_FLAGS"));
 
   std::string linkFlagsConfig =
-    cmStrCat("LINK_FLAGS_", cmSystemTools::UpperCase(this->ConfigName));
+    cmStrCat("LINK_FLAGS_", cmSystemTools::UpperCase(this->GetConfigName()));
   this->LocalGenerator->AppendFlags(
     flags, this->GeneratorTarget->GetSafeProperty(linkFlagsConfig));
 
   std::vector<std::string> opts;
-  this->GeneratorTarget->GetLinkOptions(opts, this->ConfigName, linkLanguage);
+  this->GeneratorTarget->GetLinkOptions(opts, this->GetConfigName(),
+                                        linkLanguage);
   // LINK_OPTIONS are escaped.
   this->LocalGenerator->AppendCompileOptions(flags, opts);
 
   this->LocalGenerator->AppendPositionIndependentLinkerFlags(
-    flags, this->GeneratorTarget, this->ConfigName, linkLanguage);
+    flags, this->GeneratorTarget, this->GetConfigName(), linkLanguage);
 }
 
 void cmMakefileTargetGenerator::CreateRuleFile()
@@ -154,10 +163,10 @@ void cmMakefileTargetGenerator::WriteTargetBuildRules()
   auto evaluatedFiles =
     [this](const char* prop_value) -> std::vector<std::string> {
     std::vector<std::string> files;
-    cmExpandList(
-      cmGeneratorExpression::Evaluate(prop_value, this->LocalGenerator,
-                                      this->ConfigName, this->GeneratorTarget),
-      files);
+    cmExpandList(cmGeneratorExpression::Evaluate(
+                   prop_value, this->LocalGenerator, this->GetConfigName(),
+                   this->GeneratorTarget),
+                 files);
     return files;
   };
 
@@ -187,12 +196,13 @@ void cmMakefileTargetGenerator::WriteTargetBuildRules()
   // First generate the object rule files.  Save a list of all object
   // files for this target.
   std::vector<cmSourceFile const*> customCommands;
-  this->GeneratorTarget->GetCustomCommands(customCommands, this->ConfigName);
+  this->GeneratorTarget->GetCustomCommands(customCommands,
+                                           this->GetConfigName());
   std::string currentBinDir =
     this->LocalGenerator->GetCurrentBinaryDirectory();
   for (cmSourceFile const* sf : customCommands) {
-    cmCustomCommandGenerator ccg(*sf->GetCustomCommand(), this->ConfigName,
-                                 this->LocalGenerator);
+    cmCustomCommandGenerator ccg(*sf->GetCustomCommand(),
+                                 this->GetConfigName(), this->LocalGenerator);
     this->GenerateCustomRuleFile(ccg);
     if (clean) {
       const std::vector<std::string>& outputs = ccg.GetOutputs();
@@ -220,7 +230,8 @@ void cmMakefileTargetGenerator::WriteTargetBuildRules()
              this->GeneratorTarget->GetPostBuildCommands());
 
     for (const auto& be : buildEventCommands) {
-      cmCustomCommandGenerator beg(be, this->ConfigName, this->LocalGenerator);
+      cmCustomCommandGenerator beg(be, this->GetConfigName(),
+                                   this->LocalGenerator);
       const std::vector<std::string>& byproducts = beg.GetByproducts();
       for (std::string const& byproduct : byproducts) {
         this->CleanFiles.insert(
@@ -230,17 +241,19 @@ void cmMakefileTargetGenerator::WriteTargetBuildRules()
     }
   }
   std::vector<cmSourceFile const*> headerSources;
-  this->GeneratorTarget->GetHeaderSources(headerSources, this->ConfigName);
+  this->GeneratorTarget->GetHeaderSources(headerSources,
+                                          this->GetConfigName());
   this->OSXBundleGenerator->GenerateMacOSXContentStatements(
-    headerSources, this->MacOSXContentGenerator);
+    headerSources, this->MacOSXContentGenerator, this->GetConfigName());
   std::vector<cmSourceFile const*> extraSources;
-  this->GeneratorTarget->GetExtraSources(extraSources, this->ConfigName);
+  this->GeneratorTarget->GetExtraSources(extraSources, this->GetConfigName());
   this->OSXBundleGenerator->GenerateMacOSXContentStatements(
-    extraSources, this->MacOSXContentGenerator);
+    extraSources, this->MacOSXContentGenerator, this->GetConfigName());
   const char* pchExtension =
     this->Makefile->GetDefinition("CMAKE_PCH_EXTENSION");
   std::vector<cmSourceFile const*> externalObjects;
-  this->GeneratorTarget->GetExternalObjects(externalObjects, this->ConfigName);
+  this->GeneratorTarget->GetExternalObjects(externalObjects,
+                                            this->GetConfigName());
   for (cmSourceFile const* sf : externalObjects) {
     auto const& objectFileName = sf->GetFullPath();
     if (!cmSystemTools::StringEndsWith(objectFileName, pchExtension)) {
@@ -248,7 +261,8 @@ void cmMakefileTargetGenerator::WriteTargetBuildRules()
     }
   }
   std::vector<cmSourceFile const*> objectSources;
-  this->GeneratorTarget->GetObjectSources(objectSources, this->ConfigName);
+  this->GeneratorTarget->GetObjectSources(objectSources,
+                                          this->GetConfigName());
   for (cmSourceFile const* sf : objectSources) {
     // Generate this object file's rule file.
     this->WriteObjectRuleFiles(*sf);
@@ -334,9 +348,9 @@ void cmMakefileTargetGenerator::WriteTargetLanguageFlags()
   }
 
   for (std::string const& language : languages) {
-    std::string flags = this->GetFlags(language);
-    std::string defines = this->GetDefines(language);
-    std::string includes = this->GetIncludes(language);
+    std::string flags = this->GetFlags(language, this->GetConfigName());
+    std::string defines = this->GetDefines(language, this->GetConfigName());
+    std::string includes = this->GetIncludes(language, this->GetConfigName());
     // Escape comment characters so they do not terminate assignment.
     cmSystemTools::ReplaceString(flags, "#", "\\#");
     cmSystemTools::ReplaceString(defines, "#", "\\#");
@@ -348,7 +362,7 @@ void cmMakefileTargetGenerator::WriteTargetLanguageFlags()
 }
 
 void cmMakefileTargetGenerator::MacOSXContentGeneratorType::operator()(
-  cmSourceFile const& source, const char* pkgloc)
+  cmSourceFile const& source, const char* pkgloc, const std::string& config)
 {
   // Skip OS X content when not building a Framework or Bundle.
   if (!this->Generator->GetGeneratorTarget()->IsBundleOnApple()) {
@@ -356,7 +370,8 @@ void cmMakefileTargetGenerator::MacOSXContentGeneratorType::operator()(
   }
 
   std::string macdir =
-    this->Generator->OSXBundleGenerator->InitMacOSXContentDirectory(pkgloc);
+    this->Generator->OSXBundleGenerator->InitMacOSXContentDirectory(pkgloc,
+                                                                    config);
 
   // Get the input file location.
   std::string const& input = source.GetFullPath();
@@ -451,7 +466,7 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles(
   // generate the depend scanning rule
   this->WriteObjectDependRules(source, depends);
 
-  std::string config = this->LocalGenerator->GetConfigName();
+  std::string config = this->GetConfigName();
   std::string configUpper = cmSystemTools::UpperCase(config);
 
   // Add precompile headers dependencies
@@ -593,16 +608,17 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles(
   {
     std::string targetFullPathReal;
     std::string targetFullPathPDB;
-    std::string targetFullPathCompilePDB = this->ComputeTargetCompilePDB();
+    std::string targetFullPathCompilePDB =
+      this->ComputeTargetCompilePDB(this->GetConfigName());
     if (this->GeneratorTarget->GetType() == cmStateEnums::EXECUTABLE ||
         this->GeneratorTarget->GetType() == cmStateEnums::STATIC_LIBRARY ||
         this->GeneratorTarget->GetType() == cmStateEnums::SHARED_LIBRARY ||
         this->GeneratorTarget->GetType() == cmStateEnums::MODULE_LIBRARY) {
       targetFullPathReal = this->GeneratorTarget->GetFullPath(
-        this->ConfigName, cmStateEnums::RuntimeBinaryArtifact, true);
-      targetFullPathPDB =
-        cmStrCat(this->GeneratorTarget->GetPDBDirectory(this->ConfigName), '/',
-                 this->GeneratorTarget->GetPDBName(this->ConfigName));
+        this->GetConfigName(), cmStateEnums::RuntimeBinaryArtifact, true);
+      targetFullPathPDB = cmStrCat(
+        this->GeneratorTarget->GetPDBDirectory(this->GetConfigName()), '/',
+        this->GeneratorTarget->GetPDBName(this->GetConfigName()));
     }
 
     targetOutPathReal = this->LocalGenerator->ConvertToOutputFormat(
@@ -708,13 +724,15 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles(
       std::string workingDirectory = cmSystemTools::CollapseFullPath(
         this->LocalGenerator->GetCurrentBinaryDirectory());
       compileCommand.replace(compileCommand.find(langFlags), langFlags.size(),
-                             this->GetFlags(lang));
+                             this->GetFlags(lang, this->GetConfigName()));
       std::string langDefines = std::string("$(") + lang + "_DEFINES)";
       compileCommand.replace(compileCommand.find(langDefines),
-                             langDefines.size(), this->GetDefines(lang));
+                             langDefines.size(),
+                             this->GetDefines(lang, this->GetConfigName()));
       std::string langIncludes = std::string("$(") + lang + "_INCLUDES)";
       compileCommand.replace(compileCommand.find(langIncludes),
-                             langIncludes.size(), this->GetIncludes(lang));
+                             langIncludes.size(),
+                             this->GetIncludes(lang, this->GetConfigName()));
 
       const char* eliminate[] = {
         this->Makefile->GetDefinition("CMAKE_START_TEMP_FILE"),
@@ -1068,7 +1086,8 @@ void cmMakefileTargetGenerator::WriteTargetDependRules()
     << "# Targets to which this target links.\n"
     << "set(CMAKE_TARGET_LINKED_INFO_FILES\n";
     /* clang-format on */
-    std::vector<std::string> dirs = this->GetLinkedTargetDirectories();
+    std::vector<std::string> dirs =
+      this->GetLinkedTargetDirectories(this->GetConfigName());
     for (std::string const& d : dirs) {
       *this->InfoFileStream << "  \"" << d << "/DependInfo.cmake\"\n";
     }
@@ -1171,7 +1190,7 @@ void cmMakefileTargetGenerator::DriveCustomCommands(
     sources, this->Makefile->GetSafeDefinition("CMAKE_BUILD_TYPE"));
   for (cmSourceFile* source : sources) {
     if (cmCustomCommand* cc = source->GetCustomCommand()) {
-      cmCustomCommandGenerator ccg(*cc, this->ConfigName,
+      cmCustomCommandGenerator ccg(*cc, this->GetConfigName(),
                                    this->LocalGenerator);
       cmAppend(depends, ccg.GetOutputs());
     }
@@ -1429,7 +1448,7 @@ void cmMakefileTargetGenerator::AppendTargetDepends(
   }
 
   // Loop over all library dependencies.
-  const std::string& cfg = this->LocalGenerator->GetConfigName();
+  const std::string& cfg = this->GetConfigName();
   if (cmComputeLinkInformation* cli =
         this->GeneratorTarget->GetLinkInformation(cfg)) {
     cmAppend(depends, cli->GetDepends());
@@ -1474,13 +1493,13 @@ void cmMakefileTargetGenerator::AppendLinkDepends(
 
   // Add a dependency on user-specified manifest files, if any.
   std::vector<cmSourceFile const*> manifest_srcs;
-  this->GeneratorTarget->GetManifests(manifest_srcs, this->ConfigName);
+  this->GeneratorTarget->GetManifests(manifest_srcs, this->GetConfigName());
   for (cmSourceFile const* manifest_src : manifest_srcs) {
     depends.push_back(manifest_src->GetFullPath());
   }
 
   // Add user-specified dependencies.
-  this->GeneratorTarget->GetLinkDepends(depends, this->ConfigName,
+  this->GeneratorTarget->GetLinkDepends(depends, this->GetConfigName(),
                                         linkLanguage);
 }
 
@@ -1488,10 +1507,11 @@ std::string cmMakefileTargetGenerator::GetLinkRule(
   const std::string& linkRuleVar)
 {
   std::string linkRule = this->Makefile->GetRequiredDefinition(linkRuleVar);
-  if (this->GeneratorTarget->HasImplibGNUtoMS(this->ConfigName)) {
-    std::string ruleVar = cmStrCat(
-      "CMAKE_", this->GeneratorTarget->GetLinkerLanguage(this->ConfigName),
-      "_GNUtoMS_RULE");
+  if (this->GeneratorTarget->HasImplibGNUtoMS(this->GetConfigName())) {
+    std::string ruleVar =
+      cmStrCat("CMAKE_",
+               this->GeneratorTarget->GetLinkerLanguage(this->GetConfigName()),
+               "_GNUtoMS_RULE");
     if (const char* rule = this->Makefile->GetDefinition(ruleVar)) {
       linkRule += rule;
     }
@@ -1630,7 +1650,7 @@ void cmMakefileTargetGenerator::CreateLinkLibs(
   std::string frameworkPath;
   std::string linkPath;
   cmComputeLinkInformation* pcli =
-    this->GeneratorTarget->GetLinkInformation(this->ConfigName);
+    this->GeneratorTarget->GetLinkInformation(this->GetConfigName());
   this->LocalGenerator->OutputLinkLibraries(pcli, linkLineComputer, linkLibs,
                                             frameworkPath, linkPath);
   linkLibs = frameworkPath + linkPath + linkLibs;
@@ -1638,9 +1658,10 @@ void cmMakefileTargetGenerator::CreateLinkLibs(
   if (useResponseFile &&
       linkLibs.find_first_not_of(' ') != std::string::npos) {
     // Lookup the response file reference flag.
-    std::string responseFlagVar = cmStrCat(
-      "CMAKE_", this->GeneratorTarget->GetLinkerLanguage(this->ConfigName),
-      "_RESPONSE_FILE_LINK_FLAG");
+    std::string responseFlagVar =
+      cmStrCat("CMAKE_",
+               this->GeneratorTarget->GetLinkerLanguage(this->GetConfigName()),
+               "_RESPONSE_FILE_LINK_FLAG");
     const char* responseFlag = this->Makefile->GetDefinition(responseFlagVar);
     if (!responseFlag) {
       responseFlag = "@";
@@ -1675,9 +1696,10 @@ void cmMakefileTargetGenerator::CreateObjectLists(
     this->WriteObjectsStrings(object_strings, responseFileLimit);
 
     // Lookup the response file reference flag.
-    std::string responseFlagVar = cmStrCat(
-      "CMAKE_", this->GeneratorTarget->GetLinkerLanguage(this->ConfigName),
-      "_RESPONSE_FILE_LINK_FLAG");
+    std::string responseFlagVar =
+      cmStrCat("CMAKE_",
+               this->GeneratorTarget->GetLinkerLanguage(this->GetConfigName()),
+               "_RESPONSE_FILE_LINK_FLAG");
     const char* responseFlag = this->Makefile->GetDefinition(responseFlagVar);
     if (!responseFlag) {
       responseFlag = "@";
@@ -1716,7 +1738,8 @@ void cmMakefileTargetGenerator::CreateObjectLists(
 }
 
 void cmMakefileTargetGenerator::AddIncludeFlags(std::string& flags,
-                                                const std::string& lang)
+                                                const std::string& lang,
+                                                const std::string& /*config*/)
 {
   std::string responseVar =
     cmStrCat("CMAKE_", lang, "_USE_RESPONSE_FILE_FOR_INCLUDES");
@@ -1724,11 +1747,11 @@ void cmMakefileTargetGenerator::AddIncludeFlags(std::string& flags,
 
   std::vector<std::string> includes;
   this->LocalGenerator->GetIncludeDirectories(includes, this->GeneratorTarget,
-                                              lang, this->ConfigName);
+                                              lang, this->GetConfigName());
 
   std::string includeFlags = this->LocalGenerator->GetIncludeFlags(
     includes, this->GeneratorTarget, lang, false, useResponseFile,
-    this->ConfigName);
+    this->GetConfigName());
   if (includeFlags.empty()) {
     return;
   }

+ 6 - 2
Source/cmMakefileTargetGenerator.h

@@ -52,6 +52,8 @@ public:
 
   cmGeneratorTarget* GetGeneratorTarget() { return this->GeneratorTarget; }
 
+  std::string GetConfigName();
+
 protected:
   void GetTargetLinkFlags(std::string& flags, const std::string& linkLanguage);
 
@@ -81,7 +83,8 @@ protected:
     {
     }
 
-    void operator()(cmSourceFile const& source, const char* pkgloc) override;
+    void operator()(cmSourceFile const& source, const char* pkgloc,
+                    const std::string& config) override;
 
   private:
     cmMakefileTargetGenerator* Generator;
@@ -163,7 +166,8 @@ protected:
   /** Add commands for generate def files */
   void GenDefFile(std::vector<std::string>& real_link_commands);
 
-  void AddIncludeFlags(std::string& flags, const std::string& lang) override;
+  void AddIncludeFlags(std::string& flags, const std::string& lang,
+                       const std::string& config) override;
 
   virtual void CloseFileStreams();
   cmLocalUnixMakefileGenerator3* LocalGenerator;

+ 1 - 2
Source/cmMakefileUtilityTargetGenerator.cxx

@@ -22,8 +22,7 @@ cmMakefileUtilityTargetGenerator::cmMakefileUtilityTargetGenerator(
   : cmMakefileTargetGenerator(target)
 {
   this->CustomCommandDriver = OnUtility;
-  this->OSXBundleGenerator =
-    cm::make_unique<cmOSXBundleGenerator>(target, this->ConfigName);
+  this->OSXBundleGenerator = cm::make_unique<cmOSXBundleGenerator>(target);
   this->OSXBundleGenerator->SetMacContentFolders(&this->MacContentFolders);
 }
 

+ 175 - 146
Source/cmNinjaNormalTargetGenerator.cxx

@@ -41,33 +41,25 @@
 cmNinjaNormalTargetGenerator::cmNinjaNormalTargetGenerator(
   cmGeneratorTarget* target)
   : cmNinjaTargetGenerator(target)
-  , TargetLinkLanguage("")
 {
-  this->TargetLinkLanguage = target->GetLinkerLanguage(this->GetConfigName());
-  if (target->GetType() == cmStateEnums::EXECUTABLE) {
-    this->TargetNames = this->GetGeneratorTarget()->GetExecutableNames(
-      GetLocalGenerator()->GetConfigName());
-  } else {
-    this->TargetNames = this->GetGeneratorTarget()->GetLibraryNames(
-      GetLocalGenerator()->GetConfigName());
-  }
-
   if (target->GetType() != cmStateEnums::OBJECT_LIBRARY) {
     // on Windows the output dir is already needed at compile time
     // ensure the directory exists (OutDir test)
-    EnsureDirectoryExists(target->GetDirectory(this->GetConfigName()));
+    for (auto const& config : this->GetConfigNames()) {
+      EnsureDirectoryExists(target->GetDirectory(config));
+    }
   }
 
-  this->OSXBundleGenerator =
-    cm::make_unique<cmOSXBundleGenerator>(target, this->GetConfigName());
+  this->OSXBundleGenerator = cm::make_unique<cmOSXBundleGenerator>(target);
   this->OSXBundleGenerator->SetMacContentFolders(&this->MacContentFolders);
 }
 
 cmNinjaNormalTargetGenerator::~cmNinjaNormalTargetGenerator() = default;
 
-void cmNinjaNormalTargetGenerator::Generate()
+void cmNinjaNormalTargetGenerator::Generate(const std::string& config)
 {
-  if (this->TargetLinkLanguage.empty()) {
+  std::string lang = this->GeneratorTarget->GetLinkerLanguage(config);
+  if (this->TargetLinkLanguage(config).empty()) {
     cmSystemTools::Error("CMake can not determine linker language for "
                          "target: " +
                          this->GetGeneratorTarget()->GetName());
@@ -75,25 +67,26 @@ void cmNinjaNormalTargetGenerator::Generate()
   }
 
   // Write the rules for each language.
-  this->WriteLanguagesRules();
+  this->WriteLanguagesRules(config);
 
   // Write the build statements
-  this->WriteObjectBuildStatements();
+  this->WriteObjectBuildStatements(config);
 
   if (this->GetGeneratorTarget()->GetType() == cmStateEnums::OBJECT_LIBRARY) {
-    this->WriteObjectLibStatement();
+    this->WriteObjectLibStatement(config);
   } else {
     // If this target has cuda language link inputs, and we need to do
     // device linking
-    this->WriteDeviceLinkStatement();
-    this->WriteLinkStatement();
+    this->WriteDeviceLinkStatement(config);
+    this->WriteLinkStatement(config);
   }
 
   // Find ADDITIONAL_CLEAN_FILES
-  this->AdditionalCleanFiles();
+  this->AdditionalCleanFiles(config);
 }
 
-void cmNinjaNormalTargetGenerator::WriteLanguagesRules()
+void cmNinjaNormalTargetGenerator::WriteLanguagesRules(
+  const std::string& config)
 {
 #ifdef NINJA_GEN_VERBOSE_FILES
   cmGlobalNinjaGenerator::WriteDivider(this->GetRulesFileStream());
@@ -106,8 +99,7 @@ void cmNinjaNormalTargetGenerator::WriteLanguagesRules()
   // Write rules for languages compiled in this target.
   std::set<std::string> languages;
   std::vector<cmSourceFile const*> sourceFiles;
-  this->GetGeneratorTarget()->GetObjectSources(
-    sourceFiles, this->GetMakefile()->GetSafeDefinition("CMAKE_BUILD_TYPE"));
+  this->GetGeneratorTarget()->GetObjectSources(sourceFiles, config);
   for (cmSourceFile const* sf : sourceFiles) {
     std::string const lang = sf->GetLanguage();
     if (!lang.empty()) {
@@ -139,18 +131,20 @@ const char* cmNinjaNormalTargetGenerator::GetVisibleTypeName() const
   }
 }
 
-std::string cmNinjaNormalTargetGenerator::LanguageLinkerRule() const
+std::string cmNinjaNormalTargetGenerator::LanguageLinkerRule(
+  const std::string& config) const
 {
-  return this->TargetLinkLanguage + "_" +
+  return this->TargetLinkLanguage(config) + "_" +
     cmState::GetTargetTypeName(this->GetGeneratorTarget()->GetType()) +
     "_LINKER__" +
     cmGlobalNinjaGenerator::EncodeRuleName(
            this->GetGeneratorTarget()->GetName());
 }
 
-std::string cmNinjaNormalTargetGenerator::LanguageLinkerDeviceRule() const
+std::string cmNinjaNormalTargetGenerator::LanguageLinkerDeviceRule(
+  const std::string& config) const
 {
-  return this->TargetLinkLanguage + "_" +
+  return this->TargetLinkLanguage(config) + "_" +
     cmState::GetTargetTypeName(this->GetGeneratorTarget()->GetType()) +
     "_DEVICE_LINKER__" +
     cmGlobalNinjaGenerator::EncodeRuleName(
@@ -165,9 +159,10 @@ struct cmNinjaRemoveNoOpCommands
   }
 };
 
-void cmNinjaNormalTargetGenerator::WriteDeviceLinkRule(bool useResponseFile)
+void cmNinjaNormalTargetGenerator::WriteDeviceLinkRule(
+  bool useResponseFile, const std::string& config)
 {
-  cmNinjaRule rule(this->LanguageLinkerDeviceRule());
+  cmNinjaRule rule(this->LanguageLinkerDeviceRule(config));
   if (!this->GetGlobalGenerator()->HasRule(rule.Name)) {
     cmRulePlaceholderExpander::RuleVariables vars;
     vars.CMTargetName = this->GetGeneratorTarget()->GetName().c_str();
@@ -241,30 +236,34 @@ void cmNinjaNormalTargetGenerator::WriteDeviceLinkRule(bool useResponseFile)
     rule.Command = this->GetLocalGenerator()->BuildCommandLine(linkCmds);
 
     // Write the linker rule with response file if needed.
-    rule.Comment = cmStrCat("Rule for linking ", this->TargetLinkLanguage, ' ',
-                            this->GetVisibleTypeName(), '.');
-    rule.Description = cmStrCat("Linking ", this->TargetLinkLanguage, ' ',
-                                this->GetVisibleTypeName(), " $TARGET_FILE");
+    rule.Comment =
+      cmStrCat("Rule for linking ", this->TargetLinkLanguage(config), ' ',
+               this->GetVisibleTypeName(), '.');
+    rule.Description =
+      cmStrCat("Linking ", this->TargetLinkLanguage(config), ' ',
+               this->GetVisibleTypeName(), " $TARGET_FILE");
     rule.Restat = "$RESTAT";
 
     this->GetGlobalGenerator()->AddRule(rule);
   }
 }
 
-void cmNinjaNormalTargetGenerator::WriteLinkRule(bool useResponseFile)
+void cmNinjaNormalTargetGenerator::WriteLinkRule(bool useResponseFile,
+                                                 const std::string& config)
 {
   cmStateEnums::TargetType targetType = this->GetGeneratorTarget()->GetType();
 
-  std::string linkRuleName = this->LanguageLinkerRule();
+  std::string linkRuleName = this->LanguageLinkerRule(config);
   if (!this->GetGlobalGenerator()->HasRule(linkRuleName)) {
     cmNinjaRule rule(std::move(linkRuleName));
     cmRulePlaceholderExpander::RuleVariables vars;
     vars.CMTargetName = this->GetGeneratorTarget()->GetName().c_str();
     vars.CMTargetType = cmState::GetTargetTypeName(targetType);
 
-    vars.Language = this->TargetLinkLanguage.c_str();
+    std::string lang = this->TargetLinkLanguage(config);
+    vars.Language = config.c_str();
 
-    if (this->TargetLinkLanguage == "Swift") {
+    if (this->TargetLinkLanguage(config) == "Swift") {
       vars.SwiftLibraryName = "$SWIFT_LIBRARY_NAME";
       vars.SwiftModule = "$SWIFT_MODULE";
       vars.SwiftModuleName = "$SWIFT_MODULE_NAME";
@@ -278,7 +277,8 @@ void cmNinjaNormalTargetGenerator::WriteLinkRule(bool useResponseFile)
 
     std::string responseFlag;
 
-    std::string cmakeVarLang = cmStrCat("CMAKE_", this->TargetLinkLanguage);
+    std::string cmakeVarLang =
+      cmStrCat("CMAKE_", this->TargetLinkLanguage(config));
 
     // build response file name
     std::string cmakeLinkVar = cmakeVarLang + "_RESPONSE_FILE_LINK_FLAG";
@@ -286,7 +286,7 @@ void cmNinjaNormalTargetGenerator::WriteLinkRule(bool useResponseFile)
 
     if (flag) {
       responseFlag = flag;
-    } else if (this->TargetLinkLanguage != "CUDA") {
+    } else if (this->TargetLinkLanguage(config) != "CUDA") {
       responseFlag = "@";
     }
 
@@ -304,7 +304,7 @@ void cmNinjaNormalTargetGenerator::WriteLinkRule(bool useResponseFile)
         rule.RspContent = "$in_newline";
       }
       rule.RspContent += " $LINK_PATH $LINK_LIBRARIES";
-      if (this->TargetLinkLanguage == "Swift") {
+      if (this->TargetLinkLanguage(config) == "Swift") {
         vars.SwiftSources = responseFlag.c_str();
       } else {
         vars.Objects = responseFlag.c_str();
@@ -359,7 +359,7 @@ void cmNinjaNormalTargetGenerator::WriteLinkRule(bool useResponseFile)
       this->GetLocalGenerator()->CreateRulePlaceholderExpander());
 
     // Rule for linking library/executable.
-    std::vector<std::string> linkCmds = this->ComputeLinkCmd();
+    std::vector<std::string> linkCmds = this->ComputeLinkCmd(config);
     for (std::string& linkCmd : linkCmds) {
       linkCmd = cmStrCat(launcher, linkCmd);
       rulePlaceholderExpander->ExpandRuleVariables(this->GetLocalGenerator(),
@@ -374,15 +374,18 @@ void cmNinjaNormalTargetGenerator::WriteLinkRule(bool useResponseFile)
     rule.Command = this->GetLocalGenerator()->BuildCommandLine(linkCmds);
 
     // Write the linker rule with response file if needed.
-    rule.Comment = cmStrCat("Rule for linking ", this->TargetLinkLanguage, ' ',
-                            this->GetVisibleTypeName(), '.');
-    rule.Description = cmStrCat("Linking ", this->TargetLinkLanguage, ' ',
-                                this->GetVisibleTypeName(), " $TARGET_FILE");
+    rule.Comment =
+      cmStrCat("Rule for linking ", this->TargetLinkLanguage(config), ' ',
+               this->GetVisibleTypeName(), '.');
+    rule.Description =
+      cmStrCat("Linking ", this->TargetLinkLanguage(config), ' ',
+               this->GetVisibleTypeName(), " $TARGET_FILE");
     rule.Restat = "$RESTAT";
     this->GetGlobalGenerator()->AddRule(rule);
   }
 
-  if (this->TargetNames.Output != this->TargetNames.Real &&
+  auto const tgtNames = this->TargetNames(config);
+  if (tgtNames.Output != tgtNames.Real &&
       !this->GetGeneratorTarget()->IsFrameworkOnApple()) {
     std::string cmakeCommand =
       this->GetLocalGenerator()->ConvertToOutputFormat(
@@ -441,7 +444,8 @@ std::vector<std::string> cmNinjaNormalTargetGenerator::ComputeDeviceLinkCmd()
   return linkCmds;
 }
 
-std::vector<std::string> cmNinjaNormalTargetGenerator::ComputeLinkCmd()
+std::vector<std::string> cmNinjaNormalTargetGenerator::ComputeLinkCmd(
+  const std::string& config)
 {
   std::vector<std::string> linkCmds;
   cmMakefile* mf = this->GetMakefile();
@@ -450,14 +454,14 @@ std::vector<std::string> cmNinjaNormalTargetGenerator::ComputeLinkCmd()
     // this occurs when things like IPO is enabled, and we need to use the
     // CMAKE_<lang>_CREATE_STATIC_LIBRARY_IPO define instead.
     std::string linkCmdVar = this->GetGeneratorTarget()->GetCreateRuleVariable(
-      this->TargetLinkLanguage, this->GetConfigName());
+      this->TargetLinkLanguage(config), config);
     const char* linkCmd = mf->GetDefinition(linkCmdVar);
     if (linkCmd) {
       std::string linkCmdStr = linkCmd;
-      if (this->GetGeneratorTarget()->HasImplibGNUtoMS(this->ConfigName)) {
-        std::string ruleVar = cmStrCat(
-          "CMAKE_", this->GeneratorTarget->GetLinkerLanguage(this->ConfigName),
-          "_GNUtoMS_RULE");
+      if (this->GetGeneratorTarget()->HasImplibGNUtoMS(config)) {
+        std::string ruleVar =
+          cmStrCat("CMAKE_", this->GeneratorTarget->GetLinkerLanguage(config),
+                   "_GNUtoMS_RULE");
         if (const char* rule = this->Makefile->GetDefinition(ruleVar)) {
           linkCmdStr += rule;
         }
@@ -469,9 +473,8 @@ std::vector<std::string> cmNinjaNormalTargetGenerator::ComputeLinkCmd()
             cmSystemTools::GetCMakeCommand(), cmLocalGenerator::SHELL),
           " -E __run_co_compile --lwyu=");
         cmGeneratorTarget& gt = *this->GetGeneratorTarget();
-        const std::string cfgName = this->GetConfigName();
         std::string targetOutputReal = this->ConvertToNinjaPath(
-          gt.GetFullPath(cfgName, cmStateEnums::RuntimeBinaryArtifact,
+          gt.GetFullPath(config, cmStateEnums::RuntimeBinaryArtifact,
                          /*realname=*/true));
         cmakeCommand += targetOutputReal;
         linkCmds.push_back(std::move(cmakeCommand));
@@ -490,21 +493,21 @@ std::vector<std::string> cmNinjaNormalTargetGenerator::ComputeLinkCmd()
       }
       // TODO: Use ARCHIVE_APPEND for archives over a certain size.
       {
-        std::string linkCmdVar =
-          cmStrCat("CMAKE_", this->TargetLinkLanguage, "_ARCHIVE_CREATE");
+        std::string linkCmdVar = cmStrCat(
+          "CMAKE_", this->TargetLinkLanguage(config), "_ARCHIVE_CREATE");
 
         linkCmdVar = this->GeneratorTarget->GetFeatureSpecificLinkRuleVariable(
-          linkCmdVar, this->TargetLinkLanguage, this->GetConfigName());
+          linkCmdVar, this->TargetLinkLanguage(config), config);
 
         std::string const& linkCmd = mf->GetRequiredDefinition(linkCmdVar);
         cmExpandList(linkCmd, linkCmds);
       }
       {
-        std::string linkCmdVar =
-          cmStrCat("CMAKE_", this->TargetLinkLanguage, "_ARCHIVE_FINISH");
+        std::string linkCmdVar = cmStrCat(
+          "CMAKE_", this->TargetLinkLanguage(config), "_ARCHIVE_FINISH");
 
         linkCmdVar = this->GeneratorTarget->GetFeatureSpecificLinkRuleVariable(
-          linkCmdVar, this->TargetLinkLanguage, this->GetConfigName());
+          linkCmdVar, this->TargetLinkLanguage(config), config);
 
         std::string const& linkCmd = mf->GetRequiredDefinition(linkCmdVar);
         cmExpandList(linkCmd, linkCmds);
@@ -535,7 +538,8 @@ std::vector<std::string> cmNinjaNormalTargetGenerator::ComputeLinkCmd()
   return std::vector<std::string>();
 }
 
-void cmNinjaNormalTargetGenerator::WriteDeviceLinkStatement()
+void cmNinjaNormalTargetGenerator::WriteDeviceLinkStatement(
+  const std::string& config)
 {
   cmGlobalNinjaGenerator* globalGen = this->GetGlobalGenerator();
   if (!globalGen->GetLanguageEnabled("CUDA")) {
@@ -545,7 +549,7 @@ void cmNinjaNormalTargetGenerator::WriteDeviceLinkStatement()
   cmGeneratorTarget* genTarget = this->GetGeneratorTarget();
 
   bool requiresDeviceLinking = requireDeviceLinking(
-    *this->GeneratorTarget, *this->GetLocalGenerator(), this->ConfigName);
+    *this->GeneratorTarget, *this->GetLocalGenerator(), config);
   if (!requiresDeviceLinking) {
     return;
   }
@@ -558,12 +562,11 @@ void cmNinjaNormalTargetGenerator::WriteDeviceLinkStatement()
   std::string const& objExt =
     this->Makefile->GetSafeDefinition("CMAKE_CUDA_OUTPUT_EXTENSION");
 
-  std::string const cfgName = this->GetConfigName();
   std::string const targetOutputReal = ConvertToNinjaPath(
     genTarget->ObjectDirectory + "cmake_device_link" + objExt);
 
   std::string const targetOutputImplib = ConvertToNinjaPath(
-    genTarget->GetFullPath(cfgName, cmStateEnums::ImportLibraryArtifact));
+    genTarget->GetFullPath(config, cmStateEnums::ImportLibraryArtifact));
 
   this->DeviceLinkObject = targetOutputReal;
 
@@ -575,7 +578,7 @@ void cmNinjaNormalTargetGenerator::WriteDeviceLinkStatement()
                              << " target " << this->GetTargetName() << "\n\n";
 
   // Compute the comment.
-  cmNinjaBuild build(this->LanguageLinkerDeviceRule());
+  cmNinjaBuild build(this->LanguageLinkerDeviceRule(config));
   build.Comment =
     cmStrCat("Link the ", this->GetVisibleTypeName(), ' ', targetOutputReal);
 
@@ -585,13 +588,14 @@ void cmNinjaNormalTargetGenerator::WriteDeviceLinkStatement()
   build.Outputs.push_back(targetOutputReal);
   // Compute specific libraries to link with.
   build.ExplicitDeps = this->GetObjects();
-  build.ImplicitDeps = this->ComputeLinkDeps(this->TargetLinkLanguage);
+  build.ImplicitDeps =
+    this->ComputeLinkDeps(this->TargetLinkLanguage(config), config);
 
   std::string frameworkPath;
   std::string linkPath;
 
-  std::string createRule = genTarget->GetCreateRuleVariable(
-    this->TargetLinkLanguage, this->GetConfigName());
+  std::string createRule =
+    genTarget->GetCreateRuleVariable(this->TargetLinkLanguage(config), config);
   const bool useWatcomQuote =
     this->GetMakefile()->IsOn(createRule + "_USE_WATCOM_QUOTE");
   cmLocalNinjaGenerator& localGen = *this->GetLocalGenerator();
@@ -607,15 +611,15 @@ void cmNinjaNormalTargetGenerator::WriteDeviceLinkStatement()
   linkLineComputer->SetUseWatcomQuote(useWatcomQuote);
 
   localGen.GetTargetFlags(
-    linkLineComputer.get(), this->GetConfigName(), vars["LINK_LIBRARIES"],
-    vars["FLAGS"], vars["LINK_FLAGS"], frameworkPath, linkPath, genTarget);
+    linkLineComputer.get(), config, vars["LINK_LIBRARIES"], vars["FLAGS"],
+    vars["LINK_FLAGS"], frameworkPath, linkPath, genTarget);
 
   this->addPoolNinjaVariable("JOB_POOL_LINK", genTarget, vars);
 
   vars["LINK_FLAGS"] =
     cmGlobalNinjaGenerator::EncodeLiteral(vars["LINK_FLAGS"]);
 
-  vars["MANIFESTS"] = this->GetManifests();
+  vars["MANIFESTS"] = this->GetManifests(config);
 
   vars["LINK_PATH"] = frameworkPath + linkPath;
 
@@ -624,24 +628,25 @@ void cmNinjaNormalTargetGenerator::WriteDeviceLinkStatement()
   // code between the Makefile executable and library generators.
   if (targetType == cmStateEnums::EXECUTABLE) {
     std::string t = vars["FLAGS"];
-    localGen.AddArchitectureFlags(t, genTarget, cudaLinkLanguage, cfgName);
+    localGen.AddArchitectureFlags(t, genTarget, cudaLinkLanguage, config);
     vars["FLAGS"] = t;
   } else {
     std::string t = vars["ARCH_FLAGS"];
-    localGen.AddArchitectureFlags(t, genTarget, cudaLinkLanguage, cfgName);
+    localGen.AddArchitectureFlags(t, genTarget, cudaLinkLanguage, config);
     vars["ARCH_FLAGS"] = t;
     t.clear();
     localGen.AddLanguageFlagsForLinking(t, genTarget, cudaLinkLanguage,
-                                        cfgName);
+                                        config);
     vars["LANGUAGE_COMPILE_FLAGS"] = t;
   }
-  if (genTarget->HasSOName(cfgName)) {
+  auto const tgtNames = this->TargetNames(config);
+  if (genTarget->HasSOName(config)) {
     vars["SONAME_FLAG"] =
-      this->GetMakefile()->GetSONameFlag(this->TargetLinkLanguage);
-    vars["SONAME"] = this->TargetNames.SharedObject;
+      this->GetMakefile()->GetSONameFlag(this->TargetLinkLanguage(config));
+    vars["SONAME"] = tgtNames.SharedObject;
     if (targetType == cmStateEnums::SHARED_LIBRARY) {
       std::string install_dir =
-        this->GetGeneratorTarget()->GetInstallNameDirForBuildTree(cfgName);
+        this->GetGeneratorTarget()->GetInstallNameDirForBuildTree(config);
       if (!install_dir.empty()) {
         vars["INSTALLNAME_DIR"] = localGen.ConvertToOutputFormat(
           install_dir, cmOutputConverter::SHELL);
@@ -649,7 +654,7 @@ void cmNinjaNormalTargetGenerator::WriteDeviceLinkStatement()
     }
   }
 
-  if (!this->TargetNames.ImportLibrary.empty()) {
+  if (!tgtNames.ImportLibrary.empty()) {
     const std::string impLibPath = localGen.ConvertToOutputFormat(
       targetOutputImplib, cmOutputConverter::SHELL);
     vars["TARGET_IMPLIB"] = impLibPath;
@@ -661,7 +666,7 @@ void cmNinjaNormalTargetGenerator::WriteDeviceLinkStatement()
     this->ConvertToNinjaPath(objPath), cmOutputConverter::SHELL);
   EnsureDirectoryExists(objPath);
 
-  this->SetMsvcTargetPdbVariable(vars);
+  this->SetMsvcTargetPdbVariable(vars, config);
 
   if (globalGen->IsGCCOnWindows()) {
     // ar.exe can't handle backslashes in rsp files (implicitly used by gcc)
@@ -675,55 +680,56 @@ void cmNinjaNormalTargetGenerator::WriteDeviceLinkStatement()
   // do not check if the user has explicitly forced a response file.
   int const commandLineLengthLimit =
     static_cast<int>(cmSystemTools::CalculateCommandLineLengthLimit()) -
-    globalGen->GetRuleCmdLength(this->LanguageLinkerDeviceRule());
+    globalGen->GetRuleCmdLength(this->LanguageLinkerDeviceRule(config));
 
   build.RspFile = this->ConvertToNinjaPath(std::string("CMakeFiles/") +
                                            genTarget->GetName() + ".rsp");
 
   // Gather order-only dependencies.
   this->GetLocalGenerator()->AppendTargetDepends(this->GetGeneratorTarget(),
-                                                 build.OrderOnlyDeps);
+                                                 build.OrderOnlyDeps, config);
 
   // Write the build statement for this target.
   bool usedResponseFile = false;
   globalGen->WriteBuild(this->GetBuildFileStream(), build,
                         commandLineLengthLimit, &usedResponseFile);
-  this->WriteDeviceLinkRule(usedResponseFile);
+  this->WriteDeviceLinkRule(usedResponseFile, config);
 }
 
-void cmNinjaNormalTargetGenerator::WriteLinkStatement()
+void cmNinjaNormalTargetGenerator::WriteLinkStatement(
+  const std::string& config)
 {
   cmMakefile* mf = this->GetMakefile();
   cmGlobalNinjaGenerator* globalGen = this->GetGlobalGenerator();
   cmGeneratorTarget* gt = this->GetGeneratorTarget();
 
-  const std::string cfgName = this->GetConfigName();
-  std::string targetOutput = ConvertToNinjaPath(gt->GetFullPath(cfgName));
+  std::string targetOutput = ConvertToNinjaPath(gt->GetFullPath(config));
   std::string targetOutputReal = ConvertToNinjaPath(
-    gt->GetFullPath(cfgName, cmStateEnums::RuntimeBinaryArtifact,
+    gt->GetFullPath(config, cmStateEnums::RuntimeBinaryArtifact,
                     /*realname=*/true));
   std::string targetOutputImplib = ConvertToNinjaPath(
-    gt->GetFullPath(cfgName, cmStateEnums::ImportLibraryArtifact));
+    gt->GetFullPath(config, cmStateEnums::ImportLibraryArtifact));
 
+  auto const tgtNames = this->TargetNames(config);
   if (gt->IsAppBundleOnApple()) {
     // Create the app bundle
-    std::string outpath = gt->GetDirectory(cfgName);
-    this->OSXBundleGenerator->CreateAppBundle(this->TargetNames.Output,
-                                              outpath);
+    std::string outpath = gt->GetDirectory(config);
+    this->OSXBundleGenerator->CreateAppBundle(tgtNames.Output, outpath,
+                                              config);
 
     // Calculate the output path
-    targetOutput = cmStrCat(outpath, '/', this->TargetNames.Output);
+    targetOutput = cmStrCat(outpath, '/', tgtNames.Output);
     targetOutput = this->ConvertToNinjaPath(targetOutput);
-    targetOutputReal = cmStrCat(outpath, '/', this->TargetNames.Real);
+    targetOutputReal = cmStrCat(outpath, '/', tgtNames.Real);
     targetOutputReal = this->ConvertToNinjaPath(targetOutputReal);
   } else if (gt->IsFrameworkOnApple()) {
     // Create the library framework.
-    this->OSXBundleGenerator->CreateFramework(this->TargetNames.Output,
-                                              gt->GetDirectory(cfgName));
+    this->OSXBundleGenerator->CreateFramework(
+      tgtNames.Output, gt->GetDirectory(config), config);
   } else if (gt->IsCFBundleOnApple()) {
     // Create the core foundation bundle.
-    this->OSXBundleGenerator->CreateCFBundle(this->TargetNames.Output,
-                                             gt->GetDirectory(cfgName));
+    this->OSXBundleGenerator->CreateCFBundle(tgtNames.Output,
+                                             gt->GetDirectory(config), config);
   }
 
   // Write comments.
@@ -733,7 +739,7 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement()
     << "# Link build statements for " << cmState::GetTargetTypeName(targetType)
     << " target " << this->GetTargetName() << "\n\n";
 
-  cmNinjaBuild linkBuild(this->LanguageLinkerRule());
+  cmNinjaBuild linkBuild(this->LanguageLinkerRule(config));
   cmNinjaVars& vars = linkBuild.Variables;
 
   // Compute the comment.
@@ -743,10 +749,10 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement()
   // Compute outputs.
   linkBuild.Outputs.push_back(targetOutputReal);
 
-  if (this->TargetLinkLanguage == "Swift") {
-    vars["SWIFT_LIBRARY_NAME"] = [this]() -> std::string {
+  if (this->TargetLinkLanguage(config) == "Swift") {
+    vars["SWIFT_LIBRARY_NAME"] = [this, config]() -> std::string {
       cmGeneratorTarget::Names targetNames =
-        this->GetGeneratorTarget()->GetLibraryNames(this->GetConfigName());
+        this->GetGeneratorTarget()->GetLibraryNames(config);
       return targetNames.Base;
     }();
 
@@ -782,12 +788,11 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement()
                                  "/output-file-map.json"),
         cmOutputConverter::SHELL);
 
-    vars["SWIFT_SOURCES"] = [this]() -> std::string {
+    vars["SWIFT_SOURCES"] = [this, config]() -> std::string {
       std::vector<cmSourceFile const*> sources;
       std::stringstream oss;
 
-      this->GetGeneratorTarget()->GetObjectSources(sources,
-                                                   this->GetConfigName());
+      this->GetGeneratorTarget()->GetObjectSources(sources, config);
       cmLocalGenerator const* LocalGen = this->GetLocalGenerator();
       for (const auto& source : sources) {
         oss << " "
@@ -801,15 +806,15 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement()
     // Since we do not perform object builds, compute the
     // defines/flags/includes here so that they can be passed along
     // appropriately.
-    vars["DEFINES"] = this->GetDefines("Swift");
-    vars["FLAGS"] = this->GetFlags("Swift");
-    vars["INCLUDES"] = this->GetIncludes("Swift");
+    vars["DEFINES"] = this->GetDefines("Swift", config);
+    vars["FLAGS"] = this->GetFlags("Swift", config);
+    vars["INCLUDES"] = this->GetIncludes("Swift", config);
   }
 
   // Compute specific libraries to link with.
-  if (this->TargetLinkLanguage == "Swift") {
+  if (this->TargetLinkLanguage(config) == "Swift") {
     std::vector<cmSourceFile const*> sources;
-    gt->GetObjectSources(sources, this->GetConfigName());
+    gt->GetObjectSources(sources, config);
     for (const auto& source : sources) {
       linkBuild.Outputs.push_back(
         this->ConvertToNinjaPath(this->GetObjectFilePath(source)));
@@ -821,7 +826,8 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement()
   } else {
     linkBuild.ExplicitDeps = this->GetObjects();
   }
-  linkBuild.ImplicitDeps = this->ComputeLinkDeps(this->TargetLinkLanguage);
+  linkBuild.ImplicitDeps =
+    this->ComputeLinkDeps(this->TargetLinkLanguage(config), config);
 
   if (!this->DeviceLinkObject.empty()) {
     linkBuild.ExplicitDeps.push_back(this->DeviceLinkObject);
@@ -831,7 +837,7 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement()
   std::string linkPath;
 
   std::string createRule =
-    gt->GetCreateRuleVariable(this->TargetLinkLanguage, this->GetConfigName());
+    gt->GetCreateRuleVariable(this->TargetLinkLanguage(config), config);
   bool useWatcomQuote = mf->IsOn(createRule + "_USE_WATCOM_QUOTE");
   cmLocalNinjaGenerator& localGen = *this->GetLocalGenerator();
 
@@ -844,26 +850,28 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement()
       this->GetLocalGenerator()->GetStateSnapshot().GetDirectory()));
   linkLineComputer->SetUseWatcomQuote(useWatcomQuote);
 
-  localGen.GetTargetFlags(linkLineComputer.get(), this->GetConfigName(),
+  localGen.GetTargetFlags(linkLineComputer.get(), config,
                           vars["LINK_LIBRARIES"], vars["FLAGS"],
                           vars["LINK_FLAGS"], frameworkPath, linkPath, gt);
 
   // Add OS X version flags, if any.
   if (this->GeneratorTarget->GetType() == cmStateEnums::SHARED_LIBRARY ||
       this->GeneratorTarget->GetType() == cmStateEnums::MODULE_LIBRARY) {
-    this->AppendOSXVerFlag(vars["LINK_FLAGS"], this->TargetLinkLanguage,
-                           "COMPATIBILITY", true);
-    this->AppendOSXVerFlag(vars["LINK_FLAGS"], this->TargetLinkLanguage,
-                           "CURRENT", false);
+    this->AppendOSXVerFlag(vars["LINK_FLAGS"],
+                           this->TargetLinkLanguage(config), "COMPATIBILITY",
+                           true);
+    this->AppendOSXVerFlag(vars["LINK_FLAGS"],
+                           this->TargetLinkLanguage(config), "CURRENT", false);
   }
 
   this->addPoolNinjaVariable("JOB_POOL_LINK", gt, vars);
 
-  this->AddModuleDefinitionFlag(linkLineComputer.get(), vars["LINK_FLAGS"]);
+  this->AddModuleDefinitionFlag(linkLineComputer.get(), vars["LINK_FLAGS"],
+                                config);
   vars["LINK_FLAGS"] =
     cmGlobalNinjaGenerator::EncodeLiteral(vars["LINK_FLAGS"]);
 
-  vars["MANIFESTS"] = this->GetManifests();
+  vars["MANIFESTS"] = this->GetManifests(config);
 
   vars["LINK_PATH"] = frameworkPath + linkPath;
   std::string lwyuFlags;
@@ -876,23 +884,26 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement()
   // code between the Makefile executable and library generators.
   if (targetType == cmStateEnums::EXECUTABLE) {
     std::string t = vars["FLAGS"];
-    localGen.AddArchitectureFlags(t, gt, TargetLinkLanguage, cfgName);
+    localGen.AddArchitectureFlags(t, gt, this->TargetLinkLanguage(config),
+                                  config);
     t += lwyuFlags;
     vars["FLAGS"] = t;
   } else {
     std::string t = vars["ARCH_FLAGS"];
-    localGen.AddArchitectureFlags(t, gt, TargetLinkLanguage, cfgName);
+    localGen.AddArchitectureFlags(t, gt, this->TargetLinkLanguage(config),
+                                  config);
     vars["ARCH_FLAGS"] = t;
     t.clear();
     t += lwyuFlags;
-    localGen.AddLanguageFlagsForLinking(t, gt, TargetLinkLanguage, cfgName);
+    localGen.AddLanguageFlagsForLinking(
+      t, gt, this->TargetLinkLanguage(config), config);
     vars["LANGUAGE_COMPILE_FLAGS"] = t;
   }
-  if (gt->HasSOName(cfgName)) {
-    vars["SONAME_FLAG"] = mf->GetSONameFlag(this->TargetLinkLanguage);
-    vars["SONAME"] = this->TargetNames.SharedObject;
+  if (gt->HasSOName(config)) {
+    vars["SONAME_FLAG"] = mf->GetSONameFlag(this->TargetLinkLanguage(config));
+    vars["SONAME"] = tgtNames.SharedObject;
     if (targetType == cmStateEnums::SHARED_LIBRARY) {
-      std::string install_dir = gt->GetInstallNameDirForBuildTree(cfgName);
+      std::string install_dir = gt->GetInstallNameDirForBuildTree(config);
       if (!install_dir.empty()) {
         vars["INSTALLNAME_DIR"] = localGen.ConvertToOutputFormat(
           install_dir, cmOutputConverter::SHELL);
@@ -902,17 +913,17 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement()
 
   cmNinjaDeps byproducts;
 
-  if (!this->TargetNames.ImportLibrary.empty()) {
+  if (!tgtNames.ImportLibrary.empty()) {
     const std::string impLibPath = localGen.ConvertToOutputFormat(
       targetOutputImplib, cmOutputConverter::SHELL);
     vars["TARGET_IMPLIB"] = impLibPath;
     EnsureParentDirectoryExists(impLibPath);
-    if (gt->HasImportLibrary(cfgName)) {
+    if (gt->HasImportLibrary(config)) {
       byproducts.push_back(targetOutputImplib);
     }
   }
 
-  if (!this->SetMsvcTargetPdbVariable(vars)) {
+  if (!this->SetMsvcTargetPdbVariable(vars, config)) {
     // It is common to place debug symbols at a specific place,
     // so we need a plain target name in the rule available.
     std::string prefix;
@@ -953,7 +964,7 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement()
 
   for (unsigned i = 0; i != 3; ++i) {
     for (cmCustomCommand const& cc : *cmdLists[i]) {
-      cmCustomCommandGenerator ccg(cc, cfgName, this->GetLocalGenerator());
+      cmCustomCommandGenerator ccg(cc, config, this->GetLocalGenerator());
       localGen.AppendCustomCommandLines(ccg, *cmdLineLists[i]);
       std::vector<std::string> const& ccByproducts = ccg.GetByproducts();
       std::transform(ccByproducts.begin(), ccByproducts.end(),
@@ -963,7 +974,7 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement()
 
   // maybe create .def file from list of objects
   cmGeneratorTarget::ModuleDefinitionInfo const* mdi =
-    gt->GetModuleDefinitionInfo(this->GetConfigName());
+    gt->GetModuleDefinitionInfo(config);
   if (mdi && mdi->DefFileGenerated) {
     std::string cmakeCommand =
       this->GetLocalGenerator()->ConvertToOutputFormat(
@@ -1024,7 +1035,8 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement()
     symlinkVars["POST_BUILD"] = postBuildCmdLine;
   }
 
-  std::string cmakeVarLang = cmStrCat("CMAKE_", this->TargetLinkLanguage);
+  std::string cmakeVarLang =
+    cmStrCat("CMAKE_", this->TargetLinkLanguage(config));
 
   // build response file name
   std::string cmakeLinkVar = cmakeVarLang + "_RESPONSE_FILE_LINK_FLAG";
@@ -1032,8 +1044,8 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement()
   const char* flag = GetMakefile()->GetDefinition(cmakeLinkVar);
 
   bool const lang_supports_response =
-    !(this->TargetLinkLanguage == "RC" ||
-      (this->TargetLinkLanguage == "CUDA" && !flag));
+    !(this->TargetLinkLanguage(config) == "RC" ||
+      (this->TargetLinkLanguage(config) == "CUDA" && !flag));
   int commandLineLengthLimit = -1;
   if (!lang_supports_response || !this->ForceResponseFile()) {
     commandLineLengthLimit =
@@ -1045,18 +1057,19 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement()
                                                gt->GetName() + ".rsp");
 
   // Gather order-only dependencies.
-  this->GetLocalGenerator()->AppendTargetDepends(gt, linkBuild.OrderOnlyDeps);
+  this->GetLocalGenerator()->AppendTargetDepends(gt, linkBuild.OrderOnlyDeps,
+                                                 config);
 
   // Add order-only dependencies on versioning symlinks of shared libs we link.
   if (!this->GeneratorTarget->IsDLLPlatform()) {
     if (cmComputeLinkInformation* cli =
-          this->GeneratorTarget->GetLinkInformation(this->GetConfigName())) {
+          this->GeneratorTarget->GetLinkInformation(config)) {
       for (auto const& item : cli->GetItems()) {
         if (item.Target &&
             item.Target->GetType() == cmStateEnums::SHARED_LIBRARY &&
             !item.Target->IsFrameworkOnApple()) {
-          std::string const& lib = this->ConvertToNinjaPath(
-            item.Target->GetFullPath(this->GetConfigName()));
+          std::string const& lib =
+            this->ConvertToNinjaPath(item.Target->GetFullPath(config));
           if (std::find(linkBuild.ImplicitDeps.begin(),
                         linkBuild.ImplicitDeps.end(),
                         lib) == linkBuild.ImplicitDeps.end()) {
@@ -1079,7 +1092,7 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement()
   bool usedResponseFile = false;
   globalGen->WriteBuild(this->GetBuildFileStream(), linkBuild,
                         commandLineLengthLimit, &usedResponseFile);
-  this->WriteLinkRule(usedResponseFile);
+  this->WriteLinkRule(usedResponseFile, config);
 
   if (symlinkNeeded) {
     if (targetType == cmStateEnums::EXECUTABLE) {
@@ -1094,7 +1107,7 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement()
       build.Comment = "Create library symlink " + targetOutput;
 
       std::string const soName = this->ConvertToNinjaPath(
-        this->GetTargetFilePath(this->TargetNames.SharedObject));
+        this->GetTargetFilePath(tgtNames.SharedObject, config));
       // If one link has to be created.
       if (targetOutputReal == soName || targetOutput == soName) {
         symlinkVars["SONAME"] =
@@ -1113,23 +1126,39 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement()
   }
 
   // Add aliases for the file name and the target name.
-  globalGen->AddTargetAlias(this->TargetNames.Output, gt);
-  globalGen->AddTargetAlias(this->GetTargetName(), gt);
+  globalGen->AddTargetAlias(tgtNames.Output, gt, config);
+  globalGen->AddTargetAlias(this->GetTargetName(), gt, config);
 }
 
-void cmNinjaNormalTargetGenerator::WriteObjectLibStatement()
+void cmNinjaNormalTargetGenerator::WriteObjectLibStatement(
+  const std::string& config)
 {
   // Write a phony output that depends on all object files.
   {
     cmNinjaBuild build("phony");
     build.Comment = "Object library " + this->GetTargetName();
     this->GetLocalGenerator()->AppendTargetOutputs(this->GetGeneratorTarget(),
-                                                   build.Outputs);
+                                                   build.Outputs, config);
     build.ExplicitDeps = this->GetObjects();
     this->GetGlobalGenerator()->WriteBuild(this->GetBuildFileStream(), build);
   }
 
   // Add aliases for the target name.
-  this->GetGlobalGenerator()->AddTargetAlias(this->GetTargetName(),
-                                             this->GetGeneratorTarget());
+  this->GetGlobalGenerator()->AddTargetAlias(
+    this->GetTargetName(), this->GetGeneratorTarget(), config);
+}
+
+cmGeneratorTarget::Names cmNinjaNormalTargetGenerator::TargetNames(
+  const std::string& config) const
+{
+  if (this->GeneratorTarget->GetType() == cmStateEnums::EXECUTABLE) {
+    return this->GeneratorTarget->GetExecutableNames(config);
+  }
+  return this->GeneratorTarget->GetLibraryNames(config);
+}
+
+std::string cmNinjaNormalTargetGenerator::TargetLinkLanguage(
+  const std::string& config) const
+{
+  return this->GeneratorTarget->GetLinkerLanguage(config);
 }

+ 12 - 12
Source/cmNinjaNormalTargetGenerator.h

@@ -17,30 +17,30 @@ public:
   cmNinjaNormalTargetGenerator(cmGeneratorTarget* target);
   ~cmNinjaNormalTargetGenerator() override;
 
-  void Generate() override;
+  void Generate(const std::string& config) override;
 
 private:
-  std::string LanguageLinkerRule() const;
-  std::string LanguageLinkerDeviceRule() const;
+  std::string LanguageLinkerRule(const std::string& config) const;
+  std::string LanguageLinkerDeviceRule(const std::string& config) const;
 
   const char* GetVisibleTypeName() const;
-  void WriteLanguagesRules();
+  void WriteLanguagesRules(const std::string& config);
 
-  void WriteLinkRule(bool useResponseFile);
-  void WriteDeviceLinkRule(bool useResponseFile);
+  void WriteLinkRule(bool useResponseFile, const std::string& config);
+  void WriteDeviceLinkRule(bool useResponseFile, const std::string& config);
 
-  void WriteLinkStatement();
-  void WriteDeviceLinkStatement();
+  void WriteLinkStatement(const std::string& config);
+  void WriteDeviceLinkStatement(const std::string& config);
 
-  void WriteObjectLibStatement();
+  void WriteObjectLibStatement(const std::string& config);
 
-  std::vector<std::string> ComputeLinkCmd();
+  std::vector<std::string> ComputeLinkCmd(const std::string& config);
   std::vector<std::string> ComputeDeviceLinkCmd();
 
 private:
   // Target name info.
-  cmGeneratorTarget::Names TargetNames;
-  std::string TargetLinkLanguage;
+  cmGeneratorTarget::Names TargetNames(const std::string& config) const;
+  std::string TargetLinkLanguage(const std::string& config) const;
   std::string DeviceLinkObject;
 };
 

+ 68 - 70
Source/cmNinjaTargetGenerator.cxx

@@ -138,10 +138,10 @@ std::string cmNinjaTargetGenerator::OrderDependsTargetForTarget()
 // void cmMakefileTargetGenerator::WriteTargetLanguageFlags()
 // Refactor it.
 std::string cmNinjaTargetGenerator::ComputeFlagsForObject(
-  cmSourceFile const* source, const std::string& language)
+  cmSourceFile const* source, const std::string& language,
+  const std::string& config)
 {
-  std::string flags = this->GetFlags(language);
-  const std::string configName = this->LocalGenerator->GetConfigName();
+  std::string flags = this->GetFlags(language, config);
 
   // Add Fortran format flags.
   if (language == "Fortran") {
@@ -150,7 +150,7 @@ std::string cmNinjaTargetGenerator::ComputeFlagsForObject(
 
   // Add source file specific flags.
   cmGeneratorExpressionInterpreter genexInterpreter(
-    this->LocalGenerator, configName, this->GeneratorTarget, language);
+    this->LocalGenerator, config, this->GeneratorTarget, language);
 
   const std::string COMPILE_FLAGS("COMPILE_FLAGS");
   if (const char* cflags = source->GetProperty(COMPILE_FLAGS)) {
@@ -166,16 +166,16 @@ std::string cmNinjaTargetGenerator::ComputeFlagsForObject(
 
   // Add precompile headers compile options.
   const std::string pchSource =
-    this->GeneratorTarget->GetPchSource(configName, language);
+    this->GeneratorTarget->GetPchSource(config, language);
 
   if (!pchSource.empty() && !source->GetProperty("SKIP_PRECOMPILE_HEADERS")) {
     std::string pchOptions;
     if (source->GetFullPath() == pchSource) {
-      pchOptions = this->GeneratorTarget->GetPchCreateCompileOptions(
-        configName, language);
+      pchOptions =
+        this->GeneratorTarget->GetPchCreateCompileOptions(config, language);
     } else {
       pchOptions =
-        this->GeneratorTarget->GetPchUseCompileOptions(configName, language);
+        this->GeneratorTarget->GetPchUseCompileOptions(config, language);
     }
 
     this->LocalGenerator->AppendCompileOptions(
@@ -186,16 +186,17 @@ std::string cmNinjaTargetGenerator::ComputeFlagsForObject(
 }
 
 void cmNinjaTargetGenerator::AddIncludeFlags(std::string& languageFlags,
-                                             std::string const& language)
+                                             std::string const& language,
+                                             const std::string& config)
 {
   std::vector<std::string> includes;
   this->LocalGenerator->GetIncludeDirectories(includes, this->GeneratorTarget,
-                                              language, this->GetConfigName());
+                                              language, config);
   // Add include directory flags.
   std::string includeFlags = this->LocalGenerator->GetIncludeFlags(
     includes, this->GeneratorTarget, language,
     language == "RC", // full include paths for RC needed by cmcldeps
-    false, this->GetConfigName());
+    false, config);
   if (this->GetGlobalGenerator()->IsGCCOnWindows()) {
     std::replace(includeFlags.begin(), includeFlags.end(), '\\', '/');
   }
@@ -232,10 +233,10 @@ bool cmNinjaTargetGenerator::NeedDepTypeMSVC(const std::string& lang) const
 // TODO: Refactor with
 // void cmMakefileTargetGenerator::WriteTargetLanguageFlags().
 std::string cmNinjaTargetGenerator::ComputeDefines(cmSourceFile const* source,
-                                                   const std::string& language)
+                                                   const std::string& language,
+                                                   const std::string& config)
 {
   std::set<std::string> defines;
-  const std::string config = this->LocalGenerator->GetConfigName();
   cmGeneratorExpressionInterpreter genexInterpreter(
     this->LocalGenerator, config, this->GeneratorTarget, language);
 
@@ -253,17 +254,17 @@ std::string cmNinjaTargetGenerator::ComputeDefines(cmSourceFile const* source,
       genexInterpreter.Evaluate(config_compile_defs, COMPILE_DEFINITIONS));
   }
 
-  std::string definesString = this->GetDefines(language);
+  std::string definesString = this->GetDefines(language, config);
   this->LocalGenerator->JoinDefines(defines, definesString, language);
 
   return definesString;
 }
 
 std::string cmNinjaTargetGenerator::ComputeIncludes(
-  cmSourceFile const* source, const std::string& language)
+  cmSourceFile const* source, const std::string& language,
+  const std::string& config)
 {
   std::vector<std::string> includes;
-  const std::string config = this->LocalGenerator->GetConfigName();
   cmGeneratorExpressionInterpreter genexInterpreter(
     this->LocalGenerator, config, this->GeneratorTarget, language);
 
@@ -277,13 +278,13 @@ std::string cmNinjaTargetGenerator::ComputeIncludes(
   std::string includesString = this->LocalGenerator->GetIncludeFlags(
     includes, this->GeneratorTarget, language, true, false, config);
   this->LocalGenerator->AppendFlags(includesString,
-                                    this->GetIncludes(language));
+                                    this->GetIncludes(language, config));
 
   return includesString;
 }
 
 cmNinjaDeps cmNinjaTargetGenerator::ComputeLinkDeps(
-  const std::string& linkLanguage) const
+  const std::string& linkLanguage, const std::string& config) const
 {
   // Static libraries never depend on other targets for linking.
   if (this->GeneratorTarget->GetType() == cmStateEnums::STATIC_LIBRARY ||
@@ -292,7 +293,7 @@ cmNinjaDeps cmNinjaTargetGenerator::ComputeLinkDeps(
   }
 
   cmComputeLinkInformation* cli =
-    this->GeneratorTarget->GetLinkInformation(this->GetConfigName());
+    this->GeneratorTarget->GetLinkInformation(config);
   if (!cli) {
     return cmNinjaDeps();
   }
@@ -303,8 +304,7 @@ cmNinjaDeps cmNinjaTargetGenerator::ComputeLinkDeps(
 
   // Add a dependency on the link definitions file, if any.
   if (cmGeneratorTarget::ModuleDefinitionInfo const* mdi =
-        this->GeneratorTarget->GetModuleDefinitionInfo(
-          this->GetConfigName())) {
+        this->GeneratorTarget->GetModuleDefinitionInfo(config)) {
     for (cmSourceFile const* src : mdi->Sources) {
       result.push_back(this->ConvertToNinjaPath(src->GetFullPath()));
     }
@@ -312,15 +312,14 @@ cmNinjaDeps cmNinjaTargetGenerator::ComputeLinkDeps(
 
   // Add a dependency on user-specified manifest files, if any.
   std::vector<cmSourceFile const*> manifest_srcs;
-  this->GeneratorTarget->GetManifests(manifest_srcs, this->ConfigName);
+  this->GeneratorTarget->GetManifests(manifest_srcs, config);
   for (cmSourceFile const* manifest_src : manifest_srcs) {
     result.push_back(this->ConvertToNinjaPath(manifest_src->GetFullPath()));
   }
 
   // Add user-specified dependencies.
   std::vector<std::string> linkDeps;
-  this->GeneratorTarget->GetLinkDepends(linkDeps, this->ConfigName,
-                                        linkLanguage);
+  this->GeneratorTarget->GetLinkDepends(linkDeps, config, linkLanguage);
   std::transform(linkDeps.begin(), linkDeps.end(), std::back_inserter(result),
                  MapToNinjaPath());
 
@@ -407,16 +406,17 @@ std::string cmNinjaTargetGenerator::GetTargetDependInfoPath(
   return path;
 }
 
-std::string cmNinjaTargetGenerator::GetTargetOutputDir() const
+std::string cmNinjaTargetGenerator::GetTargetOutputDir(
+  const std::string& config) const
 {
-  std::string dir = this->GeneratorTarget->GetDirectory(this->GetConfigName());
+  std::string dir = this->GeneratorTarget->GetDirectory(config);
   return ConvertToNinjaPath(dir);
 }
 
 std::string cmNinjaTargetGenerator::GetTargetFilePath(
-  const std::string& name) const
+  const std::string& name, const std::string& config) const
 {
-  std::string path = this->GetTargetOutputDir();
+  std::string path = this->GetTargetOutputDir(config);
   if (path.empty() || path == ".") {
     return name;
   }
@@ -430,21 +430,21 @@ std::string cmNinjaTargetGenerator::GetTargetName() const
   return this->GeneratorTarget->GetName();
 }
 
-bool cmNinjaTargetGenerator::SetMsvcTargetPdbVariable(cmNinjaVars& vars) const
+bool cmNinjaTargetGenerator::SetMsvcTargetPdbVariable(
+  cmNinjaVars& vars, const std::string& config) const
 {
   cmMakefile* mf = this->GetMakefile();
   if (mf->GetDefinition("MSVC_C_ARCHITECTURE_ID") ||
       mf->GetDefinition("MSVC_CXX_ARCHITECTURE_ID") ||
       mf->GetDefinition("MSVC_CUDA_ARCHITECTURE_ID")) {
     std::string pdbPath;
-    std::string compilePdbPath = this->ComputeTargetCompilePDB();
+    std::string compilePdbPath = this->ComputeTargetCompilePDB(config);
     if (this->GeneratorTarget->GetType() == cmStateEnums::EXECUTABLE ||
         this->GeneratorTarget->GetType() == cmStateEnums::STATIC_LIBRARY ||
         this->GeneratorTarget->GetType() == cmStateEnums::SHARED_LIBRARY ||
         this->GeneratorTarget->GetType() == cmStateEnums::MODULE_LIBRARY) {
-      pdbPath = cmStrCat(
-        this->GeneratorTarget->GetPDBDirectory(this->GetConfigName()), '/',
-        this->GeneratorTarget->GetPDBName(this->GetConfigName()));
+      pdbPath = cmStrCat(this->GeneratorTarget->GetPDBDirectory(config), '/',
+                         this->GeneratorTarget->GetPDBName(config));
     }
 
     vars["TARGET_PDB"] = this->GetLocalGenerator()->ConvertToOutputFormat(
@@ -787,7 +787,8 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang)
   this->GetGlobalGenerator()->AddRule(rule);
 }
 
-void cmNinjaTargetGenerator::WriteObjectBuildStatements()
+void cmNinjaTargetGenerator::WriteObjectBuildStatements(
+  const std::string& config)
 {
   // Write comments.
   cmGlobalNinjaGenerator::WriteDivider(this->GetBuildFileStream());
@@ -798,7 +799,7 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatements()
 
   {
     std::vector<cmSourceFile const*> customCommands;
-    this->GeneratorTarget->GetCustomCommands(customCommands, this->ConfigName);
+    this->GeneratorTarget->GetCustomCommands(customCommands, config);
     for (cmSourceFile const* sf : customCommands) {
       cmCustomCommand const* cc = sf->GetCustomCommand();
       this->GetLocalGenerator()->AddCustomCommandTarget(
@@ -810,23 +811,22 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatements()
   }
   {
     std::vector<cmSourceFile const*> headerSources;
-    this->GeneratorTarget->GetHeaderSources(headerSources, this->ConfigName);
+    this->GeneratorTarget->GetHeaderSources(headerSources, config);
     this->OSXBundleGenerator->GenerateMacOSXContentStatements(
-      headerSources, this->MacOSXContentGenerator.get());
+      headerSources, this->MacOSXContentGenerator.get(), config);
   }
   {
     std::vector<cmSourceFile const*> extraSources;
-    this->GeneratorTarget->GetExtraSources(extraSources, this->ConfigName);
+    this->GeneratorTarget->GetExtraSources(extraSources, config);
     this->OSXBundleGenerator->GenerateMacOSXContentStatements(
-      extraSources, this->MacOSXContentGenerator.get());
+      extraSources, this->MacOSXContentGenerator.get(), config);
   }
   {
     const char* pchExtension =
       GetMakefile()->GetDefinition("CMAKE_PCH_EXTENSION");
 
     std::vector<cmSourceFile const*> externalObjects;
-    this->GeneratorTarget->GetExternalObjects(externalObjects,
-                                              this->ConfigName);
+    this->GeneratorTarget->GetExternalObjects(externalObjects, config);
     for (cmSourceFile const* sf : externalObjects) {
       const auto objectFileName = this->GetSourceFilePath(sf);
       if (!cmSystemTools::StringEndsWith(objectFileName, pchExtension)) {
@@ -842,15 +842,14 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatements()
 
     cmNinjaDeps& orderOnlyDeps = build.OrderOnlyDeps;
     this->GetLocalGenerator()->AppendTargetDepends(
-      this->GeneratorTarget, orderOnlyDeps, DependOnTargetOrdering);
+      this->GeneratorTarget, orderOnlyDeps, config, DependOnTargetOrdering);
 
     // Add order-only dependencies on other files associated with the target.
     cmAppend(orderOnlyDeps, this->ExtraFiles);
 
     // Add order-only dependencies on custom command outputs.
     for (cmCustomCommand const* cc : this->CustomCommands) {
-      cmCustomCommandGenerator ccg(*cc, this->GetConfigName(),
-                                   this->GetLocalGenerator());
+      cmCustomCommandGenerator ccg(*cc, config, this->GetLocalGenerator());
       const std::vector<std::string>& ccoutputs = ccg.GetOutputs();
       const std::vector<std::string>& ccbyproducts = ccg.GetByproducts();
       std::transform(ccoutputs.begin(), ccoutputs.end(),
@@ -881,9 +880,9 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatements()
 
   {
     std::vector<cmSourceFile const*> objectSources;
-    this->GeneratorTarget->GetObjectSources(objectSources, this->ConfigName);
+    this->GeneratorTarget->GetObjectSources(objectSources, config);
     for (cmSourceFile const* sf : objectSources) {
-      this->WriteObjectBuildStatement(sf);
+      this->WriteObjectBuildStatement(sf, config);
     }
   }
 
@@ -895,7 +894,7 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatements()
     build.Outputs.push_back(this->GetDyndepFilePath(language));
     build.ExplicitDeps = ddiFiles;
 
-    this->WriteTargetDependInfo(language);
+    this->WriteTargetDependInfo(language, config);
 
     // Make sure dyndep files for all our dependencies have already
     // been generated so that the '<LANG>Modules.json' files they
@@ -905,8 +904,9 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatements()
     // our dependencies produces them.  Fixing this will require
     // refactoring the Ninja generator to generate targets in
     // dependency order so that we can collect the needed information.
-    this->GetLocalGenerator()->AppendTargetDepends(
-      this->GeneratorTarget, build.OrderOnlyDeps, DependOnTargetArtifact);
+    this->GetLocalGenerator()->AppendTargetDepends(this->GeneratorTarget,
+                                                   build.OrderOnlyDeps, config,
+                                                   DependOnTargetArtifact);
 
     this->GetGlobalGenerator()->WriteBuild(this->GetBuildFileStream(), build);
   }
@@ -937,7 +937,7 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatements()
 }
 
 void cmNinjaTargetGenerator::WriteObjectBuildStatement(
-  cmSourceFile const* source)
+  cmSourceFile const* source, const std::string& config)
 {
   std::string const language = source->GetLanguage();
   std::string const sourceFileName =
@@ -963,9 +963,9 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatement(
 
   cmNinjaBuild objBuild(this->LanguageCompilerRule(language));
   cmNinjaVars& vars = objBuild.Variables;
-  vars["FLAGS"] = this->ComputeFlagsForObject(source, language);
-  vars["DEFINES"] = this->ComputeDefines(source, language);
-  vars["INCLUDES"] = this->ComputeIncludes(source, language);
+  vars["FLAGS"] = this->ComputeFlagsForObject(source, language, config);
+  vars["DEFINES"] = this->ComputeDefines(source, language, config);
+  vars["INCLUDES"] = this->ComputeIncludes(source, language, config);
 
   if (!this->NeedDepTypeMSVC(language)) {
     bool replaceExt(false);
@@ -1006,13 +1006,11 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatement(
   std::vector<std::string> depList;
 
   const std::string pchSource =
-    this->GeneratorTarget->GetPchSource(this->GetConfigName(), language);
+    this->GeneratorTarget->GetPchSource(config, language);
   if (!pchSource.empty() && !source->GetProperty("SKIP_PRECOMPILE_HEADERS")) {
-    depList.push_back(
-      this->GeneratorTarget->GetPchHeader(this->GetConfigName(), language));
+    depList.push_back(this->GeneratorTarget->GetPchHeader(config, language));
     if (source->GetFullPath() != pchSource) {
-      depList.push_back(
-        this->GeneratorTarget->GetPchFile(this->GetConfigName(), language));
+      depList.push_back(this->GeneratorTarget->GetPchFile(config, language));
     }
   }
 
@@ -1114,7 +1112,7 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatement(
 
       std::string sourceDirectoryFlag = this->LocalGenerator->GetIncludeFlags(
         sourceDirectory, this->GeneratorTarget, language, false, false,
-        this->GetConfigName());
+        config);
 
       vars["INCLUDES"] = sourceDirectoryFlag + " " + vars["INCLUDES"];
     }
@@ -1163,7 +1161,7 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatement(
   this->addPoolNinjaVariable("JOB_POOL_COMPILE", this->GetGeneratorTarget(),
                              vars);
 
-  this->SetMsvcTargetPdbVariable(vars);
+  this->SetMsvcTargetPdbVariable(vars, config);
 
   objBuild.RspFile = objectFileName + ".rsp";
 
@@ -1185,7 +1183,8 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatement(
   }
 }
 
-void cmNinjaTargetGenerator::WriteTargetDependInfo(std::string const& lang)
+void cmNinjaTargetGenerator::WriteTargetDependInfo(std::string const& lang,
+                                                   const std::string& config)
 {
   Json::Value tdi(Json::objectValue);
   tdi["language"] = lang;
@@ -1213,7 +1212,7 @@ void cmNinjaTargetGenerator::WriteTargetDependInfo(std::string const& lang)
   Json::Value& tdi_include_dirs = tdi["include-dirs"] = Json::arrayValue;
   std::vector<std::string> includes;
   this->LocalGenerator->GetIncludeDirectories(includes, this->GeneratorTarget,
-                                              lang, this->GetConfigName());
+                                              lang, config);
   for (std::string const& i : includes) {
     // Convert the include directories the same way we do for -I flags.
     // See upstream ninja issue 1251.
@@ -1222,7 +1221,7 @@ void cmNinjaTargetGenerator::WriteTargetDependInfo(std::string const& lang)
 
   Json::Value& tdi_linked_target_dirs = tdi["linked-target-dirs"] =
     Json::arrayValue;
-  for (std::string const& l : this->GetLinkedTargetDirectories()) {
+  for (std::string const& l : this->GetLinkedTargetDirectories(config)) {
     tdi_linked_target_dirs.append(l);
   }
 
@@ -1349,16 +1348,14 @@ void cmNinjaTargetGenerator::ExportObjectCompileCommand(
   this->GetGlobalGenerator()->AddCXXCompileCommand(cmdLine, sourceFileName);
 }
 
-void cmNinjaTargetGenerator::AdditionalCleanFiles()
+void cmNinjaTargetGenerator::AdditionalCleanFiles(const std::string& config)
 {
   if (const char* prop_value =
         this->GeneratorTarget->GetProperty("ADDITIONAL_CLEAN_FILES")) {
     cmLocalNinjaGenerator* lg = this->LocalGenerator;
     std::vector<std::string> cleanFiles;
-    cmExpandList(cmGeneratorExpression::Evaluate(
-                   prop_value, lg,
-                   this->Makefile->GetSafeDefinition("CMAKE_BUILD_TYPE"),
-                   this->GeneratorTarget),
+    cmExpandList(cmGeneratorExpression::Evaluate(prop_value, lg, config,
+                                                 this->GeneratorTarget),
                  cleanFiles);
     std::string const& binaryDir = lg->GetCurrentBinaryDirectory();
     cmGlobalNinjaGenerator* gg = lg->GetGlobalNinjaGenerator();
@@ -1392,7 +1389,7 @@ void cmNinjaTargetGenerator::EnsureParentDirectoryExists(
 }
 
 void cmNinjaTargetGenerator::MacOSXContentGeneratorType::operator()(
-  cmSourceFile const& source, const char* pkgloc)
+  cmSourceFile const& source, const char* pkgloc, const std::string& config)
 {
   // Skip OS X content when not building a Framework or Bundle.
   if (!this->Generator->GetGeneratorTarget()->IsBundleOnApple()) {
@@ -1400,7 +1397,8 @@ void cmNinjaTargetGenerator::MacOSXContentGeneratorType::operator()(
   }
 
   std::string macdir =
-    this->Generator->OSXBundleGenerator->InitMacOSXContentDirectory(pkgloc);
+    this->Generator->OSXBundleGenerator->InitMacOSXContentDirectory(pkgloc,
+                                                                    config);
 
   // Get the input file location.
   std::string input = source.GetFullPath();

+ 23 - 14
Source/cmNinjaTargetGenerator.h

@@ -38,14 +38,14 @@ public:
   /// Destructor.
   ~cmNinjaTargetGenerator() override;
 
-  virtual void Generate() = 0;
+  virtual void Generate(const std::string& config) = 0;
 
   std::string GetTargetName() const;
 
   bool NeedDepTypeMSVC(const std::string& lang) const;
 
 protected:
-  bool SetMsvcTargetPdbVariable(cmNinjaVars&) const;
+  bool SetMsvcTargetPdbVariable(cmNinjaVars&, const std::string& config) const;
 
   cmGeneratedFileStream& GetBuildFileStream() const;
   cmGeneratedFileStream& GetRulesFileStream() const;
@@ -82,15 +82,19 @@ protected:
    *       by LanguageFlagsVarName().
    */
   std::string ComputeFlagsForObject(cmSourceFile const* source,
-                                    const std::string& language);
+                                    const std::string& language,
+                                    const std::string& config);
 
-  void AddIncludeFlags(std::string& flags, std::string const& lang) override;
+  void AddIncludeFlags(std::string& flags, std::string const& lang,
+                       const std::string& config) override;
 
   std::string ComputeDefines(cmSourceFile const* source,
-                             const std::string& language);
+                             const std::string& language,
+                             const std::string& config);
 
   std::string ComputeIncludes(cmSourceFile const* source,
-                              const std::string& language);
+                              const std::string& language,
+                              const std::string& config);
 
   std::string ConvertToNinjaPath(const std::string& path) const
   {
@@ -102,7 +106,8 @@ protected:
   }
 
   /// @return the list of link dependency for the given target @a target.
-  cmNinjaDeps ComputeLinkDeps(const std::string& linkLanguage) const;
+  cmNinjaDeps ComputeLinkDeps(const std::string& linkLanguage,
+                              const std::string& config) const;
 
   /// @return the source file path for the given @a source.
   std::string GetSourceFilePath(cmSourceFile const* source) const;
@@ -120,16 +125,19 @@ protected:
   std::string GetTargetDependInfoPath(std::string const& lang) const;
 
   /// @return the file path where the target named @a name is generated.
-  std::string GetTargetFilePath(const std::string& name) const;
+  std::string GetTargetFilePath(const std::string& name,
+                                const std::string& config) const;
 
   /// @return the output path for the target.
-  virtual std::string GetTargetOutputDir() const;
+  virtual std::string GetTargetOutputDir(const std::string& config) const;
 
   void WriteLanguageRules(const std::string& language);
   void WriteCompileRule(const std::string& language);
-  void WriteObjectBuildStatements();
-  void WriteObjectBuildStatement(cmSourceFile const* source);
-  void WriteTargetDependInfo(std::string const& lang);
+  void WriteObjectBuildStatements(const std::string& config);
+  void WriteObjectBuildStatement(cmSourceFile const* source,
+                                 const std::string& config);
+  void WriteTargetDependInfo(std::string const& lang,
+                             const std::string& config);
 
   void EmitSwiftDependencyInfo(cmSourceFile const* source);
 
@@ -139,7 +147,7 @@ protected:
     std::string const& objectFileDir, std::string const& flags,
     std::string const& defines, std::string const& includes);
 
-  void AdditionalCleanFiles();
+  void AdditionalCleanFiles(const std::string& config);
 
   cmNinjaDeps GetObjects() const { return this->Objects; }
 
@@ -155,7 +163,8 @@ protected:
     {
     }
 
-    void operator()(cmSourceFile const& source, const char* pkgloc) override;
+    void operator()(cmSourceFile const& source, const char* pkgloc,
+                    const std::string& config) override;
 
   private:
     cmNinjaTargetGenerator* Generator;

+ 8 - 11
Source/cmNinjaUtilityTargetGenerator.cxx

@@ -15,7 +15,6 @@
 #include "cmGeneratorTarget.h"
 #include "cmGlobalNinjaGenerator.h"
 #include "cmLocalNinjaGenerator.h"
-#include "cmMakefile.h"
 #include "cmNinjaTypes.h"
 #include "cmOutputConverter.h"
 #include "cmSourceFile.h"
@@ -31,7 +30,7 @@ cmNinjaUtilityTargetGenerator::cmNinjaUtilityTargetGenerator(
 
 cmNinjaUtilityTargetGenerator::~cmNinjaUtilityTargetGenerator() = default;
 
-void cmNinjaUtilityTargetGenerator::Generate()
+void cmNinjaUtilityTargetGenerator::Generate(const std::string& config)
 {
   cmGlobalNinjaGenerator* gg = this->GetGlobalGenerator();
   cmLocalNinjaGenerator* lg = this->GetLocalGenerator();
@@ -55,8 +54,8 @@ void cmNinjaUtilityTargetGenerator::Generate()
 
     for (std::vector<cmCustomCommand> const* cmdList : cmdLists) {
       for (cmCustomCommand const& ci : *cmdList) {
-        cmCustomCommandGenerator ccg(ci, this->GetConfigName(), lg);
-        lg->AppendCustomCommandDeps(ccg, deps);
+        cmCustomCommandGenerator ccg(ci, config, lg);
+        lg->AppendCustomCommandDeps(ccg, deps, config);
         lg->AppendCustomCommandLines(ccg, commands);
         std::vector<std::string> const& ccByproducts = ccg.GetByproducts();
         std::transform(ccByproducts.begin(), ccByproducts.end(),
@@ -69,13 +68,11 @@ void cmNinjaUtilityTargetGenerator::Generate()
   }
 
   {
-    std::string const& config =
-      this->GetMakefile()->GetSafeDefinition("CMAKE_BUILD_TYPE");
     std::vector<cmSourceFile*> sources;
     genTarget->GetSourceFiles(sources, config);
     for (cmSourceFile const* source : sources) {
       if (cmCustomCommand const* cc = source->GetCustomCommand()) {
-        cmCustomCommandGenerator ccg(*cc, this->GetConfigName(), lg);
+        cmCustomCommandGenerator ccg(*cc, config, lg);
         lg->AddCustomCommandTarget(cc, genTarget);
 
         // Depend on all custom command outputs.
@@ -89,8 +86,8 @@ void cmNinjaUtilityTargetGenerator::Generate()
     }
   }
 
-  lg->AppendTargetOutputs(genTarget, phonyBuild.Outputs);
-  lg->AppendTargetDepends(genTarget, deps);
+  lg->AppendTargetOutputs(genTarget, phonyBuild.Outputs, config);
+  lg->AppendTargetDepends(genTarget, deps, config);
 
   if (commands.empty()) {
     phonyBuild.Comment = "Utility command for " + this->GetTargetName();
@@ -137,12 +134,12 @@ void cmNinjaUtilityTargetGenerator::Generate()
   }
 
   // Find ADDITIONAL_CLEAN_FILES
-  this->AdditionalCleanFiles();
+  this->AdditionalCleanFiles(config);
 
   // Add an alias for the logical target name regardless of what directory
   // contains it.  Skip this for GLOBAL_TARGET because they are meant to
   // be per-directory and have one at the top-level anyway.
   if (genTarget->GetType() != cmStateEnums::GLOBAL_TARGET) {
-    gg->AddTargetAlias(this->GetTargetName(), genTarget);
+    gg->AddTargetAlias(this->GetTargetName(), genTarget, config);
   }
 }

+ 3 - 1
Source/cmNinjaUtilityTargetGenerator.h

@@ -5,6 +5,8 @@
 
 #include "cmConfigure.h" // IWYU pragma: keep
 
+#include <string>
+
 #include "cmNinjaTargetGenerator.h"
 
 class cmGeneratorTarget;
@@ -15,7 +17,7 @@ public:
   cmNinjaUtilityTargetGenerator(cmGeneratorTarget* target);
   ~cmNinjaUtilityTargetGenerator() override;
 
-  void Generate() override;
+  void Generate(const std::string& config) override;
 };
 
 #endif // ! cmNinjaUtilityTargetGenerator_h

+ 32 - 39
Source/cmOSXBundleGenerator.cxx

@@ -3,7 +3,6 @@
 #include "cmOSXBundleGenerator.h"
 
 #include <cassert>
-#include <utility>
 
 #include "cmGeneratorTarget.h"
 #include "cmLocalGenerator.h"
@@ -15,12 +14,10 @@
 
 class cmSourceFile;
 
-cmOSXBundleGenerator::cmOSXBundleGenerator(cmGeneratorTarget* target,
-                                           std::string configName)
+cmOSXBundleGenerator::cmOSXBundleGenerator(cmGeneratorTarget* target)
   : GT(target)
   , Makefile(target->Target->GetMakefile())
   , LocalGenerator(target->GetLocalGenerator())
-  , ConfigName(std::move(configName))
   , MacContentFolders(nullptr)
 {
   if (this->MustSkip()) {
@@ -34,34 +31,34 @@ bool cmOSXBundleGenerator::MustSkip()
 }
 
 void cmOSXBundleGenerator::CreateAppBundle(const std::string& targetName,
-                                           std::string& outpath)
+                                           std::string& outpath,
+                                           const std::string& config)
 {
   if (this->MustSkip()) {
     return;
   }
 
   // Compute bundle directory names.
-  std::string out =
-    cmStrCat(outpath, '/',
-             this->GT->GetAppBundleDirectory(this->ConfigName,
-                                             cmGeneratorTarget::FullLevel));
+  std::string out = cmStrCat(
+    outpath, '/',
+    this->GT->GetAppBundleDirectory(config, cmGeneratorTarget::FullLevel));
   cmSystemTools::MakeDirectory(out);
   this->Makefile->AddCMakeOutputFile(out);
 
   // Configure the Info.plist file.  Note that it needs the executable name
   // to be set.
-  std::string plist =
-    cmStrCat(outpath, '/',
-             this->GT->GetAppBundleDirectory(this->ConfigName,
-                                             cmGeneratorTarget::ContentLevel),
-             "/Info.plist");
+  std::string plist = cmStrCat(
+    outpath, '/',
+    this->GT->GetAppBundleDirectory(config, cmGeneratorTarget::ContentLevel),
+    "/Info.plist");
   this->LocalGenerator->GenerateAppleInfoPList(this->GT, targetName, plist);
   this->Makefile->AddCMakeOutputFile(plist);
   outpath = out;
 }
 
 void cmOSXBundleGenerator::CreateFramework(const std::string& targetName,
-                                           const std::string& outpath)
+                                           const std::string& outpath,
+                                           const std::string& config)
 {
   if (this->MustSkip()) {
     return;
@@ -70,15 +67,13 @@ void cmOSXBundleGenerator::CreateFramework(const std::string& targetName,
   assert(this->MacContentFolders);
 
   // Compute the location of the top-level foo.framework directory.
-  std::string contentdir =
-    cmStrCat(outpath, '/',
-             this->GT->GetFrameworkDirectory(this->ConfigName,
-                                             cmGeneratorTarget::ContentLevel),
-             '/');
+  std::string contentdir = cmStrCat(
+    outpath, '/',
+    this->GT->GetFrameworkDirectory(config, cmGeneratorTarget::ContentLevel),
+    '/');
 
   std::string newoutpath = outpath + "/" +
-    this->GT->GetFrameworkDirectory(this->ConfigName,
-                                    cmGeneratorTarget::FullLevel);
+    this->GT->GetFrameworkDirectory(config, cmGeneratorTarget::FullLevel);
 
   std::string frameworkVersion = this->GT->GetFrameworkVersion();
 
@@ -156,27 +151,26 @@ void cmOSXBundleGenerator::CreateFramework(const std::string& targetName,
 }
 
 void cmOSXBundleGenerator::CreateCFBundle(const std::string& targetName,
-                                          const std::string& root)
+                                          const std::string& root,
+                                          const std::string& config)
 {
   if (this->MustSkip()) {
     return;
   }
 
   // Compute bundle directory names.
-  std::string out =
-    cmStrCat(root, '/',
-             this->GT->GetCFBundleDirectory(this->ConfigName,
-                                            cmGeneratorTarget::FullLevel));
+  std::string out = cmStrCat(
+    root, '/',
+    this->GT->GetCFBundleDirectory(config, cmGeneratorTarget::FullLevel));
   cmSystemTools::MakeDirectory(out);
   this->Makefile->AddCMakeOutputFile(out);
 
   // Configure the Info.plist file.  Note that it needs the executable name
   // to be set.
-  std::string plist =
-    cmStrCat(root, '/',
-             this->GT->GetCFBundleDirectory(this->ConfigName,
-                                            cmGeneratorTarget::ContentLevel),
-             "/Info.plist");
+  std::string plist = cmStrCat(
+    root, '/',
+    this->GT->GetCFBundleDirectory(config, cmGeneratorTarget::ContentLevel),
+    "/Info.plist");
   std::string name = cmSystemTools::GetFilenameName(targetName);
   this->LocalGenerator->GenerateAppleInfoPList(this->GT, name, plist);
   this->Makefile->AddCMakeOutputFile(plist);
@@ -184,7 +178,7 @@ void cmOSXBundleGenerator::CreateCFBundle(const std::string& targetName,
 
 void cmOSXBundleGenerator::GenerateMacOSXContentStatements(
   std::vector<cmSourceFile const*> const& sources,
-  MacOSXContentGeneratorType* generator)
+  MacOSXContentGeneratorType* generator, const std::string& config)
 {
   if (this->MustSkip()) {
     return;
@@ -194,20 +188,19 @@ void cmOSXBundleGenerator::GenerateMacOSXContentStatements(
     cmGeneratorTarget::SourceFileFlags tsFlags =
       this->GT->GetTargetSourceFileFlags(source);
     if (tsFlags.Type != cmGeneratorTarget::SourceFileTypeNormal) {
-      (*generator)(*source, tsFlags.MacFolder);
+      (*generator)(*source, tsFlags.MacFolder, config);
     }
   }
 }
 
 std::string cmOSXBundleGenerator::InitMacOSXContentDirectory(
-  const char* pkgloc)
+  const char* pkgloc, const std::string& config)
 {
   // Construct the full path to the content subdirectory.
 
-  std::string macdir =
-    cmStrCat(this->GT->GetMacContentDirectory(
-               this->ConfigName, cmStateEnums::RuntimeBinaryArtifact),
-             '/', pkgloc);
+  std::string macdir = cmStrCat(this->GT->GetMacContentDirectory(
+                                  config, cmStateEnums::RuntimeBinaryArtifact),
+                                '/', pkgloc);
   cmSystemTools::MakeDirectory(macdir);
 
   // Record use of this content location.  Only the first level

+ 12 - 9
Source/cmOSXBundleGenerator.h

@@ -17,29 +17,33 @@ class cmSourceFile;
 class cmOSXBundleGenerator
 {
 public:
-  cmOSXBundleGenerator(cmGeneratorTarget* target, std::string configName);
+  cmOSXBundleGenerator(cmGeneratorTarget* target);
 
   // create an app bundle at a given root, and return
   // the directory within the bundle that contains the executable
-  void CreateAppBundle(const std::string& targetName, std::string& root);
+  void CreateAppBundle(const std::string& targetName, std::string& root,
+                       const std::string& config);
 
   // create a framework at a given root
-  void CreateFramework(const std::string& targetName, const std::string& root);
+  void CreateFramework(const std::string& targetName, const std::string& root,
+                       const std::string& config);
 
   // create a cf bundle at a given root
-  void CreateCFBundle(const std::string& targetName, const std::string& root);
+  void CreateCFBundle(const std::string& targetName, const std::string& root,
+                      const std::string& config);
 
   struct MacOSXContentGeneratorType
   {
     virtual ~MacOSXContentGeneratorType() = default;
-    virtual void operator()(cmSourceFile const& source,
-                            const char* pkgloc) = 0;
+    virtual void operator()(cmSourceFile const& source, const char* pkgloc,
+                            const std::string& config) = 0;
   };
 
   void GenerateMacOSXContentStatements(
     std::vector<cmSourceFile const*> const& sources,
-    MacOSXContentGeneratorType* generator);
-  std::string InitMacOSXContentDirectory(const char* pkgloc);
+    MacOSXContentGeneratorType* generator, const std::string& config);
+  std::string InitMacOSXContentDirectory(const char* pkgloc,
+                                         const std::string& config);
 
   void SetMacContentFolders(std::set<std::string>* macContentFolders)
   {
@@ -53,7 +57,6 @@ private:
   cmGeneratorTarget* GT;
   cmMakefile* Makefile;
   cmLocalGenerator* LocalGenerator;
-  std::string ConfigName;
   std::set<std::string>* MacContentFolders;
 };