diff --git a/Help/command/file.rst b/Help/command/file.rst index 81f2a0121a..ec21fae991 100644 --- a/Help/command/file.rst +++ b/Help/command/file.rst @@ -615,11 +615,12 @@ Filesystem emitted. Specifying ``COPY_ON_ERROR`` enables copying the file as a fallback if - creating the link fails. If the source is a directory, the destination - directory will be created if it does not exist, but no files will be copied - the from source one. It can be useful for handling situations such as + creating the link fails. It can be useful for handling situations such as ```` and ```` being on different drives or mount points, which would make them unable to support a hard link. + If the source is a directory, the destination directory will be created if + it does not exist. Contents of the source directory will be copied to the + destination directory unless policy :policy:`CMP0205` is not set to ``NEW``. .. signature:: file(CHMOD ... ... diff --git a/Help/manual/cmake-policies.7.rst b/Help/manual/cmake-policies.7.rst index fd010484d1..7a41e00b97 100644 --- a/Help/manual/cmake-policies.7.rst +++ b/Help/manual/cmake-policies.7.rst @@ -92,6 +92,14 @@ Supported Policies The following policies are supported. +Policies Introduced by CMake 4.3 +-------------------------------- + +.. toctree:: + :maxdepth: 1 + + CMP0205: file(CREATE_LINK) with COPY_ON_ERROR copies directory content. + Policies Introduced by CMake 4.2 -------------------------------- diff --git a/Help/policy/CMP0205.rst b/Help/policy/CMP0205.rst new file mode 100644 index 0000000000..b08ef4a16e --- /dev/null +++ b/Help/policy/CMP0205.rst @@ -0,0 +1,23 @@ +CMP0205 +------- + +.. versionadded:: 4.3 + +:command:`file(CREATE_LINK)` with ``COPY_ON_ERROR`` copies directory content. + +The :command:`file(CREATE_LINK)` command's ``COPY_ON_ERROR`` option copies +the source file to the destination as a fallback if linking it fails. +If the source is a directory, CMake 4.2 and below create the destination +directory but do not copy its contents. CMake 4.3 and above prefer to +copy the directory contents too. This policy provides compatibility with +projects that have not been updated to expect the contents to be copied. + +The ``OLD`` behavior for this policy is to create the destination directory +without copying contents. The ``NEW`` behavior for this policy to create +the destination directory and copy contents from the source directory. + +.. |INTRODUCED_IN_CMAKE_VERSION| replace:: 4.3 +.. |WARNS_OR_DOES_NOT_WARN| replace:: warns +.. include:: include/STANDARD_ADVICE.rst + +.. include:: include/DEPRECATED.rst diff --git a/Source/cmFileCommand.cxx b/Source/cmFileCommand.cxx index 057b3fa0ec..4666baa265 100644 --- a/Source/cmFileCommand.cxx +++ b/Source/cmFileCommand.cxx @@ -3221,8 +3221,13 @@ bool HandleCreateLinkCommand(std::vector const& args, return false; } + cmPolicies::PolicyStatus const cmp0205 = + status.GetMakefile().GetPolicyStatus(cmPolicies::CMP0205); + // Hard link requires original file to exist. - if (!arguments.Symbolic && !cmSystemTools::FileExists(fileName)) { + if (!arguments.Symbolic && + (!cmSystemTools::PathExists(fileName) || + (cmp0205 != cmPolicies::NEW && !cmSystemTools::FileExists(fileName)))) { result = "Cannot hard link \'" + fileName + "\' as it does not exist."; if (!arguments.Result.empty()) { status.GetMakefile().AddDefinition(arguments.Result, result); @@ -3233,20 +3238,30 @@ bool HandleCreateLinkCommand(std::vector const& args, } // Check if the new file already exists and remove it. - if (cmSystemTools::PathExists(newFileName) && - !cmSystemTools::RemoveFile(newFileName)) { - auto err = cmStrCat("Failed to create link '", newFileName, - "' because existing path cannot be removed: ", - cmSystemTools::GetLastSystemError(), '\n'); - - if (!arguments.Result.empty()) { - status.GetMakefile().AddDefinition(arguments.Result, err); - return true; + if (cmSystemTools::PathExists(newFileName)) { + cmsys::Status rmStatus; + if (cmp0205 == cmPolicies::NEW && + cmSystemTools::FileIsDirectory(newFileName)) { + rmStatus = cmSystemTools::RepeatedRemoveDirectory(newFileName); + } else { + rmStatus = cmSystemTools::RemoveFile(newFileName); + } + if (!rmStatus) { + std::string err = cmStrCat("Failed to create link '", newFileName, + "' because existing path cannot be removed: ", + rmStatus.GetString(), '\n'); + + if (!arguments.Result.empty()) { + status.GetMakefile().AddDefinition(arguments.Result, err); + return true; + } + status.SetError(err); + return false; } - status.SetError(err); - return false; } + bool const sourceIsDirectory = cmSystemTools::FileIsDirectory(fileName); + // Whether the operation completed successfully. bool completed = false; @@ -3261,20 +3276,54 @@ bool HandleCreateLinkCommand(std::vector const& args, "': ", linked.GetString()); } } else { - cmsys::Status linked = - cmSystemTools::CreateLinkQuietly(fileName, newFileName); - if (linked) { - completed = true; - } else { - result = cmStrCat("failed to create link '", newFileName, - "': ", linked.GetString()); + bool needToTry = true; + if (sourceIsDirectory) { + if (cmp0205 == cmPolicies::NEW) { + needToTry = false; + } else if (cmp0205 == cmPolicies::WARN) { + status.GetMakefile().IssueMessage( + MessageType::AUTHOR_WARNING, + cmStrCat("Path\n ", fileName, + "\nis directory. Hardlinks creation is not supported for " + "directories.\n", + cmPolicies::GetPolicyWarning(cmPolicies::CMP0205))); + } } + + if (needToTry) { + cmsys::Status linked = + cmSystemTools::CreateLinkQuietly(fileName, newFileName); + if (linked) { + completed = true; + } else { + result = cmStrCat("failed to create link '", newFileName, + "': ", linked.GetString()); + } + } else { + result = + cmStrCat("failed to create link '", newFileName, "': not supported"); + } + } + + if (arguments.CopyOnError && cmp0205 == cmPolicies::WARN && + sourceIsDirectory) { + status.GetMakefile().IssueMessage( + MessageType::AUTHOR_WARNING, + cmStrCat("Path\n ", fileName, + "\nis directory. It will be copied recursively when NEW policy " + "behavior applies for CMP0205.\n", + cmPolicies::GetPolicyWarning(cmPolicies::CMP0205))); } // Check if copy-on-error is enabled in the arguments. if (!completed && arguments.CopyOnError) { - cmsys::Status copied = - cmsys::SystemTools::CopyFileAlways(fileName, newFileName); + cmsys::Status copied; + if (cmp0205 == cmPolicies::NEW && sourceIsDirectory) { + copied = cmsys::SystemTools::CopyADirectory(fileName, newFileName); + } else { + copied = cmsys::SystemTools::CopyFileAlways(fileName, newFileName); + } + if (copied) { completed = true; } else { diff --git a/Source/cmPolicies.h b/Source/cmPolicies.h index 2f22aaad7e..554d061df5 100644 --- a/Source/cmPolicies.h +++ b/Source/cmPolicies.h @@ -612,7 +612,10 @@ class cmMakefile; 4, 2, 0, WARN) \ SELECT(POLICY, CMP0204, \ "A character set is always defined when targeting the MSVC ABI.", 4, \ - 2, 0, WARN) + 2, 0, WARN) \ + SELECT(POLICY, CMP0205, \ + "file(CREATE_LINK) with COPY_ON_ERROR copies directory content.", 4, \ + 3, 0, WARN) #define CM_SELECT_ID(F, A1, A2, A3, A4, A5, A6) F(A1) #define CM_FOR_EACH_POLICY_ID(POLICY) \ diff --git a/Source/cmSystemTools.cxx b/Source/cmSystemTools.cxx index c362689e11..45c3fd58ac 100644 --- a/Source/cmSystemTools.cxx +++ b/Source/cmSystemTools.cxx @@ -4194,21 +4194,21 @@ bool cmSystemTools::CheckRPath(std::string const& file, return newRPath.empty(); } -bool cmSystemTools::RepeatedRemoveDirectory(std::string const& dir) +cmsys::Status cmSystemTools::RepeatedRemoveDirectory(std::string const& dir) { #ifdef _WIN32 // Windows sometimes locks files temporarily so try a few times. WindowsFileRetry retry = cmSystemTools::GetWindowsFileRetry(); - for (unsigned int i = 0; i < retry.Count; ++i) { - if (cmSystemTools::RemoveADirectory(dir)) { - return true; - } + cmsys::Status status; + unsigned int tries = 0; + while (!(status = cmSystemTools::RemoveADirectory(dir)) && + ++tries < retry.Count) { cmSystemTools::Delay(retry.Delay); } - return false; + return status; #else - return static_cast(cmSystemTools::RemoveADirectory(dir)); + return cmSystemTools::RemoveADirectory(dir); #endif } diff --git a/Source/cmSystemTools.h b/Source/cmSystemTools.h index 53b2592825..9330482937 100644 --- a/Source/cmSystemTools.h +++ b/Source/cmSystemTools.h @@ -644,7 +644,7 @@ public: static bool CheckRPath(std::string const& file, std::string const& newRPath); /** Remove a directory; repeat a few times in case of locked files. */ - static bool RepeatedRemoveDirectory(std::string const& dir); + static cmsys::Status RepeatedRemoveDirectory(std::string const& dir); /** Encode a string as a URL. */ static std::string EncodeURL(std::string const& in, diff --git a/Tests/RunCMake/CMakeLists.txt b/Tests/RunCMake/CMakeLists.txt index 8652a5c4e2..880776be0d 100644 --- a/Tests/RunCMake/CMakeLists.txt +++ b/Tests/RunCMake/CMakeLists.txt @@ -719,6 +719,7 @@ foreach(var list(APPEND file-DOWNLOAD_ARGS -D${var}=${${var}}) endif() endforeach() +add_RunCMake_test(file-CREATE_LINK) add_RunCMake_test(file-DOWNLOAD) add_RunCMake_test(file-MAKE_DIRECTORY) add_RunCMake_test(file-RPATH diff --git a/Tests/RunCMake/file-CREATE_LINK/CMP0205-HardLink-NEW.cmake b/Tests/RunCMake/file-CREATE_LINK/CMP0205-HardLink-NEW.cmake new file mode 100644 index 0000000000..4cc82ae8ff --- /dev/null +++ b/Tests/RunCMake/file-CREATE_LINK/CMP0205-HardLink-NEW.cmake @@ -0,0 +1,3 @@ +set(link_name HardLink) +set(maybe_SYMBOLIC) +include("${CMAKE_CURRENT_LIST_DIR}/CMP0205-common-NEW.cmake") diff --git a/Tests/RunCMake/file-CREATE_LINK/CMP0205-HardLink-OLD.cmake b/Tests/RunCMake/file-CREATE_LINK/CMP0205-HardLink-OLD.cmake new file mode 100644 index 0000000000..e68cb7f3a2 --- /dev/null +++ b/Tests/RunCMake/file-CREATE_LINK/CMP0205-HardLink-OLD.cmake @@ -0,0 +1,3 @@ +set(link_name HardLink) +set(maybe_SYMBOLIC) +include("${CMAKE_CURRENT_LIST_DIR}/CMP0205-common-OLD.cmake") diff --git a/Tests/RunCMake/file-CREATE_LINK/CMP0205-HardLink-WARN-stderr.txt b/Tests/RunCMake/file-CREATE_LINK/CMP0205-HardLink-WARN-stderr.txt new file mode 100644 index 0000000000..52873f3e5e --- /dev/null +++ b/Tests/RunCMake/file-CREATE_LINK/CMP0205-HardLink-WARN-stderr.txt @@ -0,0 +1,38 @@ +^CMake Warning \(dev\) at [^ +]*/CMP0205-common\.cmake:[0-9]+ \(file\): + Path + + [^ +]*[\\|/]file-CREATE_LINK[\\|/]CMP0205 + + is directory. Hardlinks creation is not supported for directories. + + Policy CMP0205 is not set: file\(CREATE_LINK\) with COPY_ON_ERROR copies + directory content\. Run "cmake --help-policy CMP0205" for policy details\. + Use the cmake_policy command to set the policy and suppress this warning\. +Call Stack \(most recent call first\): + [^ +]*/CMP0205-common-WARN\.cmake:[0-9]+ \(include\) + [^ +]*/CMP0205-HardLink-WARN\.cmake:[0-9]+ \(include\) +This warning is for project developers\. Use -Wno-dev to suppress it\. + +CMake Warning \(dev\) at [^ +]*/CMP0205-common\.cmake:[0-9]+ \(file\): + Path + + [^ +]*[\\|/]file-CREATE_LINK[\\|/]CMP0205 + + is directory. It will be copied recursively when NEW policy behavior + applies for CMP0205\. + + Policy CMP0205 is not set: file\(CREATE_LINK\) with COPY_ON_ERROR copies + directory content\. Run "cmake --help-policy CMP0205" for policy details\. + Use the cmake_policy command to set the policy and suppress this warning\. +Call Stack \(most recent call first\): + [^ +]*/CMP0205-common-WARN\.cmake:[0-9]+ \(include\) + [^ +]*/CMP0205-HardLink-WARN\.cmake:[0-9]+ \(include\) +This warning is for project developers\. Use -Wno-dev to suppress it\.$ diff --git a/Tests/RunCMake/file-CREATE_LINK/CMP0205-HardLink-WARN.cmake b/Tests/RunCMake/file-CREATE_LINK/CMP0205-HardLink-WARN.cmake new file mode 100644 index 0000000000..c8ebc710c4 --- /dev/null +++ b/Tests/RunCMake/file-CREATE_LINK/CMP0205-HardLink-WARN.cmake @@ -0,0 +1,3 @@ +set(link_name HardLink) +set(maybe_SYMBOLIC) +include("${CMAKE_CURRENT_LIST_DIR}/CMP0205-common-WARN.cmake") diff --git a/Tests/RunCMake/file-CREATE_LINK/CMP0205-SymLink-NEW.cmake b/Tests/RunCMake/file-CREATE_LINK/CMP0205-SymLink-NEW.cmake new file mode 100644 index 0000000000..4831ab2b29 --- /dev/null +++ b/Tests/RunCMake/file-CREATE_LINK/CMP0205-SymLink-NEW.cmake @@ -0,0 +1,3 @@ +set(link_name SymLink) +set(maybe_SYMBOLIC SYMBOLIC) +include("${CMAKE_CURRENT_LIST_DIR}/CMP0205-common-NEW.cmake") diff --git a/Tests/RunCMake/file-CREATE_LINK/CMP0205-SymLink-OLD.cmake b/Tests/RunCMake/file-CREATE_LINK/CMP0205-SymLink-OLD.cmake new file mode 100644 index 0000000000..7fb1f6a5ca --- /dev/null +++ b/Tests/RunCMake/file-CREATE_LINK/CMP0205-SymLink-OLD.cmake @@ -0,0 +1,3 @@ +set(link_name SymLink) +set(maybe_SYMBOLIC SYMBOLIC) +include("${CMAKE_CURRENT_LIST_DIR}/CMP0205-common-OLD.cmake") diff --git a/Tests/RunCMake/file-CREATE_LINK/CMP0205-SymLink-WARN-stderr.txt b/Tests/RunCMake/file-CREATE_LINK/CMP0205-SymLink-WARN-stderr.txt new file mode 100644 index 0000000000..0399f1fd8e --- /dev/null +++ b/Tests/RunCMake/file-CREATE_LINK/CMP0205-SymLink-WARN-stderr.txt @@ -0,0 +1,19 @@ +^CMake Warning \(dev\) at [^ +]*/CMP0205-common\.cmake:[0-9]+ \(file\): + Path + + [^ +]*[\\|/]file-CREATE_LINK[\\|/]CMP0205 + + is directory. It will be copied recursively when NEW policy behavior + applies for CMP0205\. + + Policy CMP0205 is not set: file\(CREATE_LINK\) with COPY_ON_ERROR copies + directory content\. Run "cmake --help-policy CMP0205" for policy details\. + Use the cmake_policy command to set the policy and suppress this warning\. +Call Stack \(most recent call first\): + [^ +]*/CMP0205-common-WARN\.cmake:[0-9]+ \(include\) + [^ +]*/CMP0205-SymLink-WARN\.cmake:[0-9]+ \(include\) +This warning is for project developers\. Use -Wno-dev to suppress it\.$ diff --git a/Tests/RunCMake/file-CREATE_LINK/CMP0205-SymLink-WARN.cmake b/Tests/RunCMake/file-CREATE_LINK/CMP0205-SymLink-WARN.cmake new file mode 100644 index 0000000000..b14ec15df7 --- /dev/null +++ b/Tests/RunCMake/file-CREATE_LINK/CMP0205-SymLink-WARN.cmake @@ -0,0 +1,3 @@ +set(link_name SymLink) +set(maybe_SYMBOLIC SYMBOLIC) +include("${CMAKE_CURRENT_LIST_DIR}/CMP0205-common-WARN.cmake") diff --git a/Tests/RunCMake/file-CREATE_LINK/CMP0205-common-NEW.cmake b/Tests/RunCMake/file-CREATE_LINK/CMP0205-common-NEW.cmake new file mode 100644 index 0000000000..15e6a361c6 --- /dev/null +++ b/Tests/RunCMake/file-CREATE_LINK/CMP0205-common-NEW.cmake @@ -0,0 +1,12 @@ +cmake_policy(SET CMP0205 NEW) +include("${CMAKE_CURRENT_LIST_DIR}/CMP0205-common.cmake") + +if(NOT allFilesDst) + message(SEND_ERROR "Destination directory is empty: '${allFilesDst}'") +endif() + +if(NOT "${allFilesSrc}" STREQUAL "${allFilesDst}") + message(SEND_ERROR "Source and destination directories are not equal") + message(SEND_ERROR "Source files: '${allFilesSrc}'") + message(SEND_ERROR "Destination files: '${allFilesDst}'") +endif() diff --git a/Tests/RunCMake/file-CREATE_LINK/CMP0205-common-OLD.cmake b/Tests/RunCMake/file-CREATE_LINK/CMP0205-common-OLD.cmake new file mode 100644 index 0000000000..76add41239 --- /dev/null +++ b/Tests/RunCMake/file-CREATE_LINK/CMP0205-common-OLD.cmake @@ -0,0 +1,6 @@ +cmake_policy(SET CMP0205 OLD) +include("${CMAKE_CURRENT_LIST_DIR}/CMP0205-common.cmake") + +if(allFilesDst) + message(SEND_ERROR "Directory is not empty: '${allFilesDst}'") +endif() diff --git a/Tests/RunCMake/file-CREATE_LINK/CMP0205-common-WARN.cmake b/Tests/RunCMake/file-CREATE_LINK/CMP0205-common-WARN.cmake new file mode 100644 index 0000000000..ee940466b7 --- /dev/null +++ b/Tests/RunCMake/file-CREATE_LINK/CMP0205-common-WARN.cmake @@ -0,0 +1,6 @@ +# CMP0205 is unset +include("${CMAKE_CURRENT_LIST_DIR}/CMP0205-common.cmake") + +if(allFilesDst) + message(SEND_ERROR "Directory is not empty: '${allFilesDst}'") +endif() diff --git a/Tests/RunCMake/file-CREATE_LINK/CMP0205-common.cmake b/Tests/RunCMake/file-CREATE_LINK/CMP0205-common.cmake new file mode 100644 index 0000000000..deb313f9a5 --- /dev/null +++ b/Tests/RunCMake/file-CREATE_LINK/CMP0205-common.cmake @@ -0,0 +1,14 @@ +# Use COPY_ON_ERROR to handle the case where the source and destination +# directory are on different devices and empty. +file(CREATE_LINK + ${CMAKE_CURRENT_LIST_DIR}/CMP0205 ${CMAKE_CURRENT_BINARY_DIR}/CMP0205-${link_name} + ${maybe_SYMBOLIC} + RESULT result + COPY_ON_ERROR + ) +if(NOT result STREQUAL "0") + message(SEND_ERROR "COPY_ON_ERROR failed: '${result}'") +endif() + +file(GLOB_RECURSE allFilesSrc LIST_DIRECTORIES true RELATIVE "${CMAKE_CURRENT_LIST_DIR}/CMP0205" "${CMAKE_CURRENT_LIST_DIR}/CMP0205/*") +file(GLOB_RECURSE allFilesDst LIST_DIRECTORIES true RELATIVE "${CMAKE_CURRENT_BINARY_DIR}/CMP0205-${link_name}" "${CMAKE_CURRENT_BINARY_DIR}/CMP0205-${link_name}/*") diff --git a/Tests/RunCMake/file-CREATE_LINK/CMP0205/test.txt b/Tests/RunCMake/file-CREATE_LINK/CMP0205/test.txt new file mode 100644 index 0000000000..e69de29bb2 diff --git a/Tests/RunCMake/file-CREATE_LINK/CMakeLists.txt b/Tests/RunCMake/file-CREATE_LINK/CMakeLists.txt new file mode 100644 index 0000000000..39da7034a3 --- /dev/null +++ b/Tests/RunCMake/file-CREATE_LINK/CMakeLists.txt @@ -0,0 +1,3 @@ +cmake_minimum_required(VERSION 4.1) +project(${RunCMake_TEST} NONE) +include(${RunCMake_TEST}.cmake) diff --git a/Tests/RunCMake/file/CREATE_LINK-COPY_ON_ERROR.cmake b/Tests/RunCMake/file-CREATE_LINK/CREATE_LINK-COPY_ON_ERROR-file.cmake similarity index 77% rename from Tests/RunCMake/file/CREATE_LINK-COPY_ON_ERROR.cmake rename to Tests/RunCMake/file-CREATE_LINK/CREATE_LINK-COPY_ON_ERROR-file.cmake index 777ef4e6c4..e980ac00b3 100644 --- a/Tests/RunCMake/file/CREATE_LINK-COPY_ON_ERROR.cmake +++ b/Tests/RunCMake/file-CREATE_LINK/CREATE_LINK-COPY_ON_ERROR-file.cmake @@ -1,6 +1,7 @@ # Use COPY_ON_ERROR to handle the case where the source and destination -# directory are on different devices. Cross-device links are not permitted +# file are on different devices. Cross-device links are not permitted # and the following command falls back to copying the file if link fails. +# Check only command result. file(CREATE_LINK ${CMAKE_CURRENT_LIST_FILE} TestCreateLink.cmake RESULT result diff --git a/Tests/RunCMake/file/CREATE_LINK-SYMBOLIC-noexist.cmake b/Tests/RunCMake/file-CREATE_LINK/CREATE_LINK-SYMBOLIC-noexist.cmake similarity index 100% rename from Tests/RunCMake/file/CREATE_LINK-SYMBOLIC-noexist.cmake rename to Tests/RunCMake/file-CREATE_LINK/CREATE_LINK-SYMBOLIC-noexist.cmake diff --git a/Tests/RunCMake/file/CREATE_LINK-SYMBOLIC.cmake b/Tests/RunCMake/file-CREATE_LINK/CREATE_LINK-SYMBOLIC.cmake similarity index 100% rename from Tests/RunCMake/file/CREATE_LINK-SYMBOLIC.cmake rename to Tests/RunCMake/file-CREATE_LINK/CREATE_LINK-SYMBOLIC.cmake diff --git a/Tests/RunCMake/file/CREATE_LINK-noarg-result.txt b/Tests/RunCMake/file-CREATE_LINK/CREATE_LINK-noarg-result.txt similarity index 100% rename from Tests/RunCMake/file/CREATE_LINK-noarg-result.txt rename to Tests/RunCMake/file-CREATE_LINK/CREATE_LINK-noarg-result.txt diff --git a/Tests/RunCMake/file/CREATE_LINK-noarg-stderr.txt b/Tests/RunCMake/file-CREATE_LINK/CREATE_LINK-noarg-stderr.txt similarity index 100% rename from Tests/RunCMake/file/CREATE_LINK-noarg-stderr.txt rename to Tests/RunCMake/file-CREATE_LINK/CREATE_LINK-noarg-stderr.txt diff --git a/Tests/RunCMake/file/CREATE_LINK-noarg.cmake b/Tests/RunCMake/file-CREATE_LINK/CREATE_LINK-noarg.cmake similarity index 100% rename from Tests/RunCMake/file/CREATE_LINK-noarg.cmake rename to Tests/RunCMake/file-CREATE_LINK/CREATE_LINK-noarg.cmake diff --git a/Tests/RunCMake/file/CREATE_LINK-noexist-stderr.txt b/Tests/RunCMake/file-CREATE_LINK/CREATE_LINK-noexist-stderr.txt similarity index 100% rename from Tests/RunCMake/file/CREATE_LINK-noexist-stderr.txt rename to Tests/RunCMake/file-CREATE_LINK/CREATE_LINK-noexist-stderr.txt diff --git a/Tests/RunCMake/file/CREATE_LINK-noexist.cmake b/Tests/RunCMake/file-CREATE_LINK/CREATE_LINK-noexist.cmake similarity index 100% rename from Tests/RunCMake/file/CREATE_LINK-noexist.cmake rename to Tests/RunCMake/file-CREATE_LINK/CREATE_LINK-noexist.cmake diff --git a/Tests/RunCMake/file/CREATE_LINK.cmake b/Tests/RunCMake/file-CREATE_LINK/CREATE_LINK.cmake similarity index 100% rename from Tests/RunCMake/file/CREATE_LINK.cmake rename to Tests/RunCMake/file-CREATE_LINK/CREATE_LINK.cmake diff --git a/Tests/RunCMake/file-CREATE_LINK/RunCMakeTest.cmake b/Tests/RunCMake/file-CREATE_LINK/RunCMakeTest.cmake new file mode 100644 index 0000000000..ed83312207 --- /dev/null +++ b/Tests/RunCMake/file-CREATE_LINK/RunCMakeTest.cmake @@ -0,0 +1,44 @@ +include(RunCMake) + +run_cmake(CREATE_LINK) +run_cmake(CREATE_LINK-COPY_ON_ERROR-file) +run_cmake(CREATE_LINK-noarg) +run_cmake(CREATE_LINK-noexist) + +if(NOT WIN32 + AND NOT MSYS # FIXME: This works on CYGWIN but not on MSYS + ) + run_cmake(CREATE_LINK-SYMBOLIC) + run_cmake(CREATE_LINK-SYMBOLIC-noexist) +endif() + +file(MAKE_DIRECTORY ${RunCMake_BINARY_DIR}/CMP0205-Inspect/Dest) + +file(REMOVE_RECURSE ${RunCMake_BINARY_DIR}/CMP0205-Inspect-SymLink) +file(CREATE_LINK + ${RunCMake_BINARY_DIR}/CMP0205-Inspect/Dest ${RunCMake_BINARY_DIR}/CMP0205-Inspect-SymLink + SYMBOLIC + RESULT SymLink_RESULT +) +if(SymLink_RESULT STREQUAL "0") + message(STATUS "CMP0205-SymLink-* skipped: directory symbolic link creation works") + file(REMOVE ${RunCMake_BINARY_DIR}/CMP0205-Inspect-SymLink) +else() + run_cmake_script(CMP0205-SymLink-WARN) + run_cmake_script(CMP0205-SymLink-OLD) + run_cmake_script(CMP0205-SymLink-NEW) +endif() + +file(REMOVE_RECURSE ${RunCMake_BINARY_DIR}/CMP0205-Inspect-HardLink) +file(CREATE_LINK + ${RunCMake_BINARY_DIR}/CMP0205-Inspect/Dest ${RunCMake_BINARY_DIR}/CMP0205-Inspect-HardLink + RESULT HardLink_RESULT +) +if(HardLink_RESULT STREQUAL "0") + message(STATUS "CMP0205-HardLink-* skipped: directory hard link creation works") + file(REMOVE_RECURSE ${RunCMake_BINARY_DIR}/CMP0205-Inspect-HardLink) +else() + run_cmake_script(CMP0205-HardLink-WARN) + run_cmake_script(CMP0205-HardLink-OLD) + run_cmake_script(CMP0205-HardLink-NEW) +endif() diff --git a/Tests/RunCMake/file/RunCMakeTest.cmake b/Tests/RunCMake/file/RunCMakeTest.cmake index 38ec2acd33..57c191bf53 100644 --- a/Tests/RunCMake/file/RunCMakeTest.cmake +++ b/Tests/RunCMake/file/RunCMakeTest.cmake @@ -1,9 +1,5 @@ include(RunCMake) -run_cmake(CREATE_LINK) -run_cmake(CREATE_LINK-COPY_ON_ERROR) -run_cmake(CREATE_LINK-noarg) -run_cmake(CREATE_LINK-noexist) run_cmake(TOUCH) run_cmake(TOUCH-error-in-source-directory) run_cmake(TOUCH-error-missing-directory) @@ -87,8 +83,6 @@ run_cmake_command(GLOB-error-CONFIGURE_DEPENDS-SCRIPT_MODE ${CMAKE_COMMAND} -P if(NOT WIN32 AND NOT MSYS # FIXME: This works on CYGWIN but not on MSYS ) - run_cmake(CREATE_LINK-SYMBOLIC) - run_cmake(CREATE_LINK-SYMBOLIC-noexist) run_cmake(GLOB_RECURSE-cyclic-recursion) run_cmake(INSTALL-SYMLINK) run_cmake(READ_SYMLINK)