0
0
Fork 0
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:
Ryan Dahl 2020-03-17 17:59:37 -04:00 committed by GitHub
parent 97088f4eb1
commit 51d4e6b740
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 150 additions and 3 deletions

View file

@ -47,6 +47,11 @@ exclude = [
"!v8/tools/testrunner/utils/dump_build_config.py", "!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] [dependencies]
lazy_static = "1.4.0" lazy_static = "1.4.0"
libc = "0.2.67" libc = "0.2.67"

View file

@ -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 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. 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. 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` 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 ## FAQ
**Building V8 takes over 30 minutes, this is too slow for me to use this crate. **Building V8 takes over 30 minutes, this is too slow for me to use this crate.

View file

@ -23,9 +23,12 @@ fn main() {
.map(|s| s.starts_with("rls")) .map(|s| s.starts_with("rls"))
.unwrap_or(false); .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() build_v8()
} }
if !(is_cargo_doc || is_rls) { if !(is_cargo_doc || is_rls) {
print_link_flags() print_link_flags()
} }
@ -166,6 +169,70 @@ fn download_ninja_gn_binaries() {
env::set_var("NINJA", ninja); 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() { fn print_link_flags() {
println!("cargo:rustc-link-lib=static=rusty_v8"); println!("cargo:rustc-link-lib=static=rusty_v8");

62
tools/download_file.py Executable file
View 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())

View file

@ -25,7 +25,6 @@ DIR = None
def DownloadUrl(url, output_file): def DownloadUrl(url, output_file):
"""Download url into output_file.""" """Download url into output_file."""
CHUNK_SIZE = 4096 CHUNK_SIZE = 4096
TOTAL_DOTS = 10
num_retries = 3 num_retries = 3
retry_wait_s = 5 # Doubled at each retry. retry_wait_s = 5 # Doubled at each retry.