mirror of
https://github.com/bytedream/litbwraw.git
synced 2025-05-08 19:55:13 +02:00
initial commit
This commit is contained in:
commit
96adaf3211
51
.github/workflows/deploy.yml
vendored
Normal file
51
.github/workflows/deploy.yml
vendored
Normal file
@ -0,0 +1,51 @@
|
||||
name: Deploy
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
pages: write
|
||||
id-token: write
|
||||
|
||||
concurrency:
|
||||
group: "pages"
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
deploy:
|
||||
environment:
|
||||
name: github-pages
|
||||
url: ${{ steps.deployment.outputs.page_url }}
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Install mdbook
|
||||
run: cargo install mdbook
|
||||
|
||||
- name: Install emscripten
|
||||
run: sudo apt-get install -y --no-install-recommends emscripten
|
||||
|
||||
- name: Add wasm32-unknown-emscripten toolchain
|
||||
run: rustup target add wasm32-unknown-emscripten
|
||||
|
||||
- name: Build book
|
||||
run: mdbook build
|
||||
|
||||
- name: Build playground
|
||||
run: BOOK_OUTPUT_PATH="$PWD/book" cargo build --release --manifest-path=lua-playground/Cargo.toml --target wasm32-unknown-emscripten
|
||||
|
||||
- name: Setup Pages
|
||||
uses: actions/configure-pages@v2
|
||||
|
||||
- name: Upload book
|
||||
uses: actions/upload-pages-artifact@v1
|
||||
with:
|
||||
path: ./book
|
||||
|
||||
- name: Deploy
|
||||
id: deployment
|
||||
uses: actions/deploy-pages@v1
|
6
.gitignore
vendored
Normal file
6
.gitignore
vendored
Normal file
@ -0,0 +1,6 @@
|
||||
.idea
|
||||
.vscode
|
||||
|
||||
book
|
||||
|
||||
lua-playground/target
|
21
LICENSE
Normal file
21
LICENSE
Normal file
@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) bytedream
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
38
README.md
Normal file
38
README.md
Normal file
@ -0,0 +1,38 @@
|
||||
<div align="center">
|
||||
<h1>Lua in the Browser, with Rust and WebAssembly</h1>
|
||||
<strong>This smol book describes how to use Lua in the Browser, powered by Rust WebAssembly.</strong>
|
||||
<h3><a href="https://bytedream.github.io/litbwraw/">Read the book</a></h3>
|
||||
</div>
|
||||
|
||||
## 🛠 Building the Book
|
||||
|
||||
The book is made using [`mdbook`](https://github.com/rust-lang-nursery/mdBook):
|
||||
```shell
|
||||
$ cargo install mdbook
|
||||
```
|
||||
Make sure the `cargo install` directory is in your `$PATH` so that you can run
|
||||
the binary.
|
||||
|
||||
To build it, simply run this command from this directory:
|
||||
```shell
|
||||
$ mdbook build
|
||||
```
|
||||
This will build the book and output files into the `book` directory. From
|
||||
there you can navigate to the `index.html` file to view it in your browser.
|
||||
|
||||
You could also run the following command to automatically build the book whenever you make changes to it in the `src` directory:
|
||||
```shell
|
||||
$ mdbook serve
|
||||
```
|
||||
|
||||
This book also contains a little demo/repl which is able to execute arbitrary Lua code in the browser via WebAssembly.
|
||||
To build the required files, run the following command:
|
||||
```shell
|
||||
$ BOOK_OUTPUT_PATH="$PWD/book" cargo build --release --target wasm32-unknown-emscripten --manifest-path=lua-playground/Cargo.toml
|
||||
```
|
||||
Make sure to run this command _after_ you build the book.
|
||||
Also, you have to re-run it everytime when the book is rebuilt.
|
||||
|
||||
## ⚖ License
|
||||
|
||||
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for more details.
|
13
book.toml
Normal file
13
book.toml
Normal file
@ -0,0 +1,13 @@
|
||||
[book]
|
||||
authors = ["bytedream"]
|
||||
language = "en"
|
||||
multilingual = false
|
||||
src = "src"
|
||||
title = "Lua in the Browser, with Rust and WebAssembly"
|
||||
|
||||
[output.html]
|
||||
additional-js = ["lua-playground/lua-playground-loader.js"]
|
||||
git-repository-url = "https://github.com/bytedream/litbwraw"
|
||||
|
||||
[output.html.playground]
|
||||
editable = true
|
373
lua-playground/Cargo.lock
generated
Normal file
373
lua-playground/Cargo.lock
generated
Normal file
@ -0,0 +1,373 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "2.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07"
|
||||
|
||||
[[package]]
|
||||
name = "bstr"
|
||||
version = "1.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "542f33a8835a0884b006a0c3df3dadd99c0c3f296ed26c2fdc8028e01ad6230c"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.0.83"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||
|
||||
[[package]]
|
||||
name = "either"
|
||||
version = "1.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07"
|
||||
|
||||
[[package]]
|
||||
name = "errno"
|
||||
version = "0.3.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "home"
|
||||
version = "0.5.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e3d1354bf6b7235cb4a0576c2619fd4ed18183f689b12b006a0ee7329eeff9a5"
|
||||
dependencies = [
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.151"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "302d7ab3130588088d277783b1e2d2e10c9e9e4a16dd9050e6ec93fb3e7048f4"
|
||||
|
||||
[[package]]
|
||||
name = "linux-raw-sys"
|
||||
version = "0.4.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c4cd1a83af159aa67994778be9070f0ae1bd732942279cabb14f86f986a21456"
|
||||
|
||||
[[package]]
|
||||
name = "lua-playground"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"mlua",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lua-src"
|
||||
version = "546.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2da0daa7eee611a4c30c8f5ee31af55266e26e573971ba9336d2993e2da129b2"
|
||||
dependencies = [
|
||||
"cc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "luajit-src"
|
||||
version = "210.5.3+29b0b28"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0c2bb89013916ce5c949f01a1fbd6d435a58e1d980767a791d755911211d792d"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"which",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.6.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167"
|
||||
|
||||
[[package]]
|
||||
name = "mlua"
|
||||
version = "0.9.2"
|
||||
source = "git+https://github.com/khvzak/mlua.git#0b9a85e1838bed67ae69f11b42de84bcf19da80c"
|
||||
dependencies = [
|
||||
"bstr",
|
||||
"mlua-sys",
|
||||
"num-traits",
|
||||
"once_cell",
|
||||
"rustc-hash",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "mlua-sys"
|
||||
version = "0.4.0"
|
||||
source = "git+https://github.com/khvzak/mlua.git#0b9a85e1838bed67ae69f11b42de84bcf19da80c"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"cfg-if",
|
||||
"lua-src",
|
||||
"luajit-src",
|
||||
"pkg-config",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-traits"
|
||||
version = "0.2.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "once_cell"
|
||||
version = "1.19.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92"
|
||||
|
||||
[[package]]
|
||||
name = "pkg-config"
|
||||
version = "0.3.27"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.70"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "39278fbbf5fb4f646ce651690877f89d1c5811a3d4acb27700c1cb3cdb78fd3b"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.33"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustc-hash"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
|
||||
|
||||
[[package]]
|
||||
name = "rustix"
|
||||
version = "0.38.28"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "72e572a5e8ca657d7366229cdde4bd14c4eb5499a9573d4d366fe1b599daa316"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"errno",
|
||||
"libc",
|
||||
"linux-raw-sys",
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.193"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "25dd9975e68d0cb5aa1120c288333fc98731bd1dd12f561e468ea4728c042b89"
|
||||
dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.193"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "43576ca501357b9b071ac53cdc7da8ef0cbd9493d8df094cd821777ea6e894d3"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.41"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "44c8b28c477cc3bf0e7966561e3460130e1255f7a1cf71931075f1c5e7a7e269"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
|
||||
|
||||
[[package]]
|
||||
name = "which"
|
||||
version = "5.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9bf3ea8596f3a0dd5980b46430f2058dfe2c36a27ccfbb1845d6fbfcd9ba6e14"
|
||||
dependencies = [
|
||||
"either",
|
||||
"home",
|
||||
"once_cell",
|
||||
"rustix",
|
||||
"windows-sys 0.48.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-sys"
|
||||
version = "0.48.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9"
|
||||
dependencies = [
|
||||
"windows-targets 0.48.5",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-sys"
|
||||
version = "0.52.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
|
||||
dependencies = [
|
||||
"windows-targets 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-targets"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c"
|
||||
dependencies = [
|
||||
"windows_aarch64_gnullvm 0.48.5",
|
||||
"windows_aarch64_msvc 0.48.5",
|
||||
"windows_i686_gnu 0.48.5",
|
||||
"windows_i686_msvc 0.48.5",
|
||||
"windows_x86_64_gnu 0.48.5",
|
||||
"windows_x86_64_gnullvm 0.48.5",
|
||||
"windows_x86_64_msvc 0.48.5",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-targets"
|
||||
version = "0.52.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8a18201040b24831fbb9e4eb208f8892e1f50a37feb53cc7ff887feb8f50e7cd"
|
||||
dependencies = [
|
||||
"windows_aarch64_gnullvm 0.52.0",
|
||||
"windows_aarch64_msvc 0.52.0",
|
||||
"windows_i686_gnu 0.52.0",
|
||||
"windows_i686_msvc 0.52.0",
|
||||
"windows_x86_64_gnu 0.52.0",
|
||||
"windows_x86_64_gnullvm 0.52.0",
|
||||
"windows_x86_64_msvc 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_gnullvm"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_gnullvm"
|
||||
version = "0.52.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cb7764e35d4db8a7921e09562a0304bf2f93e0a51bfccee0bd0bb0b666b015ea"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_msvc"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_msvc"
|
||||
version = "0.52.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bbaa0368d4f1d2aaefc55b6fcfee13f41544ddf36801e793edbbfd7d7df075ef"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnu"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnu"
|
||||
version = "0.52.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a28637cb1fa3560a16915793afb20081aba2c92ee8af57b4d5f28e4b3e7df313"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_msvc"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_msvc"
|
||||
version = "0.52.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ffe5e8e31046ce6230cc7215707b816e339ff4d4d67c65dffa206fd0f7aa7b9a"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnu"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnu"
|
||||
version = "0.52.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3d6fa32db2bc4a2f5abeacf2b69f7992cd09dca97498da74a151a3132c26befd"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnullvm"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnullvm"
|
||||
version = "0.52.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1a657e1e9d3f514745a572a6846d3c7aa7dbe1658c056ed9c3344c4109a6949e"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_msvc"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_msvc"
|
||||
version = "0.52.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04"
|
10
lua-playground/Cargo.toml
Normal file
10
lua-playground/Cargo.toml
Normal file
@ -0,0 +1,10 @@
|
||||
[package]
|
||||
name = "lua-playground"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[lib]
|
||||
crate-type = ["cdylib"]
|
||||
|
||||
[dependencies]
|
||||
mlua = { git = "https://github.com/khvzak/mlua.git", features = ["lua51"] }
|
23
lua-playground/build.rs
Normal file
23
lua-playground/build.rs
Normal file
@ -0,0 +1,23 @@
|
||||
use std::env;
|
||||
use std::path::PathBuf;
|
||||
|
||||
fn main() {
|
||||
let book_output_path = env::var("BOOK_OUTPUT_PATH").map_or(None, Some);
|
||||
|
||||
let out_dir = env::var("OUT_DIR").unwrap();
|
||||
let pkg_name = env::var("CARGO_PKG_NAME").unwrap();
|
||||
let target_path = PathBuf::from(out_dir)
|
||||
.parent()
|
||||
.unwrap()
|
||||
.parent()
|
||||
.unwrap()
|
||||
.parent()
|
||||
.unwrap()
|
||||
.to_path_buf();
|
||||
|
||||
println!("cargo:rustc-link-arg=-sEXPORTED_RUNTIME_METHODS=['cwrap','ccall']");
|
||||
println!("cargo:rustc-link-arg=-sEXPORT_ES6=1");
|
||||
println!("cargo:rustc-link-arg=-sERROR_ON_UNDEFINED_SYMBOLS=0");
|
||||
println!("cargo:rustc-link-arg=--no-entry");
|
||||
println!("cargo:rustc-link-arg=-o{}.js", book_output_path.map(PathBuf::from).unwrap_or(target_path).join(pkg_name).to_string_lossy());
|
||||
}
|
86
lua-playground/lua-playground-loader.js
Normal file
86
lua-playground/lua-playground-loader.js
Normal file
@ -0,0 +1,86 @@
|
||||
let luaStdout = null;
|
||||
let luaStderr = null;
|
||||
|
||||
async function run_lua_code(elem) {
|
||||
let result;
|
||||
if (!elem.nextElementSibling) {
|
||||
result = document.createElement('code');
|
||||
result.classList.add('result', 'hljs', 'language-bash');
|
||||
elem.after(result)
|
||||
} else {
|
||||
result = elem.nextElementSibling;
|
||||
}
|
||||
result.innerHTML = '';
|
||||
|
||||
if (window.luaInstance === undefined) {
|
||||
let wasm;
|
||||
try {
|
||||
wasm = await import(window.rootPath + '/lua-playground.js');
|
||||
} catch (e) {
|
||||
result.innerText = 'Failed to load wasm module: ' + e.toString();
|
||||
return;
|
||||
}
|
||||
|
||||
const module = {
|
||||
print(msg) {
|
||||
if (luaStdout) luaStdout(msg)
|
||||
},
|
||||
printErr(msg) {
|
||||
if (luaStderr) luaStderr(msg)
|
||||
}
|
||||
}
|
||||
const luaPlayground = await wasm.default(module);
|
||||
|
||||
window.luaInstance = luaPlayground.ccall('lua_new', 'number', [], []);
|
||||
window.luaExecute = luaPlayground.cwrap('lua_execute', null, ['number', 'string']);
|
||||
}
|
||||
|
||||
luaStdout = (msg) => result.innerHTML += msg + '<br>';
|
||||
luaStderr = (msg) => result.innerHTML += msg + '<br>';
|
||||
window.luaExecute(window.luaInstance, ace.edit(elem).getValue());
|
||||
luaStdout = null;
|
||||
luaStderr = null;
|
||||
}
|
||||
|
||||
function main() {
|
||||
const inputElements = document.querySelectorAll('.language-lua.editable');
|
||||
|
||||
for (const inputElem of inputElements) {
|
||||
const editor = ace.edit(inputElem);
|
||||
|
||||
/* adds the run and reset button */
|
||||
const buttons = inputElem.previousElementSibling;
|
||||
const resetButton = document.createElement('button');
|
||||
resetButton.classList.add('fa', 'fa-history', 'reset-button');
|
||||
resetButton.title = 'Undo changes';
|
||||
resetButton.ariaLabel = 'Undo changes';
|
||||
resetButton.onclick = () => editor.setValue(editor.originalCode.trim(), -1);
|
||||
buttons.prepend(resetButton);
|
||||
const runButton = document.createElement('button');
|
||||
runButton.classList.add('fa', 'fa-play', 'play-button');
|
||||
runButton.title = 'Run this code';
|
||||
runButton.ariaLabel = 'Run this code';
|
||||
runButton.onclick = () => run_lua_code(inputElem);
|
||||
buttons.append(runButton);
|
||||
|
||||
/* i don't know why, but the editor always has an extra newline. when selecting it and trimming it, the newline
|
||||
gets removed */
|
||||
editor.setValue(editor.originalCode.trim(), -1);
|
||||
}
|
||||
}
|
||||
|
||||
function reloadES6() {
|
||||
window.rootPath = document.currentScript.src.replace(/lua-playground\/lua-playground-loader\.js.*/, '')
|
||||
const injectScript = document.createElement('script');
|
||||
injectScript.type = 'module';
|
||||
injectScript.src = document.currentScript.src;
|
||||
document.body.append(injectScript);
|
||||
}
|
||||
|
||||
// this script is not loaded as es6 module, so it has to "elevate" itself to an es6 module by re-injecting itself with
|
||||
// the `reloadES6` function
|
||||
if (window.rootPath) {
|
||||
main()
|
||||
} else {
|
||||
reloadES6()
|
||||
}
|
18
lua-playground/src/lib.rs
Normal file
18
lua-playground/src/lib.rs
Normal file
@ -0,0 +1,18 @@
|
||||
use std::ffi::{c_char, CStr};
|
||||
use mlua::Lua;
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn lua_new() -> *mut Lua {
|
||||
let lua = Lua::new();
|
||||
Box::into_raw(Box::new(lua))
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn lua_execute(lua: *mut Lua, to_execute: *const c_char) {
|
||||
let lua: &mut Lua = &mut *lua;
|
||||
let to_execute = CStr::from_ptr(to_execute);
|
||||
|
||||
if let Err(err) = lua.load(&to_execute.to_string_lossy().to_string()).exec() {
|
||||
eprintln!("{}", err)
|
||||
}
|
||||
}
|
13
src/SUMMARY.md
Normal file
13
src/SUMMARY.md
Normal file
@ -0,0 +1,13 @@
|
||||
# Summary
|
||||
|
||||
[Introduction](./introduction.md)
|
||||
|
||||
- [Setup](./setup.md)
|
||||
|
||||
- [Tutorial](tutorial/introduction.md)
|
||||
- [Creating a project](tutorial/creating-a-project.md)
|
||||
- [Adding wasm logic](tutorial/adding-wasm-logic.md)
|
||||
- [Compiling](tutorial/compiling.md)
|
||||
- [Calling from Javascript](tutorial/calling-from-javascript.md)
|
||||
|
||||
- [Testing](./testing.md)
|
11
src/introduction.md
Normal file
11
src/introduction.md
Normal file
@ -0,0 +1,11 @@
|
||||
# Lua in the Browser, with Rust 🦀 and WebAssembly
|
||||
|
||||
This smol book describes how to use Lua in the Browser, powered by Rust WebAssembly.
|
||||
|
||||
> You should have basic knowledge of Rust, Rust FFI and Javascript, the book will not explain language features or constructs that are irrelevant to Rust WebAssembly.
|
||||
|
||||
---
|
||||
|
||||
```lua,editable
|
||||
print("Hello from WebAssembly Lua!")
|
||||
```
|
31
src/setup.md
Normal file
31
src/setup.md
Normal file
@ -0,0 +1,31 @@
|
||||
# Setup
|
||||
|
||||
Before we can start developing, a few prerequisites must be fulfilled.
|
||||
|
||||
## The Rust toolchain
|
||||
|
||||
```shell
|
||||
rustup target add wasm32-unknown-emscripten
|
||||
```
|
||||
|
||||
## The Emscripten compiler
|
||||
|
||||
To build for the `wasm32-unknown-emscripten` target, you need the [emscripten](https://emscripten.org/) compiler toolchain.
|
||||
|
||||
General install instructions are available [here](https://emscripten.org/docs/getting_started/downloads.html) or you look if your package manager has an emscripten package (some examples provided below).
|
||||
|
||||
_Debian_
|
||||
```shell
|
||||
sudo apt install emscripten
|
||||
```
|
||||
|
||||
_Arch Linux_
|
||||
```shell
|
||||
sudo pacman -S emscripten
|
||||
|
||||
# arch does not add the path to the emscripten executables to PATH, so it must be
|
||||
# explicitly added.
|
||||
# you probably want to add this to your bashrc (or any other file which permanently
|
||||
# adds this to PATH) to make it permanently available
|
||||
export PATH=$PATH:/usr/lib/emscripten
|
||||
```
|
32
src/testing.md
Normal file
32
src/testing.md
Normal file
@ -0,0 +1,32 @@
|
||||
# Testing
|
||||
|
||||
Testing is not very different from testing any other ordinary Rust crate.
|
||||
|
||||
When running tests, Rust tries to execute the generated Javascript glue directly which will result in an error.
|
||||
You have to specify the test runner which executes the Javascript, either in the `.cargo/config.toml` file (described [here]()) or via the `CARGO_TARGET_WASM32_UNKNOWN_EMSCRIPTEN_RUNNER` env variable to `node --experimental-default-type=module`.
|
||||
<br>
|
||||
If your crate is a library, you also have to remove the `-o<library name>.js` compiler option as it modifies the output filename which the Rust test suite can't track.
|
||||
Because the `test` subcommand compiles the tests as normal binaries, the Emscripten compiler automatically creates the js glue.
|
||||
|
||||
> Also, in the current stable Rust, you have to set the `-sERROR_ON_UNDEFINED_SYMBOLS=0` compiler option in order to avoid test compilation errors. This is due to an incompatibility between emscripten and the internal Rust libc crate ([rust-lang/rust#116655](https://github.com/rust-lang/rust/issues/116655)) but a fix for it should land in Rust 1.75 ([rust-lang/rust#116527](https://github.com/rust-lang/rust/pull/116527)).
|
||||
> Alternatively you can use the nightly toolchain, the fix is already present there.
|
||||
|
||||
With this done, we can create a simple test:
|
||||
```rust,ignore
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
#[test]
|
||||
fn lua_test() {
|
||||
let lua = mlua::Lua::new();
|
||||
lua.load("print(\"test\")").exec().unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
And then run it:
|
||||
```shell
|
||||
# you can omit '--target wasm32-unknown-emscripten' if you added the .cargo/config.toml
|
||||
# file as describe in the "Setup" section
|
||||
cargo test --target wasm32-unknown-emscripten
|
||||
```
|
37
src/tutorial/adding-wasm-logic.md
Normal file
37
src/tutorial/adding-wasm-logic.md
Normal file
@ -0,0 +1,37 @@
|
||||
# Adding wasm logic
|
||||
|
||||
Adding logic on the wasm / Rust side is very much just like writing a (C compatible) shared library.
|
||||
|
||||
Let's begin simple.
|
||||
This function creates a [Lua](https://docs.rs/mlua/latest/mlua/struct.Lua.html) instance and returns the raw pointer to it.
|
||||
```rust,ignore
|
||||
#[no_mangle]
|
||||
pub extern "C" fn lua_new() -> *mut mlua::Lua {
|
||||
let lua = mlua::Lua::new();
|
||||
Box::into_raw(Box::new(lua))
|
||||
}
|
||||
```
|
||||
|
||||
Alright, good.
|
||||
Now we have a Lua instance, but no way to use it, so let us create one.
|
||||
<br>
|
||||
The function takes the pointer to the Lua struct we create in the `new_lua` function as well as an arbitrary string, which should be lua code, as parameters.
|
||||
It then executes this string via the Lua instance and may write to `stderr` if an error occurs.
|
||||
```rust,ignore
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn lua_execute(lua: *mut mlua::Lua, to_execute: *const std::ffi::c_char) {
|
||||
// casting the raw pointer of the created lua instance back to a usable Rust struct
|
||||
let lua: &mut mlua::Lua = &mut *lua;
|
||||
// converting the c string into a `CStr` (which then can be converted to a `String`)
|
||||
let to_execute = std::ffi::CStr::from_ptr(to_execute);
|
||||
|
||||
// execute the input code via the lua interpreter
|
||||
if let Err(err) = lua.load(&to_execute.to_string_lossy().to_string()).exec() {
|
||||
// because emscripten wraps stderr, we are able to catch the error on the js
|
||||
// side just fine
|
||||
eprintln!("{}", err)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Okay, this looks great! In theory. So let's head over to the next page to see how to compile the code to make it actually usable via Javascript.
|
189
src/tutorial/calling-from-javascript.md
Normal file
189
src/tutorial/calling-from-javascript.md
Normal file
@ -0,0 +1,189 @@
|
||||
# Calling from Javascript
|
||||
|
||||
> The following code examples are expecting that the compiled glue and wasm files are available as `target/wasm32-unknown-emscripten/debug/my-project.js` and `target/wasm32-unknown-emscripten/debug/my-project.wasm`.
|
||||
|
||||
## Browser
|
||||
|
||||
> Note that opening the `.html` file as normal file in your browser will prevent the wasm from loading.
|
||||
> You have to serve it with a webserver. `python3 -m http.server` is a good tool for this.
|
||||
|
||||
The following html page will be used as reference in the Javascript code.
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>My Project</title>
|
||||
</head>
|
||||
<body>
|
||||
<div>
|
||||
<h3>Code</h3>
|
||||
<textarea id="code"></textarea>
|
||||
<button>Execute</button>
|
||||
</div>
|
||||
<div style="display: flex">
|
||||
<div>
|
||||
<h3>Stderr</h3>
|
||||
<div id="stderr" />
|
||||
</div>
|
||||
<hr>
|
||||
<div>
|
||||
<h3>Stdout</h3>
|
||||
<div id="stdout" />
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
First things first, we need to load the compiled wasm file.
|
||||
For this, we import the Javascript glue that is generated when compiling and loads and configures the actual wasm file.
|
||||
A custom configuration is fully optional, but needed if you want to do things like catching stdio.
|
||||
The configuration is done via the [Module](https://emscripten.org/docs/api_reference/module.html) object.
|
||||
```javascript
|
||||
// importing the glue
|
||||
const wasm = await import('./target/wasm32-unknown-emscripten/debug/my-project.js');
|
||||
// creating a custom configuration. `print` is equal to stdout, `printErr` is equal to
|
||||
// stderr
|
||||
const module = {
|
||||
print(str) {
|
||||
const stdout = document.getElementById('stdout');
|
||||
const line = document.createElement('p');
|
||||
line.innerText = str;
|
||||
stdout.appendChild(line);
|
||||
},
|
||||
printErr(str) {
|
||||
const stderr = document.getElementById('stderr');
|
||||
const line = document.createElement('p');
|
||||
line.innerText = str;
|
||||
stderr.appendChild(line);
|
||||
}
|
||||
};
|
||||
// this loads the wasm file and exposes the `ccall` and `cwrap` functions whic we'll
|
||||
// use in the following code
|
||||
const myProject = await wasm.default(module);
|
||||
```
|
||||
|
||||
With the library loaded, it's time to call our first function, `lua_new`.
|
||||
This is done via the emscripten [ccall](https://emscripten.org/docs/api_reference/preamble.js.html#ccall) function.
|
||||
It takes the function name we want to execute, its return type, the function parameter types and the parameters as arguments.
|
||||
<br>
|
||||
This will return the raw pointer (as js number) to the address where the [Lua](https://docs.rs/mlua/latest/mlua/struct.Lua.html) struct, we created in the Rust code, resides.
|
||||
```javascript
|
||||
const luaInstance = myProject.ccall('lua_new', 'number', [], []);
|
||||
```
|
||||
|
||||
Next up, lets make the `lua_execute` function callable.
|
||||
This time we're using the emscripten [cwrap](https://emscripten.org/docs/api_reference/preamble.js.html#cwrap) function.
|
||||
It wraps a normal Javascript function around the ffi call to the wasm `lua_execute` function, which is the recommended way to handle functions which are invoked multiple times.
|
||||
It takes the function name we want to execute, its return type and the function parameters as arguments.
|
||||
```javascript
|
||||
const luaExecute = myProject.cwrap('lua_execute', null, ['number', 'string']);
|
||||
```
|
||||
|
||||
With this all set up, we are able to call any Lua code via WebAssembly, right in the browser. Great!
|
||||
```javascript
|
||||
luaExecute(luaInstance, 'print("Hello Lua Wasm")');
|
||||
```
|
||||
|
||||
<details>
|
||||
<summary>Full example as html page with Javascript</summary>
|
||||
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>My Project</title>
|
||||
<script type="module">
|
||||
const wasm = await import('./target/wasm32-unknown-emscripten/debug/my-project.js');
|
||||
const stdout = document.getElementById('stdout');
|
||||
const stderr = document.getElementById('stderr');
|
||||
const module = {
|
||||
print(str) {
|
||||
const line = document.createElement('p');
|
||||
line.innerText = str;
|
||||
stdout.appendChild(line);
|
||||
},
|
||||
printErr(str) {
|
||||
const line = document.createElement('p');
|
||||
line.innerText = str;
|
||||
stderr.appendChild(line);
|
||||
}
|
||||
};
|
||||
const myProject = await wasm.default(module);
|
||||
|
||||
const luaInstance = myProject.ccall('lua_new', 'number', [], []);
|
||||
const luaExecute = myProject.cwrap('lua_execute', null, ['number', 'string']);
|
||||
|
||||
window.execute = () => {
|
||||
// clear the output
|
||||
stdout.innerHTML = '';
|
||||
stderr.innerHTML = '';
|
||||
const code = document.getElementById('code').value;
|
||||
luaExecute(luaInstance, code);
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<div>
|
||||
<textarea id="code"></textarea>
|
||||
<button onclick="execute()">Execute</button>
|
||||
</div>
|
||||
<div style="display: flex">
|
||||
<div>
|
||||
<h3>Stderr</h3>
|
||||
<div id="stderr" />
|
||||
</div>
|
||||
<hr>
|
||||
<div>
|
||||
<h3>Stdout</h3>
|
||||
<div id="stdout" />
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
</details>
|
||||
|
||||
## NodeJS
|
||||
|
||||
> The nodejs implementation is not very different from the browser implementation, so the actions done aren't as detailed described as above.
|
||||
Please read the [Browser](#browser) section first if you want more detailed information.
|
||||
|
||||
```javascript
|
||||
class MyProject {
|
||||
#instance;
|
||||
#luaExecute;
|
||||
#stdout;
|
||||
#stderr;
|
||||
|
||||
static async init(): Promise<MyProject> {
|
||||
const myProject = new MyProject();
|
||||
|
||||
const wasm = await import('./target/wasm32-unknown-emscripten/debug/my-project.js');
|
||||
const module = {
|
||||
print(str) {
|
||||
if (myProject.#stdout) myProject.#stdout(str);
|
||||
},
|
||||
printErr(str) {
|
||||
if (myProject.#stderr) myProject.#stderr(str);
|
||||
}
|
||||
};
|
||||
const lib = await wasm.default(module);
|
||||
|
||||
myProject.#instance = lib.ccall('lua_new', 'number', [], []);
|
||||
myProject.#luaExecute = lib.cwrap('lua_execute', null, ['number', 'string']);
|
||||
|
||||
return myProject;
|
||||
}
|
||||
|
||||
execute(code, stdout, stderr) {
|
||||
if (stdout) this.#stdout = stdout;
|
||||
if (stderr) this.#stderr = stderr;
|
||||
|
||||
this.#luaExecute(this.#instance, code);
|
||||
|
||||
if (stdout) this.#stdout = null;
|
||||
if (stderr) this.#stderr = null;
|
||||
}
|
||||
}
|
||||
```
|
8
src/tutorial/compiling.md
Normal file
8
src/tutorial/compiling.md
Normal file
@ -0,0 +1,8 @@
|
||||
# Compiling
|
||||
|
||||
Before we can use our Rust code, we have to compile it first.
|
||||
```shell
|
||||
# you can omit '--target wasm32-unknown-emscripten' if you added the .cargo/config.toml
|
||||
# file as describe in the "Setup" section
|
||||
cargo build --target wasm32-unknown-emscripten
|
||||
```
|
98
src/tutorial/creating-a-project.md
Normal file
98
src/tutorial/creating-a-project.md
Normal file
@ -0,0 +1,98 @@
|
||||
# Creating a project
|
||||
|
||||
## Create the project package
|
||||
|
||||
First, you need to create a normal Rust package.
|
||||
This can either be a binary or library crate, they are working nearly the same.
|
||||
|
||||
As binary:
|
||||
```shell
|
||||
cargo init --bin my-package .
|
||||
```
|
||||
|
||||
As library
|
||||
```shell
|
||||
cargo init --lib my-package .
|
||||
```
|
||||
|
||||
## Configure files
|
||||
|
||||
Before you can start writing actual code you have to set up some files in the newly created library directory.
|
||||
|
||||
### `Cargo.toml`
|
||||
|
||||
The `mlua` dependency is the actual lua library which we'll use.
|
||||
The features `lua51`, `lua53`, `lua54` and `luau` are wasm compatible lua version (`lua53` is currently broken because I accidentally removed a function in the PR which added wasm support, oops).
|
||||
```toml
|
||||
[package]
|
||||
name = "my-project"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
mlua = { git = "https://github.com/khvzak/mlua.git", features = ["lua51"] }
|
||||
```
|
||||
|
||||
> If your crate is a library, you have to additionally add this:
|
||||
> ```toml
|
||||
> [lib]
|
||||
> crate-type = ["cdylib"]
|
||||
> ```
|
||||
> This must be done because the emscripten compiler expects the package to behave like a normal C shared library.
|
||||
|
||||
|
||||
### `build.rs`
|
||||
|
||||
You need to set some additional compiler options to be able to call your wasm code from Javascript:
|
||||
- `-sEXPORTED_RUNTIME_METHODS=['cwrap','ccall']`: this exports the `cwrap` and `ccall` Javascript functions which allows us to call our library methods
|
||||
- `-sEXPORT_ES6=1`: this makes the created js glue ES6 compatible. It is not mandatory in general but needed as this tutorial/examples utilizes ES6 imports
|
||||
- `-sERROR_ON_UNDEFINED_SYMBOLS=0` (_optional for binary crates_): this ignores undefined symbols. Typically undefined symbols are not really undefined but the linker just can't find them, which is always the case if your crate is a library
|
||||
|
||||
> If your package is a library, you have to add some additional options:
|
||||
> - `--no-entry`: this defines that the compiled wasm has no main function
|
||||
> - `-o<library name>.js`: by default, only a `.wasm` file is created, but some js glue is needed to call the built wasm file (and the wasm file needs some functions of the glue too). This creates the glue `<library name>.js` file and changes the name of the wasm output file to `<library name>.wasm`. This must be removed when running tests because it changes the output filename and the Rust test suite can't track this
|
||||
|
||||
The best way to do this is by specifying the args in a `build.rs` file which guarantees that they are set when compiling:
|
||||
```rust,ignore
|
||||
fn main() {
|
||||
println!("cargo:rustc-link-arg=-sEXPORTED_RUNTIME_METHODS=['cwrap','ccall']");
|
||||
println!("cargo:rustc-link-arg=-sEXPORT_ES6=1");
|
||||
}
|
||||
```
|
||||
|
||||
> If your package is a library, add the additionally required options to your `build.rs`:
|
||||
> ```rust,ignore
|
||||
> let out_dir = std::env::var("OUT_DIR").unwrap();
|
||||
> let pkg_name = std::env::var("CARGO_PKG_NAME").unwrap();
|
||||
>
|
||||
> // the output files should be placed in the "root" build directory (e.g.
|
||||
> // target/wasm32-unknown-emscripten/debug) but there is no env variable which
|
||||
> // provides this path, so it must be extracted this way
|
||||
>
|
||||
> let target_path = std::path::PathBuf::from(out_dir)
|
||||
> .parent()
|
||||
> .unwrap()
|
||||
> .parent()
|
||||
> .unwrap()
|
||||
> .parent()
|
||||
> .unwrap()
|
||||
> .join(pkg_name);
|
||||
>
|
||||
> println!("cargo:rustc-link-arg=-sERROR_ON_UNDEFINED_SYMBOLS=0");
|
||||
> println!("cargo:rustc-link-arg=--no-entry");
|
||||
> println!("cargo:rustc-link-arg=-o{}.js", target_path.to_string_lossy());
|
||||
> ```
|
||||
|
||||
### `.cargo/config.toml` (optional)
|
||||
|
||||
Here you can set the default target to `wasm32-unknown-emscripten`, so you don't have to specify the `--target wasm32-unknown-emscripten` flag everytime you want to compile your project.
|
||||
<br>
|
||||
You can also set the default runner binary here which is useful when running tests, as Rust tries to execute the generated js glue directly which obviously doesn't work because a Javascript file is not an executable.
|
||||
|
||||
```toml
|
||||
[build]
|
||||
target = "wasm32-unknown-emscripten"
|
||||
|
||||
[target.wasm32-unknown-emscripten]
|
||||
runner = "node --experimental-default-type=module"
|
||||
```
|
9
src/tutorial/introduction.md
Normal file
9
src/tutorial/introduction.md
Normal file
@ -0,0 +1,9 @@
|
||||
# Tutorial
|
||||
|
||||
This tutorial covers how to set up a simple project, adding logic to it and calling it from a Javascript (browser) application.
|
||||
|
||||
We will build a simple wasm binary which is able to execute arbitrary Lua input (a repl, basically).
|
||||
|
||||
## What will be covered?
|
||||
- How to set up a project (it's a bit more than just `cargo init`)
|
||||
- Calling the created wasm file from the browser
|
Loading…
x
Reference in New Issue
Block a user