godotengine / godot

Godot Engine – Multi-platform 2D and 3D game engine
https://godotengine.org
MIT License
91k stars 21.17k forks source link

macOS exporter ignores shared objects tags #60692

Open TitanNano opened 2 years ago

TitanNano commented 2 years ago

Godot version

3.4.4.stable

System information

macOS 11, M1 Pro, GLES 3

Issue description

When exporting GDNative shared objects on macOS, the exporter ignores the shared object tags and stores multiple dylib files under the same path, effectively overwriting the file. This makes it impossible to export a multi-arch app on macOS.

https://github.com/godotengine/godot/blob/3.4.4-stable/platform/osx/export/export.cpp#L936-L954

Godot Export Log:

export dylib: [...]/native/target/x86_64-apple-darwin/release/libnative.dylib -> [...]/Library/Caches/Godot/Game.app/Contents/Frameworks/libnative.dylib
codesign ([...]/Library/Caches/Godot/Game.app/Contents/Frameworks/libnative.dylib):
[...]/Library/Caches/Godot/Game.app/Contents/Frameworks/libnative.dylib: signed Mach-O thin (x86_64) [libnative-555549449b9f202bca4f3c55b3b6bf69762e15a8]

export dylib: [...]/native/target/aarch64-apple-darwin/release/libnative.dylib -> [...]/Library/Caches/Godot/Game.app/Contents/Frameworks/libnative.dylib
codesign ([...]/Library/Caches/Godot/Game.app/Contents/Frameworks/libnative.dylib):
[...]/Library/Caches/Godot/Game.app/Contents/Frameworks/libnative.dylib: replacing existing signature
[...]/Library/Caches/Godot/Game.app/Contents/Frameworks/libnative.dylib: signed Mach-O thin (arm64) [libnative-555549447c38cc49f3c13759a06cbbf489f3bfad]

Steps to reproduce

  1. add a gdnative gdnlib
  2. add the dylib paths similar to this:
    OSX.x86_64="res://native/target/x86_64-apple-darwin/release/libnative.dylib"
    OSX.arm64="res://native/target/aarch64-apple-darwin/release/libnative.dylib"
  3. add the features x86_64 and arm64 to the export preset
  4. export the project

Minimal reproduction project

No response

bruvzg commented 2 years ago

This is expected, default macOS exports are universal (x84_64 + arm64) and have both tags set. Also, placing libraries in the subfolders is not supported in 3.x (it is in 4.0), everything is placed directly into the Frameworks folder.

You can merge both libs into a single universal lib using lipo, and use a single OSX=... path in the gdnlib.

TitanNano commented 2 years ago

Thanks to https://github.com/godotengine/godot/issues/60692#issuecomment-1114265591 by @bruvzg I now set it up this way:

add three entries to the gdnlib:

[...]

[entry]

OSX.x86_64="res://native/target/x86_64-apple-darwin/release/libnative.dylib"
OSX.arm64="res://native/target/aarch64-apple-darwin/release/libnative.dylib"
OSX.universal="res://native/target/universal-apple-darwin/release/libnative.dylib"

[...]

and a universal custom feature to the export preset:

[preset.0]

name="macOS"
platform="Mac OSX"
runnable=true
custom_features="universal"

[...]

This will cause the project to be exported with a universal library file, but can still locally be executed with architecture-specific libraries. Since all three files share the same name, Godot will always locate the right library, also in the final export.