diff --git a/core/Cargo.toml b/core/Cargo.toml index b96713e195..a922e8837d 100644 --- a/core/Cargo.toml +++ b/core/Cargo.toml @@ -4,6 +4,9 @@ name = "deno" version = "0.3.5" edition = "2018" +description = "A secure JavaScript/TypeScript runtime built with V8, Rust, and Tokio" +authors = ["The deno authors "] +license = "MIT" [lib] path = "lib.rs" diff --git a/core/build.rs b/core/build.rs index 8b827d9e7f..43e993dc99 100644 --- a/core/build.rs +++ b/core/build.rs @@ -11,20 +11,6 @@ fn main() { "cargo:rustc-link-search=native={}/obj/core/libdeno", build.gn_out_dir ); - if cfg!(target_os = "windows") { - println!("cargo:rustc-link-lib=static=libdeno"); - } else { - println!("cargo:rustc-link-lib=static=deno"); - } - - // Link the system libraries that libdeno and V8 depend on. - if cfg!(any(target_os = "macos", target_os = "freebsd")) { - println!("cargo:rustc-link-lib=dylib=c++"); - } else if cfg!(target_os = "windows") { - for lib in vec!["dbghelp", "shlwapi", "winmm", "ws2_32"] { - println!("cargo:rustc-link-lib={}", lib); - } - } build.run("core:deno_core_deps"); } diff --git a/core/libdeno.rs b/core/libdeno.rs index 72003a3726..1a80330ded 100644 --- a/core/libdeno.rs +++ b/core/libdeno.rs @@ -133,6 +133,34 @@ pub struct deno_config { pub recv_cb: deno_recv_cb, } +#[cfg(not(windows))] +#[link(name = "deno")] +extern "C" {} + +#[cfg(any(target_os = "macos", target_os = "freebsd"))] +#[link(name = "c++")] +extern "C" {} + +#[cfg(windows)] +#[link(name = "libdeno")] +extern "C" {} + +#[cfg(windows)] +#[link(name = "shlwapi")] +extern "C" {} + +#[cfg(windows)] +#[link(name = "winmm")] +extern "C" {} + +#[cfg(windows)] +#[link(name = "ws2_32")] +extern "C" {} + +#[cfg(windows)] +#[link(name = "dbghelp")] +extern "C" {} + extern "C" { pub fn deno_init(); pub fn deno_v8_version() -> *const c_char; diff --git a/tools/cargo_package.py b/tools/cargo_package.py new file mode 100755 index 0000000000..fe4ebcc1ed --- /dev/null +++ b/tools/cargo_package.py @@ -0,0 +1,164 @@ +#!/usr/bin/env python +# Because of limitations in Cargo, Deno must dynamically build temporary source +# directories in order to publish to crates.io. +# The "deno" crate corresponds to the //core/ directory and depends on a +# platform dependent crate binary crate containing pre-compiled libdeno +# https://crates.io/crates/deno +# https://crates.io/crates/deno-x86_64-pc-windows-msvc +# https://crates.io/crates/deno-x86_64-apple-darwin +# https://crates.io/crates/deno-x86_64-unknown-linux-gnu + +import os +import sys +import re +import errno +from shutil import copytree, ignore_patterns, copyfile +from tempfile import mkdtemp +from string import Template +from util import root_path +from util import run + +if sys.platform == "linux2": + llvm_target = "x86_64-unknown-linux-gnu" + static_lib_suffix = ".a" +elif sys.platform == "darwin": + llvm_target = "x86_64-apple-darwin" + static_lib_suffix = ".a" +elif sys.platform == "win32": + llvm_target = "x86_64-pc-windows-msvc" + static_lib_suffix = ".lib" +else: + assert (False) + +lib_name = os.path.join(root_path, "target/release/obj/core/libdeno", + "libdeno" + static_lib_suffix) + + +def get_version(toml_path): + for line in open(toml_path): + match = re.search('version = "(.*)"', line) + if match: + return match.group(1) + + +core_path = os.path.join(root_path, "core") +cargo_toml_path = os.path.join(core_path, "Cargo.toml") +version = get_version(cargo_toml_path) + + +def main(): + os.chdir(root_path) + + run(["tools/build.py", "libdeno_static_lib", "--release"]) + assert (os.path.exists(lib_name)) + + root_temp = mkdtemp() + print "cargo package temp dir", root_temp + + build_core(root_temp) + build_platform_crate(root_temp) + + print "Now go into %s and run 'cargo publish' manually." % root_temp + + +def build_core(root_temp): + core_temp = os.path.join(root_temp, "core") + + # Copy entire core tree into temp directory, excluding build.rs and libdeno + # and unnecessary files. + copytree( + core_path, + core_temp, + ignore=ignore_patterns("build.rs", "libdeno", ".*", "*.gn", "*.orig")) + + cargo_toml_temp = os.path.join(core_temp, "Cargo.toml") + + t = cargo_toml_deps.substitute(VERSION=version) + # Append deps to //core/Cargo.toml + # This append is the entire reason we are copying the tree. + with open(cargo_toml_temp, "a") as f: + f.write(t) + + +def build_platform_crate(root_temp): + platform_temp = os.path.join(root_temp, "platform") + + copy_static_lib(platform_temp) + + inputs = {"TARGET": llvm_target, "VERSION": version} + + generate(platform_temp, "build.rs", platform_build_rs.substitute(inputs)) + generate(platform_temp, "Cargo.toml", + platform_cargo_toml.substitute(inputs)) + generate(platform_temp, "src/lib.rs", "") + + +def copy_static_lib(platform_temp): + platform_lib = os.path.join(platform_temp, "lib/") + mkdir_p(platform_lib) + platform_lib_name = os.path.join(platform_lib, os.path.basename(lib_name)) + assert (os.path.exists(lib_name)) + copyfile(lib_name, platform_lib_name) + + +platform_build_rs = Template(""" +fn main() { + use std::env::var; + use std::path::Path; + if var("TARGET") + .map(|target| target == "$TARGET") + .unwrap_or(false) + { + let dir = var("CARGO_MANIFEST_DIR").unwrap(); + println!( + "cargo:rustc-link-search=native={}", + Path::new(&dir).join("lib").display() + ); + } +} +""") + +platform_cargo_toml = Template(""" +[package] +name = "deno-$TARGET" +description = "Binary dependencies for the 'deno' crate" +authors = ["The deno authors "] +version = "$VERSION" +build = "build.rs" +include = ["src/*", "lib/*", "Cargo.toml", "build.rs"] +license = "MIT" +repository = "https://github.com/denoland/deno" +""") + +cargo_toml_deps = Template(""" +[target.x86_64-apple-darwin.dependencies] +deno-x86_64-apple-darwin = "=$VERSION" + +[target.x86_64-pc-windows-msvc.dependencies] +deno-x86_64-pc-windows-msvc = "=$VERSION" + +[target.x86_64-unknown-linux-gnu.dependencies] +deno-x86_64-unknown-linux-gnu = "=$VERSION" +""") + + +def mkdir_p(path): + try: + os.makedirs(path) + except OSError as exc: + if exc.errno == errno.EEXIST and os.path.isdir(path): + pass + else: + raise + + +def generate(out_dir, filename, content): + path = os.path.join(out_dir, filename) + d = os.path.dirname(path) + mkdir_p(d) + with open(path, "w") as f: + f.write(content) + + +if __name__ == '__main__': + sys.exit(main()) diff --git a/tools/setup.py b/tools/setup.py index 57ae80454d..9a4b443ddd 100755 --- a/tools/setup.py +++ b/tools/setup.py @@ -115,7 +115,7 @@ def write_gn_args(args_filename, args): def generate_gn_args(mode): out = [] if mode == "release": - out += ["is_official_build=true"] + out += ["is_official_build=true", "symbol_level=0"] elif mode == "debug": out += ["is_debug=true"] else: