From bfd6048a605e9a0bebced7171a98bc3f04c78192 Mon Sep 17 00:00:00 2001 From: Larry Ewing Date: Mon, 3 May 2021 13:08:42 -0500 Subject: [PATCH] [release/6.0-preview4][wasm] Fix Blazor AOT builds inside Visual Studio (#52078) * [wasm] Build tasks for net472 also (#51959) * [wasm] Fix loading WebAssembly tasks in VS - In case of `WasmAppBuilder.dll`, we were packaging only the task assembly, and `System.Reflection.MetadataLoadContext` for net472, same as net6.0 . - But for net472, VS fails with errors like: ``` C:\Program Files\dotnet\packs\Microsoft.NET.Runtime.WebAssembly.Sdk\6.0.0-preview.4.21222.10\Sdk\WasmApp.targets(424,4): Error MSB4018: The "PInvokeTableGenerator" task failed unexpectedly. System.IO.FileNotFoundException: Could not load file or assembly 'System.Reflection.Metadata, Version=1.4.5.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' or one of its dependencies. The system cannot find the file specified. File name: 'System.Reflection.Metadata, Version=1.4.5.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' at System.Reflection.MetadataLoadContext.LoadFromStreamCore(Stream peStream) at System.Reflection.MetadataLoadContext.LoadFromAssemblyPath(String assemblyPath) at System.Reflection.PathAssemblyResolver.Resolve(MetadataLoadContext context, AssemblyName assemblyName) at System.Reflection.MetadataLoadContext.TryFindAssemblyByCallingResolveHandler(RoAssemblyName refName) at System.Reflection.MetadataLoadContext.ResolveToAssemblyOrExceptionAssembly(RoAssemblyName refName) at System.Reflection.MetadataLoadContext.TryResolveAssembly(RoAssemblyName refName, Exception& e) at System.Reflection.MetadataLoadContext.TryGetCoreAssembly(String coreAssemblyName, Exception& e) at System.Reflection.TypeLoading.CoreTypes..ctor(MetadataLoadContext loader, String coreAssemblyName) at System.Reflection.MetadataLoadContext..ctor(MetadataAssemblyResolver resolver, String coreAssemblyName) at PInvokeTableGenerator.GenPInvokeTable(String[] pinvokeModules, String[] assemblies) in /Users/radical/dev/r2/src/tasks/WasmAppBuilder/PInvokeTableGenerator.cs:line 42 at PInvokeTableGenerator.Execute() in /Users/radical/dev/r2/src/tasks/WasmAppBuilder/PInvokeTableGenerator.cs:line 28 at Microsoft.Build.BackEnd.TaskExecutionHost.Microsoft.Build.BackEnd.ITaskExecutionHost.Execute() at Microsoft.Build.BackEnd.TaskBuilder.d__26.MoveNext() ``` - So, bundle all the dependent assemblies from the publish folder * Address review feedback * Update src/tasks/AotCompilerTask/MonoAOTCompiler.csproj Co-authored-by: Daniel Plaisted * Update src/tasks/AotCompilerTask/MonoAOTCompiler.csproj Co-authored-by: Daniel Plaisted * Update src/tasks/WasmAppBuilder/WasmAppBuilder.csproj Co-authored-by: Daniel Plaisted * Update src/tasks/WasmAppBuilder/WasmAppBuilder.csproj Co-authored-by: Daniel Plaisted * Apply suggestions from code review Co-authored-by: Daniel Plaisted * Use a property for net472 Co-authored-by: Ankit Jain Co-authored-by: Daniel Plaisted --- .../Sdk/Sdk.props | 3 +- .../Sdk/Sdk.targets | 7 ++-- src/tasks/AotCompilerTask/MonoAOTCompiler.cs | 8 ++--- .../AotCompilerTask/MonoAOTCompiler.csproj | 11 ++++-- src/tasks/Common/IsExternalInit.cs | 7 ++++ src/tasks/Common/Utils.cs | 2 ++ src/tasks/Directory.Build.props | 7 ++++ src/tasks/WasmAppBuilder/WasmAppBuilder.cs | 24 ++++++------- .../WasmAppBuilder/WasmAppBuilder.csproj | 35 ++++++++++++++++--- 9 files changed, 78 insertions(+), 26 deletions(-) create mode 100644 src/tasks/Common/IsExternalInit.cs create mode 100644 src/tasks/Directory.Build.props diff --git a/src/mono/nuget/Microsoft.NET.Runtime.MonoAOTCompiler.Task/Sdk/Sdk.props b/src/mono/nuget/Microsoft.NET.Runtime.MonoAOTCompiler.Task/Sdk/Sdk.props index adcad9f50e1..a94224b1858 100644 --- a/src/mono/nuget/Microsoft.NET.Runtime.MonoAOTCompiler.Task/Sdk/Sdk.props +++ b/src/mono/nuget/Microsoft.NET.Runtime.MonoAOTCompiler.Task/Sdk/Sdk.props @@ -1,6 +1,7 @@ - $(MSBuildThisFileDirectory)..\tasks\MonoAOTCompiler.dll + $(MSBuildThisFileDirectory)..\tasks\net6.0\MonoAOTCompiler.dll + $(MSBuildThisFileDirectory)..\tasks\net472\MonoAOTCompiler.dll diff --git a/src/mono/nuget/Microsoft.NET.Runtime.WebAssembly.Sdk/Sdk/Sdk.targets b/src/mono/nuget/Microsoft.NET.Runtime.WebAssembly.Sdk/Sdk/Sdk.targets index 9bd74455ac6..2c2959c87e5 100644 --- a/src/mono/nuget/Microsoft.NET.Runtime.WebAssembly.Sdk/Sdk/Sdk.targets +++ b/src/mono/nuget/Microsoft.NET.Runtime.WebAssembly.Sdk/Sdk/Sdk.targets @@ -1,8 +1,11 @@ - $(MSBuildThisFileDirectory)..\tasks\WasmAppBuilder.dll - $(MSBuildThisFileDirectory)..\tasks\WasmBuildTasks.dll + <_TasksDir Condition="'$(MSBuildRuntimeType)' == 'Core'">$(MSBuildThisFileDirectory)..\tasks\net6.0\ + <_TasksDir Condition="'$(MSBuildRuntimeType)' != 'Core'">$(MSBuildThisFileDirectory)..\tasks\net472\ + + $(_TasksDir)WasmAppBuilder.dll + $(_TasksDir)WasmBuildTasks.dll diff --git a/src/tasks/AotCompilerTask/MonoAOTCompiler.cs b/src/tasks/AotCompilerTask/MonoAOTCompiler.cs index 108b550725a..51acec5216c 100644 --- a/src/tasks/AotCompilerTask/MonoAOTCompiler.cs +++ b/src/tasks/AotCompilerTask/MonoAOTCompiler.cs @@ -185,7 +185,7 @@ public override bool Execute() if (!Enum.TryParse(Mode, true, out parsedAotMode)) { - Log.LogError($"Unknown Mode value: {Mode}. '{nameof(Mode)}' must be one of: {string.Join(',', Enum.GetNames(typeof(MonoAotMode)))}"); + Log.LogError($"Unknown Mode value: {Mode}. '{nameof(Mode)}' must be one of: {string.Join(",", Enum.GetNames(typeof(MonoAotMode)))}"); return false; } @@ -217,7 +217,7 @@ public override bool Execute() string? monoPaths = null; if (AdditionalAssemblySearchPaths != null) - monoPaths = string.Join(Path.PathSeparator, AdditionalAssemblySearchPaths); + monoPaths = string.Join(Path.PathSeparator.ToString(), AdditionalAssemblySearchPaths); if (DisableParallelAot) { @@ -252,13 +252,13 @@ private bool PrecompileLibrary(ITaskItem assemblyItem, string? monoPaths) var a = assemblyItem.GetMetadata("AotArguments"); if (a != null) { - aotArgs.AddRange(a.Split(";", StringSplitOptions.RemoveEmptyEntries)); + aotArgs.AddRange(a.Split(new char[]{ ';' }, StringSplitOptions.RemoveEmptyEntries)); } var p = assemblyItem.GetMetadata("ProcessArguments"); if (p != null) { - processArgs.AddRange(p.Split(";", StringSplitOptions.RemoveEmptyEntries)); + processArgs.AddRange(p.Split(new char[]{ ';' }, StringSplitOptions.RemoveEmptyEntries)); } Log.LogMessage(MessageImportance.Low, $"[AOT] {assembly}"); diff --git a/src/tasks/AotCompilerTask/MonoAOTCompiler.csproj b/src/tasks/AotCompilerTask/MonoAOTCompiler.csproj index 419a364377d..c9bf35cf473 100644 --- a/src/tasks/AotCompilerTask/MonoAOTCompiler.csproj +++ b/src/tasks/AotCompilerTask/MonoAOTCompiler.csproj @@ -1,11 +1,14 @@ - $(NetCoreAppToolCurrent) + $(NetCoreAppToolCurrent);$(TargetFrameworkForNETFramework) Library true false enable $(NoWarn),CA1050 + + + $(NoWarn),CS8604,CS8602 @@ -16,6 +19,7 @@ + @@ -26,7 +30,10 @@ - + <_PublishFramework Remove="@(_PublishFramework)" /> + <_PublishFramework Include="$(TargetFrameworks)" /> + + diff --git a/src/tasks/Common/IsExternalInit.cs b/src/tasks/Common/IsExternalInit.cs new file mode 100644 index 00000000000..d7be6913103 --- /dev/null +++ b/src/tasks/Common/IsExternalInit.cs @@ -0,0 +1,7 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +namespace System.Runtime.CompilerServices +{ + internal sealed class IsExternalInit { } +} diff --git a/src/tasks/Common/Utils.cs b/src/tasks/Common/Utils.cs index b7c1fd6d91e..78738d59be2 100644 --- a/src/tasks/Common/Utils.cs +++ b/src/tasks/Common/Utils.cs @@ -102,6 +102,7 @@ public static string GetEmbeddedResource(string file) return outputBuilder.ToString().Trim('\r', '\n'); } +#if NETCOREAPP public static void DirectoryCopy(string sourceDir, string destDir, Func predicate) { string[] files = Directory.GetFiles(sourceDir, "*", SearchOption.AllDirectories); @@ -118,6 +119,7 @@ public static void DirectoryCopy(string sourceDir, string destDir, Func + + + + net472 + + diff --git a/src/tasks/WasmAppBuilder/WasmAppBuilder.cs b/src/tasks/WasmAppBuilder/WasmAppBuilder.cs index d1cf986b3cc..9ef7679c292 100644 --- a/src/tasks/WasmAppBuilder/WasmAppBuilder.cs +++ b/src/tasks/WasmAppBuilder/WasmAppBuilder.cs @@ -144,18 +144,18 @@ public override bool Execute () var config = new WasmAppConfig (); // Create app - var asmRootPath = Path.Join(AppDir, config.AssemblyRoot); + var asmRootPath = Path.Combine(AppDir, config.AssemblyRoot); Directory.CreateDirectory(AppDir!); Directory.CreateDirectory(asmRootPath); foreach (var assembly in _assemblies) { - FileCopyChecked(assembly, Path.Join(asmRootPath, Path.GetFileName(assembly)), "Assemblies"); + FileCopyChecked(assembly, Path.Combine(asmRootPath, Path.GetFileName(assembly)), "Assemblies"); if (DebugLevel != 0) { var pdb = assembly; pdb = Path.ChangeExtension(pdb, ".pdb"); if (File.Exists(pdb)) - FileCopyChecked(pdb, Path.Join(asmRootPath, Path.GetFileName(pdb)), "Assemblies"); + FileCopyChecked(pdb, Path.Combine(asmRootPath, Path.GetFileName(pdb)), "Assemblies"); } } @@ -165,10 +165,10 @@ public override bool Execute () if (!FileCopyChecked(item.ItemSpec, dest, "NativeAssets")) return false; } - FileCopyChecked(MainJS!, Path.Join(AppDir, "runtime.js"), string.Empty); + FileCopyChecked(MainJS!, Path.Combine(AppDir, "runtime.js"), string.Empty); var html = @""; - File.WriteAllText(Path.Join(AppDir, "index.html"), html); + File.WriteAllText(Path.Combine(AppDir, "index.html"), html); foreach (var assembly in _assemblies) { @@ -190,16 +190,16 @@ public override bool Execute () string culture = assembly.GetMetadata("CultureName") ?? string.Empty; string fullPath = assembly.GetMetadata("Identity"); string name = Path.GetFileName(fullPath); - string directory = Path.Join(AppDir, config.AssemblyRoot, culture); + string directory = Path.Combine(AppDir, config.AssemblyRoot, culture); Directory.CreateDirectory(directory); - FileCopyChecked(fullPath, Path.Join(directory, name), "SatelliteAssemblies"); + FileCopyChecked(fullPath, Path.Combine(directory, name), "SatelliteAssemblies"); config.Assets.Add(new SatelliteAssemblyEntry(name, culture)); } } if (FilesToIncludeInFileSystem != null) { - string supportFilesDir = Path.Join(AppDir, "supportFiles"); + string supportFilesDir = Path.Combine(AppDir, "supportFiles"); Directory.CreateDirectory(supportFilesDir); var i = 0; @@ -216,7 +216,7 @@ public override bool Execute () var generatedFileName = $"{i++}_{Path.GetFileName(item.ItemSpec)}"; - FileCopyChecked(item.ItemSpec, Path.Join(supportFilesDir, generatedFileName), "FilesToIncludeInFileSystem"); + FileCopyChecked(item.ItemSpec, Path.Combine(supportFilesDir, generatedFileName), "FilesToIncludeInFileSystem"); var asset = new VfsEntry ($"supportFiles/{generatedFileName}") { VirtualPath = targetPath @@ -246,7 +246,7 @@ public override bool Execute () config.Extra[name] = valueObject; } - string monoConfigPath = Path.Join(AppDir, "mono-config.js"); + string monoConfigPath = Path.Combine(AppDir, "mono-config.js"); using (var sw = File.CreateText(monoConfigPath)) { var json = JsonSerializer.Serialize (config, new JsonSerializerOptions { WriteIndented = true }); @@ -284,9 +284,9 @@ private bool TryParseExtraConfigValue(ITaskItem extraItem, out object? valueObje return true; // Try parsing as a quoted string - if (rawValue!.Length > 1 && rawValue![0] == '"' && rawValue![^1] == '"') + if (rawValue!.Length > 1 && rawValue![0] == '"' && rawValue![rawValue!.Length - 1] == '"') { - valueObject = rawValue![1..^1]; + valueObject = rawValue!.Substring(1, rawValue!.Length - 2); return true; } diff --git a/src/tasks/WasmAppBuilder/WasmAppBuilder.csproj b/src/tasks/WasmAppBuilder/WasmAppBuilder.csproj index 0846c59795d..e7641b3ab1a 100644 --- a/src/tasks/WasmAppBuilder/WasmAppBuilder.csproj +++ b/src/tasks/WasmAppBuilder/WasmAppBuilder.csproj @@ -1,9 +1,18 @@ - $(NetCoreAppToolCurrent) + $(NetCoreAppToolCurrent);$(TargetFrameworkForNETFramework) enable $(NoWarn),CA1050 + + + $(NoWarn),CS8604,CS8602 + + + + + + @@ -13,13 +22,29 @@ + AfterTargets="Build"> + + + + <_PublishFramework Include="$(TargetFrameworks)" /> + + + - - + <_PublishFramework Remove="@(_PublishFramework)" /> + <_PublishFramework Include="$(TargetFrameworks)" /> + + + + + + + -- GitLab