</XHarnessAppBundleToTest>
</ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(TargetOS)' == 'Android'">
+ <XHarnessApkToTest>
+ <Targets Condition="'$(TargetArchitecture)' == 'arm'">armeabi-v7a</Targets>
+ <Targets Condition="'$(TargetArchitecture)' == 'arm64'">arm64-v8a</Targets>
+ <Targets Condition="'$(TargetArchitecture)' == 'x64'">x86_64</Targets>
+ <Targets Condition="'$(TargetArchitecture)' == 'x86'">x86</Targets>
+ <AndroidInstrumentationName>net.dot.MonoRunner</AndroidInstrumentationName>
+ <TestTimeout>$(_workItemTimeout)</TestTimeout>
+ </XHarnessApkToTest>
+ </ItemDefinitionGroup>
<!--
Create all the Helix data to start a set of jobs. Create a set of work items, one for each libraries
test assembly. All will have the same command line. Note that this target is listed in the
</ItemGroup>
<ItemGroup Condition="'$(TargetOS)' == 'Android'">
- <!-- We have to define this temp item list because of a bug in MSBuild that would prevent access %(Filename) right away -->
<_apks Include="$(TestArchiveTestsRoot)**/*.apk" />
<XHarnessApkToTest Include="@(_apks)">
- <Targets Condition="'$(TargetArchitecture)' == 'arm'">armeabi-v7a</Targets>
- <Targets Condition="'$(TargetArchitecture)' == 'arm64'">arm64-v8a</Targets>
- <Targets Condition="'$(TargetArchitecture)' == 'x64'">x86_64</Targets>
- <Targets Condition="'$(TargetArchitecture)' == 'x86'">x86</Targets>
<AndroidPackageName>net.dot.%(Filename)</AndroidPackageName>
- <AndroidInstrumentationName>net.dot.MonoRunner</AndroidInstrumentationName>
-
- <TestTimeout>$(_workItemTimeout)</TestTimeout>
+ </XHarnessApkToTest>
+ <_runonlyApks Include="$(TestArchiveRoot)runonly/**/*.apk" />
+ <XHarnessApkToTest Include="@(_runonlyApks)">
+ <AndroidPackageName>net.dot.%(Filename)</AndroidPackageName>
<!-- The android sample returns 42 so it should be considered by xharness as a success -->
- <ExpectedExitCode Condition="'%(Filename)' == 'HelloAndroid'">42</ExpectedExitCode>
+ <ExpectedExitCode>42</ExpectedExitCode>
</XHarnessApkToTest>
</ItemGroup>
<HelixWorkItem Include="@(_RunOnlyWorkItem -> '%(FileName)')" >
<PayloadArchive>%(Identity)</PayloadArchive>
<!-- No RunTests script generated for the sample project so we just use the direct command -->
- <Command>dotnet exec $XHARNESS_CLI_PATH wasm $XHARNESS_COMMAND --app=. --engine=V8 --engine-arg=--stack-trace-limit=1000 --js-file=runtime.js --output-directory=$HELIX_WORKITEM_UPLOAD_ROOT/xharness-output -- --run WasmSample.dll</Command>
+ <Command>dotnet exec $XHARNESS_CLI_PATH wasm $XHARNESS_COMMAND --app=. --engine=V8 --engine-arg=--stack-trace-limit=1000 --js-file=runtime.js --output-directory=$HELIX_WORKITEM_UPLOAD_ROOT/xharness-output -- --run %(FileName).dll</Command>
</HelixWorkItem>
</ItemGroup>
<HelixWorkItem Include="@(_RunOnlyWorkItem -> '%(FileName)')" >
<PayloadArchive>%(Identity)</PayloadArchive>
<!-- No RunTests script generated for the sample project so we just use the direct command -->
- <Command>dotnet exec $XHARNESS_CLI_PATH wasm $XHARNESS_COMMAND --app=. --browser=Chrome --html-file=index.html --output-directory=$HELIX_WORKITEM_UPLOAD_ROOT/xharness-output -- WasmSample.dll --testing</Command>
+ <Command>dotnet exec $XHARNESS_CLI_PATH wasm $XHARNESS_COMMAND --app=. --browser=Chrome --html-file=index.html --output-directory=$HELIX_WORKITEM_UPLOAD_ROOT/xharness-output -- %(FileName).dll --testing</Command>
</HelixWorkItem>
</ItemGroup>
Exclude="@(ProjectExclusions)"
BuildInParallel="false"
Condition="'$(TestTrimming)' == 'true'" />
- <ProjectReference Include="$(MonoProjectRoot)netcore\sample\Android\AndroidSampleApp.csproj"
- BuildInParallel="false"
- Condition="'$(ArchiveTests)' == 'true' and '$(TargetOS)' == 'Android'" />
+ </ItemGroup>
+
+ <ItemGroup Condition="'$(ArchiveTests)' == 'true' and ('$(TargetOS)' == 'iOS' or '$(TargetOS)' == 'tvOS')">
<ProjectReference Include="$(MonoProjectRoot)netcore\sample\iOS\Program.csproj"
- BuildInParallel="false"
- Condition="'$(ArchiveTests)' == 'true' and ('$(TargetOS)' == 'iOS' or '$(TargetOS)' == 'tvOS')" />
- <ProjectReference Include="$(MonoProjectRoot)netcore\sample\wasm\**\WasmSample.csproj"
- BuildInParallel="false"
- Condition="'$(ArchiveTests)' == 'true' and '$(TargetOS)' == 'Browser'" />
+ BuildInParallel="false" />
+ <ProjectReference Include="$(RepoRoot)\src\tests\FunctionalTests\iOS\**\*.Test.csproj"
+ BuildInParallel="false" />
+ </ItemGroup>
+
+ <ItemGroup Condition="'$(ArchiveTests)' == 'true' and '$(TargetOS)' == 'Android'">
+ <ProjectReference Include="$(MonoProjectRoot)netcore\sample\Android\AndroidSampleApp.csproj"
+ BuildInParallel="false" />
+ <ProjectReference Include="$(RepoRoot)\src\tests\FunctionalTests\Android\**\*.Test.csproj"
+ BuildInParallel="false" />
+ </ItemGroup>
+
+ <ItemGroup Condition="'$(ArchiveTests)' == 'true' and '$(TargetOS)' == 'Browser'">
+ <ProjectReference Include="$(MonoProjectRoot)netcore\sample\wasm\**\*.Sample.csproj"
+ BuildInParallel="false" />
+ <ProjectReference Include="$(RepoRoot)\src\tests\FunctionalTests\wasm\**\*.Test.csproj"
+ BuildInParallel="false" />
</ItemGroup>
<Target Name="GenerateMergedCoverageReport"
<!-- AnyCPU as Platform-->
<OSPlatformConfig>$(TargetOS).AnyCPU.$(Configuration)</OSPlatformConfig>
<!-- <OSPlatformConfig>$(TargetOS).$(Platform).$(Configuration)</OSPlatformConfig> -->
- <TestArchiveRoot>$(ArtifactsDir)helix/</TestArchiveRoot>
- <TestArchiveTestsRoot>$(TestArchiveRoot)tests/</TestArchiveTestsRoot>
- <TestArchiveTestsDir>$(TestArchiveTestsRoot)$(OSPlatformConfig)/</TestArchiveTestsDir>
+ <HelixArchiveRoot>$(ArtifactsDir)helix/</HelixArchiveRoot>
+ <HelixArchiveRunOnlyRoot>$(HelixArchiveRoot)runonly/</HelixArchiveRunOnlyRoot>
+ <HelixArchiveRunOnlyAppsDir>$(HelixArchiveRunOnlyRoot)$(OSPlatformConfig)/</HelixArchiveRunOnlyAppsDir>
</PropertyGroup>
<ItemGroup>
- <_appFiles Include="$(ApkBundlePath)" />
+ <_apkFiles Include="$(ApkBundlePath)" />
</ItemGroup>
- <Copy SourceFiles="@(_appFiles)"
- DestinationFolder="$(TestArchiveTestsDir)" />
+ <Copy SourceFiles="@(_apkFiles)"
+ DestinationFolder="$(HelixArchiveRunOnlyAppsDir)/%(RecursiveDir)" />
<Message Importance="High" Text="ApkBundlePath: $(ApkBundlePath)"/>
<Message Importance="High" Text="TestArchiveTestsDir: $(TestArchiveTestsDir)"/>
all: build
build:
- EMSDK_PATH=$(realpath $(TOP)/src/mono/wasm/emsdk) $(DOTNET) publish $(DOTNET_Q_ARGS) $(DOTNET_RUN_AOT_COMPILATION_ARGS) /p:Configuration=$(CONFIG) /p:TargetArchitecture=wasm /p:TargetOS=Browser $(MSBUILD_ARGS) WasmSample.csproj
+ EMSDK_PATH=$(realpath $(TOP)/src/mono/wasm/emsdk) $(DOTNET) publish $(DOTNET_Q_ARGS) $(DOTNET_RUN_AOT_COMPILATION_ARGS) /p:Configuration=$(CONFIG) /p:TargetArchitecture=wasm /p:TargetOS=Browser $(MSBUILD_ARGS) Wasm.Browser.Sample.csproj
clean:
rm -rf bin
<Target Name="PrepareForWasmBuild" BeforeTargets="WasmBuildApp">
<PropertyGroup>
<WasmAppDir>$(AppDir)</WasmAppDir>
- <WasmAOTDir>$(MSBuildProjectDirectory)\$(PublishDir)\</WasmAOTDir>
- <WasmMainAssemblyPath>$(MSBuildProjectDirectory)\bin\WasmSample.dll</WasmMainAssemblyPath>
+ <WasmBuildDir>$(MSBuildProjectDirectory)\$(PublishDir)\</WasmBuildDir>
<WasmMainJSPath>runtime.js</WasmMainJSPath>
- <WasmMainAssemblyPath>$(WasmAotDir)WasmSample.dll</WasmMainAssemblyPath>
+ <WasmMainAssemblyPath>$(WasmBuildDir)$(AssemblyName).dll</WasmMainAssemblyPath>
</PropertyGroup>
<ItemGroup>
<WasmAssembliesToBundle Include="$(TargetDir)publish\*.dll" />
<HelixArchiveRoot>$(ArtifactsDir)helix/</HelixArchiveRoot>
<HelixArchiveRunOnlyRoot>$(HelixArchiveRoot)runonly/</HelixArchiveRunOnlyRoot>
<HelixArchiveRunOnlyAppsDir>$(HelixArchiveRunOnlyRoot)$(OSPlatformConfig)/browser/</HelixArchiveRunOnlyAppsDir>
- <ZippedApp>$(OutputPath)/WasmBrowserSample.zip</ZippedApp>
+ <ZippedApp>$(OutputPath)$(AssemblyName).zip</ZippedApp>
</PropertyGroup>
<ZipDirectory SourceDirectory="$(AppDir)" DestinationFile="$(ZippedApp)" />
<Copy SourceFiles="$(ZippedApp)" DestinationFolder="$(HelixArchiveRunOnlyAppsDir)" />
var App = {
init: function () {
- var ret = BINDING.call_static_method("[WasmSample] Sample.Test:TestMeaning", []);
+ var ret = BINDING.call_static_method("[Wasm.Browser.Sample] Sample.Test:TestMeaning", []);
document.getElementById("out").innerHTML = ret;
if (is_testing)
all: build
build:
- EMSDK_PATH=$(realpath $(TOP)/src/mono/wasm/emsdk) $(DOTNET) publish $(DOTNET_Q_ARGS) $(DOTNET_RUN_AOT_COMPILATION_ARGS) $(DOTNET_EXTRA_ARGS) /p:TargetArchitecture=wasm /p:TargetOS=Browser /p:Configuration=$(CONFIG) $(MSBUILD_ARGS) WasmSample.csproj
+ EMSDK_PATH=$(realpath $(TOP)/src/mono/wasm/emsdk) $(DOTNET) publish $(DOTNET_Q_ARGS) $(DOTNET_RUN_AOT_COMPILATION_ARGS) $(DOTNET_EXTRA_ARGS) /p:TargetArchitecture=wasm /p:TargetOS=Browser /p:Configuration=$(CONFIG) $(MSBUILD_ARGS) Wasm.Console.Sample.csproj
clean:
rm -rf bin
run:
- cd bin/$(CONFIG)/AppBundle && ~/.jsvu/v8 --expose_wasm runtime.js -- $(DOTNET_MONO_LOG_LEVEL) --run WasmSample.dll
+ cd bin/$(CONFIG)/AppBundle && ~/.jsvu/v8 --expose_wasm runtime.js -- $(DOTNET_MONO_LOG_LEVEL) --run Wasm.Console.Sample.dll
<WasmAppDir>$(AppBundleDir)</WasmAppDir>
<WasmBuildDir>$(MSBuildProjectDirectory)\$(PublishDir)\</WasmBuildDir>
<WasmMainJSPath>$(MonoProjectRoot)\wasm\runtime-test.js</WasmMainJSPath>
- <WasmMainAssemblyPath>$(WasmBuildDir)WasmSample.dll</WasmMainAssemblyPath>
+ <WasmMainAssemblyPath>$(WasmBuildDir)$(AssemblyName).dll</WasmMainAssemblyPath>
<WasmGenerateRunV8Script>true</WasmGenerateRunV8Script>
</PropertyGroup>
<ItemGroup>
<HelixArchiveRoot>$(ArtifactsDir)helix/</HelixArchiveRoot>
<HelixArchiveRunOnlyRoot>$(HelixArchiveRoot)runonly/</HelixArchiveRunOnlyRoot>
<HelixArchiveRunOnlyAppsDir>$(HelixArchiveRunOnlyRoot)$(OSPlatformConfig)/console/</HelixArchiveRunOnlyAppsDir>
- <ZippedApp>$(OutputPath)/WasmConsoleSample.zip</ZippedApp>
+ <ZippedApp>$(OutputPath)$(AssemblyName).zip</ZippedApp>
</PropertyGroup>
<ZipDirectory SourceDirectory="$(AppBundleDir)" DestinationFile="$(ZippedApp)" />
<Copy SourceFiles="$(ZippedApp)" DestinationFolder="$(HelixArchiveRunOnlyAppsDir)" />
UseAotDataFile="false"
AotModulesTablePath="$(WasmBuildDir)driver-gen.c"
UseLLVM="true"
- DisableParallelAot="true"
+ DisableParallelAot="true"
LLVMPath="$(EMSDK_PATH)\upstream\bin">
<Output TaskParameter="CompiledAssemblies" ItemName="_WasmAssemblies" />
</MonoAOTCompiler>
<ItemGroup>
<_managedAppAssemblies Include="$(WasmAppDir)managed\*.dll"/>
</ItemGroup>
- <Exec Condition="'$(RunAOTCompilation)' == 'true'" Command="mono-cil-strip %(_managedAppAssemblies.Identity)" />
+ <!-- '$(ArchiveTests)' != 'true' is to skip on CI for now -->
+ <Exec Condition="'$(RunAOTCompilation)' == 'true' and '$(ArchiveTests)' != 'true'" Command="mono-cil-strip %(_managedAppAssemblies.Identity)" />
</Target>
<Target Name="_WasmBuildNative" DependsOnTargets="_WasmAotCompileApp" Condition="'$(WasmBuildNative)' == 'true'">
<PropertyGroup>
<EmccFlags>$(EmccFlags) -s DISABLE_EXCEPTION_CATCHING=0</EmccFlags>
<EmccFlags Condition="'$(RunAOTCompilation)' == 'true'">$(EmccFlags) -DENABLE_AOT=1 -DDRIVER_GEN=1</EmccFlags>
+ <_EmsdkEnvSourceCommand>source $(EMSDK_PATH)/emsdk_env.sh</_EmsdkEnvSourceCommand>
+ <_EmccCommand>$(_EmsdkEnvSourceCommand) && emcc</_EmccCommand>
</PropertyGroup>
<ReadLinesFromFile File="$(RuntimeEmccVersionFile)">
<Output TaskParameter="Lines" PropertyName="RuntimeEmccVersion" />
</ReadLinesFromFile>
- <Exec Command="source $(EMSDK_PATH)/emsdk_env.sh && emcc --version | head -1 > emcc-version.txt" IgnoreStandardErrorWarningFormat="true" WorkingDirectory="$(WasmBuildDir)" />
+ <Exec Command="bash -c '$(_EmccCommand) --version | head -1 > emcc-version.txt'" IgnoreStandardErrorWarningFormat="true" WorkingDirectory="$(WasmBuildDir)" />
<ReadLinesFromFile File="$(EmccPublishVersionFile)">
<Output TaskParameter="Lines" PropertyName="EmccVersion" />
</ReadLinesFromFile>
<PropertyGroup>
<_WasmIncludeDir>$(MicrosoftNetCoreAppRuntimePackRidDir)native/include</_WasmIncludeDir>
<_WasmSrcDir>$(MicrosoftNetCoreAppRuntimePackRidDir)native/src</_WasmSrcDir>
- <_WasmEmcc>source $(EMSDK_PATH)/emsdk_env.sh && emcc</_WasmEmcc>
<EmccCFlags>$(EmccFlags) -DCORE_BINDINGS -DGEN_PINVOKE=1 -I$(WasmBuildDir) -I$(_WasmIncludeDir)/mono-2.0 -I$(_WasmIncludeDir)/wasm</EmccCFlags>
<EmccLDFlags>$(EmccFlags) -s TOTAL_MEMORY=536870912</EmccLDFlags>
</PropertyGroup>
- <Exec Command="$(_WasmEmcc) $(EmccCFlags) $(_WasmSrcDir)/driver.c -c -o driver.o" IgnoreStandardErrorWarningFormat="true" WorkingDirectory="$(WasmBuildDir)" StandardOutputImportance="Low" />
- <Exec Command="$(_WasmEmcc) $(EmccCFlags) $(_WasmSrcDir)/corebindings.c -c -o corebindings.o" IgnoreStandardErrorWarningFormat="true" WorkingDirectory="$(WasmBuildDir)" StandardOutputImportance="Low" />
- <Exec Command="$(_WasmEmcc) $(EmccCFlags) $(_WasmSrcDir)/pinvoke.c -c -o pinvoke.o" IgnoreStandardErrorWarningFormat="true" WorkingDirectory="$(WasmBuildDir)" StandardOutputImportance="Low" />
- <Exec Command="$(_WasmEmcc) $(EmccLDFlags) --js-library $(_WasmSrcDir)/library_mono.js --js-library $(_WasmSrcDir)/binding_support.js --js-library $(_WasmSrcDir)/dotnet_support.js --js-library $(_WasmSrcDir)/pal_random.js @(_WasmAssemblies->'%(LlvmBitcodeFile)', ' ') @(_WasmObjects, ' ') -o dotnet.js" IgnoreStandardErrorWarningFormat="true" WorkingDirectory="$(WasmBuildDir)" StandardOutputImportance="Low" />
- <Exec Condition="'$(WasmNativeStrip)' == 'true'" Command="$(EMSDK_PATH)/upstream/bin/wasm-opt --strip-dwarf dotnet.wasm -o dotnet.wasm" IgnoreStandardErrorWarningFormat="true" WorkingDirectory="$(WasmBuildDir)" />
+ <Exec Command="bash -c '$(_EmccCommand) $(EmccCFlags) $(_WasmSrcDir)/driver.c -c -o driver.o'" IgnoreStandardErrorWarningFormat="true" WorkingDirectory="$(WasmBuildDir)" StandardOutputImportance="Low" />
+ <Exec Command="bash -c '$(_EmccCommand) $(EmccCFlags) $(_WasmSrcDir)/corebindings.c -c -o corebindings.o'" IgnoreStandardErrorWarningFormat="true" WorkingDirectory="$(WasmBuildDir)" StandardOutputImportance="Low" />
+ <Exec Command="bash -c '$(_EmccCommand) $(EmccCFlags) $(_WasmSrcDir)/pinvoke.c -c -o pinvoke.o'" IgnoreStandardErrorWarningFormat="true" WorkingDirectory="$(WasmBuildDir)" StandardOutputImportance="Low" />
+ <Exec Command="bash -c '$(_EmccCommand) $(EmccLDFlags) --js-library $(_WasmSrcDir)/library_mono.js --js-library $(_WasmSrcDir)/binding_support.js --js-library $(_WasmSrcDir)/dotnet_support.js --js-library $(_WasmSrcDir)/pal_random.js @(_WasmAssemblies->'%(LlvmBitcodeFile)', ' ') @(_WasmObjects, ' ') -o dotnet.js'" IgnoreStandardErrorWarningFormat="true" WorkingDirectory="$(WasmBuildDir)" StandardOutputImportance="Low" />
+ <Exec Condition="'$(WasmNativeStrip)' == 'true'" Command="bash -c '$(EMSDK_PATH)/upstream/bin/wasm-opt --strip-dwarf dotnet.wasm -o dotnet.wasm'" IgnoreStandardErrorWarningFormat="true" WorkingDirectory="$(WasmBuildDir)" />
</Target>
<Target Name="_GenerateRunV8Script">
<ItemGroup>
<DisabledProjects Include="$(TestRoot)*\**\cs_template.csproj" />
<DisabledProjects Include="$(TestRoot)Common\**\*.*proj" />
+ <DisabledProjects Include="$(TestRoot)FunctionalTests\**\*.csproj" /> <!-- They need to be isolated from the existing setup -->
<DisabledProjects Include="$(TestRoot)GC\Performance\Framework\GCPerfTestFramework.csproj" />
<DisabledProjects Include="$(TestRoot)Loader\classloader\generics\regressions\DD117522\Test.csproj" />
<DisabledProjects Include="$(TestRoot)Loader\classloader\generics\GenericMethods\VSW491668.csproj" /> <!-- issue 5501 -->
--- /dev/null
+TO-DO: add the test case for AOT mode when https://github.com/dotnet/runtime/pull/43535 has been completed.
\ No newline at end of file
--- /dev/null
+<Project Sdk="Microsoft.NET.Sdk">
+
+ <Import Project="..\..\common.props" />
+
+ <!-- Redirect 'dotnet publish' to in-tree runtime pack -->
+ <Target Name="TrickRuntimePackLocation" AfterTargets="ProcessFrameworkReferences">
+ <ItemGroup>
+ <RuntimePack>
+ <PackageDirectory>$(ArtifactsBinDir)microsoft.netcore.app.runtime.$(RuntimeIdentifier)\$(Configuration)</PackageDirectory>
+ </RuntimePack>
+ </ItemGroup>
+ <Message Text="Packaged ID: %(RuntimePack.PackageDirectory)" Importance="high" />
+ </Target>
+
+ <UsingTask TaskName="AndroidAppBuilderTask" AssemblyFile="$(AndroidAppBuilderTasksAssemblyPath)"/>
+
+ <Target Name="BuildApp" AfterTargets="CopyFilesToPublishDirectory">
+ <PropertyGroup>
+ <StripDebugSymbols>False</StripDebugSymbols>
+ <StripDebugSymbols Condition="'$(Configuration)' == 'Release'">True</StripDebugSymbols>
+ <AdbTool>$(ANDROID_SDK_ROOT)\platform-tools\adb</AdbTool>
+ <ApkDir>$(PublishDir)apk\</ApkDir>
+ </PropertyGroup>
+
+ <RemoveDir Directories="$(ApkDir)" />
+
+ <PropertyGroup>
+ <AndroidAbi Condition="'$(TargetArchitecture)' == 'arm64'">arm64-v8a</AndroidAbi>
+ <AndroidAbi Condition="'$(TargetArchitecture)' == 'arm'">armeabi-v7a</AndroidAbi>
+ <AndroidAbi Condition="'$(TargetArchitecture)' == 'x64'">x86_64</AndroidAbi>
+ <AndroidAbi Condition="'$(TargetArchitecture)' == 'x86'">x86</AndroidAbi>
+ </PropertyGroup>
+
+ <!-- TODO: delete once we switch to Android Crypto -->
+ <Copy Condition="'$(ANDROID_OPENSSL_AAR)' != ''"
+ SourceFiles="$(ANDROID_OPENSSL_AAR)\prefab\modules\crypto\libs\android.$(AndroidAbi)\libcrypto.so"
+ DestinationFolder="$(PublishDir)" SkipUnchangedFiles="true"/>
+ <Copy Condition="'$(ANDROID_OPENSSL_AAR)' != ''"
+ SourceFiles="$(ANDROID_OPENSSL_AAR)\prefab\modules\ssl\libs\android.$(AndroidAbi)\libssl.so"
+ DestinationFolder="$(PublishDir)" SkipUnchangedFiles="true"/>
+
+ <AndroidAppBuilderTask
+ RuntimeIdentifier="$(RuntimeIdentifier)"
+ SourceDir="$(PublishDir)"
+ ProjectName="Android.Emulator.Interpreter.Test"
+ ForceInterpreter="True"
+ MonoRuntimeHeaders="$(MicrosoftNetCoreAppRuntimePackDir)\native\include\mono-2.0"
+ MainLibraryFileName="Android.Emulator.Interpreter.Test.dll"
+ StripDebugSymbols="$(StripDebugSymbols)"
+ OutputDir="$(ApkDir)">
+ <Output TaskParameter="ApkBundlePath" PropertyName="ApkBundlePath" />
+ <Output TaskParameter="ApkPackageId" PropertyName="ApkPackageId" />
+ </AndroidAppBuilderTask>
+
+ <Message Importance="High" Text="Apk: $(ApkBundlePath)"/>
+ <Message Importance="High" Text="PackageId: $(ApkPackageId)"/>
+ </Target>
+
+ <ItemGroup>
+ <Compile Include="Program.cs" />
+ </ItemGroup>
+
+ <Target Name="CopySampleAppToHelixTestDir"
+ AfterTargets="Build"
+ DependsOnTargets="Publish;BuildApp" >
+ <PropertyGroup>
+ <OSPlatformConfig>$(TargetOS).AnyCPU.$(Configuration)</OSPlatformConfig>
+ <HelixArchiveRoot>$(ArtifactsDir)helix/</HelixArchiveRoot>
+ <HelixArchiveRunOnlyRoot>$(HelixArchiveRoot)runonly/</HelixArchiveRunOnlyRoot>
+ <HelixArchiveRunOnlyAppsDir>$(HelixArchiveRunOnlyRoot)$(OSPlatformConfig)/</HelixArchiveRunOnlyAppsDir>
+ </PropertyGroup>
+ <ItemGroup>
+ <_apkFiles Include="$(ApkBundlePath)" />
+ </ItemGroup>
+ <Copy SourceFiles="@(_apkFiles)"
+ DestinationFolder="$(HelixArchiveRunOnlyAppsDir)/%(RecursiveDir)" />
+
+ <Message Importance="High" Text="ApkBundlePath: $(ApkBundlePath)"/>
+ <Message Importance="High" Text="TestArchiveTestsDir: $(TestArchiveTestsDir)"/>
+ </Target>
+</Project>
--- /dev/null
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using System;
+
+public static class Program
+{
+ public static int Main(string[] args)
+ {
+ Console.WriteLine("Hello, Android!"); // logcat
+ return 42;
+ }
+}
--- /dev/null
+<Project>
+ <PropertyGroup>
+ <OutputType>Exe</OutputType>
+ <OutputPath>$(AssemblyBinDirOutputPath)</OutputPath>
+ <EnableDefaultCompileItems>false</EnableDefaultCompileItems>
+ <TargetFramework>$(NetCoreAppToolCurrent)</TargetFramework>
+ <EnableTargetingPackDownload>false</EnableTargetingPackDownload>
+ <RuntimeIdentifier>android-$(TargetArchitecture)</RuntimeIdentifier>
+ <PublishTrimmed>true</PublishTrimmed>
+ <TrimMode>Link</TrimMode>
+ <MicrosoftNetCoreAppRuntimePackDir>$(ArtifactsBinDir)microsoft.netcore.app.runtime.$(RuntimeIdentifier)\$(Configuration)\runtimes\android-$(TargetArchitecture)\</MicrosoftNetCoreAppRuntimePackDir>
+ </PropertyGroup>
+</Project>
\ No newline at end of file
--- /dev/null
+<Project>
+ <PropertyGroup>
+ <RunAnalyzers>false</RunAnalyzers>
+ <TreatWarningsAsErrors>false</TreatWarningsAsErrors>
+ <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
+ </PropertyGroup>
+
+ <Import Project="..\..\mono\Directory.Build.props" />
+</Project>
--- /dev/null
+<Project>
+ <Import Project="..\..\mono\Directory.Build.targets" />
+</Project>
\ No newline at end of file
--- /dev/null
+# Functional tests
+
+This directory contains the functional tests for the supported platforms.
+
+Currently the functional tests build is incorporated into the library tests build.
+
+The functional tests run in CI.
\ No newline at end of file
--- /dev/null
+// 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.Threading;
+using System.Threading.Tasks;
+using System.Runtime.InteropServices;
+
+// it's not part of the BCL but runtime needs it for native-to-managed callbacks in AOT
+// To be replaced with NativeCallableAttribute
+public class MonoPInvokeCallbackAttribute : Attribute
+{
+ public MonoPInvokeCallbackAttribute(Type delegateType) { }
+}
+
+public static class Program
+{
+ // Defined in main.m
+ [DllImport("__Internal")]
+ private extern static void ios_set_text(string value);
+
+ [DllImport("__Internal")]
+ private extern static void ios_register_button_click(Action action);
+
+ private static Action buttonClickHandler = null;
+
+ private static int counter = 0;
+
+ // Called by native code, see main.m
+ [MonoPInvokeCallback(typeof(Action))]
+ private static void OnButtonClick()
+ {
+ ios_set_text("OnButtonClick! #" + counter++);
+ }
+
+ public static async Task<int> Main(string[] args)
+ {
+ // Register a managed callback (will be called by UIButton, see main.m)
+ // Also, keep the handler alive so GC won't collect it.
+ ios_register_button_click(buttonClickHandler = OnButtonClick);
+
+ const string msg = "Hello World!\n.NET 5.0";
+ for (int i = 0; i < msg.Length; i++)
+ {
+ // a kind of an animation
+ ios_set_text(msg.Substring(0, i + 1));
+ await Task.Delay(100);
+ }
+
+ Console.WriteLine("Done!");
+ await Task.Delay(5000);
+ return 42;
+ }
+}
--- /dev/null
+# iOS functional test running on simulator in AOT mode
+
+Simulator: iPhone 11
+
--- /dev/null
+<Project Sdk="Microsoft.NET.Sdk">
+
+ <Import Project="..\..\common.props" />
+
+ <Import Project="$(RepoTasksDir)AotCompilerTask\MonoAOTCompiler.props" />
+ <UsingTask TaskName="AppleAppBuilderTask"
+ AssemblyFile="$(AppleAppBuilderTasksAssemblyPath)" />
+
+ <UsingTask TaskName="MonoAOTCompiler"
+ AssemblyFile="$(MonoAOTCompilerTasksAssemblyPath)" />
+
+ <Target Name="BuildAppBundle" AfterTargets="CopyFilesToPublishDirectory">
+ <PropertyGroup>
+ <AppDir>$(PublishDir)\app</AppDir>
+ <IosSimulator Condition="'$(TargetArchitecture)' == 'x64' or '$(TargetArchitecture)' == 'x86'">iPhone 11</IosSimulator>
+ <Optimized Condition="'$(Configuration)' == 'Release'">True</Optimized>
+ </PropertyGroup>
+
+ <RemoveDir Directories="$(AppDir)" />
+
+ <ItemGroup>
+ <AotInputAssemblies Include="$(PublishDir)\*.dll">
+ <AotArguments>@(MonoAOTCompilerDefaultAotArguments, ';')</AotArguments>
+ <ProcessArguments>@(MonoAOTCompilerDefaultProcessArguments, ';')</ProcessArguments>
+ </AotInputAssemblies>
+ </ItemGroup>
+
+ <Message Importance="High" Text="Output publish dir: $(PublishDir)"/>
+
+ <MonoAOTCompiler
+ CompilerBinaryPath="$(MicrosoftNetCoreAppRuntimePackDir)native\cross\mono-aot-cross"
+ Mode="Full"
+ OutputType="AsmOnly"
+ Assemblies="@(AotInputAssemblies)"
+ AotModulesTablePath="$(AppDir)\modules.m"
+ AotModulesTableLanguage="ObjC"
+ UseLLVM="True"
+ LLVMPath="$(MicrosoftNetCoreAppRuntimePackDir)native\cross">
+ <Output TaskParameter="CompiledAssemblies" ItemName="BundleAssemblies" />
+ </MonoAOTCompiler>
+
+ <AppleAppBuilderTask
+ TargetOS="$(TargetOS)"
+ Arch="$(TargetArchitecture)"
+ ProjectName="iOS.Simulator.Aot.Test"
+ MonoRuntimeHeaders="$(MicrosoftNetCoreAppRuntimePackDir)native\include\mono-2.0"
+ Assemblies="@(BundleAssemblies)"
+ MainLibraryFileName="iOS.Simulator.Aot.Test.dll"
+ GenerateXcodeProject="True"
+ BuildAppBundle="True"
+ DevTeamProvisioning="$(DevTeamProvisioning)"
+ OutputDirectory="$(AppDir)"
+ Optimized="$(Optimized)"
+ ForceAOT="True"
+ ForceInterpreter="$(MonoForceInterpreter)"
+ AppDir="$(PublishDir)">
+ <Output TaskParameter="AppBundlePath" PropertyName="AppBundlePath" />
+ <Output TaskParameter="XcodeProjectPath" PropertyName="XcodeProjectPath" />
+ </AppleAppBuilderTask>
+
+ <Message Importance="High" Text="Xcode: $(XcodeProjectPath)"/>
+ <Message Importance="High" Text="App: $(AppBundlePath)"/>
+ </Target>
+
+ <Import Project="..\..\common.targets" />
+</Project>
--- /dev/null
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+#import <UIKit/UIKit.h>
+#import "runtime.h"
+
+@interface ViewController : UIViewController
+@end
+
+@interface AppDelegate : UIResponder <UIApplicationDelegate>
+@property (strong, nonatomic) UIWindow *window;
+@property (strong, nonatomic) ViewController *controller;
+@end
+
+@implementation AppDelegate
+- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
+ self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
+ self.controller = [[ViewController alloc] initWithNibName:nil bundle:nil];
+ self.window.rootViewController = self.controller;
+ [self.window makeKeyAndVisible];
+ return YES;
+}
+@end
+
+UILabel *label;
+void (*clickHandlerPtr)(void);
+
+@implementation ViewController
+
+- (void)viewDidLoad {
+ [super viewDidLoad];
+
+ label = [[UILabel alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
+ label.textColor = [UIColor greenColor];
+ label.font = [UIFont boldSystemFontOfSize: 30];
+ label.numberOfLines = 2;
+ label.textAlignment = NSTextAlignmentCenter;
+ [self.view addSubview:label];
+
+ UIButton *button = [UIButton buttonWithType:UIButtonTypeInfoDark];
+ [button addTarget:self action:@selector(buttonClicked:) forControlEvents:UIControlEventTouchUpInside];
+ [button setFrame:CGRectMake(50, 300, 200, 50)];
+ [button setTitle:@"Click me" forState:UIControlStateNormal];
+ [button setExclusiveTouch:YES];
+ [self.view addSubview:button];
+
+ dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
+ mono_ios_runtime_init ();
+ });
+}
+-(void) buttonClicked:(UIButton*)sender
+{
+ if (clickHandlerPtr)
+ clickHandlerPtr();
+}
+
+@end
+
+// called from C# sample
+void
+ios_register_button_click (void* ptr)
+{
+ clickHandlerPtr = ptr;
+}
+
+// called from C# sample
+void
+ios_set_text (const char* value)
+{
+ NSString* nsstr = [NSString stringWithUTF8String:strdup(value)];
+ dispatch_async(dispatch_get_main_queue(), ^{
+ label.text = nsstr;
+ });
+}
+
+int main(int argc, char * argv[]) {
+ @autoreleasepool {
+ return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
+ }
+}
--- /dev/null
+// 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.Threading;
+using System.Threading.Tasks;
+using System.Runtime.InteropServices;
+
+// it's not part of the BCL but runtime needs it for native-to-managed callbacks in AOT
+// To be replaced with NativeCallableAttribute
+public class MonoPInvokeCallbackAttribute : Attribute
+{
+ public MonoPInvokeCallbackAttribute(Type delegateType) { }
+}
+
+public static class Program
+{
+ // Defined in main.m
+ [DllImport("__Internal")]
+ private extern static void ios_set_text(string value);
+
+ [DllImport("__Internal")]
+ private extern static void ios_register_button_click(Action action);
+
+ private static Action buttonClickHandler = null;
+
+ private static int counter = 0;
+
+ // Called by native code, see main.m
+ [MonoPInvokeCallback(typeof(Action))]
+ private static void OnButtonClick()
+ {
+ ios_set_text("OnButtonClick! #" + counter++);
+ }
+
+ public static async Task<int> Main(string[] args)
+ {
+ // Register a managed callback (will be called by UIButton, see main.m)
+ // Also, keep the handler alive so GC won't collect it.
+ ios_register_button_click(buttonClickHandler = OnButtonClick);
+
+ const string msg = "Hello World!\n.NET 5.0";
+ for (int i = 0; i < msg.Length; i++)
+ {
+ // a kind of an animation
+ ios_set_text(msg.Substring(0, i + 1));
+ await Task.Delay(100);
+ }
+
+ Console.WriteLine("Done!");
+ await Task.Delay(5000);
+ return 42;
+ }
+}
--- /dev/null
+# iOS functional test running on simulator in Interpreter mode
+
+Simulator: iPhone 11
--- /dev/null
+<Project Sdk="Microsoft.NET.Sdk">
+
+ <Import Project="..\..\common.props" />
+
+ <UsingTask TaskName="AppleAppBuilderTask"
+ AssemblyFile="$(AppleAppBuilderTasksAssemblyPath)" />
+
+ <Target Name="BuildAppBundle" AfterTargets="CopyFilesToPublishDirectory">
+ <PropertyGroup>
+ <AppDir>$(PublishDir)\app</AppDir>
+ <IosSimulator Condition="'$(TargetArchitecture)' == 'x64' or '$(TargetArchitecture)' == 'x86'">iPhone 11</IosSimulator>
+ <Optimized Condition="'$(Configuration)' == 'Release'">True</Optimized>
+ </PropertyGroup>
+
+ <RemoveDir Directories="$(AppDir)" />
+
+ <ItemGroup>
+ <BundleAssemblies Include="$(PublishDir)\*.dll" />
+ </ItemGroup>
+
+ <AppleAppBuilderTask
+ TargetOS="$(TargetOS)"
+ Arch="$(TargetArchitecture)"
+ ProjectName="iOS.Simulator.Interpreter.Test"
+ MonoRuntimeHeaders="$(MicrosoftNetCoreAppRuntimePackDir)native\include\mono-2.0"
+ Assemblies="@(BundleAssemblies)"
+ MainLibraryFileName="iOS.Simulator.Interpreter.Test.dll"
+ GenerateXcodeProject="True"
+ BuildAppBundle="True"
+ DevTeamProvisioning="$(DevTeamProvisioning)"
+ OutputDirectory="$(AppDir)"
+ Optimized="$(Optimized)"
+ ForceAOT="False"
+ ForceInterpreter="$(MonoForceInterpreter)"
+ AppDir="$(PublishDir)">
+ <Output TaskParameter="AppBundlePath" PropertyName="AppBundlePath" />
+ <Output TaskParameter="XcodeProjectPath" PropertyName="XcodeProjectPath" />
+ </AppleAppBuilderTask>
+
+ <Message Importance="High" Text="Xcode: $(XcodeProjectPath)"/>
+ <Message Importance="High" Text="App: $(AppBundlePath)"/>
+ </Target>
+
+ <Import Project="..\..\common.targets" />
+</Project>
--- /dev/null
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+#import <UIKit/UIKit.h>
+#import "runtime.h"
+
+@interface ViewController : UIViewController
+@end
+
+@interface AppDelegate : UIResponder <UIApplicationDelegate>
+@property (strong, nonatomic) UIWindow *window;
+@property (strong, nonatomic) ViewController *controller;
+@end
+
+@implementation AppDelegate
+- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
+ self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
+ self.controller = [[ViewController alloc] initWithNibName:nil bundle:nil];
+ self.window.rootViewController = self.controller;
+ [self.window makeKeyAndVisible];
+ return YES;
+}
+@end
+
+UILabel *label;
+void (*clickHandlerPtr)(void);
+
+@implementation ViewController
+
+- (void)viewDidLoad {
+ [super viewDidLoad];
+
+ label = [[UILabel alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
+ label.textColor = [UIColor greenColor];
+ label.font = [UIFont boldSystemFontOfSize: 30];
+ label.numberOfLines = 2;
+ label.textAlignment = NSTextAlignmentCenter;
+ [self.view addSubview:label];
+
+ UIButton *button = [UIButton buttonWithType:UIButtonTypeInfoDark];
+ [button addTarget:self action:@selector(buttonClicked:) forControlEvents:UIControlEventTouchUpInside];
+ [button setFrame:CGRectMake(50, 300, 200, 50)];
+ [button setTitle:@"Click me" forState:UIControlStateNormal];
+ [button setExclusiveTouch:YES];
+ [self.view addSubview:button];
+
+ dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
+ mono_ios_runtime_init ();
+ });
+}
+-(void) buttonClicked:(UIButton*)sender
+{
+ if (clickHandlerPtr)
+ clickHandlerPtr();
+}
+
+@end
+
+// called from C# sample
+void
+ios_register_button_click (void* ptr)
+{
+ clickHandlerPtr = ptr;
+}
+
+// called from C# sample
+void
+ios_set_text (const char* value)
+{
+ NSString* nsstr = [NSString stringWithUTF8String:strdup(value)];
+ dispatch_async(dispatch_get_main_queue(), ^{
+ label.text = nsstr;
+ });
+}
+
+int main(int argc, char * argv[]) {
+ @autoreleasepool {
+ return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
+ }
+}
--- /dev/null
+<Project>
+ <PropertyGroup>
+ <OutputType>Exe</OutputType>
+ <OutputPath>$(AssemblyBinDirOutputPath)</OutputPath>
+ <DebugType>Portable</DebugType>
+ <TargetFramework>$(NetCoreAppToolCurrent)</TargetFramework>
+ <TargetOS>iOS</TargetOS>
+ <MicrosoftNetCoreAppRuntimePackDir>$(ArtifactsBinDir)microsoft.netcore.app.runtime.ios-$(TargetArchitecture)\$(Configuration)\runtimes\ios-$(TargetArchitecture)\</MicrosoftNetCoreAppRuntimePackDir>
+ <EnableTargetingPackDownload>false</EnableTargetingPackDownload>
+ <RuntimeIdentifier>ios-$(TargetArchitecture)</RuntimeIdentifier>
+ <PublishTrimmed>true</PublishTrimmed>
+ <TrimMode>Link</TrimMode>
+ </PropertyGroup>
+</Project>
\ No newline at end of file
--- /dev/null
+<Project>
+
+ <!-- Redirect 'dotnet publish' to in-tree runtime pack -->
+ <Target Name="TrickRuntimePackLocation" AfterTargets="ProcessFrameworkReferences">
+ <ItemGroup>
+ <RuntimePack>
+ <PackageDirectory>$(ArtifactsBinDir)microsoft.netcore.app.runtime.ios-$(TargetArchitecture)\$(Configuration)</PackageDirectory>
+ </RuntimePack>
+ </ItemGroup>
+ <Message Text="Packaged ID: %(RuntimePack.PackageDirectory)" Importance="high" />
+ </Target>
+
+ <Target Name="CopySampleAppToHelixTestDir" AfterTargets="Build" DependsOnTargets="Publish;BuildAppBundle" >
+ <PropertyGroup>
+ <OSPlatformConfig>$(TargetOS).AnyCPU.$(Configuration)</OSPlatformConfig>
+ <HelixArchiveRoot>$(ArtifactsDir)helix/</HelixArchiveRoot>
+ <HelixArchiveRunOnlyRoot>$(HelixArchiveRoot)runonly/</HelixArchiveRunOnlyRoot>
+ <HelixArchiveRunOnlyAppsDir>$(HelixArchiveRunOnlyRoot)$(OSPlatformConfig)/</HelixArchiveRunOnlyAppsDir>
+ </PropertyGroup>
+ <ItemGroup>
+ <_appFiles Include="$(AppBundlePath)/../**/*" />
+ </ItemGroup>
+ <Copy SourceFiles="@(_appFiles)"
+ DestinationFolder="$(HelixArchiveRunOnlyAppsDir)/%(RecursiveDir)" />
+
+ <Message Importance="High" Text="HelixArchiveRunOnlyAppsDir: $(HelixArchiveRunOnlyAppsDir)"/>
+ </Target>
+
+</Project>
\ No newline at end of file
--- /dev/null
+// 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.Runtime.CompilerServices;
+
+namespace Sample
+{
+ public class Test
+ {
+ public static void Main(string[] args)
+ {
+ Console.WriteLine ("Hello, World!");
+ }
+
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ public static int TestMeaning()
+ {
+ return 42;
+ }
+ }
+}
--- /dev/null
+<Project Sdk="Microsoft.NET.Sdk">
+ <PropertyGroup>
+ <RunAOTCompilation>true</RunAOTCompilation>
+ <WasmModeSpecificPath>\aot\browser\</WasmModeSpecificPath>
+ </PropertyGroup>
+
+ <Import Project="..\..\common.props" />
+
+ <Target Name="PrepareForWasmBuild" BeforeTargets="WasmBuildApp">
+ <PropertyGroup>
+ <WasmAppDir>$(AppDir)</WasmAppDir>
+ <WasmBuildDir>$(PublishDir)</WasmBuildDir>
+ <WasmMainJSPath>runtime.js</WasmMainJSPath>
+ <WasmMainAssemblyPath>$(WasmBuildDir)$(AssemblyName).dll</WasmMainAssemblyPath>
+ </PropertyGroup>
+ <ItemGroup>
+ <WasmAssembliesToBundle Include="$(TargetDir)publish\*.dll" />
+ </ItemGroup>
+ </Target>
+
+ <Target Name="AfterWasmBuildApp" AfterTargets="WasmBuildApp">
+ <Copy SourceFiles="$(OutDir)\index.html" DestinationFolder="$(AppDir)" />
+ </Target>
+
+ <ItemGroup>
+ <Compile Include="Program.cs" />
+ <Content Include="index.html">
+ <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+ </Content>
+ </ItemGroup>
+
+ <Import Project="..\..\common.targets" />
+
+ <Import Project="$(MonoProjectRoot)\wasm\build\WasmApp.targets" />
+</Project>
--- /dev/null
+<!DOCTYPE html>
+<!-- Licensed to the .NET Foundation under one or more agreements. -->
+<!-- The .NET Foundation licenses this file to you under the MIT license. -->
+<html>
+ <head>
+ <title>TESTS</title>
+ <meta charset="UTF-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+ </head>
+ <body onload="onLoad()">
+ <h3 id="header">Wasm Browser Sample</h3>
+ Result from Sample.Test.TestMeaning: <span id="out"></span>
+ <script type='text/javascript'>
+ var is_testing = false;
+ var onLoad = function() {
+ var url = new URL(decodeURI(window.location));
+ let args = url.searchParams.getAll('arg');
+ is_testing = args !== undefined && (args.find(arg => arg == '--testing') !== undefined);
+ };
+
+ var test_exit = function(exit_code)
+ {
+ if (!is_testing) {
+ console.log(`test_exit: ${exitCode}`);
+ return;
+ }
+
+ /* Set result in a tests_done element, to be read by xharness */
+ var tests_done_elem = document.createElement("label");
+ tests_done_elem.id = "tests_done";
+ tests_done_elem.innerHTML = exit_code.toString();
+ document.body.appendChild(tests_done_elem);
+
+ console.log(`WASM EXIT ${exit_code}`);
+ };
+
+ var App = {
+ init: function () {
+ var ret = BINDING.call_static_method("[Wasm.Aot.Browser.Test] Sample.Test:TestMeaning", []);
+ document.getElementById("out").innerHTML = ret;
+
+ if (is_testing)
+ {
+ console.debug(`ret: ${ret}`);
+ let exit_code = ret == 42 ? 0 : 1;
+ test_exit(exit_code);
+ }
+ },
+ };
+ </script>
+ <script type="text/javascript" src="mono-config.js"></script>
+ <script type="text/javascript" src="runtime.js"></script>
+
+ <script defer src="dotnet.js"></script>
+
+ </body>
+</html>
\ No newline at end of file
--- /dev/null
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+var Module = {
+ onRuntimeInitialized: function () {
+ config.loaded_cb = function () {
+ try {
+ App.init ();
+ } catch (error) {
+ test_exit(1);
+ throw (error);
+ }
+ };
+ config.fetch_file_cb = function (asset) {
+ return fetch (asset, { credentials: 'same-origin' });
+ }
+
+ try
+ {
+ MONO.mono_load_runtime_and_bcl_args (config);
+ } catch (error) {
+ test_exit(1);
+ throw(error);
+ }
+ },
+};
--- /dev/null
+// 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.Threading.Tasks;
+
+public class Test
+{
+ public static async Task<int> Main(string[] args)
+ {
+ await Task.Delay(1);
+ Console.WriteLine("Hello World!");
+ for (int i = 0; i < args.Length; i++) {
+ Console.WriteLine($"args[{i}] = {args[i]}");
+ }
+ return args.Length;
+ }
+}
\ No newline at end of file
--- /dev/null
+<Project Sdk="Microsoft.NET.Sdk">
+ <PropertyGroup>
+ <RunAOTCompilation>true</RunAOTCompilation>
+ <WasmModeSpecificPath>\aot\console\</WasmModeSpecificPath>
+ </PropertyGroup>
+
+ <Import Project="..\..\common.props" />
+
+ <Target Name="PrepareForWasmBuild" BeforeTargets="WasmBuildApp">
+ <PropertyGroup>
+ <WasmAppDir>$(AppDir)</WasmAppDir>
+ <WasmBuildDir>$(PublishDir)</WasmBuildDir>
+ <WasmMainJSPath>$(MonoProjectRoot)\wasm\runtime-test.js</WasmMainJSPath>
+ <WasmMainAssemblyPath>$(WasmBuildDir)$(AssemblyName).dll</WasmMainAssemblyPath>
+ <WasmGenerateRunV8Script>true</WasmGenerateRunV8Script>
+ </PropertyGroup>
+ <ItemGroup>
+ <WasmAssembliesToBundle Include="$(TargetDir)publish\*.dll" />
+ </ItemGroup>
+ </Target>
+
+ <ItemGroup>
+ <Compile Include="Program.cs" />
+ </ItemGroup>
+
+ <Import Project="..\..\common.targets" />
+
+ <Import Project="$(MonoProjectRoot)\wasm\build\WasmApp.targets" />
+</Project>
--- /dev/null
+// 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.Runtime.CompilerServices;
+
+namespace Sample
+{
+ public class Test
+ {
+ public static void Main(string[] args)
+ {
+ Console.WriteLine ("Hello, World!");
+ }
+
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ public static int TestMeaning()
+ {
+ return 42;
+ }
+ }
+}
--- /dev/null
+<Project Sdk="Microsoft.NET.Sdk">
+ <PropertyGroup>
+ <RunAOTCompilation>false</RunAOTCompilation>
+ <WasmModeSpecificPath>\interpreter\browser\</WasmModeSpecificPath>
+ </PropertyGroup>
+
+ <Import Project="..\..\common.props" />
+
+ <Target Name="PrepareForWasmBuild" BeforeTargets="WasmBuildApp">
+ <PropertyGroup>
+ <WasmAppDir>$(AppDir)</WasmAppDir>
+ <WasmMainJSPath>runtime.js</WasmMainJSPath>
+ <WasmMainAssemblyPath>$(PublishDir)$(AssemblyName).dll</WasmMainAssemblyPath>
+ </PropertyGroup>
+ <ItemGroup>
+ <WasmAssembliesToBundle Include="$(TargetDir)publish\*.dll" />
+ </ItemGroup>
+ </Target>
+
+ <Target Name="AfterWasmBuildApp" AfterTargets="WasmBuildApp">
+ <Copy SourceFiles="$(OutDir)\index.html" DestinationFolder="$(AppDir)" />
+ </Target>
+
+ <ItemGroup>
+ <Compile Include="Program.cs" />
+ <Content Include="index.html">
+ <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+ </Content>
+ </ItemGroup>
+
+ <Import Project="..\..\common.targets" />
+
+ <Import Project="$(MonoProjectRoot)\wasm\build\WasmApp.targets" />
+</Project>
--- /dev/null
+<!DOCTYPE html>
+<!-- Licensed to the .NET Foundation under one or more agreements. -->
+<!-- The .NET Foundation licenses this file to you under the MIT license. -->
+<html>
+ <head>
+ <title>TESTS</title>
+ <meta charset="UTF-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+ </head>
+ <body onload="onLoad()">
+ <h3 id="header">Wasm Browser Sample</h3>
+ Result from Sample.Test.TestMeaning: <span id="out"></span>
+ <script type='text/javascript'>
+ var is_testing = false;
+ var onLoad = function() {
+ var url = new URL(decodeURI(window.location));
+ let args = url.searchParams.getAll('arg');
+ is_testing = args !== undefined && (args.find(arg => arg == '--testing') !== undefined);
+ };
+
+ var test_exit = function(exit_code)
+ {
+ if (!is_testing) {
+ console.log(`test_exit: ${exitCode}`);
+ return;
+ }
+
+ /* Set result in a tests_done element, to be read by xharness */
+ var tests_done_elem = document.createElement("label");
+ tests_done_elem.id = "tests_done";
+ tests_done_elem.innerHTML = exit_code.toString();
+ document.body.appendChild(tests_done_elem);
+
+ console.log(`WASM EXIT ${exit_code}`);
+ };
+
+ var App = {
+ init: function () {
+ var ret = BINDING.call_static_method("[Wasm.Interpreter.Browser.Test] Sample.Test:TestMeaning", []);
+ document.getElementById("out").innerHTML = ret;
+
+ if (is_testing)
+ {
+ console.debug(`ret: ${ret}`);
+ let exit_code = ret == 42 ? 0 : 1;
+ test_exit(exit_code);
+ }
+ },
+ };
+ </script>
+ <script type="text/javascript" src="mono-config.js"></script>
+ <script type="text/javascript" src="runtime.js"></script>
+
+ <script defer src="dotnet.js"></script>
+
+ </body>
+</html>
\ No newline at end of file
--- /dev/null
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+var Module = {
+ onRuntimeInitialized: function () {
+ config.loaded_cb = function () {
+ try {
+ App.init ();
+ } catch (error) {
+ test_exit(1);
+ throw (error);
+ }
+ };
+ config.fetch_file_cb = function (asset) {
+ return fetch (asset, { credentials: 'same-origin' });
+ }
+
+ try
+ {
+ MONO.mono_load_runtime_and_bcl_args (config);
+ } catch (error) {
+ test_exit(1);
+ throw(error);
+ }
+ },
+};
--- /dev/null
+// 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.Threading.Tasks;
+
+public class Test
+{
+ public static async Task<int> Main(string[] args)
+ {
+ await Task.Delay(1);
+ Console.WriteLine("Hello World!");
+ for (int i = 0; i < args.Length; i++) {
+ Console.WriteLine($"args[{i}] = {args[i]}");
+ }
+ return args.Length;
+ }
+}
\ No newline at end of file
--- /dev/null
+<Project Sdk="Microsoft.NET.Sdk">
+ <PropertyGroup>
+ <RunAOTCompilation>false</RunAOTCompilation>
+ <WasmModeSpecificPath>\interpreter\console\</WasmModeSpecificPath>
+ </PropertyGroup>
+
+ <Import Project="..\..\common.props" />
+
+ <Target Name="PrepareForWasmBuild" BeforeTargets="WasmBuildApp">
+ <PropertyGroup>
+ <WasmAppDir>$(AppDir)</WasmAppDir>
+ <WasmMainJSPath>$(MonoProjectRoot)\wasm\runtime-test.js</WasmMainJSPath>
+ <WasmMainAssemblyPath>$(PublishDir)$(AssemblyName).dll</WasmMainAssemblyPath>
+ <WasmGenerateRunV8Script>true</WasmGenerateRunV8Script>
+ </PropertyGroup>
+ <ItemGroup>
+ <WasmAssembliesToBundle Include="$(TargetDir)publish\*.dll" />
+ </ItemGroup>
+ </Target>
+
+ <ItemGroup>
+ <Compile Include="Program.cs" />
+ </ItemGroup>
+
+ <Import Project="..\..\common.targets" />
+
+ <Import Project="$(MonoProjectRoot)\wasm\build\WasmApp.targets" />
+</Project>
--- /dev/null
+<Project>
+ <PropertyGroup>
+ <OutputType>Exe</OutputType>
+ <OutputPath>$(RepoRoot)artifacts\bin\$(AssemblyName)</OutputPath>
+ <EnableDefaultCompileItems>false</EnableDefaultCompileItems>
+ <TargetFramework>$(NetCoreAppToolCurrent)</TargetFramework>
+ <RuntimeIdentifier>browser-wasm</RuntimeIdentifier>
+ <TargetArchitecture>wasm</TargetArchitecture>
+ <TargetOS>Browser</TargetOS>
+ <MicrosoftNetCoreAppRuntimePackRidDir>$(ArtifactsBinDir)microsoft.netcore.app.runtime.browser-wasm\$(Configuration)\runtimes\browser-wasm\</MicrosoftNetCoreAppRuntimePackRidDir>
+ <BuildDir>$(MSBuildThisFileDirectory)obj\$(Configuration)\wasm</BuildDir>
+ <AppDir>$(OutputPath)\$(Configuration)\AppBundle\</AppDir>
+ <PublishTrimmed>true</PublishTrimmed>
+ <TrimMode>link</TrimMode>
+ <EnableTargetingPackDownload>false</EnableTargetingPackDownload>
+ <RunAnalyzers>false</RunAnalyzers>
+ </PropertyGroup>
+
+ <PropertyGroup Condition="'$(Configuration)' != 'Debug'">
+ <!-- Runtime feature defaults to trim unnecessary code -->
+ <EventSourceSupport>false</EventSourceSupport>
+ <UseSystemResourceKeys>true</UseSystemResourceKeys>
+ <EnableUnsafeUTF7Encoding>false</EnableUnsafeUTF7Encoding>
+ <HttpActivityPropagationSupport>false</HttpActivityPropagationSupport>
+ <DebuggerSupport>false</DebuggerSupport>
+ </PropertyGroup>
+</Project>
\ No newline at end of file
--- /dev/null
+<Project>
+
+ <!-- Redirect 'dotnet publish' to in-tree runtime pack -->
+ <Target Name="TrickRuntimePackLocation" AfterTargets="ProcessFrameworkReferences">
+ <ItemGroup>
+ <RuntimePack>
+ <PackageDirectory>$(ArtifactsBinDir)microsoft.netcore.app.runtime.browser-wasm\$(Configuration)</PackageDirectory>
+ </RuntimePack>
+ </ItemGroup>
+ <Message Text="Packaged ID: %(RuntimePack.PackageDirectory)" Importance="high" />
+ </Target>
+
+ <Target Name="CopySampleAppToHelixTestDir" AfterTargets="Build" DependsOnTargets="Publish" >
+ <PropertyGroup>
+ <!-- Helix properties -->
+ <!-- AnyCPU as Platform-->
+ <OSPlatformConfig>$(TargetOS).AnyCPU.$(Configuration)</OSPlatformConfig>
+ <HelixArchiveRoot>$(ArtifactsDir)helix/</HelixArchiveRoot>
+ <HelixArchiveRunOnlyRoot>$(HelixArchiveRoot)runonly/</HelixArchiveRunOnlyRoot>
+ <HelixArchiveRunOnlyAppsDir>$(HelixArchiveRunOnlyRoot)$(OSPlatformConfig)$(WasmModeSpecificPath)/</HelixArchiveRunOnlyAppsDir>
+ <ZippedApp>$(OutputPath)$(AssemblyName).zip</ZippedApp>
+ </PropertyGroup>
+ <ZipDirectory SourceDirectory="$(AppDir)" DestinationFile="$(ZippedApp)" />
+ <Copy SourceFiles="$(ZippedApp)" DestinationFolder="$(HelixArchiveRunOnlyAppsDir)" />
+ </Target>
+
+</Project>
\ No newline at end of file