From 27017e1b97ace3cdc65918f3a975edde9544c3fd Mon Sep 17 00:00:00 2001 From: Matthew Leibowitz Date: Thu, 6 Mar 2025 05:22:53 +0800 Subject: [PATCH 1/4] Use XCFrameworks and bundle symbols --- externals/skia | 2 +- native/ios/build.cake | 110 +++++++----------- .../libSkiaSharp.xcodeproj/project.pbxproj | 6 +- native/macos/build.cake | 49 ++++---- .../libSkiaSharp.xcodeproj/project.pbxproj | 4 +- native/tvos/build.cake | 56 ++++----- .../libSkiaSharp.xcodeproj/project.pbxproj | 4 +- scripts/cake/native-shared.cake | 8 +- scripts/cake/shared.cake | 1 + scripts/cake/xcode.cake | 39 +++++++ 10 files changed, 151 insertions(+), 128 deletions(-) diff --git a/externals/skia b/externals/skia index 1801f8f742..32f9be45de 160000 --- a/externals/skia +++ b/externals/skia @@ -1 +1 @@ -Subproject commit 1801f8f7420782796a67b9fe24e245e34c039a30 +Subproject commit 32f9be45dea1d1c9cd2c87f80172b8bdce6afffc diff --git a/native/ios/build.cake b/native/ios/build.cake index 3cd6a13d3f..30f1e3f1dc 100644 --- a/native/ios/build.cake +++ b/native/ios/build.cake @@ -6,13 +6,20 @@ DirectoryPath OUTPUT_PATH = MakeAbsolute(ROOT_PATH.Combine("output/native")); string VARIANT = (BUILD_VARIANT ?? "ios").ToLower(); -string GetDeploymentTarget(string arch) -{ - switch (VARIANT) { - case "maccatalyst": return "13.1"; - default: return "11.0"; - } -} +string GetDeploymentTarget() => + VARIANT switch + { + "maccatalyst" => "13.1", + _ => "11.0", + }; + +string GetDestination(string sdk) => + VARIANT switch + { + "ios" => sdk.EndsWith("simulator") ? "generic/platform=iOS Simulator" : "generic/platform=iOS", + "maccatalyst" => "generic/platform=macOS,variant=Mac Catalyst", + _ => throw new InvalidOperationException($"Unknown variant: {VARIANT}"), + }; Task("libSkiaSharp") .IsDependentOn("git-sync-deps") @@ -20,39 +27,25 @@ Task("libSkiaSharp") .Does(() => { if (VARIANT == "ios") { - Build("iphonesimulator", "x86_64", "x64"); - Build("iphonesimulator", "arm64", "arm64"); - Build("iphoneos", "arm64", "arm64"); - // Build("iphoneos", "arm64", "arm64", "arm64e"); - - SafeCopy( - $"libSkiaSharp/bin/{CONFIGURATION}/iphonesimulator/x86_64.xcarchive", - OUTPUT_PATH.Combine($"ios/libSkiaSharp/x86_64.xcarchive")); - - CreateFatFramework(OUTPUT_PATH.Combine("ios/libSkiaSharp")); - CreateFatFramework(OUTPUT_PATH.Combine("iossimulator/libSkiaSharp")); + BuildSkia("iphonesimulator", "x86_64", "x64"); + BuildSkia("iphonesimulator", "arm64", "arm64"); + Build("iphonesimulator"); + BuildSkia("iphoneos", "arm64", "arm64"); + Build("iphoneos"); } else if (VARIANT == "maccatalyst") { - Build("macosx", "x86_64", "x64"); - Build("macosx", "arm64", "arm64"); - - CreateFatVersionedFramework(OUTPUT_PATH.Combine("maccatalyst/libSkiaSharp")); + BuildSkia("macosx", "x86_64", "x64"); + BuildSkia("macosx", "arm64", "arm64"); + Build("macosx"); } + CreateXCFramework(OUTPUT_PATH.Combine($"{VARIANT}/libSkiaSharp")); - void Build(string sdk, string arch, string skiaArch, string xcodeArch = null) + void BuildSkia(string sdk, string xcodeArch, string skiaArch) { - if (Skip(arch)) return; - - xcodeArch = xcodeArch ?? arch; - var isSim = sdk.EndsWith("simulator"); - var platform = VARIANT; - if (VARIANT == "ios" && isSim) - platform += "simulator"; - - GnNinja($"{platform}/{xcodeArch}", "skia modules/skottie", + GnNinja($"{sdk}/{xcodeArch}", "skia modules/skottie", $"target_cpu='{skiaArch}' " + $"target_os='{VARIANT}' " + - $"min_{VARIANT}_version='{GetDeploymentTarget(arch)}' " + - $"ios_use_simulator={(isSim ? "true" : "false")} " + + $"min_{VARIANT}_version='{GetDeploymentTarget()}' " + + $"ios_use_simulator={(sdk.EndsWith("simulator") ? "true" : "false")} " + $"skia_use_harfbuzz=false " + $"skia_use_icu=false " + $"skia_use_metal=true " + @@ -66,15 +59,17 @@ Task("libSkiaSharp") $"skia_enable_skottie=true " + $"extra_cflags=[ '-DSKIA_C_DLL', '-DHAVE_ARC4RANDOM_BUF' ] " + ADDITIONAL_GN_ARGS); + } - RunXCodeBuild("libSkiaSharp/libSkiaSharp.xcodeproj", "libSkiaSharp", sdk, xcodeArch, properties: new Dictionary { - { $"{VARIANT.ToUpper()}_DEPLOYMENT_TARGET_VERSION", GetDeploymentTarget(arch) }, - { $"SKIA_PLATFORM", platform }, + void Build(string sdk) + { + RunXCodeBuild("libSkiaSharp/libSkiaSharp.xcodeproj", "libSkiaSharp", sdk, GetDestination(sdk), properties: new Dictionary { + { $"{VARIANT.ToUpper()}_DEPLOYMENT_TARGET_VERSION", GetDeploymentTarget() }, }); SafeCopy( - $"libSkiaSharp/bin/{CONFIGURATION}/{sdk}/{xcodeArch}.xcarchive", - OUTPUT_PATH.Combine($"{platform}/libSkiaSharp/{xcodeArch}.xcarchive")); + $"libSkiaSharp/bin/{CONFIGURATION}/{sdk}.xcarchive", + OUTPUT_PATH.Combine($"{VARIANT}/libSkiaSharp/{sdk}.xcarchive")); } }); @@ -83,41 +78,22 @@ Task("libHarfBuzzSharp") .Does(() => { if (VARIANT == "ios") { - Build("iphonesimulator", "x86_64"); - Build("iphonesimulator", "arm64"); - Build("iphoneos", "arm64"); - // Build("iphoneos", "arm64e"); - - SafeCopy( - $"libHarfBuzzSharp/bin/{CONFIGURATION}/iphonesimulator/x86_64.xcarchive", - OUTPUT_PATH.Combine($"ios/libHarfBuzzSharp/x86_64.xcarchive")); - - CreateFatFramework(OUTPUT_PATH.Combine("ios/libHarfBuzzSharp")); - CreateFatFramework(OUTPUT_PATH.Combine("iossimulator/libHarfBuzzSharp")); + Build("iphonesimulator"); + Build("iphoneos"); } else if (VARIANT == "maccatalyst") { - Build("macosx", "x86_64"); - Build("macosx", "arm64"); - - CreateFatVersionedFramework(OUTPUT_PATH.Combine("maccatalyst/libHarfBuzzSharp")); + Build("macosx"); } + CreateXCFramework(OUTPUT_PATH.Combine($"{VARIANT}/libHarfBuzzSharp")); - void Build(string sdk, string arch, string xcodeArch = null) + void Build(string sdk) { - if (Skip(arch)) return; - - xcodeArch = xcodeArch ?? arch; - var isSim = sdk.EndsWith("simulator"); - var platform = VARIANT; - if (VARIANT == "ios" && isSim) - platform += "simulator"; - - RunXCodeBuild("libHarfBuzzSharp/libHarfBuzzSharp.xcodeproj", "libHarfBuzzSharp", sdk, xcodeArch, properties: new Dictionary { - { $"{VARIANT.ToUpper()}_DEPLOYMENT_TARGET_VERSION", GetDeploymentTarget(arch) }, + RunXCodeBuild("libHarfBuzzSharp/libHarfBuzzSharp.xcodeproj", "libHarfBuzzSharp", sdk, GetDestination(sdk), properties: new Dictionary { + { $"{VARIANT.ToUpper()}_DEPLOYMENT_TARGET_VERSION", GetDeploymentTarget() }, }); SafeCopy( - $"libHarfBuzzSharp/bin/{CONFIGURATION}/{sdk}/{xcodeArch}.xcarchive", - OUTPUT_PATH.Combine($"{platform}/libHarfBuzzSharp/{xcodeArch}.xcarchive")); + $"libHarfBuzzSharp/bin/{CONFIGURATION}/{sdk}.xcarchive", + OUTPUT_PATH.Combine($"{VARIANT}/libHarfBuzzSharp/{sdk}.xcarchive")); } }); diff --git a/native/ios/libSkiaSharp/libSkiaSharp.xcodeproj/project.pbxproj b/native/ios/libSkiaSharp/libSkiaSharp.xcodeproj/project.pbxproj index 1f8c2d3b00..b8a6ffba9d 100644 --- a/native/ios/libSkiaSharp/libSkiaSharp.xcodeproj/project.pbxproj +++ b/native/ios/libSkiaSharp/libSkiaSharp.xcodeproj/project.pbxproj @@ -330,7 +330,6 @@ ONLY_ACTIVE_ARCH = YES; OTHER_LDFLAGS = "-all_load"; SDKROOT = iphoneos; - SKIA_PLATFORM = ios; TARGETED_DEVICE_FAMILY = "1,2"; VERSIONING_SYSTEM = "apple-generic"; VERSION_INFO_PREFIX = ""; @@ -408,7 +407,6 @@ MTL_ENABLE_DEBUG_INFO = NO; OTHER_LDFLAGS = "-all_load"; SDKROOT = iphoneos; - SKIA_PLATFORM = ios; TARGETED_DEVICE_FAMILY = "1,2"; VALIDATE_PRODUCT = YES; VERSIONING_SYSTEM = "apple-generic"; @@ -431,7 +429,7 @@ IPHONEOS_DEPLOYMENT_TARGET = "$(IOS_DEPLOYMENT_TARGET_VERSION)"; "IPHONEOS_DEPLOYMENT_TARGET[sdk=macosx*]" = "$(MACCATALYST_DEPLOYMENT_TARGET_VERSION)"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - LIBRARY_SEARCH_PATHS = "../../../externals/skia/out/$(SKIA_PLATFORM)/$(ARCHS)"; + LIBRARY_SEARCH_PATHS = "../../../externals/skia/out/$(PLATFORM_NAME)/$(CURRENT_ARCH)"; OTHER_LDFLAGS = ( "-all_load", "-lskia", @@ -462,7 +460,7 @@ IPHONEOS_DEPLOYMENT_TARGET = "$(IOS_DEPLOYMENT_TARGET_VERSION)"; "IPHONEOS_DEPLOYMENT_TARGET[sdk=macosx*]" = "$(MACCATALYST_DEPLOYMENT_TARGET_VERSION)"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - LIBRARY_SEARCH_PATHS = "../../../externals/skia/out/$(SKIA_PLATFORM)/$(ARCHS)"; + LIBRARY_SEARCH_PATHS = "../../../externals/skia/out/$(PLATFORM_NAME)/$(CURRENT_ARCH)"; OTHER_LDFLAGS = ( "-all_load", "-lskia", diff --git a/native/macos/build.cake b/native/macos/build.cake index cf83e7538b..d61bf6872e 100644 --- a/native/macos/build.cake +++ b/native/macos/build.cake @@ -4,32 +4,31 @@ DirectoryPath OUTPUT_PATH = MakeAbsolute(ROOT_PATH.Combine("output/native/osx")) #load "../../scripts/cake/native-shared.cake" #load "../../scripts/cake/xcode.cake" -string GetDeploymentTarget(string arch) -{ - switch (arch.ToLower()) { - case "arm64": return "11.0"; - default: return "10.13"; - } -} +string GetDeploymentTarget(string arch) => + arch.ToLower() switch + { + "arm64" => "11.0", + _ => "10.13", + }; Task("libSkiaSharp") .IsDependentOn("git-sync-deps") .WithCriteria(IsRunningOnMacOs()) .Does(() => { - Build("x86_64", "x64"); - Build("arm64", "arm64"); + Build("macosx", "x86_64", "x64"); + Build("macosx", "arm64", "arm64"); CreateFatDylib(OUTPUT_PATH.Combine("libSkiaSharp")); - void Build(string arch, string skiaArch) + void Build(string sdk, string xcodeArch, string skiaArch) { - if (Skip(arch)) return; + if (Skip(xcodeArch)) return; - GnNinja($"macos/{arch}", "skia modules/skottie", + GnNinja($"{sdk}/{xcodeArch}", "skia modules/skottie", $"target_os='mac' " + $"target_cpu='{skiaArch}' " + - $"min_macos_version='{GetDeploymentTarget(arch)}' " + + $"min_macos_version='{GetDeploymentTarget(xcodeArch)}' " + $"skia_use_harfbuzz=false " + $"skia_use_icu=false " + $"skia_use_metal=true " + @@ -44,13 +43,13 @@ Task("libSkiaSharp") $"extra_cflags=[ '-DSKIA_C_DLL', '-DHAVE_ARC4RANDOM_BUF', '-stdlib=libc++' ] " + $"extra_ldflags=[ '-stdlib=libc++' ]"); - RunXCodeBuild("libSkiaSharp/libSkiaSharp.xcodeproj", "libSkiaSharp", "macosx", arch, properties: new Dictionary { - { "MACOSX_DEPLOYMENT_TARGET", GetDeploymentTarget(arch) }, + RunXCodeBuild("libSkiaSharp/libSkiaSharp.xcodeproj", "libSkiaSharp", sdk, xcodeArch, properties: new Dictionary { + { "MACOSX_DEPLOYMENT_TARGET", GetDeploymentTarget(xcodeArch) }, }); SafeCopy( - $"libSkiaSharp/bin/{CONFIGURATION}/macosx/{arch}.xcarchive", - OUTPUT_PATH.Combine($"libSkiaSharp/{arch}.xcarchive")); + $"libSkiaSharp/bin/{CONFIGURATION}/{sdk}/{xcodeArch}.xcarchive", + OUTPUT_PATH.Combine($"libSkiaSharp/{xcodeArch}.xcarchive")); } }); @@ -58,22 +57,22 @@ Task("libHarfBuzzSharp") .WithCriteria(IsRunningOnMacOs()) .Does(() => { - Build("x86_64"); - Build("arm64"); + Build("macosx", "x86_64"); + Build("macosx", "arm64"); CreateFatDylib(OUTPUT_PATH.Combine("libHarfBuzzSharp")); - void Build(string arch) + void Build(string sdk, string xcodeArch) { - if (Skip(arch)) return; + if (Skip(xcodeArch)) return; - RunXCodeBuild("libHarfBuzzSharp/libHarfBuzzSharp.xcodeproj", "libHarfBuzzSharp", "macosx", arch, properties: new Dictionary { - { "MACOSX_DEPLOYMENT_TARGET", GetDeploymentTarget(arch) }, + RunXCodeBuild("libHarfBuzzSharp/libHarfBuzzSharp.xcodeproj", "libHarfBuzzSharp", sdk, xcodeArch, properties: new Dictionary { + { "MACOSX_DEPLOYMENT_TARGET", GetDeploymentTarget(xcodeArch) }, }); SafeCopy( - $"libHarfBuzzSharp/bin/{CONFIGURATION}/macosx/{arch}.xcarchive", - OUTPUT_PATH.Combine($"libHarfBuzzSharp/{arch}.xcarchive")); + $"libHarfBuzzSharp/bin/{CONFIGURATION}/{sdk}/{xcodeArch}.xcarchive", + OUTPUT_PATH.Combine($"libHarfBuzzSharp/{xcodeArch}.xcarchive")); } }); diff --git a/native/macos/libSkiaSharp/libSkiaSharp.xcodeproj/project.pbxproj b/native/macos/libSkiaSharp/libSkiaSharp.xcodeproj/project.pbxproj index 6b93f65ade..31353e5adb 100644 --- a/native/macos/libSkiaSharp/libSkiaSharp.xcodeproj/project.pbxproj +++ b/native/macos/libSkiaSharp/libSkiaSharp.xcodeproj/project.pbxproj @@ -389,7 +389,7 @@ GCC_ENABLE_CPP_RTTI = NO; HEADER_SEARCH_PATHS = ../../../externals/skia; INSTALL_PATH = "@rpath"; - LIBRARY_SEARCH_PATHS = "../../../externals/skia/out/macos/$(ARCHS)"; + LIBRARY_SEARCH_PATHS = "../../../externals/skia/out/$(PLATFORM_NAME)/$(CURRENT_ARCH)"; MACOSX_DEPLOYMENT_TARGET = 10.8; OTHER_LDFLAGS = ( "-lskia", @@ -412,7 +412,7 @@ GCC_ENABLE_CPP_RTTI = NO; HEADER_SEARCH_PATHS = ../../../externals/skia; INSTALL_PATH = "@rpath"; - LIBRARY_SEARCH_PATHS = "../../../externals/skia/out/macos/$(ARCHS)"; + LIBRARY_SEARCH_PATHS = "../../../externals/skia/out/$(PLATFORM_NAME)/$(CURRENT_ARCH)"; MACOSX_DEPLOYMENT_TARGET = 10.8; OTHER_LDFLAGS = ( "-lskia", diff --git a/native/tvos/build.cake b/native/tvos/build.cake index 5fd38613f0..896910390f 100644 --- a/native/tvos/build.cake +++ b/native/tvos/build.cake @@ -4,29 +4,32 @@ DirectoryPath OUTPUT_PATH = MakeAbsolute(ROOT_PATH.Combine("output/native/tvos") #load "../../scripts/cake/native-shared.cake" #load "../../scripts/cake/xcode.cake" -string GetDeploymentTarget(string arch) -{ - return "11.0"; -} +string GetDeploymentTarget() => + "11.0"; + +string GetDestination(string sdk) => + sdk.EndsWith("simulator") ? "generic/platform=tvOS Simulator" : "generic/platform=tvOS"; Task("libSkiaSharp") .IsDependentOn("git-sync-deps") .WithCriteria(IsRunningOnMacOs()) .Does(() => { - Build("appletvsimulator", "x86_64", "x64"); - Build("appletvos", "arm64", "arm64"); + BuildSkia("appletvsimulator", "x86_64", "x64"); + BuildSkia("appletvsimulator", "arm64", "arm64"); + Build("appletvsimulator"); + BuildSkia("appletvos", "arm64", "arm64"); + Build("appletvos"); - CreateFatFramework(OUTPUT_PATH.Combine("libSkiaSharp")); + CreateXCFramework(OUTPUT_PATH.Combine("libSkiaSharp")); - void Build(string sdk, string arch, string skiaArch) + void BuildSkia(string sdk, string xcodeArch, string skiaArch) { - if (Skip(arch)) return; - - GnNinja($"tvos/{arch}", "skia modules/skottie", + GnNinja($"{sdk}/{xcodeArch}", "skia modules/skottie", $"target_os='tvos' " + $"target_cpu='{skiaArch}' " + - $"min_ios_version='{GetDeploymentTarget(arch)}' " + + $"min_ios_version='{GetDeploymentTarget()}' " + + $"ios_use_simulator={(sdk.EndsWith("simulator") ? "true" : "false")} " + $"skia_use_harfbuzz=false " + $"skia_use_icu=false " + $"skia_use_metal=true " + @@ -39,14 +42,17 @@ Task("libSkiaSharp") $"skia_use_system_zlib=false " + $"skia_enable_skottie=true " + $"extra_cflags=[ '-DSKIA_C_DLL', '-DHAVE_ARC4RANDOM_BUF' ] "); + } - RunXCodeBuild("libSkiaSharp/libSkiaSharp.xcodeproj", "libSkiaSharp", sdk, arch, properties: new Dictionary { - { "TVOS_DEPLOYMENT_TARGET", GetDeploymentTarget(arch) }, + void Build(string sdk) + { + RunXCodeBuild("libSkiaSharp/libSkiaSharp.xcodeproj", "libSkiaSharp", sdk, GetDestination(sdk), properties: new Dictionary { + { "TVOS_DEPLOYMENT_TARGET", GetDeploymentTarget() }, }); SafeCopy( - $"libSkiaSharp/bin/{CONFIGURATION}/{sdk}/{arch}.xcarchive", - OUTPUT_PATH.Combine($"libSkiaSharp/{arch}.xcarchive")); + $"libSkiaSharp/bin/{CONFIGURATION}/{sdk}.xcarchive", + OUTPUT_PATH.Combine($"libSkiaSharp/{sdk}.xcarchive")); } }); @@ -54,22 +60,20 @@ Task("libHarfBuzzSharp") .WithCriteria(IsRunningOnMacOs()) .Does(() => { - Build("appletvsimulator", "x86_64"); - Build("appletvos", "arm64"); + Build("appletvsimulator"); + Build("appletvos"); - CreateFatFramework(OUTPUT_PATH.Combine("libHarfBuzzSharp")); + CreateXCFramework(OUTPUT_PATH.Combine("libHarfBuzzSharp")); - void Build(string sdk, string arch) + void Build(string sdk) { - if (Skip(arch)) return; - - RunXCodeBuild("libHarfBuzzSharp/libHarfBuzzSharp.xcodeproj", "libHarfBuzzSharp", sdk, arch, properties: new Dictionary { - { "TVOS_DEPLOYMENT_TARGET", GetDeploymentTarget(arch) }, + RunXCodeBuild("libHarfBuzzSharp/libHarfBuzzSharp.xcodeproj", "libHarfBuzzSharp", sdk, GetDestination(sdk), properties: new Dictionary { + { "TVOS_DEPLOYMENT_TARGET", GetDeploymentTarget() }, }); SafeCopy( - $"libHarfBuzzSharp/bin/{CONFIGURATION}/{sdk}/{arch}.xcarchive", - OUTPUT_PATH.Combine($"libHarfBuzzSharp/{arch}.xcarchive")); + $"libHarfBuzzSharp/bin/{CONFIGURATION}/{sdk}.xcarchive", + OUTPUT_PATH.Combine($"libHarfBuzzSharp/{sdk}.xcarchive")); } }); diff --git a/native/tvos/libSkiaSharp/libSkiaSharp.xcodeproj/project.pbxproj b/native/tvos/libSkiaSharp/libSkiaSharp.xcodeproj/project.pbxproj index c3b6e63f8f..045eafcdd5 100644 --- a/native/tvos/libSkiaSharp/libSkiaSharp.xcodeproj/project.pbxproj +++ b/native/tvos/libSkiaSharp/libSkiaSharp.xcodeproj/project.pbxproj @@ -430,7 +430,7 @@ INFOPLIST_FILE = libSkiaSharp/Info.plist; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - LIBRARY_SEARCH_PATHS = "../../../externals/skia/out/tvos/$(ARCHS)"; + LIBRARY_SEARCH_PATHS = "../../../externals/skia/out/$(PLATFORM_NAME)/$(CURRENT_ARCH)"; OTHER_LDFLAGS = ( "-all_load", "-lskia", @@ -458,7 +458,7 @@ INFOPLIST_FILE = libSkiaSharp/Info.plist; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - LIBRARY_SEARCH_PATHS = "../../../externals/skia/out/tvos/$(ARCHS)"; + LIBRARY_SEARCH_PATHS = "../../../externals/skia/out/$(PLATFORM_NAME)/$(CURRENT_ARCH)"; OTHER_LDFLAGS = ( "-all_load", "-lskia", diff --git a/scripts/cake/native-shared.cake b/scripts/cake/native-shared.cake index aac275db40..4c63a948fc 100644 --- a/scripts/cake/native-shared.cake +++ b/scripts/cake/native-shared.cake @@ -124,7 +124,7 @@ string ReduceArch(string arch) bool Skip(string arch) { - if (BUILD_ARCH.Length == 0 || BUILD_ARCH.Contains("all")) + if (BUILD_ALL_ARCH) return false; arch = ReduceArch(arch); @@ -136,3 +136,9 @@ bool Skip(string arch) return true; } + +string[] FilterArchs(params string[] options) +{ + options = options?.Where(x => !Skip(x)).ToArray(); + return options?.Length > 0 ? options : null; +} diff --git a/scripts/cake/shared.cake b/scripts/cake/shared.cake index fca02d0ae1..99c364a5b3 100644 --- a/scripts/cake/shared.cake +++ b/scripts/cake/shared.cake @@ -10,6 +10,7 @@ var MSBUILD_EXE = Argument("msbuild", EnvironmentVariable("MSBUILD_EXE")); var BUILD_ARCH = Argument("arch", Argument("buildarch", EnvironmentVariable("BUILD_ARCH") ?? "")) .ToLower().Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries); +var BUILD_ALL_ARCH = BUILD_ARCH.Length == 0 || BUILD_ARCH.Contains("all"); var BUILD_VARIANT = Argument("variant", EnvironmentVariable("BUILD_VARIANT")); var ADDITIONAL_GN_ARGS = Argument("gnArgs", Argument("gnargs", EnvironmentVariable("ADDITIONAL_GN_ARGS"))); diff --git a/scripts/cake/xcode.cake b/scripts/cake/xcode.cake index 6896857739..1bc0f7b35c 100644 --- a/scripts/cake/xcode.cake +++ b/scripts/cake/xcode.cake @@ -4,6 +4,12 @@ void RunXCodeBuild(FilePath project, string scheme, string sdk, string arch, Dic { var dir = project.GetDirectory(); + string destination = null; + if (arch.Contains("=")) { + destination = arch; + arch = null; + } + var settings = new XCodeBuildSettings { Project = project.FullPath, Scheme = scheme, @@ -18,6 +24,9 @@ void RunXCodeBuild(FilePath project, string scheme, string sdk, string arch, Dic { "BUILD_LIBRARIES_FOR_DISTRIBUTION", "YES" }, }, }; + if (destination != null) { + settings.ArgumentCustomization = args => args.Append($"-destination \"{destination}\""); + } if (properties != null) { foreach (var prop in properties) { settings.BuildSettings[prop.Key] = prop.Value; @@ -74,6 +83,21 @@ void RunLipo(FilePath output, FilePath[] inputs) }); } +void RunXCodeBuildCreateXCFramework(DirectoryPath output, (DirectoryPath Framework, DirectoryPath Symbols)[] items) +{ + if (!IsRunningOnMacOs()) + throw new InvalidOperationException("xcodebuild is only available on macOS."); + + DeleteDir(output); + + var itemsStrings = items.Select(i => $"-framework \"{i.Framework}\" -debug-symbols \"{i.Symbols}\""); + var itemsString = string.Join(" ", itemsStrings); + + RunProcess("xcodebuild", new ProcessSettings { + Arguments = $"-create-xcframework {itemsString} -output \"{output}\"", + }); +} + void CreateFatDylib(DirectoryPath archives) { var libName = archives.GetDirectoryName(); @@ -84,6 +108,21 @@ void CreateFatDylib(DirectoryPath archives) StripSign($"{archives}.dylib"); } +void CreateXCFramework(DirectoryPath directory) +{ + var libName = directory.GetDirectoryName(); + + var archives = GetDirectories($"{directory}/*.xcarchive"); + var items = archives.Select(a => ( + Framework: GetDirectories($"{a}/Products/Library/Frameworks/{libName}.framework").First(), + Symbols: GetDirectories($"{a}/dSYMs/{libName}.framework.dSYM").First() + )).ToArray(); + + RunXCodeBuildCreateXCFramework($"{directory}.xcframework", items); + + RunZip($"{directory}.xcframework"); +} + void CreateFatFramework(DirectoryPath archives) { var libName = archives.GetDirectoryName(); From 9551d44e3307a75fbcf9f6d002c7147979eb175e Mon Sep 17 00:00:00 2001 From: Matthew Leibowitz Date: Thu, 6 Mar 2025 05:23:02 +0800 Subject: [PATCH 2/4] Improve the macOS build --- native/macos/build.cake | 48 ++++++++++++++++++++--------------------- 1 file changed, 23 insertions(+), 25 deletions(-) diff --git a/native/macos/build.cake b/native/macos/build.cake index d61bf6872e..4497876278 100644 --- a/native/macos/build.cake +++ b/native/macos/build.cake @@ -4,31 +4,29 @@ DirectoryPath OUTPUT_PATH = MakeAbsolute(ROOT_PATH.Combine("output/native/osx")) #load "../../scripts/cake/native-shared.cake" #load "../../scripts/cake/xcode.cake" -string GetDeploymentTarget(string arch) => - arch.ToLower() switch - { - "arm64" => "11.0", - _ => "10.13", - }; +string GetDeploymentTarget() => + "10.13"; + +string GetDestination(string sdk) => + "generic/platform=macOS"; Task("libSkiaSharp") .IsDependentOn("git-sync-deps") .WithCriteria(IsRunningOnMacOs()) .Does(() => { - Build("macosx", "x86_64", "x64"); - Build("macosx", "arm64", "arm64"); + BuildSkia("macosx", "x86_64", "x64"); + BuildSkia("macosx", "arm64", "arm64"); + Build("macosx"); CreateFatDylib(OUTPUT_PATH.Combine("libSkiaSharp")); - void Build(string sdk, string xcodeArch, string skiaArch) + void BuildSkia(string sdk, string xcodeArch, string skiaArch) { - if (Skip(xcodeArch)) return; - GnNinja($"{sdk}/{xcodeArch}", "skia modules/skottie", $"target_os='mac' " + $"target_cpu='{skiaArch}' " + - $"min_macos_version='{GetDeploymentTarget(xcodeArch)}' " + + $"min_macos_version='{GetDeploymentTarget()}' " + $"skia_use_harfbuzz=false " + $"skia_use_icu=false " + $"skia_use_metal=true " + @@ -42,14 +40,17 @@ Task("libSkiaSharp") $"skia_enable_skottie=true " + $"extra_cflags=[ '-DSKIA_C_DLL', '-DHAVE_ARC4RANDOM_BUF', '-stdlib=libc++' ] " + $"extra_ldflags=[ '-stdlib=libc++' ]"); + } - RunXCodeBuild("libSkiaSharp/libSkiaSharp.xcodeproj", "libSkiaSharp", sdk, xcodeArch, properties: new Dictionary { - { "MACOSX_DEPLOYMENT_TARGET", GetDeploymentTarget(xcodeArch) }, + void Build(string sdk) + { + RunXCodeBuild("libSkiaSharp/libSkiaSharp.xcodeproj", "libSkiaSharp", sdk, GetDestination(sdk), properties: new Dictionary { + { "MACOSX_DEPLOYMENT_TARGET", GetDeploymentTarget() }, }); SafeCopy( - $"libSkiaSharp/bin/{CONFIGURATION}/{sdk}/{xcodeArch}.xcarchive", - OUTPUT_PATH.Combine($"libSkiaSharp/{xcodeArch}.xcarchive")); + $"libSkiaSharp/bin/{CONFIGURATION}/{sdk}.xcarchive", + OUTPUT_PATH.Combine($"libSkiaSharp/{sdk}.xcarchive")); } }); @@ -57,22 +58,19 @@ Task("libHarfBuzzSharp") .WithCriteria(IsRunningOnMacOs()) .Does(() => { - Build("macosx", "x86_64"); - Build("macosx", "arm64"); + Build("macosx"); CreateFatDylib(OUTPUT_PATH.Combine("libHarfBuzzSharp")); - void Build(string sdk, string xcodeArch) + void Build(string sdk) { - if (Skip(xcodeArch)) return; - - RunXCodeBuild("libHarfBuzzSharp/libHarfBuzzSharp.xcodeproj", "libHarfBuzzSharp", sdk, xcodeArch, properties: new Dictionary { - { "MACOSX_DEPLOYMENT_TARGET", GetDeploymentTarget(xcodeArch) }, + RunXCodeBuild("libHarfBuzzSharp/libHarfBuzzSharp.xcodeproj", "libHarfBuzzSharp", sdk, GetDestination(sdk), properties: new Dictionary { + { "MACOSX_DEPLOYMENT_TARGET", GetDeploymentTarget() }, }); SafeCopy( - $"libHarfBuzzSharp/bin/{CONFIGURATION}/{sdk}/{xcodeArch}.xcarchive", - OUTPUT_PATH.Combine($"libHarfBuzzSharp/{xcodeArch}.xcarchive")); + $"libHarfBuzzSharp/bin/{CONFIGURATION}/{sdk}.xcarchive", + OUTPUT_PATH.Combine($"libHarfBuzzSharp/{sdk}.xcarchive")); } }); From 567e5ffc3594f68826dc3b62911ac71f6e621e77 Mon Sep 17 00:00:00 2001 From: Matthew Leibowitz Date: Thu, 6 Mar 2025 12:23:25 +0800 Subject: [PATCH 3/4] Pack the right files --- .../HarfBuzzSharp.NativeAssets.MacCatalyst.csproj | 2 +- .../HarfBuzzSharp.NativeAssets.iOS.csproj | 3 +-- .../HarfBuzzSharp.NativeAssets.tvOS.csproj | 2 +- binding/IncludeNativeAssets.HarfBuzzSharp.targets | 9 ++++----- binding/IncludeNativeAssets.SkiaSharp.targets | 9 ++++----- .../SkiaSharp.NativeAssets.MacCatalyst.csproj | 2 +- .../SkiaSharp.NativeAssets.iOS.csproj | 3 +-- .../SkiaSharp.NativeAssets.tvOS.csproj | 2 +- 8 files changed, 14 insertions(+), 18 deletions(-) diff --git a/binding/HarfBuzzSharp.NativeAssets.MacCatalyst/HarfBuzzSharp.NativeAssets.MacCatalyst.csproj b/binding/HarfBuzzSharp.NativeAssets.MacCatalyst/HarfBuzzSharp.NativeAssets.MacCatalyst.csproj index 20b4e81de1..196686a8f7 100644 --- a/binding/HarfBuzzSharp.NativeAssets.MacCatalyst/HarfBuzzSharp.NativeAssets.MacCatalyst.csproj +++ b/binding/HarfBuzzSharp.NativeAssets.MacCatalyst/HarfBuzzSharp.NativeAssets.MacCatalyst.csproj @@ -6,7 +6,7 @@ $(PackagingGroup) - Native Assets for Mac Catalyst - + diff --git a/binding/HarfBuzzSharp.NativeAssets.iOS/HarfBuzzSharp.NativeAssets.iOS.csproj b/binding/HarfBuzzSharp.NativeAssets.iOS/HarfBuzzSharp.NativeAssets.iOS.csproj index 2ab688280d..9ce7b39bd4 100644 --- a/binding/HarfBuzzSharp.NativeAssets.iOS/HarfBuzzSharp.NativeAssets.iOS.csproj +++ b/binding/HarfBuzzSharp.NativeAssets.iOS/HarfBuzzSharp.NativeAssets.iOS.csproj @@ -6,8 +6,7 @@ $(PackagingGroup) - Native Assets for iOS - - + diff --git a/binding/HarfBuzzSharp.NativeAssets.tvOS/HarfBuzzSharp.NativeAssets.tvOS.csproj b/binding/HarfBuzzSharp.NativeAssets.tvOS/HarfBuzzSharp.NativeAssets.tvOS.csproj index eec48d5941..f1ec723835 100644 --- a/binding/HarfBuzzSharp.NativeAssets.tvOS/HarfBuzzSharp.NativeAssets.tvOS.csproj +++ b/binding/HarfBuzzSharp.NativeAssets.tvOS/HarfBuzzSharp.NativeAssets.tvOS.csproj @@ -6,7 +6,7 @@ $(PackagingGroup) - Native Assets for tvOS - + diff --git a/binding/IncludeNativeAssets.HarfBuzzSharp.targets b/binding/IncludeNativeAssets.HarfBuzzSharp.targets index 075c0b61a1..f219883822 100644 --- a/binding/IncludeNativeAssets.HarfBuzzSharp.targets +++ b/binding/IncludeNativeAssets.HarfBuzzSharp.targets @@ -21,9 +21,8 @@ - - - + + @@ -34,7 +33,7 @@ - + @@ -55,7 +54,7 @@ - + diff --git a/binding/IncludeNativeAssets.SkiaSharp.targets b/binding/IncludeNativeAssets.SkiaSharp.targets index ac82a653ea..2446bd7760 100644 --- a/binding/IncludeNativeAssets.SkiaSharp.targets +++ b/binding/IncludeNativeAssets.SkiaSharp.targets @@ -21,9 +21,8 @@ - - - + + @@ -34,7 +33,7 @@ - + @@ -55,7 +54,7 @@ - + diff --git a/binding/SkiaSharp.NativeAssets.MacCatalyst/SkiaSharp.NativeAssets.MacCatalyst.csproj b/binding/SkiaSharp.NativeAssets.MacCatalyst/SkiaSharp.NativeAssets.MacCatalyst.csproj index 5fc34bd401..56875719ad 100644 --- a/binding/SkiaSharp.NativeAssets.MacCatalyst/SkiaSharp.NativeAssets.MacCatalyst.csproj +++ b/binding/SkiaSharp.NativeAssets.MacCatalyst/SkiaSharp.NativeAssets.MacCatalyst.csproj @@ -6,7 +6,7 @@ $(PackagingGroup) - Native Assets for Mac Catalyst - + diff --git a/binding/SkiaSharp.NativeAssets.iOS/SkiaSharp.NativeAssets.iOS.csproj b/binding/SkiaSharp.NativeAssets.iOS/SkiaSharp.NativeAssets.iOS.csproj index 0e84791e51..83fd2bc16c 100644 --- a/binding/SkiaSharp.NativeAssets.iOS/SkiaSharp.NativeAssets.iOS.csproj +++ b/binding/SkiaSharp.NativeAssets.iOS/SkiaSharp.NativeAssets.iOS.csproj @@ -6,8 +6,7 @@ $(PackagingGroup) - Native Assets for iOS - - + diff --git a/binding/SkiaSharp.NativeAssets.tvOS/SkiaSharp.NativeAssets.tvOS.csproj b/binding/SkiaSharp.NativeAssets.tvOS/SkiaSharp.NativeAssets.tvOS.csproj index 8daf7c2670..2ac3d33425 100644 --- a/binding/SkiaSharp.NativeAssets.tvOS/SkiaSharp.NativeAssets.tvOS.csproj +++ b/binding/SkiaSharp.NativeAssets.tvOS/SkiaSharp.NativeAssets.tvOS.csproj @@ -6,7 +6,7 @@ $(PackagingGroup) - Native Assets for tvOS - + From bbf783f0b77c28a5b83ed898d1848ef09ece4e88 Mon Sep 17 00:00:00 2001 From: Matthew Leibowitz Date: Thu, 6 Mar 2025 14:01:50 +0800 Subject: [PATCH 4/4] tvOS does not like this --- binding/Binding.Shared/PlatformConfiguration.cs | 2 +- binding/SkiaSharp/PlatformLock.cs | 5 ++++- binding/SkiaSharp/SKAutoCoInitialize.cs | 6 ++++++ 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/binding/Binding.Shared/PlatformConfiguration.cs b/binding/Binding.Shared/PlatformConfiguration.cs index 7a1fbdf18f..76f02d909e 100644 --- a/binding/Binding.Shared/PlatformConfiguration.cs +++ b/binding/Binding.Shared/PlatformConfiguration.cs @@ -85,7 +85,7 @@ public static string LinuxFlavor set => linuxFlavor = value; } -#if WINDOWS_UWP +#if WINDOWS_UWP || __IOS__ || __TVOS__ || __MACOS__ || __MACCATALYST__ || __ANDROID__ public static bool IsGlibc { get; } #else private static readonly Lazy isGlibcLazy = new Lazy (IsGlibcImplementation); diff --git a/binding/SkiaSharp/PlatformLock.cs b/binding/SkiaSharp/PlatformLock.cs index 626172bc6f..9a191802ee 100644 --- a/binding/SkiaSharp/PlatformLock.cs +++ b/binding/SkiaSharp/PlatformLock.cs @@ -68,9 +68,11 @@ public static IPlatformLock Create () /// A reference to a new platform lock implementation public static IPlatformLock DefaultFactory () { +#if !(__IOS__ || __TVOS__ || __MACOS__ || __MACCATALYST__ || __ANDROID__) if (PlatformConfiguration.IsWindows) return new NonAlertableWin32Lock (); else +#endif return new ReadWriteLock (); } @@ -90,6 +92,7 @@ class ReadWriteLock : IPlatformLock ReaderWriterLockSlim _lock = new ReaderWriterLockSlim (); } +#if !(__IOS__ || __TVOS__ || __MACOS__ || __MACCATALYST__ || __ANDROID__) /// /// Windows platform lock uses Win32 CRITICAL_SECTION /// @@ -169,6 +172,6 @@ public struct CRITICAL_SECTION static extern void LeaveCriticalSection (IntPtr lpCriticalSection); #endif } +#endif } - } diff --git a/binding/SkiaSharp/SKAutoCoInitialize.cs b/binding/SkiaSharp/SKAutoCoInitialize.cs index bcd278d54b..ef49c9edfa 100644 --- a/binding/SkiaSharp/SKAutoCoInitialize.cs +++ b/binding/SkiaSharp/SKAutoCoInitialize.cs @@ -12,9 +12,11 @@ public partial class SKAutoCoInitialize : IDisposable public SKAutoCoInitialize() { +#if !(__IOS__ || __TVOS__ || __MACOS__ || __MACCATALYST__ || __ANDROID__) if (PlatformConfiguration.IsWindows) hResult = CoInitializeEx(IntPtr.Zero, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE); else +#endif hResult = S_OK; } @@ -24,8 +26,10 @@ public void Uninitialize() { if (hResult >= 0) { +#if !(__IOS__ || __TVOS__ || __MACOS__ || __MACCATALYST__ || __ANDROID__) if (PlatformConfiguration.IsWindows) CoUninitialize(); +#endif hResult = -1; } @@ -41,6 +45,7 @@ public void Uninitialize() private const uint COINIT_DISABLE_OLE1DDE = 0x4; private const uint COINIT_SPEED_OVER_MEMORY = 0x8; +#if !(__IOS__ || __TVOS__ || __MACOS__ || __MACCATALYST__ || __ANDROID__) #if USE_LIBRARY_IMPORT [LibraryImport("ole32.dll", SetLastError = true)] private static partial long CoInitializeEx(IntPtr pvReserved, uint dwCoInit); @@ -51,6 +56,7 @@ public void Uninitialize() private static extern long CoInitializeEx([In, Optional] IntPtr pvReserved, [In] uint dwCoInit); [DllImport("ole32.dll", CharSet = CharSet.Ansi, SetLastError = true, CallingConvention = CallingConvention.StdCall)] private static extern void CoUninitialize(); +#endif #endif } }