Change:
starting with 1.35.0 bootstrap always rebuilds llvm, so for downstream distributions and gentoo users (they build from tarballs) internal llvm copy is compiled at least twice per bootstrap, same for lld if it's enabled. I believe this commit below is the reason:
says that only a no-op build should be performed in that case, looks like that isn't correct?
second lld build is a no-op indeed. but something triggers full llvm rebuild every time there is another bug here, probably related. after second rebuild, llvm install prefix somehow gets set to current build directory. so when I run installer tries to install the full llvm copy to is a builddir for LLVM. ^ I can see this set all over llvm dir in files after second rebuild. so probably something mutates some cmake knob and CMAKEINSTALL_PREFIX, triggering full rebuild and setting wrong installation prefix as a side-effect.
cc and
just fyi, manually rolling back those 3 commits from 1.35.0 tarball fixed build for me
We had the same problem on FreeBSD during the 1.35.0 update. We've skipped the LLVM rebuild with this hack:
This causes a tarball build, which normally takes about seconds for Suse's SLE, to take over seconds.
Do you have any details how you're configuring the build, or how to reproduce this? I just tried the 1.37.0 tarball with the default config, and it only built LLVM once. I ran the build again and it tried LLVM again, but that was indeed a no-op build, only 6 seconds total. I also tried with and got the same thing, except the second no-op build was only 3 seconds.
still patching 1.37, but I'll check it without patches and will attach my toml file.
powerpc example, but it also happens on x8664 looks like the second build happens on installation. the build is run using contents of CFLAGSpowerpc64le-unknown-linux-gnu=-m64 and the installation command is and the second rebuild actually happend while running x.py install I think it does not like and somehow decides to rebuild llvm. i tried to explain in destdir is not a final destination, it's a temporary staging location, where package manager takes over and packs it and later installs onto filesystem. it's critical for distributions. full build logs attached. it's huge, some key points line 1416 - first llvm build line - full build complete line - second llvm build triggered ctrl+c pressed
Yes, I do Red Hat packaging, so I'm familiar with how is used. While it's annoying that the "internal" LLVM install ends up re-copied under , I don't think that's the reason for the complete rebuild. Rather, if you compare the commands on lines 1418 and , the flags are different: "-DCMAKECFLAGS=-ffunction-sections -fdata-sections -fPIC -m64 -m64" "-DCMAKECXXFLAGS=-ffunction-sections -fdata-sections -fPIC -m64 -m64" vs. "-DCMAKECFLAGS=-ffunction-sections -fdata-sections -fPIC -m64 -mcpu=native -pipe -frecord-gcc-switches" "-DCMAKECXXFLAGS=-ffunction-sections -fdata-sections -fPIC -m64 -mcpu=native -pipe -frecord-gcc-switches" So I guess it's the difference of having your or not, and it's completely natural that this would not be a no-op build. That said, I think we could just use an empty stamp file for non-git builds (from source tarball). This means we would never rebuild LLVM automatically, but it's probably fair to say that folks aren't doing LLVM development in such environments. We could still have a warning to explain that this is happening -- maybe print the path to the stamp file for manually removal to force it anew.
AFAIK multiple rebuilds happen only for cross builds and I'm convinced cross compiling LLVM is screwed up in rustbuild. Running from Linux will fail on building LLVM for Windows (so it's 2nd LLVM build) because somehow is defined. It gets even weirder when you run build again without cleaning, this time LLVM build will succeed (Rust build will fail because it needs few tweaks). I'll open new issue for it when I find time to obtain logs, just wanted to make you aware of related bug.
See for this.
I can confirm that this helps on Solaris. Tested with Rust 1.35.0. Thank you!

Discussion:
(info, "src/llvm-project/llvm", builder.llvm_out(target), dir.join("bin")) }; <del> if !llvm_info.is_git() { println!( "git could not determine the LLVM submodule commit hash.  Assuming that an LLVM build is necessary.", ); } </del> let build_llvm_config = llvm_config_ret_dir .join(exe("llvm-config", &*builder.config.build)); let done_stamp = out_dir.join("llvm-finished-building"); <del> if let Some(llvm_commit) = llvm_info.sha() { if done_stamp.exists() { </del> <ins> if done_stamp.exists() { if let Some(llvm_commit) = llvm_info.sha() { </ins> let done_contents = t!(fs::read(&done_stamp)); // If LLVM was already built previously and the submodule's commit didn't change // from the previous build, then no action is required. if done_contents == llvm_commit.as_bytes() { <del> return build_llvm_config </del> <ins> return build_llvm_config; </ins> } <ins> } else { builder.info( "Could not determine the LLVM submodule commit hash.  Assuming that an LLVM rebuild is not necessary.", ); builder.info(&format!( "To force LLVM to rebuild, remove the file `{}`", done_stamp.display() )); return build_llvm_config; </ins> } }

cfg.build(); <del> if let Some(llvm_commit) = llvm_info.sha() { t!(fs::write(&done_stamp, llvm_commit)); } </del> <ins> t!(fs::write(&done_stamp, llvm_info.sha().unwrap_or(""))); </ins> build_llvm_config }