From e2d141d47410ad17ba2b63fd32a61cead8a50606 Mon Sep 17 00:00:00 2001 From: Stephen Kelly Date: Fri, 12 Oct 2012 16:51:16 +0200 Subject: [PATCH 1/7] GenEx: Parse colon after arguments separator colon specially. The rationale is similar to that in commit b3d8f5da (GenEx: Parse comma after colon tokens specially, 2012-10-04), in that colon tokens should not be parsed as identifier-argument delimiters after the first colon. --- Source/cmGeneratorExpressionParser.cxx | 11 +++++++++-- Tests/GeneratorExpression/CMakeLists.txt | 5 +++++ Tests/GeneratorExpression/check.cmake | 5 +++++ 3 files changed, 19 insertions(+), 2 deletions(-) diff --git a/Source/cmGeneratorExpressionParser.cxx b/Source/cmGeneratorExpressionParser.cxx index d95e1cc2e..d09e412e5 100644 --- a/Source/cmGeneratorExpressionParser.cxx +++ b/Source/cmGeneratorExpressionParser.cxx @@ -14,6 +14,8 @@ #include "cmGeneratorExpressionEvaluator.h" +#include "assert.h" + //---------------------------------------------------------------------------- cmGeneratorExpressionParser::cmGeneratorExpressionParser( const std::vector &tokens) @@ -124,6 +126,11 @@ void cmGeneratorExpressionParser::ParseGeneratorExpression( parameters.resize(parameters.size() + 1); ++this->it; } + while (this->it->TokenType == cmGeneratorExpressionToken::ColonSeparator) + { + extendText(*(parameters.end() - 1), this->it); + ++this->it; + } while(this->it->TokenType != cmGeneratorExpressionToken::EndExpression) { this->ParseContent(*(parameters.end() - 1)); @@ -133,7 +140,7 @@ void cmGeneratorExpressionParser::ParseGeneratorExpression( parameters.resize(parameters.size() + 1); ++this->it; } - if (this->it->TokenType == cmGeneratorExpressionToken::ColonSeparator) + while (this->it->TokenType == cmGeneratorExpressionToken::ColonSeparator) { extendText(*(parameters.end() - 1), this->it); ++this->it; @@ -233,7 +240,7 @@ void cmGeneratorExpressionParser::ParseContent( } else { - // TODO: Unreachable. Assert? + assert(!"Got unexpected syntax token."); } ++this->it; return; diff --git a/Tests/GeneratorExpression/CMakeLists.txt b/Tests/GeneratorExpression/CMakeLists.txt index 8bc4f32df..4967ac0a7 100644 --- a/Tests/GeneratorExpression/CMakeLists.txt +++ b/Tests/GeneratorExpression/CMakeLists.txt @@ -44,6 +44,11 @@ add_custom_target(check ALL -Dtest_strequal_one_empty=$ -Dtest_angle_r=$ -Dtest_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> -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 ec1f130ec..e46c1c1bb 100644 --- a/Tests/GeneratorExpression/check.cmake +++ b/Tests/GeneratorExpression/check.cmake @@ -45,3 +45,8 @@ 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") From 145a4af8d3812fbd6a28f27e6fd4bb4d60d715af Mon Sep 17 00:00:00 2001 From: Stephen Kelly Date: Fri, 12 Oct 2012 17:17:30 +0200 Subject: [PATCH 2/7] GenEx: Test the use of generator expressions to generate lists. We can't test this in the GeneratorExpression unit test because the ';' chars are processed specically by the CMake function argument parser. --- Tests/CompileDefinitions/compiletest.cpp | 9 +++++++++ Tests/CompileDefinitions/target_prop/CMakeLists.txt | 1 + .../TargetIncludeDirectories/CMakeLists.txt | 4 ++++ .../IncludeDirectories/TargetIncludeDirectories/main.cpp | 2 ++ 4 files changed, 16 insertions(+) diff --git a/Tests/CompileDefinitions/compiletest.cpp b/Tests/CompileDefinitions/compiletest.cpp index 4a68a0750..f18e59e67 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 fcb22b019..abdf257ec 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/IncludeDirectories/TargetIncludeDirectories/CMakeLists.txt b/Tests/IncludeDirectories/TargetIncludeDirectories/CMakeLists.txt index 4b6f682a9..d71f92e1b 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 63217f4a5..030bb1cf9 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**) { From e7230c71fdf9ed58b2e8fbf2064452a41ea57180 Mon Sep 17 00:00:00 2001 From: Stephen Kelly Date: Fri, 12 Oct 2012 17:34:16 +0200 Subject: [PATCH 3/7] GenEx: Fix termination bugs in generator expression parser. Content which is incomplete as a generator expression could cause segfaults by advancing an iterator beyond end() and dereferencing it. Such incomplete generator expressions should be treated as plain text instead. --- Source/cmGeneratorExpressionParser.cxx | 37 +++++++++++++++--------- Tests/GeneratorExpression/CMakeLists.txt | 22 ++++++++++++++ Tests/GeneratorExpression/check.cmake | 22 ++++++++++++++ 3 files changed, 68 insertions(+), 13 deletions(-) diff --git a/Source/cmGeneratorExpressionParser.cxx b/Source/cmGeneratorExpressionParser.cxx index d09e412e5..341832a18 100644 --- a/Source/cmGeneratorExpressionParser.cxx +++ b/Source/cmGeneratorExpressionParser.cxx @@ -77,6 +77,7 @@ static void extendResult(std::vector &result, void cmGeneratorExpressionParser::ParseGeneratorExpression( std::vector &result) { + assert(this->it != this->Tokens.end()); unsigned int nestedLevel = this->NestingLevel; ++this->NestingLevel; @@ -98,7 +99,8 @@ 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 @@ -115,42 +117,50 @@ void cmGeneratorExpressionParser::ParseGeneratorExpression( std::vector::const_iterator> commaTokens; std::vector::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); ++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); ++this->it; } - while (this->it->TokenType == cmGeneratorExpressionToken::ColonSeparator) + while (this->it != this->Tokens.end() && + this->it->TokenType == cmGeneratorExpressionToken::ColonSeparator) { extendText(*(parameters.end() - 1), this->it); ++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); ++this->it; } - while (this->it->TokenType == cmGeneratorExpressionToken::ColonSeparator) + while (this->it != this->Tokens.end() && + this->it->TokenType == cmGeneratorExpressionToken::ColonSeparator) { extendText(*(parameters.end() - 1), this->it); ++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; ++this->it; @@ -201,6 +211,7 @@ void cmGeneratorExpressionParser::ParseGeneratorExpression( void cmGeneratorExpressionParser::ParseContent( std::vector &result) { + assert(this->it != this->Tokens.end()); switch(this->it->TokenType) { case cmGeneratorExpressionToken::Text: @@ -245,5 +256,5 @@ void cmGeneratorExpressionParser::ParseContent( ++this->it; return; } - // Unreachable. Assert? + assert(!"Unhandled token in generator expression."); } diff --git a/Tests/GeneratorExpression/CMakeLists.txt b/Tests/GeneratorExpression/CMakeLists.txt index 4967ac0a7..cb01ec178 100644 --- a/Tests/GeneratorExpression/CMakeLists.txt +++ b/Tests/GeneratorExpression/CMakeLists.txt @@ -49,6 +49,28 @@ add_custom_target(check ALL -Dtest_colons_3=$<1:Qt5::Core> -Dtest_colons_4=$<1:C:\\CMake> -Dtest_colons_5=$<1:C:/CMake> + -Dtest_incomplete_1=$< + -Dtest_incomplete_2=$ + -Dtest_incomplete_6= + -Dtest_incomplete_7=$thing + -Dtest_incomplete_14=$< + -Dtest_incomplete_18=$<1:some,thing + -Dtest_incomplete_19=$<1:some,thing$ + -Dtest_incomplete_20=$ + -Dtest_incomplete_21=$ + -Dtest_incomplete_22=$") +check(test_incomplete_6 "") +check(test_incomplete_7 "$") +check(test_incomplete_20 "$") +check(test_incomplete_21 "$") +check(test_incomplete_22 "$ Date: Mon, 15 Oct 2012 15:33:06 +0200 Subject: [PATCH 4/7] GenEx: Break if there are no more commas in the container This was causing an assert on Windows which has safety features for iterating past the end of the container. --- Source/cmGeneratorExpressionParser.cxx | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Source/cmGeneratorExpressionParser.cxx b/Source/cmGeneratorExpressionParser.cxx index 341832a18..64d992a31 100644 --- a/Source/cmGeneratorExpressionParser.cxx +++ b/Source/cmGeneratorExpressionParser.cxx @@ -192,6 +192,10 @@ void cmGeneratorExpressionParser::ParseGeneratorExpression( { extendText(result, *commaIt); } + else + { + break; + } } } return; From fd59b10e7149026658d8dcdedfef0b3810fea226 Mon Sep 17 00:00:00 2001 From: Stephen Kelly Date: Mon, 15 Oct 2012 15:34:43 +0200 Subject: [PATCH 5/7] GenEx: Add some more asserts to verify code-sanity. --- Source/cmGeneratorExpressionParser.cxx | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/Source/cmGeneratorExpressionParser.cxx b/Source/cmGeneratorExpressionParser.cxx index 64d992a31..7a8fc510d 100644 --- a/Source/cmGeneratorExpressionParser.cxx +++ b/Source/cmGeneratorExpressionParser.cxx @@ -106,6 +106,7 @@ void cmGeneratorExpressionParser::ParseGeneratorExpression( startToken->Content, this->it->Content - startToken->Content + this->it->Length); + assert(this->it != this->Tokens.end()); ++this->it; --this->NestingLevel; content->SetIdentifier(identifier); @@ -122,6 +123,7 @@ void cmGeneratorExpressionParser::ParseGeneratorExpression( { colonToken = this->it; parameters.resize(parameters.size() + 1); + assert(this->it != this->Tokens.end()); ++this->it; while (this->it != this->Tokens.end() && @@ -129,12 +131,14 @@ void cmGeneratorExpressionParser::ParseGeneratorExpression( { 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 != this->Tokens.end() && @@ -150,12 +154,14 @@ void cmGeneratorExpressionParser::ParseGeneratorExpression( { 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; } } @@ -163,6 +169,7 @@ void cmGeneratorExpressionParser::ParseGeneratorExpression( && this->it->TokenType == cmGeneratorExpressionToken::EndExpression) { --this->NestingLevel; + assert(this->it != this->Tokens.end()); ++this->it; } } @@ -185,6 +192,7 @@ void cmGeneratorExpressionParser::ParseGeneratorExpression( parameters.end(); std::vector::const_iterator commaIt = commaTokens.begin(); + assert(parameters.size() > commaTokens.size()); for ( ; pit != pend; ++pit, ++commaIt) { extendResult(result, *pit); @@ -232,6 +240,7 @@ void cmGeneratorExpressionParser::ParseContent( TextContent *textContent = static_cast(*(result.end() - 1)); textContent->Extend(this->it->Length); + assert(this->it != this->Tokens.end()); ++this->it; return; } @@ -239,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; @@ -257,6 +268,7 @@ void cmGeneratorExpressionParser::ParseContent( { assert(!"Got unexpected syntax token."); } + assert(this->it != this->Tokens.end()); ++this->it; return; } From f7ef32b00b8d4fe74bfdcee3e690309e9a89e251 Mon Sep 17 00:00:00 2001 From: Stephen Kelly Date: Tue, 16 Oct 2012 00:22:18 +0200 Subject: [PATCH 6/7] GenEx: Replace some failing tests with Borland and NMake makefiles. The '<<' is a special sequence on those platforms, so it can't appear in the test. --- Tests/GeneratorExpression/CMakeLists.txt | 5 ++--- Tests/GeneratorExpression/check.cmake | 5 ++--- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/Tests/GeneratorExpression/CMakeLists.txt b/Tests/GeneratorExpression/CMakeLists.txt index cb01ec178..891fa11a6 100644 --- a/Tests/GeneratorExpression/CMakeLists.txt +++ b/Tests/GeneratorExpression/CMakeLists.txt @@ -62,15 +62,14 @@ add_custom_target(check ALL -Dtest_incomplete_11=$thing - -Dtest_incomplete_14=$< -Dtest_incomplete_15=$ -Dtest_incomplete_18=$<1:some,thing -Dtest_incomplete_19=$<1:some,thing$ -Dtest_incomplete_20=$ -Dtest_incomplete_21=$ - -Dtest_incomplete_22=$") check(test_incomplete_15 "$") check(test_incomplete_20 "$") check(test_incomplete_21 "$") -check(test_incomplete_22 "$ Date: Mon, 15 Oct 2012 10:27:42 +0200 Subject: [PATCH 7/7] GenEx: Fix reporting about not-found include directories and libraries. This fixes a regression introduced in commit 290e92ad (Move GetIncludeDirectories to cmGeneratorTarget, 2012-09-16) which loops over cmGeneratorTargets before they get created, so the container is empty. --- Source/cmGeneratorExpression.cxx | 49 +++++++++++++++++++ Source/cmGeneratorExpression.h | 7 +++ Source/cmGlobalGenerator.cxx | 22 ++++++--- Source/cmMakeDepend.cxx | 19 +++++-- Tests/RunCMake/CMakeLists.txt | 1 + .../include_directories/CMakeLists.txt | 3 ++ .../NotFoundContent-result.txt | 1 + .../NotFoundContent-stderr.txt | 6 +++ .../include_directories/NotFoundContent.cmake | 9 ++++ .../include_directories/RunCMakeTest.cmake | 3 ++ 10 files changed, 110 insertions(+), 10 deletions(-) create mode 100644 Tests/RunCMake/include_directories/CMakeLists.txt create mode 100644 Tests/RunCMake/include_directories/NotFoundContent-result.txt create mode 100644 Tests/RunCMake/include_directories/NotFoundContent-stderr.txt create mode 100644 Tests/RunCMake/include_directories/NotFoundContent.cmake create mode 100644 Tests/RunCMake/include_directories/RunCMakeTest.cmake diff --git a/Source/cmGeneratorExpression.cxx b/Source/cmGeneratorExpression.cxx index 3f8e962be..7d8df3733 100644 --- a/Source/cmGeneratorExpression.cxx +++ b/Source/cmGeneratorExpression.cxx @@ -13,6 +13,7 @@ #include "cmMakefile.h" #include "cmTarget.h" +#include "assert.h" #include @@ -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 d37ce97d3..29d3f444f 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/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx index 09588f983..23ec08a2d 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 @@ -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 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::const_iterator incDir = incs.begin(); incDir != incs.end(); ++incDir) diff --git a/Source/cmMakeDepend.cxx b/Source/cmMakeDepend.cxx index 75a76a42e..2ae35ef14 100644 --- a/Source/cmMakeDepend.cxx +++ b/Source/cmMakeDepend.cxx @@ -11,6 +11,7 @@ ============================================================================*/ #include "cmMakeDepend.h" #include "cmSystemTools.h" +#include "cmGeneratorExpression.h" #include @@ -58,12 +59,22 @@ void cmMakeDepend::SetMakefile(cmMakefile* makefile) // Now extract any include paths from the targets std::set uniqueIncludes; std::vector 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& 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 includes; + cmSystemTools::ExpandListArgument(incDirs.c_str(), includes); + for(std::vector::const_iterator j = includes.begin(); j != includes.end(); ++j) { diff --git a/Tests/RunCMake/CMakeLists.txt b/Tests/RunCMake/CMakeLists.txt index 2fa714170..8c67625ff 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 000000000..e8db6b05b --- /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 000000000..d00491fd7 --- /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 000000000..f608d633f --- /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 000000000..9677e0c43 --- /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 000000000..aee3f799b --- /dev/null +++ b/Tests/RunCMake/include_directories/RunCMakeTest.cmake @@ -0,0 +1,3 @@ +include(RunCMake) + +run_cmake(NotFoundContent)