Explorar o código

Merge topic 'target-transitive-sources'

9407174b target_sources: New command to add sources to target.
81ad69e0 Make the SOURCES target property writable.
6e636f2e cmTarget: Make the SOURCES origin tracable.
3676fb49 cmTarget: Allow transitive evaluation of SOURCES property.
e6971df6 cmTarget: Make the source files depend on the config.
df753df9 cmGeneratorTarget: Don't add computed sources to the target.
869328aa cmComputeTargetDepends: Use valid config to compute target depends.
Brad King %!s(int64=11) %!d(string=hai) anos
pai
achega
5376151aa1
Modificáronse 74 ficheiros con 1098 adicións e 183 borrados
  1. 28 0
      Help/command/target_sources.rst
  2. 1 0
      Help/manual/cmake-commands.7.rst
  3. 1 0
      Help/manual/cmake-properties.7.rst
  4. 15 0
      Help/prop_tgt/INTERFACE_SOURCES.rst
  5. 1 2
      Help/prop_tgt/SOURCES.rst
  6. 5 0
      Help/release/dev/target-INTERFACE_SOURCES.rst
  7. 6 0
      Help/release/dev/target-SOURCES-write.rst
  8. 5 0
      Help/release/dev/target_sources-command.rst
  9. 2 1
      Help/variable/CMAKE_DEBUG_TARGET_PROPERTIES.rst
  10. 1 0
      Source/CMakeLists.txt
  11. 28 42
      Source/cmComputeTargetDepends.cxx
  12. 2 1
      Source/cmExtraCodeBlocksGenerator.cxx
  13. 2 1
      Source/cmExtraCodeLiteGenerator.cxx
  14. 2 1
      Source/cmExtraEclipseCDT4Generator.cxx
  15. 2 1
      Source/cmExtraSublimeTextGenerator.cxx
  16. 1 1
      Source/cmFLTKWrapUICommand.cxx
  17. 12 0
      Source/cmGeneratorExpressionDAGChecker.cxx
  18. 4 1
      Source/cmGeneratorExpressionDAGChecker.h
  19. 6 3
      Source/cmGeneratorExpressionEvaluator.cxx
  20. 56 19
      Source/cmGeneratorTarget.cxx
  21. 21 11
      Source/cmGeneratorTarget.h
  22. 16 1
      Source/cmGlobalGenerator.cxx
  23. 2 1
      Source/cmGlobalKdevelopGenerator.cxx
  24. 2 1
      Source/cmGlobalUnixMakefileGenerator3.cxx
  25. 9 1
      Source/cmGlobalVisualStudioGenerator.cxx
  26. 20 8
      Source/cmGlobalXCodeGenerator.cxx
  27. 4 3
      Source/cmLocalGenerator.cxx
  28. 4 2
      Source/cmLocalUnixMakefileGenerator3.cxx
  29. 33 4
      Source/cmLocalVisualStudio6Generator.cxx
  30. 6 3
      Source/cmLocalVisualStudio7Generator.cxx
  31. 17 12
      Source/cmMakefileTargetGenerator.cxx
  32. 2 1
      Source/cmNinjaNormalTargetGenerator.cxx
  33. 9 7
      Source/cmNinjaTargetGenerator.cxx
  34. 3 1
      Source/cmNinjaUtilityTargetGenerator.cxx
  35. 2 2
      Source/cmQtAutoGenerators.cxx
  36. 287 34
      Source/cmTarget.cxx
  37. 14 4
      Source/cmTarget.h
  38. 64 0
      Source/cmTargetSourcesCommand.cxx
  39. 55 0
      Source/cmTargetSourcesCommand.h
  40. 16 13
      Source/cmVisualStudio10TargetGenerator.cxx
  41. 5 0
      Tests/CMakeLists.txt
  42. 17 0
      Tests/ConfigSources/CMakeLists.txt
  43. 4 0
      Tests/ConfigSources/iface_debug.h
  44. 7 0
      Tests/ConfigSources/iface_debug_src.cpp
  45. 5 0
      Tests/ConfigSources/iface_src.cpp
  46. 7 0
      Tests/ConfigSources/main.cpp
  47. 7 1
      Tests/QtAutogen/CMakeLists.txt
  48. 9 0
      Tests/QtAutogen/debug_class.cpp
  49. 20 0
      Tests/QtAutogen/debug_class.h
  50. 45 0
      Tests/QtAutogen/debug_class.ui
  51. 5 0
      Tests/QtAutogen/debug_resource.qrc
  52. 9 0
      Tests/QtAutogen/main.cpp
  53. 4 0
      Tests/QtAutogen/resourcetester.cpp
  54. 1 0
      Tests/RunCMake/CMakeLists.txt
  55. 3 0
      Tests/RunCMake/TargetSources/CMakeLists.txt
  56. 1 0
      Tests/RunCMake/TargetSources/ConfigNotAllowed-result.txt
  57. 14 0
      Tests/RunCMake/TargetSources/ConfigNotAllowed-stderr.txt
  58. 2 0
      Tests/RunCMake/TargetSources/ConfigNotAllowed.cmake
  59. 1 0
      Tests/RunCMake/TargetSources/OriginDebug-result.txt
  60. 31 0
      Tests/RunCMake/TargetSources/OriginDebug-stderr.txt
  61. 20 0
      Tests/RunCMake/TargetSources/OriginDebug.cmake
  62. 1 0
      Tests/RunCMake/TargetSources/OriginDebugIDE-result.txt
  63. 40 0
      Tests/RunCMake/TargetSources/OriginDebugIDE-stderr.txt
  64. 4 0
      Tests/RunCMake/TargetSources/OriginDebugIDE.cmake
  65. 9 0
      Tests/RunCMake/TargetSources/RunCMakeTest.cmake
  66. 7 0
      Tests/RunCMake/TargetSources/empty_1.cpp
  67. 7 0
      Tests/RunCMake/TargetSources/empty_2.cpp
  68. 7 0
      Tests/RunCMake/TargetSources/empty_3.cpp
  69. 7 0
      Tests/RunCMake/TargetSources/empty_4.cpp
  70. 12 0
      Tests/SourcesProperty/CMakeLists.txt
  71. 5 0
      Tests/SourcesProperty/iface.cpp
  72. 4 0
      Tests/SourcesProperty/iface.h
  73. 7 0
      Tests/SourcesProperty/main.cpp
  74. 5 0
      Tests/SourcesProperty/prop.cpp

+ 28 - 0
Help/command/target_sources.rst

@@ -0,0 +1,28 @@
+target_sources
+--------------
+
+Add sources to a target.
+
+::
+
+  target_sources(<target>
+    <INTERFACE|PUBLIC|PRIVATE> [items1...]
+    [<INTERFACE|PUBLIC|PRIVATE> [items2...] ...])
+
+Specify sources to use when compiling a given target.  The
+named ``<target>`` must have been created by a command such as
+:command:`add_executable` or :command:`add_library` and must not be an
+:prop_tgt:`IMPORTED Target`.
+
+The ``INTERFACE``, ``PUBLIC`` and ``PRIVATE`` keywords are required to
+specify the scope of the following arguments.  ``PRIVATE`` and ``PUBLIC``
+items will populate the :prop_tgt:`SOURCES` property of
+``<target>``.  ``PUBLIC`` and ``INTERFACE`` items will populate the
+:prop_tgt:`INTERFACE_SOURCES` property of ``<target>``.  The
+following arguments specify sources.  Repeated calls for the same
+``<target>`` append items in the order called.
+
+Arguments to ``target_sources`` may use "generator expressions"
+with the syntax ``$<...>``. See the :manual:`cmake-generator-expressions(7)`
+manual for available expressions.  See the :manual:`cmake-buildsystem(7)`
+manual for more on defining buildsystem properties.

+ 1 - 0
Help/manual/cmake-commands.7.rst

@@ -94,6 +94,7 @@ These commands may be used freely in CMake projects.
    /command/target_compile_options
    /command/target_compile_options
    /command/target_include_directories
    /command/target_include_directories
    /command/target_link_libraries
    /command/target_link_libraries
+   /command/target_sources
    /command/try_compile
    /command/try_compile
    /command/try_run
    /command/try_run
    /command/unset
    /command/unset

+ 1 - 0
Help/manual/cmake-properties.7.rst

@@ -152,6 +152,7 @@ Properties on Targets
    /prop_tgt/INTERFACE_INCLUDE_DIRECTORIES
    /prop_tgt/INTERFACE_INCLUDE_DIRECTORIES
    /prop_tgt/INTERFACE_LINK_LIBRARIES
    /prop_tgt/INTERFACE_LINK_LIBRARIES
    /prop_tgt/INTERFACE_POSITION_INDEPENDENT_CODE
    /prop_tgt/INTERFACE_POSITION_INDEPENDENT_CODE
