[Cmake-commits] CMake branch, next, updated. v3.0.0-rc2-1236-g669eeb4

Stephen Kelly steveire at gmail.com
Thu Mar 20 04:36:18 EDT 2014


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "CMake".

The branch, next has been updated
       via  669eeb4f20a079ce58faed45c4f52e3f5044a326 (commit)
       via  e4b1e59652eedd094cbe65a4732e6f13a0a839f4 (commit)
       via  c997d2fbba6bdc0edfc597aa4c631e3c8219420c (commit)
       via  e38aa4a1fb0c2e628baaa132c82187277b8bdd57 (commit)
       via  ff0f40ad2df3a0550df7a5f5f566235ba68f9de4 (commit)
       via  5c394361a4b20bf768864019c7176041d75849b3 (commit)
       via  2ce3f6535d9f508fa7f14d5a3f5e758bd8672802 (commit)
       via  22ad0fcf12be2d3d5fdbfa9b41cd5aaabcc2729c (commit)
       via  28dbb98a2fc027a94e037899880481040aeb9eb0 (commit)
       via  5586cdd40cd2fe69fa84161da933cbb2d24e90e1 (commit)
       via  3a7e6948adefc303af6df4a9e886efcda2edb0b8 (commit)
       via  80dea9685cd976caeaa8b1af254a1726a7be0675 (commit)
       via  fed93ec353e901ad638d74bad4a8d5f45a770dc2 (commit)
       via  cee09f9f241c30aca13094ea6d9468ec21924acf (commit)
       via  44e4ccd7af4fe3771f1fa8688c71bf6c27ae2ec6 (commit)
       via  9e559cf591396511fbc38d2bbdebf6b70126c80a (commit)
       via  bdcc3f1e0ec02bdeed38e0cb6fa8682104f0d946 (commit)
       via  96e6f5cbc0511444cd3afce9301907284b4664b2 (commit)
      from  a48654dd5a588c9dfa196f1282c41fa6d4d99653 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=669eeb4f20a079ce58faed45c4f52e3f5044a326
commit 669eeb4f20a079ce58faed45c4f52e3f5044a326
Merge: a48654d e4b1e59
Author:     Stephen Kelly <steveire at gmail.com>
AuthorDate: Thu Mar 20 04:36:14 2014 -0400
Commit:     CMake Topic Stage <kwrobot at kitware.com>
CommitDate: Thu Mar 20 04:36:14 2014 -0400

    Merge topic 'target-sources-refactor' into next
    
    e4b1e596 cmGeneratorTarget: Compute target objects on demand
    c997d2fb cmTarget: Compute languages from object libraries on demand.
    e38aa4a1 cmGeneratorTarget: Compute consumed object libraries on demand.
    ff0f40ad cmComputeTargetDepends: Track object library depends.
    5c394361 cmTarget: Allow any generator expression in SOURCES property.
    2ce3f653 cmTarget: Include TARGET_OBJECTS genex in target SOURCES property.
    22ad0fcf cmGlobalGenerator: Add interface to call ForceLinkerLanguages
    28dbb98a cmStringCommand: Add GENEX_STRIP subcommand.
    5586cdd4 Genex: Evaluate TARGET_OBJECTS as a normal expression.
    3a7e6948 cmTarget: Store strings instead of cmSourceFile* to represent SOURCES.
    80dea968 cmTarget: Remove AddSourceFile method
    fed93ec3 cmTarget: Use string API to add sources to cmTarget objects.
    cee09f9f cmTarget: Add a method to obtain list of filenames for sources.
    44e4ccd7 cmSourceFileLocation: Make copyable and assignable.
    9e559cf5 cmTarget: Rename AddSource method for backward compatibility.
    bdcc3f1e cmTarget: Use GetSourceFiles for languages.
    ...


http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=e4b1e59652eedd094cbe65a4732e6f13a0a839f4
commit e4b1e59652eedd094cbe65a4732e6f13a0a839f4
Author:     Stephen Kelly <steveire at gmail.com>
AuthorDate: Fri Mar 14 13:21:26 2014 +0100
Commit:     Stephen Kelly <steveire at gmail.com>
CommitDate: Wed Mar 19 17:28:26 2014 +0100

    cmGeneratorTarget: Compute target objects on demand
    
    Add a ComputeObjectMapping method to compute the object
    names.  It takes mapping to populate as an out-parameter so
    that it can be extended in the future with parameters
    relevant to generator expression evaluation.
    
    Remove the supporting cmGeneratorTarget::AddObject method. It is
    no longer needed as the container member is populated directly.
    
    The ComputeObjectMapping method is called whenever objects are
    requested from the cmGeneratorTarget.  Because the Xcode generator
    makes no such request, explicitly invoke the method from that
    generator so that the logic of checking for bad sources in object
    libraries is executed.
    
    In a follow-up, the UseObjectLibraries usage may be replaced by a
    true generator expression evaluator for TARGET_OBJECTS. That
    will require generators to use cmGeneratorTarget::GetExternalObjects
    which is not currently the case for Xcode and VS generators.

diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx
index 92a3ce7..31efb20 100644
--- a/Source/cmGeneratorTarget.cxx
+++ b/Source/cmGeneratorTarget.cxx
@@ -310,18 +310,36 @@ cmGeneratorTarget
 ::GetObjectSources(std::vector<cmSourceFile const*> &data) const
 {
   IMPLEMENT_VISIT(ObjectSources);
+
+  if (!this->Objects.empty())
+    {
+    return;
+    }
+
+  for(std::vector<cmSourceFile const*>::const_iterator it = data.begin();
+      it != data.end(); ++it)
+    {
+    this->Objects[*it];
+    }
+
+  this->LocalGenerator->ComputeObjectFilenames(this->Objects, this);
 }
 
-//----------------------------------------------------------------------------
-const std::string& cmGeneratorTarget::GetObjectName(cmSourceFile const* file)
+void cmGeneratorTarget::ComputeObjectMapping()
 {
-  return this->Objects[file];
+  if(!this->Objects.empty())
+    {
+    return;
+    }
+  std::vector<cmSourceFile const*> sourceFiles;
+  this->GetObjectSources(sourceFiles);
 }
 
-void cmGeneratorTarget::AddObject(cmSourceFile const* sf,
-                                  std::string const&name)
+//----------------------------------------------------------------------------
+const std::string& cmGeneratorTarget::GetObjectName(cmSourceFile const* file)
 {
-    this->Objects[sf] = name;
+  this->ComputeObjectMapping();
+  return this->Objects[file];
 }
 
 //----------------------------------------------------------------------------
@@ -333,6 +351,7 @@ void cmGeneratorTarget::AddExplicitObjectName(cmSourceFile const* sf)
 //----------------------------------------------------------------------------
 bool cmGeneratorTarget::HasExplicitObjectName(cmSourceFile const* file) const
 {
+  const_cast<cmGeneratorTarget*>(this)->ComputeObjectMapping();
   std::set<cmSourceFile const*>::const_iterator it
                                         = this->ExplicitObjectName.find(file);
   return it != this->ExplicitObjectName.end();
diff --git a/Source/cmGeneratorTarget.h b/Source/cmGeneratorTarget.h
index cb59783..38e6510 100644
--- a/Source/cmGeneratorTarget.h
+++ b/Source/cmGeneratorTarget.h
@@ -35,7 +35,6 @@ public:
   void GetObjectSources(std::vector<cmSourceFile const*> &) const;
   const std::string& GetObjectName(cmSourceFile const* file);
 
-  void AddObject(cmSourceFile const* sf, std::string const&name);
   bool HasExplicitObjectName(cmSourceFile const* file) const;
   void AddExplicitObjectName(cmSourceFile const* sf);
 
@@ -47,6 +46,8 @@ public:
   void GetCustomCommands(std::vector<cmSourceFile const*>&) const;
   void GetExpectedResxHeaders(std::set<std::string>&) const;
 
+  void ComputeObjectMapping();
+
   cmTarget* Target;
   cmMakefile* Makefile;
   cmLocalGenerator* LocalGenerator;
@@ -123,7 +124,7 @@ private:
   typedef std::map<cmSourceFile const*, SourceEntry> SourceEntriesType;
   SourceEntriesType SourceEntries;
 
-  std::map<cmSourceFile const*, std::string> Objects;
+  mutable std::map<cmSourceFile const*, std::string> Objects;
   std::set<cmSourceFile const*> ExplicitObjectName;
   mutable std::map<std::string, std::vector<std::string> > SystemIncludesCache;
 
diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx
index 6caaee3..66ccf39 100644
--- a/Source/cmGlobalGenerator.cxx
+++ b/Source/cmGlobalGenerator.cxx
@@ -1222,8 +1222,6 @@ void cmGlobalGenerator::Generate()
     this->LocalGenerators[i]->GenerateTargetManifest();
     }
 
-  this->ComputeGeneratorTargetObjects();
-
   this->ProcessEvaluationFiles();
 
   // Compute the inter-target dependencies.
@@ -1440,27 +1438,6 @@ void cmGlobalGenerator::CreateGeneratorTargets()
     }
 }
 
-//----------------------------------------------------------------------------
-void cmGlobalGenerator::ComputeGeneratorTargetObjects()
-{
-  // Construct per-target generator information.
-  for(unsigned int i=0; i < this->LocalGenerators.size(); ++i)
-    {
-    cmMakefile *mf = this->LocalGenerators[i]->GetMakefile();
-    cmGeneratorTargetsType targets = mf->GetGeneratorTargets();
-    for(cmGeneratorTargetsType::iterator ti = targets.begin();
-        ti != targets.end(); ++ti)
-      {
-      if (ti->second->Target->IsImported()
-          || ti->second->Target->GetType() == cmTarget::INTERFACE_LIBRARY)
-        {
-        continue;
-        }
-      cmGeneratorTarget* gt = ti->second;
-      this->ComputeTargetObjects(gt);
-      }
-    }
-}
 
 //----------------------------------------------------------------------------
 void cmGlobalGenerator::ClearGeneratorMembers()
@@ -1522,29 +1499,6 @@ cmGlobalGenerator::GetGeneratorTarget(cmTarget const* t) const
 }
 
 //----------------------------------------------------------------------------
-void cmGlobalGenerator::ComputeTargetObjects(cmGeneratorTarget* gt) const
-{
-  std::vector<cmSourceFile const*> objectSources;
-  gt->GetObjectSources(objectSources);
-
-  std::map<cmSourceFile const*, std::string> mapping;
-  for(std::vector<cmSourceFile const*>::const_iterator it
-      = objectSources.begin(); it != objectSources.end(); ++it)
-    {
-    mapping[*it];
-    }
-
-  gt->LocalGenerator->ComputeObjectFilenames(mapping, gt);
-
-  for(std::map<cmSourceFile const*, std::string>::const_iterator it
-      = mapping.begin(); it != mapping.end(); ++it)
-    {
-    assert(!it->second.empty());
-    gt->AddObject(it->first, it->second);
-    }
-}
-
-//----------------------------------------------------------------------------
 void cmGlobalGenerator::ComputeTargetObjectDirectory(cmGeneratorTarget*) const
 {
 }
diff --git a/Source/cmGlobalGenerator.h b/Source/cmGlobalGenerator.h
index 668bb6b..54f5f3b 100644
--- a/Source/cmGlobalGenerator.h
+++ b/Source/cmGlobalGenerator.h
@@ -444,8 +444,6 @@ private:
   friend class cmake;
   void CreateGeneratorTargets(cmMakefile* mf);
   void CreateGeneratorTargets();
-  void ComputeGeneratorTargetObjects();
-  void ComputeTargetObjects(cmGeneratorTarget* gt) const;
 
   void ClearGeneratorMembers();
 
diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx
index 2a6e522..d9d4927 100644
--- a/Source/cmGlobalXCodeGenerator.cxx
+++ b/Source/cmGlobalXCodeGenerator.cxx
@@ -987,6 +987,8 @@ cmGlobalXCodeGenerator::CreateXCodeTargets(cmLocalGenerator* gen,
     cmtarget.GetSourceFiles(classes);
     std::sort(classes.begin(), classes.end(), cmSourceFilePathCompare());
 
+    gtgt->ComputeObjectMapping();
+
     std::vector<cmXCodeObject*> externalObjFiles;
     std::vector<cmXCodeObject*> headerFiles;
     std::vector<cmXCodeObject*> resourceFiles;

http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=c997d2fbba6bdc0edfc597aa4c631e3c8219420c
commit c997d2fbba6bdc0edfc597aa4c631e3c8219420c
Author:     Stephen Kelly <steveire at gmail.com>
AuthorDate: Tue Mar 18 19:23:45 2014 +0100
Commit:     Stephen Kelly <steveire at gmail.com>
CommitDate: Wed Mar 19 17:28:26 2014 +0100

    cmTarget: Compute languages from object libraries on demand.

diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index aea6446..61260be 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -608,13 +608,6 @@ void cmTarget::AddSources(std::vector<std::string> const& srcs)
     if(src[0] == '$' && src[1] == '<')
       {
       this->AddSource(src);
-
-      if(cmHasLiteralPrefix(i->c_str(), "$<TARGET_OBJECTS:") &&
-         (*i)[i->size()-1] == '>')
-        {
-        std::string objLibName = i->substr(17, i->size()-18);
-        this->ObjectLibraries.push_back(objLibName);
-        }
       }
     else
       {
@@ -5013,6 +5006,53 @@ void cmTarget::GetLanguages(std::set<std::string>& languages) const
       languages.insert(lang);
       }
     }
