mirror of
https://github.com/denoland/rusty_v8.git
synced 2024-12-24 08:09:16 -05:00
Support binary downloads (#316)
Co-authored-by: Bert Belder <bertbelder@gmail.com>
This commit is contained in:
parent
97088f4eb1
commit
51d4e6b740
5 changed files with 150 additions and 3 deletions
|
@ -47,6 +47,11 @@ exclude = [
|
|||
"!v8/tools/testrunner/utils/dump_build_config.py",
|
||||
]
|
||||
|
||||
[features]
|
||||
# Enable this feature to download and prebuilt V8 binaries from
|
||||
# https://github.com/denoland/rusty_v8/releases
|
||||
binary = []
|
||||
|
||||
[dependencies]
|
||||
lazy_static = "1.4.0"
|
||||
libc = "0.2.67"
|
||||
|
|
16
README.md
16
README.md
|
@ -29,7 +29,7 @@ V8 Version: 8.2.308, 2020-03-12
|
|||
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.
|
||||
|
||||
## Build
|
||||
## Build V8 from Source
|
||||
|
||||
Use `cargo build -vv` to build the crate.
|
||||
|
||||
|
@ -56,6 +56,20 @@ environmental variable.
|
|||
|
||||
Env vars used in build.rs: `SCCACHE`, `GN`, `NINJA`, `CLANG_BASE_PATH`, `GN_ARGS`
|
||||
|
||||
## Binary Build
|
||||
|
||||
V8 is very large and take a long time to compile. Many users may 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).
|
||||
|
||||
To use these prebuilt binaries use the `binary` feature:
|
||||
|
||||
```
|
||||
cargo build --features="binary"
|
||||
```
|
||||
|
||||
This will cause rusty v8 to download the binaries during the build process.
|
||||
|
||||
## FAQ
|
||||
|
||||
**Building V8 takes over 30 minutes, this is too slow for me to use this crate.
|
||||
|
|
69
build.rs
69
build.rs
|
@ -23,9 +23,12 @@ fn main() {
|
|||
.map(|s| s.starts_with("rls"))
|
||||
.unwrap_or(false);
|
||||
|
||||
if !(is_trybuild || is_cargo_doc | is_rls) {
|
||||
if cfg!(feature = "binary") {
|
||||
download_static_lib_binaries();
|
||||
} else if !(is_trybuild || is_cargo_doc | is_rls) {
|
||||
build_v8()
|
||||
}
|
||||
|
||||
if !(is_cargo_doc || is_rls) {
|
||||
print_link_flags()
|
||||
}
|
||||
|
@ -166,6 +169,70 @@ fn download_ninja_gn_binaries() {
|
|||
env::set_var("NINJA", ninja);
|
||||
}
|
||||
|
||||
fn static_lib_url() -> (String, String) {
|
||||
let base = "https://github.com/denoland/rusty_v8/releases/download";
|
||||
let version = env::var("CARGO_PKG_VERSION").unwrap();
|
||||
let target = env::var("TARGET").unwrap();
|
||||
if cfg!(target_os = "windows") {
|
||||
// Note: we always use the release build on windows.
|
||||
let url = format!("{}/v{}/rusty_v8_release_{}.lib", base, version, target);
|
||||
let static_lib_name = "rusty_v8.lib".to_string();
|
||||
(url, static_lib_name)
|
||||
} else {
|
||||
let profile = env::var("PROFILE").unwrap();
|
||||
assert!(profile == "release" || profile == "debug");
|
||||
let url =
|
||||
format!("{}/v{}/librusty_v8_{}_{}.a", base, version, profile, target);
|
||||
let static_lib_name = "librusty_v8.a".to_string();
|
||||
(url, static_lib_name)
|
||||
}
|
||||
}
|
||||
|
||||
fn download_static_lib_binaries() {
|
||||
let (url, static_lib_name) = static_lib_url();
|
||||
println!("static lib URL: {}", url);
|
||||
|
||||
let root = env::current_dir().unwrap();
|
||||
|
||||
// target/debug//build/rusty_v8-d9e5a424d4f96994/out/
|
||||
let out_dir = env::var_os("OUT_DIR").unwrap();
|
||||
let out_dir_abs = root.join(out_dir);
|
||||
|
||||
// This would be target/debug or target/release
|
||||
let target_dir = out_dir_abs
|
||||
.parent()
|
||||
.unwrap()
|
||||
.parent()
|
||||
.unwrap()
|
||||
.parent()
|
||||
.unwrap();
|
||||
let obj_dir = target_dir.join("gn_out").join("obj");
|
||||
std::fs::create_dir_all(&obj_dir).unwrap();
|
||||
|
||||
println!("cargo:rustc-link-search={}", obj_dir.display());
|
||||
|
||||
let filename = obj_dir.join(static_lib_name);
|
||||
|
||||
if filename.exists() {
|
||||
println!("static lib already exists {}", filename.display());
|
||||
println!("To re-download this file, it must be manually deleted.");
|
||||
} else {
|
||||
// Using python to do the HTTP download because it's already a dependency
|
||||
// and so we don't have to add a Rust HTTP client dependency.
|
||||
println!("Downloading {}", url);
|
||||
let status = Command::new("python")
|
||||
.arg("./tools/download_file.py")
|
||||
.arg("--url")
|
||||
.arg(url)
|
||||
.arg("--filename")
|
||||
.arg(&filename)
|
||||
.status()
|
||||
.unwrap();
|
||||
assert!(status.success());
|
||||
assert!(filename.exists());
|
||||
}
|
||||
}
|
||||
|
||||
fn print_link_flags() {
|
||||
println!("cargo:rustc-link-lib=static=rusty_v8");
|
||||
|
||||
|
|
62
tools/download_file.py
Executable file
62
tools/download_file.py
Executable file
|
@ -0,0 +1,62 @@
|
|||
#!/usr/bin/env python
|
||||
# Copyright (c) 2012 The Chromium Authors. All rights reserved.
|
||||
# Use of this source code is governed by a BSD-style license that can be
|
||||
# found in the LICENSE file.
|
||||
|
||||
from __future__ import print_function
|
||||
import argparse
|
||||
import os
|
||||
import sys
|
||||
|
||||
try:
|
||||
from urllib2 import HTTPError, URLError, urlopen
|
||||
except ImportError: # For Py3 compatibility
|
||||
from urllib.error import HTTPError, URLError
|
||||
from urllib.request import urlopen
|
||||
|
||||
def DownloadUrl(url, output_file):
|
||||
"""Download url into output_file."""
|
||||
CHUNK_SIZE = 4096
|
||||
num_retries = 3
|
||||
retry_wait_s = 5 # Doubled at each retry.
|
||||
|
||||
while True:
|
||||
try:
|
||||
sys.stdout.write('Downloading %s...' % url)
|
||||
sys.stdout.flush()
|
||||
response = urlopen(url)
|
||||
bytes_done = 0
|
||||
while True:
|
||||
chunk = response.read(CHUNK_SIZE)
|
||||
if not chunk:
|
||||
break
|
||||
output_file.write(chunk)
|
||||
bytes_done += len(chunk)
|
||||
if bytes_done == 0:
|
||||
raise URLError("empty response")
|
||||
print(' Done.')
|
||||
return
|
||||
except URLError as e:
|
||||
sys.stdout.write('\n')
|
||||
print(e)
|
||||
if num_retries == 0 or isinstance(e, HTTPError) and e.code == 404:
|
||||
raise e
|
||||
num_retries -= 1
|
||||
print('Retrying in %d s ...' % retry_wait_s)
|
||||
sys.stdout.flush()
|
||||
time.sleep(retry_wait_s)
|
||||
retry_wait_s *= 2
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description='Download a file')
|
||||
parser.add_argument('--filename', help='where to put the file')
|
||||
parser.add_argument('--url', help='what url to download')
|
||||
args = parser.parse_args()
|
||||
with open(args.filename, "wb") as f:
|
||||
DownloadUrl(args.url, f)
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
sys.exit(main())
|
|
@ -25,7 +25,6 @@ DIR = None
|
|||
def DownloadUrl(url, output_file):
|
||||
"""Download url into output_file."""
|
||||
CHUNK_SIZE = 4096
|
||||
TOTAL_DOTS = 10
|
||||
num_retries = 3
|
||||
retry_wait_s = 5 # Doubled at each retry.
|
||||
|
||||
|
|
Loading…
Reference in a new issue