- Feature Name:
native_link_modifiers
- Start Date: 2020-06-12
- RFC PR: rust-lang/rfcs#2951
- Rust Issue: rust-lang/rust#81490
Summary
Provide an extensible mechanism#[link]
attributes (#[link(modifiers = "+foo,-bar")]
) and on command line (-l static:+foo,-bar=mylib
).
Motivation
Occasionally some tweaks to linking behavior
For example, some static
This RFC introduces modifier whole-archive
to address this.
In other cases we need to link to a library located at some specific
This RFC introduces modifier verbatim
to pass such libraries to the linker.
This RFC also reformulates the static-nobundle
linking kind as a modifier bundle
thus
The generic syntax
Guide-level explanation
This is an advanced feature not expected to be used commonly, see the reference-level explanation if you know that you need some of these modifiers.
Reference-level explanation
Existing syntax文法 of linking attributes and options
- Attributes:
#[link(name = "string", kind = "string", cfg(predicate))]
(some components構成要素are optional.) - Command line options:
-l kind=name:rename
(some components構成要素are optional).
Proposed extensions to the syntax文法
- Attributes:
#[link(/* same */, modifiers = "+foo,-bar")]
. - Command line options:
-l kind:+foo,-bar=name:rename
.
The modifiers are booleanname
.
+
means enable, -
means disable, multiple
The notation
If the :rename
component
Specific特定の modifiers
bundle
Only compatible with the static
linking kind.
+bundle
means objects from the static
-bundle
means the static
This modifier is supposed to supersede the static-nobundle
linking kind defined
The default for this modifier is currently +bundle
, but it could be changed later on some future edition boundary.
verbatim
+verbatim
means that rustc
itself won't add any target-specified library prefixeslib
or .a
) to the library name, and will try its best to ask for the same thing from the linker.
For ld
-like linkers rustc
will use the -l:filename
syntax
See -l namespec
in ld
documentation
For linkers not supporting any verbatim modifiers (e.g. link.exe
or ld64
) the library name will be passed as is.
The default for this modifier is -verbatim
.
This RFC changes the behaviorraw-dylib
linking kind specified.dll
suffix (or other target-specified suffixes for other targets) is now added
If your DLL doesn't have the .dll
suffix, it can be specified+verbatim
.
whole-archive
Only compatible with the static
linking kind.
+whole-archive
means that the static
This modifier translates to --whole-archive
for ld
-like linkers, to /WHOLEARCHIVE
for link.exe
, and to -force_load
for ld64
.
The modifier does nothing for linkers that don't support it.
The default for this modifier is -whole-archive
.
A motivating example for this modifier can be found in issue #56306.
as-needed
Only compatible with the dynamic
and framework
linking kinds.
+as-needed
means that the library will be actually linked only if it satisfies
This modifier translates to --as-needed
for ld
-like linkers, and to -dead_strip_dylibs
/ -needed_library
/ -needed_framework
for ld64
.
The modifier does nothing for linkers that don't support it (e.g. link.exe
).
The default for this modifier is unclear, some targets currently specify+as-needed
, some do not. We may want to try making +as-needed
a default for all targets.
A motivating example for this modifier can be found in issue #57837.
Stability story
The modifier syntax
All the specific
Relative order順序 of -l
and -Clink-arg(s)
options
This RFC also proposes to guarantee-l
and -Clink-arg(s)
command line options of rustc
is preserved when passing them to linker.
(Currently they are passed independently and the order
This provides
An equivalent-Clink-arg
, but in an attribute form,
Drawbacks
Some extra complexity in parsing
Not all modifiers are applicable to all targets and linkers, but that's true for many existing -C
options as well.
Rationale and alternatives代わりのもの、選択肢
Alternative:代わりのもの、選択肢 rely on raw生の linker options
The primarywhole-archive
and as-needed
modifiers is to rely on more target-specific raw
(Note, that rawbundle
and verbatim
modifiers that are rustc
-specific.)
The modifier support is removed from the command line options, the desired effect is achieved by something like this.
-Clink-arg=-Wl,--whole-archive -lfoo -Clink-arg=-Wl,--no-whole-archive
Note the -Wl,
that is needed when using gcc
as a linker, but not when using an ld
-like linker directly.
The -Wl,
part can potentially be addedLINKER:
modifier for target_link_options
.
Relying on raw#[link(arg = "string")]
in "Future possibilities".
Alternative:代わりのもの、選択肢 merge modifiers into kind in attributes
#[link(kind = "static",
-> #[link(kind = "static:+foo,-bar")]
.
This make attributes closer to command line, but it's unclear whether it's a goal we want to pursue. For example, we already write kind=name
on command line, but kind = "...", name = "..."
in attributes.
Prior art
gcc
provides-Wl,foo
command line syntax
The relative order-Wl
options and -l
options linking the libraries is preserved.
cl.exe
provides/link link-opts
for passing options directlylink.exe
are generally order-independent, so it is not as relevant to modifying behaviorld
-like linkers.
Unresolved questions
None currently.
Future possibilities
New modifiers
dedup
rustc
doesn't currently deduplicate linked libraries in general
The reason is that sometimes the linked libraries need to be duplicated on the command line.
However, such cases are rare-dedup
modifier as an opt-out for these rare
Introducing the dedup
modifier with the current -dedup
default doesn't make much sense.
Support #[link(arg = "string")]
in addition追加 to the modifiers
ld
supports some other niche per-library options, for example --copy-dt-needed-entries
.
ld
also supports order-dependent options like --start-group
/--end-group
applying
We may want to avoid-C link-arg
, but in the attribute form.
It may also resolve#[link_args]
and serve as its replacement.
Some analogue of CMake's LINKER:
mentioned above can improve portability