+
+  std::vector<cmTarget*> objectLibraries;
+  std::vector<cmSourceFile const*> externalObjects;
+  if (this->Makefile->GetGeneratorTargets().empty())
+    {
+    // At configure-time, this method can be called as part of getting the
+    // LOCATION property or to export() a file to be include()d.  However
+    // there is no cmGeneratorTarget at configure-time, so search the SOURCES
+    // for TARGET_OBJECTS instead for backwards compatibility with OLD
+    // behavior of CMP0024 and CMP0026 only.
+    std::vector<std::string> srcs;
+    cmSystemTools::ExpandListArgument(this->GetProperty("SOURCES"), srcs);
+    for(std::vector<std::string>::const_iterator it = srcs.begin();
+        it != srcs.end(); ++it)
+      {
+      if (cmHasLiteralPrefix(*it, "$<TARGET_OBJECTS:")
+          && cmHasLiteralSuffix(*it, ">"))
+        {
+        std::string objLibName = it->substr(17, it->size()-18);
+        if (cmTarget* tgt = this->Makefile->FindTargetToUse(objLibName))
+          {
+          objectLibraries.push_back(tgt);
+          }
+        }
+      }
+    }
+  else
+    {
+    cmGeneratorTarget* gt = this->Makefile->GetLocalGenerator()
+                                ->GetGlobalGenerator()
+                                ->GetGeneratorTarget(this);
+    gt->GetExternalObjects(externalObjects);
+    for(std::vector<cmSourceFile const*>::const_iterator
+          i = externalObjects.begin(); i != externalObjects.end(); ++i)
+      {
+      std::string objLib = (*i)->GetObjectLibrary();
+      if (cmTarget* tgt = this->Makefile->FindTargetToUse(objLib))
+        {
+        objectLibraries.push_back(tgt);
+        }
+      }
+    }
+  for(std::vector<cmTarget*>::const_iterator
+      i = objectLibraries.begin(); i != objectLibraries.end(); ++i)
+    {
+    (*i)->GetLanguages(languages);
+    }
 }
 
 //----------------------------------------------------------------------------
@@ -6077,19 +6117,6 @@ cmTarget::ComputeLinkImplementationLanguages(LinkImplementation& impl) const
   std::set<std::string> languages;
   // Get languages used in our source files.
   this->GetLanguages(languages);
-  // Get languages used in object library sources.
-  for(std::vector<std::string>::const_iterator
-      i = this->ObjectLibraries.begin();
-      i != this->ObjectLibraries.end(); ++i)
-    {
-    if(cmTarget* objLib = this->Makefile->FindTargetToUse(*i))
-      {
-      if(objLib->GetType() == cmTarget::OBJECT_LIBRARY)
-        {
-        objLib->GetLanguages(languages);
-        }
-      }
-    }
   // Copy the set of langauges to the link implementation.
   for(std::set<std::string>::iterator li = languages.begin();
       li != languages.end(); ++li)
diff --git a/Source/cmTarget.h b/Source/cmTarget.h
index 45fca53..fcbff93 100644
--- a/Source/cmTarget.h
+++ b/Source/cmTarget.h
@@ -137,10 +137,6 @@ public:
    */
   void GetSourceFiles(std::vector<std::string> &files) const;
   void GetSourceFiles(std::vector<cmSourceFile*> &files) const;
-  std::vector<std::string> const& GetObjectLibraries() const
-    {
-    return this->ObjectLibraries;
-    }
 
   /**
    * Add sources to the target.
@@ -686,7 +682,6 @@ private:
   std::vector<cmCustomCommand> PreLinkCommands;
   std::vector<cmCustomCommand> PostBuildCommands;
   TargetType TargetTypeValue;
-  std::vector<std::string> ObjectLibraries;
   LinkLibraryVectorType LinkLibraries;
   LinkLibraryVectorType PrevLinkedLibraries;
   bool LinkLibrariesAnalyzed;

http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=e38aa4a1fb0c2e628baaa132c82187277b8bdd57
commit e38aa4a1fb0c2e628baaa132c82187277b8bdd57
Author:     Stephen Kelly <steveire at gmail.com>
AuthorDate: Tue Mar 18 17:07:56 2014 +0100
Commit:     Stephen Kelly <steveire at gmail.com>
CommitDate: Wed Mar 19 17:28:26 2014 +0100

    cmGeneratorTarget: Compute consumed object libraries on demand.
    
    Remove up-front object library computation from cmGlobalGenerator.
    
    Adjust tests for message coming from the generator expression
    evaluation.

diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx
index fe70473..92a3ce7 100644
--- a/Source/cmGeneratorTarget.cxx
+++ b/Source/cmGeneratorTarget.cxx
@@ -503,57 +503,6 @@ void cmGeneratorTarget::GetSourceFiles(std::vector<cmSourceFile*> &files) const
 }
 
 //----------------------------------------------------------------------------
-void cmGeneratorTarget::LookupObjectLibraries()
-{
-  std::vector<std::string> const& objLibs =
-    this->Target->GetObjectLibraries();
-  for(std::vector<std::string>::const_iterator oli = objLibs.begin();
-      oli != objLibs.end(); ++oli)
-    {
-    std::string const& objLibName = *oli;
-    if(cmTarget* objLib = this->Makefile->FindTargetToUse(objLibName))
-      {
-      if(objLib->GetType() == cmTarget::OBJECT_LIBRARY)
-        {
-        if(this->Target->GetType() != cmTarget::EXECUTABLE &&
-           this->Target->GetType() != cmTarget::STATIC_LIBRARY &&
-           this->Target->GetType() != cmTarget::SHARED_LIBRARY &&
-           this->Target->GetType() != cmTarget::MODULE_LIBRARY)
-          {
-          this->GlobalGenerator->GetCMakeInstance()
-            ->IssueMessage(cmake::FATAL_ERROR,
-                           "Only executables and non-OBJECT libraries may "
-                           "reference target objects.",
-                           this->Target->GetBacktrace());
-          return;
-          }
-        this->ObjectLibraries.push_back(objLib);
-        }
-      else
-        {
-        cmOStringStream e;
-        e << "Objects of target \"" << objLibName
-          << "\" referenced but is not an OBJECT library.";
-        this->GlobalGenerator->GetCMakeInstance()
-          ->IssueMessage(cmake::FATAL_ERROR, e.str(),
-                         this->Target->GetBacktrace());
-        return;
-        }
-      }
-    else
-      {
-      cmOStringStream e;
-      e << "Objects of target \"" << objLibName
-        << "\" referenced but no such target exists.";
-      this->GlobalGenerator->GetCMakeInstance()
-        ->IssueMessage(cmake::FATAL_ERROR, e.str(),
-                       this->Target->GetBacktrace());
-      return;
-      }
-    }
-}
-
-//----------------------------------------------------------------------------
 std::string cmGeneratorTarget::GetModuleDefinitionFile() const
 {
   std::string data;
@@ -565,9 +514,26 @@ std::string cmGeneratorTarget::GetModuleDefinitionFile() const
 void
 cmGeneratorTarget::UseObjectLibraries(std::vector<std::string>& objs) const
 {
+  std::vector<cmSourceFile const*> objectFiles;
+  this->GetExternalObjects(objectFiles);
+  std::vector<cmTarget*> objectLibraries;
+  std::set<cmTarget*> emitted;
+  for(std::vector<cmSourceFile const*>::const_iterator
+      it = objectFiles.begin(); it != objectFiles.end(); ++it)
+    {
+    std::string objLib = (*it)->GetObjectLibrary();
+    if (cmTarget* tgt = this->Makefile->FindTargetToUse(objLib))
+      {
+      if (emitted.insert(tgt).second)
+        {
+        objectLibraries.push_back(tgt);
+        }
+      }
+    }
+
   for(std::vector<cmTarget*>::const_iterator
-        ti = this->ObjectLibraries.begin();
-      ti != this->ObjectLibraries.end(); ++ti)
+        ti = objectLibraries.begin();
+      ti != objectLibraries.end(); ++ti)
     {
     cmTarget* objLib = *ti;
     cmGeneratorTarget* ogt =
diff --git a/Source/cmGeneratorTarget.h b/Source/cmGeneratorTarget.h
index 53e27c5..cb59783 100644
--- a/Source/cmGeneratorTarget.h
+++ b/Source/cmGeneratorTarget.h
@@ -84,8 +84,6 @@ public:
    */
   void TraceDependencies();
 
-  void LookupObjectLibraries();
-
   /** Get sources that must be built before the given source.  */
   std::vector<cmSourceFile*> const*
   GetSourceDepends(cmSourceFile const* sf) const;
@@ -127,7 +125,6 @@ private:
 
   std::map<cmSourceFile const*, std::string> Objects;
   std::set<cmSourceFile const*> ExplicitObjectName;
-  std::vector<cmTarget*> ObjectLibraries;
   mutable std::map<std::string, std::vector<std::string> > SystemIncludesCache;
 
   void ConstructSourceFileFlags() const;
diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx
index 2f3c6c9..6caaee3 100644
--- a/Source/cmGlobalGenerator.cxx
+++ b/Source/cmGlobalGenerator.cxx
@@ -1457,7 +1457,6 @@ void cmGlobalGenerator::ComputeGeneratorTargetObjects()
         continue;
         }
       cmGeneratorTarget* gt = ti->second;
-      gt->LookupObjectLibraries();
       this->ComputeTargetObjects(gt);
       }
     }
diff --git a/Tests/RunCMake/ObjectLibrary/BadSourceExpression2-stderr.txt b/Tests/RunCMake/ObjectLibrary/BadSourceExpression2-stderr.txt
index f1fcbe8..7060c61 100644
--- a/Tests/RunCMake/ObjectLibrary/BadSourceExpression2-stderr.txt
+++ b/Tests/RunCMake/ObjectLibrary/BadSourceExpression2-stderr.txt
@@ -1,4 +1,8 @@
 CMake Error at BadSourceExpression2.cmake:1 \(add_library\):
+  Error evaluating generator expression:
+
+    \$<TARGET_OBJECTS:DoesNotExist>
+
   Objects of target "DoesNotExist" referenced but no such target exists.
 Call Stack \(most recent call first\):
   CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/ObjectLibrary/BadSourceExpression3-stderr.txt b/Tests/RunCMake/ObjectLibrary/BadSourceExpression3-stderr.txt
index ad14a35..838b3d8 100644
--- a/Tests/RunCMake/ObjectLibrary/BadSourceExpression3-stderr.txt
+++ b/Tests/RunCMake/ObjectLibrary/BadSourceExpression3-stderr.txt
@@ -1,4 +1,8 @@
 CMake Error at BadSourceExpression3.cmake:2 \(add_library\):
+  Error evaluating generator expression:
+
+    \$<TARGET_OBJECTS:NotObjLib>
+
   Objects of target "NotObjLib" referenced but is not an OBJECT library.
 Call Stack \(most recent call first\):
   CMakeLists.txt:3 \(include\)

http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=ff0f40ad2df3a0550df7a5f5f566235ba68f9de4
commit ff0f40ad2df3a0550df7a5f5f566235ba68f9de4
Author:     Stephen Kelly <steveire at gmail.com>
AuthorDate: Tue Mar 18 17:04:46 2014 +0100
Commit:     Stephen Kelly <steveire at gmail.com>
CommitDate: Wed Mar 19 17:28:25 2014 +0100

    cmComputeTargetDepends: Track object library depends.
    
    Relieve cmGeneratorTarget of that responsibility.

diff --git a/Source/cmComputeTargetDepends.cxx b/Source/cmComputeTargetDepends.cxx
index b4dbce7..723988b 100644
--- a/Source/cmComputeTargetDepends.cxx
+++ b/Source/cmComputeTargetDepends.cxx
@@ -16,6 +16,7 @@
 #include "cmLocalGenerator.h"
 #include "cmMakefile.h"
 #include "cmSystemTools.h"
+#include "cmSourceFile.h"
 #include "cmTarget.h"
 #include "cmake.h"
 
@@ -213,6 +214,34 @@ void cmComputeTargetDepends::CollectTargetDepends(int depender_index)
   {
   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 (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.
diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx
index 8984874..fe70473 100644
--- a/Source/cmGeneratorTarget.cxx
+++ b/Source/cmGeneratorTarget.cxx
@@ -527,7 +527,6 @@ void cmGeneratorTarget::LookupObjectLibraries()
                            this->Target->GetBacktrace());
           return;
           }
-        this->Target->AddUtility(objLib->GetName());
         this->ObjectLibraries.push_back(objLib);
         }
       else

http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=5c394361a4b20bf768864019c7176041d75849b3
commit 5c394361a4b20bf768864019c7176041d75849b3
Author:     Stephen Kelly <steveire at gmail.com>
AuthorDate: Tue Mar 18 16:40:46 2014 +0100
Commit:     Stephen Kelly <steveire at gmail.com>
CommitDate: Wed Mar 19 17:28:25 2014 +0100

    cmTarget: Allow any generator expression in SOURCES property.
    
    Remove use of UseObjectLibraries from Makefile and Ninja generators. It
    is not needed now because those generators use GetExternalObjects
    which already contains the objects from object libraries.
    
    The VS10 generator calls both the UseObjectLibraries and the GetExternalObjects
    methods. Ensure that duplicates are not created by skipping objects
    from object libraries in handling of GetExternalObjects.
    
    Similarly, fix Xcode object handling by skipping external objects from
    OBJECT_LIBRARY usage as appropriate.
    
    The error message in the BadSourceExpression1 test is now reported
    by the generator expression evaluator, so it has different text.

diff --git a/Help/command/add_executable.rst b/Help/command/add_executable.rst
index 231eeed..4ed10e1 100644
--- a/Help/command/add_executable.rst
+++ b/Help/command/add_executable.rst
@@ -35,8 +35,11 @@ If ``EXCLUDE_FROM_ALL`` is given the corresponding property will be set on
 the created target.  See documentation of the :prop_tgt:`EXCLUDE_FROM_ALL`
 target property for details.
 
