Browse Source

Merge topic 'prepare-per-config-objects'

ca697bfc cmGeneratorTarget: Drop obj libs from GetConfigCommonSourceFiles
e44a8d2c Xcode: Refactor loop over all sources
97cc29c7 VS: Teach generators how to mark per-config source files
2f6f6f0c Xcode: Use config-specific object library files on link lines
888c8af6 VS: List config-specific object library files on link lines
40aa6c05 cmGeneratorTarget: Add method to collect all sources for all configs

Acked-by: Kitware Robot <[email protected]>
Merge-request: !701
Brad King 8 years ago
parent
commit
be2c45f2a9

+ 52 - 2
Source/cmGeneratorTarget.cxx

@@ -949,6 +949,19 @@ void cmGeneratorTarget::GetSourceFiles(std::vector<cmSourceFile*>& files,
   }
 }
 
+void cmGeneratorTarget::GetSourceFilesWithoutObjectLibraries(
+  std::vector<cmSourceFile*>& files, const std::string& config) const
+{
+  KindedSources const& kinded = this->GetKindedSources(config);
+  files.reserve(kinded.Sources.size());
+  for (std::vector<SourceAndKind>::const_iterator si = kinded.Sources.begin();
+       si != kinded.Sources.end(); ++si) {
+    if (si->Source->GetObjectLibrary().empty()) {
+      files.push_back(si->Source);
+    }
+  }
+}
+
 cmGeneratorTarget::KindedSources const& cmGeneratorTarget::GetKindedSources(
   std::string const& config) const
 {
@@ -1069,6 +1082,43 @@ void cmGeneratorTarget::ComputeKindedSources(KindedSources& files,
   }
 }
 
