[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)