Skip to content

Commit

Permalink
refactor(build): better handle old glibc (denoland#16238)
Browse files Browse the repository at this point in the history
Follow-up to denoland#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 <[email protected]>
  • Loading branch information
LukeChannings and littledivy committed Oct 15, 2022
1 parent e32719c commit fa22956
Show file tree
Hide file tree
Showing 12 changed files with 350 additions and 61 deletions.
10 changes: 10 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions cli/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
62 changes: 23 additions & 39 deletions cli/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<String>,
}
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();

Expand Down
144 changes: 144 additions & 0 deletions cli/generated_symbol_exports_list_linux.def
Original file line number Diff line number Diff line change
@@ -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
Loading

0 comments on commit fa22956

Please sign in to comment.