diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs index 762bf0a271704..a79839f3c0b61 100644 --- a/src/bootstrap/src/core/build_steps/test.rs +++ b/src/bootstrap/src/core/build_steps/test.rs @@ -2291,9 +2291,6 @@ NOTE: if you're sure you want to do this, please open an issue as to why. In the target, }); } - if mode == CompiletestMode::RunMake { - builder.tool_exe(Tool::RunMakeSupport); - } // ensure that `libproc_macro` is available on the host. if suite == "mir-opt" { @@ -2306,6 +2303,36 @@ NOTE: if you're sure you want to do this, please open an issue as to why. In the let mut cmd = builder.tool_cmd(Tool::Compiletest); + if mode == CompiletestMode::RunMake { + // Find .rlib and .rmeta files of the run-make-support library, and pass them to + // compiletest + let output = builder.tool(Tool::RunMakeSupport); + let find = |extension: &str| -> Option<&PathBuf> { + output.artifacts.iter().find_map(|p| { + // We want librun_make_support .rlib and .rmeta files + // They can be in separate directories, because Cargo currently uplifts the + // .rlib file when using -Zembed-metadata=no, but it doesn't uplift the + // .rmeta file + let filename = p.file_name()?.to_str()?; + if !filename.starts_with("librun_make_support") { + return None; + } + + if extension == p.extension()? { Some(p) } else { None } + }) + }; + if !builder.config.dry_run() { + let rlib = + find("rlib").expect(".rlib not found when compiling librun_make_support"); + cmd.arg("--run-make-support-rlib").arg(rlib); + + // .rmeta might not be found if we're not using -Zembed-metadata=no + if let Some(rmeta) = find("rmeta") { + cmd.arg("--run-make-support-rmeta").arg(rmeta); + } + } + } + if suite == "mir-opt" { builder.ensure(compile::Std::new(test_compiler, target).is_for_mir_opt_tests(true)); } else { diff --git a/src/bootstrap/src/core/build_steps/tool.rs b/src/bootstrap/src/core/build_steps/tool.rs index 3605fcf5b2fa6..75d5fdcdd2c33 100644 --- a/src/bootstrap/src/core/build_steps/tool.rs +++ b/src/bootstrap/src/core/build_steps/tool.rs @@ -13,7 +13,7 @@ use std::ffi::OsStr; use std::path::{Path, PathBuf}; use std::{env, fs}; -use crate::core::build_steps::compile::is_lto_stage; +use crate::core::build_steps::compile::{CargoMessage, is_lto_stage}; use crate::core::build_steps::toolstate::ToolState; use crate::core::build_steps::{compile, llvm}; use crate::core::builder::{ @@ -63,6 +63,8 @@ pub struct ToolBuildResult { pub tool_path: PathBuf, /// Compiler used to build the tool. pub build_compiler: Compiler, + /// All Cargo artifacts produced during the compilation of this tool + pub artifacts: Vec, } impl Step for ToolBuild { @@ -152,7 +154,14 @@ impl Step for ToolBuild { builder.msg(Kind::Build, self.tool, self.mode, self.build_compiler, self.target); // we check this below - let build_success = compile::stream_cargo(builder, cargo, vec![], &mut |_| {}); + let mut artifacts = vec![]; + let build_success = compile::stream_cargo(builder, cargo, vec![], &mut |msg| match msg { + CargoMessage::CompilerArtifact { filenames, .. } => { + artifacts.extend(filenames.into_iter().map(|p| PathBuf::from(p.as_ref()))); + } + CargoMessage::BuildScriptExecuted => {} + CargoMessage::BuildFinished => {} + }); builder.save_toolstate( tool, @@ -177,7 +186,7 @@ impl Step for ToolBuild { .join(format!("lib{tool}.rlib")), }; - ToolBuildResult { tool_path, build_compiler: self.build_compiler } + ToolBuildResult { tool_path, build_compiler: self.build_compiler, artifacts } } } } @@ -409,12 +418,19 @@ macro_rules! bootstrap_tool { /// /// The actual building, if any, will be handled via [`ToolBuild`]. pub fn tool_exe(&self, tool: Tool) -> PathBuf { + self.tool(tool).tool_path + } + + /// Ensure a tool is built, then return its build output. + /// + /// The actual building, if any, will be handled via [`ToolBuild`]. + pub fn tool(&self, tool: Tool) -> ToolBuildResult { match tool { $(Tool::$name => self.ensure($name { compiler: self.compiler(0, self.config.host_target), target: self.config.host_target, - }).tool_path, + }), )+ } } @@ -1524,7 +1540,7 @@ fn build_extended_rustc_tool( ) -> ToolBuildResult { let target = compilers.target(); let build_compiler = compilers.build_compiler; - let ToolBuildResult { tool_path, .. } = builder.ensure(ToolBuild { + let ToolBuildResult { tool_path, artifacts, .. } = builder.ensure(ToolBuild { build_compiler, target, tool: tool_name, @@ -1551,9 +1567,9 @@ fn build_extended_rustc_tool( // Return a path into the bin dir. let path = bindir.join(exe(tool_name, target_compiler.host)); - ToolBuildResult { tool_path: path, build_compiler } + ToolBuildResult { tool_path: path, build_compiler, artifacts } } else { - ToolBuildResult { tool_path, build_compiler } + ToolBuildResult { tool_path, build_compiler, artifacts } } } diff --git a/src/bootstrap/src/core/builder/tests.rs b/src/bootstrap/src/core/builder/tests.rs index 499900226d026..d5e2ef1579dc1 100644 --- a/src/bootstrap/src/core/builder/tests.rs +++ b/src/bootstrap/src/core/builder/tests.rs @@ -2388,12 +2388,12 @@ mod snapshot { insta::assert_snapshot!( ctx.config("test") .path("run-make") - .render_steps(), @r" + .render_steps(), @" [build] llvm [build] rustc 0 -> rustc 1 - [build] rustc 0 -> RunMakeSupport 1 [build] rustc 1 -> std 1 [build] rustc 0 -> Compiletest 1 + [build] rustc 0 -> RunMakeSupport 1 [build] rustdoc 1 [test] compiletest-run-make 1 "); @@ -2405,12 +2405,12 @@ mod snapshot { insta::assert_snapshot!( ctx.config("test") .path("run-make-cargo") - .render_steps(), @r" + .render_steps(), @" [build] llvm [build] rustc 0 -> rustc 1 - [build] rustc 0 -> RunMakeSupport 1 [build] rustc 1 -> std 1 [build] rustc 0 -> Compiletest 1 + [build] rustc 0 -> RunMakeSupport 1 [build] rustc 0 -> cargo 1 [build] rustdoc 1 [test] compiletest-run-make-cargo 1 diff --git a/src/tools/compiletest/src/cli.rs b/src/tools/compiletest/src/cli.rs index 3af7b4dfeaeac..7efeec70b2af7 100644 --- a/src/tools/compiletest/src/cli.rs +++ b/src/tools/compiletest/src/cli.rs @@ -117,6 +117,12 @@ struct Args { /// Path to rustc to use for compiling run-make recipes. #[arg(long)] stage0_rustc_path: Option, + /// Path to librun-make-support .rlib to use for compiling run-make recipes. + #[arg(long)] + run_make_support_rlib: Option, + /// Path to librun-make-support .rmeta to use for compiling run-make recipes. + #[arg(long)] + run_make_support_rmeta: Option, /// Path to rustc to use for querying target information. #[arg(long)] query_rustc_path: Option, @@ -396,122 +402,128 @@ pub(crate) fn parse_config(args: Vec) -> Config { CodegenBackend::Llvm | CodegenBackend::Cranelift => vec![], }; + // FIXME: this run scheme is... confusing. + let run = args.run.and_then(|mode| match mode.as_str() { + "auto" => None, + "always" => Some(true), + "never" => Some(false), + _ => panic!("unknown `--run` option `{}` given", mode), + }); + Config { + // tidy-alphabetical-start + adb_device_status, + adb_path: args.adb_path, + adb_test_dir: args.adb_test_dir, + android_cross_path: args.android_cross_path, + ar: args.ar, bless: args.bless, - fail_fast: args.fail_fast || env::var_os("RUSTC_TEST_FAIL_FAST").is_some(), + build_root, + build_test_suite_root, - host_compile_lib_path: make_absolute(args.compile_lib_path), - target_run_lib_path: make_absolute(args.run_lib_path), - rustc_path: args.rustc_path, - cargo_path: args.cargo_path, - stage0_rustc_path: args.stage0_rustc_path, - query_rustc_path: args.query_rustc_path, - rustdoc_path: args.rustdoc_path, - coverage_dump_path: args.coverage_dump_path, - python: args.python, - jsondocck_path: args.jsondocck_path, - jsondoclint_path: args.jsondoclint_path, - run_clang_based_tests_with: args.run_clang_based_tests_with, - llvm_filecheck: args.llvm_filecheck, - llvm_bin_dir: args.llvm_bin_dir, + builtin_cfg_names: OnceLock::new(), + bypass_ignore_backends: args.bypass_ignore_backends, - src_root, - src_test_suite_root, + capture: !args.no_capture, - build_root, - build_test_suite_root, + cargo_path: args.cargo_path, + cc: args.cc, + cdb: args.cdb, + cdb_version, + cflags: args.cflags, + channel: args.channel, + compare_mode, + coverage_dump_path: args.coverage_dump_path, + cxx: args.cxx, + cxxflags: args.cxxflags, + default_codegen_backend, + diff_command: args.compiletest_diff_tool, - sysroot_base: args.sysroot_base, + edition: args.edition, - stage: args.stage, - stage_id: args.stage_id, + fail_fast: args.fail_fast || env::var_os("RUSTC_TEST_FAIL_FAST").is_some(), - mode, - suite: args.suite, - run_ignored: args.ignored, - with_rustc_debug_assertions: args.with_rustc_debug_assertions, - with_std_debug_assertions: args.with_std_debug_assertions, - with_std_remap_debuginfo: args.with_std_remap_debuginfo, - filters, - skip: args.skip, filter_exact: args.exact, + filters, force_pass_mode: args.pass, - // FIXME: this run scheme is... confusing. - run: args.run.and_then(|mode| match mode.as_str() { - "auto" => None, - "always" => Some(true), - "never" => Some(false), - _ => panic!("unknown `--run` option `{}` given", mode), - }), - runner: args.runner, - host_rustcflags: args.host_rustcflags, - target_rustcflags: args.target_rustcflags, - optimize_tests: args.optimize_tests, - rust_randomized_layout: args.rust_randomized_layout, - target: args.target, - host: args.host, - cdb: args.cdb, - cdb_version, + force_rerun: args.force_rerun, + + gcc_supported_target_tuples, + gdb: args.gdb, gdb_version, - lldb: args.lldb, - lldb_version, - llvm_version, - system_llvm: args.system_llvm, - android_cross_path: args.android_cross_path, - adb_path: args.adb_path, - adb_test_dir: args.adb_test_dir, - adb_device_status, - verbose: args.verbose, - verbose_run_make_subprocess_output: args.verbose_run_make_subprocess_output, - only_modified: args.only_modified, - remote_test_client: args.remote_test_client, - compare_mode, - rustfix_coverage: args.rustfix_coverage, - has_enzyme: args.has_enzyme, - has_offload: args.has_offload, - channel: args.channel, git_hash: args.git_hash, - edition: args.edition, + git_merge_commit_email: args.git_merge_commit_email, - cc: args.cc, - cxx: args.cxx, - cflags: args.cflags, - cxxflags: args.cxxflags, - ar: args.ar, - target_linker: args.target_linker, + has_enzyme: args.has_enzyme, + has_offload: args.has_offload, + host: args.host, + host_compile_lib_path: make_absolute(args.compile_lib_path), host_linker: args.host_linker, - llvm_components: args.llvm_components, - nodejs: args.nodejs, - - force_rerun: args.force_rerun, + host_rustcflags: args.host_rustcflags, + iteration_count, + jobs: args.jobs, - target_cfgs: OnceLock::new(), - builtin_cfg_names: OnceLock::new(), - supported_crate_types: OnceLock::new(), + jsondocck_path: args.jsondocck_path, + jsondoclint_path: args.jsondoclint_path, + lldb: args.lldb, + lldb_version, + llvm_bin_dir: args.llvm_bin_dir, - capture: !args.no_capture, + llvm_components: args.llvm_components, + llvm_filecheck: args.llvm_filecheck, + llvm_version, + minicore_path: args.minicore_path, + mode, nightly_branch: args.nightly_branch, - git_merge_commit_email: args.git_merge_commit_email, + nodejs: args.nodejs, + only_modified: args.only_modified, + optimize_tests: args.optimize_tests, + override_codegen_backend: args.override_codegen_backend, + parallel_frontend_threads, profiler_runtime: args.profiler_runtime, - diff_command: args.compiletest_diff_tool, + python: args.python, + query_rustc_path: args.query_rustc_path, + remote_test_client: args.remote_test_client, + run, + run_clang_based_tests_with: args.run_clang_based_tests_with, + run_ignored: args.ignored, + run_make_support_rlib: args.run_make_support_rlib, + run_make_support_rmeta: args.run_make_support_rmeta, + runner: args.runner, + rust_randomized_layout: args.rust_randomized_layout, + rustc_path: args.rustc_path, + rustdoc_path: args.rustdoc_path, + rustfix_coverage: args.rustfix_coverage, + skip: args.skip, + src_root, + src_test_suite_root, - minicore_path: args.minicore_path, + stage0_rustc_path: args.stage0_rustc_path, + stage: args.stage, + stage_id: args.stage_id, - default_codegen_backend, - override_codegen_backend: args.override_codegen_backend, - bypass_ignore_backends: args.bypass_ignore_backends, + suite: args.suite, + supported_crate_types: OnceLock::new(), - gcc_supported_target_tuples, + sysroot_base: args.sysroot_base, + system_llvm: args.system_llvm, + target: args.target, + target_cfgs: OnceLock::new(), + target_linker: args.target_linker, + target_run_lib_path: make_absolute(args.run_lib_path), + target_rustcflags: args.target_rustcflags, + verbose: args.verbose, + verbose_run_make_subprocess_output: args.verbose_run_make_subprocess_output, wasm_proc_macros: args.wasm_proc_macros, - jobs: args.jobs, - - parallel_frontend_threads, - iteration_count, + with_rustc_debug_assertions: args.with_rustc_debug_assertions, + with_std_debug_assertions: args.with_std_debug_assertions, + with_std_remap_debuginfo: args.with_std_remap_debuginfo, + // tidy-alphabetical-end } } diff --git a/src/tools/compiletest/src/common.rs b/src/tools/compiletest/src/common.rs index c5a631ad94589..1102f9eaaeff2 100644 --- a/src/tools/compiletest/src/common.rs +++ b/src/tools/compiletest/src/common.rs @@ -347,6 +347,12 @@ pub(crate) struct Config { /// - `/home/ferris/rust/build/x86_64-unknown-linux-gnu/stage0/bin/rustc` pub(crate) stage0_rustc_path: Option, + /// Path to the run-make-support .rlib file, used to build `run-make` recipes. + pub(crate) run_make_support_rlib: Option, + + /// Path to the run-make-support .rmeta file, used to build `run-make` recipes. + pub(crate) run_make_support_rmeta: Option, + /// Path to the stage 1 or higher `rustc` used to obtain target information via /// `--print=all-target-specs-json` and similar queries. /// diff --git a/src/tools/compiletest/src/runtest/run_make.rs b/src/tools/compiletest/src/runtest/run_make.rs index e1aaa2a03880f..862f38d97c8cf 100644 --- a/src/tools/compiletest/src/runtest/run_make.rs +++ b/src/tools/compiletest/src/runtest/run_make.rs @@ -76,7 +76,12 @@ impl TestCx<'_> { let tools_bin = host_build_root.join("bootstrap-tools"); let support_host_path = tools_bin.join(&self.config.host).join("release"); - let support_lib_path = support_host_path.join("librun_make_support.rlib"); + let support_lib_rlib_path = self + .config + .run_make_support_rlib + .as_ref() + .expect("run-make-support .rlib has to be passed for run-make tests"); + let support_lib_rmeta_path = self.config.run_make_support_rmeta.as_ref(); let support_lib_deps = discover_out_dirs(support_host_path.join("build")); let support_lib_deps_deps = discover_out_dirs(tools_bin.join("release").join("build")); @@ -123,17 +128,20 @@ impl TestCx<'_> { .arg("-o") .arg(&recipe_bin) // Specify library search paths for `run_make_support`. - .arg(format!("-Ldependency={}", &support_lib_path.parent().unwrap())) .args(out_dirs_to_args(support_lib_deps)) .args(out_dirs_to_args(support_lib_deps_deps)) // Provide `run_make_support` as extern prelude, so test writers don't need to write // `extern run_make_support;`. .arg("--extern") - .arg(format!("run_make_support={}", &support_lib_path)) + .arg(format!("run_make_support={}", &support_lib_rlib_path)) .arg("--edition=2024") .arg(&self.testpaths.file.join("rmake.rs")) .arg("-Cprefer-dynamic"); + if let Some(support_lib_rmeta_path) = support_lib_rmeta_path { + rustc.arg("--extern").arg(format!("run_make_support={}", &support_lib_rmeta_path)); + } + // In test code we want to be very pedantic about values being silently discarded that are // annotated with `#[must_use]`. rustc.arg("-Dunused_must_use"); diff --git a/src/tools/compiletest/src/rustdoc_gui_test.rs b/src/tools/compiletest/src/rustdoc_gui_test.rs index 88880f09837ee..b91a586c3d9ca 100644 --- a/src/tools/compiletest/src/rustdoc_gui_test.rs +++ b/src/tools/compiletest/src/rustdoc_gui_test.rs @@ -63,6 +63,8 @@ fn incomplete_config_for_rustdoc_gui_test() -> Config { rustc_path: Utf8PathBuf::default(), cargo_path: Default::default(), stage0_rustc_path: Default::default(), + run_make_support_rlib: Default::default(), + run_make_support_rmeta: Default::default(), query_rustc_path: Default::default(), rustdoc_path: Default::default(), coverage_dump_path: Default::default(),