Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP, 3.x] Build and export iOS Mono libs as .xcframeworks, for M1 iOS simulator support. #45499

Closed
wants to merge 1 commit into from

Conversation

bruvzg
Copy link
Member

@bruvzg bruvzg commented Jan 27, 2021

Followup to #45480 for the Mono libs.

Export template build depends on godotengine/godot-mono-builds#30, godotengine/build-containers#68 and godotengine/godot-build-scripts#16

…xcframework`.

Build and export iOS Mono libs as `.xcframework`s, for Apple Silicon iOS simulator support.
@aaronfranke aaronfranke requested review from neikeq and removed request for a team January 28, 2021 09:02
@naithar
Copy link
Contributor

naithar commented Jan 28, 2021

Standard build export seems to be working fine - xcframework is copied and exported correctly.


But mono seems to be broken on many levels.

So I guess right now iOS mono is not linking libraries that it should have linked as well as not adding required code to the dummy.cpp file.

@bruvzg
Copy link
Member Author

bruvzg commented Jan 28, 2021

Building export template isn't really working correctly

Building templates with mono prefixes generated by ios.py from godotengine/godot-mono-builds#30 script seems to work fine for me.

But building ARM64 iOS Simulator toolchain for osxcross (which is used to build all official templates) do not.

But mono seems to be broken on many levels.

It's broken indeed. I'm getting the same issues with both rc1 mono templates and my templates built from this PR.

@naithar
Copy link
Contributor

naithar commented Jan 28, 2021

3.2.4 beta1 also doesn't seems to be working. On export editor gives Mono AOT compiler exited with code: 134.
3.2.3 exports the same project without an issue.

@naithar
Copy link
Contributor

naithar commented Jan 28, 2021

ERROR: get_assembly_dependencies: Cannot load assembly (refonly): 'Xamarin.iOS'.
   At: modules/mono/editor/godotsharp_export.cpp:95.
ERROR: get_assembly_dependencies: Cannot load one of the dependencies for the assembly: 'System.Net.Http'.
   At: modules/mono/editor/godotsharp_export.cpp:101.
ERROR: get_assembly_dependencies: Cannot load one of the dependencies for the assembly: 'netstandard'.
   At: modules/mono/editor/godotsharp_export.cpp:101.
ERROR: get_assembly_dependencies: Cannot load one of the dependencies for the assembly: 'GodotSharp'.
   At: modules/mono/editor/godotsharp_export.cpp:101.
...
Mono Ahead of Time compiler - compiling assembly .../templates/3.2.4.rc.mono/bcl/monotouch/mscorlib.dll
AOTID F12C237B-BFE9-6086-0021-B7CC6351E341
Runtime critical type Mono.RuntimeStructs/MonoError not found
ERROR: godot_icall_GD_pusherror: Failed to export project: Mono AOT compiler exited with code: 134
   At: modules/mono/glue/gd_glue.cpp:250.
System.Exception: Mono AOT compiler exited with code: 134
  at GodotTools.Export.AotBuilder.ExecuteCompiler (System.String compiler, System.Collections.Generic.IEnumerable`1[T] compilerArgs, System.String bclDir) [0x000bf] in <b1838b89851c4ef982e5ced7f8601cd1>:0 
  at GodotTools.Export.AotBuilder.CompileAssembliesForiOS (GodotTools.Export.ExportPlugin exporter, System.Boolean isDebug, System.String[] architectures, GodotTools.Export.AotOptions aotOpts, System.String aotTempDir, System.Collections.Generic.IDictionary`2[TKey,TValue] assemblies, System.String bclDir) [0x00104] in <b1838b89851c4ef982e5ced7f8601cd1>:0 
  at GodotTools.Export.AotBuilder.CompileAssemblies (GodotTools.Export.ExportPlugin exporter, GodotTools.Export.AotOptions aotOpts, System.String[] features, System.String platform, System.Boolean isDebug, System.String bclDir, System.String outputDir, System.String outputDataDir, System.Collections.Generic.IDictionary`2[TKey,TValue] assemblies) [0x000db] in <b1838b89851c4ef982e5ced7f8601cd1>:0 
  at GodotTools.Export.ExportPlugin._ExportBeginImpl (System.String[] features, System.Boolean isDebug, System.String path, System.Int32 flags) [0x004ae] in <b1838b89851c4ef982e5ced7f8601cd1>:0 
  at GodotTools.Export.ExportPlugin._ExportBegin (System.String[] features, System.Boolean isDebug, System.String path, System.Int32 flags) [0x0000b] in <b1838b89851c4ef982e5ced7f8601cd1>:0 

I guess this log should give more info :)

@naithar
Copy link
Contributor

naithar commented Jan 28, 2021

This issue could be related: #42378.
At least Runtime critical type Mono.RuntimeStructs/MonoError not found error seems to be the same.
Maybe mono version should be downgraded?

@akien-mga
Copy link
Member

akien-mga commented Jan 28, 2021

