GithubHelp home page GithubHelp logo

rusdlem's Introduction

RuSDLem - A minimal Rust program using SDL2 to target Emscripten and the web

There are a number of tutorials out there with the goal of showing how to use Rust and its SDL2 bindings graphics library to build programs with a web target. Unfortunately, most of them have developed bit rot over the years. You should use those tutorials as the guide to get a general sense for how things should work. This example shows a minimal working solution as of November of 2021, with the quirks of getting it to compile ironed out. You can see the example in action at:

https://gregbuchholz.github.io/

Hover over large grey square with the blue diagonal line, and you should see a red line drawn from the upper left corner of the canvas to where the mouse cursor is.

You will need Emscipten installed and your path updated to point to the installation (Unix-like: source emsdk_env.sh or on Windows: emsdk_env.bat in your emscripten folder). If you want to run SDL programs locally, you will also need the SDL2 libraries installed. Emscripten already has the SDL2 libraries included for its own internal use.

Grab this repository:

git clone https://github.com/gregbuchholz/RuSDLem

One or both of the Emscripten targets will need to be added to your Rust setup:

rustup target add asmjs-unknown-emscripten
rustup target add wasm32-unknown-emscripten

...then verify things work locally as a desktop app with:

cd rusdlem
cargo run

...followed by...

em++ -c gxx_personality_v0_stub.c

...in the src/ directory to produce a stub gxx_personality_v0_stub.o in src/. Then build the project with:

cargo build --target=wasm32-unknown-emscripten --release

..and finally run a web server with:

emrun index-wasm.html

...which should start a web browser and bring up a page with the newly compiled instance. Or use the following if you are interested in asmjs...

cargo build --target=asmjs-unknown-emscripten --release
emrun index-asmjs.html

Enjoy!

===========

Further Details

Here are a few more details about the various pieces that are necessary but aren't described in other places. The .cargo/config file has lines like the following:

[target.asmjs-unknown-emscripten]
rustflags = [
    "-C", "link-args=src/gxx_personality_v0_stub.o -sUSE_SDL=2 -s ASYNCIFY -s ALLOW_MEMORY_GROWTH=1",
]

The ALLOW_MEMORY_GROWTH=1 isn't needed for this small example, but it does become necessary if you start using larger bitmaps/render targets. The symptoms are mysterious memory allocation failure assertions reported by the browser coming from the JS. Apparently there is a 16 MiB heap limit hardcoded into Emscripten that this alleviates. With all the back buffers, etc, it doesn't take much to reach this limit.

ASYNCIFY enables Asyncify, which for this example has strategic calls to emscripten_sleep() which enables the browser's main loop to have control periodically and this means we don't have to deal with set_main_loop and friends. You'll also notice the:

#[cfg(target_os = "emscripten")]
let _ = sdl2::hint::set("SDL_EMSCRIPTEN_ASYNCIFY","1");

...before the sdl2::init() in the main.rs file.

The gxx_personality_v0_stub.cpp file is there to work around the issue described at: https://stackoverflow.com/a/69198170 Without it, you'll probably get a message similar to the following:

= note: error: undefined symbol: __gxx_personality_v0 (referenced by top-level compiled C/C++ code)
        warning: Link with `-s LLD_REPORT_UNDEFINED` to get more information on undefined symbols
        warning: To disable errors for undefined symbols use `-s ERROR_ON_UNDEFINED_SYMBOLS=0`
        warning: ___gxx_personality_v0 may need to be added to EXPORTED_FUNCTIONS if it arrives from a system library
        Error: Aborting compilation due to previous errors

If you don't include --release on the emscripten builds, you might wind up with an error message:

= note: emcc: warning: please replace -g4 with -gsource-map [-Wdeprecated]
        emcc: error: wasm2js does not support source maps yet (debug in wasm for now)

The versions that this was know to work with:

$ rustc --version
rustc 1.55.0 (c8dfcfe04 2021-09-06)

$ emcc --version
emcc (Emscripten gcc/clang-like replacement + linker emulating GNU ld) 2.0.31 (4fcbf0239ccca29771f9044c990b0d34fac6e2e7)
Copyright (C) 2014 the Emscripten authors (see AUTHORS.txt)
This is free and open source software under the MIT license.
There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

rusdlem's People

Contributors

gregbuchholz avatar

Stargazers

 avatar  avatar  avatar  avatar

Watchers

 avatar

Forkers

alexpogue

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.