From f1dcfbb59d7baad9b1d1c085d67c98896c6dc623 Mon Sep 17 00:00:00 2001 From: Ryan Dahl Date: Sat, 16 Jun 2018 01:43:23 +0200 Subject: [PATCH] First pass at deno rust --- deno2/.gclient | 5 ++ deno2/.gitignore | 1 + deno2/BUILD.gn | 20 ++++++ deno2/deno.gni | 138 ++++++++++++++++++++++++++++++++++++++++++ deno2/empty.rs | 1 + deno2/main.rs | 39 ++++++++++++ deno2/tools/format.sh | 2 + 7 files changed, 206 insertions(+) create mode 100644 deno2/empty.rs create mode 100644 deno2/main.rs diff --git a/deno2/.gclient b/deno2/.gclient index 591ee2b620..94d06d4a7f 100644 --- a/deno2/.gclient +++ b/deno2/.gclient @@ -30,4 +30,9 @@ solutions = [{ 'https://chromium.googlesource.com/chromium/src/third_party/zlib@39b4a6260702da4c089eca57136abf40a39667e9', 'name': 'third_party/zlib' +}, { + 'url': + 'https://github.com/rust-lang/libc.git@8a85d662b90c14d458bc4ae9521a05564e20d7ae', + 'name': + 'third_party/rust_crates/libc' }] diff --git a/deno2/.gitignore b/deno2/.gitignore index 73d348f528..5b720fd155 100644 --- a/deno2/.gitignore +++ b/deno2/.gitignore @@ -5,4 +5,5 @@ v8/ tools/protoc_wrapper/ third_party/protobuf/ third_party/zlib/ +third_party/rust_crates/libc/ .gclient_entries diff --git a/deno2/BUILD.gn b/deno2/BUILD.gn index f6c05af1dd..4c51fb1f68 100644 --- a/deno2/BUILD.gn +++ b/deno2/BUILD.gn @@ -3,6 +3,22 @@ import("//v8/gni/v8.gni") import("//v8/snapshot_toolchain.gni") import("deno.gni") +rust_executable("deno_rs") { + source_root = "main.rs" + rust_deps = [ ":libc" ] + deps = [ + ":libdeno", + ] +} + +rust_library("libc") { + source_root = "third_party/rust_crates/libc/src/lib.rs" + cfg = [ + "feature=\"default\"", + "feature=\"use_std\"", + ] +} + executable("deno") { sources = [ "main.cc", @@ -40,6 +56,10 @@ static_library("libdeno") { ":create_snapshot_deno", ":deno_nosnapshot", ] + public_configs = [ + "v8:libplatform_config", + ":public_v8_base_config", + ] } source_set("deno_nosnapshot") { diff --git a/deno2/deno.gni b/deno2/deno.gni index 8ccf1015c1..61a40de9f2 100644 --- a/deno2/deno.gni +++ b/deno2/deno.gni @@ -57,3 +57,141 @@ template("create_snapshot") { ] } } + +template("rust_crate") { + crate_type = invoker.crate_type + source_root = invoker.source_root + action(target_name) { + script = "v8/tools/run.py" + depfile = "$target_gen_dir/$target_name.d" + sources = [ + source_root, + ] + outputs = [] + + args = [ + "rustc", + rebase_path(source_root, root_build_dir), + "--crate-name=$target_name", + "--crate-type=$crate_type", + "--emit=dep-info=" + rebase_path(depfile, root_build_dir), + ] + + # We only use staticlib for the special "empty" lib. + if (crate_type == "staticlib") { + staticlib = "$target_out_dir/$target_name.a" + outputs += [ staticlib ] + args += [ "--emit=link=" + rebase_path(staticlib, root_build_dir) ] + } + + if (crate_type == "lib" || crate_type == "bin") { + obj = "$target_out_dir/$target_name.o" + outputs += [ obj ] + args += [ "--emit=obj=" + rebase_path(obj, root_build_dir) ] + } + + if (crate_type == "lib") { + rlib = "$target_out_dir/$target_name.rlib" + outputs += [ rlib ] + args += [ "--emit=link=" + rebase_path(rlib, root_build_dir) ] + } + + if (defined(invoker.extra_flags)) { + args += invoker.extra_flags + } + + if (defined(invoker.cfg)) { + foreach(c, invoker.cfg) { + args += [ + "--cfg", + c, + ] + } + } + + deps = [] + + if (defined(invoker.rust_deps)) { + foreach(dep_label, invoker.rust_deps) { + dep_name = get_label_info(dep_label, "name") + dep_dir = get_label_info(dep_label, "target_out_dir") + dep_rlib = "$dep_dir/$dep_name.rlib" + deps += [ dep_label ] + args += [ + "--extern", + "$dep_name=" + rebase_path(dep_rlib, root_build_dir), + ] + } + } + + if (is_debug) { + args += [ "-g" ] + } + if (is_official_build) { + args += [ "-O" ] + } + } +} + +template("rust_library") { + rust_crate(target_name) { + crate_type = "lib" + forward_variables_from(invoker, "*") + } +} + +template("rust_executable") { + bin_target = target_name + "_bin" + exe_deps = invoker.deps + + rust_crate(bin_target) { + crate_type = "bin" + forward_variables_from(invoker, + [ + "source_root", + "cfg", + "rust_deps", + ]) + forward_variables_from(invoker, "*") + } + exe_deps += [ ":" + bin_target ] + + # By compiling an empty file as crate-type=staticlib we get all the code + # for the rust stdlib, which are not included in the object file outputs + # of other libs. + stdlib_target = target_name + "_stdlib" + rust_crate(stdlib_target) { + crate_type = "staticlib" + source_root = "empty.rs" + } + exe_deps += [ ":" + stdlib_target ] + + if (defined(invoker.rust_deps)) { + rust_deps = invoker.rust_deps + } else { + rust_deps = [] + } + + rust_objs = [] + rust_objs += get_target_outputs(":" + stdlib_target) + rust_objs += get_target_outputs(":" + bin_target) + foreach(dep_label, rust_deps) { + dep_name = get_label_info(dep_label, "name") + dep_dir = get_label_info(dep_label, "target_out_dir") + dep_obj = "$dep_dir/$dep_name.o" + exe_deps += [ dep_label ] + rust_objs += [ dep_obj ] + } + + executable(target_name) { + ldflags = rebase_path(rust_objs, root_build_dir) + if (current_os == "mac") { + ldflags += [ "-lresolv" ] + } + if (current_os == "win") { + ldflags += [ "userenv.lib" ] + } + inputs = rust_objs + deps = exe_deps + } +} diff --git a/deno2/empty.rs b/deno2/empty.rs new file mode 100644 index 0000000000..8b13789179 --- /dev/null +++ b/deno2/empty.rs @@ -0,0 +1 @@ + diff --git a/deno2/main.rs b/deno2/main.rs new file mode 100644 index 0000000000..3415e3a24f --- /dev/null +++ b/deno2/main.rs @@ -0,0 +1,39 @@ +extern crate libc; +use libc::c_char; +use libc::c_int; +use std::ffi::CStr; +use std::ffi::CString; + +#[link(name = "deno", kind = "static")] +extern "C" { + fn deno_v8_version() -> *const c_char; + fn deno_init(); + + // Note: `deno_set_flags` actually takes `char**` as it's second argument, + // not `const char**`, so this is technically incorrect. However it doesn't + // actually modify the contents of the strings, so it's not unsafe. + // TODO: use the correct function signature. + fn deno_set_flags(argc: *mut c_int, argv: *mut *const c_char); +} + +fn set_flags() { + // Create a vector of zero terminated c strings. + let mut argv = std::env::args() + .map(|arg| CString::new(arg).unwrap().as_ptr()) + .collect::>(); + let mut argc = argv.len() as c_int; + unsafe { + // pass the pointer of the vector's internal buffer to a C function + deno_set_flags(&mut argc, argv.as_mut_ptr()); + }; +} + +fn main() { + println!("Hi"); + set_flags(); + unsafe { deno_init() }; + let v = unsafe { deno_v8_version() }; + let c_str = unsafe { CStr::from_ptr(v) }; + let version = c_str.to_str().unwrap(); + println!("version: {}", version); +} diff --git a/deno2/tools/format.sh b/deno2/tools/format.sh index 55baa73fb1..eea97fa2cb 100755 --- a/deno2/tools/format.sh +++ b/deno2/tools/format.sh @@ -14,3 +14,5 @@ prettier --write \ # Do not format these. # js/msg.pb.js # js/msg.pb.d.ts + +rustfmt --write-mode overwrite *.rs