guix_mirror_bot pushed a commit to branch master
in repository guix.
commit a2ba31c610f37430647c28e724decd27f75a6d96
Author: Jelle Licht <[email protected]>
AuthorDate: Thu Sep 3 14:45:24 2026 +0200
gnu: node-lts: Disinherit from node-bootstrap.
* gnu/packages/node.scm (node-lts): Replace (inherit node-bootstrap)
with explicit package definition. Set name to "node".
[build-system]: Declare gnu-build-system explicitly.
[arguments]: Expand all phases inline; remove substitute-keyword-
arguments indirection.
[native-search-paths]: Add NODE_PATH search path for lib/node_modules.
[synopsis, description, home-page, license]: Add explicit fields.
[supported-systems]: Use (fold delete %supported-systems ...) instead
of deriving from node-bootstrap.
[properties]: Replace inherited properties; set max-silent-time and
timeout for ARM builds.
---
gnu/packages/node.scm | 467 ++++++++++++++++++++++++++++++--------------------
1 file changed, 278 insertions(+), 189 deletions(-)
diff --git a/gnu/packages/node.scm b/gnu/packages/node.scm
index 797ea14c920..3f83e3c7258 100644
--- a/gnu/packages/node.scm
+++ b/gnu/packages/node.scm
@@ -563,7 +563,7 @@ parser definition into a C output.")
(define-public node-lts
(package
- (inherit node-bootstrap)
+ (name "node")
(version "24.21.0")
(source (origin
(method url-fetch)
@@ -602,193 +602,268 @@ parser definition into a C output.")
"deps/uvwasi"
"deps/zlib"
"deps/zstd"))))))
+ (build-system gnu-build-system)
(arguments
- (substitute-keyword-arguments arguments
- ((#:configure-flags configure-flags)
- ''("--shared-cares"
- "--shared-libuv"
- "--shared-http-parser"
- "--shared-http-parser-libname=llhttp"
- "--shared-nghttp2"
- "--shared-openssl"
- "--shared-zlib"
- "--shared-brotli"
- "--with-intl=system-icu"
- "--shared-ngtcp2"
- "--shared-nghttp3"
- "--shared-zstd"
- "--shared-uvwasi"
- "--shared"
- ;;Needed for correct snapshot checksums
- "--v8-enable-snapshot-compression"))
- ((#:phases phases)
- `(modify-phases ,phases
- (replace 'set-bootstrap-host-rpath
- (lambda* (#:key native-inputs inputs #:allow-other-keys)
- (let* ((inputs (or native-inputs inputs))
- (c-ares (assoc-ref inputs "c-ares"))
- (brotli (assoc-ref inputs "brotli"))
- (icu4c (assoc-ref inputs "icu4c"))
- (nghttp2 (assoc-ref inputs "nghttp2"))
- (openssl (assoc-ref inputs "openssl"))
- (libuv (assoc-ref inputs "libuv"))
- (zlib (assoc-ref inputs "zlib"))
- (host-binaries '("torque"
- "bytecode_builtins_list_generator"
- "gen-regexp-special-case"
- "node_mksnapshot"
- "mksnapshot")))
- (substitute* '("node.gyp" "tools/v8_gypfiles/v8.gyp")
- (((string-append "'target_name': '("
- (string-join host-binaries "|")
- ")',")
- target)
- (string-append target
- "'ldflags': ['-Wl,-rpath="
- c-ares "/lib:"
- brotli "/lib:"
- icu4c "/lib:"
- nghttp2 "/lib:"
- openssl "/lib:"
- libuv "/lib:"
- zlib "/lib"
- "'],"))))))
- (add-after 'patch-hardcoded-program-references
- 'patch-additional-hardcoded-program-references
- (lambda* (#:key inputs #:allow-other-keys)
- (substitute* "test/parallel/test-stdin-from-file-spawn.js"
- (("'/bin/sh'") (string-append
- "'" (search-input-file inputs "/bin/sh")
- "'")))))
- (replace 'delete-problematic-tests
- (lambda* (#:key inputs #:allow-other-keys)
- ;; FIXME: These tests fail in the build container, but they
don't
- ;; seem to be indicative of real problems in practice.
- (for-each delete-file
- '("test/parallel/test-cluster-primary-error.js"
- "test/parallel/test-cluster-primary-kill.js"
- "test/parallel/test-node-run.js"))
-
- ;; These require a DNS resolver.
- (for-each delete-file
- '("test/parallel/test-dns.js"
- "test/parallel/test-dns-lookupService-promises.js"
-
"test/parallel/test-net-socket-connect-without-cb.js"
- "test/parallel/test-tcp-wrap-listen.js"
- "test/report/test-report-exclude-network.js"))
-
- ;; These tests require networking.
- (for-each delete-file
- '("test/parallel/test-https-agent-unref-socket.js"))
-
- ;; These tests are timing-sensitive, and fail sporadically on
- ;; slow, busy, or even very fast machines.
- (for-each delete-file
- '("test/parallel/test-fs-utimes.js"))
-
- ;; FIXME: This test fails randomly:
- ;; https://github.com/nodejs/node/issues/31213
- (delete-file
"test/parallel/test-net-listen-after-destroying-stdin.js")
-
- ;; FIXME: These tests fail on armhf-linux:
- ;; https://github.com/nodejs/node/issues/31970
- ,@(if (target-arm32?)
- '((for-each delete-file
- '("test/parallel/test-zlib.js"
- "test/parallel/test-zlib-brotli.js"
- "test/parallel/test-zlib-brotli-flush.js"
-
"test/parallel/test-zlib-brotli-from-brotli.js"
-
"test/parallel/test-zlib-brotli-from-string.js"
-
"test/parallel/test-zlib-convenience-methods.js"
-
"test/parallel/test-zlib-random-byte-pipes.js"
-
"test/parallel/test-zlib-write-after-flush.js")))
- '())
-
- ;; https://github.com/nodejs/node/issues/45906
- ;; This test depends on 64-bit time_t so skipping on 32-bit
systems.
- ,@(if (target-32bit?)
- '((delete-file "test/parallel/test-fs-utimes-y2K38.js")
-
- (delete-file
"test/parallel/test-debugger-heap-profiler.js"))
- '())
-
- ;; These tests have an expiry date: they depend on the validity
of
- ;; TLS certificates that are bundled with the source. We want
this
- ;; package to be reproducible forever, so remove those.
- ;; TODO: Regenerate certs instead.
- (for-each delete-file
- '("test/parallel/test-tls-passphrase.js"
- "test/parallel/test-tls-server-verify.js"))
-
- ;; These tests fail when linking to upstream libuv.
- ;; https://github.com/nodejs/node/commit/3f6addd590
- (for-each delete-file
- '("test/parallel/test-process-euid-egid.js"
- "test/parallel/test-process-initgroups.js"
- "test/parallel/test-process-setgroups.js"
- "test/parallel/test-process-uid-gid.js"))))
- (add-after 'delete-problematic-tests 'patch-problematic-tests
- (lambda _
- ;; XXX: These tests seem to not work by default
+ `(#:configure-flags '("--shared-cares"
+ "--shared-libuv"
+ "--shared-http-parser"
+ "--shared-http-parser-libname=llhttp"
+ "--shared-nghttp2"
+ "--shared-openssl"
+ "--shared-zlib"
+ "--shared-brotli"
+ "--with-intl=system-icu"
+ "--shared-ngtcp2"
+ "--shared-nghttp3"
+ "--shared-zstd"
+ "--shared-uvwasi"
+ "--shared"
+ ;; Needed for correct snapshot checksums
+ "--v8-enable-snapshot-compression")
+ #:test-target "test-ci-js"
+ #:modules
+ ((guix build gnu-build-system)
+ (guix build utils)
+ (srfi srfi-1)
+ (ice-9 match))
+ #:phases
+ (modify-phases %standard-phases
+ (add-before 'configure 'patch-hardcoded-program-references
+ (lambda* (#:key inputs #:allow-other-keys)
+ ;; Fix hardcoded /bin/sh references.
+ (substitute* '("lib/child_process.js"
+ "lib/internal/v8_prof_polyfill.js"
+
"test/parallel/test-child-process-spawnsync-shell.js"
+ "test/parallel/test-stdio-closed.js"
+ "test/sequential/test-child-process-emfile.js"
+ "test/parallel/test-fs-write-sigxfsz.js"
+ "test/parallel/test-stdin-from-file-spawn.js")
+ (("'/bin/sh'")
+ (string-append "'" (search-input-file inputs "/bin/sh") "'")))
+ ;; Fix hardcoded /usr/bin/env references.
+ (substitute*
'("test/parallel/test-child-process-default-options.js"
+ "test/parallel/test-child-process-env.js"
+ "test/parallel/test-child-process-exec-env.js")
+ (("'/usr/bin/env'")
+ (string-append "'" (search-input-file inputs "/bin/env")
"'")))))
+ (add-after 'patch-hardcoded-program-references
'delete-problematic-tests
+ (lambda* (#:key inputs #:allow-other-keys)
+ ;; FIXME: These tests fail in the build container, but they don't
+ ;; seem to be indicative of real problems in practice.
+ (for-each delete-file
+ '("test/parallel/test-cluster-primary-error.js"
+ "test/parallel/test-cluster-primary-kill.js"
+ "test/parallel/test-node-run.js"))
+ ;; These require a DNS resolver.
+ (for-each delete-file
+ '("test/parallel/test-dns.js"
+ "test/parallel/test-dns-lookupService-promises.js"
+ "test/parallel/test-net-socket-connect-without-cb.js"
+ "test/parallel/test-tcp-wrap-listen.js"
+ "test/report/test-report-exclude-network.js"))
+ ;; These tests require networking.
+ (for-each delete-file
+ '("test/parallel/test-https-agent-unref-socket.js"))
+ ;; These tests are timing-sensitive, and fail sporadically on
+ ;; slow, busy, or even very fast machines.
+ (for-each delete-file
+ '("test/parallel/test-fs-utimes.js"))
+ ;; FIXME: This test fails randomly:
+ ;; https://github.com/nodejs/node/issues/31213
+ (delete-file
"test/parallel/test-net-listen-after-destroying-stdin.js")
+ ;; FIXME: These tests fail on armhf-linux:
+ ;; https://github.com/nodejs/node/issues/31970
+ ,@(if (target-arm32?)
+ '((for-each delete-file
+ '("test/parallel/test-zlib.js"
+ "test/parallel/test-zlib-brotli.js"
+ "test/parallel/test-zlib-brotli-flush.js"
+
"test/parallel/test-zlib-brotli-from-brotli.js"
+
"test/parallel/test-zlib-brotli-from-string.js"
+
"test/parallel/test-zlib-convenience-methods.js"
+ "test/parallel/test-zlib-random-byte-pipes.js"
+
"test/parallel/test-zlib-write-after-flush.js")))
+ '())
+ ;; https://github.com/nodejs/node/issues/45906
+ ;; This test depends on 64-bit time_t so skipping on 32-bit
systems.
+ ,@(if (target-32bit?)
+ '((delete-file "test/parallel/test-fs-utimes-y2K38.js")
+ (delete-file
"test/parallel/test-debugger-heap-profiler.js"))
+ '())
+ ;; These tests have an expiry date: they depend on the validity of
+ ;; TLS certificates that are bundled with the source. We want
this
+ ;; package to be reproducible forever, so remove those.
+ ;; TODO: Regenerate certs instead.
+ (for-each delete-file
+ '("test/parallel/test-tls-passphrase.js"
+ "test/parallel/test-tls-server-verify.js"))
+ ;; These tests fail when linking to upstream libuv.
+ ;; https://github.com/nodejs/node/commit/3f6addd590
+ (for-each delete-file
+ '("test/parallel/test-process-euid-egid.js"
+ "test/parallel/test-process-initgroups.js"
+ "test/parallel/test-process-setgroups.js"
+ "test/parallel/test-process-uid-gid.js"))))
+ (add-after 'delete-problematic-tests 'patch-problematic-tests
+ (lambda _
+ ;; TODO: These tests seem to not work by default, but seem fixed
now online
+ (substitute*
+ '("test/parallel/test-http2-premature-close.js"
+ "test/parallel/test-http2-invalid-last-stream-id.js")
+ (("client\\.connect\\(address\\)")
+ "client.connect(address.port)"))))
+ (add-before 'configure 'set-bootstrap-host-rpath
+ (lambda* (#:key native-inputs inputs #:allow-other-keys)
+ (let* ((inputs (or native-inputs inputs))
+ (c-ares (assoc-ref inputs "c-ares"))
+ (brotli (assoc-ref inputs "brotli"))
+ (icu4c (assoc-ref inputs "icu4c"))
+ (nghttp2 (assoc-ref inputs "nghttp2"))
+ (openssl (assoc-ref inputs "openssl"))
+ (libuv (assoc-ref inputs "libuv"))
+ (zlib (assoc-ref inputs "zlib"))
+ (host-binaries '("torque"
+ "bytecode_builtins_list_generator"
+ "gen-regexp-special-case"
+ "node_mksnapshot"
+ "mksnapshot")))
+ (substitute* '("node.gyp" "tools/v8_gypfiles/v8.gyp")
+ (((string-append "'target_name': '("
+ (string-join host-binaries "|")
+ ")',")
+ target)
+ (string-append target
+ "'ldflags': ['-Wl,-rpath="
+ c-ares "/lib:"
+ brotli "/lib:"
+ icu4c "/lib:"
+ nghttp2 "/lib:"
+ openssl "/lib:"
+ libuv "/lib:"
+ zlib "/lib"
+ "'],"))))))
+ (replace 'configure
+ ;; Node's configure script is actually a python script, so we can't
+ ;; run it with bash.
+ (lambda* (#:key outputs (configure-flags '()) native-inputs inputs
+ #:allow-other-keys)
+ (let* ((prefix (assoc-ref outputs "out"))
+ (xflags ,(if (%current-target-system)
+ `'("--cross-compiling"
+ ,(string-append
+ "--dest-cpu="
+ (match (%current-target-system)
+ ((? (cut string-prefix? "arm" <>))
+ "arm")
+ ((? (cut string-prefix? "aarch64" <>))
+ "arm64")
+ ((? (cut string-prefix? "i686" <>))
+ "ia32")
+ ((? (cut string-prefix? "x86_64" <>))
+ "x64")
+ ((? (cut string-prefix? "powerpc64"
<>))
+ "ppc64")
+ ((? (cut string-prefix? "riscv64" <>))
+ "riscv64")
+ (_ "unsupported"))))
+ ''()))
+ (flags (cons (string-append "--prefix=" prefix)
+ (append xflags configure-flags))))
+ (format #t "build directory: ~s~%" (getcwd))
+ (format #t "configure flags: ~s~%" flags)
+ ;; Node's configure script expects the CC environment variable
to
+ ;; be set.
+ (setenv "CC_host" "gcc")
+ (setenv "CXX_host" "g++")
+ (setenv "CC" ,(cc-for-target))
+ (setenv "CXX" ,(cxx-for-target))
+ (setenv "PKG_CONFIG" ,(pkg-config-for-target))
+ (apply invoke
+ (let ((inpts (or native-inputs inputs)))
+ (with-exception-handler
+ (lambda (e)
+ (if (search-error? e)
+ (search-input-file inpts "/bin/python3")
+ (raise-exception e)))
+ (lambda ()
+ (search-input-file inpts "/bin/python"))
+ #:unwind? #t))
+ "configure"
+ flags))))
+ (add-after 'patch-shebangs 'patch-nested-shebangs
+ (lambda* (#:key inputs outputs #:allow-other-keys)
+ ;; Based on the implementation of patch-shebangs
+ ;; from (guix build gnu-build-system).
+ (let ((path (append-map (match-lambda
+ ((_ . dir)
+ (list (string-append dir "/bin")
+ (string-append dir "/sbin")
+ (string-append dir "/libexec"))))
+ (append outputs inputs))))
+ (for-each
+ (lambda (file)
+ (patch-shebang file path))
+ (find-files (search-input-directory outputs "lib/node_modules")
+ (lambda (file stat)
+ (executable-file? file))
+ #:stat lstat)))))
+ (add-after 'patch-nested-shebangs 'do-not-capture-python
+ (lambda* (#:key outputs #:allow-other-keys)
+ ;; patch-shebangs embeds the Python store path into node-gyp's
+ ;; Python scripts, pulling Python into node's closure. Revert
+ ;; to /usr/bin/env python3 so downstream gyp builds supply
+ ;; their own Python.
+ (let ((node-gyp (string-append (assoc-ref outputs "out")
+ "/lib/node_modules/npm"
+ "/node_modules/node-gyp")))
+ (for-each
+ (lambda (f)
+ (substitute* f
+ (("^#!.*/bin/python3") "#!/usr/bin/env python3")))
+ (find-files node-gyp "\\.py$")))))
+ ;; npm installs dependencies by copying their files over a tar
+ ;; stream. A file with more than one hardlink is marked as a
+ ;; "Link". pacote/lib/fetcher.js calls node-tar's extractor with a
+ ;; filter that ignores any "Link" entries. This means that
+ ;; dependending on the number of hardlinks on files in a node-*
+ ;; package *some* of its files may not be installed when generating
+ ;; another package's "node_modules" directory. The build output
+ ;; would differ depending on irrelevant file system state.
+ ;;
+ ;; To avoid this, we patch node-tar to treat files with hardlinks
+ ;; the same as any other file, so that node-tar has no choice but
+ ;; to extract all of them --- independent of pacote's filter.
+ ;;
+ ;; Why not patch pacote's filter instead? This has led to subtle
+ ;; differences in where the files are installed, so it's easier to
+ ;; just ensure that files with hardlinks are always treated as
+ ;; regular files.
+ ;;
+ ;; Discussion:
+ ;;
https://lists.gnu.org/archive/html/guix-devel/2023-07/msg00040.html
+ ;; Upstream bug report:
+ ;; https://github.com/npm/pacote/issues/285
+ (add-after 'install 'ignore-number-of-hardlinks
+ (lambda* (#:key outputs #:allow-other-keys)
+ (let ((dir (string-append (assoc-ref outputs "out")
+ "/lib/node_modules/npm/node_modules"
+ "/tar/dist")))
(substitute*
- '("test/parallel/test-http2-premature-close.js"
- "test/parallel/test-http2-invalid-last-stream-id.js")
- (("client\\.connect\\(address\\)")
- "client.connect(address.port)"))))
- ;; npm installs dependencies by copying their files over a tar
- ;; stream. A file with more than one hardlink is marked as a
- ;; "Link". pacote/lib/fetcher.js calls node-tar's extractor with a
- ;; filter that ignores any "Link" entries. This means that
- ;; dependending on the number of hardlinks on files in a node-*
- ;; package *some* of its files may not be installed when generating
- ;; another package's "node_modules" directory. The build output
- ;; would differ depending on irrelevant file system state.
- ;;
- ;; To avoid this, we patch node-tar to treat files with hardlinks
- ;; the same as any other file, so that node-tar has no choice but
- ;; to extract all of them --- independent of pacote's filter.
- ;;
- ;; Why not patch pacote's filter instead? This has led to subtle
- ;; differences in where the files are installed, so it's easier to
- ;; just ensure that files with hardlinks are always treated as
- ;; regular files.
- ;;
- ;; Discussion:
- ;;
https://lists.gnu.org/archive/html/guix-devel/2023-07/msg00040.html
- ;; Upstream bug report:
- ;; https://github.com/npm/pacote/issues/285
- (add-after 'install 'ignore-number-of-hardlinks
- (lambda* (#:key outputs #:allow-other-keys)
- (let ((dir (string-append (assoc-ref outputs "out")
- "/lib/node_modules/npm/node_modules"
- "/tar/dist")))
- (substitute*
- (list (string-append dir "/esm/write-entry.js")
- (string-append dir "/commonjs/write-entry.js"))
- (("this.stat.nlink > 1") "false")))))
- (replace 'fix-node-gyp-reference
- (lambda* (#:key inputs outputs #:allow-other-keys)
- (let ((out (assoc-ref outputs "out")))
- (for-each
- (lambda (spec)
- (wrap-program (string-append out spec)
- `("npm_package_config_node_gyp_nodedir" = (,out))))
- '("/bin/npm"
- "/bin/npx")))))
- (add-after 'patch-nested-shebangs 'do-not-capture-python
- (lambda* (#:key outputs #:allow-other-keys)
- ;; patch-shebangs embeds the Python store path into node-gyp's
- ;; Python scripts, pulling Python into node's closure. Revert
- ;; to /usr/bin/env python3 so downstream gyp builds supply
- ;; their own Python.
- (let ((node-gyp (string-append (assoc-ref outputs "out")
- "/lib/node_modules/npm"
- "/node_modules/node-gyp")))
- (for-each
- (lambda (f)
- (substitute* f
- (("^#!.*/bin/python3") "#!/usr/bin/env python3")))
- (find-files node-gyp "\\.py$")))))))))
+ (list (string-append dir "/esm/write-entry.js")
+ (string-append dir "/commonjs/write-entry.js"))
+ (("this.stat.nlink > 1") "false")))))
+ (add-after 'install 'fix-node-gyp-reference
+ ;; Note: programs like node-gyp only receive these values if
+ ;; they are started via `npm` or `npx`.
+ ;; See: https://github.com/nodejs/node-gyp#npm-configuration
+ (lambda* (#:key inputs outputs #:allow-other-keys)
+ (let ((out (assoc-ref outputs "out")))
+ (for-each
+ (lambda (spec)
+ (wrap-program (string-append out spec)
+ `("npm_package_config_node_gyp_nodedir" = (,out))))
+ '("/bin/npm"
+ "/bin/npx"))))))))
(native-inputs
(list ;; Runtime dependencies for binaries used as a bootstrap.
c-ares-for-node-lts
@@ -805,6 +880,10 @@ parser definition into a C output.")
procps
python
util-linux))
+ (native-search-paths
+ (list (search-path-specification
+ (variable "NODE_PATH")
+ (files '("lib/node_modules")))))
(inputs
(list bash-minimal
coreutils
@@ -820,9 +899,19 @@ parser definition into a C output.")
zlib
uvwasi-for-node-lts
`(,zstd "lib")))
- (supported-systems
- (cons "riscv64-linux" (package-supported-systems node-bootstrap)))
- (properties (alist-delete 'hidden? (package-properties node-bootstrap)))))
+ (synopsis "Evented I/O for V8 JavaScript")
+ (description
+ "Node.js is a platform built on Chrome's JavaScript runtime
+for easily building fast, scalable network applications. Node.js uses an
+event-driven, non-blocking I/O model that makes it lightweight and efficient,
+perfect for data-intensive real-time applications that run across distributed
+devices.")
+ (supported-systems (fold delete %supported-systems '("powerpc-linux")))
+ (home-page "https://nodejs.org/")
+ (license license:expat)
+ (properties '((max-silent-time . 7200) ;2h, needed on ARM
+ (timeout . 21600) ;6h
+ (cpe-name . "node.js")))))
(define-public node node-lts)