diff options
13 files changed, 82 insertions, 0 deletions
diff --git a/Help/manual/cmake-generator-expressions.7.rst b/Help/manual/cmake-generator-expressions.7.rst index bba98d6..f93de53 100644 --- a/Help/manual/cmake-generator-expressions.7.rst +++ b/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>`` diff --git a/Source/cmGeneratorExpressionNode.cxx b/Source/cmGeneratorExpressionNode.cxx index 50413c8..19d2b3a 100644 --- a/Source/cmGeneratorExpressionNode.cxx +++ b/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 }, diff --git a/Tests/RunCMake/GeneratorExpression/REMOVE_DUPLICATES-1-check.cmake b/Tests/RunCMake/GeneratorExpression/REMOVE_DUPLICATES-1-check.cmake new file mode 100644 index 0000000..e127711 --- /dev/null +++ b/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() diff --git a/Tests/RunCMake/GeneratorExpression/REMOVE_DUPLICATES-1.cmake b/Tests/RunCMake/GeneratorExpression/REMOVE_DUPLICATES-1.cmake new file mode 100644 index 0000000..53934af --- /dev/null +++ b/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>") diff --git a/Tests/RunCMake/GeneratorExpression/REMOVE_DUPLICATES-2-check.cmake b/Tests/RunCMake/GeneratorExpression/REMOVE_DUPLICATES-2-check.cmake new file mode 100644 index 0000000..e127711 --- /dev/null +++ b/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() diff --git a/Tests/RunCMake/GeneratorExpression/REMOVE_DUPLICATES-2.cmake b/Tests/RunCMake/GeneratorExpression/REMOVE_DUPLICATES-2.cmake new file mode 100644 index 0000000..a8aca6e --- /dev/null +++ b/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>") diff --git a/Tests/RunCMake/GeneratorExpression/REMOVE_DUPLICATES-3-check.cmake b/Tests/RunCMake/GeneratorExpression/REMOVE_DUPLICATES-3-check.cmake new file mode 100644 index 0000000..e3055ce --- /dev/null +++ b/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() diff --git a/Tests/RunCMake/GeneratorExpression/REMOVE_DUPLICATES-3.cmake b/Tests/RunCMake/GeneratorExpression/REMOVE_DUPLICATES-3.cmake new file mode 100644 index 0000000..ee2dd3e --- /dev/null +++ b/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>") diff --git a/Tests/RunCMake/GeneratorExpression/REMOVE_DUPLICATES-4-check.cmake b/Tests/RunCMake/GeneratorExpression/REMOVE_DUPLICATES-4-check.cmake new file mode 100644 index 0000000..e3055ce --- /dev/null +++ b/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() diff --git a/Tests/RunCMake/GeneratorExpression/REMOVE_DUPLICATES-4.cmake b/Tests/RunCMake/GeneratorExpression/REMOVE_DUPLICATES-4.cmake new file mode 100644 index 0000000..557bc28 --- /dev/null +++ b/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>") diff --git a/Tests/RunCMake/GeneratorExpression/REMOVE_DUPLICATES-empty-check.cmake b/Tests/RunCMake/GeneratorExpression/REMOVE_DUPLICATES-empty-check.cmake new file mode 100644 index 0000000..f779d48 --- /dev/null +++ b/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() diff --git a/Tests/RunCMake/GeneratorExpression/REMOVE_DUPLICATES-empty.cmake b/Tests/RunCMake/GeneratorExpression/REMOVE_DUPLICATES-empty.cmake new file mode 100644 index 0000000..3b9d674 --- /dev/null +++ b/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:>") diff --git a/Tests/RunCMake/GeneratorExpression/RunCMakeTest.cmake b/Tests/RunCMake/GeneratorExpression/RunCMakeTest.cmake index 8a5604c..63c12a9 100644 --- a/Tests/RunCMake/GeneratorExpression/RunCMakeTest.cmake +++ b/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) |