Jelajahi Sumber

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 11 tahun lalu
induk
melakukan
e6971df6ab
44 mengubah file dengan 492 tambahan dan 138 penghapusan
  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;
+}