Parcourir la source

cmTarget: Make the source files depend on the config.

Disallow the use of config-specific source files with
the Visual Studio and Xcode generators. They don't have
any way to represent the condition currently.

Use the same common-config API in cmQtAutoGenerators. While
it accepts config-specific files, it doesn't have to support
multiple configurations yet.

Loop over the configs in cmTargetTraceDependencies
and cmGlobalGenerator::WriteSummary and consume all source
files.

Loop over the configs in cmComputeTargetDepends and compute the
object library dependencies for each config.
Stephen Kelly il y a 11 ans
Parent
commit
e6971df6ab
44 fichiers modifiés avec 492 ajouts et 138 suppressions
  1. 24 25
      Source/cmComputeTargetDepends.cxx
  2. 2 1
      Source/cmExtraCodeBlocksGenerator.cxx
  3. 2 1
      Source/cmExtraCodeLiteGenerator.cxx
  4. 2 1
      Source/cmExtraEclipseCDT4Generator.cxx
  5. 2 1
      Source/cmExtraSublimeTextGenerator.cxx
  6. 1 1
      Source/cmFLTKWrapUICommand.cxx
  7. 1 1
      Source/cmGeneratorExpressionEvaluator.cxx
  8. 52 19
      Source/cmGeneratorTarget.cxx
  9. 21 11
      Source/cmGeneratorTarget.h
  10. 16 1
      Source/cmGlobalGenerator.cxx
  11. 2 1
      Source/cmGlobalKdevelopGenerator.cxx
  12. 2 1
      Source/cmGlobalUnixMakefileGenerator3.cxx
  13. 9 1
      Source/cmGlobalVisualStudioGenerator.cxx
  14. 20 8
      Source/cmGlobalXCodeGenerator.cxx
  15. 4 3
      Source/cmLocalGenerator.cxx
  16. 4 2
      Source/cmLocalUnixMakefileGenerator3.cxx
  17. 33 4
      Source/cmLocalVisualStudio6Generator.cxx
  18. 6 3
      Source/cmLocalVisualStudio7Generator.cxx
  19. 17 12
      Source/cmMakefileTargetGenerator.cxx
  20. 2 1
      Source/cmNinjaNormalTargetGenerator.cxx
  21. 9 7
      Source/cmNinjaTargetGenerator.cxx
  22. 3 1
      Source/cmNinjaUtilityTargetGenerator.cxx
  23. 2 2
      Source/cmQtAutoGenerators.cxx
  24. 73 12
      Source/cmTarget.cxx
  25. 9 4
      Source/cmTarget.h
  26. 16 13
      Source/cmVisualStudio10TargetGenerator.cxx
  27. 4 0
      Tests/CMakeLists.txt
  28. 9 0
      Tests/ConfigSources/CMakeLists.txt
  29. 5 0
      Tests/ConfigSources/main.cpp
  30. 7 1
      Tests/QtAutogen/CMakeLists.txt
  31. 9 0
      Tests/QtAutogen/debug_class.cpp
  32. 20 0
      Tests/QtAutogen/debug_class.h
  33. 45 0
      Tests/QtAutogen/debug_class.ui
  34. 5 0
      Tests/QtAutogen/debug_resource.qrc
  35. 9 0
      Tests/QtAutogen/main.cpp
  36. 4 0
      Tests/QtAutogen/resourcetester.cpp
  37. 1 0
      Tests/RunCMake/CMakeLists.txt
  38. 3 0
      Tests/RunCMake/TargetSources/CMakeLists.txt
  39. 1 0
      Tests/RunCMake/TargetSources/ConfigNotAllowed-result.txt
  40. 14 0
      Tests/RunCMake/TargetSources/ConfigNotAllowed-stderr.txt
  41. 2 0
      Tests/RunCMake/TargetSources/ConfigNotAllowed.cmake
  42. 6 0
      Tests/RunCMake/TargetSources/RunCMakeTest.cmake
  43. 7 0
      Tests/RunCMake/TargetSources/empty_1.cpp
  44. 7 0
      Tests/RunCMake/TargetSources/empty_2.cpp

+ 24 - 25
Source/cmComputeTargetDepends.cxx

