{"id":18802995,"url":"https://github.com/scristobal/cross-compiling-rust-c-wasm-zig","last_synced_at":"2025-04-13T18:22:50.221Z","repository":{"id":223015196,"uuid":"758983007","full_name":"scristobal/cross-compiling-rust-c-wasm-zig","owner":"scristobal","description":"Cross compiling Rust + C codebase to Web Assembly (web and WASI) using Zig","archived":false,"fork":false,"pushed_at":"2024-10-22T19:45:39.000Z","size":67,"stargazers_count":13,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-04-10T09:05:41.988Z","etag":null,"topics":["c","crosscompile","rust","wasi","wasm","webassembly","zig"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/scristobal.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-02-17T16:39:09.000Z","updated_at":"2025-02-01T17:46:11.000Z","dependencies_parsed_at":"2024-03-21T17:29:06.663Z","dependency_job_id":"0d3387fd-eb06-4ed7-a9e5-04d2b8e33dd4","html_url":"https://github.com/scristobal/cross-compiling-rust-c-wasm-zig","commit_stats":null,"previous_names":["scristobal/cross-compiling-rust-c-wasm-zig"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/scristobal%2Fcross-compiling-rust-c-wasm-zig","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/scristobal%2Fcross-compiling-rust-c-wasm-zig/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/scristobal%2Fcross-compiling-rust-c-wasm-zig/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/scristobal%2Fcross-compiling-rust-c-wasm-zig/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/scristobal","download_url":"https://codeload.github.com/scristobal/cross-compiling-rust-c-wasm-zig/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248759135,"owners_count":21157096,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["c","crosscompile","rust","wasi","wasm","webassembly","zig"],"created_at":"2024-11-07T22:32:35.892Z","updated_at":"2025-04-13T18:22:50.193Z","avatar_url":"https://github.com/scristobal.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Crosscompile a Rust project with C dependencies into Web Assembly (WASM and WASI) using Zig\n\nEasy way using [rust-bindgen](https://github.com/rust-lang/rust-bindgen) and [cargo-zigbuild](https://github.com/rust-cross/cargo-zigbuild) CLI tools.\n\n### Generate Rust bindings for the C code\n\nWe just need the C/C++ header files wit the definitions and [rust-bindgen](https://github.com/rust-lang/rust-bindgen) will generate the Rust FFI bindings.\n\n```bash\nbindgen some-c-code/gcd.h -o src/bindings.rs # generate Rust FFI bindings for gcd.h\n```\n\n### Quick WASI try out\n\nUsing [zigbuild](https://github.com/rust-cross/cargo-zigbuild) we can cross compile to WASI \n\n```bash\nrustup target add wasm32-wasip1 # make sure wasm32-wasi target is installed \ncargo zigbuild --target=wasm32-wasip1 --release # cross compile to WASI, release flag is optional\n```\n\n\u003e [!warning]\n\u003e Previously the target `wasm32-wasip1` was `wasm32-wasi` but it is now being deprecated, still you might want to use it even if you [get some warnings](https://blog.rust-lang.org/2024/04/09/updates-to-rusts-wasi-targets.html#renaming-wasm32-wasi-to-wasm32-wasip1).\n\nwe can try it with [wasm3](https://github.com/wasm3/wasm3) engine \n\n```bash\nwasm3 target/wasm32-wasip1/release/rust-ffi-playground.wasm # try it out, requires wasm3 \n```\n\nor [wasmi](https://github.com/wasmi-labs/wasmi)\n\n```bash\nwasmi_cli target/wasm32-wasip1/release/rust-ffi-playground.wasm # run it with wasmi runtime\n```\n\n\n### Cross compile for web (WASM)\n\nGenerate code for WASM with [zigbuild](https://github.com/rust-cross/cargo-zigbuild), and then use [wasm-bindgen](https://github.com/rustwasm/wasm-bindgen) to generate the js/ts bindings to the WASM code.\n\n```bash\ncargo zigbuild --target=wasm32-unknown-unknown --release # cross compile to WASM, release flag is optional\nwasm-bindgen target/wasm32-unknown-unknown/release/rust-ffi-playground.wasm --out-dir ./dist --target web # generate JS and TS FFI bindings into WASM code\n```\n\nTo try it, manually include the script tag to load and initialize the wasm module\n\n```html\n\u003cscript type=\"module\"\u003e\n  import init from \"./bin/rust-ffi-playground.js\";\n  init().then(() =\u003e console.log(\"WASM Loaded\"));\n\u003c/script\u003e\n```\n\nor use a WASM plugin like [`vite-plugin-wasm`](https://www.npmjs.com/package/vite-plugin-wasm) or use [Trunk](https://trunkrs.dev/)\n\nNote: As in this [github issue](https://github.com/rustwasm/team/issues/291#issuecomment-644946504) it can be compiled to `wasm32-unknown-emscripten`.\n\nSame [example](https://github.com/rustwasm/team/issues/291#issuecomment-645492619) but using `wasm-pack`, hence `wasm-bindgen` instead\n\n### Going further\n\nNot a trivial project, eg. building a native library, link to a system library...\n\nReplace CLI commands with a simple `Makefile` or (even  better) a `builder.rs` file, eg. use `cargo_zigbuild` and `bindgen` directly in `build.rs` by replacing `cc` with `zigbuild`\n\n```rust\nuse cargo_zigbuild::Zig::Cc;\nuse std::{env, error::Error};\n\nfn main() -\u003e Result\u003c(), Box\u003cdyn Error\u003e\u003e {\n    cc::Build::new().file(\"some-c-code/def.c\").compile(\"def\");\n\n    let out_dir = env::var(\"OUT_DIR\").unwrap();\n\n    let cc = Cc {\n        args: vec![\n            format!(\"some-c-code/def.c\"),\n            \"-c\".to_string(),\n            \"-o\".to_string(),\n            format!(\"{}/def.o\", out_dir),\n        ],\n    };\n\n    cc.execute().expect(\"Failed to compile def.c\");\n\n    let ar = cargo_zigbuild::Zig::Ar {\n        args: vec![\n            \"crus\".to_string(),\n            format!(\"{}/libdef.a\", out_dir),\n            format!(\"{}/def.o\", out_dir),\n        ],\n    };\n\n    ar.execute().expect(\"Failed to create def.a\");\n\n    println!(\"cargo:rustc-link-search=native={}\", out_dir);\n    println!(\"cargo:rustc-link-lib=static=def\");\n\n    println!(\"cargo:rerun-if-changed=some-c-code\");\n    println!(\"cargo:rerun-if-changed=build.rs\");\n    Ok(())\n}\n```\n\n## References\n\n- [The `cc-rs` project](https://crates.io/crates/cc)\n- [Official cargo reference](https://doc.rust-lang.org/cargo/reference/build-script-examples.html)\n- Zig cross compilation\n- [Bindgen tutorial](https://rust-lang.github.io/rust-bindgen/tutorial-3.html)\n- [The embedded Rust book](https://docs.rust-embedded.org/book/interoperability/c-with-rust.html)\n- [Shrinking `.wasm` code size](https://rustwasm.github.io/docs/book/reference/code-size.html)\n\n## Issues\n\nwasm-bindgen targets `wasm32-unknown-unknown` and `wasi-unknown` do not (fully) support C-ABI, only older targets like `wasm32-unknown-emscripten`.\n\nSee [comment](https://github.com/rustwasm/team/issues/291#issuecomment-645482430), [comment](https://github.com/rustwasm/team/issues/291#issuecomment-645494771) and [documentation PR](https://github.com/rustwasm/wasm-bindgen/pull/2209)\n\nThere is an experimental flag `--Z wasm_c_abi=spec` that [circumvents this limitation](https://github.com/rustwasm/team/issues/291#issuecomment-2138201722)\n\n## Other tools\n\n- [c2rust](https://github.com/immunant/c2rust) - C to Rust translator produces `unsafe` Rust code from C99-compilant C code. It does not support cross compilation, but maybe it can with the help of Zig.\n\nFrom their website:\n\n\u003e C source code is parsed and typechecked using clang before being translated by our tool.\n\nwould it be possible to use it with Zig as a drop-in replacement for clang?\n\nFrom their README:\n\n\u003e I translated code on platform X, but it didn't work correctly on platform Y.\n\u003e We run the C preprocessor before translation to Rust. This specializes the code to the host platform. For this reason, we do not support cross compiling translated code at the moment.\n\u003e What platforms can C2Rust be run on?\n\u003e The translator and refactoring tool support both macOS and Linux. Other features, such as cross checking the functionality between C and Rust code, are currently limited to Linux hosts.\n\n## Utils\n\n- \u003chttps://wasm-feature-detect.surma.technology/\u003e [source](https://github.com/GoogleChromeLabs/wasm-feature-detect)\n\n---\n\n## Remarks\n\n\u003e In general, a `lib\u003cname\u003e.so` or `lib\u003cname\u003e.a` should be referenced in the build file by `\u003cname\u003e`.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fscristobal%2Fcross-compiling-rust-c-wasm-zig","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fscristobal%2Fcross-compiling-rust-c-wasm-zig","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fscristobal%2Fcross-compiling-rust-c-wasm-zig/lists"}