Skip to content

Commit

Permalink
Rollup merge of #98513 - ehuss:rebuild-llvm-download, r=Mark-Simulacrum
Browse files Browse the repository at this point in the history
Fix LLVM rebuild with download-ci-llvm.

This fixes an issue where updating a local checkout that includes a change in `src/version` causes a linking failure.

The cause is that the `rustc_llvm` build script uses `rerun-if-changed` of `llvm-config` to know if it needs to rerun. Cargo only compares the timestamp of the last time the build script to the file. However, extracting the tar files retains the timestamps in the tarball which may be some time in the past. Since `src/version` is included in the LLVM `.so` filename, `rustc` attempts to load the wrong shared library since the `rustc_llvm` build script doesn't rerun.

rust-lang/cargo#10791 contains a more detailed explanation.

The solution here is a hack which updates the timestamp of `llvm-config` to the current time when it is extracted.

This is a bit of a hack, but seems to be the best solution I can think of until rust-lang/cargo#10791 is fixed. There are likely several other situations where this is a problem (such as using system LLVM), and this isn't really a complete fix.

Note that apple platforms are not directly affected by this problem because they don't have a version in the dylib filename.

How to test this:

1. On a linux host, enable download-ci-llvm
2. Check out 7036449 (the commit just before the last version bump)
3. `./x.py build library/std`
4. Check out 5f015a2 (the commit that bumped the version)
5. `./x.py build library/std`

Fixes #98495
  • Loading branch information
JohnTitor authored Jun 26, 2022
2 parents c3b2291 + 418b1fa commit fba8dfd
Showing 1 changed file with 13 additions and 0 deletions.
13 changes: 13 additions & 0 deletions src/bootstrap/native.rs
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,19 @@ pub(crate) fn maybe_download_ci_llvm(builder: &Builder<'_>) {
for binary in ["llvm-config", "FileCheck"] {
builder.fix_bin_or_dylib(&llvm_root.join("bin").join(binary));
}

// Update the timestamp of llvm-config to force rustc_llvm to be
// rebuilt. This is a hacky workaround for a deficiency in Cargo where
// the rerun-if-changed directive doesn't handle changes very well.
// https://github.com/rust-lang/cargo/issues/10791
// Cargo only compares the timestamp of the file relative to the last
// time `rustc_llvm` build script ran. However, the timestamps of the
// files in the tarball are in the past, so it doesn't trigger a
// rebuild.
let now = filetime::FileTime::from_system_time(std::time::SystemTime::now());
let llvm_config = llvm_root.join("bin/llvm-config");
t!(filetime::set_file_times(&llvm_config, now, now));

let llvm_lib = llvm_root.join("lib");
for entry in t!(fs::read_dir(&llvm_lib)) {
let lib = t!(entry).path();
Expand Down

0 comments on commit fba8dfd

Please sign in to comment.