From 4e7c2f231097e6a1d1329b203fd118089010b3b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Fi=C5=A1era?= Date: Thu, 17 Aug 2023 12:18:25 +0200 Subject: [PATCH 01/17] Use WasmSdk in browser template --- .../templates/templates/browser/README.md | 26 ------------------- .../templates/browser/browser.0.csproj | 11 ++------ .../browser/{ => wwwroot}/index.html | 0 .../templates/browser/{ => wwwroot}/main.js | 0 4 files changed, 2 insertions(+), 35 deletions(-) delete mode 100644 src/mono/wasm/templates/templates/browser/README.md rename src/mono/wasm/templates/templates/browser/{ => wwwroot}/index.html (100%) rename src/mono/wasm/templates/templates/browser/{ => wwwroot}/main.js (100%) diff --git a/src/mono/wasm/templates/templates/browser/README.md b/src/mono/wasm/templates/templates/browser/README.md deleted file mode 100644 index 7ddf4fd1bce9bd..00000000000000 --- a/src/mono/wasm/templates/templates/browser/README.md +++ /dev/null @@ -1,26 +0,0 @@ -## .NET WebAssembly Browser app - -## Build - -You can build the app from Visual Studio or from the command-line: - -``` -dotnet build -c Debug/Release -``` - -After building the app, the result is in the `bin/$(Configuration)/net7.0/browser-wasm/AppBundle` directory. - -## Run - -You can build the app from Visual Studio or the command-line: - -``` -dotnet run -c Debug/Release -``` - -Or you can start any static file server from the AppBundle directory: - -``` -dotnet tool install dotnet-serve -dotnet serve -d:bin/$(Configuration)/net7.0/browser-wasm/AppBundle -``` \ No newline at end of file diff --git a/src/mono/wasm/templates/templates/browser/browser.0.csproj b/src/mono/wasm/templates/templates/browser/browser.0.csproj index 401bdae24fab86..588c5219582125 100644 --- a/src/mono/wasm/templates/templates/browser/browser.0.csproj +++ b/src/mono/wasm/templates/templates/browser/browser.0.csproj @@ -1,13 +1,6 @@ - + - net7.0 - browser-wasm - Exe + net8.0 true - - - - - diff --git a/src/mono/wasm/templates/templates/browser/index.html b/src/mono/wasm/templates/templates/browser/wwwroot/index.html similarity index 100% rename from src/mono/wasm/templates/templates/browser/index.html rename to src/mono/wasm/templates/templates/browser/wwwroot/index.html diff --git a/src/mono/wasm/templates/templates/browser/main.js b/src/mono/wasm/templates/templates/browser/wwwroot/main.js similarity index 100% rename from src/mono/wasm/templates/templates/browser/main.js rename to src/mono/wasm/templates/templates/browser/wwwroot/main.js From be4830db5adc591822968ee6fba092da11399add Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Fi=C5=A1era?= Date: Fri, 18 Aug 2023 10:56:56 +0200 Subject: [PATCH 02/17] Remove default html-path --- .../templates/templates/browser/runtimeconfig.template.json | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/mono/wasm/templates/templates/browser/runtimeconfig.template.json b/src/mono/wasm/templates/templates/browser/runtimeconfig.template.json index 8f0557352c6ed3..b96a94320ba5ee 100644 --- a/src/mono/wasm/templates/templates/browser/runtimeconfig.template.json +++ b/src/mono/wasm/templates/templates/browser/runtimeconfig.template.json @@ -3,9 +3,8 @@ "perHostConfig": [ { "name": "browser", - "html-path": "index.html", - "Host": "browser" + "host": "browser" } ] } -} +} \ No newline at end of file From 78da11ba8b59d4c32917a56495edb5941e376e83 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Fi=C5=A1era?= Date: Fri, 18 Aug 2023 10:57:26 +0200 Subject: [PATCH 03/17] Use wwwroot when looking for main.js in template for replacement --- src/mono/wasm/Wasm.Build.Tests/Templates/WasmTemplateTests.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mono/wasm/Wasm.Build.Tests/Templates/WasmTemplateTests.cs b/src/mono/wasm/Wasm.Build.Tests/Templates/WasmTemplateTests.cs index 76a64c9fe4e76a..219e0a61798eac 100644 --- a/src/mono/wasm/Wasm.Build.Tests/Templates/WasmTemplateTests.cs +++ b/src/mono/wasm/Wasm.Build.Tests/Templates/WasmTemplateTests.cs @@ -39,7 +39,7 @@ private void UpdateProgramCS() private void UpdateBrowserMainJs(string targetFramework, string runtimeAssetsRelativePath = DefaultRuntimeAssetsRelativePath) { - string mainJsPath = Path.Combine(_projectDir!, "main.js"); + string mainJsPath = Path.Combine(_projectDir!, "wwwroot", "main.js"); string mainJsContent = File.ReadAllText(mainJsPath); // .withExitOnUnhandledError() is available only only >net7.0 From 472b42f247c8b22ef0560bf0578061aa50ee3e50 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Fi=C5=A1era?= Date: Fri, 18 Aug 2023 11:08:28 +0200 Subject: [PATCH 04/17] Temporarily remove WasmRuntimeAssetsLocation from WBT because WasmSDK doesn't support it yet --- .../Wasm.Build.Tests/Templates/WasmTemplateTests.cs | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/src/mono/wasm/Wasm.Build.Tests/Templates/WasmTemplateTests.cs b/src/mono/wasm/Wasm.Build.Tests/Templates/WasmTemplateTests.cs index 219e0a61798eac..229324f6c12912 100644 --- a/src/mono/wasm/Wasm.Build.Tests/Templates/WasmTemplateTests.cs +++ b/src/mono/wasm/Wasm.Build.Tests/Templates/WasmTemplateTests.cs @@ -407,23 +407,21 @@ public void ConsolePublishAndRun(string config, bool aot, bool relinking) } [Theory] - [InlineData("", BuildTestBase.DefaultTargetFramework, DefaultRuntimeAssetsRelativePath)] - [InlineData("", BuildTestBase.DefaultTargetFramework, "./")] + [InlineData("", BuildTestBase.DefaultTargetFramework)] // [ActiveIssue("https://github.com/dotnet/runtime/issues/79313")] // [InlineData("-f net7.0", "net7.0")] - [InlineData("-f net8.0", "net8.0", DefaultRuntimeAssetsRelativePath)] - [InlineData("-f net8.0", "net8.0", "./")] - public async Task BrowserBuildAndRun(string extraNewArgs, string targetFramework, string runtimeAssetsRelativePath) + [InlineData("-f net8.0", "net8.0")] + public async Task BrowserBuildAndRun(string extraNewArgs, string targetFramework) { string config = "Debug"; string id = $"browser_{config}_{GetRandomId()}"; CreateWasmTemplateProject(id, "wasmbrowser", extraNewArgs); - UpdateBrowserMainJs(targetFramework, runtimeAssetsRelativePath); + UpdateBrowserMainJs(targetFramework); new DotNetCommand(s_buildEnv, _testOutput) .WithWorkingDirectory(_projectDir!) - .Execute($"build -c {config} -bl:{Path.Combine(s_buildEnv.LogRootPath, $"{id}.binlog")} {(runtimeAssetsRelativePath != DefaultRuntimeAssetsRelativePath ? "-p:WasmRuntimeAssetsLocation=" + runtimeAssetsRelativePath : "")}") + .Execute($"build -c {config} -bl:{Path.Combine(s_buildEnv.LogRootPath, $"{id}.binlog")}") .EnsureSuccessful(); using var runCommand = new RunCommand(s_buildEnv, _testOutput) From 74436a966dfe82c10e57fe20be1149ad65e5166e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Fi=C5=A1era?= Date: Fri, 18 Aug 2023 15:31:42 +0200 Subject: [PATCH 05/17] Integrate console log forward into DevServer --- src/mono/wasm/host/DevServer/DevServer.cs | 3 +- .../wasm/host/DevServer/DevServerStartup.cs | 33 ++++++++++++++++--- 2 files changed, 30 insertions(+), 6 deletions(-) diff --git a/src/mono/wasm/host/DevServer/DevServer.cs b/src/mono/wasm/host/DevServer/DevServer.cs index b1369deabcc0cc..1acbe6954eeb3b 100644 --- a/src/mono/wasm/host/DevServer/DevServer.cs +++ b/src/mono/wasm/host/DevServer/DevServer.cs @@ -70,8 +70,7 @@ private static IConfiguration ConfigureHostConfiguration(DevServerOptions option [WebHostDefaults.EnvironmentKey] = "Development", ["Logging:LogLevel:Microsoft"] = "Warning", ["Logging:LogLevel:Microsoft.Hosting.Lifetime"] = "Information", - [WebHostDefaults.StaticWebAssetsKey] = options.StaticWebAssetsPath, - ["ApplyCopHeaders"] = options.WebServerUseCrossOriginPolicy.ToString() + [WebHostDefaults.StaticWebAssetsKey] = options.StaticWebAssetsPath }; config.AddInMemoryCollection(inMemoryConfiguration); diff --git a/src/mono/wasm/host/DevServer/DevServerStartup.cs b/src/mono/wasm/host/DevServer/DevServerStartup.cs index f438caf4b4b7ae..417500c4682291 100644 --- a/src/mono/wasm/host/DevServer/DevServerStartup.cs +++ b/src/mono/wasm/host/DevServer/DevServerStartup.cs @@ -1,14 +1,18 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using System.Diagnostics; using System.IO; +using System.Net.WebSockets; using System.Threading.Tasks; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Routing; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Options; using Microsoft.WebAssembly.AppHost; namespace Microsoft.WebAssembly.AppHost.DevServer; @@ -27,16 +31,16 @@ public static void ConfigureServices(IServiceCollection services) services.AddRouting(); } - public static void Configure(IApplicationBuilder app, TaskCompletionSource realUrlsAvailableTcs, ILogger logger, IHostApplicationLifetime applicationLifetime, IConfiguration configuration) + public static void Configure(IApplicationBuilder app, IOptions optionsContainer, TaskCompletionSource realUrlsAvailableTcs, ILogger logger, IHostApplicationLifetime applicationLifetime, IConfiguration configuration) { app.UseDeveloperExceptionPage(); EnableConfiguredPathbase(app, configuration); app.UseWebAssemblyDebugging(); - bool applyCopHeaders = configuration.GetValue("ApplyCopHeaders"); + DevServerOptions options = optionsContainer.Value; - if (applyCopHeaders) + if (options.WebServerUseCrossOriginPolicy) { app.Use(async (ctx, next) => { @@ -63,6 +67,27 @@ public static void Configure(IApplicationBuilder app, TaskCompletionSource + { + router.MapGet("/console", async context => + { + if (!context.WebSockets.IsWebSocketRequest) + { + context.Response.StatusCode = 400; + return; + } + + using WebSocket socket = await context.WebSockets.AcceptWebSocketAsync(); + await options.OnConsoleConnected(socket); + }); + }); + } app.UseEndpoints(endpoints => { @@ -70,7 +95,7 @@ public static void Configure(IApplicationBuilder app, TaskCompletionSource { - if (applyCopHeaders) + if (options.WebServerUseCrossOriginPolicy) { // Browser multi-threaded runtime requires cross-origin policy headers to enable SharedArrayBuffer. ApplyCrossOriginPolicyHeaders(fileContext.Context); From 61789ebd3adf853fc41c9d865b4c413095c5868b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Fi=C5=A1era?= Date: Fri, 18 Aug 2023 15:44:11 +0200 Subject: [PATCH 06/17] Replace UseRouter --- src/mono/wasm/host/DevServer/DevServerStartup.cs | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/mono/wasm/host/DevServer/DevServerStartup.cs b/src/mono/wasm/host/DevServer/DevServerStartup.cs index 417500c4682291..52611bd7b2c1b7 100644 --- a/src/mono/wasm/host/DevServer/DevServerStartup.cs +++ b/src/mono/wasm/host/DevServer/DevServerStartup.cs @@ -73,19 +73,21 @@ public static void Configure(IApplicationBuilder app, IOptions if (options.OnConsoleConnected is not null) { - app.UseRouter(router => + app.Use(async (ctx, next) => { - router.MapGet("/console", async context => + if (ctx.Request.Path.StartsWithSegments("/console")) { - if (!context.WebSockets.IsWebSocketRequest) + if (!ctx.WebSockets.IsWebSocketRequest) { - context.Response.StatusCode = 400; + ctx.Response.StatusCode = 400; return; } - using WebSocket socket = await context.WebSockets.AcceptWebSocketAsync(); + using WebSocket socket = await ctx.WebSockets.AcceptWebSocketAsync(); await options.OnConsoleConnected(socket); - }); + } + + await next(ctx); }); } From 26294d6deac47b255807b5bb5f15d0227ca9e6f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Fi=C5=A1era?= Date: Mon, 21 Aug 2023 11:02:50 +0200 Subject: [PATCH 07/17] Use next middleware only if it's not console --- src/mono/wasm/host/DevServer/DevServerStartup.cs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/mono/wasm/host/DevServer/DevServerStartup.cs b/src/mono/wasm/host/DevServer/DevServerStartup.cs index 52611bd7b2c1b7..20a9f644d18132 100644 --- a/src/mono/wasm/host/DevServer/DevServerStartup.cs +++ b/src/mono/wasm/host/DevServer/DevServerStartup.cs @@ -86,8 +86,10 @@ public static void Configure(IApplicationBuilder app, IOptions using WebSocket socket = await ctx.WebSockets.AcceptWebSocketAsync(); await options.OnConsoleConnected(socket); } - - await next(ctx); + else + { + await next(ctx); + } }); } From 6e33fc244f3f486a40c5700c2e75727562ef2daf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Fi=C5=A1era?= Date: Mon, 21 Aug 2023 11:09:49 +0200 Subject: [PATCH 08/17] CancellationTokenSource on CancelKeyPress --- src/mono/wasm/host/Program.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/mono/wasm/host/Program.cs b/src/mono/wasm/host/Program.cs index a5005dce9d0fc4..105eb59929ecab 100644 --- a/src/mono/wasm/host/Program.cs +++ b/src/mono/wasm/host/Program.cs @@ -30,6 +30,9 @@ public static async Task Main(string[] args) RegisterHostHandler(WasmHost.Wasmtime, WasiEngineHost.InvokeAsync); using CancellationTokenSource cts = new(); + + Console.CancelKeyPress += (object? sender, ConsoleCancelEventArgs e) => cts.Cancel(); + ILoggerFactory loggerFactory = LoggerFactory.Create(builder => builder .AddPassThroughConsole() From b108639a854f1e0732c91072771e979cfaf4b914 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Fi=C5=A1era?= Date: Mon, 21 Aug 2023 11:33:12 +0200 Subject: [PATCH 09/17] Address feedback from initial DevServer integration --- src/mono/wasm/host/BrowserHost.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mono/wasm/host/BrowserHost.cs b/src/mono/wasm/host/BrowserHost.cs index 5c16a420e76deb..6de58518a67a42 100644 --- a/src/mono/wasm/host/BrowserHost.cs +++ b/src/mono/wasm/host/BrowserHost.cs @@ -167,7 +167,7 @@ private static DevServerOptions CreateDevServerOptions(BrowserArguments args, st devServerOptions = CreateDevServerOptions(urls, staticWebAssetsPath, onConsoleConnected); if (devServerOptions == null) - throw new CommandLineException("Please, provide mainAssembly in hostProperties of runtimeconfig"); + throw new CommandLineException($"Please, provide mainAssembly in hostProperties of runtimeconfig. Alternatively leave the static web assets manifest ('*{staticWebAssetsV2Extension}') in the build output directory '{appPath}'"); } return devServerOptions; @@ -183,7 +183,7 @@ private static DevServerOptions CreateDevServerOptions(BrowserArguments args, st ); private static string? FindFirstFileWithExtension(string directory, string extension) - => Directory.EnumerateFiles(directory, "*" + extension).First(); + => Directory.EnumerateFiles(directory, "*" + extension).FirstOrDefault(); private async Task RunConsoleMessagesPump(WebSocket socket, WasmTestMessagesProcessor messagesProcessor, CancellationToken token) { From dd1ac7554d1ec5d4b4c213a4453b7b3021a21399 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Fi=C5=A1era?= Date: Tue, 22 Aug 2023 08:35:26 +0200 Subject: [PATCH 10/17] Update src/mono/wasm/host/BrowserHost.cs Co-authored-by: Ankit Jain --- src/mono/wasm/host/BrowserHost.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mono/wasm/host/BrowserHost.cs b/src/mono/wasm/host/BrowserHost.cs index 6de58518a67a42..adb24f81f88dac 100644 --- a/src/mono/wasm/host/BrowserHost.cs +++ b/src/mono/wasm/host/BrowserHost.cs @@ -167,7 +167,7 @@ private static DevServerOptions CreateDevServerOptions(BrowserArguments args, st devServerOptions = CreateDevServerOptions(urls, staticWebAssetsPath, onConsoleConnected); if (devServerOptions == null) - throw new CommandLineException($"Please, provide mainAssembly in hostProperties of runtimeconfig. Alternatively leave the static web assets manifest ('*{staticWebAssetsV2Extension}') in the build output directory '{appPath}'"); + throw new CommandLineException($"Please, provide mainAssembly in hostProperties of runtimeconfig. Alternatively leave the static web assets manifest ('*{staticWebAssetsV2Extension}') in the build output directory '{appPath}' ."); } return devServerOptions; From c31fdc13898a3298a8892750fd775a1fd5a83980 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Fi=C5=A1era?= Date: Tue, 22 Aug 2023 11:46:55 +0200 Subject: [PATCH 11/17] Remove debugging code --- src/mono/wasm/host/DevServer/DevServerStartup.cs | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/mono/wasm/host/DevServer/DevServerStartup.cs b/src/mono/wasm/host/DevServer/DevServerStartup.cs index 20a9f644d18132..0fdc45a1754fdf 100644 --- a/src/mono/wasm/host/DevServer/DevServerStartup.cs +++ b/src/mono/wasm/host/DevServer/DevServerStartup.cs @@ -1,7 +1,6 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System.Diagnostics; using System.IO; using System.Net.WebSockets; using System.Threading.Tasks; @@ -69,8 +68,6 @@ public static void Configure(IApplicationBuilder app, IOptions app.UseRouting(); app.UseWebSockets(); - Debugger.Launch(); - if (options.OnConsoleConnected is not null) { app.Use(async (ctx, next) => From adf78fed77a088189377560686d9eda4877fede5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Fi=C5=A1era?= Date: Tue, 22 Aug 2023 11:47:05 +0200 Subject: [PATCH 12/17] Fix WBT --- .../Wasm.Build.Tests/WasmTemplateTestBase.cs | 34 ++++++++++++++++--- 1 file changed, 29 insertions(+), 5 deletions(-) diff --git a/src/mono/wasm/Wasm.Build.Tests/WasmTemplateTestBase.cs b/src/mono/wasm/Wasm.Build.Tests/WasmTemplateTestBase.cs index a76aaee38a929b..681777b0983b0c 100644 --- a/src/mono/wasm/Wasm.Build.Tests/WasmTemplateTestBase.cs +++ b/src/mono/wasm/Wasm.Build.Tests/WasmTemplateTestBase.cs @@ -59,19 +59,23 @@ public string CreateWasmTemplateProject(string id, string template = "wasmbrowse public (string projectDir, string buildOutput) BuildTemplateProject(BuildArgs buildArgs, string id, - BuildProjectOptions buildProjectOptions, - AssertTestMainJsAppBundleOptions? assertAppBundleOptions = null) + BuildProjectOptions buildProjectOptions) { (CommandResult res, string logFilePath) = BuildProjectWithoutAssert(id, buildArgs.Config, buildProjectOptions); if (buildProjectOptions.UseCache) _buildContext.CacheBuild(buildArgs, new BuildProduct(_projectDir!, logFilePath, true, res.Output)); if (buildProjectOptions.AssertAppBundle) - AssertBundle(buildArgs, buildProjectOptions, res.Output, assertAppBundleOptions); + { + if (buildProjectOptions.IsBrowserProject) + AssertWasmSdkBundle(buildArgs, buildProjectOptions, res.Output); + else + AssertTestMainJsBundle(buildArgs, buildProjectOptions, res.Output); + } return (_projectDir!, res.Output); } - public void AssertBundle(BuildArgs buildArgs, + public void AssertTestMainJsBundle(BuildArgs buildArgs, BuildProjectOptions buildProjectOptions, string? buildOutput = null, AssertTestMainJsAppBundleOptions? assertAppBundleOptions = null) @@ -79,11 +83,31 @@ public void AssertBundle(BuildArgs buildArgs, if (buildOutput is not null) ProjectProviderBase.AssertRuntimePackPath(buildOutput, buildProjectOptions.TargetFramework ?? DefaultTargetFramework); - // TODO: templates don't use wasm sdk yet var testMainJsProvider = new TestMainJsProjectProvider(_testOutput, _projectDir!); if (assertAppBundleOptions is not null) testMainJsProvider.AssertBundle(assertAppBundleOptions); else testMainJsProvider.AssertBundle(buildArgs, buildProjectOptions); } + + public void AssertWasmSdkBundle(BuildArgs buildArgs, + BuildProjectOptions buildProjectOptions, + string? buildOutput = null, + AssertWasmSdkBundleOptions? assertAppBundleOptions = null) + { + if (buildOutput is not null) + ProjectProviderBase.AssertRuntimePackPath(buildOutput, buildProjectOptions.TargetFramework ?? DefaultTargetFramework); + + var projectProvider = new WasmSdkBasedProjectProvider(_testOutput, _projectDir!); + projectProvider.AssertBundle(assertAppBundleOptions ?? new( + Config: buildArgs.Config, + IsPublish: buildProjectOptions.Publish, + TargetFramework: buildProjectOptions.TargetFramework ?? DefaultTargetFramework, + BinFrameworkDir: buildProjectOptions.BinFrameworkDir ?? projectProvider.FindBinFrameworkDir(buildArgs.Config, buildProjectOptions.Publish, buildProjectOptions.TargetFramework ?? DefaultTargetFramework), + PredefinedIcudt: buildProjectOptions.PredefinedIcudt, + GlobalizationMode: buildProjectOptions.GlobalizationMode, + AssertSymbolsFile: false, + ExpectedFileType: buildProjectOptions.Publish && buildArgs.Config == "Release" ? NativeFilesType.Relinked : NativeFilesType.FromRuntimePack + )); + } } From 2b7969841e49c554830ccb79f8f9cd13c085a274 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Fi=C5=A1era?= Date: Tue, 22 Aug 2023 13:53:35 +0200 Subject: [PATCH 13/17] Fix starting outside of project directory --- .../build/Microsoft.NET.Sdk.WebAssembly.Browser.targets | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/mono/nuget/Microsoft.NET.Sdk.WebAssembly.Pack/build/Microsoft.NET.Sdk.WebAssembly.Browser.targets b/src/mono/nuget/Microsoft.NET.Sdk.WebAssembly.Pack/build/Microsoft.NET.Sdk.WebAssembly.Browser.targets index 64539a49fdaa8a..1219d25e02ff3a 100644 --- a/src/mono/nuget/Microsoft.NET.Sdk.WebAssembly.Pack/build/Microsoft.NET.Sdk.WebAssembly.Browser.targets +++ b/src/mono/nuget/Microsoft.NET.Sdk.WebAssembly.Pack/build/Microsoft.NET.Sdk.WebAssembly.Browser.targets @@ -19,9 +19,13 @@ Copyright (c) .NET Foundation. All rights reserved. dotnet $([MSBuild]::NormalizeDirectory($(MSBuildThisFileDirectory), '..', 'WasmAppHost')) - <_RuntimeConfigJsonPath>$([MSBuild]::NormalizePath($(OutputPath), '$(AssemblyName).runtimeconfig.json')) + + <_RunWorkingDirectory>$(OutputPath) + <_RunWorkingDirectory Condition="'$(_RunWorkingDirectory)' != '' and !$([System.IO.Path]::IsPathRooted($(_RunWorkingDirectory)))">$([System.IO.Path]::Combine($(MSBuildProjectDirectory), $(_RunWorkingDirectory))) + <_RuntimeConfigJsonPath>$([MSBuild]::NormalizePath($(_RunWorkingDirectory), '$(AssemblyName).runtimeconfig.json')) + exec "$([MSBuild]::NormalizePath($(WasmAppHostDir), 'WasmAppHost.dll'))" --use-staticwebassets --runtime-config "$(_RuntimeConfigJsonPath)" $(WasmHostArguments) - $(OutputPath) + $(_RunWorkingDirectory) From f56f090e8fdc934da8d664e5b4ae891398b6fee3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Fi=C5=A1era?= Date: Tue, 22 Aug 2023 17:58:09 +0200 Subject: [PATCH 14/17] Support WasmRuntimeAssetsLocation in Wasm SDK --- ...rosoft.NET.Sdk.WebAssembly.Browser.targets | 11 +++++++--- .../Templates/WasmTemplateTests.cs | 12 ++++++----- .../AssetsComputingHelper.cs | 10 +++++----- .../ComputeWasmBuildAssets.cs | 20 ++++++++++--------- .../ComputeWasmPublishAssets.cs | 8 +++++--- 5 files changed, 36 insertions(+), 25 deletions(-) diff --git a/src/mono/nuget/Microsoft.NET.Sdk.WebAssembly.Pack/build/Microsoft.NET.Sdk.WebAssembly.Browser.targets b/src/mono/nuget/Microsoft.NET.Sdk.WebAssembly.Pack/build/Microsoft.NET.Sdk.WebAssembly.Browser.targets index 1219d25e02ff3a..1084e0b94a2972 100644 --- a/src/mono/nuget/Microsoft.NET.Sdk.WebAssembly.Pack/build/Microsoft.NET.Sdk.WebAssembly.Browser.targets +++ b/src/mono/nuget/Microsoft.NET.Sdk.WebAssembly.Pack/build/Microsoft.NET.Sdk.WebAssembly.Browser.targets @@ -48,9 +48,12 @@ Copyright (c) .NET Foundation. All rights reserved. <_WebAssemblySdkTasksTFM Condition=" '$(MSBuildRuntimeType)' == 'Core'">net8.0 <_WebAssemblySdkTasksTFM Condition=" '$(MSBuildRuntimeType)' != 'Core'">net472 <_WebAssemblySdkTasksAssembly>$(WebAssemblySdkDirectoryRoot)tools\$(_WebAssemblySdkTasksTFM)\Microsoft.NET.Sdk.WebAssembly.Pack.Tasks.dll + + <_WasmRuntimeAssetsLocation>$(WasmRuntimeAssetsLocation) + <_WasmRuntimeAssetsLocation Condition="'$(_WasmRuntimeAssetsLocation)' == ''">_framework - $(CompressionIncludePatterns);_framework\** + $(CompressionIncludePatterns);$(_WasmRuntimeAssetsLocation)\** true @@ -262,6 +265,7 @@ Copyright (c) .NET Foundation. All rights reserved. FingerprintDotNetJs="$(WasmFingerprintDotnetJs)" EnableThreads="$(_WasmEnableThreads)" EmitSourceMap="$(_WasmEmitSourceMapBuild)" + RuntimeAssetsLocation="$(_WasmRuntimeAssetsLocation)" > @@ -315,7 +319,7 @@ Copyright (c) .NET Foundation. All rights reserved. <_BuildWasmBootJson Include="$(_WasmBuildBootJsonPath)" - RelativePath="_framework/blazor.boot.json" /> + RelativePath="$(_WasmRuntimeAssetsLocation)/blazor.boot.json" /> @@ -510,7 +515,7 @@ Copyright (c) .NET Foundation. All rights reserved. <_PublishWasmBootJson Include="$(IntermediateOutputPath)blazor.publish.boot.json" - RelativePath="_framework/blazor.boot.json" /> + RelativePath="$(_WasmRuntimeAssetsLocation)/blazor.boot.json" /> 0) { var debugSymbols = new TaskItem(ProjectDebugSymbols[0]); - debugSymbols.SetMetadata("RelativePath", $"_framework/{debugSymbols.GetMetadata("FileName")}{debugSymbols.GetMetadata("Extension")}"); + debugSymbols.SetMetadata("RelativePath", $"{RuntimeAssetsLocation}/{debugSymbols.GetMetadata("FileName")}{debugSymbols.GetMetadata("Extension")}"); assetCandidates.Add(debugSymbols); } @@ -212,7 +214,7 @@ public override bool Execute() var projectAssemblyAssetPath = Path.GetFullPath(Path.Combine( OutputPath, "wwwroot", - "_framework", + RuntimeAssetsLocation, ProjectAssembly[0].GetMetadata("FileName") + ProjectAssembly[0].GetMetadata("Extension"))); var normalizedPath = assetCandidate.GetMetadata("TargetPath").Replace('\\', '/'); @@ -221,7 +223,7 @@ public override bool Execute() assetCandidate.SetMetadata("AssetRole", "Related"); assetCandidate.SetMetadata("AssetTraitName", "Culture"); assetCandidate.SetMetadata("AssetTraitValue", candidateCulture); - assetCandidate.SetMetadata("RelativePath", Path.Combine("_framework", normalizedPath)); + assetCandidate.SetMetadata("RelativePath", Path.Combine(RuntimeAssetsLocation, normalizedPath)); assetCandidate.SetMetadata("RelatedAsset", projectAssemblyAssetPath); assetCandidates.Add(assetCandidate); diff --git a/src/tasks/Microsoft.NET.Sdk.WebAssembly.Pack.Tasks/ComputeWasmPublishAssets.cs b/src/tasks/Microsoft.NET.Sdk.WebAssembly.Pack.Tasks/ComputeWasmPublishAssets.cs index 429addedfd555e..d3e2323b19c575 100644 --- a/src/tasks/Microsoft.NET.Sdk.WebAssembly.Pack.Tasks/ComputeWasmPublishAssets.cs +++ b/src/tasks/Microsoft.NET.Sdk.WebAssembly.Pack.Tasks/ComputeWasmPublishAssets.cs @@ -66,6 +66,8 @@ public class ComputeWasmPublishAssets : Task public bool IsWebCilEnabled { get; set; } + public string? RuntimeAssetsLocation { get; set; } + [Output] public ITaskItem[] NewCandidates { get; set; } @@ -223,8 +225,8 @@ private List ProcessNativeAssets( newDotNetJs.SetMetadata("OriginalItemSpec", aotDotNetJs.ItemSpec); string relativePath = baseName != "dotnet" || FingerprintDotNetJs - ? $"_framework/{$"{baseName}.{DotNetJsVersion}.{FileHasher.GetFileHash(aotDotNetJs.ItemSpec)}.js"}" - : $"_framework/{baseName}.js"; + ? $"{RuntimeAssetsLocation}/{$"{baseName}.{DotNetJsVersion}.{FileHasher.GetFileHash(aotDotNetJs.ItemSpec)}.js"}" + : $"{RuntimeAssetsLocation}/{baseName}.js"; newDotNetJs.SetMetadata("RelativePath", relativePath); @@ -576,7 +578,7 @@ private void GroupResolvedFilesToPublish( var resolvedFilesToPublish = ResolvedFilesToPublish.ToList(); if (AssetsComputingHelper.TryGetAssetFilename(CustomIcuCandidate, out string customIcuCandidateFilename)) { - var customIcuCandidate = AssetsComputingHelper.GetCustomIcuAsset(CustomIcuCandidate); + var customIcuCandidate = AssetsComputingHelper.GetCustomIcuAsset(CustomIcuCandidate, RuntimeAssetsLocation); resolvedFilesToPublish.Add(customIcuCandidate); } From 76033a9a4245c5a6605acf47cf4acb292ca4bec7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Fi=C5=A1era?= Date: Wed, 23 Aug 2023 10:46:54 +0200 Subject: [PATCH 15/17] Revert "Support WasmRuntimeAssetsLocation in Wasm SDK" --- ...rosoft.NET.Sdk.WebAssembly.Browser.targets | 11 +++------- .../AssetsComputingHelper.cs | 10 +++++----- .../ComputeWasmBuildAssets.cs | 20 +++++++++---------- .../ComputeWasmPublishAssets.cs | 8 +++----- 4 files changed, 20 insertions(+), 29 deletions(-) diff --git a/src/mono/nuget/Microsoft.NET.Sdk.WebAssembly.Pack/build/Microsoft.NET.Sdk.WebAssembly.Browser.targets b/src/mono/nuget/Microsoft.NET.Sdk.WebAssembly.Pack/build/Microsoft.NET.Sdk.WebAssembly.Browser.targets index 1084e0b94a2972..1219d25e02ff3a 100644 --- a/src/mono/nuget/Microsoft.NET.Sdk.WebAssembly.Pack/build/Microsoft.NET.Sdk.WebAssembly.Browser.targets +++ b/src/mono/nuget/Microsoft.NET.Sdk.WebAssembly.Pack/build/Microsoft.NET.Sdk.WebAssembly.Browser.targets @@ -48,12 +48,9 @@ Copyright (c) .NET Foundation. All rights reserved. <_WebAssemblySdkTasksTFM Condition=" '$(MSBuildRuntimeType)' == 'Core'">net8.0 <_WebAssemblySdkTasksTFM Condition=" '$(MSBuildRuntimeType)' != 'Core'">net472 <_WebAssemblySdkTasksAssembly>$(WebAssemblySdkDirectoryRoot)tools\$(_WebAssemblySdkTasksTFM)\Microsoft.NET.Sdk.WebAssembly.Pack.Tasks.dll - - <_WasmRuntimeAssetsLocation>$(WasmRuntimeAssetsLocation) - <_WasmRuntimeAssetsLocation Condition="'$(_WasmRuntimeAssetsLocation)' == ''">_framework - $(CompressionIncludePatterns);$(_WasmRuntimeAssetsLocation)\** + $(CompressionIncludePatterns);_framework\** true @@ -265,7 +262,6 @@ Copyright (c) .NET Foundation. All rights reserved. FingerprintDotNetJs="$(WasmFingerprintDotnetJs)" EnableThreads="$(_WasmEnableThreads)" EmitSourceMap="$(_WasmEmitSourceMapBuild)" - RuntimeAssetsLocation="$(_WasmRuntimeAssetsLocation)" > @@ -319,7 +315,7 @@ Copyright (c) .NET Foundation. All rights reserved. <_BuildWasmBootJson Include="$(_WasmBuildBootJsonPath)" - RelativePath="$(_WasmRuntimeAssetsLocation)/blazor.boot.json" /> + RelativePath="_framework/blazor.boot.json" /> @@ -515,7 +510,7 @@ Copyright (c) .NET Foundation. All rights reserved. <_PublishWasmBootJson Include="$(IntermediateOutputPath)blazor.publish.boot.json" - RelativePath="$(_WasmRuntimeAssetsLocation)/blazor.boot.json" /> + RelativePath="_framework/blazor.boot.json" /> 0) { var debugSymbols = new TaskItem(ProjectDebugSymbols[0]); - debugSymbols.SetMetadata("RelativePath", $"{RuntimeAssetsLocation}/{debugSymbols.GetMetadata("FileName")}{debugSymbols.GetMetadata("Extension")}"); + debugSymbols.SetMetadata("RelativePath", $"_framework/{debugSymbols.GetMetadata("FileName")}{debugSymbols.GetMetadata("Extension")}"); assetCandidates.Add(debugSymbols); } @@ -214,7 +212,7 @@ public override bool Execute() var projectAssemblyAssetPath = Path.GetFullPath(Path.Combine( OutputPath, "wwwroot", - RuntimeAssetsLocation, + "_framework", ProjectAssembly[0].GetMetadata("FileName") + ProjectAssembly[0].GetMetadata("Extension"))); var normalizedPath = assetCandidate.GetMetadata("TargetPath").Replace('\\', '/'); @@ -223,7 +221,7 @@ public override bool Execute() assetCandidate.SetMetadata("AssetRole", "Related"); assetCandidate.SetMetadata("AssetTraitName", "Culture"); assetCandidate.SetMetadata("AssetTraitValue", candidateCulture); - assetCandidate.SetMetadata("RelativePath", Path.Combine(RuntimeAssetsLocation, normalizedPath)); + assetCandidate.SetMetadata("RelativePath", Path.Combine("_framework", normalizedPath)); assetCandidate.SetMetadata("RelatedAsset", projectAssemblyAssetPath); assetCandidates.Add(assetCandidate); diff --git a/src/tasks/Microsoft.NET.Sdk.WebAssembly.Pack.Tasks/ComputeWasmPublishAssets.cs b/src/tasks/Microsoft.NET.Sdk.WebAssembly.Pack.Tasks/ComputeWasmPublishAssets.cs index d3e2323b19c575..429addedfd555e 100644 --- a/src/tasks/Microsoft.NET.Sdk.WebAssembly.Pack.Tasks/ComputeWasmPublishAssets.cs +++ b/src/tasks/Microsoft.NET.Sdk.WebAssembly.Pack.Tasks/ComputeWasmPublishAssets.cs @@ -66,8 +66,6 @@ public class ComputeWasmPublishAssets : Task public bool IsWebCilEnabled { get; set; } - public string? RuntimeAssetsLocation { get; set; } - [Output] public ITaskItem[] NewCandidates { get; set; } @@ -225,8 +223,8 @@ private List ProcessNativeAssets( newDotNetJs.SetMetadata("OriginalItemSpec", aotDotNetJs.ItemSpec); string relativePath = baseName != "dotnet" || FingerprintDotNetJs - ? $"{RuntimeAssetsLocation}/{$"{baseName}.{DotNetJsVersion}.{FileHasher.GetFileHash(aotDotNetJs.ItemSpec)}.js"}" - : $"{RuntimeAssetsLocation}/{baseName}.js"; + ? $"_framework/{$"{baseName}.{DotNetJsVersion}.{FileHasher.GetFileHash(aotDotNetJs.ItemSpec)}.js"}" + : $"_framework/{baseName}.js"; newDotNetJs.SetMetadata("RelativePath", relativePath); @@ -578,7 +576,7 @@ private void GroupResolvedFilesToPublish( var resolvedFilesToPublish = ResolvedFilesToPublish.ToList(); if (AssetsComputingHelper.TryGetAssetFilename(CustomIcuCandidate, out string customIcuCandidateFilename)) { - var customIcuCandidate = AssetsComputingHelper.GetCustomIcuAsset(CustomIcuCandidate, RuntimeAssetsLocation); + var customIcuCandidate = AssetsComputingHelper.GetCustomIcuAsset(CustomIcuCandidate); resolvedFilesToPublish.Add(customIcuCandidate); } From abf3b2657daa5dc895accf2632fcd71d82a962bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Fi=C5=A1era?= Date: Wed, 23 Aug 2023 10:49:57 +0200 Subject: [PATCH 16/17] Active issue for WasmRuntimeAssetsLocation --- .../wasm/Wasm.Build.Tests/Templates/WasmTemplateTests.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/mono/wasm/Wasm.Build.Tests/Templates/WasmTemplateTests.cs b/src/mono/wasm/Wasm.Build.Tests/Templates/WasmTemplateTests.cs index 219e0a61798eac..08488d487a6151 100644 --- a/src/mono/wasm/Wasm.Build.Tests/Templates/WasmTemplateTests.cs +++ b/src/mono/wasm/Wasm.Build.Tests/Templates/WasmTemplateTests.cs @@ -408,11 +408,12 @@ public void ConsolePublishAndRun(string config, bool aot, bool relinking) [Theory] [InlineData("", BuildTestBase.DefaultTargetFramework, DefaultRuntimeAssetsRelativePath)] - [InlineData("", BuildTestBase.DefaultTargetFramework, "./")] + // [ActiveIssue("https://github.com/dotnet/runtime/issues/90979")] + // [InlineData("", BuildTestBase.DefaultTargetFramework, "./")] + // [InlineData("-f net8.0", "net8.0", "./")] // [ActiveIssue("https://github.com/dotnet/runtime/issues/79313")] // [InlineData("-f net7.0", "net7.0")] [InlineData("-f net8.0", "net8.0", DefaultRuntimeAssetsRelativePath)] - [InlineData("-f net8.0", "net8.0", "./")] public async Task BrowserBuildAndRun(string extraNewArgs, string targetFramework, string runtimeAssetsRelativePath) { string config = "Debug"; From e02289fd97e65ef731786c2ff200c8eb106bf7f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Fi=C5=A1era?= Date: Wed, 23 Aug 2023 10:59:32 +0200 Subject: [PATCH 17/17] Feedback --- .../WasmSdkBasedProjectProvider.cs | 15 +++++++++++++++ .../wasm/Wasm.Build.Tests/WasmTemplateTestBase.cs | 14 ++++---------- 2 files changed, 19 insertions(+), 10 deletions(-) diff --git a/src/mono/wasm/Wasm.Build.Tests/WasmSdkBasedProjectProvider.cs b/src/mono/wasm/Wasm.Build.Tests/WasmSdkBasedProjectProvider.cs index 1f70aa46df8fa1..9ff2155c68e600 100644 --- a/src/mono/wasm/Wasm.Build.Tests/WasmSdkBasedProjectProvider.cs +++ b/src/mono/wasm/Wasm.Build.Tests/WasmSdkBasedProjectProvider.cs @@ -57,6 +57,21 @@ protected override IReadOnlySet GetDotNetFilesExpectedSet(AssertBundleOp return res; } + + public void AssertBundle(BuildArgs buildArgs, BuildProjectOptions buildProjectOptions) + { + AssertBundle(new( + Config: buildArgs.Config, + IsPublish: buildProjectOptions.Publish, + TargetFramework: buildProjectOptions.TargetFramework, + BinFrameworkDir: buildProjectOptions.BinFrameworkDir ?? FindBinFrameworkDir(buildArgs.Config, buildProjectOptions.Publish, buildProjectOptions.TargetFramework), + PredefinedIcudt: buildProjectOptions.PredefinedIcudt, + GlobalizationMode: buildProjectOptions.GlobalizationMode, + AssertSymbolsFile: false, + ExpectedFileType: buildProjectOptions.Publish && buildArgs.Config == "Release" ? NativeFilesType.Relinked : NativeFilesType.FromRuntimePack + )); + } + public void AssertBundle(AssertWasmSdkBundleOptions assertOptions) { IReadOnlyDictionary actualDotnetFiles = AssertBasicBundle(assertOptions); diff --git a/src/mono/wasm/Wasm.Build.Tests/WasmTemplateTestBase.cs b/src/mono/wasm/Wasm.Build.Tests/WasmTemplateTestBase.cs index 681777b0983b0c..6280a022c1a424 100644 --- a/src/mono/wasm/Wasm.Build.Tests/WasmTemplateTestBase.cs +++ b/src/mono/wasm/Wasm.Build.Tests/WasmTemplateTestBase.cs @@ -99,15 +99,9 @@ public void AssertWasmSdkBundle(BuildArgs buildArgs, ProjectProviderBase.AssertRuntimePackPath(buildOutput, buildProjectOptions.TargetFramework ?? DefaultTargetFramework); var projectProvider = new WasmSdkBasedProjectProvider(_testOutput, _projectDir!); - projectProvider.AssertBundle(assertAppBundleOptions ?? new( - Config: buildArgs.Config, - IsPublish: buildProjectOptions.Publish, - TargetFramework: buildProjectOptions.TargetFramework ?? DefaultTargetFramework, - BinFrameworkDir: buildProjectOptions.BinFrameworkDir ?? projectProvider.FindBinFrameworkDir(buildArgs.Config, buildProjectOptions.Publish, buildProjectOptions.TargetFramework ?? DefaultTargetFramework), - PredefinedIcudt: buildProjectOptions.PredefinedIcudt, - GlobalizationMode: buildProjectOptions.GlobalizationMode, - AssertSymbolsFile: false, - ExpectedFileType: buildProjectOptions.Publish && buildArgs.Config == "Release" ? NativeFilesType.Relinked : NativeFilesType.FromRuntimePack - )); + if (assertAppBundleOptions is not null) + projectProvider.AssertBundle(assertAppBundleOptions); + else + projectProvider.AssertBundle(buildArgs, buildProjectOptions); } }