summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrad King <brad.king@kitware.com>2017-04-13 20:32:51 (GMT)
committerBrad King <brad.king@kitware.com>2017-04-13 20:32:51 (GMT)
commit99b90dbf3c6ddb1093dfd867c6810003a61cdde7 (patch)
treedab3ca97289660b1a5a487a75d0f3597de82654e
parentdadf1570d919a8dd79547b8a01644d03ae607040 (diff)
downloadCMake-99b90dbf3c6ddb1093dfd867c6810003a61cdde7.zip
CMake-99b90dbf3c6ddb1093dfd867c6810003a61cdde7.tar.gz
CMake-99b90dbf3c6ddb1093dfd867c6810003a61cdde7.tar.bz2
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.
-rw-r--r--Source/cmFileCommand.cxx40
-rw-r--r--Tests/RunCMake/file/INSTALL-FILES_FROM_DIR-bad-result.txt1
-rw-r--r--Tests/RunCMake/file/INSTALL-FILES_FROM_DIR-bad-stderr.txt15
-rw-r--r--Tests/RunCMake/file/INSTALL-FILES_FROM_DIR-bad.cmake5
-rw-r--r--Tests/RunCMake/file/INSTALL-FILES_FROM_DIR-stdout.txt8
-rw-r--r--Tests/RunCMake/file/INSTALL-FILES_FROM_DIR.cmake7
-rw-r--r--Tests/RunCMake/file/RunCMakeTest.cmake2
-rw-r--r--Tests/RunCMake/file/from/a.txt0
-rw-r--r--Tests/RunCMake/file/from/a/b.txt0
-rw-r--r--Tests/RunCMake/file/from/a/b/c.txt0
10 files changed, 77 insertions, 1 deletions
diff --git a/Source/cmFileCommand.cxx b/Source/cmFileCommand.cxx
index 51fb945..034a266 100644
--- a/Source/cmFileCommand.cxx
+++ b/Source/cmFileCommand.cxx
@@ -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 "
diff --git a/Tests/RunCMake/file/INSTALL-FILES_FROM_DIR-bad-result.txt b/Tests/RunCMake/file/INSTALL-FILES_FROM_DIR-bad-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/file/INSTALL-FILES_FROM_DIR-bad-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/file/INSTALL-FILES_FROM_DIR-bad-stderr.txt b/Tests/RunCMake/file/INSTALL-FILES_FROM_DIR-bad-stderr.txt
new file mode 100644
index 0000000..9d5f876
--- /dev/null
+++ b/Tests/RunCMake/file/INSTALL-FILES_FROM_DIR-bad-stderr.txt
@@ -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\)$
diff --git a/Tests/RunCMake/file/INSTALL-FILES_FROM_DIR-bad.cmake b/Tests/RunCMake/file/INSTALL-FILES_FROM_DIR-bad.cmake
new file mode 100644
index 0000000..807b704
--- /dev/null
+++ b/Tests/RunCMake/file/INSTALL-FILES_FROM_DIR-bad.cmake
@@ -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)
diff --git a/Tests/RunCMake/file/INSTALL-FILES_FROM_DIR-stdout.txt b/Tests/RunCMake/file/INSTALL-FILES_FROM_DIR-stdout.txt
new file mode 100644
index 0000000..1c3c693
--- /dev/null
+++ b/Tests/RunCMake/file/INSTALL-FILES_FROM_DIR-stdout.txt
@@ -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
diff --git a/Tests/RunCMake/file/INSTALL-FILES_FROM_DIR.cmake b/Tests/RunCMake/file/INSTALL-FILES_FROM_DIR.cmake
new file mode 100644
index 0000000..24e5282
--- /dev/null
+++ b/Tests/RunCMake/file/INSTALL-FILES_FROM_DIR.cmake
@@ -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")
diff --git a/Tests/RunCMake/file/RunCMakeTest.cmake b/Tests/RunCMake/file/RunCMakeTest.cmake
index 63cbdd9..26051b4 100644
--- a/Tests/RunCMake/file/RunCMakeTest.cmake
+++ b/Tests/RunCMake/file/RunCMakeTest.cmake
@@ -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)
diff --git a/Tests/RunCMake/file/from/a.txt b/Tests/RunCMake/file/from/a.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/Tests/RunCMake/file/from/a.txt
diff --git a/Tests/RunCMake/file/from/a/b.txt b/Tests/RunCMake/file/from/a/b.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/Tests/RunCMake/file/from/a/b.txt
diff --git a/Tests/RunCMake/file/from/a/b/c.txt b/Tests/RunCMake/file/from/a/b/c.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/Tests/RunCMake/file/from/a/b/c.txt