You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
511 lines
20 KiB
511 lines
20 KiB
date: 2008-10-09 22:30:07 +0300; author: king; state: Exp; lines: +29 -30; commitid: jdAfWT6Sw8VXhZlt;
|
|
ENH: Fix optional use of relative paths.
|
|
|
|
These changes refactor cmLocalGenerator methods Convert and
|
|
ConvertToOutputForExisting to support references inside the build tree
|
|
using relative paths. After this commit, all tests pass with Makefile
|
|
generators when relative paths are enabled by default. See issue #7779.
|
|
|
|
The patch can be retrieved from upstream CVS with:
|
|
$ cvs diff -u -D "2008-10-09 22:30 +0300" -D "2008-10-09 22:31 +0300"
|
|
|
|
"File version" hunks were removed for the patch to apply. Also one hunk
|
|
was unfuzzed.
|
|
--- a/Source/cmLocalGenerator.cxx
|
|
+++ b/Source/cmLocalGenerator.cxx
|
|
@@ -1074,22 +1074,54 @@
|
|
s = expandedInput;
|
|
}
|
|
|
|
-
|
|
-std::string
|
|
-cmLocalGenerator::ConvertToOutputForExisting(const char* p)
|
|
+//----------------------------------------------------------------------------
|
|
+std::string
|
|
+cmLocalGenerator::ConvertToOutputForExistingCommon(const char* remote,
|
|
+ std::string const& result)
|
|
{
|
|
- std::string ret = p;
|
|
- if(this->WindowsShell && ret.find(' ') != ret.npos
|
|
- && cmSystemTools::FileExists(p))
|
|
+ // 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->WindowsShell && result.find(' ') != result.npos &&
|
|
+ cmSystemTools::FileExists(remote))
|
|
{
|
|
- if(cmSystemTools::GetShortPath(p, ret))
|
|
+ std::string tmp;
|
|
+ if(cmSystemTools::GetShortPath(remote, tmp))
|
|
{
|
|
- return this->Convert(ret.c_str(), NONE, SHELL, true);
|
|
+ return this->Convert(tmp.c_str(), NONE, SHELL, true);
|
|
}
|
|
}
|
|
- return this->Convert(p, START_OUTPUT, SHELL, true);
|
|
+
|
|
+ // Otherwise, leave it unchanged.
|
|
+ return result;
|
|
+}
|
|
+
|
|
+//----------------------------------------------------------------------------
|
|
+std::string
|
|
+cmLocalGenerator::ConvertToOutputForExisting(const char* remote,
|
|
+ RelativeRoot local)
|
|
+{
|
|
+ // Perform standard conversion.
|
|
+ std::string result = this->Convert(remote, local, SHELL, true);
|
|
+
|
|
+ // Consider short-path.
|
|
+ return this->ConvertToOutputForExistingCommon(remote, result);
|
|
+}
|
|
+
|
|
+//----------------------------------------------------------------------------
|
|
+std::string
|
|
+cmLocalGenerator::ConvertToOutputForExisting(RelativeRoot remote,
|
|
+ const char* local)
|
|
+{
|
|
+ // Perform standard conversion.
|
|
+ std::string result = this->Convert(remote, local, SHELL, true);
|
|
+
|
|
+ // Consider short-path.
|
|
+ const char* remotePath = this->GetRelativeRootPath(remote);
|
|
+ return this->ConvertToOutputForExistingCommon(remotePath, result);
|
|
}
|
|
|
|
+//----------------------------------------------------------------------------
|
|
const char* cmLocalGenerator::GetIncludeFlags(const char* lang)
|
|
{
|
|
if(!lang)
|
|
@@ -1983,7 +2015,21 @@
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
-std::string cmLocalGenerator::Convert(const char* source,
|
|
+const char* cmLocalGenerator::GetRelativeRootPath(RelativeRoot relroot)
|
|
+{
|
|
+ switch (relroot)
|
|
+ {
|
|
+ case HOME: return this->Makefile->GetHomeDirectory();
|
|
+ case START: return this->Makefile->GetStartDirectory();
|
|
+ case HOME_OUTPUT: return this->Makefile->GetHomeOutputDirectory();
|
|
+ case START_OUTPUT: return this->Makefile->GetStartOutputDirectory();
|
|
+ default: break;
|
|
+ }
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+//----------------------------------------------------------------------------
|
|
+std::string cmLocalGenerator::Convert(const char* source,
|
|
RelativeRoot relative,
|
|
OutputFormat output,
|
|
bool optional)
|
|
@@ -2031,7 +2077,15 @@
|
|
break;
|
|
}
|
|
}
|
|
- // Now convert it to an output path.
|
|
+ return this->ConvertToOutputFormat(result.c_str(), output);
|
|
+}
|
|
+
|
|
+//----------------------------------------------------------------------------
|
|
+std::string cmLocalGenerator::ConvertToOutputFormat(const char* source,
|
|
+ OutputFormat output)
|
|
+{
|
|
+ std::string result = source;
|
|
+ // Convert it to an output path.
|
|
if (output == MAKEFILE)
|
|
{
|
|
result = cmSystemTools::ConvertToOutputPath(result.c_str());
|
|
@@ -2064,6 +2118,40 @@
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
+std::string cmLocalGenerator::Convert(RelativeRoot remote,
|
|
+ const char* local,
|
|
+ OutputFormat output,
|
|
+ bool optional)
|
|
+{
|
|
+ const char* remotePath = this->GetRelativeRootPath(remote);
|
|
+ if(local && (!optional || this->UseRelativePaths))
|
|
+ {
|
|
+ std::vector<std::string> components;
|
|
+ std::string result;
|
|
+ switch(remote)
|
|
+ {
|
|
+ case HOME:
|
|
+ case HOME_OUTPUT:
|
|
+ case START:
|
|
+ case START_OUTPUT:
|
|
+ cmSystemTools::SplitPath(local, components);
|
|
+ result = this->ConvertToRelativePath(components, remotePath);
|
|
+ break;
|
|
+ case FULL:
|
|
+ result = remotePath;
|
|
+ break;
|
|
+ case NONE:
|
|
+ break;
|
|
+ }
|
|
+ return this->ConvertToOutputFormat(result.c_str(), output);
|
|
+ }
|
|
+ else
|
|
+ {
|
|
+ return this->ConvertToOutputFormat(remotePath, output);
|
|
+ }
|
|
+}
|
|
+
|
|
+//----------------------------------------------------------------------------
|
|
std::string cmLocalGenerator::FindRelativePathTopSource()
|
|
{
|
|
// Relative path conversion within a single tree managed by CMake is
|
|
--- a/Source/cmLocalGenerator.h
|
|
+++ b/Source/cmLocalGenerator.h
|
|
@@ -108,10 +108,18 @@
|
|
*/
|
|
enum RelativeRoot { NONE, FULL, HOME, START, HOME_OUTPUT, START_OUTPUT };
|
|
enum OutputFormat { UNCHANGED, MAKEFILE, SHELL };
|
|
- std::string Convert(const char* source,
|
|
- RelativeRoot relative,
|
|
+ std::string ConvertToOutputFormat(const char* source, OutputFormat output);
|
|
+ std::string Convert(const char* remote, RelativeRoot local,
|
|
OutputFormat output = UNCHANGED,
|
|
bool optional = false);
|
|
+ std::string Convert(RelativeRoot remote, const char* local,
|
|
+ OutputFormat output = UNCHANGED,
|
|
+ bool optional = false);
|
|
+
|
|
+ /**
|
|
+ * Get path for the specified relative root.
|
|
+ */
|
|
+ const char* GetRelativeRootPath(RelativeRoot relroot);
|
|
|
|
/**
|
|
* Convert the given path to an output path that is optionally
|
|
@@ -162,7 +170,13 @@
|
|
std::string GetRealLocation(const char* inName, const char* config);
|
|
|
|
///! for existing files convert to output path and short path if spaces
|
|
- std::string ConvertToOutputForExisting(const char* p);
|
|
+ std::string ConvertToOutputForExisting(const char* remote,
|
|
+ RelativeRoot local = START_OUTPUT);
|
|
+
|
|
+ /** For existing path identified by RelativeRoot convert to output
|
|
+ path and short path if spaces. */
|
|
+ std::string ConvertToOutputForExisting(RelativeRoot remote,
|
|
+ const char* local = 0);
|
|
|
|
/** Called from command-line hook to clear dependencies. */
|
|
virtual void ClearDependencies(cmMakefile* /* mf */,
|
|
@@ -386,6 +400,9 @@
|
|
|
|
unsigned int BackwardsCompatibility;
|
|
bool BackwardsCompatibilityFinal;
|
|
+private:
|
|
+ std::string ConvertToOutputForExistingCommon(const char* remote,
|
|
+ std::string const& result);
|
|
};
|
|
|
|
#endif
|
|
--- a/Source/cmLocalUnixMakefileGenerator3.cxx
|
|
+++ b/Source/cmLocalUnixMakefileGenerator3.cxx
|
|
@@ -360,7 +360,7 @@
|
|
);
|
|
this->CreateCDCommand(commands,
|
|
this->Makefile->GetHomeOutputDirectory(),
|
|
- this->Makefile->GetStartOutputDirectory());
|
|
+ cmLocalGenerator::START_OUTPUT);
|
|
}
|
|
|
|
// Write the rule to the makefile.
|
|
@@ -404,7 +404,7 @@
|
|
(makefile2.c_str(),localName.c_str()));
|
|
this->CreateCDCommand(commands,
|
|
this->Makefile->GetHomeOutputDirectory(),
|
|
- this->Makefile->GetStartOutputDirectory());
|
|
+ cmLocalGenerator::START_OUTPUT);
|
|
this->WriteMakeRule(ruleFileStream, "Convenience name for target.",
|
|
localName.c_str(), depends, commands, true);
|
|
|
|
@@ -432,7 +432,7 @@
|
|
(makefileName.c_str(), makeTargetName.c_str()));
|
|
this->CreateCDCommand(commands,
|
|
this->Makefile->GetHomeOutputDirectory(),
|
|
- this->Makefile->GetStartOutputDirectory());
|
|
+ cmLocalGenerator::START_OUTPUT);
|
|
this->WriteMakeRule(ruleFileStream, "fast build rule for target.",
|
|
localName.c_str(), depends, commands, true);
|
|
|
|
@@ -450,7 +450,7 @@
|
|
(makefile2.c_str(), makeTargetName.c_str()));
|
|
this->CreateCDCommand(commands,
|
|
this->Makefile->GetHomeOutputDirectory(),
|
|
- this->Makefile->GetStartOutputDirectory());
|
|
+ cmLocalGenerator::START_OUTPUT);
|
|
this->WriteMakeRule(ruleFileStream,
|
|
"Manual pre-install relink rule for target.",
|
|
localName.c_str(), depends, commands, true);
|
|
@@ -835,7 +835,7 @@
|
|
{
|
|
this->CreateCDCommand(commands,
|
|
this->Makefile->GetHomeOutputDirectory(),
|
|
- this->Makefile->GetStartOutputDirectory());
|
|
+ cmLocalGenerator::START_OUTPUT);
|
|
}
|
|
this->WriteMakeRule(makefileStream,
|
|
"Special rule to run CMake to check the build system "
|
|
@@ -953,12 +953,13 @@
|
|
void
|
|
cmLocalUnixMakefileGenerator3
|
|
::AppendCustomCommands(std::vector<std::string>& commands,
|
|
- const std::vector<cmCustomCommand>& ccs)
|
|
+ const std::vector<cmCustomCommand>& ccs,
|
|
+ cmLocalGenerator::RelativeRoot relative)
|
|
{
|
|
for(std::vector<cmCustomCommand>::const_iterator i = ccs.begin();
|
|
i != ccs.end(); ++i)
|
|
{
|
|
- this->AppendCustomCommand(commands, *i, true);
|
|
+ this->AppendCustomCommand(commands, *i, true, relative);
|
|
}
|
|
}
|
|
|
|
@@ -966,7 +967,8 @@
|
|
void
|
|
cmLocalUnixMakefileGenerator3
|
|
::AppendCustomCommand(std::vector<std::string>& commands,
|
|
- const cmCustomCommand& cc, bool echo_comment)
|
|
+ const cmCustomCommand& cc, bool echo_comment,
|
|
+ cmLocalGenerator::RelativeRoot relative)
|
|
{
|
|
// Optionally create a command to display the custom command's
|
|
// comment text. This is used for pre-build, pre-link, and
|
|
@@ -1072,8 +1074,7 @@
|
|
}
|
|
|
|
// Setup the proper working directory for the commands.
|
|
- this->CreateCDCommand(commands1, dir,
|
|
- this->Makefile->GetHomeOutputDirectory());
|
|
+ this->CreateCDCommand(commands1, dir, relative);
|
|
|
|
// push back the custom commands
|
|
commands.insert(commands.end(), commands1.begin(), commands1.end());
|
|
@@ -1610,9 +1611,11 @@
|
|
this->AppendCustomDepends(depends,
|
|
glIt->second.GetPostBuildCommands());
|
|
this->AppendCustomCommands(commands,
|
|
- glIt->second.GetPreBuildCommands());
|
|
+ glIt->second.GetPreBuildCommands(),
|
|
+ cmLocalGenerator::START_OUTPUT);
|
|
this->AppendCustomCommands(commands,
|
|
- glIt->second.GetPostBuildCommands());
|
|
+ glIt->second.GetPostBuildCommands(),
|
|
+ cmLocalGenerator::START_OUTPUT);
|
|
std::string targetName = glIt->second.GetName();
|
|
this->WriteMakeRule(ruleFileStream, targetString.c_str(),
|
|
targetName.c_str(), depends, commands, true);
|
|
@@ -1674,7 +1677,7 @@
|
|
recursiveTarget.c_str()));
|
|
this->CreateCDCommand(commands,
|
|
this->Makefile->GetHomeOutputDirectory(),
|
|
- this->Makefile->GetStartOutputDirectory());
|
|
+ cmLocalGenerator::START_OUTPUT);
|
|
{
|
|
cmOStringStream progCmd;
|
|
progCmd << "$(CMAKE_COMMAND) -E cmake_progress_start "; // # 0
|
|
@@ -1696,7 +1699,7 @@
|
|
recursiveTarget.c_str()));
|
|
this->CreateCDCommand(commands,
|
|
this->Makefile->GetHomeOutputDirectory(),
|
|
- this->Makefile->GetStartOutputDirectory());
|
|
+ cmLocalGenerator::START_OUTPUT);
|
|
this->WriteMakeRule(ruleFileStream, "The main clean target", "clean",
|
|
depends, commands, true);
|
|
commands.clear();
|
|
@@ -1726,7 +1729,7 @@
|
|
(this->GetRecursiveMakeCall(mf2Dir.c_str(), recursiveTarget.c_str()));
|
|
this->CreateCDCommand(commands,
|
|
this->Makefile->GetHomeOutputDirectory(),
|
|
- this->Makefile->GetStartOutputDirectory());
|
|
+ cmLocalGenerator::START_OUTPUT);
|
|
this->WriteMakeRule(ruleFileStream, "Prepare targets for installation.",
|
|
"preinstall", depends, commands, true);
|
|
depends.clear();
|
|
@@ -1747,7 +1750,7 @@
|
|
commands.push_back(runRule);
|
|
this->CreateCDCommand(commands,
|
|
this->Makefile->GetHomeOutputDirectory(),
|
|
- this->Makefile->GetStartOutputDirectory());
|
|
+ cmLocalGenerator::START_OUTPUT);
|
|
this->WriteMakeRule(ruleFileStream, "clear depends",
|
|
"depend",
|
|
depends, commands, true);
|
|
@@ -2126,8 +2129,10 @@
|
|
//----------------------------------------------------------------------------
|
|
void cmLocalUnixMakefileGenerator3
|
|
::CreateCDCommand(std::vector<std::string>& commands, const char *tgtDir,
|
|
- const char *retDir)
|
|
+ cmLocalGenerator::RelativeRoot relRetDir)
|
|
{
|
|
+ const char* retDir = this->GetRelativeRootPath(relRetDir);
|
|
+
|
|
// do we need to cd?
|
|
if (!strcmp(tgtDir,retDir))
|
|
{
|
|
@@ -2140,18 +2145,12 @@
|
|
// back because the shell keeps the working directory between
|
|
// commands.
|
|
std::string cmd = "cd ";
|
|
- cmd += this->ConvertToOutputForExisting(tgtDir);
|
|
+ cmd += this->ConvertToOutputForExisting(tgtDir, relRetDir);
|
|
commands.insert(commands.begin(),cmd);
|
|
-
|
|
- // Change back to the starting directory. Any trailing slash must be
|
|
- // removed to avoid problems with Borland Make.
|
|
- std::string back = retDir;
|
|
- if(back.size() && back[back.size()-1] == '/')
|
|
- {
|
|
- back = back.substr(0, back.size()-1);
|
|
- }
|
|
+
|
|
+ // Change back to the starting directory.
|
|
cmd = "cd ";
|
|
- cmd += this->ConvertToOutputForExisting(back.c_str());
|
|
+ cmd += this->ConvertToOutputForExisting(relRetDir, tgtDir);
|
|
commands.push_back(cmd);
|
|
}
|
|
else
|
|
@@ -2163,7 +2162,7 @@
|
|
for (; i != commands.end(); ++i)
|
|
{
|
|
std::string cmd = "cd ";
|
|
- cmd += this->ConvertToOutputForExisting(tgtDir);
|
|
+ cmd += this->ConvertToOutputForExisting(tgtDir, relRetDir);
|
|
cmd += " && ";
|
|
cmd += *i;
|
|
*i = cmd;
|
|
--- a/Source/cmLocalUnixMakefileGenerator3.h
|
|
+++ b/Source/cmLocalUnixMakefileGenerator3.h
|
|
@@ -197,7 +197,8 @@
|
|
|
|
// create a command that cds to the start dir then runs the commands
|
|
void CreateCDCommand(std::vector<std::string>& commands,
|
|
- const char *targetDir, const char *returnDir);
|
|
+ const char *targetDir,
|
|
+ cmLocalGenerator::RelativeRoot returnDir);
|
|
|
|
static std::string ConvertToQuotedOutputPath(const char* p);
|
|
|
|
@@ -321,10 +322,14 @@
|
|
void AppendCustomDepend(std::vector<std::string>& depends,
|
|
const cmCustomCommand& cc);
|
|
void AppendCustomCommands(std::vector<std::string>& commands,
|
|
- const std::vector<cmCustomCommand>& ccs);
|
|
+ const std::vector<cmCustomCommand>& ccs,
|
|
+ cmLocalGenerator::RelativeRoot relative =
|
|
+ cmLocalGenerator::HOME_OUTPUT);
|
|
void AppendCustomCommand(std::vector<std::string>& commands,
|
|
const cmCustomCommand& cc,
|
|
- bool echo_comment=false);
|
|
+ bool echo_comment=false,
|
|
+ cmLocalGenerator::RelativeRoot relative =
|
|
+ cmLocalGenerator::HOME_OUTPUT);
|
|
void AppendCleanCommand(std::vector<std::string>& commands,
|
|
const std::vector<std::string>& files,
|
|
cmTarget& target, const char* filename =0);
|
|
--- a/Source/cmMakefileExecutableTargetGenerator.cxx
|
|
+++ b/Source/cmMakefileExecutableTargetGenerator.cxx
|
|
@@ -435,7 +435,7 @@
|
|
this->LocalGenerator->CreateCDCommand
|
|
(commands1,
|
|
this->Makefile->GetStartOutputDirectory(),
|
|
- this->Makefile->GetHomeOutputDirectory());
|
|
+ cmLocalGenerator::HOME_OUTPUT);
|
|
commands.insert(commands.end(), commands1.begin(), commands1.end());
|
|
commands1.clear();
|
|
|
|
@@ -449,7 +449,7 @@
|
|
commands1.push_back(symlink);
|
|
this->LocalGenerator->CreateCDCommand(commands1,
|
|
this->Makefile->GetStartOutputDirectory(),
|
|
- this->Makefile->GetHomeOutputDirectory());
|
|
+ cmLocalGenerator::HOME_OUTPUT);
|
|
commands.insert(commands.end(), commands1.begin(), commands1.end());
|
|
commands1.clear();
|
|
}
|
|
--- a/Source/cmMakefileLibraryTargetGenerator.cxx
|
|
+++ b/Source/cmMakefileLibraryTargetGenerator.cxx
|
|
@@ -591,7 +591,7 @@
|
|
this->LocalGenerator->CreateCDCommand
|
|
(commands1,
|
|
this->Makefile->GetStartOutputDirectory(),
|
|
- this->Makefile->GetHomeOutputDirectory());
|
|
+ cmLocalGenerator::HOME_OUTPUT);
|
|
commands.insert(commands.end(), commands1.begin(), commands1.end());
|
|
commands1.clear();
|
|
}
|
|
@@ -872,7 +872,7 @@
|
|
this->LocalGenerator->CreateCDCommand
|
|
(commands1,
|
|
this->Makefile->GetStartOutputDirectory(),
|
|
- this->Makefile->GetHomeOutputDirectory());
|
|
+ cmLocalGenerator::HOME_OUTPUT);
|
|
commands.insert(commands.end(), commands1.begin(), commands1.end());
|
|
commands1.clear();
|
|
|
|
@@ -888,7 +888,7 @@
|
|
commands1.push_back(symlink);
|
|
this->LocalGenerator->CreateCDCommand(commands1,
|
|
this->Makefile->GetStartOutputDirectory(),
|
|
- this->Makefile->GetHomeOutputDirectory());
|
|
+ cmLocalGenerator::HOME_OUTPUT);
|
|
commands.insert(commands.end(), commands1.begin(), commands1.end());
|
|
commands1.clear();
|
|
}
|
|
--- a/Source/cmMakefileTargetGenerator.cxx
|
|
+++ b/Source/cmMakefileTargetGenerator.cxx
|
|
@@ -567,7 +567,7 @@
|
|
if(this->LocalGenerator->UseRelativePaths)
|
|
{
|
|
sourceFile = this->Convert(sourceFile.c_str(),
|
|
- cmLocalGenerator::HOME_OUTPUT);
|
|
+ cmLocalGenerator::START_OUTPUT);
|
|
}
|
|
sourceFile = this->Convert(sourceFile.c_str(),
|
|
cmLocalGenerator::NONE,
|
|
@@ -614,7 +614,7 @@
|
|
this->LocalGenerator->CreateCDCommand
|
|
(compileCommands,
|
|
this->Makefile->GetStartOutputDirectory(),
|
|
- this->Makefile->GetHomeOutputDirectory());
|
|
+ cmLocalGenerator::HOME_OUTPUT);
|
|
commands.insert(commands.end(),
|
|
compileCommands.begin(), compileCommands.end());
|
|
|
|
@@ -725,7 +725,7 @@
|
|
this->LocalGenerator->CreateCDCommand
|
|
(preprocessCommands,
|
|
this->Makefile->GetStartOutputDirectory(),
|
|
- this->Makefile->GetHomeOutputDirectory());
|
|
+ cmLocalGenerator::HOME_OUTPUT);
|
|
commands.insert(commands.end(),
|
|
preprocessCommands.begin(),
|
|
preprocessCommands.end());
|
|
@@ -781,7 +781,7 @@
|
|
this->LocalGenerator->CreateCDCommand
|
|
(assemblyCommands,
|
|
this->Makefile->GetStartOutputDirectory(),
|
|
- this->Makefile->GetHomeOutputDirectory());
|
|
+ cmLocalGenerator::HOME_OUTPUT);
|
|
commands.insert(commands.end(),
|
|
assemblyCommands.begin(),
|
|
assemblyCommands.end());
|
|
@@ -895,7 +895,7 @@
|
|
this->LocalGenerator->CreateCDCommand
|
|
(commands,
|
|
this->Makefile->GetStartOutputDirectory(),
|
|
- this->Makefile->GetHomeOutputDirectory());
|
|
+ cmLocalGenerator::HOME_OUTPUT);
|
|
|
|
// Write the rule.
|
|
this->LocalGenerator->WriteMakeRule(*this->BuildFileStream, 0,
|