There's this issue which seems related: #43065.

I thought it was I was still using a pre-built AOT cross-compiler from Mono 6.10 6.6 even though the rest of Mono was 6.12, but as of 3.2.4 RC 1 both Mono and the pre-built AOT cross-compiler are from the same 6.12.0.114.

@naithar
Copy link
Contributor

naithar commented Jan 28, 2021

There's this issue which seems related: #43065.

Yeah, that's the issue that gets fixed by manually linking the libraries.

3.2.3 also misses a library if there is no C# script in Godot project, but when even an empty script is added everything works fine.
Which Mono version was used for 3.2.3 release?

@akien-mga
Copy link
Member

Which Mono version was used for 3.2.3 release?

6.6.0.166 I think. At least that's what the 3.2.3 RC 6 post mentions: https://godotengine.org/article/release-candidate-godot-3-2-3-rc-6

Then 3.2.4 beta moved to 6.12.x, which might indeed be part of the issue.

@naithar
Copy link
Contributor

naithar commented Jan 29, 2021

Tested 6.4.0 version. Same issue.

@naithar
Copy link
Contributor

naithar commented Jan 29, 2021

I've noticed that I'm also getting It was not possible to find any installed .NET Core SDKs warning. Installing .NET Core removed the warning, but still didn't fix the error. Reverting mono module to 3.2.3 stable version also didn't help - getting same Runtime critical type Mono.RuntimeStructs/MonoError not found error on export.

@naithar
Copy link
Contributor

naithar commented Jan 29, 2021

After Installing Xamarin export fails silently and doesn't give any error anymore.
There are also this error now:


Unhandled Exception:
System.TypeInitializationException: The type initializer for 'System.IO.Path' threw an exception. ---> System.TypeInitializationException: The type initializer for 'System.IO.MonoIO' threw an exception. ---> System.MissingMethodException:  assembly:<unknown assembly> type:<unknown type> member:(null)
  at (wrapper managed-to-native) Mono.SafeStringMarshal.StringToUtf8(string)
  at Mono.SafeStringMarshal.get_Value () [0x0001a] in <cf2ee04626774e668283f5d5669b38b8>:0 
  at System.Environment.internalGetEnvironmentVariable (System.String variable) [0x0000c] in <cf2ee04626774e668283f5d5669b38b8>:0 
  at System.Environment.GetEnvironmentVariable (System.String variable) [0x00000] in <cf2ee04626774e668283f5d5669b38b8>:0 
  at System.IO.MonoIO..cctor () [0x0000c] in <cf2ee04626774e668283f5d5669b38b8>:0 
   --- End of inner exception stack trace ---
  at System.IO.Path..cctor () [0x00021] in <cf2ee04626774e668283f5d5669b38b8>:0 
   --- End of inner exception stack trace ---
  at System.IO.File.Exists (System.String path) [0x00013] in <cf2ee04626774e668283f5d5669b38b8>:0 
  at GodotTools.Utils.File.Exists (System.String path) [0x00006] in <d651d08a41ab4937bb48b0e2dc9dfd78>:0 
  at GodotTools.GodotSharpEditor.EnablePlugin () [0x00233] in <d651d08a41ab4937bb48b0e2dc9dfd78>:0 
ERROR: debug_send_unhandled_exception_error: System.TypeInitializationException: The type initializer for 'System.IO.Path' threw an exception.
   At: modules/mono/mono_gd/gd_mono_utils.cpp:371.

...

Unhandled Exception:
System.NullReferenceException: Object reference not set to an instance of an object
  at GodotTools.HotReloadAssemblyWatcher.RestartTimer () [0x00000] in <d651d08a41ab4937bb48b0e2dc9dfd78>:0 
  at GodotTools.HotReloadAssemblyWatcher._Notification (System.Int32 what) [0x00008] in <d651d08a41ab4937bb48b0e2dc9dfd78>:0 
ERROR: debug_send_unhandled_exception_error: System.NullReferenceException: Object reference not set to an instance of an object
   At: modules/mono/mono_gd/gd_mono_utils.cpp:371.

Unhandled Exception:
System.NullReferenceException: Object reference not set to an instance of an object
  at GodotTools.HotReloadAssemblyWatcher.RestartTimer () [0x00000] in <d651d08a41ab4937bb48b0e2dc9dfd78>:0 
  at GodotTools.HotReloadAssemblyWatcher._Notification (System.Int32 what) [0x00008] in <d651d08a41ab4937bb48b0e2dc9dfd78>:0 
  at (wrapper managed-to-native) System.Threading.Monitor.Exit(object)
  at Godot.GodotTaskScheduler.ExecuteQueuedTasks () [0x00050] in <128686e36e4345c892524365e31d2d29>:0 
  at Godot.GodotTaskScheduler.Activate () [0x00001] in <128686e36e4345c892524365e31d2d29>:0 
  at (wrapper native-to-managed) Godot.GodotTaskScheduler.Activate(Godot.GodotTaskScheduler,System.Exception&)

