This commit is contained in:
Jérôme Laban 2018-04-17 15:53:43 -04:00
Коммит cfe0f04ade
31 изменённых файлов: 2215 добавлений и 0 удалений

33
.appveyor.yml Normal file
Просмотреть файл

@ -0,0 +1,33 @@
image: Visual Studio 2017
branches:
only:
- master
- stable
# Don't create a build when a PR is opened
skip_branch_with_pr: true
nuget:
disable_publish_on_pr: true
skip_commits:
files:
- 'doc/**/*.*'
init:
- ps: git config --global core.autocrlf true
build_script:
- cmd: git submodule update --init --recursive
- ps: .\build\build.ps1 -script build\build.cake
artifacts:
- path: .\build\nuget\*.nupkg
deploy:
provider: NuGet
api_key:
secure: q2moGyPXNP7agMjH6aHxbg8a9Q4ftB/al9aZPYL97Fdte0cZ+d1ak0yoBFc1eWNr
skip_symbols: true
artifact: /.*\.nupkg/

63
.gitattributes поставляемый Normal file
Просмотреть файл

@ -0,0 +1,63 @@
###############################################################################
# Set default behavior to automatically normalize line endings.
###############################################################################
* text=auto
###############################################################################
# Set default behavior for command prompt diff.
#
# This is need for earlier builds of msysgit that does not have it on by
# default for csharp files.
# Note: This is only used by command line
###############################################################################
#*.cs diff=csharp
###############################################################################
# Set the merge driver for project and solution files
#
# Merging from the command prompt will add diff markers to the files if there
# are conflicts (Merging from VS is not affected by the settings below, in VS
# the diff markers are never inserted). Diff markers may cause the following
# file extensions to fail to load in VS. An alternative would be to treat
# these files as binary and thus will always conflict and require user
# intervention with every merge. To do so, just uncomment the entries below
###############################################################################
#*.sln merge=binary
#*.csproj merge=binary
#*.vbproj merge=binary
#*.vcxproj merge=binary
#*.vcproj merge=binary
#*.dbproj merge=binary
#*.fsproj merge=binary
#*.lsproj merge=binary
#*.wixproj merge=binary
#*.modelproj merge=binary
#*.sqlproj merge=binary
#*.wwaproj merge=binary
###############################################################################
# behavior for image files
#
# image files are treated as binary by default.
###############################################################################
#*.jpg binary
#*.png binary
#*.gif binary
###############################################################################
# diff behavior for common document formats
#
# Convert binary document formats to text before diffing them. This feature
# is only available from the command line. Turn it on by uncommenting the
# entries below.
###############################################################################
#*.doc diff=astextplain
#*.DOC diff=astextplain
#*.docx diff=astextplain
#*.DOCX diff=astextplain
#*.dot diff=astextplain
#*.DOT diff=astextplain
#*.pdf diff=astextplain
#*.PDF diff=astextplain
#*.rtf diff=astextplain
#*.RTF diff=astextplain

247
.gitignore поставляемый Normal file
Просмотреть файл

