diff --git a/src/bootstrap/src/core/build_steps/dist.rs b/src/bootstrap/src/core/build_steps/dist.rs index b51d3e157887b..78176665929b6 100644 --- a/src/bootstrap/src/core/build_steps/dist.rs +++ b/src/bootstrap/src/core/build_steps/dist.rs @@ -1548,6 +1548,7 @@ impl Step for Extended { compiler: builder.compiler(stage, target), backend: "cranelift".to_string(), }); + add_component!("llvm-bitcode-linker" => LlvmBitcodeLinker {compiler, target}); let etc = builder.src.join("src/etc/installer"); @@ -2224,6 +2225,53 @@ impl Step for LlvmTools { } } +#[derive(Debug, PartialOrd, Ord, Clone, Hash, PartialEq, Eq)] +pub struct LlvmBitcodeLinker { + pub compiler: Compiler, + pub target: TargetSelection, +} + +impl Step for LlvmBitcodeLinker { + type Output = Option; + const DEFAULT: bool = true; + const ONLY_HOSTS: bool = true; + + fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { + let default = should_build_extended_tool(run.builder, "llvm-bitcode-linker"); + run.alias("llvm-bitcode-linker").default_condition(default) + } + + fn make_run(run: RunConfig<'_>) { + run.builder.ensure(LlvmBitcodeLinker { + compiler: run.builder.compiler_for( + run.builder.top_stage, + run.builder.config.build, + run.target, + ), + target: run.target, + }); + } + + fn run(self, builder: &Builder<'_>) -> Option { + let compiler = self.compiler; + let target = self.target; + + let llbc_linker = + builder.ensure(tool::LlvmBitcodeLinker { compiler, target, extra_features: vec![] }); + + let self_contained_bin_dir = format!("lib/rustlib/{}/bin/self-contained", target.triple); + + // Prepare the image directory + let mut tarball = Tarball::new(builder, "llvm-bitcode-linker", &target.triple); + tarball.set_overlay(OverlayKind::LlvmBitcodeLinker); + tarball.is_preview(true); + + tarball.add_file(llbc_linker, self_contained_bin_dir, 0o755); + + Some(tarball.generate()) + } +} + // Tarball intended for internal consumption to ease rustc/std development. // // Should not be considered stable by end users. diff --git a/src/bootstrap/src/core/build_steps/install.rs b/src/bootstrap/src/core/build_steps/install.rs index 41920fabaa974..767c0f6936494 100644 --- a/src/bootstrap/src/core/build_steps/install.rs +++ b/src/bootstrap/src/core/build_steps/install.rs @@ -300,6 +300,15 @@ install!((self, builder, _config), ); } }; + LlvmBitcodeLinker, alias = "llvm-bitcode-linker", Self::should_build(_config), only_hosts: true, { + if let Some(tarball) = builder.ensure(dist::LlvmBitcodeLinker { compiler: self.compiler, target: self.target }) { + install_sh(builder, "llvm-bitcode-linker", self.compiler.stage, Some(self.target), &tarball); + } else { + builder.info( + &format!("skipping llvm-bitcode-linker stage{} ({})", self.compiler.stage, self.target), + ); + } + }; ); #[derive(Debug, Clone, Hash, PartialEq, Eq)] diff --git a/src/bootstrap/src/core/build_steps/tool.rs b/src/bootstrap/src/core/build_steps/tool.rs index 1edf65d28b76e..8d1ff2fcb245f 100644 --- a/src/bootstrap/src/core/build_steps/tool.rs +++ b/src/bootstrap/src/core/build_steps/tool.rs @@ -746,9 +746,11 @@ impl Step for LlvmBitcodeLinker { .join(exe(bin_name, self.compiler.host)); if self.compiler.stage > 0 { - let bindir = builder.sysroot(self.compiler).join("bin"); - t!(fs::create_dir_all(&bindir)); - let bin_destination = bindir.join(exe(bin_name, self.compiler.host)); + let bindir_self_contained = builder + .sysroot(self.compiler) + .join(format!("lib/rustlib/{}/bin/self-contained", self.target.triple)); + t!(fs::create_dir_all(&bindir_self_contained)); + let bin_destination = bindir_self_contained.join(exe(bin_name, self.compiler.host)); builder.copy_link(&tool_out, &bin_destination); bin_destination } else { diff --git a/src/bootstrap/src/core/builder.rs b/src/bootstrap/src/core/builder.rs index 224f5350e40a7..f31bc46d25fcb 100644 --- a/src/bootstrap/src/core/builder.rs +++ b/src/bootstrap/src/core/builder.rs @@ -853,6 +853,7 @@ impl<'a> Builder<'a> { dist::Clippy, dist::Miri, dist::LlvmTools, + dist::LlvmBitcodeLinker, dist::RustDev, dist::Bootstrap, dist::Extended, diff --git a/src/bootstrap/src/utils/tarball.rs b/src/bootstrap/src/utils/tarball.rs index 4f99079a57f36..89fcac2a84b0a 100644 --- a/src/bootstrap/src/utils/tarball.rs +++ b/src/bootstrap/src/utils/tarball.rs @@ -20,6 +20,7 @@ pub(crate) enum OverlayKind { RLS, RustAnalyzer, RustcCodegenCranelift, + LlvmBitcodeLinker, } impl OverlayKind { @@ -64,6 +65,12 @@ impl OverlayKind { "compiler/rustc_codegen_cranelift/LICENSE-APACHE", "compiler/rustc_codegen_cranelift/LICENSE-MIT", ], + OverlayKind::LlvmBitcodeLinker => &[ + "COPYRIGHT", + "LICENSE-APACHE", + "LICENSE-MIT", + "src/tools/llvm-bitcode-linker/README.md", + ], } } @@ -87,6 +94,7 @@ impl OverlayKind { .rust_analyzer_info .version(builder, &builder.release_num("rust-analyzer/crates/rust-analyzer")), OverlayKind::RustcCodegenCranelift => builder.rust_version(), + OverlayKind::LlvmBitcodeLinker => builder.rust_version(), } } } diff --git a/src/doc/unstable-book/src/compiler-flags/codegen-options.md b/src/doc/unstable-book/src/compiler-flags/codegen-options.md index 31dfcdb199ab9..cc51554706d07 100644 --- a/src/doc/unstable-book/src/compiler-flags/codegen-options.md +++ b/src/doc/unstable-book/src/compiler-flags/codegen-options.md @@ -10,6 +10,10 @@ In addition to the stable set of linker flavors, the following unstable values a - `ptx`: use [`rust-ptx-linker`](https://github.com/denzp/rust-ptx-linker) for Nvidia NVPTX GPGPU support. - `bpf`: use [`bpf-linker`](https://github.com/alessandrod/bpf-linker) for eBPF support. +- `llbc`: for linking in llvm bitcode. Install the preview rustup components`llvm-bitcode-linker` + and `llvm-tools` to use as a self-contained linker by passing + `-Zunstable-options -Clink-self-contained=+linker` together with `-Clinker-flavor=llbc`. + Can currently only be used for Nvidia NVPTX targets (`nvptx64-nvidia-cuda`). Additionally, a set of more precise linker flavors also exists, for example allowing targets to declare that they use the LLD linker by default. The following values are currently unstable, and diff --git a/src/tools/llvm-bitcode-linker/src/linker.rs b/src/tools/llvm-bitcode-linker/src/linker.rs index aa6b6443e4d90..40572f22342be 100644 --- a/src/tools/llvm-bitcode-linker/src/linker.rs +++ b/src/tools/llvm-bitcode-linker/src/linker.rs @@ -62,7 +62,7 @@ impl Session { .arg("-o") .arg(&self.link_path) .output() - .unwrap(); + .context("An error occured when calling llvm-link. Make sure the llvm-tools component is installed.")?; if !llvm_link_output.status.success() { tracing::error!( @@ -108,7 +108,9 @@ impl Session { opt_cmd.arg("--strip-debug"); } - let opt_output = opt_cmd.output().unwrap(); + let opt_output = opt_cmd.output().context( + "An error occured when calling opt. Make sure the llvm-tools component is installed.", + )?; if !opt_output.status.success() { tracing::error!( @@ -133,8 +135,11 @@ impl Session { lcc_command.arg("--mcpu").arg(mcpu); } - let lcc_output = - lcc_command.arg(&self.opt_path).arg("-o").arg(&self.out_path).output().unwrap(); + let lcc_output = lcc_command + .arg(&self.opt_path) + .arg("-o").arg(&self.out_path) + .output() + .context("An error occured when calling llc. Make sure the llvm-tools component is installed.")?; if !lcc_output.status.success() { tracing::error!(