Skip to content

Commit

Permalink
Merge pull request #903 from unoplatform/dev/jela/cache-break
Browse files Browse the repository at this point in the history
fix: Restore cache breaking
  • Loading branch information
jeromelaban authored Oct 17, 2024
2 parents 2aa82e3 + ca336cc commit 0d862de
Show file tree
Hide file tree
Showing 13 changed files with 453 additions and 362 deletions.
2 changes: 1 addition & 1 deletion .vsts-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -53,4 +53,4 @@ stages:
- template: build/ci/stage-build-macos-tests.yml
parameters:
jobName: macOS_Tests
vmImage: macOS-12
vmImage: macOS-14
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { config as unoConfig } from "$(REMOTE_WEBAPP_PATH)uno-config.js";
import { config as unoConfig } from "$(REMOTE_WEBAPP_PATH)$(REMOTE_BASE_PATH)/uno-config.js";


if (unoConfig.environmentVariables["UNO_BOOTSTRAP_DEBUGGER_ENABLED"] !== "True") {
Expand Down
58 changes: 58 additions & 0 deletions src/Uno.Wasm.Bootstrap/Extensions/TaskItemExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using Microsoft.Build.Framework;

namespace Uno.Wasm.Bootstrap.Extensions;

internal static class TaskItemExtensions
{
public static (string fullPath, string relativePath) GetFilePaths(this ITaskItem item, Microsoft.Build.Utilities.TaskLoggingHelper log, string currentProjectPath)
{
if (item.GetMetadata("RelativePath") is { } relativePath && !string.IsNullOrEmpty(relativePath))
{
log.LogMessage(MessageImportance.Low, $"RelativePath '{relativePath}' for full path '{item.GetMetadata("FullPath")}' (ItemSpec: {item.ItemSpec})");

// This case is mainly for shared projects and files out of the baseSourceFile path
return (item.GetMetadata("FullPath"), relativePath);
}
else if (item.GetMetadata("TargetPath") is { } targetPath && !string.IsNullOrEmpty(targetPath))
{
log.LogMessage(MessageImportance.Low, $"TargetPath '{targetPath}' for full path '{item.GetMetadata("FullPath")}' (ItemSpec: {item.ItemSpec})");

// This is used for item remapping
return (item.GetMetadata("FullPath"), targetPath);
}
else if (item.GetMetadata("Link") is { } link && !string.IsNullOrEmpty(link))
{
log.LogMessage(MessageImportance.Low, $"Link '{link}' for full path '{item.GetMetadata("FullPath")}' (ItemSpec: {item.ItemSpec})");

// This case is mainly for shared projects and files out of the baseSourceFile path
return (item.GetMetadata("FullPath"), link);
}
else if (item.GetMetadata("FullPath") is { } fullPath && File.Exists(fullPath))
{
log.LogMessage(MessageImportance.Low, $"FullPath '{fullPath}' (ItemSpec: {item.ItemSpec})");

var sourceFilePath = item.ItemSpec;

if (sourceFilePath.StartsWith(currentProjectPath))
{
// This is for files added explicitly through other targets (e.g. Microsoft.TypeScript.MSBuild)
return (fullPath: fullPath, sourceFilePath.Replace(currentProjectPath + Path.DirectorySeparatorChar, ""));
}
else
{
return (fullPath, sourceFilePath);
}
}
else
{
log.LogMessage(MessageImportance.Low, $"Without metadata '{item.GetMetadata("FullPath")}' (ItemSpec: {item.ItemSpec})");

return (item.GetMetadata("FullPath"), item.ItemSpec);
}
}

}
5 changes: 4 additions & 1 deletion src/Uno.Wasm.Bootstrap/GenerateUnoAssetsManifestTask.cs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@ public class GenerateUnoAssetsManifest_v0 : Microsoft.Build.Utilities.Task
[Required]
public string IntermediateOutputPath { get; set; } = "";

[Required]
public string OutputPackagePath { get; set; } = "";

[Output]
public ITaskItem[] UnoAssetsFile { get; set; } = [];

Expand Down Expand Up @@ -76,7 +79,7 @@ private void AddStaticAsset(string targetPath, string filePath)
{
["CopyToOutputDirectory"] = "PreserveNewest",
["ContentRoot"] = contentRoot,
["Link"] = "wwwroot/" + targetPath,
["Link"] = $"wwwroot/{OutputPackagePath}/" + targetPath,
});

