Procházet zdrojové kódy

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 před 11 roky
rodič
revize
5376151aa1
74 změnil soubory, kde provedl 1098 přidání a 183 odebrání
  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_include_directories
    /command/target_link_libraries
+   /command/target_sources
    /command/try_compile
    /command/try_run
    /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_LINK_LIBRARIES
    /prop_tgt/INTERFACE_POSITION_INDEPENDENT_CODE
+   /prop_tgt/INTERFACE_SOURCES
    /prop_tgt/INTERFACE_SYSTEM_INCLUDE_DIRECTORIES
    /prop_tgt/INTERPROCEDURAL_OPTIMIZATION_CONFIG
    /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.
 
-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
 debug output for when evaluating target properties.  Currently it can
 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
 listed in :prop_tgt:`COMPATIBLE_INTERFACE_STRING` and other ``COMPATIBLE_INTERFACE_``
 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
     cmTargetCompileOptionsCommand
     cmTargetIncludeDirectoriesCommand
+    cmTargetSourcesCommand
     cmUseMangledMesaCommand
     cmUtilitySourceCommand
     cmVariableRequiresCommand

+ 28 - 42
Source/cmComputeTargetDepends.cxx

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

+ 2 - 1
Source/cmExtraCodeBlocksGenerator.cxx

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

+ 2 - 1
Source/cmExtraCodeLiteGenerator.cxx

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

+ 2 - 1
Source/cmExtraEclipseCDT4Generator.cxx

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

+ 2 - 1
Source/cmExtraSublimeTextGenerator.cxx

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

+ 1 - 1
Source/cmFLTKWrapUICommand.cxx

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

+ 12 - 0
Source/cmGeneratorExpressionDAGChecker.cxx

@@ -179,6 +179,18 @@ bool cmGeneratorExpressionDAGChecker::EvaluatingLinkLibraries(const char *tgt)
        || 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 {
 #define DEFINE_ENUM_ENTRY(NAME) NAME,
   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, EvaluatingCompileDefinitions,       COMPILE_DEFINITIONS) \
   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) \
   CM_FOR_EACH_TRANSITIVE_PROPERTY_IMPL(F, CM_SELECT_BOTH)
@@ -70,6 +71,8 @@ struct cmGeneratorExpressionDAGChecker
   void SetTransitivePropertiesOnly()
     { this->TransitivePropertiesOnly = true; }
 
+  std::string TopTarget() const;
+
 private:
   Result CheckGraph() const;
 

+ 6 - 3
Source/cmGeneratorExpressionEvaluator.cxx

@@ -985,7 +985,8 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode
     if (propertyName == "LINKER_LANGUAGE")
       {
       if (target->LinkLanguagePropagatesToDependents() &&
-          dagCheckerParent && dagCheckerParent->EvaluatingLinkLibraries())
+          dagCheckerParent && (dagCheckerParent->EvaluatingLinkLibraries()
+            || dagCheckerParent->EvaluatingSources()))
         {
         reportError(context, content->GetOriginalExpression(),
             "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;
-    gt->GetObjectSources(objectSources);
+    gt->GetObjectSources(objectSources, context->Config);
     std::map<cmSourceFile const*, std::string> mapping;
 
     for(std::vector<cmSourceFile const*>::const_iterator it
@@ -1579,7 +1580,9 @@ struct TargetFilesystemArtifact : public cmGeneratorExpressionNode
                   "Target \"" + name + "\" is not an executable or library.");
       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(),
                     "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) \
   { \
   std::vector<cmSourceFile*> sourceFiles; \
-  this->Target->GetSourceFiles(sourceFiles); \
+  this->Target->GetSourceFiles(sourceFiles, config); \
   TagVisitor<DATA ## Tag DATATYPE> visitor(this->Target, data); \
   for(std::vector<cmSourceFile*>::const_iterator si = sourceFiles.begin(); \
       si != sourceFiles.end(); ++si) \
@@ -308,7 +308,8 @@ static void handleSystemIncludesDep(cmMakefile *mf, cmTarget* depTgt,
 //----------------------------------------------------------------------------
 void
 cmGeneratorTarget
-::GetObjectSources(std::vector<cmSourceFile const*> &data) const
+::GetObjectSources(std::vector<cmSourceFile const*> &data,
+                   const std::string& config) const
 {
   IMPLEMENT_VISIT(ObjectSources);
 
@@ -332,8 +333,19 @@ void cmGeneratorTarget::ComputeObjectMapping()
     {
     return;
     }
-  std::vector<cmSourceFile const*> sourceFiles;
-  this->GetObjectSources(sourceFiles);
+
+  std::vector<std::string> configs;
+  this->Makefile->GetConfigurations(configs);
+  if (configs.empty())
+    {
+    configs.push_back("");
+    }
+  for(std::vector<std::string>::const_iterator ci = configs.begin();
+      ci != configs.end(); ++ci)
+    {
+    std::vector<cmSourceFile const*> sourceFiles;
+    this->GetObjectSources(sourceFiles, *ci);
+    }
 }
 
 //----------------------------------------------------------------------------
@@ -360,7 +372,8 @@ bool cmGeneratorTarget::HasExplicitObjectName(cmSourceFile const* file) const
 
 //----------------------------------------------------------------------------
 void cmGeneratorTarget
-::GetIDLSources(std::vector<cmSourceFile const*>& data) const
+::GetIDLSources(std::vector<cmSourceFile const*>& data,
+                const std::string& config) const
 {
   IMPLEMENT_VISIT(IDLSources);
 }
@@ -368,14 +381,16 @@ void cmGeneratorTarget
 //----------------------------------------------------------------------------
 void
 cmGeneratorTarget
-::GetHeaderSources(std::vector<cmSourceFile const*>& data) const
+::GetHeaderSources(std::vector<cmSourceFile const*>& data,
+                   const std::string& config) const
 {
   IMPLEMENT_VISIT(HeaderSources);
 }
 
 //----------------------------------------------------------------------------
 void cmGeneratorTarget
-::GetExtraSources(std::vector<cmSourceFile const*>& data) const
+::GetExtraSources(std::vector<cmSourceFile const*>& data,
+                  const std::string& config) const
 {
   IMPLEMENT_VISIT(ExtraSources);
 }
@@ -383,7 +398,8 @@ void cmGeneratorTarget
 //----------------------------------------------------------------------------
 void
 cmGeneratorTarget
-::GetCustomCommands(std::vector<cmSourceFile const*>& data) const
+::GetCustomCommands(std::vector<cmSourceFile const*>& data,
+                    const std::string& config) const
 {
   IMPLEMENT_VISIT(CustomCommands);
 }
@@ -391,14 +407,16 @@ cmGeneratorTarget
 //----------------------------------------------------------------------------
 void
 cmGeneratorTarget
-::GetExternalObjects(std::vector<cmSourceFile const*>& data) const
+::GetExternalObjects(std::vector<cmSourceFile const*>& data,
+                     const std::string& config) const
 {
   IMPLEMENT_VISIT(ExternalObjects);
 }
 
 //----------------------------------------------------------------------------
 void
-cmGeneratorTarget::GetExpectedResxHeaders(std::set<std::string>& srcs) const
+cmGeneratorTarget::GetExpectedResxHeaders(std::set<std::string>& srcs,
+                                          const std::string& config) const
 {
   ResxData data;
   IMPLEMENT_VISIT_IMPL(Resx, COMMA cmGeneratorTarget::ResxData)
@@ -407,7 +425,8 @@ cmGeneratorTarget::GetExpectedResxHeaders(std::set<std::string>& srcs) const
 
 //----------------------------------------------------------------------------
 void cmGeneratorTarget
-::GetResxSources(std::vector<cmSourceFile const*>& srcs) const
+::GetResxSources(std::vector<cmSourceFile const*>& srcs,
+                 const std::string& config) const
 {
   ResxData data;
   IMPLEMENT_VISIT_IMPL(Resx, COMMA cmGeneratorTarget::ResxData)
@@ -517,13 +536,15 @@ bool cmGeneratorTarget::GetPropertyAsBool(const std::string& prop) const
 }
 
 //----------------------------------------------------------------------------
-void cmGeneratorTarget::GetSourceFiles(std::vector<cmSourceFile*> &files) const
+void cmGeneratorTarget::GetSourceFiles(std::vector<cmSourceFile*> &files,
+                                       const std::string& config) const
 {
-  this->Target->GetSourceFiles(files);
+  this->Target->GetSourceFiles(files, config);
 }
 
 //----------------------------------------------------------------------------
-std::string cmGeneratorTarget::GetModuleDefinitionFile() const
+std::string
+cmGeneratorTarget::GetModuleDefinitionFile(const std::string& config) const
 {
   std::string data;
   IMPLEMENT_VISIT_IMPL(ModuleDefinitionFile, COMMA std::string)
@@ -532,10 +553,11 @@ std::string cmGeneratorTarget::GetModuleDefinitionFile() const
 
 //----------------------------------------------------------------------------
 void
-cmGeneratorTarget::UseObjectLibraries(std::vector<std::string>& objs) const
+cmGeneratorTarget::UseObjectLibraries(std::vector<std::string>& objs,
+                                      const std::string &config) const
 {
   std::vector<cmSourceFile const*> objectFiles;
-  this->GetExternalObjects(objectFiles);
+  this->GetExternalObjects(objectFiles, config);
   std::vector<cmTarget*> objectLibraries;
   std::set<cmTarget*> emitted;
   for(std::vector<cmSourceFile const*>::const_iterator
@@ -559,7 +581,7 @@ cmGeneratorTarget::UseObjectLibraries(std::vector<std::string>& objs) const
     cmGeneratorTarget* ogt =
       this->GlobalGenerator->GetGeneratorTarget(objLib);
     std::vector<cmSourceFile const*> objectSources;
-    ogt->GetObjectSources(objectSources);
+    ogt->GetObjectSources(objectSources, config);
     for(std::vector<cmSourceFile const*>::const_iterator
           si = objectSources.begin();
         si != objectSources.end(); ++si)
@@ -615,11 +637,26 @@ cmTargetTraceDependencies
   if (this->Target->GetType() != cmTarget::INTERFACE_LIBRARY)
     {
     std::vector<std::string> sources;
-    this->Target->GetSourceFiles(sources);
+    std::vector<std::string> configs;
+    this->Makefile->GetConfigurations(configs);
+    if (configs.empty())
+      {
+      configs.push_back("");
+      }
+    for(std::vector<std::string>::const_iterator ci = configs.begin();
+        ci != configs.end(); ++ci)
+      {
+      this->Target->GetSourceFiles(sources, *ci);
+      }
+    std::set<std::string> emitted;
     for(std::vector<std::string>::const_iterator si = sources.begin();
         si != sources.end(); ++si)
       {
-      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;
   const char *GetProperty(const std::string& prop) const;
   bool GetPropertyAsBool(const std::string& prop) const;
-  void GetSourceFiles(std::vector<cmSourceFile*>& files) const;
+  void GetSourceFiles(std::vector<cmSourceFile*>& files,
+                      const std::string& config) const;
 
-  void GetObjectSources(std::vector<cmSourceFile const*> &) const;
+  void GetObjectSources(std::vector<cmSourceFile const*> &,
+                        const std::string& config) const;
   const std::string& GetObjectName(cmSourceFile const* file);
 
   bool HasExplicitObjectName(cmSourceFile const* file) const;
   void AddExplicitObjectName(cmSourceFile const* sf);
 
-  void GetResxSources(std::vector<cmSourceFile const*>&) const;
-  void GetIDLSources(std::vector<cmSourceFile const*>&) const;
-  void GetExternalObjects(std::vector<cmSourceFile const*>&) const;
-  void GetHeaderSources(std::vector<cmSourceFile const*>&) const;
-  void GetExtraSources(std::vector<cmSourceFile const*>&) const;
-  void GetCustomCommands(std::vector<cmSourceFile const*>&) const;
-  void GetExpectedResxHeaders(std::set<std::string>&) const;
+  void GetResxSources(std::vector<cmSourceFile const*>&,
+                      const std::string& config) const;
+  void GetIDLSources(std::vector<cmSourceFile const*>&,
+                     const std::string& config) const;
+  void GetExternalObjects(std::vector<cmSourceFile const*>&,
+                          const std::string& config) const;
+  void GetHeaderSources(std::vector<cmSourceFile const*>&,
+                        const std::string& config) const;
+  void GetExtraSources(std::vector<cmSourceFile const*>&,
+                       const std::string& config) const;
+  void GetCustomCommands(std::vector<cmSourceFile const*>&,
+                         const std::string& config) const;
+  void GetExpectedResxHeaders(std::set<std::string>&,
+                              const std::string& config) const;
 
   void ComputeObjectMapping();
 
@@ -53,14 +62,15 @@ public:
   cmLocalGenerator* LocalGenerator;
   cmGlobalGenerator const* GlobalGenerator;
 
-  std::string GetModuleDefinitionFile() const;
+  std::string GetModuleDefinitionFile(const std::string& config) const;
 
   /** Full path with trailing slash to the top-level directory
       holding object files for this target.  Includes the build
       time config name placeholder if needed for the generator.  */
   std::string ObjectDirectory;
 
-  void UseObjectLibraries(std::vector<std::string>& objs) const;
+  void UseObjectLibraries(std::vector<std::string>& objs,
+                          const std::string& config) const;
 
   void GetAppleArchs(const std::string& config,
                      std::vector<std::string>& archVec) const;

+ 16 - 1
Source/cmGlobalGenerator.cxx

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

+ 2 - 1
Source/cmGlobalKdevelopGenerator.cxx

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

+ 2 - 1
Source/cmGlobalUnixMakefileGenerator3.cxx

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

+ 9 - 1
Source/cmGlobalVisualStudioGenerator.cxx

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

+ 20 - 8
Source/cmGlobalXCodeGenerator.cxx

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

+ 4 - 3
Source/cmLocalGenerator.cxx

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

+ 4 - 2
Source/cmLocalUnixMakefileGenerator3.cxx

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

+ 33 - 4
Source/cmLocalVisualStudio6Generator.cxx

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

+ 6 - 3
Source/cmLocalVisualStudio7Generator.cxx

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

+ 17 - 12
Source/cmMakefileTargetGenerator.cxx

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

+ 2 - 1
Source/cmNinjaNormalTargetGenerator.cxx

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

+ 9 - 7
Source/cmNinjaTargetGenerator.cxx

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

+ 3 - 1
Source/cmNinjaUtilityTargetGenerator.cxx

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

+ 2 - 2
Source/cmQtAutoGenerators.cxx

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

+ 287 - 34
Source/cmTarget.cxx

@@ -159,10 +159,13 @@ public:
                                 CachedLinkInterfaceCompileOptionsEntries;
   mutable std::map<std::string, std::vector<TargetPropertyEntry*> >
                                 CachedLinkInterfaceCompileDefinitionsEntries;
+  mutable std::map<std::string, std::vector<TargetPropertyEntry*> >
+                                CachedLinkInterfaceSourcesEntries;
 
   mutable std::map<std::string, bool> CacheLinkInterfaceIncludeDirectoriesDone;
   mutable std::map<std::string, bool> CacheLinkInterfaceCompileDefinitionsDone;
   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->CachedLinkInterfaceCompileOptionsEntries);
   deleteAndClear(this->CachedLinkInterfaceCompileDefinitionsEntries);
+  deleteAndClear(this->CachedLinkInterfaceSourcesEntries);
 }
 
 //----------------------------------------------------------------------------
@@ -220,6 +224,7 @@ cmTarget::cmTarget()
   this->DebugIncludesDone = false;
   this->DebugCompileOptionsDone = 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;
-  this->GetSourceFiles(srcs);
+  this->GetSourceFiles(srcs, config, head);
 
   std::set<cmSourceFile*> emitted;
 
@@ -1487,6 +1698,25 @@ void cmTarget::SetProperty(const std::string& prop, const char* value)
     this->Internal->LinkImplementationPropertyEntries.push_back(entry);
     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->MaybeInvalidatePropertyCache(prop);
 }
@@ -1554,6 +1784,25 @@ void cmTarget::AppendProperty(const std::string& prop, const char* value,
     this->Internal->LinkImplementationPropertyEntries.push_back(entry);
     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->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;
-  this->GetSourceFiles(sourceFiles);
+  this->GetSourceFiles(sourceFiles, config, head);
   for(std::vector<cmSourceFile*>::const_iterator
         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()
                                 ->GetGlobalGenerator()
                                 ->GetGeneratorTarget(this);
-    gt->GetExternalObjects(externalObjects);
+    gt->GetExternalObjects(externalObjects, config);
     for(std::vector<cmSourceFile const*>::const_iterator
           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
       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.
     LinkImplementation impl;
     this->ComputeLinkImplementation(config, impl, head);
-    this->ComputeLinkImplementationLanguages(impl);
+    this->ComputeLinkImplementationLanguages(config, impl, head);
 
     // Store the information for this configuration.
     cmTargetInternals::LinkImplMapType::value_type entry(key, impl);
@@ -5999,7 +6250,7 @@ cmTarget::GetLinkImplementation(const std::string& config,
     }
   else if (i->second.Languages.empty())
     {
-    this->ComputeLinkImplementationLanguages(i->second);
+    this->ComputeLinkImplementationLanguages(config, i->second, head);
     }
 
   return &i->second;
@@ -6112,12 +6363,14 @@ void cmTarget::ComputeLinkImplementation(const std::string& config,
 
 //----------------------------------------------------------------------------
 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.
   std::set<std::string> languages;
   // Get languages used in our source files.
-  this->GetLanguages(languages);
+  this->GetLanguages(languages, config, head);
   // Copy the set of langauges to the link implementation.
   for(std::set<std::string>::iterator li = languages.begin();
       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
    */
-  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.
@@ -465,7 +470,9 @@ public:
   // when source file properties are changed and we do not have enough
   // information to forward these property changes to the targets
   // until we have per-target object file properties.
-  void GetLanguages(std::set<std::string>& languages) const;
+  void GetLanguages(std::set<std::string>& languages,
+                    std::string const& config,
+                    cmTarget const* head = 0) const;
 
   /** Return whether this target is an executable with symbol exports
       enabled.  */
@@ -703,6 +710,7 @@ private:
   mutable std::map<std::string, bool> DebugCompatiblePropertiesDone;
   mutable bool DebugCompileOptionsDone;
   mutable bool DebugCompileDefinitionsDone;
+  mutable bool DebugSourcesDone;
   mutable std::set<std::string> LinkImplicitNullProperties;
   bool BuildInterfaceIncludesAppended;
 
@@ -738,7 +746,9 @@ private:
   void ComputeLinkImplementation(const std::string& config,
                                  LinkImplementation& impl,
                                  cmTarget const* head) const;
-  void ComputeLinkImplementationLanguages(LinkImplementation& impl) const;
+  void ComputeLinkImplementationLanguages(const std::string& config,
+                                          LinkImplementation& impl,
+                                          cmTarget const* head) const;
   void ComputeLinkClosure(const std::string& config, LinkClosure& lc,
                           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()
 {
   std::vector<cmSourceFile const*> resxObjs;
-    this->GeneratorTarget->GetResxSources(resxObjs);
+    this->GeneratorTarget->GetResxSources(resxObjs, "");
   if(!resxObjs.empty())
     {
     this->WriteString("<ItemGroup>\n", 1);
@@ -553,7 +553,7 @@ void cmVisualStudio10TargetGenerator::WriteCustomCommands()
 {
   this->SourcesVisited.clear();
   std::vector<cmSourceFile const*> customCommands;
-  this->GeneratorTarget->GetCustomCommands(customCommands);
+  this->GeneratorTarget->GetCustomCommands(customCommands, "");
   for(std::vector<cmSourceFile const*>::const_iterator
         si = customCommands.begin();
       si != customCommands.end(); ++si)
@@ -704,7 +704,10 @@ void cmVisualStudio10TargetGenerator::WriteGroups()
   std::vector<cmSourceGroup> sourceGroups =
     this->Makefile->GetSourceGroups();
   std::vector<cmSourceFile*> classes;
-  this->Target->GetSourceFiles(classes);
+  if (!this->Target->GetConfigCommonSourceFiles(classes))
+    {
+    return;
+    }
 
   std::set<cmSourceGroup*> groupsUsed;
   for(std::vector<cmSourceFile*>::const_iterator s = classes.begin();
@@ -749,7 +752,7 @@ void cmVisualStudio10TargetGenerator::WriteGroups()
     }
 
   std::vector<cmSourceFile const*> resxObjs;
-    this->GeneratorTarget->GetResxSources(resxObjs);
+    this->GeneratorTarget->GetResxSources(resxObjs, "");
   if(!resxObjs.empty())
     {
     this->WriteString("<ItemGroup>\n", 1);
@@ -768,7 +771,7 @@ void cmVisualStudio10TargetGenerator::WriteGroups()
 
   // Add object library contents as external objects.
   std::vector<std::string> objs;
-  this->GeneratorTarget->UseObjectLibraries(objs);
+  this->GeneratorTarget->UseObjectLibraries(objs, "");
   if(!objs.empty())
     {
     this->WriteString("<ItemGroup>\n", 1);
@@ -1005,14 +1008,14 @@ void cmVisualStudio10TargetGenerator::WriteAllSources()
   this->WriteString("<ItemGroup>\n", 1);
 
   std::vector<cmSourceFile const*> headerSources;
-  this->GeneratorTarget->GetHeaderSources(headerSources);
+  this->GeneratorTarget->GetHeaderSources(headerSources, "");
   this->WriteSources("ClInclude", headerSources);
   std::vector<cmSourceFile const*> idlSources;
-  this->GeneratorTarget->GetIDLSources(idlSources);
+  this->GeneratorTarget->GetIDLSources(idlSources, "");
   this->WriteSources("Midl", idlSources);
 
   std::vector<cmSourceFile const*> objectSources;
-  this->GeneratorTarget->GetObjectSources(objectSources);
+  this->GeneratorTarget->GetObjectSources(objectSources, "");
   for(std::vector<cmSourceFile const*>::const_iterator
         si = objectSources.begin();
       si != objectSources.end(); ++si)
@@ -1053,7 +1056,7 @@ void cmVisualStudio10TargetGenerator::WriteAllSources()
     }
 
   std::vector<cmSourceFile const*> externalObjects;
-  this->GeneratorTarget->GetExternalObjects(externalObjects);
+  this->GeneratorTarget->GetExternalObjects(externalObjects, "");
   for(std::vector<cmSourceFile const*>::iterator
         si = externalObjects.begin();
       si != externalObjects.end(); )
@@ -1088,12 +1091,12 @@ void cmVisualStudio10TargetGenerator::WriteAllSources()
     }
 
   std::vector<cmSourceFile const*> extraSources;
-  this->GeneratorTarget->GetExtraSources(extraSources);
+  this->GeneratorTarget->GetExtraSources(extraSources, "");
   this->WriteSources("None", extraSources);
 
   // Add object library contents as external objects.
   std::vector<std::string> objs;
-  this->GeneratorTarget->UseObjectLibraries(objs);
+  this->GeneratorTarget->UseObjectLibraries(objs, "");
   for(std::vector<std::string>::const_iterator
         oi = objs.begin(); oi != objs.end(); ++oi)
     {
@@ -1694,7 +1697,7 @@ cmVisualStudio10TargetGenerator::ComputeLinkOptions(std::string const& config)
   linkOptions.AddFlag("ImportLibrary", imLib.c_str());
   linkOptions.AddFlag("ProgramDataBaseFile", pdb.c_str());
   linkOptions.Parse(flags.c_str());
-  std::string def = this->GeneratorTarget->GetModuleDefinitionFile();
+  std::string def = this->GeneratorTarget->GetModuleDefinitionFile("");
   if(!def.empty())
     {
     linkOptions.AddFlag("ModuleDefinitionFile", def.c_str());
@@ -1924,7 +1927,7 @@ bool cmVisualStudio10TargetGenerator::
   IsResxHeader(const std::string& headerFile)
 {
   std::set<std::string> expectedResxHeaders;
-  this->GeneratorTarget->GetExpectedResxHeaders(expectedResxHeaders);
+  this->GeneratorTarget->GetExpectedResxHeaders(expectedResxHeaders, "");
 
   std::set<std::string>::const_iterator it =
                                         expectedResxHeaders.find(headerFile);

+ 5 - 0
Tests/CMakeLists.txt

@@ -278,6 +278,11 @@ if(BUILD_TESTING)
   ADD_TEST_MACRO(AliasTarget AliasTarget)
   ADD_TEST_MACRO(StagingPrefix StagingPrefix)
   ADD_TEST_MACRO(InterfaceLibrary InterfaceLibrary)
+  if (CMAKE_BUILD_TYPE MATCHES "[Dd][Ee][Bb][Uu][Gg]")
+    set(ConfigSources_BUILD_OPTIONS -DCMAKE_BUILD_TYPE=Debug)
+    ADD_TEST_MACRO(ConfigSources ConfigSources)
+  endif()
+  ADD_TEST_MACRO(SourcesProperty SourcesProperty)
   set_tests_properties(EmptyLibrary PROPERTIES
     PASS_REGULAR_EXPRESSION "CMake Error: CMake can not determine linker language for target: test")
   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"
 )
 
+message("CMAKE_BUILD_TYPE = ${CMAKE_BUILD_TYPE}")
+if (CMAKE_BUILD_TYPE MATCHES "[Dd][Ee][Bb][Uu][Gg]" AND NOT CMAKE_CONFIGURATION_TYPES)
+  set(debug_srcs "$<$<CONFIG:Debug>:debug_class.cpp>" $<$<CONFIG:Debug>:debug_resource.qrc>)
+  add_definitions(-DTEST_DEBUG_CLASS)
+endif()
+
 add_executable(QtAutogen main.cpp calwidget.cpp second_widget.cpp foo.cpp blub.cpp bar.cpp abc.cpp
                xyz.cpp yaf.cpp gadget.cpp $<TARGET_OBJECTS:privateSlot>
-               test.qrc second_resource.qrc resourcetester.cpp generated.cpp
+               test.qrc second_resource.qrc resourcetester.cpp generated.cpp ${debug_srcs}
 )
 set_property(TARGET QtAutogen APPEND PROPERTY AUTOGEN_TARGET_DEPENDS generate_moc_input "${CMAKE_CURRENT_BINARY_DIR}/myotherinterface.h")
 

+ 9 - 0
Tests/QtAutogen/debug_class.cpp

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

+ 20 - 0
Tests/QtAutogen/debug_class.h

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

+ 45 - 0
Tests/QtAutogen/debug_class.ui

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

+ 5 - 0
Tests/QtAutogen/debug_resource.qrc

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

+ 9 - 0
Tests/QtAutogen/main.cpp

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

+ 4 - 0
Tests/QtAutogen/resourcetester.cpp

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

+ 1 - 0
Tests/RunCMake/CMakeLists.txt

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

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

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

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

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

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

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

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

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

+ 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;
+}