Add separate `simulator` flag for iOS build, change main library to `xcframework`.

Build and export iOS Mono libs as `.xcframework`s, for Apple Silicon iOS simulator support.
This commit is contained in:
bruvzg 2021-01-26 16:55:34 +02:00 committed by Ignacio Roldán Etchevery
parent 92713854a5
commit 683f96df35
22 changed files with 260 additions and 23 deletions

View File

@ -8,7 +8,7 @@
/* Begin PBXBuildFile section */ /* Begin PBXBuildFile section */
1F1575721F582BE20003B888 /* dylibs in Resources */ = {isa = PBXBuildFile; fileRef = 1F1575711F582BE20003B888 /* dylibs */; }; 1F1575721F582BE20003B888 /* dylibs in Resources */ = {isa = PBXBuildFile; fileRef = 1F1575711F582BE20003B888 /* dylibs */; };
DEADBEEF2F582BE20003B888 /* $binary.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DEADBEEF1F582BE20003B888 /* $binary.a */; }; DEADBEEF2F582BE20003B888 /* $binary.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = DEADBEEF1F582BE20003B888 /* $binary.xcframework */; };
$modules_buildfile $modules_buildfile
1FF8DBB11FBA9DE1009DE660 /* dummy.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1FF8DBB01FBA9DE1009DE660 /* dummy.cpp */; }; 1FF8DBB11FBA9DE1009DE660 /* dummy.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1FF8DBB01FBA9DE1009DE660 /* dummy.cpp */; };
D07CD44E1C5D589C00B7FB28 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = D07CD44D1C5D589C00B7FB28 /* Images.xcassets */; }; D07CD44E1C5D589C00B7FB28 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = D07CD44D1C5D589C00B7FB28 /* Images.xcassets */; };
@ -33,7 +33,7 @@
/* Begin PBXFileReference section */ /* Begin PBXFileReference section */
1F1575711F582BE20003B888 /* dylibs */ = {isa = PBXFileReference; lastKnownFileType = folder; name = dylibs; path = "$binary/dylibs"; sourceTree = "<group>"; }; 1F1575711F582BE20003B888 /* dylibs */ = {isa = PBXFileReference; lastKnownFileType = folder; name = dylibs; path = "$binary/dylibs"; sourceTree = "<group>"; };
DEADBEEF1F582BE20003B888 /* $binary.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = godot; path = "$binary.a"; sourceTree = "<group>"; }; DEADBEEF1F582BE20003B888 /* $binary.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = godot; path = "$binary.xcframework"; sourceTree = "<group>"; };
$modules_fileref $modules_fileref
1FF4C1881F584E6300A41E41 /* $binary.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = "$binary.entitlements"; sourceTree = "<group>"; }; 1FF4C1881F584E6300A41E41 /* $binary.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = "$binary.entitlements"; sourceTree = "<group>"; };
1FF8DBB01FBA9DE1009DE660 /* dummy.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = dummy.cpp; sourceTree = "<group>"; }; 1FF8DBB01FBA9DE1009DE660 /* dummy.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = dummy.cpp; sourceTree = "<group>"; };
@ -52,7 +52,7 @@
isa = PBXFrameworksBuildPhase; isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
DEADBEEF2F582BE20003B888 /* $binary.a */, DEADBEEF2F582BE20003B888 /* $binary.xcframework */,
$modules_buildphase $modules_buildphase
$additional_pbx_frameworks_build $additional_pbx_frameworks_build
); );
@ -84,7 +84,7 @@
D0BCFE3618AEBDA2004A7AAE /* Frameworks */ = { D0BCFE3618AEBDA2004A7AAE /* Frameworks */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
DEADBEEF1F582BE20003B888 /* $binary.a */, DEADBEEF1F582BE20003B888 /* $binary.xcframework */,
$modules_buildgrp $modules_buildgrp
$additional_pbx_frameworks_refs $additional_pbx_frameworks_refs
); );

View File

@ -0,0 +1,40 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>AvailableLibraries</key>
<array>
<dict>
<key>LibraryIdentifier</key>
<string>ios-arm64</string>
<key>LibraryPath</key>
<string>libgodot.a</string>
<key>SupportedArchitectures</key>
<array>
<string>arm64</string>
</array>
<key>SupportedPlatform</key>
<string>ios</string>
</dict>
<dict>
<key>LibraryIdentifier</key>
<string>ios-arm64_x86_64-simulator</string>
<key>LibraryPath</key>
<string>libgodot.a</string>
<key>SupportedArchitectures</key>
<array>
<string>arm64</string>
<string>x86_64</string>
</array>
<key>SupportedPlatform</key>
<string>ios</string>
<key>SupportedPlatformVariant</key>
<string>simulator</string>
</dict>
</array>
<key>CFBundlePackageType</key>
<string>XFWK</string>
<key>XCFrameworkFormatVersion</key>
<string>1.0</string>
</dict>
</plist>