-See the :manual:`cmake-buildsystem(7)` manual for more on defining
-buildsystem properties.
+Source arguments to ``add_executable`` 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.
+
 
 --------------------------------------------------------------------------
 
diff --git a/Help/command/add_library.rst b/Help/command/add_library.rst
index 0944269..e93ef53 100644
--- a/Help/command/add_library.rst
+++ b/Help/command/add_library.rst
@@ -39,8 +39,10 @@ If ``EXCLUDE_FROM_ALL`` is given the corresponding property will be set on
 the created target.  See documentation of the :prop_tgt:`EXCLUDE_FROM_ALL`
 target property for details.
 
-See the :manual:`cmake-buildsystem(7)` manual for more on defining buildsystem
-properties.
+Source arguments to ``add_library`` 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.
 
 --------------------------------------------------------------------------
 
diff --git a/Help/release/dev/target-SOURCES-genex.rst b/Help/release/dev/target-SOURCES-genex.rst
index 1ca6f66..9a65101 100644
--- a/Help/release/dev/target-SOURCES-genex.rst
+++ b/Help/release/dev/target-SOURCES-genex.rst
@@ -5,3 +5,8 @@ target-SOURCES-genex
   :manual:`generator expression <cmake-generator-expressions(7)>`
   such as ``TARGET_OBJECTS`` when read at configure time, if
   policy :policy:`CMP0051` is ``NEW``.
+
+* The :prop_tgt:`SOURCES` target property now generally supports
+  :manual:`generator expression <cmake-generator-expressions(7)>`.  The
+  generator expressions may be used in the :command:`add_library` and
+  :command:`add_executable` commands.
diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx
index fdf73d6..2a6e522 100644
--- a/Source/cmGlobalXCodeGenerator.cxx
+++ b/Source/cmGlobalXCodeGenerator.cxx
@@ -1007,7 +1007,10 @@ cmGlobalXCodeGenerator::CreateXCodeTargets(cmLocalGenerator* gen,
       if(filetype &&
          filetype->GetString() == "compiled.mach-o.objfile")
         {
-        externalObjFiles.push_back(xsf);
+        if ((*i)->GetObjectLibrary().empty())
+          {
+          externalObjFiles.push_back(xsf);
+          }
         }
       else if(this->IsHeaderFile(*i) ||
         (tsFlags.Type == cmGeneratorTarget::SourceFileTypePrivateHeader) ||
diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx
index 6759d05..c520f9e 100644
--- a/Source/cmMakefileTargetGenerator.cxx
+++ b/Source/cmMakefileTargetGenerator.cxx
@@ -202,9 +202,6 @@ void cmMakefileTargetGenerator::WriteTargetBuildRules()
     // Generate this object file's rule file.
     this->WriteObjectRuleFiles(**si);
     }
-
-  // Add object library contents as external objects.
-  this->GeneratorTarget->UseObjectLibraries(this->ExternalObjects);
 }
 
 //----------------------------------------------------------------------------
diff --git a/Source/cmNinjaTargetGenerator.cxx b/Source/cmNinjaTargetGenerator.cxx
index 4319f3c..ae3bff4 100644
--- a/Source/cmNinjaTargetGenerator.cxx
+++ b/Source/cmNinjaTargetGenerator.cxx
@@ -520,17 +520,6 @@ cmNinjaTargetGenerator
     this->ModuleDefinitionFile = this->ConvertToNinjaPath(def.c_str());
     }
 
