mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-27 01:04:03 +00:00
Support --print native-static-libs
with rust dylibs
This commit is contained in:
parent
09e1fae118
commit
39ba9dadee
@ -544,10 +544,36 @@ fn link_staticlib<'a>(
|
|||||||
|
|
||||||
ab.build(out_filename);
|
ab.build(out_filename);
|
||||||
|
|
||||||
if !all_native_libs.is_empty() {
|
let crates = codegen_results.crate_info.used_crates.iter();
|
||||||
if sess.opts.prints.contains(&PrintRequest::NativeStaticLibs) {
|
|
||||||
print_native_static_libs(sess, &all_native_libs);
|
let fmts = codegen_results
|
||||||
|
.crate_info
|
||||||
|
.dependency_formats
|
||||||
|
.iter()
|
||||||
|
.find_map(|&(ty, ref list)| if ty == CrateType::Staticlib { Some(list) } else { None })
|
||||||
|
.expect("no dependency formats for staticlib");
|
||||||
|
|
||||||
|
let mut all_rust_dylibs = vec![];
|
||||||
|
for &cnum in crates {
|
||||||
|
match fmts.get(cnum.as_usize() - 1) {
|
||||||
|
Some(&Linkage::Dynamic) => {}
|
||||||
|
_ => continue,
|
||||||
}
|
}
|
||||||
|
let crate_name = codegen_results.crate_info.crate_name[&cnum];
|
||||||
|
let used_crate_source = &codegen_results.crate_info.used_crate_source[&cnum];
|
||||||
|
if let Some((path, _)) = &used_crate_source.dylib {
|
||||||
|
all_rust_dylibs.push(&**path);
|
||||||
|
} else {
|
||||||
|
if used_crate_source.rmeta.is_some() {
|
||||||
|
sess.emit_fatal(errors::LinkRlibError::OnlyRmetaFound { crate_name });
|
||||||
|
} else {
|
||||||
|
sess.emit_fatal(errors::LinkRlibError::NotFound { crate_name });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if sess.opts.prints.contains(&PrintRequest::NativeStaticLibs) {
|
||||||
|
print_native_static_libs(sess, &all_native_libs, &all_rust_dylibs);
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
@ -1291,8 +1317,12 @@ enum RlibFlavor {
|
|||||||
StaticlibBase,
|
StaticlibBase,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn print_native_static_libs(sess: &Session, all_native_libs: &[NativeLib]) {
|
fn print_native_static_libs(
|
||||||
let lib_args: Vec<_> = all_native_libs
|
sess: &Session,
|
||||||
|
all_native_libs: &[NativeLib],
|
||||||
|
all_rust_dylibs: &[&Path],
|
||||||
|
) {
|
||||||
|
let mut lib_args: Vec<_> = all_native_libs
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|l| relevant_lib(sess, l))
|
.filter(|l| relevant_lib(sess, l))
|
||||||
.filter_map(|lib| {
|
.filter_map(|lib| {
|
||||||
@ -1322,6 +1352,41 @@ fn print_native_static_libs(sess: &Session, all_native_libs: &[NativeLib]) {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
for path in all_rust_dylibs {
|
||||||
|
// FIXME deduplicate with add_dynamic_crate
|
||||||
|
|
||||||
|
// Just need to tell the linker about where the library lives and
|
||||||
|
// what its name is
|
||||||
|
let parent = path.parent();
|
||||||
|
if let Some(dir) = parent {
|
||||||
|
let dir = fix_windows_verbatim_for_gcc(dir);
|
||||||
|
if sess.target.is_like_msvc {
|
||||||
|
let mut arg = String::from("/LIBPATH:");
|
||||||
|
arg.push_str(&dir.display().to_string());
|
||||||
|
lib_args.push(arg);
|
||||||
|
} else {
|
||||||
|
lib_args.push("-L".to_owned());
|
||||||
|
lib_args.push(dir.display().to_string());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let stem = path.file_stem().unwrap().to_str().unwrap();
|
||||||
|
// Convert library file-stem into a cc -l argument.
|
||||||
|
let prefix = if stem.starts_with("lib") && !sess.target.is_like_windows { 3 } else { 0 };
|
||||||
|
let lib = &stem[prefix..];
|
||||||
|
let path = parent.unwrap_or_else(|| Path::new(""));
|
||||||
|
if sess.target.is_like_msvc {
|
||||||
|
// When producing a dll, the MSVC linker may not actually emit a
|
||||||
|
// `foo.lib` file if the dll doesn't actually export any symbols, so we
|
||||||
|
// check to see if the file is there and just omit linking to it if it's
|
||||||
|
// not present.
|
||||||
|
let name = format!("{}.dll.lib", lib);
|
||||||
|
if path.join(&name).exists() {
|
||||||
|
lib_args.push(name);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
lib_args.push(format!("-l{}", lib));
|
||||||
|
}
|
||||||
|
}
|
||||||
if !lib_args.is_empty() {
|
if !lib_args.is_empty() {
|
||||||
sess.emit_note(errors::StaticLibraryNativeArtifacts);
|
sess.emit_note(errors::StaticLibraryNativeArtifacts);
|
||||||
// Prefix for greppability
|
// Prefix for greppability
|
||||||
|
@ -1,27 +1,14 @@
|
|||||||
include ../tools.mk
|
include ../tools.mk
|
||||||
|
|
||||||
TARGET_SYSROOT := $(shell $(RUSTC) --print sysroot)/lib/rustlib/$(TARGET)/lib
|
all:
|
||||||
|
|
||||||
ifdef IS_MSVC
|
|
||||||
LIBSTD := $(wildcard $(TARGET_SYSROOT)/libstd-*.dll.lib)
|
|
||||||
else
|
|
||||||
LIBSTD := $(wildcard $(TARGET_SYSROOT)/$(call DYLIB_GLOB,std))
|
|
||||||
STD := $(basename $(patsubst lib%,%, $(notdir $(LIBSTD))))
|
|
||||||
endif
|
|
||||||
|
|
||||||
all: $(call RUN_BINFILE,foo)
|
|
||||||
$(call RUN,foo)
|
|
||||||
|
|
||||||
ifdef IS_MSVC
|
|
||||||
CLIBS := $(TMPDIR)/foo.lib $(TMPDIR)/bar.dll.lib $(LIBSTD)
|
|
||||||
$(call RUN_BINFILE,foo): $(call STATICLIB,foo)
|
|
||||||
$(CC) $(CFLAGS) foo.c $(CLIBS) $(call OUT_EXE,foo)
|
|
||||||
else
|
|
||||||
CLIBS := $(TMPDIR)/libfoo.a -lbar -l$(STD) -L $(TMPDIR) -L $(TARGET_SYSROOT)
|
|
||||||
$(call RUN_BINFILE,foo): $(call STATICLIB,foo)
|
|
||||||
$(CC) $(CFLAGS) foo.c $(CLIBS) -o $(call RUN_BINFILE,foo)
|
|
||||||
endif
|
|
||||||
|
|
||||||
$(call STATICLIB,foo):
|
|
||||||
$(RUSTC) -C prefer-dynamic bar.rs
|
$(RUSTC) -C prefer-dynamic bar.rs
|
||||||
$(RUSTC) foo.rs
|
$(RUSTC) foo.rs --crate-type staticlib --print native-static-libs 2>&1 | grep 'note: native-static-libs: ' | sed 's/note: native-static-libs: \(.*\)/\1/' > $(TMPDIR)/libs.txt
|
||||||
|
cat $(TMPDIR)/libs.txt
|
||||||
|
|
||||||
|
ifdef IS_MSVC
|
||||||
|
$(CC) $(CFLAGS) foo.c $(TMPDIR)/foo.lib $$(cat $(TMPDIR)/libs.txt) $(call OUT_EXE,foo)
|
||||||
|
else
|
||||||
|
$(CC) $(CFLAGS) foo.c -L $(TMPDIR) -lfoo $$(cat $(TMPDIR)/libs.txt) -o $(call RUN_BINFILE,foo)
|
||||||
|
endif
|
||||||
|
|
||||||
|
$(call RUN,foo)
|
||||||
|
Loading…
Reference in New Issue
Block a user