cmState: Store computed relative paths to to current directories.

This commit is contained in:
Stephen Kelly 2015-05-04 23:30:29 +02:00
parent 991f5e4968
commit 9e4b6cc2ce
5 changed files with 132 additions and 121 deletions

View File

@ -66,7 +66,6 @@ cmLocalGenerator::cmLocalGenerator(cmGlobalGenerator* gg,
this->UseRelativePaths = false; this->UseRelativePaths = false;
this->Configured = false; this->Configured = false;
this->EmitUniversalBinaryFlags = true; this->EmitUniversalBinaryFlags = true;
this->RelativePathsConfigured = false;
this->BackwardsCompatibility = 0; this->BackwardsCompatibility = 0;
this->BackwardsCompatibilityFinal = false; this->BackwardsCompatibilityFinal = false;
} }
@ -2778,97 +2777,6 @@ std::string cmLocalGenerator::Convert(RelativeRoot remote,
} }
} }
//----------------------------------------------------------------------------
std::string cmLocalGenerator::FindRelativePathTopSource()
{
cmState::Snapshot snapshot = this->StateSnapshot;
std::vector<cmState::Snapshot> snapshots;
snapshots.push_back(snapshot);
while (true)
{
snapshot = snapshot.GetParent();
if (snapshot.IsValid())
{
snapshots.push_back(snapshot);
}
else
{
break;
}
}
std::string result = snapshots.front().GetCurrentSourceDirectory();
for (std::vector<cmState::Snapshot>::const_iterator it =
snapshots.begin() + 1; it != snapshots.end(); ++it)
{
std::string currentSource = it->GetCurrentSourceDirectory();
if(cmSystemTools::IsSubDirectory(result, currentSource))
{
result = currentSource;
}
}
return result;
}
//----------------------------------------------------------------------------
std::string cmLocalGenerator::FindRelativePathTopBinary()
{
cmState::Snapshot snapshot = this->StateSnapshot;
std::vector<cmState::Snapshot> snapshots;
snapshots.push_back(snapshot);
while (true)
{
snapshot = snapshot.GetParent();
if (snapshot.IsValid())
{
snapshots.push_back(snapshot);
}
else
{
break;
}
}
std::string result = snapshots.front().GetCurrentBinaryDirectory();
for (std::vector<cmState::Snapshot>::const_iterator it =
snapshots.begin() + 1; it != snapshots.end(); ++it)
{
std::string currentBinary = it->GetCurrentBinaryDirectory();
if(cmSystemTools::IsSubDirectory(result, currentBinary))
{
result = currentBinary;
}
}
return result;
}
//----------------------------------------------------------------------------
void cmLocalGenerator::ConfigureRelativePaths()
{
// Relative path conversion inside the source tree is not used to
// construct relative paths passed to build tools so it is safe to
// even when the source is a network path.
std::string source = this->FindRelativePathTopSource();
this->RelativePathTopSource = source;
// The current working directory on Windows cannot be a network
// path. Therefore relative paths cannot work when the binary tree
// is a network path.
std::string binary = this->FindRelativePathTopBinary();
if(binary.size() < 2 || binary.substr(0, 2) != "//")
{
this->RelativePathTopBinary = binary;
}
else
{
this->RelativePathTopBinary = "";
}
}
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
static bool cmLocalGeneratorNotAbove(const char* a, const char* b) static bool cmLocalGeneratorNotAbove(const char* a, const char* b)
{ {
@ -2894,26 +2802,19 @@ cmLocalGenerator::ConvertToRelativePath(const std::vector<std::string>& local,
return in_remote; return in_remote;
} }
// Make sure relative path conversion is configured.
if(!this->RelativePathsConfigured)
{
this->ConfigureRelativePaths();
this->RelativePathsConfigured = true;
}
if(!force) if(!force)
{ {
// Skip conversion if the path and local are not both in the source // Skip conversion if the path and local are not both in the source
// or both in the binary tree. // or both in the binary tree.
std::string local_path = cmSystemTools::JoinPath(local); std::string local_path = cmSystemTools::JoinPath(local);
if(!((cmLocalGeneratorNotAbove(local_path.c_str(), if(!((cmLocalGeneratorNotAbove(local_path.c_str(),
this->RelativePathTopBinary.c_str()) && this->StateSnapshot.GetRelativePathTopBinary()) &&
cmLocalGeneratorNotAbove(in_remote.c_str(), cmLocalGeneratorNotAbove(in_remote.c_str(),
this->RelativePathTopBinary.c_str())) || this->StateSnapshot.GetRelativePathTopBinary())) ||
(cmLocalGeneratorNotAbove(local_path.c_str(), (cmLocalGeneratorNotAbove(local_path.c_str(),
this->RelativePathTopSource.c_str()) && this->StateSnapshot.GetRelativePathTopSource()) &&
cmLocalGeneratorNotAbove(in_remote.c_str(), cmLocalGeneratorNotAbove(in_remote.c_str(),
this->RelativePathTopSource.c_str())))) this->StateSnapshot.GetRelativePathTopSource()))))
{ {
return in_remote; return in_remote;
} }

View File

@ -440,10 +440,6 @@ protected:
std::string const& dir_max); std::string const& dir_max);
void ComputeObjectMaxPath(); void ComputeObjectMaxPath();
void ConfigureRelativePaths();
std::string FindRelativePathTopSource();
std::string FindRelativePathTopBinary();
virtual std::string ConvertToLinkReference(std::string const& lib, virtual std::string ConvertToLinkReference(std::string const& lib,
OutputFormat format = SHELL); OutputFormat format = SHELL);
@ -473,15 +469,6 @@ protected:
// committed. // committed.
std::string TargetImplib; std::string TargetImplib;
// The top-most directories for relative path conversion. Both the
// source and destination location of a relative path conversion
// must be underneath one of these directories (both under source or
// both under binary) in order for the relative path to be evaluated
// safely by the build tools.
std::string RelativePathTopSource;
std::string RelativePathTopBinary;
bool RelativePathsConfigured;
cmIML_INT_uint64_t BackwardsCompatibility; cmIML_INT_uint64_t BackwardsCompatibility;
bool BackwardsCompatibilityFinal; bool BackwardsCompatibilityFinal;
private: private:

View File

@ -545,9 +545,11 @@ void cmLocalUnixMakefileGenerator3::WriteDirectoryInformationFile()
// Setup relative path conversion tops. // Setup relative path conversion tops.
infoFileStream infoFileStream
<< "# Relative path conversion top directories.\n" << "# Relative path conversion top directories.\n"
<< "set(CMAKE_RELATIVE_PATH_TOP_SOURCE \"" << this->RelativePathTopSource << "set(CMAKE_RELATIVE_PATH_TOP_SOURCE \""
<< this->StateSnapshot.GetRelativePathTopSource()
<< "\")\n" << "\")\n"
<< "set(CMAKE_RELATIVE_PATH_TOP_BINARY \"" << this->RelativePathTopBinary << "set(CMAKE_RELATIVE_PATH_TOP_BINARY \""
<< this->StateSnapshot.GetRelativePathTopBinary()
<< "\")\n" << "\")\n"
<< "\n"; << "\n";
@ -1613,16 +1615,15 @@ cmLocalUnixMakefileGenerator3
} }
// Setup relative path top directories. // Setup relative path top directories.
this->RelativePathsConfigured = true;
if(const char* relativePathTopSource = if(const char* relativePathTopSource =
mf->GetDefinition("CMAKE_RELATIVE_PATH_TOP_SOURCE")) mf->GetDefinition("CMAKE_RELATIVE_PATH_TOP_SOURCE"))
{ {
this->RelativePathTopSource = relativePathTopSource; this->StateSnapshot.SetRelativePathTopSource(relativePathTopSource);
} }
if(const char* relativePathTopBinary = if(const char* relativePathTopBinary =
mf->GetDefinition("CMAKE_RELATIVE_PATH_TOP_BINARY")) mf->GetDefinition("CMAKE_RELATIVE_PATH_TOP_BINARY"))
{ {
this->RelativePathTopBinary = relativePathTopBinary; this->StateSnapshot.SetRelativePathTopBinary(relativePathTopBinary);
} }
} }
else else