@ -0,0 +1,247 @@
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
# User-specific files
*.suo
*.user
*.userosscache
*.sln.docstates
# User-specific files (MonoDevelop/Xamarin Studio)
*.userprefs
# Build results
[Dd]ebug/
[Dd]ebugPublic/
[Rr]elease/
[Rr]eleases/
[Xx]64/
[Xx]86/
bld/
[Bb]in/
[Oo]bj/
[Gg]enerated[Ff]iles/
# Visual Studio 2015 cache/options directory
.vs/
# Uncomment if you have tasks that create the project's static files in wwwroot
#wwwroot/
# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*
# NUNIT
*.VisualState.xml
TestResult.xml
# Build Results of an ATL Project
[Dd]ebugPS/
[Rr]eleasePS/
dlldata.c
# DNX
project.lock.json
artifacts/
*_i.c
*_p.c
*_i.h
*.ilk
*.meta
*.obj
*.pch
*.pdb
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.tmp_proj
*.log
*.vspscc
*.vssscc
.builds
*.pidb
*.svclog
*.scc
# Chutzpah Test files
_Chutzpah*
# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opendb
*.opensdf
*.sdf
*.cachefile
*.VC.db
# Visual Studio profiler
*.psess
*.vsp
*.vspx
*.sap
# TFS 2012 Local Workspace
$tf/
# Guidance Automation Toolkit
*.gpState
# ReSharper is a .NET coding add-in
_ReSharper*/
*.[Rr]e[Ss]harper
*.DotSettings.user
# JustCode is a .NET coding add-in
.JustCode
# TeamCity is a build add-in
_TeamCity*
# DotCover is a Code Coverage Tool
*.dotCover
# NCrunch
_NCrunch_*
.*crunch*.local.xml
nCrunchTemp_*
# MightyMoose
*.mm.*
AutoTest.Net/
# Web workbench (sass)
.sass-cache/
# Installshield output folder
[Ee]xpress/
# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help/*.HxT
DocProject/Help/*.HxC
DocProject/Help/*.hhc
DocProject/Help/*.hhk
DocProject/Help/*.hhp
DocProject/Help/Html2
DocProject/Help/html
# Click-Once directory
publish/
# Publish Web Output
*.[Pp]ublish.xml
*.azurePubxml
# TODO: Un-comment the next line if you do not want to checkin
# your web deploy settings because they may include unencrypted
# passwords
#*.pubxml
*.publishproj
# NuGet Packages
*.nupkg
# The packages folder can be ignored because of Package Restore
**/packages/*
# except build/, which is used as an MSBuild target.
!**/packages/build/
# Uncomment if necessary however generally it will be regenerated when needed
#!**/packages/repositories.config
# NuGet v3's project.json files produces more ignoreable files
*.nuget.props
*.nuget.targets
# Microsoft Azure Build Output
csx/
*.build.csdef
# Microsoft Azure Emulator
ecf/
rcf/
# Microsoft Azure ApplicationInsights config file
ApplicationInsights.config
# Windows Store app package directory
AppPackages/
BundleArtifacts/
# Visual Studio cache files
# files ending in .cache can be ignored
*.[Cc]ache
# but keep track of directories ending in .cache
!*.[Cc]ache/
# Others
ClientBin/
[Ss]tyle[Cc]op.*
~$*
*~
*.dbmdl
*.dbproj.schemaview
*.pfx
*.publishsettings
node_modules/
orleans.codegen.cs
# RIA/Silverlight projects
Generated_Code/
# Backup & report files from converting an old project file
# to a newer Visual Studio version. Backup files are not needed,
# because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
UpgradeLog*.htm
# SQL Server files
*.mdf
*.ldf
# Business Intelligence projects
*.rdl.data
*.bim.layout
*.bim_*.settings
# Microsoft Fakes
FakesAssemblies/
# GhostDoc plugin setting file
*.GhostDoc.xml
# Node.js Tools for Visual Studio
.ntvs_analysis.dat
# Visual Studio 6 build log
*.plg
# Visual Studio 6 workspace options file
*.opt
# Visual Studio LightSwitch build output
**/*.HTMLClient/GeneratedArtifacts
**/*.DesktopClient/GeneratedArtifacts
**/*.DesktopClient/ModelManifest.xml
**/*.Server/GeneratedArtifacts
**/*.Server/ModelManifest.xml
_Pvt_Extensions
# LightSwitch generated files
GeneratedArtifacts/
ModelManifest.xml
# Paket dependency manager
.paket/paket.exe
# FAKE - F# Make
.fake/
build/tools/**
!build/tools/packages.config

3
.gitmodules поставляемый Normal file
Просмотреть файл

@ -0,0 +1,3 @@
[submodule "src/Uno.Wasm.Bootstrap/linker"]
path = src/Uno.Wasm.Bootstrap/linker
url = https://github.com/mono/linker.git

209
License.md Normal file
Просмотреть файл

@ -0,0 +1,209 @@
# Uno.Roslyn
Copyright (c) nventive
All rights reserved.
# Apache 2.0 License
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

67
Readme.md Normal file
Просмотреть файл

@ -0,0 +1,67 @@
# Uno.Wasm.Bootstrap
Uno.Wasm.Bootstrap provides a simple way to package a C# .NET Standard 2.0 library, and run it from a compatible browser environment.
It is a standalone Mono Web Assembly (WASM) sdk bootstrapper taking the form of a nuget package.
Installing it on a .NET Standard 2.0 library with an entry point allows to publish it as part of a WASM distribution folder, along with CSS, Javascript and content files.
This package only provides the bootstrapping features to run a .NET assembly and write to the javascript console, through `Console.WriteLine`.
This package is based on the excellent work from @praeclarum's [OOui Wasm MSBuild task](https://github.com/praeclarum/Ooui).
## How to use the package
* Create a .NET Standard 2.0 library, with the following basic definition:
```xml
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netstandard2.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Uno.Wasm.Bootstrapp" Version="1.0.0-dev.16" />
</ItemGroup>
</Project>
```
* Add a main entry point:
```csharp
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Hello from C#!");
}
}
```
* Build the project, the WASM output will be located in `bin\Debug\netstandard2.0\dist`.
* Run the `server.py`, which will open an HTTP server on http://localhost:8000. On Windows, use Python tools or the excellent Linux Subsystem.
* The output of the Console.WriteLine will appear in the javascript debugging console
## Features
### Support for additional JS files
Providing additional JS files is done through the inclusion of `EmbeddedResource` msbuild item files, in a project folder named `WasmScripts`.
Files are processed as embedded resources to allow for libraries to provide javascript files.
### Support for additional CSS files
Additional CSS files are supported through the inclusion of `EmbeddedResource` msbuild item files, in a project folder named `WasmCSS`.
### Support for additional Content files
Additional CSS files are supported through the inclusion of `Content` files. The folder structure is preserved in the output `dist` folder.
### Linker configuration
The linker may be configured via the inclusion of `LinkerDescriptors` msbuild item files.
The file format of the descriptor can [be found here](https://github.com/mono/linker/tree/master/linker#syntax-of-xml-descriptor).
### Configuration of the runtime
- The msbuild property `RuntimeDebugLogging` can be set to `true` to allow for mono to output additional debugging details.
- The msbuild property `RuntimeConfiguration` allows for the selection of the debug runtime, but is mainly used for debugging the runtime itself. The value can either be `release` or `debug`.
## TODO
Lots!
- The main missing part is the ability to change the index.html, but it should pretty easy to add.
- The other one is the ability to use an actual release of the mono-wasm release.

24
build/AssemblyVersion.cs Normal file
Просмотреть файл

@ -0,0 +1,24 @@
// ******************************************************************
// Copyright <20> 2015-2018 nventive inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// ******************************************************************
[assembly: System.Reflection.AssemblyVersion("1.0.0.0")]
[assembly: System.Reflection.AssemblyFileVersion("1.0.8888")]
[assembly: System.Reflection.AssemblyInformationalVersion("1.0.8888 - ")]
[assembly: System.Reflection.AssemblyProduct("Uno.Wasm.ShellBase")]
[assembly: System.Reflection.AssemblyCompany("nventive")]
[assembly: System.Reflection.AssemblyCopyright("Copyright (C) nVentive 2011-2018")]

3
build/UpdateHeaders.cmd Normal file
Просмотреть файл

@ -0,0 +1,3 @@
@ECHO OFF
PowerShell.exe -file build.ps1 -target=UpdateHeaders -Verbosity Verbose
PAUSE

151
build/build.cake Normal file
Просмотреть файл

@ -0,0 +1,151 @@
#addin "nuget:?package=Cake.FileHelpers"
#addin "nuget:?package=Cake.Powershell"
#tool "nuget:?package=GitVersion.CommandLine"
using System;
using System.Linq;
using System.Text.RegularExpressions;
//////////////////////////////////////////////////////////////////////
// ARGUMENTS
//////////////////////////////////////////////////////////////////////
var target = Argument("target", "Default");
//////////////////////////////////////////////////////////////////////
// VERSIONS
//////////////////////////////////////////////////////////////////////
var gitVersioningVersion = "2.0.41";
var signClientVersion = "0.9.0";
//////////////////////////////////////////////////////////////////////
// VARIABLES
//////////////////////////////////////////////////////////////////////
var baseDir = MakeAbsolute(Directory("../")).ToString();
var buildDir = baseDir + "/build";
var Solution = baseDir + "/src/Uno.Wasm.Bootstrap.sln";
var toolsDir = buildDir + "/tools";
GitVersion versionInfo = null;
//////////////////////////////////////////////////////////////////////
// METHODS
//////////////////////////////////////////////////////////////////////
void VerifyHeaders(bool Replace)
{
var header = FileReadText("header.txt") + "\r\n";
bool hasMissing = false;
Func<IFileSystemInfo, bool> exclude_objDir =
fileSystemInfo => !fileSystemInfo.Path.Segments.Contains("obj");
var files = GetFiles(baseDir + "/**/*.cs", exclude_objDir).Where(file =>
{
var path = file.ToString();
return !(path.EndsWith(".g.cs") || path.EndsWith(".i.cs") || System.IO.Path.GetFileName(path).Contains("TemporaryGeneratedFile"));
});
Information("\nChecking " + files.Count() + " file header(s)");
foreach(var file in files)
{
var oldContent = FileReadText(file);
if(oldContent.Contains("// <auto-generated>"))
{
continue;
}
var rgx = new Regex("^(//.*\r?\n|\r?\n)*");
var newContent = header + rgx.Replace(oldContent, "");
if(!newContent.Equals(oldContent, StringComparison.Ordinal))
{
if(Replace)
{
Information("\nUpdating " + file + " header...");
FileWriteText(file, newContent);
}
else
{
Error("\nWrong/missing header on " + file);
hasMissing = true;
}
}
}
if(!Replace && hasMissing)
{
throw new Exception("Please run UpdateHeaders.bat or '.\\build.ps1 -target=UpdateHeaders' and commit the changes.");
}
}
//////////////////////////////////////////////////////////////////////
// DEFAULT TASK
//////////////////////////////////////////////////////////////////////
Task("Build")
.IsDependentOn("Version")
.Description("Build all projects and get the assemblies")
.Does(() =>
{
Information("\nBuilding Solution");
var buildSettings = new MSBuildSettings
{
MaxCpuCount = 1
}
.SetConfiguration("Release")
.WithProperty("PackageVersion", versionInfo.FullSemVer)
.WithProperty("InformationalVersion", versionInfo.InformationalVersion)
.WithProperty("PackageOutputPath", System.IO.Path.Combine(buildDir, "nuget"))
.WithTarget("Restore")
.WithTarget("Build")
.WithTarget("Pack");
MSBuild(Solution, buildSettings);
});
//////////////////////////////////////////////////////////////////////
// TASK TARGETS
//////////////////////////////////////////////////////////////////////
Task("Default")
.IsDependentOn("Build");
Task("UpdateHeaders")
.Description("Updates the headers in *.cs files")
.Does(() =>
{
VerifyHeaders(true);
});
Task("Version")
.Description("Updates target versions")
.Does(() =>
{
versionInfo = GitVersion(new GitVersionSettings {
UpdateAssemblyInfo = true,
UpdateAssemblyInfoFilePath = baseDir + "/build/AssemblyVersion.cs"
});
Information($"FullSemVer: {versionInfo.FullSemVer} Sha: {versionInfo.Sha}");
var files = new[] {
@"..\src\Uno.Wasm.Bootstrap\Uno.Wasm.Bootstrap.csproj",
@"..\src\Uno.Wasm.Bootstrap\ShellTask.cs",
@"..\src\Uno.Wasm.Bootstrap\build\Uno.Wasm.Bootstrap.targets"
};
foreach(var file in files)
{
var text = System.IO.File.ReadAllText(file);
System.IO.File.WriteAllText(file, text.Replace("v0", "v" + versionInfo.Sha));
}
});
//////////////////////////////////////////////////////////////////////
// EXECUTION
//////////////////////////////////////////////////////////////////////
RunTarget(target);

