Skip to content

Commit

Permalink
parse no_mangle in cfg_attr
Browse files Browse the repository at this point in the history
fixes rksm#36

the predicate currently isn't checked, which may cause false positives,
but this is very unlikely to happen and this can be dealt with in the future.
the relevant documentation and example have been adjusted.

the documentation for #[no_mangle_if_debug] has been removed since it doesn't
work with optimizations or the feature flag anyways.
it should later be deprecated and phased out.
  • Loading branch information
SArpnt committed Oct 27, 2024
1 parent c9fbbfe commit 4c91d46
Show file tree
Hide file tree
Showing 5 changed files with 55 additions and 14 deletions.
13 changes: 7 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -264,9 +264,10 @@ When you define a feature like this
```toml
[features]
default = []
reload = ["dep:hot-lib-reloader"]
reload = ["lib/reload", "dep:hot-lib-reloader"]

[dependencies]
lib = { path = "lib" }
hot-lib-reloader = { version = "^0.6", optional = true }
```

Expand All @@ -283,13 +284,13 @@ use lib::*;
mod hot_lib { /*...*/ }
```

To run the static version just use `cargo run` the hot reloadable variant with `cargo run --features reload`.


### Disable `#[no-mangle]` in release mode
You can also conditionally use `#[no_mangle]` in your library:

To not pay a penalty for exposing functions using `#[no_mangle]` in release mode where everything is statically compiled (see previous tip) and no functions need to be exported, you can use the [no-mangle-if-debug attribute macro](./macro-no-mangle-if-debug). It will conditionally disable name mangling, depending on wether you build release or debug mode.
```rust
#[cfg_attr(feature = "reload", no_mangle)]
```

To run the static version just use `cargo run` the hot reloadable variant with `cargo run --features reload`.

### Use serialization or generic values for changing types

Expand Down
2 changes: 1 addition & 1 deletion examples/reload-feature/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,4 @@ log = "*"

[features]
default = []
reload = ["dep:hot-lib-reloader"]
reload = ["lib/reload", "dep:hot-lib-reloader"]
4 changes: 4 additions & 0 deletions examples/reload-feature/lib/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,7 @@ edition = "2021"

[lib]
crate-type = ["rlib", "dylib"]

[features]
default = []
reload = []
2 changes: 1 addition & 1 deletion examples/reload-feature/lib/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#[no_mangle]
#[cfg_attr(feature = "reload", no_mangle)]
pub fn do_stuff() {
println!("step called");
}
48 changes: 42 additions & 6 deletions macro/src/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,13 +50,49 @@ pub fn read_functions_from_file(
// we can optionally assume that the function will be unmangled
// by other means than a direct attribute
if !ignore_no_mangle {
let no_mangle = fun
.attrs
.iter()
.filter_map(|attr| attr.path.get_ident())
.any(|ident| *ident == "no_mangle");
fn cfg_no_mangle<'a>(
mut cfg_items: impl Iterator<Item = &'a syn::NestedMeta>,
) -> bool {
let _predicate = cfg_items.next();
// TODO: return false if predicate is false
// false positives are unlikely, but can still compile error

if !no_mangle {
cfg_items.any(|meta| {
let meta = match meta {
syn::NestedMeta::Meta(m) => m,
_ => return false,
};
match meta {
syn::Meta::Path(path) => path.is_ident("no_mangle"),
syn::Meta::List(m) => cfg_no_mangle(m.nested.iter()),
_ => false,
}
})
}

fn is_no_mangle<'a>(
mut attrs: impl Iterator<Item = &'a syn::Attribute>,
) -> bool {
attrs.any(|attr| {
let ident = match attr.path.get_ident() {
Some(i) => i,
None => return false,
};
if *ident == "no_mangle" {
true
} else if *ident == "cfg_attr" {
let nested = match attr.parse_meta() {
Ok(syn::Meta::List(m)) => m.nested,
_ => return false,
};
cfg_no_mangle(nested.iter())
} else {
false
}
})
}

if !is_no_mangle(fun.attrs.iter()) {
continue;
};
}
Expand Down

0 comments on commit 4c91d46

Please sign in to comment.