View File

@ -0,0 +1 @@
Dummy file to make dylibs folder exported

View File

@ -0,0 +1 @@
Dummy file to make dylibs folder exported

View File

@ -0,0 +1,40 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>AvailableLibraries</key>
<array>
<dict>
<key>LibraryIdentifier</key>
<string>ios-arm64</string>
<key>LibraryPath</key>
<string>libgodot.a</string>
<key>SupportedArchitectures</key>
<array>
<string>arm64</string>
</array>
<key>SupportedPlatform</key>
<string>ios</string>
</dict>
<dict>
<key>LibraryIdentifier</key>
<string>ios-arm64_x86_64-simulator</string>
<key>LibraryPath</key>
<string>libgodot.a</string>
<key>SupportedArchitectures</key>
<array>
<string>arm64</string>
<string>x86_64</string>
</array>
<key>SupportedPlatform</key>
<string>ios</string>
<key>SupportedPlatformVariant</key>
<string>simulator</string>
</dict>
</array>
<key>CFBundlePackageType</key>
<string>XFWK</string>
<key>XCFrameworkFormatVersion</key>
<string>1.0</string>
</dict>
</plist>

View File

@ -0,0 +1 @@
Dummy file to make dylibs folder exported

View File

@ -0,0 +1 @@
Dummy file to make dylibs folder exported

View File

@ -0,0 +1,40 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>AvailableLibraries</key>
<array>
<dict>
<key>LibraryIdentifier</key>
<string>ios-arm64</string>
<key>LibraryPath</key>
<string>libmono-native.a</string>
<key>SupportedArchitectures</key>
<array>
<string>arm64</string>
</array>
<key>SupportedPlatform</key>
<string>ios</string>
</dict>
<dict>
<key>LibraryIdentifier</key>
<string>ios-arm64_x86_64-simulator</string>
<key>LibraryPath</key>
<string>libmono-native.a</string>
<key>SupportedArchitectures</key>
<array>
<string>arm64</string>
<string>x86_64</string>
</array>
<key>SupportedPlatform</key>
<string>ios</string>
<key>SupportedPlatformVariant</key>
<string>simulator</string>
</dict>
</array>
<key>CFBundlePackageType</key>
<string>XFWK</string>
<key>XCFrameworkFormatVersion</key>
<string>1.0</string>
</dict>
</plist>

View File

@ -0,0 +1 @@
Dummy file to make dylibs folder exported

View File

@ -0,0 +1 @@
Dummy file to make dylibs folder exported

View File

@ -0,0 +1,40 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>AvailableLibraries</key>
<array>
<dict>
<key>LibraryIdentifier</key>
<string>ios-arm64</string>
<key>LibraryPath</key>
<string>libmono-profiler-log.a</string>
<key>SupportedArchitectures</key>
<array>
<string>arm64</string>
</array>
<key>SupportedPlatform</key>
<string>ios</string>
</dict>
<dict>
<key>LibraryIdentifier</key>
<string>ios-arm64_x86_64-simulator</string>
<key>LibraryPath</key>
<string>libmono-profiler-log.a</string>
<key>SupportedArchitectures</key>
<array>
<string>arm64</string>
<string>x86_64</string>
</array>
<key>SupportedPlatform</key>
<string>ios</string>
<key>SupportedPlatformVariant</key>
<string>simulator</string>
</dict>
</array>
<key>CFBundlePackageType</key>
<string>XFWK</string>
<key>XCFrameworkFormatVersion</key>
<string>1.0</string>
</dict>
</plist>

View File

@ -0,0 +1 @@
Dummy file to make dylibs folder exported

View File

@ -0,0 +1 @@
Dummy file to make dylibs folder exported

View File

@ -0,0 +1,40 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>AvailableLibraries</key>
<array>
<dict>
<key>LibraryIdentifier</key>
<string>ios-arm64</string>
<key>LibraryPath</key>
<string>libmonosgen.a</string>
<key>SupportedArchitectures</key>
<array>
<string>arm64</string>
</array>
<key>SupportedPlatform</key>
<string>ios</string>
</dict>
<dict>
<key>LibraryIdentifier</key>
<string>ios-arm64_x86_64-simulator</string>
<key>LibraryPath</key>
<string>libmonosgen.a</string>
<key>SupportedArchitectures</key>
<array>
<string>arm64</string>
<string>x86_64</string>
</array>
<key>SupportedPlatform</key>
<string>ios</string>
<key>SupportedPlatformVariant</key>
<string>simulator</string>
</dict>
</array>
<key>CFBundlePackageType</key>
<string>XFWK</string>
<key>XCFrameworkFormatVersion</key>
<string>1.0</string>
</dict>
</plist>

View File

@ -0,0 +1 @@
Dummy file to make dylibs folder exported

View File

@ -0,0 +1 @@
Dummy file to make dylibs folder exported

View File

@ -86,7 +86,7 @@ def configure(env, env_mono):
is_android = env["platform"] == "android" is_android = env["platform"] == "android"
is_javascript = env["platform"] == "javascript" is_javascript = env["platform"] == "javascript"
is_ios = env["platform"] == "iphone" is_ios = env["platform"] == "iphone"
is_ios_sim = is_ios and env["arch"] in ["x86", "x86_64"] is_ios_sim = is_ios and env["ios_simulator"]
tools_enabled = env["tools"] tools_enabled = env["tools"]
mono_static = env["mono_static"] mono_static = env["mono_static"]
@ -271,8 +271,19 @@ def configure(env, env_mono):
arch = env["arch"] arch = env["arch"]
def copy_mono_lib(libname_wo_ext): def copy_mono_lib(libname_wo_ext):
if is_ios_sim:
copy_file( copy_file(
mono_lib_path, "#bin", libname_wo_ext + ".a", "%s.iphone.%s.a" % (libname_wo_ext, arch) mono_lib_path,
"#bin",
libname_wo_ext + ".a",
"%s.iphone.%s.simulator.a" % (libname_wo_ext, arch),
)
else:
copy_file(
mono_lib_path,
"#bin",
libname_wo_ext + ".a",
"%s.iphone.%s.a" % (libname_wo_ext, arch),
) )
# Copy Mono libraries to the output folder. These are meant to be bundled with # Copy Mono libraries to the output folder. These are meant to be bundled with

View File

@ -340,9 +340,14 @@ MONO_AOT_MODE_LAST = 1000,
string MonoLibFromTemplate(string libFileName) => string MonoLibFromTemplate(string libFileName) =>
Path.Combine(Internal.FullTemplatesDir, "iphone-mono-libs", MonoLibFile(libFileName)); Path.Combine(Internal.FullTemplatesDir, "iphone-mono-libs", MonoLibFile(libFileName));
exporter.AddIosProjectStaticLib(MonoLibFromTemplate("libmonosgen-2.0")); string MonoFrameworkFile(string frameworkFileName) => frameworkFileName + ".xcframework";
exporter.AddIosProjectStaticLib(MonoLibFromTemplate("libmono-native")); string MonoFrameworkFromTemplate(string frameworkFileName) =>
Path.Combine(Internal.FullTemplatesDir, "iphone-mono-libs", MonoFrameworkFile(frameworkFileName));
exporter.AddIosProjectStaticLib(MonoFrameworkFromTemplate("libmonosgen-2.0"));
exporter.AddIosProjectStaticLib(MonoFrameworkFromTemplate("libmono-native"));
if (aotOpts.UseInterpreter) if (aotOpts.UseInterpreter)
{ {
@ -366,7 +371,7 @@ MONO_AOT_MODE_LAST = 1000,
// functions in System.Native/libmono-native). Instead, we should use cecil to search for // 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}'. // DllImports in assemblies and pass them to 'ld' as '-u/--undefined {pinvoke_symbol}'.
exporter.AddIosLinkerFlags("-rdynamic"); exporter.AddIosLinkerFlags("-rdynamic");
exporter.AddIosLinkerFlags($"-force_load \"$(SRCROOT)/{MonoLibFile("libmono-native")}\""); exporter.AddIosLinkerFlags($"-force_load \"$(SRCROOT)/{MonoFrameworkFile("libmono-native")}\"");
} }
/// Converts an assembly name to a valid symbol name in the same way the AOT compiler does /// Converts an assembly name to a valid symbol name in the same way the AOT compiler does

View File

