Skip to content

Commit 0f371ca

Browse files
committed
Support linking to rust dylibs from a staticlib
1 parent bcb610d commit 0f371ca

File tree

5 files changed

+65
-13
lines changed

5 files changed

+65
-13
lines changed

compiler/rustc_metadata/src/dependency_format.rs

+10-13
Original file line numberDiff line numberDiff line change
@@ -89,11 +89,12 @@ fn calculate_type(tcx: TyCtxt<'_>, ty: CrateType) -> DependencyList {
8989
// to try to eagerly statically link all dependencies. This is normally
9090
// done for end-product dylibs, not intermediate products.
9191
//
92-
// Treat cdylibs similarly. If `-C prefer-dynamic` is set, the caller may
93-
// be code-size conscious, but without it, it makes sense to statically
94-
// link a cdylib.
95-
CrateType::Dylib | CrateType::Cdylib if !sess.opts.cg.prefer_dynamic => Linkage::Static,
96-
CrateType::Dylib | CrateType::Cdylib => Linkage::Dynamic,
92+
// Treat cdylibs and staticlibs similarly. If `-C prefer-dynamic` is set,
93+
// the caller may be code-size conscious, but without it, it makes sense
94+
// to statically link a cdylib or staticlib.
95+
CrateType::Dylib | CrateType::Cdylib | CrateType::Staticlib => {
96+
if sess.opts.cg.prefer_dynamic { Linkage::Dynamic } else { Linkage::Static }
97+
}
9798

9899
// If the global prefer_dynamic switch is turned off, or the final
99100
// executable will be statically linked, prefer static crate linkage.
@@ -108,9 +109,6 @@ fn calculate_type(tcx: TyCtxt<'_>, ty: CrateType) -> DependencyList {
108109
// No linkage happens with rlibs, we just needed the metadata (which we
109110
// got long ago), so don't bother with anything.
110111
CrateType::Rlib => Linkage::NotLinked,
111-
112-
// staticlibs must have all static dependencies.
113-
CrateType::Staticlib => Linkage::Static,
114112
};
115113

116114
match preferred_linkage {
@@ -123,12 +121,11 @@ fn calculate_type(tcx: TyCtxt<'_>, ty: CrateType) -> DependencyList {
123121
return v;
124122
}
125123

126-
// Staticlibs and static executables must have all static dependencies.
124+
// Static executables must have all static dependencies.
127125
// If any are not found, generate some nice pretty errors.
128-
if ty == CrateType::Staticlib
129-
|| (ty == CrateType::Executable
130-
&& sess.crt_static(Some(ty))
131-
&& !sess.target.crt_static_allows_dylibs)
126+
if ty == CrateType::Executable
127+
&& sess.crt_static(Some(ty))
128+
&& !sess.target.crt_static_allows_dylibs
132129
{
133130
for &cnum in tcx.crates(()).iter() {
134131
if tcx.dep_kind(cnum).macros_only() {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
include ../tools.mk
2+
3+
TARGET_SYSROOT := $(shell $(RUSTC) --print sysroot)/lib/rustlib/$(TARGET)/lib
4+
5+
ifdef IS_MSVC
6+
LIBSTD := $(wildcard $(TARGET_SYSROOT)/libstd-*.dll.lib)
7+
else
8+
LIBSTD := $(wildcard $(TARGET_SYSROOT)/$(call DYLIB_GLOB,std))
9+
STD := $(basename $(patsubst lib%,%, $(notdir $(LIBSTD))))
10+
endif
11+
12+
all: $(call RUN_BINFILE,foo)
13+
$(call RUN,foo)
14+
15+
ifdef IS_MSVC
16+
CLIBS := $(TMPDIR)/foo.lib $(TMPDIR)/bar.dll.lib $(LIBSTD)
17+
$(call RUN_BINFILE,foo): $(call STATICLIB,foo)
18+
$(CC) $(CFLAGS) foo.c $(CLIBS) $(call OUT_EXE,foo)
19+
else
20+
CLIBS := $(TMPDIR)/libfoo.a -lbar -l$(STD) -L $(TMPDIR) -L $(TARGET_SYSROOT)
21+
$(call RUN_BINFILE,foo): $(call STATICLIB,foo)
22+
$(CC) $(CFLAGS) foo.c $(CLIBS) -o $(call RUN_BINFILE,foo)
23+
endif
24+
25+
$(call STATICLIB,foo):
26+
$(RUSTC) -C prefer-dynamic bar.rs
27+
$(RUSTC) foo.rs
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
#![crate_type = "dylib"]
2+
3+
pub fn bar() {
4+
println!("hello!");
5+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
#include <assert.h>
2+
3+
extern void foo();
4+
extern unsigned bar(unsigned a, unsigned b);
5+
6+
int main() {
7+
foo();
8+
assert(bar(1, 2) == 3);
9+
return 0;
10+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
#![crate_type = "staticlib"]
2+
3+
extern crate bar;
4+
5+
#[no_mangle]
6+
pub extern "C" fn foo() {
7+
bar::bar();
8+
}
9+
10+
#[no_mangle]
11+
pub extern "C" fn bar(a: u32, b: u32) -> u32 {
12+
a + b
13+
}

0 commit comments

Comments
 (0)