-  {
-  // Add object library contents as external objects.
-  std::vector<std::string> objs;
-  this->GeneratorTarget->UseObjectLibraries(objs);
-  for(std::vector<std::string>::iterator oi = objs.begin();
-      oi != objs.end(); ++oi)
-    {
-    this->Objects.push_back(ConvertToNinjaPath(oi->c_str()));
-    }
-  }
-
   this->GetBuildFileStream() << "\n";
 }
 
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index 04ae5af..aea6446 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -551,15 +551,16 @@ void cmTarget::GetSourceFiles(std::vector<std::string> &files) const
       si != this->Internal->SourceEntries.end(); ++si)
     {
     std::vector<std::string> srcs;
-    cmSystemTools::ExpandListArgument((*si)->ge->GetInput(), srcs);
+    cmSystemTools::ExpandListArgument((*si)->ge->Evaluate(this->Makefile,
+                                        "",
+                                        false,
+                                        this),
+                                      srcs);
+
     for(std::vector<std::string>::const_iterator i = srcs.begin();
         i != srcs.end(); ++i)
       {
       std::string src = *i;
-      if (cmGeneratorExpression::Find(src) != std::string::npos)
-        {
-        continue;
-        }
       cmSourceFile* sf = this->Makefile->GetOrCreateSource(src);
       std::string e;
       src = sf->GetFullPath(&e);
@@ -606,7 +607,14 @@ void cmTarget::AddSources(std::vector<std::string> const& srcs)
     const char* src = i->c_str();
     if(src[0] == '$' && src[1] == '<')
       {
-      this->ProcessSourceExpression(*i);
+      this->AddSource(src);
+
+      if(cmHasLiteralPrefix(i->c_str(), "$<TARGET_OBJECTS:") &&
+         (*i)[i->size()-1] == '>')
+        {
+        std::string objLibName = i->substr(17, i->size()-18);
+        this->ObjectLibraries.push_back(objLibName);
+        }
       }
     else
       {
@@ -734,28 +742,11 @@ cmSourceFile* cmTarget::AddSource(const std::string& src)
     this->Internal->SourceEntries.push_back(
                           new cmTargetInternals::TargetPropertyEntry(cge));
     }
-  return this->Makefile->GetOrCreateSource(src);
-}
-
-
-
-//----------------------------------------------------------------------------
-void cmTarget::ProcessSourceExpression(std::string const& expr)
-{
-  if(cmHasLiteralPrefix(expr.c_str(), "$<TARGET_OBJECTS:") &&
-     expr[expr.size()-1] == '>')
+  if (cmGeneratorExpression::Find(src) != std::string::npos)
     {
-    std::string objLibName = expr.substr(17, expr.size()-18);
-    this->ObjectLibraries.push_back(objLibName);
-    this->AddSource(expr);
-    }
-  else
-    {
-    cmOStringStream e;
-    e << "Unrecognized generator expression:\n"
-      << "  " << expr;
-    this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
+    return 0;
     }
+  return this->Makefile->GetOrCreateSource(src);
 }
 
 //----------------------------------------------------------------------------
@@ -2886,6 +2877,14 @@ const char *cmTarget::GetProperty(const std::string& prop,
           {
           std::string objLibName = li->substr(17, li->size()-18);
 
+          if (cmGeneratorExpression::Find(objLibName) != std::string::npos)
+            {
+            ss << sep;
+            sep = ";";
+            ss << *li;
+            continue;
+            }
+
           bool addContent = false;
           bool noMessage = true;
           cmOStringStream e;
@@ -2920,6 +2919,12 @@ const char *cmTarget::GetProperty(const std::string& prop,
             ss << *li;
             }
           }
+        else if (cmGeneratorExpression::Find(*li) == std::string::npos)
+          {
+          ss << sep;
+          sep = ";";
+          ss << *li;
+          }
         else
           {
           cmSourceFile *sf = this->Makefile->GetOrCreateSource(*li);
diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx
index bb76b7f..8d10e7c 100644
--- a/Source/cmVisualStudio10TargetGenerator.cxx
+++ b/Source/cmVisualStudio10TargetGenerator.cxx
@@ -1054,6 +1054,19 @@ void cmVisualStudio10TargetGenerator::WriteAllSources()
 
   std::vector<cmSourceFile const*> externalObjects;
   this->GeneratorTarget->GetExternalObjects(externalObjects);
+  for(std::vector<cmSourceFile const*>::iterator
+        si = externalObjects.begin();
+      si != externalObjects.end(); )
+    {
+    if (!(*si)->GetObjectLibrary().empty())
+      {
+      si = externalObjects.erase(si);
+      }
+    else
+      {
+      ++si;
+      }
+    }
   if(this->LocalGenerator->GetVersion() > cmLocalVisualStudioGenerator::VS10)
     {
     // For VS >= 11 we use LinkObjects to avoid linking custom command
diff --git a/Tests/GeneratorExpression/CMakeLists.txt b/Tests/GeneratorExpression/CMakeLists.txt
index 66b175a..b506853 100644
--- a/Tests/GeneratorExpression/CMakeLists.txt
+++ b/Tests/GeneratorExpression/CMakeLists.txt
@@ -166,7 +166,7 @@ add_library(imported4 SHARED IMPORTED)
 set_property(TARGET imported4 APPEND PROPERTY
   INCLUDE_DIRECTORIES $<TARGET_PROPERTY:imported3,INTERFACE_INCLUDE_DIRECTORIES>)
 
-add_executable(someexe empty.cpp)
+add_executable(someexe $<1:empty.cpp> $<0:does_not_exist>)
 add_executable(Alias::SomeExe ALIAS someexe)
 
 add_library(Alias::SomeLib ALIAS empty1)
diff --git a/Tests/RunCMake/ObjectLibrary/BadSourceExpression1-stderr.txt b/Tests/RunCMake/ObjectLibrary/BadSourceExpression1-stderr.txt
index a1cac36..859dc3f 100644
--- a/Tests/RunCMake/ObjectLibrary/BadSourceExpression1-stderr.txt
+++ b/Tests/RunCMake/ObjectLibrary/BadSourceExpression1-stderr.txt
@@ -1,6 +1,8 @@
 CMake Error at BadSourceExpression1.cmake:1 \(add_library\):
-  Unrecognized generator expression:
+  Error evaluating generator expression:
 
     \$<BAD_EXPRESSION>
+
+  Expression did not evaluate to a known generator expression
 Call Stack \(most recent call first\):
   CMakeLists.txt:3 \(include\)

http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=2ce3f6535d9f508fa7f14d5a3f5e758bd8672802
commit 2ce3f6535d9f508fa7f14d5a3f5e758bd8672802
Author:     Stephen Kelly <steveire at gmail.com>
AuthorDate: Tue Mar 18 16:15:15 2014 +0100
Commit:     Stephen Kelly <steveire at gmail.com>
CommitDate: Wed Mar 19 17:28:25 2014 +0100

    cmTarget: Include TARGET_OBJECTS genex in target SOURCES property.
    
    Add policy CMP0051 to control this behavior.

diff --git a/Help/manual/cmake-policies.7.rst b/Help/manual/cmake-policies.7.rst
index 8650a58..b763882 100644
--- a/Help/manual/cmake-policies.7.rst
+++ b/Help/manual/cmake-policies.7.rst
@@ -102,3 +102,4 @@ All Policies
    /policy/CMP0048
    /policy/CMP0049
    /policy/CMP0050
+   /policy/CMP0051
diff --git a/Help/policy/CMP0051.rst b/Help/policy/CMP0051.rst
new file mode 100644
index 0000000..7d85929
--- /dev/null
+++ b/Help/policy/CMP0051.rst
@@ -0,0 +1,24 @@
+CMP0051
+-------
+
+List TARGET_OBJECTS in SOURCES target property.
+
+CMake 3.0 and lower did not include the ``TARGET_OBJECTS``
+:manual:`generator expression <cmake-generator-expressions(7)>` when
+returning the :prop_tgt:`SOURCES` target property.
+
+Configure-time CMake code is not able to handle generator expressions.  If
+using the :prop_tgt:`SOURCES` target property at configure time, it may be
+necessary to first remove generator expressions using the
+:command:`string(STRIP_GENEX)` command.  Generate-time CMake code such as
+:command:`file(GENERATE)` can handle the content without stripping.
+
+The ``OLD`` behavior for this policy is to omit ``TARGET_OBJECTS``
+expressions from the :prop_tgt:`SOURCES` target property.  The ``NEW``
+behavior for this policy is to include ``TARGET_OBJECTS`` expressions
+in the output.
+
+This policy was introduced in CMake version 3.1.
+CMake version |release| warns when the policy is not set and uses
+``OLD`` behavior.  Use the :command:`cmake_policy` command to set it
+to ``OLD`` or ``NEW`` explicitly.
diff --git a/Help/release/dev/target-SOURCES-genex.rst b/Help/release/dev/target-SOURCES-genex.rst
new file mode 100644
index 0000000..1ca6f66
--- /dev/null
+++ b/Help/release/dev/target-SOURCES-genex.rst
@@ -0,0 +1,7 @@
+target-SOURCES-genex
+--------------------
+
+* The :prop_tgt:`SOURCES` target property now contains
+  :manual:`generator expression <cmake-generator-expressions(7)>`
+  such as ``TARGET_OBJECTS`` when read at configure time, if
+  policy :policy:`CMP0051` is ``NEW``.
diff --git a/Source/cmPolicies.cxx b/Source/cmPolicies.cxx
index 2bd553f..226d6c6 100644
--- a/Source/cmPolicies.cxx
+++ b/Source/cmPolicies.cxx
@@ -343,6 +343,11 @@ cmPolicies::cmPolicies()
     CMP0050, "CMP0050",
     "Disallow add_custom_command SOURCE signatures.",
     3,0,0, cmPolicies::WARN);
+
+  this->DefinePolicy(
+    CMP0051, "CMP0051",
+    "List TARGET_OBJECTS in SOURCES target property.",
+    3,0,0, cmPolicies::WARN);
 }
 
 cmPolicies::~cmPolicies()
diff --git a/Source/cmPolicies.h b/Source/cmPolicies.h
index b77235d..7a08a34 100644
--- a/Source/cmPolicies.h
+++ b/Source/cmPolicies.h
@@ -104,6 +104,7 @@ public:
     CMP0048, ///< project() command manages VERSION variables
     CMP0049, ///< Do not expand variables in target source entries
     CMP0050, ///< Disallow add_custom_command SOURCE signatures
+    CMP0051, ///< List TARGET_OBJECTS in SOURCES target property
 
     /** \brief Always the last entry.
      *
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index 8bfc428..04ae5af 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -556,6 +556,10 @@ void cmTarget::GetSourceFiles(std::vector<std::string> &files) const
         i != srcs.end(); ++i)
       {
       std::string src = *i;
+      if (cmGeneratorExpression::Find(src) != std::string::npos)
+        {
+        continue;
+        }
       cmSourceFile* sf = this->Makefile->GetOrCreateSource(src);
       std::string e;
       src = sf->GetFullPath(&e);
@@ -743,6 +747,7 @@ void cmTarget::ProcessSourceExpression(std::string const& expr)
     {
     std::string objLibName = expr.substr(17, expr.size()-18);
     this->ObjectLibraries.push_back(objLibName);
+    this->AddSource(expr);
     }
   else
     {
@@ -2876,20 +2881,62 @@ const char *cmTarget::GetProperty(const std::string& prop,
       for (std::vector<std::string>::const_iterator
           li = files.begin(); li != files.end(); ++li)
         {
-        cmSourceFile *sf = this->Makefile->GetOrCreateSource(*li);
-        // Construct what is known about this source file location.
-        cmSourceFileLocation const& location = sf->GetLocation();
-        std::string sname = location.GetDirectory();
-        if(!sname.empty())
+        if(cmHasLiteralPrefix(*li, "$<TARGET_OBJECTS:") &&
+            (*li)[li->size() - 1] == '>')
           {
-          sname += "/";
+          std::string objLibName = li->substr(17, li->size()-18);
+
+          bool addContent = false;
+          bool noMessage = true;
+          cmOStringStream e;
+          cmake::MessageType messageType = cmake::AUTHOR_WARNING;
+          switch(this->Makefile->GetPolicyStatus(cmPolicies::CMP0051))
+            {
+            case cmPolicies::WARN:
+              e << (this->Makefile->GetPolicies()
+                    ->GetPolicyWarning(cmPolicies::CMP0051)) << "\n";
+              noMessage = false;
+            case cmPolicies::OLD:
+              break;
+            case cmPolicies::REQUIRED_ALWAYS:
+            case cmPolicies::REQUIRED_IF_USED:
+            case cmPolicies::NEW:
+              addContent = true;
+            }
+          if (!noMessage)
+            {
+            e << "Target \"" << this->Name << "\" contains $<TARGET_OBJECTS> "
+            "generator expression in its sources list.  This content was not "
+            "previously part of the SOURCES property when that property was "
+            "read at configure time.  Code reading that property needs to be "
+            "adapted to ignore the generator expression using the "
+            "string(GENEX_STRIP) command.";
+            this->Makefile->IssueMessage(messageType, e.str());
+            }
+          if (addContent)
+            {
+            ss << sep;
+            sep = ";";
+            ss << *li;
+            }
           }
-        sname += location.GetName();
+        else
+          {
+          cmSourceFile *sf = this->Makefile->GetOrCreateSource(*li);
+          // Construct what is known about this source file location.
+          cmSourceFileLocation const& location = sf->GetLocation();
+          std::string sname = location.GetDirectory();
+          if(!sname.empty())
+            {
+            sname += "/";
+            }
+          sname += location.GetName();
 
-        ss << sep;
-        sep = ";";
-        // Append this list entry.
-        ss << sname;
+          ss << sep;
+          sep = ";";
+          // Append this list entry.
+          ss << sname;
+          }
         }
       }
     this->Properties.SetProperty("SOURCES", ss.str().c_str(),

http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=22ad0fcf12be2d3d5fdbfa9b41cd5aaabcc2729c
commit 22ad0fcf12be2d3d5fdbfa9b41cd5aaabcc2729c
Author:     Stephen Kelly <steveire at gmail.com>
AuthorDate: Wed Mar 19 09:11:11 2014 +0100
Commit:     Stephen Kelly <steveire at gmail.com>
CommitDate: Wed Mar 19 17:28:25 2014 +0100

    cmGlobalGenerator: Add interface to call ForceLinkerLanguages
    
    Avoid calling it too early when cmGeneratorTarget instances don't
    yet exist.

diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx
index 07637b3..2f3c6c9 100644
--- a/Source/cmGlobalGenerator.cxx
+++ b/Source/cmGlobalGenerator.cxx
@@ -216,6 +216,11 @@ bool cmGlobalGenerator::GenerateImportFile(const std::string &file)
   return false;
 }
 
+void cmGlobalGenerator::ForceLinkerLanguages()
+{
+
+}
+
 bool
 cmGlobalGenerator::IsExportedTargetsFile(const std::string &filename) const
 {
@@ -1194,6 +1199,8 @@ void cmGlobalGenerator::Generate()
   // Create per-target generator information.
   this->CreateGeneratorTargets();
 
+  this->ForceLinkerLanguages();
+
 #ifdef CMAKE_BUILD_WITH_CMAKE
   for (AutogensType::iterator it = autogens.begin(); it != autogens.end();
        ++it)
diff --git a/Source/cmGlobalGenerator.h b/Source/cmGlobalGenerator.h
index 49a418d..668bb6b 100644
--- a/Source/cmGlobalGenerator.h
+++ b/Source/cmGlobalGenerator.h
@@ -423,6 +423,8 @@ private:
   void WriteSummary(cmTarget* target);
   void FinalizeTargetCompileInfo();
 
+  virtual void ForceLinkerLanguages();
+
   virtual void PrintCompilerAdvice(std::ostream& os, std::string const& lang,
                                    const char* envVar) const;
   void CheckCompilerIdCompatibility(cmMakefile* mf,
diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx
index 96b23d2..fdf73d6 100644
--- a/Source/cmGlobalXCodeGenerator.cxx
+++ b/Source/cmGlobalXCodeGenerator.cxx
@@ -343,7 +343,6 @@ void cmGlobalXCodeGenerator::Generate()
     // add ALL_BUILD, INSTALL, etc
     this->AddExtraTargets(root, it->second);
     }
-  this->ForceLinkerLanguages();
   this->cmGlobalGenerator::Generate();
   if(cmSystemTools::GetErrorOccuredFlag())
     {

http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=28dbb98a2fc027a94e037899880481040aeb9eb0
commit 28dbb98a2fc027a94e037899880481040aeb9eb0
Author:     Stephen Kelly <steveire at gmail.com>
AuthorDate: Tue Mar 18 16:21:08 2014 +0100
Commit:     Stephen Kelly <steveire at gmail.com>
CommitDate: Wed Mar 19 17:28:25 2014 +0100

    cmStringCommand: Add GENEX_STRIP subcommand.
    
    Strip out any generator expressions in the input string.

diff --git a/Help/command/string.rst b/Help/command/string.rst
index af18825..abde6ee 100644
--- a/Help/command/string.rst
+++ b/Help/command/string.rst
@@ -35,6 +35,7 @@ String operations.
   string(FIND <string> <substring> <output variable> [REVERSE])
   string(TIMESTAMP <output variable> [<format string>] [UTC])
   string(MAKE_C_IDENTIFIER <input string> <output variable>)
+  string(GENEX_STRIP <input string> <output variable>)
 
 REGEX MATCH will match the regular expression once and store the match
 in the output variable.
@@ -154,3 +155,7 @@ If no explicit <format string> is given it will default to:
 
 MAKE_C_IDENTIFIER will write a string which can be used as an
 identifier in C.
+
+``GENEX_STRIP`` will strip any
+:manual:`generator expressions <cmake-generator-expressions(7)>` from the
+``input string`` and store the result in the ``output variable``.
diff --git a/Help/release/dev/string-GENEX_STRIP.rst b/Help/release/dev/string-GENEX_STRIP.rst
new file mode 100644
index 0000000..b5b1074
--- /dev/null
+++ b/Help/release/dev/string-GENEX_STRIP.rst
@@ -0,0 +1,6 @@
+string-GENEX_STRIP
+------------------
+
+* The :command:`string` command learned a new ``GENEX_STRIP`` subcommand
+  which removes
+  :manual:`generator expression <cmake-generator-expressions(7)>`.
diff --git a/Source/cmStringCommand.cxx b/Source/cmStringCommand.cxx
index 7bc7b05..ea762eb 100644
--- a/Source/cmStringCommand.cxx
+++ b/Source/cmStringCommand.cxx
@@ -101,6 +101,10 @@ bool cmStringCommand
     {
     return this->HandleMakeCIdentifierCommand(args);
     }
+  else if(subCommand == "GENEX_STRIP")
+    {
+    return this->HandleGenexStripCommand(args);
+    }
 
   std::string e = "does not recognize sub-command "+subCommand;
   this->SetError(e);
@@ -810,6 +814,27 @@ bool cmStringCommand
 }
 
 //----------------------------------------------------------------------------
+bool cmStringCommand
+::HandleGenexStripCommand(std::vector<std::string> const& args)
+{
+  if(args.size() != 3)
+    {
+    this->SetError("sub-command GENEX_STRIP requires two arguments.");
+    return false;
+    }
+
+  const std::string& input = args[1];
+
+  std::string result = cmGeneratorExpression::Preprocess(input,
+                        cmGeneratorExpression::StripAllGeneratorExpressions);
+
+  const std::string& variableName = args[2];
+
+  this->Makefile->AddDefinition(variableName, result.c_str());
+  return true;
+}
+
+//----------------------------------------------------------------------------
 bool cmStringCommand::HandleStripCommand(
   std::vector<std::string> const& args)
 {
diff --git a/Source/cmStringCommand.h b/Source/cmStringCommand.h
index b8053c5..5b7412d 100644
--- a/Source/cmStringCommand.h
+++ b/Source/cmStringCommand.h
@@ -75,6 +75,7 @@ protected:
   bool HandleFindCommand(std::vector<std::string> const& args);
   bool HandleTimestampCommand(std::vector<std::string> const& args);
   bool HandleMakeCIdentifierCommand(std::vector<std::string> const& args);
+  bool HandleGenexStripCommand(std::vector<std::string> const& args);
 
   class RegexReplacement
   {
diff --git a/Tests/StringFileTest/CMakeLists.txt b/Tests/StringFileTest/CMakeLists.txt
index 00383ab..be6d8fe 100644
--- a/Tests/StringFileTest/CMakeLists.txt
+++ b/Tests/StringFileTest/CMakeLists.txt
@@ -286,3 +286,9 @@ string(MAKE_C_IDENTIFIER "1one-two$" MCI_1)
 if(NOT MCI_1 STREQUAL _1one_two_)
   message(SEND_ERROR "MAKE_C_IDENTIFIER did not create expected result.")
 endif()
+
+string(GENEX_STRIP "one;$<1:two;three>;four;$<TARGET_OBJECTS:some_target>" strip_result)
+
+if (NOT strip_result STREQUAL "one;four")
+  message(SEND_ERROR "GENEX_STRIP did not create expected result: ${strip_result}")
+endif()

http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=5586cdd40cd2fe69fa84161da933cbb2d24e90e1
commit 5586cdd40cd2fe69fa84161da933cbb2d24e90e1
Author:     Stephen Kelly <steveire at gmail.com>
AuthorDate: Wed Feb 26 15:59:18 2014 +0100
Commit:     Stephen Kelly <steveire at gmail.com>
CommitDate: Wed Mar 19 17:28:11 2014 +0100

    Genex: Evaluate TARGET_OBJECTS as a normal expression.

diff --git a/Help/manual/cmake-generator-expressions.7.rst b/Help/manual/cmake-generator-expressions.7.rst
index ac8c3f8..17263d4 100644
--- a/Help/manual/cmake-generator-expressions.7.rst
+++ b/Help/manual/cmake-generator-expressions.7.rst
@@ -188,3 +188,6 @@ property is non-empty::
   Content of ``...`` converted to upper case.
 ``$<MAKE_C_IDENTIFIER:...>``
   Content of ``...`` converted to a C identifier.
+``$<TARGET_OBJECTS:objLib>``
+  List of objects resulting from build of ``objLib``. ``objLib`` must be an
+  object of type ``OBJECT_LIBRARY``.
diff --git a/Help/release/dev/file-GENERATE-TARGET_OBJECTS.rst b/Help/release/dev/file-GENERATE-TARGET_OBJECTS.rst
new file mode 100644
index 0000000..853a803
--- /dev/null
+++ b/Help/release/dev/file-GENERATE-TARGET_OBJECTS.rst
@@ -0,0 +1,6 @@
+file-GENERATE-TARGET_OBJECTS
+----------------------------
+
+* The :command:`file(GENERATE)` subcommand learned to evaluate the
+  ``TARGET_OBJECTS``
+  :manual:`generator expression <cmake-generator-expressions(7)>`.
diff --git a/Source/cmGeneratorExpressionEvaluator.cxx b/Source/cmGeneratorExpressionEvaluator.cxx
index 14b2a1a..669694c 100644
--- a/Source/cmGeneratorExpressionEvaluator.cxx
+++ b/Source/cmGeneratorExpressionEvaluator.cxx
@@ -15,6 +15,8 @@
 #include "cmGeneratorExpressionParser.h"
 #include "cmGeneratorExpressionDAGChecker.h"
 #include "cmGeneratorExpression.h"
+#include "cmLocalGenerator.h"
+#include "cmSourceFile.h"
 
 #include <cmsys/String.h>
 
@@ -1240,6 +1242,67 @@ static const struct TargetNameNode : public cmGeneratorExpressionNode
 } targetNameNode;
 
 //----------------------------------------------------------------------------
+static const struct TargetObjectsNode : public cmGeneratorExpressionNode
+{
+  TargetObjectsNode() {}
+
+  std::string Evaluate(const std::vector<std::string> &parameters,
+                       cmGeneratorExpressionContext *context,
+                       const GeneratorExpressionContent *content,
+                       cmGeneratorExpressionDAGChecker *) const
+  {
+    std::string tgtName = parameters.front();
+    cmGeneratorTarget* gt =
+                context->Makefile->FindGeneratorTargetToUse(tgtName.c_str());
+    if (!gt)
+      {
+      cmOStringStream e;
+      e << "Objects of target \"" << tgtName
+        << "\" referenced but no such target exists.";
+      reportError(context, content->GetOriginalExpression(), e.str());
+      return std::string();
+      }
+    if (gt->GetType() != cmTarget::OBJECT_LIBRARY)
+      {
+      cmOStringStream e;
+      e << "Objects of target \"" << tgtName
+        << "\" referenced but is not an OBJECT library.";
+      reportError(context, content->GetOriginalExpression(), e.str());
+      return std::string();
+      }
+
+    std::vector<cmSourceFile const*> objectSources;
+    gt->GetObjectSources(objectSources);
+    std::map<cmSourceFile const*, std::string> mapping;
+
+    for(std::vector<cmSourceFile const*>::const_iterator it
+        = objectSources.begin(); it != objectSources.end(); ++it)
+      {
+      mapping[*it];
+      }
+
+    gt->LocalGenerator->ComputeObjectFilenames(mapping, gt);
+
+    std::string obj_dir = gt->ObjectDirectory;
+    std::string result;
+    const char* sep = "";
+    for(std::map<cmSourceFile const*, std::string>::const_iterator it
+        = mapping.begin(); it != mapping.end(); ++it)
+      {
+      assert(!it->second.empty());
+      result += sep;
+      std::string objFile = obj_dir + it->second;
+      cmSourceFile* sf = context->Makefile->GetOrCreateSource(objFile, true);
+      sf->SetObjectLibrary(tgtName);
+      sf->SetProperty("EXTERNAL_OBJECT", "1");
+      result += objFile;
+      sep = ";";
+      }
+    return result;
+  }
+} targetObjectsNode;
+
+//----------------------------------------------------------------------------
 static const char* targetPolicyWhitelist[] = {
   0
 #define TARGET_POLICY_STRING(POLICY) \
@@ -1593,6 +1656,7 @@ cmGeneratorExpressionNode* GetNode(const std::string &identifier)
     nodeMap["SEMICOLON"] = &semicolonNode;
     nodeMap["TARGET_PROPERTY"] = &targetPropertyNode;
     nodeMap["TARGET_NAME"] = &targetNameNode;
+    nodeMap["TARGET_OBJECTS"] = &targetObjectsNode;
     nodeMap["TARGET_POLICY"] = &targetPolicyNode;
     nodeMap["BUILD_INTERFACE"] = &buildInterfaceNode;
     nodeMap["INSTALL_INTERFACE"] = &installInterfaceNode;
diff --git a/Source/cmSourceFile.cxx b/Source/cmSourceFile.cxx
index b9b6251..0ab30a2 100644
--- a/Source/cmSourceFile.cxx
+++ b/Source/cmSourceFile.cxx
@@ -39,6 +39,18 @@ std::string const& cmSourceFile::GetExtension() const
 }
 
 //----------------------------------------------------------------------------
+void cmSourceFile::SetObjectLibrary(std::string const& objlib)
+{
+  this->ObjectLibrary = objlib;
+}
+
+//----------------------------------------------------------------------------
+std::string cmSourceFile::GetObjectLibrary() const
+{
+  return this->ObjectLibrary;
+}
+
+//----------------------------------------------------------------------------
 std::string cmSourceFile::GetLanguage()
 {
   // If the language was set explicitly by the user then use it.
diff --git a/Source/cmSourceFile.h b/Source/cmSourceFile.h
index 17c96ac..755a2cf 100644
--- a/Source/cmSourceFile.h
+++ b/Source/cmSourceFile.h
@@ -97,6 +97,9 @@ public:
    */
   bool Matches(cmSourceFileLocation const&);
 
+  void SetObjectLibrary(std::string const& objlib);
+  std::string GetObjectLibrary() const;
+
 private:
   cmSourceFileLocation Location;
   cmPropertyMap Properties;
@@ -105,6 +108,7 @@ private:
   std::string Language;
   std::string FullPath;
   bool FindFullPathFailed;
+  std::string ObjectLibrary;
 
   bool FindFullPath(std::string* error);
   bool TryFullPath(const std::string& path, const std::string& ext);
diff --git a/Tests/GeneratorExpression/CMakeLists.txt b/Tests/GeneratorExpression/CMakeLists.txt
index a0e34ef..66b175a 100644
--- a/Tests/GeneratorExpression/CMakeLists.txt
+++ b/Tests/GeneratorExpression/CMakeLists.txt
@@ -258,3 +258,17 @@ set(CMP0044_TYPE NEW)
 add_subdirectory(CMP0044 ${CMAKE_BINARY_DIR}/CMP0044-NEW)
 set(CMP0044_TYPE OLD)
 add_subdirectory(CMP0044 ${CMAKE_BINARY_DIR}/CMP0044-OLD)
+
+add_library(objlib OBJECT objlib1.c objlib2.c)
+file(GENERATE
+  OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/objlib_files"
+  CONTENT "$<JOIN:$<TARGET_OBJECTS:objlib>,\n>\n"
+)
+add_custom_target(check_object_files ALL
+  COMMAND ${CMAKE_COMMAND}
+    "-DOBJLIB_LISTFILE=${CMAKE_CURRENT_BINARY_DIR}/objlib_files"
+    -DTEST_CONFIGURATION=${CMAKE_BUILD_TYPE}
+    -DEXPECTED_NUM_OBJECTFILES=2
+    -P "${CMAKE_CURRENT_SOURCE_DIR}/check_object_files.cmake"
+  DEPENDS objlib
+)
diff --git a/Tests/GeneratorExpression/check_object_files.cmake b/Tests/GeneratorExpression/check_object_files.cmake
new file mode 100644
index 0000000..889fe80
--- /dev/null
+++ b/Tests/GeneratorExpression/check_object_files.cmake
@@ -0,0 +1,48 @@
+
+if (NOT EXISTS ${OBJLIB_LISTFILE})
+  message(SEND_ERROR "Object listing file \"${OBJLIB_LISTFILE}\" not found!")
+endif()
+
+file(STRINGS ${OBJLIB_LISTFILE} objlib_files)
+
+list(LENGTH objlib_files num_objectfiles)
+if (NOT EXPECTED_NUM_OBJECTFILES EQUAL num_objectfiles)
+  message(SEND_ERROR "Unexpected number of entries in object list file (${num_objectfiles} instead of ${EXPECTED_NUM_OBJECTFILES})")
+endif()
+
+foreach(objlib_file ${objlib_files})
+  set(file_exists False)
+  if (EXISTS ${objlib_file})
+    set(file_exists True)
+  endif()
+
+  if (NOT file_exists)
+    if (objlib_file MATCHES ".(CURRENT_ARCH)")
+      string(REPLACE "$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)" "*" config_file "${objlib_file}")
+      string(REPLACE "$(PROJECT_NAME)" "GeneratorExpression" config_file "${config_file}")
+      string(REPLACE "$(CURRENT_ARCH)" "*" config_file "${config_file}")
+      file(GLOB_RECURSE files "${config_file}")
+      list(LENGTH files num_files)
+      if (NOT files)
+        message(SEND_ERROR "Got no files for expression ${config_file}")
+      endif()
+      set(file_exists True)
+    else()
+      foreach(config_macro "$(Configuration)" "$(OutDir)" "$(IntDir)")
+        string(REPLACE "${config_macro}" "${TEST_CONFIGURATION}" config_file "${objlib_file}")
+        list(APPEND attempts ${config_file})
+        if (EXISTS ${config_file})
+          set(file_exists True)
+        endif()
+      endforeach()
+    endif()
+  endif()
+
+  if (NOT file_exists)
+    if(attempts)
+      list(REMOVE_DUPLICATES attempts)
+      set(tried "  Tried ${attempts}")
+    endif()
+    message(SEND_ERROR "File \"${objlib_file}\" does not exist!${tried}")
+  endif()
+endforeach()
diff --git a/Tests/GeneratorExpression/objlib1.c b/Tests/GeneratorExpression/objlib1.c
new file mode 100644
index 0000000..aa8de0a
--- /dev/null
+++ b/Tests/GeneratorExpression/objlib1.c
@@ -0,0 +1,5 @@
+
+void objlib1()
+{
+
+}
diff --git a/Tests/GeneratorExpression/objlib2.c b/Tests/GeneratorExpression/objlib2.c
new file mode 100644
index 0000000..3c7307a
--- /dev/null
+++ b/Tests/GeneratorExpression/objlib2.c
@@ -0,0 +1,5 @@
+
+void objlib2()
+{
+
+}
diff --git a/Tests/RunCMake/CMakeLists.txt b/Tests/RunCMake/CMakeLists.txt
index f9d590a..658aed3 100644
--- a/Tests/RunCMake/CMakeLists.txt
+++ b/Tests/RunCMake/CMakeLists.txt
@@ -49,6 +49,7 @@ add_RunCMake_test(GeneratorToolset)
 add_RunCMake_test(TargetPropertyGeneratorExpressions)
 add_RunCMake_test(Languages)
 add_RunCMake_test(ObjectLibrary)
+add_RunCMake_test(TargetObjects)
 add_RunCMake_test(find_dependency)
 if(NOT WIN32)
   add_RunCMake_test(PositionIndependentCode)
diff --git a/Tests/RunCMake/TargetObjects/CMakeLists.txt b/Tests/RunCMake/TargetObjects/CMakeLists.txt
new file mode 100644
index 0000000..be9d403
--- /dev/null
+++ b/Tests/RunCMake/TargetObjects/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 2.8.4)
+project(${RunCMake_TEST})
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/TargetObjects/NoTarget-result.txt b/Tests/RunCMake/TargetObjects/NoTarget-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/TargetObjects/NoTarget-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/TargetObjects/NoTarget-stderr.txt b/Tests/RunCMake/TargetObjects/NoTarget-stderr.txt
new file mode 100644
index 0000000..2c4f877
--- /dev/null
+++ b/Tests/RunCMake/TargetObjects/NoTarget-stderr.txt
@@ -0,0 +1,8 @@
+CMake Error at NoTarget.cmake:2 \(file\):
+  Error evaluating generator expression:
+
+    \$<TARGET_OBJECTS:NoTarget>
+
+  Objects of target "NoTarget" referenced but no such target exists.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/TargetObjects/NoTarget.cmake b/Tests/RunCMake/TargetObjects/NoTarget.cmake
new file mode 100644
index 0000000..f203c23
--- /dev/null
+++ b/Tests/RunCMake/TargetObjects/NoTarget.cmake
@@ -0,0 +1,2 @@
+
+file(GENERATE OUTPUT test_output CONTENT $<TARGET_OBJECTS:NoTarget>)
diff --git a/Tests/RunCMake/TargetObjects/NotObjlibTarget-result.txt b/Tests/RunCMake/TargetObjects/NotObjlibTarget-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/TargetObjects/NotObjlibTarget-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/TargetObjects/NotObjlibTarget-stderr.txt b/Tests/RunCMake/TargetObjects/NotObjlibTarget-stderr.txt
new file mode 100644
index 0000000..bb83934
--- /dev/null
+++ b/Tests/RunCMake/TargetObjects/NotObjlibTarget-stderr.txt
@@ -0,0 +1,8 @@
+CMake Error at NotObjlibTarget.cmake:4 \(file\):
+  Error evaluating generator expression:
+
+    \$<TARGET_OBJECTS:StaticLib>
+
+  Objects of target "StaticLib" referenced but is not an OBJECT library.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/TargetObjects/NotObjlibTarget.cmake b/Tests/RunCMake/TargetObjects/NotObjlibTarget.cmake
new file mode 100644
index 0000000..c7f8a71
--- /dev/null
+++ b/Tests/RunCMake/TargetObjects/NotObjlibTarget.cmake
@@ -0,0 +1,4 @@
+
+add_library(StaticLib empty.cpp)
+
+file(GENERATE OUTPUT test_output CONTENT $<TARGET_OBJECTS:StaticLib>)
diff --git a/Tests/RunCMake/TargetObjects/RunCMakeTest.cmake b/Tests/RunCMake/TargetObjects/RunCMakeTest.cmake
new file mode 100644
index 0000000..30b9fee
--- /dev/null
+++ b/Tests/RunCMake/TargetObjects/RunCMakeTest.cmake
@@ -0,0 +1,4 @@
+include(RunCMake)
+
+run_cmake(NoTarget)
+run_cmake(NotObjlibTarget)
diff --git a/Tests/RunCMake/TargetObjects/empty.cpp b/Tests/RunCMake/TargetObjects/empty.cpp
new file mode 100644
index 0000000..bfbbdde
--- /dev/null
+++ b/Tests/RunCMake/TargetObjects/empty.cpp
@@ -0,0 +1,7 @@
+#ifdef _WIN32
+__declspec(dllexport)
+#endif
+int empty()
+{
+  return 0;
+}

http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=3a7e6948adefc303af6df4a9e886efcda2edb0b8
commit 3a7e6948adefc303af6df4a9e886efcda2edb0b8
Author:     Stephen Kelly <steveire at gmail.com>
AuthorDate: Mon Mar 17 18:36:04 2014 +0100
Commit:     Stephen Kelly <steveire at gmail.com>
CommitDate: Wed Mar 19 16:37:33 2014 +0100

    cmTarget: Store strings instead of cmSourceFile* to represent SOURCES.
    
    This will allow the strings to contain generator expressions.
    
    At this point, generator expressions are still not part of the
    SOURCES property when it is read.

diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index 9d17320..8bfc428 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -150,6 +150,7 @@ public:
   std::vector<TargetPropertyEntry*> IncludeDirectoriesEntries;
   std::vector<TargetPropertyEntry*> CompileOptionsEntries;
   std::vector<TargetPropertyEntry*> CompileDefinitionsEntries;
+  std::vector<TargetPropertyEntry*> SourceEntries;
   std::vector<cmValueWithOrigin> LinkImplementationPropertyEntries;
 
   mutable std::map<std::string, std::vector<TargetPropertyEntry*> >
@@ -545,37 +546,51 @@ bool cmTarget::IsBundleOnApple() const
 void cmTarget::GetSourceFiles(std::vector<std::string> &files) const
 {
   assert(this->GetType() != INTERFACE_LIBRARY);
-  std::vector<cmSourceFile*> sourceFiles;
-  this->GetSourceFiles(sourceFiles);
-  for(std::vector<cmSourceFile*>::const_iterator
-      si = sourceFiles.begin();
-      si != sourceFiles.end(); ++si)
-    {
-    files.push_back((*si)->GetFullPath());
+  for(std::vector<cmTargetInternals::TargetPropertyEntry*>::const_iterator
+      si = this->Internal->SourceEntries.begin();
+      si != this->Internal->SourceEntries.end(); ++si)
+    {
+    std::vector<std::string> srcs;
+    cmSystemTools::ExpandListArgument((*si)->ge->GetInput(), srcs);
+    for(std::vector<std::string>::const_iterator i = srcs.begin();
+        i != srcs.end(); ++i)
+      {
+      std::string src = *i;
+      cmSourceFile* sf = this->Makefile->GetOrCreateSource(src);
+      std::string e;
+      src = sf->GetFullPath(&e);
+      if(src.empty())
+        {
+        if(!e.empty())
+          {
+          cmake* cm = this->Makefile->GetCMakeInstance();
+          cm->IssueMessage(cmake::FATAL_ERROR, e,
+                          this->GetBacktrace());
+          }
+        return;
+        }
+      files.push_back(src);
+      }
     }
 }
 
 //----------------------------------------------------------------------------
 void cmTarget::GetSourceFiles(std::vector<cmSourceFile*> &files) const
 {
-  assert(this->GetType() != INTERFACE_LIBRARY);
-  for(std::vector<cmSourceFile*>::const_iterator
-      si = this->SourceFiles.begin();
-      si != this->SourceFiles.end(); ++si)
+  std::vector<std::string> srcs;
+  this->GetSourceFiles(srcs);
+
+  std::set<cmSourceFile*> emitted;
+
+  for(std::vector<std::string>::const_iterator i = srcs.begin();
+      i != srcs.end(); ++i)
     {
-    std::string e;
-    if((*si)->GetFullPath(&e).empty())
+    cmSourceFile* sf = this->Makefile->GetOrCreateSource(*i);
+    if (emitted.insert(sf).second)
       {
-      if(!e.empty())
-        {
-        cmake* cm = this->Makefile->GetCMakeInstance();
-        cm->IssueMessage(cmake::FATAL_ERROR, e,
-                         this->GetBacktrace());
-        }
-      return;
+      files.push_back(sf);
       }
     }
-  files = this->SourceFiles;
 }
 
 //----------------------------------------------------------------------------
@@ -640,17 +655,86 @@ cmSourceFile* cmTarget::AddSourceCMP0049(const std::string& s)
 }
 
 //----------------------------------------------------------------------------
+struct CreateLocation
+{
+  cmMakefile const* Makefile;
+
+  CreateLocation(cmMakefile const* mf)
+    : Makefile(mf)
+  {
+
+  }
+
+  cmSourceFileLocation operator()(const std::string& filename)
+  {
+    return cmSourceFileLocation(this->Makefile, filename);
+  }
+};
+
+//----------------------------------------------------------------------------
+struct LocationMatcher
+{
+  const cmSourceFileLocation& Needle;
+
+  LocationMatcher(const cmSourceFileLocation& needle)
+    : Needle(needle)
+  {
+
+  }
+
+  bool operator()(cmSourceFileLocation &loc)
+  {
+    return loc.Matches(this->Needle);
+  }
+};
+
+
+//----------------------------------------------------------------------------
+struct TargetPropertyEntryFinder
+{
+private:
+  const cmSourceFileLocation& Needle;
+public:
+  TargetPropertyEntryFinder(const cmSourceFileLocation& needle)
+    : Needle(needle)
+  {
+
+  }
+
+  bool operator()(cmTargetInternals::TargetPropertyEntry* entry)
+  {
+    std::vector<std::string> files;
+    cmSystemTools::ExpandListArgument(entry->ge->GetInput(), files);
+    std::vector<cmSourceFileLocation> locations(files.size());
+    std::transform(files.begin(), files.end(), locations.begin(),
+                   CreateLocation(this->Needle.GetMakefile()));
+
+    return std::find_if(locations.begin(), locations.end(),
+        LocationMatcher(this->Needle)) != locations.end();
+  }
+};
+
+//----------------------------------------------------------------------------
 cmSourceFile* cmTarget::AddSource(const std::string& src)
 {
-  cmSourceFile* sf = this->Makefile->GetOrCreateSource(src);
-  if (std::find(this->SourceFiles.begin(), this->SourceFiles.end(), sf)
-                                            == this->SourceFiles.end())
+  cmSourceFileLocation sfl(this->Makefile, src);
+  if (std::find_if(this->Internal->SourceEntries.begin(),
+                   this->Internal->SourceEntries.end(),
+                   TargetPropertyEntryFinder(sfl))
+                                      == this->Internal->SourceEntries.end())
     {
-    this->SourceFiles.push_back(sf);
+    cmListFileBacktrace lfbt;
+    this->Makefile->GetBacktrace(lfbt);
+    cmGeneratorExpression ge(lfbt);
+    cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(src);
+    this->Internal->SourceEntries.push_back(
+                          new cmTargetInternals::TargetPropertyEntry(cge));
     }
-  return sf;
+  return this->Makefile->GetOrCreateSource(src);
 }
 
+
+
 //----------------------------------------------------------------------------
 void cmTarget::ProcessSourceExpression(std::string const& expr)
 {
@@ -2779,25 +2863,34 @@ const char *cmTarget::GetProperty(const std::string& prop,
     {
     cmOStringStream ss;
     const char* sep = "";
-    for(std::vector<cmSourceFile*>::const_iterator
-          i = this->SourceFiles.begin();
-        i != this->SourceFiles.end(); ++i)
+    typedef cmTargetInternals::TargetPropertyEntry
+                                TargetPropertyEntry;
+    for(std::vector<TargetPropertyEntry*>::const_iterator
+          i = this->Internal->SourceEntries.begin();
+        i != this->Internal->SourceEntries.end(); ++i)
       {
-      // Separate from the previous list entries.
-      ss << sep;
-      sep = ";";
+      std::string entry = (*i)->ge->GetInput();
 
-      // Construct what is known about this source file location.
-      cmSourceFileLocation const& location = (*i)->GetLocation();
-      std::string sname = location.GetDirectory();
-      if(!sname.empty())
+      std::vector<std::string> files;
+      cmSystemTools::ExpandListArgument(entry, files);
+      for (std::vector<std::string>::const_iterator
+          li = files.begin(); li != files.end(); ++li)
         {
-        sname += "/";
-        }
-      sname += location.GetName();
+        cmSourceFile *sf = this->Makefile->GetOrCreateSource(*li);
+        // Construct what is known about this source file location.
+        cmSourceFileLocation const& location = sf->GetLocation();
+        std::string sname = location.GetDirectory();
+        if(!sname.empty())
+          {
+          sname += "/";
+          }
+        sname += location.GetName();
 
-      // Append this list entry.
-      ss << sname;
+        ss << sep;
+        sep = ";";
+        // Append this list entry.
+        ss << sname;
+        }
       }
     this->Properties.SetProperty("SOURCES", ss.str().c_str(),
                                  cmProperty::TARGET);
@@ -6410,6 +6503,7 @@ cmTargetInternalPointer::~cmTargetInternalPointer()
   deleteAndClear(this->Pointer->IncludeDirectoriesEntries);
   deleteAndClear(this->Pointer->CompileOptionsEntries);
   deleteAndClear(this->Pointer->CompileDefinitionsEntries);
+  deleteAndClear(this->Pointer->SourceEntries);
   delete this->Pointer;
 }
 
diff --git a/Source/cmTarget.h b/Source/cmTarget.h
index e9e3622..45fca53 100644
--- a/Source/cmTarget.h
+++ b/Source/cmTarget.h
@@ -686,7 +686,6 @@ private:
   std::vector<cmCustomCommand> PreLinkCommands;
   std::vector<cmCustomCommand> PostBuildCommands;
   TargetType TargetTypeValue;
-  std::vector<cmSourceFile*> SourceFiles;
   std::vector<std::string> ObjectLibraries;
   LinkLibraryVectorType LinkLibraries;
   LinkLibraryVectorType PrevLinkedLibraries;

http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=80dea9685cd976caeaa8b1af254a1726a7be0675
commit 80dea9685cd976caeaa8b1af254a1726a7be0675
Author:     Stephen Kelly <steveire at gmail.com>
AuthorDate: Mon Mar 17 18:45:37 2014 +0100
Commit:     Stephen Kelly <steveire at gmail.com>
CommitDate: Wed Mar 19 16:37:33 2014 +0100

    cmTarget: Remove AddSourceFile method
    
    It is no longer used.

diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index 0866d10..9d17320 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -579,16 +579,6 @@ void cmTarget::GetSourceFiles(std::vector<cmSourceFile*> &files) const
 }
 
 //----------------------------------------------------------------------------
-void cmTarget::AddSourceFile(cmSourceFile* sf)
-{
-  if (std::find(this->SourceFiles.begin(), this->SourceFiles.end(), sf)
-                                            == this->SourceFiles.end())
-    {
-    this->SourceFiles.push_back(sf);
-    }
-}
-
-//----------------------------------------------------------------------------
 void cmTarget::AddSources(std::vector<std::string> const& srcs)
 {
   for(std::vector<std::string>::const_iterator i = srcs.begin();
@@ -653,7 +643,11 @@ cmSourceFile* cmTarget::AddSourceCMP0049(const std::string& s)
 cmSourceFile* cmTarget::AddSource(const std::string& src)
 {
   cmSourceFile* sf = this->Makefile->GetOrCreateSource(src);
-  this->AddSourceFile(sf);
+  if (std::find(this->SourceFiles.begin(), this->SourceFiles.end(), sf)
+                                            == this->SourceFiles.end())
+    {
+    this->SourceFiles.push_back(sf);
+    }
   return sf;
 }
 
diff --git a/Source/cmTarget.h b/Source/cmTarget.h
index 8df9bd8..e9e3622 100644
--- a/Source/cmTarget.h
+++ b/Source/cmTarget.h
@@ -137,7 +137,6 @@ public:
    */
   void GetSourceFiles(std::vector<std::string> &files) const;
   void GetSourceFiles(std::vector<cmSourceFile*> &files) const;
-  void AddSourceFile(cmSourceFile* sf);
   std::vector<std::string> const& GetObjectLibraries() const
     {
     return this->ObjectLibraries;

http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=fed93ec353e901ad638d74bad4a8d5f45a770dc2
commit fed93ec353e901ad638d74bad4a8d5f45a770dc2
Author:     Stephen Kelly <steveire at gmail.com>
AuthorDate: Wed Mar 12 12:45:14 2014 +0100
Commit:     Stephen Kelly <steveire at gmail.com>
CommitDate: Wed Mar 19 16:37:33 2014 +0100

    cmTarget: Use string API to add sources to cmTarget objects.
    
    Continue to call GetOrCreateSource where necessary to create
    cmSourceFile objects which have the GENERATED attribute set.

diff --git a/Source/cmFLTKWrapUICommand.cxx b/Source/cmFLTKWrapUICommand.cxx
index 0a36b82..e2b114a 100644
--- a/Source/cmFLTKWrapUICommand.cxx
+++ b/Source/cmFLTKWrapUICommand.cxx
@@ -168,7 +168,7 @@ void cmFLTKWrapUICommand::FinalPass()
     for(size_t classNum = 0; classNum < lastHeadersClass; classNum++)
       {
       this->Makefile->GetTargets()[this->Target]
-        .AddSourceFile(this->GeneratedSourcesClasses[classNum]);
+        .AddSource(this->GeneratedSourcesClasses[classNum]->GetFullPath());
       }
     }
 }
diff --git a/Source/cmGlobalVisualStudio8Generator.cxx b/Source/cmGlobalVisualStudio8Generator.cxx
index ab4380c..e80df84 100644
--- a/Source/cmGlobalVisualStudio8Generator.cxx
+++ b/Source/cmGlobalVisualStudio8Generator.cxx
@@ -16,6 +16,7 @@
 #include "cmVisualStudioWCEPlatformParser.h"
 #include "cmake.h"
 #include "cmGeneratedFileStream.h"
+#include "cmSourceFile.h"
 
 static const char vs8generatorName[] = "Visual Studio 8 2005";
 
@@ -323,7 +324,7 @@ bool cmGlobalVisualStudio8Generator::AddCheckTarget()
        no_main_dependency, commandLines, "Checking Build System",
        no_working_directory, true))
     {
-    tgt->AddSourceFile(file);
+    tgt->AddSource(file->GetFullPath());
     }
   else
     {
diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx
index f93fc12..96b23d2 100644
--- a/Source/cmGlobalXCodeGenerator.cxx
+++ b/Source/cmGlobalXCodeGenerator.cxx
@@ -1260,7 +1260,7 @@ void cmGlobalXCodeGenerator::ForceLinkerLanguage(cmTarget& cmtarget)
   if(cmSourceFile* sf = mf->GetOrCreateSource(fname.c_str()))
     {
     sf->SetProperty("LANGUAGE", llang.c_str());
-    cmtarget.AddSourceFile(sf);
+    cmtarget.AddSource(fname);
     }
 }
 
