[Cmake-commits] CMake branch, next, updated. v3.3.1-2253-gc9b7376

Brad King brad.king at kitware.com
Mon Aug 17 10:55:40 EDT 2015


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  c9b737643982b4db614a73518fd5c3773cab6be3 (commit)
       via  e66a7d6973fa58bb3bf37b540f67e2c33bb9fae2 (commit)
      from  9fe5cfd082e84c09aa63aea6aff4bad407e22033 (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=c9b737643982b4db614a73518fd5c3773cab6be3
commit c9b737643982b4db614a73518fd5c3773cab6be3
Merge: 9fe5cfd e66a7d6
Author:     Brad King <brad.king at kitware.com>
AuthorDate: Mon Aug 17 10:55:39 2015 -0400
Commit:     CMake Topic Stage <kwrobot at kitware.com>
CommitDate: Mon Aug 17 10:55:39 2015 -0400

    Merge topic 'OUTPUT_NAME-genex-no-recursion' into next
    
    e66a7d69 cmGeneratorTarget: Avoid recursion in GetOutputName method


http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=e66a7d6973fa58bb3bf37b540f67e2c33bb9fae2
commit e66a7d6973fa58bb3bf37b540f67e2c33bb9fae2
Author:     Robert Goulet <robert.goulet at autodesk.com>
AuthorDate: Fri Aug 14 20:35:58 2015 +0000
Commit:     Brad King <brad.king at kitware.com>
CommitDate: Mon Aug 17 10:43:08 2015 -0400

    cmGeneratorTarget: Avoid recursion in GetOutputName method
    
    Since support for generator expressions was added to OUTPUT_NAME it is
    possible for project code to cause recursion in this method by using a
    $<TARGET_FILE> genex.  Detect and reject such cases.

diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx
index 299c112..7d4bb67 100644
--- a/Source/cmGeneratorTarget.cxx
+++ b/Source/cmGeneratorTarget.cxx
@@ -270,48 +270,70 @@ const char *cmGeneratorTarget::GetProperty(const std::string& prop) const
 std::string cmGeneratorTarget::GetOutputName(const std::string& config,
                                              bool implib) const
 {
-  std::vector<std::string> props;
-  std::string type = this->Target->GetOutputTargetType(implib);
-  std::string configUpper = cmSystemTools::UpperCase(config);
-  if(!type.empty() && !configUpper.empty())
-    {
-    // <ARCHIVE|LIBRARY|RUNTIME>_OUTPUT_NAME_<CONFIG>
-    props.push_back(type + "_OUTPUT_NAME_" + configUpper);
-    }
-  if(!type.empty())
+  // Lookup/compute/cache the output name for this configuration.
+  cmGeneratorTarget::OutputNameMapType::iterator i =
+    this->OutputNameMap.find(config);
+  if(i == this->OutputNameMap.end())
     {
-    // <ARCHIVE|LIBRARY|RUNTIME>_OUTPUT_NAME
-    props.push_back(type + "_OUTPUT_NAME");
-    }
-  if(!configUpper.empty())
-    {
-    // OUTPUT_NAME_<CONFIG>
-    props.push_back("OUTPUT_NAME_" + configUpper);
-    // <CONFIG>_OUTPUT_NAME
-    props.push_back(configUpper + "_OUTPUT_NAME");
-    }
-  // OUTPUT_NAME
-  props.push_back("OUTPUT_NAME");
+    // Add empty name in map to detect potential recursion.
+    OutputNameMapType::value_type entry(config, "");
+    i = this->OutputNameMap.insert(entry).first;
 
-  std::string outName;
-  for(std::vector<std::string>::const_iterator i = props.begin();
-      i != props.end(); ++i)
-    {
-    if (const char* outNameProp = this->Target->GetProperty(*i))
+    // Compute output name.
+    std::vector<std::string> props;
+    std::string type = this->Target->GetOutputTargetType(implib);
+    std::string configUpper = cmSystemTools::UpperCase(config);
+    if(!type.empty() && !configUpper.empty())
       {
-      outName = outNameProp;
-      break;
+      // <ARCHIVE|LIBRARY|RUNTIME>_OUTPUT_NAME_<CONFIG>
+      props.push_back(type + "_OUTPUT_NAME_" + configUpper);
+      }
+    if(!type.empty())
+      {
+      // <ARCHIVE|LIBRARY|RUNTIME>_OUTPUT_NAME
+      props.push_back(type + "_OUTPUT_NAME");
+      }
+    if(!configUpper.empty())
+      {
+      // OUTPUT_NAME_<CONFIG>
+      props.push_back("OUTPUT_NAME_" + configUpper);
+      // <CONFIG>_OUTPUT_NAME
+      props.push_back(configUpper + "_OUTPUT_NAME");
+      }
+    // OUTPUT_NAME
+    props.push_back("OUTPUT_NAME");
+
+    std::string outName;
+    for(std::vector<std::string>::const_iterator it = props.begin();
+        it != props.end(); ++it)
+      {
+      if (const char* outNameProp = this->Target->GetProperty(*it))
+        {
+        outName = outNameProp;
+        break;
+        }
       }
-    }
 
-  if (outName.empty())
+    if(outName.empty())
+      {
+      outName = this->GetName();
+      }
+
+    // Now evaluate genex and update the previously-prepared map entry.
+    cmGeneratorExpression ge;
+    cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(outName);
+    i->second = cge->Evaluate(this->Makefile, config);
+    }
+  else if(i->second.empty())
     {
-    outName = this->GetName();
+    // An empty map entry indicates we have been called recursively
+    // from the above block.
+    this->Makefile->GetCMakeInstance()->IssueMessage(
+      cmake::FATAL_ERROR,
+      "Target '" + this->GetName() + "' OUTPUT_NAME depends on itself.",
+      this->Target->GetBacktrace());
     }
-
-  cmGeneratorExpression ge;
-  cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(outName);
-  return cge->Evaluate(this->Makefile, config);
+  return i->second;
 }
 
 //----------------------------------------------------------------------------
