From d6cd338e3a9c0c7f33c8f0e65105dca6c1911bc5 Mon Sep 17 00:00:00 2001 From: Daniel Paoliello Date: Fri, 29 Jul 2022 10:26:06 -0700 Subject: [PATCH 1/2] Add documentation for raw-dylib and link_ordinal --- src/attributes.md | 3 ++ src/items/external-blocks.md | 59 +++++++++++++++++++++++++++++++++++- 2 files changed, 61 insertions(+), 1 deletion(-) diff --git a/src/attributes.md b/src/attributes.md index 857cd7d72..b7c1ef609 100644 --- a/src/attributes.md +++ b/src/attributes.md @@ -228,6 +228,8 @@ The following is an index of all built-in attributes. - [`link`] — Specifies a native library to link with an `extern` block. - [`link_name`] — Specifies the name of the symbol for functions or statics in an `extern` block. + - [`link_ordinal`] — Specifies the ordinal of the symbol for functions or + statics in an `extern` block. - [`no_link`] — Prevents linking an extern crate. - [`repr`] — Controls type layout. - [`crate_type`] — Specifies the type of crate (library, executable, etc.). @@ -297,6 +299,7 @@ The following is an index of all built-in attributes. [`ignore`]: attributes/testing.md#the-ignore-attribute [`inline`]: attributes/codegen.md#the-inline-attribute [`link_name`]: items/external-blocks.md#the-link_name-attribute +[`link_ordinal`]: items/external-blocks.md#the-link_ordinal-attribute [`link_section`]: abi.md#the-link_section-attribute [`link`]: items/external-blocks.md#the-link-attribute [`macro_export`]: macros-by-example.md#path-based-scope diff --git a/src/items/external-blocks.md b/src/items/external-blocks.md index e768a1502..e13ca5438 100644 --- a/src/items/external-blocks.md +++ b/src/items/external-blocks.md @@ -122,6 +122,9 @@ specifies the kind of library with the following possible values: - `static` — Indicates a static library. - `framework` — Indicates a macOS framework. This is only valid for macOS targets. +- `raw-dylib` - Indicates a dynamic library where the compiler will generate + an import library to link against (see [`dylib` versus `raw-dylib`] below + for details). This is only valid for Windows targets. The `name` key must be included if `kind` is specified. @@ -198,9 +201,26 @@ The default for this modifier is `-whole-archive`. More implementation details about this modifier can be found in [`whole-archive` documentation for rustc]. +#### `dylib` versus `raw-dylib` + +On Windows, linking against a dynamic library requires that an import library +is provided to the linker: this is a special static library that declares all +of the symbols exported by the dynamic library in such a way that the linker +knows that they have to be dynamically loaded at runtime. + +Specifying `kind = "dylib"` instructs the Rust compiler to link an import +library based on the `name` key, the linker will then use its normal library +resolution logic to find that import library. Alternatively, specifying +`kind = "raw-dylib"` instructs the compiler to generate an import library +during compilation and provide that to the linker instead. + +`raw-dylib` is only supported on Windows and not supported on x86 +(`target_arch="x86"`), see [58713]. Using it when targeting other platforms or +x86 on Windows will result in a compiler error. + ### The `link_name` attribute -The `link_name` attribute may be specified on declarations inside an `extern` +The *`link_name` attribute* may be specified on declarations inside an `extern` block to indicate the symbol to import for the given function or static. It uses the [_MetaNameValueStr_] syntax to specify the name of the symbol. @@ -211,6 +231,41 @@ extern { } ``` +Using this attribute with the `link_ordinal` attribute will result in a +compiler error. + +### The `link_ordinal` attribute + +The *`link_ordinal` attribute* can be applied on declarations inside an `extern` +block to indicate the numeric ordinal to use when generating the import library +to link against. An ordinal is a unique number per symbol exported by a dynamic +library on Windows and can be used when the library is being loaded to find +that symbol rather than having to look it up by name. + +
+ +Warning: `link_ordinal` should only be used in cases where the ordinal of the +symbol is known to be stable: if the ordinal of a symbol is not explicitly set +when its containing binary is built then one will be automatically assigned to +it, and that assigned ordinal may change between builds of the binary. + +
+ + +```rust,ignore +#[link(name = "exporter", kind = "raw-dylib")] +extern "stdcall" { + #[link_ordinal(15)] + fn imported_function_stdcall(i: i32); +} +``` + +This attribute is only used with the `raw-dylib` linking kind. +Using any other kind will result in a compiler error. + +Using this attribute with the `link_name` attribute will result in a +compiler error. + ### Attributes on function parameters Attributes on extern function parameters follow the same rules and @@ -233,3 +288,5 @@ restrictions as [regular function parameters]. [regular function parameters]: functions.md#attributes-on-function-parameters [`bundle` documentation for rustc]: ../../rustc/command-line-arguments.html#linking-modifiers-bundle [`whole-archive` documentation for rustc]: ../../rustc/command-line-arguments.html#linking-modifiers-whole-archive +[`dylib` versus `raw-dylib`]: #dylib-versus-raw-dylib +[58713]: https://github.com/rust-lang/rust/issues/58713 From 300ac4bdb40b91945a8e774f534a2902564d41ec Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Mon, 19 Sep 2022 16:18:44 -0700 Subject: [PATCH 2/2] Editorial changes for raw-dylib. --- src/items/external-blocks.md | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/items/external-blocks.md b/src/items/external-blocks.md index e13ca5438..c91e1d10c 100644 --- a/src/items/external-blocks.md +++ b/src/items/external-blocks.md @@ -122,7 +122,7 @@ specifies the kind of library with the following possible values: - `static` — Indicates a static library. - `framework` — Indicates a macOS framework. This is only valid for macOS targets. -- `raw-dylib` - Indicates a dynamic library where the compiler will generate +- `raw-dylib` — Indicates a dynamic library where the compiler will generate an import library to link against (see [`dylib` versus `raw-dylib`] below for details). This is only valid for Windows targets. @@ -209,13 +209,13 @@ of the symbols exported by the dynamic library in such a way that the linker knows that they have to be dynamically loaded at runtime. Specifying `kind = "dylib"` instructs the Rust compiler to link an import -library based on the `name` key, the linker will then use its normal library +library based on the `name` key. The linker will then use its normal library resolution logic to find that import library. Alternatively, specifying `kind = "raw-dylib"` instructs the compiler to generate an import library during compilation and provide that to the linker instead. -`raw-dylib` is only supported on Windows and not supported on x86 -(`target_arch="x86"`), see [58713]. Using it when targeting other platforms or +`raw-dylib` is only supported on Windows and not supported on 32-bit x86 +(`target_arch="x86"`). Using it when targeting other platforms or x86 on Windows will result in a compiler error. ### The `link_name` attribute @@ -289,4 +289,3 @@ restrictions as [regular function parameters]. [`bundle` documentation for rustc]: ../../rustc/command-line-arguments.html#linking-modifiers-bundle [`whole-archive` documentation for rustc]: ../../rustc/command-line-arguments.html#linking-modifiers-whole-archive [`dylib` versus `raw-dylib`]: #dylib-versus-raw-dylib -[58713]: https://github.com/rust-lang/rust/issues/58713