Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions eng/pipelines/mono/templates/workloads-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ jobs:
IntermediateArtifacts/MonoRuntimePacks/Shipping/Microsoft.NET.Runtime.MonoTargets.Sdk*.nupkg
IntermediateArtifacts/MonoRuntimePacks/Shipping/Microsoft.NET.Runtime.MonoAOTCompiler.Task*.nupkg
IntermediateArtifacts/MonoRuntimePacks/Shipping/Microsoft.NET.Runtime.WebAssembly.Sdk*.nupkg
IntermediateArtifacts/MonoRuntimePacks/Shipping/Microsoft.NET.Runtime.WebAssembly.Templates*.nupkg

- task: CopyFiles@2
displayName: Flatten packages
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
"description": ".NET WebAssembly build tools",
"packs": [
"Microsoft.NET.Runtime.WebAssembly.Sdk",
"Microsoft.NET.Runtime.WebAssembly.Templates",
"Microsoft.NETCore.App.Runtime.Mono.browser-wasm",
"Microsoft.NETCore.App.Runtime.AOT.Cross.browser-wasm"
],
Expand Down Expand Up @@ -140,6 +141,10 @@
"kind": "Sdk",
"version": "${PackageVersion}"
},
"Microsoft.NET.Runtime.WebAssembly.Templates": {
"kind": "template",
"version": "${PackageVersion}"
},
"Microsoft.NETCore.App.Runtime.Mono.android-arm": {
"kind": "framework",
"version": "${PackageVersion}"
Expand Down
1 change: 1 addition & 0 deletions src/mono/nuget/mono-packages.proj
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
<ProjectReference Include="Microsoft.NET.Runtime.wasm.Sample.Mono\Microsoft.NET.Runtime.wasm.Sample.Mono.pkgproj" />
<ProjectReference Include="Microsoft.NETCore.BrowserDebugHost.Transport\Microsoft.NETCore.BrowserDebugHost.Transport.pkgproj" />
<ProjectReference Include="Microsoft.NET.Runtime.WebAssembly.Sdk\Microsoft.NET.Runtime.WebAssembly.Sdk.pkgproj" />
<ProjectReference Include="..\wasm\templates\Microsoft.NET.Runtime.WebAssembly.Templates.csproj" />
</ItemGroup>

<ItemGroup Condition="'$(TargetOS)' == 'iOS' or '$(TargetOS)' == 'iOSSimulator'">
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<PackageType>Template</PackageType>
<PackageId>Microsoft.NET.Runtime.WebAssembly.Templates</PackageId>
<Title>WebAssembly Templates</Title>
<Authors>Microsoft</Authors>
<Description>Templates to create WebAssembly projects.</Description>
<PackageTags>dotnet-new;templates</PackageTags>

<TargetFramework>net6.0</TargetFramework>

<IncludeContentInPack>true</IncludeContentInPack>
<IncludeBuildOutput>false</IncludeBuildOutput>
<ContentTargetFolders>content</ContentTargetFolders>
<NoWarn>$(NoWarn);NU5128</NoWarn>
<IsPackable>true</IsPackable>
</PropertyGroup>

<ItemGroup>
<Content Include="templates\**\*" Exclude="templates\**\bin\**;templates\**\obj\**" />
<Compile Remove="**\*" />
</ItemGroup>

<Target Name="CreateManifestResourceNames" />
<Target Name="CoreCompile" />
<Target Name="_SetProductVersion" DependsOnTargets="GetProductVersions" BeforeTargets="Pack">
<PropertyGroup>
<PackageVersion>$(ProductVersion)</PackageVersion>
</PropertyGroup>
</Target>

</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"$schema": "http://json.schemastore.org/template",
"author": "Microsoft",
"classifications": [ "Web", "WebAssembly", "Browser" ],
"identity": "WebAssembly.Browser",
"name": "WebAssembly Browser App",
"shortName": "wasmbrowser",
"tags": {
"language": "C#",
"type": "project"
}
}
12 changes: 12 additions & 0 deletions src/mono/wasm/templates/templates/browser/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
using System;
using System.Runtime.CompilerServices;

Console.WriteLine ("Hello, Console!");

public class MyClass {
[MethodImpl(MethodImplOptions.NoInlining)]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we still need this NoInlining ?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess its purpose is to avoid inlining the method during AOT. Not sure whether anything changed recently in that area though. @lewing, do you know if we need it?

public static string CallMeFromJS()
{
return "Hello, World!";
}
}
17 changes: 17 additions & 0 deletions src/mono/wasm/templates/templates/browser/browser.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<TargetArchitecture>wasm</TargetArchitecture>
<TargetOS>Browser</TargetOS>
<RuntimeIdentifier>browser-wasm</RuntimeIdentifier>
<UseMonoRuntime>true</UseMonoRuntime>
<WasmMainJSPath>main.js</WasmMainJSPath>
<OutputType>Exe</OutputType>
<WasmEnableES6>yes</WasmEnableES6>
</PropertyGroup>

<ItemGroup>
<WasmExtraFilesToDeploy Include="index.html" />
<WasmExtraFilesToDeploy Include="main.js" />
</ItemGroup>
</Project>
19 changes: 19 additions & 0 deletions src/mono/wasm/templates/templates/browser/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<!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>Sample ES6</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="modulepreload" href="./main.js" />
<link rel="modulepreload" href="./dotnet.js" />
</head>

<body>
<span id="out"></span>
<script type='module' src="./main.js"></script>
</body>

</html>
13 changes: 13 additions & 0 deletions src/mono/wasm/templates/templates/browser/main.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import createDotnetRuntime from './dotnet.js'

try {
const { MONO, BINDING, Module, RuntimeBuildInfo } = await createDotnetRuntime();
const managedMethod = BINDING.bind_static_method("[browser] MyClass:CallMeFromJS");
const text = managedMethod();
document.getElementById("out").innerHTML = `${text}`;

await MONO.mono_run_main("browser.dll", []);
} catch (err) {
console.log(`WASM ERROR ${err}`);
document.getElementById("out").innerHTML = `error: ${err}`;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"$schema": "http://json.schemastore.org/template",
"author": "Microsoft",
"classifications": [ "Web", "WebAssembly", "Console" ],
"identity": "WebAssembly.Console",
"name": "WebAssembly Console App",
"shortName": "wasmconsole",
"tags": {
"language": "C#",
"type": "project"
}
}
18 changes: 18 additions & 0 deletions src/mono/wasm/templates/templates/console/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
using System;
using System.Threading.Tasks;

public class Test
{
public static async Task<int> Main(string[] args)
{
Console.WriteLine("Hello World!");

for (int i = 0; i < args.Length; i++) {
Console.WriteLine($"args[{i}] = {args[i]}");
}

await Task.Delay(0);

return 0;
}
}
16 changes: 16 additions & 0 deletions src/mono/wasm/templates/templates/console/console.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<TargetArchitecture>wasm</TargetArchitecture>
<TargetOS>Browser</TargetOS>
<RuntimeIdentifier>browser-wasm</RuntimeIdentifier>
<UseMonoRuntime>true</UseMonoRuntime>
<WasmMainJSPath>main.mjs</WasmMainJSPath>
<OutputType>Exe</OutputType>
<WasmEnableES6>yes</WasmEnableES6>
</PropertyGroup>

<ItemGroup>
<WasmExtraFilesToDeploy Include="package.json" />
</ItemGroup>
</Project>
19 changes: 19 additions & 0 deletions src/mono/wasm/templates/templates/console/main.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { createRequire } from 'module';
import { dirname } from 'path';
import { fileURLToPath } from 'url';
import createDotnetRuntime from './dotnet.js'

const { MONO } = await createDotnetRuntime(() => ({
imports: {
//TODO internalize into dotnet.js if possible
require: createRequire(import.meta.url)
},
//TODO internalize into dotnet.js if possible
scriptDirectory: dirname(fileURLToPath(import.meta.url)) + '/',
disableDotnet6Compatibility: true,
configSrc: "./mono-config.json",
}));

