Ver código fonte

Merge topic 'join-genex'

a7ba452 Add the JOIN generator expression.
96ec314 Make it possible for any genex to have arbitrary content at the end.
bd638ee Rename the method determining if a genex accepts arbitrary content.
dc742fe Extract the ProcessArbitraryContent method.
Brad King 12 anos atrás
pai
commit
3db29d2724

+ 2 - 0
Source/cmDocumentGeneratorExpressions.h

@@ -28,6 +28,8 @@
   "strings which contain a ',' for example.\n"                          \
   "  $<SEMICOLON>              = A literal ';'. Used to prevent "       \
   "list expansion on an argument with ';'.\n"                           \
+  "  $<JOIN:list,...>          = joins the list with the content of "   \
+  "\"...\"\n"                                                           \
   "  $<TARGET_NAME:...>        = Marks ... as being the name of a "     \
   "target.  This is required if exporting targets to multiple "         \
   "dependent export sets.  The '...' must be a literal name of a "      \

+ 106 - 48
Source/cmGeneratorExpressionEvaluator.cxx

@@ -51,7 +51,7 @@ struct cmGeneratorExpressionNode
 
   virtual bool RequiresLiteralInput() const { return false; }
 
-  virtual bool AcceptsSingleArbitraryContentParameter() const
+  virtual bool AcceptsArbitraryContentParameter() const
     { return false; }
 
   virtual int NumExpectedParameters() const { return 1; }
@@ -70,7 +70,7 @@ static const struct ZeroNode : public cmGeneratorExpressionNode
 
   virtual bool GeneratesContent() const { return false; }
 
