mirror of https://github.com/bazelbuild/rules_rust
Added support for multiple javascript rule sets to wasm_bindgen package (#2284)
This PR converts the core `rust_wasm_bindgen` rule into a standalone rule that users can user to write custom interfaces into any rules/targets they desire while also supporting interfaces for existing Javascript rule sets. Users loading the root `@rules_rust//wasm_bindgen` symbols will be using the core Rust rules, where users loading symbols from the new sub directories `rules_nodejs` and `rules_js` will have variants that offer better integrations.
This commit is contained in:
parent
b96e37ecf4
commit
76daee3047
|
@ -412,8 +412,6 @@ tasks:
|
|||
- "//..."
|
||||
# The proto rules do not work on windows
|
||||
- "-//proto/..."
|
||||
# The wasm rules do not work on windows
|
||||
- "-//wasm/..."
|
||||
# The bindgen rules are currently broken on windows
|
||||
# https://github.com/bazelbuild/rules_rust/issues/2009
|
||||
- "-//bindgen/..."
|
||||
|
|
|
@ -10,7 +10,7 @@ on:
|
|||
- synchronize
|
||||
|
||||
jobs:
|
||||
clang-format-checking:
|
||||
code-format-checks:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
@ -19,3 +19,13 @@ jobs:
|
|||
source: '.'
|
||||
extensions: 'h,c,cc,proto'
|
||||
clangFormatVersion: 14
|
||||
- uses: actionsx/prettier@v2
|
||||
with:
|
||||
args: --config "${{ github.workspace }}/.prettierrc.toml" --write "**/*.{js,ts}"
|
||||
# Prettier has no diff view so we must make one ourselves
|
||||
# https://github.com/prettier/prettier/issues/6885
|
||||
- run: |
|
||||
git diff
|
||||
if [[ -n "$(git status --porcelain)" ]]; then
|
||||
exit 1
|
||||
fi
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
# Prettier config file. For more opitons see https://prettier.io/docs/en/options
|
||||
tabWidth = 4
|
||||
trailingComma = "all"
|
|
@ -9,7 +9,6 @@ bzl_library(
|
|||
srcs = [
|
||||
"@bazel_tools//tools:bzl_srcs",
|
||||
"@com_google_protobuf//:bzl_srcs",
|
||||
"@rules_nodejs//nodejs:bzl",
|
||||
],
|
||||
deps = [
|
||||
"@bazel_skylib//lib:paths",
|
||||
|
@ -152,6 +151,7 @@ PAGES = dict([
|
|||
"rust_wasm_bindgen_register_toolchains",
|
||||
"rust_wasm_bindgen_toolchain",
|
||||
"rust_wasm_bindgen",
|
||||
"RustWasmBindgenInfo",
|
||||
],
|
||||
),
|
||||
page(
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
* [CrateInfo](#CrateInfo)
|
||||
* [DepInfo](#DepInfo)
|
||||
* [RustWasmBindgenInfo](#RustWasmBindgenInfo)
|
||||
* [StdLibInfo](#StdLibInfo)
|
||||
* [capture_clippy_output](#capture_clippy_output)
|
||||
* [cargo_bootstrap_repository](#cargo_bootstrap_repository)
|
||||
|
@ -1330,17 +1331,6 @@ Generates javascript and typescript bindings for a webassembly module using [was
|
|||
|
||||
[ws]: https://rustwasm.github.io/docs/wasm-bindgen/
|
||||
|
||||
To use the Rust WebAssembly bindgen rules, add the following to your `WORKSPACE` file to add the
|
||||
external repositories for the Rust bindgen toolchain (in addition to the Rust rules setup):
|
||||
|
||||
```python
|
||||
load("@rules_rust//wasm_bindgen:repositories.bzl", "rust_wasm_bindgen_repositories")
|
||||
|
||||
rust_wasm_bindgen_repositories()
|
||||
```
|
||||
|
||||
For more details on `rust_wasm_bindgen_repositories`, see [here](#rust_wasm_bindgen_repositories).
|
||||
|
||||
An example of this rule in use can be seen at [@rules_rust//examples/wasm](../examples/wasm)
|
||||
|
||||
|
||||
|
@ -1509,6 +1499,26 @@ A provider containing information about a Crate's dependencies.
|
|||
| <a id="DepInfo-transitive_proc_macro_data"></a>transitive_proc_macro_data | depset[File]: Data of all transitive proc-macro dependencies, and non-macro dependencies of those macros. |
|
||||
|
||||
|
||||
<a id="RustWasmBindgenInfo"></a>
|
||||
|
||||
## RustWasmBindgenInfo
|
||||
|
||||
<pre>
|
||||
RustWasmBindgenInfo(<a href="#RustWasmBindgenInfo-js">js</a>, <a href="#RustWasmBindgenInfo-ts">ts</a>, <a href="#RustWasmBindgenInfo-wasm">wasm</a>)
|
||||
</pre>
|
||||
|
||||
Info about wasm-bindgen outputs.
|
||||
|
||||
**FIELDS**
|
||||
|
||||
|
||||
| Name | Description |
|
||||
| :------------- | :------------- |
|
||||
| <a id="RustWasmBindgenInfo-js"></a>js | Depset[File]: The Javascript files produced by <code>wasm-bindgen</code>. |
|
||||
| <a id="RustWasmBindgenInfo-ts"></a>ts | Depset[File]: The Typescript files produced by <code>wasm-bindgen</code>. |
|
||||
| <a id="RustWasmBindgenInfo-wasm"></a>wasm | File: The <code>.wasm</code> file generated by <code>wasm-bindgen</code>. |
|
||||
|
||||
|
||||
<a id="StdLibInfo"></a>
|
||||
|
||||
## StdLibInfo
|
||||
|
|
|
@ -5,24 +5,45 @@
|
|||
* [rust_wasm_bindgen_register_toolchains](#rust_wasm_bindgen_register_toolchains)
|
||||
* [rust_wasm_bindgen_toolchain](#rust_wasm_bindgen_toolchain)
|
||||
* [rust_wasm_bindgen](#rust_wasm_bindgen)
|
||||
* [RustWasmBindgenInfo](#RustWasmBindgenInfo)
|
||||
|
||||
|
||||
## Overview
|
||||
|
||||
To build a `rust_binary` for `wasm32-unknown-unknown` target add the `--platforms=@rules_rust//rust/platform:wasm` flag.
|
||||
Bazel rules for generating wasm modules for Javascript using [wasm-bindgen][wb].
|
||||
|
||||
```command
|
||||
bazel build @examples//hello_world_wasm --platforms=@rules_rust//rust/platform:wasm
|
||||
## Setup
|
||||
|
||||
To begin using the `wasm-bindgen` rules, users can load the necessary dependencies
|
||||
in their workspace by adding the following to their `WORKSPACE.bazel` file.
|
||||
|
||||
```starlark
|
||||
load("@rules_rust//wasm_bindgen:repositories.bzl", "rust_wasm_bindgen_dependencies", "rust_wasm_bindgen_register_toolchains")
|
||||
|
||||
rust_wasm_bindgen_dependencies()
|
||||
|
||||
rust_wasm_bindgen_register_toolchains()
|
||||
```
|
||||
|
||||
To build a `rust_binary` for `wasm32-wasi` target add the `--platforms=@rules_rust//rust/platform:wasi` flag.
|
||||
This should enable users to start using the [rust_wasm_bindgen](#rust_wasm_bindgen)
|
||||
rule. However, it's common to want to control the version of `wasm-bindgen` in the
|
||||
workspace instead of relying on the one provided by `rules_rust`. In this case, users
|
||||
should avoid calling `rust_wasm_bindgen_register_toolchains` and instead use the
|
||||
[rust_wasm_bindgen_toolchain](#rust_wasm_bindgen_toolchain) rule to define their own
|
||||
toolchains to register in the workspace.
|
||||
|
||||
```command
|
||||
bazel build @examples//hello_world_wasm --platforms=@rules_rust//rust/platform:wasi
|
||||
```
|
||||
### Interfacing with Javascript rules
|
||||
|
||||
`rust_wasm_bindgen` will automatically transition to the `wasm` platform and can be used when
|
||||
building WebAssembly code for the host target.
|
||||
While it's recommended for users to mantain their own , in the
|
||||
`@rules_rust//wasm_bindgen` package there exists interface sub-packages for various
|
||||
Javascript Bazel rules. E.g. `build_bazel_rules_nodejs` or `aspect_rules_js`. The
|
||||
rules defined there are a more convenient way to use `rust_wasm_bindgen` with the
|
||||
associated javascript rules due to the inclusion of additional providers. Each
|
||||
directory contains a `defs.bzl` file that defines the different variants of
|
||||
`rust_wasm_bindgen`. (e.g. `nodejs_rust_wasm_bindgen` for the `rules_nodejs` submodule).
|
||||
|
||||
|
||||
[wb]: https://github.com/rustwasm/wasm-bindgen
|
||||
|
||||
|
||||
<a id="rust_wasm_bindgen"></a>
|
||||
|
@ -37,17 +58,6 @@ Generates javascript and typescript bindings for a webassembly module using [was
|
|||
|
||||
[ws]: https://rustwasm.github.io/docs/wasm-bindgen/
|
||||
|
||||
To use the Rust WebAssembly bindgen rules, add the following to your `WORKSPACE` file to add the
|
||||
external repositories for the Rust bindgen toolchain (in addition to the Rust rules setup):
|
||||
|
||||
```python
|
||||
load("@rules_rust//wasm_bindgen:repositories.bzl", "rust_wasm_bindgen_repositories")
|
||||
|
||||
rust_wasm_bindgen_repositories()
|
||||
```
|
||||
|
||||
For more details on `rust_wasm_bindgen_repositories`, see [here](#rust_wasm_bindgen_repositories).
|
||||
|
||||
An example of this rule in use can be seen at [@rules_rust//examples/wasm](../examples/wasm)
|
||||
|
||||
|
||||
|
@ -110,6 +120,26 @@ For additional information, see the [Bazel toolchains documentation][toolchains]
|
|||
| <a id="rust_wasm_bindgen_toolchain-bindgen"></a>bindgen | The label of a <code>wasm-bindgen-cli</code> executable. | <a href="https://bazel.build/concepts/labels">Label</a> | optional | <code>None</code> |
|
||||
|
||||
|
||||
<a id="RustWasmBindgenInfo"></a>
|
||||
|
||||
## RustWasmBindgenInfo
|
||||
|
||||
<pre>
|
||||
RustWasmBindgenInfo(<a href="#RustWasmBindgenInfo-js">js</a>, <a href="#RustWasmBindgenInfo-ts">ts</a>, <a href="#RustWasmBindgenInfo-wasm">wasm</a>)
|
||||
</pre>
|
||||
|
||||
Info about wasm-bindgen outputs.
|
||||
|
||||
**FIELDS**
|
||||
|
||||
|
||||
| Name | Description |
|
||||
| :------------- | :------------- |
|
||||
| <a id="RustWasmBindgenInfo-js"></a>js | Depset[File]: The Javascript files produced by <code>wasm-bindgen</code>. |
|
||||
| <a id="RustWasmBindgenInfo-ts"></a>ts | Depset[File]: The Typescript files produced by <code>wasm-bindgen</code>. |
|
||||
| <a id="RustWasmBindgenInfo-wasm"></a>wasm | File: The <code>.wasm</code> file generated by <code>wasm-bindgen</code>. |
|
||||
|
||||
|
||||
<a id="rust_wasm_bindgen_dependencies"></a>
|
||||
|
||||
## rust_wasm_bindgen_dependencies
|
||||
|
|
|
@ -1,18 +1,38 @@
|
|||
#[[
|
||||
## Overview
|
||||
|
||||
To build a `rust_binary` for `wasm32-unknown-unknown` target add the `--platforms=@rules_rust//rust/platform:wasm` flag.
|
||||
Bazel rules for generating wasm modules for Javascript using [wasm-bindgen][wb].
|
||||
|
||||
```command
|
||||
bazel build @examples//hello_world_wasm --platforms=@rules_rust//rust/platform:wasm
|
||||
## Setup
|
||||
|
||||
To begin using the `wasm-bindgen` rules, users can load the necessary dependencies
|
||||
in their workspace by adding the following to their `WORKSPACE.bazel` file.
|
||||
|
||||
```starlark
|
||||
load("@rules_rust//wasm_bindgen:repositories.bzl", "rust_wasm_bindgen_dependencies", "rust_wasm_bindgen_register_toolchains")
|
||||
|
||||
rust_wasm_bindgen_dependencies()
|
||||
|
||||
rust_wasm_bindgen_register_toolchains()
|
||||
```
|
||||
|
||||
To build a `rust_binary` for `wasm32-wasi` target add the `--platforms=@rules_rust//rust/platform:wasi` flag.
|
||||
This should enable users to start using the [rust_wasm_bindgen](#rust_wasm_bindgen)
|
||||
rule. However, it's common to want to control the version of `wasm-bindgen` in the
|
||||
workspace instead of relying on the one provided by `rules_rust`. In this case, users
|
||||
should avoid calling `rust_wasm_bindgen_register_toolchains` and instead use the
|
||||
[rust_wasm_bindgen_toolchain](#rust_wasm_bindgen_toolchain) rule to define their own
|
||||
toolchains to register in the workspace.
|
||||
|
||||
```command
|
||||
bazel build @examples//hello_world_wasm --platforms=@rules_rust//rust/platform:wasi
|
||||
```
|
||||
### Interfacing with Javascript rules
|
||||
|
||||
`rust_wasm_bindgen` will automatically transition to the `wasm` platform and can be used when
|
||||
building WebAssembly code for the host target.
|
||||
While it's recommended for users to mantain their own , in the
|
||||
`@rules_rust//wasm_bindgen` package there exists interface sub-packages for various
|
||||
Javascript Bazel rules. E.g. `build_bazel_rules_nodejs` or `aspect_rules_js`. The
|
||||
rules defined there are a more convenient way to use `rust_wasm_bindgen` with the
|
||||
associated javascript rules due to the inclusion of additional providers. Each
|
||||
directory contains a `defs.bzl` file that defines the different variants of
|
||||
`rust_wasm_bindgen`. (e.g. `nodejs_rust_wasm_bindgen` for the `rules_nodejs` submodule).
|
||||
|
||||
|
||||
[wb]: https://github.com/rustwasm/wasm-bindgen
|
||||
]]#
|
||||
|
|
|
@ -110,16 +110,17 @@ load(
|
|||
"@rules_rust//rust/settings:incompatible.bzl",
|
||||
_incompatible_flag = "incompatible_flag",
|
||||
)
|
||||
load(
|
||||
"@rules_rust//wasm_bindgen:defs.bzl",
|
||||
_RustWasmBindgenInfo = "RustWasmBindgenInfo",
|
||||
_rust_wasm_bindgen = "rust_wasm_bindgen",
|
||||
_rust_wasm_bindgen_toolchain = "rust_wasm_bindgen_toolchain",
|
||||
)
|
||||
load(
|
||||
"@rules_rust//wasm_bindgen:repositories.bzl",
|
||||
_rust_wasm_bindgen_dependencies = "rust_wasm_bindgen_dependencies",
|
||||
_rust_wasm_bindgen_register_toolchains = "rust_wasm_bindgen_register_toolchains",
|
||||
)
|
||||
load(
|
||||
"@rules_rust//wasm_bindgen:wasm_bindgen.bzl",
|
||||
_rust_wasm_bindgen = "rust_wasm_bindgen",
|
||||
_rust_wasm_bindgen_toolchain = "rust_wasm_bindgen_toolchain",
|
||||
)
|
||||
|
||||
rust_binary = _rust_binary
|
||||
rust_library = _rust_library
|
||||
|
@ -161,6 +162,7 @@ rust_wasm_bindgen = _rust_wasm_bindgen
|
|||
rust_wasm_bindgen_dependencies = _rust_wasm_bindgen_dependencies
|
||||
rust_wasm_bindgen_register_toolchains = _rust_wasm_bindgen_register_toolchains
|
||||
rust_wasm_bindgen_toolchain = _rust_wasm_bindgen_toolchain
|
||||
RustWasmBindgenInfo = _RustWasmBindgenInfo
|
||||
|
||||
rules_rust_dependencies = _rules_rust_dependencies
|
||||
rust_register_toolchains = _rust_register_toolchains
|
||||
|
|
|
@ -50,6 +50,14 @@ rust_wasm_bindgen_dependencies()
|
|||
|
||||
rust_wasm_bindgen_register_toolchains()
|
||||
|
||||
load("@rules_rust//wasm_bindgen/rules_nodejs:repositories.bzl", "nodejs_rust_wasm_bindgen_dependencies")
|
||||
|
||||
nodejs_rust_wasm_bindgen_dependencies()
|
||||
|
||||
load("@rules_rust//wasm_bindgen/rules_js:repositories.bzl", "js_rust_wasm_bindgen_dependencies")
|
||||
|
||||
js_rust_wasm_bindgen_dependencies()
|
||||
|
||||
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
|
||||
|
||||
###############################################################################
|
||||
|
@ -81,14 +89,29 @@ rust_repository_set(
|
|||
|
||||
http_archive(
|
||||
name = "build_bazel_rules_nodejs",
|
||||
sha256 = "c78216f5be5d451a42275b0b7dc809fb9347e2b04a68f68bad620a2b01f5c774",
|
||||
urls = ["https://github.com/bazelbuild/rules_nodejs/releases/download/5.5.2/rules_nodejs-5.5.2.tar.gz"],
|
||||
sha256 = "709cc0dcb51cf9028dd57c268066e5bc8f03a119ded410a13b5c3925d6e43c48",
|
||||
urls = ["https://github.com/bazelbuild/rules_nodejs/releases/download/5.8.4/rules_nodejs-5.8.4.tar.gz"],
|
||||
)
|
||||
|
||||
load("@build_bazel_rules_nodejs//:index.bzl", "node_repositories")
|
||||
|
||||
node_repositories()
|
||||
|
||||
load("@aspect_rules_js//js:repositories.bzl", "rules_js_dependencies")
|
||||
|
||||
rules_js_dependencies()
|
||||
|
||||
load("@rules_nodejs//nodejs:repositories.bzl", "DEFAULT_NODE_VERSION", "nodejs_register_toolchains")
|
||||
|
||||
nodejs_register_toolchains(
|
||||
name = "nodejs",
|
||||
node_version = DEFAULT_NODE_VERSION,
|
||||
)
|
||||
|
||||
load("@bazel_features//:deps.bzl", "bazel_features_deps")
|
||||
|
||||
bazel_features_deps()
|
||||
|
||||
http_archive(
|
||||
name = "rules_foreign_cc",
|
||||
sha256 = "69023642d5781c68911beda769f91fcbc8ca48711db935a75da7f6536b65047f",
|
||||
|
|
|
@ -1,23 +0,0 @@
|
|||
"use strict";
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const assert = require('assert');
|
||||
|
||||
const main = async function (typ) {
|
||||
const wasm_file = path.join(__dirname, 'hello_world_'+typ+'_wasm_bindgen_bg.wasm');
|
||||
assert.ok(fs.existsSync(wasm_file));
|
||||
|
||||
const buf = fs.readFileSync(wasm_file);
|
||||
assert.ok(buf);
|
||||
|
||||
const res = await WebAssembly.instantiate(buf);
|
||||
assert.ok(res);
|
||||
assert.strictEqual(res.instance.exports.double(2), 4);
|
||||
};
|
||||
|
||||
["bundler", "web", "deno", "nomodules", "nodejs"].forEach((typ) => {
|
||||
main(typ).catch(function (err) {
|
||||
console.error(err);
|
||||
process.exit(1);
|
||||
});
|
||||
})
|
|
@ -12,11 +12,15 @@
|
|||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
load("@build_bazel_rules_nodejs//:index.bzl", "nodejs_test")
|
||||
load("@rules_rust//rust:defs.bzl", "rust_binary", "rust_shared_library")
|
||||
load("@rules_rust//wasm_bindgen:wasm_bindgen.bzl", "rust_wasm_bindgen")
|
||||
load("@rules_rust//wasm_bindgen:defs.bzl", "rust_wasm_bindgen")
|
||||
|
||||
package(default_visibility = ["//visibility:public"])
|
||||
package(default_visibility = ["//wasm_bindgen:__subpackages__"])
|
||||
|
||||
exports_files([
|
||||
"hello_world_wasm_test.js",
|
||||
"main.rs",
|
||||
])
|
||||
|
||||
rust_binary(
|
||||
name = "hello_world_bin_wasm",
|
||||
|
@ -64,15 +68,3 @@ rust_wasm_bindgen(
|
|||
target = "nodejs",
|
||||
wasm_file = ":hello_world_lib_wasm",
|
||||
)
|
||||
|
||||
nodejs_test(
|
||||
name = "hello_world_wasm_test",
|
||||
data = [
|
||||
":hello_world_bundler_wasm_bindgen",
|
||||
":hello_world_deno_wasm_bindgen",
|
||||
":hello_world_nodejs_wasm_bindgen",
|
||||
":hello_world_nomodules_wasm_bindgen",
|
||||
":hello_world_web_wasm_bindgen",
|
||||
],
|
||||
entry_point = "hello_world_wasm_test.js",
|
||||
)
|
|
@ -0,0 +1,27 @@
|
|||
"use strict";
|
||||
const fs = require("fs");
|
||||
const path = require("path");
|
||||
const assert = require("assert");
|
||||
|
||||
const main = async function (typ, dir) {
|
||||
const wasm_file = path.join(
|
||||
__dirname,
|
||||
dir,
|
||||
"hello_world_" + typ + "_wasm_bindgen_bg.wasm",
|
||||
);
|
||||
const buf = fs.readFileSync(wasm_file);
|
||||
assert.ok(buf);
|
||||
|
||||
const res = await WebAssembly.instantiate(buf);
|
||||
assert.ok(res);
|
||||
assert.strictEqual(res.instance.exports.double(2), 4);
|
||||
};
|
||||
|
||||
["bundler", "web", "deno", "nomodules", "nodejs"].forEach((typ) => {
|
||||
main(typ, process.argv.length > 2 ? process.argv[2] : "").catch(function (
|
||||
err,
|
||||
) {
|
||||
console.error(err);
|
||||
process.exit(1);
|
||||
});
|
||||
});
|
|
@ -0,0 +1,71 @@
|
|||
load("@aspect_rules_js//js:defs.bzl", "js_test")
|
||||
load("@bazel_skylib//rules:copy_file.bzl", "copy_file")
|
||||
load("@rules_rust//rust:defs.bzl", "rust_binary", "rust_shared_library")
|
||||
load("@rules_rust//wasm_bindgen/rules_js:defs.bzl", "js_rust_wasm_bindgen")
|
||||
|
||||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
copy_file(
|
||||
name = "hello_world_wasm_test.src",
|
||||
src = "//wasm_bindgen:hello_world_wasm_test.js",
|
||||
out = "hello_world_wasm_test.js",
|
||||
)
|
||||
|
||||
rust_binary(
|
||||
name = "hello_world_bin_wasm",
|
||||
srcs = ["//wasm_bindgen:main.rs"],
|
||||
edition = "2018",
|
||||
deps = [
|
||||
"@rules_rust//wasm_bindgen/3rdparty:wasm_bindgen",
|
||||
],
|
||||
)
|
||||
|
||||
rust_shared_library(
|
||||
name = "hello_world_lib_wasm",
|
||||
srcs = ["//wasm_bindgen:main.rs"],
|
||||
edition = "2018",
|
||||
deps = [
|
||||
"@rules_rust//wasm_bindgen/3rdparty:wasm_bindgen",
|
||||
],
|
||||
)
|
||||
|
||||
js_rust_wasm_bindgen(
|
||||
name = "hello_world_bundler_wasm_bindgen",
|
||||
wasm_file = ":hello_world_bin_wasm",
|
||||
)
|
||||
|
||||
js_rust_wasm_bindgen(
|
||||
name = "hello_world_web_wasm_bindgen",
|
||||
target = "web",
|
||||
wasm_file = ":hello_world_lib_wasm",
|
||||
)
|
||||
|
||||
js_rust_wasm_bindgen(
|
||||
name = "hello_world_deno_wasm_bindgen",
|
||||
target = "deno",
|
||||
wasm_file = ":hello_world_lib_wasm",
|
||||
)
|
||||
|
||||
js_rust_wasm_bindgen(
|
||||
name = "hello_world_nomodules_wasm_bindgen",
|
||||
target = "no-modules",
|
||||
wasm_file = ":hello_world_lib_wasm",
|
||||
)
|
||||
|
||||
js_rust_wasm_bindgen(
|
||||
name = "hello_world_nodejs_wasm_bindgen",
|
||||
target = "nodejs",
|
||||
wasm_file = ":hello_world_lib_wasm",
|
||||
)
|
||||
|
||||
js_test(
|
||||
name = "hello_world_wasm_test",
|
||||
data = [
|
||||
":hello_world_bundler_wasm_bindgen",
|
||||
":hello_world_deno_wasm_bindgen",
|
||||
":hello_world_nodejs_wasm_bindgen",
|
||||
":hello_world_nomodules_wasm_bindgen",
|
||||
":hello_world_web_wasm_bindgen",
|
||||
],
|
||||
entry_point = ":hello_world_wasm_test.js",
|
||||
)
|
|
@ -0,0 +1,65 @@
|
|||
load("@build_bazel_rules_nodejs//:index.bzl", "nodejs_test")
|
||||
load("@rules_rust//rust:defs.bzl", "rust_binary", "rust_shared_library")
|
||||
load("@rules_rust//wasm_bindgen/rules_nodejs:defs.bzl", "nodejs_rust_wasm_bindgen")
|
||||
|
||||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
rust_binary(
|
||||
name = "hello_world_bin_wasm",
|
||||
srcs = ["//wasm_bindgen:main.rs"],
|
||||
edition = "2018",
|
||||
deps = [
|
||||
"@rules_rust//wasm_bindgen/3rdparty:wasm_bindgen",
|
||||
],
|
||||
)
|
||||
|
||||
rust_shared_library(
|
||||
name = "hello_world_lib_wasm",
|
||||
srcs = ["//wasm_bindgen:main.rs"],
|
||||
edition = "2018",
|
||||
deps = [
|
||||
"@rules_rust//wasm_bindgen/3rdparty:wasm_bindgen",
|
||||
],
|
||||
)
|
||||
|
||||
nodejs_rust_wasm_bindgen(
|
||||
name = "hello_world_bundler_wasm_bindgen",
|
||||
wasm_file = ":hello_world_bin_wasm",
|
||||
)
|
||||
|
||||
nodejs_rust_wasm_bindgen(
|
||||
name = "hello_world_web_wasm_bindgen",
|
||||
target = "web",
|
||||
wasm_file = ":hello_world_lib_wasm",
|
||||
)
|
||||
|
||||
nodejs_rust_wasm_bindgen(
|
||||
name = "hello_world_deno_wasm_bindgen",
|
||||
target = "deno",
|
||||
wasm_file = ":hello_world_lib_wasm",
|
||||
)
|
||||
|
||||
nodejs_rust_wasm_bindgen(
|
||||
name = "hello_world_nomodules_wasm_bindgen",
|
||||
target = "no-modules",
|
||||
wasm_file = ":hello_world_lib_wasm",
|
||||
)
|
||||
|
||||
nodejs_rust_wasm_bindgen(
|
||||
name = "hello_world_nodejs_wasm_bindgen",
|
||||
target = "nodejs",
|
||||
wasm_file = ":hello_world_lib_wasm",
|
||||
)
|
||||
|
||||
nodejs_test(
|
||||
name = "hello_world_wasm_test",
|
||||
args = ["rules_nodejs"],
|
||||
data = [
|
||||
":hello_world_bundler_wasm_bindgen",
|
||||
":hello_world_deno_wasm_bindgen",
|
||||
":hello_world_nodejs_wasm_bindgen",
|
||||
":hello_world_nomodules_wasm_bindgen",
|
||||
":hello_world_web_wasm_bindgen",
|
||||
],
|
||||
entry_point = "//wasm_bindgen:hello_world_wasm_test.js",
|
||||
)
|
|
@ -1,5 +1,5 @@
|
|||
load("@bazel_skylib//:bzl_library.bzl", "bzl_library")
|
||||
load("//wasm_bindgen:wasm_bindgen.bzl", "rust_wasm_bindgen_toolchain")
|
||||
load("//wasm_bindgen:defs.bzl", "rust_wasm_bindgen_toolchain")
|
||||
|
||||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
|
@ -7,13 +7,6 @@ toolchain_type(
|
|||
name = "toolchain_type",
|
||||
)
|
||||
|
||||
alias(
|
||||
name = "wasm_bindgen_toolchain",
|
||||
actual = "toolchain_type",
|
||||
deprecation = "instead use `@rules_rust//wasm_bindgen:toolchain_type`",
|
||||
tags = ["manual"],
|
||||
)
|
||||
|
||||
bzl_library(
|
||||
name = "bzl_lib",
|
||||
srcs = glob(["**/*.bzl"]),
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
"""Bazel rules for [wasm-bindgen](https://crates.io/crates/wasm-bindgen)"""
|
||||
|
||||
load(
|
||||
"//wasm_bindgen:providers.bzl",
|
||||
_RustWasmBindgenInfo = "RustWasmBindgenInfo",
|
||||
)
|
||||
load(
|
||||
"//wasm_bindgen/private:wasm_bindgen.bzl",
|
||||
_rust_wasm_bindgen = "rust_wasm_bindgen",
|
||||
_rust_wasm_bindgen_toolchain = "rust_wasm_bindgen_toolchain",
|
||||
)
|
||||
|
||||
rust_wasm_bindgen = _rust_wasm_bindgen
|
||||
rust_wasm_bindgen_toolchain = _rust_wasm_bindgen_toolchain
|
||||
RustWasmBindgenInfo = _RustWasmBindgenInfo
|
|
@ -4,6 +4,7 @@ bzl_library(
|
|||
name = "bzl_lib",
|
||||
srcs = [
|
||||
"transitions.bzl",
|
||||
"wasm_bindgen.bzl",
|
||||
],
|
||||
visibility = ["//wasm_bindgen:__pkg__"],
|
||||
)
|
||||
|
|
|
@ -0,0 +1,203 @@
|
|||
"""Bazel rules for [wasm-bindgen](https://crates.io/crates/wasm-bindgen)"""
|
||||
|
||||
load("//rust:defs.bzl", "rust_common")
|
||||
load("//wasm_bindgen:providers.bzl", "RustWasmBindgenInfo")
|
||||
load("//wasm_bindgen/private:transitions.bzl", "wasm_bindgen_transition")
|
||||
|
||||
def rust_wasm_bindgen_action(ctx, toolchain, wasm_file, target_output, bindgen_flags = []):
|
||||
"""Spawn a `RustWasmBindgen` action.
|
||||
|
||||
Args:
|
||||
ctx (ctx): _description_
|
||||
toolchain (ToolchainInfo): _description_
|
||||
wasm_file (Target): _description_
|
||||
target_output (str): _description_
|
||||
bindgen_flags (list, optional): _description_. Defaults to [].
|
||||
|
||||
Returns:
|
||||
RustWasmBindgenInfo: _description_
|
||||
"""
|
||||
bindgen_bin = toolchain.bindgen
|
||||
|
||||
# Since the `wasm_file` attribute is behind a transition, it will be converted
|
||||
# to a list.
|
||||
if len(wasm_file) == 1:
|
||||
if rust_common.crate_info in wasm_file[0]:
|
||||
target = wasm_file[0]
|
||||
crate_info = target[rust_common.crate_info]
|
||||
|
||||
# Provide a helpful warning informing users how to use the rule
|
||||
if rust_common.crate_info in target:
|
||||
supported_types = ["cdylib", "bin"]
|
||||
if crate_info.type not in supported_types:
|
||||
fail("The target '{}' is not a supported type: {}".format(
|
||||
ctx.attr.crate.label,
|
||||
supported_types,
|
||||
))
|
||||
|
||||
progress_message_label = target.label
|
||||
input_file = crate_info.output
|
||||
else:
|
||||
wasm_files = wasm_file[0][DefaultInfo].files.to_list()
|
||||
if len(wasm_files) != 1:
|
||||
fail("Unexpected number of wasm files: {}".format(wasm_files))
|
||||
|
||||
progress_message_label = wasm_files[0].path
|
||||
input_file = wasm_files[0]
|
||||
else:
|
||||
fail("wasm_file is expected to be a transitioned label attr on `{}`. Got `{}`".format(
|
||||
ctx.label,
|
||||
wasm_file,
|
||||
))
|
||||
|
||||
bindgen_wasm_module = ctx.actions.declare_file(ctx.label.name + "_bg.wasm")
|
||||
|
||||
js_out = [ctx.actions.declare_file(ctx.label.name + ".js")]
|
||||
ts_out = [ctx.actions.declare_file(ctx.label.name + ".d.ts")]
|
||||
|
||||
if target_output == "bundler":
|
||||
js_out.append(ctx.actions.declare_file(ctx.label.name + "_bg.js"))
|
||||
ts_out.append(ctx.actions.declare_file(ctx.label.name + "_bg.wasm.d.ts"))
|
||||
|
||||
outputs = [bindgen_wasm_module] + js_out + ts_out
|
||||
|
||||
args = ctx.actions.args()
|
||||
args.add("--target", target_output)
|
||||
args.add("--out-dir", bindgen_wasm_module.dirname)
|
||||
args.add("--out-name", ctx.label.name)
|
||||
args.add_all(bindgen_flags)
|
||||
args.add(input_file)
|
||||
|
||||
ctx.actions.run(
|
||||
executable = bindgen_bin,
|
||||
inputs = [input_file],
|
||||
outputs = outputs,
|
||||
mnemonic = "RustWasmBindgen",
|
||||
progress_message = "Generating WebAssembly bindings for {}...".format(progress_message_label),
|
||||
arguments = [args],
|
||||
)
|
||||
|
||||
return RustWasmBindgenInfo(
|
||||
wasm = bindgen_wasm_module,
|
||||
js = depset(js_out),
|
||||
ts = depset(ts_out),
|
||||
)
|
||||
|
||||
def _rust_wasm_bindgen_impl(ctx):
|
||||
toolchain = ctx.toolchains[Label("//wasm_bindgen:toolchain_type")]
|
||||
|
||||
info = rust_wasm_bindgen_action(
|
||||
ctx = ctx,
|
||||
toolchain = toolchain,
|
||||
wasm_file = ctx.attr.wasm_file,
|
||||
target_output = ctx.attr.target,
|
||||
bindgen_flags = ctx.attr.bindgen_flags,
|
||||
)
|
||||
|
||||
return [
|
||||
DefaultInfo(
|
||||
files = depset(transitive = [info.js, info.ts]),
|
||||
),
|
||||
info,
|
||||
]
|
||||
|
||||
WASM_BINDGEN_ATTR = {
|
||||
"bindgen_flags": attr.string_list(
|
||||
doc = "Flags to pass directly to the bindgen executable. See https://github.com/rustwasm/wasm-bindgen/ for details.",
|
||||
),
|
||||
"target": attr.string(
|
||||
doc = "The type of output to generate. See https://rustwasm.github.io/wasm-bindgen/reference/deployment.html for details.",
|
||||
default = "bundler",
|
||||
values = ["web", "bundler", "nodejs", "no-modules", "deno"],
|
||||
),
|
||||
"wasm_file": attr.label(
|
||||
doc = "The `.wasm` file or crate to generate bindings for.",
|
||||
allow_single_file = True,
|
||||
cfg = wasm_bindgen_transition,
|
||||
mandatory = True,
|
||||
),
|
||||
"_allowlist_function_transition": attr.label(
|
||||
default = Label("//tools/allowlists/function_transition_allowlist"),
|
||||
),
|
||||
}
|
||||
|
||||
rust_wasm_bindgen = rule(
|
||||
implementation = _rust_wasm_bindgen_impl,
|
||||
doc = """\
|
||||
Generates javascript and typescript bindings for a webassembly module using [wasm-bindgen][ws].
|
||||
|
||||
[ws]: https://rustwasm.github.io/docs/wasm-bindgen/
|
||||
|
||||
An example of this rule in use can be seen at [@rules_rust//examples/wasm](../examples/wasm)
|
||||
""",
|
||||
attrs = {
|
||||
"bindgen_flags": attr.string_list(
|
||||
doc = "Flags to pass directly to the bindgen executable. See https://github.com/rustwasm/wasm-bindgen/ for details.",
|
||||
),
|
||||
"target": attr.string(
|
||||
doc = "The type of output to generate. See https://rustwasm.github.io/wasm-bindgen/reference/deployment.html for details.",
|
||||
default = "bundler",
|
||||
values = ["web", "bundler", "nodejs", "no-modules", "deno"],
|
||||
),
|
||||
"wasm_file": attr.label(
|
||||
doc = "The `.wasm` file or crate to generate bindings for.",
|
||||
allow_single_file = True,
|
||||
cfg = wasm_bindgen_transition,
|
||||
mandatory = True,
|
||||
),
|
||||
"_allowlist_function_transition": attr.label(
|
||||
default = Label("//tools/allowlists/function_transition_allowlist"),
|
||||
),
|
||||
},
|
||||
toolchains = [
|
||||
str(Label("//wasm_bindgen:toolchain_type")),
|
||||
],
|
||||
incompatible_use_toolchain_transition = True,
|
||||
)
|
||||
|
||||
def _rust_wasm_bindgen_toolchain_impl(ctx):
|
||||
return platform_common.ToolchainInfo(
|
||||
bindgen = ctx.executable.bindgen,
|
||||
)
|
||||
|
||||
rust_wasm_bindgen_toolchain = rule(
|
||||
implementation = _rust_wasm_bindgen_toolchain_impl,
|
||||
doc = """\
|
||||
The tools required for the `rust_wasm_bindgen` rule.
|
||||
|
||||
In cases where users want to control or change the version of `wasm-bindgen` used by [rust_wasm_bindgen](#rust_wasm_bindgen),
|
||||
a unique toolchain can be created as in the example below:
|
||||
|
||||
```python
|
||||
load("@rules_rust//bindgen:bindgen.bzl", "rust_bindgen_toolchain")
|
||||
|
||||
rust_bindgen_toolchain(
|
||||
bindgen = "//3rdparty/crates:wasm_bindgen_cli__bin",
|
||||
)
|
||||
|
||||
toolchain(
|
||||
name = "wasm_bindgen_toolchain",
|
||||
toolchain = "wasm_bindgen_toolchain_impl",
|
||||
toolchain_type = "@rules_rust//wasm_bindgen:toolchain_type",
|
||||
)
|
||||
```
|
||||
|
||||
Now that you have your own toolchain, you need to register it by
|
||||
inserting the following statement in your `WORKSPACE` file:
|
||||
|
||||
```python
|
||||
register_toolchains("//my/toolchains:wasm_bindgen_toolchain")
|
||||
```
|
||||
|
||||
For additional information, see the [Bazel toolchains documentation][toolchains].
|
||||
|
||||
[toolchains]: https://docs.bazel.build/versions/master/toolchains.html
|
||||
""",
|
||||
attrs = {
|
||||
"bindgen": attr.label(
|
||||
doc = "The label of a `wasm-bindgen-cli` executable.",
|
||||
executable = True,
|
||||
cfg = "exec",
|
||||
),
|
||||
},
|
||||
)
|
|
@ -1,10 +1,10 @@
|
|||
"""A module for re-exporting the providers used by the rust_wasm_bindgen rule"""
|
||||
"""Rust WASM bindgen providers"""
|
||||
|
||||
load(
|
||||
"@rules_nodejs//nodejs:providers.bzl",
|
||||
_DeclarationInfo = "DeclarationInfo",
|
||||
_JSModuleInfo = "JSModuleInfo",
|
||||
RustWasmBindgenInfo = provider(
|
||||
doc = "Info about wasm-bindgen outputs.",
|
||||
fields = {
|
||||
"js": "Depset[File]: The Javascript files produced by `wasm-bindgen`.",
|
||||
"ts": "Depset[File]: The Typescript files produced by `wasm-bindgen`.",
|
||||
"wasm": "File: The `.wasm` file generated by `wasm-bindgen`.",
|
||||
},
|
||||
)
|
||||
|
||||
DeclarationInfo = _DeclarationInfo
|
||||
JSModuleInfo = _JSModuleInfo
|
||||
|
|
|
@ -39,13 +39,6 @@ def rust_wasm_bindgen_dependencies():
|
|||
patches = [Label("//wasm_bindgen/3rdparty/patches:resolver.patch")],
|
||||
)
|
||||
|
||||
maybe(
|
||||
http_archive,
|
||||
name = "rules_nodejs",
|
||||
sha256 = "017e2348bb8431156d5cf89b6f502c2e7fcffc568729f74f89e4a12bd8279e90",
|
||||
urls = ["https://github.com/bazelbuild/rules_nodejs/releases/download/5.5.2/rules_nodejs-core-5.5.2.tar.gz"],
|
||||
)
|
||||
|
||||
crate_repositories()
|
||||
|
||||
# buildifier: disable=unnamed-macro
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
"""Rust WASM-bindgen rules for interfacing with aspects/rules_js"""
|
|
@ -0,0 +1,49 @@
|
|||
"""Rust WASM-bindgen rules for interfacing with aspect-build/rules_js"""
|
||||
|
||||
load("@aspect_rules_js//js:providers.bzl", "JsInfo")
|
||||
load("//wasm_bindgen/private:wasm_bindgen.bzl", "WASM_BINDGEN_ATTR", "rust_wasm_bindgen_action")
|
||||
|
||||
def _js_rust_wasm_bindgen_impl(ctx):
|
||||
toolchain = ctx.toolchains[Label("//wasm_bindgen:toolchain_type")]
|
||||
|
||||
info = rust_wasm_bindgen_action(
|
||||
ctx = ctx,
|
||||
toolchain = toolchain,
|
||||
wasm_file = ctx.attr.wasm_file,
|
||||
target_output = ctx.attr.target,
|
||||
bindgen_flags = ctx.attr.bindgen_flags,
|
||||
)
|
||||
|
||||
# Return a structure that is compatible with the deps[] of a ts_library.
|
||||
declarations = info.ts
|
||||
es5_sources = info.js
|
||||
|
||||
return [
|
||||
DefaultInfo(
|
||||
files = depset([info.wasm], transitive = [info.js, info.ts]),
|
||||
),
|
||||
info,
|
||||
JsInfo(
|
||||
declarations = declarations,
|
||||
sources = es5_sources,
|
||||
transitive_declarations = declarations,
|
||||
transitive_sources = es5_sources,
|
||||
),
|
||||
]
|
||||
|
||||
js_rust_wasm_bindgen = rule(
|
||||
doc = """\
|
||||
Generates javascript and typescript bindings for a webassembly module using [wasm-bindgen][ws] that interface with [aspect-build/rules_js][abjs].
|
||||
|
||||
[ws]: https://rustwasm.github.io/docs/wasm-bindgen/
|
||||
[abjs]: https://github.com/aspect-build/rules_js
|
||||
|
||||
An example of this rule in use can be seen at [@rules_rust//examples/wasm_bindgen/rules_js](../examples/wasm_bindgen/rules_js)
|
||||
""",
|
||||
implementation = _js_rust_wasm_bindgen_impl,
|
||||
attrs = WASM_BINDGEN_ATTR,
|
||||
toolchains = [
|
||||
str(Label("//wasm_bindgen:toolchain_type")),
|
||||
],
|
||||
incompatible_use_toolchain_transition = True,
|
||||
)
|
|
@ -0,0 +1,23 @@
|
|||
"""TODO"""
|
||||
|
||||
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
|
||||
load("@bazel_tools//tools/build_defs/repo:utils.bzl", "maybe")
|
||||
load(
|
||||
"//wasm_bindgen:repositories.bzl",
|
||||
_rust_wasm_bindgen_dependencies = "rust_wasm_bindgen_dependencies",
|
||||
_rust_wasm_bindgen_register_toolchains = "rust_wasm_bindgen_register_toolchains",
|
||||
)
|
||||
|
||||
def js_rust_wasm_bindgen_dependencies():
|
||||
_rust_wasm_bindgen_dependencies()
|
||||
|
||||
maybe(
|
||||
http_archive,
|
||||
name = "aspect_rules_js",
|
||||
sha256 = "7b2a4d1d264e105eae49a27e2e78065b23e2e45724df2251eacdd317e95bfdfd",
|
||||
strip_prefix = "rules_js-1.31.0",
|
||||
url = "https://github.com/aspect-build/rules_js/releases/download/v1.31.0/rules_js-v1.31.0.tar.gz",
|
||||
)
|
||||
|
||||
def js_rust_wasm_bindgen_register_toolchains(**kwargs):
|
||||
_rust_wasm_bindgen_register_toolchains(**kwargs)
|
|
@ -0,0 +1,52 @@
|
|||
"""Rust WASM-bindgen rules for interfacing with bazelbuild/rules_nodejs"""
|
||||
|
||||
load("@rules_nodejs//nodejs:providers.bzl", "DeclarationInfo", "JSModuleInfo")
|
||||
load("//wasm_bindgen/private:wasm_bindgen.bzl", "WASM_BINDGEN_ATTR", "rust_wasm_bindgen_action")
|
||||
|
||||
def _nodejs_rust_wasm_bindgen_impl(ctx):
|
||||
toolchain = ctx.toolchains[Label("//wasm_bindgen:toolchain_type")]
|
||||
|
||||
info = rust_wasm_bindgen_action(
|
||||
ctx = ctx,
|
||||
toolchain = toolchain,
|
||||
wasm_file = ctx.attr.wasm_file,
|
||||
target_output = ctx.attr.target,
|
||||
bindgen_flags = ctx.attr.bindgen_flags,
|
||||
)
|
||||
|
||||
# Return a structure that is compatible with the deps[] of a ts_library.
|
||||
declarations = info.ts
|
||||
es5_sources = info.js
|
||||
|
||||
return [
|
||||
DefaultInfo(
|
||||
files = depset([info.wasm], transitive = [info.js, info.ts]),
|
||||
),
|
||||
DeclarationInfo(
|
||||
declarations = declarations,
|
||||
transitive_declarations = declarations,
|
||||
type_blocklisted_declarations = depset([]),
|
||||
),
|
||||
JSModuleInfo(
|
||||
direct_sources = es5_sources,
|
||||
sources = es5_sources,
|
||||
),
|
||||
info,
|
||||
]
|
||||
|
||||
nodejs_rust_wasm_bindgen = rule(
|
||||
doc = """\
|
||||
Generates javascript and typescript bindings for a webassembly module using [wasm-bindgen][ws] that interface with [bazelbuild/rules_nodejs][bbnjs].
|
||||
|
||||
[ws]: https://rustwasm.github.io/docs/wasm-bindgen/
|
||||
[bbnjs]: https://github.com/bazelbuild/rules_nodejs
|
||||
|
||||
An example of this rule in use can be seen at [@rules_rust//examples/wasm_bindgen/rules_js](../examples/wasm_bindgen/rules_js)
|
||||
""",
|
||||
implementation = _nodejs_rust_wasm_bindgen_impl,
|
||||
attrs = WASM_BINDGEN_ATTR,
|
||||
toolchains = [
|
||||
str(Label("//wasm_bindgen:toolchain_type")),
|
||||
],
|
||||
incompatible_use_toolchain_transition = True,
|
||||
)
|
|
@ -0,0 +1,22 @@
|
|||
"""TODO"""
|
||||
|
||||
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
|
||||
load("@bazel_tools//tools/build_defs/repo:utils.bzl", "maybe")
|
||||
load(
|
||||
"//wasm_bindgen:repositories.bzl",
|
||||
_rust_wasm_bindgen_dependencies = "rust_wasm_bindgen_dependencies",
|
||||
_rust_wasm_bindgen_register_toolchains = "rust_wasm_bindgen_register_toolchains",
|
||||
)
|
||||
|
||||
def nodejs_rust_wasm_bindgen_dependencies():
|
||||
_rust_wasm_bindgen_dependencies()
|
||||
|
||||
maybe(
|
||||
http_archive,
|
||||
name = "rules_nodejs",
|
||||
sha256 = "8fc8e300cb67b89ceebd5b8ba6896ff273c84f6099fc88d23f24e7102319d8fd",
|
||||
urls = ["https://github.com/bazelbuild/rules_nodejs/releases/download/5.8.4/rules_nodejs-core-5.8.4.tar.gz"],
|
||||
)
|
||||
|
||||
def nodejs_rust_wasm_bindgen_register_toolchains(**kwargs):
|
||||
_rust_wasm_bindgen_register_toolchains(**kwargs)
|
|
@ -1,190 +0,0 @@
|
|||
# Copyright 2019 The Bazel Authors. All rights reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
"""Bazel rules for [wasm-bindgen](https://crates.io/crates/wasm-bindgen)"""
|
||||
|
||||
load("//rust:defs.bzl", "rust_common")
|
||||
load(
|
||||
"//wasm_bindgen:providers.bzl",
|
||||
"DeclarationInfo",
|
||||
"JSModuleInfo",
|
||||
)
|
||||
load("//wasm_bindgen/private:transitions.bzl", "wasm_bindgen_transition")
|
||||
|
||||
_WASM_BINDGEN_DOC = """\
|
||||
Generates javascript and typescript bindings for a webassembly module using [wasm-bindgen][ws].
|
||||
|
||||
[ws]: https://rustwasm.github.io/docs/wasm-bindgen/
|
||||
|
||||
To use the Rust WebAssembly bindgen rules, add the following to your `WORKSPACE` file to add the
|
||||
external repositories for the Rust bindgen toolchain (in addition to the Rust rules setup):
|
||||
|
||||
```python
|
||||
load("@rules_rust//wasm_bindgen:repositories.bzl", "rust_wasm_bindgen_repositories")
|
||||
|
||||
rust_wasm_bindgen_repositories()
|
||||
```
|
||||
|
||||
For more details on `rust_wasm_bindgen_repositories`, see [here](#rust_wasm_bindgen_repositories).
|
||||
|
||||
An example of this rule in use can be seen at [@rules_rust//examples/wasm](../examples/wasm)
|
||||
"""
|
||||
|
||||
_WASM_BINDGEN_TOOLCHAIN_DOC = """\
|
||||
The tools required for the `rust_wasm_bindgen` rule.
|
||||
|
||||
In cases where users want to control or change the version of `wasm-bindgen` used by [rust_wasm_bindgen](#rust_wasm_bindgen),
|
||||
a unique toolchain can be created as in the example below:
|
||||
|
||||
```python
|
||||
load("@rules_rust//bindgen:bindgen.bzl", "rust_bindgen_toolchain")
|
||||
|
||||
rust_bindgen_toolchain(
|
||||
bindgen = "//3rdparty/crates:wasm_bindgen_cli__bin",
|
||||
)
|
||||
|
||||
toolchain(
|
||||
name = "wasm_bindgen_toolchain",
|
||||
toolchain = "wasm_bindgen_toolchain_impl",
|
||||
toolchain_type = "@rules_rust//wasm_bindgen:toolchain_type",
|
||||
)
|
||||
```
|
||||
|
||||
Now that you have your own toolchain, you need to register it by
|
||||
inserting the following statement in your `WORKSPACE` file:
|
||||
|
||||
```python
|
||||
register_toolchains("//my/toolchains:wasm_bindgen_toolchain")
|
||||
```
|
||||
|
||||
For additional information, see the [Bazel toolchains documentation][toolchains].
|
||||
|
||||
[toolchains]: https://docs.bazel.build/versions/master/toolchains.html
|
||||
"""
|
||||
|
||||
def _rust_wasm_bindgen_impl(ctx):
|
||||
toolchain = ctx.toolchains[Label("//wasm_bindgen:wasm_bindgen_toolchain")]
|
||||
bindgen_bin = toolchain.bindgen
|
||||
|
||||
# Since the `wasm_file` attribute is behind a transition, it will be converted
|
||||
# to a list.
|
||||
if len(ctx.attr.wasm_file) == 1 and rust_common.crate_info in ctx.attr.wasm_file[0]:
|
||||
target = ctx.attr.wasm_file[0]
|
||||
crate_info = target[rust_common.crate_info]
|
||||
|
||||
# Provide a helpful warning informing users how to use the rule
|
||||
if rust_common.crate_info in target:
|
||||
supported_types = ["cdylib", "bin"]
|
||||
if crate_info.type not in supported_types:
|
||||
fail("The target '{}' is not a supported type: {}".format(
|
||||
ctx.attr.crate.label,
|
||||
supported_types,
|
||||
))
|
||||
|
||||
progress_message_label = target.label
|
||||
input_file = crate_info.output
|
||||
else:
|
||||
progress_message_label = ctx.file.wasm_file.path
|
||||
input_file = ctx.file.wasm_file
|
||||
|
||||
bindgen_wasm_module = ctx.actions.declare_file(ctx.attr.name + "_bg.wasm")
|
||||
|
||||
js_out = [ctx.actions.declare_file(ctx.attr.name + ".js")]
|
||||
ts_out = [ctx.actions.declare_file(ctx.attr.name + ".d.ts")]
|
||||
|
||||
if ctx.attr.target == "bundler":
|
||||
js_out.append(ctx.actions.declare_file(ctx.attr.name + "_bg.js"))
|
||||
ts_out.append(ctx.actions.declare_file(ctx.attr.name + "_bg.wasm.d.ts"))
|
||||
|
||||
outputs = [bindgen_wasm_module] + js_out + ts_out
|
||||
|
||||
args = ctx.actions.args()
|
||||
args.add("--target", ctx.attr.target)
|
||||
args.add("--out-dir", bindgen_wasm_module.dirname)
|
||||
args.add("--out-name", ctx.attr.name)
|
||||
args.add_all(ctx.attr.bindgen_flags)
|
||||
args.add(input_file)
|
||||
|
||||
ctx.actions.run(
|
||||
executable = bindgen_bin,
|
||||
inputs = [input_file],
|
||||
outputs = outputs,
|
||||
mnemonic = "RustWasmBindgen",
|
||||
progress_message = "Generating WebAssembly bindings for {}...".format(progress_message_label),
|
||||
arguments = [args],
|
||||
)
|
||||
|
||||
# Return a structure that is compatible with the deps[] of a ts_library.
|
||||
declarations = depset(ts_out)
|
||||
es5_sources = depset(js_out)
|
||||
|
||||
return [
|
||||
DefaultInfo(
|
||||
files = depset(outputs),
|
||||
),
|
||||
DeclarationInfo(
|
||||
declarations = declarations,
|
||||
transitive_declarations = declarations,
|
||||
type_blocklisted_declarations = depset([]),
|
||||
),
|
||||
JSModuleInfo(
|
||||
direct_sources = es5_sources,
|
||||
sources = es5_sources,
|
||||
),
|
||||
]
|
||||
|
||||
rust_wasm_bindgen = rule(
|
||||
implementation = _rust_wasm_bindgen_impl,
|
||||
doc = _WASM_BINDGEN_DOC,
|
||||
attrs = {
|
||||
"bindgen_flags": attr.string_list(
|
||||
doc = "Flags to pass directly to the bindgen executable. See https://github.com/rustwasm/wasm-bindgen/ for details.",
|
||||
),
|
||||
"target": attr.string(
|
||||
doc = "The type of output to generate. See https://rustwasm.github.io/wasm-bindgen/reference/deployment.html for details.",
|
||||
default = "bundler",
|
||||
values = ["web", "bundler", "nodejs", "no-modules", "deno"],
|
||||
),
|
||||
"wasm_file": attr.label(
|
||||
doc = "The `.wasm` file or crate to generate bindings for.",
|
||||
allow_single_file = True,
|
||||
cfg = wasm_bindgen_transition,
|
||||
mandatory = True,
|
||||
),
|
||||
"_allowlist_function_transition": attr.label(
|
||||
default = Label("//tools/allowlists/function_transition_allowlist"),
|
||||
),
|
||||
},
|
||||
toolchains = [
|
||||
str(Label("//wasm_bindgen:wasm_bindgen_toolchain")),
|
||||
],
|
||||
incompatible_use_toolchain_transition = True,
|
||||
)
|
||||
|
||||
def _rust_wasm_bindgen_toolchain_impl(ctx):
|
||||
return platform_common.ToolchainInfo(
|
||||
bindgen = ctx.executable.bindgen,
|
||||
)
|
||||
|
||||
rust_wasm_bindgen_toolchain = rule(
|
||||
implementation = _rust_wasm_bindgen_toolchain_impl,
|
||||
doc = _WASM_BINDGEN_TOOLCHAIN_DOC,
|
||||
attrs = {
|
||||
"bindgen": attr.label(
|
||||
doc = "The label of a `wasm-bindgen-cli` executable.",
|
||||
executable = True,
|
||||
cfg = "exec",
|
||||
),
|
||||
},
|
||||
)
|
Loading…
Reference in New Issue