Skip to content

Commit 80a65bc

Browse files
committed
Auto merge of #68448 - maurer:dyn-cdylib, r=alexcrichton
rustc: Allow cdylibs to link against dylibs Previously, rustc mandated that cdylibs could only link against rlibs as dependencies (not dylibs). This commit disables that restriction and tests that it works in a simple case. I don't have a windows rustc dev environment, so I guessed at the MSVC test code, I'm hoping the CI can run that for me. Additionally, we might want to consider emitting (through cargo or rustc) some metadata to help C users of a cdylib figure out where all the dylibs they need are. I don't think that should be needed to land this change, as it will still be usable by homogeneous build systems without it. My new test was templated off the `tests/run-make-fulldeps/cdylib` test. It seemed more appropriate to have it as a separate test, since both foo.rs and bar.rs would need to be replicated to make that test cover both cases, but I can do that if it would be preferred. If I'm doing anything out of order/process, please let me know; this is only my second change to rustc and the prior one was trivial. r? alexcrichton
2 parents 8bf1758 + 72aaa3a commit 80a65bc

File tree

8 files changed

+66
-24
lines changed

8 files changed

+66
-24
lines changed

src/librustc_metadata/dependency_format.rs

+11-9
Original file line numberDiff line numberDiff line change
@@ -83,14 +83,17 @@ fn calculate_type(tcx: TyCtxt<'_>, ty: config::CrateType) -> DependencyList {
8383
}
8484

8585
let preferred_linkage = match ty {
86-
// cdylibs must have all static dependencies.
87-
config::CrateType::Cdylib => Linkage::Static,
88-
8986
// Generating a dylib without `-C prefer-dynamic` means that we're going
9087
// to try to eagerly statically link all dependencies. This is normally
9188
// done for end-product dylibs, not intermediate products.
92-
config::CrateType::Dylib if !sess.opts.cg.prefer_dynamic => Linkage::Static,
93-
config::CrateType::Dylib => Linkage::Dynamic,
89+
//
90+
// Treat cdylibs similarly. If `-C prefer-dynamic` is set, the caller may
91+
// be code-size conscious, but without it, it makes sense to statically
92+
// link a cdylib.
93+
config::CrateType::Dylib | config::CrateType::Cdylib if !sess.opts.cg.prefer_dynamic => {
94+
Linkage::Static
95+
}
96+
config::CrateType::Dylib | config::CrateType::Cdylib => Linkage::Dynamic,
9497

9598
// If the global prefer_dynamic switch is turned off, or the final
9699
// executable will be statically linked, prefer static crate linkage.
@@ -122,10 +125,9 @@ fn calculate_type(tcx: TyCtxt<'_>, ty: config::CrateType) -> DependencyList {
122125
return v;
123126
}
124127

125-
// Staticlibs, cdylibs, and static executables must have all static
126-
// dependencies. If any are not found, generate some nice pretty errors.
127-
if ty == config::CrateType::Cdylib
128-
|| ty == config::CrateType::Staticlib
128+
// Staticlibs and static executables must have all static dependencies.
129+
// If any are not found, generate some nice pretty errors.
130+
if ty == config::CrateType::Staticlib
129131
|| (ty == config::CrateType::Executable
130132
&& sess.crt_static()
131133
&& !sess.target.target.options.crt_static_allows_dylibs)
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.dll.lib $(TMPDIR)/bar.dll.lib $(LIBSTD)
17+
$(call RUN_BINFILE,foo): $(call DYLIB,foo)
18+
$(CC) $(CFLAGS) foo.c $(CLIBS) $(call OUT_EXE,foo)
19+
else
20+
CLIBS := -lfoo -lbar -l$(STD) -L $(TMPDIR) -L $(TARGET_SYSROOT)
21+
$(call RUN_BINFILE,foo): $(call DYLIB,foo)
22+
$(CC) $(CFLAGS) foo.c $(CLIBS) -o $(call RUN_BINFILE,foo)
23+
endif
24+
25+
$(call DYLIB,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 = "cdylib"]
2+
3+
extern crate bar;
4+
5+
#[no_mangle]
6+
pub extern fn foo() {
7+
bar::bar();
8+
}
9+
10+
#[no_mangle]
11+
pub extern fn bar(a: u32, b: u32) -> u32 {
12+
a + b
13+
}

src/test/ui/auxiliary/cdylib-dep.rs

-1
This file was deleted.

src/test/ui/cdylib-deps-must-be-static.rs

-10
This file was deleted.

src/test/ui/cdylib-deps-must-be-static.stderr

-4
This file was deleted.

0 commit comments

Comments
 (0)