Skip to content

Commit d5fc49c

Browse files
konradkoschelemilio
authored andcommitted
feat: Custom attributes for extern fn blocks
chore: allow both wasm_import and raw-dylib feat: Refactor specific attribute solution to general solution chore: rustfmt fix: wasm import module binding order fix: Use different test attribute
1 parent ac0fa3b commit d5fc49c

File tree

9 files changed

+66
-8
lines changed

9 files changed

+66
-8
lines changed

bindgen-tests/tests/expectations/tests/extern-fn-block-attrs-many.rs

Lines changed: 6 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

bindgen-tests/tests/expectations/tests/extern-fn-block-attrs-wasm.rs

Lines changed: 6 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

bindgen-tests/tests/expectations/tests/extern-fn-block-attrs.rs

Lines changed: 5 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
// bindgen-flags: --extern-fn-block-attrs '#[allow(dead_code)]' --extern-fn-block-attrs '#[cfg_attr(not(windows), link(wasm_import_module = "test-module"))]'
2+
3+
void test_function();
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
// bindgen-flags: --extern-fn-block-attrs '#[allow(dead_code)]' --wasm-import-module-name test-module
2+
3+
void test_function();
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
// bindgen-flags: --extern-fn-block-attrs '#[allow(dead_code)]'
2+
3+
void test_function();

bindgen/codegen/mod.rs

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4665,13 +4665,19 @@ impl CodeGenerator for Function {
46654665
}
46664666
}
46674667

4668-
// Unfortunately this can't piggyback on the `attributes` list because
4669-
// the #[link(wasm_import_module)] needs to happen before the `extern
4670-
// "C"` block. It doesn't get picked up properly otherwise
4671-
let wasm_link_attribute =
4672-
ctx.options().wasm_import_module_name.as_ref().map(|name| {
4673-
quote! { #[link(wasm_import_module = #name)] }
4668+
let mut block_attributes = quote! {};
4669+
for attr in &ctx.options().extern_fn_block_attrs {
4670+
let parsed_attr = proc_macro2::TokenStream::from_str(attr).unwrap_or_else(
4671+
|err| {
4672+
panic!(
4673+
"Error parsing extern fn block attribute `{attr}`: {err}"
4674+
)
4675+
},
4676+
);
4677+
block_attributes.extend(quote! {
4678+
#parsed_attr
46744679
});
4680+
}
46754681

46764682
let should_wrap = is_internal &&
46774683
ctx.options().wrap_static_fns &&
@@ -4725,7 +4731,7 @@ impl CodeGenerator for Function {
47254731
.then(|| quote!(unsafe));
47264732

47274733
let tokens = quote! {
4728-
#wasm_link_attribute
4734+
#block_attributes
47294735
#safety extern #abi {
47304736
#(#attributes)*
47314737
pub fn #ident ( #( #args ),* ) #ret;

bindgen/options/cli.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -423,6 +423,9 @@ struct BindgenCommand {
423423
/// The NAME to be used in a #[link(wasm_import_module = ...)] statement
424424
#[arg(long, value_name = "NAME")]
425425
wasm_import_module_name: Option<String>,
426+
/// Attributes to apply to the extern function block.
427+
#[arg(long, value_name = "ATTRS")]
428+
extern_fn_block_attrs: Vec<String>,
426429
/// Use dynamic loading mode with the given library NAME.
427430
#[arg(long, value_name = "NAME")]
428431
dynamic_loading: Option<String>,
@@ -647,6 +650,7 @@ where
647650
enable_function_attribute_detection,
648651
use_array_pointers_in_arguments,
649652
wasm_import_module_name,
653+
extern_fn_block_attrs,
650654
dynamic_loading,
651655
dynamic_link_require_all,
652656
prefix_link_name,
@@ -907,6 +911,7 @@ where
907911
time_phases,
908912
use_array_pointers_in_arguments => Builder::array_pointers_in_arguments,
909913
wasm_import_module_name,
914+
extern_fn_block_attrs => Builder::extern_fn_block_attrs,
910915
ctypes_prefix,
911916
anon_fields_prefix,
912917
generate => Builder::with_codegen_config,

bindgen/options/mod.rs

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1916,6 +1916,25 @@ options! {
19161916
},
19171917
as_args: "--use-array-pointers-in-arguments",
19181918
},
1919+
/// Attributes to add to all `extern` blocks.
1920+
extern_fn_block_attrs: Vec<String> {
1921+
methods: {
1922+
/// Add an attribute to all the `extern` blocks generated by `bindgen`.
1923+
///
1924+
/// This can be used to add attributes such as `#[link(...)]` to all
1925+
/// the `extern` blocks.
1926+
pub fn extern_fn_block_attrs<T: Into<String>>(mut self, attr: T) -> Self {
1927+
self.options.extern_fn_block_attrs.push(attr.into());
1928+
self
1929+
}
1930+
},
1931+
as_args: |attrs, args| {
1932+
for attr in attrs {
1933+
args.push("--extern-fn-block-attrs".to_owned());
1934+
args.push(attr.clone());
1935+
}
1936+
},
1937+
},
19191938
/// The name of the `wasm_import_module`.
19201939
wasm_import_module_name: Option<String> {
19211940
methods: {
@@ -1927,7 +1946,9 @@ options! {
19271946
mut self,
19281947
import_name: T,
19291948
) -> Self {
1930-
self.options.wasm_import_module_name = Some(import_name.into());
1949+
self.options.extern_fn_block_attrs.push(format!(
1950+
"#[link(wasm_import_module = \"{}\")]", import_name.into()
1951+
));
19311952
self
19321953
}
19331954
},

0 commit comments

Comments
 (0)