@@ -213,34 +213,10 @@ void cmComputeTargetDepends::CollectTargetDepends(int depender_index)
   // deal with config-specific dependencies.
   {
   std::set<std::string> emitted;
-  {
   cmGeneratorTarget* gt = depender->GetMakefile()->GetLocalGenerator()
                                   ->GetGlobalGenerator()
                                   ->GetGeneratorTarget(depender);
-  std::vector<cmSourceFile const*> objectFiles;
-  gt->GetExternalObjects(objectFiles);
-  for(std::vector<cmSourceFile const*>::const_iterator
-      it = objectFiles.begin(); it != objectFiles.end(); ++it)
-    {
-    std::string objLib = (*it)->GetObjectLibrary();
-    if (!objLib.empty() && emitted.insert(objLib).second)
-      {
-      if(depender->GetType() != cmTarget::EXECUTABLE &&
-          depender->GetType() != cmTarget::STATIC_LIBRARY &&
-          depender->GetType() != cmTarget::SHARED_LIBRARY &&
-          depender->GetType() != cmTarget::MODULE_LIBRARY)
-        {
-        this->GlobalGenerator->GetCMakeInstance()
-          ->IssueMessage(cmake::FATAL_ERROR,
-                          "Only executables and non-OBJECT libraries may "
-                          "reference target objects.",
-                          depender->GetBacktrace());
-        return;
-        }
-      const_cast<cmTarget*>(depender)->AddUtility(objLib);
-      }
-    }
-  }
+
   std::vector<std::string> configs;
   depender->GetMakefile()->GetConfigurations(configs);
   if (configs.empty())
@@ -250,6 +226,29 @@ void cmComputeTargetDepends::CollectTargetDepends(int depender_index)
   for (std::vector<std::string>::const_iterator it = configs.begin();
     it != configs.end(); ++it)
     {
+    std::vector<cmSourceFile const*> objectFiles;
+    gt->GetExternalObjects(objectFiles, *it);
+    for(std::vector<cmSourceFile const*>::const_iterator
+        oi = objectFiles.begin(); oi != objectFiles.end(); ++oi)
+      {
+      std::string objLib = (*oi)->GetObjectLibrary();
+      if (!objLib.empty() && emitted.insert(objLib).second)
+        {
+        if(depender->GetType() != cmTarget::EXECUTABLE &&
+            depender->GetType() != cmTarget::STATIC_LIBRARY &&
+            depender->GetType() != cmTarget::SHARED_LIBRARY &&
+            depender->GetType() != cmTarget::MODULE_LIBRARY)
+          {
+          this->GlobalGenerator->GetCMakeInstance()
+            ->IssueMessage(cmake::FATAL_ERROR,
+                            "Only executables and non-OBJECT libraries may "
+                            "reference target objects.",
+                            depender->GetBacktrace());
+          return;
+          }
+        const_cast<cmTarget*>(depender)->AddUtility(objLib);
+        }
+      }
     std::vector<std::string> tlibs;
     depender->GetDirectLinkLibraries(*it, tlibs, depender);
 

+ 2 - 1
Source/cmExtraCodeBlocksGenerator.cxx

@@ -399,7 +399,8 @@ void cmExtraCodeBlocksGenerator
         case cmTarget::UTILITY: // can have sources since 2.6.3
           {
           std::vector<cmSourceFile*> sources;
-          ti->second.GetSourceFiles(sources);
+          ti->second.GetSourceFiles(sources,
+                            makefile->GetSafeDefinition("CMAKE_BUILD_TYPE"));
           for (std::vector<cmSourceFile*>::const_iterator si=sources.begin();
                si!=sources.end(); si++)
             {

+ 2 - 1
Source/cmExtraCodeLiteGenerator.cxx

@@ -214,7 +214,8 @@ void cmExtraCodeLiteGenerator
         case cmTarget::MODULE_LIBRARY:
           {
           std::vector<cmSourceFile*> sources;
-          ti->second.GetSourceFiles(sources);
+          ti->second.GetSourceFiles(sources,
+                            makefile->GetSafeDefinition("CMAKE_BUILD_TYPE"));
           for (std::vector<cmSourceFile*>::const_iterator si=sources.begin();
                si!=sources.end(); si++)
             {

+ 2 - 1
Source/cmExtraEclipseCDT4Generator.cxx

@@ -560,7 +560,8 @@ void cmExtraEclipseCDT4Generator::CreateLinksForTargets(
           // get the files from the source lists then add them to the groups
           cmTarget* tgt = const_cast<cmTarget*>(&ti->second);
           std::vector<cmSourceFile*> files;
-          tgt->GetSourceFiles(files);
+          tgt->GetSourceFiles(files,
+                            makefile->GetSafeDefinition("CMAKE_BUILD_TYPE"));
           for(std::vector<cmSourceFile*>::const_iterator sfIt = files.begin();
               sfIt != files.end();
               sfIt++)

+ 2 - 1
Source/cmExtraSublimeTextGenerator.cxx

@@ -238,7 +238,8 @@ void cmExtraSublimeTextGenerator::
       cmGeneratorTarget *gtgt = this->GlobalGenerator
                                     ->GetGeneratorTarget(target);
       std::vector<cmSourceFile*> sourceFiles;
-      target->GetSourceFiles(sourceFiles);
+      target->GetSourceFiles(sourceFiles,
+                             makefile->GetSafeDefinition("CMAKE_BUILD_TYPE"));
       std::vector<cmSourceFile*>::const_iterator sourceFilesEnd =
         sourceFiles.end();
       for (std::vector<cmSourceFile*>::const_iterator iter =

+ 1 - 1
Source/cmFLTKWrapUICommand.cxx

@@ -133,7 +133,7 @@ void cmFLTKWrapUICommand::FinalPass()
     return;
     }
   std::vector<cmSourceFile*> srcs;
-  target->GetSourceFiles(srcs);
+  target->GetSourceFiles(srcs, "");
   bool found = false;
   for (unsigned int i = 0; i < srcs.size(); ++i)
     {

+ 1 - 1
Source/cmGeneratorExpressionEvaluator.cxx

@@ -1272,7 +1272,7 @@ static const struct TargetObjectsNode : public cmGeneratorExpressionNode
       }
 
     std::vector<cmSourceFile const*> objectSources;
-    gt->GetObjectSources(objectSources);
+    gt->GetObjectSources(objectSources, context->Config);
     std::map<cmSourceFile const*, std::string> mapping;
 
     for(std::vector<cmSourceFile const*>::const_iterator it

+ 52 - 19
Source/cmGeneratorTarget.cxx

@@ -289,7 +289,7 @@ static void handleSystemIncludesDep(cmMakefile *mf, cmTarget* depTgt,
 #define IMPLEMENT_VISIT_IMPL(DATA, DATATYPE) \
   { \
   std::vector<cmSourceFile*> sourceFiles; \
-  this->Target->GetSourceFiles(sourceFiles); \
+  this->Target->GetSourceFiles(sourceFiles, config); \
   TagVisitor<DATA ## Tag DATATYPE> visitor(this->Target, data); \
   for(std::vector<cmSourceFile*>::const_iterator si = sourceFiles.begin(); \
       si != sourceFiles.end(); ++si) \
@@ -308,7 +308,8 @@ static void handleSystemIncludesDep(cmMakefile *mf, cmTarget* depTgt,
 //----------------------------------------------------------------------------
 void
 cmGeneratorTarget
-::GetObjectSources(std::vector<cmSourceFile const*> &data) const
+::GetObjectSources(std::vector<cmSourceFile const*> &data,
+                   const std::string& config) const
 {
   IMPLEMENT_VISIT(ObjectSources);
 
@@ -332,8 +333,19 @@ void cmGeneratorTarget::ComputeObjectMapping()
     {
     return;
     }
-  std::vector<cmSourceFile const*> sourceFiles;
-  this->GetObjectSources(sourceFiles);
+
+  std::vector<std::string> configs;
+  this->Makefile->GetConfigurations(configs);
+  if (configs.empty())
+    {
+    configs.push_back("");
+    }
+  for(std::vector<std::string>::const_iterator ci = configs.begin();
+      ci != configs.end(); ++ci)
+    {
+    std::vector<cmSourceFile const*> sourceFiles;
+    this->GetObjectSources(sourceFiles, *ci);
+    }
 }
 
 //----------------------------------------------------------------------------
@@ -360,7 +372,8 @@ bool cmGeneratorTarget::HasExplicitObjectName(cmSourceFile const* file) const
 
 //----------------------------------------------------------------------------
 void cmGeneratorTarget
-::GetIDLSources(std::vector<cmSourceFile const*>& data) const
+::GetIDLSources(std::vector<cmSourceFile const*>& data,
+                const std::string& config) const
 {
   IMPLEMENT_VISIT(IDLSources);
 }
@@ -368,14 +381,16 @@ void cmGeneratorTarget
 //----------------------------------------------------------------------------
 void
 cmGeneratorTarget
-::GetHeaderSources(std::vector<cmSourceFile const*>& data) const
+::GetHeaderSources(std::vector<cmSourceFile const*>& data,
+                   const std::string& config) const
 {
   IMPLEMENT_VISIT(HeaderSources);
 }
 
 //----------------------------------------------------------------------------
 void cmGeneratorTarget
-::GetExtraSources(std::vector<cmSourceFile const*>& data) const
+::GetExtraSources(std::vector<cmSourceFile const*>& data,
+                  const std::string& config) const
 {
   IMPLEMENT_VISIT(ExtraSources);
 }
@@ -383,7 +398,8 @@ void cmGeneratorTarget
 //----------------------------------------------------------------------------
 void
 cmGeneratorTarget
-::GetCustomCommands(std::vector<cmSourceFile const*>& data) const
+::GetCustomCommands(std::vector<cmSourceFile const*>& data,
+                    const std::string& config) const
 {
   IMPLEMENT_VISIT(CustomCommands);
 }
@@ -391,14 +407,16 @@ cmGeneratorTarget
 //----------------------------------------------------------------------------
 void
 cmGeneratorTarget
-::GetExternalObjects(std::vector<cmSourceFile const*>& data) const
+::GetExternalObjects(std::vector<cmSourceFile const*>& data,
+                     const std::string& config) const
 {
   IMPLEMENT_VISIT(ExternalObjects);
 }
 
 //----------------------------------------------------------------------------
 void
-cmGeneratorTarget::GetExpectedResxHeaders(std::set<std::string>& srcs) const
+cmGeneratorTarget::GetExpectedResxHeaders(std::set<std::string>& srcs,
+                                          const std::string& config) const
 {
   ResxData data;
   IMPLEMENT_VISIT_IMPL(Resx, COMMA cmGeneratorTarget::ResxData)
@@ -407,7 +425,8 @@ cmGeneratorTarget::GetExpectedResxHeaders(std::set<std::string>& srcs) const
 
 //----------------------------------------------------------------------------
 void cmGeneratorTarget
-::GetResxSources(std::vector<cmSourceFile const*>& srcs) const
+::GetResxSources(std::vector<cmSourceFile const*>& srcs,
+                 const std::string& config) const
 {
   ResxData data;
   IMPLEMENT_VISIT_IMPL(Resx, COMMA cmGeneratorTarget::ResxData)
@@ -517,13 +536,15 @@ bool cmGeneratorTarget::GetPropertyAsBool(const std::string& prop) const
 }
 
 //----------------------------------------------------------------------------
-void cmGeneratorTarget::GetSourceFiles(std::vector<cmSourceFile*> &files) const
+void cmGeneratorTarget::GetSourceFiles(std::vector<cmSourceFile*> &files,
+                                       const std::string& config) const
 {
-  this->Target->GetSourceFiles(files);
+  this->Target->GetSourceFiles(files, config);
 }
 
 //----------------------------------------------------------------------------
-std::string cmGeneratorTarget::GetModuleDefinitionFile() const
+std::string
+cmGeneratorTarget::GetModuleDefinitionFile(const std::string& config) const
 {
   std::string data;
   IMPLEMENT_VISIT_IMPL(ModuleDefinitionFile, COMMA std::string)
@@ -532,10 +553,11 @@ std::string cmGeneratorTarget::GetModuleDefinitionFile() const
 
 //----------------------------------------------------------------------------
 void
-cmGeneratorTarget::UseObjectLibraries(std::vector<std::string>& objs) const
+cmGeneratorTarget::UseObjectLibraries(std::vector<std::string>& objs,
+                                      const std::string &config) const
 {
   std::vector<cmSourceFile const*> objectFiles;
-  this->GetExternalObjects(objectFiles);
+  this->GetExternalObjects(objectFiles, config);
   std::vector<cmTarget*> objectLibraries;
   std::set<cmTarget*> emitted;
   for(std::vector<cmSourceFile const*>::const_iterator
@@ -559,7 +581,7 @@ cmGeneratorTarget::UseObjectLibraries(std::vector<std::string>& objs) const
     cmGeneratorTarget* ogt =
       this->GlobalGenerator->GetGeneratorTarget(objLib);
     std::vector<cmSourceFile const*> objectSources;
-    ogt->GetObjectSources(objectSources);
+    ogt->GetObjectSources(objectSources, config);
     for(std::vector<cmSourceFile const*>::const_iterator
           si = objectSources.begin();
         si != objectSources.end(); ++si)
@@ -615,11 +637,22 @@ cmTargetTraceDependencies
   if (this->Target->GetType() != cmTarget::INTERFACE_LIBRARY)
     {
     std::vector<std::string> sources;
-    this->Target->GetSourceFiles(sources);
+    std::vector<std::string> configs;
+    this->Makefile->GetConfigurations(configs);
+    if (configs.empty())
+      {
+      configs.push_back("");
+      }
+    for(std::vector<std::string>::const_iterator ci = configs.begin();
+        ci != configs.end(); ++ci)
+      {
+      this->Target->GetSourceFiles(sources, *ci);
+      }
+    std::set<std::string> emitted;
     for(std::vector<std::string>::const_iterator si = sources.begin();
         si != sources.end(); ++si)
       {
-      if(this->SourcesQueued.insert(*si).second)
+      if(emitted.insert(*si).second && this->SourcesQueued.insert(*si).second)
         {
         this->SourceQueue.push(*si);
         this->Makefile->GetOrCreateSource(*si);

+ 21 - 11
Source/cmGeneratorTarget.h

@@ -30,21 +30,30 @@ public:
   std::string GetName() const;
   const char *GetProperty(const std::string& prop) const;
   bool GetPropertyAsBool(const std::string& prop) const;
-  void GetSourceFiles(std::vector<cmSourceFile*>& files) const;
+  void GetSourceFiles(std::vector<cmSourceFile*>& files,
+                      const std::string& config) const;
 
-  void GetObjectSources(std::vector<cmSourceFile const*> &) const;
+  void GetObjectSources(std::vector<cmSourceFile const*> &,
+                        const std::string& config) const;
   const std::string& GetObjectName(cmSourceFile const* file);
 
   bool HasExplicitObjectName(cmSourceFile const* file) const;
   void AddExplicitObjectName(cmSourceFile const* sf);
 
-  void GetResxSources(std::vector<cmSourceFile const*>&) const;
-  void GetIDLSources(std::vector<cmSourceFile const*>&) const;
-  void GetExternalObjects(std::vector<cmSourceFile const*>&) const;
-  void GetHeaderSources(std::vector<cmSourceFile const*>&) const;
-  void GetExtraSources(std::vector<cmSourceFile const*>&) const;
-  void GetCustomCommands(std::vector<cmSourceFile const*>&) const;
-  void GetExpectedResxHeaders(std::set<std::string>&) const;
+  void GetResxSources(std::vector<cmSourceFile const*>&,
+                      const std::string& config) const;
+  void GetIDLSources(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*>&,
+                        const std::string& config) const;
+  void GetExtraSources(std::vector<cmSourceFile const*>&,
+                       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 ComputeObjectMapping();
 
@@ -53,14 +62,15 @@ public:
   cmLocalGenerator* LocalGenerator;
   cmGlobalGenerator const* GlobalGenerator;
 
-  std::string GetModuleDefinitionFile() const;
+  std::string GetModuleDefinitionFile(const std::string& config) const;
 
   /** Full path with trailing slash to the top-level directory
       holding object files for this target.  Includes the build
       time config name placeholder if needed for the generator.  */
   std::string ObjectDirectory;
 
-  void UseObjectLibraries(std::vector<std::string>& objs) const;
+  void UseObjectLibraries(std::vector<std::string>& objs,
+                          const std::string& config) const;
 
   void GetAppleArchs(const std::string& config,
                      std::vector<std::string>& archVec) const;

+ 16 - 1
Source/cmGlobalGenerator.cxx

@@ -2900,10 +2900,25 @@ void cmGlobalGenerator::WriteSummary(cmTarget* target)
     // List the source files with any per-source labels.
     fout << "# Source files and their labels\n";
     std::vector<cmSourceFile*> sources;
-    target->GetSourceFiles(sources);
+    std::vector<std::string> configs;
+    target->GetMakefile()->GetConfigurations(configs);
+    if (configs.empty())
+      {
+      configs.push_back("");
+      }
+    for(std::vector<std::string>::const_iterator ci = configs.begin();
+        ci != configs.end(); ++ci)
+      {
+      target->GetSourceFiles(sources, *ci);
+      }
+    std::set<cmSourceFile*> emitted;
     for(std::vector<cmSourceFile*>::const_iterator si = sources.begin();
         si != sources.end(); ++si)
       {
+      if (!emitted.insert(*si).second)
+        {
+        continue;
+        }
       cmSourceFile* sf = *si;
       fout << sf->GetFullPath() << "\n";
       if(const char* svalue = sf->GetProperty("LABELS"))

+ 2 - 1
Source/cmGlobalKdevelopGenerator.cxx

@@ -139,7 +139,8 @@ bool cmGlobalKdevelopGenerator
          ti != targets.end(); ti++)
       {
       std::vector<cmSourceFile*> sources;
-      ti->second.GetSourceFiles(sources);
+      ti->second.GetSourceFiles(sources, ti->second.GetMakefile()
+                                    ->GetSafeDefinition("CMAKE_BUILD_TYPE"));
       for (std::vector<cmSourceFile*>::const_iterator si=sources.begin();
            si!=sources.end(); si++)
         {

+ 2 - 1
Source/cmGlobalUnixMakefileGenerator3.cxx

@@ -1081,7 +1081,8 @@ bool cmGlobalUnixMakefileGenerator3
 ::NeedRequiresStep(cmTarget const& target)
 {
   std::set<std::string> languages;
-  target.GetLanguages(languages);
+  target.GetLanguages(languages,
+                target.GetMakefile()->GetSafeDefinition("CMAKE_BUILD_TYPE"));
   for(std::set<std::string>::const_iterator l = languages.begin();
       l != languages.end(); ++l)
     {

+ 9 - 1
Source/cmGlobalVisualStudioGenerator.cxx

@@ -815,7 +815,15 @@ cmGlobalVisualStudioGenerator::TargetIsFortranOnly(cmTarget const& target)
 {
   // check to see if this is a fortran build
   std::set<std::string> languages;
-  target.GetLanguages(languages);
+  {
+  // Issue diagnostic if the source files depend on the config.
+  std::vector<cmSourceFile*> sources;
+  if (!target.GetConfigCommonSourceFiles(sources))
+    {
+    return false;
+    }
+  }
+  target.GetLanguages(languages, "");
   if(languages.size() == 1)
     {
     if(*languages.begin() == "Fortran")

+ 20 - 8
Source/cmGlobalXCodeGenerator.cxx

@@ -984,7 +984,10 @@ cmGlobalXCodeGenerator::CreateXCodeTargets(cmLocalGenerator* gen,
 
     // organize the sources
     std::vector<cmSourceFile*> classes;
-    cmtarget.GetSourceFiles(classes);
+    if (!cmtarget.GetConfigCommonSourceFiles(classes))
+      {
+      return;
+      }
     std::sort(classes.begin(), classes.end(), cmSourceFilePathCompare());
 
     gtgt->ComputeObjectMapping();
@@ -1043,7 +1046,7 @@ cmGlobalXCodeGenerator::CreateXCodeTargets(cmLocalGenerator* gen,
       // the externalObjFiles above, except each one is not a cmSourceFile
       // within the target.)
       std::vector<std::string> objs;
-      gtgt->UseObjectLibraries(objs);
+      gtgt->UseObjectLibraries(objs, "");
       for(std::vector<std::string>::const_iterator
             oi = objs.begin(); oi != objs.end(); ++oi)
         {
@@ -1359,7 +1362,10 @@ void cmGlobalXCodeGenerator::CreateCustomCommands(cmXCodeObject* buildPhases,
     }
 
   std::vector<cmSourceFile*> classes;
-  cmtarget.GetSourceFiles(classes);
+  if (!cmtarget.GetConfigCommonSourceFiles(classes))
+    {
+    return;
+    }
   // add all the sources
   std::vector<cmCustomCommand> commands;
   for(std::vector<cmSourceFile*>::const_iterator i = classes.begin();
@@ -2439,7 +2445,11 @@ cmGlobalXCodeGenerator::CreateUtilityTarget(cmTarget& cmtarget)
   if(cmtarget.GetType() == cmTarget::UTILITY)
     {
     std::vector<cmSourceFile*> sources;
-    cmtarget.GetSourceFiles(sources);
+    if (!cmtarget.GetConfigCommonSourceFiles(sources))
+      {
+      return 0;
+      }
+
     for(std::vector<cmSourceFile*>::const_iterator i = sources.begin();
         i != sources.end(); ++i)
       {
@@ -2808,7 +2818,7 @@ void cmGlobalXCodeGenerator
       std::string linkObjs;
       const char* sep = "";
       std::vector<std::string> objs;
-      this->GetGeneratorTarget(cmtarget)->UseObjectLibraries(objs);
+      this->GetGeneratorTarget(cmtarget)->UseObjectLibraries(objs, "");
       for(std::vector<std::string>::const_iterator
             oi = objs.begin(); oi != objs.end(); ++oi)
         {
@@ -2943,8 +2953,10 @@ void cmGlobalXCodeGenerator::CreateGroups(cmLocalGenerator* root,
         }
 
       std::vector<cmSourceFile*> classes;
-      cmtarget.GetSourceFiles(classes);
-
+      if (!cmtarget.GetConfigCommonSourceFiles(classes))
+        {
+        return;
+        }
       // Put cmSourceFile instances in proper groups:
       for(std::vector<cmSourceFile*>::const_iterator s = classes.begin();
           s != classes.end(); s++)
@@ -2962,7 +2974,7 @@ void cmGlobalXCodeGenerator::CreateGroups(cmLocalGenerator* root,
 
       // Put OBJECT_LIBRARY objects in proper groups:
       std::vector<std::string> objs;
-      this->GetGeneratorTarget(&cmtarget)->UseObjectLibraries(objs);
+      this->GetGeneratorTarget(&cmtarget)->UseObjectLibraries(objs, "");
       for(std::vector<std::string>::const_iterator
             oi = objs.begin(); oi != objs.end(); ++oi)
         {

+ 4 - 3
Source/cmLocalGenerator.cxx

@@ -662,7 +662,8 @@ void cmLocalGenerator::AddBuildTargetRule(const std::string& llang,
   std::vector<std::string> objVector;
   // Add all the sources outputs to the depends of the target
   std::vector<cmSourceFile*> classes;
-  target.GetSourceFiles(classes);
+  target.GetSourceFiles(classes,
+                      this->Makefile->GetSafeDefinition("CMAKE_BUILD_TYPE"));
   for(std::vector<cmSourceFile*>::const_iterator i = classes.begin();
       i != classes.end(); ++i)
     {
@@ -1644,7 +1645,7 @@ void cmLocalGenerator::GetTargetFlags(std::string& linkLibs,
          !(this->Makefile->IsOn("CYGWIN") || this->Makefile->IsOn("MINGW")))
         {
         std::vector<cmSourceFile*> sources;
-        target->GetSourceFiles(sources);
+        target->GetSourceFiles(sources, buildType);
         for(std::vector<cmSourceFile*>::const_iterator i = sources.begin();
             i != sources.end(); ++i)
           {
@@ -1692,7 +1693,7 @@ void cmLocalGenerator::GetTargetFlags(std::string& linkLibs,
         linkFlags += this->Makefile->GetSafeDefinition(build);
         linkFlags += " ";
         }
-      std::string linkLanguage = target->Target->GetLinkerLanguage();
+      std::string linkLanguage = target->Target->GetLinkerLanguage(buildType);
       if(linkLanguage.empty())
         {
         cmSystemTools::Error

+ 4 - 2
Source/cmLocalUnixMakefileGenerator3.cxx

@@ -200,7 +200,8 @@ GetLocalObjectFiles(std::map<std::string, LocalObjectInfo> &localObjectFiles)
       continue;
       }
     std::vector<cmSourceFile const*> objectSources;
-    gt->GetObjectSources(objectSources);
+    gt->GetObjectSources(objectSources, this->Makefile
+                                    ->GetSafeDefinition("CMAKE_BUILD_TYPE"));
     // Compute full path to object file directory for this target.
     std::string dir;
     dir += gt->Makefile->GetCurrentOutputDirectory();
@@ -1262,7 +1263,8 @@ cmLocalUnixMakefileGenerator3
     {
     // Get the set of source languages in the target.
     std::set<std::string> languages;
-    target.GetLanguages(languages);
+    target.GetLanguages(languages,
+                      this->Makefile->GetSafeDefinition("CMAKE_BUILD_TYPE"));
     fout << "\n"
          << "# Per-language clean rules from dependency scanning.\n"
          << "foreach(lang";

+ 33 - 4
Source/cmLocalVisualStudio6Generator.cxx

@@ -317,7 +317,10 @@ void cmLocalVisualStudio6Generator::WriteDSPFile(std::ostream& fout,
 
   // get the classes from the source lists then add them to the groups
   std::vector<cmSourceFile*> classes;
-  target.GetSourceFiles(classes);
+  if (!target.GetConfigCommonSourceFiles(classes))
+    {
+    return;
+    }
 
   // now all of the source files have been properly assigned to the target
   // now stick them into source groups using the reg expressions
@@ -1269,7 +1272,20 @@ void cmLocalVisualStudio6Generator
   if(targetBuilds)
     {
     // Get the language to use for linking.
-    const std::string& linkLanguage = target.GetLinkerLanguage();
+    std::vector<std::string> configs;
+    target.GetMakefile()->GetConfigurations(configs);
+    std::vector<std::string>::const_iterator it = configs.begin();
+    const std::string& linkLanguage = target.GetLinkerLanguage(*it);
+    for ( ; it != configs.end(); ++it)
+      {
+      const std::string& configLinkLanguage = target.GetLinkerLanguage(*it);
+      if (configLinkLanguage != linkLanguage)
+        {
+        cmSystemTools::Error
+          ("Linker language must not vary by configuration for target: ",
+          target.GetName().c_str());
+        }
+      }
     if(linkLanguage.empty())
       {
       cmSystemTools::Error
@@ -1691,7 +1707,20 @@ void cmLocalVisualStudio6Generator
     if(target.GetType() >= cmTarget::EXECUTABLE &&
        target.GetType() <= cmTarget::OBJECT_LIBRARY)
       {
-      const std::string& linkLanguage = target.GetLinkerLanguage();
+      std::vector<std::string> configs;
+      target.GetMakefile()->GetConfigurations(configs);
+      std::vector<std::string>::const_iterator it = configs.begin();
+      const std::string& linkLanguage = target.GetLinkerLanguage(*it);
+      for ( ; it != configs.end(); ++it)
+        {
+        const std::string& configLinkLanguage = target.GetLinkerLanguage(*it);
+        if (configLinkLanguage != linkLanguage)
+          {
+          cmSystemTools::Error
+            ("Linker language must not vary by configuration for target: ",
+            target.GetName().c_str());
+          }
+        }
       if(linkLanguage.empty())
         {
         cmSystemTools::Error
@@ -1889,7 +1918,7 @@ void cmLocalVisualStudio6Generator
   cmGeneratorTarget* gt =
     this->GlobalGenerator->GetGeneratorTarget(&target);
   std::vector<std::string> objs;
-  gt->UseObjectLibraries(objs);
+  gt->UseObjectLibraries(objs, "");
   for(std::vector<std::string>::const_iterator
         oi = objs.begin(); oi != objs.end(); ++oi)
     {

+ 6 - 3
Source/cmLocalVisualStudio7Generator.cxx

@@ -1330,7 +1330,7 @@ cmLocalVisualStudio7GeneratorInternals
   cmGeneratorTarget* gt =
     lg->GetGlobalGenerator()->GetGeneratorTarget(t);
   std::vector<std::string> objs;
-  gt->UseObjectLibraries(objs);
+  gt->UseObjectLibraries(objs, "");
   const char* sep = isep? isep : "";
   for(std::vector<std::string>::const_iterator
         oi = objs.begin(); oi != objs.end(); ++oi)
@@ -1397,7 +1397,10 @@ void cmLocalVisualStudio7Generator::WriteVCProjFile(std::ostream& fout,
   // get the classes from the source lists then add them to the groups
   this->ModuleDefinitionFile = "";
   std::vector<cmSourceFile*> classes;
-  target.GetSourceFiles(classes);
+  if (!target.GetConfigCommonSourceFiles(classes))
+    {
+    return;
+    }
   for(std::vector<cmSourceFile*>::const_iterator i = classes.begin();
       i != classes.end(); i++)
     {
@@ -1438,7 +1441,7 @@ void cmLocalVisualStudio7Generator::WriteVCProjFile(std::ostream& fout,
     cmGeneratorTarget* gt =
       this->GlobalGenerator->GetGeneratorTarget(&target);
     std::vector<std::string> objs;
-    gt->UseObjectLibraries(objs);
+    gt->UseObjectLibraries(objs, "");
     if(!objs.empty())
       {
       // TODO: Separate sub-filter for each object library used?

+ 17 - 12
Source/cmMakefileTargetGenerator.cxx

@@ -128,14 +128,15 @@ void cmMakefileTargetGenerator::CreateRuleFile()
 //----------------------------------------------------------------------------
 void cmMakefileTargetGenerator::WriteTargetBuildRules()
 {
+  const std::string& config =
+    this->Makefile->GetSafeDefinition("CMAKE_BUILD_TYPE");
+
   // write the custom commands for this target
   // Look for files registered for cleaning in this directory.
   if(const char* additional_clean_files =
      this->Makefile->GetProperty
      ("ADDITIONAL_MAKE_CLEAN_FILES"))
     {
-    const std::string& config =
-      this->Makefile->GetDefinition("CMAKE_BUILD_TYPE");
     cmListFileBacktrace lfbt;
     cmGeneratorExpression ge(lfbt);
     cmsys::auto_ptr<cmCompiledGeneratorExpression> cge =
@@ -154,7 +155,7 @@ void cmMakefileTargetGenerator::WriteTargetBuildRules()
   // First generate the object rule files.  Save a list of all object
   // files for this target.
   std::vector<cmSourceFile const*> customCommands;
-  this->GeneratorTarget->GetCustomCommands(customCommands);
+  this->GeneratorTarget->GetCustomCommands(customCommands, config);
   for(std::vector<cmSourceFile const*>::const_iterator
         si = customCommands.begin();
       si != customCommands.end(); ++si)
@@ -177,17 +178,17 @@ void cmMakefileTargetGenerator::WriteTargetBuildRules()
       }
     }
   std::vector<cmSourceFile const*> headerSources;
-  this->GeneratorTarget->GetHeaderSources(headerSources);
+  this->GeneratorTarget->GetHeaderSources(headerSources, config);
   this->OSXBundleGenerator->GenerateMacOSXContentStatements(
     headerSources,
     this->MacOSXContentGenerator);
   std::vector<cmSourceFile const*> extraSources;
-  this->GeneratorTarget->GetExtraSources(extraSources);
+  this->GeneratorTarget->GetExtraSources(extraSources, config);
   this->OSXBundleGenerator->GenerateMacOSXContentStatements(
     extraSources,
     this->MacOSXContentGenerator);
   std::vector<cmSourceFile const*> externalObjects;
-  this->GeneratorTarget->GetExternalObjects(externalObjects);
+  this->GeneratorTarget->GetExternalObjects(externalObjects, config);
   for(std::vector<cmSourceFile const*>::const_iterator
         si = externalObjects.begin();
       si != externalObjects.end(); ++si)
@@ -195,7 +196,7 @@ void cmMakefileTargetGenerator::WriteTargetBuildRules()
     this->ExternalObjects.push_back((*si)->GetFullPath());
     }
   std::vector<cmSourceFile const*> objectSources;
-  this->GeneratorTarget->GetObjectSources(objectSources);
+  this->GeneratorTarget->GetObjectSources(objectSources, config);
   for(std::vector<cmSourceFile const*>::const_iterator
         si = objectSources.begin(); si != objectSources.end(); ++si)
     {
@@ -344,7 +345,8 @@ void cmMakefileTargetGenerator::WriteTargetLanguageFlags()
 {
   // write language flags for target
   std::set<std::string> languages;
-  this->Target->GetLanguages(languages);
+  this->Target->GetLanguages(languages,
+                      this->Makefile->GetSafeDefinition("CMAKE_BUILD_TYPE"));
   // put the compiler in the rules.make file so that if it changes
   // things rebuild
   for(std::set<std::string>::const_iterator l = languages.begin();
@@ -1173,7 +1175,8 @@ cmMakefileTargetGenerator
 {
   // Depend on all custom command outputs.
   std::vector<cmSourceFile*> sources;
-  this->Target->GetSourceFiles(sources);
+  this->Target->GetSourceFiles(sources,
+                      this->Makefile->GetSafeDefinition("CMAKE_BUILD_TYPE"));
   for(std::vector<cmSourceFile*>::const_iterator source = sources.begin();
       source != sources.end(); ++source)
     {
@@ -1670,7 +1673,8 @@ void cmMakefileTargetGenerator
   this->AppendTargetDepends(depends);
 
   // Add a dependency on the link definitions file, if any.
-  std::string def = this->GeneratorTarget->GetModuleDefinitionFile();
+  std::string def = this->GeneratorTarget->GetModuleDefinitionFile(
+                      this->Makefile->GetSafeDefinition("CMAKE_BUILD_TYPE"));
   if(!def.empty())
     {
     depends.push_back(def);
@@ -2064,7 +2068,7 @@ void cmMakefileTargetGenerator::AddFortranFlags(std::string& flags)
     {
     std::vector<std::string> includes;
     const std::string& config =
-      this->Makefile->GetDefinition("CMAKE_BUILD_TYPE");
+      this->Makefile->GetSafeDefinition("CMAKE_BUILD_TYPE");
     this->LocalGenerator->GetIncludeDirectories(includes,
                                                 this->GeneratorTarget,
                                                 "C", config);
@@ -2083,7 +2087,8 @@ void cmMakefileTargetGenerator::AddFortranFlags(std::string& flags)
 //----------------------------------------------------------------------------
 void cmMakefileTargetGenerator::AddModuleDefinitionFlag(std::string& flags)
 {
-  std::string def = this->GeneratorTarget->GetModuleDefinitionFile();
+  std::string def = this->GeneratorTarget->GetModuleDefinitionFile(
+                      this->Makefile->GetSafeDefinition("CMAKE_BUILD_TYPE"));
   if(def.empty())
     {
     return;

+ 2 - 1
Source/cmNinjaNormalTargetGenerator.cxx

@@ -111,7 +111,8 @@ void cmNinjaNormalTargetGenerator::WriteLanguagesRules()
 #endif
 
   std::set<std::string> languages;
-  this->GetTarget()->GetLanguages(languages);
+  this->GetTarget()->GetLanguages(languages,
+                  this->GetMakefile()->GetSafeDefinition("CMAKE_BUILD_TYPE"));
   for(std::set<std::string>::const_iterator l = languages.begin();
       l != languages.end();
       ++l)

+ 9 - 7
Source/cmNinjaTargetGenerator.cxx

@@ -485,8 +485,9 @@ cmNinjaTargetGenerator
     << this->GetTargetName()
     << "\n\n";
 
+  std::string config = this->Makefile->GetSafeDefinition("CMAKE_BUILD_TYPE");
   std::vector<cmSourceFile const*> customCommands;
-  this->GeneratorTarget->GetCustomCommands(customCommands);
+  this->GeneratorTarget->GetCustomCommands(customCommands, config);
   for(std::vector<cmSourceFile const*>::const_iterator
         si = customCommands.begin();
       si != customCommands.end(); ++si)
@@ -495,17 +496,17 @@ cmNinjaTargetGenerator
      this->GetLocalGenerator()->AddCustomCommandTarget(cc, this->GetTarget());
      }
   std::vector<cmSourceFile const*> headerSources;
-  this->GeneratorTarget->GetHeaderSources(headerSources);
+  this->GeneratorTarget->GetHeaderSources(headerSources, config);
   this->OSXBundleGenerator->GenerateMacOSXContentStatements(
     headerSources,
     this->MacOSXContentGenerator);
   std::vector<cmSourceFile const*> extraSources;
-  this->GeneratorTarget->GetExtraSources(extraSources);
+  this->GeneratorTarget->GetExtraSources(extraSources, config);
   this->OSXBundleGenerator->GenerateMacOSXContentStatements(
     extraSources,
     this->MacOSXContentGenerator);
   std::vector<cmSourceFile const*> externalObjects;
-  this->GeneratorTarget->GetExternalObjects(externalObjects);
+  this->GeneratorTarget->GetExternalObjects(externalObjects, config);
   for(std::vector<cmSourceFile const*>::const_iterator
         si = externalObjects.begin();
       si != externalObjects.end(); ++si)
@@ -513,13 +514,13 @@ cmNinjaTargetGenerator
     this->Objects.push_back(this->GetSourceFilePath(*si));
     }
   std::vector<cmSourceFile const*> objectSources;
-  this->GeneratorTarget->GetObjectSources(objectSources);
+  this->GeneratorTarget->GetObjectSources(objectSources, config);
   for(std::vector<cmSourceFile const*>::const_iterator
         si = objectSources.begin(); si != objectSources.end(); ++si)
     {
     this->WriteObjectBuildStatement(*si);
     }
-  std::string def = this->GeneratorTarget->GetModuleDefinitionFile();
+  std::string def = this->GeneratorTarget->GetModuleDefinitionFile(config);
   if(!def.empty())
     {
     this->ModuleDefinitionFile = this->ConvertToNinjaPath(def.c_str());
@@ -565,7 +566,8 @@ cmNinjaTargetGenerator
 
   // Add order-only dependencies on custom command outputs.
   std::vector<cmSourceFile const*> customCommands;
-  this->GeneratorTarget->GetCustomCommands(customCommands);
+  std::string config = this->Makefile->GetSafeDefinition("CMAKE_BUILD_TYPE");
+  this->GeneratorTarget->GetCustomCommands(customCommands, config);
   for(std::vector<cmSourceFile const*>::const_iterator
         si = customCommands.begin();
       si != customCommands.end(); ++si)

+ 3 - 1
Source/cmNinjaUtilityTargetGenerator.cxx

@@ -46,7 +46,9 @@ void cmNinjaUtilityTargetGenerator::Generate()
   }
 
   std::vector<cmSourceFile*> sources;
-  this->GetTarget()->GetSourceFiles(sources);
+  std::string config = this->GetMakefile()
+                           ->GetSafeDefinition("CMAKE_BUILD_TYPE");
+  this->GetTarget()->GetSourceFiles(sources, config);
   for(std::vector<cmSourceFile*>::const_iterator source = sources.begin();
       source != sources.end(); ++source)
     {

+ 2 - 2
Source/cmQtAutoGenerators.cxx

@@ -472,7 +472,7 @@ void cmQtAutoGenerators::SetupSourceFiles(cmTarget const* target)
   const char* sepHeaders = "";
 
   std::vector<cmSourceFile*> srcFiles;
-  target->GetSourceFiles(srcFiles);
+  target->GetConfigCommonSourceFiles(srcFiles);
 
   const char *skipMocSep = "";
   const char *skipUicSep = "";
@@ -862,7 +862,7 @@ void cmQtAutoGenerators::SetupAutoRccTarget(cmTarget const* target)
   cmMakefile *makefile = target->GetMakefile();
 
   std::vector<cmSourceFile*> srcFiles;
-  target->GetSourceFiles(srcFiles);
+  target->GetConfigCommonSourceFiles(srcFiles);
 
   std::string rccFileFiles;
   std::string rccFileOptions;

+ 73 - 12
Source/cmTarget.cxx

@@ -543,7 +543,8 @@ bool cmTarget::IsBundleOnApple() const
 }
 
 //----------------------------------------------------------------------------
-void cmTarget::GetSourceFiles(std::vector<std::string> &files) const
+void cmTarget::GetSourceFiles(std::vector<std::string> &files,
+                              const std::string& config) const
 {
   assert(this->GetType() != INTERFACE_LIBRARY);
   for(std::vector<cmTargetInternals::TargetPropertyEntry*>::const_iterator
@@ -552,7 +553,7 @@ void cmTarget::GetSourceFiles(std::vector<std::string> &files) const
     {
     std::vector<std::string> srcs;
     cmSystemTools::ExpandListArgument((*si)->ge->Evaluate(this->Makefile,
-                                        "",
+                                        config,
                                         false,
                                         this),
                                       srcs);
@@ -580,10 +581,68 @@ void cmTarget::GetSourceFiles(std::vector<std::string> &files) const
 }
 
 //----------------------------------------------------------------------------
-void cmTarget::GetSourceFiles(std::vector<cmSourceFile*> &files) const
+bool
+cmTarget::GetConfigCommonSourceFiles(std::vector<cmSourceFile*>& files) const
+{
+  std::vector<std::string> configs;
+  this->Makefile->GetConfigurations(configs);
+  if (configs.empty())
+    {
+    configs.push_back("");
+    }
+
+  std::vector<std::string>::const_iterator it = configs.begin();
+  const std::string& firstConfig = *it;
+  this->GetSourceFiles(files, firstConfig);
+
+  for ( ; it != configs.end(); ++it)
+    {
+    std::vector<cmSourceFile*> configFiles;
+    this->GetSourceFiles(configFiles, *it);
+    if (configFiles != files)
+      {
+      std::string firstConfigFiles;
+      const char* sep = "";
+      for (std::vector<cmSourceFile*>::const_iterator fi = files.begin();
+           fi != files.end(); ++fi)
+        {
+        firstConfigFiles += sep;
+        firstConfigFiles += (*fi)->GetFullPath();
+        sep = "\n  ";
+        }
+
+      std::string thisConfigFiles;
+      sep = "";
+      for (std::vector<cmSourceFile*>::const_iterator fi = configFiles.begin();
+           fi != configFiles.end(); ++fi)
+        {
+        thisConfigFiles += sep;
+        thisConfigFiles += (*fi)->GetFullPath();
+        sep = "\n  ";
+        }
+      cmOStringStream e;
+      e << "Target \"" << this->Name << "\" has source files which vary by "
+        "configuration. This is not supported by the \""
+        << this->Makefile->GetLocalGenerator()
+                         ->GetGlobalGenerator()->GetName()
+        << "\" generator.\n"
+          "Config \"" << firstConfig << "\":\n"
+          "  " << firstConfigFiles << "\n"
+          "Config \"" << *it << "\":\n"
+          "  " << thisConfigFiles << "\n";
+      this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
+      return false;
+      }
+    }
+  return true;
+}
+
+//----------------------------------------------------------------------------
+void cmTarget::GetSourceFiles(std::vector<cmSourceFile*> &files,
+                              const std::string& config) const
 {
   std::vector<std::string> srcs;
-  this->GetSourceFiles(srcs);
+  this->GetSourceFiles(srcs, config);
 
   std::set<cmSourceFile*> emitted;
 
@@ -4993,10 +5052,11 @@ bool cmTarget::IsLinkInterfaceDependentNumberMaxProperty(const std::string &p,
 }
 
 //----------------------------------------------------------------------------
-void cmTarget::GetLanguages(std::set<std::string>& languages) const
+void cmTarget::GetLanguages(std::set<std::string>& languages,
+                            const std::string& config) const
 {
   std::vector<cmSourceFile*> sourceFiles;
-  this->GetSourceFiles(sourceFiles);
+  this->GetSourceFiles(sourceFiles, config);
   for(std::vector<cmSourceFile*>::const_iterator
         i = sourceFiles.begin(); i != sourceFiles.end(); ++i)
     {
@@ -5037,7 +5097,7 @@ void cmTarget::GetLanguages(std::set<std::string>& languages) const
     cmGeneratorTarget* gt = this->Makefile->GetLocalGenerator()
                                 ->GetGlobalGenerator()
                                 ->GetGeneratorTarget(this);
-    gt->GetExternalObjects(externalObjects);
+    gt->GetExternalObjects(externalObjects, config);
     for(std::vector<cmSourceFile const*>::const_iterator
           i = externalObjects.begin(); i != externalObjects.end(); ++i)
       {
@@ -5051,7 +5111,7 @@ void cmTarget::GetLanguages(std::set<std::string>& languages) const
   for(std::vector<cmTarget*>::const_iterator
       i = objectLibraries.begin(); i != objectLibraries.end(); ++i)
     {
-    (*i)->GetLanguages(languages);
+    (*i)->GetLanguages(languages, config);
     }
 }
 
@@ -5990,7 +6050,7 @@ cmTarget::GetLinkImplementation(const std::string& config,
     // Compute the link implementation for this configuration.
     LinkImplementation impl;
     this->ComputeLinkImplementation(config, impl, head);
-    this->ComputeLinkImplementationLanguages(impl);
+    this->ComputeLinkImplementationLanguages(config, impl);
 
     // Store the information for this configuration.
     cmTargetInternals::LinkImplMapType::value_type entry(key, impl);
@@ -5998,7 +6058,7 @@ cmTarget::GetLinkImplementation(const std::string& config,
     }
   else if (i->second.Languages.empty())
     {
-    this->ComputeLinkImplementationLanguages(i->second);
+    this->ComputeLinkImplementationLanguages(config, i->second);
     }
 
   return &i->second;
@@ -6111,12 +6171,13 @@ void cmTarget::ComputeLinkImplementation(const std::string& config,
 
 //----------------------------------------------------------------------------
 void
-cmTarget::ComputeLinkImplementationLanguages(LinkImplementation& impl) const
+cmTarget::ComputeLinkImplementationLanguages(const std::string& config,
+                                             LinkImplementation& impl) const
 {
   // This target needs runtime libraries for its source languages.
   std::set<std::string> languages;
   // Get languages used in our source files.
-  this->GetLanguages(languages);
+  this->GetLanguages(languages, config);
   // Copy the set of langauges to the link implementation.
   for(std::set<std::string>::iterator li = languages.begin();
       li != languages.end(); ++li)

+ 9 - 4
Source/cmTarget.h

@@ -135,8 +135,11 @@ public:
   /**
    * Get the list of the source files used by this target
    */
-  void GetSourceFiles(std::vector<std::string> &files) const;
-  void GetSourceFiles(std::vector<cmSourceFile*> &files) const;
+  void GetSourceFiles(std::vector<std::string> &files,
+                      const std::string& config) const;
+  void GetSourceFiles(std::vector<cmSourceFile*> &files,
+                      const std::string& config) const;
+  bool GetConfigCommonSourceFiles(std::vector<cmSourceFile*>& files) const;
 
   /**
    * Add sources to the target.
@@ -465,7 +468,8 @@ public:
   // when source file properties are changed and we do not have enough
   // information to forward these property changes to the targets
   // until we have per-target object file properties.
-  void GetLanguages(std::set<std::string>& languages) const;
+  void GetLanguages(std::set<std::string>& languages,
+                    const std::string& config) const;
 
   /** Return whether this target is an executable with symbol exports
       enabled.  */
@@ -738,7 +742,8 @@ private:
   void ComputeLinkImplementation(const std::string& config,
                                  LinkImplementation& impl,
                                  cmTarget const* head) const;
-  void ComputeLinkImplementationLanguages(LinkImplementation& impl) const;
+  void ComputeLinkImplementationLanguages(const std::string& config,
+                                          LinkImplementation& impl) const;
   void ComputeLinkClosure(const std::string& config, LinkClosure& lc,
                           cmTarget const* head) const;
 

+ 16 - 13
Source/cmVisualStudio10TargetGenerator.cxx

@@ -379,7 +379,7 @@ void cmVisualStudio10TargetGenerator::WriteDotNetReferences()
 void cmVisualStudio10TargetGenerator::WriteEmbeddedResourceGroup()
 {
   std::vector<cmSourceFile const*> resxObjs;
-    this->GeneratorTarget->GetResxSources(resxObjs);
+    this->GeneratorTarget->GetResxSources(resxObjs, "");
   if(!resxObjs.empty())
     {
     this->WriteString("<ItemGroup>\n", 1);
@@ -553,7 +553,7 @@ void cmVisualStudio10TargetGenerator::WriteCustomCommands()
 {
   this->SourcesVisited.clear();
   std::vector<cmSourceFile const*> customCommands;
-  this->GeneratorTarget->GetCustomCommands(customCommands);
+  this->GeneratorTarget->GetCustomCommands(customCommands, "");
   for(std::vector<cmSourceFile const*>::const_iterator
         si = customCommands.begin();
       si != customCommands.end(); ++si)
@@ -704,7 +704,10 @@ void cmVisualStudio10TargetGenerator::WriteGroups()
   std::vector<cmSourceGroup> sourceGroups =
     this->Makefile->GetSourceGroups();
   std::vector<cmSourceFile*> classes;
-  this->Target->GetSourceFiles(classes);
+  if (!this->Target->GetConfigCommonSourceFiles(classes))
+    {
+    return;
+    }
 
   std::set<cmSourceGroup*> groupsUsed;
   for(std::vector<cmSourceFile*>::const_iterator s = classes.begin();
@@ -749,7 +752,7 @@ void cmVisualStudio10TargetGenerator::WriteGroups()
     }
 
   std::vector<cmSourceFile const*> resxObjs;
-    this->GeneratorTarget->GetResxSources(resxObjs);
+    this->GeneratorTarget->GetResxSources(resxObjs, "");
   if(!resxObjs.empty())
     {
     this->WriteString("<ItemGroup>\n", 1);
@@ -768,7 +771,7 @@ void cmVisualStudio10TargetGenerator::WriteGroups()
 
   // Add object library contents as external objects.
   std::vector<std::string> objs;
-  this->GeneratorTarget->UseObjectLibraries(objs);
+  this->GeneratorTarget->UseObjectLibraries(objs, "");
   if(!objs.empty())
     {
     this->WriteString("<ItemGroup>\n", 1);
@@ -1005,14 +1008,14 @@ void cmVisualStudio10TargetGenerator::WriteAllSources()
   this->WriteString("<ItemGroup>\n", 1);
 
   std::vector<cmSourceFile const*> headerSources;
-  this->GeneratorTarget->GetHeaderSources(headerSources);
+  this->GeneratorTarget->GetHeaderSources(headerSources, "");
   this->WriteSources("ClInclude", headerSources);
   std::vector<cmSourceFile const*> idlSources;
-  this->GeneratorTarget->GetIDLSources(idlSources);
+  this->GeneratorTarget->GetIDLSources(idlSources, "");
   this->WriteSources("Midl", idlSources);
 
   std::vector<cmSourceFile const*> objectSources;
-  this->GeneratorTarget->GetObjectSources(objectSources);
+  this->GeneratorTarget->GetObjectSources(objectSources, "");
   for(std::vector<cmSourceFile const*>::const_iterator
         si = objectSources.begin();
       si != objectSources.end(); ++si)
@@ -1053,7 +1056,7 @@ void cmVisualStudio10TargetGenerator::WriteAllSources()
     }
 
   std::vector<cmSourceFile const*> externalObjects;
-  this->GeneratorTarget->GetExternalObjects(externalObjects);
+  this->GeneratorTarget->GetExternalObjects(externalObjects, "");
   for(std::vector<cmSourceFile const*>::iterator
         si = externalObjects.begin();
       si != externalObjects.end(); )
@@ -1088,12 +1091,12 @@ void cmVisualStudio10TargetGenerator::WriteAllSources()
     }
 
   std::vector<cmSourceFile const*> extraSources;
-  this->GeneratorTarget->GetExtraSources(extraSources);
+  this->GeneratorTarget->GetExtraSources(extraSources, "");
   this->WriteSources("None", extraSources);
 
   // Add object library contents as external objects.
   std::vector<std::string> objs;
-  this->GeneratorTarget->UseObjectLibraries(objs);
+  this->GeneratorTarget->UseObjectLibraries(objs, "");
   for(std::vector<std::string>::const_iterator
         oi = objs.begin(); oi != objs.end(); ++oi)
     {
@@ -1694,7 +1697,7 @@ cmVisualStudio10TargetGenerator::ComputeLinkOptions(std::string const& config)
   linkOptions.AddFlag("ImportLibrary", imLib.c_str());
   linkOptions.AddFlag("ProgramDataBaseFile", pdb.c_str());
   linkOptions.Parse(flags.c_str());
-  std::string def = this->GeneratorTarget->GetModuleDefinitionFile();
+  std::string def = this->GeneratorTarget->GetModuleDefinitionFile("");
   if(!def.empty())
     {
     linkOptions.AddFlag("ModuleDefinitionFile", def.c_str());
@@ -1924,7 +1927,7 @@ bool cmVisualStudio10TargetGenerator::
   IsResxHeader(const std::string& headerFile)
 {
   std::set<std::string> expectedResxHeaders;
-  this->GeneratorTarget->GetExpectedResxHeaders(expectedResxHeaders);
+  this->GeneratorTarget->GetExpectedResxHeaders(expectedResxHeaders, "");
 
   std::set<std::string>::const_iterator it =
                                         expectedResxHeaders.find(headerFile);

+ 4 - 0
Tests/CMakeLists.txt

@@ -278,6 +278,10 @@ if(BUILD_TESTING)
   ADD_TEST_MACRO(AliasTarget AliasTarget)
   ADD_TEST_MACRO(StagingPrefix StagingPrefix)
   ADD_TEST_MACRO(InterfaceLibrary InterfaceLibrary)
+  if (CMAKE_BUILD_TYPE MATCHES "[Dd][Ee][Bb][Uu][Gg]")
+    set(ConfigSources_BUILD_OPTIONS -DCMAKE_BUILD_TYPE=Debug)
+    ADD_TEST_MACRO(ConfigSources ConfigSources)
+  endif()
   set_tests_properties(EmptyLibrary PROPERTIES
     PASS_REGULAR_EXPRESSION "CMake Error: CMake can not determine linker language for target: test")
   ADD_TEST_MACRO(CrossCompile CrossCompile)

+ 9 - 0
Tests/ConfigSources/CMakeLists.txt

@@ -0,0 +1,9 @@
+
+cmake_minimum_required(VERSION 3.0)
+
+project(ConfigSources)
+
+add_executable(ConfigSources
+  $<$<CONFIG:Debug>:main.cpp>
+  $<$<CONFIG:Release>:does_not_exist.cpp>
+)

+ 5 - 0
Tests/ConfigSources/main.cpp

@@ -0,0 +1,5 @@
+
+int main(int argc, char** argv)
+{
+  return 0;
+}

+ 7 - 1
Tests/QtAutogen/CMakeLists.txt

@@ -64,9 +64,15 @@ add_custom_command(
   DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/myotherinterface.h.in"
 )
 
+message("CMAKE_BUILD_TYPE = ${CMAKE_BUILD_TYPE}")
+if (CMAKE_BUILD_TYPE MATCHES "[Dd][Ee][Bb][Uu][Gg]" AND NOT CMAKE_CONFIGURATION_TYPES)
+  set(debug_srcs "$<$<CONFIG:Debug>:debug_class.cpp>" $<$<CONFIG:Debug>:debug_resource.qrc>)
+  add_definitions(-DTEST_DEBUG_CLASS)
+endif()
+
 add_executable(QtAutogen main.cpp calwidget.cpp second_widget.cpp foo.cpp blub.cpp bar.cpp abc.cpp
                xyz.cpp yaf.cpp gadget.cpp $<TARGET_OBJECTS:privateSlot>
-               test.qrc second_resource.qrc resourcetester.cpp generated.cpp
+               test.qrc second_resource.qrc resourcetester.cpp generated.cpp ${debug_srcs}
 )
 set_property(TARGET QtAutogen APPEND PROPERTY AUTOGEN_TARGET_DEPENDS generate_moc_input "${CMAKE_CURRENT_BINARY_DIR}/myotherinterface.h")
 

+ 9 - 0
Tests/QtAutogen/debug_class.cpp

@@ -0,0 +1,9 @@
+
+#include "debug_class.h"
+#include "ui_debug_class.h"
+
+DebugClass::DebugClass(QWidget *parent)
+  : QWidget(parent), ui(new Ui::DebugClass)
+{
+  ui->setupUi(this);
+}

+ 20 - 0
Tests/QtAutogen/debug_class.h

@@ -0,0 +1,20 @@
+
+#include <QWidget>
+
+namespace Ui
+{
+class DebugClass;
+}
+
+class DebugClass : public QWidget
+{
+  Q_OBJECT
+public:
+  explicit DebugClass(QWidget *parent = 0);
+
+signals:
+  void someSignal();
+
+private:
+  Ui::DebugClass *ui;
+};

+ 45 - 0
Tests/QtAutogen/debug_class.ui

@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>DebugClass</class>
+ <widget class="QWidget" name="DebugClass">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>400</width>
+    <height>300</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>DebugClass</string>
+  </property>
+  <widget class="QCheckBox" name="checkBox">
+   <property name="geometry">
+    <rect>
+     <x>50</x>
+     <y>20</y>
+     <width>82</width>
+     <height>21</height>
+    </rect>
+   </property>
+   <property name="text">
+    <string>CheckBox</string>
+   </property>
+  </widget>
+  <widget class="QPushButton" name="pushButton">
+   <property name="geometry">
+    <rect>
+     <x>40</x>
+     <y>70</y>
+     <width>94</width>
+     <height>24</height>
+    </rect>
+   </property>
+   <property name="text">
+    <string>PushButton</string>
+   </property>
+  </widget>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>

+ 5 - 0
Tests/QtAutogen/debug_resource.qrc

@@ -0,0 +1,5 @@
+<!DOCTYPE RCC><RCC version="1.0">
+<qresource>
+    <file>debug_class.ui</file>
+</qresource>
+</RCC>

+ 9 - 0
Tests/QtAutogen/main.cpp

@@ -51,6 +51,11 @@
 #include "yaf.h"
 #include "libC.h"
 #include "resourcetester.h"
+#ifdef TEST_DEBUG_CLASS
+#include "debug_class.h"
+#include <iostream>
+#endif
+
 
 int main(int argv, char **args)
 {
@@ -81,5 +86,9 @@ int main(int argv, char **args)
 
   QTimer::singleShot(0, &rt, SLOT(doTest()));
 
+#ifdef TEST_DEBUG_CLASS
+  std::cout << DebugClass::staticMetaObject.className() << std::endl;
+#endif
+
   return app.exec();
 }

+ 4 - 0
Tests/QtAutogen/resourcetester.cpp

@@ -18,6 +18,10 @@ void ResourceTester::doTest()
       qApp->exit(EXIT_FAILURE);
   if (!QFile::exists(":/main.cpp"))
       qApp->exit(EXIT_FAILURE);
+#ifdef TEST_DEBUG_CLASS
+  if (!QFile::exists(":/debug_class.ui"))
+      qApp->exit(EXIT_FAILURE);
+#endif
 
   QTimer::singleShot(0, qApp, SLOT(quit()));
 }

+ 1 - 0
Tests/RunCMake/CMakeLists.txt

@@ -51,6 +51,7 @@ add_RunCMake_test(TargetPropertyGeneratorExpressions)
 add_RunCMake_test(Languages)
 add_RunCMake_test(ObjectLibrary)
 add_RunCMake_test(TargetObjects)
+add_RunCMake_test(TargetSources)
 add_RunCMake_test(find_dependency)
 if(NOT WIN32)
   add_RunCMake_test(PositionIndependentCode)

+ 3 - 0
Tests/RunCMake/TargetSources/CMakeLists.txt

@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 2.8.4)
+project(${RunCMake_TEST} NONE)
+include(${RunCMake_TEST}.cmake)

+ 1 - 0
Tests/RunCMake/TargetSources/ConfigNotAllowed-result.txt

@@ -0,0 +1 @@
+1

+ 14 - 0
Tests/RunCMake/TargetSources/ConfigNotAllowed-stderr.txt

@@ -0,0 +1,14 @@
+CMake Error in CMakeLists.txt:
+  Target "somelib" has source files which vary by configuration.  This is not
+  supported by the "[^"]+" generator.
+
+  Config "Debug":
+
+    .*/Tests/RunCMake/TargetSources/empty_1.cpp
+    .*/Tests/RunCMake/TargetSources/empty_2.cpp
+    .*/Tests/RunCMake/TargetSources/CMakeLists.txt
+
+  Config "Release":
+
+    .*/Tests/RunCMake/TargetSources/empty_1.cpp
+    .*/Tests/RunCMake/TargetSources/CMakeLists.txt

+ 2 - 0
Tests/RunCMake/TargetSources/ConfigNotAllowed.cmake

@@ -0,0 +1,2 @@
+
+add_library(somelib empty_1.cpp $<$<CONFIG:Debug>:empty_2.cpp>)

+ 6 - 0
Tests/RunCMake/TargetSources/RunCMakeTest.cmake

@@ -0,0 +1,6 @@
+include(RunCMake)
+
+if(RunCMake_GENERATOR MATCHES Xcode
+    OR RunCMake_GENERATOR MATCHES "Visual Studio")
+  run_cmake(ConfigNotAllowed)
+endif()

+ 7 - 0
Tests/RunCMake/TargetSources/empty_1.cpp

@@ -0,0 +1,7 @@
+#ifdef _WIN32
+__declspec(dllexport)
+#endif
+int empty()
+{
+  return 0;
+}

+ 7 - 0
Tests/RunCMake/TargetSources/empty_2.cpp

@@ -0,0 +1,7 @@
+#ifdef _WIN32
+__declspec(dllexport)
+#endif
+int empty()
+{
+  return 0;
+}