diff options
author | David Cole <david.cole@kitware.com> | 2012-10-17 20:44:44 (GMT) |
---|---|---|
committer | CMake Topic Stage <kwrobot@kitware.com> | 2012-10-17 20:44:44 (GMT) |
commit | 982905c0d23aded548718cf64665002cac350e77 (patch) | |
tree | 2b1d75092972373572ff521a2ef043d379743bd4 | |
parent | e8b1c1ffc0a9eb3a224fbdb205627096ea6453c0 (diff) | |
parent | 79edd00235091475d5b3f1305bcf991cad3e45f4 (diff) | |
download | CMake-982905c0d23aded548718cf64665002cac350e77.zip CMake-982905c0d23aded548718cf64665002cac350e77.tar.gz CMake-982905c0d23aded548718cf64665002cac350e77.tar.bz2 |
Merge topic 'generator-expression-bug-fixes'
79edd00 GenEx: Fix reporting about not-found include directories and libraries.
f7ef32b GenEx: Replace some failing tests with Borland and NMake makefiles.
fd59b10 GenEx: Add some more asserts to verify code-sanity.
6dd2b36 GenEx: Break if there are no more commas in the container
e7230c7 GenEx: Fix termination bugs in generator expression parser.
145a4af GenEx: Test the use of generator expressions to generate lists.
e2d141d GenEx: Parse colon after arguments separator colon specially.
-rw-r--r-- | Source/cmGeneratorExpression.cxx | 49 | ||||
-rw-r--r-- | Source/cmGeneratorExpression.h | 7 | ||||
-rw-r--r-- | Source/cmGeneratorExpressionParser.cxx | 60 | ||||
-rw-r--r-- | Source/cmGlobalGenerator.cxx | 22 | ||||
-rw-r--r-- | Source/cmMakeDepend.cxx | 19 | ||||
-rw-r--r-- | Tests/CompileDefinitions/compiletest.cpp | 9 | ||||
-rw-r--r-- | Tests/CompileDefinitions/target_prop/CMakeLists.txt | 1 | ||||
-rw-r--r-- | Tests/GeneratorExpression/CMakeLists.txt | 26 | ||||
-rw-r--r-- | Tests/GeneratorExpression/check.cmake | 26 | ||||
-rw-r--r-- | Tests/IncludeDirectories/TargetIncludeDirectories/CMakeLists.txt | 4 | ||||
-rw-r--r-- | Tests/IncludeDirectories/TargetIncludeDirectories/main.cpp | 2 | ||||
-rw-r--r-- | Tests/RunCMake/CMakeLists.txt | 1 | ||||
-rw-r--r-- | Tests/RunCMake/include_directories/CMakeLists.txt | 3 | ||||
-rw-r--r-- | Tests/RunCMake/include_directories/NotFoundContent-result.txt | 1 | ||||
-rw-r--r-- | Tests/RunCMake/include_directories/NotFoundContent-stderr.txt | 6 | ||||
-rw-r--r-- | Tests/RunCMake/include_directories/NotFoundContent.cmake | 9 | ||||
-rw-r--r-- | Tests/RunCMake/include_directories/RunCMakeTest.cmake | 3 |
17 files changed, 225 insertions, 23 deletions
diff --git a/Source/cmGeneratorExpression.cxx b/Source/cmGeneratorExpression.cxx index 3f8e962..7d8df37 100644 --- a/Source/cmGeneratorExpression.cxx +++ b/Source/cmGeneratorExpression.cxx @@ -13,6 +13,7 @@ #include "cmMakefile.h" #include "cmTarget.h" +#include "assert.h" #include <cmsys/String.h> @@ -129,3 +130,51 @@ cmCompiledGeneratorExpression::~cmCompiledGeneratorExpression() delete *it; } } + +std::string cmGeneratorExpression::Preprocess(const std::string &input, + PreprocessContext context) +{ + if (context != StripAllGeneratorExpressions) + { + assert(!"cmGeneratorExpression::Preprocess called with invalid args"); + return std::string(); + } + + std::string result; + std::string::size_type pos = 0; + std::string::size_type lastPos = pos; + while((pos = input.find("$<", lastPos)) != input.npos) + { + result += input.substr(lastPos, pos - lastPos); + pos += 2; + int nestingLevel = 1; + const char *c = input.c_str() + pos; + const char * const cStart = c; + for ( ; *c; ++c) + { + if(c[0] == '$' && c[1] == '<') + { + ++nestingLevel; + ++c; + continue; + } + if(c[0] == '>') + { + --nestingLevel; + if (nestingLevel == 0) + { + break; + } + } + } + const std::string::size_type traversed = (c - cStart) + 1; + if (!*c) + { + result += "$<" + input.substr(pos, traversed); + } + pos += traversed; + lastPos = pos; + } + result += input.substr(lastPos); + return result; +} diff --git a/Source/cmGeneratorExpression.h b/Source/cmGeneratorExpression.h index d37ce97..29d3f44 100644 --- a/Source/cmGeneratorExpression.h +++ b/Source/cmGeneratorExpression.h @@ -48,6 +48,13 @@ public: const cmCompiledGeneratorExpression& Parse(std::string const& input); const cmCompiledGeneratorExpression& Parse(const char* input); + enum PreprocessContext { + StripAllGeneratorExpressions + }; + + static std::string Preprocess(const std::string &input, + PreprocessContext context); + private: cmGeneratorExpression(const cmGeneratorExpression &); void operator=(const cmGeneratorExpression &); diff --git a/Source/cmGeneratorExpressionParser.cxx b/Source/cmGeneratorExpressionParser.cxx index d95e1cc..7a8fc51 100644 --- a/Source/cmGeneratorExpressionParser.cxx +++ b/Source/cmGeneratorExpressionParser.cxx @@ -14,6 +14,8 @@ #include "cmGeneratorExpressionEvaluator.h" +#include "assert.h" + //---------------------------------------------------------------------------- cmGeneratorExpressionParser::cmGeneratorExpressionParser( const std::vector<cmGeneratorExpressionToken> &tokens) @@ -75,6 +77,7 @@ static void extendResult(std::vector<cmGeneratorExpressionEvaluator*> &result, void cmGeneratorExpressionParser::ParseGeneratorExpression( std::vector<cmGeneratorExpressionEvaluator*> &result) { + assert(this->it != this->Tokens.end()); unsigned int nestedLevel = this->NestingLevel; ++this->NestingLevel; @@ -96,12 +99,14 @@ void cmGeneratorExpressionParser::ParseGeneratorExpression( // ERROR } - if (this->it->TokenType == cmGeneratorExpressionToken::EndExpression) + if (this->it != this->Tokens.end() && + this->it->TokenType == cmGeneratorExpressionToken::EndExpression) { GeneratorExpressionContent *content = new GeneratorExpressionContent( startToken->Content, this->it->Content - startToken->Content + this->it->Length); + assert(this->it != this->Tokens.end()); ++this->it; --this->NestingLevel; content->SetIdentifier(identifier); @@ -113,39 +118,58 @@ void cmGeneratorExpressionParser::ParseGeneratorExpression( std::vector<std::vector<cmGeneratorExpressionToken>::const_iterator> commaTokens; std::vector<cmGeneratorExpressionToken>::const_iterator colonToken; - if (this->it->TokenType == cmGeneratorExpressionToken::ColonSeparator) + if (this->it != this->Tokens.end() && + this->it->TokenType == cmGeneratorExpressionToken::ColonSeparator) { colonToken = this->it; parameters.resize(parameters.size() + 1); + assert(this->it != this->Tokens.end()); ++this->it; - while (this->it->TokenType == cmGeneratorExpressionToken::CommaSeparator) + + while (this->it != this->Tokens.end() && + this->it->TokenType == cmGeneratorExpressionToken::CommaSeparator) { commaTokens.push_back(this->it); parameters.resize(parameters.size() + 1); + assert(this->it != this->Tokens.end()); + ++this->it; + } + while (this->it != this->Tokens.end() && + this->it->TokenType == cmGeneratorExpressionToken::ColonSeparator) + { + extendText(*(parameters.end() - 1), this->it); + assert(this->it != this->Tokens.end()); ++this->it; } - while(this->it->TokenType != cmGeneratorExpressionToken::EndExpression) + while (this->it != this->Tokens.end() && + this->it->TokenType != cmGeneratorExpressionToken::EndExpression) { this->ParseContent(*(parameters.end() - 1)); - while (this->it->TokenType == cmGeneratorExpressionToken::CommaSeparator) + if (this->it == this->Tokens.end()) + { + break; + } + while (this->it != this->Tokens.end() && + this->it->TokenType == cmGeneratorExpressionToken::CommaSeparator) { commaTokens.push_back(this->it); parameters.resize(parameters.size() + 1); + assert(this->it != this->Tokens.end()); ++this->it; } - if (this->it->TokenType == cmGeneratorExpressionToken::ColonSeparator) + while (this->it != this->Tokens.end() && + this->it->TokenType == cmGeneratorExpressionToken::ColonSeparator) { extendText(*(parameters.end() - 1), this->it); + assert(this->it != this->Tokens.end()); ++this->it; } - if (this->it == this->Tokens.end()) - { - break; - } } - if(this->it->TokenType == cmGeneratorExpressionToken::EndExpression) + if(this->it != this->Tokens.end() + && this->it->TokenType == cmGeneratorExpressionToken::EndExpression) { --this->NestingLevel; + assert(this->it != this->Tokens.end()); ++this->it; } } @@ -168,6 +192,7 @@ void cmGeneratorExpressionParser::ParseGeneratorExpression( parameters.end(); std::vector<TokenVector::const_iterator>::const_iterator commaIt = commaTokens.begin(); + assert(parameters.size() > commaTokens.size()); for ( ; pit != pend; ++pit, ++commaIt) { extendResult(result, *pit); @@ -175,6 +200,10 @@ void cmGeneratorExpressionParser::ParseGeneratorExpression( { extendText(result, *commaIt); } + else + { + break; + } } } return; @@ -194,6 +223,7 @@ void cmGeneratorExpressionParser::ParseGeneratorExpression( void cmGeneratorExpressionParser::ParseContent( std::vector<cmGeneratorExpressionEvaluator*> &result) { + assert(this->it != this->Tokens.end()); switch(this->it->TokenType) { case cmGeneratorExpressionToken::Text: @@ -210,6 +240,7 @@ void cmGeneratorExpressionParser::ParseContent( TextContent *textContent = static_cast<TextContent*>(*(result.end() - 1)); textContent->Extend(this->it->Length); + assert(this->it != this->Tokens.end()); ++this->it; return; } @@ -217,10 +248,12 @@ void cmGeneratorExpressionParser::ParseContent( cmGeneratorExpressionEvaluator* n = new TextContent(this->it->Content, this->it->Length); result.push_back(n); + assert(this->it != this->Tokens.end()); ++this->it; return ; } case cmGeneratorExpressionToken::BeginExpression: + assert(this->it != this->Tokens.end()); ++this->it; this->ParseGeneratorExpression(result); return; @@ -233,10 +266,11 @@ void cmGeneratorExpressionParser::ParseContent( } else { - // TODO: Unreachable. Assert? + assert(!"Got unexpected syntax token."); } + assert(this->it != this->Tokens.end()); ++this->it; return; } - // Unreachable. Assert? + assert(!"Unhandled token in generator expression."); } diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx index 09588f9..23ec08a 100644 --- a/Source/cmGlobalGenerator.cxx +++ b/Source/cmGlobalGenerator.cxx @@ -25,6 +25,7 @@ #include "cmComputeTargetDepends.h" #include "cmGeneratedFileStream.h" #include "cmGeneratorTarget.h" +#include "cmGeneratorExpression.h" #include <cmsys/Directory.hxx> @@ -1152,13 +1153,13 @@ void cmGlobalGenerator::CheckLocalGenerators() { manager = this->LocalGenerators[i]->GetMakefile()->GetCacheManager(); this->LocalGenerators[i]->ConfigureFinalPass(); - cmGeneratorTargetsType targets = - this->LocalGenerators[i]->GetMakefile()->GetGeneratorTargets(); - for (cmGeneratorTargetsType::iterator l = targets.begin(); + cmTargets &targets = + this->LocalGenerators[i]->GetMakefile()->GetTargets(); + for (cmTargets::iterator l = targets.begin(); l != targets.end(); l++) { const cmTarget::LinkLibraryVectorType& libs = - l->second->Target->GetOriginalLinkLibraries(); + l->second.GetOriginalLinkLibraries(); for(cmTarget::LinkLibraryVectorType::const_iterator lib = libs.begin(); lib != libs.end(); ++lib) { @@ -1174,14 +1175,23 @@ void cmGlobalGenerator::CheckLocalGenerators() } std::string text = notFoundMap[varName]; text += "\n linked by target \""; - text += l->second->GetName(); + text += l->second.GetName(); text += "\" in directory "; text+=this->LocalGenerators[i]->GetMakefile()->GetCurrentDirectory(); notFoundMap[varName] = text; } } std::vector<std::string> incs; - this->LocalGenerators[i]->GetIncludeDirectories(incs, l->second); + const char *incDirProp = l->second.GetProperty("INCLUDE_DIRECTORIES"); + if (!incDirProp) + { + continue; + } + + std::string incDirs = cmGeneratorExpression::Preprocess(incDirProp, + cmGeneratorExpression::StripAllGeneratorExpressions); + + cmSystemTools::ExpandListArgument(incDirs.c_str(), incs); for( std::vector<std::string>::const_iterator incDir = incs.begin(); incDir != incs.end(); ++incDir) diff --git a/Source/cmMakeDepend.cxx b/Source/cmMakeDepend.cxx index 75a76a4..2ae35ef 100644 --- a/Source/cmMakeDepend.cxx +++ b/Source/cmMakeDepend.cxx @@ -11,6 +11,7 @@ ============================================================================*/ #include "cmMakeDepend.h" #include "cmSystemTools.h" +#include "cmGeneratorExpression.h" #include <cmsys/RegularExpression.hxx> @@ -58,12 +59,22 @@ void cmMakeDepend::SetMakefile(cmMakefile* makefile) // Now extract any include paths from the targets std::set<std::string> uniqueIncludes; std::vector<std::string> orderedAndUniqueIncludes; - cmGeneratorTargetsType targets = this->Makefile->GetGeneratorTargets(); - for (cmGeneratorTargetsType::iterator l = targets.begin(); + cmTargets &targets = this->Makefile->GetTargets(); + for (cmTargets::iterator l = targets.begin(); l != targets.end(); ++l) { - const std::vector<std::string>& includes = - l->second->GetIncludeDirectories(); + const char *incDirProp = l->second.GetProperty("INCLUDE_DIRECTORIES"); + if (!incDirProp) + { + continue; + } + + std::string incDirs = cmGeneratorExpression::Preprocess(incDirProp, + cmGeneratorExpression::StripAllGeneratorExpressions); + + std::vector<std::string> includes; + cmSystemTools::ExpandListArgument(incDirs.c_str(), includes); + for(std::vector<std::string>::const_iterator j = includes.begin(); j != includes.end(); ++j) { diff --git a/Tests/CompileDefinitions/compiletest.cpp b/Tests/CompileDefinitions/compiletest.cpp index 4a68a07..f18e59e 100644 --- a/Tests/CompileDefinitions/compiletest.cpp +++ b/Tests/CompileDefinitions/compiletest.cpp @@ -34,6 +34,15 @@ enum { #ifdef GE_NOT_DEFINED #error Expect not defined generator expression #endif + +#ifndef ARGUMENT +#error Expected define expanded from list +#endif +#ifndef LIST +#error Expected define expanded from list +#endif + +// TEST_GENERATOR_EXPRESSIONS #endif int main(int argc, char **argv) diff --git a/Tests/CompileDefinitions/target_prop/CMakeLists.txt b/Tests/CompileDefinitions/target_prop/CMakeLists.txt index fcb22b0..abdf257 100644 --- a/Tests/CompileDefinitions/target_prop/CMakeLists.txt +++ b/Tests/CompileDefinitions/target_prop/CMakeLists.txt @@ -12,4 +12,5 @@ set_property(TARGET target_prop_executable APPEND PROPERTY COMPILE_DEFINITIONS TEST_GENERATOR_EXPRESSIONS "$<1:CMAKE_IS_DECLARATIVE>" "$<0:GE_NOT_DEFINED>" + "$<1:ARGUMENT;LIST>" ) diff --git a/Tests/GeneratorExpression/CMakeLists.txt b/Tests/GeneratorExpression/CMakeLists.txt index 8bc4f32..891fa11 100644 --- a/Tests/GeneratorExpression/CMakeLists.txt +++ b/Tests/GeneratorExpression/CMakeLists.txt @@ -44,6 +44,32 @@ add_custom_target(check ALL -Dtest_strequal_one_empty=$<STREQUAL:something,> -Dtest_angle_r=$<ANGLE-R> -Dtest_comma=$<COMMA> + -Dtest_colons_1=$<1::> + -Dtest_colons_2=$<1:::> + -Dtest_colons_3=$<1:Qt5::Core> + -Dtest_colons_4=$<1:C:\\CMake> + -Dtest_colons_5=$<1:C:/CMake> + -Dtest_incomplete_1=$< + -Dtest_incomplete_2=$<something + -Dtest_incomplete_3=$<something: + -Dtest_incomplete_4=$<something:, + -Dtest_incomplete_5=$something:,> + -Dtest_incomplete_6=<something:,> + -Dtest_incomplete_7=$<something:: + -Dtest_incomplete_8=$<something:, + -Dtest_incomplete_9=$<something:,, + -Dtest_incomplete_10=$<something:,: + -Dtest_incomplete_11=$<something,, + -Dtest_incomplete_12=$<,, + -Dtest_incomplete_13=$<some$<1:special>thing + -Dtest_incomplete_14=$<$<ANGLE-R> + -Dtest_incomplete_15=$<some$<thing + -Dtest_incomplete_16=$<BOOL:something + -Dtest_incomplete_17=$<1:some$thing> + -Dtest_incomplete_18=$<1:some,thing + -Dtest_incomplete_19=$<1:some,thing$<ANGLE-R> + -Dtest_incomplete_20=$<CONFIGURATION$<ANGLE-R> + -Dtest_incomplete_21=$<BOOL:something$<ANGLE-R> -P ${CMAKE_CURRENT_SOURCE_DIR}/check.cmake COMMAND ${CMAKE_COMMAND} -E echo "check done" VERBATIM diff --git a/Tests/GeneratorExpression/check.cmake b/Tests/GeneratorExpression/check.cmake index ec1f130..8ffa481 100644 --- a/Tests/GeneratorExpression/check.cmake +++ b/Tests/GeneratorExpression/check.cmake @@ -45,3 +45,29 @@ check(test_strequal_both_empty "1") check(test_strequal_one_empty "0") check(test_angle_r ">") check(test_comma ",") +check(test_colons_1 ":") +check(test_colons_2 "::") +check(test_colons_3 "Qt5::Core") +check(test_colons_4 "C:\\\\CMake") +check(test_colons_5 "C:/CMake") +check(test_incomplete_1 "$<") +check(test_incomplete_2 "$<something") +check(test_incomplete_3 "$<something:") +check(test_incomplete_4 "$<something:,") +check(test_incomplete_5 "$something:,>") +check(test_incomplete_6 "<something:,>") +check(test_incomplete_7 "$<something::") +check(test_incomplete_8 "$<something:,") +check(test_incomplete_9 "$<something:,,") +check(test_incomplete_10 "$<something:,:") +check(test_incomplete_11 "$<something,,") +check(test_incomplete_12 "$<,,") +check(test_incomplete_13 "$<somespecialthing") +check(test_incomplete_14 "$<>") +check(test_incomplete_15 "$<some$<thing") +check(test_incomplete_16 "$<BOOL:something") +check(test_incomplete_17 "some$thing") +check(test_incomplete_18 "$<1:some,thing") +check(test_incomplete_19 "$<1:some,thing>") +check(test_incomplete_20 "$<CONFIGURATION>") +check(test_incomplete_21 "$<BOOL:something>") diff --git a/Tests/IncludeDirectories/TargetIncludeDirectories/CMakeLists.txt b/Tests/IncludeDirectories/TargetIncludeDirectories/CMakeLists.txt index 4b6f682..d71f92e 100644 --- a/Tests/IncludeDirectories/TargetIncludeDirectories/CMakeLists.txt +++ b/Tests/IncludeDirectories/TargetIncludeDirectories/CMakeLists.txt @@ -15,6 +15,8 @@ create_header(baz) create_header(bang) create_header(bing) create_header(bung) +create_header(arguments) +create_header(list) set(CMAKE_INCLUDE_CURRENT_DIR ON) @@ -30,3 +32,5 @@ set_property(TARGET TargetIncludeDirectories APPEND PROPERTY include_directories("${CMAKE_CURRENT_BINARY_DIR}/baz") include_directories("$<1:${CMAKE_CURRENT_BINARY_DIR}/bung>") include_directories("sing$<1:/ting>") + +include_directories("$<1:${CMAKE_CURRENT_BINARY_DIR}/arguments;${CMAKE_CURRENT_BINARY_DIR}/list>") diff --git a/Tests/IncludeDirectories/TargetIncludeDirectories/main.cpp b/Tests/IncludeDirectories/TargetIncludeDirectories/main.cpp index 63217f4..030bb1c 100644 --- a/Tests/IncludeDirectories/TargetIncludeDirectories/main.cpp +++ b/Tests/IncludeDirectories/TargetIncludeDirectories/main.cpp @@ -7,6 +7,8 @@ #include "bing.h" #include "bung.h" #include "ting.h" +#include "arguments.h" +#include "list.h" int main(int, char**) { diff --git a/Tests/RunCMake/CMakeLists.txt b/Tests/RunCMake/CMakeLists.txt index 2fa7141..8c67625 100644 --- a/Tests/RunCMake/CMakeLists.txt +++ b/Tests/RunCMake/CMakeLists.txt @@ -53,6 +53,7 @@ add_RunCMake_test(ObjectLibrary) add_RunCMake_test(build_command) add_RunCMake_test(find_package) add_RunCMake_test(include) +add_RunCMake_test(include_directories) add_RunCMake_test(list) if("${CMAKE_TEST_GENERATOR}" MATCHES "Visual Studio [^6]") diff --git a/Tests/RunCMake/include_directories/CMakeLists.txt b/Tests/RunCMake/include_directories/CMakeLists.txt new file mode 100644 index 0000000..e8db6b0 --- /dev/null +++ b/Tests/RunCMake/include_directories/CMakeLists.txt @@ -0,0 +1,3 @@ +cmake_minimum_required(VERSION 2.8) +project(${RunCMake_TEST} NONE) +include(${RunCMake_TEST}.cmake) diff --git a/Tests/RunCMake/include_directories/NotFoundContent-result.txt b/Tests/RunCMake/include_directories/NotFoundContent-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/include_directories/NotFoundContent-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/include_directories/NotFoundContent-stderr.txt b/Tests/RunCMake/include_directories/NotFoundContent-stderr.txt new file mode 100644 index 0000000..f608d63 --- /dev/null +++ b/Tests/RunCMake/include_directories/NotFoundContent-stderr.txt @@ -0,0 +1,6 @@ +CMake Error: The following variables are used in this project, but they are set to NOTFOUND. +Please set them or make sure they are set and tested correctly in the CMake files: +NotThere1 + used as include directory in directory .* +NotThere2 + used as include directory in directory .* diff --git a/Tests/RunCMake/include_directories/NotFoundContent.cmake b/Tests/RunCMake/include_directories/NotFoundContent.cmake new file mode 100644 index 0000000..9677e0c --- /dev/null +++ b/Tests/RunCMake/include_directories/NotFoundContent.cmake @@ -0,0 +1,9 @@ + +include_directories(NotThere1-NOTFOUND) + +include_directories($<1:There1-NOTFOUND>) + +file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/dummy.cpp" "int main(int,char**) { return 0; }\n") +add_executable(dummy "${CMAKE_CURRENT_BINARY_DIR}/dummy.cpp") +set_property(TARGET dummy APPEND PROPERTY INCLUDE_DIRECTORIES "NotThere2-NOTFOUND") +set_property(TARGET dummy APPEND PROPERTY INCLUDE_DIRECTORIES "$<1:There2-NOTFOUND>") diff --git a/Tests/RunCMake/include_directories/RunCMakeTest.cmake b/Tests/RunCMake/include_directories/RunCMakeTest.cmake new file mode 100644 index 0000000..aee3f79 --- /dev/null +++ b/Tests/RunCMake/include_directories/RunCMakeTest.cmake @@ -0,0 +1,3 @@ +include(RunCMake) + +run_cmake(NotFoundContent) |