NordSecurity / uniffi-bindgen-go

Uniffi bindings generator for Golang
Mozilla Public License 2.0
75 stars 21 forks source link

How to use the bindings #32

Closed MrMaavin closed 10 months ago

MrMaavin commented 10 months ago

I tried to create bindings for the didcomm-rust library using version v0.2.0 + v0.25.0

I am not sure how to integrate the generated bindings in my project. The README only says that I have to copy the generated go file, see here.

I created a new go module for the bindings. The first problem, I ran into, was the following:

go run main.go
# command-line-arguments
/usr/local/go/pkg/tool/linux_amd64/link: running gcc failed: exit status 1
/usr/bin/ld: /tmp/go-link-4063076886/000001.o: in function `_cgo_320faa912c93_Cfunc_ffi_didcomm_uniffi_rustbuffer_from_bytes':
/tmp/go-build/cgo-gcc-prolog:66: undefined reference to `ffi_didcomm_uniffi_rustbuffer_from_bytes'
/usr/bin/ld: /tmp/go-link-4063076886/000001.o: in function `_cgo_320faa912c93_Cfunc_ffi_didcomm_uniffi_uniffi_contract_version':
...

My thought was, that the binary of the rust library was not linked with the go program. This is why I tried to use some compiler flags in the generated bindings.

/*
#cgo LDFLAGS: -L./didcomm -ldidcomm_uniffi

#include "didcomm.h"
*/

This did not help to solve the problems with the undefined references.

I checked the symbols in the binary and those were named differently than the bindings:

nm -D libdidcomm_uniffi.so

000000000008f1a0 T uniffi_rustbuffer_from_bytes
000000000008f330 T uniffi_rustbuffer_reserve
...

I have noticed that it works when the functions are renamed like the symbols in the binary, and that there are decorators to instruct the compiler to not mangle the names. On the one hand, I would like to be able to generate the bindings and on the other hand cannot change the source code of the rust library.

Do you have any idea how to solve this problem? It would be awesome if someone has a working example on how to integrate generated bindings in a go project.

arg0d commented 10 months ago

Make sure to use matching uniffi-rs and uniffi-bindgen-go versions. Using different versions will cause these kind of issues. I see right now in main branch 0.24 is used for the library, but you said you are generating Go bindings with 0.25.

arg0d commented 10 months ago

I'm talking about the version in library here: https://github.com/sicpa-dlab/didcomm-rust/blob/4abaf5a4a3c6149d4d29c4dbcfede473b74c2fba/uniffi/Cargo.toml#L26C1-L26C1

iBims1JFK commented 10 months ago

Hey thank you for the quick reply. Does this mean that the general approach of adding the link of the binary in the go file was the right thing to do? And I do see a way to install the version 0.24 of the bindgen-go apart of using this repo. Is this right?

arg0d commented 10 months ago

Yeap, you need to link the Rust library into your Go program in some way yourself right now. I'm afraid 0.24 was skipped for uniffi-bindgen-go. You could try to update the Rust library to use uniffi-rs 0.25.

kegsay commented 10 months ago

I had a similar issue in that I couldn't get it linked correctly. What worked for me was:

This will only help if the issue you're having is failing to find your functions. If it's failing to find one or two uniffi functions, then it's most likely a version mismatch (e.g the rust project in question uses uniffi 0.24 whilst the bindgen uses 0.25). In that case, there is very little you can do beyond forking it and updating the dependency sadly.

MrMaavin commented 10 months ago

Yeap, you need to link the Rust library into your Go program in some way yourself right now. I'm afraid 0.24 was skipped for uniffi-bindgen-go. You could try to update the Rust library to use uniffi-rs 0.25.

Thanks for your help Updating the rust library in the cargo.toml worked. I updated the following lines:

...
[dependencies]
uniffi = "0.25.2" 
...
[build-dependencies]
uniffi_build = { version = "0.25.2", features=["builtin-bindgen"] }

Also the linking @kegsay mentioned was needed.