+   /prop_tgt/INTERFACE_SOURCES
    /prop_tgt/INTERFACE_SYSTEM_INCLUDE_DIRECTORIES
    /prop_tgt/INTERFACE_SYSTEM_INCLUDE_DIRECTORIES
    /prop_tgt/INTERPROCEDURAL_OPTIMIZATION_CONFIG
    /prop_tgt/INTERPROCEDURAL_OPTIMIZATION_CONFIG
    /prop_tgt/INTERPROCEDURAL_OPTIMIZATION
    /prop_tgt/INTERPROCEDURAL_OPTIMIZATION

+ 15 - 0
Help/prop_tgt/INTERFACE_SOURCES.rst

@@ -0,0 +1,15 @@
+INTERFACE_SOURCES
+-----------------
+
+List of interface sources to pass to the compiler.
+
+Targets may populate this property to publish the sources
+for consuming targets to compile.  Consuming
+targets can add entries to their own :prop_tgt:`SOURCES` property
+such as ``$<TARGET_PROPERTY:foo,INTERFACE_SOURCES>`` to use the
+sources specified in the interface of ``foo``.
+
+Contents of ``INTERFACE_SOURCES`` may use "generator expressions"
+with the syntax ``$<...>``.  See the :manual:`cmake-generator-expressions(7)`
+manual for available expressions.  See the :manual:`cmake-buildsystem(7)`
+manual for more on defining buildsystem properties.

+ 1 - 2
Help/prop_tgt/SOURCES.rst

@@ -3,5 +3,4 @@ SOURCES
 
 
 Source names specified for a target.
 Source names specified for a target.
 
 
-Read-only list of sources specified for a target.  The names returned
-are suitable for passing to the set_source_files_properties command.
+List of sources specified for a target.

+ 5 - 0
Help/release/dev/target-INTERFACE_SOURCES.rst

@@ -0,0 +1,5 @@
+target-INTERFACE_SOURCES
+------------------------
+
+* A new :prop_tgt:`INTERFACE_SOURCES` target property was introduced. This is
+  consumed by dependent targets, which compile and link the listed sources.

+ 6 - 0
Help/release/dev/target-SOURCES-write.rst

@@ -0,0 +1,6 @@
+target-SOURCES-write.rst
+------------------------
+
+* It is now possible to write and append to the :prop_tgt:`SOURCES` target
+  property.  The :variable:`CMAKE_DEBUG_TARGET_PROPERTIES` variable may be
+  used to trace the origin of sources.

+ 5 - 0
Help/release/dev/target_sources-command.rst

@@ -0,0 +1,5 @@
+target_sources-command
+----------------------
+
+* The :command:`target_sources` command was added to add to the
+  :prop_tgt:`SOURCES` target property.

+ 2 - 1
Help/variable/CMAKE_DEBUG_TARGET_PROPERTIES.rst

@@ -6,7 +6,8 @@ Enables tracing output for target properties.
 This variable can be populated with a list of properties to generate
 This variable can be populated with a list of properties to generate
 debug output for when evaluating target properties.  Currently it can
 debug output for when evaluating target properties.  Currently it can
 only be used when evaluating the :prop_tgt:`INCLUDE_DIRECTORIES`,
 only be used when evaluating the :prop_tgt:`INCLUDE_DIRECTORIES`,
-:prop_tgt:`COMPILE_DEFINITIONS`, :prop_tgt:`COMPILE_OPTIONS`, :prop_tgt:`AUTOUIC_OPTIONS`,
+:prop_tgt:`COMPILE_DEFINITIONS`, :prop_tgt:`COMPILE_OPTIONS`,
+:prop_tgt:`AUTOUIC_OPTIONS`, :prop_tgt:`SOURCES`,
 :prop_tgt:`POSITION_INDEPENDENT_CODE` target properties and any other property
 :prop_tgt:`POSITION_INDEPENDENT_CODE` target properties and any other property
 listed in :prop_tgt:`COMPATIBLE_INTERFACE_STRING` and other ``COMPATIBLE_INTERFACE_``
 listed in :prop_tgt:`COMPATIBLE_INTERFACE_STRING` and other ``COMPATIBLE_INTERFACE_``
 properties.  It outputs an origin for each entry in the target property.
 properties.  It outputs an origin for each entry in the target property.

+ 1 - 0
Source/CMakeLists.txt

