Browse Source

Merge topic 'src-named-for-config'

70c85c1d6f Tests: Add case for source files named with CONFIG genex
3b547e2e4b VS: Simplify logic adding source file C/C++ language flag to MSVC
27ead9d4b7 VS: Compute managed type from an existing configuration
1222327c89 VS: Write custom commands for sources from all configurations
65fe58a4b4 cmVisualStudio10TargetGenerator: Adopt Windows Store and Phone infrastructure
3fa3b7a402 cmGeneratorTarget: Remove default config from Get* methods
d6a88d2158 cmTarget: Replace "perConfig" constructor boolean with enum

Acked-by: Kitware Robot <[email protected]>
Merge-request: !4761
Brad King 5 years ago
parent
commit
2f3a356ea8

+ 3 - 1
Source/cmExportBuildAndroidMKGenerator.cxx

@@ -47,7 +47,9 @@ void cmExportBuildAndroidMKGenerator::GenerateImportTargetCode(
   os << "LOCAL_MODULE := ";
   os << targetName << "\n";
   os << "LOCAL_SRC_FILES := ";
-  std::string path = cmSystemTools::ConvertToOutputPath(target->GetFullPath());
+  std::string const noConfig; // FIXME: What config to use here?
+  std::string path =
+    cmSystemTools::ConvertToOutputPath(target->GetFullPath(noConfig));
   os << path << "\n";
 }
 

+ 1 - 1
Source/cmExportTryCompileFileGenerator.cxx

@@ -71,7 +71,7 @@ std::string cmExportTryCompileFileGenerator::FindTargets(
 
   cmTarget dummyHead("try_compile_dummy_exe", cmStateEnums::EXECUTABLE,
                      cmTarget::VisibilityNormal, tgt->Target->GetMakefile(),
-                     true);
+                     cmTarget::PerConfig::Yes);
 
   cmGeneratorTarget gDummyHead(&dummyHead, tgt->GetLocalGenerator());
 

+ 14 - 64
Source/cmGeneratorTarget.cxx

@@ -976,51 +976,12 @@ void cmGeneratorTarget::GetExternalObjects(
   IMPLEMENT_VISIT(SourceKindExternalObject);
 }
 
-void cmGeneratorTarget::GetExpectedResxHeaders(std::set<std::string>& headers,
-                                               const std::string& config) const
-{
-  KindedSources const& kinded = this->GetKindedSources(config);
-  headers = kinded.ExpectedResxHeaders;
-}
-
-void cmGeneratorTarget::GetResxSources(std::vector<cmSourceFile const*>& data,
-                                       const std::string& config) const
-{
-  IMPLEMENT_VISIT(SourceKindResx);
-}
-
-void cmGeneratorTarget::GetAppManifest(std::vector<cmSourceFile const*>& data,
-                                       const std::string& config) const
-{
-  IMPLEMENT_VISIT(SourceKindAppManifest);
-}
-
 void cmGeneratorTarget::GetManifests(std::vector<cmSourceFile const*>& data,
                                      const std::string& config) const
 {
   IMPLEMENT_VISIT(SourceKindManifest);
 }
 
