cargo: improve Windows symlink handling#10
Open
walter-zeromatter wants to merge 1 commit intohermeticbuild:mainfrom
Open
cargo: improve Windows symlink handling#10walter-zeromatter wants to merge 1 commit intohermeticbuild:mainfrom
walter-zeromatter wants to merge 1 commit intohermeticbuild:mainfrom
Conversation
Rewrite remove_symlink on Windows to properly classify file symlinks, directory symlinks, and junctions using FileTypeExt. Merge the separate drain_runfiles_dir_unix/drain_runfiles_dir_windows into a single drain_runfiles_dir_impl(symlinks_used) that tolerates missing entries in both modes. Make symlink_if_not_exists return bool to avoid adding pre-existing paths to the cleanup list, and tolerate PermissionDenied errors during exec_root link cleanup on Windows.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fixes Windows build failures in the Cargo build script runner caused by incorrect symlink/junction handling. Verified against Zeromatter's repo using
--override_module:main): build fails withDirectoryNotEmpty(os error 145) when removing junctions, andos error 3from broken symlink resolutionChanges
bin.rssymlink_if_not_existsnow returnsResult<bool, ...>— Tracks whether a new symlink was actually created vs one that already existed. Pre-existing entries (e.g..githubjunctions that Bazel placed) are no longer added toexec_root_links, so we don't attempt to remove paths we didn't create. This fixes theDirectoryNotEmpty(os error 145) failure observed when crates contain directory entries that become junctions.Exec-root link removal is warning-only on Windows — On Windows, symlink removal can fail with
PermissionDeniedif another process still holds a handle to the target directory (common in parallel Bazel builds). These are temporary links in the build sandbox that Bazel will clean up, so we log a warning and continue rather than failing the entire build script.Removed
swallow_already_existshelper — The logic is now inlined in thesymlink_if_not_existsmatch arms; the standalone function is unused.cargo_manifest_dir.rsremove_symlinkon Windows usesFileTypeExt— The old implementation usedpath.is_dir(), which follows the symlink target rather than inspecting the reparse point type. The new version usessymlink_metadata()+FileTypeExtto correctly distinguish symlink-files, symlink-dirs, and junctions, then calls the appropriate removal function (remove_filevsremove_dir) with fallbacks.Unified
drain_runfiles_dir_impl(symlinks_used: bool)— Replaces the separatedrain_runfiles_dir_unixanddrain_runfiles_dir_windowsmethods. The key behavioral change:NotFounderrors are now tolerated in both modes. On Windows, the runfiles directory can be incomplete (e.g. aCargo.lockthat was never created), and the old code would hard-fail on the missing entry. This was observed asos error 3failures during builds.Added 4 new tests — Cover
NotFoundtolerance, suffix-retention logic, and the copy-back path for both symlink and non-symlink modes.Test plan
mainfails building on Windows (DirectoryNotEmpty,os error 3)