@@ -2934,8 +2934,8 @@ void cmGlobalXCodeGenerator::CreateGroups(cmLocalGenerator* root,
       if(cmtarget.GetPropertyAsBool("MACOSX_BUNDLE"))
         {
         std::string plist = this->ComputeInfoPListLocation(cmtarget);
-        cmSourceFile* sf = mf->GetOrCreateSource(plist.c_str(), true);
-        cmtarget.AddSourceFile(sf);
+        mf->GetOrCreateSource(plist, true);
+        cmtarget.AddSource(plist);
         }
 
       std::vector<cmSourceFile*> classes;
diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx
index c63de79..42c9fce 100644
--- a/Source/cmLocalGenerator.cxx
+++ b/Source/cmLocalGenerator.cxx
@@ -753,8 +753,8 @@ void cmLocalGenerator::AddBuildTargetRule(const std::string& llang,
     comment.c_str(),
     this->Makefile->GetStartOutputDirectory()
     );
-  target.Target->AddSourceFile
-    (this->Makefile->GetSource(targetFullPath));
+  this->Makefile->GetSource(targetFullPath);
+  target.Target->AddSource(targetFullPath);
 }
 
 
diff --git a/Source/cmLocalVisualStudio6Generator.cxx b/Source/cmLocalVisualStudio6Generator.cxx
index 2ab25cc..e3ab142 100644
--- a/Source/cmLocalVisualStudio6Generator.cxx
+++ b/Source/cmLocalVisualStudio6Generator.cxx
@@ -255,7 +255,7 @@ void cmLocalVisualStudio6Generator::AddDSPBuildRule(cmTarget& tgt)
                                            no_working_directory, true);
   if(cmSourceFile* file = this->Makefile->GetSource(makefileIn.c_str()))
     {
-    tgt.AddSourceFile(file);
+    tgt.AddSource(makefileIn);
     }
   else
     {
@@ -591,7 +591,7 @@ cmLocalVisualStudio6Generator
        origCommand.GetCommandLines(), comment,
        origCommand.GetWorkingDirectory().c_str()))
     {
-    target.AddSourceFile(outsf);
+    target.AddSource(outsf->GetFullPath());
     }
 
   // Replace the dependencies with the output of this rule so that the