UnoAssetsFile = UnoAssetsFile.Concat([indexMetadata]).ToArray();
Expand Down
139 changes: 139 additions & 0 deletions src/Uno.Wasm.Bootstrap/GenerateUnoNativeAssetsTask.AOTProfile.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
// ******************************************************************
// Copyright � 2015-2022 Uno Platform inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// ******************************************************************
//
// This file is based on the work from https://github.com/praeclarum/Ooui
//
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Diagnostics;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Net;
using System.Runtime.InteropServices;
using System.Security;
using System.Security.Cryptography;
using System.Text;
using System.Text.RegularExpressions;
using System.Transactions;
using Microsoft.Build.Framework;
using Microsoft.Win32.SafeHandles;
using Mono.Cecil;
using Mono.CompilerServices.SymbolWriter;
using Newtonsoft.Json.Linq;
using Uno.Wasm.Bootstrap.Extensions;

namespace Uno.Wasm.Bootstrap;

public partial class GenerateUnoNativeAssetsTask_v0
{
/// <summary>
/// Applies a temporary workaround for https://github.com/mono/mono/issues/19824
/// </summary>
private string? TransformAOTProfile()
{
var profilePath = AotProfile;

if (profilePath != null)
{
var reader = new Mono.Profiler.Aot.ProfileReader();
Mono.Profiler.Aot.ProfileData profile;
using (FileStream stream = File.OpenRead(profilePath))
{
profile = reader.ReadAllData(stream);
}

var excludedMethodsList = AOTProfileExcludedMethods
.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries)
.ToList();

var excludedAssemblies = MixedModeExcludedAssembly?.ToDictionary(i => i.ItemSpec, i => i.ItemSpec)
?? new Dictionary<string, string>();

if (excludedMethodsList.Any() || excludedAssemblies.Any())
{
// LoadIntoBufferAsync uses exception filtering
excludedMethodsList.AddRange(DefaultAOTProfileExcludedMethods);

TryDumpProfileMethods(profile, "AOTProfileDump.Original.txt");

var excludedMethods = excludedMethodsList.Select(e => new Regex(e)).ToList();

var q = from m in profile.Methods
where !excludedMethods.Any(e => e.Match(m.Type.FullName + '.' + m.Name).Success)
&& !excludedAssemblies.ContainsKey(m.Type.Module.Name)
select m;

profile.Methods = q.ToArray();

TryDumpProfileMethods(profile, "AOTProfileDump.Filtered.txt");

var writer = new Mono.Profiler.Aot.ProfileWriter();

var outputFile = Path.Combine(IntermediateOutputPath, "aot-filtered.profile");
using (var outStream = File.Create(outputFile))
{
writer.WriteAllData(outStream, profile);
}

return outputFile;
}
}

return profilePath;
}

private IEnumerable<string> DefaultAOTProfileExcludedMethods =>
new[]
{
@"ManifestBasedResourceGroveler\.InternalGetSatelliteAssembly", // https://github.com/dotnet/runtime/issues/45698

@"System\.Reflection\.Assembly\.GetExecutingAssembly", // https://github.com/dotnet/runtime/issues/47996
@"System\.RuntimeType\.GetType",
@"System\.RuntimeTypeHandle\.internal_from_name",
@"System\.RuntimeTypeHandle\.GetTypeByName",
@"System\.Type\.GetType",
@"System\.Runtime\.Loader\.AssemblyLoadContext\.InternalLoadFromPath",
@"System\.Runtime\.Loader\.AssemblyLoadContext\.InternalLoadFile",
@"System\.Runtime\.Loader\.AssemblyLoadContext\.LoadFromAssemblyName",
@"System\.Reflection\.Assembly\.Load",
@"System\.Reflection\.Assembly\.InternalLoad",
@"System\.Reflection\.RuntimeAssembly\.InternalGetSatelliteAssembly",
@"System\.Reflection\.RuntimeAssembly\.InternalLoad",
};

