Selaa lähdekoodia

Genex: Add $<REMOVE_DUPLICATES:list>

Sebastian Lipponer 6 vuotta sitten
vanhempi
sitoutus
abbb8a7b1d

+ 2 - 0
Help/manual/cmake-generator-expressions.7.rst

@@ -88,6 +88,8 @@ String Comparisons
 ``$<IN_LIST:string,list>``
   ``1`` if ``string`` is member of the semicolon-separated ``list``, else ``0``.
   Uses case-sensitive comparisons.
+``$<REMOVE_DUPLICATES:list>``
+  Removes duplicated items in the given ``list``.
 ``$<VERSION_LESS:v1,v2>``
   ``1`` if ``v1`` is a version less than ``v2``, else ``0``.
 ``$<VERSION_GREATER:v1,v2>``

+ 30 - 0
Source/cmGeneratorExpressionNode.cxx

@@ -15,6 +15,7 @@
 #include "cmMessageType.h"
 #include "cmOutputConverter.h"
 #include "cmPolicies.h"
+#include "cmRange.h"
 #include "cmState.h"
 #include "cmStateSnapshot.h"
 #include "cmStateTypes.h"
@@ -326,6 +327,34 @@ static const struct InListNode : public cmGeneratorExpressionNode
   }
 } inListNode;
 
