macosgocgodylib

How can I specify a relative dylib path in cgo on macOS


I am currently attempting to get an existing dylib written in C working in Go. For this, I am using Cgo and everything compiles correctly. When go build attempts to run the resulting executable dyld cannot find the dylib that is located in the Go source directory.

I am using these CFLAGS and LDFLAGS without success:

// #cgo CFLAGS: -I${SRCDIR}
// #cgo LDFLAGS: -L. -lMyLibrary

I also read that I could use the magic string @executable_path in order to specify a relative library search path, but adding it to -L or trying to add -install_name to the linker flags yields no result.

This is the linker error message I get:

/Users/benedikt/sdk/go1.19.7/bin/go build -o /private/var/folders/.../T/GoLand/___1go_build_myapp myapp #gosetup
/private/var/folders/.../T/GoLand/___1go_build_myapp
dyld[58935]: Library not loaded: '/usr/local/lib/libMyLibrary.dylib'
  Referenced from: '/private/var/folders/.../T/GoLand/___1go_build_myapp'
  Reason: tried: '/usr/local/lib/libMyLibrary.dylib' (no such file), '/usr/lib/libMyLibrary.dylib' (no such file)

While not adding any build steps outside go, how can I configure Cgo correctly to use my dylib that is located in the same folder that the binary will be located in later and so that it will run with go build?


Solution

  • It turns out I was already pretty close to my goal, but the search path stored inside the actual library was wrong.

    The code in my question works fine after modifying the library as follows:

    install_name_tool -id @loader_path/libMyLibrary.dylib libMyLibrary.dylib
    

    While I have not yet found a clean way to get go build controlled by GoLand to copy my library to the output directory it runs the application from, I preliminarily got it to work by setting the output directory to an absolute path and adding a pre-execution command that copies the dependencies to the output folder.