235
build/build.ps1 Normal file
Просмотреть файл

@ -0,0 +1,235 @@
##########################################################################
# This is the Cake bootstrapper script for PowerShell.
# This file was downloaded from https://github.com/cake-build/resources
# Feel free to change this file to fit your needs.
##########################################################################
<#
.SYNOPSIS
This is a Powershell script to bootstrap a Cake build.
.DESCRIPTION
This Powershell script will download NuGet if missing, restore NuGet tools (including Cake)
and execute your Cake build script with the parameters you provide.
.PARAMETER Script
The build script to execute.
.PARAMETER Target
The build script target to run.
.PARAMETER Configuration
The build configuration to use.
.PARAMETER Verbosity
Specifies the amount of information to be displayed.
.PARAMETER ShowDescription
Shows description about tasks.
.PARAMETER DryRun
Performs a dry run.
.PARAMETER Experimental
Uses the nightly builds of the Roslyn script engine.
.PARAMETER Mono
Uses the Mono Compiler rather than the Roslyn script engine.
.PARAMETER SkipToolPackageRestore
Skips restoring of packages.
.PARAMETER ScriptArgs
Remaining arguments are added here.
.LINK
https://cakebuild.net
#>
[CmdletBinding()]
Param(
[string]$Script = "build.cake",
[string]$Target,
[string]$Configuration,
[ValidateSet("Quiet", "Minimal", "Normal", "Verbose", "Diagnostic")]
[string]$Verbosity,
[switch]$ShowDescription,
[Alias("WhatIf", "Noop")]
[switch]$DryRun,
[switch]$Experimental,
[switch]$Mono,
[switch]$SkipToolPackageRestore,
[Parameter(Position=0,Mandatory=$false,ValueFromRemainingArguments=$true)]
[string[]]$ScriptArgs
)
[Reflection.Assembly]::LoadWithPartialName("System.Security") | Out-Null
function MD5HashFile([string] $filePath)
{
if ([string]::IsNullOrEmpty($filePath) -or !(Test-Path $filePath -PathType Leaf))
{
return $null
}
[System.IO.Stream] $file = $null;
[System.Security.Cryptography.MD5] $md5 = $null;
try
{
$md5 = [System.Security.Cryptography.MD5]::Create()
$file = [System.IO.File]::OpenRead($filePath)
return [System.BitConverter]::ToString($md5.ComputeHash($file))
}
finally
{
if ($file -ne $null)
{
$file.Dispose()
}
}
}
function GetProxyEnabledWebClient
{
$wc = New-Object System.Net.WebClient
$proxy = [System.Net.WebRequest]::GetSystemWebProxy()
$proxy.Credentials = [System.Net.CredentialCache]::DefaultCredentials
$wc.Proxy = $proxy
return $wc
}
Write-Host "Preparing to run build script..."
if(!$PSScriptRoot){
$PSScriptRoot = Split-Path $MyInvocation.MyCommand.Path -Parent
}
$TOOLS_DIR = Join-Path $PSScriptRoot "tools"
$ADDINS_DIR = Join-Path $TOOLS_DIR "Addins"
$MODULES_DIR = Join-Path $TOOLS_DIR "Modules"
$NUGET_EXE = Join-Path $TOOLS_DIR "nuget.exe"
$CAKE_EXE = Join-Path $TOOLS_DIR "Cake/Cake.exe"
$NUGET_URL = "https://dist.nuget.org/win-x86-commandline/latest/nuget.exe"
$PACKAGES_CONFIG = Join-Path $TOOLS_DIR "packages.config"
$PACKAGES_CONFIG_MD5 = Join-Path $TOOLS_DIR "packages.config.md5sum"
$ADDINS_PACKAGES_CONFIG = Join-Path $ADDINS_DIR "packages.config"
$MODULES_PACKAGES_CONFIG = Join-Path $MODULES_DIR "packages.config"
# Make sure tools folder exists
if ((Test-Path $PSScriptRoot) -and !(Test-Path $TOOLS_DIR)) {
Write-Verbose -Message "Creating tools directory..."
New-Item -Path $TOOLS_DIR -Type directory | out-null
}
# Make sure that packages.config exist.
if (!(Test-Path $PACKAGES_CONFIG)) {
Write-Verbose -Message "Downloading packages.config..."
try {
$wc = GetProxyEnabledWebClient
$wc.DownloadFile("https://cakebuild.net/download/bootstrapper/packages", $PACKAGES_CONFIG) } catch {
Throw "Could not download packages.config."
}
}
# Try find NuGet.exe in path if not exists
if (!(Test-Path $NUGET_EXE)) {
Write-Verbose -Message "Trying to find nuget.exe in PATH..."
$existingPaths = $Env:Path -Split ';' | Where-Object { (![string]::IsNullOrEmpty($_)) -and (Test-Path $_ -PathType Container) }
$NUGET_EXE_IN_PATH = Get-ChildItem -Path $existingPaths -Filter "nuget.exe" | Select -First 1
if ($NUGET_EXE_IN_PATH -ne $null -and (Test-Path $NUGET_EXE_IN_PATH.FullName)) {
Write-Verbose -Message "Found in PATH at $($NUGET_EXE_IN_PATH.FullName)."
$NUGET_EXE = $NUGET_EXE_IN_PATH.FullName
}
}
# Try download NuGet.exe if not exists
if (!(Test-Path $NUGET_EXE)) {
Write-Verbose -Message "Downloading NuGet.exe..."
try {
$wc = GetProxyEnabledWebClient
$wc.DownloadFile($NUGET_URL, $NUGET_EXE)
} catch {
Throw "Could not download NuGet.exe."
}
}
# Save nuget.exe path to environment to be available to child processed
$ENV:NUGET_EXE = $NUGET_EXE
# Restore tools from NuGet?
if(-Not $SkipToolPackageRestore.IsPresent) {
Push-Location
Set-Location $TOOLS_DIR
# Check for changes in packages.config and remove installed tools if true.
[string] $md5Hash = MD5HashFile($PACKAGES_CONFIG)
if((!(Test-Path $PACKAGES_CONFIG_MD5)) -Or
($md5Hash -ne (Get-Content $PACKAGES_CONFIG_MD5 ))) {
Write-Verbose -Message "Missing or changed package.config hash..."
Get-ChildItem -Exclude packages.config,nuget.exe,Cake.Bakery |
Remove-Item -Recurse
}
Write-Verbose -Message "Restoring tools from NuGet..."
$NuGetOutput = Invoke-Expression "&`"$NUGET_EXE`" install -ExcludeVersion -OutputDirectory `"$TOOLS_DIR`""
if ($LASTEXITCODE -ne 0) {
Throw "An error occurred while restoring NuGet tools."
}
else
{
$md5Hash | Out-File $PACKAGES_CONFIG_MD5 -Encoding "ASCII"
}
Write-Verbose -Message ($NuGetOutput | out-string)
Pop-Location
}
# Restore addins from NuGet
if (Test-Path $ADDINS_PACKAGES_CONFIG) {
Push-Location
Set-Location $ADDINS_DIR
Write-Verbose -Message "Restoring addins from NuGet..."
$NuGetOutput = Invoke-Expression "&`"$NUGET_EXE`" install -ExcludeVersion -OutputDirectory `"$ADDINS_DIR`""
if ($LASTEXITCODE -ne 0) {
Throw "An error occurred while restoring NuGet addins."
}
Write-Verbose -Message ($NuGetOutput | out-string)
Pop-Location
}
# Restore modules from NuGet
if (Test-Path $MODULES_PACKAGES_CONFIG) {
Push-Location
Set-Location $MODULES_DIR
Write-Verbose -Message "Restoring modules from NuGet..."
$NuGetOutput = Invoke-Expression "&`"$NUGET_EXE`" install -ExcludeVersion -OutputDirectory `"$MODULES_DIR`""
if ($LASTEXITCODE -ne 0) {
Throw "An error occurred while restoring NuGet modules."
}
Write-Verbose -Message ($NuGetOutput | out-string)
Pop-Location
}
# Make sure that Cake has been installed.
if (!(Test-Path $CAKE_EXE)) {
Throw "Could not find Cake.exe at $CAKE_EXE"
}
# Build Cake arguments
$cakeArguments = @("$Script");
if ($Target) { $cakeArguments += "-target=$Target" }
if ($Configuration) { $cakeArguments += "-configuration=$Configuration" }
if ($Verbosity) { $cakeArguments += "-verbosity=$Verbosity" }
if ($ShowDescription) { $cakeArguments += "-showdescription" }
if ($DryRun) { $cakeArguments += "-dryrun" }
if ($Experimental) { $cakeArguments += "-experimental" }
if ($Mono) { $cakeArguments += "-mono" }
$cakeArguments += $ScriptArgs
# Start Cake
Write-Host "Running build script..."
&$CAKE_EXE $cakeArguments
exit $LASTEXITCODE

