|
|
@@ -46,7 +46,7 @@
|
|
|
cmLocalGenerator::cmLocalGenerator(cmGlobalGenerator* gg,
|
|
|
cmLocalGenerator* parent,
|
|
|
cmState::Snapshot snapshot)
|
|
|
- : StateSnapshot(snapshot)
|
|
|
+ : cmOutputConverter(snapshot), StateSnapshot(snapshot)
|
|
|
{
|
|
|
assert(snapshot.IsValid());
|
|
|
this->GlobalGenerator = gg;
|
|
|
@@ -58,7 +58,6 @@ cmLocalGenerator::cmLocalGenerator(cmGlobalGenerator* gg,
|
|
|
|
|
|
this->Makefile = new cmMakefile(this);
|
|
|
|
|
|
- this->LinkScriptShell = false;
|
|
|
this->EmitUniversalBinaryFlags = true;
|
|
|
this->BackwardsCompatibility = 0;
|
|
|
this->BackwardsCompatibilityFinal = false;
|
|
|
@@ -1095,58 +1094,6 @@ void cmLocalGenerator::InsertRuleLauncher(std::string& s, cmTarget* target,
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-//----------------------------------------------------------------------------
|
|
|
-std::string
|
|
|
-cmLocalGenerator::ConvertToOutputForExistingCommon(const std::string& remote,
|
|
|
- std::string const& result,
|
|
|
- OutputFormat format)
|
|
|
-{
|
|
|
- // If this is a windows shell, the result has a space, and the path
|
|
|
- // already exists, we can use a short-path to reference it without a
|
|
|
- // space.
|
|
|
- if(this->GetState()->UseWindowsShell() && result.find(' ') != result.npos &&
|
|
|
- cmSystemTools::FileExists(remote.c_str()))
|
|
|
- {
|
|
|
- std::string tmp;
|
|
|
- if(cmSystemTools::GetShortPath(remote, tmp))
|
|
|
- {
|
|
|
- return this->ConvertToOutputFormat(tmp, format);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- // Otherwise, leave it unchanged.
|
|
|
- return result;
|
|
|
-}
|
|
|
-
|
|
|
-//----------------------------------------------------------------------------
|
|
|
-std::string
|
|
|
-cmLocalGenerator::ConvertToOutputForExisting(const std::string& remote,
|
|
|
- RelativeRoot local,
|
|
|
- OutputFormat format)
|
|
|
-{
|
|
|
- static_cast<void>(local);
|
|
|
-
|
|
|
- // Perform standard conversion.
|
|
|
- std::string result = this->ConvertToOutputFormat(remote, format);
|
|
|
-
|
|
|
- // Consider short-path.
|
|
|
- return this->ConvertToOutputForExistingCommon(remote, result, format);
|
|
|
-}
|
|
|
-
|
|
|
-//----------------------------------------------------------------------------
|
|
|
-std::string
|
|
|
-cmLocalGenerator::ConvertToOutputForExisting(RelativeRoot remote,
|
|
|
- const std::string& local,
|
|
|
- OutputFormat format)
|
|
|
-{
|
|
|
- // Perform standard conversion.
|
|
|
- std::string result = this->Convert(remote, local, format, true);
|
|
|
-
|
|
|
- // Consider short-path.
|
|
|
- const char* remotePath = this->GetRelativeRootPath(remote);
|
|
|
- return this->ConvertToOutputForExistingCommon(remotePath, result, format);
|
|
|
-}
|
|
|
-
|
|
|
//----------------------------------------------------------------------------
|
|
|
std::string
|
|
|
cmLocalGenerator::ConvertToIncludeReference(std::string const& path,
|
|
|
@@ -2603,230 +2550,6 @@ cmLocalGenerator::ConstructComment(cmCustomCommandGenerator const& ccg,
|
|
|
return default_comment;
|
|
|
}
|
|
|
|
|
|
-//----------------------------------------------------------------------------
|
|
|
-const char* cmLocalGenerator::GetRelativeRootPath(RelativeRoot relroot)
|
|
|
-{
|
|
|
- switch (relroot)
|
|
|
- {
|
|
|
- case HOME: return this->GetState()->GetSourceDirectory();
|
|
|
- case START: return this->StateSnapshot.GetCurrentSourceDirectory();
|
|
|
- case HOME_OUTPUT: return this->GetState()->GetBinaryDirectory();
|
|
|
- case START_OUTPUT: return this->StateSnapshot.GetCurrentBinaryDirectory();
|
|
|
- default: break;
|
|
|
- }
|
|
|
- return 0;
|
|
|
-}
|
|
|
-
|
|
|
-//----------------------------------------------------------------------------
|
|
|
-std::string cmLocalGenerator::Convert(const std::string& source,
|
|
|
- RelativeRoot relative,
|
|
|
- OutputFormat output)
|
|
|
-{
|
|
|
- // Convert the path to a relative path.
|
|
|
- std::string result = source;
|
|
|
-
|
|
|
- switch (relative)
|
|
|
- {
|
|
|
- case HOME:
|
|
|
- //result = cmSystemTools::CollapseFullPath(result.c_str());
|
|
|
- result = this->ConvertToRelativePath(
|
|
|
- this->GetState()->GetSourceDirectoryComponents(), result);
|
|
|
- break;
|
|
|
- case START:
|
|
|
- //result = cmSystemTools::CollapseFullPath(result.c_str());
|
|
|
- result = this->ConvertToRelativePath(
|
|
|
- this->StateSnapshot.GetCurrentSourceDirectoryComponents(), result);
|
|
|
- break;
|
|
|
- case HOME_OUTPUT:
|
|
|
- //result = cmSystemTools::CollapseFullPath(result.c_str());
|
|
|
- result = this->ConvertToRelativePath(
|
|
|
- this->GetState()->GetBinaryDirectoryComponents(), result);
|
|
|
- break;
|
|
|
- case START_OUTPUT:
|
|
|
- //result = cmSystemTools::CollapseFullPath(result.c_str());
|
|
|
- result = this->ConvertToRelativePath(
|
|
|
- this->StateSnapshot.GetCurrentBinaryDirectoryComponents(), result);
|
|
|
- break;
|
|
|
- case FULL:
|
|
|
- result = cmSystemTools::CollapseFullPath(result);
|
|
|
- break;
|
|
|
- case NONE:
|
|
|
- break;
|
|
|
-
|
|
|
- }
|
|
|
- return this->ConvertToOutputFormat(result, output);
|
|
|
-}
|
|
|
-
|
|
|
-//----------------------------------------------------------------------------
|
|
|
-std::string cmLocalGenerator::ConvertToOutputFormat(const std::string& source,
|
|
|
- OutputFormat output)
|
|
|
-{
|
|
|
- std::string result = source;
|
|
|
- // Convert it to an output path.
|
|
|
- if (output == MAKERULE)
|
|
|
- {
|
|
|
- result = cmSystemTools::ConvertToOutputPath(result.c_str());
|
|
|
- }
|
|
|
- else if(output == SHELL || output == WATCOMQUOTE)
|
|
|
- {
|
|
|
- // For the MSYS shell convert drive letters to posix paths, so
|
|
|
- // that c:/some/path becomes /c/some/path. This is needed to
|
|
|
- // avoid problems with the shell path translation.
|
|
|
- if(this->GetState()->UseMSYSShell() && !this->LinkScriptShell)
|
|
|
- {
|
|
|
- if(result.size() > 2 && result[1] == ':')
|
|
|
- {
|
|
|
- result[1] = result[0];
|
|
|
- result[0] = '/';
|
|
|
- }
|
|
|
- }
|
|
|
- if(this->GetState()->UseWindowsShell())
|
|
|
- {
|
|
|
- std::replace(result.begin(), result.end(), '/', '\\');
|
|
|
- }
|
|
|
- result = this->EscapeForShell(result, true, false, output == WATCOMQUOTE);
|
|
|
- }
|
|
|
- else if(output == RESPONSE)
|
|
|
- {
|
|
|
- result = this->EscapeForShell(result, false, false, false);
|
|
|
- }
|
|
|
- return result;
|
|
|
-}
|
|
|
-
|
|
|
-//----------------------------------------------------------------------------
|
|
|
-std::string cmLocalGenerator::Convert(RelativeRoot remote,
|
|
|
- const std::string& local,
|
|
|
- OutputFormat output, bool optional)
|
|
|
-{
|
|
|
- const char* remotePath = this->GetRelativeRootPath(remote);
|
|
|
-
|
|
|
- // The relative root must have a path (i.e. not FULL or NONE)
|
|
|
- assert(remotePath != 0);
|
|
|
-
|
|
|
- if(!local.empty() && !optional)
|
|
|
- {
|
|
|
- std::vector<std::string> components;
|
|
|
- cmSystemTools::SplitPath(local, components);
|
|
|
- std::string result = this->ConvertToRelativePath(components, remotePath);
|
|
|
- return this->ConvertToOutputFormat(result, output);
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- return this->ConvertToOutputFormat(remotePath, output);
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-//----------------------------------------------------------------------------
|
|
|
-static bool cmLocalGeneratorNotAbove(const char* a, const char* b)
|
|
|
-{
|
|
|
- return (cmSystemTools::ComparePath(a, b) ||
|
|
|
- cmSystemTools::IsSubDirectory(a, b));
|
|
|
-}
|
|
|
-
|
|
|
-//----------------------------------------------------------------------------
|
|
|
-std::string
|
|
|
-cmLocalGenerator::ConvertToRelativePath(const std::vector<std::string>& local,
|
|
|
- const std::string& in_remote,
|
|
|
- bool force)
|
|
|
-{
|
|
|
- // The path should never be quoted.
|
|
|
- assert(in_remote[0] != '\"');
|
|
|
-
|
|
|
- // The local path should never have a trailing slash.
|
|
|
- assert(!local.empty() && !(local[local.size()-1] == ""));
|
|
|
-
|
|
|
- // If the path is already relative then just return the path.
|
|
|
- if(!cmSystemTools::FileIsFullPath(in_remote.c_str()))
|
|
|
- {
|
|
|
- return in_remote;
|
|
|
- }
|
|
|
-
|
|
|
- if(!force)
|
|
|
- {
|
|
|
- // 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);
|
|
|
- if(!((cmLocalGeneratorNotAbove(local_path.c_str(),
|
|
|
- this->StateSnapshot.GetRelativePathTopBinary()) &&
|
|
|
- cmLocalGeneratorNotAbove(in_remote.c_str(),
|
|
|
- this->StateSnapshot.GetRelativePathTopBinary())) ||
|
|
|
- (cmLocalGeneratorNotAbove(local_path.c_str(),
|
|
|
- this->StateSnapshot.GetRelativePathTopSource()) &&
|
|
|
- cmLocalGeneratorNotAbove(in_remote.c_str(),
|
|
|
- this->StateSnapshot.GetRelativePathTopSource()))))
|
|
|
- {
|
|
|
- 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],
|
|
|
- local[common]))
|
|
|
- {
|
|
|
- ++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].empty() &&
|
|
|
- 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.
|
|
|
-
|
|
|
- if(!relative.empty() && !remote.empty())
|
|
|
- {
|
|
|
- relative += "/";
|
|
|
- }
|
|
|
- relative += cmJoin(cmRange(remote).advance(common), "/");
|
|
|
-
|
|
|
- // Finally return the path.
|
|
|
- return relative;
|
|
|
-}
|
|
|
-
|
|
|
//----------------------------------------------------------------------------
|
|
|
class cmInstallTargetGeneratorLocal: public cmInstallTargetGenerator
|
|
|
{
|
|
|
@@ -3219,150 +2942,6 @@ cmLocalGenerator
|
|
|
return source.GetLanguage();
|
|
|
}
|
|
|
|
|
|
-//----------------------------------------------------------------------------
|
|
|
-static bool cmLocalGeneratorIsShellOperator(const std::string& str)
|
|
|
-{
|
|
|
- static std::set<std::string> shellOperators;
|
|
|
- if(shellOperators.empty())
|
|
|
- {
|
|
|
- shellOperators.insert("<");
|
|
|
- shellOperators.insert(">");
|
|
|
- shellOperators.insert("<<");
|
|
|
- shellOperators.insert(">>");
|
|
|
- shellOperators.insert("|");
|
|
|
- shellOperators.insert("||");
|
|
|
- shellOperators.insert("&&");
|
|
|
- shellOperators.insert("&>");
|
|
|
- shellOperators.insert("1>");
|
|
|
- shellOperators.insert("2>");
|
|
|
- shellOperators.insert("2>&1");
|
|
|
- shellOperators.insert("1>&2");
|
|
|
- }
|
|
|
- return shellOperators.count(str) > 0;
|
|
|
-}
|
|
|
-
|
|
|
-//----------------------------------------------------------------------------
|
|
|
-std::string cmLocalGenerator::EscapeForShell(const std::string& str,
|
|
|
- bool makeVars,
|
|
|
- bool forEcho,
|
|
|
- bool useWatcomQuote)
|
|
|
-{
|
|
|
- // Do not escape shell operators.
|
|
|
- if(cmLocalGeneratorIsShellOperator(str))
|
|
|
- {
|
|
|
- return str;
|
|
|
- }
|
|
|
-
|
|
|
- // Compute the flags for the target shell environment.
|
|
|
- int flags = 0;
|
|
|
- if(this->GetState()->UseWindowsVSIDE())
|
|
|
- {
|
|
|
- flags |= cmsysSystem_Shell_Flag_VSIDE;
|
|
|
- }
|
|
|
- else if(!this->LinkScriptShell)
|
|
|
- {
|
|
|
- flags |= cmsysSystem_Shell_Flag_Make;
|
|
|
- }
|
|
|
- if(makeVars)
|
|
|
- {
|
|
|
- flags |= cmsysSystem_Shell_Flag_AllowMakeVariables;
|
|
|
- }
|
|
|
- if(forEcho)
|
|
|
- {
|
|
|
- flags |= cmsysSystem_Shell_Flag_EchoWindows;
|
|
|
- }
|
|
|
- if(useWatcomQuote)
|
|
|
- {
|
|
|
- flags |= cmsysSystem_Shell_Flag_WatcomQuote;
|
|
|
- }
|
|
|
- if(this->GetState()->UseWatcomWMake())
|
|
|
- {
|
|
|
- flags |= cmsysSystem_Shell_Flag_WatcomWMake;
|
|
|
- }
|
|
|
- if(this->GetState()->UseMinGWMake())
|
|
|
- {
|
|
|
- flags |= cmsysSystem_Shell_Flag_MinGWMake;
|
|
|
- }
|
|
|
- if(this->GetState()->UseNMake())
|
|
|
- {
|
|
|
- flags |= cmsysSystem_Shell_Flag_NMake;
|
|
|
- }
|
|
|
-
|
|
|
- // Compute the buffer size needed.
|
|
|
- int size = (this->GetState()->UseWindowsShell() ?
|
|
|
- cmsysSystem_Shell_GetArgumentSizeForWindows(str.c_str(), flags) :
|
|
|
- cmsysSystem_Shell_GetArgumentSizeForUnix(str.c_str(), flags));
|
|
|
-
|
|
|
- // Compute the shell argument itself.
|
|
|
- std::vector<char> arg(size);
|
|
|
- if(this->GetState()->UseWindowsShell())
|
|
|
- {
|
|
|
- cmsysSystem_Shell_GetArgumentForWindows(str.c_str(), &arg[0], flags);
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- cmsysSystem_Shell_GetArgumentForUnix(str.c_str(), &arg[0], flags);
|
|
|
- }
|
|
|
- return std::string(&arg[0]);
|
|
|
-}
|
|
|
-
|
|
|
-//----------------------------------------------------------------------------
|
|
|
-std::string cmLocalGenerator::EscapeForCMake(const std::string& str)
|
|
|
-{
|
|
|
- // Always double-quote the argument to take care of most escapes.
|
|
|
- std::string result = "\"";
|
|
|
- for(const char* c = str.c_str(); *c; ++c)
|
|
|
- {
|
|
|
- if(*c == '"')
|
|
|
- {
|
|
|
- // Escape the double quote to avoid ending the argument.
|
|
|
- result += "\\\"";
|
|
|
- }
|
|
|
- else if(*c == '$')
|
|
|
- {
|
|
|
- // Escape the dollar to avoid expanding variables.
|
|
|
- result += "\\$";
|
|
|
- }
|
|
|
- else if(*c == '\\')
|
|
|
- {
|
|
|
- // Escape the backslash to avoid other escapes.
|
|
|
- result += "\\\\";
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- // Other characters will be parsed correctly.
|
|
|
- result += *c;
|
|
|
- }
|
|
|
- }
|
|
|
- result += "\"";
|
|
|
- return result;
|
|
|
-}
|
|
|
-
|
|
|
-//----------------------------------------------------------------------------
|
|
|
-cmLocalGenerator::FortranFormat
|
|
|
-cmLocalGenerator::GetFortranFormat(const char* value)
|
|
|
-{
|
|
|
- FortranFormat format = FortranFormatNone;
|
|
|
- if(value && *value)
|
|
|
- {
|
|
|
- std::vector<std::string> fmt;
|
|
|
- cmSystemTools::ExpandListArgument(value, fmt);
|
|
|
- for(std::vector<std::string>::iterator fi = fmt.begin();
|
|
|
- fi != fmt.end(); ++fi)
|
|
|
- {
|
|
|
- if(*fi == "FIXED")
|
|
|
- {
|
|
|
- format = FortranFormatFixed;
|
|
|
- }
|
|
|
- if(*fi == "FREE")
|
|
|
- {
|
|
|
- format = FortranFormatFree;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- return format;
|
|
|
-}
|
|
|
-
|
|
|
//----------------------------------------------------------------------------
|
|
|
std::string
|
|
|
cmLocalGenerator::GetTargetDirectory(cmTarget const&) const
|