|
|
@@ -1379,6 +1379,97 @@ bool HandleRename(std::vector<std::string> const& args,
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
+bool HandleCopyFile(std::vector<std::string> const& args,
|
|
|
+ cmExecutionStatus& status)
|
|
|
+{
|
|
|
+ if (args.size() < 3) {
|
|
|
+ status.SetError("COPY_FILE must be called with at least two additional "
|
|
|
+ "arguments");
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ // Compute full path for old and new names.
|
|
|
+ std::string oldname = args[1];
|
|
|
+ if (!cmsys::SystemTools::FileIsFullPath(oldname)) {
|
|
|
+ oldname =
|
|
|
+ cmStrCat(status.GetMakefile().GetCurrentSourceDirectory(), '/', args[1]);
|
|
|
+ }
|
|
|
+ std::string newname = args[2];
|
|
|
+ if (!cmsys::SystemTools::FileIsFullPath(newname)) {
|
|
|
+ newname =
|
|
|
+ cmStrCat(status.GetMakefile().GetCurrentSourceDirectory(), '/', args[2]);
|
|
|
+ }
|
|
|
+
|
|
|
+ struct Arguments
|
|
|
+ {
|
|
|
+ bool OnlyIfDifferent = false;
|
|
|
+ std::string Result;
|
|
|
+ };
|
|
|
+
|
|
|
+ static auto const parser =
|
|
|
+ cmArgumentParser<Arguments>{}
|
|
|
+ .Bind("ONLY_IF_DIFFERENT"_s, &Arguments::OnlyIfDifferent)
|
|
|
+ .Bind("RESULT"_s, &Arguments::Result);
|
|
|
+
|
|
|
+ std::vector<std::string> unconsumedArgs;
|
|
|
+ Arguments const arguments =
|
|
|
+ parser.Parse(cmMakeRange(args).advance(3), &unconsumedArgs);
|
|
|
+ if (!unconsumedArgs.empty()) {
|
|
|
+ status.SetError("COPY_FILE unknown argument:\n " +
|
|
|
+ unconsumedArgs.front());
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ bool result = true;
|
|
|
+ if (cmsys::SystemTools::FileIsDirectory(oldname)) {
|
|
|
+ if (!arguments.Result.empty()) {
|
|
|
+ status.GetMakefile().AddDefinition(arguments.Result,
|
|
|
+ "cannot copy a directory");
|
|
|
+ } else {
|
|
|
+ status.SetError(
|
|
|
+ cmStrCat("COPY_FILE cannot copy a directory\n ", oldname));
|
|
|
+ result = false;
|
|
|
+ }
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+ if (cmsys::SystemTools::FileIsDirectory(newname)) {
|
|
|
+ if (!arguments.Result.empty()) {
|
|
|
+ status.GetMakefile().AddDefinition(arguments.Result,
|
|
|
+ "cannot copy to a directory");
|
|
|
+ } else {
|
|
|
+ status.SetError(
|
|
|
+ cmStrCat("COPY_FILE cannot copy to a directory\n ", newname));
|
|
|
+ result = false;
|
|
|
+ }
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+
|
|
|
+ cmSystemTools::CopyWhen when;
|
|
|
+ if (arguments.OnlyIfDifferent) {
|
|
|
+ when = cmSystemTools::CopyWhen::OnlyIfDifferent;
|
|
|
+ } else {
|
|
|
+ when = cmSystemTools::CopyWhen::Always;
|
|
|
+ }
|
|
|
+
|
|
|
+ std::string err;
|
|
|
+ if (cmSystemTools::CopySingleFile(oldname, newname, when, &err) ==
|
|
|
+ cmSystemTools::CopyResult::Success) {
|
|
|
+ if (!arguments.Result.empty()) {
|
|
|
+ status.GetMakefile().AddDefinition(arguments.Result, "0");
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ if (!arguments.Result.empty()) {
|
|
|
+ status.GetMakefile().AddDefinition(arguments.Result, err);
|
|
|
+ } else {
|
|
|
+ status.SetError(cmStrCat("COPY_FILE failed to copy\n ", oldname,
|
|
|
+ "\nto\n ", newname, "\nbecause: ", err, "\n"));
|
|
|
+ result = false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return result;
|
|
|
+}
|
|
|
+
|
|
|
bool HandleRemoveImpl(std::vector<std::string> const& args, bool recurse,
|
|
|
cmExecutionStatus& status)
|
|
|
{
|
|
|
@@ -3609,6 +3700,7 @@ bool cmFileCommand(std::vector<std::string> const& args,
|
|
|
{ "GLOB_RECURSE"_s, HandleGlobRecurseCommand },
|
|
|
{ "MAKE_DIRECTORY"_s, HandleMakeDirectoryCommand },
|
|
|
{ "RENAME"_s, HandleRename },
|
|
|
+ { "COPY_FILE"_s, HandleCopyFile },
|
|
|
{ "REMOVE"_s, HandleRemove },
|
|
|
{ "REMOVE_RECURSE"_s, HandleRemoveRecurse },
|
|
|
{ "COPY"_s, HandleCopyCommand },
|