The crate is part of the linktime project.
| crate | docs | version |
|---|---|---|
linktime |
||
ctor |
||
dtor |
||
link-section |
ctor
Module initialization functions for Rust (like __attribute__((constructor)) in
C/C++) for Linux, OSX, Windows, WASM, BSD-likes, and many others.
use ctor;
MSRV
For most platforms, this library currently has a MSRV of Rust >= 1.60.
MSRV for WASM targets is Rust >= 1.85.
Lightweight
ctor has no dependencies other than the ctor-proc-macro and link-section
crates. The proc-macro is only used to delegate to the declarative macro and
should have minimal effect on compilation time.
Support
This library works and is regularly tested on Linux, OSX, Windows, and FreeBSD,
with both +crt-static and -crt-static and bin/cdylib outputs.
Contributions to support other platforms or improve testing are welcome.
| OS | Supported | CI Tested |
|---|---|---|
| Linux | ✅ | ✅ |
| OSX | ✅ | ✅ |
| Windows | ✅ | ✅ |
| FreeBSD | ✅ | ✅ |
| WASM | ✅ | ✅ |
| NetBSD | ✅ | - |
| OpenBSD | ✅ | - |
| DragonFlyBSD | ✅ | - |
| Illumos | ✅ | - |
| Android | ✅ | - |
| iOS | ✅ | - |
| AIX | ✅ | - |
| Haiku | ✅ | - |
| VxWorks | ✅ | - |
| Xtensa | ✅ | - |
| NTO | ✅ | - |
Warnings
Rust's philosophy is that nothing happens before or after main and this library
explicitly subverts that. The code that runs in the ctor and dtor functions
should be careful to limit itself to libc functions and code that does not
rely on Rust's stdlib services.
See ::life_before_main for more information.
Usage
#[ctor] decorates a function item to be called as a module constructor. Both
free (a global fn()) and impl functions (Self::method()) are supported.
The example below marks the function foo as a module constructor, called when
a static library is loaded or an executable is started:
use ;
use ctor;
static INITED: AtomicBool = new;
Implementation methods can also be decorated with #[ctor], as long as they
have no self parameter:
use ctor;
static items
The #[ctor] macro also supports decorating static items, which are
initialized at startup time. static items declared in this way must not be
accessed from other threads before the module constructors have run (if this is
done without caution, the initializer may panic).
The below example creates a HashMap populated with strings, which would
normally not be possible with const items:
use HashMap;
use ctor;
/// This is an immutable static, evaluated at init time
static STATIC_CTOR: = ;
As a building block
The #[ctor] macro can be used as a building block for more complex
initialization logic. Use the declarative::ctor to
easily export macros that re-use ctor functionality.
use ctor;
static DRIVERS: Mutex = new;
register_driver!;
Under the Hood
The #[ctor] macro makes use of linker sections to ensure that a function is
run at startup time.
The above example translates into the following Rust code (approximately):
/* ... other platforms elided ... */
static FOO: extern fn = ;
Inspiration
The idea for ctor was originally inspired by the Neon project.
Crate Features
| Cargo feature | Description |
|---|---|
no_warn_on_missing_unsafe |
Do not warn when a ctor is missing the unsafe keyword. |
priority_enabled |
Enable support for the priority parameter. |
proc_macro |
Enable support for the proc-macro #[ctor] attribute. The declarative form (ctor!(...)) is always available. It is recommended that crates re-exporting the ctor macro disable this feature and only use the declarative form. |
std |
Enable support for the standard library. |
used_linker |
Applies used(linker) to all ctor-generated functions. Requires nightly and feature(used_with_arg). |
Macro Attributes
Do not give the constructor a name in the generated code (allows for
multiple constructors with the same name). Equivalent to wrapping the
constructor in an anonymous const (i.e.: const _ = { ... };).
The path to the ctor crate containing the support macros. If you
re-export ctor items as part of your crate, you can use this to
redirect the macro’s output to the correct crate.
Using the declarative ctor! form is
preferred over this parameter.
Specify a custom export name prefix for the constructor function.
If specified, an export with the given prefix will be generated in the form:
<prefix><priority>_<unique_id>
Place the constructor function pointer in a custom link section. By default, this uses the appropriate platform-specific link section.
Marks a ctor as unsafe. Recommended.
The priority of the constructor. Higher-N-priority constructors are
run last. N must be between 0 and 999 inclusive for ordering
guarantees (N >= 1000 ordering is platform-defined).
Priority is specified as an isize, string literal, or the identifiers
early, late, or naked. The integer value will be clamped to a
platform-defined range (typically 0-65535), while the string value will
unprocessed. naked indicates that the constructor should not use a
priority value, and should use the low-level platform-specific
unprioritized mechanism.
Priority is applied as follows:
earlyis the default, and is run first (constructors annotated withearlyand those with no priority attribute are run in the same phase).Nis run in increasing order, from 0 <= N <= 999.lateis run last, and will be positioned to run after most constructors, even outside the range 0 <= N <= 999.mainis run, for binary targets.
Ordering outside of 0 <= N <= 999 is platform-defined with respect to
the list above, however platforms will order constructors within a given
length range in ascending order (ie: 10000 will run before 20000).
Mark generated functions for this ctor as used(linker). Requires nightly and feature(used_with_arg).
Defaults
export_name_prefix
export_name_prefix = "__sinit"
// default
export_name_prefix =
link_section
link_section = "__DATA,__mod_init_func,mod_init_funcs"
link_section = ".init_array"
link_section = ".init_array"
link_section = ".ctors"
link_section = ".CRT$XCU"
link_section = ".ctors"
link_section =
// default
link_section =
priority
priority = early
// default
priority = naked