diff options
| author | bors <bors@rust-lang.org> | 2021-06-06 03:59:17 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2021-06-06 03:59:17 +0000 |
| commit | 9a576175cc9a0aecb85d0764a4f66ee29e26e155 (patch) | |
| tree | a154cec601fdf15e22d503c1b62f8111782d1677 /src | |
| parent | f434217aab9abf583ebc928b97ab4116921137aa (diff) | |
| parent | 6aa45b71b11823a3140736536a93c5eac11ceecb (diff) | |
| download | rust-9a576175cc9a0aecb85d0764a4f66ee29e26e155.tar.gz rust-9a576175cc9a0aecb85d0764a4f66ee29e26e155.zip | |
Auto merge of #84171 - ricobbe:raw-dylib-via-llvm, r=petrochenkov
Partial support for raw-dylib linkage First cut of functionality for issue #58713: add support for `#[link(kind = "raw-dylib")]` on `extern` blocks in lib crates compiled to .rlib files. Does not yet support `#[link_name]` attributes on functions, or the `#[link_ordinal]` attribute, or `#[link(kind = "raw-dylib")]` on `extern` blocks in bin crates; I intend to publish subsequent PRs to fill those gaps. It's also not yet clear whether this works for functions in `extern "stdcall"` blocks; I also intend to investigate that shortly and make any necessary changes as a follow-on PR. This implementation calls out to an LLVM function to construct the actual `.idata` sections as temporary `.lib` files on disk and then links those into the generated .rlib.
Diffstat (limited to 'src')
18 files changed, 158 insertions, 1 deletions
diff --git a/src/test/run-make/raw-dylib/Makefile b/src/test/run-make/raw-dylib/Makefile new file mode 100644 index 00000000000..7ce46fd9331 --- /dev/null +++ b/src/test/run-make/raw-dylib/Makefile @@ -0,0 +1,21 @@ +# Test the behavior of #[link(.., kind = "raw-dylib")] on windows-msvc + +# only-windows +# only-msvc + +-include ../../run-make-fulldeps/tools.mk + +all: + $(call COMPILE_OBJ,"$(TMPDIR)"/extern_1.obj,extern_1.c) + $(call COMPILE_OBJ,"$(TMPDIR)"/extern_2.obj,extern_2.c) + $(CC) "$(TMPDIR)"/extern_1.obj -link -dll -out:"$(TMPDIR)"/extern_1.dll + $(CC) "$(TMPDIR)"/extern_2.obj -link -dll -out:"$(TMPDIR)"/extern_2.dll + $(RUSTC) --crate-type lib --crate-name raw_dylib_test lib.rs + $(RUSTC) --crate-type bin driver.rs -L "$(TMPDIR)" + "$(TMPDIR)"/driver > "$(TMPDIR)"/output.txt + +ifdef RUSTC_BLESS_TEST + cp "$(TMPDIR)"/output.txt output.txt +else + $(DIFF) output.txt "$(TMPDIR)"/output.txt +endif diff --git a/src/test/run-make/raw-dylib/driver.rs b/src/test/run-make/raw-dylib/driver.rs new file mode 100644 index 00000000000..4059ede11fc --- /dev/null +++ b/src/test/run-make/raw-dylib/driver.rs @@ -0,0 +1,5 @@ +extern crate raw_dylib_test; + +fn main() { + raw_dylib_test::library_function(); +} diff --git a/src/test/run-make/raw-dylib/extern_1.c b/src/test/run-make/raw-dylib/extern_1.c new file mode 100644 index 00000000000..72737c086eb --- /dev/null +++ b/src/test/run-make/raw-dylib/extern_1.c @@ -0,0 +1,16 @@ +#include <stdio.h> + +__declspec(dllexport) void extern_fn_1() { + printf("extern_fn_1\n"); + fflush(stdout); +} + +__declspec(dllexport) void extern_fn_2() { + printf("extern_fn_2; didn't get the rename\n"); + fflush(stdout); +} + +__declspec(dllexport) void extern_fn_with_long_name() { + printf("extern_fn_with_long_name; got the rename\n"); + fflush(stdout); +} diff --git a/src/test/run-make/raw-dylib/extern_2.c b/src/test/run-make/raw-dylib/extern_2.c new file mode 100644 index 00000000000..ae87fc3f821 --- /dev/null +++ b/src/test/run-make/raw-dylib/extern_2.c @@ -0,0 +1,6 @@ +#include <stdio.h> + +__declspec(dllexport) void extern_fn_3() { + printf("extern_fn_3\n"); + fflush(stdout); +} diff --git a/src/test/run-make/raw-dylib/lib.rs b/src/test/run-make/raw-dylib/lib.rs new file mode 100644 index 00000000000..d8e6301f38e --- /dev/null +++ b/src/test/run-make/raw-dylib/lib.rs @@ -0,0 +1,22 @@ +#![feature(raw_dylib, native_link_modifiers, native_link_modifiers_verbatim)] + +#[link(name = "extern_1.dll", kind = "raw-dylib", modifiers = "+verbatim")] +extern { + fn extern_fn_1(); +} + +#[link(name = "extern_2", kind = "raw-dylib")] +extern { + fn extern_fn_3(); +} + +pub fn library_function() { + #[link(name = "extern_1", kind = "raw-dylib")] + extern { fn extern_fn_2(); } + + unsafe { + extern_fn_1(); + extern_fn_2(); + extern_fn_3(); + } +} diff --git a/src/test/run-make/raw-dylib/output.txt b/src/test/run-make/raw-dylib/output.txt new file mode 100644 index 00000000000..7800cba1872 --- /dev/null +++ b/src/test/run-make/raw-dylib/output.txt @@ -0,0 +1,3 @@ +extern_fn_1 +extern_fn_2; didn't get the rename +extern_fn_3 diff --git a/src/test/ui/rfc-2627-raw-dylib/feature-gate-raw-dylib-2.rs b/src/test/ui/feature-gates/feature-gate-raw-dylib-2.rs index 518aa20dd68..518aa20dd68 100644 --- a/src/test/ui/rfc-2627-raw-dylib/feature-gate-raw-dylib-2.rs +++ b/src/test/ui/feature-gates/feature-gate-raw-dylib-2.rs diff --git a/src/test/ui/rfc-2627-raw-dylib/feature-gate-raw-dylib-2.stderr b/src/test/ui/feature-gates/feature-gate-raw-dylib-2.stderr index dbee5f316b0..dbee5f316b0 100644 --- a/src/test/ui/rfc-2627-raw-dylib/feature-gate-raw-dylib-2.stderr +++ b/src/test/ui/feature-gates/feature-gate-raw-dylib-2.stderr diff --git a/src/test/ui/feature-gates/feature-gate-raw-dylib-windows-gnu.rs b/src/test/ui/feature-gates/feature-gate-raw-dylib-windows-gnu.rs new file mode 100644 index 00000000000..33f9c539313 --- /dev/null +++ b/src/test/ui/feature-gates/feature-gate-raw-dylib-windows-gnu.rs @@ -0,0 +1,8 @@ +// gate-test-raw_dylib +// only-windows-gnu +#[link(name = "foo", kind = "raw-dylib")] +//~^ ERROR: kind="raw-dylib" is unstable +//~| WARNING: `#[link(...)]` with `kind = "raw-dylib"` not supported on windows-gnu +extern "C" {} + +fn main() {} diff --git a/src/test/ui/feature-gates/feature-gate-raw-dylib-windows-gnu.stderr b/src/test/ui/feature-gates/feature-gate-raw-dylib-windows-gnu.stderr new file mode 100644 index 00000000000..14dfadf4126 --- /dev/null +++ b/src/test/ui/feature-gates/feature-gate-raw-dylib-windows-gnu.stderr @@ -0,0 +1,18 @@ +warning: `#[link(...)]` with `kind = "raw-dylib"` not supported on windows-gnu + --> $DIR/feature-gate-raw-dylib-windows-gnu.rs:3:1 + | +LL | #[link(name = "foo", kind = "raw-dylib")] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0658]: kind="raw-dylib" is unstable + --> $DIR/feature-gate-raw-dylib-windows-gnu.rs:3:1 + | +LL | #[link(name = "foo", kind = "raw-dylib")] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #58713 <https://github.com/rust-lang/rust/issues/58713> for more information + = help: add `#![feature(raw_dylib)]` to the crate attributes to enable + +error: aborting due to previous error; 1 warning emitted + +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/rfc-2627-raw-dylib/feature-gate-raw-dylib.rs b/src/test/ui/feature-gates/feature-gate-raw-dylib-windows-msvc.rs index 29edd0f9ef9..49de24ea9ab 100644 --- a/src/test/ui/rfc-2627-raw-dylib/feature-gate-raw-dylib.rs +++ b/src/test/ui/feature-gates/feature-gate-raw-dylib-windows-msvc.rs @@ -1,3 +1,5 @@ +// gate-test-raw_dylib +// only-windows-msvc #[link(name = "foo", kind = "raw-dylib")] //~^ ERROR: kind="raw-dylib" is unstable extern "C" {} diff --git a/src/test/ui/rfc-2627-raw-dylib/feature-gate-raw-dylib.stderr b/src/test/ui/feature-gates/feature-gate-raw-dylib-windows-msvc.stderr index a670b6c6c2a..11988080812 100644 --- a/src/test/ui/rfc-2627-raw-dylib/feature-gate-raw-dylib.stderr +++ b/src/test/ui/feature-gates/feature-gate-raw-dylib-windows-msvc.stderr @@ -1,5 +1,5 @@ error[E0658]: kind="raw-dylib" is unstable - --> $DIR/feature-gate-raw-dylib.rs:1:1 + --> $DIR/feature-gate-raw-dylib-windows-msvc.rs:3:1 | LL | #[link(name = "foo", kind = "raw-dylib")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/src/test/ui/manual/manual-link-unsupported-kind.rs b/src/test/ui/manual/manual-link-unsupported-kind.rs new file mode 100644 index 00000000000..34814db593f --- /dev/null +++ b/src/test/ui/manual/manual-link-unsupported-kind.rs @@ -0,0 +1,5 @@ +// compile-flags:-l raw-dylib=foo +// error-pattern: unknown library kind `raw-dylib`, expected one of dylib, framework, or static + +fn main() { +} diff --git a/src/test/ui/manual/manual-link-unsupported-kind.stderr b/src/test/ui/manual/manual-link-unsupported-kind.stderr new file mode 100644 index 00000000000..acb4463cb04 --- /dev/null +++ b/src/test/ui/manual/manual-link-unsupported-kind.stderr @@ -0,0 +1,2 @@ +error: unknown library kind `raw-dylib`, expected one of dylib, framework, or static + diff --git a/src/test/ui/rfc-2627-raw-dylib/raw-dylib-msvc-only.rs b/src/test/ui/rfc-2627-raw-dylib/raw-dylib-msvc-only.rs new file mode 100644 index 00000000000..e9690f03f45 --- /dev/null +++ b/src/test/ui/rfc-2627-raw-dylib/raw-dylib-msvc-only.rs @@ -0,0 +1,8 @@ +// only-windows-gnu +// check-pass +// compile-flags: --crate-type lib +#![feature(raw_dylib)] +//~^ WARNING: the feature `raw_dylib` is incomplete +#[link(name = "foo", kind = "raw-dylib")] +//~^ WARNING: `#[link(...)]` with `kind = "raw-dylib"` not supported on windows-gnu +extern "C" {} diff --git a/src/test/ui/rfc-2627-raw-dylib/raw-dylib-msvc-only.stderr b/src/test/ui/rfc-2627-raw-dylib/raw-dylib-msvc-only.stderr new file mode 100644 index 00000000000..6e24112b3c3 --- /dev/null +++ b/src/test/ui/rfc-2627-raw-dylib/raw-dylib-msvc-only.stderr @@ -0,0 +1,17 @@ +warning: the feature `raw_dylib` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/raw-dylib-msvc-only.rs:4:12 + | +LL | #![feature(raw_dylib)] + | ^^^^^^^^^ + | + = note: `#[warn(incomplete_features)]` on by default + = note: see issue #58713 <https://github.com/rust-lang/rust/issues/58713> for more information + +warning: `#[link(...)]` with `kind = "raw-dylib"` not supported on windows-gnu + --> $DIR/raw-dylib-msvc-only.rs:6:1 + | +LL | #[link(name = "foo", kind = "raw-dylib")] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +warning: 2 warnings emitted + diff --git a/src/test/ui/rfc-2627-raw-dylib/raw-dylib-windows-only.rs b/src/test/ui/rfc-2627-raw-dylib/raw-dylib-windows-only.rs new file mode 100644 index 00000000000..7a5d7ac2934 --- /dev/null +++ b/src/test/ui/rfc-2627-raw-dylib/raw-dylib-windows-only.rs @@ -0,0 +1,7 @@ +// ignore-windows +// compile-flags: --crate-type lib +#![feature(raw_dylib)] +//~^ WARNING: the feature `raw_dylib` is incomplete +#[link(name = "foo", kind = "raw-dylib")] +//~^ ERROR: `#[link(...)]` with `kind = "raw-dylib"` only supported on Windows +extern "C" {} diff --git a/src/test/ui/rfc-2627-raw-dylib/raw-dylib-windows-only.stderr b/src/test/ui/rfc-2627-raw-dylib/raw-dylib-windows-only.stderr new file mode 100644 index 00000000000..f3879b63f91 --- /dev/null +++ b/src/test/ui/rfc-2627-raw-dylib/raw-dylib-windows-only.stderr @@ -0,0 +1,17 @@ +warning: the feature `raw_dylib` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/raw-dylib-windows-only.rs:3:12 + | +LL | #![feature(raw_dylib)] + | ^^^^^^^^^ + | + = note: `#[warn(incomplete_features)]` on by default + = note: see issue #58713 <https://github.com/rust-lang/rust/issues/58713> for more information + +error: `#[link(...)]` with `kind = "raw-dylib"` only supported on Windows + --> $DIR/raw-dylib-windows-only.rs:5:1 + | +LL | #[link(name = "foo", kind = "raw-dylib")] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to previous error; 1 warning emitted + |
