From fa22956a8616c34482b10bb3ae1aed76ad017c3e Mon Sep 17 00:00:00 2001 From: Luke Channings <461449+LukeChannings@users.noreply.github.com> Date: Sat, 15 Oct 2022 16:21:04 +0100 Subject: refactor(build): better handle old glibc (#16238) Follow-up to #16208. - Refactors build.rs behaviour to use `-exported_symbols_list` / `--export-dynamic-symbol-list` - Since all build systems now rely on a symbols list file, I have added `generate_exported_symbols_list`, which derives the symbol list file depending on the platform, which makes `tools/napi/generate_link_win.js` redundant. - Fixes a missed instance of `i8` being used instead of `c_char` Co-authored-by: Divy Srivastava --- cli/Cargo.toml | 1 + cli/build.rs | 62 ++++------- cli/exports.def | 146 -------------------------- cli/generated_symbol_exports_list_linux.def | 144 +++++++++++++++++++++++++ cli/generated_symbol_exports_list_macos.def | 144 +++++++++++++++++++++++++ cli/generated_symbol_exports_list_windows.def | 146 ++++++++++++++++++++++++++ cli/napi/README.md | 6 +- cli/napi/mod.rs | 4 +- cli/napi_sym/README.md | 4 +- 9 files changed, 465 insertions(+), 192 deletions(-) delete mode 100644 cli/exports.def create mode 100644 cli/generated_symbol_exports_list_linux.def create mode 100644 cli/generated_symbol_exports_list_macos.def create mode 100644 cli/generated_symbol_exports_list_windows.def (limited to 'cli') diff --git a/cli/Cargo.toml b/cli/Cargo.toml index 267048b27..094a32d53 100644 --- a/cli/Cargo.toml +++ b/cli/Cargo.toml @@ -43,6 +43,7 @@ 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 0d683780f..98d044a3e 100644 --- a/cli/build.rs +++ b/cli/build.rs @@ -332,56 +332,40 @@ 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:{}", - std::path::Path::new("exports.def") - .canonicalize() - .expect( - "Missing exports.def! Generate using tools/napi/generate_link_win.js" - ) - .display(), + symbols_path.display() + ); + + #[cfg(target_os = "macos")] + println!( + "cargo:rustc-link-arg-bin=deno=-Wl,-exported_symbols_list,{}", + symbols_path.display() ); - #[cfg(all( - not(target_os = "windows"), - not(all(target_os = "linux", target_arch = "aarch64")) - ))] + #[cfg(target_os = "linux")] { - // 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,-exported_symbol,_{}", - symbol - ); - #[cfg(target_os = "linux")] + 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 { println!( - "cargo:rustc-link-arg-bin=deno=-Wl,--export-dynamic-symbol={}", - symbol + "cargo:rustc-link-arg-bin=deno=-Wl,--export-dynamic-symbol-list={}", + symbols_path.display() ); } } - // 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/exports.def b/cli/exports.def deleted file mode 100644 index 0b6cb946a..000000000 --- a/cli/exports.def +++ /dev/null @@ -1,146 +0,0 @@ -LIBRARY -EXPORTS - 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_linux.def b/cli/generated_symbol_exports_list_linux.def new file mode 100644 index 000000000..0adba1dce --- /dev/null +++ b/cli/generated_symbol_exports_list_linux.def @@ -0,0 +1,144 @@ +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 new file mode 100644 index 000000000..7c588ea2f --- /dev/null +++ b/cli/generated_symbol_exports_list_macos.def @@ -0,0 +1,144 @@ +_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_windows.def b/cli/generated_symbol_exports_list_windows.def new file mode 100644 index 000000000..0b6cb946a --- /dev/null +++ b/cli/generated_symbol_exports_list_windows.def @@ -0,0 +1,146 @@ +LIBRARY +EXPORTS + 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 7f46d9797..210d89b18 100644 --- a/cli/napi/README.md +++ b/cli/napi/README.md @@ -44,10 +44,10 @@ pub fn napi_get_boolean( } ``` -Update the Windows `.def` file using the script: +Update the generated symbol lists using the script: ``` -deno run --allow-write tools/napi/generate_link_win.js +deno run --allow-write tools/napi/generate_symbols_lists.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 8982a732a..1712632a5 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_link_win.js` is used to generate the LINK `cli/exports.def` on Windows, +//! `./tools/napi/generate_symbols_list.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_link_win.js` to update `cli/exports.def`. +//! 3. Finally, run `./tools/napi/generate_symbols_list.js` to update `cli/generated_symbol_exports_list_*.def`. pub mod r#async; pub mod env; diff --git a/cli/napi_sym/README.md b/cli/napi_sym/README.md index 80bb2be0f..b3e2ab43b 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 exectable's dynamic +A file containing the symbols that need to be put into the executable'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_link_win.js`](../../tools/napi/generate_link_win.js). +[`tools/napi/generate_symbols_lists.js`](../../tools/napi/generate_symbols_lists.js). -- cgit v1.2.3