| //@ ignore-cross-compile |
| //@ needs-crate-type: dylib |
| |
| // Tests the -Zembed-metadata compiler flag. |
| // Tracking issue: https://github.com/rust-lang/rust/issues/139165 |
| |
| use run_make_support::rfs::{create_dir, remove_file, rename}; |
| use run_make_support::{Rustc, dynamic_lib_name, path, run_in_tmpdir, rust_lib_name, rustc}; |
| |
| #[derive(Debug, Copy, Clone)] |
| enum LibraryKind { |
| Rlib, |
| Dylib, |
| } |
| |
| impl LibraryKind { |
| fn crate_type(&self) -> &str { |
| match self { |
| LibraryKind::Rlib => "rlib", |
| LibraryKind::Dylib => "dylib", |
| } |
| } |
| |
| fn add_extern(&self, rustc: &mut Rustc, dep_name: &str, dep_path: &str) { |
| let dep_path = match self { |
| LibraryKind::Dylib => format!("{dep_path}/{}", dynamic_lib_name(dep_name)), |
| LibraryKind::Rlib => format!("{dep_path}/{}", rust_lib_name(dep_name)), |
| }; |
| rustc.extern_(dep_name, dep_path); |
| } |
| } |
| |
| fn main() { |
| // The compiler takes different paths based on if --extern is passed or not, so we test all |
| // combinations (`rlib`/`dylib` x `--extern`/`no --extern`). |
| for kind in [LibraryKind::Rlib, LibraryKind::Dylib] { |
| eprintln!("Testing library kind {kind:?}"); |
| lookup_rmeta_in_lib_dir(kind); |
| lookup_rmeta_through_extern(kind); |
| lookup_rmeta_missing(kind); |
| } |
| } |
| |
| // Lookup .rmeta file in the same directory as a rlib/dylib with stub metadata. |
| fn lookup_rmeta_in_lib_dir(kind: LibraryKind) { |
| run_in_tmpdir(|| { |
| build_dep_rustc(kind).run(); |
| rustc().input("foo.rs").run(); |
| }); |
| } |
| |
| // Lookup .rmeta file when specifying the dependency using --extern. |
| fn lookup_rmeta_through_extern(kind: LibraryKind) { |
| run_in_tmpdir(|| { |
| // Generate libdep1.rlib and libdep1.rmeta in deps |
| create_dir("deps"); |
| build_dep_rustc(kind).out_dir("deps").run(); |
| |
| let mut rustc = rustc(); |
| kind.add_extern(&mut rustc, "dep1", "deps"); |
| rustc.extern_("dep1", path("deps").join("libdep1.rmeta")); |
| rustc.input("foo.rs").run(); |
| }); |
| } |
| |
| // Check the error message when the .rmeta file is missing. |
| fn lookup_rmeta_missing(kind: LibraryKind) { |
| run_in_tmpdir(|| { |
| create_dir("deps"); |
| build_dep_rustc(kind).out_dir("deps").run(); |
| |
| let mut rustc = rustc(); |
| kind.add_extern(&mut rustc, "dep1", "deps"); |
| rustc.input("foo.rs").run_fail().assert_stderr_contains("only metadata stub found"); |
| }); |
| } |
| |
| fn build_dep_rustc(kind: LibraryKind) -> Rustc { |
| let mut dep_rustc = rustc(); |
| dep_rustc |
| .arg("-Zembed-metadata=no") |
| .crate_type(kind.crate_type()) |
| .input("dep1.rs") |
| .emit("metadata,link"); |
| if matches!(kind, LibraryKind::Dylib) { |
| dep_rustc.arg("-Cprefer-dynamic"); |
| } |
| dep_rustc |
| } |