-void cmGeneratorTarget::GetCertificates(std::vector<cmSourceFile const*>& data,
-                                        const std::string& config) const
-{
-  IMPLEMENT_VISIT(SourceKindCertificate);
-}
-
-void cmGeneratorTarget::GetExpectedXamlHeaders(std::set<std::string>& headers,
-                                               const std::string& config) const
-{
-  KindedSources const& kinded = this->GetKindedSources(config);
-  headers = kinded.ExpectedXamlHeaders;
-}
-
-void cmGeneratorTarget::GetExpectedXamlSources(std::set<std::string>& srcs,
-                                               const std::string& config) const
-{
-  KindedSources const& kinded = this->GetKindedSources(config);
-  srcs = kinded.ExpectedXamlSources;
-}
-
 std::set<cmLinkItem> const& cmGeneratorTarget::GetUtilityItems() const
 {
   if (!this->UtilityItemsDone) {
@@ -1040,12 +1001,6 @@ std::set<cmLinkItem> const& cmGeneratorTarget::GetUtilityItems() const
   return this->UtilityItems;
 }
 
-void cmGeneratorTarget::GetXamlSources(std::vector<cmSourceFile const*>& data,
-                                       const std::string& config) const
-{
-  IMPLEMENT_VISIT(SourceKindXaml);
-}
-
 const std::string& cmGeneratorTarget::GetLocation(
   const std::string& config) const
 {
@@ -1097,7 +1052,8 @@ const std::string& cmGeneratorTarget::GetLocationForBuild() const
   }
 
   // Now handle the deprecated build-time configuration location.
-  location = this->GetDirectory();
+  std::string const noConfig;
+  location = this->GetDirectory(noConfig);
   const char* cfgid = this->Makefile->GetDefinition("CMAKE_CFG_INTDIR");
   if (cfgid && strcmp(cfgid, ".") != 0) {
     location += "/";
@@ -1727,14 +1683,6 @@ void cmGeneratorTarget::ComputeKindedSources(KindedSources& files,
       }
     } else if (ext == "resx") {
       kind = SourceKindResx;
-      // Build and save the name of the corresponding .h file
-      // This relationship will be used later when building the project files.
-      // Both names would have been auto generated from Visual Studio
-      // where the user supplied the file name and Visual Studio
-      // appended the suffix.
-      std::string resx = sf->ResolveFullPath();
-      std::string hFileName = resx.substr(0, resx.find_last_of('.')) + ".h";
-      files.ExpectedResxHeaders.insert(hFileName);
     } else if (ext == "appxmanifest") {
       kind = SourceKindAppManifest;
     } else if (ext == "manifest") {
@@ -1743,16 +1691,6 @@ void cmGeneratorTarget::ComputeKindedSources(KindedSources& files,
       kind = SourceKindCertificate;
     } else if (ext == "xaml") {
       kind = SourceKindXaml;
-      // Build and save the name of the corresponding .h and .cpp file
-      // This relationship will be used later when building the project files.
-      // Both names would have been auto generated from Visual Studio
-      // where the user supplied the file name and Visual Studio
-      // appended the suffix.
-      std::string xaml = sf->ResolveFullPath();
-      std::string hFileName = xaml + ".h";
-      std::string cppFileName = xaml + ".cpp";
-      files.ExpectedXamlHeaders.insert(hFileName);
-      files.ExpectedXamlSources.insert(cppFileName);
     } else if (header_regex.find(sf->ResolveFullPath())) {
       kind = SourceKindHeader;
     } else {
@@ -1810,6 +1748,18 @@ void cmGeneratorTarget::ComputeAllConfigSources() const
   }
 }
 
+std::vector<cmGeneratorTarget::AllConfigSource>
+cmGeneratorTarget::GetAllConfigSources(SourceKind kind) const
+{
+  std::vector<AllConfigSource> result;
+  for (AllConfigSource const& source : this->GetAllConfigSources()) {
+    if (source.Kind == kind) {
+      result.push_back(source);
+    }
+  }
+  return result;
+}
+
 std::set<std::string> cmGeneratorTarget::GetAllConfigCompileLanguages() const
 {
   std::set<std::string> languages;

+ 11 - 26
Source/cmGeneratorTarget.h

@@ -117,9 +117,6 @@ public:
   struct KindedSources
   {
     std::vector<SourceAndKind> Sources;
-    std::set<std::string> ExpectedResxHeaders;
-    std::set<std::string> ExpectedXamlHeaders;
-    std::set<std::string> ExpectedXamlSources;
     bool Initialized = false;
   };
 
@@ -137,6 +134,9 @@ public:
       per-source configurations assigned.  */
   std::vector<AllConfigSource> const& GetAllConfigSources() const;
 
+  /** Get all sources needed for all configurations with given kind.  */
+  std::vector<AllConfigSource> GetAllConfigSources(SourceKind kind) const;
+
   /** Get all languages used to compile sources in any configuration.
       This excludes the languages of objects from object libraries.  */
   std::set<std::string> GetAllConfigCompileLanguages() const;
@@ -151,8 +151,6 @@ public:
 
   void GetModuleDefinitionSources(std::vector<cmSourceFile const*>&,
                                   const std::string& config) const;
-  void GetResxSources(std::vector<cmSourceFile const*>&,
-                      const std::string& config) const;
   void GetExternalObjects(std::vector<cmSourceFile const*>&,
                           const std::string& config) const;
   void GetHeaderSources(std::vector<cmSourceFile const*>&,
@@ -161,20 +159,8 @@ public:
                        const std::string& config) const;
   void GetCustomCommands(std::vector<cmSourceFile const*>&,
                          const std::string& config) const;
-  void GetExpectedResxHeaders(std::set<std::string>&,
-                              const std::string& config) const;
-  void GetAppManifest(std::vector<cmSourceFile const*>&,
-                      const std::string& config) const;
   void GetManifests(std::vector<cmSourceFile const*>&,
                     const std::string& config) const;
-  void GetCertificates(std::vector<cmSourceFile const*>&,
-                       const std::string& config) const;
-  void GetXamlSources(std::vector<cmSourceFile const*>&,
-                      const std::string& config) const;
-  void GetExpectedXamlHeaders(std::set<std::string>&,
-                              const std::string& config) const;
-  void GetExpectedXamlSources(std::set<std::string>&,
-                              const std::string& config) const;
 
   std::set<cmLinkItem> const& GetUtilityItems() const;
 
@@ -245,7 +231,7 @@ public:
   /** Get the full path to the target according to the settings in its
       makefile and the configuration type.  */
   std::string GetFullPath(
-    const std::string& config = "",
+    const std::string& config,
     cmStateEnums::ArtifactType artifact = cmStateEnums::RuntimeBinaryArtifact,
     bool realname = false) const;
   std::string NormalGetFullPath(const std::string& config,
@@ -283,7 +269,7 @@ public:
 
   /** Get the full name of the target according to the settings in its
       makefile.  */
-  std::string GetFullName(const std::string& config = "",
+  std::string GetFullName(const std::string& config,
                           cmStateEnums::ArtifactType artifact =
                             cmStateEnums::RuntimeBinaryArtifact) const;
 
@@ -326,8 +312,7 @@ public:
   std::string GetSOName(const std::string& config) const;
 
   void GetFullNameComponents(std::string& prefix, std::string& base,
-                             std::string& suffix,
-                             const std::string& config = "",
+                             std::string& suffix, const std::string& config,
                              cmStateEnums::ArtifactType artifact =
                                cmStateEnums::RuntimeBinaryArtifact) const;
 
@@ -540,7 +525,7 @@ public:
       configuration name is given then the generator will add its
       subdirectory for that configuration.  Otherwise just the canonical
       output directory is given.  */
-  std::string GetDirectory(const std::string& config = "",
+  std::string GetDirectory(const std::string& config,
                            cmStateEnums::ArtifactType artifact =
                              cmStateEnums::RuntimeBinaryArtifact) const;
 
@@ -548,7 +533,7 @@ public:
       If the configuration name is given then the generator will add its
       subdirectory for that configuration.  Otherwise just the canonical
       compiler pdb output directory is given.  */
-  std::string GetCompilePDBDirectory(const std::string& config = "") const;
+  std::string GetCompilePDBDirectory(const std::string& config) const;
 
   /** Get sources that must be built before the given source.  */
   std::vector<cmSourceFile*> const* GetSourceDepends(
@@ -577,7 +562,7 @@ public:
   std::string GetPDBOutputName(const std::string& config) const;
 
   /** Get the name of the pdb file for the target.  */
-  std::string GetPDBName(const std::string& config = "") const;
+  std::string GetPDBName(const std::string& config) const;
 
   /** Whether this library has soname enabled and platform supports it.  */
   bool HasSOName(const std::string& config) const;
@@ -595,10 +580,10 @@ public:
   bool IsNullImpliedByLinkLibraries(const std::string& p) const;
 
   /** Get the name of the compiler pdb file for the target.  */
-  std::string GetCompilePDBName(const std::string& config = "") const;
+  std::string GetCompilePDBName(const std::string& config) const;
 
   /** Get the path for the MSVC /Fd option for this target.  */
-  std::string GetCompilePDBPath(const std::string& config = "") const;
+  std::string GetCompilePDBPath(const std::string& config) const;
 
   // Get the target base name.
   std::string GetOutputName(const std::string& config,

+ 2 - 2
Source/cmGlobalGenerator.cxx

@@ -2535,7 +2535,7 @@ void cmGlobalGenerator::AddGlobalTarget_EditCache(
   }
   GlobalTargetInfo gti;
   gti.Name = editCacheTargetName;
-  gti.PerConfig = false;
+  gti.PerConfig = cmTarget::PerConfig::No;
   cmCustomCommandLine singleLine;
 
   // Use generator preference for the edit_cache rule if it is defined.
@@ -2571,7 +2571,7 @@ void cmGlobalGenerator::AddGlobalTarget_RebuildCache(
   gti.Name = rebuildCacheTargetName;
   gti.Message = "Running CMake to regenerate build system...";
   gti.UsesTerminal = true;
-  gti.PerConfig = false;
+  gti.PerConfig = cmTarget::PerConfig::No;
   cmCustomCommandLine singleLine;
   singleLine.push_back(cmSystemTools::GetCMakeCommand());
   singleLine.push_back("--regenerate-during-build");

+ 1 - 1
Source/cmGlobalGenerator.h

@@ -553,7 +553,7 @@ protected:
     std::vector<std::string> Depends;
     std::string WorkingDir;
     bool UsesTerminal = false;
-    bool PerConfig = true;
+    cmTarget::PerConfig PerConfig = cmTarget::PerConfig::Yes;
     bool StdPipesUTF8 = false;
   };
 

+ 6 - 6
Source/cmMakefile.cxx

@@ -2081,11 +2081,11 @@ cmTarget* cmMakefile::AddExecutable(const std::string& exeName,
 cmTarget* cmMakefile::AddNewTarget(cmStateEnums::TargetType type,
                                    const std::string& name)
 {
-  auto it =
-    this->Targets
-      .emplace(name,
-               cmTarget(name, type, cmTarget::VisibilityNormal, this, true))
-      .first;
+  auto it = this->Targets
+              .emplace(name,
+                       cmTarget(name, type, cmTarget::VisibilityNormal, this,
+                                cmTarget::PerConfig::Yes))
+              .first;
   this->OrderedTargets.push_back(&it->second);
   this->GetGlobalGenerator()->IndexTarget(&it->second);
   this->GetStateSnapshot().GetDirectory().AddNormalTargetName(name);
@@ -4261,7 +4261,7 @@ cmTarget* cmMakefile::AddImportedTarget(const std::string& name,
     new cmTarget(name, type,
                  global ? cmTarget::VisibilityImportedGlobally
                         : cmTarget::VisibilityImported,
-                 this, true));
+                 this, cmTarget::PerConfig::Yes));
 
   // Add to the set of available imported targets.
   this->ImportedTargets[name] = target.get();

+ 1 - 1
Source/cmNinjaNormalTargetGenerator.cxx

@@ -1024,7 +1024,7 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement(
     std::string prefix;
     std::string base;
     std::string suffix;
-    gt->GetFullNameComponents(prefix, base, suffix);
+    gt->GetFullNameComponents(prefix, base, suffix, config);
     std::string dbg_suffix = ".dbg";
     // TODO: Where to document?
     if (mf->GetDefinition("CMAKE_DEBUG_SYMBOL_SUFFIX")) {

+ 2 - 2
Source/cmTarget.cxx

@@ -215,7 +215,7 @@ public:
 };
 
 cmTarget::cmTarget(std::string const& name, cmStateEnums::TargetType type,
-                   Visibility vis, cmMakefile* mf, bool perConfig)
+                   Visibility vis, cmMakefile* mf, PerConfig perConfig)
   : impl(cm::make_unique<cmTargetInternals>())
 {
   assert(mf);
@@ -231,7 +231,7 @@ cmTarget::cmTarget(std::string const& name, cmStateEnums::TargetType type,
     (vis == VisibilityImported || vis == VisibilityImportedGlobally);
   impl->ImportedGloballyVisible = vis == VisibilityImportedGlobally;
   impl->BuildInterfaceIncludesAppended = false;
-  impl->PerConfig = perConfig;
+  impl->PerConfig = (perConfig == PerConfig::Yes);
 
   // Check whether this is a DLL platform.
   impl->IsDLLPlatform =

+ 7 - 1
Source/cmTarget.h

@@ -45,8 +45,14 @@ public:
     VisibilityImportedGlobally
   };
 
+  enum class PerConfig
+  {
+    Yes,
+    No
+  };
+
   cmTarget(std::string const& name, cmStateEnums::TargetType type,
-           Visibility vis, cmMakefile* mf, bool perConfig);
+           Visibility vis, cmMakefile* mf, PerConfig perConfig);
 
   cmTarget(cmTarget const&) = delete;
   cmTarget(cmTarget&&) noexcept;

+ 117 - 96
Source/cmVisualStudio10TargetGenerator.cxx

@@ -248,6 +248,7 @@ cmVisualStudio10TargetGenerator::cmVisualStudio10TargetGenerator(
     this->LocalGenerator->GetTargetDirectory(this->GeneratorTarget);
   this->InSourceBuild = (this->Makefile->GetCurrentSourceDirectory() ==
                          this->Makefile->GetCurrentBinaryDirectory());
+  this->ClassifyAllConfigSources();
 }
 
 cmVisualStudio10TargetGenerator::~cmVisualStudio10TargetGenerator()
@@ -921,13 +922,11 @@ void cmVisualStudio10TargetGenerator::WriteDotNetDocumentationFile(Elem& e0)
 
 void cmVisualStudio10TargetGenerator::WriteEmbeddedResourceGroup(Elem& e0)
 {
-  std::vector<cmSourceFile const*> resxObjs;
-  this->GeneratorTarget->GetResxSources(resxObjs, "");
-  if (!resxObjs.empty()) {
+  if (!this->ResxObjs.empty()) {
     Elem e1(e0, "ItemGroup");
     std::string srcDir = this->Makefile->GetCurrentSourceDirectory();
     ConvertToWindowsSlash(srcDir);
-    for (cmSourceFile const* oi : resxObjs) {
+    for (cmSourceFile const* oi : this->ResxObjs) {
       std::string obj = oi->GetFullPath();
       ConvertToWindowsSlash(obj);
       bool useRelativePath = false;
@@ -1016,11 +1015,9 @@ void cmVisualStudio10TargetGenerator::WriteEmbeddedResourceGroup(Elem& e0)
 
 void cmVisualStudio10TargetGenerator::WriteXamlFilesGroup(Elem& e0)
 {
-  std::vector<cmSourceFile const*> xamlObjs;
-  this->GeneratorTarget->GetXamlSources(xamlObjs, "");
-  if (!xamlObjs.empty()) {
+  if (!this->XamlObjs.empty()) {
     Elem e1(e0, "ItemGroup");
-    for (cmSourceFile const* oi : xamlObjs) {
+    for (cmSourceFile const* oi : this->XamlObjs) {
       std::string obj = oi->GetFullPath();
       std::string xamlType;
       cmProp xamlTypeProperty = oi->GetProperty("VS_XAML_TYPE");
@@ -1329,21 +1326,27 @@ void cmVisualStudio10TargetGenerator::WriteNsightTegraConfigurationValues(
 void cmVisualStudio10TargetGenerator::WriteCustomCommands(Elem& e0)
 {
   this->CSharpCustomCommandNames.clear();
-  std::vector<cmSourceFile const*> customCommands;
-  this->GeneratorTarget->GetCustomCommands(customCommands, "");
-  for (cmSourceFile const* si : customCommands) {
-    this->WriteCustomCommand(e0, si);
+
+  cmSourceFile const* srcCMakeLists =
+    this->LocalGenerator->CreateVCProjBuildRule();
+
+  for (cmGeneratorTarget::AllConfigSource const& si :
+       this->GeneratorTarget->GetAllConfigSources()) {
+    if (si.Source == srcCMakeLists) {
+      // Skip explicit reference to CMakeLists.txt source.
+      continue;
+    }
+    this->WriteCustomCommand(e0, si.Source);
   }
 
   // Add CMakeLists.txt file with rule to re-run CMake for user convenience.
   if (this->GeneratorTarget->GetType() != cmStateEnums::GLOBAL_TARGET &&
       this->GeneratorTarget->GetName() != CMAKE_CHECK_BUILD_SYSTEM_TARGET) {
-    if (cmSourceFile const* sf =
-          this->LocalGenerator->CreateVCProjBuildRule()) {
+    if (srcCMakeLists) {
       // Write directly rather than through WriteCustomCommand because
       // we do not want the de-duplication and it has no dependencies.
-      if (cmCustomCommand const* command = sf->GetCustomCommand()) {
-        this->WriteCustomRule(e0, sf, *command);
+      if (cmCustomCommand const* command = srcCMakeLists->GetCustomCommand()) {
+        this->WriteCustomRule(e0, srcCMakeLists, *command);
       }
     }
   }
@@ -1624,11 +1627,9 @@ void cmVisualStudio10TargetGenerator::WriteGroups()
       }
     }
 
-    std::vector<cmSourceFile const*> resxObjs;
-    this->GeneratorTarget->GetResxSources(resxObjs, "");
-    if (!resxObjs.empty()) {
+    if (!this->ResxObjs.empty()) {
       Elem e1(e0, "ItemGroup");
-      for (cmSourceFile const* oi : resxObjs) {
+      for (cmSourceFile const* oi : this->ResxObjs) {
         std::string obj = oi->GetFullPath();
         ConvertToWindowsSlash(obj);
         Elem e2(e1, "EmbeddedResource");
@@ -1656,7 +1657,7 @@ void cmVisualStudio10TargetGenerator::WriteGroups()
         }
       }
 
-      if (!resxObjs.empty() || !this->AddedFiles.empty()) {
+      if (!this->ResxObjs.empty() || !this->AddedFiles.empty()) {
         std::string guidName = "SG_Filter_Resource Files";
         std::string guid = this->GlobalGenerator->GetGUID(guidName);
         Elem e2(e1, "Filter");
@@ -2209,10 +2210,10 @@ void cmVisualStudio10TargetGenerator::WriteAllSources(Elem& e0)
         }
       } break;
       case cmGeneratorTarget::SourceKindResx:
-        // Handled elsewhere.
+        this->ResxObjs.push_back(si.Source);
         break;
       case cmGeneratorTarget::SourceKindXaml:
-        // Handled elsewhere.
+        this->XamlObjs.push_back(si.Source);
         break;
     }
 
@@ -2317,21 +2318,13 @@ void cmVisualStudio10TargetGenerator::OutputSourceSpecificFlags(
       cmGeneratorExpression::Find(*cincludes) != std::string::npos;
     includes += *cincludes;
   }
-  std::string lang =
-    this->GlobalGenerator->GetLanguageFromExtension(sf.GetExtension().c_str());
-  std::string sourceLang = this->LocalGenerator->GetSourceFileLanguage(sf);
-  const std::string& linkLanguage =
-    this->GeneratorTarget->GetLinkerLanguage("");
-  bool needForceLang = false;
-  // source file does not match its extension language
-  if (lang != sourceLang) {
-    needForceLang = true;
-    lang = sourceLang;
-  }
-  // if the source file does not match the linker language
-  // then force c or c++
+
+  // Force language if the file extension does not match.
+  std::string lang = this->LocalGenerator->GetSourceFileLanguage(sf);
   const char* compileAs = 0;
-  if (needForceLang || (linkLanguage != lang)) {
+  if (lang !=
+      this->GlobalGenerator->GetLanguageFromExtension(
+        sf.GetExtension().c_str())) {
     if (lang == "CXX") {
       // force a C++ file type
       compileAs = "CompileAsCpp";
@@ -2340,6 +2333,7 @@ void cmVisualStudio10TargetGenerator::OutputSourceSpecificFlags(
       compileAs = "CompileAsC";
     }
   }
+
   bool noWinRT = this->TargetCompileAsWinRT && lang == "C";
   // for the first time we need a new line if there is something
   // produced here.
@@ -2736,13 +2730,6 @@ bool cmVisualStudio10TargetGenerator::ComputeClOptions(
     this->LocalGenerator->AddCompileOptions(flags, this->GeneratorTarget,
                                             langForClCompile, configName);
   }
-  // set the correct language
-  if (linkLanguage == "C") {
-    clOptions.AddFlag("CompileAs", "CompileAsC");
-  }
-  if (linkLanguage == "CXX") {
-    clOptions.AddFlag("CompileAs", "CompileAsCpp");
-  }
 
   // Put the IPO enabled configurations into a set.
   if (this->GeneratorTarget->IsIPOEnabled(linkLanguage, configName)) {
@@ -3493,12 +3480,12 @@ void cmVisualStudio10TargetGenerator::WriteAntBuildOptions(
   // its location as the root source directory.
   std::string rootDir = this->LocalGenerator->GetCurrentSourceDirectory();
   {
-    std::vector<cmSourceFile const*> extraSources;
-    this->GeneratorTarget->GetExtraSources(extraSources, "");
-    for (cmSourceFile const* si : extraSources) {
-      if ("androidmanifest.xml" ==
-          cmSystemTools::LowerCase(si->GetLocation().GetName())) {
-        rootDir = si->GetLocation().GetDirectory();
+    for (cmGeneratorTarget::AllConfigSource const& source :
+         this->GeneratorTarget->GetAllConfigSources()) {
+      if (source.Kind == cmGeneratorTarget::SourceKindExtra &&
+          "androidmanifest.xml" ==
+            cmSystemTools::LowerCase(source.Source->GetLocation().GetName())) {
+        rootDir = source.Source->GetLocation().GetDirectory();
         break;
       }
     }
@@ -4133,7 +4120,8 @@ void cmVisualStudio10TargetGenerator::WriteProjectReferences(Elem& e0)
     }
 
     // Don't reference targets that don't produce any output.
-    if (dt->GetManagedType("") == cmGeneratorTarget::ManagedType::Undefined) {
+    if (dt->GetManagedType(this->Configurations[0]) ==
+        cmGeneratorTarget::ManagedType::Undefined) {
       e2.Element("ReferenceOutputAssembly", "false");
       e2.Element("CopyToOutputDirectory", "Never");
     }
@@ -4234,12 +4222,13 @@ void cmVisualStudio10TargetGenerator::WriteWinRTPackageCertificateKeyFile(
        this->GlobalGenerator->TargetsWindowsPhone()) &&
       (cmStateEnums::EXECUTABLE == this->GeneratorTarget->GetType())) {
     std::string pfxFile;
-    std::vector<cmSourceFile const*> certificates;
-    this->GeneratorTarget->GetCertificates(certificates, "");
-    for (cmSourceFile const* si : certificates) {
-      pfxFile = this->ConvertPath(si->GetFullPath(), false);
-      ConvertToWindowsSlash(pfxFile);
-      break;
+    for (cmGeneratorTarget::AllConfigSource const& source :
+         this->GeneratorTarget->GetAllConfigSources()) {
+      if (source.Kind == cmGeneratorTarget::SourceKindCertificate) {
+        pfxFile = this->ConvertPath(source.Source->GetFullPath(), false);
+        ConvertToWindowsSlash(pfxFile);
+        break;
+      }
     }
 
     if (this->IsMissingFiles &&
@@ -4285,28 +4274,61 @@ void cmVisualStudio10TargetGenerator::WriteWinRTPackageCertificateKeyFile(
   }
 }
 
+void cmVisualStudio10TargetGenerator::ClassifyAllConfigSources()
+{
+  for (cmGeneratorTarget::AllConfigSource const& source :
+       this->GeneratorTarget->GetAllConfigSources()) {
+    this->ClassifyAllConfigSource(source);
+  }
+}
+
+void cmVisualStudio10TargetGenerator::ClassifyAllConfigSource(
+  cmGeneratorTarget::AllConfigSource const& acs)
+{
+  switch (acs.Kind) {
+    case cmGeneratorTarget::SourceKindResx: {
+      // Build and save the name of the corresponding .h file
+      // This relationship will be used later when building the project files.
+      // Both names would have been auto generated from Visual Studio
+      // where the user supplied the file name and Visual Studio
+      // appended the suffix.
+      std::string resx = acs.Source->ResolveFullPath();
+      std::string hFileName = resx.substr(0, resx.find_last_of('.')) + ".h";
+      this->ExpectedResxHeaders.insert(hFileName);
+    } break;
+    case cmGeneratorTarget::SourceKindXaml: {
+      // Build and save the name of the corresponding .h and .cpp file
+      // This relationship will be used later when building the project files.
+      // Both names would have been auto generated from Visual Studio
+      // where the user supplied the file name and Visual Studio
+      // appended the suffix.
+      std::string xaml = acs.Source->ResolveFullPath();
+      std::string hFileName = xaml + ".h";
+      std::string cppFileName = xaml + ".cpp";
+      this->ExpectedXamlHeaders.insert(hFileName);
+      this->ExpectedXamlSources.insert(cppFileName);
+    } break;
+    default:
+      break;
+  }
+}
+
 bool cmVisualStudio10TargetGenerator::IsResxHeader(
   const std::string& headerFile)
 {
-  std::set<std::string> expectedResxHeaders;
-  this->GeneratorTarget->GetExpectedResxHeaders(expectedResxHeaders, "");
-  return expectedResxHeaders.count(headerFile) > 0;
+  return this->ExpectedResxHeaders.count(headerFile) > 0;
 }
 
 bool cmVisualStudio10TargetGenerator::IsXamlHeader(
   const std::string& headerFile)
 {
-  std::set<std::string> expectedXamlHeaders;
-  this->GeneratorTarget->GetExpectedXamlHeaders(expectedXamlHeaders, "");
-  return expectedXamlHeaders.count(headerFile) > 0;
+  return this->ExpectedXamlHeaders.count(headerFile) > 0;
 }
 
 bool cmVisualStudio10TargetGenerator::IsXamlSource(
   const std::string& sourceFile)
 {
-  std::set<std::string> expectedXamlSources;
-  this->GeneratorTarget->GetExpectedXamlSources(expectedXamlSources, "");
-  return expectedXamlSources.count(sourceFile) > 0;
+  return this->ExpectedXamlSources.count(sourceFile) > 0;
 }
 
 void cmVisualStudio10TargetGenerator::WriteApplicationTypeSettings(Elem& e1)
@@ -4387,39 +4409,38 @@ void cmVisualStudio10TargetGenerator::VerifyNecessaryFiles()
   // For Windows and Windows Phone executables, we will assume that if a
   // manifest is not present that we need to add all the necessary files
   if (this->GeneratorTarget->GetType() == cmStateEnums::EXECUTABLE) {
-    std::vector<cmSourceFile const*> manifestSources;
-    this->GeneratorTarget->GetAppManifest(manifestSources, "");
-    {
-      std::string const& v = this->GlobalGenerator->GetSystemVersion();
-      if (this->GlobalGenerator->TargetsWindowsPhone()) {
-        if (v == "8.0") {
-          // Look through the sources for WMAppManifest.xml
-          std::vector<cmSourceFile const*> extraSources;
-          this->GeneratorTarget->GetExtraSources(extraSources, "");
-          bool foundManifest = false;
-          for (cmSourceFile const* si : extraSources) {
-            // Need to do a lowercase comparison on the filename
-            if ("wmappmanifest.xml" ==
-                cmSystemTools::LowerCase(si->GetLocation().GetName())) {
-              foundManifest = true;
-              break;
-            }
-          }
-          if (!foundManifest) {
-            this->IsMissingFiles = true;
-          }
-        } else if (v == "8.1") {
-          if (manifestSources.empty()) {
-            this->IsMissingFiles = true;
+    std::vector<cmGeneratorTarget::AllConfigSource> manifestSources =
+      this->GeneratorTarget->GetAllConfigSources(
+        cmGeneratorTarget::SourceKindAppManifest);
+    std::string const& v = this->GlobalGenerator->GetSystemVersion();
+    if (this->GlobalGenerator->TargetsWindowsPhone()) {
+      if (v == "8.0") {
+        // Look through the sources for WMAppManifest.xml
+        bool foundManifest = false;
+        for (cmGeneratorTarget::AllConfigSource const& source :
+             this->GeneratorTarget->GetAllConfigSources()) {
+          if (source.Kind == cmGeneratorTarget::SourceKindExtra &&
+              "wmappmanifest.xml" ==
+                cmSystemTools::LowerCase(
+                  source.Source->GetLocation().GetName())) {
+            foundManifest = true;
+            break;
           }
         }
-      } else if (this->GlobalGenerator->TargetsWindowsStore()) {
+        if (!foundManifest) {
+          this->IsMissingFiles = true;
+        }
+      } else if (v == "8.1") {
         if (manifestSources.empty()) {
-          if (v == "8.0") {
-            this->IsMissingFiles = true;
-          } else if (v == "8.1" || cmHasLiteralPrefix(v, "10.0")) {
-            this->IsMissingFiles = true;
-          }
+          this->IsMissingFiles = true;
+        }
+      }
+    } else if (this->GlobalGenerator->TargetsWindowsStore()) {
+      if (manifestSources.empty()) {
+        if (v == "8.0") {
+          this->IsMissingFiles = true;
+        } else if (v == "8.1" || cmHasLiteralPrefix(v, "10.0")) {
+          this->IsMissingFiles = true;
         }
       }
     }

+ 10 - 1
Source/cmVisualStudio10TargetGenerator.h

@@ -13,10 +13,11 @@
 #include <unordered_map>
 #include <vector>
 
+#include "cmGeneratorTarget.h"
+
 class cmComputeLinkInformation;
 class cmCustomCommand;
 class cmGeneratedFileStream;
-class cmGeneratorTarget;
 class cmGlobalVisualStudio10Generator;
 class cmLocalVisualStudio10Generator;
 class cmMakefile;
@@ -238,6 +239,14 @@ private:
   using ToolSourceMap = std::map<std::string, ToolSources>;
   ToolSourceMap Tools;
 
+  std::set<std::string> ExpectedResxHeaders;
+  std::set<std::string> ExpectedXamlHeaders;
+  std::set<std::string> ExpectedXamlSources;
+  std::vector<cmSourceFile const*> ResxObjs;
+  std::vector<cmSourceFile const*> XamlObjs;
+  void ClassifyAllConfigSources();
+  void ClassifyAllConfigSource(cmGeneratorTarget::AllConfigSource const& acs);
+
   using ConfigToSettings =
     std::unordered_map<std::string,
                        std::unordered_map<std::string, std::string>>;

+ 2 - 1
Source/cmXCodeScheme.cxx

@@ -396,7 +396,8 @@ void cmXCodeScheme::WriteBuildableReference(cmXMLWriter& xout,
   xout.BreakAttributes();
   xout.Attribute("BuildableIdentifier", "primary");
   xout.Attribute("BlueprintIdentifier", xcObj->GetId());
-  xout.Attribute("BuildableName", xcObj->GetTarget()->GetFullName());
+  std::string const noConfig; // FIXME: What config to use here?
+  xout.Attribute("BuildableName", xcObj->GetTarget()->GetFullName(noConfig));
   xout.Attribute("BlueprintName", xcObj->GetTarget()->GetName());
   xout.Attribute("ReferencedContainer", "container:" + container);
   xout.EndElement();

+ 7 - 0
Tests/ConfigSources/CMakeLists.txt

@@ -5,6 +5,12 @@ if(NOT _isMultiConfig AND NOT CMAKE_BUILD_TYPE)
 endif()
 project(ConfigSources CXX)
 
+# Source file(s) named with the configuration(s).
+file(GENERATE
+  OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/config_$<CONFIG>.cpp"
+  CONTENT "void config_$<CONFIG>() {}\n"
+  )
+
 # Per-config sources via INTERFACE_SOURCES.
 add_library(iface INTERFACE)
 target_sources(iface INTERFACE
@@ -21,6 +27,7 @@ add_executable(ConfigSources
   $<$<CONFIG:Debug>:main_debug.cpp>
   $<$<NOT:$<CONFIG:Debug>>:main_other.cpp>
   $<$<CONFIG:NotAConfig>:does_not_exist.cpp>
+  ${CMAKE_CURRENT_BINARY_DIR}/config_$<CONFIG>.cpp
   )
 target_link_libraries(ConfigSources iface)