2019-12-04 10:44:54 -05:00
|
|
|
# Rusty V8 Binding
|
|
|
|
|
2022-05-28 12:28:43 -04:00
|
|
|
V8 Version: 10.3.174.8
|
2019-11-01 00:10:00 -04:00
|
|
|
|
2021-02-14 10:15:49 -05:00
|
|
|
[![ci](https://github.com/denoland/rusty_v8/workflows/ci/badge.svg?branch=main)](https://github.com/denoland/rusty_v8/actions)
|
2021-10-27 08:32:12 -04:00
|
|
|
[![crates](https://img.shields.io/crates/v/v8.svg)](https://crates.io/crates/v8)
|
|
|
|
[![docs](https://docs.rs/v8/badge.svg)](https://docs.rs/v8)
|
2019-11-01 00:10:00 -04:00
|
|
|
|
2019-12-04 17:09:45 -05:00
|
|
|
## Goals
|
2019-11-19 17:48:50 -05:00
|
|
|
|
2019-12-04 17:09:45 -05:00
|
|
|
1. Provide high quality Rust bindings to [V8's C++
|
|
|
|
API](https://cs.chromium.org/chromium/src/v8/include/v8.h). The API should
|
2020-05-20 16:56:41 -04:00
|
|
|
match the original API as closely as possible.
|
2019-11-01 13:50:12 -04:00
|
|
|
|
2019-12-04 17:09:45 -05:00
|
|
|
2. Do not introduce additional call overhead. (For example, previous attempts at
|
|
|
|
Rust V8 bindings forced the use of Persistent handles.)
|
|
|
|
|
|
|
|
3. Do not rely on a binary `libv8.a` built outside of cargo. V8 is a very large
|
|
|
|
project (over 600,000 lines of C++) which often takes 30 minutes to compile.
|
|
|
|
Furthermore, V8 relies on Chromium's bespoke build system (gn + ninja) which is
|
|
|
|
not easy to use outside of Chromium. For this reason many attempts to bind to V8
|
|
|
|
rely on pre-built binaries that are built separately from the binding itself.
|
|
|
|
While this is simple, it makes upgrading V8 difficult, it makes CI difficult, it
|
|
|
|
makes producing builds with different configurations difficult, and it is a
|
|
|
|
security concern since binary blobs can hide malicious code. For this reason we
|
|
|
|
believe it is imperative to build V8 from source code during "cargo build".
|
|
|
|
|
|
|
|
4. Publish the crate on crates.io and allow docs.rs to generate documentation.
|
|
|
|
Due to the complexity and size of V8's build, this is nontrivial. For example
|
|
|
|
the crate size must be kept under 10 MiB in order to publish.
|
|
|
|
|
2020-03-27 16:17:19 -04:00
|
|
|
## Binary Build
|
|
|
|
|
|
|
|
V8 is very large and takes a long time to compile. Many users will prefer to use
|
|
|
|
a prebuilt version of V8. We publish static libs for every version of rusty v8
|
|
|
|
on [Github](https://github.com/denoland/rusty_v8/releases).
|
|
|
|
|
|
|
|
Binaries builds are turned on by default: `cargo build` will initiate a download
|
|
|
|
from github to get the static lib. To disable this build using the
|
|
|
|
`V8_FROM_SOURCE` environmental variable.
|
|
|
|
|
|
|
|
When making changes to rusty_v8 itself, it should be tested by build from
|
|
|
|
source. The CI always builds from source.
|
|
|
|
|
2021-09-22 06:02:55 -04:00
|
|
|
## The `V8_FORCE_DEBUG` environment variable
|
|
|
|
|
|
|
|
By default `rusty_v8` will link against release builds of `v8`, if you want to
|
|
|
|
use a debug build of `v8` set `V8_FORCE_DEBUG=true`.
|
|
|
|
|
|
|
|
We default to release builds of `v8` due to performance & CI reasons in `deno`.
|
|
|
|
|
2020-10-07 02:39:02 -04:00
|
|
|
## The `RUSTY_V8_MIRROR` environment variable
|
|
|
|
|
|
|
|
Tells the build script where to get binary builds from. Understands
|
|
|
|
`http://` and `https://` URLs, and file paths. The default is
|
|
|
|
https://github.com/denoland/rusty_v8/releases/download.
|
|
|
|
|
|
|
|
File-based mirrors are good for using cached downloads. First, point
|
|
|
|
the environment variable to a suitable location:
|
|
|
|
|
|
|
|
# you might want to add this to your .bashrc
|
|
|
|
$ export RUSTY_V8_MIRROR=$HOME/.cache/rusty_v8
|
|
|
|
|
|
|
|
Then populate the cache:
|
|
|
|
|
|
|
|
```bash
|
|
|
|
#!/bin/bash
|
|
|
|
|
|
|
|
# see https://github.com/denoland/rusty_v8/releases
|
|
|
|
|
2020-12-27 11:37:14 -05:00
|
|
|
for REL in v0.13.0 v0.12.0; do
|
2020-10-07 02:39:02 -04:00
|
|
|
mkdir -p $RUSTY_V8_MIRROR/$REL
|
|
|
|
for FILE in \
|
|
|
|
librusty_v8_debug_x86_64-unknown-linux-gnu.a \
|
|
|
|
librusty_v8_release_x86_64-unknown-linux-gnu.a \
|
|
|
|
; do
|
|
|
|
if [ ! -f $RUSTY_V8_MIRROR/$REL/$FILE ]; then
|
2020-12-27 11:37:14 -05:00
|
|
|
wget -O $RUSTY_V8_MIRROR/$REL/$FILE \
|
2020-10-07 02:39:02 -04:00
|
|
|
https://github.com/denoland/rusty_v8/releases/download/$REL/$FILE
|
|
|
|
fi
|
|
|
|
done
|
|
|
|
done
|
|
|
|
```
|
|
|
|
|
2021-10-25 16:35:19 -04:00
|
|
|
## The `RUSTY_V8_ARCHIVE` environment variable
|
|
|
|
|
|
|
|
Tell the build script to use a specific v8 library. This can be an URL
|
|
|
|
or a path. This is useful when you have a prebuilt archive somewhere:
|
|
|
|
|
|
|
|
```bash
|
|
|
|
export RUSTY_V8_ARCHIVE=/path/to/custom_archive.a
|
|
|
|
cargo build
|
|
|
|
```
|
|
|
|
|
2020-03-17 17:59:37 -04:00
|
|
|
## Build V8 from Source
|
2019-12-04 17:09:45 -05:00
|
|
|
|
2020-03-27 16:17:19 -04:00
|
|
|
Use `V8_FROM_SOURCE=1 cargo build -vv` to build the crate completely from
|
|
|
|
source.
|
2019-12-04 17:09:45 -05:00
|
|
|
|
2022-05-23 16:05:22 -04:00
|
|
|
The build scripts require Python 3 to be available as `python` in your `PATH`.
|
2019-12-04 17:09:45 -05:00
|
|
|
|
2019-12-20 12:08:38 -05:00
|
|
|
For linux builds: glib-2.0 development files need to be installed such that
|
|
|
|
pkg-config can find them. On Ubuntu, run `sudo apt install libglib2.0-dev` to
|
|
|
|
install them.
|
|
|
|
|
2020-02-10 11:56:59 -05:00
|
|
|
For Windows builds: the 64-bit toolchain needs to be used. 32-bit targets are
|
|
|
|
not supported.
|
|
|
|
|
2020-12-25 04:20:53 -05:00
|
|
|
The build depends on several binary tools: `gn`, `ninja` and `clang`. The
|
|
|
|
tools will automatically be downloaded, if they are not detected in the environment.
|
|
|
|
|
|
|
|
Specifying the `$GN` and `$NINJA` environmental variables can be used to skip
|
|
|
|
the download of gn and ninja. The clang download can be skipped by setting
|
|
|
|
`$CLANG_BASE_PATH` to the directory containing a `llvm`/`clang` installation.
|
|
|
|
V8 is known to rely on bleeding edge features, so LLVM v8.0+ or Apple clang 11.0+
|
|
|
|
is recommended.
|
|
|
|
|
|
|
|
Arguments can be passed to `gn` by setting the `$GN_ARGS` environmental variable.
|
2019-12-26 09:43:39 -05:00
|
|
|
|
2020-09-03 13:22:07 -04:00
|
|
|
Env vars used in when building from source: `SCCACHE`, `CCACHE`, `GN`, `NINJA`,
|
2020-03-27 16:17:19 -04:00
|
|
|
`CLANG_BASE_PATH`, `GN_ARGS`
|
2020-03-17 17:59:37 -04:00
|
|
|
|
2021-12-11 05:16:43 -05:00
|
|
|
## C++ IDE integration
|
|
|
|
|
|
|
|
`rusty_v8` supports IDE integration for the C++ bindings through the use of the
|
|
|
|
`clangd` language server, bringing features such as diagnostics, code completion
|
|
|
|
and code navigations to your editor. [See the instructions for how to set it up
|
|
|
|
with your favorite editor.](https://clangd.llvm.org/installation.html#editor-plugins)
|
|
|
|
|
|
|
|
Before you can use `clangd` with `rusty_v8`, you must first generate the
|
|
|
|
compilation database:
|
|
|
|
|
|
|
|
```sh
|
|
|
|
V8_FROM_SOURCE=1 GENERATE_COMPDB= cargo build
|
|
|
|
```
|
|
|
|
|
|
|
|
This will write the `clang` compilation database as the `compile_commands.json`
|
|
|
|
file at the root of the project repository. You can pass a path to the
|
|
|
|
`GENERATE_COMPDB` environment variable to change the location where the
|
|
|
|
compilation database will be written.
|
|
|
|
|
|
|
|
You must pass the `GENERATE_COMPDB` environment variable to regenerate the
|
|
|
|
compilation database, it will not be regenerated automatically.
|
|
|
|
|
2019-12-04 17:09:45 -05:00
|
|
|
## FAQ
|
|
|
|
|
|
|
|
**Building V8 takes over 30 minutes, this is too slow for me to use this crate.
|
|
|
|
What should I do?**
|
|
|
|
|
2020-09-03 13:22:07 -04:00
|
|
|
Install [sccache](https://github.com/mozilla/sccache) or
|
|
|
|
[ccache](https://ccache.dev/). Our build scripts will detect and use them. Set
|
|
|
|
the `$SCCACHE` or `$CCACHE` environmental variable if it's not in your path.
|
2019-12-04 17:09:45 -05:00
|
|
|
|
|
|
|
**What are all these random directories for like `build` and `buildtools` are
|
|
|
|
these really necessary?**
|
|
|
|
|
|
|
|
In order to build V8 from source code, we must provide a certain directory
|
|
|
|
structure with some git submodules from Chromium. We welcome any simplifications
|
|
|
|
to the code base, but this is a structure we have found after many failed
|
|
|
|
attempts that carefully balances the requirements of cargo crates and
|
|
|
|
GN/Ninja.
|
|
|
|
|
|
|
|
**V8 has a very large API with hundreds of methods. Why don't you automate the
|
|
|
|
generation of this binding code?**
|
|
|
|
|
2019-12-05 21:03:28 -05:00
|
|
|
In the limit we would like to auto-generate bindings. We have actually started
|
2020-03-27 16:17:19 -04:00
|
|
|
down this route several times, however due to many eccentric features of the V8
|
2019-12-04 17:09:45 -05:00
|
|
|
API, this has not proven successful. Therefore we are proceeding in a
|
|
|
|
brute-force fashion for now, focusing on solving our stated goals first. We hope
|
|
|
|
to auto-generate bindings in the future.
|
|
|
|
|
|
|
|
**Why are you building this?**
|
|
|
|
|
|
|
|
This is to support [the Deno project](https://deno.land/). We previously have
|
|
|
|
gotten away with a simpler high-level Rust binding to V8 called
|
|
|
|
[libdeno](https://github.com/denoland/deno/tree/32937251315493ef2c3b42dd29340e8a34501aa4/core/libdeno).
|
|
|
|
But as Deno has matured we've found ourselves continually needing access to an
|
|
|
|
increasing amount of V8's API in Rust.
|
2020-01-23 14:29:25 -05:00
|
|
|
|
|
|
|
**When building I get unknown argument: '-gno-inline-line-tables'**
|
|
|
|
|
|
|
|
Use `export GN_ARGS="no_inline_line_tables=false"` during build.
|