Просмотр исходного кода

cmTarget: Fix listing of source files at configure-time.

Since commit e5da9e51 (cmTarget: Allow any generator expression in
SOURCES property., 2014-03-18), source files are computed by
true evaluation of generator expressions, including TARGET_OBJECTS.
This evaluation requires the presence of cmGeneratorTarget objects
since commit bf98cc25 (Genex: Evaluate TARGET_OBJECTS as a normal
expression., 2014-02-26).

Ensure that we don't attempt to evaluate the TARGET_OBJECTS generator
expression at configure-time, as can happen if CMP0024 or CMP0026
are OLD.  Use old-style parsing of the source item to extract
object target names in that case.

Avoid calling GetProperty("SOURCES") to bypass warnings from CMP0051.
Refactor existing logic in GetLanguages which is similar in intent to
the new GetSourceFiles code.
Stephen Kelly 11 лет назад
Родитель
Сommit
b8af201168

+ 72 - 20
Source/cmTarget.cxx

@@ -647,6 +647,38 @@ void cmTarget::GetSourceFiles(std::vector<std::string> &files,
 {
   assert(this->GetType() != INTERFACE_LIBRARY);
 
+  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.
+
+    typedef cmTargetInternals::TargetPropertyEntry
+                                TargetPropertyEntry;
+    for(std::vector<TargetPropertyEntry*>::const_iterator
+          i = this->Internal->SourceEntries.begin();
+        i != this->Internal->SourceEntries.end(); ++i)
+      {
+      std::string entry = (*i)->ge->GetInput();
+
+      std::vector<std::string> items;
+      cmSystemTools::ExpandListArgument(entry, items);
+      for (std::vector<std::string>::const_iterator
+          li = items.begin(); li != items.end(); ++li)
+        {
+        if(cmHasLiteralPrefix(*li, "$<TARGET_OBJECTS:") &&
+            (*li)[li->size() - 1] == '>')
+          {
+          continue;
+          }
+        files.push_back(*li);
+        }
+      }
+    return;
+    }
+
   std::vector<std::string> debugProperties;
   const char *debugProp =
               this->Makefile->GetDefinition("CMAKE_DEBUG_TARGET_PROPERTIES");
@@ -5342,6 +5374,45 @@ bool cmTarget::IsLinkInterfaceDependentNumberMaxProperty(const std::string &p,
                                  config);
 }
 
+//----------------------------------------------------------------------------
+void
+cmTarget::GetObjectLibrariesCMP0026(std::vector<cmTarget*>& objlibs) const
+{
+  // 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.
+  typedef cmTargetInternals::TargetPropertyEntry
+                              TargetPropertyEntry;
+  for(std::vector<TargetPropertyEntry*>::const_iterator
+        i = this->Internal->SourceEntries.begin();
+      i != this->Internal->SourceEntries.end(); ++i)
+    {
+    std::string entry = (*i)->ge->GetInput();
+
+    std::vector<std::string> files;
+    cmSystemTools::ExpandListArgument(entry, files);
+    for (std::vector<std::string>::const_iterator
+        li = files.begin(); li != files.end(); ++li)
+      {
+      if(cmHasLiteralPrefix(*li, "$<TARGET_OBJECTS:") &&
+          (*li)[li->size() - 1] == '>')
+        {
+        std::string objLibName = li->substr(17, li->size()-18);
+
+        if (cmGeneratorExpression::Find(objLibName) != std::string::npos)
+          {
+          continue;
+          }
+        cmTarget *objLib = this->Makefile->FindTargetToUse(objLibName.c_str());
+        assert(objLib);
+        objlibs.push_back(objLib);
+        }
+      }
+    }
+}
+
 //----------------------------------------------------------------------------
 void cmTarget::GetLanguages(std::set<std::string>& languages,
                             const std::string& config,
@@ -5363,26 +5434,7 @@ void cmTarget::GetLanguages(std::set<std::string>& languages,
   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);
-          }
-        }
-      }
+    this->GetObjectLibrariesCMP0026(objectLibraries);
     }
   else
     {

+ 2 - 0
Source/cmTarget.h

@@ -241,6 +241,8 @@ public:
 
   bool IsImported() const {return this->IsImportedTarget;}
 
+  void GetObjectLibrariesCMP0026(std::vector<cmTarget*>& objlibs) const;
+
   /** The link interface specifies transitive library dependencies and
       other information needed by targets that link to this target.  */
   struct LinkInterface

+ 1 - 0
Tests/RunCMake/TargetSources/CMP0026-LOCATION-result.txt

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

+ 1 - 0
Tests/RunCMake/TargetSources/CMP0026-LOCATION-stderr.txt

@@ -0,0 +1 @@
+^$

+ 13 - 0
Tests/RunCMake/TargetSources/CMP0026-LOCATION.cmake

@@ -0,0 +1,13 @@
+
+cmake_policy(SET CMP0026 OLD)
+
+add_library(objlib OBJECT
+    empty_1.cpp
+)
+
+add_executable(my_exe
+    empty_2.cpp
+    $<TARGET_OBJECTS:objlib>
+)
+
+get_target_property( loc my_exe LOCATION)

+ 1 - 1
Tests/RunCMake/TargetSources/CMakeLists.txt

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

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

@@ -7,3 +7,5 @@ if(RunCMake_GENERATOR MATCHES Xcode
 else()
   run_cmake(OriginDebug)
 endif()
+
+run_cmake(CMP0026-LOCATION)