diff --git a/Source/cmGeneratorTarget.h b/Source/cmGeneratorTarget.h
index 68e7a8a..a603975 100644
--- a/Source/cmGeneratorTarget.h
+++ b/Source/cmGeneratorTarget.h
@@ -375,6 +375,9 @@ private:
   };
   mutable std::map<std::string, LinkImplClosure> LinkImplClosureMap;
 
+  typedef std::map<std::string, std::string> OutputNameMapType;
+  mutable OutputNameMapType OutputNameMap;
+
 public:
   std::vector<cmTarget const*> const&
     GetLinkImplementationClosure(const std::string& config) const;
diff --git a/Tests/RunCMake/GeneratorExpression/OUTPUT_NAME-recursion-result.txt b/Tests/RunCMake/GeneratorExpression/OUTPUT_NAME-recursion-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/OUTPUT_NAME-recursion-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/GeneratorExpression/OUTPUT_NAME-recursion-stderr.txt b/Tests/RunCMake/GeneratorExpression/OUTPUT_NAME-recursion-stderr.txt
new file mode 100644
index 0000000..bf592e7
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/OUTPUT_NAME-recursion-stderr.txt
@@ -0,0 +1,4 @@
+CMake Error at OUTPUT_NAME-recursion.cmake:[0-9]+ \(add_executable\):
+  Target 'empty1' OUTPUT_NAME depends on itself.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/GeneratorExpression/OUTPUT_NAME-recursion.cmake b/Tests/RunCMake/GeneratorExpression/OUTPUT_NAME-recursion.cmake
new file mode 100644
index 0000000..5cb8050
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/OUTPUT_NAME-recursion.cmake
@@ -0,0 +1,3 @@
+enable_language(C)
+add_executable(empty1 empty.c)
+set_property(TARGET empty1 PROPERTY OUTPUT_NAME $<TARGET_FILE_NAME:empty1>)
diff --git a/Tests/RunCMake/GeneratorExpression/RunCMakeTest.cmake b/Tests/RunCMake/GeneratorExpression/RunCMakeTest.cmake
index 21fc851..0679024 100644
--- a/Tests/RunCMake/GeneratorExpression/RunCMakeTest.cmake
+++ b/Tests/RunCMake/GeneratorExpression/RunCMakeTest.cmake
@@ -26,6 +26,7 @@ run_cmake(COMPILE_LANGUAGE-add_library)
 run_cmake(COMPILE_LANGUAGE-add_test)
 run_cmake(COMPILE_LANGUAGE-unknown-lang)
 run_cmake(TARGET_FILE-recursion)
+run_cmake(OUTPUT_NAME-recursion)
 
 run_cmake(ImportedTarget-TARGET_PDB_FILE)
 if(LINKER_SUPPORTS_PDB)
diff --git a/Tests/RunCMake/GeneratorExpression/TARGET_FILE-recursion.cmake b/Tests/RunCMake/GeneratorExpression/TARGET_FILE-recursion.cmake
index 7633be1..e780103 100644
--- a/Tests/RunCMake/GeneratorExpression/TARGET_FILE-recursion.cmake
+++ b/Tests/RunCMake/GeneratorExpression/TARGET_FILE-recursion.cmake
@@ -1,3 +1,4 @@
 enable_language(C)
 add_executable(empty1 empty.c)
+set_property(TARGET empty1 PROPERTY OUTPUT_NAME $<TARGET_FILE_NAME:empty1>)
 set_property(TARGET empty1 PROPERTY RUNTIME_OUTPUT_DIRECTORY $<TARGET_FILE_DIR:empty1>)

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

Summary of changes:
 Source/cmGeneratorTarget.cxx                       |   92 ++++++++++++--------
 Source/cmGeneratorTarget.h                         |    3 +
 .../OUTPUT_NAME-recursion-result.txt}              |    0
 .../OUTPUT_NAME-recursion-stderr.txt               |    4 +
 .../OUTPUT_NAME-recursion.cmake                    |    3 +
 .../GeneratorExpression/RunCMakeTest.cmake         |    1 +
 .../TARGET_FILE-recursion.cmake                    |    1 +
 7 files changed, 69 insertions(+), 35 deletions(-)
 copy Tests/RunCMake/{CMP0004/CMP0004-NEW-result.txt => GeneratorExpression/OUTPUT_NAME-recursion-result.txt} (100%)
 create mode 100644 Tests/RunCMake/GeneratorExpression/OUTPUT_NAME-recursion-stderr.txt
 create mode 100644 Tests/RunCMake/GeneratorExpression/OUTPUT_NAME-recursion.cmake


hooks/post-receive
-- 
CMake


More information about the Cmake-commits mailing list