From af388d8ab874fd7ad9a17b33cb55f86fdd547eb6 Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Wed, 18 Jun 2025 16:22:18 -0700 Subject: [PATCH 01/23] Split into two paragraphs --- src/items/external-blocks.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/items/external-blocks.md b/src/items/external-blocks.md index 6fdb70028f..e38b986b72 100644 --- a/src/items/external-blocks.md +++ b/src/items/external-blocks.md @@ -312,7 +312,9 @@ r[items.extern.attributes.link.modifiers.bundle.behavior] When building a rlib or staticlib `+bundle` means that the native static library will be packed into the rlib or staticlib archive, and then retrieved from there during linking of the final binary. r[items.extern.attributes.link.modifiers.bundle.behavior-negative] -When building a rlib `-bundle` means that the native static library is registered as a dependency of that rlib "by name", and object files from it are included only during linking of the final binary, the file search by that name is also performed during final linking. When building a staticlib `-bundle` means that the native static library is simply not included into the archive and some higher level build system will need to add it later during linking of the final binary. +When building a rlib `-bundle` means that the native static library is registered as a dependency of that rlib "by name", and object files from it are included only during linking of the final binary, the file search by that name is also performed during final linking. + +When building a staticlib `-bundle` means that the native static library is simply not included into the archive and some higher level build system will need to add it later during linking of the final binary. r[items.extern.attributes.link.modifiers.bundle.no-effect] This modifier has no effect when building other targets like executables or dynamic libraries. From 80afa43cf63b0eb502755a29e4d578af3873f0c4 Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Wed, 18 Jun 2025 16:26:37 -0700 Subject: [PATCH 02/23] Link "attribute" --- src/items/external-blocks.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/items/external-blocks.md b/src/items/external-blocks.md index e38b986b72..a3eb9335b3 100644 --- a/src/items/external-blocks.md +++ b/src/items/external-blocks.md @@ -249,7 +249,7 @@ r[items.extern.attributes.link] ### The `link` attribute r[items.extern.attributes.link.intro] -The *`link` attribute* specifies the name of a native library that the compiler should link with for the items within an `extern` block. +The *`link` [attribute][attributes]* specifies the name of a native library that the compiler should link with for the items within an `extern` block. r[items.extern.attributes.link.syntax] It uses the [MetaListNameValueStr] syntax to specify its inputs. The `name` key is the name of the native library to link. The `kind` key is an optional value which specifies the kind of library with the following possible values: From c91837d6e49bc974b7248cd0b3b6b93db03e4e6e Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Wed, 18 Jun 2025 16:27:29 -0700 Subject: [PATCH 03/23] Move link example to the intro --- src/items/external-blocks.md | 37 ++++++++++++++++++------------------ 1 file changed, 19 insertions(+), 18 deletions(-) diff --git a/src/items/external-blocks.md b/src/items/external-blocks.md index a3eb9335b3..ec4cee19d6 100644 --- a/src/items/external-blocks.md +++ b/src/items/external-blocks.md @@ -251,6 +251,25 @@ r[items.extern.attributes.link] r[items.extern.attributes.link.intro] The *`link` [attribute][attributes]* specifies the name of a native library that the compiler should link with for the items within an `extern` block. +> [!EXAMPLE] +> +> ```rust,ignore +> #[link(name = "crypto")] +> unsafe extern { +> // … +> } +> +> #[link(name = "CoreFoundation", kind = "framework")] +> unsafe extern { +> // … +> } +> +> #[link(wasm_import_module = "foo")] +> unsafe extern { +> // … +> } +> ``` + r[items.extern.attributes.link.syntax] It uses the [MetaListNameValueStr] syntax to specify its inputs. The `name` key is the name of the native library to link. The `kind` key is an optional value which specifies the kind of library with the following possible values: @@ -281,24 +300,6 @@ Specifying multiple `modifiers` arguments in a single `link` attribute, or multi r[items.extern.attributes.link.wasm_import_module] The `wasm_import_module` key may be used to specify the [WebAssembly module] name for the items within an `extern` block when importing symbols from the host environment. The default module name is `env` if `wasm_import_module` is not specified. - -```rust,ignore -#[link(name = "crypto")] -unsafe extern { - // … -} - -#[link(name = "CoreFoundation", kind = "framework")] -unsafe extern { - // … -} - -#[link(wasm_import_module = "foo")] -unsafe extern { - // … -} -``` - r[items.extern.attributes.link.empty-block] It is valid to add the `link` attribute on an empty extern block. You can use this to satisfy the linking requirements of extern blocks elsewhere in your code (including upstream crates) instead of adding the attribute to each extern block. From 9a25f8d3382bba098d83fa8ece50bfb73b584422 Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Wed, 18 Jun 2025 16:51:39 -0700 Subject: [PATCH 04/23] Fix wrong heading depth for `verbatim` --- src/items/external-blocks.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/items/external-blocks.md b/src/items/external-blocks.md index ec4cee19d6..b8ead6e4f6 100644 --- a/src/items/external-blocks.md +++ b/src/items/external-blocks.md @@ -340,7 +340,7 @@ The default for this modifier is `-whole-archive`. More implementation details about this modifier can be found in [`whole-archive` documentation for rustc]. r[items.extern.attributes.link.modifiers.verbatim] -### Linking modifiers: `verbatim` +#### Linking modifiers: `verbatim` r[items.extern.attributes.link.modifiers.verbatim.allowed-kinds] This modifier is compatible with all linking kinds. From 53b2459ec3fe46cc636ac10993f8b521a5452633 Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Wed, 18 Jun 2025 16:52:51 -0700 Subject: [PATCH 05/23] Rework items.extern.attributes.link.syntax The old text was missing some keys. This adds the keys as a list, with some more explicit organization. --- src/items/external-blocks.md | 28 ++++++++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/src/items/external-blocks.md b/src/items/external-blocks.md index b8ead6e4f6..547c4f8f37 100644 --- a/src/items/external-blocks.md +++ b/src/items/external-blocks.md @@ -271,7 +271,24 @@ The *`link` [attribute][attributes]* specifies the name of a native library that > ``` r[items.extern.attributes.link.syntax] -It uses the [MetaListNameValueStr] syntax to specify its inputs. The `name` key is the name of the native library to link. The `kind` key is an optional value which specifies the kind of library with the following possible values: +The `link` attribute uses the [MetaListNameValueStr] syntax to specify its inputs. It accepts the following keys: + +- [`name`][items.extern.attributes.link.name] --- the name of the native library to link. +- [`kind`][items.extern.attributes.link.kinds] --- the kind of library. +- [`modifiers`][items.extern.attributes.link.modifiers] --- modifiers that change the behavior of how the library is linked. +- [`wasm_import_module`][items.extern.attributes.link.wasm_import_module] --- specifies the WebAssembly module name. +- [`import_name_type`][items.extern.attributes.link.import_name_type] --- on x86 Windows, this changes how functions are named. + +r[items.extern.attributes.link.name] +#### The `name` key + + + +r[items.extern.attributes.link.name.requirement] +The `name` key must be included unless `wasm_import_module` is used. + +r[items.extern.attributes.link.kinds] +#### The `kind` key r[items.extern.attributes.link.dylib] - `dylib` --- Indicates a dynamic library. This is the default if `kind` is not specified. @@ -285,10 +302,10 @@ r[items.extern.attributes.link.framework] r[items.extern.attributes.link.raw-dylib] - `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. -r[items.extern.attributes.link.name-requirement] -The `name` key must be included if `kind` is specified. - r[items.extern.attributes.link.modifiers] +#### The `modifiers` key + +r[items.extern.attributes.link.modifiers.intro] The optional `modifiers` argument is a way to specify linking modifiers for the library to link. r[items.extern.attributes.link.modifiers.syntax] @@ -298,6 +315,9 @@ r[items.extern.attributes.link.modifiers.multiple] Specifying multiple `modifiers` arguments in a single `link` attribute, or multiple identical modifiers in the same `modifiers` argument is not currently supported. Example: `#[link(name = "mylib", kind = "static", modifiers = "+whole-archive")]`. r[items.extern.attributes.link.wasm_import_module] +#### The `wasm_import_module` key + +r[items.extern.attributes.link.wasm_import_module.behavior] The `wasm_import_module` key may be used to specify the [WebAssembly module] name for the items within an `extern` block when importing symbols from the host environment. The default module name is `env` if `wasm_import_module` is not specified. r[items.extern.attributes.link.empty-block] From c837e696f8c379ffb888f9f18dfd59ae05b4ed72 Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Wed, 18 Jun 2025 16:53:19 -0700 Subject: [PATCH 06/23] Move items.extern.attributes.link.empty-block It was in the wrong section. --- src/items/external-blocks.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/items/external-blocks.md b/src/items/external-blocks.md index 547c4f8f37..a58bbc8260 100644 --- a/src/items/external-blocks.md +++ b/src/items/external-blocks.md @@ -279,6 +279,9 @@ The `link` attribute uses the [MetaListNameValueStr] syntax to specify its input - [`wasm_import_module`][items.extern.attributes.link.wasm_import_module] --- specifies the WebAssembly module name. - [`import_name_type`][items.extern.attributes.link.import_name_type] --- on x86 Windows, this changes how functions are named. +r[items.extern.attributes.link.empty-block] +It is valid to add the `link` attribute on an empty extern block. You can use this to satisfy the linking requirements of extern blocks elsewhere in your code (including upstream crates) instead of adding the attribute to each extern block. + r[items.extern.attributes.link.name] #### The `name` key @@ -320,9 +323,6 @@ r[items.extern.attributes.link.wasm_import_module] r[items.extern.attributes.link.wasm_import_module.behavior] The `wasm_import_module` key may be used to specify the [WebAssembly module] name for the items within an `extern` block when importing symbols from the host environment. The default module name is `env` if `wasm_import_module` is not specified. -r[items.extern.attributes.link.empty-block] -It is valid to add the `link` attribute on an empty extern block. You can use this to satisfy the linking requirements of extern blocks elsewhere in your code (including upstream crates) instead of adding the attribute to each extern block. - r[items.extern.attributes.link.modifiers.bundle] #### Linking modifiers: `bundle` From e10cb0c4810c749df5b1141300869bb9535a83d0 Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Wed, 18 Jun 2025 17:40:30 -0700 Subject: [PATCH 07/23] Add ABI to the example There is a warning without it. --- src/items/external-blocks.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/items/external-blocks.md b/src/items/external-blocks.md index a58bbc8260..45c2a87beb 100644 --- a/src/items/external-blocks.md +++ b/src/items/external-blocks.md @@ -255,17 +255,17 @@ The *`link` [attribute][attributes]* specifies the name of a native library that > > ```rust,ignore > #[link(name = "crypto")] -> unsafe extern { +> unsafe extern "C" { > // … > } > > #[link(name = "CoreFoundation", kind = "framework")] -> unsafe extern { +> unsafe extern "C" { > // … > } > > #[link(wasm_import_module = "foo")] -> unsafe extern { +> unsafe extern "C" { > // … > } > ``` From 999548d8a3b9181bd0018d8b2600f91fce0fc56a Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Wed, 18 Jun 2025 17:40:47 -0700 Subject: [PATCH 08/23] Clarify that link names cannot be repeated --- src/items/external-blocks.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/items/external-blocks.md b/src/items/external-blocks.md index 45c2a87beb..c88e7b64be 100644 --- a/src/items/external-blocks.md +++ b/src/items/external-blocks.md @@ -279,6 +279,8 @@ The `link` attribute uses the [MetaListNameValueStr] syntax to specify its input - [`wasm_import_module`][items.extern.attributes.link.wasm_import_module] --- specifies the WebAssembly module name. - [`import_name_type`][items.extern.attributes.link.import_name_type] --- on x86 Windows, this changes how functions are named. +None of the keys may be specified more than once. + r[items.extern.attributes.link.empty-block] It is valid to add the `link` attribute on an empty extern block. You can use this to satisfy the linking requirements of extern blocks elsewhere in your code (including upstream crates) instead of adding the attribute to each extern block. From d108beb525199217a02072799d021e7bb10ddda6 Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Wed, 18 Jun 2025 17:41:08 -0700 Subject: [PATCH 09/23] Add link allowed-positions and duplicates --- src/items/external-blocks.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/items/external-blocks.md b/src/items/external-blocks.md index c88e7b64be..59a42c2e03 100644 --- a/src/items/external-blocks.md +++ b/src/items/external-blocks.md @@ -281,6 +281,15 @@ The `link` attribute uses the [MetaListNameValueStr] syntax to specify its input None of the keys may be specified more than once. +r[items.extern.attributes.link.allowed-positions] +The `link` attribute may be applied to [`extern` blocks]. + +> [!NOTE] +> `rustc` currently warns in other positions, but this may be rejected in the future. + +r[items.extern.attributes.link.duplicates] +The `link` attribute may be specified multiple times, and the corresponding linking instructions for each attribute will be passed to the linker. + r[items.extern.attributes.link.empty-block] It is valid to add the `link` attribute on an empty extern block. You can use this to satisfy the linking requirements of extern blocks elsewhere in your code (including upstream crates) instead of adding the attribute to each extern block. @@ -492,3 +501,4 @@ Attributes on extern function parameters follow the same rules and restrictions [value namespace]: ../names/namespaces.md [win32 api]: https://learn.microsoft.com/en-us/windows/win32/api/ [`link_ordinal`]: items.extern.attributes.link_ordinal +[`extern` blocks]: external-blocks.md From cb4b70c29e4600d433361907047c6c71ae3d2134 Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Wed, 18 Jun 2025 17:42:10 -0700 Subject: [PATCH 10/23] Add link `name` intro --- src/items/external-blocks.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/items/external-blocks.md b/src/items/external-blocks.md index 59a42c2e03..f243cb6eda 100644 --- a/src/items/external-blocks.md +++ b/src/items/external-blocks.md @@ -296,7 +296,12 @@ It is valid to add the `link` attribute on an empty extern block. You can use th r[items.extern.attributes.link.name] #### The `name` key - +r[items.extern.attributes.link.name.intro] +The `name` key specifies the name of the library to link. + + + + r[items.extern.attributes.link.name.requirement] The `name` key must be included unless `wasm_import_module` is used. From 3eab03d46b614faf9b52c3ecfcb3e8ade2eff8fd Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Wed, 18 Jun 2025 17:43:14 -0700 Subject: [PATCH 11/23] Rework link kind to not use a list, and add examples --- src/items/external-blocks.md | 51 +++++++++++++++++++++++++++++------- 1 file changed, 41 insertions(+), 10 deletions(-) diff --git a/src/items/external-blocks.md b/src/items/external-blocks.md index f243cb6eda..313afa5ede 100644 --- a/src/items/external-blocks.md +++ b/src/items/external-blocks.md @@ -274,7 +274,7 @@ r[items.extern.attributes.link.syntax] The `link` attribute uses the [MetaListNameValueStr] syntax to specify its inputs. It accepts the following keys: - [`name`][items.extern.attributes.link.name] --- the name of the native library to link. -- [`kind`][items.extern.attributes.link.kinds] --- the kind of library. +- [`kind`][items.extern.attributes.link.kind] --- the kind of library. - [`modifiers`][items.extern.attributes.link.modifiers] --- modifiers that change the behavior of how the library is linked. - [`wasm_import_module`][items.extern.attributes.link.wasm_import_module] --- specifies the WebAssembly module name. - [`import_name_type`][items.extern.attributes.link.import_name_type] --- on x86 Windows, this changes how functions are named. @@ -306,20 +306,51 @@ The `name` key specifies the name of the library to link. r[items.extern.attributes.link.name.requirement] The `name` key must be included unless `wasm_import_module` is used. -r[items.extern.attributes.link.kinds] +r[items.extern.attributes.link.kind] #### The `kind` key -r[items.extern.attributes.link.dylib] -- `dylib` --- Indicates a dynamic library. This is the default if `kind` is not specified. +r[items.extern.attributes.link.kind.intro] +The `kind` key specifies the kind of the library. -r[items.extern.attributes.link.static] -- `static` --- Indicates a static library. +r[items.extern.attributes.link.kind.dylib] +The `dylib` kind indicates a dynamic library. This is the default if `kind` is not specified. -r[items.extern.attributes.link.framework] -- `framework` --- Indicates a macOS framework. This is only valid for macOS targets. +> [!EXAMPLE] +> +> ```rust,ignore +> #[link(name = "example", kind = "dylib")] +> unsafe extern "C" {} +> ``` + +r[items.extern.attributes.link.kind.static] +The `static` kind indicates a static library. + +> [!EXAMPLE] +> +> ```rust,ignore +> #[link(name = "example", kind = "static")] +> unsafe extern "C" {} +> ``` + +r[items.extern.attributes.link.kind.framework] +The `framework` kind indicates a macOS framework. This is only valid for macOS targets. -r[items.extern.attributes.link.raw-dylib] -- `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. +> [!EXAMPLE] +> +> ```rust,ignore +> #[link(name = "CoreFoundation", kind = "framework")] +> unsafe extern "C" {} +> ``` + +r[items.extern.attributes.link.kind.raw-dylib] +The `raw-dylib` kind 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. + +> [!EXAMPLE] +> +> ```rust,ignore +> #[link(name = "example", kind = "raw-dylib")] +> unsafe extern "C" {} +> ``` r[items.extern.attributes.link.modifiers] #### The `modifiers` key From fcc078dec575c3e07eb80db52cd611e37defed98 Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Wed, 18 Jun 2025 17:44:21 -0700 Subject: [PATCH 12/23] Move dylib vs raw-dylib into a note block This doesn't look like behavioral rules, but more of an explanation. Also move it to the `raw-dylib` section, since it seems mostly relevant there. --- src/items/external-blocks.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/items/external-blocks.md b/src/items/external-blocks.md index 313afa5ede..9d944128d6 100644 --- a/src/items/external-blocks.md +++ b/src/items/external-blocks.md @@ -352,6 +352,13 @@ The `raw-dylib` kind indicates a dynamic library where the compiler will generat > unsafe extern "C" {} > ``` +> [!NOTE] +> ##### `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. + r[items.extern.attributes.link.modifiers] #### The `modifiers` key @@ -423,14 +430,7 @@ The default for this modifier is `-verbatim`. More implementation details about this modifier can be found in [`verbatim` documentation for rustc]. -r[items.extern.attributes.link.kind-raw-dylib] -#### `dylib` versus `raw-dylib` - -r[items.extern.attributes.link.kind-raw-dylib.intro] -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. -r[items.extern.attributes.link.kind-raw-dylib.import] -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. r[items.extern.attributes.link.kind-raw-dylib.platform-specific] `raw-dylib` is only supported on Windows. Using it when targeting other platforms will result in a compiler error. From fb4ddc6913884c7fe5c6fc67f0705a66c3d0b4b0 Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Wed, 18 Jun 2025 17:44:41 -0700 Subject: [PATCH 13/23] Delete raw-dylib platform-specific This is already specified in the raw-dylib section. --- src/items/external-blocks.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/items/external-blocks.md b/src/items/external-blocks.md index 9d944128d6..3cac30cb1e 100644 --- a/src/items/external-blocks.md +++ b/src/items/external-blocks.md @@ -432,8 +432,6 @@ More implementation details about this modifier can be found in [`verbatim` docu -r[items.extern.attributes.link.kind-raw-dylib.platform-specific] -`raw-dylib` is only supported on Windows. Using it when targeting other platforms will result in a compiler error. r[items.extern.attributes.link.import_name_type] #### The `import_name_type` key From 4bdd6957038153ce8e8c9a5d9930babd26a56c23 Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Wed, 18 Jun 2025 17:47:36 -0700 Subject: [PATCH 14/23] Small tweaks to link modifiers Add an example, and slight rewording. --- src/items/external-blocks.md | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/items/external-blocks.md b/src/items/external-blocks.md index 3cac30cb1e..509df77f5c 100644 --- a/src/items/external-blocks.md +++ b/src/items/external-blocks.md @@ -365,11 +365,21 @@ r[items.extern.attributes.link.modifiers] r[items.extern.attributes.link.modifiers.intro] The optional `modifiers` argument is a way to specify linking modifiers for the library to link. +> [!EXAMPLE] +> +> ```rust,ignore +> #[link(name = "mylib", kind = "static", modifiers = "+whole-archive")] +> unsafe extern "C" {} +> ``` + r[items.extern.attributes.link.modifiers.syntax] Modifiers are specified as a comma-delimited string with each modifier prefixed with either a `+` or `-` to indicate that the modifier is enabled or disabled, respectively. -r[items.extern.attributes.link.modifiers.multiple] -Specifying multiple `modifiers` arguments in a single `link` attribute, or multiple identical modifiers in the same `modifiers` argument is not currently supported. Example: `#[link(name = "mylib", kind = "static", modifiers = "+whole-archive")]`. +r[items.extern.attributes.link.modifiers.once] +The `modifiers` argument may only be specified once. + +r[items.extern.attributes.link.modifiers.duplicates] +Duplicate modifiers are not allowed within a `modifiers` argument. r[items.extern.attributes.link.wasm_import_module] #### The `wasm_import_module` key From 8ff8b78ba3ba0d30f3236727b1ed75b6eb6bc8bf Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Wed, 18 Jun 2025 17:50:15 -0700 Subject: [PATCH 15/23] Move wasm_import_module and add example It was in the middle of the modifiers section. --- src/items/external-blocks.md | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/items/external-blocks.md b/src/items/external-blocks.md index 509df77f5c..cdac24b305 100644 --- a/src/items/external-blocks.md +++ b/src/items/external-blocks.md @@ -381,12 +381,6 @@ The `modifiers` argument may only be specified once. r[items.extern.attributes.link.modifiers.duplicates] Duplicate modifiers are not allowed within a `modifiers` argument. -r[items.extern.attributes.link.wasm_import_module] -#### The `wasm_import_module` key - -r[items.extern.attributes.link.wasm_import_module.behavior] -The `wasm_import_module` key may be used to specify the [WebAssembly module] name for the items within an `extern` block when importing symbols from the host environment. The default module name is `env` if `wasm_import_module` is not specified. - r[items.extern.attributes.link.modifiers.bundle] #### Linking modifiers: `bundle` @@ -440,8 +434,18 @@ The default for this modifier is `-verbatim`. More implementation details about this modifier can be found in [`verbatim` documentation for rustc]. +r[items.extern.attributes.link.wasm_import_module] +#### The `wasm_import_module` key +r[items.extern.attributes.link.wasm_import_module.behavior] +The `wasm_import_module` key may be used to specify the [WebAssembly module] name for the items within an `extern` block when importing symbols from the host environment. The default module name is `env` if `wasm_import_module` is not specified. +> [!EXAMPLE] +> +> ```rust,ignore +> #[link(wasm_import_module = "foo")] +> unsafe extern "C" {} +> ``` r[items.extern.attributes.link.import_name_type] #### The `import_name_type` key From 717a8fbd6294dab1d87d5158f63a2edc218c5e13 Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Wed, 18 Jun 2025 18:00:14 -0700 Subject: [PATCH 16/23] Add more link examples --- src/items/external-blocks.md | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/src/items/external-blocks.md b/src/items/external-blocks.md index cdac24b305..d46c9423c5 100644 --- a/src/items/external-blocks.md +++ b/src/items/external-blocks.md @@ -384,6 +384,13 @@ Duplicate modifiers are not allowed within a `modifiers` argument. r[items.extern.attributes.link.modifiers.bundle] #### Linking modifiers: `bundle` +> [!EXAMPLE] +> +> ```rust,ignore +> #[link(name = "mylib", kind = "static", modifiers = "+bundle")] +> unsafe extern "C" {} +> ``` + r[items.extern.attributes.link.modifiers.bundle.allowed-kinds] This modifier is only compatible with the `static` linking kind. Using any other kind will result in a compiler error. @@ -406,6 +413,13 @@ More implementation details about this modifier can be found in [`bundle` docume r[items.extern.attributes.link.modifiers.whole-archive] #### Linking modifiers: `whole-archive` +> [!EXAMPLE] +> +> ```rust,ignore +> #[link(name = "mylib", kind = "static", modifiers = "+whole-archive")] +> unsafe extern "C" {} +> ``` + r[items.extern.attributes.link.modifiers.whole-archive.allowed-kinds] This modifier is only compatible with the `static` linking kind. Using any other kind will result in a compiler error. @@ -420,6 +434,13 @@ More implementation details about this modifier can be found in [`whole-archive` r[items.extern.attributes.link.modifiers.verbatim] #### Linking modifiers: `verbatim` +> [!EXAMPLE] +> +> ```rust,ignore +> #[link(name = "mylib", kind = "static", modifiers = "+verbatim")] +> unsafe extern "C" {} +> ``` + r[items.extern.attributes.link.modifiers.verbatim.allowed-kinds] This modifier is compatible with all linking kinds. @@ -450,6 +471,13 @@ The `wasm_import_module` key may be used to specify the [WebAssembly module] nam r[items.extern.attributes.link.import_name_type] #### The `import_name_type` key +> [!EXAMPLE] +> +> ```rust,ignore +> #[link(name = "mylib", kind = "raw-dylib", import_name_type = "undecorated")] +> unsafe extern "C" {} +> ``` + r[items.extern.attributes.link.import_name_type.intro] On x86 Windows, names of functions are "decorated" (i.e., have a specific prefix and/or suffix added) to indicate their calling convention. For example, a `stdcall` calling convention function with the name `fn1` that has no arguments would be decorated as `_fn1@0`. However, the [PE Format] does also permit names to have no prefix or be undecorated. Additionally, the MSVC and GNU toolchains use different decorations for the same calling conventions which means, by default, some Win32 functions cannot be called using the `raw-dylib` link kind via the GNU toolchain. From aa79fc0cfe74127f06450a59716152df3466e936 Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Mon, 30 Jun 2025 11:20:59 -0700 Subject: [PATCH 17/23] Tweak wording of `dylib` versus `raw-dylib` Dropping the use of "Rust compiler". --- src/items/external-blocks.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/items/external-blocks.md b/src/items/external-blocks.md index d46c9423c5..90755fbdb3 100644 --- a/src/items/external-blocks.md +++ b/src/items/external-blocks.md @@ -357,7 +357,7 @@ The `raw-dylib` kind indicates a dynamic library where the compiler will generat > > 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. +> Specifying `kind = "dylib"` links 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"` generates an import library during compilation and provide that to the linker instead. r[items.extern.attributes.link.modifiers] #### The `modifiers` key From dd6a5039c19baa1c3c5392767c21830f72b783ef Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Mon, 30 Jun 2025 11:32:19 -0700 Subject: [PATCH 18/23] Reword link allowed-kinds This just simplifies the wording, and links to the relevant section. --- src/items/external-blocks.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/items/external-blocks.md b/src/items/external-blocks.md index 90755fbdb3..edf561d06a 100644 --- a/src/items/external-blocks.md +++ b/src/items/external-blocks.md @@ -392,7 +392,7 @@ r[items.extern.attributes.link.modifiers.bundle] > ``` r[items.extern.attributes.link.modifiers.bundle.allowed-kinds] -This modifier is only compatible with the `static` linking kind. Using any other kind will result in a compiler error. +The `bundle` modifier may only be used with [`static` linking]. r[items.extern.attributes.link.modifiers.bundle.behavior] When building a rlib or staticlib `+bundle` means that the native static library will be packed into the rlib or staticlib archive, and then retrieved from there during linking of the final binary. @@ -421,7 +421,7 @@ r[items.extern.attributes.link.modifiers.whole-archive] > ``` r[items.extern.attributes.link.modifiers.whole-archive.allowed-kinds] -This modifier is only compatible with the `static` linking kind. Using any other kind will result in a compiler error. +The `whole-archive` modifier may only be used with [`static` linking]. r[items.extern.attributes.link.modifiers.whole-archive.behavior] `+whole-archive` means that the static library is linked as a whole archive without throwing any object files away. @@ -578,3 +578,4 @@ Attributes on extern function parameters follow the same rules and restrictions [win32 api]: https://learn.microsoft.com/en-us/windows/win32/api/ [`link_ordinal`]: items.extern.attributes.link_ordinal [`extern` blocks]: external-blocks.md +[`static` linking]: link.staticlib From 73fc8034edd7761567c3f505898abd1b6d894f38 Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Mon, 30 Jun 2025 11:32:39 -0700 Subject: [PATCH 19/23] Move implementation note into a note block --- src/items/external-blocks.md | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/items/external-blocks.md b/src/items/external-blocks.md index edf561d06a..76b9276c8a 100644 --- a/src/items/external-blocks.md +++ b/src/items/external-blocks.md @@ -408,7 +408,8 @@ This modifier has no effect when building other targets like executables or dyna r[items.extern.attributes.link.modifiers.bundle.default] The default for this modifier is `+bundle`. -More implementation details about this modifier can be found in [`bundle` documentation for rustc]. +> [!NOTE] +> More implementation details about this modifier can be found in [`bundle` documentation for rustc]. r[items.extern.attributes.link.modifiers.whole-archive] #### Linking modifiers: `whole-archive` @@ -429,7 +430,8 @@ r[items.extern.attributes.link.modifiers.whole-archive.behavior] r[items.extern.attributes.link.modifiers.whole-archive.default] The default for this modifier is `-whole-archive`. -More implementation details about this modifier can be found in [`whole-archive` documentation for rustc]. +> [!NOTE] +> More implementation details about this modifier can be found in [`whole-archive` documentation for rustc]. r[items.extern.attributes.link.modifiers.verbatim] #### Linking modifiers: `verbatim` @@ -453,7 +455,8 @@ r[items.extern.attributes.link.modifiers.verbatim.behavior-negative] r[items.extern.attributes.link.modifiers.verbatim.default] The default for this modifier is `-verbatim`. -More implementation details about this modifier can be found in [`verbatim` documentation for rustc]. +> [!NOTE] +> More implementation details about this modifier can be found in [`verbatim` documentation for rustc]. r[items.extern.attributes.link.wasm_import_module] #### The `wasm_import_module` key From 526ca8974a04885dcfa0a1c08dae6ec51a32b633 Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Mon, 30 Jun 2025 11:33:01 -0700 Subject: [PATCH 20/23] Add comma to introductory clause for clarity --- src/items/external-blocks.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/items/external-blocks.md b/src/items/external-blocks.md index 76b9276c8a..36ca56479e 100644 --- a/src/items/external-blocks.md +++ b/src/items/external-blocks.md @@ -395,12 +395,12 @@ r[items.extern.attributes.link.modifiers.bundle.allowed-kinds] The `bundle` modifier may only be used with [`static` linking]. r[items.extern.attributes.link.modifiers.bundle.behavior] -When building a rlib or staticlib `+bundle` means that the native static library will be packed into the rlib or staticlib archive, and then retrieved from there during linking of the final binary. +When building a rlib or staticlib, `+bundle` means that the native static library will be packed into the rlib or staticlib archive, and then retrieved from there during linking of the final binary. r[items.extern.attributes.link.modifiers.bundle.behavior-negative] -When building a rlib `-bundle` means that the native static library is registered as a dependency of that rlib "by name", and object files from it are included only during linking of the final binary, the file search by that name is also performed during final linking. +When building a rlib, `-bundle` means that the native static library is registered as a dependency of that rlib "by name", and object files from it are included only during linking of the final binary, the file search by that name is also performed during final linking. -When building a staticlib `-bundle` means that the native static library is simply not included into the archive and some higher level build system will need to add it later during linking of the final binary. +When building a staticlib, `-bundle` means that the native static library is simply not included into the archive and some higher level build system will need to add it later during linking of the final binary. r[items.extern.attributes.link.modifiers.bundle.no-effect] This modifier has no effect when building other targets like executables or dynamic libraries. From c4f3d5e33c6dad81fed3c77a6e220db2d0d63b04 Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Mon, 30 Jun 2025 11:33:13 -0700 Subject: [PATCH 21/23] Specify what "this" is --- src/items/external-blocks.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/items/external-blocks.md b/src/items/external-blocks.md index 36ca56479e..80e81c230b 100644 --- a/src/items/external-blocks.md +++ b/src/items/external-blocks.md @@ -403,7 +403,7 @@ When building a rlib, `-bundle` means that the native static library is register When building a staticlib, `-bundle` means that the native static library is simply not included into the archive and some higher level build system will need to add it later during linking of the final binary. r[items.extern.attributes.link.modifiers.bundle.no-effect] -This modifier has no effect when building other targets like executables or dynamic libraries. +The `bundle` modifier has no effect when building other targets like executables or dynamic libraries. r[items.extern.attributes.link.modifiers.bundle.default] The default for this modifier is `+bundle`. From 628bb3f4c37dfa9b9e1e54074efbf92fe7909145 Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Mon, 30 Jun 2025 11:33:30 -0700 Subject: [PATCH 22/23] Drop use of "rustc" --- src/items/external-blocks.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/items/external-blocks.md b/src/items/external-blocks.md index 80e81c230b..89efbaf079 100644 --- a/src/items/external-blocks.md +++ b/src/items/external-blocks.md @@ -447,10 +447,10 @@ r[items.extern.attributes.link.modifiers.verbatim.allowed-kinds] This modifier is compatible with all linking kinds. r[items.extern.attributes.link.modifiers.verbatim.behavior] -`+verbatim` means that rustc itself won't add any target-specified library prefixes or suffixes (like `lib` or `.a`) to the library name, and will try its best to ask for the same thing from the linker. +`+verbatim` means that the compiler won't add any target-specified library prefixes or suffixes (like `lib` or `.a`) to the library name, and will try its best to ask for the same thing from the linker. r[items.extern.attributes.link.modifiers.verbatim.behavior-negative] -`-verbatim` means that rustc will either add a target-specific prefix and suffix to the library name before passing it to linker, or won't prevent linker from implicitly adding it. +`-verbatim` means that the compiler will either add a target-specific prefix and suffix to the library name before passing it to linker, or won't prevent linker from implicitly adding it. r[items.extern.attributes.link.modifiers.verbatim.default] The default for this modifier is `-verbatim`. From 1289ee4247363d77a26fd4131fdab0da61cbe505 Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Tue, 7 Oct 2025 13:49:35 -0700 Subject: [PATCH 23/23] Update link for updated attribute template --- src/items/external-blocks.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/items/external-blocks.md b/src/items/external-blocks.md index 89efbaf079..bc586f1392 100644 --- a/src/items/external-blocks.md +++ b/src/items/external-blocks.md @@ -245,6 +245,7 @@ r[items.extern.attributes] r[items.extern.attributes.intro] The following [attributes] control the behavior of external blocks. + r[items.extern.attributes.link] ### The `link` attribute @@ -282,10 +283,10 @@ The `link` attribute uses the [MetaListNameValueStr] syntax to specify its input None of the keys may be specified more than once. r[items.extern.attributes.link.allowed-positions] -The `link` attribute may be applied to [`extern` blocks]. +The `link` attribute may only be applied to [`extern` blocks]. > [!NOTE] -> `rustc` currently warns in other positions, but this may be rejected in the future. +> `rustc` ignores use in other positions but lints against it. This may become an error in the future. r[items.extern.attributes.link.duplicates] The `link` attribute may be specified multiple times, and the corresponding linking instructions for each attribute will be passed to the linker.