diff --git a/docs/workflow/testing/libraries/testing-wasm.md b/docs/workflow/testing/libraries/testing-wasm.md
index f060a00f9b458..a8d7eb1a7934d 100644
--- a/docs/workflow/testing/libraries/testing-wasm.md
+++ b/docs/workflow/testing/libraries/testing-wasm.md
@@ -144,6 +144,21 @@ At the moment supported values are:
By default, `chrome` browser is used.
+## AOT library tests
+
+- Building library tests with AOT, and (even) with `EnableAggressiveTrimming` takes 3-9mins on CI, and that adds up for all the assemblies, causing
+a large build time. To circumvent that on CI, we build the test assemblies on the build machine, but skip the WasmApp build part of it, since
+that includes the expensive AOT step.
+
+- Instead, we take the built test assembly+dependencies, and enough related bits to be able to run the `WasmBuildApp` target, with the original
+inputs.
+
+- To recreate a similar build+test run locally, add `/p:BuildAOTTestsOnHelix=true` to the usual command line.
+- For example, with `./dotnet.sh build /t:Test src/libraries/System.AppContext/tests /p:TargetOS=Browser /p:TargetArchitecture=wasm /p:Configuration=Release`
+
+ - AOT: add `/p:EnableAggressiveTrimming=true /p:RunAOTCompilation=true /p:BuildAOTTestsOnHelix=true`
+ - Only trimming (helpful to isolate issues caused by trimming):
+ - add `/p:EnableAggressiveTrimming=true /p:BuildAOTTestsOnHelix=true`
## Debugging
### Getting more information
diff --git a/eng/pipelines/common/platform-matrix.yml b/eng/pipelines/common/platform-matrix.yml
index e638ecbda6c59..6e92936ffca30 100644
--- a/eng/pipelines/common/platform-matrix.yml
+++ b/eng/pipelines/common/platform-matrix.yml
@@ -219,7 +219,7 @@ jobs:
targetRid: browser-wasm
platform: Browser_wasm
container:
- image: ubuntu-18.04-webassembly-20210223133559-4800846
+ image: ubuntu-18.04-webassembly-20210309143118-005aab4
registry: mcr
jobParameters:
runtimeFlavor: ${{ parameters.runtimeFlavor }}
diff --git a/eng/pipelines/runtime-staging.yml b/eng/pipelines/runtime-staging.yml
index d8ed185dbcbff..35a3fd9f9bc21 100644
--- a/eng/pipelines/runtime-staging.yml
+++ b/eng/pipelines/runtime-staging.yml
@@ -205,8 +205,47 @@ jobs:
jobParameters:
testGroup: innerloop
nameSuffix: AllSubsets_Mono_AOT
- buildArgs: -s mono+libs+host+packs+libs.tests -c $(_BuildConfig) /p:ArchiveTests=true /p:EnableAggressiveTrimming=true /p:RunAOTCompilation=true
- timeoutInMinutes: 120
+ buildArgs: -s mono+libs+host+packs+libs.tests -c $(_BuildConfig) /p:ArchiveTests=true /p:EnableAggressiveTrimming=true /p:BuildAOTTestsOnHelix=true /p:RunAOTCompilation=true
+ timeoutInMinutes: 180
+ condition: >-
+ or(
+ eq(dependencies.evaluate_paths.outputs['SetPathVars_libraries.containsChange'], true),
+ eq(dependencies.evaluate_paths.outputs['SetPathVars_mono.containsChange'], true),
+ eq(dependencies.evaluate_paths.outputs['SetPathVars_installer.containsChange'], true),
+ eq(variables['isFullMatrix'], true))
+ # extra steps, run tests
+ extraStepsTemplate: /eng/pipelines/libraries/helix.yml
+ extraStepsParameters:
+ creator: dotnet-bot
+ testRunNamePrefixSuffix: Mono_$(_BuildConfig)
+ extraHelixArguments: /p:NeedsToBuildWasmAppsOnHelix=true
+ scenarios:
+ - normal
+ condition: >-
+ or(
+ eq(variables['librariesContainsChange'], true),
+ eq(variables['monoContainsChange'], true),
+ eq(variables['isFullMatrix'], true))
+
+- template: /eng/pipelines/common/platform-matrix.yml
+ parameters:
+ jobTemplate: /eng/pipelines/common/global-build-job.yml
+ helixQueuesTemplate: /eng/pipelines/libraries/helix-queues-setup.yml
+ buildConfig: Release
+ runtimeFlavor: mono
+ platforms:
+ - Browser_wasm
+ variables:
+ # map dependencies variables to local variables
+ - name: librariesContainsChange
+ value: $[ dependencies.evaluate_paths.outputs['SetPathVars_libraries.containsChange'] ]
+ - name: monoContainsChange
+ value: $[ dependencies.evaluate_paths.outputs['SetPathVars_mono.containsChange'] ]
+ jobParameters:
+ testGroup: innerloop
+ nameSuffix: AllSubsets_Mono_EAT
+ buildArgs: -s mono+libs+host+packs+libs.tests -c $(_BuildConfig) /p:ArchiveTests=true /p:EnableAggressiveTrimming=true /p:BuildAOTTestsOnHelix=true /p:RunAOTCompilation=false
+ timeoutInMinutes: 180
condition: >-
or(
eq(dependencies.evaluate_paths.outputs['SetPathVars_libraries.containsChange'], true),
@@ -218,6 +257,7 @@ jobs:
extraStepsParameters:
creator: dotnet-bot
testRunNamePrefixSuffix: Mono_$(_BuildConfig)
+ extraHelixArguments: /p:NeedsToBuildWasmAppsOnHelix=true
scenarios:
- normal
condition: >-
diff --git a/eng/testing/ILLink.Descriptor.TestUtilities.xml b/eng/testing/ILLink.Descriptor.TestUtilities.xml
new file mode 100644
index 0000000000000..ac7e328c9038e
--- /dev/null
+++ b/eng/testing/ILLink.Descriptor.TestUtilities.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/eng/testing/ILLink.Descriptor.xunit.xml b/eng/testing/ILLink.Descriptor.xunit.xml
index dcba661e13692..16da46cbccb73 100644
--- a/eng/testing/ILLink.Descriptor.xunit.xml
+++ b/eng/testing/ILLink.Descriptor.xunit.xml
@@ -12,6 +12,7 @@
+
-
+
diff --git a/eng/testing/tests.mobile.targets b/eng/testing/tests.mobile.targets
index 36d20963a936b..aea51ddee8c28 100644
--- a/eng/testing/tests.mobile.targets
+++ b/eng/testing/tests.mobile.targets
@@ -167,7 +167,7 @@
-
@@ -243,7 +243,8 @@
-
+
+
diff --git a/eng/testing/tests.wasm.targets b/eng/testing/tests.wasm.targets
index 89f967d865c1e..97e72ea56dc38 100644
--- a/eng/testing/tests.wasm.targets
+++ b/eng/testing/tests.wasm.targets
@@ -3,6 +3,15 @@
$(BundleTestAppTargets);BundleTestWasmApp
true
+
+ true
+
+
+
+ helix
+ helix
+ local
@@ -14,49 +23,119 @@
<_XHarnessArgs Condition="'$(Scenario)' != 'WasmTestOnBrowser'">$(_XHarnessArgs) --engine=$(JSEngine) $(JSEngineArgs) --js-file=runtime.js
<_XHarnessArgs Condition="'$(IsFunctionalTest)' == 'true'" >$(_XHarnessArgs) --expected-exit-code=$(ExpectedExitCode)
- <_XHarnessArgs Condition="'$(WasmXHarnessArgs)' != '' and '$(OS)' != 'Windows_NT'">$(_XHarnessArgs) $(WasmXHarnessArgs) %24WasmXHarnessArgs
- <_XHarnessArgs Condition="'$(WasmXHarnessArgs)' != '' and '$(OS)' == 'Windows_NT'">$(_XHarnessArgs) $(WasmXHarnessArgs) %WasmXHarnessArgs%
+ <_XHarnessArgs Condition="'$(WasmXHarnessArgs)' != ''" >$(_XHarnessArgs) $(WasmXHarnessArgs)
<_AppArgs Condition="'$(IsFunctionalTest)' != 'true' and '$(Scenario)' != 'BuildWasmApps'">--run WasmTestRunner.dll $(AssemblyName).dll
<_AppArgs Condition="'$(IsFunctionalTest)' == 'true'">--run $(AssemblyName).dll --testing
- <_AppArgs Condition="'$(WasmTestAppArgs)' != ''">$(_AppArgs) $(WasmTestAppArgs) %24WasmTestAppArgs
- $HARNESS_RUNNER $(_XHarnessArgs) -- $(WasmXHarnessMonoArgs) %24WasmXHarnessMonoArgs $(_AppArgs)
- %HARNESS_RUNNER% $(_XHarnessArgs) -- $(WasmXHarnessMonoArgs) %WasmXHarnessMonoArgs% $(_AppArgs)
+ <_AppArgs Condition="'$(WasmTestAppArgs)' != ''">$(_AppArgs) $(WasmTestAppArgs)
+
+ $HARNESS_RUNNER $(_XHarnessArgs) %24WasmXHarnessArgs -- $(WasmXHarnessMonoArgs) %24WasmXHarnessMonoArgs $(_AppArgs) %24WasmTestAppArgs
+ $HARNESS_RUNNER $(_XHarnessArgs) %WasmXHarnessArgs% -- $(WasmXHarnessMonoArgs) %WasmXHarnessMonoArgs% $(_AppArgs) %WasmTestAppArgs%
+
+
+
+ <_AOTBuildCommand>dotnet msbuild publish/AOTTestProjectForHelix.proj /bl:$XHARNESS_OUT/AOTBuild.binlog
+
+
+ <_AOTBuildCommand Condition="'$(ContinuousIntegrationBuild)' != 'true'">$(_AOTBuildCommand) /p:RuntimeSrcDir=$(RepoRoot) /p:RuntimeConfig=$(Configuration)
+
+ <_AOTBuildCommand>$(_AOTBuildCommand) /p:RunAOTCompilation=$(RunAOTCompilation)
+ <_AOTBuildCommand>$(_AOTBuildCommand) && cd wasm_build/AppBundle
+
+ $(_AOTBuildCommand)
+ $(_AOTBuildCommand) && $(RunScriptCommand)
false
- true
+ false
false
false
- false
+ false
-
-
+
+
+
PrepareForWasmBuildApp;$(WasmBuildAppDependsOn)
- $([MSBuild]::NormalizeDirectory('$(RepoRoot)', 'src', 'mono', 'wasm', 'emsdk'))
+ $([MSBuild]::NormalizeDirectory('$(RepoRoot)', 'src', 'mono', 'wasm', 'emsdk'))
+
+ WasmBuildApp
+ StageEmSdkForHelix
+
+ $(BundleTestWasmAppDependsOn);_BundleAOTTestWasmAppForHelix
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ <_BundlePdbFiles Include="$([System.IO.Path]::ChangeExtension('%(WasmAssembliesToBundle.Identity)', '.pdb'))" />
+
+
+
+
+
+ <_WasmPropertyNames Include="InvariantGlobalization" />
+ <_WasmPropertyNames Include="AOTMode" />
+ <_WasmPropertyNames Include="WasmDebugLevel" />
+ <_WasmPropertyNames Include="WasmBuildNative" />
+ <_WasmPropertyNames Include="_WasmDevel" />
+ <_WasmPropertyNames Include="WasmLinkIcalls" />
+ <_WasmPropertyNames Include="WasmDedup" />
+ <_WasmPropertyNames Include="IncludeSatelliteAssembliesInVFS" />
+
+ <_WasmPropertiesToPass
+ Include="$(%(_WasmPropertyNames.Identity))"
+ Name="%(_WasmPropertyNames.Identity)"
+ ConditionToUse="%(_WasmPropertyNames.ConditionToUse)" />
+
+ <_WasmVFSFilesToCopy Include="@(WasmFilesToIncludeInFileSystem)" />
+ <_WasmVFSFilesToCopy TargetPath="%(FileName)%(Extension)" Condition="'%(TargetPath)' == ''" />
+
+
+
+
+
+
+
+
-
-
+
+
-
-
+
+
@@ -74,17 +153,30 @@
-
- $([System.IO.Directory]::GetParent('%(Identity)').Name)
-
+
-
-
+
+
+ <_CopyLocalPaths
+ Include="@(PublishItemsOutputGroupOutputs)"
+ Condition="'%(PublishItemsOutputGroupOutputs.BuildReference)' == 'true' and
+ !$([System.String]::new('%(PublishItemsOutputGroupOutputs.Identity)').EndsWith('.resources.dll'))" />
+
+ <_CopyLocalPaths TargetPath="%(_CopyLocalPaths.RelativePath)" Condition="'%(_CopyLocalPaths.RelativePath)' != ''" />
+ <_CopyLocalPaths TargetPath="%(FileName)%(Extension)" Condition="'%(_CopyLocalPaths.RelativePath)' == ''" />
+
+
-
+
diff --git a/src/libraries/Microsoft.CSharp/tests/Microsoft.CSharp.Tests.csproj b/src/libraries/Microsoft.CSharp/tests/Microsoft.CSharp.Tests.csproj
index bc793f0595eef..c115e0c43497f 100644
--- a/src/libraries/Microsoft.CSharp/tests/Microsoft.CSharp.Tests.csproj
+++ b/src/libraries/Microsoft.CSharp/tests/Microsoft.CSharp.Tests.csproj
@@ -7,6 +7,8 @@
"Operator '-' cannot be applied to operands of type 'ushort' and 'EnumArithmeticTests.UInt16Enum'"
-->
$(Features.Replace('strict', '')
+
+ true
diff --git a/src/libraries/System.Collections.Concurrent/tests/System.Collections.Concurrent.Tests.csproj b/src/libraries/System.Collections.Concurrent/tests/System.Collections.Concurrent.Tests.csproj
index 1ef1827987185..d0beb0ebc4699 100644
--- a/src/libraries/System.Collections.Concurrent/tests/System.Collections.Concurrent.Tests.csproj
+++ b/src/libraries/System.Collections.Concurrent/tests/System.Collections.Concurrent.Tests.csproj
@@ -3,6 +3,7 @@
true
true
$(NetCoreAppCurrent)
+ true
-
\ No newline at end of file
+
diff --git a/src/libraries/System.Collections.Immutable/tests/System.Collections.Immutable.Tests.csproj b/src/libraries/System.Collections.Immutable/tests/System.Collections.Immutable.Tests.csproj
index f71e364a81ea2..5dc59a3838215 100644
--- a/src/libraries/System.Collections.Immutable/tests/System.Collections.Immutable.Tests.csproj
+++ b/src/libraries/System.Collections.Immutable/tests/System.Collections.Immutable.Tests.csproj
@@ -2,6 +2,7 @@
0436
$(NetCoreAppCurrent);net461
+ true
true
$(NetCoreAppCurrent)
+ true
diff --git a/src/libraries/System.Collections/tests/System.Collections.Tests.csproj b/src/libraries/System.Collections/tests/System.Collections.Tests.csproj
index a9aba5d5add00..66f5dee8d5ba6 100644
--- a/src/libraries/System.Collections/tests/System.Collections.Tests.csproj
+++ b/src/libraries/System.Collections/tests/System.Collections.Tests.csproj
@@ -2,6 +2,7 @@
$(NetCoreAppCurrent)
true
+ true
diff --git a/src/libraries/System.ComponentModel.TypeConverter/tests/System.ComponentModel.TypeConverter.Tests.csproj b/src/libraries/System.ComponentModel.TypeConverter/tests/System.ComponentModel.TypeConverter.Tests.csproj
index 4f96c81aea140..6b01697f2af27 100644
--- a/src/libraries/System.ComponentModel.TypeConverter/tests/System.ComponentModel.TypeConverter.Tests.csproj
+++ b/src/libraries/System.ComponentModel.TypeConverter/tests/System.ComponentModel.TypeConverter.Tests.csproj
@@ -164,6 +164,6 @@
-
+
-
\ No newline at end of file
+
diff --git a/src/libraries/System.Composition.TypedParts/tests/System.Composition.TypedParts.Tests.csproj b/src/libraries/System.Composition.TypedParts/tests/System.Composition.TypedParts.Tests.csproj
index 5701c13ee3fb5..293590ae99aff 100644
--- a/src/libraries/System.Composition.TypedParts/tests/System.Composition.TypedParts.Tests.csproj
+++ b/src/libraries/System.Composition.TypedParts/tests/System.Composition.TypedParts.Tests.csproj
@@ -1,6 +1,7 @@
$(NetCoreAppCurrent);net461
+ true
@@ -16,4 +17,4 @@
-
\ No newline at end of file
+
diff --git a/src/libraries/System.Diagnostics.StackTrace/tests/System.Diagnostics.StackTrace.Tests.csproj b/src/libraries/System.Diagnostics.StackTrace/tests/System.Diagnostics.StackTrace.Tests.csproj
index 93673781e705f..d6d002664cfef 100644
--- a/src/libraries/System.Diagnostics.StackTrace/tests/System.Diagnostics.StackTrace.Tests.csproj
+++ b/src/libraries/System.Diagnostics.StackTrace/tests/System.Diagnostics.StackTrace.Tests.csproj
@@ -3,6 +3,9 @@
$(NetCoreAppCurrent)
true
true
+
+
+ true
diff --git a/src/libraries/System.Drawing.Primitives/tests/System.Drawing.Primitives.Tests.csproj b/src/libraries/System.Drawing.Primitives/tests/System.Drawing.Primitives.Tests.csproj
index b3a3a3ea5e3d6..53f60dbcb9092 100644
--- a/src/libraries/System.Drawing.Primitives/tests/System.Drawing.Primitives.Tests.csproj
+++ b/src/libraries/System.Drawing.Primitives/tests/System.Drawing.Primitives.Tests.csproj
@@ -1,6 +1,7 @@
$(NetCoreAppCurrent)
+ true
diff --git a/src/libraries/System.Linq/tests/System.Linq.Tests.csproj b/src/libraries/System.Linq/tests/System.Linq.Tests.csproj
index 4e4a90f7f2f0d..cd15cfbbf59d5 100644
--- a/src/libraries/System.Linq/tests/System.Linq.Tests.csproj
+++ b/src/libraries/System.Linq/tests/System.Linq.Tests.csproj
@@ -1,6 +1,7 @@
$(NetCoreAppCurrent)
+ true
@@ -75,4 +76,4 @@
-
\ No newline at end of file
+
diff --git a/src/libraries/System.Text.RegularExpressions/tests/System.Text.RegularExpressions.Tests.csproj b/src/libraries/System.Text.RegularExpressions/tests/System.Text.RegularExpressions.Tests.csproj
index 45fe74f628769..dff58ce1bf5ce 100644
--- a/src/libraries/System.Text.RegularExpressions/tests/System.Text.RegularExpressions.Tests.csproj
+++ b/src/libraries/System.Text.RegularExpressions/tests/System.Text.RegularExpressions.Tests.csproj
@@ -4,6 +4,7 @@
$(NoWarn);xUnit2008
$(NetCoreAppCurrent);net48
+ true
diff --git a/src/libraries/System.Threading.Channels/tests/System.Threading.Channels.Tests.csproj b/src/libraries/System.Threading.Channels/tests/System.Threading.Channels.Tests.csproj
index c67e5e5fed5cd..45be5f8572173 100644
--- a/src/libraries/System.Threading.Channels/tests/System.Threading.Channels.Tests.csproj
+++ b/src/libraries/System.Threading.Channels/tests/System.Threading.Channels.Tests.csproj
@@ -1,6 +1,7 @@
$(NetCoreAppCurrent);net461
+ true
diff --git a/src/libraries/sendtohelix.proj b/src/libraries/sendtohelix.proj
index 4d113c917f7b5..22d2f24fad15e 100644
--- a/src/libraries/sendtohelix.proj
+++ b/src/libraries/sendtohelix.proj
@@ -63,6 +63,7 @@
<_ProjectsToBuild Include="$(PerScenarioProjectFile)">
$(_PropertiesToPass);Scenario=%(_Scenarios.Identity);TestArchiveRuntimeFile=$(TestArchiveRuntimeFile)
+ %(_ProjectsToBuild.AdditionalProperties);NeedsToBuildWasmAppsOnHelix=$(NeedsToBuildWasmAppsOnHelix)
diff --git a/src/libraries/sendtohelixhelp.proj b/src/libraries/sendtohelixhelp.proj
index d9c2f5571237e..d326ebfae5310 100644
--- a/src/libraries/sendtohelixhelp.proj
+++ b/src/libraries/sendtohelixhelp.proj
@@ -50,6 +50,7 @@
$(TestRunNamePrefix)$(Scenario)-
$(WaitForWorkItemCompletion)
+ true
@@ -104,7 +105,7 @@
-
+
true
true
sdk
@@ -255,6 +256,8 @@
$([MSBuild]::NormalizeDirectory('$(RepoRoot)', 'src', 'mono', 'wasm', 'build'))
+
+
$(HelixPostCommands);
@@ -266,7 +269,7 @@
-
+
diff --git a/src/libraries/tests.proj b/src/libraries/tests.proj
index dd9618608d408..acd3fd1f87f17 100644
--- a/src/libraries/tests.proj
+++ b/src/libraries/tests.proj
@@ -224,101 +224,109 @@
-
-
-
-
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
+
+
+
+
-
-
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
+
+
-
-
+
+
+
+
-
-
+
+
+
+
+
-
-
+
+
+
+
+
-
-
+
+
-
-
-
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/mono/wasm/data/aot-tests/AOTTestProjectForHelix.proj b/src/mono/wasm/data/aot-tests/AOTTestProjectForHelix.proj
new file mode 100644
index 0000000000000..f7b9d3fcc4fd0
--- /dev/null
+++ b/src/mono/wasm/data/aot-tests/AOTTestProjectForHelix.proj
@@ -0,0 +1,48 @@
+
+
+
+ $(HELIX_WORKITEM_ROOT)\wasm_build\
+ $(MSBuildThisFileDirectory)..\wasm_build\
+
+ true
+ $(TestRootDir)..\publish\
+ $(OriginalPublishDir)..\extraFiles\
+ $(TestRootDir)\obj\
+
+ false
+ true
+ false
+ PrepareForWasmBuildApp;$(WasmBuildAppDependsOn)
+
+
+
+
+
+
+
+
+ $(TestRootDir)AppBundle\
+ $(OriginalPublishDir)WasmTestRunner.dll
+ $(OriginalPublishDir)runtime-test.js
+ true
+
+
+
+
+
+
+
+
+ <_ExtraFiles Include="$(ExtraFilesPath)**\*" />
+
+
+
+
+ <_SatelliteAssembliesForVFS Include="@(WasmSatelliteAssemblies)" />
+ <_SatelliteAssembliesForVFS TargetPath="%(CultureName)\%(FileName)%(Extension)" />
+
+
+
+
+
+
diff --git a/src/mono/wasm/data/aot-tests/Directory.Build.props b/src/mono/wasm/data/aot-tests/Directory.Build.props
new file mode 100644
index 0000000000000..6b0501e8f631f
--- /dev/null
+++ b/src/mono/wasm/data/aot-tests/Directory.Build.props
@@ -0,0 +1,17 @@
+
+
+ $(HELIX_CORRELATION_PAYLOAD)\build\
+ <_WasmTargetsDir>$(WasmBuildSupportDir)\wasm\
+ $(WasmBuildSupportDir)\emsdk\
+
+
+
+ <_WasmTargetsDir Condition="'$(_WasmTargetsDir)' == '' and '$(RuntimeSrcDir)' != ''">$(RuntimeSrcDir)\src\mono\wasm\build\
+ <_WasmTargetsDir Condition="'$(_WasmTargetsDir)' != ''">$([MSBuild]::EnsureTrailingSlash($(_WasmTargetsDir)))
+
+
+
+
+ PrepareForWasmBuild;$(WasmBuildAppDependsOn)
+
+
diff --git a/src/mono/wasm/data/aot-tests/Directory.Build.targets b/src/mono/wasm/data/aot-tests/Directory.Build.targets
new file mode 100644
index 0000000000000..5f8bd42de2250
--- /dev/null
+++ b/src/mono/wasm/data/aot-tests/Directory.Build.targets
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/tasks/WasmBuildTasks/GenerateAOTProps.cs b/src/tasks/WasmBuildTasks/GenerateAOTProps.cs
new file mode 100644
index 0000000000000..8e6c9c3142a9b
--- /dev/null
+++ b/src/tasks/WasmBuildTasks/GenerateAOTProps.cs
@@ -0,0 +1,55 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using System;
+using System.Collections.Generic;
+using System.Diagnostics.CodeAnalysis;
+using System.IO;
+using System.Text;
+using Microsoft.Build.Framework;
+using Microsoft.Build.Utilities;
+
+namespace Microsoft.WebAssembly.Build.Tasks
+{
+ public class GenerateAOTProps : Task
+ {
+ [NotNull]
+ [Required]
+ public ITaskItem[]? Properties { get; set; }
+
+ [NotNull]
+ [Required]
+ public string? OutputFile { get; set; }
+
+ public override bool Execute()
+ {
+ var outDir = Path.GetDirectoryName(OutputFile);
+ if (!string.IsNullOrEmpty(outDir) && !Directory.Exists(outDir))
+ Directory.CreateDirectory(outDir);
+
+ StringBuilder sb = new();
+
+ sb.AppendLine("");
+ sb.AppendLine(" ");
+
+ foreach (var prop in Properties)
+ {
+ string value = prop.ItemSpec;
+ string? name = prop.GetMetadata("Name");
+ string? condition = prop.GetMetadata("ConditionToUse");
+
+ if (!string.IsNullOrEmpty(condition))
+ sb.AppendLine($" <{name} Condition=\"{condition}\">{value}{name}>");
+ else
+ sb.AppendLine($" <{name}>{value}{name}>");
+ }
+
+ sb.AppendLine(" ");
+ sb.AppendLine("");
+
+ File.WriteAllText(OutputFile, sb.ToString());
+ return !Log.HasLoggedErrors;
+ }
+
+ }
+}
diff --git a/src/tests/BuildWasmApps/Wasm.Build.Tests/Wasm.Build.Tests.csproj b/src/tests/BuildWasmApps/Wasm.Build.Tests/Wasm.Build.Tests.csproj
index b6991b4d528c4..a8048fb95a80f 100644
--- a/src/tests/BuildWasmApps/Wasm.Build.Tests/Wasm.Build.Tests.csproj
+++ b/src/tests/BuildWasmApps/Wasm.Build.Tests/Wasm.Build.Tests.csproj
@@ -2,6 +2,7 @@
$(NetCoreAppToolCurrent)
true
+ true
true
true
BuildAndRun