@@ -348,6 +348,7 @@ foreach(command_file
     cmTargetCompileDefinitionsCommand
     cmTargetCompileDefinitionsCommand
     cmTargetCompileOptionsCommand
     cmTargetCompileOptionsCommand
     cmTargetIncludeDirectoriesCommand
     cmTargetIncludeDirectoriesCommand
+    cmTargetSourcesCommand
     cmUseMangledMesaCommand
     cmUseMangledMesaCommand
     cmUtilitySourceCommand
     cmUtilitySourceCommand
     cmVariableRequiresCommand
     cmVariableRequiresCommand

+ 28 - 42
Source/cmComputeTargetDepends.cxx

@@ -213,56 +213,42 @@ void cmComputeTargetDepends::CollectTargetDepends(int depender_index)
   // deal with config-specific dependencies.
   // deal with config-specific dependencies.
   {
   {
   std::set<std::string> emitted;
   std::set<std::string> emitted;
-  {
   cmGeneratorTarget* gt = depender->GetMakefile()->GetLocalGenerator()
   cmGeneratorTarget* gt = depender->GetMakefile()->GetLocalGenerator()
                                   ->GetGlobalGenerator()
                                   ->GetGlobalGenerator()
                                   ->GetGeneratorTarget(depender);
                                   ->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> tlibs;
-  depender->GetDirectLinkLibraries("", tlibs, depender);
-  // A target should not depend on itself.
-  emitted.insert(depender->GetName());
-  for(std::vector<std::string>::const_iterator lib = tlibs.begin();
-      lib != tlibs.end(); ++lib)
-    {
-    // Don't emit the same library twice for this target.
-    if(emitted.insert(*lib).second)
-      {
-      this->AddTargetDepend(depender_index, *lib, true);
-      this->AddInterfaceDepends(depender_index, *lib,
-                                true, emitted);
-      }
-    }
-  }
+
   std::vector<std::string> configs;
   std::vector<std::string> configs;
   depender->GetMakefile()->GetConfigurations(configs);
   depender->GetMakefile()->GetConfigurations(configs);
+  if (configs.empty())
+    {
+    configs.push_back("");
+    }
   for (std::vector<std::string>::const_iterator it = configs.begin();
   for (std::vector<std::string>::const_iterator it = configs.begin();
     it != configs.end(); ++it)
     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;
     std::vector<std::string> tlibs;
     depender->GetDirectLinkLibraries(*it, tlibs, depender);
     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
         case cmTarget::UTILITY: // can have sources since 2.6.3
           {
           {
           std::vector<cmSourceFile*> sources;
           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();
           for (std::vector<cmSourceFile*>::const_iterator si=sources.begin();
                si!=sources.end(); si++)
                si!=sources.end(); si++)
             {
             {

+ 2 - 1
Source/cmExtraCodeLiteGenerator.cxx

@@ -214,7 +214,8 @@ void cmExtraCodeLiteGenerator
         case cmTarget::MODULE_LIBRARY:
         case cmTarget::MODULE_LIBRARY:
           {
           {
           std::vector<cmSourceFile*> sources;
           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();
           for (std::vector<cmSourceFile*>::const_iterator si=sources.begin();
                si!=sources.end(); si++)
                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
           // get the files from the source lists then add them to the groups
           cmTarget* tgt = const_cast<cmTarget*>(&ti->second);
           cmTarget* tgt = const_cast<cmTarget*>(&ti->second);
           std::vector<cmSourceFile*> files;
           std::vector<cmSourceFile*> files;
-          tgt->GetSourceFiles(files);
+          tgt->GetSourceFiles(files,
+                            makefile->GetSafeDefinition("CMAKE_BUILD_TYPE"));
           for(std::vector<cmSourceFile*>::const_iterator sfIt = files.begin();
           for(std::vector<cmSourceFile*>::const_iterator sfIt = files.begin();
               sfIt != files.end();
               sfIt != files.end();
               sfIt++)
               sfIt++)

+ 2 - 1
Source/cmExtraSublimeTextGenerator.cxx

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

+ 1 - 1
Source/cmFLTKWrapUICommand.cxx

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

+ 12 - 0
Source/cmGeneratorExpressionDAGChecker.cxx

@@ -179,6 +179,18 @@ bool cmGeneratorExpressionDAGChecker::EvaluatingLinkLibraries(const char *tgt)
        || strcmp(prop, "INTERFACE_LINK_LIBRARIES") == 0;
        || strcmp(prop, "INTERFACE_LINK_LIBRARIES") == 0;
 }
 }
 
 
+std::string cmGeneratorExpressionDAGChecker::TopTarget() const
+{
+  const cmGeneratorExpressionDAGChecker *top = this;
+  const cmGeneratorExpressionDAGChecker *parent = this->Parent;
+  while (parent)
+    {
+    top = parent;
+    parent = parent->Parent;
+    }
+  return top->Target;
+}
+
 enum TransitiveProperty {
 enum TransitiveProperty {
 #define DEFINE_ENUM_ENTRY(NAME) NAME,
 #define DEFINE_ENUM_ENTRY(NAME) NAME,
   CM_FOR_EACH_TRANSITIVE_PROPERTY_NAME(DEFINE_ENUM_ENTRY)
   CM_FOR_EACH_TRANSITIVE_PROPERTY_NAME(DEFINE_ENUM_ENTRY)

+ 4 - 1
Source/cmGeneratorExpressionDAGChecker.h

@@ -25,7 +25,8 @@
   SELECT(F, EvaluatingSystemIncludeDirectories, SYSTEM_INCLUDE_DIRECTORIES) \
   SELECT(F, EvaluatingSystemIncludeDirectories, SYSTEM_INCLUDE_DIRECTORIES) \
   SELECT(F, EvaluatingCompileDefinitions,       COMPILE_DEFINITIONS) \
   SELECT(F, EvaluatingCompileDefinitions,       COMPILE_DEFINITIONS) \
   SELECT(F, EvaluatingCompileOptions,           COMPILE_OPTIONS) \
   SELECT(F, EvaluatingCompileOptions,           COMPILE_OPTIONS) \
-  SELECT(F, EvaluatingAutoUicOptions,           AUTOUIC_OPTIONS)
+  SELECT(F, EvaluatingAutoUicOptions,           AUTOUIC_OPTIONS) \
+  SELECT(F, EvaluatingSources,                  SOURCES)
 
 
 #define CM_FOR_EACH_TRANSITIVE_PROPERTY(F) \
 #define CM_FOR_EACH_TRANSITIVE_PROPERTY(F) \
   CM_FOR_EACH_TRANSITIVE_PROPERTY_IMPL(F, CM_SELECT_BOTH)
   CM_FOR_EACH_TRANSITIVE_PROPERTY_IMPL(F, CM_SELECT_BOTH)
@@ -70,6 +71,8 @@ struct cmGeneratorExpressionDAGChecker
   void SetTransitivePropertiesOnly()
   void SetTransitivePropertiesOnly()
     { this->TransitivePropertiesOnly = true; }
     { this->TransitivePropertiesOnly = true; }
 
 
+  std::string TopTarget() const;
+
 private:
 private:
   Result CheckGraph() const;
   Result CheckGraph() const;
 
 

+ 6 - 3
Source/cmGeneratorExpressionEvaluator.cxx

@@ -985,7 +985,8 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode
     if (propertyName == "LINKER_LANGUAGE")
     if (propertyName == "LINKER_LANGUAGE")
       {
       {
       if (target->LinkLanguagePropagatesToDependents() &&
       if (target->LinkLanguagePropagatesToDependents() &&
-          dagCheckerParent && dagCheckerParent->EvaluatingLinkLibraries())
+          dagCheckerParent && (dagCheckerParent->EvaluatingLinkLibraries()
+            || dagCheckerParent->EvaluatingSources()))
         {
         {
         reportError(context, content->GetOriginalExpression(),
         reportError(context, content->GetOriginalExpression(),
             "LINKER_LANGUAGE target property can not be used while evaluating "
             "LINKER_LANGUAGE target property can not be used while evaluating "
@@ -1282,7 +1283,7 @@ static const struct TargetObjectsNode : public cmGeneratorExpressionNode
       }
       }
 
 
     std::vector<cmSourceFile const*> objectSources;
     std::vector<cmSourceFile const*> objectSources;
-    gt->GetObjectSources(objectSources);
+    gt->GetObjectSources(objectSources, context->Config);
     std::map<cmSourceFile const*, std::string> mapping;
     std::map<cmSourceFile const*, std::string> mapping;
 
 
     for(std::vector<cmSourceFile const*>::const_iterator it
     for(std::vector<cmSourceFile const*>::const_iterator it
@@ -1579,7 +1580,9 @@ struct TargetFilesystemArtifact : public cmGeneratorExpressionNode
                   "Target \"" + name + "\" is not an executable or library.");
                   "Target \"" + name + "\" is not an executable or library.");
       return std::string();
       return std::string();
       }
       }
-    if (dagChecker && dagChecker->EvaluatingLinkLibraries(name.c_str()))
+    if (dagChecker && (dagChecker->EvaluatingLinkLibraries(name.c_str())
+        || (dagChecker->EvaluatingSources()
+          && name == dagChecker->TopTarget())))
       {
       {
       ::reportError(context, content->GetOriginalExpression(),
       ::reportError(context, content->GetOriginalExpression(),
                     "Expressions which require the linker language may not "
                     "Expressions which require the linker language may not "

+ 56 - 19
Source/cmGeneratorTarget.cxx

@@ -289,7 +289,7 @@ static void handleSystemIncludesDep(cmMakefile *mf, cmTarget* depTgt,
 #define IMPLEMENT_VISIT_IMPL(DATA, DATATYPE) \
 #define IMPLEMENT_VISIT_IMPL(DATA, DATATYPE) \
   { \
   { \
   std::vector<cmSourceFile*> sourceFiles; \
   std::vector<cmSourceFile*> sourceFiles; \
-  this->Target->GetSourceFiles(sourceFiles); \
+  this->Target->GetSourceFiles(sourceFiles, config); \
   TagVisitor<DATA ## Tag DATATYPE> visitor(this->Target, data); \
   TagVisitor<DATA ## Tag DATATYPE> visitor(this->Target, data); \
   for(std::vector<cmSourceFile*>::const_iterator si = sourceFiles.begin(); \
   for(std::vector<cmSourceFile*>::const_iterator si = sourceFiles.begin(); \
       si != sourceFiles.end(); ++si) \
       si != sourceFiles.end(); ++si) \
@@ -308,7 +308,8 @@ static void handleSystemIncludesDep(cmMakefile *mf, cmTarget* depTgt,
 //----------------------------------------------------------------------------
 //----------------------------------------------------------------------------
 void
 void
 cmGeneratorTarget
 cmGeneratorTarget
-::GetObjectSources(std::vector<cmSourceFile const*> &data) const
+::GetObjectSources(std::vector<cmSourceFile const*> &data,
+                   const std::string& config) const
 {
 {
   IMPLEMENT_VISIT(ObjectSources);
   IMPLEMENT_VISIT(ObjectSources);
 
 
@@ -332,8 +333,19 @@ void cmGeneratorTarget::ComputeObjectMapping()
     {
     {
     return;
     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
 void cmGeneratorTarget
-::GetIDLSources(std::vector<cmSourceFile const*>& data) const
+::GetIDLSources(std::vector<cmSourceFile const*>& data,
+                const std::string& config) const
 {
 {
   IMPLEMENT_VISIT(IDLSources);
   IMPLEMENT_VISIT(IDLSources);
 }
 }
@@ -368,14 +381,16 @@ void cmGeneratorTarget
 //----------------------------------------------------------------------------
 //----------------------------------------------------------------------------
 void
 void
 cmGeneratorTarget
 cmGeneratorTarget
-::GetHeaderSources(std::vector<cmSourceFile const*>& data) const
+::GetHeaderSources(std::vector<cmSourceFile const*>& data,
+                   const std::string& config) const
 {
 {
   IMPLEMENT_VISIT(HeaderSources);
   IMPLEMENT_VISIT(HeaderSources);
 }
 }
 
 
 //----------------------------------------------------------------------------
 //----------------------------------------------------------------------------
 void cmGeneratorTarget
 void cmGeneratorTarget
-::GetExtraSources(std::vector<cmSourceFile const*>& data) const
+::GetExtraSources(std::vector<cmSourceFile const*>& data,
+                  const std::string& config) const
 {
 {
   IMPLEMENT_VISIT(ExtraSources);
   IMPLEMENT_VISIT(ExtraSources);
 }
 }
@@ -383,7 +398,8 @@ void cmGeneratorTarget
 //----------------------------------------------------------------------------
 //----------------------------------------------------------------------------
 void
 void
 cmGeneratorTarget
 cmGeneratorTarget
-::GetCustomCommands(std::vector<cmSourceFile const*>& data) const
+::GetCustomCommands(std::vector<cmSourceFile const*>& data,
+                    const std::string& config) const
 {
 {
   IMPLEMENT_VISIT(CustomCommands);
   IMPLEMENT_VISIT(CustomCommands);
 }
 }
@@ -391,14 +407,16 @@ cmGeneratorTarget
 //----------------------------------------------------------------------------
 //----------------------------------------------------------------------------
 void
 void
 cmGeneratorTarget
 cmGeneratorTarget
-::GetExternalObjects(std::vector<cmSourceFile const*>& data) const
+::GetExternalObjects(std::vector<cmSourceFile const*>& data,
+                     const std::string& config) const
 {
 {
   IMPLEMENT_VISIT(ExternalObjects);
   IMPLEMENT_VISIT(ExternalObjects);
 }
 }
 
 
 //----------------------------------------------------------------------------
 //----------------------------------------------------------------------------
 void
 void
-cmGeneratorTarget::GetExpectedResxHeaders(std::set<std::string>& srcs) const
+cmGeneratorTarget::GetExpectedResxHeaders(std::set<std::string>& srcs,
+                                          const std::string& config) const
 {
 {
   ResxData data;
   ResxData data;
   IMPLEMENT_VISIT_IMPL(Resx, COMMA cmGeneratorTarget::ResxData)
   IMPLEMENT_VISIT_IMPL(Resx, COMMA cmGeneratorTarget::ResxData)
@@ -407,7 +425,8 @@ cmGeneratorTarget::GetExpectedResxHeaders(std::set<std::string>& srcs) const
 
 
 //----------------------------------------------------------------------------
 //----------------------------------------------------------------------------
 void cmGeneratorTarget
 void cmGeneratorTarget
-::GetResxSources(std::vector<cmSourceFile const*>& srcs) const
+::GetResxSources(std::vector<cmSourceFile const*>& srcs,
+                 const std::string& config) const
 {
 {
   ResxData data;
   ResxData data;
   IMPLEMENT_VISIT_IMPL(Resx, COMMA cmGeneratorTarget::ResxData)
   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;
   std::string data;
   IMPLEMENT_VISIT_IMPL(ModuleDefinitionFile, COMMA std::string)
   IMPLEMENT_VISIT_IMPL(ModuleDefinitionFile, COMMA std::string)
@@ -532,10 +553,11 @@ std::string cmGeneratorTarget::GetModuleDefinitionFile() const
 
 
 //----------------------------------------------------------------------------
 //----------------------------------------------------------------------------
 void
 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;
   std::vector<cmSourceFile const*> objectFiles;
-  this->GetExternalObjects(objectFiles);
+  this->GetExternalObjects(objectFiles, config);
   std::vector<cmTarget*> objectLibraries;
   std::vector<cmTarget*> objectLibraries;
   std::set<cmTarget*> emitted;
   std::set<cmTarget*> emitted;
   for(std::vector<cmSourceFile const*>::const_iterator
   for(std::vector<cmSourceFile const*>::const_iterator
@@ -559,7 +581,7 @@ cmGeneratorTarget::UseObjectLibraries(std::vector<std::string>& objs) const
     cmGeneratorTarget* ogt =
     cmGeneratorTarget* ogt =
       this->GlobalGenerator->GetGeneratorTarget(objLib);
       this->GlobalGenerator->GetGeneratorTarget(objLib);
     std::vector<cmSourceFile const*> objectSources;
     std::vector<cmSourceFile const*> objectSources;
-    ogt->GetObjectSources(objectSources);
+    ogt->GetObjectSources(objectSources, config);
     for(std::vector<cmSourceFile const*>::const_iterator
     for(std::vector<cmSourceFile const*>::const_iterator
           si = objectSources.begin();
           si = objectSources.begin();
         si != objectSources.end(); ++si)
         si != objectSources.end(); ++si)
@@ -615,11 +637,26 @@ cmTargetTraceDependencies
   if (this->Target->GetType() != cmTarget::INTERFACE_LIBRARY)
   if (this->Target->GetType() != cmTarget::INTERFACE_LIBRARY)
     {
     {
     std::vector<std::string> sources;
     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();
     for(std::vector<std::string>::const_iterator si = sources.begin();
         si != sources.end(); ++si)
         si != sources.end(); ++si)
       {
       {
-      this->QueueSource(*si);
+      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;
   std::string GetName() const;
   const char *GetProperty(const std::string& prop) const;
   const char *GetProperty(const std::string& prop) const;
   bool GetPropertyAsBool(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);
   const std::string& GetObjectName(cmSourceFile const* file);
 
 
   bool HasExplicitObjectName(cmSourceFile const* file) const;
   bool HasExplicitObjectName(cmSourceFile const* file) const;
   void AddExplicitObjectName(cmSourceFile const* sf);
   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();
   void ComputeObjectMapping();
 
 
@@ -53,14 +62,15 @@ public:
   cmLocalGenerator* LocalGenerator;
   cmLocalGenerator* LocalGenerator;
   cmGlobalGenerator const* GlobalGenerator;
   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
   /** Full path with trailing slash to the top-level directory
       holding object files for this target.  Includes the build
       holding object files for this target.  Includes the build
       time config name placeholder if needed for the generator.  */
       time config name placeholder if needed for the generator.  */
   std::string ObjectDirectory;
   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,
   void GetAppleArchs(const std::string& config,
                      std::vector<std::string>& archVec) const;
                      std::vector<std::string>& archVec) const;

+ 16 - 1
Source/cmGlobalGenerator.cxx

@@ -2902,10 +2902,25 @@ void cmGlobalGenerator::WriteSummary(cmTarget* target)
     // List the source files with any per-source labels.
     // List the source files with any per-source labels.
     fout << "# Source files and their labels\n";
     fout << "# Source files and their labels\n";
     std::vector<cmSourceFile*> sources;
     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();
     for(std::vector<cmSourceFile*>::const_iterator si = sources.begin();
         si != sources.end(); ++si)
         si != sources.end(); ++si)
       {
       {
+      if (!emitted.insert(*si).second)
+        {
+        continue;
+        }
       cmSourceFile* sf = *si;
       cmSourceFile* sf = *si;
       fout << sf->GetFullPath() << "\n";
       fout << sf->GetFullPath() << "\n";
       if(const char* svalue = sf->GetProperty("LABELS"))
       if(const char* svalue = sf->GetProperty("LABELS"))

+ 2 - 1
Source/cmGlobalKdevelopGenerator.cxx

@@ -139,7 +139,8 @@ bool cmGlobalKdevelopGenerator
          ti != targets.end(); ti++)
          ti != targets.end(); ti++)
       {
       {
       std::vector<cmSourceFile*> sources;
       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();
       for (std::vector<cmSourceFile*>::const_iterator si=sources.begin();
            si!=sources.end(); si++)
            si!=sources.end(); si++)
         {
         {

+ 2 - 1
Source/cmGlobalUnixMakefileGenerator3.cxx

@@ -1081,7 +1081,8 @@ bool cmGlobalUnixMakefileGenerator3
 ::NeedRequiresStep(cmTarget const& target)
 ::NeedRequiresStep(cmTarget const& target)
 {
 {
   std::set<std::string> languages;
   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();
   for(std::set<std::string>::const_iterator l = languages.begin();
       l != languages.end(); ++l)
       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
   // check to see if this is a fortran build
   std::set<std::string> languages;
   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.size() == 1)
     {
     {
     if(*languages.begin() == "Fortran")
     if(*languages.begin() == "Fortran")

+ 20 - 8
Source/cmGlobalXCodeGenerator.cxx

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

+ 4 - 3
Source/cmLocalGenerator.cxx

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

+ 4 - 2
Source/cmLocalUnixMakefileGenerator3.cxx

@@ -200,7 +200,8 @@ GetLocalObjectFiles(std::map<std::string, LocalObjectInfo> &localObjectFiles)
       continue;
       continue;
       }
       }
     std::vector<cmSourceFile const*> objectSources;
     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.
     // Compute full path to object file directory for this target.
     std::string dir;
     std::string dir;
     dir += gt->Makefile->GetCurrentOutputDirectory();
     dir += gt->Makefile->GetCurrentOutputDirectory();
@@ -1262,7 +1263,8 @@ cmLocalUnixMakefileGenerator3
     {
     {
     // Get the set of source languages in the target.
     // Get the set of source languages in the target.
     std::set<std::string> languages;
     std::set<std::string> languages;
-    target.GetLanguages(languages);
+    target.GetLanguages(languages,
+                      this->Makefile->GetSafeDefinition("CMAKE_BUILD_TYPE"));
     fout << "\n"
     fout << "\n"
          << "# Per-language clean rules from dependency scanning.\n"
          << "# Per-language clean rules from dependency scanning.\n"
          << "foreach(lang";
          << "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
   // get the classes from the source lists then add them to the groups
   std::vector<cmSourceFile*> classes;
   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 all of the source files have been properly assigned to the target
   // now stick them into source groups using the reg expressions
   // now stick them into source groups using the reg expressions
@@ -1269,7 +1272,20 @@ void cmLocalVisualStudio6Generator
   if(targetBuilds)
   if(targetBuilds)
     {
     {
     // Get the language to use for linking.
     // 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())
     if(linkLanguage.empty())
       {
       {
       cmSystemTools::Error
       cmSystemTools::Error
@@ -1691,7 +1707,20 @@ void cmLocalVisualStudio6Generator
     if(target.GetType() >= cmTarget::EXECUTABLE &&
     if(target.GetType() >= cmTarget::EXECUTABLE &&
        target.GetType() <= cmTarget::OBJECT_LIBRARY)
        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())
       if(linkLanguage.empty())
         {
         {
         cmSystemTools::Error
         cmSystemTools::Error
@@ -1889,7 +1918,7 @@ void cmLocalVisualStudio6Generator
   cmGeneratorTarget* gt =
   cmGeneratorTarget* gt =
     this->GlobalGenerator->GetGeneratorTarget(&target);
     this->GlobalGenerator->GetGeneratorTarget(&target);
   std::vector<std::string> objs;
   std::vector<std::string> objs;
-  gt->UseObjectLibraries(objs);
+  gt->UseObjectLibraries(objs, "");
   for(std::vector<std::string>::const_iterator
   for(std::vector<std::string>::const_iterator
         oi = objs.begin(); oi != objs.end(); ++oi)
         oi = objs.begin(); oi != objs.end(); ++oi)
     {
     {

+ 6 - 3
Source/cmLocalVisualStudio7Generator.cxx

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

+ 17 - 12
Source/cmMakefileTargetGenerator.cxx

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

+ 2 - 1
Source/cmNinjaNormalTargetGenerator.cxx

@@ -111,7 +111,8 @@ void cmNinjaNormalTargetGenerator::WriteLanguagesRules()
 #endif
 #endif
 
 
   std::set<std::string> languages;
   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();
   for(std::set<std::string>::const_iterator l = languages.begin();
       l != languages.end();
       l != languages.end();
       ++l)
       ++l)

+ 9 - 7
Source/cmNinjaTargetGenerator.cxx

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

+ 3 - 1
Source/cmNinjaUtilityTargetGenerator.cxx

@@ -46,7 +46,9 @@ void cmNinjaUtilityTargetGenerator::Generate()
   }
   }
 
 
   std::vector<cmSourceFile*> sources;
   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();
   for(std::vector<cmSourceFile*>::const_iterator source = sources.begin();
       source != sources.end(); ++source)
       source != sources.end(); ++source)
     {
     {

+ 2 - 2
Source/cmQtAutoGenerators.cxx

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

+ 287 - 34
Source/cmTarget.cxx

@@ -159,10 +159,13 @@ public:
                                 CachedLinkInterfaceCompileOptionsEntries;
                                 CachedLinkInterfaceCompileOptionsEntries;
   mutable std::map<std::string, std::vector<TargetPropertyEntry*> >
   mutable std::map<std::string, std::vector<TargetPropertyEntry*> >
                                 CachedLinkInterfaceCompileDefinitionsEntries;
                                 CachedLinkInterfaceCompileDefinitionsEntries;
+  mutable std::map<std::string, std::vector<TargetPropertyEntry*> >
+                                CachedLinkInterfaceSourcesEntries;
 
 
   mutable std::map<std::string, bool> CacheLinkInterfaceIncludeDirectoriesDone;
   mutable std::map<std::string, bool> CacheLinkInterfaceIncludeDirectoriesDone;
   mutable std::map<std::string, bool> CacheLinkInterfaceCompileDefinitionsDone;
   mutable std::map<std::string, bool> CacheLinkInterfaceCompileDefinitionsDone;
   mutable std::map<std::string, bool> CacheLinkInterfaceCompileOptionsDone;
   mutable std::map<std::string, bool> CacheLinkInterfaceCompileOptionsDone;
+  mutable std::map<std::string, bool> CacheLinkInterfaceSourcesDone;
 };
 };
 
 
 //----------------------------------------------------------------------------
 //----------------------------------------------------------------------------
@@ -198,6 +201,7 @@ cmTargetInternals::~cmTargetInternals()
   deleteAndClear(this->CachedLinkInterfaceIncludeDirectoriesEntries);
   deleteAndClear(this->CachedLinkInterfaceIncludeDirectoriesEntries);
   deleteAndClear(this->CachedLinkInterfaceCompileOptionsEntries);
   deleteAndClear(this->CachedLinkInterfaceCompileOptionsEntries);
   deleteAndClear(this->CachedLinkInterfaceCompileDefinitionsEntries);
   deleteAndClear(this->CachedLinkInterfaceCompileDefinitionsEntries);
+  deleteAndClear(this->CachedLinkInterfaceSourcesEntries);
 }
 }
 
 
 //----------------------------------------------------------------------------
 //----------------------------------------------------------------------------
@@ -220,6 +224,7 @@ cmTarget::cmTarget()
   this->DebugIncludesDone = false;
   this->DebugIncludesDone = false;
   this->DebugCompileOptionsDone = false;
   this->DebugCompileOptionsDone = false;
   this->DebugCompileDefinitionsDone = false;
   this->DebugCompileDefinitionsDone = false;
+  this->DebugSourcesDone = false;
 }
 }
 
 
 //----------------------------------------------------------------------------
 //----------------------------------------------------------------------------
@@ -543,47 +548,253 @@ bool cmTarget::IsBundleOnApple() const
 }
 }
 
 
 //----------------------------------------------------------------------------
 //----------------------------------------------------------------------------
-void cmTarget::GetSourceFiles(std::vector<std::string> &files) const
+static void processSources(cmTarget const* tgt,
+      const std::vector<cmTargetInternals::TargetPropertyEntry*> &entries,
+      std::vector<std::string> &srcs,
+      std::set<std::string> &uniqueSrcs,
+      cmGeneratorExpressionDAGChecker *dagChecker,
+      cmTarget const* head,
+      std::string const& config, bool debugSources)
 {
 {
-  assert(this->GetType() != INTERFACE_LIBRARY);
-  for(std::vector<cmTargetInternals::TargetPropertyEntry*>::const_iterator
-      si = this->Internal->SourceEntries.begin();
-      si != this->Internal->SourceEntries.end(); ++si)
+  cmMakefile *mf = tgt->GetMakefile();
+
+  for (std::vector<cmTargetInternals::TargetPropertyEntry*>::const_iterator
+      it = entries.begin(), end = entries.end(); it != end; ++it)
     {
     {
-    std::vector<std::string> srcs;
-    cmSystemTools::ExpandListArgument((*si)->ge->Evaluate(this->Makefile,
-                                        "",
-                                        false,
-                                        this),
-                                      srcs);
+    bool cacheSources = false;
+    std::vector<std::string> entrySources = (*it)->CachedEntries;
+    if(entrySources.empty())
+      {
+      cmSystemTools::ExpandListArgument((*it)->ge->Evaluate(mf,
+                                                config,
+                                                false,
+                                                head ? head : tgt,
+                                                tgt,
+                                                dagChecker),
+                                      entrySources);
+      if (mf->IsGeneratingBuildSystem()
+          && !(*it)->ge->GetHadContextSensitiveCondition())
+        {
+        cacheSources = true;
+        }
 
 
-    for(std::vector<std::string>::const_iterator i = srcs.begin();
-        i != srcs.end(); ++i)
+      for(std::vector<std::string>::iterator i = entrySources.begin();
+          i != entrySources.end(); ++i)
+        {
+        std::string& src = *i;
+
+        cmSourceFile* sf = mf->GetOrCreateSource(src);
+        std::string e;
+        src = sf->GetFullPath(&e);
+        if(src.empty())
+          {
+          if(!e.empty())
+            {
+            cmake* cm = mf->GetCMakeInstance();
+            cm->IssueMessage(cmake::FATAL_ERROR, e,
+                            tgt->GetBacktrace());
+            }
+          return;
+          }
+        }
+      if (cacheSources)
+        {
+        (*it)->CachedEntries = entrySources;
+        }
+      }
+    std::string usedSources;
+    for(std::vector<std::string>::iterator
+          li = entrySources.begin(); li != entrySources.end(); ++li)
       {
       {
-      std::string src = *i;
-      cmSourceFile* sf = this->Makefile->GetOrCreateSource(src);
-      std::string e;
-      src = sf->GetFullPath(&e);
-      if(src.empty())
+      std::string src = *li;
+
+      if(uniqueSrcs.insert(src).second)
         {
         {
-        if(!e.empty())
+        srcs.push_back(src);
+        if (debugSources)
           {
           {
-          cmake* cm = this->Makefile->GetCMakeInstance();
-          cm->IssueMessage(cmake::FATAL_ERROR, e,
-                          this->GetBacktrace());
+          usedSources += " * " + src + "\n";
           }
           }
-        return;
         }
         }
-      files.push_back(src);
+      }
+    if (!usedSources.empty())
+      {
+      mf->GetCMakeInstance()->IssueMessage(cmake::LOG,
+                            std::string("Used sources for target ")
+                            + tgt->GetName() + ":\n"
+                            + usedSources, (*it)->ge->GetBacktrace());
       }
       }
     }
     }
 }
 }
 
 
 //----------------------------------------------------------------------------
 //----------------------------------------------------------------------------
-void cmTarget::GetSourceFiles(std::vector<cmSourceFile*> &files) const
+void cmTarget::GetSourceFiles(std::vector<std::string> &files,
+                              const std::string& config,
+                              cmTarget const* head) const
+{
+  assert(this->GetType() != INTERFACE_LIBRARY);
+
+  std::vector<std::string> debugProperties;
+  const char *debugProp =
+              this->Makefile->GetDefinition("CMAKE_DEBUG_TARGET_PROPERTIES");
+  if (debugProp)
+    {
+    cmSystemTools::ExpandListArgument(debugProp, debugProperties);
+    }
+
+  bool debugSources = !this->DebugSourcesDone
+                    && std::find(debugProperties.begin(),
+                                 debugProperties.end(),
+                                 "SOURCES")
+                        != debugProperties.end();
+
+  if (this->Makefile->IsGeneratingBuildSystem())
+    {
+    this->DebugSourcesDone = true;
+    }
+
+  cmListFileBacktrace lfbt;
+
+  cmGeneratorExpressionDAGChecker dagChecker(lfbt,
+                                              this->GetName(),
+                                              "SOURCES", 0, 0);
+
+  std::set<std::string> uniqueSrcs;
+  processSources(this,
+                 this->Internal->SourceEntries,
+                 files,
+                 uniqueSrcs,
+                 &dagChecker,
+                 head,
+                 config,
+                 debugSources);
+
+  if (!this->Internal->CacheLinkInterfaceSourcesDone[config])
+    {
+    for (std::vector<cmValueWithOrigin>::const_iterator
+        it = this->Internal->LinkImplementationPropertyEntries.begin(),
+        end = this->Internal->LinkImplementationPropertyEntries.end();
+        it != end; ++it)
+      {
+      if (!cmGeneratorExpression::IsValidTargetName(it->Value)
+          && cmGeneratorExpression::Find(it->Value) == std::string::npos)
+        {
+        continue;
+        }
+      {
+      cmGeneratorExpression ge(lfbt);
+      cmsys::auto_ptr<cmCompiledGeneratorExpression> cge =
+                                                        ge.Parse(it->Value);
+      std::string targetResult = cge->Evaluate(this->Makefile, config,
+                                        false, this, 0, &dagChecker);
+      if (!this->Makefile->FindTargetToUse(targetResult))
+        {
+        continue;
+        }
+      }
+      std::string sourceGenex = "$<TARGET_PROPERTY:" +
+                              it->Value + ",INTERFACE_SOURCES>";
+      if (cmGeneratorExpression::Find(it->Value) != std::string::npos)
+        {
+        // Because it->Value is a generator expression, ensure that it
+        // evaluates to the non-empty string before being used in the
+        // TARGET_PROPERTY expression.
+        sourceGenex = "$<$<BOOL:" + it->Value + ">:" + sourceGenex + ">";
+        }
+      cmGeneratorExpression ge(it->Backtrace);
+      cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(
+                                                                sourceGenex);
+
+      this->Internal
+        ->CachedLinkInterfaceSourcesEntries[config].push_back(
+                        new cmTargetInternals::TargetPropertyEntry(cge,
+                                                              it->Value));
+      }
+    }
+
+  processSources(this,
+    this->Internal->CachedLinkInterfaceSourcesEntries[config],
+                            files,
+                            uniqueSrcs,
+                            &dagChecker,
+                            head,
+                            config,
+                            debugSources);
+
+  if (!this->Makefile->IsGeneratingBuildSystem())
+    {
+    deleteAndClear(this->Internal->CachedLinkInterfaceSourcesEntries);
+    }
+  else
+    {
+    this->Internal->CacheLinkInterfaceSourcesDone[config] = true;
+    }
+}
+
+//----------------------------------------------------------------------------
+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,
+                              cmTarget const* head) const
 {
 {
   std::vector<std::string> srcs;
   std::vector<std::string> srcs;
-  this->GetSourceFiles(srcs);
+  this->GetSourceFiles(srcs, config, head);
 
 
   std::set<cmSourceFile*> emitted;
   std::set<cmSourceFile*> emitted;
 
 
@@ -1487,6 +1698,25 @@ void cmTarget::SetProperty(const std::string& prop, const char* value)
     this->Internal->LinkImplementationPropertyEntries.push_back(entry);
     this->Internal->LinkImplementationPropertyEntries.push_back(entry);
     return;
     return;
     }
     }
+  if (prop == "SOURCES")
+    {
+    if(this->IsImported())
+      {
+      cmOStringStream e;
+      e << "SOURCES property can't be set on imported targets (\""
+            << this->Name << "\")\n";
+      this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
+      return;
+      }
+    cmListFileBacktrace lfbt;
+    this->Makefile->GetBacktrace(lfbt);
+    cmGeneratorExpression ge(lfbt);
+    this->Internal->SourceEntries.clear();
+    cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(value);
+    this->Internal->SourceEntries.push_back(
+                          new cmTargetInternals::TargetPropertyEntry(cge));
+    return;
+    }
   this->Properties.SetProperty(prop, value, cmProperty::TARGET);
   this->Properties.SetProperty(prop, value, cmProperty::TARGET);
   this->MaybeInvalidatePropertyCache(prop);
   this->MaybeInvalidatePropertyCache(prop);
 }
 }
@@ -1554,6 +1784,25 @@ void cmTarget::AppendProperty(const std::string& prop, const char* value,
     this->Internal->LinkImplementationPropertyEntries.push_back(entry);
     this->Internal->LinkImplementationPropertyEntries.push_back(entry);
     return;
     return;
     }
     }
+  if (prop == "SOURCES")
+    {
+    if(this->IsImported())
+      {
+      cmOStringStream e;
+      e << "SOURCES property can't be set on imported targets (\""
+            << this->Name << "\")\n";
+      this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
+      return;
+      }
+
+      cmListFileBacktrace lfbt;
+      this->Makefile->GetBacktrace(lfbt);
+      cmGeneratorExpression ge(lfbt);
+      cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(value);
+      this->Internal->SourceEntries.push_back(
+                            new cmTargetInternals::TargetPropertyEntry(cge));
+    return;
+    }
   this->Properties.AppendProperty(prop, value, cmProperty::TARGET, asString);
   this->Properties.AppendProperty(prop, value, cmProperty::TARGET, asString);
   this->MaybeInvalidatePropertyCache(prop);
   this->MaybeInvalidatePropertyCache(prop);
 }
 }
@@ -4994,10 +5243,12 @@ 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,
+                            cmTarget const* head) const
 {
 {
   std::vector<cmSourceFile*> sourceFiles;
   std::vector<cmSourceFile*> sourceFiles;
-  this->GetSourceFiles(sourceFiles);
+  this->GetSourceFiles(sourceFiles, config, head);
   for(std::vector<cmSourceFile*>::const_iterator
   for(std::vector<cmSourceFile*>::const_iterator
         i = sourceFiles.begin(); i != sourceFiles.end(); ++i)
         i = sourceFiles.begin(); i != sourceFiles.end(); ++i)
     {
     {
@@ -5038,7 +5289,7 @@ void cmTarget::GetLanguages(std::set<std::string>& languages) const
     cmGeneratorTarget* gt = this->Makefile->GetLocalGenerator()
     cmGeneratorTarget* gt = this->Makefile->GetLocalGenerator()
                                 ->GetGlobalGenerator()
                                 ->GetGlobalGenerator()
                                 ->GetGeneratorTarget(this);
                                 ->GetGeneratorTarget(this);
-    gt->GetExternalObjects(externalObjects);
+    gt->GetExternalObjects(externalObjects, config);
     for(std::vector<cmSourceFile const*>::const_iterator
     for(std::vector<cmSourceFile const*>::const_iterator
           i = externalObjects.begin(); i != externalObjects.end(); ++i)
           i = externalObjects.begin(); i != externalObjects.end(); ++i)
       {
       {
@@ -5052,7 +5303,7 @@ void cmTarget::GetLanguages(std::set<std::string>& languages) const
   for(std::vector<cmTarget*>::const_iterator
   for(std::vector<cmTarget*>::const_iterator
       i = objectLibraries.begin(); i != objectLibraries.end(); ++i)
       i = objectLibraries.begin(); i != objectLibraries.end(); ++i)
     {
     {
-    (*i)->GetLanguages(languages);
+    (*i)->GetLanguages(languages, config, head);
     }
     }
 }
 }
 
 
@@ -5991,7 +6242,7 @@ cmTarget::GetLinkImplementation(const std::string& config,
     // Compute the link implementation for this configuration.
     // Compute the link implementation for this configuration.
     LinkImplementation impl;
     LinkImplementation impl;
     this->ComputeLinkImplementation(config, impl, head);
     this->ComputeLinkImplementation(config, impl, head);
-    this->ComputeLinkImplementationLanguages(impl);
+    this->ComputeLinkImplementationLanguages(config, impl, head);
 
 
     // Store the information for this configuration.
     // Store the information for this configuration.
     cmTargetInternals::LinkImplMapType::value_type entry(key, impl);
     cmTargetInternals::LinkImplMapType::value_type entry(key, impl);
@@ -5999,7 +6250,7 @@ cmTarget::GetLinkImplementation(const std::string& config,
     }
     }
   else if (i->second.Languages.empty())
   else if (i->second.Languages.empty())
     {
     {
-    this->ComputeLinkImplementationLanguages(i->second);
+    this->ComputeLinkImplementationLanguages(config, i->second, head);
     }
     }
 
 
   return &i->second;
   return &i->second;
@@ -6112,12 +6363,14 @@ void cmTarget::ComputeLinkImplementation(const std::string& config,
 
 
 //----------------------------------------------------------------------------
 //----------------------------------------------------------------------------
 void
 void
-cmTarget::ComputeLinkImplementationLanguages(LinkImplementation& impl) const
+cmTarget::ComputeLinkImplementationLanguages(const std::string& config,
+                                             LinkImplementation& impl,
+                                             cmTarget const* head) const
 {
 {
   // This target needs runtime libraries for its source languages.
   // This target needs runtime libraries for its source languages.
   std::set<std::string> languages;
   std::set<std::string> languages;
   // Get languages used in our source files.
   // Get languages used in our source files.
-  this->GetLanguages(languages);
+  this->GetLanguages(languages, config, head);
   // Copy the set of langauges to the link implementation.
   // Copy the set of langauges to the link implementation.
   for(std::set<std::string>::iterator li = languages.begin();
   for(std::set<std::string>::iterator li = languages.begin();
       li != languages.end(); ++li)
       li != languages.end(); ++li)

+ 14 - 4
Source/cmTarget.h

@@ -135,8 +135,13 @@ public:
   /**
   /**
    * Get the list of the source files used by this target
    * 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,
+                      cmTarget const* head = 0) const;
+  void GetSourceFiles(std::vector<cmSourceFile*> &files,
+                      const std::string& config,
+                      cmTarget const* head = 0) const;
+  bool GetConfigCommonSourceFiles(std::vector<cmSourceFile*>& files) const;
 
 
   /**
   /**
    * Add sources to the target.
    * Add sources to the target.
@@ -465,7 +470,9 @@ public:
   // when source file properties are changed and we do not have enough
   // when source file properties are changed and we do not have enough
   // information to forward these property changes to the targets
   // information to forward these property changes to the targets
   // until we have per-target object file properties.
   // until we have per-target object file properties.
-  void GetLanguages(std::set<std::string>& languages) const;
+  void GetLanguages(std::set<std::string>& languages,
+                    std::string const& config,
+                    cmTarget const* head = 0) const;
 
 
   /** Return whether this target is an executable with symbol exports
   /** Return whether this target is an executable with symbol exports
       enabled.  */
       enabled.  */
@@ -703,6 +710,7 @@ private:
   mutable std::map<std::string, bool> DebugCompatiblePropertiesDone;
   mutable std::map<std::string, bool> DebugCompatiblePropertiesDone;
   mutable bool DebugCompileOptionsDone;
   mutable bool DebugCompileOptionsDone;
   mutable bool DebugCompileDefinitionsDone;
   mutable bool DebugCompileDefinitionsDone;
+  mutable bool DebugSourcesDone;
   mutable std::set<std::string> LinkImplicitNullProperties;
   mutable std::set<std::string> LinkImplicitNullProperties;
   bool BuildInterfaceIncludesAppended;
   bool BuildInterfaceIncludesAppended;
 
 
@@ -738,7 +746,9 @@ private:
   void ComputeLinkImplementation(const std::string& config,
   void ComputeLinkImplementation(const std::string& config,
                                  LinkImplementation& impl,
                                  LinkImplementation& impl,
                                  cmTarget const* head) const;
                                  cmTarget const* head) const;
-  void ComputeLinkImplementationLanguages(LinkImplementation& impl) const;
+  void ComputeLinkImplementationLanguages(const std::string& config,
+                                          LinkImplementation& impl,
+                                          cmTarget const* head) const;
   void ComputeLinkClosure(const std::string& config, LinkClosure& lc,
   void ComputeLinkClosure(const std::string& config, LinkClosure& lc,
                           cmTarget const* head) const;
                           cmTarget const* head) const;
 
 

+ 64 - 0
Source/cmTargetSourcesCommand.cxx

@@ -0,0 +1,64 @@
+/*============================================================================
+  CMake - Cross Platform Makefile Generator
+  Copyright 2014 Stephen Kelly <[email protected]>
+
+  Distributed under the OSI-approved BSD License (the "License");
+  see accompanying file Copyright.txt for details.
+
+  This software is distributed WITHOUT ANY WARRANTY; without even the
+  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+  See the License for more information.
+============================================================================*/
+#include "cmTargetSourcesCommand.h"
+
+#include "cmGeneratorExpression.h"
+
+//----------------------------------------------------------------------------
+bool cmTargetSourcesCommand
+::InitialPass(std::vector<std::string> const& args, cmExecutionStatus &)
+{
+  return this->HandleArguments(args, "SOURCES");
+}
+
+//----------------------------------------------------------------------------
+void cmTargetSourcesCommand
+::HandleImportedTarget(const std::string &tgt)
+{
+  cmOStringStream e;
+  e << "Cannot specify sources for imported target \""
+    << tgt << "\".";
+  this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
+}
+
+//----------------------------------------------------------------------------
+void cmTargetSourcesCommand
+::HandleMissingTarget(const std::string &name)
+{
+  cmOStringStream e;
+  e << "Cannot specify sources for target \"" << name << "\" "
+       "which is not built by this project.";
+  this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
+}
+
+//----------------------------------------------------------------------------
+std::string cmTargetSourcesCommand
+::Join(const std::vector<std::string> &content)
+{
+  std::string srcs;
+  std::string sep;
+  for(std::vector<std::string>::const_iterator it = content.begin();
+    it != content.end(); ++it)
+    {
+    srcs += sep + *it;
+    sep = ";";
+    }
+  return srcs;
+}
+
+//----------------------------------------------------------------------------
+void cmTargetSourcesCommand
+::HandleDirectContent(cmTarget *tgt, const std::vector<std::string> &content,
+                      bool, bool)
+{
+  tgt->AppendProperty("SOURCES", this->Join(content).c_str());
+}

+ 55 - 0
Source/cmTargetSourcesCommand.h

@@ -0,0 +1,55 @@
+/*============================================================================
+  CMake - Cross Platform Makefile Generator
+  Copyright 2014 Stephen Kelly <[email protected]>
+
+  Distributed under the OSI-approved BSD License (the "License");
+  see accompanying file Copyright.txt for details.
+
+  This software is distributed WITHOUT ANY WARRANTY; without even the
+  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+  See the License for more information.
+============================================================================*/
+
+#ifndef cmTargetSourcesCommand_h
+#define cmTargetSourcesCommand_h
+
+#include "cmTargetPropCommandBase.h"
+
+//----------------------------------------------------------------------------
+class cmTargetSourcesCommand : public cmTargetPropCommandBase
+{
+public:
+  /**
+   * This is a virtual constructor for the command.
+   */
+  virtual cmCommand* Clone()
+    {
+    return new cmTargetSourcesCommand;
+    }
+
+  /**
+   * This is called when the command is first encountered in
+   * the CMakeLists.txt file.
+   */
+  virtual bool InitialPass(std::vector<std::string> const& args,
+                           cmExecutionStatus &status);
+
+  /**
+   * The name of the command as specified in CMakeList.txt.
+   */
+  virtual std::string GetName() const { return "target_sources";}
+
+  cmTypeMacro(cmTargetSourcesCommand, cmTargetPropCommandBase);
+
+private:
+  virtual void HandleImportedTarget(const std::string &tgt);
+  virtual void HandleMissingTarget(const std::string &name);
+
+  virtual void HandleDirectContent(cmTarget *tgt,
+                                   const std::vector<std::string> &content,
+                                   bool prepend, bool system);
+
+  virtual std::string Join(const std::vector<std::string> &content);
+};
+
+#endif

+ 16 - 13
Source/cmVisualStudio10TargetGenerator.cxx

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

+ 5 - 0
Tests/CMakeLists.txt

@@ -278,6 +278,11 @@ if(BUILD_TESTING)
   ADD_TEST_MACRO(AliasTarget AliasTarget)
   ADD_TEST_MACRO(AliasTarget AliasTarget)
   ADD_TEST_MACRO(StagingPrefix StagingPrefix)
   ADD_TEST_MACRO(StagingPrefix StagingPrefix)
   ADD_TEST_MACRO(InterfaceLibrary InterfaceLibrary)
   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()
+  ADD_TEST_MACRO(SourcesProperty SourcesProperty)
   set_tests_properties(EmptyLibrary PROPERTIES
   set_tests_properties(EmptyLibrary PROPERTIES
     PASS_REGULAR_EXPRESSION "CMake Error: CMake can not determine linker language for target: test")
     PASS_REGULAR_EXPRESSION "CMake Error: CMake can not determine linker language for target: test")
   ADD_TEST_MACRO(CrossCompile CrossCompile)
   ADD_TEST_MACRO(CrossCompile CrossCompile)

+ 17 - 0
Tests/ConfigSources/CMakeLists.txt

@@ -0,0 +1,17 @@
+
+cmake_minimum_required(VERSION 3.0)
+
+project(ConfigSources)
+
+add_library(iface INTERFACE)
+set_property(TARGET iface PROPERTY INTERFACE_SOURCES
+  iface_src.cpp
+  $<$<CONFIG:Debug>:iface_debug_src.cpp>
+  $<$<CONFIG:Release>:does_not_exist.cpp>
+)
+
+add_executable(ConfigSources
+  $<$<CONFIG:Debug>:main.cpp>
+  $<$<CONFIG:Release>:does_not_exist.cpp>
+)
+target_link_libraries(ConfigSources iface)

+ 4 - 0
Tests/ConfigSources/iface_debug.h

@@ -0,0 +1,4 @@
+
+int iface_src();
+
+int iface_debug();

+ 7 - 0
Tests/ConfigSources/iface_debug_src.cpp

@@ -0,0 +1,7 @@
+
+#include "iface_debug.h"
+
+int iface_debug()
+{
+  return 0;
+}

+ 5 - 0
Tests/ConfigSources/iface_src.cpp

@@ -0,0 +1,5 @@
+
+int iface_src()
+{
+  return 0;
+}

+ 7 - 0
Tests/ConfigSources/main.cpp

@@ -0,0 +1,7 @@
+
+#include "iface_debug.h"
+
+int main(int argc, char** argv)
+{
+  return iface_src() + iface_debug();
+}

+ 7 - 1
Tests/QtAutogen/CMakeLists.txt

@@ -64,9 +64,15 @@ add_custom_command(
   DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/myotherinterface.h.in"
   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
 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>
                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")
 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 "yaf.h"
 #include "libC.h"
 #include "libC.h"
 #include "resourcetester.h"
 #include "resourcetester.h"
+#ifdef TEST_DEBUG_CLASS
+#include "debug_class.h"
+#include <iostream>
+#endif
+
 
 
 int main(int argv, char **args)
 int main(int argv, char **args)
 {
 {
@@ -81,5 +86,9 @@ int main(int argv, char **args)
 
 
   QTimer::singleShot(0, &rt, SLOT(doTest()));
   QTimer::singleShot(0, &rt, SLOT(doTest()));
 
 
+#ifdef TEST_DEBUG_CLASS
+  std::cout << DebugClass::staticMetaObject.className() << std::endl;
+#endif
+
   return app.exec();
   return app.exec();
 }
 }

+ 4 - 0
Tests/QtAutogen/resourcetester.cpp

@@ -18,6 +18,10 @@ void ResourceTester::doTest()
       qApp->exit(EXIT_FAILURE);
       qApp->exit(EXIT_FAILURE);
   if (!QFile::exists(":/main.cpp"))
   if (!QFile::exists(":/main.cpp"))
       qApp->exit(EXIT_FAILURE);
       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()));
   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(Languages)
 add_RunCMake_test(ObjectLibrary)
 add_RunCMake_test(ObjectLibrary)
 add_RunCMake_test(TargetObjects)
 add_RunCMake_test(TargetObjects)
+add_RunCMake_test(TargetSources)
 add_RunCMake_test(find_dependency)
 add_RunCMake_test(find_dependency)
 if(NOT WIN32)
 if(NOT WIN32)
   add_RunCMake_test(PositionIndependentCode)
   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>)

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

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

+ 31 - 0
Tests/RunCMake/TargetSources/OriginDebug-stderr.txt

@@ -0,0 +1,31 @@
+CMake Debug Log at OriginDebug.cmake:13 \(add_library\):
+  Used sources for target OriginDebug:
+
+   \* .*Tests/RunCMake/TargetSources/empty_2.cpp
+
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)
++
+CMake Debug Log at OriginDebug.cmake:16 \(set_property\):
+  Used sources for target OriginDebug:
+
+   \* .*Tests/RunCMake/TargetSources/empty_3.cpp
+
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)
++
+CMake Debug Log at OriginDebug.cmake:20 \(target_sources\):
+  Used sources for target OriginDebug:
+
+   \* .*Tests/RunCMake/TargetSources/empty_4.cpp
+
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)
++
+CMake Debug Log at OriginDebug.cmake:14 \(target_link_libraries\):
+  Used sources for target OriginDebug:
+
+   \* .*Tests/RunCMake/TargetSources/empty_1.cpp
+
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)

+ 20 - 0
Tests/RunCMake/TargetSources/OriginDebug.cmake

@@ -0,0 +1,20 @@
+
+cmake_minimum_required(VERSION 3.0)
+
+project(OriginDebug)
+
+set(CMAKE_DEBUG_TARGET_PROPERTIES SOURCES)
+
+add_library(iface INTERFACE)
+set_property(TARGET iface PROPERTY INTERFACE_SOURCES
+  empty_1.cpp
+)
+
+add_library(OriginDebug empty_2.cpp)
+target_link_libraries(OriginDebug iface)
+
+set_property(TARGET OriginDebug APPEND PROPERTY SOURCES
+  empty_3.cpp
+)
+
+target_sources(OriginDebug PRIVATE empty_4.cpp)

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

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

+ 40 - 0
Tests/RunCMake/TargetSources/OriginDebugIDE-stderr.txt

@@ -0,0 +1,40 @@
+CMake Debug Log at OriginDebug.cmake:13 \(add_library\):
+  Used sources for target OriginDebug:
+
+   \* .*Tests/RunCMake/TargetSources/empty_2.cpp
+
+Call Stack \(most recent call first\):
+  OriginDebugIDE.cmake:4 \(include\)
+  CMakeLists.txt:3 \(include\)
++
+CMake Debug Log at OriginDebug.cmake:16 \(set_property\):
+  Used sources for target OriginDebug:
+
+   \* .*Tests/RunCMake/TargetSources/empty_3.cpp
+
+Call Stack \(most recent call first\):
+  OriginDebugIDE.cmake:4 \(include\)
+  CMakeLists.txt:3 \(include\)
++
+CMake Debug Log at OriginDebug.cmake:20 \(target_sources\):
+  Used sources for target OriginDebug:
+
+   \* .*Tests/RunCMake/TargetSources/empty_4.cpp
+
+Call Stack \(most recent call first\):
+  OriginDebugIDE.cmake:4 \(include\)
+  CMakeLists.txt:3 \(include\)
++
+CMake Debug Log:
+  Used sources for target OriginDebug:
+
+   * .*CMakeLists.txt
++
+CMake Debug Log at OriginDebug.cmake:14 \(target_link_libraries\):
+  Used sources for target OriginDebug:
+
+   \* .*Tests/RunCMake/TargetSources/empty_1.cpp
+
+Call Stack \(most recent call first\):
+  OriginDebugIDE.cmake:4 \(include\)
+  CMakeLists.txt:3 \(include\)

+ 4 - 0
Tests/RunCMake/TargetSources/OriginDebugIDE.cmake

@@ -0,0 +1,4 @@
+
+# Separate test for the IDEs, because they show the CMakeLists.txt file
+# as a source file.
+include(${CMAKE_CURRENT_LIST_DIR}/OriginDebug.cmake)

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

@@ -0,0 +1,9 @@
+include(RunCMake)
+
+if(RunCMake_GENERATOR MATCHES Xcode
+    OR RunCMake_GENERATOR MATCHES "Visual Studio")
+  run_cmake(ConfigNotAllowed)
+  run_cmake(OriginDebugIDE)
+else()
+  run_cmake(OriginDebug)
+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;
+}

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

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

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

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

+ 12 - 0
Tests/SourcesProperty/CMakeLists.txt

@@ -0,0 +1,12 @@
+
+cmake_minimum_required(VERSION 3.0)
+
+project(SourcesProperty)
+
+add_library(iface INTERFACE)
+set_property(TARGET iface PROPERTY INTERFACE_SOURCES iface.cpp)
+
+add_executable(SourcesProperty main.cpp)
+target_link_libraries(SourcesProperty iface)
+
+set_property(TARGET SourcesProperty APPEND PROPERTY SOURCES prop.cpp)

+ 5 - 0
Tests/SourcesProperty/iface.cpp

@@ -0,0 +1,5 @@
+
+int iface()
+{
+  return 0;
+}

+ 4 - 0
Tests/SourcesProperty/iface.h

@@ -0,0 +1,4 @@
+
+int iface();
+
+int prop();

+ 7 - 0
Tests/SourcesProperty/main.cpp

@@ -0,0 +1,7 @@
+
+#include "iface.h"
+
+int main(int argc, char** argv)
+{
+  return iface() + prop();
+}

+ 5 - 0
Tests/SourcesProperty/prop.cpp

@@ -0,0 +1,5 @@
+
+int prop()
+{
+  return 0;
+}