Skip to content

Commit 5a4d780

Browse files
committed
Fix Windows build: link against node.lib for V8 symbols
On Windows/MSVC, V8 symbols must be resolved at link time via node.lib (the import library). On Unix, they resolve at runtime when Node.js loads the .node addon. The build script now finds node.lib from the node-gyp cache or the Node.js install directory.
1 parent 881b810 commit 5a4d780

1 file changed

Lines changed: 48 additions & 1 deletion

File tree

build.rs

Lines changed: 48 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ extern crate napi_build;
1717
fn main() {
1818
napi_build::setup();
1919

20+
let target = std::env::var("TARGET").unwrap_or_default();
21+
2022
// Compile v8_helpers.cpp — direct V8 bulk object creation
2123
let node_include = node_include_dir();
2224
let mut build = cc::Build::new();
@@ -25,7 +27,6 @@ fn main() {
2527
.file("src/v8_helpers.cpp")
2628
.include(&node_include);
2729

28-
let target = std::env::var("TARGET").unwrap_or_default();
2930
if target.contains("msvc") {
3031
// MSVC flags
3132
build.flag("/std:c++20").flag("/EHs-").flag("/GR-");
@@ -40,6 +41,52 @@ fn main() {
4041
}
4142

4243
build.compile("v8_helpers");
44+
45+
// On Windows, link against node.lib for V8 symbols.
46+
// On Unix, V8 symbols resolve at runtime when Node.js loads the .node addon.
47+
if target.contains("windows") {
48+
link_node_lib(&node_include);
49+
}
50+
}
51+
52+
/// Link against node.lib on Windows.
53+
///
54+
/// Searches for node.lib in:
55+
/// 1. node-gyp cache: <version_dir>/<arch>/node.lib
56+
/// 2. Node.js install directory (next to node.exe)
57+
fn link_node_lib(include_dir: &str) {
58+
let include_path = std::path::Path::new(include_dir);
59+
60+
// node-gyp cache layout: .../Cache/<version>/include/node/
61+
// node.lib is at: .../Cache/<version>/x64/node.lib
62+
if let Some(version_dir) = include_path.parent().and_then(|p| p.parent()) {
63+
for arch in &["x64", "arm64", "x86"] {
64+
let lib_dir = version_dir.join(arch);
65+
if lib_dir.join("node.lib").exists() {
66+
println!("cargo:rustc-link-search={}", lib_dir.display());
67+
println!("cargo:rustc-link-lib=node");
68+
return;
69+
}
70+
}
71+
}
72+
73+
// Fallback: node.lib next to node.exe
74+
let output = std::process::Command::new("node")
75+
.args(["-e", "console.log(require('path').dirname(process.execPath))"])
76+
.output()
77+
.ok();
78+
if let Some(out) = output {
79+
if let Ok(dir) = String::from_utf8(out.stdout) {
80+
let dir = dir.trim();
81+
if std::path::Path::new(dir).join("node.lib").exists() {
82+
println!("cargo:rustc-link-search={dir}");
83+
println!("cargo:rustc-link-lib=node");
84+
return;
85+
}
86+
}
87+
}
88+
89+
panic!("node.lib not found. Required for Windows builds. Run: npx node-gyp install");
4390
}
4491

4592
/// Get Node.js include directory for V8 headers.

0 commit comments

Comments
 (0)