-
Notifications
You must be signed in to change notification settings - Fork 355
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Compilation to WASM? #722
Comments
I think a first step would be to create a new codegen backend which doesn't actually do any codegen and just dumps the metadata. That way we should be able to build a rustc which doesn't depend on llvm or other C code. |
I had created one in the past but it bitrotted and it was unused, so I removed it in rust-lang/rust#58847. If you copy https://github.com/bjorn3/rustc_codegen_cranelift/blob/11d816c/src/lib.rs#L182-L190 into Another thing necessary is replacing the |
I want to do the same for https://github.com/bjorn3/rustc_codegen_cranelift/, but I want it to pass the rustc test suite first and |
Intriguing. :) I should add one warning though: Miri isn't a fast interpreter. It's really slow. So I don't think it is actually a good environment to use to run code, I see it as more useful for debugging and testing. But, don't let me stop you! I just felt I should give you a fair warning. And if ideas like this leak to people making Miri lightning fast while maintaining all the UB checking, I'll be even more happier. :D |
That's understandable, but I think it's ought to be good enough for typical playground snippets :) |
I guess that's one way, although I was wondering if Miri actually needs the main |
The codegen backend is necessary for |
Fair enough. |
I am currently trying to compile rustc for wasm (https://github.com/bjorn3/rust/tree/compile_rustc_for_wasm), but I am hitting a compiler bug: rust-lang/rust#60540. |
@bjorn3 I've rebased your branch onto master, updated deps and fixed cfg's from Eventually it compiled successfully, but then ran into the same runtime validation issue with invalid code generated by Rust. However, I recompiled in release mode and then it passed validation! That got me thinking it should work now, but running the generated file with |
@bjorn3 Oh... maybe it's just been taking so long (especially the compilation part). I've tried
|
Yes, it takes several minutes to compile it using
🎉 🎉 🎉
I tried actually compiling something, but it errors with:
I am currently trying to figure out were it errors. |
Places needing patching:
Edit: pushed bjorn3/rust@15f980f (based on @RReverser's branch). Now it errors at
Which is expected, as I had to remove the codegen backend dynamic loader. Will try to get https://github.com/bjorn3/rustc_codegen_cranelift to work with it. |
This needs a rustc compiled for wasi (see rust-lang/miri#722) It also needs bytecodealliance/target-lexicon#14
FWIW previously (before even filing this issue) I tried compiling rustc with Emscripten instead, which should, in theory, reduce number of these places to patch, as it supports a bit more than WASI does. Haven't gotten too far though, because I tried to build completely unpatched rustc and there were few things that still didn't compile and probably needed similar fixes as in your branch.
I thought the plan was to build it without any codegen, just with miri? Or do you want to build an actual full rustc? |
I want them both. :) I currently have |
Yeah for that I think you'll need to do the proper build (via |
Seems like it doesn't even reach the rustc version check for the libraries. I added |
Switching from wasmer to wasmtime fixed it. It even got to the beginning of codegen. Edit: filled wasmerio/wasmer#434. |
I am currently working on making miri compile for wasi, which this issue was actually about. |
It seems to trap while calling the
I pushed the wip stuff to my branch. |
@bjorn3 Left a comment on your MIRI commit on your branch. |
@bjorn3 But also, I'm not sure why rustc is now depending on miri... shouldn't it be the other way around? (like in non-WASI version) |
I did that to be able to prevent having to recompile every rustc crate, which is slow and to prevent having to copy all files in the dir layout rustc wants a sysroot to be. |
I'm not sure I understand what you're saying... neither should be affected by which crate you compile as an entry point. I've changed my local copy of Rust & MIRI to do just that, and got |
I meant that I had already compiled all crates in |
I took https://github.com/bjorn3/browser_wasi_shim/blob/main/examples/rustc.html and made it invoke the miri I built from the second to last commit of the compile_rustc_for_wasm13 branch instead. |
For others trying to run it, thats
|
Somehow no one pasted this here: https://garriga.dev/rubri/
cc @LyonSyonII |
New version available at the compile_rustc_for_wasm16 branch of https://github.com/bjorn3/rust. @oligamiq created a PR to use @whitequark's LLVM fork, so it should now be able to build for wasm, though I haven't tested linking yet. It also currently requires using wasm32-wasip1-threads, which doesn't work with browser_wasi_shim yet. You can still use the cg_clif backend with wasm32-wasip1 without threads instead by omitting |
FWIW, I'm happy to see this effort and will support it from my side as much as I'm able to. Let me know if you need any further adjustments LLVM-side (though I'm sorta waiting on consensus on handling pthreads shims in wasi-libc at the moment). |
The pthread shims thing (or adding wasip1-threads support to browser_wasi_shim) is the biggest blocker for getting this working in the browser. For complete end-to-end execution in the browser, lld would also need to be supported. I haven't checked if it already works though. Would need to rebuild LLVM again to check. And I did probably need to patch the rust standard library to support a custom host call for spawning processes such that rustc can actually invoke lld. |
Regarding
However, since no thread pool has been created and files are accessible from multiple workers, the speed has significantly dropped... I feel bad for Bjorn since I continued working after submitting the pull request when I made the file system accessible from multiple workers. Currently, I'm working on a different branch. ※Require SharedArrayBuffer |
I hadn't looked at your browser_wasi_shim PR yet as I assumed it to be under heavy development. Let me know when it is ready for review/ready for me to try it out. |
I've looked into that. Ideally, LLD would be built as a library and linked into the rustc binary. LLD already has a function you can call to run its main routine in-process, so you should probably use that instead of a hostcall; this has the advantage that the resulting |
Do you have any pointers on how to do that?
Be aware that rustc.wasm is pretty large at 134MB. And it needs another 72MB for the standard library compiled to wasm32-wasip1-threads. |
How familiar are you with LLVM? You're looking to call
That sounds about right. I woulde expect LLD to add ~50M more, so ~250M before compression, maybe ~100M after. In my view this is still worth it since the object can be cached indefinitely at the client. The distribution infrastructure I'm using supports such large packages just fine. Have you seen my FPGA toolchain integration with VS Code? The packages used in the demo are a ~50M download in total (from memory), which is a little high but is fine if you have broadband. ~100M of rustc isn't such a stretch, and I was planning on shipping yowasp-clang that would be of a similar size, anyway. |
Is enabling building of the lld standalone tool enough to build whatever static library I need to link against for |
I think so, since the lld executable is a really thin wrapper (which is, iirc, autogenerated) over the function I linked to. But I would personally still scour the build system to see which target it is that does it. |
So after looking into it, I think you should probably build the |
Managed to get linking using lld working: bjorn3/rust#8 |
I also use miri (and a few other solutions) here to run various programming languages in the browser: https://x0k.github.io/ppp/editor |
And you can use the YoWASP VS Code toolchain if you want a full editor in your browser when running programming language compilers. |
https://github.com/oligamiq/rubrc @bjorn3 Also, regarding the environment variable WASI_SYSROOT, it is required by cc, so it cannot be removed. Although the compilation can still proceed without it, unresolved imports such as |
wasm32-wasip2 uses wasm-component-ld, which is a wrapper around lld. It should be possible to integrate it directly into rustc, though depending on how exactly wasm-component-ld is designed, it may require patching wasm-component-ld itself. As for native targets, it is harder than conventional cross-compilation as those generally depend on gcc or clang wrapping the linker. |
LLVM's ELF, COFF, and Mach-O linker should be included as well, but is there no way to make use of them? |
You can use lld for non-wasm targets with rustc.wasm, but on Unix targets you don't normally directly invoke the linker. Instead what you invoke is gcc or clang, which in turn invoke the linker with the right arguments. Rustc doesn't (yet) support directly invoking the linker for Unix targets as it doesn't know all the arguments that are necessary to successfully link that gcc or clang would pass to the linker. |
Oh, it seems I may need to pull in Clang or contribute to the Rustc code. |
I changed the arguments, and successfully compiled for x86_64-unknown-linux-musl. I was also able to run the downloaded file locally without any issues. I would appreciate it if you could kindly share the source of this information. |
For musl specifically rustc has most knowledge builtin for the self-contained mode. You may be missing certain security mitigations though. For pretty much every other Unix target it doesn't have builtin knowledge. |
I've been using some of the rustc.wasm's that folks have produced in this issue, and wanted to ask a few questions and maybe help out if I can. 1.) Is the 2.) I have access to an x86 machine, but unlimited access to an apple machine. Is there anything other than the config.toml's in these branches that is linux specific? I've modified the config and replaced an elf var with macho, and am able to produce a rustc.wasm on apple silicon, though it doesn't successfully compile rust it seems. To do so though I have to comment out this assertion as I guess the 3.) I found the exchange below slightly confusing:
It seems to indicate that you've used the linker when targeting wasm32-wasip1 @oligamiq?, but also @bjorn3 and the comment.txt files seem to indicate that that isn't supported? For my use case, I'm primarily interested in targeting wasm32-wasip1 rather than wasm32-wasip2, but want to make heavy use of linking. Given that, is it expected that in it's current state, the latest rustc.wasm can be used with lld to link crates when targeting p1? Or would that require building with
Thanks! |
If I recall correctly there is not much difference between the two other than a rebase. I currently use compile_rustc_for_wasm17 as scratchpad that I force-push to occasionally until there are significant changes to announce here, at which point I switch to working on a new branch.
I don't think there is anything linux specific, but it's been a while since I last looked.
This exchange was about using the produced rustc.wasm to compile binaries for wasm. rustc.wasm itself needs to be compiled for wasm32-wasip1-threads for the time being. (It might start to work with minor changes on wasm32-wasip1 with the next wasi-sdk, but that depends on if the emulated C++ mutexes for single threaded wasm land before wasi-sdk does a new release or not.) |
As far as I know, it was broken due to the rustc update two weeks ago.
I’m not familiar with macOS, so I don’t know.
In compile_rustc_for_wasm16, it should have been possible to compile directly to .wasm using the wasm-ld that was included by default, but the arguments might have been incorrect. This is an example of the compile command:
rustc doesn't properly recognize the --sysroot option. For example, even if you add the --sysroot argument to rustc -vV, it is not used. This causes the error. Currently, there is no workaround, and you will need to force an overwrite as shown in |
Miri maintainer note: this is a fun project, but not something we currently intend to support officially. To keep maintenance manageable, Miri only supports running on platforms that rustc supports running on.
Compiling the whole Rustc to WASM is a pretty big undertaking for many reasons.
However, Miri doesn't need an actual codegen and many other parts of the whole Rustc, so I wonder how realistic it would be to compile it and the pieces it depends on to WASM instead? Are there any obvious blockers?
Mostly opening this to gauge interest and estimate complexity, as I believe there is an interest in running Rust directly in the browser on playground-like websites.
P.S. Despite what I said in the first sentence, this was actually done for Clang a while ago - https://tbfleming.github.io/cib/ - which includes LLVM compiled to WASM that, in turn, generates more WASM dynamically during runtime. In theory, it should be possible to do the same for Rust, especially since they share LLVM, but for now having just an interpreter could already be an interesting starting goal.
The text was updated successfully, but these errors were encountered: