Fix distributed compilation for no-hash dep files and dist overlay issues - #2850
Open
justdoGIT wants to merge 4 commits into
Open
Fix distributed compilation for no-hash dep files and dist overlay issues#2850justdoGIT wants to merge 4 commits into
justdoGIT wants to merge 4 commits into
Conversation
Modern rustc (1.75+) emits extended metadata per dependency line in
`rustc -Z ls=root` output:
N libname[-hash] hash HASH host_hash ... kind ... public
Crates built without a content hash suffix (e.g. crc_fast, a
build-script artifact) appear as:
N crc_fast hash 05bce6... host_hash None kind Unconditional public
parse_rustc_z_ls used splitn(2, ' ') which yields libstring as the
entire trailing metadata ("crc_fast hash 05bce6... host_hash ...").
The subsequent rsplitn(2, '-') finds no '-' and libname becomes the
whole string, so it never matches the bare "crc_fast" parsed from
rmeta filenames during crate_link_paths scanning.
The unmatched dep is silently skipped, its rmeta is not packaged for
the dist worker, and the worker fails with E0463: can't find crate
for `crc_fast`.
Fix: take only the first whitespace-delimited token of libstring
before the existing rsplitn('-') logic runs, so crates with and
without a -HASH suffix both resolve to the bare crate name.
Signed-off-by: KK <pandeykamal13526@gmail.com>
The RustInputsPackager scans crate_link_paths for dependency rmeta and rlib files, extracting the crate name from each filename via rsplitn(2, '-'). This assumes every file has a -<metadata-hash> suffix. When a file has no hash (e.g. libcrc_fast.rmeta produced by a crate with crate-type = ["lib", "cdylib", "staticlib"]), rsplitn yields a single element and the code hits continue, skipping the file entirely. The file is never packaged and sent to the dist worker, which then fails with E0463: can't find crate for crc_fast. Extract the crate-name-and-extension logic into a testable helper, crate_name_and_ext_from_lib_path, that uses file_stem() to strip the extension before rsplitn, then falls back to the whole stem as the libname when no - separator is found. Signed-off-by: KK <pandeykamal13526@gmail.com>
When sccache-dist restarts, the in-memory toolchain_dir_map is wiped but the on-disk toolchain directories survive. On the next build, prepare_overlay_dirs hits the else branch (toolchain not in the map) and calls fs::create_dir on the existing directory, which returns an AlreadyExists error and fails the build. Guard create_dir with an exists() check. The archive_id is a content hash, so a pre-existing directory for the same id already holds the correct unpacked toolchain and is safe to reuse. Signed-off-by: KK <pandeykamal13526@gmail.com>
On distros where rustc --print sysroot reports /usr (e.g. Void
Linux), the ToolchainPackager joins LIBS_DIR ("lib") to the
sysroot and packages the entire /usr/lib tree. This drags the full
system library set (several GiB) into every distributed toolchain
archive, blowing past the toolchain cache size and making toolchain
packaging prohibitively slow.
Package the rustlib/ subtree instead, which is the actual Rust
standard library. Fall back to the old behavior (whole lib dir) if
rustlib/ does not exist, preserving compatibility with non-standard
sysroot layouts.
Signed-off-by: KK <pandeykamal13526@gmail.com>
This was referenced Sep 11, 2026
There was a problem hiding this comment.
🟡 Changes recommended
Unresolved critical cross-platform test risk and moderate overlay reuse behavior require changes; additional regression tests are also needed.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Pull request overview
This PR fixes distributed Rust compilation for no-hash dependencies and improves toolchain packaging and overlay handling.
Changes:
- Corrects Rust dependency and library-name parsing.
- Packages
rustlibselectively with a fallback. - Adjusts overlay toolchain directory handling.
File summaries
| File | Review summary |
|---|---|
src/compiler/rust.rs |
Dependency parsing and sysroot packaging updates. Findings: hard-coded .so fixtures may fail cross-platform tests (critical, 1 vote); archive-layout regression coverage is missing (nit, 3 votes). |
src/bin/sccache-dist/build.rs |
Overlay directory handling updates. Findings: existing-directory reuse remains incomplete and cleanup is inconsistent (moderate, 3 votes); regression coverage is missing (nit, 1 vote). |
Review details
Suppressed comments (1)
src/bin/sccache-dist/build.rs:197
- The new pre-existing-toolchain-directory path has no regression test. Please add a test that exercises
prepare_overlay_dirswith an existing toolchain directory and verifies it no longer fails withAlreadyExists, so this restart/leftover-directory fix remains protected.
// The directory can persist on disk from a previous server
// process (or a toolchain evicted from the in-memory map
// without its directory). Treat it as already-prepared.
if !toolchain_dir.exists() {
fs::create_dir(&toolchain_dir)?;
- Files reviewed: 2/2 changed files
- Comments generated: 3
- Review effort level: Lite
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Comment on lines
+2064
to
+2065
| let p = Path::new("libfoo-abc123.so"); | ||
| assert_eq!(crate_name_and_ext_from_lib_path(p), Some(("foo", "so"))); |
Comment on lines
+196
to
+197
| if !toolchain_dir.exists() { | ||
| fs::create_dir(&toolchain_dir)?; |
Comment on lines
+2350
to
+2354
| let rustlib_path = libs_path.join("rustlib"); | ||
| if rustlib_path.is_dir() { | ||
| package_builder.add_dir_contents(&rustlib_path)?; | ||
| } else { | ||
| package_builder.add_dir_contents(&libs_path)?; |
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
This PR consolidates four independent fixes for sccache-dist that together resolve E0463 "can't find crate" errors on dist workers and make sccache-dist usable on distros like Void Linux. Supersedes #2847 and #2849.
Fix 1: parse_rustc_z_ls misparses deps without -HASH suffix
Modern rustc (1.75+) emits extended metadata per dependency line in
rustc -Z ls=rootoutput:Crates built without a content hash suffix (e.g.
crc_fast, a cdylib) appear as:parse_rustc_z_lsusedsplitn(2, ' ')which yieldslibstringas the entire trailing metadata ("crc_fast hash 05bce6... host_hash ..."). The subsequentrsplitn(2, '-')finds no-andlibnamebecomes the whole string instead of just "crc_fast". This broken name never matches duringcrate_link_pathsscanning, so the rmeta is not identified as a dependency.Fix: take only the first whitespace-delimited token of
libstringbeforersplitn('-').Fix 2: crate_link_paths scan skips no-hash dep files
RustInputsPackagerscanscrate_link_pathsfor dependency rmeta/rlib files, extracting the crate name from each filename viarsplitn(2, '-'). This assumes every file has a-<metadata-hash>suffix. When a file has no hash (e.g.libcrc_fast.rmetaproduced by a crate withcrate-type = ["lib", "cdylib", "staticlib"]),rsplitnyields a single element and the code hitscontinue, skipping the file entirely. The file is never packaged and sent to the dist worker, which then fails with:Fix: extract the crate-name-and-extension logic into a testable helper,
crate_name_and_ext_from_lib_path, that usesfile_stem()to strip the extension beforersplitn, then falls back to the whole stem as the libname when no-separator is found.Fix 3: OverlayBuilder crash on persistent toolchain dirs
When sccache-dist restarts, the in-memory
toolchain_dir_mapis wiped but on-disk toolchain directories survive. On the next build,prepare_overlay_dirscallsfs::create_diron the existing directory, which returnsAlreadyExistsand fails the build.Fix: guard
create_dirwith anexists()check. Thearchive_idis a content hash, so a pre-existing directory for the same id already holds the correct unpacked toolchain.Fix 4: Package rustlib/ instead of whole sysroot lib dir
On distros where
rustc --print sysrootreports/usr(e.g. Void Linux), theToolchainPackagerjoinsLIBS_DIR("lib") to the sysroot and packages the entire/usr/libtree — several GiB — blowing past the toolchain cache size.Fix: package the
rustlib/subtree (the actual Rust stdlib) instead. Fall back to old behavior ifrustlib/doesn't exist.Testing
test_parse_rustc_z_ls_modern_no_hash_suffix,test_parse_rustc_z_ls_pre_1_55,test_parse_rustc_z_ls_post_1_55,test_crate_name_and_ext_from_lib_path,test_can_trim_thisxai-grok-telemetry(previously failing with E0463 oncrc_fast) now compiles successfully via sccache-distRelated