summaryrefslogtreecommitdiffstats
path: root/Source/cmFileCommand.cxx
diff options
context:
space:
mode:
authorBrad King <brad.king@kitware.com>2007-03-12 18:15:25 (GMT)
committerBrad King <brad.king@kitware.com>2007-03-12 18:15:25 (GMT)
commite105c7fedc026d4f455a5b8d240db7d638341f2f (patch)
tree3392d055fe6d0b510413fdfcb22103823ce7be69 /Source/cmFileCommand.cxx
parente01cdf2065d93cdbb873999b45414133978860b2 (diff)
downloadCMake-e105c7fedc026d4f455a5b8d240db7d638341f2f.zip
CMake-e105c7fedc026d4f455a5b8d240db7d638341f2f.tar.gz
CMake-e105c7fedc026d4f455a5b8d240db7d638341f2f.tar.bz2
BUG: Preserve symlinks during installation. This addresses bug#4384.
Diffstat (limited to 'Source/cmFileCommand.cxx')
-rw-r--r--Source/cmFileCommand.cxx68
1 files changed, 68 insertions, 0 deletions
diff --git a/Source/cmFileCommand.cxx b/Source/cmFileCommand.cxx
index 9f8523c..1353988 100644
--- a/Source/cmFileCommand.cxx
+++ b/Source/cmFileCommand.cxx
@@ -474,9 +474,65 @@ public:
}
return true;
}
+
+private:
+ bool InstallSymlink(const char* fromFile, const char* toFile, bool always);
};
//----------------------------------------------------------------------------
+bool cmFileInstaller::InstallSymlink(const char* fromFile, const char* toFile,
+ bool always)
+{
+ // Inform the user about this file installation.
+ std::string message = "Installing ";
+ message += toFile;
+ this->Makefile->DisplayStatus(message.c_str(), -1);
+
+ // Read the original symlink.
+ std::string symlinkTarget;
+ if(!cmSystemTools::ReadSymlink(fromFile, symlinkTarget))
+ {
+ cmOStringStream e;
+ e << "INSTALL cannot read symlink \"" << fromFile
+ << "\" to duplicate at \"" << toFile << "\".";
+ this->FileCommand->SetError(e.str().c_str());
+ return false;
+ }
+
+ // Compare the symlink value to that at the destination if not
+ // always installing.
+ if(!always)
+ {
+ std::string oldSymlinkTarget;
+ if(cmSystemTools::ReadSymlink(toFile, oldSymlinkTarget))
+ {
+ if(symlinkTarget == oldSymlinkTarget)
+ {
+ return true;
+ }
+ }
+ }
+
+ // Remove the destination file so we can always create the symlink.
+ cmSystemTools::RemoveFile(toFile);
+
+ // Create the symlink.
+ if(!cmSystemTools::CreateSymlink(symlinkTarget.c_str(), toFile))
+ {
+ cmOStringStream e;
+ e << "INSTALL cannot duplicate symlink \"" << fromFile
+ << "\" at \"" << toFile << "\".";
+ this->FileCommand->SetError(e.str().c_str());
+ return false;
+ }
+
+ // Add the file to the manifest.
+ this->ManifestAppend(toFile);
+
+ return true;
+}
+
+//----------------------------------------------------------------------------
bool cmFileInstaller::InstallFile(const char* fromFile, const char* toFile,
bool always)
{
@@ -489,6 +545,12 @@ bool cmFileInstaller::InstallFile(const char* fromFile, const char* toFile,
return true;
}
+ // Short-circuit for symbolic links.
+ if(cmSystemTools::FileIsSymlink(fromFile))
+ {
+ return this->InstallSymlink(fromFile, toFile, always);
+ }
+
// Inform the user about this file installation.
std::string message = "Installing ";
message += toFile;
@@ -541,6 +603,12 @@ bool cmFileInstaller::InstallDirectory(const char* source,
return true;
}
+ // Short-circuit for symbolic links.
+ if(cmSystemTools::FileIsSymlink(source))
+ {
+ return this->InstallSymlink(source, destination, always);
+ }
+
// Inform the user about this directory installation.
std::string message = "Installing ";
message += destination;