diff options
author | Brad King <brad.king@kitware.com> | 2007-03-12 18:15:25 (GMT) |
---|---|---|
committer | Brad King <brad.king@kitware.com> | 2007-03-12 18:15:25 (GMT) |
commit | e105c7fedc026d4f455a5b8d240db7d638341f2f (patch) | |
tree | 3392d055fe6d0b510413fdfcb22103823ce7be69 /Source/cmFileCommand.cxx | |
parent | e01cdf2065d93cdbb873999b45414133978860b2 (diff) | |
download | CMake-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.cxx | 68 |
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; |