Hi folks, continuing with my previous post WebAssembly, the end of Javascript era? , today we are going to demonstrate WebAssembly with two simple
examples, one with C++ and the other with GO language. The example from two languages will help us to see different implementations that allow us to reach the same result.
Before jumping into setting up WebAssembly, I want to briefly cover the tools I’ve used to create this example ranging from IDE (integrated development environment) to WebAssembly plugin
In the C++ project I used CLion and for the GO project I pick the Goland which are both created by JetBrain . Of course, there are alternatives IDEs but these two have been chosen for consistency for side-by-side comparison
The other thing we will need in both cases is to compile and integrate with javascript. GO since version 1.11.4 already included WebAssembly port as a build-in feature we will go in depth in the next section.
For C++, we will have to install and set up EMSDK, a toolchain provided by WebAssembly that not only compile your code into .wasm file, but also provides a scripting language that you can embed on your C++, allows extern “c” statements, generate HTML output (including javascript’s integration of wasm) and more.
As I already mentioned, for GO lang we will need to have version 1.11, which includes an experimental port to WebAssembly.
Now you only need to set GOARCH=wasm and GOOS=js environment variables to compile this small example into WebAssembly:
package main import "fmt" func main() { fmt.Println("Hello, WebAssembly!") }
with just this line,
$ GOOS=js GOARCH=wasm go build -o main.wasm
Of course you can always automate this task in your IDE, here’s how to configure Goland
For C++, in addition to the compiler that match your OS, for example gcc, you will need to install the EMSDK.
$ git clone https://github.com/juj/emsdk.git $ cd emsdk $ ./emsdk install latest $ ./emsdk activate latest
If you don’t want to use git, you can download the zip version.
For a fully working example, the wasm file is not enough. Here we will need a web server that serves the HTML and javascript, and the javascript file that execute the wasm in the browser.
First we need to get the wasm_exec.js and and wasm_exec.html that can be copied from GO installation
cp "$(go env GOROOT)/misc/wasm/wasm_exec.*” .
The next thing will be a web server, here’s a snippet of a simple net/http based server:
package main import ( "flag" "log" "net/http" ) var ( listen = flag.String("listen", ":8080", "listen address") dir = flag.String("dir", ".", "directory to serve") ) func main() { flag.Parse() log.Printf("listening on %q...", *listen) log.Fatal(http.ListenAndServe(*listen, http.FileServer(http.Dir(*dir)))) }
And finally “the code”, you will notice that instead of import “fmt” I use “syscall/js”, this library gives us the ability to access to DOM elements and invoke javascript actions on them.
package main import ( "syscall/js" ) func main() { console := js.Global().Get("console") console.Call("log", "Hi!") wasmtest := js.Global().Get("document").Call("getElementById", "wasmtest") wasmtest.Set("innerText", "Am I a Gopher?") }
When this code is loaded, it shows a “Run” button and when you click it, a “Hi!” message will be printed in browser’s console and a “<p>” element enclosing “Am I a Gopher?” will append to the browser.
This example workflow is slightly easier than the previous one thanks of the EMSDK.
In this case we only need to implement the C++ code
#include <iostream> int main() { std::cout << "Hello, WebAssemby!" << std::endl; return 0; }
The SDK will generate all support files needed, such as Make files. To compile run:
emcc main.cpp -s WASM=1 -o hello.html
Once it finishes you can either open the HTML file in the browser or run a web server pointing to you project directory.
$ emrun --no_browser --port 8080 .
and open in your browse http://localhost:8080/hello.html
You will see a debug page created by emscripten.
You can do more elaborated things using emscripten library which allows you, for example, run native C++ code in the browser with the use of “extern C”
#include <stdio.h>
#include <emscripten/emscripten.h>
int main(int argc, char ** argv) {
printf("Hello WebAssembly\n");
}
#ifdef __cplusplus
extern "C" {
#endif
void EMSCRIPTEN_KEEPALIVE myCustomLog(int argc, char ** argv) {
printf("myCustomLog Called: %s", argv[0]);
}
#ifdef __cplusplus
}
#endif
For more information about this library take a peek at EMScripten documentation
As you could sneak peek with these two small examples, this is a promising new tech. However, as a very early tool scarce in features, it will take a while for WebAssembly to takeoff. Despite it’s lack in features, I am excited to see what the web could become.
Hope you enjoyed reading and see you on the next post. Thank you!
Tags: c++, cpp, golang, javascript, programming, wasm, web apps, webassembly
Categories: Golang, JavaScript, Programming
Lets talk!
Join our mailing list, we promise not to spam.