[HN Gopher] Show HN: How to compile C/C++ for WASM, pure Clang, ... ___________________________________________________________________ Show HN: How to compile C/C++ for WASM, pure Clang, no libs, no framework A little help for programmers, who wants to run C/C++ code in the browser. (This is my second attempt to show it, first time I got banned bcoz of my personal page domain, I don't really understand it why is is suspicious.) Author : ern0 Score : 120 points Date : 2022-04-11 16:35 UTC (6 hours ago) (HTM) web link (github.com) (TXT) w3m dump (github.com) | syrusakbary wrote: | This is really awesome, good work! | | We did a similar thing running Clang on the browser, which is now | uploaded to WAPM: https://wapm.io/syrusakbary/clang | hobo_mark wrote: | Excellent, I wonder if using a two year old LLVM fork is still | required, wasm support should be in trunk by now. | syrusakbary wrote: | Running Clang with WASI requires compiling LLVM to WASI | first, which unfortunately currently requires a fork (because | of the "hackyness" of it, as some syscalls are mocked or | certain code is just skipped). | | This talk from Ben Smith goes into a bit more depth on what | was required to change on LLVM to compile to WASI: | https://www.youtube.com/watch?v=5N4b-rU-OAA | gspr wrote: | Very cool! | | I've been desperately looking for something similar for Rust. I'm | too old for all these magic frameworks and "deployers" :-) | | I have some Rust code, possibly linking in some objects compiled | from C. How do I compile to wasm and deploy without magic? Any | pointers? | aquova wrote: | I made some emulators in Rust as a learning project during the | start of the pandemic, and ran into the exact same issue when I | wanted to make a wasm version to run in a browser. Eventually, | I was able to figure out how to do it, although I do use the | 'wasm-pack' Cargo package to assist with it (I think you can | get away without it if you're really motivated, you just need | to set up the targets and other elements yourself). Basically | you define some Rust API to expose whatever you need from your | project, then that and the project get compiled into one .wasm | binary and some (surprisingly readable) JavaScript "glue" gets | generated which allows for easy inclusion into a web page. It | works well for code in the std, but I've had issues with 3rd | party packages. | | It's focused on emulation development, but I wrote a document | that describes the process I followed: | https://github.com/aquova/chip8-book/blob/master/src/wasm.md | melony wrote: | This looks good! In my experience the hardest part for compiling | WebAssembly is third party dependencies. Getting arbitrary | libraries to build can be rather challenging. | jhgb wrote: | Getting arbitrary libraries to build is IMO quite often | challenging even if you're not compiling for WebAssembly. | eeegnu wrote: | It seems your first attempt to post this was flagged because the | domain name sounds like it'll act like a redirect, and the page | itself only had an image with no elaboration and just the link to | github. | 0x20cowboy wrote: | Not trying to steal your thunder, but here is another nostdlib | clang -> wasm example with malloc, a few math functions, rand, | and writing to a canvas doing animation. | | => https://github.com/robrohan/wefx | drfuchs wrote: | (Obligatory:) Neat! Still, a lot of copying bits around, and more | JS than one might hope for. Could you send a pointer to canvas | into the C code and operate on it in a direct, zero-copy way | there? | dosshell wrote: | directly when reading this code I cannot help myself but to get | into review-mode. It is an awesome example, which i will probably | use myself one day. | | However... | | inc.cpp:27 | | Gray is not the average of RGB, it is usally approximated with `Y | = 0.299 R + 0.587 G + 0.114 B`. | syrusakbary wrote: | For future readers, this is the code that is being referred: | | https://github.com/ern0/howto-wasm-minimal/blob/master/inc.c... | | It should be: uint32_t gray = 0.299 * ptr[i] | + 0.587 * ptr[i+1] + 0.114 * ptr[i+2]; ptr[i] = gray; | ptr[i+1] = gray; ptr[i+2] = gray; | Datagenerator wrote: | Marvelous example of the bikeshed effect | jhgb wrote: | That doesn't seem applicable unless there are bigger problems | to solve that are being ignored. | Asooka wrote: | Also, you must work in linear colour space. In OP's case you | would have to apply the inverse sRGB transform, do the | calculation, then apply the forward sRGB transform. Best if you | just work with linear colour end to end, if you have the memory | to spare. | david2ndaccount wrote: | I do a similar thing for my side project. Note that the clang | that comes with Xcode (Apple clang) doesn't have wasm support. | eatonphil wrote: | Meta comment: your committer email is not in sync with your | profile so the Github UI shows the commits attached to a blank | user. If you want these two in sync you can either add your | committing email to your Github account or you can modify your | git config to use your Github email as your commit email. | | Or you can just leave it as is too. :) | pulse7 wrote: | Is there a similar example for C? | nhatcher wrote: | Shameless plug: https://github.com/nhatcher/matrix-algebra | petters wrote: | See also my example I put together some time ago: | https://github.com/PetterS/clang-wasm | | At the time, I could not find something like this online. | | It's fun to write your own malloc! :-) | moefh wrote: | This is really cool! I never looked into WASM before, I'm really | happy to see it's not that difficult to build a simple example | like this. | | One thing that's bothering me about that code is the declaration | of `memory` as an uint8_t when it's clearly being used for its | address: extern uint8_t memory; | | And then in a _lot_ of places: uint8_t* ptr = | &memory; ptr[FOO] = BAR; | | Declaring `memory` as an array is much more idiomatic C, and | generates the exact same assembly: extern | uint8_t memory[]; | | And then memory[FOO] = BAR; | | I just tested it, and it seems to work exactly as one would | expect from a plain C linker (so there's no WASM magic I can | see). Am I missing something? | jstimpfle wrote: | Pedantically, it might even be undefined behaviour (not sure, | maybe a point of contention, similar to container_of macro). | It's unlikely to cause problems, but the way you suggested is | better (and can even be accompanied by a length field). | | Thank you to the author though! It is a nice little example. | hobo_mark wrote: | That is half of what I would need for a project, the other half | being Clang itself running in the browser (to use for teaching). | In theory there is [1] since many years, but in practice it never | worked for me (even now I get "Runtime error: memory access out | of bounds"). | | [1] https://tbfleming.github.io/cib/ | randomsilence wrote: | Do you know https://webassembly-studio.kamenokosoft.com/ ? | | I don't know if it compiles in the browser or on a server. | hobo_mark wrote: | That's fast! But it looks like it still needs a server, and | I'd rather avoid giving the internet arbitrary code execution | rights to some server I pay for and risk having my bill | explode or my account terminated for abuse. | randomsilence wrote: | Choose a supplier with a 100Mbit limit and unlimited | bandwidth. | hobo_mark wrote: | I'm way more worried about ending up hosting miners or | other malicious crap, Godbolt himself said users have | found all sorts of ways to escape the compiler explorer | sandbox over the years. I'd rather serve the compiler as | a static blob that runs in the browser. | mbrock wrote: | It's not ready just yet but if you're curious about Zig they're | going to have a nice self-hosted WebAssembly toolchain soon, | with no LLVM dependency. I'm really looking forward to it and | I'm happy to see the Zig compiler work making lots of progress | these days. I hope I'll be able to start playing with this in a | couple of weeks or so. | hobo_mark wrote: | I was quite excited about `zig cc (although I understand why | they would want to throw LLVM away), but despite what the | crab people shout all day I still need C++. | bialpio wrote: | This was a topic at CppCon'19 (seems like exactly the same use | case as you are describing: teaching!). Take a look at | https://www.youtube.com/watch?v=5N4b-rU-OAA. I think it relies | on the LLVM fork, so not sure how well it'll work for you, | quick web search points to: https://github.com/binji/llvm- | project. | aquova wrote: | If anyone is curious, I wrote a guide on Chip-8 emulation in | Rust, and the final step was building the emulator to work in a | browser via WASM. I do use a Cargo package to assist with targets | and compilation, but other than that it allows you to build and | load a wasm module into any old website. | | https://github.com/aquova/chip8-book/blob/master/src/wasm.md | bla3 wrote: | These are also good resources on using wasm without dependencies: | | https://depth-first.com/articles/2019/10/16/compiling-c-to-w... | | https://github.com/diekmann/wasm-fizzbuzz | jhgb wrote: | This is exactly what I needed. Thanks! ___________________________________________________________________ (page generated 2022-04-11 23:00 UTC)