diff --git a/Source/cmLocalVisualStudio7Generator.cxx b/Source/cmLocalVisualStudio7Generator.cxx
index 52524aa..e8562ca 100644
--- a/Source/cmLocalVisualStudio7Generator.cxx
+++ b/Source/cmLocalVisualStudio7Generator.cxx
@@ -117,7 +117,7 @@ void cmLocalVisualStudio7Generator::AddCMakeListsRules()
         {
         if(l->first != CMAKE_CHECK_BUILD_SYSTEM_TARGET)
           {
-          l->second.AddSourceFile(sf);
+          l->second.AddSource(sf->GetFullPath());
           }
         }
       }
@@ -153,7 +153,7 @@ void cmLocalVisualStudio7Generator::FixGlobalTargets()
            force.c_str(), no_depends, no_main_dependency,
            force_commands, " ", 0, true))
         {
-        tgt.AddSourceFile(file);
+        tgt.AddSource(file->GetFullPath());
         }
       }
     }
diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx
index c12a5cd..d3a3c16 100644
--- a/Source/cmMakefile.cxx
+++ b/Source/cmMakefile.cxx
@@ -1174,7 +1174,7 @@ cmMakefile::AddCustomCommandOldStyle(const std::string& target,
       {
       if (this->Targets.find(target) != this->Targets.end())
         {
-        this->Targets[target].AddSourceFile(sf);
+        this->Targets[target].AddSource(sf->GetFullPath());
         }
       else
         {
diff --git a/Source/cmQtAutoGenerators.cxx b/Source/cmQtAutoGenerators.cxx
index 7b11b61..c957306 100644
--- a/Source/cmQtAutoGenerators.cxx
+++ b/Source/cmQtAutoGenerators.cxx
@@ -187,13 +187,11 @@ bool cmQtAutoGenerators::InitializeAutogenTarget(cmTarget* target)
     mocCppFile += "/";
     mocCppFile += automocTargetName;
     mocCppFile += ".cpp";
-    cmSourceFile* mocCppSource = makefile->GetOrCreateSource(
-                                                          mocCppFile,
-                                                          true);
+    makefile->GetOrCreateSource(mocCppFile, true);
     makefile->AppendProperty("ADDITIONAL_MAKE_CLEAN_FILES",
                             mocCppFile.c_str(), false);
 
-    target->AddSourceFile(mocCppSource);
+    target->AddSource(mocCppFile);
     }
   // create a custom target for running generators at buildtime:
   std::string autogenTargetName = getAutogenTargetName(target);
@@ -479,7 +477,7 @@ void cmQtAutoGenerators::SetupSourceFiles(cmTarget const* target)
   const char *skipMocSep = "";
   const char *skipUicSep = "";
 
-  std::vector<cmSourceFile*> newRccFiles;
+  std::vector<std::string> newRccFiles;
 
   for(std::vector<cmSourceFile*>::const_iterator fileIt = srcFiles.begin();
       fileIt != srcFiles.end();
@@ -512,9 +510,8 @@ void cmQtAutoGenerators::SetupSourceFiles(cmTarget const* target)
         rcc_output_file += "/qrc_" + basename + ".cpp";
         makefile->AppendProperty("ADDITIONAL_MAKE_CLEAN_FILES",
                                 rcc_output_file.c_str(), false);
-        cmSourceFile* rccCppSource
-                = makefile->GetOrCreateSource(rcc_output_file, true);
-        newRccFiles.push_back(rccCppSource);
+        makefile->GetOrCreateSource(rcc_output_file, true);
+        newRccFiles.push_back(rcc_output_file);
         }
       }
 
@@ -546,11 +543,11 @@ void cmQtAutoGenerators::SetupSourceFiles(cmTarget const* target)
       }
     }
 
