guix_mirror_bot pushed a commit to branch javascript-team in repository guix.
commit ad080d7d361a5c98a108456e47cff7a7208d0792 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)
