Skip to content

Commit

Permalink
rustc: Allow cdylibs to link against dylibs
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
maurer committed Jan 23, 2020
1 parent c0e02ad commit 72aaa3a
Show file tree
Hide file tree
Showing 8 changed files with 66 additions and 24 deletions.
20 changes: 11 additions & 9 deletions src/librustc_metadata/dependency_format.rs
Original file line number Diff line number Diff line change
Expand Up @@ -83,14 +83,17 @@ fn calculate_type(tcx: TyCtxt<'_>, ty: config::CrateType) -> DependencyList {
}

let preferred_linkage = match ty {
// cdylibs must have all static dependencies.
config::CrateType::Cdylib => Linkage::Static,

// Generating a dylib without `-C prefer-dynamic` means that we're going
// to try to eagerly statically link all dependencies. This is normally
// done for end-product dylibs, not intermediate products.
config::CrateType::Dylib if !sess.opts.cg.prefer_dynamic => Linkage::Static,
config::CrateType::Dylib => Linkage::Dynamic,
//
// Treat cdylibs similarly. If `-C prefer-dynamic` is set, the caller may
// be code-size conscious, but without it, it makes sense to statically
// link a cdylib.
config::CrateType::Dylib | config::CrateType::Cdylib if !sess.opts.cg.prefer_dynamic => {
Linkage::Static
}
config::CrateType::Dylib | config::CrateType::Cdylib => Linkage::Dynamic,

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

// Staticlibs, cdylibs, and static executables must have all static
// dependencies. If any are not found, generate some nice pretty errors.
if ty == config::CrateType::Cdylib
|| ty == config::CrateType::Staticlib
// Staticlibs and static executables must have all static dependencies.
// If any are not found, generate some nice pretty errors.
if ty == config::CrateType::Staticlib
|| (ty == config::CrateType::Executable
&& sess.crt_static()
&& !sess.target.target.options.crt_static_allows_dylibs)
Expand Down
27 changes: 27 additions & 0 deletions src/test/run-make-fulldeps/cdylib-dylib-linkage/Makefile
Original file line number Diff line number Diff line change
@@ -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.dll.lib $(TMPDIR)/bar.dll.lib $(LIBSTD)
$(call RUN_BINFILE,foo): $(call DYLIB,foo)
$(CC) $(CFLAGS) foo.c $(CLIBS) $(call OUT_EXE,foo)
else
CLIBS := -lfoo -lbar -l$(STD) -L $(TMPDIR) -L $(TARGET_SYSROOT)
$(call RUN_BINFILE,foo): $(call DYLIB,foo)
$(CC) $(CFLAGS) foo.c $(CLIBS) -o $(call RUN_BINFILE,foo)
endif

$(call DYLIB,foo):
$(RUSTC) -C prefer-dynamic bar.rs
$(RUSTC) foo.rs
5 changes: 5 additions & 0 deletions src/test/run-make-fulldeps/cdylib-dylib-linkage/bar.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#![crate_type = "dylib"]

pub fn bar() {
println!("hello!");
}
10 changes: 10 additions & 0 deletions src/test/run-make-fulldeps/cdylib-dylib-linkage/foo.c
Original file line number Diff line number Diff line change
@@ -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 changes: 13 additions & 0 deletions src/test/run-make-fulldeps/cdylib-dylib-linkage/foo.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#![crate_type = "cdylib"]

extern crate bar;

#[no_mangle]
pub extern fn foo() {
bar::bar();
}

#[no_mangle]
pub extern fn bar(a: u32, b: u32) -> u32 {
a + b
}
1 change: 0 additions & 1 deletion src/test/ui/auxiliary/cdylib-dep.rs

This file was deleted.

10 changes: 0 additions & 10 deletions src/test/ui/cdylib-deps-must-be-static.rs

This file was deleted.

4 changes: 0 additions & 4 deletions src/test/ui/cdylib-deps-must-be-static.stderr

This file was deleted.

0 comments on commit 72aaa3a

Please sign in to comment.