Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Symbols from multiple Rust projects can conflict in a shared namespace #1670

Closed
aringenbach opened this issue Jul 25, 2023 · 8 comments
Closed

Comments

@aringenbach
Copy link

Steps to reproduce:

  • Create a project with a shared C namespace, e.g. an iOS application
  • Import more than one Rust static library built with Uniffi

Result:

Some symbols will conflict between the two libraries, namely:

rust_eh_personality
uniffi_foreign_executor_callback_set
uniffi_rustbuffer_from_bytes
uniffi_rustbuffer_alloc
uniffi_rustbuffer_free
uniffi_rustbuffer_reserve

(first one is weird because I thought it wouldn't be exposed)

This is especially dire for the uniffi_foreign_executor_callback_set because if the wrong function is called and one of the libraries doesn't implement the foreign executor, it will completely break, even if using the same version of Uniffi.

Potential change suggestion:

Generate name for symbols that get exposed in the static library with something like uniffi_library_name_rustbuffer_... instead of just a uniffi prefix.

Note on megazords frameworks

I know that this could be avoided with setting up in a single library and build everything together at the Rust/Uniffi level, but we can also see the value on avoiding those kind of clashes: if I want to build an application with e.g. Mozilla's application-services plus some other Rust libraries, I don't want to bother re-packaging things that have nothing to do together.

@goncalo-frade-iohk
Copy link

Hey @aringenbach . Did you find a solution for this? Im having this problem right now, were the C methods of Rust are conflicting and being duplicated.

@aringenbach
Copy link
Author

Hello @goncalo-frade-iohk

I currently run a very unsatisfying solution, but it does work: I simply fork uniffi-rs and rename these functions manually. One of my library is built with standard uniffi and the other one is built with the fork. Of course this doesn't scale well if you want to run more than 2 Rust libraries.

@goncalo-frade-iohk
Copy link

Thx @aringenbach

It's a solution that I didn't thought off. I tried to do some work with the linking but was unsuccessful.
But at leats for now it seems if you got 2 Uniffi libraries inside the same Swift project you will have this duplication problem.

@goncalo-frade-iohk
Copy link

Hey @aringenbach . I tried your solution but it seems my symbols are not uniffi but rust ones, so I cannot actually rename them. Im totally stuck with this :(

duplicate symbol '___rust_foreign_exception'
duplicate symbol '_rust_begin_unwind'
duplicate symbol '___rdl_alloc_zeroed'
duplicate symbol '___rdl_realloc'
duplicate symbol '___rdl_dealloc'
duplicate symbol '___rdl_alloc'
duplicate symbol '_rust_panic'
duplicate symbol '___rust_drop_panic'
duplicate symbol '___rg_oom'
duplicate symbol '___rdl_oom'

@arg0d
Copy link
Contributor

arg0d commented Aug 23, 2023

Goods news, it looks like prefixed rustbuffer functions are already implemented in scaffolding code, and the prefixed functions are used in foreign language bindings. All thats needed to do is remove extern "C" from functions in rustbuffer.rs. This fixes rustbuffer duplicate symbol issues.

For uniffi_foreign_executor_callback_set, some additional work is required.

I'm not sure about rust_eh_personality. Haven't seen this before.

@goncalo-frade-iohk
Copy link

Hey sorry I forgot to update.

The error was actually on my side, I forgot that Swift Packages builds libraries by default as static. So adding the type: .dynamic to the library just works without a problem.

Here you can see how I setup the swift package Package.swift:
https://github.com/input-output-hk/anoncreds-rs/tree/main/uniffi/output-frameworks/anoncreds-swift

If you need to see it completed package you can run:
https://github.com/input-output-hk/anoncreds-rs/blob/main/uniffi/build-release-apple-universal.sh

@badboy
Copy link
Member

badboy commented Sep 6, 2023

@arg0d #1735 was merged which means both the rustbuffer functions and uniffi_foreign_executor_callback_set are not no_mangle'd anymore.

@arg0d
Copy link
Contributor

arg0d commented Sep 7, 2023

Thats awesome! Big thanks guys.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants