Add wasm build

This commit is contained in:
Frank A. Krueger 2018-03-08 13:30:06 -08:00
parent e78bde556b
commit 881330e49e
No known key found for this signature in database
GPG Key ID: 0471C67474FFE664
5 changed files with 221 additions and 0 deletions

66
Ooui.Wasm/Dockerfile Normal file
View File

@ -0,0 +1,66 @@
FROM alpine:3.7
RUN apk update \
&& apk upgrade \
&& apk add --no-cache g++ musl-dev make cmake git subversion python
RUN mkdir /mono-wasm \
&& cd /mono-wasm \
&& git clone --depth 1 https://github.com/lrz/mono-wasm.git build
# RUN cd /mono-wasm \
# && svn co --quiet http://llvm.org/svn/llvm-project/llvm/trunk llvm \
# && cd llvm/tools \
# && svn co --quiet http://llvm.org/svn/llvm-project/cfe/trunk clang \
# && svn co --quiet http://llvm.org/svn/llvm-project/lld/trunk lld
RUN cd /mono-wasm \
&& wget http://releases.llvm.org/5.0.1/llvm-5.0.1.src.tar.xz \
&& unxz llvm-5.0.1.src.tar.xz \
&& tar xf llvm-5.0.1.src.tar \
&& rm llvm-5.0.1.src.tar \
&& mv llvm-5.0.1.src llvm \
&& cd llvm/tools \
&& wget http://releases.llvm.org/5.0.1/cfe-5.0.1.src.tar.xz \
&& unxz cfe-5.0.1.src.tar.xz \
&& tar xf cfe-5.0.1.src.tar \
&& rm cfe-5.0.1.src.tar \
&& mv cfe-5.0.1.src clang \
&& wget http://releases.llvm.org/5.0.1/lld-5.0.1.src.tar.xz \
&& unxz lld-5.0.1.src.tar.xz \
&& tar xf lld-5.0.1.src.tar \
&& rm lld-5.0.1.src.tar \
&& mv lld-5.0.1.src lld
RUN mkdir /mono-wasm/llvm-build \
&& cd /mono-wasm/llvm-build \
&& cmake -G "Unix Makefiles" -DCMAKE_C_COMPILER=/usr/bin/gcc -DCMAKE_CXX_COMPILER=/usr/bin/g++ -DLLVM_TARGETS_TO_BUILD=X86 -DLLVM_EXPERIMENTAL_TARGETS_TO_BUILD=WebAssembly -DCMAKE_BUILD_TYPE=Release ../llvm \
&& make -j7
RUN cd /mono-wasm \
&& git clone --depth 1 https://github.com/mono/llvm.git llvm-mono
ENV CXXFLAGS="-fpermissive"
RUN mkdir /mono-wasm/llvm-mono-build \
&& cd /mono-wasm/llvm-mono-build \
&& cmake -G "Unix Makefiles" -DCMAKE_OSX_ARCHITECTURES="i386;x86_64" -DLLVM_TARGETS_TO_BUILD=X86 ../llvm-mono \
&& cp -R ../llvm-mono/include/* include/ \
&& sed -i "s/#if defined(_LARGEFILE64_SOURCE) || defined(_GNU_SOURCE)/#if 0/" /usr/include/stdio.h \
&& sed -i "s/#if defined(_LARGEFILE64_SOURCE) || defined(_GNU_SOURCE)/#if 0/" /usr/include/sys/stat.h \
# && sed -i "s/namespace llvm/#undef fopen\n#undef fopen64\n#undef fseeko\n#undef fseeko64\n#undef fstat\n#undef fstat64\n#undef ftello\n#undef ftello64\n#undef lstat\n#undef lstat64\n#undef stat\n#undef stat64\n#undef tmpfile\n#undef tmpfile64\n\nnamespace llvm/" /mono-wasm/llvm-mono-build/include/llvm/Target/TargetLibraryInfo.h
&& make -j7
ENV CXXFLAGS=""
RUN cd /mono-wasm \
&& git clone --depth 1 https://github.com/lrz/mono-wasm-mono.git mono-compiler
RUN apk add --no-cache bash autoconf automake libtool linux-headers \
&& cd /mono-wasm/mono-compiler \
&& ./autogen.sh --with-cross-offsets=offsets-wasm32.h CFLAGS="-DCOMPILE_WASM32 -DMONO_CROSS_COMPILE" CXXFLAGS="-DCOMPILE_WASM32 -DMONO_CROSS_COMPILE" --disable-boehm --with-sigaltstack=no --enable-llvm --enable-llvm-runtime --with-llvm=../llvm-mono-build --disable-btls --with-runtime_preset=testing_aot_full
# RUN cd /mono-wasm/mono-compiler/eglib \
# && make -j7 \
# && cd ../mono \
# && make -j7

18
Ooui.Wasm/Makefile Normal file
View File

@ -0,0 +1,18 @@
OOUI_SRCS=$(wildcard ../Ooui/*.cs)
all: hello.exe output/index.wasm output/index.html
hello.exe: hello.cs Ooui.dll Makefile
mcs -nostdlib -noconfig -r:mono-wasm-macos/dist/lib/mscorlib.dll -r:Ooui.dll hello.cs -out:hello.exe
Ooui.dll: $(OOUI_SRCS) System.Core.cs Makefile
mcs -nostdlib -noconfig -r:mono-wasm-macos/dist/lib/mscorlib.dll -define:NO_PROCESS,NO_SERVER,NO_XML System.Core.cs $(OOUI_SRCS) -out:Ooui.dll
output/index.wasm: hello.exe Makefile
mono-wasm-macos/dist/bin/mono-wasm -i hello.exe -o output
output/index.html: index.html
cp index.html output
clean:
rm -rf build output hello.exe

16
Ooui.Wasm/System.Core.cs Normal file
View File

@ -0,0 +1,16 @@
using System;
namespace System.ComponentModel
{
public interface INotifyPropertyChanged
{
}
public class PropertyChangedEventArgs : EventArgs
{
}
public delegate void PropertyChangedEventHandler (object sender, PropertyChangedEventArgs e);
}

77
Ooui.Wasm/hello.cs Normal file
View File

@ -0,0 +1,77 @@
using Mono.WebAssembly;
using System;
class Hello
{
static int Factorial(int n)
{
if (n == 0) {
return 1;
}
return n * Factorial(n - 1);
}
// This function is called from the browser by JavaScript.
// Here we calculate the factorial of the given number then use the
// Mono.WebAssembly API to retrieve the element from the DOM and set its
// innerText property to the factorial result.
static void FactorialInElement(int n, string element_id)
{
Console.WriteLine(
"Calculating factorial of {0} into DOM element {1}",
n, element_id);
int f = Factorial(n);
var elem = HtmlPage.Document.GetElementById(element_id);
elem.InnerText = f.ToString();
}
static void PrintHtmlElements(HtmlElement elem, int level)
{
string str = "";
for (int i = 0; i < level; i++) {
str += " ";
}
str += $"<{elem.TagName}";
foreach (var name in elem.AttributeNames) {
var value = elem.GetAttribute(name);
str += $" {name}='{value}'";
}
str += ">";
Console.WriteLine(str);
var list = elem.Children;
for (int i = 0; i < list.Count; i++) {
var child = list[i];
PrintHtmlElements(child, level + 1);
}
}
static int Main(string[] args)
{
Ooui.Div odiv = new Ooui.Div ();
int f = Factorial(6);
HtmlPage.Window.Alert($"Hello world! factorial(6) -> {odiv}");
var bi = HtmlPage.BrowserInformation;
Console.WriteLine($"BrowserInformation: Name {bi.Name} BrowserVersion {bi.BrowserVersion} UserAgent {bi.UserAgent} Platform {bi.Platform} CookiesEnabled {bi.CookiesEnabled} ProductName {bi.ProductName}");
var d = HtmlPage.Document;
Console.WriteLine($"Document Location: {d.Location}");
PrintHtmlElements(d.DocumentElement, 0);
var p = d.CreateElement("p");
p.InnerText = "This text was added at runtime.";
d.Body.AppendChild(p);
if (args.Length > 0) FactorialInElement(0, ""); // this is a hack so that the linker does not remove the FactorialInElement() method
return f;
}
}

44
Ooui.Wasm/index.html Normal file
View File

@ -0,0 +1,44 @@
<!DOCTYPE html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>WebAssembly Example</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="styles.css">
</head>
<body>
<p>
<form name="factorial_form" onSubmit="return factorial_submit()">
Number: <input type="text" name="input" value="6"/>
<br/><br/>
Result: <span id="factorial_result">...</span>
<br/><br/>
<input name="Submit" type="submit" value="Calculate"/>
</form>
</p>
<script src="index.js"></script>
<script>
function factorial_submit() {
// This function is called by the form. We now call into the
// Hello.FactorialInElement() C# method, passing the input (a number)
// and the element ID which should be set with the result (here, the
// <span> element defined above.
var input = document.forms["factorial_form"]["input"].value;
var klass = MonoClass("", "Hello");
if (klass) {
var method = MonoMethod(klass, "FactorialInElement", true);
if (method) {
MonoInvoke(0, method, [parseInt(input), "factorial_result"]);
}
}
return false;
}
document.addEventListener('WebAssemblyContentLoaded', function() {
// Calculate the initial form value.
factorial_submit();
}, false);
</script>
</body>
</html>