-  virtual bool AcceptsSingleArbitraryContentParameter() const { return true; }
+  virtual bool AcceptsArbitraryContentParameter() const { return true; }
 
   std::string Evaluate(const std::vector<std::string> &,
                        cmGeneratorExpressionContext *,
@@ -87,7 +87,7 @@ static const struct OneNode : public cmGeneratorExpressionNode
 {
   OneNode() {}
 
-  virtual bool AcceptsSingleArbitraryContentParameter() const { return true; }
+  virtual bool AcceptsArbitraryContentParameter() const { return true; }
 
   std::string Evaluate(const std::vector<std::string> &,
                        cmGeneratorExpressionContext *,
@@ -307,6 +307,34 @@ static const struct ConfigurationTestNode : public cmGeneratorExpressionNode
 } configurationTestNode;
 
 
+static const struct JoinNode : public cmGeneratorExpressionNode
+{
+  JoinNode() {}
+
+  virtual int NumExpectedParameters() const { return 2; }
+
+  virtual bool AcceptsArbitraryContentParameter() const { return true; }
+
+  std::string Evaluate(const std::vector<std::string> &parameters,
+                       cmGeneratorExpressionContext *,
+                       const GeneratorExpressionContent *,
+                       cmGeneratorExpressionDAGChecker *) const
+  {
+    std::string result;
+
+    std::vector<std::string> list;
+    cmSystemTools::ExpandListArgument(parameters.front(), list);
+    std::string sep;
+    for(std::vector<std::string>::const_iterator li = list.begin();
+      li != list.end(); ++li)
+      {
+      result += sep + *li;
+      sep = parameters[1];
+      }
+    return result;
+  }
+} joinNode;
+
 //----------------------------------------------------------------------------
 static const char* targetPropertyTransitiveWhitelist[] = {
     "INTERFACE_INCLUDE_DIRECTORIES"
@@ -600,7 +628,7 @@ static const struct TargetNameNode : public cmGeneratorExpressionNode
 
   virtual bool GeneratesContent() const { return true; }
 
-  virtual bool AcceptsSingleArbitraryContentParameter() const { return true; }
+  virtual bool AcceptsArbitraryContentParameter() const { return true; }
   virtual bool RequiresLiteralInput() const { return true; }
 
   std::string Evaluate(const std::vector<std::string> &parameters,
@@ -973,6 +1001,8 @@ cmGeneratorExpressionNode* GetNode(const std::string &identifier)
     return &installInterfaceNode;
   else if (identifier == "INSTALL_PREFIX")
     return &installPrefixNode;
+  else if (identifier == "JOIN")
+    return &joinNode;
   return 0;
 
 }
@@ -992,6 +1022,57 @@ std::string GeneratorExpressionContent::GetOriginalExpression() const
   return std::string(this->StartContent, this->ContentLength);
 }
 
+//----------------------------------------------------------------------------
+std::string GeneratorExpressionContent::ProcessArbitraryContent(
+    const cmGeneratorExpressionNode *node,
+    const std::string &identifier,
+    cmGeneratorExpressionContext *context,
+    cmGeneratorExpressionDAGChecker *dagChecker,
+    std::vector<std::vector<cmGeneratorExpressionEvaluator*> >::const_iterator
+    pit) const
+{
+  std::string result;
+
+  const
+  std::vector<std::vector<cmGeneratorExpressionEvaluator*> >::const_iterator
+                                      pend = this->ParamChildren.end();
+  for ( ; pit != pend; ++pit)
+    {
+    std::vector<cmGeneratorExpressionEvaluator*>::const_iterator it
+                                                            = pit->begin();
+    const std::vector<cmGeneratorExpressionEvaluator*>::const_iterator end
+                                                              = pit->end();
+    for ( ; it != end; ++it)
+      {
+      if (node->RequiresLiteralInput())
+        {
+        if ((*it)->GetType() != cmGeneratorExpressionEvaluator::Text)
+          {
+          reportError(context, this->GetOriginalExpression(),
+                "$<" + identifier + "> expression requires literal input.");
+          return std::string();
+          }
+        }
+      result += (*it)->Evaluate(context, dagChecker);
+      if (context->HadError)
+        {
+        return std::string();
+        }
+      }
+      if ((pit + 1) != pend)
+        {
+        result += ",";
+        }
+    }
+  if (node->RequiresLiteralInput())
+    {
+    std::vector<std::string> parameters;
+    parameters.push_back(result);
+    return node->Evaluate(parameters, context, this, dagChecker);
+    }
+  return result;
+}
+
 //----------------------------------------------------------------------------
 std::string GeneratorExpressionContent::Evaluate(
                             cmGeneratorExpressionContext *context,
@@ -1024,7 +1105,8 @@ std::string GeneratorExpressionContent::Evaluate(
 
   if (!node->GeneratesContent())
     {
-    if (node->AcceptsSingleArbitraryContentParameter())
+    if (node->NumExpectedParameters() == 1
+        && node->AcceptsArbitraryContentParameter())
       {
       if (this->ParamChildren.empty())
         {
@@ -1041,49 +1123,12 @@ std::string GeneratorExpressionContent::Evaluate(
     return std::string();
     }
 
-  if (node->AcceptsSingleArbitraryContentParameter())
+  if (node->NumExpectedParameters() == 1
+        && node->AcceptsArbitraryContentParameter())
     {
-    std::string result;
-    std::vector<std::vector<cmGeneratorExpressionEvaluator*> >::const_iterator
-                                        pit = this->ParamChildren.begin();
-    const
-    std::vector<std::vector<cmGeneratorExpressionEvaluator*> >::const_iterator
-                                        pend = this->ParamChildren.end();
-    for ( ; pit != pend; ++pit)
-      {
-      std::vector<cmGeneratorExpressionEvaluator*>::const_iterator it
-                                                              = pit->begin();
-      const std::vector<cmGeneratorExpressionEvaluator*>::const_iterator end
-                                                                = pit->end();
-      for ( ; it != end; ++it)
-        {
-        if (node->RequiresLiteralInput())
-          {
-          if ((*it)->GetType() != cmGeneratorExpressionEvaluator::Text)
-            {
-            reportError(context, this->GetOriginalExpression(),
-                  "$<" + identifier + "> expression requires literal input.");
-            return std::string();
-            }
-          }
-        result += (*it)->Evaluate(context, dagChecker);
-        if (context->HadError)
-          {
-          return std::string();
-          }
-        }
-      if ((pit + 1) != pend)
-        {
-        result += ",";
-        }
-      }
-    if (node->RequiresLiteralInput())
-      {
-      std::vector<std::string> parameters;
-      parameters.push_back(result);
-      return node->Evaluate(parameters, context, this, dagChecker);
-      }
-    return result;
+    return this->ProcessArbitraryContent(node, identifier, context,
+                                         dagChecker,
+                                         this->ParamChildren.begin());
     }
 
   std::vector<std::string> parameters;
@@ -1104,12 +1149,15 @@ std::string GeneratorExpressionContent::EvaluateParameters(
                                 cmGeneratorExpressionDAGChecker *dagChecker,
                                 std::vector<std::string> &parameters) const
 {
+  const int numExpected = node->NumExpectedParameters();
   {
   std::vector<std::vector<cmGeneratorExpressionEvaluator*> >::const_iterator
                                         pit = this->ParamChildren.begin();
   const
   std::vector<std::vector<cmGeneratorExpressionEvaluator*> >::const_iterator
                                         pend = this->ParamChildren.end();
+  const bool acceptsArbitraryContent
+                                  = node->AcceptsArbitraryContentParameter();
   for ( ; pit != pend; ++pit)
     {
     std::string parameter;
@@ -1126,10 +1174,20 @@ std::string GeneratorExpressionContent::EvaluateParameters(
         }
       }
     parameters.push_back(parameter);
+    if (acceptsArbitraryContent
+        && parameters.size() == (unsigned int)numExpected - 1)
+      {
+      assert(pit != pend);
+      std::string lastParam = this->ProcessArbitraryContent(node, identifier,
+                                                            context,
+                                                            dagChecker,
+                                                            pit + 1);
+      parameters.push_back(lastParam);
+      return std::string();
+      }
     }
   }
 
-  int numExpected = node->NumExpectedParameters();
   if ((numExpected != -1 && (unsigned int)numExpected != parameters.size()))
     {
     if (numExpected == 0)

+ 8 - 0
Source/cmGeneratorExpressionEvaluator.h

@@ -129,6 +129,14 @@ private:
                                  cmGeneratorExpressionDAGChecker *dagChecker,
                                  std::vector<std::string> &parameters) const;
 
+  std::string ProcessArbitraryContent(
+    const cmGeneratorExpressionNode *node,
+    const std::string &identifier,
+    cmGeneratorExpressionContext *context,
+    cmGeneratorExpressionDAGChecker *dagChecker,
+    std::vector<std::vector<cmGeneratorExpressionEvaluator*> >::const_iterator
+    pit) const;
+
 private:
   std::vector<cmGeneratorExpressionEvaluator*> IdentifierChildren;
   std::vector<std::vector<cmGeneratorExpressionEvaluator*> > ParamChildren;

+ 17 - 3
Tests/CompileDefinitions/compiletest.cpp

@@ -20,10 +20,16 @@ static const char very_fun_string[] = CMAKE_IS_REALLY;
 #endif
 
 enum {
-  StringLiteralTest1 = sizeof(CMakeStaticAssert<sizeof(CMAKE_IS_) == sizeof("Fun")>)
+  StringLiteralTest1 = sizeof(CMakeStaticAssert<sizeof(CMAKE_IS_) == sizeof("Fun")>),
 #ifndef NO_SPACES_IN_DEFINE_VALUES
-  ,
-  StringLiteralTest2 = sizeof(CMakeStaticAssert<sizeof(CMAKE_IS_REALLY) == sizeof("Very Fun")>)
+  StringLiteralTest2 = sizeof(CMakeStaticAssert<sizeof(CMAKE_IS_REALLY) == sizeof("Very Fun")>),
+#endif
+#ifdef TEST_GENERATOR_EXPRESSIONS
+  StringLiteralTest3 = sizeof(CMakeStaticAssert<sizeof(LETTER_LIST1) == sizeof("A,B,C,D")>),
+  StringLiteralTest4 = sizeof(CMakeStaticAssert<sizeof(LETTER_LIST2) == sizeof("A,,B,,C,,D")>),
+  StringLiteralTest5 = sizeof(CMakeStaticAssert<sizeof(LETTER_LIST3) == sizeof("A,-B,-C,-D")>),
+  StringLiteralTest6 = sizeof(CMakeStaticAssert<sizeof(LETTER_LIST4) == sizeof("A-,-B-,-C-,-D")>),
+  StringLiteralTest7 = sizeof(CMakeStaticAssert<sizeof(LETTER_LIST5) == sizeof("A-,B-,C-,D")>)
 #endif
 };
 
@@ -42,6 +48,14 @@ enum {
 #error Expected define expanded from list
 #endif
 
+#ifndef PREFIX_DEF1
+#error Expect PREFIX_DEF1
+#endif
+
+#ifndef PREFIX_DEF2
+#error Expect PREFIX_DEF2
+#endif
+
 // TEST_GENERATOR_EXPRESSIONS
 #endif
 

+ 6 - 0
Tests/CompileDefinitions/target_prop/CMakeLists.txt

@@ -13,6 +13,12 @@ set_property(TARGET target_prop_executable APPEND PROPERTY COMPILE_DEFINITIONS
     "$<1:CMAKE_IS_DECLARATIVE>"
     "$<0:GE_NOT_DEFINED>"
     "$<1:ARGUMENT;LIST>"
+    PREFIX_$<JOIN:DEF1;DEF2,;PREFIX_>
+    LETTER_LIST1=\"$<JOIN:A;B;C;D,,>\"
+    LETTER_LIST2=\"$<JOIN:A;B;C;D,,,>\"
+    LETTER_LIST3=\"$<JOIN:A;B;C;D,,->\"
+    LETTER_LIST4=\"$<JOIN:A;B;C;D,-,->\"
+    LETTER_LIST5=\"$<JOIN:A;B;C;D,-,>\"
 )
 
 set_property(TARGET target_prop_executable APPEND PROPERTY COMPILE_DEFINITIONS

+ 5 - 0
Tests/IncludeDirectories/TargetIncludeDirectories/CMakeLists.txt

@@ -123,3 +123,8 @@ target_link_libraries(lib5 libbad libgood)
 target_include_directories(lib5
   BEFORE PRIVATE $<TARGET_PROPERTY:libgood,INTERFACE_INCLUDE_DIRECTORIES>
 )
+
+file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/prefix_foo/prefix_bar/prefix_bat")
+file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/prefix_foo/prefix_bar/prefix_bat/prefix_foo_bar_bat.h" "// prefix_foo_bar_bat.h\n")
+
+target_include_directories(TargetIncludeDirectories PRIVATE "${CMAKE_CURRENT_BINARY_DIR}/prefix_$<JOIN:foo;bar;bat,/prefix_>")

+ 1 - 0
Tests/IncludeDirectories/TargetIncludeDirectories/main.cpp

@@ -10,6 +10,7 @@
 #include "arguments.h"
 #include "list.h"
 #include "target.h"
+#include "prefix_foo_bar_bat.h"
 
 int main(int, char**)
 {