16
build/header.txt Normal file
Просмотреть файл

@ -0,0 +1,16 @@
// ******************************************************************
// Copyright © 2015-2018 nventive inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// ******************************************************************

Двоичные данные
build/nuget/nuget.exe Normal file

Двоичный файл не отображается.

Просмотреть файл

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Cake" version="0.24.0" />
</packages>

15
gitversion.yml Normal file
Просмотреть файл

@ -0,0 +1,15 @@
assembly-versioning-scheme: MajorMinorPatch
mode: ContinuousDeployment
next-version: 1.0.0
continuous-delivery-fallback-tag: ""
branches:
master:
tag: dev
(stable):
tag: ""
dev/.*?/(.*?):
tag: dev.{BranchName}
projects/(.*?):
tag: proj-{BranchName}
ignore:
sha: []

Просмотреть файл

@ -0,0 +1,34 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.27520.0
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Uno.Wasm.Sample", "Uno.Wasm.Sample\Uno.Wasm.Sample.csproj", "{5641753C-F10C-4CC0-881B-1734B25E0F48}"
ProjectSection(ProjectDependencies) = postProject
{A3899B5E-FDE5-4F5B-B960-6B2BE73685B1} = {A3899B5E-FDE5-4F5B-B960-6B2BE73685B1}
EndProjectSection
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Uno.Wasm.Bootstrap", "Uno.Wasm.Bootstrap\Uno.Wasm.Bootstrap.csproj", "{A3899B5E-FDE5-4F5B-B960-6B2BE73685B1}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{5641753C-F10C-4CC0-881B-1734B25E0F48}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{5641753C-F10C-4CC0-881B-1734B25E0F48}.Debug|Any CPU.Build.0 = Debug|Any CPU
{5641753C-F10C-4CC0-881B-1734B25E0F48}.Release|Any CPU.ActiveCfg = Release|Any CPU
{5641753C-F10C-4CC0-881B-1734B25E0F48}.Release|Any CPU.Build.0 = Release|Any CPU
{A3899B5E-FDE5-4F5B-B960-6B2BE73685B1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A3899B5E-FDE5-4F5B-B960-6B2BE73685B1}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A3899B5E-FDE5-4F5B-B960-6B2BE73685B1}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A3899B5E-FDE5-4F5B-B960-6B2BE73685B1}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {FA350FE9-9316-4846-8145-356F9A0ACBC7}
EndGlobalSection
EndGlobal

Просмотреть файл

@ -0,0 +1,54 @@
// ******************************************************************
// Copyright <20> 2015-2018 nventive inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// ******************************************************************
using System;
using System.Linq;
using System.IO;
using System.Reflection;
using System.Xml;
using System.Xml.XPath;
using Mono.Cecil;
using System.Collections.Generic;
namespace Mono.Linker.Steps
{
public class ExplicitBlacklistStep : BaseStep
{
private readonly IEnumerable<string> _linkerDescriptors;
public ExplicitBlacklistStep(IEnumerable<string> linkerDescriptors)
{
_linkerDescriptors = linkerDescriptors ?? Enumerable.Empty<string>();
}
protected override void Process()
{
if (_linkerDescriptors.Any())
{
foreach (var def in _linkerDescriptors)
{
var step = new ResolveFromXmlStep(new XPathDocument(def));
Context.Pipeline.AddStepAfter(typeof(TypeMapStep), step);
Context.LogMessage($"Processing explicit linker descriptor: {def}");
}
}
}
}
}

Просмотреть файл

@ -0,0 +1,107 @@
// ******************************************************************
// Copyright <20> 2015-2018 nventive inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// ******************************************************************
using System;
using System.Collections.Generic;
using System.Text;
using Mono.Cecil;
namespace Uno.Wasm.Bootstrap
{
internal static class Extensions
{
public static bool Inherits(this TypeReference self, string className)
{
if (className == null)
{
throw new ArgumentNullException("className");
}
if (self == null)
{
return false;
}
TypeReference current = self.Resolve();
while (current != null)
{
string fullname = current.FullName;
if (fullname == className)
{
return true;
}
if (fullname == "System.Object")
{
return false;
}
if (current.Resolve() == null)
{
return false;
}
current = current.Resolve()?.BaseType;
}
return false;
}
public static bool Is(this TypeReference type, string @namespace, string name)
=> type != null && type.Name == name && type.Namespace == @namespace;
public static bool Inherits(this TypeReference self, string @namespace, string name)
{
if (@namespace == null)
{
throw new ArgumentNullException("namespace");
}
if (name == null)
{
throw new ArgumentNullException("name");
}
if (self == null)
{
return false;
}
TypeDefinition typeDefinition;
for (TypeReference typeReference = self.Resolve(); typeReference != null; typeReference = typeDefinition.BaseType)
{
if (typeReference.Is(@namespace, name))
{
return true;
}
if (typeReference.Is("System", "Object"))
{
return false;
}
typeDefinition = typeReference.Resolve();
if (typeDefinition == null)
{
return false;
}
}
return false;
}
}
}

