summaryrefslogtreecommitdiffstats
path: root/Source
diff options
context:
space:
mode:
authorMarc Chevrier <marc.chevrier@gmail.com>2019-05-18 08:25:16 (GMT)
committerKitware Robot <kwrobot@kitware.com>2019-05-18 08:25:39 (GMT)
commit3bd8ed22e8017e5490b8e758f486433b005ace30 (patch)
tree345287512179b56dc428b5a8b688dc95d5b75947 /Source
parent8ada05980f1a12a2673f78f4ea7bab9df6b9d987 (diff)
parente3ff7ced630808e2e74f0853a720bc90d3f35abb (diff)
downloadCMake-3bd8ed22e8017e5490b8e758f486433b005ace30.zip
CMake-3bd8ed22e8017e5490b8e758f486433b005ace30.tar.gz
CMake-3bd8ed22e8017e5490b8e758f486433b005ace30.tar.bz2
Merge topic 'file-install-follow-symlink-chain'
e3ff7ced63 file(INSTALL): Add FOLLOW_SYMLINK_CHAIN argument Acked-by: Kitware Robot <kwrobot@kitware.com> Acked-by: Brad King <brad.king@kitware.com> Merge-request: !3332
Diffstat (limited to 'Source')
-rw-r--r--Source/cmFileCopier.cxx71
-rw-r--r--Source/cmFileCopier.h2
2 files changed, 66 insertions, 7 deletions
diff --git a/Source/cmFileCopier.cxx b/Source/cmFileCopier.cxx
index 8913e6d..972cd6e 100644
--- a/Source/cmFileCopier.cxx
+++ b/Source/cmFileCopier.cxx
@@ -31,6 +31,7 @@ cmFileCopier::cmFileCopier(cmFileCommand* command, const char* name)
, UseGivenPermissionsFile(false)
, UseGivenPermissionsDir(false)
, UseSourcePermissions(true)
+ , FollowSymlinkChain(false)
, Doing(DoingNone)
{
}
@@ -249,6 +250,9 @@ bool cmFileCopier::CheckKeyword(std::string const& arg)
this->Doing = DoingPattern;
} else if (arg == "REGEX") {
this->Doing = DoingRegex;
+ } else if (arg == "FOLLOW_SYMLINK_CHAIN") {
+ this->FollowSymlinkChain = true;
+ this->Doing = DoingNone;
} else if (arg == "EXCLUDE") {
// Add this property to the current match rule.
if (this->CurrentMatchRule) {
@@ -464,16 +468,69 @@ bool cmFileCopier::Install(const std::string& fromFile,
if (cmSystemTools::SameFile(fromFile, toFile)) {
return true;
}
- if (cmSystemTools::FileIsSymlink(fromFile)) {
- return this->InstallSymlink(fromFile, toFile);
+
+ std::string newFromFile = fromFile;
+ std::string newToFile = toFile;
+
+ if (this->FollowSymlinkChain &&
+ !this->InstallSymlinkChain(newFromFile, newToFile)) {
+ return false;
}
- if (cmSystemTools::FileIsDirectory(fromFile)) {
- return this->InstallDirectory(fromFile, toFile, match_properties);
+
+ if (cmSystemTools::FileIsSymlink(newFromFile)) {
+ return this->InstallSymlink(newFromFile, newToFile);
}
- if (cmSystemTools::FileExists(fromFile)) {
- return this->InstallFile(fromFile, toFile, match_properties);
+ if (cmSystemTools::FileIsDirectory(newFromFile)) {
+ return this->InstallDirectory(newFromFile, newToFile, match_properties);
}
- return this->ReportMissing(fromFile);
+ if (cmSystemTools::FileExists(newFromFile)) {
+ return this->InstallFile(newFromFile, newToFile, match_properties);
+ }
+ return this->ReportMissing(newFromFile);
+}
+
+bool cmFileCopier::InstallSymlinkChain(std::string& fromFile,
+ std::string& toFile)
+{
+ std::string newFromFile;
+ std::string toFilePath = cmSystemTools::GetFilenamePath(toFile);
+ while (cmSystemTools::ReadSymlink(fromFile, newFromFile)) {
+ if (!cmSystemTools::FileIsFullPath(newFromFile)) {
+ std::string fromFilePath = cmSystemTools::GetFilenamePath(fromFile);
+ newFromFile = fromFilePath + "/" + newFromFile;
+ }
+
+ std::string symlinkTarget = cmSystemTools::GetFilenameName(newFromFile);
+
+ bool copy = true;
+ if (!this->Always) {
+ std::string oldSymlinkTarget;
+ if (cmSystemTools::ReadSymlink(toFile, oldSymlinkTarget)) {
+ if (symlinkTarget == oldSymlinkTarget) {
+ copy = false;
+ }
+ }
+ }
+
+ this->ReportCopy(toFile, TypeLink, copy);
+
+ if (copy) {
+ cmSystemTools::RemoveFile(toFile);
+ cmSystemTools::MakeDirectory(toFilePath);
+
+ if (!cmSystemTools::CreateSymlink(symlinkTarget, toFile)) {
+ std::ostringstream e;
+ e << this->Name << " cannot create symlink \"" << toFile << "\".";
+ this->FileCommand->SetError(e.str());
+ return false;
+ }
+ }
+
+ fromFile = newFromFile;
+ toFile = toFilePath + "/" + symlinkTarget;
+ }
+
+ return true;
}
bool cmFileCopier::InstallSymlink(const std::string& fromFile,
diff --git a/Source/cmFileCopier.h b/Source/cmFileCopier.h
index 003b8f6..a79a60b 100644
--- a/Source/cmFileCopier.h
+++ b/Source/cmFileCopier.h
@@ -64,6 +64,7 @@ protected:
// Translate an argument to a permissions bit.
bool CheckPermissions(std::string const& arg, mode_t& permissions);
+ bool InstallSymlinkChain(std::string& fromFile, std::string& toFile);
bool InstallSymlink(const std::string& fromFile, const std::string& toFile);
bool InstallFile(const std::string& fromFile, const std::string& toFile,
MatchProperties match_properties);
@@ -86,6 +87,7 @@ protected:
bool UseGivenPermissionsFile;
bool UseGivenPermissionsDir;
bool UseSourcePermissions;
+ bool FollowSymlinkChain;
std::string Destination;
std::string FilesFromDir;
std::vector<std::string> Files;