-  for(std::vector<cmSourceFile*>::const_iterator fileIt = newRccFiles.begin();
+  for(std::vector<std::string>::const_iterator fileIt = newRccFiles.begin();
       fileIt != newRccFiles.end();
       ++fileIt)
     {
-    const_cast<cmTarget*>(target)->AddSourceFile(*fileIt);
+    const_cast<cmTarget*>(target)->AddSource(*fileIt);
     }
 }
 

http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=cee09f9f241c30aca13094ea6d9468ec21924acf
commit cee09f9f241c30aca13094ea6d9468ec21924acf
Author:     Stephen Kelly <steveire at gmail.com>
AuthorDate: Mon Mar 17 17:49:38 2014 +0100
Commit:     Stephen Kelly <steveire at gmail.com>
CommitDate: Wed Mar 19 16:37:33 2014 +0100

    cmTarget: Add a method to obtain list of filenames for sources.

diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx
index 2a144c6..8984874 100644
--- a/Source/cmGeneratorTarget.cxx
+++ b/Source/cmGeneratorTarget.cxx
@@ -599,12 +599,12 @@ private:
   cmGlobalGenerator const* GlobalGenerator;
   typedef cmGeneratorTarget::SourceEntry SourceEntry;
   SourceEntry* CurrentEntry;
-  std::queue<cmSourceFile*> SourceQueue;
-  std::set<cmSourceFile*> SourcesQueued;
+  std::queue<std::string> SourceQueue;
+  std::set<std::string> SourcesQueued;
   typedef std::map<std::string, cmSourceFile*> NameMapType;
   NameMapType NameMap;
 
-  void QueueSource(cmSourceFile* sf);
+  void QueueSource(std::string const& name);
   void FollowName(std::string const& name);
   void FollowNames(std::vector<std::string> const& names);
   bool IsUtility(std::string const& dep);
@@ -624,11 +624,11 @@ cmTargetTraceDependencies
   this->CurrentEntry = 0;
 
   // Queue all the source files already specified for the target.
-  std::vector<cmSourceFile*> sources;
   if (this->Target->GetType() != cmTarget::INTERFACE_LIBRARY)
     {
+    std::vector<std::string> sources;
     this->Target->GetSourceFiles(sources);
-    for(std::vector<cmSourceFile*>::const_iterator si = sources.begin();
+    for(std::vector<std::string>::const_iterator si = sources.begin();
         si != sources.end(); ++si)
       {
       this->QueueSource(*si);
@@ -648,7 +648,8 @@ void cmTargetTraceDependencies::Trace()
   while(!this->SourceQueue.empty())
     {
     // Get the next source from the queue.
-    cmSourceFile* sf = this->SourceQueue.front();
+    std::string src = this->SourceQueue.front();
+    cmSourceFile* sf = this->Makefile->GetSource(src);
     this->SourceQueue.pop();
     this->CurrentEntry = &this->GeneratorTarget->SourceEntries[sf];
 
@@ -676,14 +677,14 @@ void cmTargetTraceDependencies::Trace()
 }
 
 //----------------------------------------------------------------------------
-void cmTargetTraceDependencies::QueueSource(cmSourceFile* sf)
+void cmTargetTraceDependencies::QueueSource(std::string const& name)
 {
-  if(this->SourcesQueued.insert(sf).second)
+  if(this->SourcesQueued.insert(name).second)
     {
-    this->SourceQueue.push(sf);
+    this->SourceQueue.push(name);
 
     // Make sure this file is in the target.
-    this->Target->AddSourceFile(sf);
+    this->Target->AddSource(name);
     }
 }
 
@@ -705,8 +706,7 @@ void cmTargetTraceDependencies::FollowName(std::string const& name)
       {
       this->CurrentEntry->Depends.push_back(sf);
       }
-
-    this->QueueSource(sf);
+    this->QueueSource(sf->GetFullPath());
     }
 }
 
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index 835aaad..0866d10 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -542,6 +542,20 @@ bool cmTarget::IsBundleOnApple() const
 }
 
 //----------------------------------------------------------------------------
+void cmTarget::GetSourceFiles(std::vector<std::string> &files) const
+{
+  assert(this->GetType() != INTERFACE_LIBRARY);
+  std::vector<cmSourceFile*> sourceFiles;
+  this->GetSourceFiles(sourceFiles);
+  for(std::vector<cmSourceFile*>::const_iterator
+      si = sourceFiles.begin();
+      si != sourceFiles.end(); ++si)
+    {
+    files.push_back((*si)->GetFullPath());
+    }
+}
+
+//----------------------------------------------------------------------------
 void cmTarget::GetSourceFiles(std::vector<cmSourceFile*> &files) const
 {
   assert(this->GetType() != INTERFACE_LIBRARY);
diff --git a/Source/cmTarget.h b/Source/cmTarget.h
index e385443..8df9bd8 100644
--- a/Source/cmTarget.h
+++ b/Source/cmTarget.h
@@ -135,6 +135,7 @@ 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 AddSourceFile(cmSourceFile* sf);
   std::vector<std::string> const& GetObjectLibraries() const

http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=44e4ccd7af4fe3771f1fa8688c71bf6c27ae2ec6
commit 44e4ccd7af4fe3771f1fa8688c71bf6c27ae2ec6
Author:     Stephen Kelly <steveire at gmail.com>
AuthorDate: Wed Feb 26 13:26:05 2014 +0100
Commit:     Stephen Kelly <steveire at gmail.com>
CommitDate: Wed Mar 19 16:37:33 2014 +0100

    cmSourceFileLocation: Make copyable and assignable.
    
    This allows using it in containers and algorithms.

diff --git a/Source/cmSourceFileLocation.cxx b/Source/cmSourceFileLocation.cxx
index 30a53cb..3e78b29 100644
--- a/Source/cmSourceFileLocation.cxx
+++ b/Source/cmSourceFileLocation.cxx
@@ -16,6 +16,42 @@
 #include "cmGlobalGenerator.h"
 #include "cmSystemTools.h"
 
+#include "assert.h"
+
+//----------------------------------------------------------------------------
+cmSourceFileLocation::cmSourceFileLocation()
+  : Makefile(0), AmbiguousDirectory(true), AmbiguousExtension(true)
+{
+
+}
+
+//----------------------------------------------------------------------------
+cmSourceFileLocation::cmSourceFileLocation(const cmSourceFileLocation& loc)
+  : Makefile(loc.Makefile)
+{
+  this->AmbiguousDirectory = loc.AmbiguousDirectory;
+  this->AmbiguousExtension = loc.AmbiguousExtension;
+  this->Directory = loc.Directory;
+  this->Name = loc.Name;
+}
+
+//----------------------------------------------------------------------------
+cmSourceFileLocation&
+cmSourceFileLocation::operator=(const cmSourceFileLocation& loc)
+{
+  if(this == &loc)
+    {
+    return *this;
+    }
+  this->Makefile = loc.Makefile;
+  this->AmbiguousDirectory = loc.AmbiguousDirectory;
+  this->AmbiguousExtension = loc.AmbiguousExtension;
+  this->Directory = loc.Directory;
+  this->Name = loc.Name;
+  this->UpdateExtension(this->Name);
+  return *this;
+}
+
 //----------------------------------------------------------------------------
 cmSourceFileLocation
 ::cmSourceFileLocation(cmMakefile const* mf, const std::string& name)
@@ -59,6 +95,7 @@ void cmSourceFileLocation::Update(cmSourceFileLocation const& loc)
 //----------------------------------------------------------------------------
 void cmSourceFileLocation::DirectoryUseSource()
 {
+  assert(this->Makefile);
   if(this->AmbiguousDirectory)
     {
     this->Directory =
@@ -71,6 +108,7 @@ void cmSourceFileLocation::DirectoryUseSource()
 //----------------------------------------------------------------------------
 void cmSourceFileLocation::DirectoryUseBinary()
 {
+  assert(this->Makefile);
   if(this->AmbiguousDirectory)
     {
     this->Directory =
@@ -83,6 +121,7 @@ void cmSourceFileLocation::DirectoryUseBinary()
 //----------------------------------------------------------------------------
 void cmSourceFileLocation::UpdateExtension(const std::string& name)
 {
+  assert(this->Makefile);
   // Check the extension.
   std::string ext = cmSystemTools::GetFilenameLastExtension(name);
   if(!ext.empty()) { ext = ext.substr(1); }
@@ -152,6 +191,7 @@ bool
 cmSourceFileLocation
 ::MatchesAmbiguousExtension(cmSourceFileLocation const& loc) const
 {
+  assert(this->Makefile);
   // This location's extension is not ambiguous but loc's extension
   // is.  See if the names match as-is.
   if(this->Name == loc.Name)
@@ -188,6 +228,7 @@ cmSourceFileLocation
 //----------------------------------------------------------------------------
 bool cmSourceFileLocation::Matches(cmSourceFileLocation const& loc)
 {
+  assert(this->Makefile);
   if(this->AmbiguousExtension && loc.AmbiguousExtension)
     {
     // Both extensions are ambiguous.  Since only the old fixed set of
diff --git a/Source/cmSourceFileLocation.h b/Source/cmSourceFileLocation.h
index c83e8c0..82a62ab 100644
--- a/Source/cmSourceFileLocation.h
+++ b/Source/cmSourceFileLocation.h
@@ -34,6 +34,9 @@ public:
    * instance with an initial name.
    */
   cmSourceFileLocation(cmMakefile const* mf, const std::string& name);
+  cmSourceFileLocation();
+  cmSourceFileLocation(const cmSourceFileLocation& loc);
+  cmSourceFileLocation& operator=(const cmSourceFileLocation& loc);
 
   /**
    * Return whether the givne source file location could refers to the

http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=9e559cf591396511fbc38d2bbdebf6b70126c80a
commit 9e559cf591396511fbc38d2bbdebf6b70126c80a
Author:     Stephen Kelly <steveire at gmail.com>
AuthorDate: Mon Mar 17 16:54:11 2014 +0100
Commit:     Stephen Kelly <steveire at gmail.com>
CommitDate: Wed Mar 19 16:37:32 2014 +0100

    cmTarget: Rename AddSource method for backward compatibility.
    
    Add a new AddSource method for future use.

diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx
index d4eb85b..f93fc12 100644
--- a/Source/cmGlobalXCodeGenerator.cxx
+++ b/Source/cmGlobalXCodeGenerator.cxx
@@ -412,7 +412,7 @@ cmGlobalXCodeGenerator::AddExtraTargets(cmLocalGenerator* root,
   std::string listfile = mf->GetStartDirectory();
   listfile += "/";
   listfile += "CMakeLists.txt";
-  allbuild->AddSource(listfile.c_str());
+  allbuild->AddSourceCMP0049(listfile.c_str());
 
   // Add XCODE depend helper
   std::string dir = mf->GetCurrentOutputDirectory();
@@ -495,7 +495,7 @@ cmGlobalXCodeGenerator::AddExtraTargets(cmLocalGenerator* root,
       listfile = lg->GetMakefile()->GetStartDirectory();
       listfile += "/";
       listfile += "CMakeLists.txt";
-      target.AddSource(listfile.c_str());
+      target.AddSourceCMP0049(listfile.c_str());
       }
     }
 }
diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx
index 58625fb..c12a5cd 100644
--- a/Source/cmMakefile.cxx
+++ b/Source/cmMakefile.cxx
@@ -1258,7 +1258,7 @@ cmMakefile::AddUtilityCommand(const std::string& utilityName,
                                  commandLines, comment,
                                  workingDirectory, no_replace,
                                  escapeOldStyle);
-  cmSourceFile* sf = target->AddSource(force);
+  cmSourceFile* sf = target->AddSourceCMP0049(force);
 
   // The output is not actually created so mark it symbolic.
   if(sf)
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index a7c4488..835aaad 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -587,13 +587,13 @@ void cmTarget::AddSources(std::vector<std::string> const& srcs)
       }
     else
       {
-      this->AddSource(src);
+      this->AddSourceCMP0049(src);
       }
     }
 }
 
 //----------------------------------------------------------------------------
-cmSourceFile* cmTarget::AddSource(const std::string& s)
+cmSourceFile* cmTarget::AddSourceCMP0049(const std::string& s)
 {
   std::string src = s;
 
@@ -632,7 +632,12 @@ cmSourceFile* cmTarget::AddSource(const std::string& s)
         }
       }
     }
+  return this->AddSource(src);
+}
 
+//----------------------------------------------------------------------------
+cmSourceFile* cmTarget::AddSource(const std::string& src)
+{
   cmSourceFile* sf = this->Makefile->GetOrCreateSource(src);
   this->AddSourceFile(sf);
   return sf;
diff --git a/Source/cmTarget.h b/Source/cmTarget.h
index 3ef853b..e385443 100644
--- a/Source/cmTarget.h
+++ b/Source/cmTarget.h
@@ -146,6 +146,7 @@ public:
    * Add sources to the target.
    */
   void AddSources(std::vector<std::string> const& srcs);
+  cmSourceFile* AddSourceCMP0049(const std::string& src);
   cmSourceFile* AddSource(const std::string& src);
 
   enum LinkLibraryType {GENERAL, DEBUG, OPTIMIZED};

http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=bdcc3f1e0ec02bdeed38e0cb6fa8682104f0d946
commit bdcc3f1e0ec02bdeed38e0cb6fa8682104f0d946
Author:     Stephen Kelly <steveire at gmail.com>
AuthorDate: Wed Mar 12 12:29:58 2014 +0100
Commit:     Stephen Kelly <steveire at gmail.com>
CommitDate: Wed Mar 19 16:37:32 2014 +0100

    cmTarget: Use GetSourceFiles for languages.

diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index 17c8a4d..a7c4488 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -4844,8 +4844,10 @@ bool cmTarget::IsLinkInterfaceDependentNumberMaxProperty(const std::string &p,
 //----------------------------------------------------------------------------
 void cmTarget::GetLanguages(std::set<std::string>& languages) const
 {
+  std::vector<cmSourceFile*> sourceFiles;
+  this->GetSourceFiles(sourceFiles);
   for(std::vector<cmSourceFile*>::const_iterator
-        i = this->SourceFiles.begin(); i != this->SourceFiles.end(); ++i)
+        i = sourceFiles.begin(); i != sourceFiles.end(); ++i)
     {
     const std::string& lang = (*i)->GetLanguage();
     if(!lang.empty())

http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=96e6f5cbc0511444cd3afce9301907284b4664b2
commit 96e6f5cbc0511444cd3afce9301907284b4664b2
Author:     Stephen Kelly <steveire at gmail.com>
AuthorDate: Tue Mar 18 17:46:37 2014 +0100
Commit:     Stephen Kelly <steveire at gmail.com>
CommitDate: Wed Mar 19 16:37:32 2014 +0100

    cmGeneratorTarget: Compute the object directory early.
    
    Ensure it is populated before tracing dependencies.

diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx
index 5b6d729..07637b3 100644
--- a/Source/cmGlobalGenerator.cxx
+++ b/Source/cmGlobalGenerator.cxx
@@ -1407,6 +1407,7 @@ void cmGlobalGenerator::CreateGeneratorTargets(cmMakefile *mf)
     {
     cmTarget* t = &ti->second;
     cmGeneratorTarget* gt = new cmGeneratorTarget(t);
+    this->ComputeTargetObjectDirectory(gt);
     this->GeneratorTargets[t] = gt;
     generatorTargets[t] = gt;
     }
@@ -1449,7 +1450,6 @@ void cmGlobalGenerator::ComputeGeneratorTargetObjects()
         continue;
         }
       cmGeneratorTarget* gt = ti->second;
-      this->ComputeTargetObjectDirectory(gt);
       gt->LookupObjectLibraries();
       this->ComputeTargetObjects(gt);
       }

-----------------------------------------------------------------------

Summary of changes:
 Help/command/add_executable.rst                    |    7 +-
 Help/command/add_library.rst                       |    6 +-
 Help/command/string.rst                            |    5 +
 Help/manual/cmake-generator-expressions.7.rst      |    3 +
 Help/manual/cmake-policies.7.rst                   |    1 +
 Help/policy/CMP0051.rst                            |   24 ++
 Help/release/dev/file-GENERATE-TARGET_OBJECTS.rst  |    6 +
 Help/release/dev/string-GENEX_STRIP.rst            |    6 +
 Help/release/dev/target-SOURCES-genex.rst          |   12 +
 Source/cmComputeTargetDepends.cxx                  |   29 ++
 Source/cmFLTKWrapUICommand.cxx                     |    2 +-
 Source/cmGeneratorExpressionEvaluator.cxx          |   64 ++++
 Source/cmGeneratorTarget.cxx                       |  128 ++++----
 Source/cmGeneratorTarget.h                         |    8 +-
 Source/cmGlobalGenerator.cxx                       |   56 +---
 Source/cmGlobalGenerator.h                         |    4 +-
 Source/cmGlobalVisualStudio8Generator.cxx          |    3 +-
 Source/cmGlobalXCodeGenerator.cxx                  |   18 +-
 Source/cmLocalGenerator.cxx                        |    4 +-
 Source/cmLocalVisualStudio6Generator.cxx           |    4 +-
 Source/cmLocalVisualStudio7Generator.cxx           |    4 +-
 Source/cmMakefile.cxx                              |    4 +-
 Source/cmMakefileTargetGenerator.cxx               |    3 -
 Source/cmNinjaTargetGenerator.cxx                  |   11 -
 Source/cmPolicies.cxx                              |    5 +
 Source/cmPolicies.h                                |    1 +
 Source/cmQtAutoGenerators.cxx                      |   17 +-
 Source/cmSourceFile.cxx                            |   12 +
 Source/cmSourceFile.h                              |    4 +
 Source/cmSourceFileLocation.cxx                    |   41 +++
 Source/cmSourceFileLocation.h                      |    3 +
 Source/cmStringCommand.cxx                         |   25 ++
 Source/cmStringCommand.h                           |    1 +
 Source/cmTarget.cxx                                |  312 ++++++++++++++++----
 Source/cmTarget.h                                  |    9 +-
 Source/cmVisualStudio10TargetGenerator.cxx         |   13 +
 Tests/GeneratorExpression/CMakeLists.txt           |   16 +-
 Tests/GeneratorExpression/check_object_files.cmake |   48 +++
 Tests/GeneratorExpression/objlib1.c                |    5 +
 Tests/GeneratorExpression/objlib2.c                |    5 +
 Tests/RunCMake/CMakeLists.txt                      |    1 +
 .../ObjectLibrary/BadSourceExpression1-stderr.txt  |    4 +-
 .../ObjectLibrary/BadSourceExpression2-stderr.txt  |    4 +
 .../ObjectLibrary/BadSourceExpression3-stderr.txt  |    4 +
 .../{export => TargetObjects}/CMakeLists.txt       |    0
 .../NoTarget-result.txt}                           |    0
 Tests/RunCMake/TargetObjects/NoTarget-stderr.txt   |    8 +
 Tests/RunCMake/TargetObjects/NoTarget.cmake        |    2 +
 .../NotObjlibTarget-result.txt}                    |    0
 .../TargetObjects/NotObjlibTarget-stderr.txt       |    8 +
 Tests/RunCMake/TargetObjects/NotObjlibTarget.cmake |    4 +
 .../RunCMakeTest.cmake                             |    1 +
 .../RunCMake/{CMP0022 => TargetObjects}/empty.cpp  |    0
 Tests/StringFileTest/CMakeLists.txt                |    6 +
 54 files changed, 728 insertions(+), 243 deletions(-)
 create mode 100644 Help/policy/CMP0051.rst
 create mode 100644 Help/release/dev/file-GENERATE-TARGET_OBJECTS.rst
 create mode 100644 Help/release/dev/string-GENEX_STRIP.rst
 create mode 100644 Help/release/dev/target-SOURCES-genex.rst
 create mode 100644 Tests/GeneratorExpression/check_object_files.cmake
 create mode 100644 Tests/GeneratorExpression/objlib1.c
 create mode 100644 Tests/GeneratorExpression/objlib2.c
 copy Tests/RunCMake/{export => TargetObjects}/CMakeLists.txt (100%)
 copy Tests/RunCMake/{CMP0004/CMP0004-NEW-result.txt => TargetObjects/NoTarget-result.txt} (100%)
 create mode 100644 Tests/RunCMake/TargetObjects/NoTarget-stderr.txt
 create mode 100644 Tests/RunCMake/TargetObjects/NoTarget.cmake
 copy Tests/RunCMake/{CMP0004/CMP0004-NEW-result.txt => TargetObjects/NotObjlibTarget-result.txt} (100%)
 create mode 100644 Tests/RunCMake/TargetObjects/NotObjlibTarget-stderr.txt
 create mode 100644 Tests/RunCMake/TargetObjects/NotObjlibTarget.cmake
 copy Tests/RunCMake/{add_dependencies => TargetObjects}/RunCMakeTest.cmake (59%)
 copy Tests/RunCMake/{CMP0022 => TargetObjects}/empty.cpp (100%)


hooks/post-receive
-- 
CMake


More information about the Cmake-commits mailing list