Support linking to rust dylibs from a staticlib
This commit is contained in:
parent
3a5c8e91f0
commit
09e1fae118
@ -89,11 +89,12 @@ fn calculate_type(tcx: TyCtxt<'_>, ty: CrateType) -> DependencyList {
|
|||||||
// to try to eagerly statically link all dependencies. This is normally
|
// to try to eagerly statically link all dependencies. This is normally
|
||||||
// done for end-product dylibs, not intermediate products.
|
// done for end-product dylibs, not intermediate products.
|
||||||
//
|
//
|
||||||
// Treat cdylibs similarly. If `-C prefer-dynamic` is set, the caller may
|
// Treat cdylibs and staticlibs similarly. If `-C prefer-dynamic` is set,
|
||||||
// be code-size conscious, but without it, it makes sense to statically
|
// the caller may be code-size conscious, but without it, it makes sense
|
||||||
// link a cdylib.
|
// to statically link a cdylib or staticlib.
|
||||||
CrateType::Dylib | CrateType::Cdylib if !sess.opts.cg.prefer_dynamic => Linkage::Static,
|
CrateType::Dylib | CrateType::Cdylib | CrateType::Staticlib => {
|
||||||
CrateType::Dylib | CrateType::Cdylib => Linkage::Dynamic,
|
if sess.opts.cg.prefer_dynamic { Linkage::Dynamic } else { Linkage::Static }
|
||||||
|
}
|
||||||
|
|
||||||
// If the global prefer_dynamic switch is turned off, or the final
|
// If the global prefer_dynamic switch is turned off, or the final
|
||||||
// executable will be statically linked, prefer static crate linkage.
|
// executable will be statically linked, prefer static crate linkage.
|
||||||
@ -108,9 +109,6 @@ fn calculate_type(tcx: TyCtxt<'_>, ty: CrateType) -> DependencyList {
|
|||||||
// No linkage happens with rlibs, we just needed the metadata (which we
|
// No linkage happens with rlibs, we just needed the metadata (which we
|
||||||
// got long ago), so don't bother with anything.
|
// got long ago), so don't bother with anything.
|
||||||
CrateType::Rlib => Linkage::NotLinked,
|
CrateType::Rlib => Linkage::NotLinked,
|
||||||
|
|
||||||
// staticlibs must have all static dependencies.
|
|
||||||
CrateType::Staticlib => Linkage::Static,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
match preferred_linkage {
|
match preferred_linkage {
|
||||||
@ -123,12 +121,11 @@ fn calculate_type(tcx: TyCtxt<'_>, ty: CrateType) -> DependencyList {
|
|||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Staticlibs and static executables must have all static dependencies.
|
// Static executables must have all static dependencies.
|
||||||
// If any are not found, generate some nice pretty errors.
|
// If any are not found, generate some nice pretty errors.
|
||||||
if ty == CrateType::Staticlib
|
if ty == CrateType::Executable
|
||||||
|| (ty == CrateType::Executable
|
&& sess.crt_static(Some(ty))
|
||||||
&& sess.crt_static(Some(ty))
|
&& !sess.target.crt_static_allows_dylibs
|
||||||
&& !sess.target.crt_static_allows_dylibs)
|
|
||||||
{
|
{
|
||||||
for &cnum in tcx.crates(()).iter() {
|
for &cnum in tcx.crates(()).iter() {
|
||||||
if tcx.dep_kind(cnum).macros_only() {
|
if tcx.dep_kind(cnum).macros_only() {
|
||||||
|
27
tests/run-make/staticlib-dylib-linkage/Makefile
Normal file
27
tests/run-make/staticlib-dylib-linkage/Makefile
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
include ../tools.mk
|
||||||
|
|
||||||
|
TARGET_SYSROOT := $(shell $(RUSTC) --print sysroot)/lib/rustlib/$(TARGET)/lib
|
||||||
|
|
||||||
|
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) foo.rs
|
5
tests/run-make/staticlib-dylib-linkage/bar.rs
Normal file
5
tests/run-make/staticlib-dylib-linkage/bar.rs
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
#![crate_type = "dylib"]
|
||||||
|
|
||||||
|
pub fn bar() {
|
||||||
|
println!("hello!");
|
||||||
|
}
|
10
tests/run-make/staticlib-dylib-linkage/foo.c
Normal file
10
tests/run-make/staticlib-dylib-linkage/foo.c
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
extern void foo();
|
||||||
|
extern unsigned bar(unsigned a, unsigned b);
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
foo();
|
||||||
|
assert(bar(1, 2) == 3);
|
||||||
|
return 0;
|
||||||
|
}
|
13
tests/run-make/staticlib-dylib-linkage/foo.rs
Normal file
13
tests/run-make/staticlib-dylib-linkage/foo.rs
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
#![crate_type = "staticlib"]
|
||||||
|
|
||||||
|
extern crate bar;
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub extern "C" fn foo() {
|
||||||
|
bar::bar();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub extern "C" fn bar(a: u32, b: u32) -> u32 {
|
||||||
|
a + b
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user