mirror of
https://github.com/Kitware/CMake.git
synced 2026-01-02 20:00:38 -06:00
@@ -1029,6 +1029,19 @@ Available commands are:
|
||||
``copy_directory_if_different`` does follow symlinks.
|
||||
The command fails when the source directory does not exist.
|
||||
|
||||
.. option:: copy_directory_if_newer <dir>... <destination>
|
||||
|
||||
.. versionadded:: 4.2
|
||||
|
||||
Copy content of ``<dir>...`` directories to ``<destination>`` directory
|
||||
if source files are newer than destination files (based on file timestamps).
|
||||
If ``<destination>`` directory does not exist it will be created.
|
||||
|
||||
``copy_directory_if_newer`` does follow symlinks.
|
||||
The command fails when the source directory does not exist.
|
||||
This is faster than ``copy_directory_if_different`` as it only compares
|
||||
file timestamps instead of file contents.
|
||||
|
||||
.. option:: copy_if_different <file>... <destination>
|
||||
|
||||
Copy files to ``<destination>`` (either file or directory) if
|
||||
@@ -1040,6 +1053,18 @@ Available commands are:
|
||||
.. versionadded:: 3.5
|
||||
Support for multiple input files.
|
||||
|
||||
.. option:: copy_if_newer <file>... <destination>
|
||||
|
||||
.. versionadded:: 4.2
|
||||
|
||||
Copy files to ``<destination>`` (either file or directory) if
|
||||
source files are newer than destination files (based on file timestamps).
|
||||
If multiple files are specified, the ``<destination>`` must be
|
||||
directory and it must exist.
|
||||
``copy_if_newer`` does follow symlinks.
|
||||
This is faster than ``copy_if_different`` as it only compares
|
||||
file timestamps instead of file contents.
|
||||
|
||||
.. option:: create_symlink <old> <new>
|
||||
|
||||
Create a symbolic link ``<new>`` naming ``<old>``.
|
||||
|
||||
9
Help/release/dev/cmake-copy-if-newer.rst
Normal file
9
Help/release/dev/cmake-copy-if-newer.rst
Normal file
@@ -0,0 +1,9 @@
|
||||
cmake-copy-if-newer
|
||||
-------------------
|
||||
|
||||
* The :manual:`cmake(1)` command-line tool now supports
|
||||
``cmake -E copy_if_newer`` and ``cmake -E copy_directory_if_newer``
|
||||
subcommands to copy files based on timestamp comparison instead of
|
||||
content comparison. These commands copy files only if the source is
|
||||
newer than the destination, providing better performance for build
|
||||
systems compared to ``copy_if_different`` which compares file contents.
|
||||
@@ -1571,6 +1571,18 @@ cmSystemTools::CopyResult cmSystemTools::CopySingleFile(
|
||||
return CopyResult::Success;
|
||||
}
|
||||
break;
|
||||
case CopyWhen::OnlyIfNewer: {
|
||||
if (!SystemTools::FileExists(newname)) {
|
||||
break;
|
||||
}
|
||||
int timeResult = 0;
|
||||
cmsys::Status timeStatus =
|
||||
cmsys::SystemTools::FileTimeCompare(oldname, newname, &timeResult);
|
||||
if (timeStatus.IsSuccess() && timeResult <= 0) {
|
||||
return CopyResult::Success;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
mode_t perm = 0;
|
||||
@@ -1632,6 +1644,20 @@ cmSystemTools::CopyResult cmSystemTools::CopySingleFile(
|
||||
return CopyResult::Success;
|
||||
}
|
||||
|
||||
bool cmSystemTools::CopyFileIfNewer(std::string const& source,
|
||||
std::string const& destination)
|
||||
{
|
||||
return cmsys::SystemTools::CopyFileIfNewer(source, destination).IsSuccess();
|
||||
}
|
||||
|
||||
bool cmSystemTools::CopyADirectory(std::string const& source,
|
||||
std::string const& destination,
|
||||
CopyWhen when)
|
||||
{
|
||||
return cmsys::SystemTools::CopyADirectory(source, destination, when)
|
||||
.IsSuccess();
|
||||
}
|
||||
|
||||
bool cmSystemTools::RenameFile(std::string const& oldname,
|
||||
std::string const& newname)
|
||||
{
|
||||
|
||||
@@ -167,11 +167,6 @@ public:
|
||||
static bool SimpleGlob(std::string const& glob,
|
||||
std::vector<std::string>& files, int type = 0);
|
||||
|
||||
enum class CopyWhen
|
||||
{
|
||||
Always,
|
||||
OnlyIfDifferent,
|
||||
};
|
||||
enum class CopyInputRecent
|
||||
{
|
||||
No,
|
||||
@@ -210,6 +205,15 @@ public:
|
||||
CopyInputRecent inputRecent,
|
||||
std::string* err = nullptr);
|
||||
|
||||
/** Copy a file if it is newer than the destination. */
|
||||
static bool CopyFileIfNewer(std::string const& source,
|
||||
std::string const& destination);
|
||||
|
||||
/** Copy directory contents with specified copy behavior. */
|
||||
static bool CopyADirectory(std::string const& source,
|
||||
std::string const& destination,
|
||||
CopyWhen when = CopyWhen::Always);
|
||||
|
||||
enum class Replace
|
||||
{
|
||||
Yes,
|
||||
|
||||
@@ -5614,7 +5614,8 @@ void cmVisualStudio10TargetGenerator::WriteMissingFilesWP80(Elem& e1)
|
||||
this->AddedFiles.push_back(smallLogo);
|
||||
|
||||
std::string logo = cmStrCat(this->DefaultArtifactDir, "/Logo.png");
|
||||
cmSystemTools::CopyAFile(cmStrCat(templateFolder, "/Logo.png"), logo, false);
|
||||
cmSystemTools::CopyAFile(cmStrCat(templateFolder, "/Logo.png"), logo,
|
||||
cmSystemTools::CopyWhen::OnlyIfDifferent);
|
||||
ConvertToWindowsSlash(logo);
|
||||
Elem(e1, "Image").Attribute("Include", logo);
|
||||
this->AddedFiles.push_back(logo);
|
||||
@@ -5894,7 +5895,8 @@ void cmVisualStudio10TargetGenerator::WriteCommonMissingFiles(
|
||||
this->AddedFiles.push_back(smallLogo44);
|
||||
|
||||
std::string logo = cmStrCat(this->DefaultArtifactDir, "/Logo.png");
|
||||
cmSystemTools::CopyAFile(cmStrCat(templateFolder, "/Logo.png"), logo, false);
|
||||
cmSystemTools::CopyAFile(cmStrCat(templateFolder, "/Logo.png"), logo,
|
||||
cmSystemTools::CopyWhen::OnlyIfDifferent);
|
||||
ConvertToWindowsSlash(logo);
|
||||
Elem(e1, "Image").Attribute("Include", logo);
|
||||
this->AddedFiles.push_back(logo);
|
||||
|
||||
@@ -97,7 +97,9 @@ char const* const HELP_AVAILABLE_COMMANDS = R"(Available commands:
|
||||
copy <file>... destination - copy files to destination (either file or directory)
|
||||
copy_directory <dir>... destination - copy content of <dir>... directories to 'destination' directory
|
||||
copy_directory_if_different <dir>... destination - copy changed content of <dir>... directories to 'destination' directory
|
||||
copy_directory_if_newer <dir>... destination - copy newer content of <dir>... directories to 'destination' directory
|
||||
copy_if_different <file>... destination - copy files if it has changed
|
||||
copy_if_newer <file>... destination - copy files if source is newer than destination
|
||||
echo [<string>...] - displays arguments as text
|
||||
echo_append [<string>...] - displays arguments as text but no new line
|
||||
env [--unset=NAME ...] [NAME=VALUE ...] [--] <command> [<arg>...]
|
||||
@@ -778,15 +780,45 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string> const& args,
|
||||
return return_value;
|
||||
}
|
||||
|
||||
// Copy file if newer.
|
||||
if (args[1] == "copy_if_newer" && args.size() > 3) {
|
||||
// If multiple source files specified,
|
||||
// then destination must be directory
|
||||
if ((args.size() > 4) &&
|
||||
(!cmSystemTools::FileIsDirectory(args.back()))) {
|
||||
std::cerr << "Error: Target (for copy_if_newer command) \""
|
||||
<< args.back() << "\" is not a directory.\n";
|
||||
return 1;
|
||||
}
|
||||
// If error occurs we want to continue copying next files.
|
||||
bool return_value = false;
|
||||
for (auto const& arg : cmMakeRange(args).advance(2).retreat(1)) {
|
||||
if (!cmSystemTools::CopyFileIfNewer(arg, args.back())) {
|
||||
std::cerr << "Error copying file (if newer) from \"" << arg
|
||||
<< "\" to \"" << args.back() << "\".\n";
|
||||
return_value = true;
|
||||
}
|
||||
}
|
||||
return return_value;
|
||||
}
|
||||
|
||||
// Copy directory contents
|
||||
if ((args[1] == "copy_directory" ||
|
||||
args[1] == "copy_directory_if_different") &&
|
||||
args[1] == "copy_directory_if_different" ||
|
||||
args[1] == "copy_directory_if_newer") &&
|
||||
args.size() > 3) {
|
||||
// If error occurs we want to continue copying next files.
|
||||
bool return_value = false;
|
||||
bool const copy_always = (args[1] == "copy_directory");
|
||||
|
||||
cmsys::SystemTools::CopyWhen when = cmsys::SystemTools::CopyWhen::Always;
|
||||
if (args[1] == "copy_directory_if_different") {
|
||||
when = cmsys::SystemTools::CopyWhen::OnlyIfDifferent;
|
||||
} else if (args[1] == "copy_directory_if_newer") {
|
||||
when = cmsys::SystemTools::CopyWhen::OnlyIfNewer;
|
||||
}
|
||||
|
||||
for (auto const& arg : cmMakeRange(args).advance(2).retreat(1)) {
|
||||
if (!cmSystemTools::CopyADirectory(arg, args.back(), copy_always)) {
|
||||
if (!cmSystemTools::CopyADirectory(arg, args.back(), when)) {
|
||||
std::cerr << "Error copying directory from \"" << arg << "\" to \""
|
||||
<< args.back() << "\".\n";
|
||||
return_value = true;
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
1
|
||||
@@ -0,0 +1 @@
|
||||
^Error copying directory from ".+" to ".+"\.$
|
||||
@@ -0,0 +1 @@
|
||||
^$
|
||||
@@ -0,0 +1 @@
|
||||
1
|
||||
@@ -0,0 +1 @@
|
||||
^Error copying file \(if different\) from ".+" to ".+"\.$
|
||||
@@ -0,0 +1 @@
|
||||
1
|
||||
@@ -0,0 +1 @@
|
||||
^Error copying file \(if newer\) from ".+" to ".+"\.$
|
||||
@@ -0,0 +1 @@
|
||||
^$
|
||||
@@ -0,0 +1 @@
|
||||
^$
|
||||
@@ -0,0 +1 @@
|
||||
^Error: Target \(for copy_if_newer command\).* is not a directory\.$
|
||||
@@ -616,6 +616,16 @@ run_cmake_command(E_copy_if_different-three-source-files-target-is-directory
|
||||
${CMAKE_COMMAND} -E copy_if_different ${in}/f1.txt ${in}/f2.txt ${in}/f3.txt ${out})
|
||||
run_cmake_command(E_copy_if_different-three-source-files-target-is-file
|
||||
${CMAKE_COMMAND} -E copy_if_different ${in}/f1.txt ${in}/f2.txt ${in}/f3.txt ${out}/f1.txt)
|
||||
run_cmake_command(E_copy_if_different-nonexistent-source
|
||||
${CMAKE_COMMAND} -E copy_if_different ${in}/nonexistent.txt ${out})
|
||||
run_cmake_command(E_copy_if_newer-one-source-directory-target-is-directory
|
||||
${CMAKE_COMMAND} -E copy_if_newer ${in}/f1.txt ${out})
|
||||
run_cmake_command(E_copy_if_newer-three-source-files-target-is-directory
|
||||
${CMAKE_COMMAND} -E copy_if_newer ${in}/f1.txt ${in}/f2.txt ${in}/f3.txt ${out})
|
||||
run_cmake_command(E_copy_if_newer-three-source-files-target-is-file
|
||||
${CMAKE_COMMAND} -E copy_if_newer ${in}/f1.txt ${in}/f2.txt ${in}/f3.txt ${out}/f1.txt)
|
||||
run_cmake_command(E_copy_if_newer-nonexistent-source
|
||||
${CMAKE_COMMAND} -E copy_if_newer ${in}/nonexistent.txt ${out})
|
||||
unset(in)
|
||||
unset(out)
|
||||
|
||||
@@ -625,6 +635,10 @@ 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})
|
||||
run_cmake_command(E_copy_directory_if_newer
|
||||
${CMAKE_COMMAND} -E copy_directory_if_newer ${in} ${out})
|
||||
run_cmake_command(E_copy_directory_if_newer-nonexistent-source
|
||||
${CMAKE_COMMAND} -E copy_directory_if_newer ${in}/nonexistent ${out}/target)
|
||||
unset(in)
|
||||
unset(out)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user