summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Source/cmGlobalGenerator.cxx138
-rw-r--r--Source/cmGlobalGenerator.h18
-rw-r--r--Source/cmLocalGenerator.cxx130
-rw-r--r--Source/cmLocalGenerator.h36
-rw-r--r--Source/cmLocalUnixMakefileGenerator2.cxx147
-rw-r--r--Source/cmLocalUnixMakefileGenerator2.h9
6 files changed, 239 insertions, 239 deletions
diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx
index 296a008..4b8d711 100644
--- a/Source/cmGlobalGenerator.cxx
+++ b/Source/cmGlobalGenerator.cxx
@@ -24,6 +24,8 @@
#include <windows.h>
#endif
+#include <assert.h>
+
int cmGlobalGenerator::s_TryCompileTimeout = 0;
cmGlobalGenerator::cmGlobalGenerator()
@@ -487,7 +489,10 @@ void cmGlobalGenerator::Configure()
delete m_LocalGenerators[i];
}
m_LocalGenerators.clear();
-
+
+ // Setup relative path generation.
+ this->ConfigureRelativePaths();
+
// start with this directory
cmLocalGenerator *lg = this->CreateLocalGenerator();
m_LocalGenerators.push_back(lg);
@@ -573,6 +578,7 @@ void cmGlobalGenerator::Configure()
}
}
+
// loop through the directories creating cmLocalGenerators and Configure()
void cmGlobalGenerator::RecursiveConfigure(cmLocalGenerator *lg,
float startProgress,
@@ -877,3 +883,133 @@ cmTarget* cmGlobalGenerator::FindTarget(const char* name)
return 0;
}
+//----------------------------------------------------------------------------
+void cmGlobalGenerator::ConfigureRelativePaths()
+{
+ // Identify the longest shared path component between the source
+ // directory and the build directory.
+ std::vector<std::string> source;
+ std::vector<std::string> binary;
+ cmSystemTools::SplitPath(m_CMakeInstance->GetHomeDirectory(), source);
+ cmSystemTools::SplitPath(m_CMakeInstance->GetHomeOutputDirectory(), binary);
+ unsigned int common=0;
+ while(common < source.size() && common < binary.size() &&
+ cmSystemTools::ComparePath(source[common].c_str(),
+ binary[common].c_str()))
+ {
+ ++common;
+ }
+
+ // Require more than just the root portion of the path to be in
+ // common before allowing relative paths. Also disallow relative
+ // paths if the build tree is a network path. The current working
+ // directory on Windows cannot be a network path. Therefore
+ // relative paths cannot work with network paths.
+ if(common > 1 && source[0] != "//")
+ {
+ // Build the minimum prefix required of a path to be converted to
+ // a relative path.
+ source.erase(source.begin()+common, source.end());
+ m_RelativePathTop = cmSystemTools::JoinPath(source);
+ }
+ else
+ {
+ // Disable relative paths.
+ m_RelativePathTop = "";
+ }
+}
+
+//----------------------------------------------------------------------------
+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 or relative paths are disabled
+ // then just return the path.
+ if(m_RelativePathTop.size() == 0 ||
+ !cmSystemTools::FileIsFullPath(in_remote))
+ {
+ return in_remote;
+ }
+
+ // If the path does not begin with the minimum relative path prefix
+ // then do not convert it.
+ std::string original = in_remote;
+ if(original.size() < m_RelativePathTop.size() ||
+ !cmSystemTools::ComparePath(
+ original.substr(0, m_RelativePathTop.size()).c_str(),
+ m_RelativePathTop.c_str()))
+ {
+ 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 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;
+}
+
diff --git a/Source/cmGlobalGenerator.h b/Source/cmGlobalGenerator.h
index 6f4d3b4..7832a96 100644
--- a/Source/cmGlobalGenerator.h
+++ b/Source/cmGlobalGenerator.h
@@ -129,11 +129,24 @@ public:
const char* GetLanguageOutputExtensionForLanguage(const char* lang);
///! What is the output extension for a given source file extension.
const char* GetLanguageOutputExtensionFromExtension(const char* lang);
+
+ /**
+ * 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);
+
protected:
// Fill the m_ProjectMap, this must be called after m_LocalGenerators has been populated.
void FillProjectMap();
bool IsExcluded(cmLocalGenerator* root, cmLocalGenerator* gen);
void FindMakeProgram(cmMakefile*);
+
+ void ConfigureRelativePaths();
bool m_ForceUnixPaths;
cmStdString m_FindMakeProgramFile;
@@ -157,6 +170,11 @@ private:
std::map<cmStdString, cmStdString> m_LanguageToOutputExtension;
std::map<cmStdString, cmStdString> m_ExtensionToLanguage;
std::map<cmStdString, cmStdString> m_LanguageToLinkerPreference;
+
+ // The prefix required of a path to be converted to a relative path.
+ // No sequence of ../.. will ever go past this path. This is the
+ // longest common path between the top level source and build trees.
+ std::string m_RelativePathTop;
};
#endif
diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx
index e0d296c..61f20ec 100644
--- a/Source/cmLocalGenerator.cxx
+++ b/Source/cmLocalGenerator.cxx
@@ -51,6 +51,16 @@ void cmLocalGenerator::Configure()
std::string currentStart = m_Makefile->GetStartDirectory();
currentStart += "/CMakeLists.txt";
m_Makefile->ReadListFile(currentStart.c_str());
+
+ // Setup the current output directory components for use by
+ // ConvertToRelativePath.
+ std::string outdir =
+ cmSystemTools::CollapseFullPath(m_Makefile->GetCurrentOutputDirectory());
+ cmSystemTools::SplitPath(outdir.c_str(), m_CurrentOutputDirectoryComponents);
+
+ // Check whether relative paths should be used for optionally
+ // relative paths.
+ m_UseRelativePaths = m_Makefile->IsOn("CMAKE_USE_RELATIVE_PATHS");
}
void cmLocalGenerator::SetGlobalGenerator(cmGlobalGenerator *gg)
@@ -404,83 +414,6 @@ std::string cmLocalGenerator::GetFullTargetName(const char* n,
return name;
}
-
-std::string cmLocalGenerator::ConvertToRelativeOutputPath(const char* p)
-{
- if ( !m_Makefile->IsOn("CMAKE_USE_RELATIVE_PATHS") )
- {
- return cmSystemTools::ConvertToOutputPath(p);
- }
- // NOTE, much of this was copied to
- // cmGlobalXCodeGenerator::ConvertToRelativeOutputPath
- // fixes here should be made there as well.
-
- // copy to a string class
- std::string pathIn = p;
- // check to see if the path is already relative, it is
- // considered relative if one of the following is true
- // - has no / in it at all
- // - does not start with / or drive leter :
- // - starts with a ".."
- if(pathIn.find('/') == pathIn.npos ||
- (pathIn[0] != '/' && pathIn[1] != ':') ||
- pathIn.find("..") == 0)
- {
- return cmSystemTools::ConvertToOutputPath(p);
- }
-
- // do not use relative paths for network build trees
- // the network paths do not work
- const char* outputDirectory = m_Makefile->GetHomeOutputDirectory();
- if ( outputDirectory && *outputDirectory && *(outputDirectory+1) &&
- outputDirectory[0] == '/' && outputDirectory[1] == '/' )
- {
- return cmSystemTools::ConvertToOutputPath(p);
- }
- // if the path is double quoted remove the double quotes
- if(pathIn.size() && pathIn[0] == '\"')
- {
- pathIn = pathIn.substr(1, pathIn.size()-2);
- }
- // The first time this is called
- // initialize m_CurrentOutputDirectory to contain
- // the full path to the current output directory
- // This has to be done here and not in the constructor
- // because the output directory is not yet set in the constructor.
- if(m_CurrentOutputDirectory.size() == 0)
- {
- m_CurrentOutputDirectory = cmSystemTools::CollapseFullPath(m_Makefile->GetCurrentOutputDirectory());
- }
- // Given that we are in m_CurrentOutputDirectory how to we
- // get to pathIn with a relative path, store in ret
- std::string ret = cmSystemTools::RelativePath(m_CurrentOutputDirectory.c_str(), pathIn.c_str());
- // If the path is 0 sized make it a .
- // this happens when pathIn is the same as m_CurrentOutputDirectory
- if(ret.size() == 0)
- {
- ret = ".";
- }
- // if there was a trailing / there still is one, and
- // if there was not one, there still is not one
- if(ret[ret.size()-1] == '/' &&
- pathIn[pathIn.size()-1] != '/')
- {
- ret.erase(ret.size()-1, 1);
- }
- if(ret[ret.size()-1] != '/' &&
- pathIn[pathIn.size()-1] == '/')
- {
- ret += "/";
- }
- // Now convert the relative path to an output path
- ret = cmSystemTools::ConvertToOutputPath(ret.c_str());
- // finally return the path
- // at this point it should be relative and in the correct format
- // for the native build system. (i.e. \ for windows and / for unix,
- // and correct escaping/quoting of spaces in the path
- return ret;
-}
-
void cmLocalGenerator::AddCustomCommandToCreateObject(const char* ofname,
const char* lang,
cmSourceFile& source,
@@ -1356,3 +1289,46 @@ cmLocalGenerator::ConstructScript(const cmCustomCommandLines& commandLines,
}
return script;
}
+
+//----------------------------------------------------------------------------
+std::string cmLocalGenerator::ConvertToRelativePath(const char* remote)
+{
+ return (m_GlobalGenerator
+ ->ConvertToRelativePath(m_CurrentOutputDirectoryComponents,
+ remote));
+}
+
+//----------------------------------------------------------------------------
+std::string
+cmLocalGenerator::ConvertToRelativeOutputPath(const char* remote)
+{
+ // TODO: Make this behave like its documentation...always convert.
+ // This involves identifying all calls to it that should be calls to
+ // the optional one.
+ return this->ConvertToOptionallyRelativeOutputPath(remote);
+}
+
+//----------------------------------------------------------------------------
+std::string
+cmLocalGenerator::ConvertToOptionallyRelativePath(const char* remote)
+{
+ if(m_UseRelativePaths)
+ {
+ return this->ConvertToRelativePath(remote);
+ }
+ else
+ {
+ return remote;
+ }
+}
+
+//----------------------------------------------------------------------------
+std::string
+cmLocalGenerator::ConvertToOptionallyRelativeOutputPath(const char* remote)
+{
+ // Convert the path to a relative path.
+ std::string relative = this->ConvertToOptionallyRelativePath(remote);
+
+ // Now convert it to an output path.
+ return cmSystemTools::ConvertToOutputPath(relative.c_str());
+}
diff --git a/Source/cmLocalGenerator.h b/Source/cmLocalGenerator.h
index eaa9a8a..0932c76 100644
--- a/Source/cmLocalGenerator.h
+++ b/Source/cmLocalGenerator.h
@@ -77,8 +77,35 @@ public:
/** Get the full name of the target's file, without path. */
std::string GetFullTargetName(const char* n, const cmTarget& t);
- std::string ConvertToRelativeOutputPath(const char* p);
-
+ /**
+ * Convert the given remote path to a relative path with respect to
+ * this generator's output directory. The remote path must use
+ * forward slashes and not already be escaped or quoted.
+ */
+ std::string ConvertToRelativePath(const char* remote);
+
+ /**
+ * Convert to an output path that is relative to the current output
+ * directory. The remote path must use forward slashes and not
+ * already be escaped or quoted.
+ */
+ std::string ConvertToRelativeOutputPath(const char* remote);
+
+ /**
+ * Calls ConvertToRelativePath conditionally on the cache option
+ * CMAKE_USE_RELATIVE_PATHS. The remote path must use forward
+ * slashes and not already be escaped or quoted.
+ */
+ std::string ConvertToOptionallyRelativePath(const char* remote);
+
+ /**
+ * Convert the given path to an output path that is optionally
+ * relative based on the cache option CMAKE_USE_RELATIVE_PATHS. The
+ * remote path must use forward slashes and not already be escaped
+ * or quoted.
+ */
+ std::string ConvertToOptionallyRelativeOutputPath(const char* remote);
+
// flag to determine if this project should be included in a parent project
bool GetExcludeAll()
{
@@ -156,10 +183,7 @@ protected:
// members used for relative path function ConvertToMakefilePath
std::string m_RelativePathToSourceDir;
std::string m_RelativePathToBinaryDir;
- std::string m_CurrentOutputDirectory;
- std::string m_HomeOutputDirectory;
- std::string m_HomeDirectory;
- std::string m_HomeOutputDirectoryNoSlash;
+ std::vector<std::string> m_CurrentOutputDirectoryComponents;
bool m_ExcludeFromAll;
cmLocalGenerator* m_Parent;
std::map<cmStdString, cmStdString> m_LanguageToIncludeFlags;
diff --git a/Source/cmLocalUnixMakefileGenerator2.cxx b/Source/cmLocalUnixMakefileGenerator2.cxx
index 5eec9f7..2a2aeae 100644
--- a/Source/cmLocalUnixMakefileGenerator2.cxx
+++ b/Source/cmLocalUnixMakefileGenerator2.cxx
@@ -33,8 +33,6 @@
#include <memory> // auto_ptr
#include <queue>
-#include <assert.h>
-
// TODO: Convert makefile name to a runtime switch.
#define CMLUMG_MAKEFILE_NAME "Makefile"
@@ -1998,6 +1996,7 @@ cmLocalUnixMakefileGenerator2
for(std::vector<std::string>::const_iterator i = objects.begin();
i != objects.end(); ++i)
{
+ // TODO: Make sure we don't escape spaces and quote.
ruleFileStream
<< " \\\n"
<< "\"" << this->ConvertToRelativeOutputPath(i->c_str()) << "\"";
@@ -2310,94 +2309,6 @@ cmLocalUnixMakefileGenerator2
//----------------------------------------------------------------------------
std::string
-cmLocalUnixMakefileGenerator2::ConvertToRelativePath(const char* p)
-{
- // The path should never be quoted.
- assert(p[0] != '\"');
-
- // If the path is already relative or relative paths are disabled
- // then just return the path.
- if(m_RelativePathTop.size() == 0 || !cmSystemTools::FileIsFullPath(p))
- {
- return p;
- }
-
- // If the path does not begin with the minimum relative path prefix
- // then do not convert it.
- std::string original = p;
- if(original.size() < m_RelativePathTop.size() ||
- !this->ComparePath(original.substr(0, m_RelativePathTop.size()).c_str(),
- m_RelativePathTop.c_str()))
- {
- return p;
- }
-
- // Identify the longest shared path component between the given path
- // and the current output directory.
- std::vector<std::string> path;
- cmSystemTools::SplitPath(p, path);
- unsigned int common=0;
- while(common < path.size() &&
- common < m_CurrentOutputDirectoryComponents.size() &&
- this->ComparePath(path[common].c_str(),
- m_CurrentOutputDirectoryComponents[common].c_str()))
- {
- ++common;
- }
-
- // If the entire path is in common then just return a ".".
- if(common == path.size() &&
- common == m_CurrentOutputDirectoryComponents.size())
- {
- return ".";
- }
-
- // If the entire path is in common except for a trailing slash then
- // just return a "./".
- if(common+1 == path.size() && path[common].size() == 0 &&
- common == m_CurrentOutputDirectoryComponents.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 m_CurrentOutputDirectoryComponents will never be
- // empty because m_CurrentOutputDirectory does not have a trailing
- // slash.
- for(unsigned int i=common; i < m_CurrentOutputDirectoryComponents.size(); ++i)
- {
- relative += "..";
- if(i < m_CurrentOutputDirectoryComponents.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 < path.size(); ++i)
- {
- if(relative.size() > 0)
- {
- relative += "/";
- }
- relative += path[i];
- }
-
- // Finally return the path.
- return relative;
-}
-
-//----------------------------------------------------------------------------
-std::string
cmLocalUnixMakefileGenerator2::ConvertToRelativeOutputPath(const char* p)
{
// Convert the path to a relative path.
@@ -2424,52 +2335,6 @@ void cmLocalUnixMakefileGenerator2::ConfigureOutputPaths()
m_ExecutableOutputPath = exeOut;
this->FormatOutputPath(m_ExecutableOutputPath, "EXECUTABLE");
}
-
- // Setup fully collapsed paths.
- m_CurrentOutputDirectory =
- cmSystemTools::CollapseFullPath(m_Makefile->GetCurrentOutputDirectory());
- m_HomeOutputDirectory =
- cmSystemTools::CollapseFullPath(m_Makefile->GetHomeOutputDirectory());
- m_HomeDirectory =
- cmSystemTools::CollapseFullPath(m_Makefile->GetHomeDirectory());
-
- // Identify the longest shared path component between the source
- // directory and the build directory.
- std::vector<std::string> source;
- std::vector<std::string> binary;
- cmSystemTools::SplitPath(m_HomeDirectory.c_str(), source);
- cmSystemTools::SplitPath(m_HomeOutputDirectory.c_str(), binary);
- unsigned int common=0;
- while(common < source.size() && common < binary.size() &&
- this->ComparePath(source[common].c_str(), binary[common].c_str()))
- {
- ++common;
- }
-
- // Require more than just the root portion of the path to be in
- // common before allowing relative paths. Also disallow relative
- // paths if the build tree is a network path. The current working
- // directory on Windows cannot be a network path. Therefore
- // relative paths cannot work with network paths.
- if(common > 1 && source[0] != "//")
- {
- // Build the minimum prefix required of a path to be converted to
- // a relative path.
- m_RelativePathTop = source[0];
- for(unsigned int i=1; i < common; ++i)
- {
- if(i > 1)
- {
- m_RelativePathTop += "/";
- }
- m_RelativePathTop += source[i];
- }
-
- // Split the current output directory now to save time when
- // converting paths.
- cmSystemTools::SplitPath(m_CurrentOutputDirectory.c_str(),
- m_CurrentOutputDirectoryComponents);
- }
}
//----------------------------------------------------------------------------
@@ -2504,16 +2369,6 @@ void cmLocalUnixMakefileGenerator2::FormatOutputPath(std::string& path,
}
//----------------------------------------------------------------------------
-bool cmLocalUnixMakefileGenerator2::ComparePath(const char* c1, const char* c2)
-{
-#if defined(_WIN32) || defined(__APPLE__)
- return cmSystemTools::Strucmp(c1, c2) == 0;
-#else
- return strcmp(c1, c2) == 0;
-#endif
-}
-
-//----------------------------------------------------------------------------
void
cmLocalUnixMakefileGenerator2
::AppendTargetDepends(std::vector<std::string>& depends,
diff --git a/Source/cmLocalUnixMakefileGenerator2.h b/Source/cmLocalUnixMakefileGenerator2.h
index efa03cd..90997f1 100644
--- a/Source/cmLocalUnixMakefileGenerator2.h
+++ b/Source/cmLocalUnixMakefileGenerator2.h
@@ -198,11 +198,9 @@ protected:
const cmSourceFile& source);
const char* GetSourceFileLanguage(const cmSourceFile& source);
std::string ConvertToFullPath(const std::string& localPath);
- std::string ConvertToRelativePath(const char* p);
std::string ConvertToRelativeOutputPath(const char* p);
void ConfigureOutputPaths();
void FormatOutputPath(std::string& path, const char* name);
- bool ComparePath(const char* c1, const char* c2);
void AppendTargetDepends(std::vector<std::string>& depends,
const cmTarget& target);
@@ -277,13 +275,6 @@ private:
// Set of object file names that will be built in this directory.
std::set<cmStdString> m_ObjectFiles;
-
- // The prefix required of a path to be converted to a relative path.
- // No sequence of ../.. will ever go past this path.
- std::string m_RelativePathTop;
-
- // The pre-split current output directory.
- std::vector<std::string> m_CurrentOutputDirectoryComponents;
};
#endif