summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cli/build.rs47
-rw-r--r--cli/mainrt.rs1
-rw-r--r--tests/integration/compile_tests.rs63
-rw-r--r--tests/testdata/compile/napi/main.ts7
-rw-r--r--tests/testdata/compile/napi/module.c68
5 files changed, 174 insertions, 12 deletions
diff --git a/cli/build.rs b/cli/build.rs
index 4fe6fd1ea..f131bc1dc 100644
--- a/cli/build.rs
+++ b/cli/build.rs
@@ -404,16 +404,28 @@ fn main() {
);
#[cfg(target_os = "windows")]
- println!(
- "cargo:rustc-link-arg-bin=deno=/DEF:{}",
- symbols_path.display()
- );
+ {
+ println!(
+ "cargo:rustc-link-arg-bin=deno=/DEF:{}",
+ symbols_path.display()
+ );
+ println!(
+ "cargo:rustc-link-arg-bin=denort=/DEF:{}",
+ symbols_path.display()
+ );
+ }
#[cfg(target_os = "macos")]
- println!(
- "cargo:rustc-link-arg-bin=deno=-Wl,-exported_symbols_list,{}",
- symbols_path.display()
- );
+ {
+ println!(
+ "cargo:rustc-link-arg-bin=deno=-Wl,-exported_symbols_list,{}",
+ symbols_path.display()
+ );
+ println!(
+ "cargo:rustc-link-arg-bin=denort=-Wl,-exported_symbols_list,{}",
+ symbols_path.display()
+ );
+ }
#[cfg(target_os = "linux")]
{
@@ -426,19 +438,30 @@ fn main() {
{
println!("cargo:warning=Compiling with all symbols exported, this will result in a larger binary. Please use glibc 2.35 or later for an optimised build.");
println!("cargo:rustc-link-arg-bin=deno=-rdynamic");
+ println!("cargo:rustc-link-arg-bin=denort=-rdynamic");
} else {
println!(
"cargo:rustc-link-arg-bin=deno=-Wl,--export-dynamic-symbol-list={}",
symbols_path.display()
);
+ println!(
+ "cargo:rustc-link-arg-bin=denort=-Wl,--export-dynamic-symbol-list={}",
+ symbols_path.display()
+ );
}
}
#[cfg(target_os = "android")]
- println!(
- "cargo:rustc-link-arg-bin=deno=-Wl,--export-dynamic-symbol-list={}",
- symbols_path.display()
- );
+ {
+ println!(
+ "cargo:rustc-link-arg-bin=deno=-Wl,--export-dynamic-symbol-list={}",
+ symbols_path.display()
+ );
+ println!(
+ "cargo:rustc-link-arg-bin=denort=-Wl,--export-dynamic-symbol-list={}",
+ symbols_path.display()
+ );
+ }
// To debug snapshot issues uncomment:
// op_fetch_asset::trace_serializer();
diff --git a/cli/mainrt.rs b/cli/mainrt.rs
index aafbf7932..ef163dd00 100644
--- a/cli/mainrt.rs
+++ b/cli/mainrt.rs
@@ -15,6 +15,7 @@ mod errors;
mod file_fetcher;
mod http_util;
mod js;
+mod napi;
mod node;
mod npm;
mod resolver;
diff --git a/tests/integration/compile_tests.rs b/tests/integration/compile_tests.rs
index 17054637e..cd6e429b3 100644
--- a/tests/integration/compile_tests.rs
+++ b/tests/integration/compile_tests.rs
@@ -1283,3 +1283,66 @@ fn standalone_jsr_dynamic_import() {
output.assert_exit_code(0);
output.assert_matches_text("Hello world\n");
}
+
+#[test]
+fn standalone_require_node_addons() {
+ #[cfg(not(target_os = "windows"))]
+ {
+ let context = TestContextBuilder::for_jsr().build();
+ let dir = context.temp_dir();
+ let libout = dir.path().join("module.node");
+
+ let cc = context
+ .new_command()
+ .name("cc")
+ .current_dir(util::testdata_path());
+
+ #[cfg(not(target_os = "macos"))]
+ let c_module = cc
+ .arg("./compile/napi/module.c")
+ .arg("-shared")
+ .arg("-o")
+ .arg(&libout);
+
+ #[cfg(target_os = "macos")]
+ let c_module = {
+ cc.arg("./compile/napi/module.c")
+ .arg("-undefined")
+ .arg("dynamic_lookup")
+ .arg("-shared")
+ .arg("-Wl,-no_fixup_chains")
+ .arg("-dynamic")
+ .arg("-o")
+ .arg(&libout)
+ };
+ let c_module_output = c_module.output().unwrap();
+
+ assert!(c_module_output.status.success());
+
+ let exe = if cfg!(windows) {
+ dir.path().join("main.exe")
+ } else {
+ dir.path().join("main")
+ };
+
+ context
+ .new_command()
+ .env("NPM_CONFIG_REGISTRY", "https://registry.npmjs.org/")
+ .args_vec([
+ "compile",
+ "--allow-read",
+ "--allow-ffi",
+ "--output",
+ &exe.to_string_lossy(),
+ "./compile/napi/main.ts",
+ ])
+ .run()
+ .skip_output_check()
+ .assert_exit_code(0);
+
+ let output = context.new_command().name(&exe).arg(&libout).run();
+
+ output.assert_exit_code(0);
+ output.assert_matches_text("{}\n");
+ }
+}
diff --git a/tests/testdata/compile/napi/main.ts b/tests/testdata/compile/napi/main.ts
new file mode 100644
index 000000000..91e8a0561
--- /dev/null
+++ b/tests/testdata/compile/napi/main.ts
@@ -0,0 +1,7 @@
+import Module from "node:module";
+
+const mod = new Module("");
+
+const filepath = Deno.args[0];
+
+console.log(mod.require(filepath));
diff --git a/tests/testdata/compile/napi/module.c b/tests/testdata/compile/napi/module.c
new file mode 100644
index 000000000..4548aa37f
--- /dev/null
+++ b/tests/testdata/compile/napi/module.c
@@ -0,0 +1,68 @@
+typedef struct napi_module {
+ int nm_version;
+ unsigned int nm_flags;
+ const char* nm_filename;
+ void* nm_register_func;
+ const char* nm_modname;
+ void* nm_priv;
+ void* reserved[4];
+} napi_module;
+
+#ifdef _WIN32
+#define NAPI_EXTERN __declspec(dllexport)
+#define NAPI_CDECL __cdecl
+#else
+#define NAPI_EXTERN __attribute__((visibility("default")))
+#define NAPI_CDECL
+#endif
+
+NAPI_EXTERN void NAPI_CDECL
+napi_module_register(napi_module* mod);
+
+#if defined(_MSC_VER)
+#if defined(__cplusplus)
+#define NAPI_C_CTOR(fn) \
+ static void NAPI_CDECL fn(void); \
+ namespace { \
+ struct fn##_ { \
+ fn##_() { fn(); } \
+ } fn##_v_; \
+ } \
+ static void NAPI_CDECL fn(void)
+#else // !defined(__cplusplus)
+#pragma section(".CRT$XCU", read)
+// The NAPI_C_CTOR macro defines a function fn that is called during CRT
+// initialization.
+// C does not support dynamic initialization of static variables and this code
+// simulates C++ behavior. Exporting the function pointer prevents it from being
+// optimized. See for details:
+// https://docs.microsoft.com/en-us/cpp/c-runtime-library/crt-initialization?view=msvc-170
+#define NAPI_C_CTOR(fn) \
+ static void NAPI_CDECL fn(void); \
+ __declspec(dllexport, allocate(".CRT$XCU")) void(NAPI_CDECL * fn##_)(void) = \
+ fn; \
+ static void NAPI_CDECL fn(void)
+#endif // defined(__cplusplus)
+#else
+#define NAPI_C_CTOR(fn) \
+ static void fn(void) __attribute__((constructor)); \
+ static void fn(void)
+#endif
+
+#define NAPI_MODULE_TEST(modname, regfunc) \
+ static napi_module _module = { \
+ 1, \
+ 0, \
+ __FILE__, \
+ regfunc, \
+ #modname, \
+ 0, \
+ {0}, \
+ }; \
+ NAPI_C_CTOR(_register_##modname) { napi_module_register(&_module); } \
+
+void* init(void* env __attribute__((unused)), void* exports) {
+ return exports;
+}
+
+NAPI_MODULE_TEST(TEST_NAPI_MODULE_NAME, init)