diff --git a/Cargo.lock b/Cargo.lock index 5e4913561e..1799a10bb3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -843,7 +843,6 @@ dependencies = [ "flaky_test", "flate2", "fwdansi", - "glibc_version", "google-storage1", "http", "import_map", @@ -2048,15 +2047,6 @@ dependencies = [ "polyval", ] -[[package]] -name = "glibc_version" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "803ff7635f1ab4e2c064b68a0c60da917d3d18dc8d086130f689d62ce4f1c33e" -dependencies = [ - "regex", -] - [[package]] name = "glob" version = "0.3.0" diff --git a/cli/Cargo.toml b/cli/Cargo.toml index 094a32d53b..267048b271 100644 --- a/cli/Cargo.toml +++ b/cli/Cargo.toml @@ -43,7 +43,6 @@ regex = "=1.6.0" serde = { version = "=1.0.144", features = ["derive"] } serde_json = "1.0.64" zstd = '=0.11.2' -glibc_version = "0.1.2" [target.'cfg(windows)'.build-dependencies] winapi = "=0.3.9" diff --git a/cli/build.rs b/cli/build.rs index 98d044a3e9..0d683780f2 100644 --- a/cli/build.rs +++ b/cli/build.rs @@ -332,40 +332,56 @@ fn main() { panic!("Cross compiling with snapshot is not supported."); } - let symbols_path = std::path::Path::new( - format!("generated_symbol_exports_list_{}.def", env::consts::OS).as_str(), - ) - .canonicalize() - .expect( - "Missing symbols list! Generate using tools/napi/generate_symbols_lists.js", - ); - #[cfg(target_os = "windows")] println!( "cargo:rustc-link-arg-bin=deno=/DEF:{}", - symbols_path.display() + std::path::Path::new("exports.def") + .canonicalize() + .expect( + "Missing exports.def! Generate using tools/napi/generate_link_win.js" + ) + .display(), ); - #[cfg(target_os = "macos")] - println!( - "cargo:rustc-link-arg-bin=deno=-Wl,-exported_symbols_list,{}", - symbols_path.display() - ); - - #[cfg(target_os = "linux")] + #[cfg(all( + not(target_os = "windows"), + not(all(target_os = "linux", target_arch = "aarch64")) + ))] { - let ver = glibc_version::get_version().unwrap(); - if ver.major <= 2 && ver.minor < 35 { - 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"); - } else { + // Load the symbols file generated by the `napi_sym` macro. + #[derive(serde::Deserialize)] + struct Symbols { + symbols: Vec, + } + let symbols_json = + std::fs::read_to_string("./napi_sym/symbol_exports.json").expect( + "Missing ./napi_sym/symbol_exports.json! This is a bug in napi_sym", + ); + let symbols: Symbols = serde_json::from_str(&symbols_json) + .expect("./napi_sym/symbol_exports.json is not valid JSON"); + + // Don't export all symbols into the dynamic symbol table. -rdynamic exports *all* symbols introducing binary bloat. + // We only need to export Node API symbols. + for symbol in symbols.symbols { + // TODO(@littledivy): We _might_ hit an argument size limit? + // Maybe use `--export-dynamic-symbol-list` / `--exported_symbols_list` instead? https://reviews.llvm.org/D107317 + #[cfg(target_os = "macos")] println!( - "cargo:rustc-link-arg-bin=deno=-Wl,--export-dynamic-symbol-list={}", - symbols_path.display() + "cargo:rustc-link-arg-bin=deno=-Wl,-exported_symbol,_{}", + symbol + ); + #[cfg(target_os = "linux")] + println!( + "cargo:rustc-link-arg-bin=deno=-Wl,--export-dynamic-symbol={}", + symbol ); } } + // Linux + aarch64 does not support a glibc version that supports `--export-dynamic-symbol`. + #[cfg(all(target_os = "linux", target_arch = "aarch64"))] + println!("cargo:rustc-link-arg-bin=deno=-rdynamic"); + // To debug snapshot issues uncomment: // op_fetch_asset::trace_serializer(); diff --git a/cli/generated_symbol_exports_list_windows.def b/cli/exports.def similarity index 100% rename from cli/generated_symbol_exports_list_windows.def rename to cli/exports.def diff --git a/cli/generated_symbol_exports_list_linux.def b/cli/generated_symbol_exports_list_linux.def deleted file mode 100644 index 0adba1dcef..0000000000 --- a/cli/generated_symbol_exports_list_linux.def +++ /dev/null @@ -1,144 +0,0 @@ -node_api_create_syntax_error -napi_make_callback -napi_has_named_property -napi_async_destroy -napi_coerce_to_object -napi_get_arraybuffer_info -napi_detach_arraybuffer -napi_get_undefined -napi_reference_unref -napi_fatal_error -napi_open_callback_scope -napi_close_callback_scope -napi_get_value_uint32 -napi_create_function -napi_create_arraybuffer -napi_get_value_int64 -napi_get_all_property_names -napi_resolve_deferred -napi_is_detached_arraybuffer -napi_create_string_utf8 -napi_create_threadsafe_function -node_api_throw_syntax_error -napi_create_bigint_int64 -napi_wrap -napi_set_property -napi_get_value_bigint_int64 -napi_open_handle_scope -napi_create_error -napi_create_buffer -napi_cancel_async_work -napi_is_exception_pending -napi_acquire_threadsafe_function -napi_create_external -napi_get_threadsafe_function_context -napi_get_null -napi_create_string_utf16 -napi_get_value_bigint_uint64 -napi_module_register -napi_is_typedarray -napi_create_external_buffer -napi_get_new_target -napi_get_instance_data -napi_close_handle_scope -napi_get_value_string_utf16 -napi_get_property_names -napi_is_arraybuffer -napi_get_cb_info -napi_define_properties -napi_add_env_cleanup_hook -node_api_get_module_file_name -napi_get_node_version -napi_create_int64 -napi_create_double -napi_get_and_clear_last_exception -napi_create_reference -napi_get_typedarray_info -napi_call_threadsafe_function -napi_get_last_error_info -napi_create_array_with_length -napi_coerce_to_number -napi_get_global -napi_is_error -napi_set_instance_data -napi_create_typedarray -napi_throw_type_error -napi_has_property -napi_get_value_external -napi_create_range_error -napi_typeof -napi_ref_threadsafe_function -napi_create_bigint_uint64 -napi_get_prototype -napi_adjust_external_memory -napi_release_threadsafe_function -napi_delete_async_work -napi_create_string_latin1 -napi_is_array -napi_unref_threadsafe_function -napi_throw_error -napi_has_own_property -napi_get_reference_value -napi_remove_env_cleanup_hook -napi_get_value_string_utf8 -napi_is_promise -napi_get_boolean -napi_run_script -napi_get_element -napi_get_named_property -napi_get_buffer_info -napi_get_value_bool -napi_reference_ref -napi_create_object -napi_create_promise -napi_create_int32 -napi_escape_handle -napi_open_escapable_handle_scope -napi_throw -napi_get_value_double -napi_set_named_property -napi_call_function -napi_create_date -napi_object_freeze -napi_get_uv_event_loop -napi_get_value_string_latin1 -napi_reject_deferred -napi_add_finalizer -napi_create_array -napi_delete_reference -napi_get_date_value -napi_create_dataview -napi_get_version -napi_define_class -napi_is_date -napi_remove_wrap -napi_delete_property -napi_instanceof -napi_create_buffer_copy -napi_delete_element -napi_object_seal -napi_queue_async_work -napi_get_value_bigint_words -napi_is_buffer -napi_get_array_length -napi_get_property -napi_new_instance -napi_set_element -napi_create_bigint_words -napi_strict_equals -napi_is_dataview -napi_close_escapable_handle_scope -napi_get_dataview_info -napi_get_value_int32 -napi_unwrap -napi_throw_range_error -napi_coerce_to_bool -napi_create_uint32 -napi_has_element -napi_create_external_arraybuffer -napi_create_symbol -napi_coerce_to_string -napi_create_type_error -napi_fatal_exception -napi_create_async_work -napi_async_init diff --git a/cli/generated_symbol_exports_list_macos.def b/cli/generated_symbol_exports_list_macos.def deleted file mode 100644 index 7c588ea2fd..0000000000 --- a/cli/generated_symbol_exports_list_macos.def +++ /dev/null @@ -1,144 +0,0 @@ -_node_api_create_syntax_error -_napi_make_callback -_napi_has_named_property -_napi_async_destroy -_napi_coerce_to_object -_napi_get_arraybuffer_info -_napi_detach_arraybuffer -_napi_get_undefined -_napi_reference_unref -_napi_fatal_error -_napi_open_callback_scope -_napi_close_callback_scope -_napi_get_value_uint32 -_napi_create_function -_napi_create_arraybuffer -_napi_get_value_int64 -_napi_get_all_property_names -_napi_resolve_deferred -_napi_is_detached_arraybuffer -_napi_create_string_utf8 -_napi_create_threadsafe_function -_node_api_throw_syntax_error -_napi_create_bigint_int64 -_napi_wrap -_napi_set_property -_napi_get_value_bigint_int64 -_napi_open_handle_scope -_napi_create_error -_napi_create_buffer -_napi_cancel_async_work -_napi_is_exception_pending -_napi_acquire_threadsafe_function -_napi_create_external -_napi_get_threadsafe_function_context -_napi_get_null -_napi_create_string_utf16 -_napi_get_value_bigint_uint64 -_napi_module_register -_napi_is_typedarray -_napi_create_external_buffer -_napi_get_new_target -_napi_get_instance_data -_napi_close_handle_scope -_napi_get_value_string_utf16 -_napi_get_property_names -_napi_is_arraybuffer -_napi_get_cb_info -_napi_define_properties -_napi_add_env_cleanup_hook -_node_api_get_module_file_name -_napi_get_node_version -_napi_create_int64 -_napi_create_double -_napi_get_and_clear_last_exception -_napi_create_reference -_napi_get_typedarray_info -_napi_call_threadsafe_function -_napi_get_last_error_info -_napi_create_array_with_length -_napi_coerce_to_number -_napi_get_global -_napi_is_error -_napi_set_instance_data -_napi_create_typedarray -_napi_throw_type_error -_napi_has_property -_napi_get_value_external -_napi_create_range_error -_napi_typeof -_napi_ref_threadsafe_function -_napi_create_bigint_uint64 -_napi_get_prototype -_napi_adjust_external_memory -_napi_release_threadsafe_function -_napi_delete_async_work -_napi_create_string_latin1 -_napi_is_array -_napi_unref_threadsafe_function -_napi_throw_error -_napi_has_own_property -_napi_get_reference_value -_napi_remove_env_cleanup_hook -_napi_get_value_string_utf8 -_napi_is_promise -_napi_get_boolean -_napi_run_script -_napi_get_element -_napi_get_named_property -_napi_get_buffer_info -_napi_get_value_bool -_napi_reference_ref -_napi_create_object -_napi_create_promise -_napi_create_int32 -_napi_escape_handle -_napi_open_escapable_handle_scope -_napi_throw -_napi_get_value_double -_napi_set_named_property -_napi_call_function -_napi_create_date -_napi_object_freeze -_napi_get_uv_event_loop -_napi_get_value_string_latin1 -_napi_reject_deferred -_napi_add_finalizer -_napi_create_array -_napi_delete_reference -_napi_get_date_value -_napi_create_dataview -_napi_get_version -_napi_define_class -_napi_is_date -_napi_remove_wrap -_napi_delete_property -_napi_instanceof -_napi_create_buffer_copy -_napi_delete_element -_napi_object_seal -_napi_queue_async_work -_napi_get_value_bigint_words -_napi_is_buffer -_napi_get_array_length -_napi_get_property -_napi_new_instance -_napi_set_element -_napi_create_bigint_words -_napi_strict_equals -_napi_is_dataview -_napi_close_escapable_handle_scope -_napi_get_dataview_info -_napi_get_value_int32 -_napi_unwrap -_napi_throw_range_error -_napi_coerce_to_bool -_napi_create_uint32 -_napi_has_element -_napi_create_external_arraybuffer -_napi_create_symbol -_napi_coerce_to_string -_napi_create_type_error -_napi_fatal_exception -_napi_create_async_work -_napi_async_init diff --git a/cli/napi/README.md b/cli/napi/README.md index 210d89b180..7f46d97973 100644 --- a/cli/napi/README.md +++ b/cli/napi/README.md @@ -44,10 +44,10 @@ pub fn napi_get_boolean( } ``` -Update the generated symbol lists using the script: +Update the Windows `.def` file using the script: ``` -deno run --allow-write tools/napi/generate_symbols_lists.js +deno run --allow-write tools/napi/generate_link_win.js ``` Add a test in [`/test_napi`](../../test_napi/). You can also refer to Node.js @@ -109,7 +109,7 @@ unsafe extern "C" fn napi_register_module_v1( ) -> napi_value { ... + boolean::init(env, exports); - + exports } ``` diff --git a/cli/napi/mod.rs b/cli/napi/mod.rs index 1712632a5c..8982a732a5 100644 --- a/cli/napi/mod.rs +++ b/cli/napi/mod.rs @@ -7,13 +7,13 @@ //! Symbols to be exported are now defined in this JSON file. //! The `#[napi_sym]` macro checks for missing entries and panics. //! -//! `./tools/napi/generate_symbols_list.js` is used to generate the LINK `cli/exports.def` on Windows, +//! `./tools/napi/generate_link_win.js` is used to generate the LINK `cli/exports.def` on Windows, //! which is also checked into git. //! //! To add a new napi function: //! 1. Place `#[napi_sym]` on top of your implementation. //! 2. Add the function's identifier to this JSON list. -//! 3. Finally, run `./tools/napi/generate_symbols_list.js` to update `cli/generated_symbol_exports_list_*.def`. +//! 3. Finally, run `./tools/napi/generate_link_win.js` to update `cli/exports.def`. pub mod r#async; pub mod env; diff --git a/cli/napi_sym/README.md b/cli/napi_sym/README.md index b3e2ab43bc..80bb2be0f7 100644 --- a/cli/napi_sym/README.md +++ b/cli/napi_sym/README.md @@ -24,11 +24,11 @@ fn napi_get_boolean( ### `symbol_exports.json` -A file containing the symbols that need to be put into the executable's dynamic +A file containing the symbols that need to be put into the exectable's dynamic symbol table at link-time. This is done using `/DEF:` on Windows, `-exported_symbol,_` on macOS and `--export-dynamic-symbol=` on Linux. See [`cli/build.rs`](../build.rs). On Windows, you need to generate the `.def` file by running -[`tools/napi/generate_symbols_lists.js`](../../tools/napi/generate_symbols_lists.js). +[`tools/napi/generate_link_win.js`](../../tools/napi/generate_link_win.js). diff --git a/test_napi/src/object_wrap.rs b/test_napi/src/object_wrap.rs index 40189e01c5..a38f97c9cd 100644 --- a/test_napi/src/object_wrap.rs +++ b/test_napi/src/object_wrap.rs @@ -130,7 +130,7 @@ pub fn init(env: napi_env, exports: napi_value) { unsafe { napi_define_class( env, - "NapiObject\0".as_ptr() as *mut c_char, + "NapiObject\0".as_ptr() as *mut i8, usize::MAX, Some(NapiObject::new), ptr::null_mut(), diff --git a/tools/napi/generate_link_win.js b/tools/napi/generate_link_win.js new file mode 100755 index 0000000000..7d16f81c3e --- /dev/null +++ b/tools/napi/generate_link_win.js @@ -0,0 +1,14 @@ +#!/usr/bin/env -S deno run --unstable --allow-read --allow-write +// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license. + +import exports from "../../cli/napi_sym/symbol_exports.json" assert { + type: "json", +}; + +let def = "LIBRARY\nEXPORTS\n"; +for (const symbol of exports.symbols) { + def += ` ${symbol}\n`; +} + +const defUrl = new URL("../../cli/exports.def", import.meta.url); +await Deno.writeTextFile(defUrl.pathname, def, { create: true }); diff --git a/tools/napi/generate_symbols_lists.js b/tools/napi/generate_symbols_lists.js deleted file mode 100755 index 3e41c3f065..0000000000 --- a/tools/napi/generate_symbols_lists.js +++ /dev/null @@ -1,20 +0,0 @@ -#!/usr/bin/env -S deno run --unstable --allow-read --allow-write -// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license. - -import exports from "../../cli/napi_sym/symbol_exports.json" assert { - type: "json", -}; - -for await (const os of ["linux", "macos", "windows"]) { - let def = os === "windows" ? "LIBRARY\nEXPORTS\n" : ""; - const prefix = os === "windows" ? " " : os === "macos" ? "_" : ""; - for (const symbol of exports.symbols) { - def += `${prefix}${symbol}\n`; - } - - const defUrl = new URL( - `../../cli/generated_symbol_exports_list_${os}.def`, - import.meta.url, - ); - await Deno.writeTextFile(defUrl.pathname, def, { create: true }); -}