cmDependsC: Collapse relative include paths

While calculating dependencies collapse sequences such as

 ../../../a/b/c/../../d/e/../../e/f

to avoid total path lengths over the Windows path length limit as much
as possible.
This commit is contained in:
Pavel Shramov 2013-06-19 16:35:23 +04:00 committed by Brad King
parent 7c61c73fbc
commit 551d3343cd
3 changed files with 44 additions and 14 deletions

View File

@ -193,17 +193,8 @@ bool cmDependsC::WriteDependencies(const std::set<std::string>& sources,
// Construct the name of the file as if it were in the current
// include directory. Avoid using a leading "./".
tempPathStr = "";
if((*i) == ".")
{
tempPathStr += current.FileName;
}
else
{
tempPathStr += *i;
tempPathStr+="/";
tempPathStr+=current.FileName;
}
tempPathStr =
cmSystemTools::CollapseCombinedPath(*i, current.FileName);
// Look for the file in this location.
if(cmSystemTools::FileExists(tempPathStr.c_str(), true))
@ -458,9 +449,8 @@ void cmDependsC::Scan(std::istream& is, const char* directory,
// This was a double-quoted include with a relative path. We
// must check for the file in the directory containing the
// file we are scanning.
entry.QuotedLocation = directory;
entry.QuotedLocation += "/";
entry.QuotedLocation += entry.FileName;
entry.QuotedLocation =
cmSystemTools::CollapseCombinedPath(directory, entry.FileName);
}
// Queue the file if it has not yet been encountered and it

View File

@ -1594,6 +1594,40 @@ std::string cmSystemTools::RelativePath(const char* local, const char* remote)
return cmsys::SystemTools::RelativePath(local, remote);
}
std::string cmSystemTools::CollapseCombinedPath(std::string const& dir,
std::string const& file)
{
if(dir.empty() || dir == ".")
{
return file;
}
std::vector<std::string> dirComponents;
std::vector<std::string> fileComponents;
cmSystemTools::SplitPath(dir.c_str(), dirComponents);
cmSystemTools::SplitPath(file.c_str(), fileComponents);
if(fileComponents.empty())
{
return dir;
}
if(fileComponents[0] != "")
{
// File is not a relative path.
return file;
}
std::vector<std::string>::iterator i = fileComponents.begin()+1;
while(i != fileComponents.end() && *i == ".." && dirComponents.size() > 1)
{
++i; // Remove ".." file component.
dirComponents.pop_back(); // Remove last dir component.
}
dirComponents.insert(dirComponents.end(), i, fileComponents.end());
return cmSystemTools::JoinPath(dirComponents);
}
#ifdef CMAKE_BUILD_WITH_CMAKE
//----------------------------------------------------------------------
bool cmSystemTools::UnsetEnv(const char* value)

View File

@ -365,6 +365,12 @@ public:
*/
static std::string RelativePath(const char* local, const char* remote);
/** Joins two paths while collapsing x/../ parts
* For example CollapseCombinedPath("a/b/c", "../../d") results in "a/d"
*/
static std::string CollapseCombinedPath(std::string const& dir,
std::string const& file);
#ifdef CMAKE_BUILD_WITH_CMAKE
/** Remove an environment variable */
static bool UnsetEnv(const char* value);