+static const struct RemoveDuplicatesNode : public cmGeneratorExpressionNode
+{
+  RemoveDuplicatesNode() {} // NOLINT(modernize-use-equals-default)
+
+  int NumExpectedParameters() const override { return 1; }
+
+  std::string Evaluate(
+    const std::vector<std::string>& parameters,
+    cmGeneratorExpressionContext* context,
+    const GeneratorExpressionContent* content,
+    cmGeneratorExpressionDAGChecker* /*dagChecker*/) const override
+  {
+    if (parameters.size() != 1) {
+      reportError(
+        context, content->GetOriginalExpression(),
+        "$<REMOVE_DUPLICATES:...> expression requires one parameter");
+    }
+
+    std::vector<std::string> values;
+    cmSystemTools::ExpandListArgument(parameters.front(), values, true);
+
+    auto valuesEnd = cmRemoveDuplicates(values);
+    auto valuesBegin = values.cbegin();
+    return cmJoin(cmMakeRange(valuesBegin, valuesEnd), ";");
+  }
+
+} removeDuplicatesNode;
+
 static const struct TargetExistsNode : public cmGeneratorExpressionNode
 {
   TargetExistsNode() {} // NOLINT(modernize-use-equals-default)
@@ -2158,6 +2187,7 @@ const cmGeneratorExpressionNode* cmGeneratorExpressionNode::GetNode(
     { "STREQUAL", &strEqualNode },
     { "EQUAL", &equalNode },
     { "IN_LIST", &inListNode },
+    { "REMOVE_DUPLICATES", &removeDuplicatesNode },
     { "LOWER_CASE", &lowerCaseNode },
     { "UPPER_CASE", &upperCaseNode },
     { "MAKE_C_IDENTIFIER", &makeCIdentifierNode },

+ 6 - 0
Tests/RunCMake/GeneratorExpression/REMOVE_DUPLICATES-1-check.cmake

@@ -0,0 +1,6 @@
+file(READ "${RunCMake_TEST_BINARY_DIR}/REMOVE_DUPLICATES-generated.txt" content)
+
+set(expected "1")
+if(NOT content STREQUAL expected)
+  set(RunCMake_TEST_FAILED "actual content:\n [[${content}]]\nbut expected:\n [[${expected}]]")
+endif()

+ 3 - 0
Tests/RunCMake/GeneratorExpression/REMOVE_DUPLICATES-1.cmake

@@ -0,0 +1,3 @@
+cmake_policy(VERSION 3.11)
+
+file(GENERATE OUTPUT "REMOVE_DUPLICATES-generated.txt" CONTENT "$<REMOVE_DUPLICATES:1>")

+ 6 - 0
Tests/RunCMake/GeneratorExpression/REMOVE_DUPLICATES-2-check.cmake

@@ -0,0 +1,6 @@
+file(READ "${RunCMake_TEST_BINARY_DIR}/REMOVE_DUPLICATES-generated.txt" content)
+
+set(expected "1")
+if(NOT content STREQUAL expected)
+  set(RunCMake_TEST_FAILED "actual content:\n [[${content}]]\nbut expected:\n [[${expected}]]")
+endif()

+ 3 - 0
Tests/RunCMake/GeneratorExpression/REMOVE_DUPLICATES-2.cmake

@@ -0,0 +1,3 @@
+cmake_policy(VERSION 3.11)
+
+file(GENERATE OUTPUT "REMOVE_DUPLICATES-generated.txt" CONTENT "$<REMOVE_DUPLICATES:1$<SEMICOLON>1>")

+ 6 - 0
Tests/RunCMake/GeneratorExpression/REMOVE_DUPLICATES-3-check.cmake

@@ -0,0 +1,6 @@
+file(READ "${RunCMake_TEST_BINARY_DIR}/REMOVE_DUPLICATES-generated.txt" content)
+
+set(expected "2;1")
+if(NOT content STREQUAL expected)
+  set(RunCMake_TEST_FAILED "actual content:\n [[${content}]]\nbut expected:\n [[${expected}]]")
+endif()

+ 3 - 0
Tests/RunCMake/GeneratorExpression/REMOVE_DUPLICATES-3.cmake

@@ -0,0 +1,3 @@
+cmake_policy(VERSION 3.11)
+
+file(GENERATE OUTPUT "REMOVE_DUPLICATES-generated.txt" CONTENT "$<REMOVE_DUPLICATES:2$<SEMICOLON>1>")

+ 6 - 0
Tests/RunCMake/GeneratorExpression/REMOVE_DUPLICATES-4-check.cmake

@@ -0,0 +1,6 @@
+file(READ "${RunCMake_TEST_BINARY_DIR}/REMOVE_DUPLICATES-generated.txt" content)
+
+set(expected "2;1")
+if(NOT content STREQUAL expected)
+  set(RunCMake_TEST_FAILED "actual content:\n [[${content}]]\nbut expected:\n [[${expected}]]")
+endif()

+ 3 - 0
Tests/RunCMake/GeneratorExpression/REMOVE_DUPLICATES-4.cmake

@@ -0,0 +1,3 @@
+cmake_policy(VERSION 3.11)
+
+file(GENERATE OUTPUT "REMOVE_DUPLICATES-generated.txt" CONTENT "$<REMOVE_DUPLICATES:2$<SEMICOLON>1$<SEMICOLON>2>")

+ 6 - 0
Tests/RunCMake/GeneratorExpression/REMOVE_DUPLICATES-empty-check.cmake

@@ -0,0 +1,6 @@
+file(READ "${RunCMake_TEST_BINARY_DIR}/REMOVE_DUPLICATES-generated.txt" content)
+
+set(expected "")
+if(NOT content STREQUAL expected)
+  set(RunCMake_TEST_FAILED "actual content:\n [[${content}]]\nbut expected:\n [[${expected}]]")
+endif()

+ 3 - 0
Tests/RunCMake/GeneratorExpression/REMOVE_DUPLICATES-empty.cmake

@@ -0,0 +1,3 @@
+cmake_policy(VERSION 3.11)
+
+file(GENERATE OUTPUT "REMOVE_DUPLICATES-generated.txt" CONTENT "$<REMOVE_DUPLICATES:>")

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

@@ -53,6 +53,11 @@ run_cmake(TARGET_GENEX_EVAL)
 run_cmake(GENEX_EVAL-recursion1)
 run_cmake(GENEX_EVAL-recursion2)
 run_cmake(GENEX_EVAL)
+run_cmake(REMOVE_DUPLICATES-empty)
+run_cmake(REMOVE_DUPLICATES-1)
+run_cmake(REMOVE_DUPLICATES-2)
+run_cmake(REMOVE_DUPLICATES-3)
+run_cmake(REMOVE_DUPLICATES-4)
 
 run_cmake(ImportedTarget-TARGET_BUNDLE_DIR)
 run_cmake(ImportedTarget-TARGET_BUNDLE_CONTENT_DIR)