summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrad King <brad.king@kitware.com>2007-03-07 20:15:46 (GMT)
committerBrad King <brad.king@kitware.com>2007-03-07 20:15:46 (GMT)
commitfc19882e8f85516c4f774083b6d9f57f843fb941 (patch)
tree0e673dc5a8b7dfe6eedeb01bfe8f2ec123e3d7bb
parent3bd9d67488b98cb1141b7aaadbffb6550935f2aa (diff)
downloadCMake-fc19882e8f85516c4f774083b6d9f57f843fb941.zip
CMake-fc19882e8f85516c4f774083b6d9f57f843fb941.tar.gz
CMake-fc19882e8f85516c4f774083b6d9f57f843fb941.tar.bz2
ENH: Moved ConvertToRelativePath from cmGlobalGenerator to cmLocalGenerator. This is in preparation for setting up each local generator to have its own RelativePathTopSource and RelativePathTopBinary based on its ancestor directories.
-rw-r--r--Source/cmGlobalGenerator.cxx160
-rw-r--r--Source/cmGlobalGenerator.h21
-rw-r--r--Source/cmLocalGenerator.cxx182
-rw-r--r--Source/cmLocalGenerator.h21
4 files changed, 191 insertions, 193 deletions
diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx
index 92f6420..36d6fba 100644
--- a/Source/cmGlobalGenerator.cxx
+++ b/Source/cmGlobalGenerator.cxx
@@ -42,9 +42,6 @@ cmGlobalGenerator::cmGlobalGenerator()
// By default do not use link scripts.
this->UseLinkScript = false;
- // Relative paths are not configured in the constructor.
- this->RelativePathsConfigured = false;
-
// Whether an install target is needed.
this->InstallTargetEnabled = false;
@@ -1107,163 +1104,6 @@ cmTarget* cmGlobalGenerator::FindTarget(const char* project,
return 0;
}
-//----------------------------------------------------------------------------
-void cmGlobalGenerator::ConfigureRelativePaths()
-{
- // The current working directory on Windows cannot be a network
- // path. Therefore relative paths cannot work when the build tree
- // is a network path.
- std::string source = this->CMakeInstance->GetHomeDirectory();
- std::string binary = this->CMakeInstance->GetHomeOutputDirectory();
- if(binary.size() < 2 || binary.substr(0, 2) != "//")
- {
- this->RelativePathTopSource = source;
- this->RelativePathTopBinary = binary;
- }
- else
- {
- this->RelativePathTopSource = "";
- this->RelativePathTopBinary = "";
- }
-}
-
-//----------------------------------------------------------------------------
-std::string cmGlobalGenerator
-::ConvertToRelativePath(const std::vector<std::string>& local,
- const char* in_remote)
-{
- // The path should never be quoted.
- assert(in_remote[0] != '\"');
-
- // The local path should never have a trailing slash.
- assert(local.size() > 0 && !(local[local.size()-1] == ""));
-
- // If the path is already relative then just return the path.
- if(!cmSystemTools::FileIsFullPath(in_remote))
- {
- return in_remote;
- }
-
- // Make sure relative path conversion is configured.
- if(!this->RelativePathsConfigured)
- {
- this->ConfigureRelativePaths();
- this->RelativePathsConfigured = true;
- }
-
- std::string original = in_remote;
-
- // Skip conversion if the path and local are not both in the source or both
- // in the binary tree
- std::string local_path = cmSystemTools::JoinPath(local);
- bool should_convert = false;
-
- // is the root in the binary tree?
- if (local_path.size() >= this->RelativePathTopBinary.size() &&
- cmSystemTools::ComparePath
- (local_path.substr(0, this->RelativePathTopBinary.size()).c_str(),
- this->RelativePathTopBinary.c_str()))
- {
- // is the source also in the binary tree?
- if (original.size() >= this->RelativePathTopBinary.size() &&
- cmSystemTools::ComparePath
- (original.substr(0, this->RelativePathTopBinary.size()).c_str(),
- this->RelativePathTopBinary.c_str()))
- {
- should_convert = true;
- }
- }
-
- if (local_path.size() >= this->RelativePathTopSource.size() &&
- cmSystemTools::ComparePath
- (local_path.substr(0, this->RelativePathTopSource.size()).c_str(),
- this->RelativePathTopSource.c_str()))
- {
- // is the source also in the binary tree?
- if (original.size() >= this->RelativePathTopSource.size() &&
- cmSystemTools::ComparePath
- (original.substr(0, this->RelativePathTopSource.size()).c_str(),
- this->RelativePathTopSource.c_str()))
- {
- should_convert = true;
- }
- }
-
- if (!should_convert)
- {
- return in_remote;
- }
-
- // Identify the longest shared path component between the remote
- // path and the local path.
- std::vector<std::string> remote;
- cmSystemTools::SplitPath(in_remote, remote);
- unsigned int common=0;
- while(common < remote.size() &&
- common < local.size() &&
- cmSystemTools::ComparePath(remote[common].c_str(),
- local[common].c_str()))
- {
- ++common;
- }
-
- // If no part of the path is in common then return the full path.
- if(common == 0)
- {
- return in_remote;
- }
-
- // If the entire path is in common then just return a ".".
- if(common == remote.size() &&
- common == local.size())
- {
- return ".";
- }
-
- // If the entire path is in common except for a trailing slash then
- // just return a "./".
- if(common+1 == remote.size() &&
- remote[common].size() == 0 &&
- common == local.size())
- {
- return "./";
- }
-
- // Construct the relative path.
- std::string relative;
-
- // First add enough ../ to get up to the level of the shared portion
- // of the path. Leave off the trailing slash. Note that the last
- // component of local will never be empty because local should never
- // have a trailing slash.
- for(unsigned int i=common; i < local.size(); ++i)
- {
- relative += "..";
- if(i < local.size()-1)
- {
- relative += "/";
- }
- }
-
- // Now add the portion of the destination path that is not included
- // in the shared portion of the path. Add a slash the first time
- // only if there was already something in the path. If there was a
- // trailing slash in the input then the last iteration of the loop
- // will add a slash followed by an empty string which will preserve
- // the trailing slash in the output.
- for(unsigned int i=common; i < remote.size(); ++i)
- {
- if(relative.size() > 0)
- {
- relative += "/";
- }
- relative += remote[i];
- }
-
- // Finally return the path.
- return relative;
-}
-
inline std::string removeQuotes(const std::string& s)
{
if(s[0] == '\"' && s[s.size()-1] == '\"')
diff --git a/Source/cmGlobalGenerator.h b/Source/cmGlobalGenerator.h
index da98f52..7072f26 100644
--- a/Source/cmGlobalGenerator.h
+++ b/Source/cmGlobalGenerator.h
@@ -144,16 +144,6 @@ public:
///! What is the configurations directory variable called?
virtual const char* GetCMakeCFGInitDirectory() { return "."; }
- /**
- * Convert the given remote path to a relative path with respect to
- * the given local path. The local path must be given in component
- * form (see SystemTools::SplitPath) without a trailing slash. The
- * remote path must use forward slashes and not already be escaped
- * or quoted.
- */
- std::string ConvertToRelativePath(const std::vector<std::string>& local,
- const char* remote);
-
/** Get whether the generator should use a script for link commands. */
bool GetUseLinkScript() { return this->UseLinkScript; }
@@ -209,9 +199,6 @@ protected:
void FillProjectMap();
bool IsExcluded(cmLocalGenerator* root, cmLocalGenerator* gen);
- void ConfigureRelativePaths();
- bool RelativePathsConfigured;
-
void CreateDefaultGlobalTargets(cmTargets* targets);
cmTarget CreateGlobalTarget(const char* name, const char* message,
const cmCustomCommandLines* commandLines,
@@ -246,14 +233,6 @@ private:
std::map<cmStdString, cmStdString> ExtensionToLanguage;
std::map<cmStdString, cmStdString> LanguageToLinkerPreference;
- // The paths to the tops of the source and binary trees used for
- // relative path computation. A path must be either in the source
- // tree or the build tree to be converted to a relative path. The
- // ConfigureRelativePaths method may set these to be empty when
- // using relative paths is unsafe.
- std::string RelativePathTopSource;
- std::string RelativePathTopBinary;
-
// this is used to improve performance
std::map<cmStdString,cmTarget *> TotalTargets;
};
diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx
index 1a68871..559482f 100644
--- a/Source/cmLocalGenerator.cxx
+++ b/Source/cmLocalGenerator.cxx
@@ -45,6 +45,7 @@ cmLocalGenerator::cmLocalGenerator()
this->UseRelativePaths = false;
this->Configured = false;
this->EmitUniversalBinaryFlags = true;
+ this->RelativePathsConfigured = false;
}
cmLocalGenerator::~cmLocalGenerator()
@@ -2020,27 +2021,25 @@ std::string cmLocalGenerator::Convert(const char* source,
{
case HOME:
//result = cmSystemTools::CollapseFullPath(result.c_str());
- result = this->GlobalGenerator->
- ConvertToRelativePath(this->HomeDirectoryComponents,
- result.c_str());
+ result = this->ConvertToRelativePath(this->HomeDirectoryComponents,
+ result.c_str());
break;
case START:
//result = cmSystemTools::CollapseFullPath(result.c_str());
- result = this->GlobalGenerator->
- ConvertToRelativePath(this->StartDirectoryComponents,
- result.c_str());
+ result = this->ConvertToRelativePath(this->StartDirectoryComponents,
+ result.c_str());
break;
case HOME_OUTPUT:
//result = cmSystemTools::CollapseFullPath(result.c_str());
- result = this->GlobalGenerator->
- ConvertToRelativePath(this->HomeOutputDirectoryComponents,
- result.c_str());
+ result =
+ this->ConvertToRelativePath(this->HomeOutputDirectoryComponents,
+ result.c_str());
break;
case START_OUTPUT:
//result = cmSystemTools::CollapseFullPath(result.c_str());
- result = this->GlobalGenerator->
- ConvertToRelativePath(this->StartOutputDirectoryComponents,
- result.c_str());
+ result =
+ this->ConvertToRelativePath(this->StartOutputDirectoryComponents,
+ result.c_str());
break;
case FULL:
result = cmSystemTools::CollapseFullPath(result.c_str());
@@ -2082,6 +2081,165 @@ std::string cmLocalGenerator::Convert(const char* source,
return result;
}
+//----------------------------------------------------------------------------
+void cmLocalGenerator::ConfigureRelativePaths()
+{
+ // The current working directory on Windows cannot be a network
+ // path. Therefore relative paths cannot work when the build tree
+ // is a network path.
+ std::string source = this->Makefile->GetHomeDirectory();
+ std::string binary = this->Makefile->GetHomeOutputDirectory();
+ if(binary.size() < 2 || binary.substr(0, 2) != "//")
+ {
+ this->RelativePathTopSource = source;
+ this->RelativePathTopBinary = binary;
+ }
+ else
+ {
+ this->RelativePathTopSource = "";
+ this->RelativePathTopBinary = "";
+ }
+}
+
+//----------------------------------------------------------------------------
+std::string
+cmLocalGenerator
+::ConvertToRelativePath(const std::vector<std::string>& local,
+ const char* in_remote)
+{
+ // The path should never be quoted.
+ assert(in_remote[0] != '\"');
+
+ // The local path should never have a trailing slash.
+ assert(local.size() > 0 && !(local[local.size()-1] == ""));
+
+ // If the path is already relative then just return the path.
+ if(!cmSystemTools::FileIsFullPath(in_remote))
+ {
+ return in_remote;
+ }
+
+ // Make sure relative path conversion is configured.
+ if(!this->RelativePathsConfigured)
+ {
+ this->ConfigureRelativePaths();
+ this->RelativePathsConfigured = true;
+ }
+
+ std::string original = in_remote;
+
+ // Skip conversion if the path and local are not both in the source or both
+ // in the binary tree
+ std::string local_path = cmSystemTools::JoinPath(local);
+ bool should_convert = false;
+
+ // A relative path is safe if both the local and remote locations
+ // are underneath the current relative path top in the binary tree.
+ if (local_path.size() >= this->RelativePathTopBinary.size() &&
+ cmSystemTools::ComparePath
+ (local_path.substr(0, this->RelativePathTopBinary.size()).c_str(),
+ this->RelativePathTopBinary.c_str()))
+ {
+ if (original.size() >= this->RelativePathTopBinary.size() &&
+ cmSystemTools::ComparePath
+ (original.substr(0, this->RelativePathTopBinary.size()).c_str(),
+ this->RelativePathTopBinary.c_str()))
+ {
+ should_convert = true;
+ }
+ }
+
+ // A relative path is safe if both the local and remote locations
+ // are underneath the current relative path top in the source tree.
+ if (local_path.size() >= this->RelativePathTopSource.size() &&
+ cmSystemTools::ComparePath
+ (local_path.substr(0, this->RelativePathTopSource.size()).c_str(),
+ this->RelativePathTopSource.c_str()))
+ {
+ if (original.size() >= this->RelativePathTopSource.size() &&
+ cmSystemTools::ComparePath
+ (original.substr(0, this->RelativePathTopSource.size()).c_str(),
+ this->RelativePathTopSource.c_str()))
+ {
+ should_convert = true;
+ }
+ }
+
+ // Do not convert if it is not safe.
+ if(!should_convert)
+ {
+ return in_remote;
+ }
+
+ // Identify the longest shared path component between the remote
+ // path and the local path.
+ std::vector<std::string> remote;
+ cmSystemTools::SplitPath(in_remote, remote);
+ unsigned int common=0;
+ while(common < remote.size() &&
+ common < local.size() &&
+ cmSystemTools::ComparePath(remote[common].c_str(),
+ local[common].c_str()))
+ {
+ ++common;
+ }
+
+ // If no part of the path is in common then return the full path.
+ if(common == 0)
+ {
+ return in_remote;
+ }
+
+ // If the entire path is in common then just return a ".".
+ if(common == remote.size() &&
+ common == local.size())
+ {
+ return ".";
+ }
+
+ // If the entire path is in common except for a trailing slash then
+ // just return a "./".
+ if(common+1 == remote.size() &&
+ remote[common].size() == 0 &&
+ common == local.size())
+ {
+ return "./";
+ }
+
+ // Construct the relative path.
+ std::string relative;
+
+ // First add enough ../ to get up to the level of the shared portion
+ // of the path. Leave off the trailing slash. Note that the last
+ // component of local will never be empty because local should never
+ // have a trailing slash.
+ for(unsigned int i=common; i < local.size(); ++i)
+ {
+ relative += "..";
+ if(i < local.size()-1)
+ {
+ relative += "/";
+ }
+ }
+
+ // Now add the portion of the destination path that is not included
+ // in the shared portion of the path. Add a slash the first time
+ // only if there was already something in the path. If there was a
+ // trailing slash in the input then the last iteration of the loop
+ // will add a slash followed by an empty string which will preserve
+ // the trailing slash in the output.
+ for(unsigned int i=common; i < remote.size(); ++i)
+ {
+ if(relative.size() > 0)
+ {
+ relative += "/";
+ }
+ relative += remote[i];
+ }
+
+ // Finally return the path.
+ return relative;
+}
//----------------------------------------------------------------------------
void
diff --git a/Source/cmLocalGenerator.h b/Source/cmLocalGenerator.h
index 1b8f124..6b4d7dc 100644
--- a/Source/cmLocalGenerator.h
+++ b/Source/cmLocalGenerator.h
@@ -266,6 +266,18 @@ protected:
std::string GetObjectFileNameWithoutTarget(const cmSourceFile& source);
std::string& CreateSafeUniqueObjectFileName(const char* sin);
+ void ConfigureRelativePaths();
+
+ /**
+ * Convert the given remote path to a relative path with respect to
+ * the given local path. The local path must be given in component
+ * form (see SystemTools::SplitPath) without a trailing slash. The
+ * remote path must use forward slashes and not already be escaped
+ * or quoted.
+ */
+ std::string ConvertToRelativePath(const std::vector<std::string>& local,
+ const char* remote);
+
cmMakefile *Makefile;
cmGlobalGenerator *GlobalGenerator;
// members used for relative path function ConvertToMakefilePath
@@ -291,6 +303,15 @@ protected:
// Hack for ExpandRuleVariable until object-oriented version is
// committed.
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;
};
#endif