NordSecurity / uniffi-bindgen-go

Uniffi bindings generator for Golang
Mozilla Public License 2.0
65 stars 18 forks source link

Unable to run compiled code using Commandline Tools / XCode v15 linker #27

Closed damienstanton closed 3 months ago

damienstanton commented 8 months ago

Hello, I am experimenting with bindings in a couple different Go versions. So far nothing works due to linking errors.

My environment is

macOS 13.5.2
rustc 1.73.0
uniffi-rs 0.23.0

In Go 1.21, running the math.udl example from the uniffi-rs book, upon invoking

uniffi-bindgen-go src/math.udl
go run main.go

we see

# command-line-arguments
/opt/homebrew/Cellar/go/1.21.3/libexec/pkg/tool/darwin_arm64/link: running cc failed: exit status 1
ld: Undefined symbols:
  _ffi_math_14e3_rustbuffer_free, referenced from:
      __cgo_09bf5ab87068_Cfunc_ffi_math_14e3_rustbuffer_free in 000001.o
  _math_14e3_add, referenced from:
      __cgo_09bf5ab87068_Cfunc_math_14e3_add in 000001.o
clang: error: linker command failed with exit code 1 (use -v to see invocation)

In Go 1.19, the linker error is accompanied by a warning but otherwise is the same.

/opt/homebrew/Cellar/go@1.19/1.19.13/libexec/pkg/tool/darwin_arm64/link: running clang failed: exit status 1
ld: warning: '/private/var/folders/9q/bmlk103n25q8kh9lbptl9r1h0000gp/T/go-link-2705399158/go.o' has malformed LC_DYSYMTAB, expected 51 undefined symbols to start at index 3083, found 59 undefined symbols starting at index 15
ld: Undefined symbols:
  _ffi_math_14e3_rustbuffer_free, referenced from:
      __cgo_09bf5ab87068_Cfunc_ffi_math_14e3_rustbuffer_free in 000001.o
  _math_14e3_add, referenced from:
      __cgo_09bf5ab87068_Cfunc_math_14e3_add in 000001.o
clang: error: linker command failed with exit code 1 (use -v to see invocation)

The output of ld -v is

@(#)PROGRAM:ld  PROJECT:dyld-1015.7
BUILD 18:48:48 Aug 22 2023
configured to support archs: armv6 armv7 armv7s arm64 arm64e arm64_32 i386 x86_64 x86_64h armv6m armv7k armv7m armv7em
will use ld-classic for: armv6 armv7 armv7s arm64_32 i386 armv6m armv7k armv7m armv7em
LTO support using: LLVM version 15.0.0 (static support for 29, runtime is 29)
TAPI support using: Apple TAPI version 15.0.0 (tapi-1500.0.12.3)
Library search paths:
Framework search paths:

Any ideas are greatly appreciated!

arg0d commented 8 months ago

I can't reproduce this on my intel Mac. @dignifiedquire are you using Intel or Arm Mac?

dignifiedquire commented 8 months ago

All my tests have been on arm, and my colleagues as well, and it works fine there. I am currently on macos@13.1

dignifiedquire commented 8 months ago

you need to path the link flags and sources, are you doing that correctly @damienstanton? See https://github.com/NordSecurity/uniffi-bindgen-go/issues/19 for some details

damienstanton commented 8 months ago

@dignifiedquire ah yes, I think this is the issue. I haven't used CGo in ~7 years and didn't even think of the manual flags. I'll take a look at the test and see if I can get it running.

dignifiedquire commented 8 months ago

I haven't used CGo in ~7 years

luck you :)

damienstanton commented 8 months ago

Hmm, I think I have the right config here but still getting the same linking errors (I use fish, so had to modify the syntax a bit from the test fixtures). I have a crate called goadder, with the following layout which is based on the uniffi-rs tutorial. I've expanded the target to show what's been output:

uniffi-demo

My invocation after running cargo build and uniffi-bindgen-go src/math.udl is

set LD_LIBRARY_PATH src/target/debug; \
set CGO_ENABLED 1; \
set CGO_LDFLAGS "-lgoadder -Lsrc/target/debug -lm -ldl"; go run test.go

but this still produces

ld: Undefined symbols:
  _ffi_math_14e3_rustbuffer_free, referenced from:
      __cgo_65dc62b5a664_Cfunc_ffi_math_14e3_rustbuffer_free in 000001.o
  _math_14e3_add, referenced from:
      __cgo_65dc62b5a664_Cfunc_math_14e3_add in 000001.o
clang: error: linker command failed with exit code 1 (use -v to see invocation)

The test file is:

package main

import (
    "fmt"
    "path/to/goadder/src/uniffi/math"
)

func main() {
    four := math.Add(2, 2)
    fmt.Println(four)
}

I feel I must be making some obvious mistake. Thanks in advance!

dignifiedquire commented 8 months ago

any chance you can push this to a git repo? that would probably the easiest for me to look at

kegsay commented 7 months ago

set LD_LIBRARY_PATH src/target/debug; \

I think this is your problem. LD_LIBRARY_PATH != LIBRARY_PATH - https://stackoverflow.com/questions/4250624/ld-library-path-vs-library-path you probably meant LIBRARY_PATH.

damienstanton commented 7 months ago

@dignifiedquire thanks again for looking into this. I've uploaded my test to this repo: https://github.com/damienstanton/goadder.

@kegsay no such luck: the same error occurs when setting LIBRARY_PATH as opposed to LD_LIBRARY_PATH. Since the distinction there seems to be between shared/static libs, I also tried modifying the Cargo.toml crate-type to variously cdylib, lib, and static. No combination of those or the library path env var made a difference in the error output.

arg0d commented 7 months ago

I haven't yet seen anyone using set command to set environment variables. Is that actually working in your shell? Try echo $CGO_LDFLAGS after running your set commands.

damienstanton commented 7 months ago

Hi @arg0d, I am using fish shell, and set FOO bar is indeed the correct syntax.

E.g. if I invoke my whole test workflow

cargo clean && cargo build && uniffi-bindgen-go src/math.udl && set LD_LIBRARY_PATH src/target/debug; set CGO_ENABLED 1; set CGO_LDFLAGS "-lgoadder -Lsrc
/target/debug -lm -ldl"; go run test.go

then check the one you asked about, it is correct.

echo $CGO_LDFLAGS 
-lgoadder -Lsrc/target/debug -lm -ldl
arg0d commented 7 months ago

I see, I was just pointing out something that looked off to me :D This is very strange, the code you posted looks correct otherwise, and works on my Linux, Intel Mac machines. From your messages it looks like you are getting link errors, so either the library you are linking with does not contain the required symbols, or the library is not actually being linked. Some more wild ideas for debugging:

damienstanton commented 7 months ago

I am running the most up to date macOS on an M1 and M2 device (both have this error), so I wonder if it's something isolated to Apple silicon. I'll try some of those suggestions, thanks!