commit
7d975bb50a
11 changed files with 96 additions and 84 deletions
76
.github/workflows/windows-arm.yml
vendored
Normal file
76
.github/workflows/windows-arm.yml
vendored
Normal file
|
@ -0,0 +1,76 @@
|
||||||
|
name: Windows arm64
|
||||||
|
|
||||||
|
env:
|
||||||
|
DEBUG: 'napi:*'
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
pull_request:
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build_and_test:
|
||||||
|
name: stable - windows-latest - arm64 - node@14
|
||||||
|
runs-on: windows-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
|
||||||
|
- name: Setup node
|
||||||
|
uses: actions/setup-node@v1
|
||||||
|
with:
|
||||||
|
node-version: 14
|
||||||
|
|
||||||
|
- name: Cache NPM dependencies
|
||||||
|
uses: actions/cache@v1
|
||||||
|
with:
|
||||||
|
path: node_modules
|
||||||
|
key: npm-cache-windows-arm64-node@lts-${{ hashFiles('yarn.lock') }}
|
||||||
|
|
||||||
|
- name: 'Install dependencies'
|
||||||
|
run: yarn install --frozen-lockfile --registry https://registry.npmjs.org --network-timeout 300000
|
||||||
|
|
||||||
|
- name: 'Build TypeScript'
|
||||||
|
run: yarn build
|
||||||
|
|
||||||
|
- name: Install
|
||||||
|
uses: actions-rs/toolchain@v1
|
||||||
|
with:
|
||||||
|
toolchain: stable
|
||||||
|
profile: minimal
|
||||||
|
override: true
|
||||||
|
|
||||||
|
- name: Install arm64 toolchain
|
||||||
|
run: rustup target add aarch64-pc-windows-msvc
|
||||||
|
|
||||||
|
- name: Generate Cargo.lock
|
||||||
|
uses: actions-rs/cargo@v1
|
||||||
|
with:
|
||||||
|
command: generate-lockfile
|
||||||
|
|
||||||
|
- name: Cache cargo registry
|
||||||
|
uses: actions/cache@v1
|
||||||
|
with:
|
||||||
|
path: ~/.cargo/registry
|
||||||
|
key: stable-windows-arm64-node@lts-cargo-registry-trimmed-${{ hashFiles('**/Cargo.lock') }}
|
||||||
|
|
||||||
|
- name: Cache cargo index
|
||||||
|
uses: actions/cache@v1
|
||||||
|
with:
|
||||||
|
path: ~/.cargo/git
|
||||||
|
key: stable-windows-arm64-node@lts-cargo-index-trimmed-${{ hashFiles('**/Cargo.lock') }}
|
||||||
|
|
||||||
|
- name: Check build
|
||||||
|
uses: actions-rs/cargo@v1
|
||||||
|
with:
|
||||||
|
command: check
|
||||||
|
args: --all --bins --examples --tests --target aarch64-pc-windows-msvc -vvv
|
||||||
|
|
||||||
|
- name: Build release target
|
||||||
|
run: cargo build --release --target aarch64-pc-windows-msvc
|
||||||
|
|
||||||
|
- name: Clear the cargo caches
|
||||||
|
run: |
|
||||||
|
cargo install cargo-cache --no-default-features --features ci-autoclean
|
||||||
|
cargo-cache
|
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -3,7 +3,6 @@ target/
|
||||||
.DS_Store
|
.DS_Store
|
||||||
Cargo.lock
|
Cargo.lock
|
||||||
node_modules
|
node_modules
|
||||||
napi/src/sys/bindings.rs
|
|
||||||
*.node
|
*.node
|
||||||
build/LICENSE
|
build/LICENSE
|
||||||
napi/LICENSE
|
napi/LICENSE
|
||||||
|
|
|
@ -20,17 +20,20 @@ A minimal library for building compiled `Node.js` add-ons in `Rust`.
|
||||||
![Linux-armv7](https://github.com/napi-rs/napi-rs/workflows/Linux-armv7/badge.svg)
|
![Linux-armv7](https://github.com/napi-rs/napi-rs/workflows/Linux-armv7/badge.svg)
|
||||||
![macOS-Android](https://github.com/napi-rs/napi-rs/workflows/macOS-Android/badge.svg)
|
![macOS-Android](https://github.com/napi-rs/napi-rs/workflows/macOS-Android/badge.svg)
|
||||||
![Windows i686](https://github.com/napi-rs/napi-rs/workflows/Windows%20i686/badge.svg)
|
![Windows i686](https://github.com/napi-rs/napi-rs/workflows/Windows%20i686/badge.svg)
|
||||||
|
[![Windows arm64](https://github.com/napi-rs/napi-rs/actions/workflows/windows-arm.yml/badge.svg)](https://github.com/napi-rs/napi-rs/actions/workflows/windows-arm.yml)
|
||||||
[![FreeBSD](https://api.cirrus-ci.com/github/napi-rs/napi-rs.svg)](https://cirrus-ci.com/github/napi-rs/napi-rs?branch=main)
|
[![FreeBSD](https://api.cirrus-ci.com/github/napi-rs/napi-rs.svg)](https://cirrus-ci.com/github/napi-rs/napi-rs?branch=main)
|
||||||
|
|
||||||
| | node12 | node14 | node16 |
|
| | node12 | node14 | node16 |
|
||||||
| --------------------- | ------ | ------ | ------ |
|
| --------------------- | ------ | ------ | ------ |
|
||||||
| Windows x64 | ✓ | ✓ | ✓ |
|
| Windows x64 | ✓ | ✓ | ✓ |
|
||||||
| Windows x86 | ✓ | ✓ | ✓ |
|
| Windows x86 | ✓ | ✓ | ✓ |
|
||||||
|
| Windows arm64 | ✓ | ✓ | ✓ |
|
||||||
| macOS x64 | ✓ | ✓ | ✓ |
|
| macOS x64 | ✓ | ✓ | ✓ |
|
||||||
| macOS aarch64 | ✓ | ✓ | ✓ |
|
| macOS aarch64 | ✓ | ✓ | ✓ |
|
||||||
| Linux x64 gnu | ✓ | ✓ | ✓ |
|
| Linux x64 gnu | ✓ | ✓ | ✓ |
|
||||||
| Linux x64 musl | ✓ | ✓ | ✓ |
|
| Linux x64 musl | ✓ | ✓ | ✓ |
|
||||||
| Linux aarch64 gnu | ✓ | ✓ | ✓ |
|
| Linux aarch64 gnu | ✓ | ✓ | ✓ |
|
||||||
|
| Linux aarch64 musl | ✓ | ✓ | ✓ |
|
||||||
| Linux arm gnueabihf | ✓ | ✓ | ✓ |
|
| Linux arm gnueabihf | ✓ | ✓ | ✓ |
|
||||||
| Linux aarch64 android | ✓ | ✓ | ✓ |
|
| Linux aarch64 android | ✓ | ✓ | ✓ |
|
||||||
| FreeBSD x64 | ✓ | ✓ | ✓ |
|
| FreeBSD x64 | ✓ | ✓ | ✓ |
|
||||||
|
|
|
@ -13,10 +13,10 @@ napi-derive = {path = "../napi-derive"}
|
||||||
serde = "1"
|
serde = "1"
|
||||||
serde_json = "1"
|
serde_json = "1"
|
||||||
|
|
||||||
[target.'cfg(all(unix, not(target_env = "musl"), not(target_arch = "aarch64")))'.dependencies]
|
[target.'cfg(all(unix, not(target_env = "musl"), not(target_arch = "aarch64"), not(target_arch = "arm")))'.dependencies]
|
||||||
jemallocator = {version = "0.3", features = ["disable_initial_exec_tls"]}
|
jemallocator = {version = "0.3", features = ["disable_initial_exec_tls"]}
|
||||||
|
|
||||||
[target.'cfg(windows)'.dependencies]
|
[target.'cfg(all(windows, not(target_arch = "aarch64")))'.dependencies]
|
||||||
mimalloc = {version = "0.1"}
|
mimalloc = {version = "0.1"}
|
||||||
|
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
|
|
|
@ -7,7 +7,7 @@ use napi::{Env, JsObject, Result};
|
||||||
#[global_allocator]
|
#[global_allocator]
|
||||||
static ALLOC: jemallocator::Jemalloc = jemallocator::Jemalloc;
|
static ALLOC: jemallocator::Jemalloc = jemallocator::Jemalloc;
|
||||||
|
|
||||||
#[cfg(windows)]
|
#[cfg(all(windows, not(target_arch = "aarch64")))]
|
||||||
#[global_allocator]
|
#[global_allocator]
|
||||||
static ALLOC: mimalloc::MiMalloc = mimalloc::MiMalloc;
|
static ALLOC: mimalloc::MiMalloc = mimalloc::MiMalloc;
|
||||||
|
|
||||||
|
|
|
@ -2,15 +2,10 @@
|
||||||
authors = ["LongYinan <lynweklm@gmail.com>"]
|
authors = ["LongYinan <lynweklm@gmail.com>"]
|
||||||
description = "N-API build support"
|
description = "N-API build support"
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
|
include = ["src/**/*", "Cargo.toml", "README.md", "LICENSE"]
|
||||||
keywords = ["NodeJS", "FFI", "NAPI", "n-api"]
|
keywords = ["NodeJS", "FFI", "NAPI", "n-api"]
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
name = "napi-build"
|
name = "napi-build"
|
||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
repository = "https://github.com/napi-rs/napi-rs"
|
repository = "https://github.com/napi-rs/napi-rs"
|
||||||
version = "1.0.2"
|
version = "1.0.2"
|
||||||
|
|
||||||
[dependencies]
|
|
||||||
cfg-if = "1"
|
|
||||||
|
|
||||||
[target.'cfg(not(target_env = "musl"))'.dependencies]
|
|
||||||
ureq = "2"
|
|
||||||
|
|
|
@ -1,23 +1,10 @@
|
||||||
mod macos;
|
mod macos;
|
||||||
|
mod windows;
|
||||||
cfg_if::cfg_if! {
|
|
||||||
if #[cfg(not(target_env = "musl"))] {
|
|
||||||
mod windows;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn setup() {
|
pub fn setup() {
|
||||||
match std::env::var("CARGO_CFG_TARGET_OS").as_deref() {
|
match std::env::var("CARGO_CFG_TARGET_OS").as_deref() {
|
||||||
Ok("macos") => macos::setup(),
|
Ok("macos") => macos::setup(),
|
||||||
Ok("windows") => {
|
Ok("windows") => windows::setup(),
|
||||||
cfg_if::cfg_if! {
|
|
||||||
if #[cfg(not(target_env = "musl"))] {
|
|
||||||
windows::setup()
|
|
||||||
} else {
|
|
||||||
eprintln!("Cross compiling to windows-msvc is not supported from *-musl hosts")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
BIN
build/src/libs/node-arm64.lib
Normal file
BIN
build/src/libs/node-arm64.lib
Normal file
Binary file not shown.
BIN
build/src/libs/node-x64.lib
Normal file
BIN
build/src/libs/node-x64.lib
Normal file
Binary file not shown.
BIN
build/src/libs/node-x86.lib
Normal file
BIN
build/src/libs/node-x86.lib
Normal file
Binary file not shown.
|
@ -1,54 +1,20 @@
|
||||||
#![allow(clippy::expect_fun_call)]
|
#![allow(clippy::expect_fun_call)]
|
||||||
use std::collections::hash_map::DefaultHasher;
|
|
||||||
use std::env;
|
use std::env;
|
||||||
use std::fs::{metadata, write};
|
use std::fs::{metadata, write};
|
||||||
use std::hash::{Hash, Hasher};
|
|
||||||
use std::io::Read;
|
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use std::process::Command;
|
|
||||||
|
|
||||||
fn get_node_version() -> std::io::Result<String> {
|
fn copy_node_lib(arch: &str) -> Vec<u8> {
|
||||||
let output = Command::new("node").arg("-v").output()?;
|
match arch {
|
||||||
let stdout_str = String::from_utf8_lossy(&output.stdout);
|
"x64" => include_bytes!("libs/node-x64.lib").to_vec(),
|
||||||
|
"x86" => include_bytes!("libs/node-x86.lib").to_vec(),
|
||||||
// version should not have a leading "v" or trailing whitespace
|
"arm64" => include_bytes!("libs/node-arm64.lib").to_vec(),
|
||||||
Ok(stdout_str.trim().trim_start_matches('v').to_string())
|
_ => unreachable!(),
|
||||||
}
|
|
||||||
|
|
||||||
fn download_node_lib(dist_url: &str, version: &str, arch: &str) -> Vec<u8> {
|
|
||||||
// Assume windows since we know we are building on windows.
|
|
||||||
let url = format!(
|
|
||||||
"{dist_url}/v{version}/win-{arch}/node.lib",
|
|
||||||
dist_url = dist_url,
|
|
||||||
version = version,
|
|
||||||
arch = arch
|
|
||||||
);
|
|
||||||
|
|
||||||
match ureq::get(&url).call() {
|
|
||||||
Ok(response) => {
|
|
||||||
let mut reader = response.into_reader();
|
|
||||||
let mut bytes = vec![];
|
|
||||||
reader.read_to_end(&mut bytes).unwrap();
|
|
||||||
bytes
|
|
||||||
}
|
|
||||||
Err(error) => {
|
|
||||||
panic!("Failed to download node.lib: {:#?}", error);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn setup() {
|
pub fn setup() {
|
||||||
let out_dir = env::var("OUT_DIR").expect("OUT_DIR is not set");
|
let out_dir = env::var("OUT_DIR").expect("OUT_DIR is not set");
|
||||||
|
|
||||||
// Assume nodejs if not specified.
|
|
||||||
let dist_url =
|
|
||||||
env::var("NPM_CONFIG_DISTURL").unwrap_or_else(|_| "https://nodejs.org/dist".to_string());
|
|
||||||
|
|
||||||
// Try to get local nodejs version if not specified.
|
|
||||||
let node_version = env::var("NPM_CONFIG_TARGET")
|
|
||||||
.or_else(|_| get_node_version())
|
|
||||||
.expect("Failed to determine nodejs version");
|
|
||||||
|
|
||||||
// NPM also gives us an arch var, but let's trust cargo more.
|
// NPM also gives us an arch var, but let's trust cargo more.
|
||||||
// We translate from cargo's arch env format into npm/gyps's.
|
// We translate from cargo's arch env format into npm/gyps's.
|
||||||
// See https://doc.rust-lang.org/reference/conditional-compilation.html#target_arch for rust env values.
|
// See https://doc.rust-lang.org/reference/conditional-compilation.html#target_arch for rust env values.
|
||||||
|
@ -62,37 +28,23 @@ pub fn setup() {
|
||||||
"x86_64" => "x64",
|
"x86_64" => "x64",
|
||||||
// https://github.com/nodejs/node/issues/25998
|
// https://github.com/nodejs/node/issues/25998
|
||||||
// actually not supported for now
|
// actually not supported for now
|
||||||
// because we can not get `node.lib` file for `aarch64` device
|
// but we can get it from https://unofficial-builds.nodejs.org/download/release
|
||||||
|
// just set the `NPM_CONFIG_DISTURL` to `https://unofficial-builds.nodejs.org/download/release`
|
||||||
"aarch64" => "arm64",
|
"aarch64" => "arm64",
|
||||||
arch => panic!("Unsupported CPU Architecture: {}", arch),
|
arch => panic!("Unsupported CPU Architecture: {}", arch),
|
||||||
})
|
})
|
||||||
.expect("Failed to determine target arch");
|
.expect("Failed to determine target arch");
|
||||||
|
|
||||||
println!("cargo:rerun-if-env-changed=NPM_CONFIG_DISTURL");
|
|
||||||
println!("cargo:rerun-if-env-changed=NPM_CONFIG_TARGET");
|
|
||||||
|
|
||||||
let mut node_lib_file_path = PathBuf::from(out_dir);
|
let mut node_lib_file_path = PathBuf::from(out_dir);
|
||||||
let link_search_dir = node_lib_file_path.clone();
|
let link_search_dir = node_lib_file_path.clone();
|
||||||
|
|
||||||
// Hash the dist_url and store it in the node lib file name.
|
// Encode arch to detect and require node.lib.
|
||||||
let dist_url_hash = {
|
let node_lib_file_name = format!("node-{arch}.lib", arch = arch,);
|
||||||
let mut hasher = DefaultHasher::new();
|
|
||||||
dist_url.hash(&mut hasher);
|
|
||||||
hasher.finish()
|
|
||||||
};
|
|
||||||
|
|
||||||
// Encode version, arch, and dist_url to detect and reaquire node.lib when these 3 change.
|
|
||||||
let node_lib_file_name = format!(
|
|
||||||
"node-{version}-{arch}-{dist_url_hash}.lib",
|
|
||||||
version = node_version,
|
|
||||||
arch = arch,
|
|
||||||
dist_url_hash = dist_url_hash
|
|
||||||
);
|
|
||||||
node_lib_file_path.push(&node_lib_file_name);
|
node_lib_file_path.push(&node_lib_file_name);
|
||||||
|
|
||||||
// If file does not exist, download it.
|
// If file does not exist, download it.
|
||||||
if metadata(&node_lib_file_path).is_err() {
|
if metadata(&node_lib_file_path).is_err() {
|
||||||
let node_lib = download_node_lib(&dist_url, &node_version, &arch);
|
let node_lib = copy_node_lib(&arch);
|
||||||
|
|
||||||
write(&node_lib_file_path, &node_lib).expect(&format!(
|
write(&node_lib_file_path, &node_lib).expect(&format!(
|
||||||
"Could not save file to {}",
|
"Could not save file to {}",
|
||||||
|
|
Loading…
Reference in a new issue