From d0c31cbff94b86ae00fddac89c6f404cc4229370 Mon Sep 17 00:00:00 2001 From: Georg Schwab Date: Thu, 6 May 2021 11:26:09 +0200 Subject: [PATCH] Windows: Use real artifact versioning symlinks if possible When cross compiling from Windows to a platform that uses SONAMEs, real symlinks are now created for the VERSION and SOVERSION links instead of copies, if the user has the necessary privileges. Fixes: #22128 --- Source/cmcmd.cxx | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/Source/cmcmd.cxx b/Source/cmcmd.cxx index 30347f23b9..98946b64fb 100644 --- a/Source/cmcmd.cxx +++ b/Source/cmcmd.cxx @@ -1643,10 +1643,21 @@ cmsys::Status cmcmd::SymlinkInternal(std::string const& file, if (cmSystemTools::FileExists(link) || cmSystemTools::FileIsSymlink(link)) { cmSystemTools::RemoveFile(link); } -#if defined(_WIN32) && !defined(__CYGWIN__) - return cmSystemTools::CopyFileAlways(file, link); -#else std::string linktext = cmSystemTools::GetFilenameName(file); +#if defined(_WIN32) && !defined(__CYGWIN__) + std::string errorMessage; + cmsys::Status status = + cmSystemTools::CreateSymlink(linktext, link, &errorMessage); + // Creating a symlink will fail with ERROR_PRIVILEGE_NOT_HELD if the user + // does not have SeCreateSymbolicLinkPrivilege, or if developer mode is not + // active. In that case, we try to copy the file. + if (status.GetWindows() == ERROR_PRIVILEGE_NOT_HELD) { + status = cmSystemTools::CopyFileAlways(file, link); + } else if (!status) { + cmSystemTools::Error(errorMessage); + } + return status; +#else return cmSystemTools::CreateSymlink(linktext, link); #endif }