refactor: decouple sys module of new napi-rs into a crate
This commit is contained in:
parent
cce5f1fe00
commit
244db37c3b
22 changed files with 176 additions and 150 deletions
2
.github/workflows/linux-musl.yaml
vendored
2
.github/workflows/linux-musl.yaml
vendored
|
@ -33,7 +33,7 @@ jobs:
|
|||
|
||||
- name: Run tests
|
||||
run: |
|
||||
docker run --rm -v $(pwd)/.cargo:/root/.cargo -v $(pwd):/napi-rs -w /napi-rs builder cargo test -p napi-rs --lib -- --nocapture
|
||||
docker run --rm -v $(pwd)/.cargo:/root/.cargo -v $(pwd):/napi-rs -w /napi-rs builder cargo test -p napi-sys --lib -- --nocapture
|
||||
|
||||
- name: Unit test
|
||||
run: |
|
||||
|
|
2
.github/workflows/linux.yaml
vendored
2
.github/workflows/linux.yaml
vendored
|
@ -58,7 +58,7 @@ jobs:
|
|||
timeout-minutes: 5
|
||||
with:
|
||||
command: test
|
||||
args: -p napi-rs --lib -- --nocapture
|
||||
args: -p napi-sys --lib -- --nocapture
|
||||
|
||||
- name: Unit tests
|
||||
run: |
|
||||
|
|
2
.github/workflows/macos.yaml
vendored
2
.github/workflows/macos.yaml
vendored
|
@ -58,7 +58,7 @@ jobs:
|
|||
timeout-minutes: 5
|
||||
with:
|
||||
command: test
|
||||
args: -p napi-rs --lib -- --nocapture
|
||||
args: -p napi-sys --lib -- --nocapture
|
||||
|
||||
- name: Unit tests
|
||||
run: |
|
||||
|
|
2
.github/workflows/napi3.yaml
vendored
2
.github/workflows/napi3.yaml
vendored
|
@ -54,7 +54,7 @@ jobs:
|
|||
timeout-minutes: 5
|
||||
with:
|
||||
command: test
|
||||
args: -p napi-rs --lib -- --nocapture
|
||||
args: -p napi-sys --lib -- --nocapture
|
||||
|
||||
- name: Unit tests
|
||||
run: |
|
||||
|
|
4
.github/workflows/windows.yaml
vendored
4
.github/workflows/windows.yaml
vendored
|
@ -57,14 +57,14 @@ jobs:
|
|||
uses: actions-rs/cargo@v1
|
||||
with:
|
||||
command: check
|
||||
args: -p napi-rs -vvv
|
||||
args: --all --bins --examples --tests -vvv
|
||||
|
||||
- name: Tests
|
||||
uses: actions-rs/cargo@v1
|
||||
timeout-minutes: 5
|
||||
with:
|
||||
command: test
|
||||
args: -p napi-rs --lib -- --nocapture
|
||||
args: -p napi-sys --lib -- --nocapture
|
||||
|
||||
- name: Unit tests
|
||||
run: |
|
||||
|
|
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -9,6 +9,7 @@ build/LICENSE
|
|||
napi/LICENSE
|
||||
napi/README.md
|
||||
napi-derive/LICENSE
|
||||
sys/LICENSE
|
||||
|
||||
# Created by https://www.gitignore.io/api/node
|
||||
# Edit at https://www.gitignore.io/?templates=node
|
||||
|
|
|
@ -3,6 +3,7 @@ members = [
|
|||
"./build",
|
||||
"./napi",
|
||||
"./napi-derive",
|
||||
"./napi-derive-example"
|
||||
"./napi-derive-example",
|
||||
"./sys"
|
||||
]
|
||||
exclude = ["./test_module"]
|
||||
|
|
|
@ -8,8 +8,8 @@ edition = "2018"
|
|||
crate-type = ["cdylib"]
|
||||
|
||||
[dependencies]
|
||||
napi-rs = { path = "../napi" }
|
||||
napi-rs-derive = { path = "../napi-derive" }
|
||||
napi = { path = "../napi" }
|
||||
napi-derive = { path = "../napi-derive" }
|
||||
|
||||
[build-dependencies]
|
||||
napi-build = { path = "../build" }
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#[macro_use]
|
||||
extern crate napi_rs as napi;
|
||||
extern crate napi;
|
||||
#[macro_use]
|
||||
extern crate napi_rs_derive;
|
||||
extern crate napi_derive;
|
||||
|
||||
use napi::{CallContext, Error, JsNumber, JsUnknown, Module, Result, Status};
|
||||
use std::convert::TryInto;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "napi-rs-derive"
|
||||
version = "0.2.0"
|
||||
name = "napi-derive"
|
||||
version = "0.4.0"
|
||||
authors = ["LongYinan <lynweklm@gmail.com>"]
|
||||
edition = "2018"
|
||||
description = "N-API procedural macros"
|
||||
|
|
|
@ -82,24 +82,24 @@ pub fn js_function(attr: TokenStream, input: TokenStream) -> TokenStream {
|
|||
#signature #(#fn_block)*
|
||||
|
||||
#visibility extern "C" fn #fn_name(
|
||||
raw_env: napi_rs::sys::napi_env,
|
||||
cb_info: napi_rs::sys::napi_callback_info,
|
||||
) -> napi_rs::sys::napi_value {
|
||||
raw_env: napi::sys::napi_env,
|
||||
cb_info: napi::sys::napi_callback_info,
|
||||
) -> napi::sys::napi_value {
|
||||
use std::io::Write;
|
||||
use std::mem;
|
||||
use std::os::raw::c_char;
|
||||
use std::ptr;
|
||||
use std::ffi::CString;
|
||||
use napi_rs::{JsUnknown, Env, Status, NapiValue, CallContext};
|
||||
use napi::{JsUnknown, Env, Status, NapiValue, CallContext};
|
||||
let mut argc = #arg_len_span as usize;
|
||||
let mut raw_args =
|
||||
unsafe { mem::MaybeUninit::<[napi_rs::sys::napi_value; #arg_len_span as usize]>::uninit().assume_init() };
|
||||
unsafe { mem::MaybeUninit::<[napi::sys::napi_value; #arg_len_span as usize]>::uninit().assume_init() };
|
||||
let mut raw_this = ptr::null_mut();
|
||||
|
||||
let mut has_error = false;
|
||||
|
||||
unsafe {
|
||||
let status = napi_rs::sys::napi_get_cb_info(
|
||||
let status = napi::sys::napi_get_cb_info(
|
||||
raw_env,
|
||||
cb_info,
|
||||
&mut argc as *mut usize as *mut u64,
|
||||
|
@ -120,10 +120,10 @@ pub fn js_function(attr: TokenStream, input: TokenStream) -> TokenStream {
|
|||
Err(e) => {
|
||||
let message = format!("{}", e);
|
||||
unsafe {
|
||||
napi_rs::sys::napi_throw_error(raw_env, ptr::null(), CString::from_vec_unchecked(message.into()).as_ptr() as *const c_char);
|
||||
napi::sys::napi_throw_error(raw_env, ptr::null(), CString::from_vec_unchecked(message.into()).as_ptr() as *const c_char);
|
||||
}
|
||||
let mut undefined = ptr::null_mut();
|
||||
unsafe { napi_rs::sys::napi_get_undefined(raw_env, &mut undefined) };
|
||||
unsafe { napi::sys::napi_get_undefined(raw_env, &mut undefined) };
|
||||
undefined
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "napi-rs"
|
||||
version = "0.3.1"
|
||||
name = "napi"
|
||||
version = "0.4.0"
|
||||
authors = ["Nathan Sobo <nathan@github.com>", "Yinan Long <lynweklm@gmail.com>"]
|
||||
license = "MIT"
|
||||
description = "N-API bindings"
|
||||
|
@ -13,6 +13,9 @@ edition = "2018"
|
|||
libuv = ["futures"]
|
||||
tokio_rt = ["futures", "tokio", "once_cell"]
|
||||
|
||||
[dependencies]
|
||||
napi-sys = { version = "0.4", path = "../sys" }
|
||||
|
||||
[dependencies.futures]
|
||||
version = "0.3"
|
||||
optional = true
|
||||
|
@ -27,14 +30,5 @@ version = "1.4"
|
|||
optional = true
|
||||
|
||||
|
||||
[target.'cfg(windows)'.build-dependencies]
|
||||
flate2 = "1.0"
|
||||
reqwest = { version = "0.10", features = ["native-tls", "blocking"] }
|
||||
tar = "0.4"
|
||||
|
||||
[build-dependencies]
|
||||
bindgen = "0.54"
|
||||
glob = "0.3"
|
||||
napi-build = { version = "0.1", path = "../build" }
|
||||
regex = "1.3"
|
||||
semver = "0.10"
|
||||
|
|
113
napi/build.rs
113
napi/build.rs
|
@ -1,118 +1,5 @@
|
|||
extern crate bindgen;
|
||||
#[cfg(windows)]
|
||||
extern crate flate2;
|
||||
extern crate glob;
|
||||
extern crate napi_build;
|
||||
#[cfg(windows)]
|
||||
extern crate reqwest;
|
||||
extern crate semver;
|
||||
#[cfg(windows)]
|
||||
extern crate tar;
|
||||
|
||||
use glob::glob;
|
||||
|
||||
use std::env;
|
||||
use std::path::PathBuf;
|
||||
use std::process::Command;
|
||||
|
||||
// https://stackoverflow.com/questions/37498864/finding-executable-in-path-with-rust
|
||||
|
||||
const NODE_PRINT_EXEC_PATH: &'static str = "console.log(process.execPath)";
|
||||
|
||||
fn main() {
|
||||
napi_build::setup();
|
||||
let node_full_version =
|
||||
String::from_utf8(Command::new("node").arg("-v").output().unwrap().stdout).unwrap();
|
||||
let node_version = semver::Version::parse(node_full_version.as_str().get(1..).unwrap()).unwrap();
|
||||
|
||||
let node_major_version = node_version.major;
|
||||
|
||||
println!("cargo:rerun-if-env-changed=NODE_INCLUDE_PATH");
|
||||
for entry in glob("./src/sys/**/*.*").unwrap() {
|
||||
println!(
|
||||
"cargo:rerun-if-changed={}",
|
||||
entry.unwrap().to_str().unwrap()
|
||||
);
|
||||
}
|
||||
|
||||
if node_major_version < 10 {
|
||||
panic!("node version is too low")
|
||||
}
|
||||
|
||||
let node_include_path = find_node_include_path(node_full_version.trim_end());
|
||||
|
||||
let out_path = PathBuf::from(env::var("OUT_DIR").unwrap());
|
||||
|
||||
let mut sys_bindigs_path = PathBuf::from("src");
|
||||
sys_bindigs_path.push("sys");
|
||||
sys_bindigs_path.push("bindings.h");
|
||||
|
||||
bindgen::Builder::default()
|
||||
.header(sys_bindigs_path.to_str().unwrap().to_owned())
|
||||
.clang_arg(String::from("-I") + node_include_path.to_str().unwrap())
|
||||
.rustified_enum("(napi_|uv_).+")
|
||||
.whitelist_function("(napi_|uv_|extras_).+")
|
||||
.whitelist_type("(napi_|uv_|extras_).+")
|
||||
.generate()
|
||||
.expect("Unable to generate napi bindings")
|
||||
.write_to_file(out_path.join("bindings.rs"))
|
||||
.expect("Unable to write napi bindings");
|
||||
}
|
||||
|
||||
#[cfg(target_os = "windows")]
|
||||
fn find_node_include_path(node_full_version: &str) -> PathBuf {
|
||||
let mut node_exec_path = PathBuf::from(
|
||||
String::from_utf8(
|
||||
Command::new("node")
|
||||
.arg("-e")
|
||||
.arg(NODE_PRINT_EXEC_PATH)
|
||||
.output()
|
||||
.unwrap()
|
||||
.stdout,
|
||||
)
|
||||
.expect("can not find executable node"),
|
||||
)
|
||||
.parent()
|
||||
.unwrap()
|
||||
.to_path_buf();
|
||||
node_exec_path.push(format!("node-headers-{}.tar.gz", node_full_version));
|
||||
let mut header_dist_path = PathBuf::from(&PathBuf::from(&node_exec_path).parent().unwrap());
|
||||
let unpack_path = PathBuf::from(&header_dist_path);
|
||||
header_dist_path.push(format!("node-{}", node_full_version));
|
||||
header_dist_path.push("include");
|
||||
header_dist_path.push("node");
|
||||
if !header_dist_path.exists() {
|
||||
let header_file_download_url = String::from_utf8(
|
||||
Command::new("node")
|
||||
.args(vec!["-e", "console.log(process.release.headersUrl)"])
|
||||
.output()
|
||||
.unwrap()
|
||||
.stdout,
|
||||
)
|
||||
.unwrap();
|
||||
let resp = reqwest::blocking::get(&header_file_download_url).expect("request failed");
|
||||
tar::Archive::new(flate2::read::GzDecoder::new(resp))
|
||||
.unpack(&unpack_path)
|
||||
.expect("Unpack headers file failed");
|
||||
};
|
||||
header_dist_path
|
||||
}
|
||||
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
fn find_node_include_path(_node_full_version: &str) -> PathBuf {
|
||||
let node_exec_path = String::from_utf8(
|
||||
Command::new("node")
|
||||
.arg("-e")
|
||||
.arg(NODE_PRINT_EXEC_PATH)
|
||||
.output()
|
||||
.unwrap()
|
||||
.stdout,
|
||||
)
|
||||
.unwrap();
|
||||
PathBuf::from(node_exec_path)
|
||||
.parent()
|
||||
.unwrap()
|
||||
.parent()
|
||||
.unwrap()
|
||||
.join("include/node")
|
||||
}
|
||||
|
|
|
@ -65,7 +65,6 @@ mod module;
|
|||
#[cfg(all(feature = "libuv", napi4))]
|
||||
mod promise;
|
||||
mod status;
|
||||
pub mod sys;
|
||||
mod task;
|
||||
#[cfg(napi4)]
|
||||
pub mod threadsafe_function;
|
||||
|
@ -75,6 +74,8 @@ mod tokio_rt;
|
|||
mod uv;
|
||||
mod version;
|
||||
|
||||
pub use napi_sys as sys;
|
||||
|
||||
pub use call_context::CallContext;
|
||||
pub use env::*;
|
||||
pub use error::{Error, Result};
|
||||
|
|
20
sys/Cargo.toml
Normal file
20
sys/Cargo.toml
Normal file
|
@ -0,0 +1,20 @@
|
|||
[package]
|
||||
name = "napi-sys"
|
||||
version = "0.4.0"
|
||||
authors = ["LongYinan <lynweklm@gmail.com>"]
|
||||
edition = "2018"
|
||||
readme = "README.md"
|
||||
repository = "https://github.com/Brooooooklyn/napi-rs"
|
||||
license = "MIT"
|
||||
keywords = ["NodeJS", "FFI", "NAPI", "n-api"]
|
||||
|
||||
[target.'cfg(windows)'.build-dependencies]
|
||||
flate2 = "1.0"
|
||||
reqwest = { version = "0.10", features = ["native-tls", "blocking"] }
|
||||
tar = "0.4"
|
||||
|
||||
[build-dependencies]
|
||||
bindgen = "0.54"
|
||||
glob = "0.3"
|
||||
regex = "1.3"
|
||||
semver = "0.10"
|
5
sys/README.md
Normal file
5
sys/README.md
Normal file
|
@ -0,0 +1,5 @@
|
|||
# napi-sys
|
||||
|
||||
Low-level N-API bindings for Node.js addons written in Rust.
|
||||
|
||||
See the [napi](https://github.com/napi-rs/napi-rs) for the high-level API.
|
115
sys/build.rs
Normal file
115
sys/build.rs
Normal file
|
@ -0,0 +1,115 @@
|
|||
extern crate bindgen;
|
||||
#[cfg(windows)]
|
||||
extern crate flate2;
|
||||
extern crate glob;
|
||||
#[cfg(windows)]
|
||||
extern crate reqwest;
|
||||
extern crate semver;
|
||||
#[cfg(windows)]
|
||||
extern crate tar;
|
||||
|
||||
use glob::glob;
|
||||
|
||||
use std::env;
|
||||
use std::path::PathBuf;
|
||||
use std::process::Command;
|
||||
|
||||
// https://stackoverflow.com/questions/37498864/finding-executable-in-path-with-rust
|
||||
|
||||
const NODE_PRINT_EXEC_PATH: &'static str = "console.log(process.execPath)";
|
||||
|
||||
fn main() {
|
||||
let node_full_version =
|
||||
String::from_utf8(Command::new("node").arg("-v").output().unwrap().stdout).unwrap();
|
||||
let node_version = semver::Version::parse(node_full_version.as_str().get(1..).unwrap()).unwrap();
|
||||
|
||||
let node_major_version = node_version.major;
|
||||
|
||||
println!("cargo:rerun-if-env-changed=NODE_INCLUDE_PATH");
|
||||
for entry in glob("./src/**/*.*").unwrap() {
|
||||
println!(
|
||||
"cargo:rerun-if-changed={}",
|
||||
entry.unwrap().to_str().unwrap()
|
||||
);
|
||||
}
|
||||
|
||||
if node_major_version < 10 {
|
||||
panic!("node version is too low")
|
||||
}
|
||||
|
||||
let node_include_path = find_node_include_path(node_full_version.trim_end());
|
||||
|
||||
let out_path = PathBuf::from(env::var("OUT_DIR").unwrap());
|
||||
|
||||
let mut sys_bindigs_path = PathBuf::from("src");
|
||||
sys_bindigs_path.push("bindings.h");
|
||||
|
||||
bindgen::Builder::default()
|
||||
.header(sys_bindigs_path.to_str().unwrap().to_owned())
|
||||
.clang_arg(String::from("-I") + node_include_path.to_str().unwrap())
|
||||
.rustified_enum("(napi_|uv_).+")
|
||||
.whitelist_function("(napi_|uv_|extras_).+")
|
||||
.whitelist_type("(napi_|uv_|extras_).+")
|
||||
.generate()
|
||||
.expect("Unable to generate napi bindings")
|
||||
.write_to_file(out_path.join("bindings.rs"))
|
||||
.expect("Unable to write napi bindings");
|
||||
}
|
||||
|
||||
#[cfg(target_os = "windows")]
|
||||
fn find_node_include_path(node_full_version: &str) -> PathBuf {
|
||||
let mut node_exec_path = PathBuf::from(
|
||||
String::from_utf8(
|
||||
Command::new("node")
|
||||
.arg("-e")
|
||||
.arg(NODE_PRINT_EXEC_PATH)
|
||||
.output()
|
||||
.unwrap()
|
||||
.stdout,
|
||||
)
|
||||
.expect("can not find executable node"),
|
||||
)
|
||||
.parent()
|
||||
.unwrap()
|
||||
.to_path_buf();
|
||||
node_exec_path.push(format!("node-headers-{}.tar.gz", node_full_version));
|
||||
let mut header_dist_path = PathBuf::from(&PathBuf::from(&node_exec_path).parent().unwrap());
|
||||
let unpack_path = PathBuf::from(&header_dist_path);
|
||||
header_dist_path.push(format!("node-{}", node_full_version));
|
||||
header_dist_path.push("include");
|
||||
header_dist_path.push("node");
|
||||
if !header_dist_path.exists() {
|
||||
let header_file_download_url = String::from_utf8(
|
||||
Command::new("node")
|
||||
.args(vec!["-e", "console.log(process.release.headersUrl)"])
|
||||
.output()
|
||||
.unwrap()
|
||||
.stdout,
|
||||
)
|
||||
.unwrap();
|
||||
let resp = reqwest::blocking::get(&header_file_download_url).expect("request failed");
|
||||
tar::Archive::new(flate2::read::GzDecoder::new(resp))
|
||||
.unpack(&unpack_path)
|
||||
.expect("Unpack headers file failed");
|
||||
};
|
||||
header_dist_path
|
||||
}
|
||||
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
fn find_node_include_path(_node_full_version: &str) -> PathBuf {
|
||||
let node_exec_path = String::from_utf8(
|
||||
Command::new("node")
|
||||
.arg("-e")
|
||||
.arg(NODE_PRINT_EXEC_PATH)
|
||||
.output()
|
||||
.unwrap()
|
||||
.stdout,
|
||||
)
|
||||
.unwrap();
|
||||
PathBuf::from(node_exec_path)
|
||||
.parent()
|
||||
.unwrap()
|
||||
.parent()
|
||||
.unwrap()
|
||||
.join("include/node")
|
||||
}
|
2
sys/src/lib.rs
Normal file
2
sys/src/lib.rs
Normal file
|
@ -0,0 +1,2 @@
|
|||
mod sys;
|
||||
pub use sys::*;
|
|
@ -9,8 +9,8 @@ crate-type = ["cdylib"]
|
|||
|
||||
[dependencies]
|
||||
futures = "0.3"
|
||||
napi-rs = { path = "../napi", features = ["libuv", "tokio_rt"] }
|
||||
napi-rs-derive = { path = "../napi-derive" }
|
||||
napi = { path = "../napi", features = ["libuv", "tokio_rt"] }
|
||||
napi-derive = { path = "../napi-derive" }
|
||||
tokio = { version = "0.2", features = ["default", "fs"]}
|
||||
|
||||
[build-dependencies]
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#[macro_use]
|
||||
extern crate napi_rs as napi;
|
||||
extern crate napi;
|
||||
#[macro_use]
|
||||
extern crate napi_rs_derive;
|
||||
extern crate napi_derive;
|
||||
|
||||
use napi::{CallContext, Error, JsString, JsUnknown, Module, Result, Status};
|
||||
|
||||
|
|
Loading…
Reference in a new issue