Repository: electron/electron
Pull request: build: allow unbundling of Node.js dependencies

#### Description of Change

Closes https://github.com/electron/electron/issues/44691.

Linux distributions have guidelines on using distro-provided dependencies, rather than compiling them in statically.

This PR this enables downstream packagers to unbundle these dependencies. We don't need to do this for zlib, as the existing gn workflow uses the same `//third_party/zlib`, so unbundling `zlib` with Chromium tools in `//build/linux/unbundle` works already. This adds support for some of the others.

Upstreamed at https://github.com/nodejs/node/pull/55903

#### Checklist
<!-- Remove items that do not apply. For completed items, change [ ] to [x]. -->

- [x] PR description included and stakeholders cc'd
- [x] `npm test` passes
- [x] [PR release notes](https://github.com/electron/clerk/blob/main/README.md) describe the change in a way relevant to app developers, and are [capitalized, punctuated, and past tense](https://github.com/electron/clerk/blob/main/README.md#examples).

#### Release Notes

Notes: none


Changed files:
filename: patches/node/.patches
patch: @@ -44,3 +44,4 @@ fix_remove_harmony-import-assertions_from_node_cc.patch
 win_almost_fix_race_detecting_esrch_in_uv_kill.patch
 chore_disable_deprecation_ftbfs_in_simdjson_header.patch
 src_provide_workaround_for_container-overflow.patch
+build_allow_unbundling_of_node_js_dependencies.patch

filename: patches/node/build_allow_unbundling_of_node_js_dependencies.patch
patch: @@ -0,0 +1,83 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Shelley Vohr <shelley.vohr@gmail.com>
+Date: Sun, 17 Nov 2024 22:33:19 +0100
+Subject: build: allow unbundling of Node.js dependencies
+
+Linux distributions have guidelines on using distro-provided dependencies,
+rather than compiling them in statically.
+
+This PR this enables downstream packagers to unbundle these dependencies.
+We don't need to do this for zlib, as the existing gn workflow uses the same
+//third_party/zlib, so unbundling zlib with Chromium tools in
+//build/linux/unbundle works already. This adds support for some of the others.
+
+Upstreamed at https://github.com/nodejs/node/pull/55903
+
+diff --git a/node.gni b/node.gni
+index 18d58591e3d0f1f3512db00033c3410a65702864..99ec540ec41ddf5682eed7618ba87d6935b3b982 100644
+--- a/node.gni
++++ b/node.gni
+@@ -61,6 +61,12 @@ declare_args() {
+   #   1. cross-os compilation is not supported.
+   #   2. node_mksnapshot crashes when cross-compiling for x64 from arm64.
+   node_use_node_snapshot = false
++
++  # Allows downstream packagers (eg. Linux distributions) to build against system shared libraries.
++  use_system_cares = false
++  use_system_nghttp2 = false
++  use_system_llhttp = false
++  use_system_histogram = false
+ }
+ 
+ assert(!node_enable_inspector || node_use_openssl,
+diff --git a/unofficial.gni b/unofficial.gni
+index 3d8b7957e791ce2fa2a8d0937a87b6010087803d..c23922a301a721662ff34bf6e54fd26b41f25ccc 100644
+--- a/unofficial.gni
++++ b/unofficial.gni
+@@ -147,7 +147,6 @@ template("node_gn_build") {
+       ":run_node_js2c",
+       "deps/cares",
+       "deps/histogram",
+-      "deps/llhttp",
+       "deps/nbytes",
+       "deps/nghttp2",
+       "deps/postject",
+@@ -178,7 +177,17 @@ template("node_gn_build") {
+       configs -= [ "//build/config/gcc:symbol_visibility_hidden" ]
+       configs += [ "//build/config/gcc:symbol_visibility_default" ]
+     }
+-
++    if (use_system_llhttp) {
++      libs += [ "llhttp" ]
++    } else {
++      deps += [ "deps/llhttp" ]
++    }
++    if (use_system_histogram) {
++      libs += [ "hdr_histogram" ]
++      include_dirs += [ "/usr/include/hdr" ]
++    } else {
++      deps += [ "deps/histogram" ]
++    }
+     if (v8_enable_i18n_support) {
+       deps += [ "//third_party/icu" ]
+     }
+@@ -205,6 +214,19 @@ template("node_gn_build") {
+       sources += node_inspector.node_inspector_sources +
+                  node_inspector.node_inspector_generated_sources
+     }
++    if (is_linux) {
++      import("//build/config/linux/pkg_config.gni")
++        if (use_system_cares) {
++          pkg_config("cares") {
++            packages = [ "libcares" ]
++          }
++        }
++      if (use_system_nghttp2) {
++        pkg_config("nghttp2") {
++          packages = [ "libnghttp2" ]
++        }
++      }
++    }
+   }
+ 
+   executable(target_name) {