@ -33,6 +33,7 @@ def get_opts():
"/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain", "/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain",
), ),
("IPHONESDK", "Path to the iPhone SDK", ""), ("IPHONESDK", "Path to the iPhone SDK", ""),
BoolVariable("ios_simulator", "Build for iOS Simulator", False),
BoolVariable("ios_exceptions", "Enable exceptions", False), BoolVariable("ios_exceptions", "Enable exceptions", False),
("ios_triple", "Triple for ios toolchain", ""), ("ios_triple", "Triple for ios toolchain", ""),
] ]
@ -106,26 +107,35 @@ def configure(env):
## Compile flags ## Compile flags
if env["arch"] == "x86" or env["arch"] == "x86_64": if env["ios_simulator"]:
detect_darwin_sdk_path("iphonesimulator", env) detect_darwin_sdk_path("iphonesimulator", env)
env.Append(CCFLAGS=["-mios-simulator-version-min=10.0"])
env.Append(LINKFLAGS=["-mios-simulator-version-min=10.0"])
env.extra_suffix = ".simulator" + env.extra_suffix
else:
detect_darwin_sdk_path("iphone", env)
env.Append(CCFLAGS=["-miphoneos-version-min=10.0"])
env.Append(LINKFLAGS=["-miphoneos-version-min=10.0"])
if env["arch"] == "x86" or env["arch"] == "x86_64":
env["ENV"]["MACOSX_DEPLOYMENT_TARGET"] = "10.9" env["ENV"]["MACOSX_DEPLOYMENT_TARGET"] = "10.9"
arch_flag = "i386" if env["arch"] == "x86" else env["arch"] arch_flag = "i386" if env["arch"] == "x86" else env["arch"]
env.Append( env.Append(
CCFLAGS=( CCFLAGS=(
"-arch " "-arch "
+ arch_flag + arch_flag
+ " -fobjc-arc -fobjc-abi-version=2 -fobjc-legacy-dispatch -fmessage-length=0 -fpascal-strings -fblocks -fasm-blocks -isysroot $IPHONESDK -mios-simulator-version-min=10.0" + " -fobjc-arc -fobjc-abi-version=2 -fobjc-legacy-dispatch -fmessage-length=0 -fpascal-strings -fblocks -fasm-blocks -isysroot $IPHONESDK"
).split() ).split()
) )
elif env["arch"] == "arm": elif env["arch"] == "arm":
detect_darwin_sdk_path("iphone", env) detect_darwin_sdk_path("iphone", env)
env.Append( env.Append(
CCFLAGS='-fobjc-arc -arch armv7 -fmessage-length=0 -fno-strict-aliasing -fdiagnostics-print-source-range-info -fdiagnostics-show-category=id -fdiagnostics-parseable-fixits -fpascal-strings -fblocks -isysroot $IPHONESDK -fvisibility=hidden -mthumb "-DIBOutlet=__attribute__((iboutlet))" "-DIBOutletCollection(ClassName)=__attribute__((iboutletcollection(ClassName)))" "-DIBAction=void)__attribute__((ibaction)" -miphoneos-version-min=10.0 -MMD -MT dependencies'.split() CCFLAGS='-fobjc-arc -arch armv7 -fmessage-length=0 -fno-strict-aliasing -fdiagnostics-print-source-range-info -fdiagnostics-show-category=id -fdiagnostics-parseable-fixits -fpascal-strings -fblocks -isysroot $IPHONESDK -fvisibility=hidden -mthumb "-DIBOutlet=__attribute__((iboutlet))" "-DIBOutletCollection(ClassName)=__attribute__((iboutletcollection(ClassName)))" "-DIBAction=void)__attribute__((ibaction)" -MMD -MT dependencies'.split()
) )
elif env["arch"] == "arm64": elif env["arch"] == "arm64":
detect_darwin_sdk_path("iphone", env) detect_darwin_sdk_path("iphone", env)
env.Append( env.Append(
CCFLAGS="-fobjc-arc -arch arm64 -fmessage-length=0 -fno-strict-aliasing -fdiagnostics-print-source-range-info -fdiagnostics-show-category=id -fdiagnostics-parseable-fixits -fpascal-strings -fblocks -fvisibility=hidden -MMD -MT dependencies -miphoneos-version-min=10.0 -isysroot $IPHONESDK".split() CCFLAGS="-fobjc-arc -arch arm64 -fmessage-length=0 -fno-strict-aliasing -fdiagnostics-print-source-range-info -fdiagnostics-show-category=id -fdiagnostics-parseable-fixits -fpascal-strings -fblocks -fvisibility=hidden -MMD -MT dependencies -isysroot $IPHONESDK".split()
) )
env.Append(CPPDEFINES=["NEED_LONG_INT"]) env.Append(CPPDEFINES=["NEED_LONG_INT"])
env.Append(CPPDEFINES=["LIBYUV_DISABLE_NEON"]) env.Append(CPPDEFINES=["LIBYUV_DISABLE_NEON"])
@ -148,7 +158,6 @@ def configure(env):
LINKFLAGS=[ LINKFLAGS=[
"-arch", "-arch",
arch_flag, arch_flag,
"-mios-simulator-version-min=10.0",
"-isysroot", "-isysroot",
"$IPHONESDK", "$IPHONESDK",
"-Xlinker", "-Xlinker",
@ -159,9 +168,9 @@ def configure(env):
] ]
) )
elif env["arch"] == "arm": elif env["arch"] == "arm":
env.Append(LINKFLAGS=["-arch", "armv7", "-Wl,-dead_strip", "-miphoneos-version-min=10.0"]) env.Append(LINKFLAGS=["-arch", "armv7", "-Wl,-dead_strip"])
if env["arch"] == "arm64": if env["arch"] == "arm64":
env.Append(LINKFLAGS=["-arch", "arm64", "-Wl,-dead_strip", "-miphoneos-version-min=10.0"]) env.Append(LINKFLAGS=["-arch", "arm64", "-Wl,-dead_strip"])
env.Append( env.Append(
LINKFLAGS=[ LINKFLAGS=[

View File

@ -1504,9 +1504,9 @@ Error EditorExportPlatformIOS::export_project(const Ref<EditorExportPreset> &p_p
return ERR_SKIP; return ERR_SKIP;
} }
String library_to_use = "libgodot.iphone." + String(p_debug ? "debug" : "release") + ".fat.a"; String library_to_use = "libgodot.iphone." + String(p_debug ? "debug" : "release") + ".xcframework";
print_line("Static library: " + library_to_use); print_line("Static framework: " + library_to_use);
String pkg_name; String pkg_name;
if (p_preset->get("application/name") != "") { if (p_preset->get("application/name") != "") {
pkg_name = p_preset->get("application/name"); // app_name pkg_name = p_preset->get("application/name"); // app_name
@ -1592,7 +1592,7 @@ Error EditorExportPlatformIOS::export_project(const Ref<EditorExportPreset> &p_p
if (files_to_parse.has(file)) { if (files_to_parse.has(file)) {
_fix_config_file(p_preset, data, config_data, p_debug); _fix_config_file(p_preset, data, config_data, p_debug);
} else if (file.begins_with("libgodot.iphone")) { } else if (file.begins_with("libgodot.iphone")) {
if (file != library_to_use) { if (!file.begins_with(library_to_use) || file.ends_with(String("/empty"))) {
ret = unzGoToNextFile(src_pkg_zip); ret = unzGoToNextFile(src_pkg_zip);
continue; //ignore! continue; //ignore!
} }
@ -1600,7 +1600,7 @@ Error EditorExportPlatformIOS::export_project(const Ref<EditorExportPreset> &p_p
#if defined(OSX_ENABLED) || defined(X11_ENABLED) #if defined(OSX_ENABLED) || defined(X11_ENABLED)
is_execute = true; is_execute = true;
#endif #endif
file = "godot_ios.a"; file = file.replace(library_to_use, binary_name + ".xcframework");
} }
if (file == project_file) { if (file == project_file) {
@ -1670,7 +1670,9 @@ Error EditorExportPlatformIOS::export_project(const Ref<EditorExportPreset> &p_p
for (int j = 0; j < project_static_libs.size(); j++) { for (int j = 0; j < project_static_libs.size(); j++) {
const String &static_lib_path = project_static_libs[j]; const String &static_lib_path = project_static_libs[j];
String dest_lib_file_path = dest_dir + static_lib_path.get_file(); String dest_lib_file_path = dest_dir + static_lib_path.get_file();
Error lib_copy_err = tmp_app_path->copy(static_lib_path, dest_lib_file_path);
bool dir_exists = tmp_app_path->dir_exists(static_lib_path);
Error lib_copy_err = dir_exists ? tmp_app_path->copy_dir(static_lib_path, dest_lib_file_path) : tmp_app_path->copy(static_lib_path, dest_lib_file_path);
if (lib_copy_err != OK) { if (lib_copy_err != OK) {
ERR_PRINTS("Can't copy '" + static_lib_path + "'."); ERR_PRINTS("Can't copy '" + static_lib_path + "'.");
memdelete(tmp_app_path); memdelete(tmp_app_path);