From 8adaee2b0b2651cfd93bb4a915d11bdd4cba1b51 Mon Sep 17 00:00:00 2001 From: David Cole Date: Tue, 24 Jan 2012 11:54:46 -0500 Subject: [PATCH] CMake: Eliminate cmMakefile::IncludeDirectories Instead, re-implement it in terms of the directory property INCLUDE_DIRECTORIES. --- Source/cmLocalGenerator.cxx | 6 +- Source/cmMakefile.cxx | 144 ++++++++++++++++++------------------ Source/cmMakefile.h | 17 +---- 3 files changed, 77 insertions(+), 90 deletions(-) diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx index fe481fa626..27b1b1b686 100644 --- a/Source/cmLocalGenerator.cxx +++ b/Source/cmLocalGenerator.cxx @@ -1399,7 +1399,7 @@ void cmLocalGenerator::GetIncludeDirectories(std::vector& dirs, } // Get the project-specified include directories. - std::vector& includes = + const std::vector& includes = this->Makefile->GetIncludeDirectories(); // Support putting all the in-project include directories first if @@ -1408,7 +1408,7 @@ void cmLocalGenerator::GetIncludeDirectories(std::vector& dirs, { const char* topSourceDir = this->Makefile->GetHomeDirectory(); const char* topBinaryDir = this->Makefile->GetHomeOutputDirectory(); - for(std::vector::iterator i = includes.begin(); + for(std::vector::const_iterator i = includes.begin(); i != includes.end(); ++i) { // Emit this directory only if it is a subdirectory of the @@ -1427,7 +1427,7 @@ void cmLocalGenerator::GetIncludeDirectories(std::vector& dirs, } // Construct the final ordered include directory list. - for(std::vector::iterator i = includes.begin(); + for(std::vector::const_iterator i = includes.begin(); i != includes.end(); ++i) { if(emitted.insert(*i).second) diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx index fdf5b31d11..cdb699ebb0 100644 --- a/Source/cmMakefile.cxx +++ b/Source/cmMakefile.cxx @@ -116,7 +116,6 @@ cmMakefile::cmMakefile(const cmMakefile& mf): Internal(new Internals) this->Targets = mf.Targets; this->SourceFiles = mf.SourceFiles; this->Tests = mf.Tests; - this->IncludeDirectories = mf.IncludeDirectories; this->LinkDirectories = mf.LinkDirectories; this->SystemIncludeDirectories = mf.SystemIncludeDirectories; this->ListFiles = mf.ListFiles; @@ -278,8 +277,6 @@ void cmMakefile::Print() this->cmHomeDirectory.c_str() << std::endl; std::cout << " this->ProjectName; " << this->ProjectName.c_str() << std::endl; - this->PrintStringVector("this->IncludeDirectories;", - this->IncludeDirectories); this->PrintStringVector("this->LinkDirectories", this->LinkDirectories); #if defined(CMAKE_BUILD_WITH_CMAKE) for( std::vector::const_iterator i = @@ -1478,7 +1475,8 @@ void cmMakefile::InitializeFromParent() this->Internal->VarStack.top() = parent->Internal->VarStack.top().Closure(); // copy include paths - this->IncludeDirectories = parent->IncludeDirectories; + this->SetProperty("INCLUDE_DIRECTORIES", + parent->GetProperty("INCLUDE_DIRECTORIES")); this->SystemIncludeDirectories = parent->SystemIncludeDirectories; // define flags @@ -1603,43 +1601,77 @@ void cmMakefile::AddSubDirectory(const char* srcPath, const char *binPath, } } +//---------------------------------------------------------------------------- +void AddStringToProperty(cmProperty *prop, const char* name, const char* s, + bool before) +{ + if (!prop) + { + return; + } + + // Don't worry about duplicates at this point. We eliminate them when + // we convert the property to a vector in GetIncludeDirectories. + + if (before) + { + const char *val = prop->GetValue(); + cmOStringStream oss; + + if(val && *val) + { + oss << s << ";" << val; + } + else + { + oss << s; + } + + std::string newVal = oss.str(); + prop->Set(name, newVal.c_str()); + } + else + { + prop->Append(name, s); + } +} + +//---------------------------------------------------------------------------- void cmMakefile::AddIncludeDirectory(const char* inc, bool before) { - // if there is a newline then break it into multiple arguments if (!inc) { return; } - // Don't add an include directory that is already present. Yes, - // this linear search results in n^2 behavior, but n won't be - // getting much bigger than 20. We cannot use a set because of - // order dependency of the include path. - std::vector::iterator i = - std::find(this->IncludeDirectories.begin(), - this->IncludeDirectories.end(), inc); - if(i == this->IncludeDirectories.end()) + // Directory property: + cmProperty *prop = + this->GetProperties().GetOrCreateProperty("INCLUDE_DIRECTORIES"); + AddStringToProperty(prop, "INCLUDE_DIRECTORIES", inc, before); +} + +//---------------------------------------------------------------------------- +std::vector cmMakefile::GetIncludeDirectories() +{ + std::vector includes; + const char *val = this->GetProperty("INCLUDE_DIRECTORIES"); + if(val) { - if (before) + cmSystemTools::ExpandListArgument(val, includes); + } + + std::set uniqueIncludes; + std::vector orderedAndUniqueIncludes; + for(std::vector::const_iterator + li = includes.begin(); li != includes.end(); ++li) + { + if(uniqueIncludes.insert(*li).second) { - // WARNING: this *is* expensive (linear time) since it's a vector - this->IncludeDirectories.insert(this->IncludeDirectories.begin(), inc); - } - else - { - this->IncludeDirectories.push_back(inc); - } - } - else - { - if(before) - { - // if this before and already in the path then remove it - this->IncludeDirectories.erase(i); - // WARNING: this *is* expensive (linear time) since it's a vector - this->IncludeDirectories.insert(this->IncludeDirectories.begin(), inc); + orderedAndUniqueIncludes.push_back(*li); } } + + return orderedAndUniqueIncludes; } //---------------------------------------------------------------------------- @@ -2093,17 +2125,23 @@ void cmMakefile::AddExtraDirectory(const char* dir) } -// expance CMAKE_BINARY_DIR and CMAKE_SOURCE_DIR in the +// expand CMAKE_BINARY_DIR and CMAKE_SOURCE_DIR in the // include and library directories. void cmMakefile::ExpandVariables() { // Now expand variables in the include and link strings - for(std::vector::iterator d = this->IncludeDirectories.begin(); - d != this->IncludeDirectories.end(); ++d) + + // May not be necessary anymore... But may need a policy for strict + // backwards compatibility + const char *includeDirs = this->GetProperty("INCLUDE_DIRECTORIES"); + if (includeDirs) { - this->ExpandVariablesInString(*d, true, true); + std::string dirs = includeDirs; + this->ExpandVariablesInString(dirs, true, true); + this->SetProperty("INCLUDE_DIRECTORIES", dirs.c_str()); } + for(std::vector::iterator d = this->LinkDirectories.begin(); d != this->LinkDirectories.end(); ++d) { @@ -3317,16 +3355,6 @@ void cmMakefile::SetProperty(const char* prop, const char* value) // handle special props std::string propname = prop; - if ( propname == "INCLUDE_DIRECTORIES" ) - { - std::vector varArgsExpanded; - if(value) - { - cmSystemTools::ExpandListArgument(value, varArgsExpanded); - } - this->SetIncludeDirectories(varArgsExpanded); - return; - } if ( propname == "LINK_DIRECTORIES" ) { @@ -3368,17 +3396,6 @@ void cmMakefile::AppendProperty(const char* prop, const char* value, // handle special props std::string propname = prop; - if ( propname == "INCLUDE_DIRECTORIES" ) - { - std::vector varArgsExpanded; - cmSystemTools::ExpandListArgument(value, varArgsExpanded); - for(std::vector::const_iterator vi = varArgsExpanded.begin(); - vi != varArgsExpanded.end(); ++vi) - { - this->AddIncludeDirectory(vi->c_str()); - } - return; - } if ( propname == "LINK_DIRECTORIES" ) { @@ -3474,23 +3491,6 @@ const char *cmMakefile::GetProperty(const char* prop, output += this->DefineFlagsOrig; return output.c_str(); } - else if (!strcmp("INCLUDE_DIRECTORIES",prop) ) - { - cmOStringStream str; - for (std::vector::const_iterator - it = this->GetIncludeDirectories().begin(); - it != this->GetIncludeDirectories().end(); - ++ it ) - { - if ( it != this->GetIncludeDirectories().begin()) - { - str << ";"; - } - str << it->c_str(); - } - output = str.str(); - return output.c_str(); - } else if (!strcmp("LINK_DIRECTORIES",prop)) { cmOStringStream str; diff --git a/Source/cmMakefile.h b/Source/cmMakefile.h index 1c46a733b4..5e5310f91c 100644 --- a/Source/cmMakefile.h +++ b/Source/cmMakefile.h @@ -524,18 +524,7 @@ public: /** * Get a list of include directories in the build. */ - std::vector& GetIncludeDirectories() - { - return this->IncludeDirectories; - } - const std::vector& GetIncludeDirectories() const - { - return this->IncludeDirectories; - } - void SetIncludeDirectories(const std::vector& vec) - { - this->IncludeDirectories = vec; - } + std::vector GetIncludeDirectories(); /** * Mark include directories as system directories. @@ -880,9 +869,7 @@ protected: // Tests std::map Tests; - // The include and link-library paths. These may have order - // dependency, so they must be vectors (not set). - std::vector IncludeDirectories; + // The link-library paths. Order matters, use std::vector (not std::set). std::vector LinkDirectories; // The set of include directories that are marked as system include