Skip to content

treeform/nim_emscripten_tutorial

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

46 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Nim Emscripten Tutorial for Windows.

Installing Emscripten:

Depends on which operating system you are using you are going to have to do different things to install emscripten.

Windows.

First, install Python if it is not already installed.

If you do not have Python installed, get it here..

Note: ensure you check the box to add Python to your PATH.

After installing Python, disable Windows 10's alias for Python.

python --version

Should print this (or a newer version):

Python 3.8.3

Next, clone the emsdk - This is kind of like choosenim which will install the actual emcc compiler.

git clone https://github.com/emscripten-core/emsdk.git
cd emsdk

Lets install emcc - the actual compiler we will be using.

./emsdk install latest
./emsdk activate latest
./emsdk_env.bat
cd ..

Macos

Mac is much easier. We can use brew to install emscripten.

brew install emscripten

Linux

Linux is also easy. We can use apt to install emscripten.

sudo apt install emscripten

Step 0: Making sure Emscripten can compile C:

After the installation is complete, change directories into a clone of this repo and install the dependencies:

git clone https://github.com/treeform/nim_emscripten_tutorial
cd nim_emscripten_tutorial
nimble install

Now inside of the tutorial folder, lets compile a basic C program to make sure it works:

emcc step0.c -o step0.html

To view the files we need to run a webserver. The easiest one to run is the python simple server:

python -m http.server 8000

Note: If compiling with threads then you need extra headers when serving the files (See here for details)

Cross-Origin-Opener-Policy: same-origin
Cross-Origin-Embedder-Policy: require-corp

Next, open a browser to the step0 page: http://localhost:8000/step0.html

You should see the Emscripten default chrome:

step0.c with emscripten

Make sure you got the Hello, world! in the console.

To remove the ugly Emscripten default chrome, you need to use your own minimal html. I provided one in this repo, just call:

emcc step0.c -o step0.html --shell-file shell_minimal.html

step0.c with emscripten

Now the Hello, world! in the JS console.

Step 1: Using Nim with Emscripten.

Next lets try Nim, look at the very simple step1.nim:

echo "Hello World, from Nim."

Most of the work will be done but the step1.nims file:

if defined(emscripten):
  # This path will only run if -d:emscripten is passed to nim.

  --nimcache:tmp # Store intermediate files close by in the ./tmp dir.

  --os:linux # Emscripten pretends to be linux.
  --cpu:wasm32 # Emscripten is 32bits.
  --cc:clang # Emscripten is very close to clang, so we ill replace it.
  when defined(windows):
    --clang.exe:emcc.bat  # Replace C
    --clang.linkerexe:emcc.bat # Replace C linker
    --clang.cpp.exe:emcc.bat # Replace C++
    --clang.cpp.linkerexe:emcc.bat # Replace C++ linker.
  else:
    --clang.exe:emcc  # Replace C
    --clang.linkerexe:emcc # Replace C linker
    --clang.cpp.exe:emcc # Replace C++
    --clang.cpp.linkerexe:emcc # Replace C++ linker.
  when compileOption("threads"):
    # We can have a pool size to populate and be available on page run
    # --passL:"-sPTHREAD_POOL_SIZE=2"
    discard
  --listCmd # List what commands we are running so that we can debug them.

  --gc:arc # GC:arc is friendlier with crazy platforms.
  --exceptions:goto # Goto exceptions are friendlier with crazy platforms.
  --define:noSignalHandler # Emscripten doesn't support signal handlers.

  # Pass this to Emscripten linker to generate html file scaffold for us.
  switch("passL", "-o step1.html --shell-file shell_minimal.html")

Lets compile it!

nim c -d:emscripten step1.nim

Lets go to step1.html, this is how it should look: http://localhost:8000/step1.html

step1

Take note of the console output with Hello World, from Nim..

Nim with OpenGL.

We can do a ton of stuff with just "console" programs, but what Emscripten is all about is doing graphics. We can use normal OpenGL, and Emscripten will convert it to WebGL. We can also use normal SDL or GLFW windowing and input library and Emscripten will convert it to HTML events for us. Emscripten also gives us a "fake" file system to load files from. Many things that would be missing from just having WASM running in the browser we get from free with Emscripten.

I will be using GLFW for my examples. I will be using https://github.com/treeform/staticglfw because it has been made to work with Emscripten.

See: step2.nim

First lets make sure it runs in normal native mode:

nim r step2.nim

Because native mode is faster to compile and more performant, I recommend developing in native mode and then compiling to the browser for compatibility.

step2

You should just see a window with changing background color.

Now lets try it with -d:emscripten:

nim c -d:emscripten step2.nim

Again a ton of work is happening in the settings file step2.nims.

Lets go take a look: http://localhost:8000/step2.html

step2

Again you should see red window with pulsating color.

Step3: Nim with OpenGL Triangle.

The step3.nim is more complex as it requires loading shaders and setting up a triangle to draw. It also in includes a directory in a virtual files system: --preload-file data which generates a file called step3.data which is loaded right before a module is run. It also handles resizing of window as well.

Again see it run natively:

nim r step3.nim

step3b

Then compile it for the browser:

nim c -d:emscripten step3.nim

And see it run: http://localhost:8000/step3.html

step3a

Step 4: Nim with Windy and Boxy.

The step4.nim is a simple example of using Windy and Boxy to draw a simple with rotating circles on a gradient background.

First lets run it natively:

nim r step4.nim

step4a

nim c -d:emscripten step4.nim

And see it run: http://localhost:8000/step4.html

step4b

Boxy is a powerful library for drawing graphics in the browser. They can load many image formats, have layering, masking, blending, and can even render fonts!

About

Nim emscripten tutorial.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 5