const app_args = process.argv.slice(2);
const dllName = "console.dll";
await MONO.mono_run_main_and_exit(dllName, app_args);
3 changes: 3 additions & 0 deletions src/mono/wasm/templates/templates/console/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"type":"module"
}
34 changes: 25 additions & 9 deletions src/tests/BuildWasmApps/Wasm.Build.Tests/BuildTestBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,8 @@ protected string RunAndTestWasmApp(BuildArgs buildArgs,
string? buildDir = null,
int expectedExitCode = 0,
string? args = null,
Dictionary<string, string>? envVars = null)
Dictionary<string, string>? envVars = null,
string targetFramework = "net6.0")
{
buildDir ??= _projectDir;
envVars ??= new();
Expand All @@ -144,7 +145,7 @@ protected string RunAndTestWasmApp(BuildArgs buildArgs,
envVars[kvp.Key] = kvp.Value;
}

string bundleDir = Path.Combine(GetBinDir(baseDir: buildDir, config: buildArgs.Config), "AppBundle");
string bundleDir = Path.Combine(GetBinDir(baseDir: buildDir, config: buildArgs.Config, targetFramework: targetFramework), "AppBundle");
(string testCommand, string extraXHarnessArgs) = host switch
{
RunHost.V8 => ("wasm test", "--js-file=test-main.js --engine=V8 -v trace"),
Expand Down Expand Up @@ -341,8 +342,8 @@ protected static BuildArgs ExpandBuildArgs(BuildArgs buildArgs, string extraProp

if (options.ExpectSuccess)
{
string bundleDir = Path.Combine(GetBinDir(config: buildArgs.Config), "AppBundle");
AssertBasicAppBundle(bundleDir, buildArgs.ProjectName, buildArgs.Config, options.HasIcudt, options.DotnetWasmFromRuntimePack ?? !buildArgs.AOT);
string bundleDir = Path.Combine(GetBinDir(config: buildArgs.Config, targetFramework: options.TargetFramework ?? "net6.0"), "AppBundle");
AssertBasicAppBundle(bundleDir, buildArgs.ProjectName, buildArgs.Config, options.MainJS ?? "test-main.js", options.HasV8Script, options.HasIcudt, options.DotnetWasmFromRuntimePack ?? !buildArgs.AOT);
}

if (options.UseCache)
Expand Down Expand Up @@ -371,6 +372,18 @@ public void InitBlazorWasmProjectDir(string id)
File.Copy(Path.Combine(BuildEnvironment.TestDataPath, "Blazor.Directory.Build.targets"), Path.Combine(_projectDir, "Directory.Build.targets"));
}

public string CreateWasmTemplateProject(string id, string template = "wasmbrowser")
{
InitPaths(id);
InitProjectDir(id);
new DotNetCommand(s_buildEnv, useDefaultArgs: false)
.WithWorkingDirectory(_projectDir!)
.ExecuteWithCapturedOutput($"new {template}")
.EnsureSuccessful();

return Path.Combine(_projectDir!, $"{id}.csproj");
}

public string CreateBlazorWasmTemplateProject(string id)
{
InitBlazorWasmProjectDir(id);
Expand Down Expand Up @@ -476,19 +489,19 @@ static void AssertRuntimePackPath(string buildOutput)
throw new XunitException($"Runtime pack path doesn't match.{Environment.NewLine}Expected: {s_buildEnv.RuntimePackDir}{Environment.NewLine}Actual: {actualPath}");
}

protected static void AssertBasicAppBundle(string bundleDir, string projectName, string config, bool hasIcudt=true, bool dotnetWasmFromRuntimePack=true)
protected static void AssertBasicAppBundle(string bundleDir, string projectName, string config, string mainJS, bool hasV8Script, bool hasIcudt=true, bool dotnetWasmFromRuntimePack=true)
{
AssertFilesExist(bundleDir, new []
{
"index.html",
"test-main.js",
mainJS,
"dotnet.timezones.blat",
"dotnet.wasm",
"mono-config.json",
"dotnet.js",
"run-v8.sh"
"dotnet.js"
});

AssertFilesExist(bundleDir, new[] { "run-v8.sh" }, expectToExist: hasV8Script);
AssertFilesExist(bundleDir, new[] { "icudt.dat" }, expectToExist: hasIcudt);

string managedDir = Path.Combine(bundleDir, "managed");
Expand Down Expand Up @@ -866,7 +879,10 @@ public record BuildProjectOptions
bool CreateProject = true,
bool Publish = true,
bool BuildOnlyAfterPublish = true,
bool HasV8Script = true,
string? Verbosity = null,
string? Label = null
string? Label = null,
string? TargetFramework = null,
string? MainJS = null
);
}
Loading