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)