private void TryDumpProfileMethods(Mono.Profiler.Aot.ProfileData profile, string filePath)
{
if (GenerateAOTProfileDebugList)
{
var sb = new StringBuilder();

foreach (var method in profile.Methods)
{
var genericParameters = string.Join("|", method.GenericInst?.Types.Select(t => t.ToString()) ?? []);

sb.AppendLine($"{method.Type.Module.Name};{method.Type.FullName}.{method.Name};{method.GenericInst?.Id};{genericParameters}");
}

File.WriteAllText(Path.Combine(IntermediateOutputPath, filePath), sb.ToString());
}
}

private bool UseAotProfile
=> !string.IsNullOrEmpty(AotProfile) && _runtimeExecutionMode == RuntimeExecutionMode.InterpreterAndAOT;
}
123 changes: 123 additions & 0 deletions src/Uno.Wasm.Bootstrap/GenerateUnoNativeAssetsTask.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@

// ******************************************************************
// Copyright � 2015-2022 Uno Platform inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// ******************************************************************
//
// This file is based on the work from https://github.com/praeclarum/Ooui
//
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Numerics;
using System.Runtime.InteropServices;
using System.Security.Cryptography;
using Microsoft.Build.Framework;
using Microsoft.Build.Utilities;
using Uno.Wasm.Bootstrap.Extensions;

namespace Uno.Wasm.Bootstrap;

public partial class GenerateUnoNativeAssetsTask_v0 : Microsoft.Build.Utilities.Task
{
private RuntimeExecutionMode _runtimeExecutionMode;

public string AotProfile { get; set; } = "";

public bool GenerateAOTProfile { get; set; }

public string AOTProfileExcludedMethods { get; set; } = "";

public bool GenerateAOTProfileDebugList { get; set; } = false;

public bool WasmBuildNative { get; set; }

public bool RunAOTCompilation { get; set; }

public Microsoft.Build.Framework.ITaskItem[]? MixedModeExcludedAssembly { get; set; }

public bool EnableThreads { get; set; }

public ITaskItem[]? Assets { get; set; }

public string EmscriptenVersion { get; set; } = "";

[Required]
public string IntermediateOutputPath { get; set; } = "";

[Required]
public string CurrentProjectPath { get; set; } = "";

[Output]
public ITaskItem[] NativeFileReference { get; set; } = [];

[Output]
public string? FilteredAotProfile { get; set; } = "";

public override bool Execute()
{
ParseProperties();
GenerateBitcodeFiles();
BuildAOTProfile();

return true;
}

private void ParseProperties()
=> _runtimeExecutionMode
= WasmBuildNative && RunAOTCompilation ? RuntimeExecutionMode.InterpreterAndAOT : RuntimeExecutionMode.Interpreter;

private void BuildAOTProfile()
{
var useAotProfile = !GenerateAOTProfile && UseAotProfile;

if (useAotProfile)
{
// If the profile was transformed, we need to use the transformed profile
FilteredAotProfile = TransformAOTProfile();
}
}
private void GenerateBitcodeFiles()
{
var bitcodeFiles = Assets
?.Where(a => a.ItemSpec.EndsWith(".o") || a.ItemSpec.EndsWith(".a"))
.Where(a => !bool.TryParse(a.GetMetadata("UnoAotCompile"), out var compile) || compile)
.Select(a => a.GetFilePaths(Log, CurrentProjectPath).fullPath)
.ToArray()
?? [];

List<string> features = new()
{
EnableThreads ? "mt" : "st",
"simd"
};

Log.LogMessage(MessageImportance.Low, $"Bitcode files features lookup filter: {string.Join(",", features)}");

if (Version.TryParse(EmscriptenVersion, out var emsdkVersion))
{
var list = BitcodeFilesSelector.Filter(emsdkVersion, features.ToArray(), bitcodeFiles);

NativeFileReference = list.Select(i => new TaskItem(i)).ToArray();
}
else
{
Log.LogMessage(MessageImportance.Low, $"EmscriptenVersion is not set, skipping native assets");
}
}

}
43 changes: 0 additions & 43 deletions src/Uno.Wasm.Bootstrap/RemoveDirTask.cs

This file was deleted.

Loading

0 comments on commit 0d862de

Please sign in to comment.