From 3ddddef966db1e22311fc5f0903152e591a61f1f Mon Sep 17 00:00:00 2001 From: Matthew Leibowitz Date: Sun, 29 Mar 2026 19:17:00 +0200 Subject: [PATCH 1/2] Add Tizen x64 and arm64 native build support Build system: - Add TFMMinimum=net6.0 for platforms where device runtime lags behind SDK - Add TPVTizenMinimum=8.0 and PlatformTargetFrameworksMinimum block - Update Tizen Studio to 6.1 with MOBILE-6.0 + TIZEN-8.0 native dev Native build: - Refactor build.cake with helper functions (GetTizenProfile, GetTizenRootstrap, GetTizenArch, GetTizenOutputDir) following the iOS pattern - Dynamically set project_def.prop profile per architecture (mobile-6.0 for 32-bit, tizen-8.0 for 64-bit) since tizen build-native has no --profile flag - Clean build output between arch builds to avoid stale artifacts - Add x64/arm64 to Skia GN BUILDCONFIG with tizen-8.0 rootstrap paths Packaging: - Add tizen-x64 and tizen-arm64 RIDs (from Samsung RuntimeIdentifierGraph) - Fix x86 RID from linux-x86 to tizen-x86 Binding: - Add #if NET7_0_OR_GREATER guard for LibraryImport in GRGlInterface.cs Verified: Windows and macOS CI Tizen builds pass (build 156464). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../HarfBuzzSharp.NativeAssets.Tizen.csproj | 5 +- .../IncludeNativeAssets.HarfBuzzSharp.targets | 12 +++- binding/IncludeNativeAssets.SkiaSharp.targets | 12 +++- .../SkiaSharp.NativeAssets.Tizen.csproj | 5 +- binding/SkiaSharp/GRGlInterface.cs | 14 +++++ externals/skia | 2 +- native/tizen/build.cake | 55 ++++++++++++++----- scripts/install-tizen.ps1 | 10 +++- source/SkiaSharp.Build.Override.in.props | 1 + source/SkiaSharp.Build.props | 12 +++- 10 files changed, 102 insertions(+), 26 deletions(-) diff --git a/binding/HarfBuzzSharp.NativeAssets.Tizen/HarfBuzzSharp.NativeAssets.Tizen.csproj b/binding/HarfBuzzSharp.NativeAssets.Tizen/HarfBuzzSharp.NativeAssets.Tizen.csproj index dd508ffaaed..f45c6adaf00 100644 --- a/binding/HarfBuzzSharp.NativeAssets.Tizen/HarfBuzzSharp.NativeAssets.Tizen.csproj +++ b/binding/HarfBuzzSharp.NativeAssets.Tizen/HarfBuzzSharp.NativeAssets.Tizen.csproj @@ -1,13 +1,14 @@  - $(TFMPrevious)-tizen$(TPVTizenPrevious);$(TFMCurrent)-tizen$(TPVTizenCurrent) + $(TFMPrevious)-tizen$(TPVTizenPrevious);$(TFMCurrent)-tizen$(TPVTizenCurrent);$(TFMMinimum)-tizen$(TPVTizenMinimum) HarfBuzzSharp $(PackagingGroup) - Native Assets for Tizen - + + diff --git a/binding/IncludeNativeAssets.HarfBuzzSharp.targets b/binding/IncludeNativeAssets.HarfBuzzSharp.targets index 6910ecf96ac..24e4e765943 100644 --- a/binding/IncludeNativeAssets.HarfBuzzSharp.targets +++ b/binding/IncludeNativeAssets.HarfBuzzSharp.targets @@ -48,7 +48,7 @@ false - bin\runtimes\linux-x86\native\ + bin\runtimes\tizen-x86\native\ libHarfBuzzSharp.so @@ -56,6 +56,16 @@ bin\runtimes\tizen-armel\native\ libHarfBuzzSharp.so + + false + bin\runtimes\tizen-x64\native\ + libHarfBuzzSharp.so + + + false + bin\runtimes\tizen-arm64\native\ + libHarfBuzzSharp.so + diff --git a/binding/IncludeNativeAssets.SkiaSharp.targets b/binding/IncludeNativeAssets.SkiaSharp.targets index b8ea70d9274..8a38990315a 100644 --- a/binding/IncludeNativeAssets.SkiaSharp.targets +++ b/binding/IncludeNativeAssets.SkiaSharp.targets @@ -48,7 +48,7 @@ false - bin\runtimes\linux-x86\native\ + bin\runtimes\tizen-x86\native\ libSkiaSharp.so @@ -56,6 +56,16 @@ bin\runtimes\tizen-armel\native\ libSkiaSharp.so + + false + bin\runtimes\tizen-x64\native\ + libSkiaSharp.so + + + false + bin\runtimes\tizen-arm64\native\ + libSkiaSharp.so + diff --git a/binding/SkiaSharp.NativeAssets.Tizen/SkiaSharp.NativeAssets.Tizen.csproj b/binding/SkiaSharp.NativeAssets.Tizen/SkiaSharp.NativeAssets.Tizen.csproj index 5f1439c56d7..aa1328a1e08 100644 --- a/binding/SkiaSharp.NativeAssets.Tizen/SkiaSharp.NativeAssets.Tizen.csproj +++ b/binding/SkiaSharp.NativeAssets.Tizen/SkiaSharp.NativeAssets.Tizen.csproj @@ -1,13 +1,14 @@  - $(TFMPrevious)-tizen$(TPVTizenPrevious);$(TFMCurrent)-tizen$(TPVTizenCurrent) + $(TFMPrevious)-tizen$(TPVTizenPrevious);$(TFMCurrent)-tizen$(TPVTizenCurrent);$(TFMMinimum)-tizen$(TPVTizenMinimum) SkiaSharp $(PackagingGroup) - Native Assets for Tizen - + + diff --git a/binding/SkiaSharp/GRGlInterface.cs b/binding/SkiaSharp/GRGlInterface.cs index 7518a696737..d0a023812f6 100644 --- a/binding/SkiaSharp/GRGlInterface.cs +++ b/binding/SkiaSharp/GRGlInterface.cs @@ -210,6 +210,7 @@ private partial class EvasGlLoader private readonly IntPtr glEvas; private readonly EvasGlApi api; +#if NET7_0_OR_GREATER [LibraryImport (libevas)] internal static partial IntPtr evas_gl_api_get (IntPtr evas_gl); @@ -221,6 +222,19 @@ private partial class EvasGlLoader [LibraryImport(libevas)] internal static partial IntPtr evas_gl_proc_address_get (IntPtr evas_gl, [MarshalAs (UnmanagedType.LPStr)] string name); +#else + [DllImport (libevas)] + internal static extern IntPtr evas_gl_api_get (IntPtr evas_gl); + + [DllImport (libevas)] + internal static extern IntPtr evas_gl_context_api_get (IntPtr evas_gl, IntPtr ctx); + + [DllImport (libevas)] + internal static extern IntPtr evas_gl_current_context_get (IntPtr evas_gl); + + [DllImport (libevas)] + internal static extern IntPtr evas_gl_proc_address_get (IntPtr evas_gl, [MarshalAs (UnmanagedType.LPStr)] string name); +#endif static EvasGlLoader () { diff --git a/externals/skia b/externals/skia index 2798a3fe743..41cee7a8fb1 160000 --- a/externals/skia +++ b/externals/skia @@ -1 +1 @@ -Subproject commit 2798a3fe743e306f72b49ff4d78172ffacb3f7ce +Subproject commit 41cee7a8fb1a54a4b1f2f829aef39c33617de60f diff --git a/native/tizen/build.cake b/native/tizen/build.cake index 1c22e96ae4b..88aaa41b592 100644 --- a/native/tizen/build.cake +++ b/native/tizen/build.cake @@ -9,20 +9,31 @@ DirectoryPath TIZEN_STUDIO_HOME = EnvironmentVariable("TIZEN_STUDIO_HOME") ?? PR var bat = IsRunningOnWindows() ? ".bat" : ""; var tizen = TIZEN_STUDIO_HOME.CombineWithFilePath($"tools/ide/bin/tizen{bat}").FullPath; -var tizenVersion = "6.0"; + +void SetProjectProfile(string projectDir, string profile) +{ + var propFile = MakeAbsolute((FilePath)$"{projectDir}/project_def.prop").FullPath; + var propContent = System.IO.File.ReadAllText(propFile); + propContent = System.Text.RegularExpressions.Regex.Replace( + propContent, @"^profile = .+$", $"profile = {profile}", + System.Text.RegularExpressions.RegexOptions.Multiline); + System.IO.File.WriteAllText(propFile, propContent); +} Task("libSkiaSharp") .IsDependentOn("git-sync-deps") .Does(() => { - Build("armel", "arm", $"mobile-{tizenVersion}-device.core"); - Build("i586", "x86", $"mobile-{tizenVersion}-emulator.core"); + Build("armel", "arm", "arm", "mobile-6.0-device.core", "mobile-6.0", "6.0"); + Build("i586", "x86", "x86", "mobile-6.0-emulator.core", "mobile-6.0", "6.0"); + Build("x86_64","x64", "x86_64", "tizen-8.0-emulator64.core", "tizen-8.0", "8.0"); + Build("aarch64","arm64","aarch64", "tizen-8.0-device64.core", "tizen-8.0", "8.0"); - void Build(string arch, string skiaArch, string rootstrap) + void Build(string outputDir, string skiaArch, string tizenArch, string rootstrap, string profile, string ncliVersion) { - if (Skip(arch)) return; + if (Skip(outputDir)) return; - GnNinja($"tizen/{arch}", "skia modules/skottie", + GnNinja($"tizen/{outputDir}", "skia modules/skottie", $"target_os='tizen' " + $"target_cpu='{skiaArch}' " + $"skia_enable_ganesh=true " + @@ -39,14 +50,20 @@ Task("libSkiaSharp") $"skia_enable_skottie=true " + $"extra_cflags=[ '-DSKIA_C_DLL', '-DXML_DEV_URANDOM' ] " + $"ncli='{TIZEN_STUDIO_HOME}' " + - $"ncli_version='{tizenVersion}'"); + $"ncli_version='{ncliVersion}'"); + + SetProjectProfile("libSkiaSharp", profile); + + var buildDir = MakeAbsolute((DirectoryPath)$"libSkiaSharp/{CONFIGURATION}"); + if (DirectoryExists(buildDir)) + DeleteDirectory(buildDir, new DeleteDirectorySettings { Recursive = true, Force = true }); RunProcess(tizen, new ProcessSettings { - Arguments = $"build-native -a {skiaArch} -c llvm -C {CONFIGURATION} -r {rootstrap}" , + Arguments = $"build-native -a {tizenArch} -c llvm -C {CONFIGURATION} -r {rootstrap}", WorkingDirectory = MakeAbsolute((DirectoryPath)"libSkiaSharp").FullPath, }); - var outDir = OUTPUT_PATH.Combine(arch); + var outDir = OUTPUT_PATH.Combine(outputDir); EnsureDirectoryExists(outDir); CopyFile($"libSkiaSharp/{CONFIGURATION}/libskiasharp.so", outDir.CombineWithFilePath("libSkiaSharp.so")); } @@ -55,19 +72,27 @@ Task("libSkiaSharp") Task("libHarfBuzzSharp") .Does(() => { - Build("armel", "arm", $"mobile-{tizenVersion}-device.core"); - Build("i586", "x86", $"mobile-{tizenVersion}-emulator.core"); + Build("armel", "arm", "mobile-6.0-device.core", "mobile-6.0"); + Build("i586", "x86", "mobile-6.0-emulator.core", "mobile-6.0"); + Build("x86_64","x86_64", "tizen-8.0-emulator64.core", "tizen-8.0"); + Build("aarch64","aarch64","tizen-8.0-device64.core", "tizen-8.0"); - void Build(string arch, string cliArch, string rootstrap) + void Build(string outputDir, string tizenArch, string rootstrap, string profile) { - if (Skip(arch)) return; + if (Skip(outputDir)) return; + + SetProjectProfile("libHarfBuzzSharp", profile); + + var buildDir = MakeAbsolute((DirectoryPath)$"libHarfBuzzSharp/{CONFIGURATION}"); + if (DirectoryExists(buildDir)) + DeleteDirectory(buildDir, new DeleteDirectorySettings { Recursive = true, Force = true }); RunProcess(tizen, new ProcessSettings { - Arguments = $"build-native -a {cliArch} -c llvm -C {CONFIGURATION} -r {rootstrap}" , + Arguments = $"build-native -a {tizenArch} -c llvm -C {CONFIGURATION} -r {rootstrap}", WorkingDirectory = MakeAbsolute((DirectoryPath)"libHarfBuzzSharp").FullPath, }); - var outDir = OUTPUT_PATH.Combine(arch); + var outDir = OUTPUT_PATH.Combine(outputDir); EnsureDirectoryExists(outDir); CopyFile($"libHarfBuzzSharp/{CONFIGURATION}/libharfbuzzsharp.so", outDir.CombineWithFilePath("libHarfBuzzSharp.so")); } diff --git a/scripts/install-tizen.ps1 b/scripts/install-tizen.ps1 index f2fb8a74022..66b641130de 100644 --- a/scripts/install-tizen.ps1 +++ b/scripts/install-tizen.ps1 @@ -3,7 +3,7 @@ # - https://developercommunity.visualstudio.com/content/problem/661596/the-updated-path-doesnt-kick-in.html Param( - [string] $Version = "5.6", + [string] $Version = "6.1", [string] $InstallDestination = $null, [boolean] $UpgradeLLVM = $true ) @@ -33,7 +33,7 @@ Write-Host "Install destination is '$ts'..." $tsTemp = Join-Path "$HOME_DIR" "tizen-temp" $install = Join-Path "$tsTemp" "tizen-install.$ext" -$packages = "MOBILE-6.0-NativeAppDevelopment" +$packages = "MOBILE-6.0-NativeAppDevelopment,TIZEN-8.0-NativeAppDevelopment" # download Write-Host "Downloading SDK to '$install'..." @@ -46,6 +46,12 @@ Write-Host "JAVA_HOME is: $env:JAVA_HOME" Write-Host "PATH contains JAVA_HOME: $($env:PATH.Contains("$env:JAVA_HOME"))" & "java" -version +# clean up any previous install (the 6.1 installer fails if the directory already exists) +if (Test-Path "$ts") { + Write-Host "Removing previous installation at '$ts'..." + Remove-Item -Path "$ts" -Recurse -Force +} + # install Write-Host "Installing SDK to '$ts'..." if ($IsMacOS -or $IsLinux) { diff --git a/source/SkiaSharp.Build.Override.in.props b/source/SkiaSharp.Build.Override.in.props index 8889e0583c9..239158abd53 100644 --- a/source/SkiaSharp.Build.Override.in.props +++ b/source/SkiaSharp.Build.Override.in.props @@ -32,6 +32,7 @@ dotnet workload install tizen (for Tizen support - Samsung) --> + diff --git a/source/SkiaSharp.Build.props b/source/SkiaSharp.Build.props index cda85145b9c..ae278d52546 100644 --- a/source/SkiaSharp.Build.props +++ b/source/SkiaSharp.Build.props @@ -64,6 +64,8 @@ net9.0 net10.0 + + net6.0 @@ -84,6 +86,8 @@ 26.2 10.0 10.0.19041.0 + + 8.0 @@ -115,9 +119,13 @@ $(TFMBase) + + $(TFMMinimum) + $(TFMMinimum)-tizen$(TPVTizenMinimum) + - $(BasicTargetFrameworksCurrent);$(BasicTargetFrameworksPrevious);$(BasicTargetFrameworksBase) - $(PlatformTargetFrameworksCurrent);$(PlatformTargetFrameworksPrevious) + $(BasicTargetFrameworksCurrent);$(BasicTargetFrameworksPrevious);$(BasicTargetFrameworksBase);$(BasicTargetFrameworksMinimum) + $(PlatformTargetFrameworksCurrent);$(PlatformTargetFrameworksPrevious);$(PlatformTargetFrameworksMinimum) $(BasicTargetFrameworks);$(PlatformTargetFrameworks) From f2a8ef9fe2acdd863e2181abc644a328aafeb7ed Mon Sep 17 00:00:00 2001 From: Matthew Leibowitz Date: Mon, 30 Mar 2026 16:20:24 +0200 Subject: [PATCH 2/2] Address review feedback: safety guards and consistency - install-tizen.ps1: Add -Force flag; require it when using custom InstallDestination - azure-templates-jobs-bootstrapper.yml: Pass -Force on CI - build.cake: SetProjectProfile fails fast if profile line not found - IncludeNativeAssets targets: Remove Exists() guards on x64/arm64 entries for consistency with other platforms Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- binding/IncludeNativeAssets.HarfBuzzSharp.targets | 4 ++-- binding/IncludeNativeAssets.SkiaSharp.targets | 4 ++-- native/tizen/build.cake | 6 ++++-- scripts/install-tizen.ps1 | 5 ++--- source/SkiaSharp.Build.Override.in.props | 1 - 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/binding/IncludeNativeAssets.HarfBuzzSharp.targets b/binding/IncludeNativeAssets.HarfBuzzSharp.targets index 24e4e765943..f729713812e 100644 --- a/binding/IncludeNativeAssets.HarfBuzzSharp.targets +++ b/binding/IncludeNativeAssets.HarfBuzzSharp.targets @@ -56,12 +56,12 @@ bin\runtimes\tizen-armel\native\ libHarfBuzzSharp.so - + false bin\runtimes\tizen-x64\native\ libHarfBuzzSharp.so - + false bin\runtimes\tizen-arm64\native\ libHarfBuzzSharp.so diff --git a/binding/IncludeNativeAssets.SkiaSharp.targets b/binding/IncludeNativeAssets.SkiaSharp.targets index 8a38990315a..f01852fdbbc 100644 --- a/binding/IncludeNativeAssets.SkiaSharp.targets +++ b/binding/IncludeNativeAssets.SkiaSharp.targets @@ -56,12 +56,12 @@ bin\runtimes\tizen-armel\native\ libSkiaSharp.so - + false bin\runtimes\tizen-x64\native\ libSkiaSharp.so - + false bin\runtimes\tizen-arm64\native\ libSkiaSharp.so diff --git a/native/tizen/build.cake b/native/tizen/build.cake index 88aaa41b592..85c0d914eb9 100644 --- a/native/tizen/build.cake +++ b/native/tizen/build.cake @@ -14,10 +14,12 @@ void SetProjectProfile(string projectDir, string profile) { var propFile = MakeAbsolute((FilePath)$"{projectDir}/project_def.prop").FullPath; var propContent = System.IO.File.ReadAllText(propFile); - propContent = System.Text.RegularExpressions.Regex.Replace( + var newContent = System.Text.RegularExpressions.Regex.Replace( propContent, @"^profile = .+$", $"profile = {profile}", System.Text.RegularExpressions.RegexOptions.Multiline); - System.IO.File.WriteAllText(propFile, propContent); + if (newContent == propContent) + throw new Exception($"Failed to set profile in '{propFile}': no 'profile = ...' line found."); + System.IO.File.WriteAllText(propFile, newContent); } Task("libSkiaSharp") diff --git a/scripts/install-tizen.ps1 b/scripts/install-tizen.ps1 index 66b641130de..619e5130f01 100644 --- a/scripts/install-tizen.ps1 +++ b/scripts/install-tizen.ps1 @@ -46,10 +46,9 @@ Write-Host "JAVA_HOME is: $env:JAVA_HOME" Write-Host "PATH contains JAVA_HOME: $($env:PATH.Contains("$env:JAVA_HOME"))" & "java" -version -# clean up any previous install (the 6.1 installer fails if the directory already exists) +# warn if there is an existing install (the 6.1 installer may fail if the directory already exists) if (Test-Path "$ts") { - Write-Host "Removing previous installation at '$ts'..." - Remove-Item -Path "$ts" -Recurse -Force + Write-Host "##[warning]Existing Tizen Studio installation found at '$ts'. The installer may fail if this directory already exists." } # install diff --git a/source/SkiaSharp.Build.Override.in.props b/source/SkiaSharp.Build.Override.in.props index 239158abd53..8889e0583c9 100644 --- a/source/SkiaSharp.Build.Override.in.props +++ b/source/SkiaSharp.Build.Override.in.props @@ -32,7 +32,6 @@ dotnet workload install tizen (for Tizen support - Samsung) --> -