diff --git a/src/SourceGenerators/Uno.UI.Tasks/Content/Uno.UI.Tasks.targets b/src/SourceGenerators/Uno.UI.Tasks/Content/Uno.UI.Tasks.targets
index 7a0ad2adaa4a..59ab282bd3cb 100644
--- a/src/SourceGenerators/Uno.UI.Tasks/Content/Uno.UI.Tasks.targets
+++ b/src/SourceGenerators/Uno.UI.Tasks/Content/Uno.UI.Tasks.targets
@@ -11,6 +11,8 @@
+
+
@@ -45,7 +47,7 @@
+ Condition="'$(DesignTimeBuild)' != 'true'">
@@ -178,16 +180,51 @@
+
+
+
+
+ <_UnoUpriResource Condition="'%(GeneratedFiles.UnoResourceTarget)' == 'Uno'" Include="@(GeneratedFiles->'%(LogicalName)')">
+ %(GeneratedFiles.Language)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
@@ -195,49 +232,61 @@
<_SubstitutionFiles Include="$(IntermediateOutputPath)\Substitutions\*.Substitutions.xml" />
+
+
+
+
+ TargetDefinitionFile="$(IntermediateOutputPath)ILLink.Substitutions.xml" />
-
+
+
+ $(TargetsTriggeredByCompilation);_UnoSetupEmbeddedResourcesInjection
+
+
+
+
+
+ <_UnoRequiresEmbeddedResourcesInjection>true
+
+
+
+
<_UnoEmbeddedResourcesInjectionAfterTargets Include="CoreCompile" />
- <_UnoEmbeddedResourcesInjectionAfterTargets Include="_UnoLinkerHintsSubstitutionsMerge" />
- <_UnoEmbeddedResourcesInjectionAssembliesForReferencePaths
- Include="@(ReferencePath)"
- Condition="'%(Extension)' == '.dll'" />
+ <_UnoEmbeddedResourcesInjectionAssembliesForReferencePaths Include="@(ReferencePath)" Condition="'%(Extension)' == '.dll'" />
+ ReferencePath="@(_UnoEmbeddedResourcesInjectionAssembliesForReferencePaths)" />
+
+
+
Encoding.UTF8;
- }
}
}
diff --git a/src/SourceGenerators/Uno.UI.Tasks/ResourcesGenerator/ResourcesGenerationTask.cs b/src/SourceGenerators/Uno.UI.Tasks/ResourcesGenerator/ResourcesGenerationTask.cs
index 36fb8e8bd18a..aa3119ceb429 100644
--- a/src/SourceGenerators/Uno.UI.Tasks/ResourcesGenerator/ResourcesGenerationTask.cs
+++ b/src/SourceGenerators/Uno.UI.Tasks/ResourcesGenerator/ResourcesGenerationTask.cs
@@ -165,7 +165,8 @@ string buildBasePath()
new Dictionary()
{
{ "UnoResourceTarget", "Uno" },
- { "LogicalName", logicalTargetPath.Replace(Path.DirectorySeparatorChar, '.') }
+ { "LogicalName", logicalTargetPath.Replace(Path.DirectorySeparatorChar, '.') },
+ { "Language", language }
}
);
}
diff --git a/src/SourceGenerators/Uno.UI.Tasks/ResourcesGenerator/UpriFeaturesGeneratorTask.cs b/src/SourceGenerators/Uno.UI.Tasks/ResourcesGenerator/UpriFeaturesGeneratorTask.cs
new file mode 100644
index 000000000000..0309d78fb660
--- /dev/null
+++ b/src/SourceGenerators/Uno.UI.Tasks/ResourcesGenerator/UpriFeaturesGeneratorTask.cs
@@ -0,0 +1,58 @@
+#nullable enable
+
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Globalization;
+using System.Linq;
+using Microsoft.Build.Framework;
+using Microsoft.Build.Utilities;
+
+namespace Uno.UI.Tasks.ResourcesGenerator
+{
+ public class UpriFeaturesGeneratorTask_v0 : Task
+ {
+ public ITaskItem[]? Languages { get; set; }
+
+ [Output]
+ public ITaskItem[]? OutputFeatures { get; set; }
+
+ public override bool Execute()
+ {
+ // Debugger.Launch();
+
+ if (Languages != null && Languages.Length > 0)
+ {
+ // Get all cultures except Invariant and legacy Chinese (superseded by zh-Hans and zh-Hant)
+ var allCultures =
+ CultureInfo
+ .GetCultures(CultureTypes.NeutralCultures | CultureTypes.SpecificCultures)
+ .Where(c => c.IetfLanguageTag != string.Empty && c.Name != "zh-CHS" && c.Name != "zh-CHT")
+ .ToDictionary(c => c.IetfLanguageTag, c => "false");
+
+ foreach (var language in Languages)
+ {
+ var culture = new CultureInfo(language.ItemSpec);
+
+ while (culture.IetfLanguageTag != string.Empty)
+ {
+ allCultures[culture.IetfLanguageTag] = "true";
+
+ culture = culture.Parent;
+ }
+ }
+
+ OutputFeatures =
+ allCultures
+ .Select(kvp => new TaskItem($"UPRI_{kvp.Key.Replace('-', '_').ToLowerInvariant()}", new Dictionary() { ["Value"] = kvp.Value }))
+ .ToArray();
+ }
+ else
+ {
+ OutputFeatures = Array.Empty();
+ }
+
+ return true;
+ }
+ }
+}
diff --git a/src/SourceGenerators/Uno.UI.Tasks/ResourcesGenerator/UpriSubstitutionsGeneratorTask.cs b/src/SourceGenerators/Uno.UI.Tasks/ResourcesGenerator/UpriSubstitutionsGeneratorTask.cs
new file mode 100644
index 000000000000..e3404be4f55d
--- /dev/null
+++ b/src/SourceGenerators/Uno.UI.Tasks/ResourcesGenerator/UpriSubstitutionsGeneratorTask.cs
@@ -0,0 +1,69 @@
+#nullable enable
+
+using System.Diagnostics;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Xml;
+using Microsoft.Build.Framework;
+using Microsoft.Build.Utilities;
+
+namespace Uno.UI.Tasks.ResourcesGenerator
+{
+ ///
+ /// Generates a linker substitution file for UPRI resources.
+ /// This allows the linker to trim unused localization resources.
+ ///
+ public class UpriSubstitutionsGeneratorTask_v0 : Task
+ {
+ [Required]
+ public string? AssemblyName { get; set; }
+
+ [Required]
+ public ITaskItem[]? Resources { get; set; }
+
+ [Required]
+ public string? OutputFile { get; set; }
+
+ public override bool Execute()
+ {
+ // Debugger.Launch();
+
+ if (!string.IsNullOrEmpty(AssemblyName) && Resources != null && !string.IsNullOrEmpty(OutputFile))
+ {
+ var xml = new XmlDocument();
+
+ var linkerNode = xml.CreateElement(string.Empty, "linker", string.Empty);
+
+ xml.AppendChild(linkerNode);
+
+ foreach (var resourceGroup in Resources.GroupBy(r => r.GetMetadata("Language").Replace('-', '_').ToLowerInvariant()))
+ {
+ var assemblyNode = xml.CreateElement(string.Empty, "assembly", string.Empty);
+ assemblyNode.SetAttribute("fullname", AssemblyName);
+ assemblyNode.SetAttribute("feature", $"UPRI_{resourceGroup.Key}");
+ assemblyNode.SetAttribute("featurevalue", "false");
+
+ linkerNode.AppendChild(assemblyNode);
+
+ foreach (var resource in resourceGroup)
+ {
+ var resourceNode = xml.CreateElement(string.Empty, "resource", string.Empty);
+ resourceNode.SetAttribute("name", resource.ItemSpec);
+ resourceNode.SetAttribute("action", "remove");
+
+ assemblyNode.AppendChild(resourceNode);
+ }
+ }
+
+ Directory.CreateDirectory(Path.GetDirectoryName(OutputFile));
+
+ using var sw = new StreamWriter(OutputFile, append: false, Encoding.UTF8);
+
+ xml.Save(sw);
+ }
+
+ return true;
+ }
+ }
+}
diff --git a/src/Uno.UI.Wasm.Tests/Uno.UI.Wasm.Tests.csproj b/src/Uno.UI.Wasm.Tests/Uno.UI.Wasm.Tests.csproj
index fd0ab4811b3c..d11cd78b5620 100644
--- a/src/Uno.UI.Wasm.Tests/Uno.UI.Wasm.Tests.csproj
+++ b/src/Uno.UI.Wasm.Tests/Uno.UI.Wasm.Tests.csproj
@@ -6,9 +6,6 @@
$(MSBuildThisFileDirectory)tsbindings
$(DefineConstants);__WASM__
-
- true
-
true
false
@@ -83,10 +80,6 @@
-
- <_UnoEmbeddedResourcesInjectionAfterTargets Include="CompileTypeScriptWithTSConfig" />
-
-