openfl / lime

A foundational Haxe framework for cross-platform development
https://lime.openfl.org/
MIT License
749 stars 361 forks source link

`lime.ndll` fails to load `libneko.dylib` with certain homebrew installs of haxe/neko #1750

Closed tobil4sk closed 2 weeks ago

tobil4sk commented 6 months ago

When haxe/neko are installed via homebrew, they are installed to /opt/homebrew on an Apple Silicon Mac system. This means that libneko exists in /opt/homebrew/lib rather than the traditional paths. As a result, when lime.ndll tries to load libneko.dylib (via dlopen), it fails because dlopen does not check the homebrew path.

Running a lime command from the terminal gives the error:

Could not link to neko.
Called from lime/_internal/backend/native/NativeCFFI.hx line 632
Called from lime/system/CFFI.hx line 177
Called from lime/system/CFFI.hx line 300
Uncaught exception - Segmentation fault

Homebrew does not have a solution for this problem: https://github.com/Homebrew/brew/issues/13481.

To work around this, it is possible to set DYLD_LIBRARY_PATH to /opt/homebrew/lib, but this only works if System Integrity Protection is disabled, which is not ideal.

One possible option is for lime.ndll to have a hardcoded full path to libneko (by setting install_name). However, system specific paths wouldn't really work for the precompiled lime.ndlls distributed via haxelib. Also, this would only work if lime.ndll is compiled with -lneko, which is currently not the case.

Also, it looks like /usr/local/lib may not be a default path anymore either: https://developer.apple.com/forums/thread/737920.

Not sure if this is the best place to put this, but lime won't work natively on Apple Silicon without resolving this.

tobil4sk commented 5 months ago

One possible option is for lime.ndll to have a hardcoded full path to libneko (by setting install_name).

Here is a hacky patch that implements this solution: https://github.com/tobil4sk/lime/commit/a308fe725950eb25da3ee98ee99982f9a62a479a

tobil4sk commented 5 months ago

One possible option is for lime.ndll to have a hardcoded full path to libneko (by setting install_name). [...] Also, this would only work if lime.ndll is compiled with -lneko

It is a problem to link lime.ndll to libneko like this, because with cpp builds, libneko should not be a dependency. It turns out it is enough to set the rpath, because dlopen respects rpath. Here is an updated patch: https://github.com/tobil4sk/lime/commit/cae245808c8be0f106719ca07000873b7f4c42a1

Perhaps it is best to remove the rpath (using install_name_tool) when copying lime.ndll to the output directory when building an app, because otherwise the distributed app will have a lime.ndll with a hardcoded rpath that was only relevant to the host system.

tobil4sk commented 4 weeks ago

Reopening for now while we figure out what's going on with: 47936494ac22708db891504db685c54be42e9ec7

joshtynjala commented 2 weeks ago

I found some time today to try installing Haxe with Apple Silicon Homebrew again. I confirmed that commit 47936494ac22708db891504db685c54be42e9ec7 broke Lime tools, as you expected, @tobil4sk. I've reverted my change, and we once again set the rpath in build.xml instead of using install_name_tool.

tobil4sk commented 2 weeks ago

Thanks for testing this out!

I'm still a bit confused about the difference with installing haxe/neko via different methods. Via the universal installer (a nightly build is now available), there is no need for this patch still, but with homebrew it is necessary. I'd imagine that the homebrew build is probably built with xcode 15+. The x86_64 neko build is built on macos-12, which still has xcode 14, but the arm64 build is on macos-14 which has xcode 15. But then these binaries are combined to create the universal binary (also in macos-14).

I wonder if neko x86_64 being built on xcode 15 would make this patch necessary with the installer build as well, or if there is something wrong with the homebrew setup of neko.