Skip to content

Commit 7ac4a39

Browse files
committed
Use link_name for dynamic library loading
1 parent 59a43e1 commit 7ac4a39

File tree

2 files changed

+49
-33
lines changed

2 files changed

+49
-33
lines changed

bindgen/codegen/dyngen.rs

+10-6
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,7 @@ impl DynamicItems {
131131
pub(crate) fn push_func(
132132
&mut self,
133133
ident: Ident,
134+
symbol: &str,
134135
abi: ClangAbi,
135136
is_variadic: bool,
136137
is_required: bool,
@@ -181,11 +182,12 @@ impl DynamicItems {
181182
}
182183

183184
// N.B: Unwrap the signature upon construction if it is required to be resolved.
184-
let ident_str = codegen::helpers::ast_ty::cstr_expr(ident.to_string());
185+
let symbol_cstr =
186+
codegen::helpers::ast_ty::cstr_expr(symbol.to_string());
185187
let library_get = if ctx.options().wrap_unsafe_ops {
186-
quote!(unsafe { __library.get(#ident_str) })
188+
quote!(unsafe { __library.get(#symbol_cstr) })
187189
} else {
188-
quote!(__library.get(#ident_str))
190+
quote!(__library.get(#symbol_cstr))
189191
};
190192

191193
self.constructor_inits.push(if is_required {
@@ -206,6 +208,7 @@ impl DynamicItems {
206208
pub fn push_var(
207209
&mut self,
208210
ident: Ident,
211+
symbol: &str,
209212
ty: TokenStream,
210213
is_required: bool,
211214
wrap_unsafe_ops: bool,
@@ -231,12 +234,13 @@ impl DynamicItems {
231234
}
232235
});
233236

234-
let ident_str = codegen::helpers::ast_ty::cstr_expr(ident.to_string());
237+
let symbol_cstr =
238+
codegen::helpers::ast_ty::cstr_expr(symbol.to_string());
235239

236240
let library_get = if wrap_unsafe_ops {
237-
quote!(unsafe { __library.get::<*mut #ty>(#ident_str) })
241+
quote!(unsafe { __library.get::<*mut #ty>(#symbol_cstr) })
238242
} else {
239-
quote!(__library.get::<*mut #ty>(#ident_str))
243+
quote!(__library.get::<*mut #ty>(#symbol_cstr))
240244
};
241245

242246
let qmark = if is_required { quote!(?) } else { quote!() };

bindgen/codegen/mod.rs

+39-27
Original file line numberDiff line numberDiff line change
@@ -779,17 +779,25 @@ impl CodeGenerator for Var {
779779
}
780780
}
781781
} else {
782-
// If necessary, apply a `#[link_name]` attribute
783-
if let Some(link_name) = self.link_name() {
784-
attrs.push(attributes::link_name::<false>(link_name));
785-
} else {
786-
let link_name =
787-
self.mangled_name().unwrap_or_else(|| self.name());
788-
if !utils::names_will_be_identical_after_mangling(
789-
&canonical_name,
790-
link_name,
791-
None,
792-
) {
782+
// None means the canonical name will end up working out the same, so no need to add the attribute.
783+
let link_name_attribute: Option<&str> =
784+
self.link_name().or_else(|| {
785+
let link_name =
786+
self.mangled_name().unwrap_or_else(|| self.name());
787+
if utils::names_will_be_identical_after_mangling(
788+
&canonical_name,
789+
link_name,
790+
None,
791+
) {
792+
None
793+
} else {
794+
Some(link_name)
795+
}
796+
});
797+
798+
// Apply the `#[link_name]` attribute if necessary, but not if we're not generating dynamic library bindings as they're linked at runtime.
799+
if let Some(link_name) = link_name_attribute {
800+
if ctx.options().dynamic_library_name.is_none() {
793801
attrs.push(attributes::link_name::<false>(link_name));
794802
}
795803
}
@@ -814,8 +822,10 @@ impl CodeGenerator for Var {
814822
);
815823

816824
if ctx.options().dynamic_library_name.is_some() {
825+
let symbol = link_name_attribute.unwrap_or(&canonical_name);
817826
result.dynamic_items().push_var(
818827
canonical_ident,
828+
symbol,
819829
self.ty()
820830
.to_rust_ty_or_opaque(ctx, &())
821831
.into_token_stream(),
@@ -4641,21 +4651,19 @@ impl CodeGenerator for Function {
46414651
write!(&mut canonical_name, "{times_seen}").unwrap();
46424652
}
46434653

4644-
let mut has_link_name_attr = false;
4645-
if let Some(link_name) = self.link_name() {
4646-
attributes.push(attributes::link_name::<false>(link_name));
4647-
has_link_name_attr = true;
4648-
} else {
4649-
let link_name = mangled_name.unwrap_or(name);
4650-
if !is_dynamic_function &&
4651-
!utils::names_will_be_identical_after_mangling(
4652-
&canonical_name,
4653-
link_name,
4654-
Some(abi),
4655-
)
4656-
{
4654+
let link_name_attr = self.link_name().or_else(|| {
4655+
let mangled_name = mangled_name.unwrap_or(name);
4656+
(!utils::names_will_be_identical_after_mangling(
4657+
&canonical_name,
4658+
mangled_name,
4659+
Some(abi),
4660+
))
4661+
.then(|| mangled_name)
4662+
});
4663+
4664+
if let Some(link_name) = link_name_attr {
4665+
if ctx.options().dynamic_library_name.is_none() {
46574666
attributes.push(attributes::link_name::<false>(link_name));
4658-
has_link_name_attr = true;
46594667
}
46604668
}
46614669

@@ -4667,8 +4675,9 @@ impl CodeGenerator for Function {
46674675
quote! { #[link(wasm_import_module = #name)] }
46684676
});
46694677

4670-
let should_wrap =
4671-
is_internal && ctx.options().wrap_static_fns && !has_link_name_attr;
4678+
let should_wrap = is_internal &&
4679+
ctx.options().wrap_static_fns &&
4680+
link_name_attr.is_none();
46724681

46734682
if should_wrap {
46744683
let name = canonical_name.clone() + ctx.wrap_static_fns_suffix();
@@ -4734,11 +4743,14 @@ impl CodeGenerator for Function {
47344743

47354744
// If we're doing dynamic binding generation, add to the dynamic items.
47364745
if is_dynamic_function {
4746+
let ident_str = ident.to_string();
4747+
let symbol = link_name_attr.unwrap_or(&ident_str);
47374748
let args_identifiers =
47384749
utils::fnsig_argument_identifiers(ctx, signature);
47394750
let ret_ty = utils::fnsig_return_ty(ctx, signature);
47404751
result.dynamic_items().push_func(
47414752
ident,
4753+
symbol,
47424754
abi,
47434755
signature.is_variadic(),
47444756
ctx.options().dynamic_link_require_all,

0 commit comments

Comments
 (0)