[llvm] [llvm][support] Refactor symlink handling and add readlink (PR #184256)
Michael Spencer via llvm-commits
llvm-commits at lists.llvm.org
Tue Mar 10 20:17:06 PDT 2026
================
@@ -338,8 +338,52 @@ std::error_code create_directory(const Twine &path, bool IgnoreExisting,
return std::error_code();
}
-// We can't use symbolic links for windows.
+std::error_code create_symlink(const Twine &to, const Twine &from) {
+ SmallVector<wchar_t, 128> wide_from;
+ SmallVector<wchar_t, 128> wide_to;
+ if (std::error_code ec = widenPath(from, wide_from))
+ return ec;
+ if (std::error_code ec = widenPath(to, wide_to))
+ return ec;
+
+ // The Win32 API normally allows forward slashes, but under some cases it does
+ // not correctly handle them in the target of a symlink.
+ for (wchar_t &C : wide_to)
+ if (C == L'/')
+ C = L'\\';
+
+ // Windows requires SYMBOLIC_LINK_FLAG_DIRECTORY for directory symlinks.
+ DWORD Flags = 0;
+ DWORD Attr = ::GetFileAttributesW(wide_to.begin());
+ if (Attr != INVALID_FILE_ATTRIBUTES && (Attr & FILE_ATTRIBUTE_DIRECTORY))
+ Flags |= SYMBOLIC_LINK_FLAG_DIRECTORY;
+
+ // Try with SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE first, which works
+ // when Developer Mode is enabled on Windows 10+.
+ if (::CreateSymbolicLinkW(wide_from.begin(), wide_to.begin(),
+ Flags |
+ SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE))
+ return std::error_code();
+
+ // If the flag is not recognized (older Windows), retry without it.
+ DWORD Err = ::GetLastError();
+ if (Err == ERROR_INVALID_PARAMETER) {
----------------
Bigcheese wrote:
Hmm, I'm not sure `SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE` would fail in that case? It should only fail for UWP programs when you're no in developer mode.
https://github.com/llvm/llvm-project/pull/184256
More information about the llvm-commits
mailing list