|
| 1 | +// Tests the -Zembed-metadata compiler flag. |
| 2 | +// Tracking issue: https://github.com/rust-lang/rust/issues/139165 |
| 3 | + |
| 4 | +use run_make_support::rfs::{create_dir, remove_file, rename}; |
| 5 | +use run_make_support::{Rustc, dynamic_lib_name, path, run_in_tmpdir, rust_lib_name, rustc}; |
| 6 | + |
| 7 | +#[derive(Debug, Copy, Clone)] |
| 8 | +enum LibraryKind { |
| 9 | + Rlib, |
| 10 | + Dylib, |
| 11 | +} |
| 12 | + |
| 13 | +impl LibraryKind { |
| 14 | + fn crate_type(&self) -> &str { |
| 15 | + match self { |
| 16 | + LibraryKind::Rlib => "rlib", |
| 17 | + LibraryKind::Dylib => "dylib", |
| 18 | + } |
| 19 | + } |
| 20 | + |
| 21 | + fn add_extern(&self, rustc: &mut Rustc, dep_name: &str, dep_path: &str) { |
| 22 | + let dep_path = match self { |
| 23 | + LibraryKind::Dylib => format!("{dep_path}/{}", dynamic_lib_name(dep_name)), |
| 24 | + LibraryKind::Rlib => format!("{dep_path}/{}", rust_lib_name(dep_name)), |
| 25 | + }; |
| 26 | + rustc.extern_(dep_name, dep_path); |
| 27 | + } |
| 28 | +} |
| 29 | + |
| 30 | +fn main() { |
| 31 | + // The compiler takes different paths based on if --extern is passed or not, so we test all |
| 32 | + // combinations (`rlib`/`dylib` x `--extern`/`no --extern`). |
| 33 | + for kind in [LibraryKind::Rlib, LibraryKind::Dylib] { |
| 34 | + eprintln!("Testing library kind {kind:?}"); |
| 35 | + lookup_rmeta_in_lib_dir(kind); |
| 36 | + lookup_rmeta_through_extern(kind); |
| 37 | + lookup_rmeta_missing(kind); |
| 38 | + } |
| 39 | +} |
| 40 | + |
| 41 | +// Lookup .rmeta file in the same directory as a rlib/dylib with stub metadata. |
| 42 | +fn lookup_rmeta_in_lib_dir(kind: LibraryKind) { |
| 43 | + run_in_tmpdir(|| { |
| 44 | + build_dep_rustc(kind).run(); |
| 45 | + rustc().input("foo.rs").run(); |
| 46 | + }); |
| 47 | +} |
| 48 | + |
| 49 | +// Lookup .rmeta file when specifying the dependency using --extern. |
| 50 | +fn lookup_rmeta_through_extern(kind: LibraryKind) { |
| 51 | + run_in_tmpdir(|| { |
| 52 | + // Generate libdep1.rlib and libdep1.rmeta in deps |
| 53 | + create_dir("deps"); |
| 54 | + build_dep_rustc(kind).out_dir("deps").run(); |
| 55 | + |
| 56 | + let mut rustc = rustc(); |
| 57 | + kind.add_extern(&mut rustc, "dep1", "deps"); |
| 58 | + rustc.extern_("dep1", path("deps").join("libdep1.rmeta")); |
| 59 | + rustc.input("foo.rs").run(); |
| 60 | + }); |
| 61 | +} |
| 62 | + |
| 63 | +// Check the error message when the .rmeta file is missing. |
| 64 | +fn lookup_rmeta_missing(kind: LibraryKind) { |
| 65 | + run_in_tmpdir(|| { |
| 66 | + create_dir("deps"); |
| 67 | + build_dep_rustc(kind).out_dir("deps").run(); |
| 68 | + |
| 69 | + let mut rustc = rustc(); |
| 70 | + kind.add_extern(&mut rustc, "dep1", "deps"); |
| 71 | + rustc.input("foo.rs").run_fail().assert_stderr_contains("only metadata stub found"); |
| 72 | + }); |
| 73 | +} |
| 74 | + |
| 75 | +fn build_dep_rustc(kind: LibraryKind) -> Rustc { |
| 76 | + let mut dep_rustc = rustc(); |
| 77 | + dep_rustc |
| 78 | + .arg("-Zembed-metadata=no") |
| 79 | + .crate_type(kind.crate_type()) |
| 80 | + .input("dep1.rs") |
| 81 | + .emit("metadata,link"); |
| 82 | + if matches!(kind, LibraryKind::Dylib) { |
| 83 | + dep_rustc.arg("-Cprefer-dynamic"); |
| 84 | + } |
| 85 | + dep_rustc |
| 86 | +} |
0 commit comments