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
This commit is contained in:
bors 2020-01-25 07:49:40 +00:00
commit 80a65bcaf2
8 changed files with 66 additions and 24 deletions

View 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.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

View file

@ -0,0 +1,5 @@
#![crate_type = "dylib"]
pub fn bar() {
println!("hello!");
}

View 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;
}

View file

@ -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
}

View file

@ -1 +0,0 @@
#![crate_type = "dylib"]

View file

@ -1,10 +0,0 @@
// build-fail
// error-pattern: crate `cdylib_dep` required to be available in rlib format, but was not found
// aux-build:cdylib-dep.rs
// ignore-musl
// ignore-cloudabi
// ignore-emscripten
// ignore-sgx no dynamic libraries
#![crate_type = "cdylib"]
extern crate cdylib_dep;

View file

@ -1,4 +0,0 @@
error: crate `cdylib_dep` required to be available in rlib format, but was not found in this form
error: aborting due to previous error