+std::vector<cmGeneratorTarget::AllConfigSource> const&
+cmGeneratorTarget::GetAllConfigSources() const
+{
+  if (this->AllConfigSources.empty()) {
+    this->ComputeAllConfigSources();
+  }
+  return this->AllConfigSources;
+}
+
+void cmGeneratorTarget::ComputeAllConfigSources() const
+{
+  std::vector<std::string> configs;
+  this->Makefile->GetConfigurations(configs);
+
+  std::map<cmSourceFile const*, size_t> index;
+
+  for (size_t ci = 0; ci < configs.size(); ++ci) {
+    KindedSources const& sources = this->GetKindedSources(configs[ci]);
+    for (std::vector<cmGeneratorTarget::SourceAndKind>::const_iterator si =
+           sources.Sources.begin();
+         si != sources.Sources.end(); ++si) {
+      std::map<cmSourceFile const*, size_t>::iterator mi =
+        index.find(si->Source);
+      if (mi == index.end()) {
+        AllConfigSource acs;
+        acs.Source = si->Source;
+        acs.Kind = si->Kind;
+        this->AllConfigSources.push_back(acs);
+        std::map<cmSourceFile const*, size_t>::value_type entry(
+          si->Source, this->AllConfigSources.size() - 1);
+        mi = index.insert(entry).first;
+      }
+      this->AllConfigSources[mi->second].Configs.push_back(ci);
+    }
+  }
+}
+
 std::string cmGeneratorTarget::GetCompilePDBName(
   const std::string& config) const
 {
@@ -4900,11 +4950,11 @@ bool cmGeneratorTarget::GetConfigCommonSourceFiles(
 
   std::vector<std::string>::const_iterator it = configs.begin();
   const std::string& firstConfig = *it;
-  this->GetSourceFiles(files, firstConfig);
+  this->GetSourceFilesWithoutObjectLibraries(files, firstConfig);
 
   for (; it != configs.end(); ++it) {
     std::vector<cmSourceFile*> configFiles;
-    this->GetSourceFiles(configFiles, *it);
+    this->GetSourceFilesWithoutObjectLibraries(configFiles, *it);
     if (configFiles != files) {
       std::string firstConfigFiles;
       const char* sep = "";

+ 20 - 0
Source/cmGeneratorTarget.h

@@ -12,6 +12,7 @@
 
 #include <map>
 #include <set>
+#include <stddef.h>
 #include <string>
 #include <utility>
 #include <vector>
@@ -69,6 +70,8 @@ public:
   bool GetPropertyAsBool(const std::string& prop) const;
   void GetSourceFiles(std::vector<cmSourceFile*>& files,
                       const std::string& config) const;
+  void GetSourceFilesWithoutObjectLibraries(std::vector<cmSourceFile*>& files,
+                                            const std::string& config) const;
 
   /** Source file kinds (classifications).
       Generators use this to decide how to treat a source file.  */
@@ -107,6 +110,17 @@ public:
   /** Get all sources needed for a configuration with kinds assigned.  */
   KindedSources const& GetKindedSources(std::string const& config) const;
 
+  struct AllConfigSource
+  {
+    cmSourceFile const* Source;
+    cmGeneratorTarget::SourceKind Kind;
+    std::vector<size_t> Configs;
+  };
+
+  /** Get all sources needed for all configurations with kinds and
+      per-source configurations assigned.  */
+  std::vector<AllConfigSource> const& GetAllConfigSources() const;
+
   void GetObjectSources(std::vector<cmSourceFile const*>&,
                         const std::string& config) const;
   const std::string& GetObjectName(cmSourceFile const* file);
@@ -338,6 +352,9 @@ public:
   std::string GetFullNameImported(const std::string& config,
                                   bool implib) const;
 
+  /** Get source files common to all configurations and diagnose cases
+      with per-config sources.  Excludes sources added by a TARGET_OBJECTS
+      generator expression.  */
   bool GetConfigCommonSourceFiles(std::vector<cmSourceFile*>& files) const;
 
   bool HaveBuildTreeRPATH(const std::string& config) const;
@@ -731,6 +748,9 @@ private:
   void ComputeKindedSources(KindedSources& files,
                             std::string const& config) const;
 
+  mutable std::vector<AllConfigSource> AllConfigSources;
+  void ComputeAllConfigSources() const;
+
   std::vector<TargetPropertyEntry*> IncludeDirectoriesEntries;
   std::vector<TargetPropertyEntry*> CompileOptionsEntries;
   std::vector<TargetPropertyEntry*> CompileFeaturesEntries;

+ 13 - 34
Source/cmGlobalXCodeGenerator.cxx

@@ -651,11 +651,6 @@ std::string GetGroupMapKeyFromPath(cmGeneratorTarget* target,
   return key;
 }
 
-std::string GetGroupMapKey(cmGeneratorTarget* target, cmSourceFile* sf)
-{
-  return GetGroupMapKeyFromPath(target, sf->GetFullPath());
-}
-
 cmXCodeObject* cmGlobalXCodeGenerator::CreateXCodeSourceFileFromPath(
   const std::string& fullpath, cmGeneratorTarget* target,
   const std::string& lang, cmSourceFile* sf)
@@ -2673,7 +2668,7 @@ void cmGlobalXCodeGenerator::AddDependAndLinkInformation(cmXCodeObject* target)
       std::string linkObjs;
       const char* sep = "";
       std::vector<cmSourceFile const*> objs;
-      gt->GetExternalObjects(objs, "");
+      gt->GetExternalObjects(objs, configName);
       for (std::vector<cmSourceFile const*>::const_iterator oi = objs.begin();
            oi != objs.end(); ++oi) {
         if ((*oi)->GetObjectLibrary().empty()) {
@@ -2788,42 +2783,26 @@ bool cmGlobalXCodeGenerator::CreateGroups(
         gtgt->AddSource(plist);
       }
 
-      std::vector<cmSourceFile*> classes;
-      if (!gtgt->GetConfigCommonSourceFiles(classes)) {
-        return false;
-      }
+      std::vector<cmGeneratorTarget::AllConfigSource> const& sources =
+        gtgt->GetAllConfigSources();
+
       // Put cmSourceFile instances in proper groups:
-      for (std::vector<cmSourceFile*>::const_iterator s = classes.begin();
-           s != classes.end(); s++) {
-        cmSourceFile* sf = *s;
+      for (std::vector<cmGeneratorTarget::AllConfigSource>::const_iterator si =
+             sources.begin();
+           si != sources.end(); ++si) {
+        cmSourceFile const* sf = si->Source;
+        if (this->XcodeVersion >= 50 && !sf->GetObjectLibrary().empty()) {
+          // Object library files go on the link line instead.
+          continue;
+        }
         // Add the file to the list of sources.
         std::string const& source = sf->GetFullPath();
         cmSourceGroup* sourceGroup =
           mf->FindSourceGroup(source.c_str(), sourceGroups);
         cmXCodeObject* pbxgroup = this->CreateOrGetPBXGroup(gtgt, sourceGroup);
-        std::string key = GetGroupMapKey(gtgt, sf);
+        std::string key = GetGroupMapKeyFromPath(gtgt, source);
         this->GroupMap[key] = pbxgroup;
       }
-
-      if (this->XcodeVersion < 50) {
-        // Put OBJECT_LIBRARY objects in proper groups:
-        std::vector<cmSourceFile const*> objs;
-        gtgt->GetExternalObjects(objs, "");
-        for (std::vector<cmSourceFile const*>::const_iterator oi =
-               objs.begin();
-             oi != objs.end(); ++oi) {
-          if ((*oi)->GetObjectLibrary().empty()) {
-            continue;
-          }
-          std::string const& source = (*oi)->GetFullPath();
-          cmSourceGroup* sourceGroup =
-            mf->FindSourceGroup(source.c_str(), sourceGroups);
-          cmXCodeObject* pbxgroup =
-            this->CreateOrGetPBXGroup(gtgt, sourceGroup);
-          std::string key = GetGroupMapKeyFromPath(gtgt, source);
-          this->GroupMap[key] = pbxgroup;
-        }
-      }
     }
   }
   return true;

+ 52 - 32
Source/cmLocalVisualStudio7Generator.cxx

@@ -30,7 +30,7 @@ public:
   typedef cmComputeLinkInformation::ItemVector ItemVector;
   void OutputLibraries(std::ostream& fout, ItemVector const& libs);
   void OutputObjects(std::ostream& fout, cmGeneratorTarget* t,
-                     const char* isep = 0);
+                     std::string const& config, const char* isep = 0);
 
 private:
   cmLocalVisualStudio7Generator* LocalGenerator;
@@ -1043,7 +1043,7 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(
       if (this->GetVersion() < cmGlobalVisualStudioGenerator::VS8 ||
           this->FortranProject) {
         std::ostringstream libdeps;
-        this->Internal->OutputObjects(libdeps, target);
+        this->Internal->OutputObjects(libdeps, target, configName);
         if (!libdeps.str().empty()) {
           fout << "\t\t\t\tAdditionalDependencies=\"" << libdeps.str()
                << "\"\n";
@@ -1096,7 +1096,7 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(
            << this->Makefile->GetSafeDefinition(standardLibsVar.c_str());
       if (this->GetVersion() < cmGlobalVisualStudioGenerator::VS8 ||
           this->FortranProject) {
-        this->Internal->OutputObjects(fout, target, " ");
+        this->Internal->OutputObjects(fout, target, configName, " ");
       }
       fout << " ";
       this->Internal->OutputLibraries(fout, cli.GetItems());
@@ -1181,7 +1181,7 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(
            << this->Makefile->GetSafeDefinition(standardLibsVar.c_str());
       if (this->GetVersion() < cmGlobalVisualStudioGenerator::VS8 ||
           this->FortranProject) {
-        this->Internal->OutputObjects(fout, target, " ");
+        this->Internal->OutputObjects(fout, target, configName, " ");
       }
       fout << " ";
       this->Internal->OutputLibraries(fout, cli.GetItems());
@@ -1300,21 +1300,20 @@ void cmLocalVisualStudio7GeneratorInternals::OutputLibraries(
 }
 
 void cmLocalVisualStudio7GeneratorInternals::OutputObjects(
-  std::ostream& fout, cmGeneratorTarget* gt, const char* isep)
+  std::ostream& fout, cmGeneratorTarget* gt, std::string const& configName,
+  const char* isep)
 {
   // VS < 8 does not support per-config source locations so we
   // list object library content on the link line instead.
   cmLocalVisualStudio7Generator* lg = this->LocalGenerator;
   std::string currentBinDir = lg->GetCurrentBinaryDirectory();
 
-  std::vector<cmSourceFile*> sources;
-  if (!gt->GetConfigCommonSourceFiles(sources)) {
-    return;
-  }
+  std::vector<cmSourceFile const*> objs;
+  gt->GetExternalObjects(objs, configName);
 
   const char* sep = isep ? isep : "";
-  for (std::vector<cmSourceFile*>::const_iterator i = sources.begin();
-       i != sources.end(); i++) {
+  for (std::vector<cmSourceFile const*>::const_iterator i = objs.begin();
+       i != objs.end(); ++i) {
     if (!(*i)->GetObjectLibrary().empty()) {
       std::string const& objFile = (*i)->GetFullPath();
       std::string rel = lg->ConvertToRelativePath(currentBinDir, objFile);
@@ -1369,14 +1368,14 @@ void cmLocalVisualStudio7Generator::WriteVCProjFile(std::ostream& fout,
   // We may be modifying the source groups temporarily, so make a copy.
   std::vector<cmSourceGroup> sourceGroups = this->Makefile->GetSourceGroups();
 
-  // get the classes from the source lists then add them to the groups
-  std::vector<cmSourceFile*> classes;
-  if (!target->GetConfigCommonSourceFiles(classes)) {
-    return;
-  }
-  for (std::vector<cmSourceFile*>::const_iterator i = classes.begin();
-       i != classes.end(); i++) {
-    if (!(*i)->GetObjectLibrary().empty()) {
+  std::vector<cmGeneratorTarget::AllConfigSource> const& sources =
+    target->GetAllConfigSources();
+  std::map<cmSourceFile const*, size_t> sourcesIndex;
+
+  for (size_t si = 0; si < sources.size(); ++si) {
+    cmSourceFile const* sf = sources[si].Source;
+    sourcesIndex[sf] = si;
+    if (!sf->GetObjectLibrary().empty()) {
       if (this->GetVersion() < cmGlobalVisualStudioGenerator::VS8 ||
           this->FortranProject) {
         // VS < 8 does not support per-config source locations so we
@@ -1386,10 +1385,10 @@ void cmLocalVisualStudio7Generator::WriteVCProjFile(std::ostream& fout,
       }
     }
     // Add the file to the list of sources.
-    std::string source = (*i)->GetFullPath();
+    std::string const source = sf->GetFullPath();
     cmSourceGroup* sourceGroup =
       this->Makefile->FindSourceGroup(source.c_str(), sourceGroups);
-    sourceGroup->AssignSource(*i);
+    sourceGroup->AssignSource(sf);
   }
 
   // open the project
@@ -1402,7 +1401,7 @@ void cmLocalVisualStudio7Generator::WriteVCProjFile(std::ostream& fout,
   // Loop through every source group.
   for (unsigned int i = 0; i < sourceGroups.size(); ++i) {
     cmSourceGroup sg = sourceGroups[i];
-    this->WriteGroup(&sg, target, fout, libName, configs);
+    this->WriteGroup(&sg, target, fout, libName, configs, sourcesIndex);
   }
 
   fout << "\t</Files>\n";
@@ -1424,25 +1423,28 @@ struct cmLVS7GFileConfig
 class cmLocalVisualStudio7GeneratorFCInfo
 {
 public:
-  cmLocalVisualStudio7GeneratorFCInfo(cmLocalVisualStudio7Generator* lg,
-                                      cmGeneratorTarget* target,
-                                      cmSourceFile const& sf,
-                                      std::vector<std::string> const& configs);
+  cmLocalVisualStudio7GeneratorFCInfo(
+    cmLocalVisualStudio7Generator* lg, cmGeneratorTarget* target,
+    cmGeneratorTarget::AllConfigSource const& acs,
+    std::vector<std::string> const& configs);
   std::map<std::string, cmLVS7GFileConfig> FileConfigMap;
 };
 
 cmLocalVisualStudio7GeneratorFCInfo::cmLocalVisualStudio7GeneratorFCInfo(
   cmLocalVisualStudio7Generator* lg, cmGeneratorTarget* gt,
-  cmSourceFile const& sf, std::vector<std::string> const& configs)
+  cmGeneratorTarget::AllConfigSource const& acs,
+  std::vector<std::string> const& configs)
 {
+  cmSourceFile const& sf = *acs.Source;
   std::string objectName;
   if (gt->HasExplicitObjectName(&sf)) {
     objectName = gt->GetObjectName(&sf);
   }
 
   // Compute per-source, per-config information.
+  size_t ci = 0;
   for (std::vector<std::string>::const_iterator i = configs.begin();
-       i != configs.end(); ++i) {
+       i != configs.end(); ++i, ++ci) {
     std::string configUpper = cmSystemTools::UpperCase(*i);
     cmLVS7GFileConfig fc;
     bool needfc = false;
@@ -1508,7 +1510,9 @@ cmLocalVisualStudio7GeneratorFCInfo::cmLocalVisualStudio7GeneratorFCInfo(
     }
     // If HEADER_FILE_ONLY is set, we must suppress this generation in
     // the project file
-    fc.ExcludedFromBuild = (sf.GetPropertyAsBool("HEADER_FILE_ONLY"));
+    fc.ExcludedFromBuild = sf.GetPropertyAsBool("HEADER_FILE_ONLY") ||
+      std::find(acs.Configs.begin(), acs.Configs.end(), ci) ==
+        acs.Configs.end();
     if (fc.ExcludedFromBuild) {
       needfc = true;
     }
@@ -1563,7 +1567,8 @@ std::string cmLocalVisualStudio7Generator::ComputeLongestObjectDirectory(
 
 bool cmLocalVisualStudio7Generator::WriteGroup(
   const cmSourceGroup* sg, cmGeneratorTarget* target, std::ostream& fout,
-  const std::string& libName, std::vector<std::string> const& configs)
+  const std::string& libName, std::vector<std::string> const& configs,
+  std::map<cmSourceFile const*, size_t> const& sourcesIndex)
 {
   cmGlobalVisualStudio7Generator* gg =
     static_cast<cmGlobalVisualStudio7Generator*>(this->GlobalGenerator);
@@ -1574,7 +1579,8 @@ bool cmLocalVisualStudio7Generator::WriteGroup(
   bool hasChildrenWithSources = false;
   std::ostringstream tmpOut;
   for (unsigned int i = 0; i < children.size(); ++i) {
-    if (this->WriteGroup(&children[i], target, tmpOut, libName, configs)) {
+    if (this->WriteGroup(&children[i], target, tmpOut, libName, configs,
+                         sourcesIndex)) {
       hasChildrenWithSources = true;
     }
   }
@@ -1590,15 +1596,26 @@ bool cmLocalVisualStudio7Generator::WriteGroup(
     this->WriteVCProjBeginGroup(fout, name.c_str(), "");
   }
 
+  std::vector<cmGeneratorTarget::AllConfigSource> const& sources =
+    target->GetAllConfigSources();
+
   // Loop through each source in the source group.
   for (std::vector<const cmSourceFile*>::const_iterator sf =
          sourceFiles.begin();
        sf != sourceFiles.end(); ++sf) {
     std::string source = (*sf)->GetFullPath();
-    FCInfo fcinfo(this, target, *(*sf), configs);
 
     if (source != libName || target->GetType() == cmStateEnums::UTILITY ||
         target->GetType() == cmStateEnums::GLOBAL_TARGET) {
+      // Look up the source kind and configs.
+      std::map<cmSourceFile const*, size_t>::const_iterator map_it =
+        sourcesIndex.find(*sf);
+      // The map entry must exist because we populated it earlier.
+      assert(map_it != sourcesIndex.end());
+      cmGeneratorTarget::AllConfigSource const& acs = sources[map_it->second];
+
+      FCInfo fcinfo(this, target, acs, configs);
+
       fout << "\t\t\t<File\n";
       std::string d = this->ConvertToXMLOutputPathSingle(source.c_str());
       // Tell MS-Dev what the source is.  If the compiler knows how to
@@ -1638,6 +1655,9 @@ bool cmLocalVisualStudio7Generator::WriteGroup(
             lang == "ASM_MASM") {
           aCompilerTool = "MASM";
         }
+        if (acs.Kind == cmGeneratorTarget::SourceKindExternalObject) {
+          aCompilerTool = "VCCustomBuildTool";
+        }
         for (std::map<std::string, cmLVS7GFileConfig>::const_iterator fci =
                fcinfo.FileConfigMap.begin();
              fci != fcinfo.FileConfigMap.end(); ++fci) {

+ 2 - 1
Source/cmLocalVisualStudio7Generator.h

@@ -119,7 +119,8 @@ private:
 
   bool WriteGroup(const cmSourceGroup* sg, cmGeneratorTarget* target,
                   std::ostream& fout, const std::string& libName,
-                  std::vector<std::string> const& configs);
+                  std::vector<std::string> const& configs,
+                  std::map<cmSourceFile const*, size_t> const& sourcesIndex);
 
   friend class cmLocalVisualStudio7GeneratorFCInfo;
   friend class cmLocalVisualStudio7GeneratorInternals;

+ 52 - 14
Source/cmVisualStudio10TargetGenerator.cxx

@@ -1241,16 +1241,15 @@ void cmVisualStudio10TargetGenerator::WriteGroups()
 
   // collect up group information
   std::vector<cmSourceGroup> sourceGroups = this->Makefile->GetSourceGroups();
-  std::vector<cmSourceFile*> classes;
-  if (!this->GeneratorTarget->GetConfigCommonSourceFiles(classes)) {
-    return;
-  }
+
+  std::vector<cmGeneratorTarget::AllConfigSource> const& sources =
+    this->GeneratorTarget->GetAllConfigSources();
 
   std::set<cmSourceGroup*> groupsUsed;
-  for (std::vector<cmSourceFile*>::const_iterator s = classes.begin();
-       s != classes.end(); s++) {
-    cmSourceFile* sf = *s;
-    std::string const& source = sf->GetFullPath();
+  for (std::vector<cmGeneratorTarget::AllConfigSource>::const_iterator si =
+         sources.begin();
+       si != sources.end(); ++si) {
+    std::string const& source = si->Source->GetFullPath();
     cmSourceGroup* sourceGroup =
       this->Makefile->FindSourceGroup(source.c_str(), sourceGroups);
     groupsUsed.insert(sourceGroup);
@@ -1734,12 +1733,17 @@ void cmVisualStudio10TargetGenerator::WriteAllSources()
   }
   this->WriteString("<ItemGroup>\n", 1);
 
-  cmGeneratorTarget::KindedSources const& sources =
-    this->GeneratorTarget->GetKindedSources("");
+  std::vector<size_t> all_configs;
+  for (size_t ci = 0; ci < this->Configurations.size(); ++ci) {
+    all_configs.push_back(ci);
+  }
+
+  std::vector<cmGeneratorTarget::AllConfigSource> const& sources =
+    this->GeneratorTarget->GetAllConfigSources();
 
-  for (std::vector<cmGeneratorTarget::SourceAndKind>::const_iterator si =
-         sources.Sources.begin();
-       si != sources.Sources.end(); ++si) {
+  for (std::vector<cmGeneratorTarget::AllConfigSource>::const_iterator si =
+         sources.begin();
+       si != sources.end(); ++si) {
     std::string tool;
     switch (si->Kind) {
       case cmGeneratorTarget::SourceKindAppManifest:
@@ -1810,14 +1814,35 @@ void cmVisualStudio10TargetGenerator::WriteAllSources()
     }
 
     if (!tool.empty()) {
+      // Compute set of configurations to exclude, if any.
+      std::vector<size_t> const& include_configs = si->Configs;
+      std::vector<size_t> exclude_configs;
+      std::set_difference(all_configs.begin(), all_configs.end(),
+                          include_configs.begin(), include_configs.end(),
+                          std::back_inserter(exclude_configs));
+
       if (si->Kind == cmGeneratorTarget::SourceKindObjectSource) {
+        // FIXME: refactor generation to avoid tracking XML syntax state.
         this->WriteSource(tool, si->Source, " ");
-        if (this->OutputSourceSpecificFlags(si->Source)) {
+        bool have_nested = this->OutputSourceSpecificFlags(si->Source);
+        if (!exclude_configs.empty()) {
+          if (!have_nested) {
+            (*this->BuildFileStream) << ">\n";
+          }
+          this->WriteExcludeFromBuild(exclude_configs);
+          have_nested = true;
+        }
+        if (have_nested) {
           this->WriteString("</", 2);
           (*this->BuildFileStream) << tool << ">\n";
         } else {
           (*this->BuildFileStream) << " />\n";
         }
+      } else if (!exclude_configs.empty()) {
+        this->WriteSource(tool, si->Source, ">\n");
+        this->WriteExcludeFromBuild(exclude_configs);
+        this->WriteString("</", 2);
+        (*this->BuildFileStream) << tool << ">\n";
       } else {
         this->WriteSource(tool, si->Source);
       }
@@ -2001,6 +2026,19 @@ bool cmVisualStudio10TargetGenerator::OutputSourceSpecificFlags(
   return hasFlags;
 }
 
+void cmVisualStudio10TargetGenerator::WriteExcludeFromBuild(
+  std::vector<size_t> const& exclude_configs)
+{
+  for (std::vector<size_t>::const_iterator ci = exclude_configs.begin();
+       ci != exclude_configs.end(); ++ci) {
+    this->WriteString("", 3);
+    (*this->BuildFileStream)
+      << "<ExcludedFromBuild Condition=\"'$(Configuration)|$(Platform)'=='"
+      << cmVS10EscapeXML(this->Configurations[*ci]) << "|"
+      << cmVS10EscapeXML(this->Platform) << "'\">true</ExcludedFromBuild>\n";
+  }
+}
+
 void cmVisualStudio10TargetGenerator::WritePathAndIncrementalLinkOptions()
 {
   cmStateEnums::TargetType ttype = this->GeneratorTarget->GetType();

+ 1 - 0
Source/cmVisualStudio10TargetGenerator.h

@@ -62,6 +62,7 @@ private:
   void WriteNsightTegraConfigurationValues(std::string const& config);
   void WriteSource(std::string const& tool, cmSourceFile const* sf,
                    const char* end = 0);
+  void WriteExcludeFromBuild(std::vector<size_t> const& exclude_configs);
   void WriteAllSources();
   void WriteDotNetReferences();
   void WriteDotNetReference(std::string const& ref, std::string const& hint);