diff --git a/misc/dist/iphone-mono-libs/libmono-ee-interp.xcframework/Info.plist b/misc/dist/iphone-mono-libs/libmono-ee-interp.xcframework/Info.plist
new file mode 100644
index 00000000000..85b0b982098
--- /dev/null
+++ b/misc/dist/iphone-mono-libs/libmono-ee-interp.xcframework/Info.plist
@@ -0,0 +1,40 @@
+
+
+
+
+ AvailableLibraries
+
+
+ LibraryIdentifier
+ ios-arm64
+ LibraryPath
+ libmono-ee-interp.a
+ SupportedArchitectures
+
+ arm64
+
+ SupportedPlatform
+ ios
+
+
+ LibraryIdentifier
+ ios-arm64_x86_64-simulator
+ LibraryPath
+ libmono-ee-interp.a
+ SupportedArchitectures
+
+ arm64
+ x86_64
+
+ SupportedPlatform
+ ios
+ SupportedPlatformVariant
+ simulator
+
+
+ CFBundlePackageType
+ XFWK
+ XCFrameworkFormatVersion
+ 1.0
+
+
diff --git a/misc/dist/iphone-mono-libs/libmono-ee-interp.xcframework/ios-arm64/empty b/misc/dist/iphone-mono-libs/libmono-ee-interp.xcframework/ios-arm64/empty
new file mode 100644
index 00000000000..bd3e8943336
--- /dev/null
+++ b/misc/dist/iphone-mono-libs/libmono-ee-interp.xcframework/ios-arm64/empty
@@ -0,0 +1 @@
+Dummy file to make dylibs folder exported
diff --git a/misc/dist/iphone-mono-libs/libmono-ee-interp.xcframework/ios-arm64_x86_64-simulator/empty b/misc/dist/iphone-mono-libs/libmono-ee-interp.xcframework/ios-arm64_x86_64-simulator/empty
new file mode 100644
index 00000000000..bd3e8943336
--- /dev/null
+++ b/misc/dist/iphone-mono-libs/libmono-ee-interp.xcframework/ios-arm64_x86_64-simulator/empty
@@ -0,0 +1 @@
+Dummy file to make dylibs folder exported
diff --git a/misc/dist/iphone-mono-libs/libmono-icall-table.xcframework/Info.plist b/misc/dist/iphone-mono-libs/libmono-icall-table.xcframework/Info.plist
new file mode 100644
index 00000000000..feadce5e97d
--- /dev/null
+++ b/misc/dist/iphone-mono-libs/libmono-icall-table.xcframework/Info.plist
@@ -0,0 +1,40 @@
+
+
+
+
+ AvailableLibraries
+
+
+ LibraryIdentifier
+ ios-arm64
+ LibraryPath
+ libmono-icall-table.a
+ SupportedArchitectures
+
+ arm64
+
+ SupportedPlatform
+ ios
+
+
+ LibraryIdentifier
+ ios-arm64_x86_64-simulator
+ LibraryPath
+ libmono-icall-table.a
+ SupportedArchitectures
+
+ arm64
+ x86_64
+
+ SupportedPlatform
+ ios
+ SupportedPlatformVariant
+ simulator
+
+
+ CFBundlePackageType
+ XFWK
+ XCFrameworkFormatVersion
+ 1.0
+
+
diff --git a/misc/dist/iphone-mono-libs/libmono-icall-table.xcframework/ios-arm64/empty b/misc/dist/iphone-mono-libs/libmono-icall-table.xcframework/ios-arm64/empty
new file mode 100644
index 00000000000..bd3e8943336
--- /dev/null
+++ b/misc/dist/iphone-mono-libs/libmono-icall-table.xcframework/ios-arm64/empty
@@ -0,0 +1 @@
+Dummy file to make dylibs folder exported
diff --git a/misc/dist/iphone-mono-libs/libmono-icall-table.xcframework/ios-arm64_x86_64-simulator/empty b/misc/dist/iphone-mono-libs/libmono-icall-table.xcframework/ios-arm64_x86_64-simulator/empty
new file mode 100644
index 00000000000..bd3e8943336
--- /dev/null
+++ b/misc/dist/iphone-mono-libs/libmono-icall-table.xcframework/ios-arm64_x86_64-simulator/empty
@@ -0,0 +1 @@
+Dummy file to make dylibs folder exported
diff --git a/misc/dist/iphone-mono-libs/libmono-ilgen.xcframework/Info.plist b/misc/dist/iphone-mono-libs/libmono-ilgen.xcframework/Info.plist
new file mode 100644
index 00000000000..95abbe7a94f
--- /dev/null
+++ b/misc/dist/iphone-mono-libs/libmono-ilgen.xcframework/Info.plist
@@ -0,0 +1,40 @@
+
+
+
+
+ AvailableLibraries
+
+
+ LibraryIdentifier
+ ios-arm64
+ LibraryPath
+ libmono-ilgen.a
+ SupportedArchitectures
+
+ arm64
+
+ SupportedPlatform
+ ios
+
+
+ LibraryIdentifier
+ ios-arm64_x86_64-simulator
+ LibraryPath
+ libmono-ilgen.a
+ SupportedArchitectures
+
+ arm64
+ x86_64
+
+ SupportedPlatform
+ ios
+ SupportedPlatformVariant
+ simulator
+
+
+ CFBundlePackageType
+ XFWK
+ XCFrameworkFormatVersion
+ 1.0
+
+
diff --git a/misc/dist/iphone-mono-libs/libmono-ilgen.xcframework/ios-arm64/empty b/misc/dist/iphone-mono-libs/libmono-ilgen.xcframework/ios-arm64/empty
new file mode 100644
index 00000000000..bd3e8943336
--- /dev/null
+++ b/misc/dist/iphone-mono-libs/libmono-ilgen.xcframework/ios-arm64/empty
@@ -0,0 +1 @@
+Dummy file to make dylibs folder exported
diff --git a/misc/dist/iphone-mono-libs/libmono-ilgen.xcframework/ios-arm64_x86_64-simulator/empty b/misc/dist/iphone-mono-libs/libmono-ilgen.xcframework/ios-arm64_x86_64-simulator/empty
new file mode 100644
index 00000000000..bd3e8943336
--- /dev/null
+++ b/misc/dist/iphone-mono-libs/libmono-ilgen.xcframework/ios-arm64_x86_64-simulator/empty
@@ -0,0 +1 @@
+Dummy file to make dylibs folder exported
diff --git a/modules/mono/editor/GodotTools/GodotTools/Export/AotBuilder.cs b/modules/mono/editor/GodotTools/GodotTools/Export/AotBuilder.cs
index 372cccc46ec..92aeb25e7ac 100644
--- a/modules/mono/editor/GodotTools/GodotTools/Export/AotBuilder.cs
+++ b/modules/mono/editor/GodotTools/GodotTools/Export/AotBuilder.cs
@@ -22,7 +22,12 @@ namespace GodotTools.Export
public bool FullAot;
private bool _useInterpreter;
- public bool UseInterpreter { get => _useInterpreter && !LLVMOnly; set => _useInterpreter = value; }
+
+ public bool UseInterpreter
+ {
+ get => _useInterpreter && !LLVMOnly;
+ set => _useInterpreter = value;
+ }
public string[] ExtraAotOptions;
public string[] ExtraOptimizerOptions;
@@ -82,7 +87,6 @@ namespace GodotTools.Export
public static void CompileAssembliesForAndroid(ExportPlugin exporter, bool isDebug, string[] abis, AotOptions aotOpts, string aotTempDir, IDictionary assemblies, string bclDir)
{
-
foreach (var assembly in assemblies)
{
string assemblyName = assembly.Key;
@@ -107,7 +111,7 @@ namespace GodotTools.Export
ExecuteCompiler(FindCrossCompiler(compilerDirPath), compilerArgs, bclDir);
// The Godot exporter expects us to pass the abi in the tags parameter
- exporter.AddSharedObject(soFilePath, tags: new[] { abi });
+ exporter.AddSharedObject(soFilePath, tags: new[] {abi});
}
}
}
@@ -146,11 +150,101 @@ namespace GodotTools.Export
public static void CompileAssembliesForiOS(ExportPlugin exporter, bool isDebug, string[] architectures, AotOptions aotOpts, string aotTempDir, IDictionary assemblies, string bclDir)
{
+ void RunAr(IEnumerable objFilePaths, string outputFilePath)
+ {
+ var arArgs = new List()
+ {
+ "cr",
+ outputFilePath
+ };
+
+ foreach (string objFilePath in objFilePaths)
+ arArgs.Add(objFilePath);
+
+ int arExitCode = OS.ExecuteCommand(XcodeHelper.FindXcodeTool("ar"), arArgs);
+ if (arExitCode != 0)
+ throw new Exception($"Command 'ar' exited with code: {arExitCode}");
+ }
+
+ void RunLipo(IEnumerable libFilePaths, string outputFilePath)
+ {
+ var lipoArgs = new List();
+ lipoArgs.Add("-create");
+ lipoArgs.AddRange(libFilePaths);
+ lipoArgs.Add("-output");
+ lipoArgs.Add(outputFilePath);
+
+ int lipoExitCode = OS.ExecuteCommand(XcodeHelper.FindXcodeTool("lipo"), lipoArgs);
+ if (lipoExitCode != 0)
+ throw new Exception($"Command 'lipo' exited with code: {lipoExitCode}");
+ }
+
+ void CreateDummyLibForSimulator(string name, string xcFrameworkPath = null)
+ {
+ xcFrameworkPath = xcFrameworkPath ?? MonoFrameworkFromTemplate(name);
+ string simulatorSubDir = Path.Combine(xcFrameworkPath, "ios-arm64_x86_64-simulator");
+
+ string libFilePath = Path.Combine(simulatorSubDir, name + ".a");
+
+ if (File.Exists(libFilePath))
+ return;
+
+ string CompileForArch(string arch)
+ {
+ string baseFilePath = Path.Combine(aotTempDir, $"{name}.{arch}");
+ string sourceFilePath = baseFilePath + ".c";
+
+ string source = $"int _{AssemblyNameToAotSymbol(name)}() {{ return 0; }}\n";
+ File.WriteAllText(sourceFilePath, source);
+
+ const string iOSPlatformName = "iPhoneSimulator";
+ const string versionMin = "10.0";
+ string iOSSdkPath = Path.Combine(XcodeHelper.XcodePath,
+ $"Contents/Developer/Platforms/{iOSPlatformName}.platform/Developer/SDKs/{iOSPlatformName}.sdk");
+
+ string objFilePath = baseFilePath + ".o";
+
+ var clangArgs = new[]
+ {
+ "-isysroot", iOSSdkPath,
+ $"-miphonesimulator-version-min={versionMin}",
+ "-arch", arch,
+ "-c",
+ "-o", objFilePath,
+ sourceFilePath
+ };
+
+ int clangExitCode = OS.ExecuteCommand(XcodeHelper.FindXcodeTool("clang"), clangArgs);
+ if (clangExitCode != 0)
+ throw new Exception($"Command 'clang' exited with code: {clangExitCode}");
+
+ string arOutputFilePath = Path.Combine(aotTempDir, baseFilePath + ".a");
+ RunAr(new[] {objFilePath}, arOutputFilePath);
+
+ return arOutputFilePath;
+ }
+
+ RunLipo(new[] {CompileForArch("arm64"), CompileForArch("x86_64")}, libFilePath);
+ }
+
+ string projectAssemblyName = GodotSharpEditor.ProjectAssemblyName;
+ string libAotName = $"lib-aot-{projectAssemblyName}";
+
+ string libAotXcFrameworkPath = Path.Combine(aotTempDir, $"{libAotName}.xcframework");
+ string libAotXcFrameworkDevicePath = Path.Combine(libAotXcFrameworkPath, "ios-arm64");
+ string libAotXcFrameworkSimPath = Path.Combine(libAotXcFrameworkPath, "ios-arm64_x86_64-simulator");
+
+ Directory.CreateDirectory(libAotXcFrameworkPath);
+ Directory.CreateDirectory(libAotXcFrameworkDevicePath);
+ Directory.CreateDirectory(libAotXcFrameworkSimPath);
+
+ string libAotFileName = $"{libAotName}.a";
+ string libAotFilePath = Path.Combine(libAotXcFrameworkDevicePath, libAotFileName);
+
var cppCode = new StringBuilder();
var aotModuleInfoSymbols = new List(assemblies.Count);
- // {arch: paths}
- var objFilePathsForiOSArch = architectures.ToDictionary(arch => arch, arch => new List(assemblies.Count));
+ var aotObjFilePaths = new List(assemblies.Count);
foreach (var assembly in assemblies)
{
@@ -160,36 +254,29 @@ namespace GodotTools.Export
string asmFileName = assemblyName + ".dll.S";
string objFileName = assemblyName + ".dll.o";
- foreach (string arch in architectures)
{
- string aotArchTempDir = Path.Combine(aotTempDir, arch);
- string asmFilePath = Path.Combine(aotArchTempDir, asmFileName);
+ string asmFilePath = Path.Combine(aotTempDir, asmFileName);
- var compilerArgs = GetAotCompilerArgs(OS.Platforms.iOS, isDebug, arch, aotOpts, assemblyPath, asmFilePath);
+ var compilerArgs = GetAotCompilerArgs(OS.Platforms.iOS, isDebug, "arm64", aotOpts, assemblyPath, asmFilePath);
- // Make sure the output directory exists
- Directory.CreateDirectory(aotArchTempDir);
-
- string compilerDirPath = Path.Combine(GodotSharpDirs.DataEditorToolsDir, "aot-compilers", $"{OS.Platforms.iOS}-{arch}");
+ string compilerDirPath = Path.Combine(GodotSharpDirs.DataEditorToolsDir, "aot-compilers", $"{OS.Platforms.iOS}-arm64");
ExecuteCompiler(FindCrossCompiler(compilerDirPath), compilerArgs, bclDir);
// Assembling
- bool isSim = arch == "i386" || arch == "x86_64"; // Shouldn't really happen as we don't do AOT for the simulator
- string versionMinName = isSim ? "iphonesimulator" : "iphoneos";
- string iOSPlatformName = isSim ? "iPhoneSimulator" : "iPhoneOS";
+ const string iOSPlatformName = "iPhoneOS";
const string versionMin = "10.0"; // TODO: Turn this hard-coded version into an exporter setting
string iOSSdkPath = Path.Combine(XcodeHelper.XcodePath,
- $"Contents/Developer/Platforms/{iOSPlatformName}.platform/Developer/SDKs/{iOSPlatformName}.sdk");
+ $"Contents/Developer/Platforms/{iOSPlatformName}.platform/Developer/SDKs/{iOSPlatformName}.sdk");
- string objFilePath = Path.Combine(aotArchTempDir, objFileName);
+ string objFilePath = Path.Combine(aotTempDir, objFileName);
var clangArgs = new List()
{
"-isysroot", iOSSdkPath,
"-Qunused-arguments",
- $"-m{versionMinName}-version-min={versionMin}",
- "-arch", arch,
+ $"-miphoneos-version-min={versionMin}",
+ "-arch", "arm64",
"-c",
"-o", objFilePath,
"-x", "assembler"
@@ -204,18 +291,67 @@ namespace GodotTools.Export
if (clangExitCode != 0)
throw new Exception($"Command 'clang' exited with code: {clangExitCode}");
- objFilePathsForiOSArch[arch].Add(objFilePath);
+ aotObjFilePaths.Add(objFilePath);
}
aotModuleInfoSymbols.Add($"mono_aot_module_{AssemblyNameToAotSymbol(assemblyName)}_info");
}
- // Generate driver code
- cppCode.AppendLine("#if defined(__arm__) || defined(__arm64__) || defined(__aarch64__)");
- cppCode.AppendLine("#define IOS_DEVICE");
- cppCode.AppendLine("#endif");
+ RunAr(aotObjFilePaths, libAotFilePath);
- cppCode.AppendLine("#ifdef IOS_DEVICE");
+ // Archive the AOT object files into a static library
+
+ File.WriteAllText(Path.Combine(libAotXcFrameworkPath, "Info.plist"),
+ $@"
+
+
+
+ AvailableLibraries
+
+
+ LibraryIdentifier
+ ios-arm64
+ LibraryPath
+ {libAotFileName}
+ SupportedArchitectures
+
+ arm64
+
+ SupportedPlatform
+ ios
+
+
+ LibraryIdentifier
+ ios-arm64_x86_64-simulator
+ LibraryPath
+ {libAotFileName}
+ SupportedArchitectures
+
+ arm64
+ x86_64
+
+ SupportedPlatform
+ ios
+ SupportedPlatformVariant
+ simulator
+
+
+ CFBundlePackageType
+ XFWK
+ XCFrameworkFormatVersion
+ 1.0
+
+
+");
+
+ // Add the fat AOT static library to the Xcode project
+ CreateDummyLibForSimulator(libAotName, libAotXcFrameworkPath);
+ exporter.AddIosProjectStaticLib(libAotXcFrameworkPath);
+
+ // Generate driver code
+ cppCode.AppendLine("#include ");
+
+ cppCode.AppendLine("#if !TARGET_OS_SIMULATOR");
cppCode.AppendLine("extern \"C\" {");
cppCode.AppendLine("// Mono API");
cppCode.AppendLine(@"
@@ -280,59 +416,11 @@ MONO_AOT_MODE_LAST = 1000,
cppCode.AppendLine("} // gd_mono_setup_aot");
cppCode.AppendLine("} // extern \"C\"");
- cppCode.AppendLine("#endif // IOS_DEVICE");
+ cppCode.AppendLine("#endif // !TARGET_OS_SIMULATOR");
// Add the driver code to the Xcode project
exporter.AddIosCppCode(cppCode.ToString());
- // Archive the AOT object files into a static library
-
- var arFilePathsForAllArchs = new List();
- string projectAssemblyName = GodotSharpEditor.ProjectAssemblyName;
-
- foreach (var archPathsPair in objFilePathsForiOSArch)
- {
- string arch = archPathsPair.Key;
- var objFilePaths = archPathsPair.Value;
-
- string arOutputFilePath = Path.Combine(aotTempDir, $"lib-aot-{projectAssemblyName}.{arch}.a");
-
- var arArgs = new List()
- {
- "cr",
- arOutputFilePath
- };
-
- foreach (string objFilePath in objFilePaths)
- arArgs.Add(objFilePath);
-
- int arExitCode = OS.ExecuteCommand(XcodeHelper.FindXcodeTool("ar"), arArgs);
- if (arExitCode != 0)
- throw new Exception($"Command 'ar' exited with code: {arExitCode}");
-
- arFilePathsForAllArchs.Add(arOutputFilePath);
- }
-
- // It's lipo time
-
- string fatOutputFileName = $"lib-aot-{projectAssemblyName}.fat.a";
- string fatOutputFilePath = Path.Combine(aotTempDir, fatOutputFileName);
-
- var lipoArgs = new List();
- lipoArgs.Add("-create");
- lipoArgs.AddRange(arFilePathsForAllArchs);
- lipoArgs.Add("-output");
- lipoArgs.Add(fatOutputFilePath);
-
- int lipoExitCode = OS.ExecuteCommand(XcodeHelper.FindXcodeTool("lipo"), lipoArgs);
- if (lipoExitCode != 0)
- throw new Exception($"Command 'lipo' exited with code: {lipoExitCode}");
-
- // TODO: Add the AOT lib and interpreter libs as device only to suppress warnings when targeting the simulator
-
- // Add the fat AOT static library to the Xcode project
- exporter.AddIosProjectStaticLib(fatOutputFilePath);
-
// Add the required Mono libraries to the Xcode project
string MonoLibFile(string libFileName) => libFileName + ".iphone.fat.a";
@@ -351,9 +439,12 @@ MONO_AOT_MODE_LAST = 1000,
if (aotOpts.UseInterpreter)
{
- exporter.AddIosProjectStaticLib(MonoLibFromTemplate("libmono-ee-interp"));
- exporter.AddIosProjectStaticLib(MonoLibFromTemplate("libmono-icall-table"));
- exporter.AddIosProjectStaticLib(MonoLibFromTemplate("libmono-ilgen"));
+ CreateDummyLibForSimulator("libmono-ee-interp");
+ exporter.AddIosProjectStaticLib(MonoFrameworkFromTemplate("libmono-ee-interp"));
+ CreateDummyLibForSimulator("libmono-icall-table");
+ exporter.AddIosProjectStaticLib(MonoFrameworkFromTemplate("libmono-icall-table"));
+ CreateDummyLibForSimulator("libmono-ilgen");
+ exporter.AddIosProjectStaticLib(MonoFrameworkFromTemplate("libmono-ilgen"));
}
// TODO: Turn into an exporter option
@@ -379,11 +470,8 @@ MONO_AOT_MODE_LAST = 1000,
{
var builder = new StringBuilder();
- foreach (var charByte in Encoding.UTF8.GetBytes(assemblyName))
- {
- char @char = (char)charByte;
- builder.Append(Char.IsLetterOrDigit(@char) || @char == '_' ? @char : '_');
- }
+ foreach (char @char in assemblyName)
+ builder.Append(char.IsLetterOrDigit(@char) || @char == '_' ? @char : '_');
return builder.ToString();
}
@@ -582,27 +670,27 @@ MONO_AOT_MODE_LAST = 1000,
{
case OS.Platforms.Windows:
case OS.Platforms.UWP:
- {
- string arch = bits == "64" ? "x86_64" : "i686";
- return $"windows-{arch}";
- }
+ {
+ string arch = bits == "64" ? "x86_64" : "i686";
+ return $"windows-{arch}";
+ }
case OS.Platforms.OSX:
- {
- Debug.Assert(bits == null || bits == "64");
- string arch = "x86_64";
- return $"{platform}-{arch}";
- }
+ {
+ Debug.Assert(bits == null || bits == "64");
+ string arch = "x86_64";
+ return $"{platform}-{arch}";
+ }
case OS.Platforms.X11:
case OS.Platforms.Server:
- {
- string arch = bits == "64" ? "x86_64" : "i686";
- return $"linux-{arch}";
- }
+ {
+ string arch = bits == "64" ? "x86_64" : "i686";
+ return $"linux-{arch}";
+ }
case OS.Platforms.Haiku:
- {
- string arch = bits == "64" ? "x86_64" : "i686";
- return $"{platform}-{arch}";
- }
+ {
+ string arch = bits == "64" ? "x86_64" : "i686";
+ return $"{platform}-{arch}";
+ }
default:
throw new NotSupportedException($"Platform not supported: {platform}");
}