Преглед изворни кода

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 година
родитељ
комит
2f3a356ea8

+ 3 - 1
Source/cmExportBuildAndroidMKGenerator.cxx

@@ -47,7 +47,9 @@ void cmExportBuildAndroidMKGenerator::GenerateImportTargetCode(
   os << "LOCAL_MODULE := ";
   os << "LOCAL_MODULE := ";
   os << targetName << "\n";
   os << targetName << "\n";
   os << "LOCAL_SRC_FILES := ";
   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";
   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 dummyHead("try_compile_dummy_exe", cmStateEnums::EXECUTABLE,
                      cmTarget::VisibilityNormal, tgt->Target->GetMakefile(),
                      cmTarget::VisibilityNormal, tgt->Target->GetMakefile(),
-                     true);
+                     cmTarget::PerConfig::Yes);
 
 
   cmGeneratorTarget gDummyHead(&dummyHead, tgt->GetLocalGenerator());
   cmGeneratorTarget gDummyHead(&dummyHead, tgt->GetLocalGenerator());
 
 

+ 14 - 64
Source/cmGeneratorTarget.cxx

@@ -976,51 +976,12 @@ void cmGeneratorTarget::GetExternalObjects(
   IMPLEMENT_VISIT(SourceKindExternalObject);
   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,
 void cmGeneratorTarget::GetManifests(std::vector<cmSourceFile const*>& data,
                                      const std::string& config) const
                                      const std::string& config) const
 {
 {
   IMPLEMENT_VISIT(SourceKindManifest);
   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
 std::set<cmLinkItem> const& cmGeneratorTarget::GetUtilityItems() const
 {
 {
   if (!this->UtilityItemsDone) {
   if (!this->UtilityItemsDone) {
@@ -1040,12 +1001,6 @@ std::set<cmLinkItem> const& cmGeneratorTarget::GetUtilityItems() const
   return this->UtilityItems;
   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& cmGeneratorTarget::GetLocation(
   const std::string& config) const
   const std::string& config) const
 {
 {
@@ -1097,7 +1052,8 @@ const std::string& cmGeneratorTarget::GetLocationForBuild() const
   }
   }
 
 
   // Now handle the deprecated build-time configuration location.
   // 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");
   const char* cfgid = this->Makefile->GetDefinition("CMAKE_CFG_INTDIR");
   if (cfgid && strcmp(cfgid, ".") != 0) {
   if (cfgid && strcmp(cfgid, ".") != 0) {
     location += "/";
     location += "/";
@@ -1727,14 +1683,6 @@ void cmGeneratorTarget::ComputeKindedSources(KindedSources& files,
       }
       }
     } else if (ext == "resx") {
     } else if (ext == "resx") {
       kind = SourceKindResx;
       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") {
     } else if (ext == "appxmanifest") {
       kind = SourceKindAppManifest;
       kind = SourceKindAppManifest;
     } else if (ext == "manifest") {
     } else if (ext == "manifest") {
@@ -1743,16 +1691,6 @@ void cmGeneratorTarget::ComputeKindedSources(KindedSources& files,
       kind = SourceKindCertificate;
       kind = SourceKindCertificate;
     } else if (ext == "xaml") {
     } else if (ext == "xaml") {
       kind = SourceKindXaml;
       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())) {
     } else if (header_regex.find(sf->ResolveFullPath())) {
       kind = SourceKindHeader;
       kind = SourceKindHeader;
     } else {
     } 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> cmGeneratorTarget::GetAllConfigCompileLanguages() const
 {
 {
   std::set<std::string> languages;
   std::set<std::string> languages;

+ 11 - 26
Source/cmGeneratorTarget.h

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

+ 2 - 2
Source/cmGlobalGenerator.cxx

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

+ 1 - 1
Source/cmGlobalGenerator.h

@@ -553,7 +553,7 @@ protected:
     std::vector<std::string> Depends;
     std::vector<std::string> Depends;
     std::string WorkingDir;
     std::string WorkingDir;
     bool UsesTerminal = false;
     bool UsesTerminal = false;
-    bool PerConfig = true;
+    cmTarget::PerConfig PerConfig = cmTarget::PerConfig::Yes;
     bool StdPipesUTF8 = false;
     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,
 cmTarget* cmMakefile::AddNewTarget(cmStateEnums::TargetType type,
                                    const std::string& name)
                                    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->OrderedTargets.push_back(&it->second);
   this->GetGlobalGenerator()->IndexTarget(&it->second);
   this->GetGlobalGenerator()->IndexTarget(&it->second);
   this->GetStateSnapshot().GetDirectory().AddNormalTargetName(name);
   this->GetStateSnapshot().GetDirectory().AddNormalTargetName(name);
@@ -4261,7 +4261,7 @@ cmTarget* cmMakefile::AddImportedTarget(const std::string& name,
     new cmTarget(name, type,
     new cmTarget(name, type,
                  global ? cmTarget::VisibilityImportedGlobally
                  global ? cmTarget::VisibilityImportedGlobally
                         : cmTarget::VisibilityImported,
                         : cmTarget::VisibilityImported,
-                 this, true));
+                 this, cmTarget::PerConfig::Yes));
 
 
   // Add to the set of available imported targets.
   // Add to the set of available imported targets.
   this->ImportedTargets[name] = target.get();
   this->ImportedTargets[name] = target.get();

+ 1 - 1
Source/cmNinjaNormalTargetGenerator.cxx

@@ -1024,7 +1024,7 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement(
     std::string prefix;
     std::string prefix;
     std::string base;
     std::string base;
     std::string suffix;
     std::string suffix;
-    gt->GetFullNameComponents(prefix, base, suffix);
+    gt->GetFullNameComponents(prefix, base, suffix, config);
     std::string dbg_suffix = ".dbg";
     std::string dbg_suffix = ".dbg";
     // TODO: Where to document?
     // TODO: Where to document?
     if (mf->GetDefinition("CMAKE_DEBUG_SYMBOL_SUFFIX")) {
     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,
 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>())
   : impl(cm::make_unique<cmTargetInternals>())
 {
 {
   assert(mf);
   assert(mf);
@@ -231,7 +231,7 @@ cmTarget::cmTarget(std::string const& name, cmStateEnums::TargetType type,
     (vis == VisibilityImported || vis == VisibilityImportedGlobally);
     (vis == VisibilityImported || vis == VisibilityImportedGlobally);
   impl->ImportedGloballyVisible = vis == VisibilityImportedGlobally;
   impl->ImportedGloballyVisible = vis == VisibilityImportedGlobally;
   impl->BuildInterfaceIncludesAppended = false;
   impl->BuildInterfaceIncludesAppended = false;
-  impl->PerConfig = perConfig;
+  impl->PerConfig = (perConfig == PerConfig::Yes);
 
 
   // Check whether this is a DLL platform.
   // Check whether this is a DLL platform.
   impl->IsDLLPlatform =
   impl->IsDLLPlatform =

+ 7 - 1
Source/cmTarget.h

@@ -45,8 +45,14 @@ public:
     VisibilityImportedGlobally
     VisibilityImportedGlobally
   };
   };
 
 
+  enum class PerConfig
+  {
+    Yes,
+    No
+  };
+
   cmTarget(std::string const& name, cmStateEnums::TargetType type,
   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 const&) = delete;
   cmTarget(cmTarget&&) noexcept;
   cmTarget(cmTarget&&) noexcept;

+ 117 - 96
Source/cmVisualStudio10TargetGenerator.cxx

@@ -248,6 +248,7 @@ cmVisualStudio10TargetGenerator::cmVisualStudio10TargetGenerator(
     this->LocalGenerator->GetTargetDirectory(this->GeneratorTarget);
     this->LocalGenerator->GetTargetDirectory(this->GeneratorTarget);
   this->InSourceBuild = (this->Makefile->GetCurrentSourceDirectory() ==
   this->InSourceBuild = (this->Makefile->GetCurrentSourceDirectory() ==
                          this->Makefile->GetCurrentBinaryDirectory());
                          this->Makefile->GetCurrentBinaryDirectory());
+  this->ClassifyAllConfigSources();
 }
 }
 
 
 cmVisualStudio10TargetGenerator::~cmVisualStudio10TargetGenerator()
 cmVisualStudio10TargetGenerator::~cmVisualStudio10TargetGenerator()
@@ -921,13 +922,11 @@ void cmVisualStudio10TargetGenerator::WriteDotNetDocumentationFile(Elem& e0)
 
 
 void cmVisualStudio10TargetGenerator::WriteEmbeddedResourceGroup(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");
     Elem e1(e0, "ItemGroup");
     std::string srcDir = this->Makefile->GetCurrentSourceDirectory();
     std::string srcDir = this->Makefile->GetCurrentSourceDirectory();
     ConvertToWindowsSlash(srcDir);
     ConvertToWindowsSlash(srcDir);
-    for (cmSourceFile const* oi : resxObjs) {
+    for (cmSourceFile const* oi : this->ResxObjs) {
       std::string obj = oi->GetFullPath();
       std::string obj = oi->GetFullPath();
       ConvertToWindowsSlash(obj);
       ConvertToWindowsSlash(obj);
       bool useRelativePath = false;
       bool useRelativePath = false;
@@ -1016,11 +1015,9 @@ void cmVisualStudio10TargetGenerator::WriteEmbeddedResourceGroup(Elem& e0)
 
 
 void cmVisualStudio10TargetGenerator::WriteXamlFilesGroup(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");
     Elem e1(e0, "ItemGroup");
-    for (cmSourceFile const* oi : xamlObjs) {
+    for (cmSourceFile const* oi : this->XamlObjs) {
       std::string obj = oi->GetFullPath();
       std::string obj = oi->GetFullPath();
       std::string xamlType;
       std::string xamlType;
       cmProp xamlTypeProperty = oi->GetProperty("VS_XAML_TYPE");
       cmProp xamlTypeProperty = oi->GetProperty("VS_XAML_TYPE");
@@ -1329,21 +1326,27 @@ void cmVisualStudio10TargetGenerator::WriteNsightTegraConfigurationValues(
 void cmVisualStudio10TargetGenerator::WriteCustomCommands(Elem& e0)
 void cmVisualStudio10TargetGenerator::WriteCustomCommands(Elem& e0)
 {
 {
   this->CSharpCustomCommandNames.clear();
   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.
   // Add CMakeLists.txt file with rule to re-run CMake for user convenience.
   if (this->GeneratorTarget->GetType() != cmStateEnums::GLOBAL_TARGET &&
   if (this->GeneratorTarget->GetType() != cmStateEnums::GLOBAL_TARGET &&
       this->GeneratorTarget->GetName() != CMAKE_CHECK_BUILD_SYSTEM_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
       // Write directly rather than through WriteCustomCommand because
       // we do not want the de-duplication and it has no dependencies.
       // 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");
       Elem e1(e0, "ItemGroup");
-      for (cmSourceFile const* oi : resxObjs) {
+      for (cmSourceFile const* oi : this->ResxObjs) {
         std::string obj = oi->GetFullPath();
         std::string obj = oi->GetFullPath();
         ConvertToWindowsSlash(obj);
         ConvertToWindowsSlash(obj);
         Elem e2(e1, "EmbeddedResource");
         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 guidName = "SG_Filter_Resource Files";
         std::string guid = this->GlobalGenerator->GetGUID(guidName);
         std::string guid = this->GlobalGenerator->GetGUID(guidName);
         Elem e2(e1, "Filter");
         Elem e2(e1, "Filter");
@@ -2209,10 +2210,10 @@ void cmVisualStudio10TargetGenerator::WriteAllSources(Elem& e0)
         }
         }
       } break;
       } break;
       case cmGeneratorTarget::SourceKindResx:
       case cmGeneratorTarget::SourceKindResx:
-        // Handled elsewhere.
+        this->ResxObjs.push_back(si.Source);
         break;
         break;
       case cmGeneratorTarget::SourceKindXaml:
       case cmGeneratorTarget::SourceKindXaml:
-        // Handled elsewhere.
+        this->XamlObjs.push_back(si.Source);
         break;
         break;
     }
     }
 
 
@@ -2317,21 +2318,13 @@ void cmVisualStudio10TargetGenerator::OutputSourceSpecificFlags(
       cmGeneratorExpression::Find(*cincludes) != std::string::npos;
       cmGeneratorExpression::Find(*cincludes) != std::string::npos;
     includes += *cincludes;
     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;
   const char* compileAs = 0;
-  if (needForceLang || (linkLanguage != lang)) {
+  if (lang !=
+      this->GlobalGenerator->GetLanguageFromExtension(
+        sf.GetExtension().c_str())) {
     if (lang == "CXX") {
     if (lang == "CXX") {
       // force a C++ file type
       // force a C++ file type
       compileAs = "CompileAsCpp";
       compileAs = "CompileAsCpp";
@@ -2340,6 +2333,7 @@ void cmVisualStudio10TargetGenerator::OutputSourceSpecificFlags(
       compileAs = "CompileAsC";
       compileAs = "CompileAsC";
     }
     }
   }
   }
+
   bool noWinRT = this->TargetCompileAsWinRT && lang == "C";
   bool noWinRT = this->TargetCompileAsWinRT && lang == "C";
   // for the first time we need a new line if there is something
   // for the first time we need a new line if there is something
   // produced here.
   // produced here.
@@ -2736,13 +2730,6 @@ bool cmVisualStudio10TargetGenerator::ComputeClOptions(
     this->LocalGenerator->AddCompileOptions(flags, this->GeneratorTarget,
     this->LocalGenerator->AddCompileOptions(flags, this->GeneratorTarget,
                                             langForClCompile, configName);
                                             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.
   // Put the IPO enabled configurations into a set.
   if (this->GeneratorTarget->IsIPOEnabled(linkLanguage, configName)) {
   if (this->GeneratorTarget->IsIPOEnabled(linkLanguage, configName)) {
@@ -3493,12 +3480,12 @@ void cmVisualStudio10TargetGenerator::WriteAntBuildOptions(
   // its location as the root source directory.
   // its location as the root source directory.
   std::string rootDir = this->LocalGenerator->GetCurrentSourceDirectory();
   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;
         break;
       }
       }
     }
     }
@@ -4133,7 +4120,8 @@ void cmVisualStudio10TargetGenerator::WriteProjectReferences(Elem& e0)
     }
     }
 
 
     // Don't reference targets that don't produce any output.
     // 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("ReferenceOutputAssembly", "false");
       e2.Element("CopyToOutputDirectory", "Never");
       e2.Element("CopyToOutputDirectory", "Never");
     }
     }
@@ -4234,12 +4222,13 @@ void cmVisualStudio10TargetGenerator::WriteWinRTPackageCertificateKeyFile(
        this->GlobalGenerator->TargetsWindowsPhone()) &&
        this->GlobalGenerator->TargetsWindowsPhone()) &&
       (cmStateEnums::EXECUTABLE == this->GeneratorTarget->GetType())) {
       (cmStateEnums::EXECUTABLE == this->GeneratorTarget->GetType())) {
     std::string pfxFile;
     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 &&
     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(
 bool cmVisualStudio10TargetGenerator::IsResxHeader(
   const std::string& headerFile)
   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(
 bool cmVisualStudio10TargetGenerator::IsXamlHeader(
   const std::string& headerFile)
   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(
 bool cmVisualStudio10TargetGenerator::IsXamlSource(
   const std::string& sourceFile)
   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)
 void cmVisualStudio10TargetGenerator::WriteApplicationTypeSettings(Elem& e1)
@@ -4387,39 +4409,38 @@ void cmVisualStudio10TargetGenerator::VerifyNecessaryFiles()
   // For Windows and Windows Phone executables, we will assume that if a
   // 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
   // manifest is not present that we need to add all the necessary files
   if (this->GeneratorTarget->GetType() == cmStateEnums::EXECUTABLE) {
   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 (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 <unordered_map>
 #include <vector>
 #include <vector>
 
 
+#include "cmGeneratorTarget.h"
+
 class cmComputeLinkInformation;
 class cmComputeLinkInformation;
 class cmCustomCommand;
 class cmCustomCommand;
 class cmGeneratedFileStream;
 class cmGeneratedFileStream;
-class cmGeneratorTarget;
 class cmGlobalVisualStudio10Generator;
 class cmGlobalVisualStudio10Generator;
 class cmLocalVisualStudio10Generator;
 class cmLocalVisualStudio10Generator;
 class cmMakefile;
 class cmMakefile;
@@ -238,6 +239,14 @@ private:
   using ToolSourceMap = std::map<std::string, ToolSources>;
   using ToolSourceMap = std::map<std::string, ToolSources>;
   ToolSourceMap Tools;
   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 =
   using ConfigToSettings =
     std::unordered_map<std::string,
     std::unordered_map<std::string,
                        std::unordered_map<std::string, 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.BreakAttributes();
   xout.Attribute("BuildableIdentifier", "primary");
   xout.Attribute("BuildableIdentifier", "primary");
   xout.Attribute("BlueprintIdentifier", xcObj->GetId());
   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("BlueprintName", xcObj->GetTarget()->GetName());
   xout.Attribute("ReferencedContainer", "container:" + container);
   xout.Attribute("ReferencedContainer", "container:" + container);
   xout.EndElement();
   xout.EndElement();

+ 7 - 0
Tests/ConfigSources/CMakeLists.txt

@@ -5,6 +5,12 @@ if(NOT _isMultiConfig AND NOT CMAKE_BUILD_TYPE)
 endif()
 endif()
 project(ConfigSources CXX)
 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.
 # Per-config sources via INTERFACE_SOURCES.
 add_library(iface INTERFACE)
 add_library(iface INTERFACE)
 target_sources(iface INTERFACE
 target_sources(iface INTERFACE
@@ -21,6 +27,7 @@ add_executable(ConfigSources
   $<$<CONFIG:Debug>:main_debug.cpp>
   $<$<CONFIG:Debug>:main_debug.cpp>
   $<$<NOT:$<CONFIG:Debug>>:main_other.cpp>
   $<$<NOT:$<CONFIG:Debug>>:main_other.cpp>
   $<$<CONFIG:NotAConfig>:does_not_exist.cpp>
   $<$<CONFIG:NotAConfig>:does_not_exist.cpp>
+  ${CMAKE_CURRENT_BINARY_DIR}/config_$<CONFIG>.cpp
   )
   )
 target_link_libraries(ConfigSources iface)
 target_link_libraries(ConfigSources iface)