diff options
author | Larry Ewing <lewing@microsoft.com> | 2021-05-03 21:08:42 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-05-03 21:08:42 +0300 |
commit | bfd6048a605e9a0bebced7171a98bc3f04c78192 (patch) | |
tree | 96596fe2e5e166c25329cedbfea732ef120a67e1 | |
parent | bd2d701e7509c4e15e2475a7ca1f6487f7ff7663 (diff) |
[release/6.0-preview4][wasm] Fix Blazor AOT builds inside Visual Studio (#52078)v6.0.0-preview.4.21253.7
* [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.<ExecuteInstantiatedTask>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 <dsplaisted@gmail.com>
* Update src/tasks/AotCompilerTask/MonoAOTCompiler.csproj
Co-authored-by: Daniel Plaisted <dsplaisted@gmail.com>
* Update src/tasks/WasmAppBuilder/WasmAppBuilder.csproj
Co-authored-by: Daniel Plaisted <dsplaisted@gmail.com>
* Update src/tasks/WasmAppBuilder/WasmAppBuilder.csproj
Co-authored-by: Daniel Plaisted <dsplaisted@gmail.com>
* Apply suggestions from code review
Co-authored-by: Daniel Plaisted <dsplaisted@gmail.com>
* Use a property for net472
Co-authored-by: Ankit Jain <radical@gmail.com>
Co-authored-by: Daniel Plaisted <dsplaisted@gmail.com>
-rw-r--r-- | src/mono/nuget/Microsoft.NET.Runtime.MonoAOTCompiler.Task/Sdk/Sdk.props | 3 | ||||
-rw-r--r-- | src/mono/nuget/Microsoft.NET.Runtime.WebAssembly.Sdk/Sdk/Sdk.targets | 7 | ||||
-rw-r--r-- | src/tasks/AotCompilerTask/MonoAOTCompiler.cs | 8 | ||||
-rw-r--r-- | src/tasks/AotCompilerTask/MonoAOTCompiler.csproj | 11 | ||||
-rw-r--r-- | src/tasks/Common/IsExternalInit.cs | 7 | ||||
-rw-r--r-- | src/tasks/Common/Utils.cs | 2 | ||||
-rw-r--r-- | src/tasks/Directory.Build.props | 7 | ||||
-rw-r--r-- | src/tasks/WasmAppBuilder/WasmAppBuilder.cs | 24 | ||||
-rw-r--r-- | src/tasks/WasmAppBuilder/WasmAppBuilder.csproj | 35 |
9 files changed, 78 insertions, 26 deletions
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 @@ <Project> <PropertyGroup> - <MonoAOTCompilerTasksAssemblyPath>$(MSBuildThisFileDirectory)..\tasks\MonoAOTCompiler.dll</MonoAOTCompilerTasksAssemblyPath> + <MonoAOTCompilerTasksAssemblyPath Condition="'$(MSBuildRuntimeType)' == 'Core'">$(MSBuildThisFileDirectory)..\tasks\net6.0\MonoAOTCompiler.dll</MonoAOTCompilerTasksAssemblyPath> + <MonoAOTCompilerTasksAssemblyPath Condition="'$(MSBuildRuntimeType)' != 'Core'">$(MSBuildThisFileDirectory)..\tasks\net472\MonoAOTCompiler.dll</MonoAOTCompilerTasksAssemblyPath> </PropertyGroup> <UsingTask TaskName="MonoAOTCompiler" AssemblyFile="$(MonoAOTCompilerTasksAssemblyPath)" /> </Project> 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 @@ <Project> <!-- Property overrides --> <PropertyGroup> - <WasmAppBuilderTasksAssemblyPath>$(MSBuildThisFileDirectory)..\tasks\WasmAppBuilder.dll</WasmAppBuilderTasksAssemblyPath> - <WasmBuildTasksAssemblyPath>$(MSBuildThisFileDirectory)..\tasks\WasmBuildTasks.dll</WasmBuildTasksAssemblyPath> + <_TasksDir Condition="'$(MSBuildRuntimeType)' == 'Core'">$(MSBuildThisFileDirectory)..\tasks\net6.0\</_TasksDir> + <_TasksDir Condition="'$(MSBuildRuntimeType)' != 'Core'">$(MSBuildThisFileDirectory)..\tasks\net472\</_TasksDir> + + <WasmAppBuilderTasksAssemblyPath>$(_TasksDir)WasmAppBuilder.dll</WasmAppBuilderTasksAssemblyPath> + <WasmBuildTasksAssemblyPath>$(_TasksDir)WasmBuildTasks.dll</WasmBuildTasksAssemblyPath> </PropertyGroup> <Import Project="$(MSBuildThisFileDirectory)\WasmApp.props" /> 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 class MonoAOTCompiler : Microsoft.Build.Utilities.Task 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 class MonoAOTCompiler : Microsoft.Build.Utilities.Task 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 @@ public class MonoAOTCompiler : Microsoft.Build.Utilities.Task 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 @@ <Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> - <TargetFramework>$(NetCoreAppToolCurrent)</TargetFramework> + <TargetFrameworks>$(NetCoreAppToolCurrent);$(TargetFrameworkForNETFramework)</TargetFrameworks> <OutputType>Library</OutputType> <TreatWarningsAsErrors>true</TreatWarningsAsErrors> <EnableDefaultCompileItems>false</EnableDefaultCompileItems> <Nullable>enable</Nullable> <NoWarn>$(NoWarn),CA1050</NoWarn> + + <!-- Ignore nullable warnings on net4* --> + <NoWarn Condition="$([MSBuild]::GetTargetFrameworkIdentifier('$(TargetFramework)')) == '.NETFramework'">$(NoWarn),CS8604,CS8602</NoWarn> </PropertyGroup> <ItemGroup> <PackageReference Include="Microsoft.Build" Version="$(RefOnlyMicrosoftBuildVersion)" /> @@ -16,6 +19,7 @@ <ItemGroup> <Compile Include="MonoAOTCompiler.cs" /> <Compile Include="..\Common\Utils.cs" /> + <Compile Include="$(RepoRoot)src\libraries\System.Private.CoreLib/src/System/Diagnostics/CodeAnalysis/NullableAttributes.cs" Condition="'$(TargetFrameworkIdentifier)' == '.NETFramework'" /> </ItemGroup> <ItemGroup> <Content Include="MonoAOTCompiler.props"> @@ -26,7 +30,10 @@ <!-- GetFilesToPackage assists to place `MonoAOTCompiler.dll` in a NuGet package in Microsoft.NET.Runtime.MonoAOTCompiler.Task.pkgproj for external use --> <Target Name="GetFilesToPackage" Returns="@(FilesToPackage)"> <ItemGroup> - <FilesToPackage Include="$(OutputPath)$(AssemblyName).dll" TargetPath="tasks" /> + <_PublishFramework Remove="@(_PublishFramework)" /> + <_PublishFramework Include="$(TargetFrameworks)" /> + + <FilesToPackage Include="$(OutputPath)%(_PublishFramework.Identity)\$(AssemblyName).dll" TargetPath="tasks\%(_PublishFramework.Identity)" /> </ItemGroup> </Target> </Project> 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 @@ internal static class Utils return outputBuilder.ToString().Trim('\r', '\n'); } +#if NETCOREAPP public static void DirectoryCopy(string sourceDir, string destDir, Func<string, bool> predicate) { string[] files = Directory.GetFiles(sourceDir, "*", SearchOption.AllDirectories); @@ -118,6 +119,7 @@ internal static class Utils File.Copy(file, Path.Combine(destDir, relativePath), true); } } +#endif public static TaskLoggingHelper? Logger { get; set; } diff --git a/src/tasks/Directory.Build.props b/src/tasks/Directory.Build.props new file mode 100644 index 00000000000..7ed8a459d2f --- /dev/null +++ b/src/tasks/Directory.Build.props @@ -0,0 +1,7 @@ +<Project> + <Import Project="$([MSBuild]::GetPathOfFileAbove(Directory.Build.props, '$(MSBuildThisFileDirectory)..'))" /> + + <PropertyGroup> + <TargetFrameworkForNETFramework>net472</TargetFrameworkForNETFramework> + </PropertyGroup> +</Project> 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 class WasmAppBuilder : Task 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 class WasmAppBuilder : Task 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 = @"<html><body><script type=""text/javascript"" src=""runtime.js""></script></body></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 class WasmAppBuilder : Task 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 class WasmAppBuilder : Task 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 class WasmAppBuilder : Task 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 @@ public class WasmAppBuilder : Task 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 @@ <Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> - <TargetFramework>$(NetCoreAppToolCurrent)</TargetFramework> + <TargetFrameworks>$(NetCoreAppToolCurrent);$(TargetFrameworkForNETFramework)</TargetFrameworks> <Nullable>enable</Nullable> <NoWarn>$(NoWarn),CA1050</NoWarn> + + <!-- Ignore nullable warnings on net4* --> + <NoWarn Condition="$([MSBuild]::GetTargetFrameworkIdentifier('$(TargetFramework)')) == '.NETFramework'">$(NoWarn),CS8604,CS8602</NoWarn> </PropertyGroup> + + <ItemGroup Condition="'$(TargetFrameworkIdentifier)' == '.NETFramework'"> + <Compile Include="..\Common\IsExternalInit.cs" /> + <Compile Include="$(RepoRoot)src\libraries\System.Private.CoreLib/src/System/Diagnostics/CodeAnalysis/NullableAttributes.cs" /> + </ItemGroup> + <ItemGroup> <PackageReference Include="Microsoft.Build" Version="$(RefOnlyMicrosoftBuildVersion)" /> <PackageReference Include="Microsoft.Build.Framework" Version="$(RefOnlyMicrosoftBuildFrameworkVersion)" /> @@ -13,13 +22,29 @@ </ItemGroup> <Target Name="PublishBuilder" - AfterTargets="Build" - DependsOnTargets="Publish" /> + AfterTargets="Build"> + + <!-- needed for publishing with multi-targeting. We are publishing essentially to get the SR.MetadataLoadContext.dll :/ --> + <ItemGroup> + <_PublishFramework Include="$(TargetFrameworks)" /> + </ItemGroup> + <MSBuild Projects="$(MSBuildProjectFile)" Targets="Publish" Properties="TargetFramework=%(_PublishFramework.Identity)" /> + </Target> <Target Name="GetFilesToPackage" Returns="@(FilesToPackage)"> <ItemGroup> - <FilesToPackage Include="$(OutputPath)$(MSBuildProjectName)*" TargetPath="tasks" /> - <FilesToPackage Include="$(PublishDir)System.Reflection.MetadataLoadContext.dll" TargetPath="tasks" /> + <_PublishFramework Remove="@(_PublishFramework)" /> + <_PublishFramework Include="$(TargetFrameworks)" /> + + <!-- non-net4* --> + <FilesToPackage Include="$(OutputPath)$(NetCoreAppToolCurrent)\$(MSBuildProjectName)*" + TargetPath="tasks\$(NetCoreAppToolCurrent)" /> + <FilesToPackage Include="$(OutputPath)$(NetCoreAppToolCurrent)\publish\System.Reflection.MetadataLoadContext.dll" + TargetPath="tasks\$(NetCoreAppToolCurrent)" /> + + <!-- for net472 we need all the dependent assemblies too, so copy from the publish folder --> + <FilesToPackage Include="$(OutputPath)$(TargetFrameworkForNETFramework)\publish\*" + TargetPath="tasks\$(TargetFrameworkForNETFramework)" /> </ItemGroup> </Target> |