cmake: Add -E copy_directory_if_different

Fixes #21584
This commit is contained in:
Robert Maynard
2023-01-11 16:19:09 -05:00
parent 51a0292d9c
commit c1170b5602
4 changed files with 31 additions and 3 deletions

View File

@@ -876,6 +876,16 @@ Available commands are:
The command now fails when the source directory does not exist. The command now fails when the source directory does not exist.
Previously it succeeded by creating an empty destination directory. Previously it succeeded by creating an empty destination directory.
.. option:: copy_directory_if_different <dir>... <destination>
.. versionadded:: 3.26
Copy changed content of ``<dir>...`` directories to ``<destination>`` directory.
If ``<destination>`` directory does not exist it will be created.
``copy_directory_if_different`` does follow symlinks.
The command fails when the source directory does not exist.
.. option:: copy_if_different <file>... <destination> .. option:: copy_if_different <file>... <destination>
Copy files to ``<destination>`` (either file or directory) if Copy files to ``<destination>`` (either file or directory) if

View File

@@ -0,0 +1,4 @@
cmake-E-copy-directory-if-different
-----------------------------------
* The :manual:`cmake(1)` ``-E`` option learned a new ``copy_directory_if_different`` command.

View File

@@ -110,6 +110,8 @@ void CMakeCommandUsage(std::string const& program)
"(either file or directory)\n" "(either file or directory)\n"
<< " copy_directory <dir>... destination - copy content of <dir>... " << " copy_directory <dir>... destination - copy content of <dir>... "
"directories to 'destination' directory\n" "directories to 'destination' directory\n"
<< " copy_directory_if_different <dir>... destination - copy changed content of <dir>... "
"directories to 'destination' directory\n"
<< " copy_if_different <file>... destination - copy files if it has " << " copy_if_different <file>... destination - copy files if it has "
"changed\n" "changed\n"
<< " echo [<string>...] - displays arguments as text\n" << " echo [<string>...] - displays arguments as text\n"
@@ -731,12 +733,15 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string> const& args,
return return_value; return return_value;
} }
// Copy directory content // Copy directory contents
if (args[1] == "copy_directory" && args.size() > 3) { if ((args[1] == "copy_directory" ||
args[1] == "copy_directory_if_different") &&
args.size() > 3) {
// If error occurs we want to continue copying next files. // If error occurs we want to continue copying next files.
bool return_value = false; bool return_value = false;
const bool copy_always = (args[1] == "copy_directory");
for (auto const& arg : cmMakeRange(args).advance(2).retreat(1)) { for (auto const& arg : cmMakeRange(args).advance(2).retreat(1)) {
if (!cmSystemTools::CopyADirectory(arg, args.back())) { if (!cmSystemTools::CopyADirectory(arg, args.back(), copy_always)) {
std::cerr << "Error copying directory from \"" << arg << "\" to \"" std::cerr << "Error copying directory from \"" << arg << "\" to \""
<< args.back() << "\".\n"; << args.back() << "\".\n";
return_value = true; return_value = true;

View File

@@ -593,6 +593,15 @@ run_cmake_command(E_copy_if_different-three-source-files-target-is-file
unset(in) unset(in)
unset(out) unset(out)
set(in ${RunCMake_SOURCE_DIR}/copy_input)
set(out ${RunCMake_BINARY_DIR}/copy_directory_different_output)
file(REMOVE_RECURSE "${out}")
file(MAKE_DIRECTORY ${out})
run_cmake_command(E_copy_directory_if_different
${CMAKE_COMMAND} -E copy_directory_if_different ${in} ${out})
unset(in)
unset(out)
set(in ${RunCMake_SOURCE_DIR}/copy_input) set(in ${RunCMake_SOURCE_DIR}/copy_input)
set(out ${RunCMake_BINARY_DIR}/copy_directory_output) set(out ${RunCMake_BINARY_DIR}/copy_directory_output)
set(outfile ${out}/file_for_test.txt) set(outfile ${out}/file_for_test.txt)