@naithar
Copy link
Contributor

naithar commented Jan 29, 2021

Okay, so in the end it seems like installing Xamarin fixed the issue. Reverting mono module back to the current 3.2 state and recompiling seems to be fixing the error that popped during export.

But exported project is broken:

  • XCFrameworks are embedded, while they shouldn't as they contain .a libraries
  • Mono libraries are linked multiple times.
  • -force_load doest seem to like .xcframework values. Also it seems like it should be libmonosgen that needs to be force loaded. So changing to -force_load "$(SRCROOT)/libmonosgen-2.0.xcframework/ios-arm64/libmonosgen.a" seems to be fixing this compilation problem. But I don't think that will work for simulators.
    Maybe using something like this would work:
    OTHER_LDFLAGS = (
        "-rdynamic",
        "-force_load",
        "\"$(SRCROOT)/libmonosgen-2.0.xcframework/ios-arm64/libmonosgen.a\"",
    );
    "OTHER_LDFLAGS[sdk=iphoneos*]" = (
        "-rdynamic",
        "-force_load",
        "\"$(SRCROOT)/libmonosgen-2.0.xcframework/ios-arm64/libmonosgen.a\"",
    );
    "OTHER_LDFLAGS[sdk=iphonesimulator*]" = (
        "-rdynamic",
        "-force_load",
        "\"$(SRCROOT)/libmonosgen-2.0.xcframework/ios-arm64_x86_64-simulator/libmonosgen.a\"",
    );
    

Edit:

This patch seems to fix incorrect Xcode project. But if -force_load should be used, I guess some changes should be made, so linker flags could be enabled for specific config, like [sdk=iphonesimulator*].

diff --git a/modules/mono/editor/GodotTools/GodotTools/Export/AotBuilder.cs b/modules/mono/editor/GodotTools/GodotTools/Export/AotBuilder.cs
index 372cccc46e..c3b259192b 100644
--- a/modules/mono/editor/GodotTools/GodotTools/Export/AotBuilder.cs
+++ b/modules/mono/editor/GodotTools/GodotTools/Export/AotBuilder.cs
@@ -371,7 +371,7 @@ MONO_AOT_MODE_LAST = 1000,
             // functions in System.Native/libmono-native). Instead, we should use cecil to search for
             // DllImports in assemblies and pass them to 'ld' as '-u/--undefined {pinvoke_symbol}'.
             exporter.AddIosLinkerFlags("-rdynamic");
-            exporter.AddIosLinkerFlags($"-force_load \"$(SRCROOT)/{MonoFrameworkFile("libmono-native")}\"");
+            exporter.AddIosLinkerFlags($"-force_load \"$(SRCROOT)/{MonoFrameworkFile("libmonosgen-2.0")}/ios-arm64/libmonosgen.a\"");
         }
 
         /// Converts an assembly name to a valid symbol name in the same way the AOT compiler does
diff --git a/platform/iphone/export/export.cpp b/platform/iphone/export/export.cpp
index fcd2fc74b7..78e7518a49 100644
--- a/platform/iphone/export/export.cpp
+++ b/platform/iphone/export/export.cpp
@@ -1177,9 +1177,10 @@ Error EditorExportPlatformIOS::_export_additional_assets(const String &p_out_dir
                ERR_FAIL_COND_V(err, err);
 
                Vector<String> project_static_libs = export_plugins[i]->get_ios_project_static_libs();
-               for (int j = 0; j < project_static_libs.size(); j++)
+               for (int j = 0; j < project_static_libs.size(); j++) {
                        project_static_libs.write[j] = project_static_libs[j].get_file(); // Only the file name as it's copied to the project
-               err = _export_additional_assets(p_out_dir, project_static_libs, true, true, r_exported_assets);
+               }
+               err = _export_additional_assets(p_out_dir, project_static_libs, true, false, r_exported_assets);
                ERR_FAIL_COND_V(err, err);
 
                Vector<String> ios_bundle_files = export_plugins[i]->get_ios_bundle_files();

Edit 2:

On the other hand it seems like the problem could be linked to application signing.
Before export actually managed to complete correctly I've had to allow access to some aot program in macOS security settings.

Base automatically changed from 3.2 to 3.x March 16, 2021 11:11
@aaronfranke aaronfranke modified the milestones: 3.2, 3.3 Mar 16, 2021
@akien-mga akien-mga changed the title [WIP, 3.2] Build and export iOS Mono libs as .xcframeworks, for M1 iOS simulator support. [WIP, 3.x] Build and export iOS Mono libs as .xcframeworks, for M1 iOS simulator support. Mar 26, 2021
@bruvzg
Copy link
Member Author

bruvzg commented Jun 2, 2021

Superseded by #49248

@bruvzg bruvzg closed this Jun 2, 2021
@bruvzg bruvzg deleted the ios_mono_xcf branch November 5, 2021 13:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants