MLX42 supports compilation towards WASM. What this means is you can run any application written in C directly in the browser! This overcomes a lot of issues with for instance showing projects towards others or have an environment where building natively just won't work.
In this README you will learn how to compile your project towards Webassembly and later deploy it on github!
- Emscripten, you can install this via brew or read the instructions they provide for Windows or Linux
Once you made sure you have emscripten installed (check if emcc
and emcake
work).
Run:
emcmake cmake -B build && cmake --build build --parallel
You're only required to do a few modifications to your main.c
.
For this we will use the demo main provided in the root readme.
Add the following headers at the top:
#include <emscripten/html5.h>
#include <emscripten/emscripten.h>
Modify your main:
// Invoked instead of mlx_loop directly.
void emscripten_main_loop() {
mlx_loop(mlx);
}
int32_t main(int argc, char **argv)
{
// Gotta error check this stuff
if (!(mlx = mlx_init(WIDTH, HEIGHT, "MLX42", true)))
{
puts(mlx_strerror(mlx_errno));
return(EXIT_FAILURE);
}
if (!(image = mlx_new_image(mlx, 128, 128)))
{
mlx_close_window(mlx);
puts(mlx_strerror(mlx_errno));
return(EXIT_FAILURE);
}
if (mlx_image_to_window(mlx, image, 0, 0) == -1)
{
mlx_close_window(mlx);
puts(mlx_strerror(mlx_errno));
return(EXIT_FAILURE);
}
mlx_loop_hook(mlx, ft_randomize, mlx);
mlx_loop_hook(mlx, ft_hook, mlx);
// This function will set up the main loop
emscripten_set_main_loop(emscripten_main_loop, 0, true);
mlx_terminate(mlx);
return (EXIT_SUCCESS);
}
Thats actually it! It may or may not be necessary to modify your own source code depending on what you do but that's most often not the case. It is that easy to just re-deploy your own app into webassembly.
# Compile C into JS/WASM
emcc -O3 -I include -I mlx -pthread main.c \
-o ./web/demo.js \
./build/libmlx42.a \
-s USE_GLFW=3 -s USE_WEBGL2=1 -s FULL_ES3=1 -s WASM=1 \
-s NO_EXIT_RUNTIME=1 -s EXPORTED_RUNTIME_METHODS='["ccall", "cwrap"]' \
-s ALLOW_MEMORY_GROWTH
# Navigate into the web folder (if you're running this directly from this repo)
cd web
# Launch local webserver, this is required to make the service worker function.
python3 -m http.server 8000
Once the server is up and running all you need to do now is go to localhost. There you can locally develop your application without having to do any git commits or actions shenanigans.
For a free, quick and easy hosting solution you can realistically deploy this anywhere. However for now we will only focus on putting this up via github pages.
What you need in your repository is a .github/workflows/static.yml
file.
It can be named anything static
, ci
, whatever. Later on if you learn more about CI Pipelines you can use this to do a lot of useful things.
Once selected, you need to commit an actions file.
For now you can copy paste MLX42's wasm.yml
file which functionally does the exact same.
# Simple workflow for deploying static content to GitHub Pages
name: Deploy static content to Pages
on:
push:
branches: ["master"] # Change to main or whatever fancy name
workflow_dispatch:
permissions:
contents: read
pages: write
id-token: write
# Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued.
# However, do NOT cancel in-progress runs as we want to allow these production deployments to complete.
concurrency:
group: "pages"
cancel-in-progress: false
# Single deploy job since we're just deploying
jobs:
deploy:
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
runs-on: ubuntu-latest
#TODO: add a build step to get the wasm file instead of commiting it.
#Doesn't really matter atm since the git history is polluted anyway
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Pages
uses: actions/configure-pages@v5
- name: Upload artifact
uses: actions/upload-pages-artifact@v3
with:
path: './web' # <= Set this variable to the directory relative to the root of the repo.
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v4
Once you commit this file github will do it's magic and create a deployment. You should then get a link to where you can access you program. Now you can access your app anywhere!