file: Add COPY/INSTALL option for fixed layout relative to a directory

Add a `FILES_FROM_DIR` option to install a specific set of files
specified relative to a given directory and preserve their layout
in the destination.  Currently we intend to use this internally
to implement other things so we don't provide an `install()`
porcelain or documentation yet.
This commit is contained in:
Brad King
2017-04-13 16:32:51 -04:00
parent dadf1570d9
commit 99b90dbf3c
10 changed files with 77 additions and 1 deletions
+39 -1
View File
@@ -1147,6 +1147,7 @@ protected:
bool UseGivenPermissionsDir;
bool UseSourcePermissions;
std::string Destination;
std::string FilesFromDir;
std::vector<std::string> Files;
int Doing;
@@ -1156,6 +1157,7 @@ protected:
DoingNone,
DoingError,
DoingDestination,
DoingFilesFromDir,
DoingFiles,
DoingPattern,
DoingRegex,
@@ -1251,6 +1253,12 @@ bool cmFileCopier::CheckKeyword(std::string const& arg)
} else {
this->Doing = DoingDestination;
}
} else if (arg == "FILES_FROM_DIR") {
if (this->CurrentMatchRule) {
this->NotAfterMatch(arg);
} else {
this->Doing = DoingFilesFromDir;
}
} else if (arg == "PATTERN") {
this->Doing = DoingPattern;
} else if (arg == "REGEX") {
@@ -1325,6 +1333,16 @@ bool cmFileCopier::CheckValue(std::string const& arg)
}
this->Doing = DoingNone;
break;
case DoingFilesFromDir:
if (cmSystemTools::FileIsFullPath(arg.c_str())) {
this->FilesFromDir = arg;
} else {
this->FilesFromDir = this->Makefile->GetCurrentSourceDirectory();
this->FilesFromDir += "/" + arg;
}
cmSystemTools::ConvertToUnixSlashes(this->FilesFromDir);
this->Doing = DoingNone;
break;
case DoingPattern: {
// Convert the pattern to a regular expression. Require a
// leading slash and trailing end-of-string in the matched
@@ -1388,9 +1406,17 @@ bool cmFileCopier::Run(std::vector<std::string> const& args)
i != this->Files.end(); ++i) {
std::string file;
if (!i->empty() && !cmSystemTools::FileIsFullPath(*i)) {
file = this->Makefile->GetCurrentSourceDirectory();
if (!this->FilesFromDir.empty()) {
file = this->FilesFromDir;
} else {
file = this->Makefile->GetCurrentSourceDirectory();
}
file += "/";
file += *i;
} else if (!this->FilesFromDir.empty()) {
this->FileCommand->SetError("option FILES_FROM_DIR requires all files "
"to be specified as relative paths.");
return false;
} else {
file = *i;
}
@@ -1404,6 +1430,13 @@ bool cmFileCopier::Run(std::vector<std::string> const& args)
// Compute the full path to the destination file.
std::string toFile = this->Destination;
if (!this->FilesFromDir.empty()) {
std::string dir = cmSystemTools::GetFilenamePath(*i);
if (!dir.empty()) {
toFile += "/";
toFile += dir;
}
}
std::string const& toName = this->ToName(fromName);
if (!toName.empty()) {
toFile += "/";
@@ -1754,6 +1787,11 @@ bool cmFileInstaller::Parse(std::vector<std::string> const& args)
}
if (!this->Rename.empty()) {
if (!this->FilesFromDir.empty()) {
this->FileCommand->SetError("INSTALL option RENAME may not be "
"combined with FILES_FROM_DIR.");
return false;
}
if (this->InstallType != cmInstallType_FILES &&
this->InstallType != cmInstallType_PROGRAMS) {
this->FileCommand->SetError("INSTALL option RENAME may be used "
@@ -0,0 +1 @@
1
@@ -0,0 +1,15 @@
^CMake Error at INSTALL-FILES_FROM_DIR-bad.cmake:[0-9]+ \(file\):
file option FILES_FROM_DIR requires all files to be specified as relative
paths\.
Call Stack \(most recent call first\):
CMakeLists.txt:[0-9]+ \(include\)
+
CMake Error at INSTALL-FILES_FROM_DIR-bad.cmake:[0-9]+ \(file\):
file INSTALL option RENAME may not be combined with FILES_FROM_DIR\.
Call Stack \(most recent call first\):
CMakeLists.txt:[0-9]+ \(include\)
+
CMake Error at INSTALL-FILES_FROM_DIR-bad.cmake:[0-9]+ \(file\):
file option FILES_FROM_DIR may not appear after PATTERN or REGEX\.
Call Stack \(most recent call first\):
CMakeLists.txt:[0-9]+ \(include\)$
@@ -0,0 +1,5 @@
set(src ${CMAKE_CURRENT_SOURCE_DIR}/from)
set(dst ${CMAKE_CURRENT_BINARY_DIR}/from)
file(INSTALL FILES ${src}/a.txt FILES_FROM_DIR ${src} DESTINATION ${dst})
file(INSTALL FILES a.txt FILES_FROM_DIR ${src} DESTINATION ${dst} RENAME b.txt)
file(INSTALL FILES a.txt DESTINATION ${dst} PATTERN *.txt FILES_FROM_DIR)
@@ -0,0 +1,8 @@
-- Before Installing
-- Installing: .*/Tests/RunCMake/file/INSTALL-FILES_FROM_DIR-build/from/a.txt
-- Installing: .*/Tests/RunCMake/file/INSTALL-FILES_FROM_DIR-build/from/a/b.txt
-- Installing: .*/Tests/RunCMake/file/INSTALL-FILES_FROM_DIR-build/from/a/b/c.txt
-- Up-to-date: .*/Tests/RunCMake/file/INSTALL-FILES_FROM_DIR-build/from/a.txt
-- Up-to-date: .*/Tests/RunCMake/file/INSTALL-FILES_FROM_DIR-build/from/a/b.txt
-- Up-to-date: .*/Tests/RunCMake/file/INSTALL-FILES_FROM_DIR-build/from/a/b/c.txt
-- After Installing
@@ -0,0 +1,7 @@
set(src ${CMAKE_CURRENT_SOURCE_DIR}/from)
set(dst ${CMAKE_CURRENT_BINARY_DIR}/from)
file(REMOVE RECURSE ${dst})
message(STATUS "Before Installing")
file(INSTALL FILES a.txt a/b.txt a/b/c.txt FILES_FROM_DIR ${src} DESTINATION ${dst})
file(INSTALL FILES a.txt a/b.txt a/b/c.txt FILES_FROM_DIR from DESTINATION ${dst})
message(STATUS "After Installing")
+2
View File
@@ -8,6 +8,8 @@ run_cmake(UPLOAD-unused-argument)
run_cmake(UPLOAD-httpheader-not-set)
run_cmake(UPLOAD-pass-not-set)
run_cmake(INSTALL-DIRECTORY)
run_cmake(INSTALL-FILES_FROM_DIR)
run_cmake(INSTALL-FILES_FROM_DIR-bad)
run_cmake(INSTALL-MESSAGE-bad)
run_cmake(FileOpenFailRead)
run_cmake(LOCK)
View File
View File
View File