Просмотреть файл

@ -0,0 +1,78 @@
//******************************************************************
// This file is part of the Xamarin.Android SDK
// The MIT License(MIT)
// Copyright(c) .NET Foundation Contributors
// All rights reserved.
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//
//******************************************************************
using System;
using System.Linq;
using Mono.Linker;
using Mono.Cecil;
using Mono.Linker.Steps;
namespace Uno.Wasm.Bootstrap
{
public class PreserveTypeConverters : ResolveStep
{
protected override void Process()
{
var asms = Context.GetAssemblies();
foreach (var a in asms)
{
foreach (var m in a.Modules)
{
foreach (var t in m.Types.Where(IsTypeConverter))
{
PreserveTypeConverter(t);
}
}
}
}
void PreserveTypeConverter(TypeDefinition type)
{
if (!type.HasMethods)
{
return;
}
foreach (var ctor in type.Methods.Where(m => m.IsConstructor))
{
// We only care about ctors with 0 or 1 params.
if (ctor.HasParameters && ctor.Parameters.Count > 1)
{
continue;
}
Annotations.AddPreservedMethod(type, ctor);
}
}
static bool IsTypeConverter(TypeDefinition type)
{
return type.Inherits("System.ComponentModel", "TypeConverter");
}
}
}

Просмотреть файл

@ -0,0 +1,104 @@
// ******************************************************************
// Copyright <20> 2015-2018 nventive inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// ******************************************************************
using System;
using System.Collections.Generic;
using System.Linq;
using Mono.Cecil;
using Mono.Linker;
using Mono.Linker.Steps;
namespace Uno.Wasm.Bootstrap
{
internal class PreserveUsingAttributesStep : ResolveStep
{
readonly HashSet<string> ignoreAsmNames;
public PreserveUsingAttributesStep(IEnumerable<string> ignoreAsmNames)
{
this.ignoreAsmNames = new HashSet<string>(ignoreAsmNames.Where(n => n != "mscorlib"));
}
protected override void Process()
{
var asms = Context.GetAssemblies();
foreach (var a in asms.Where(x => !ignoreAsmNames.Contains(x.Name.Name)))
{
foreach (var m in a.Modules)
{
foreach (var t in m.Types)
{
PreserveTypeIfRequested(t);
}
}
}
}
void PreserveTypeIfRequested(TypeDefinition type)
{
var typePreserved = IsTypePreserved(type);
if (IsTypePreserved(type))
{
MarkAndPreserveAll(type);
}
else
{
foreach (var m in type.Methods.Where(IsMethodPreserved))
{
Annotations.AddPreservedMethod(type, m);
}
foreach (var t in type.NestedTypes)
{
PreserveTypeIfRequested(t);
}
}
}
static bool IsTypePreserved(TypeDefinition m)
{
// Exclude WasmRuntime to that timer can get called properly
// https://github.com/mono/mono/blob/a49aa771c10889c6ac1974af81f9fcc375d391cb/mcs/class/corlib/System.Threading/Timer.cs#L56
if (m.Name.EndsWith("WasmRuntime"))
{
return true;
}
return m.CustomAttributes.FirstOrDefault(x => x.AttributeType.Name.StartsWith("Preserve", StringComparison.Ordinal)) != null;
}
static bool IsMethodPreserved(MethodDefinition m)
{
return m.CustomAttributes.FirstOrDefault(x => x.AttributeType.Name.StartsWith("Preserve", StringComparison.Ordinal)) != null;
}
void MarkAndPreserveAll(TypeDefinition type)
{
Annotations.MarkAndPush(type);
Annotations.SetPreserve(type, TypePreserve.All);
if (!type.HasNestedTypes)
{
Tracer.Pop();
return;
}
foreach (TypeDefinition nested in type.NestedTypes)
{
MarkAndPreserveAll(nested);
}
Tracer.Pop();
}
}
}

Просмотреть файл

@ -0,0 +1,380 @@
// ******************************************************************
// Copyright <20> 2015-2018 nventive inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// ******************************************************************
//
// This file is based on the work from https://github.com/praeclarum/Ooui
//
using System;
using System.Collections.Generic;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Net;
using System.Text;
using Microsoft.Build.Utilities;
using Mono.Cecil;
using Mono.Cecil.Cil;
using Mono.Linker;
using Mono.Linker.Steps;
namespace Uno.Wasm.Bootstrap
{
public partial class ShellTask_v0 : Microsoft.Build.Utilities.Task
{
private const string SdkUrl = "https://jenkins.mono-project.com/job/test-mono-mainline-webassembly/62/label=highsierra/Azure/processDownloadRequest/62/highsierra/sdks/wasm/mono-wasm-ddf4e7be31b.zip";
private string _distPath;
private string _managedPath;
private string _bclPath;
private List<string> _linkedAsmPaths;
private List<string> _referencedAssemblies;
private Dictionary<string, string> _bclAssemblies;
private string _sdkPath;
private List<string> _additionalScripts = new List<string>();
private string[] _additionalStyles;
[Microsoft.Build.Framework.Required]
public string Assembly { get; set; }
[Microsoft.Build.Framework.Required]
public string OutputPath { get; set; }
public string ReferencePath { get; set; }
public Microsoft.Build.Framework.ITaskItem[] Assets { get; set; }
public Microsoft.Build.Framework.ITaskItem[] LinkerDescriptors { get; set; }
[Microsoft.Build.Framework.Required]
public string RuntimeConfiguration { get; set; }
[Microsoft.Build.Framework.Required]
public bool RuntimeDebugLogging { get; set; }
public override bool Execute()
{
try
{
InstallSdk();
GetBcl();
CreateDist();
CopyContent();
CopyRuntime();
LinkAssemblies();
ExtractAdditionalJS();
ExtractAdditionalCSS();
GenerateHtml();
return true;
}
catch (Exception ex)
{
Log.LogErrorFromException(ex, false, true, null);
return false;
}
}
private void InstallSdk()
{
var sdkName = Path.GetFileNameWithoutExtension(new Uri(SdkUrl).AbsolutePath.Replace('/', Path.DirectorySeparatorChar));
Log.LogMessage("SDK: " + sdkName);
_sdkPath = Path.Combine(Path.GetTempPath(), sdkName);
Log.LogMessage("SDK Path: " + _sdkPath);
if (Directory.Exists(_sdkPath))
{
return;
}
var client = new WebClient();
var zipPath = _sdkPath + ".zip";
Log.LogMessage($"Downloading {sdkName} to {zipPath}");
client.DownloadFile(SdkUrl, zipPath);
ZipFile.ExtractToDirectory(zipPath, _sdkPath);
Log.LogMessage($"Extracted {sdkName} to {_sdkPath}");
}
private void GetBcl()
{
_bclPath = Path.Combine(_sdkPath, "bcl");
var reals = Directory.GetFiles(_bclPath, "*.dll");
var facades = Directory.GetFiles(Path.Combine(_bclPath, "Facades"), "*.dll");
var allFiles = reals.Concat(facades);
_bclAssemblies = allFiles.ToDictionary(x => Path.GetFileName(x));
}
private void CreateDist()
{
var outputPath = Path.GetFullPath(OutputPath);
_distPath = Path.Combine(outputPath, "dist");
_managedPath = Path.Combine(_distPath, "managed");
Directory.CreateDirectory(_managedPath);
}
private void CopyRuntime()
{
var runtimePath = Path.Combine(_sdkPath, RuntimeConfiguration.ToLower());
foreach (var sourceFile in Directory.EnumerateFiles(runtimePath))
{
var dest = Path.Combine(_distPath, Path.GetFileName(sourceFile));
Log.LogMessage($"Runtime {sourceFile} -> {dest}");
File.Copy(sourceFile, dest, true);
}
File.Copy(Path.Combine(_sdkPath, "server.py"), Path.Combine(_distPath, "server.py"), true);
}
private void CopyContent()
{
if (Assets != null)
{
var runtimePath = Path.Combine(_sdkPath, RuntimeConfiguration.ToLower());
foreach (var sourceFile in Assets)
{
var baseSourceFile = sourceFile.GetMetadata("DefiningProjectDirectory");
Directory.CreateDirectory(Path.Combine(_distPath, Path.GetDirectoryName(sourceFile.ToString())));
var dest = Path.Combine(_distPath, sourceFile.ItemSpec);
var fullSourcePath = Path.Combine(baseSourceFile, sourceFile.ItemSpec);
Log.LogMessage($"ContentFile {fullSourcePath} -> {dest}");
File.Copy(fullSourcePath, dest, true);
}
}
}
class Logger : ILogger
{
private TaskLoggingHelper log;
public Logger(TaskLoggingHelper log) => this.log = log;
public void LogMessage(MessageImportance importance, string message, params object[] values)
{
switch (importance)
{
case MessageImportance.High:
log.LogMessage(Microsoft.Build.Framework.MessageImportance.High, message, values);
break;
case MessageImportance.Normal:
log.LogMessage(Microsoft.Build.Framework.MessageImportance.Normal, message, values);
break;
case MessageImportance.Low:
log.LogMessage(Microsoft.Build.Framework.MessageImportance.Low, message, values);
break;
}
}
}
void LinkAssemblies()
{
var references = ReferencePath.Split(';').Select(x => x.Trim()).Where(x => x.Length > 0).ToList();
_referencedAssemblies = new List<string>();
foreach (var r in references)
{
var name = Path.GetFileName(r);
if (_bclAssemblies.ContainsKey(name))
{
_referencedAssemblies.Add(_bclAssemblies[name]);
}
else
{
_referencedAssemblies.Add(r);
}
}
var asmPath = Path.GetFullPath(Assembly);
var pipeline = GetLinkerPipeline();
using (var context = new LinkContext(pipeline))
{
context.CoreAction = AssemblyAction.Link;
context.UserAction = AssemblyAction.Link;
// Disabled until we can actually use symbols, and that
// the rewriter does not fail for a memory allocation error.
// context.SymbolReaderProvider = new DefaultSymbolReaderProvider(true);
// context.SymbolWriterProvider = new DefaultSymbolWriterProvider();
// context.LinkSymbols = true;
context.Logger = new Logger(Log);
context.LogMessages = true;
context.KeepTypeForwarderOnlyAssemblies = true;
context.OutputDirectory = _managedPath;
pipeline.PrependStep(new ResolveFromAssemblyStep(asmPath, ResolveFromAssemblyStep.RootVisibility.Any));
var refdirs = _referencedAssemblies.Select(x => Path.GetDirectoryName(x)).Distinct().ToList();
refdirs.Insert(0, Path.Combine(_bclPath, "Facades"));
refdirs.Insert(0, _bclPath);
foreach (var d in refdirs.Distinct())
{
context.Resolver.AddSearchDirectory(d);
}
pipeline.AddStepAfter(typeof(LoadReferencesStep), new LoadI18nAssemblies(I18nAssemblies.None));
foreach (var dll in Directory.GetFiles(_managedPath, "*.dll"))
{
File.Delete(dll);
}
pipeline.Process(context);
}
_linkedAsmPaths = Directory.GetFiles(_managedPath, "*.dll")
.Concat(Directory.GetFiles(_managedPath, "*.exe"))
.OrderBy(x => Path.GetFileName(x))
.ToList();
}
Pipeline GetLinkerPipeline()
{
var p = new Pipeline();
p.AppendStep(new LoadReferencesStep());
p.AppendStep(new PreserveUsingAttributesStep(_bclAssemblies.Values.Select(Path.GetFileNameWithoutExtension)));
p.AppendStep(new PreserveTypeConverters());
p.AppendStep(new BlacklistStep());
p.AppendStep(new ExplicitBlacklistStep(LinkerDescriptors?.Select(l => l.ItemSpec)));
p.AppendStep(new TypeMapStep());
p.AppendStep(new MarkStep());
p.AppendStep(new SweepStep());
p.AppendStep(new CleanStep());
p.AppendStep(new RegenerateGuidStep());
p.AppendStep(new OutputStep());
return p;
}
private void ExtractAdditionalJS()
{
var q = EnumerateResources("js", "WasmDist")
.Concat(EnumerateResources("js", "WasmScripts"));
q.AsParallel().ForAll(res =>
{
if (res.name != "uno-bootstrap.js")
{
_additionalScripts.Add(res.name);
}
CopyResourceToOutput(res.name, res.resource);
Log.LogMessage($"Additional JS {res.name}");
});
}
private void ExtractAdditionalCSS()
{
var q = EnumerateResources("css", "WasmCSS");
_additionalStyles = q.AsParallel().Select(res => {
using (var srcs = res.resource.GetResourceStream())
{
CopyResourceToOutput(res.name, res.resource);
Log.LogMessage($"Additional CSS {res.name}");
}
return res.name;
})
.ToArray();
}
private void CopyResourceToOutput(string name, EmbeddedResource resource)
{
var dest = Path.Combine(_distPath, name);
using (var srcs = resource.GetResourceStream())
{
using (var dests = new FileStream(dest, FileMode.Create, FileAccess.Write))
{
srcs.CopyTo(dests);
}
}
}
private IEnumerable<(string name, EmbeddedResource resource)> EnumerateResources(string extension, string folder)
{
var fullExtension = "." + extension;
var fullFolder = "." + folder + ".";
return from asmPath in _referencedAssemblies.Concat(new[] { Assembly, this.GetType().Assembly.Location })
let asm = AssemblyDefinition.ReadAssembly(asmPath)
from res in asm.MainModule.Resources.OfType<EmbeddedResource>()
where res.Name.EndsWith(fullExtension)
where res.Name.Contains(fullFolder)
select (
name: res.Name.Substring(res.Name.IndexOf(fullFolder) + fullFolder.Length),
resource: res
);
}
private MethodDefinition DiscoverEntryPoint()
{
var asm = AssemblyDefinition.ReadAssembly(Assembly);
if (asm?.EntryPoint is MethodDefinition def)
{
return def;
}
throw new Exception($"{Path.GetFileName(Assembly)} is missing an entry point");
}
private void GenerateHtml()
{
var htmlPath = Path.Combine(_distPath, "index.html");
var entryPoint = DiscoverEntryPoint();
using (var w = new StreamWriter(htmlPath, false, new UTF8Encoding(false)))
{
string indexHtmlResName = $"{GetType().Assembly.GetName().Name}.Templates.Index.html";
var stream = this.GetType().Assembly.GetManifestResourceStream(indexHtmlResName);
if (stream == null)
{
throw new InvalidOperationException($"Unable to find {indexHtmlResName}");
}
using (var sr = new StreamReader(stream))
{
var html = sr.ReadToEnd();
var assemblies = string.Join(", ", _linkedAsmPaths.Select(x => $"\"{Path.GetFileName(x)}\""));
html = html.Replace("$(ASSEMBLIES_LIST)", assemblies);
html = html.Replace("$(MAIN_ASSEMBLY_NAME)", entryPoint.DeclaringType.Module.Assembly.Name.Name);
html = html.Replace("$(MAIN_NAMESPACE)", entryPoint.DeclaringType.Namespace);
html = html.Replace("$(MAIN_TYPENAME)", entryPoint.DeclaringType.Name);
html = html.Replace("$(MAIN_METHOD)", entryPoint.Name);
html = html.Replace("$(ENABLE_RUNTIMEDEBUG)", RuntimeDebugLogging.ToString().ToLower());
var scripts = string.Join("\r\n", _additionalScripts.Select(s => $"<script defer type=\"text/javascript\" src=\"{s}\"></script>"));
html = html.Replace("$(ADDITIONAL_SCRIPTS)", scripts);
var styles = string.Join("\r\n", _additionalStyles.Select(s => $"<link rel=\"stylesheet\" type=\"text/css\" href=\"{s}\" />"));
html = html.Replace("$(ADDITIONAL_CSS)", styles);
w.Write(html);
}
Log.LogMessage($"HTML {htmlPath}");
}
}
}
}

Просмотреть файл

@ -0,0 +1,27 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="stylesheet" href="https://ajax.aspnetcdn.com/ajax/bootstrap/3.3.7/css/bootstrap.min.css" />
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css" />
$(ADDITIONAL_CSS)
</head>
<body>
<div id="uno-body" class="container-fluid">
<p id="loading"><i class="fa fa-refresh fa-spin" style="font-size:14px;margin-right:0.5em;"></i> Loading...</p>
</div>
<script defer type="text/javascript" src="uno-bootstrap.js"></script>
<script type="text/javascript">
var assemblies = [$(ASSEMBLIES_LIST)];
document.addEventListener(
"DOMContentLoaded",
function (event) {
unoWasmMain("$(MAIN_ASSEMBLY_NAME)", "$(MAIN_NAMESPACE)", "$(MAIN_TYPENAME)", "$(MAIN_METHOD)", assemblies, $(ENABLE_RUNTIMEDEBUG));
}
);
</script>
<script defer type="text/javascript" src="mono.js"></script>
$(ADDITIONAL_SCRIPTS)
</body>
</html>

Просмотреть файл

@ -0,0 +1,69 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<DefineConstants>NET_CORE</DefineConstants>
<NoWarn>1701;1702;1705;649</NoWarn>
<AssemblyName>Uno.Wasm.Bootstrap.v0</AssemblyName>
<RootNamespace>Uno.Wasm.Bootstrap.v0</RootNamespace>
<PackageId>Uno.Wasm.Bootstrap</PackageId>
<IsTool>true</IsTool>
</PropertyGroup>
<PropertyGroup>
<Authors>nventive</Authors>
<PackageProjectUrl>https://github.com/nventive/Uno.Wasm.Bootstrap</PackageProjectUrl>
<PackageIconUrl>https://nv-assets.azurewebsites.net/logos/uno.png</PackageIconUrl>
<RepositoryUrl>https://github.com/nventive/Uno.Core</RepositoryUrl>
<Description>This package provides a Wasm bootstap for netstandard 2.0 projects.</Description>
<Copyright>Copyright (C) 2015-2018 nventive inc. - all rights reserved</Copyright>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Build" Version="15.3.409" />
<PackageReference Include="Microsoft.Build.Framework" Version="15.3.409" />
<PackageReference Include="Microsoft.Build.Utilities.Core" Version="15.3.409" />
<PackageReference Include="Microsoft.Build.Tasks.Core" Version="15.3.409" />
</ItemGroup>
<ItemGroup>
<None Remove="linker\**" />
<Compile Remove="linker\**" />
<Compile Include="linker\linker\Linker\**\*.cs" />
<Compile Include="linker\linker\Linker.Steps\**\*.cs" />
<Compile Include="linker\cecil\Mono.Cecil\**\*.cs" />
<Compile Include="linker\cecil\Mono.Cecil.Cil\**\*.cs" />
<Compile Include="linker\cecil\Mono.Cecil.Metadata\**\*.cs" />
<Compile Include="linker\cecil\Mono.Cecil.PE\**\*.cs" />
<Compile Include="linker\cecil\Mono.Collections.Generic\**\*.cs*" />
<Compile Include="linker\cecil\symbols\mdb\Mono.Cecil.Mdb\**\*.cs*" />
<Compile Include="linker\cecil\symbols\mdb\Mono.CompilerServices.SymbolWriter\**\*.cs*" />
<Compile Include="linker\cecil\symbols\pdb\Microsoft.Cci.Pdb\**\*.cs*" />
<Compile Include="linker\cecil\symbols\pdb\Mono.Cecil.Pdb\**\*.cs*" />
<Compile Include="linker\cecil\Mono\**\*.cs" />
<Compile Remove="linker\cecil\symbols\mdb\Mono.Cecil.Mdb\AssemblyInfo.cs" />
<Compile Remove="linker\cecil\symbols\pdb\Mono.Cecil.Pdb\AssemblyInfo.cs" />
<Compile Remove="linker\linker\Linker\Driver.cs" />
<Compile Remove="linker\linker\Linker\AssemblyInfo.cs" />
<Compile Remove="linker\cecil\Mono.Cecil\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<None Remove="Templates\Index.html" />
<None Remove="WasmScripts\uno-bootstrap.js" />
</ItemGroup>
<ItemGroup>
<Content Include="build\Uno.Wasm.Bootstrap.targets">
<Pack>true</Pack>
<PackagePath>build</PackagePath>
</Content>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="WasmScripts\uno-bootstrap.js" />
<EmbeddedResource Include="Templates\Index.html" />
</ItemGroup>
</Project>

Просмотреть файл

@ -0,0 +1,122 @@
var debug = false;
function unoWasmMain(mainAsmName, mainNamespace, mainClassName, mainMethodName, assemblies, isDebug) {
Module.entryPoint = { "a": mainAsmName, "n": mainNamespace, "t": mainClassName, "m": mainMethodName };
Module.assemblies = assemblies;
debug = isDebug;
}
var Module = {
onRuntimeInitialized: function () {
if (debug) console.log("Done with WASM module instantiation.");
Module.FS_createPath("/", "managed", true, true);
var pending = 0;
this.assemblies.forEach(function (asm_name) {
if (debug) console.log("Loading", asm_name);
++pending;
fetch("managed/" + asm_name, { credentials: 'same-origin' }).then(function (response) {
if (!response.ok)
throw "failed to load Assembly '" + asm_name + "'";
return response['arrayBuffer']();
}).then(function (blob) {
var asm = new Uint8Array(blob);
Module.FS_createDataFile("managed/" + asm_name, null, asm, true, true, true);
--pending;
if (pending == 0)
Module.bclLoadingDone();
});
});
},
bclLoadingDone: function () {
if (debug) console.log("Done loading the BCL.");
MonoRuntime.init();
}
};
var MonoRuntime = {
init: function () {
this.load_runtime = Module.cwrap('mono_wasm_load_runtime', null, ['string', 'number']);
this.assembly_load = Module.cwrap('mono_wasm_assembly_load', 'number', ['string']);
this.find_class = Module.cwrap('mono_wasm_assembly_find_class', 'number', ['number', 'string', 'string']);
this.find_method = Module.cwrap('mono_wasm_assembly_find_method', 'number', ['number', 'string', 'number']);
this.invoke_method = Module.cwrap('mono_wasm_invoke_method', 'number', ['number', 'number', 'number']);
this.mono_string_get_utf8 = Module.cwrap('mono_wasm_string_get_utf8', 'number', ['number']);
this.mono_string = Module.cwrap('mono_wasm_string_from_js', 'number', ['string']);
this.load_runtime("managed", 1);
if (debug) console.log("Done initializing the runtime.");
WebAssemblyApp.init();
},
conv_string: function (mono_obj) {
if (mono_obj == 0)
return null;
var raw = this.mono_string_get_utf8(mono_obj);
var res = Module.UTF8ToString(raw);
Module._free(raw);
return res;
},
call_method: function (method, this_arg, args) {
var args_mem = Module._malloc(args.length * 4);
var eh_throw = Module._malloc(4);
for (var i = 0; i < args.length; ++i)
Module.setValue(args_mem + i * 4, args[i], "i32");
Module.setValue(eh_throw, 0, "i32");
var res = this.invoke_method(method, this_arg, args_mem, eh_throw);
var eh_res = Module.getValue(eh_throw, "i32");
Module._free(args_mem);
Module._free(eh_throw);
if (eh_res != 0) {
var msg = this.conv_string(res);
throw new Error(msg);
}
return res;
},
};
var WebAssemblyApp = {
init: function () {
this.loading = document.getElementById("loading");
this.findMethods();
this.runApp();
this.loading.hidden = true;
},
runApp: function () {
try {
MonoRuntime.call_method(this.main_method, null, []);
} catch (e) {
console.error(e);
}
},
findMethods: function () {
this.main_module = MonoRuntime.assembly_load(Module.entryPoint.a);
if (!this.main_module)
throw "Could not find Main Module " + Module.entryPoint.a + ".dll";
this.main_class = MonoRuntime.find_class(this.main_module, Module.entryPoint.n, Module.entryPoint.t)
if (!this.main_class)
throw "Could not find Program class in main module";
this.main_method = MonoRuntime.find_method(this.main_class, Module.entryPoint.m, -1)
if (!this.main_method)
throw "Could not find Main method";
},
};

Просмотреть файл

@ -0,0 +1,26 @@
<Project>
<PropertyGroup>
<_packageBinaryPath>$(MSBuildThisFileDirectory)../tools/Uno.Wasm.Bootstrap.v0.dll</_packageBinaryPath>
<WasmShellTasksPath Condition="!Exists('$(_packageBinaryPath)')">$(MSBuildThisFileDirectory)../bin/$(Configuration)/netstandard2.0</WasmShellTasksPath>
<WasmShellTasksPath Condition="Exists('$(_packageBinaryPath)')">../tools</WasmShellTasksPath>
<MonoWasmRuntimeConfiguration Condition="'$(WasmRuntimeConfiguration)'==''">release</MonoWasmRuntimeConfiguration>
<MonoRuntimeDebugLogging Condition="'$(WasmRuntimeDebug)'==''">false</MonoRuntimeDebugLogging>
</PropertyGroup>
<UsingTask AssemblyFile="$(WasmShellTasksPath)/Uno.Wasm.Bootstrap.v0.dll" TaskName="Uno.Wasm.Bootstrap.ShellTask_v0" />
<Target Name="BuildDist" AfterTargets="AfterBuild">
<ShellTask_v0
Assembly="$(IntermediateOutputPath)$(TargetFileName)"
OutputPath="$(OutputPath)"
LinkerDescriptors="@(LinkerDescriptor)"
RuntimeConfiguration="$(MonoWasmRuntimeConfiguration)"
RuntimeDebugLogging="$(MonoRuntimeDebugLogging)"
Assets="@(Content)"
ReferencePath="@(ReferencePath)" />
</Target>
</Project>

@ -0,0 +1 @@
Subproject commit 08277b61d8c00aa3f5ab069d45fa17e4a318809b

Двоичные данные
src/Uno.Wasm.Sample/Content/LockScreenLogo.scale-200.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 1.4 KiB

Просмотреть файл

@ -0,0 +1,5 @@
<linker>
<assembly fullname="Uno.Wasm.Sample">
<namespace fullname="Uno.Wasm.Sample" />
</assembly>
</linker>

Просмотреть файл

@ -0,0 +1,45 @@
// ******************************************************************
// Copyright <20> 2015-2018 nventive inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// ******************************************************************
using System;
using System.Collections.Immutable;
namespace Uno.Wasm.Sample
{
public static class Program
{
static void Main(string[] args)
{
Console.WriteLine("Main!");
try
{
NewMethod();
}
catch(Exception e)
{
Console.WriteLine(e);
}
}
private static void NewMethod()
{
ImmutableDictionary<string, string> s = ImmutableDictionary<string, string>.Empty;
Console.WriteLine($"test new method {s.Count}");
}
}
}

Просмотреть файл

@ -0,0 +1,35 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<OutputType>Exe</OutputType>
<IsPackable>false</IsPackable>
<StartupObject>Uno.Wasm.Sample.Program</StartupObject>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="System.Collections.Immutable" Version="1.4.0" />
</ItemGroup>
<Import Project="..\Uno.Wasm.Bootstrap\build\Uno.Wasm.Bootstrap.targets" />
<ItemGroup>
<None Include="WasmScripts\**\*.js" />
<None Include="WasmCSS\**\*.css" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="WasmScripts\**\*.js" />
<EmbeddedResource Include="WasmCSS\**\*.css" />
</ItemGroup>
<ItemGroup>
<LinkerDescriptor Include="LinkerDescriptors.xml" />
</ItemGroup>
<ItemGroup>
<Content Include="Content\**" />
</ItemGroup>
</Project>

Просмотреть файл

@ -0,0 +1,53 @@
/* http://meyerweb.com/eric/tools/css/reset/
v2.0 | 20110126
License: none (public domain)
*/
html, body, div, span, applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code,
del, dfn, em, img, ins, kbd, q, s, samp,
small, strike, strong, sub, sup, tt, var,
b, u, i, center,
dl, dt, dd, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td,
article, aside, canvas, details, embed,
figure, figcaption, footer, header, hgroup,
menu, nav, output, ruby, section, summary,
time, mark, audio, video {
margin: 0;
padding: 0;
border: 0;
font-size: 100%;
font: inherit;
vertical-align: baseline;
}
/* HTML5 display-role reset for older browsers */
article, aside, details, figcaption, figure,
footer, header, hgroup, menu, nav, section {
display: block;
}
body {
line-height: 1;
}
ol, ul {
list-style: none;
}
blockquote, q {
quotes: none;
}
blockquote:before, blockquote:after,
q:before, q:after {
content: '';
content: none;
}
table {
border-collapse: collapse;
border-spacing: 0;
}

Просмотреть файл

@ -0,0 +1,5 @@
window.onload = function () {
var txt = document.createTextNode("Loaded !");
var parent = document.getElementById('uno-body');
parent.insertBefore(txt, parent.lastChild);
}