Skip to content

Commit 881b810

Browse files
committed
Fix cross-platform CI builds
- build.rs: Auto-detect V8 headers from standard path or node-gyp cache, auto-install via `npx node-gyp install` when headers are missing (Windows) - build.rs: Use MSVC-compatible flags (/std:c++20) on Windows targets - CI: Use target-specific CC/CXX env vars for aarch64-linux cross-compilation to avoid the host compiler picking up the cross-compiler
1 parent 4e1f30f commit 881b810

3 files changed

Lines changed: 74 additions & 32 deletions

File tree

.github/workflows/ci.yml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,9 @@ jobs:
3030
build: |
3131
sudo apt-get update
3232
sudo apt-get install -y gcc-aarch64-linux-gnu g++-aarch64-linux-gnu
33-
export CC=aarch64-linux-gnu-gcc
34-
export CXX=aarch64-linux-gnu-g++
33+
export CC_aarch64_unknown_linux_gnu=aarch64-linux-gnu-gcc
34+
export CXX_aarch64_unknown_linux_gnu=aarch64-linux-gnu-g++
35+
export CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER=aarch64-linux-gnu-gcc
3536
npm run build -- --target aarch64-unknown-linux-gnu
3637
- host: windows-latest
3738
target: x86_64-pc-windows-msvc

.github/workflows/publish.yml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,9 @@ jobs:
2828
build: |
2929
sudo apt-get update
3030
sudo apt-get install -y gcc-aarch64-linux-gnu g++-aarch64-linux-gnu
31-
export CC=aarch64-linux-gnu-gcc
32-
export CXX=aarch64-linux-gnu-g++
31+
export CC_aarch64_unknown_linux_gnu=aarch64-linux-gnu-gcc
32+
export CXX_aarch64_unknown_linux_gnu=aarch64-linux-gnu-g++
33+
export CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER=aarch64-linux-gnu-gcc
3334
npm run build -- --target aarch64-unknown-linux-gnu
3435
- host: windows-latest
3536
target: x86_64-pc-windows-msvc

build.rs

Lines changed: 68 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -19,44 +19,84 @@ fn main() {
1919

2020
// Compile v8_helpers.cpp — direct V8 bulk object creation
2121
let node_include = node_include_dir();
22-
cc::Build::new()
22+
let mut build = cc::Build::new();
23+
build
2324
.cpp(true)
2425
.file("src/v8_helpers.cpp")
25-
.include(&node_include)
26-
.flag("-std=c++20")
27-
.flag("-fno-exceptions")
28-
.flag("-fno-rtti")
29-
.flag("-Wno-unused-parameter")
30-
.flag("-O2")
31-
.compile("v8_helpers");
26+
.include(&node_include);
27+
28+
let target = std::env::var("TARGET").unwrap_or_default();
29+
if target.contains("msvc") {
30+
// MSVC flags
31+
build.flag("/std:c++20").flag("/EHs-").flag("/GR-");
32+
} else {
33+
// GCC/Clang flags
34+
build
35+
.flag("-std=c++20")
36+
.flag("-fno-exceptions")
37+
.flag("-fno-rtti")
38+
.flag("-Wno-unused-parameter")
39+
.flag("-O2");
40+
}
41+
42+
build.compile("v8_helpers");
3243
}
3344

3445
/// Get Node.js include directory for V8 headers.
35-
/// Resolves symlinks to find the actual install prefix.
46+
///
47+
/// Checks multiple locations:
48+
/// 1. Standard Node.js install prefix (Linux/macOS with dev headers)
49+
/// 2. node-gyp cache (Windows, or when headers installed via `npx node-gyp install`)
50+
/// 3. Auto-installs headers via node-gyp if not found
3651
fn node_include_dir() -> String {
52+
let script = r#"
53+
const p = require('path'), fs = require('fs');
54+
55+
function find(dirs) {
56+
for (const d of dirs) {
57+
if (d && fs.existsSync(p.join(d, 'v8.h'))) return d;
58+
}
59+
return null;
60+
}
61+
62+
const real = fs.realpathSync(process.execPath);
63+
const stdDir = p.resolve(real, '..', '..', 'include', 'node');
64+
const v = process.version.slice(1);
65+
const home = process.env.HOME || '';
66+
const la = process.env.LOCALAPPDATA || '';
67+
const gypDirs = [
68+
p.join(home, '.node-gyp', v, 'include', 'node'),
69+
p.join(la, 'node-gyp', 'Cache', v, 'include', 'node'),
70+
];
71+
72+
let dir = find([stdDir, ...gypDirs]);
73+
if (dir) { console.log(dir); process.exit(0); }
74+
75+
// Auto-install headers via node-gyp
76+
try {
77+
require('child_process').execSync('npx --yes node-gyp install', { stdio: 'inherit' });
78+
} catch {}
79+
80+
dir = find(gypDirs);
81+
if (dir) { console.log(dir); process.exit(0); }
82+
83+
process.exit(1);
84+
"#;
85+
3786
let output = std::process::Command::new("node")
38-
.args([
39-
"-e",
40-
"const p = require('path'); \
41-
const fs = require('fs'); \
42-
const real = fs.realpathSync(process.execPath); \
43-
console.log(p.resolve(real, '..', '..', 'include', 'node'));",
44-
])
87+
.args(["-e", script])
4588
.output()
4689
.expect("Failed to find Node.js. Make sure `node` is in your PATH.");
4790

48-
let dir = String::from_utf8(output.stdout)
49-
.expect("Invalid UTF-8 in Node.js include path")
50-
.trim()
51-
.to_string();
52-
53-
let v8_header = std::path::Path::new(&dir).join("v8.h");
54-
if !v8_header.exists() {
55-
panic!(
56-
"V8 headers not found at {dir}/v8.h. \
57-
Install Node.js development headers."
58-
);
91+
if output.status.success() {
92+
return String::from_utf8(output.stdout)
93+
.expect("Invalid UTF-8 in Node.js include path")
94+
.trim()
95+
.to_string();
5996
}
6097

61-
dir
98+
panic!(
99+
"V8 headers not found. Install Node.js development headers \
100+
or run: npx node-gyp install"
101+
);
62102
}

0 commit comments

Comments
 (0)