Browse Source

cmTarget: Include TARGET_OBJECTS genex in target SOURCES property.

Add policy CMP0051 to control this behavior.
Stephen Kelly 11 years ago
parent
commit
5702e10677

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

@@ -102,3 +102,4 @@ All Policies
    /policy/CMP0048
    /policy/CMP0049
    /policy/CMP0050
+   /policy/CMP0051

+ 24 - 0
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.

+ 7 - 0
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``.

+ 5 - 0
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,1,0, cmPolicies::WARN);
 }
 
 cmPolicies::~cmPolicies()

+ 1 - 0
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.
      *

+ 58 - 11
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(),

+ 1 - 0
Tests/RunCMake/CMP0051/CMP0051-NEW-result.txt

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

+ 1 - 0
Tests/RunCMake/CMP0051/CMP0051-NEW-stderr.txt

@@ -0,0 +1 @@
+^Sources: "empty.cpp;\$<TARGET_OBJECTS:objects>"$

+ 10 - 0
Tests/RunCMake/CMP0051/CMP0051-NEW.cmake

@@ -0,0 +1,10 @@
+
+cmake_policy(SET CMP0051 NEW)
+
+add_library(objects OBJECT empty.cpp)
+
+add_library(empty empty.cpp $<TARGET_OBJECTS:objects>)
+
+get_target_property(srcs empty SOURCES)
+
+message("Sources: \"${srcs}\"")

+ 1 - 0
Tests/RunCMake/CMP0051/CMP0051-OLD-result.txt

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

+ 1 - 0
Tests/RunCMake/CMP0051/CMP0051-OLD-stderr.txt

@@ -0,0 +1 @@
+^Sources: "empty.cpp"$

+ 10 - 0
Tests/RunCMake/CMP0051/CMP0051-OLD.cmake

@@ -0,0 +1,10 @@
+
+cmake_policy(SET CMP0051 OLD)
+
+add_library(objects OBJECT empty.cpp)
+
+add_library(empty empty.cpp $<TARGET_OBJECTS:objects>)
+
+get_target_property(srcs empty SOURCES)
+
+message("Sources: \"${srcs}\"")

+ 1 - 0
Tests/RunCMake/CMP0051/CMP0051-WARN-result.txt

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

+ 15 - 0
Tests/RunCMake/CMP0051/CMP0051-WARN-stderr.txt

@@ -0,0 +1,15 @@
+CMake Warning \(dev\) at CMP0051-WARN.cmake:6 \(get_target_property\):
+  Policy CMP0051 is not set: List TARGET_OBJECTS in SOURCES target property.
+  Run "cmake --help-policy CMP0051" for policy details.  Use the cmake_policy
+  command to set the policy and suppress this warning.
+
+  Target "empty" 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.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)
+This warning is for project developers.  Use -Wno-dev to suppress it.
+
+Sources: "empty.cpp"$

+ 8 - 0
Tests/RunCMake/CMP0051/CMP0051-WARN.cmake

@@ -0,0 +1,8 @@
+
+add_library(objects OBJECT empty.cpp)
+
+add_library(empty empty.cpp $<TARGET_OBJECTS:objects>)
+
+get_target_property(srcs empty SOURCES)
+
+message("Sources: \"${srcs}\"")

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

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

+ 5 - 0
Tests/RunCMake/CMP0051/RunCMakeTest.cmake

@@ -0,0 +1,5 @@
+include(RunCMake)
+
+run_cmake(CMP0051-OLD)
+run_cmake(CMP0051-NEW)
+run_cmake(CMP0051-WARN)

+ 7 - 0
Tests/RunCMake/CMP0051/empty.cpp

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

+ 1 - 0
Tests/RunCMake/CMakeLists.txt

@@ -34,6 +34,7 @@ add_RunCMake_test(CMP0045)
 add_RunCMake_test(CMP0046)
 add_RunCMake_test(CMP0049)
 add_RunCMake_test(CMP0050)
+add_RunCMake_test(CMP0051)
 add_RunCMake_test(CTest)
 if(UNIX AND "${CMAKE_GENERATOR}" MATCHES "Unix Makefiles")
   add_RunCMake_test(CompilerChange)