View File

@ -199,6 +199,8 @@ void cmState::Initialize()
this->ParentPositions.clear(); this->ParentPositions.clear();
this->CurrentSourceDirectoryComponents.clear(); this->CurrentSourceDirectoryComponents.clear();
this->CurrentBinaryDirectoryComponents.clear(); this->CurrentBinaryDirectoryComponents.clear();
this->RelativePathTopSource.clear();
this->RelativePathTopBinary.clear();
this->CreateSnapshot(Snapshot()); this->CreateSnapshot(Snapshot());
this->DefineProperty this->DefineProperty
@ -496,6 +498,86 @@ std::vector<std::string> const& cmState::GetBinaryDirectoryComponents() const
return this->BinaryDirectoryComponents; return this->BinaryDirectoryComponents;
} }
void cmState::Snapshot::ComputeRelativePathTopSource()
{
// Relative path conversion inside the source tree is not used to
// construct relative paths passed to build tools so it is safe to use
// even when the source is a network path.
cmState::Snapshot snapshot = *this;
std::vector<cmState::Snapshot> snapshots;
snapshots.push_back(snapshot);
while (true)
{
snapshot = snapshot.GetParent();
if (snapshot.IsValid())
{
snapshots.push_back(snapshot);
}
else
{
break;
}
}
std::string result = snapshots.front().GetCurrentSourceDirectory();
for (std::vector<cmState::Snapshot>::const_iterator it =
snapshots.begin() + 1; it != snapshots.end(); ++it)
{
std::string currentSource = it->GetCurrentSourceDirectory();
if(cmSystemTools::IsSubDirectory(result, currentSource))
{
result = currentSource;
}
}
this->State->RelativePathTopSource[this->Position] = result;
}
void cmState::Snapshot::ComputeRelativePathTopBinary()
{
cmState::Snapshot snapshot = *this;
std::vector<cmState::Snapshot> snapshots;
snapshots.push_back(snapshot);
while (true)
{
snapshot = snapshot.GetParent();
if (snapshot.IsValid())
{
snapshots.push_back(snapshot);
}
else
{
break;
}
}
std::string result =
snapshots.front().GetCurrentBinaryDirectory();
for (std::vector<cmState::Snapshot>::const_iterator it =
snapshots.begin() + 1; it != snapshots.end(); ++it)
{
std::string currentBinary = it->GetCurrentBinaryDirectory();
if(cmSystemTools::IsSubDirectory(result, currentBinary))
{
result = currentBinary;
}
}
// The current working directory on Windows cannot be a network
// path. Therefore relative paths cannot work when the binary tree
// is a network path.
if(result.size() < 2 || result.substr(0, 2) != "//")
{
this->State->RelativePathTopBinary[this->Position] = result;
}
else
{
this->State->RelativePathTopBinary[this->Position] = "";
}
}
cmState::Snapshot cmState::CreateSnapshot(Snapshot originSnapshot) cmState::Snapshot cmState::CreateSnapshot(Snapshot originSnapshot)
{ {
PositionType pos = this->ParentPositions.size(); PositionType pos = this->ParentPositions.size();
@ -506,6 +588,8 @@ cmState::Snapshot cmState::CreateSnapshot(Snapshot originSnapshot)
this->CurrentSourceDirectoryComponents.size() + 1); this->CurrentSourceDirectoryComponents.size() + 1);
this->CurrentBinaryDirectoryComponents.resize( this->CurrentBinaryDirectoryComponents.resize(
this->CurrentBinaryDirectoryComponents.size() + 1); this->CurrentBinaryDirectoryComponents.size() + 1);
this->RelativePathTopSource.resize(this->RelativePathTopSource.size() + 1);
this->RelativePathTopBinary.resize(this->RelativePathTopBinary.size() + 1);
return cmState::Snapshot(this, pos); return cmState::Snapshot(this, pos);
} }
@ -533,6 +617,7 @@ void cmState::Snapshot::SetCurrentSourceDirectory(std::string const& dir)
cmSystemTools::SplitPath( cmSystemTools::SplitPath(
this->State->Locations[this->Position], this->State->Locations[this->Position],
this->State->CurrentSourceDirectoryComponents[this->Position]); this->State->CurrentSourceDirectoryComponents[this->Position]);
this->ComputeRelativePathTopSource();
} }
const char* cmState::Snapshot::GetCurrentBinaryDirectory() const const char* cmState::Snapshot::GetCurrentBinaryDirectory() const
@ -553,6 +638,7 @@ void cmState::Snapshot::SetCurrentBinaryDirectory(std::string const& dir)
cmSystemTools::SplitPath( cmSystemTools::SplitPath(
this->State->OutputLocations[this->Position], this->State->OutputLocations[this->Position],
this->State->CurrentBinaryDirectoryComponents[this->Position]); this->State->CurrentBinaryDirectoryComponents[this->Position]);
this->ComputeRelativePathTopBinary();
} }
std::vector<std::string> const& std::vector<std::string> const&
@ -567,6 +653,26 @@ cmState::Snapshot::GetCurrentBinaryDirectoryComponents()
return this->State->CurrentBinaryDirectoryComponents[this->Position]; return this->State->CurrentBinaryDirectoryComponents[this->Position];
} }
const char* cmState::Snapshot::GetRelativePathTopSource() const
{
return this->State->RelativePathTopSource[this->Position].c_str();
}
const char* cmState::Snapshot::GetRelativePathTopBinary() const
{
return this->State->RelativePathTopBinary[this->Position].c_str();
}
void cmState::Snapshot::SetRelativePathTopSource(const char* dir)
{
this->State->RelativePathTopSource[this->Position] = dir;
}
void cmState::Snapshot::SetRelativePathTopBinary(const char* dir)
{
this->State->RelativePathTopBinary[this->Position] = dir;
}
bool cmState::Snapshot::IsValid() const bool cmState::Snapshot::IsValid() const
{ {
return this->State ? true : false; return this->State ? true : false;

View File

@ -39,9 +39,18 @@ public:
std::vector<std::string> const& GetCurrentSourceDirectoryComponents(); std::vector<std::string> const& GetCurrentSourceDirectoryComponents();
std::vector<std::string> const& GetCurrentBinaryDirectoryComponents(); std::vector<std::string> const& GetCurrentBinaryDirectoryComponents();
const char* GetRelativePathTopSource() const;
const char* GetRelativePathTopBinary() const;
void SetRelativePathTopSource(const char* dir);
void SetRelativePathTopBinary(const char* dir);
bool IsValid() const; bool IsValid() const;
Snapshot GetParent() const; Snapshot GetParent() const;
private:
void ComputeRelativePathTopSource();
void ComputeRelativePathTopBinary();
private: private:
friend class cmState; friend class cmState;
cmState* State; cmState* State;
@ -141,6 +150,13 @@ private:
std::vector<std::vector<std::string> > CurrentSourceDirectoryComponents; std::vector<std::vector<std::string> > CurrentSourceDirectoryComponents;
std::vector<std::vector<std::string> > CurrentBinaryDirectoryComponents; std::vector<std::vector<std::string> > CurrentBinaryDirectoryComponents;
// The top-most directories for relative path conversion. Both the
// source and destination location of a relative path conversion
// must be underneath one of these directories (both under source or
// both under binary) in order for the relative path to be evaluated
// safely by the build tools.
std::vector<std::string> RelativePathTopSource;
std::vector<std::string> RelativePathTopBinary;
std::vector<std::string> SourceDirectoryComponents; std::vector<std::string> SourceDirectoryComponents;
std::vector<std::string> BinaryDirectoryComponents; std::vector<std::string> BinaryDirectoryComponents;