nixpkgs mirror (for testing) github.com/NixOS/nixpkgs
nix
at python-updates 635 lines 23 kB view raw
1{ 2 lib, 3 stdenv, 4 fetchurl, 5 fetchpatch2, 6 fetchFromGitHub, 7 python, 8 ada, 9 brotli, 10 c-ares, 11 libuv, 12 llhttp, 13 nghttp2, 14 nghttp3, 15 ngtcp2, 16 openssl, 17 simdjson, 18 simdutf, 19 simdutf_6 ? ( 20 simdutf.overrideAttrs { 21 version = "6.5.0"; 22 23 src = fetchFromGitHub { 24 owner = "simdutf"; 25 repo = "simdutf"; 26 rev = "v6.5.0"; 27 hash = "sha256-bZ4r62GMz2Dkd3fKTJhelitaA8jUBaDjG6jOysEg8Nk="; 28 }; 29 } 30 ), 31 sqlite, 32 uvwasi, 33 zlib, 34 zstd, 35 icu, 36 bash, 37 ninja, 38 pkgconf, 39 unixtools, 40 runCommand, 41 buildPackages, 42 testers, 43 # for `.pkgs` attribute 44 callPackage, 45 # Updater dependencies 46 writeScript, 47 coreutils, 48 gnugrep, 49 jq, 50 curl, 51 common-updater-scripts, 52 runtimeShell, 53 gnupg, 54 installShellFiles, 55 darwin, 56}: 57 58{ 59 enableNpm ? true, 60 version, 61 sha256, 62 patches ? [ ], 63}@args: 64 65let 66 67 majorVersion = lib.versions.major version; 68 minorVersion = lib.versions.minor version; 69 70 pname = if enableNpm then "nodejs" else "nodejs-slim"; 71 72 canExecute = stdenv.buildPlatform.canExecute stdenv.hostPlatform; 73 emulator = stdenv.hostPlatform.emulator buildPackages; 74 canEmulate = stdenv.hostPlatform.emulatorAvailable buildPackages; 75 buildNode = buildPackages."${pname}_${majorVersion}"; 76 77 # See valid_os and valid_arch in configure.py. 78 destOS = 79 let 80 platform = stdenv.hostPlatform; 81 in 82 if platform.isiOS then 83 "ios" 84 else if platform.isAndroid then 85 "android" 86 else if platform.isWindows then 87 "win" 88 else if platform.isDarwin then 89 "mac" 90 else if platform.isLinux then 91 "linux" 92 else if platform.isOpenBSD then 93 "openbsd" 94 else if platform.isFreeBSD then 95 "freebsd" 96 else 97 throw "unsupported os ${platform.uname.system}"; 98 destARMFPU = 99 let 100 platform = stdenv.hostPlatform; 101 in 102 if platform.isAarch32 && platform ? gcc.fpu then 103 lib.throwIfNot (builtins.elem platform.gcc.fpu [ 104 "vfp" 105 "vfpv2" 106 "vfpv3" 107 "vfpv3-d16" 108 "neon" 109 ]) "unsupported ARM FPU ${platform.gcc.fpu}" platform.gcc.fpu 110 else 111 null; 112 destARMFloatABI = 113 let 114 platform = stdenv.hostPlatform; 115 in 116 if platform.isAarch32 && platform ? gcc.float-abi then 117 lib.throwIfNot (builtins.elem platform.gcc.float-abi [ 118 "soft" 119 "softfp" 120 "hard" 121 ]) "unsupported ARM float ABI ${platform.gcc.float-abi}" platform.gcc.float-abi 122 else 123 null; 124 # TODO: also handle MIPS flags (mips_arch, mips_fpu, mips_float_abi). 125 126 useSharedAdaAndSimd = !stdenv.hostPlatform.isStatic && lib.versionAtLeast version "22.2"; 127 useSharedSQLite = !stdenv.hostPlatform.isStatic && lib.versionAtLeast version "22.5"; 128 useSharedZstd = !stdenv.hostPlatform.isStatic && lib.versionAtLeast version "22.15"; 129 130 sharedLibDeps = 131 (lib.optionalAttrs (!stdenv.hostPlatform.isStatic) { 132 inherit 133 brotli 134 libuv 135 nghttp3 136 ngtcp2 137 openssl 138 uvwasi 139 zlib 140 ; 141 cares = c-ares; 142 http-parser = llhttp; 143 nghttp2 = nghttp2.overrideAttrs { 144 patches = [ 145 (fetchpatch2 { 146 url = "https://github.com/nghttp2/nghttp2/commit/7784fa979d0bcf801a35f1afbb25fb048d815cd7.patch?full_index=1"; 147 hash = "sha256-RG87Qifjpl7HTP9ac2JwHj2XAbDlFgOpAnpZX3ET6gU="; 148 excludes = [ "lib/includes/nghttp2/nghttp2.h" ]; 149 revert = true; 150 }) 151 ]; 152 }; 153 }) 154 // (lib.optionalAttrs useSharedAdaAndSimd { 155 inherit 156 ada 157 simdjson 158 ; 159 simdutf = if lib.versionAtLeast version "25" then simdutf else simdutf_6; 160 }) 161 // (lib.optionalAttrs useSharedSQLite { 162 inherit sqlite; 163 }) 164 // (lib.optionalAttrs useSharedZstd { 165 inherit zstd; 166 }); 167 168 copyLibHeaders = map (name: "${lib.getDev sharedLibDeps.${name}}/include/*") ( 169 builtins.attrNames sharedLibDeps 170 ); 171 172 # Currently stdenv sets CC/LD/AR/etc environment variables to program names 173 # instead of absolute paths. If we add cctools to nativeBuildInputs, that 174 # would shadow stdenv’s bintools and potentially break other parts of the 175 # build. The correct behavior is to use absolute paths, and there is a PR for 176 # that, see https://github.com/NixOS/nixpkgs/pull/314920. As a temporary 177 # workaround, we use only a single program we need (and that is not part of 178 # the stdenv). 179 darwin-cctools-only-libtool = 180 # Would be nice to have onlyExe builder similar to onlyBin… 181 runCommand "darwin-cctools-only-libtool" { cctools = lib.getBin buildPackages.cctools; } '' 182 mkdir -p "$out/bin" 183 ln -s "$cctools/bin/libtool" "$out/bin/libtool" 184 ''; 185 186 # a script which claims to be a different script but switches to simply touching its output 187 # when an environment variable is set. See CC_host, --cross-compiling, and postConfigure. 188 touchScript = 189 real: 190 writeScript "touch-script" '' 191 #!${stdenv.shell} 192 if [ -z "$FAKE_TOUCH" ]; then 193 exec "${real}" "$@" 194 fi 195 while [ "$#" != "0" ]; do 196 if [ "$1" == "-o" ]; then 197 shift 198 touch "$1" 199 fi 200 shift 201 done 202 ''; 203 204 downloadDir = if lib.strings.hasInfix "-rc." version then "download/rc" else "dist"; 205 206 package = stdenv.mkDerivation ( 207 finalAttrs: 208 let 209 /** 210 the final package fixed point, after potential overrides 211 */ 212 self = finalAttrs.finalPackage; 213 in 214 { 215 inherit pname version; 216 217 src = fetchurl { 218 url = "https://nodejs.org/${downloadDir}/v${version}/node-v${version}.tar.xz"; 219 inherit sha256; 220 }; 221 222 strictDeps = true; 223 224 env = { 225 # Tell ninja to avoid ANSI sequences, otherwise we don’t see build 226 # progress in Nix logs. 227 # 228 # Note: do not set TERM=dumb environment variable globally, it is used in 229 # test-ci-js test suite to skip tests that otherwise run fine. 230 NINJA = "TERM=dumb ninja"; 231 } 232 // lib.optionalAttrs (!canExecute && !canEmulate) { 233 # these are used in the --cross-compiling case. see comment at postConfigure. 234 CC_host = touchScript "${buildPackages.stdenv.cc}/bin/cc"; 235 CXX_host = touchScript "${buildPackages.stdenv.cc}/bin/c++"; 236 AR_host = touchScript "${buildPackages.stdenv.cc}/bin/ar"; 237 }; 238 239 # NB: technically, we do not need bash in build inputs since all scripts are 240 # wrappers over the corresponding JS scripts. There are some packages though 241 # that use bash wrappers, e.g. polaris-web. 242 buildInputs = [ 243 bash 244 icu 245 ] 246 ++ builtins.attrValues sharedLibDeps; 247 248 nativeBuildInputs = [ 249 installShellFiles 250 ninja 251 pkgconf 252 python 253 ] 254 ++ lib.optionals stdenv.buildPlatform.isDarwin [ 255 # gyp checks `sysctl -n hw.memsize` if `sys.platform == "darwin"`. 256 unixtools.sysctl 257 ] 258 ++ lib.optionals stdenv.hostPlatform.isDarwin [ 259 # For gyp-mac-tool if `flavor == "mac"`. 260 darwin-cctools-only-libtool 261 ]; 262 263 # We currently rely on Makefile and stdenv for build phases, so do not let 264 # ninja’s setup hook to override default stdenv phases. 265 dontUseNinjaBuild = true; 266 dontUseNinjaCheck = true; 267 dontUseNinjaInstall = true; 268 269 outputs = [ 270 "out" 271 "libv8" 272 ] 273 ++ lib.optionals (stdenv.hostPlatform == stdenv.buildPlatform) [ "dev" ]; 274 setOutputFlags = false; 275 moveToDev = false; 276 277 configureFlags = [ 278 "--ninja" 279 "--with-intl=system-icu" 280 "--openssl-use-def-ca-store" 281 # --cross-compiling flag enables use of CC_host et. al 282 (if canExecute || canEmulate then "--no-cross-compiling" else "--cross-compiling") 283 "--dest-os=${destOS}" 284 "--dest-cpu=${stdenv.hostPlatform.node.arch}" 285 ] 286 ++ lib.optionals (destARMFPU != null) [ "--with-arm-fpu=${destARMFPU}" ] 287 ++ lib.optionals (destARMFloatABI != null) [ "--with-arm-float-abi=${destARMFloatABI}" ] 288 ++ lib.optionals (!canExecute && canEmulate) [ 289 # Node.js requires matching bitness between build and host platforms, e.g. 290 # for V8 startup snapshot builder (see tools/snapshot) and some other 291 # tools. We apply a patch that runs these tools using a host platform 292 # emulator and avoid cross-compiling altogether (from the build system’s 293 # perspective). 294 "--emulator=${emulator}" 295 ] 296 ++ lib.optionals (lib.versionOlder version "19") [ "--without-dtrace" ] 297 ++ lib.optionals (!enableNpm) [ "--without-npm" ] 298 ++ lib.concatMap (name: [ 299 "--shared-${name}" 300 "--shared-${name}-libpath=${lib.getLib sharedLibDeps.${name}}/lib" 301 /** 302 Closure notes: we explicitly avoid specifying --shared-*-includes, 303 as that would put the paths into bin/nodejs. 304 Including pkg-config in build inputs would also have the same effect! 305 306 FIXME: the statement above is outdated, we have to include pkg-config 307 in build inputs for system-icu. 308 */ 309 ]) (builtins.attrNames sharedLibDeps); 310 311 configurePlatforms = [ ]; 312 313 dontDisableStatic = true; 314 315 configureScript = writeScript "nodejs-configure" '' 316 exec ${python.executable} configure.py "$@" 317 ''; 318 319 # In order to support unsupported cross configurations, we copy some intermediate executables 320 # from a native build and replace all the build-system tools with a script which simply touches 321 # its outfile. We have to indiana-jones-swap the build-system-targeted tools since they are 322 # tested for efficacy at configure time. 323 postConfigure = lib.optionalString (!canEmulate && !canExecute) '' 324 cp ${buildNode.dev}/bin/* out/Release 325 export FAKE_TOUCH=1 326 ''; 327 328 enableParallelBuilding = true; 329 330 # Don't allow enabling content addressed conversion as `nodejs` 331 # checksums it's image before conversion happens and image loading 332 # breaks: 333 # $ nix build -f. nodejs --arg config '{ contentAddressedByDefault = true; }' 334 # $ ./result/bin/node 335 # Check failed: VerifyChecksum(blob). 336 __contentAddressed = false; 337 338 passthru.interpreterName = "nodejs"; 339 340 passthru.pkgs = callPackage ../../node-packages/default.nix { 341 nodejs = self; 342 }; 343 344 setupHook = ./setup-hook.sh; 345 346 pos = builtins.unsafeGetAttrPos "version" args; 347 348 inherit patches; 349 350 postPatch = lib.optionalString stdenv.hostPlatform.isDarwin '' 351 substituteInPlace test/parallel/test-macos-app-sandbox.js \ 352 --subst-var-by codesign '${darwin.sigtool}/bin/codesign' 353 ''; 354 355 __darwinAllowLocalNetworking = true; # for tests 356 357 doCheck = canExecute; 358 359 # See https://github.com/nodejs/node/issues/22006 360 enableParallelChecking = false; 361 362 # Some dependencies required for tools/doc/node_modules (and therefore 363 # test-addons, jstest and others) target are not included in the tarball. 364 # Run test targets that do not require network access. 365 checkTarget = lib.concatStringsSep " " ( 366 [ 367 "build-js-native-api-tests" 368 "build-node-api-tests" 369 "tooltest" 370 "cctest" 371 ] 372 ++ lib.optionals (!stdenv.buildPlatform.isDarwin || lib.versionAtLeast version "20") [ 373 # There are some test failures on macOS before v20 that are not worth the 374 # time to debug for a version that would be eventually removed in less 375 # than a year (Node.js 18 will be EOL at 2025-04-30). Note that these 376 # failures are specific to Nix sandbox on macOS and should not affect 377 # actual functionality. 378 "test-ci-js" 379 ] 380 ); 381 382 checkFlags = [ 383 # Do not create __pycache__ when running tests. 384 "PYTHONDONTWRITEBYTECODE=1" 385 ] 386 ++ lib.optionals (stdenv.buildPlatform.isDarwin && stdenv.buildPlatform.isx86_64) [ 387 # Python 3.12 introduced a warning for calling `os.fork()` in a 388 # multi‐threaded program. For some reason, the Node.js 389 # `tools/pseudo-tty.py` program used for PTY‐related tests 390 # triggers this warning on Hydra, on `x86_64-darwin` only, 391 # despite not creating any threads itself. This causes the 392 # Node.js test runner to misinterpret the warnings as part of the 393 # test output and fail. It does not reproduce reliably off Hydra 394 # on Intel Macs, or occur on the `aarch64-darwin` builds. 395 # 396 # This seems likely to be related to Rosetta 2, but it could also 397 # be some strange x86‐64‐only threading behaviour of the Darwin 398 # system libraries, or a bug in CPython, or something else 399 # haunted about the Nixpkgs/Hydra build environment. We silence 400 # the warnings in the hope that closing our eyes will make the 401 # ghosts go away. 402 "PYTHONWARNINGS=ignore::DeprecationWarning" 403 ] 404 ++ lib.optionals (!stdenv.buildPlatform.isDarwin || lib.versionAtLeast version "20") [ 405 "FLAKY_TESTS=skip" 406 # Skip some tests that are not passing in this context 407 "CI_SKIP_TESTS=${ 408 lib.concatStringsSep "," ( 409 [ 410 # Tests don't work in sandbox. 411 "test-child-process-exec-env" 412 "test-child-process-uid-gid" 413 "test-fs-write-stream-eagain" 414 "test-process-euid-egid" 415 "test-process-initgroups" 416 "test-process-setgroups" 417 "test-process-uid-gid" 418 # This is a bit weird, but for some reason fs watch tests fail with 419 # sandbox. 420 "test-fs-promises-watch" 421 "test-fs-watch" 422 "test-fs-watch-encoding" 423 "test-fs-watch-non-recursive" 424 "test-fs-watch-recursive-add-file" 425 "test-fs-watch-recursive-add-file-to-existing-subfolder" 426 "test-fs-watch-recursive-add-file-to-new-folder" 427 "test-fs-watch-recursive-add-file-with-url" 428 "test-fs-watch-recursive-add-folder" 429 "test-fs-watch-recursive-assert-leaks" 430 "test-fs-watch-recursive-promise" 431 "test-fs-watch-recursive-symlink" 432 "test-fs-watch-recursive-sync-write" 433 "test-fs-watch-recursive-update-file" 434 "test-fs-watchfile" 435 "test-runner-run" 436 "test-runner-watch-mode" 437 "test-watch-mode-files_watcher" 438 439 # fail on openssl 3.6.0 440 "test-http2-server-unknown-protocol" 441 "test-tls-ocsp-callback" 442 ] 443 ++ lib.optionals (!lib.versionAtLeast version "22") [ 444 "test-tls-multi-key" 445 ] 446 ++ lib.optionals useSharedAdaAndSimd [ 447 # Different versions of Ada affect the WPT tests 448 "test-url" 449 ] 450 ++ lib.optionals stdenv.hostPlatform.is32bit [ 451 # utime (actually utimensat) fails with EINVAL on 2038 timestamp 452 "test-fs-utimes-y2K38" 453 ] 454 ++ lib.optionals stdenv.buildPlatform.isDarwin [ 455 # Disable tests that don’t work under macOS sandbox. 456 # uv_os_setpriority returned EPERM (operation not permitted) 457 "test-os" 458 "test-os-process-priority" 459 460 # Debugger tests failing on macOS 15.4 461 "test-debugger-extract-function-name" 462 "test-debugger-random-port-with-inspect-port" 463 "test-debugger-launch" 464 "test-debugger-pid" 465 466 # Those are annoyingly flaky, but not enough to be marked as such upstream. 467 "test-wasi" 468 469 # This is failing on newer macOS versions, no fix has yet been provided upstream: 470 "test-cluster-dgram-1" 471 ] 472 ++ lib.optionals stdenv.hostPlatform.isMusl [ 473 # Doesn't work in sandbox on x86_64. 474 "test-dns-set-default-order" 475 ] 476 ++ lib.optionals (stdenv.buildPlatform.isDarwin && stdenv.buildPlatform.isx86_64) [ 477 # These tests fail on x86_64-darwin (even without sandbox). 478 # TODO: revisit at a later date. 479 "test-fs-readv" 480 "test-fs-readv-sync" 481 "test-vm-memleak" 482 483 # Those are annoyingly flaky, but not enough to be marked as such upstream. 484 "test-tick-processor-arguments" 485 "test-set-raw-mode-reset-signal" 486 ] 487 # Those are annoyingly flaky, but not enough to be marked as such upstream. 488 ++ lib.optional (majorVersion == "22") "test-child-process-stdout-flush-exit" 489 ++ lib.optional ( 490 majorVersion == "22" && stdenv.buildPlatform.isDarwin 491 ) "test/sequential/test-http-server-request-timeouts-mixed.js" 492 ) 493 }" 494 ]; 495 496 sandboxProfile = '' 497 (allow file-read* 498 (literal "/Library/Keychains/System.keychain") 499 (literal "/private/var/db/mds/system/mdsDirectory.db") 500 (literal "/private/var/db/mds/system/mdsObject.db")) 501 502 ; Allow files written by Module Directory Services (MDS), which is used 503 ; by Security.framework: https://apple.stackexchange.com/a/411476 504 ; These rules are based on the system sandbox profiles found in 505 ; /System/Library/Sandbox/Profiles. 506 (allow file-write* 507 (regex #"^/private/var/folders/[^/]+/[^/]+/C/mds/mdsDirectory\.db$") 508 (regex #"^/private/var/folders/[^/]+/[^/]+/C/mds/mdsObject\.db_?$") 509 (regex #"^/private/var/folders/[^/]+/[^/]+/C/mds/mds\.lock$")) 510 511 (allow mach-lookup 512 (global-name "com.apple.FSEvents") 513 (global-name "com.apple.SecurityServer") 514 (global-name "com.apple.system.opendirectoryd.membership")) 515 ''; 516 517 postInstall = 518 let 519 # nodejs_18 does not have node_js2c, and we don't want to rebuild the other ones 520 # FIXME: fix this cleanly in staging 521 tools = 522 if majorVersion == "18" then 523 "{bytecode_builtins_list_generator,mksnapshot,torque,gen-regexp-special-case}" 524 else 525 "{bytecode_builtins_list_generator,mksnapshot,torque,node_js2c,gen-regexp-special-case}"; 526 in 527 lib.optionalString (stdenv.hostPlatform == stdenv.buildPlatform) '' 528 mkdir -p $dev/bin 529 cp out/Release/${tools} $dev/bin 530 '' 531 + '' 532 533 HOST_PATH=$out/bin patchShebangs --host $out 534 535 ${lib.optionalString canExecute '' 536 $out/bin/node --completion-bash > node.bash 537 installShellCompletion node.bash 538 ''} 539 540 ${lib.optionalString enableNpm '' 541 mkdir -p $out/share/bash-completion/completions 542 ln -s $out/lib/node_modules/npm/lib/utils/completion.sh \ 543 $out/share/bash-completion/completions/npm 544 for dir in "$out/lib/node_modules/npm/man/"*; do 545 mkdir -p $out/share/man/$(basename "$dir") 546 for page in "$dir"/*; do 547 ln -rs $page $out/share/man/$(basename "$dir") 548 done 549 done 550 ''} 551 552 # install the missing headers for node-gyp 553 # TODO: use propagatedBuildInputs instead of copying headers. 554 cp -r ${lib.concatStringsSep " " copyLibHeaders} $out/include/node 555 556 # assemble a static v8 library and put it in the 'libv8' output 557 mkdir -p $libv8/lib 558 pushd out/Release/obj 559 find . -path "**/torque_*/**/*.o" -or -path "**/v8*/**/*.o" \ 560 -and -not -name "torque.*" \ 561 -and -not -name "mksnapshot.*" \ 562 -and -not -name "gen-regexp-special-case.*" \ 563 -and -not -name "bytecode_builtins_list_generator.*" \ 564 | sort -u >files 565 test -s files # ensure that the list is not empty 566 $AR -cqs $libv8/lib/libv8.a @files 567 popd 568 569 # copy v8 headers 570 cp -r deps/v8/include $libv8/ 571 572 # create a pkgconfig file for v8 573 major=$(grep V8_MAJOR_VERSION deps/v8/include/v8-version.h | cut -d ' ' -f 3) 574 minor=$(grep V8_MINOR_VERSION deps/v8/include/v8-version.h | cut -d ' ' -f 3) 575 patch=$(grep V8_PATCH_LEVEL deps/v8/include/v8-version.h | cut -d ' ' -f 3) 576 mkdir -p $libv8/lib/pkgconfig 577 cat > $libv8/lib/pkgconfig/v8.pc << EOF 578 Name: v8 579 Description: V8 JavaScript Engine 580 Version: $major.$minor.$patch 581 Libs: -L$libv8/lib -lv8 -pthread -licui18n -licuuc 582 Cflags: -I$libv8/include 583 EOF 584 '' 585 + lib.optionalString (stdenv.hostPlatform == stdenv.buildPlatform) '' 586 cp -r $out/include $dev/include 587 ''; 588 589 passthru.tests = { 590 version = testers.testVersion { 591 package = self; 592 version = "v${lib.head (lib.strings.splitString "-rc." version)}"; 593 }; 594 }; 595 596 passthru.updateScript = import ./update.nix { 597 inherit 598 writeScript 599 common-updater-scripts 600 coreutils 601 curl 602 fetchurl 603 gnugrep 604 gnupg 605 jq 606 runtimeShell 607 ; 608 inherit lib; 609 inherit majorVersion; 610 }; 611 612 meta = { 613 description = "Event-driven I/O framework for the V8 JavaScript engine"; 614 homepage = "https://nodejs.org"; 615 changelog = "https://github.com/nodejs/node/releases/tag/v${version}"; 616 license = lib.licenses.mit; 617 maintainers = with lib.maintainers; [ aduh95 ]; 618 # https://github.com/nodejs/node/blob/732ab9d658e057af5191d4ecd156d38487509462/BUILDING.md#platform-list 619 platforms = 620 (lib.lists.intersectLists ( 621 lib.platforms.linux ++ lib.platforms.darwin ++ lib.platforms.freebsd 622 ) lib.platforms.littleEndian) 623 ++ [ "s390x-linux" ]; 624 # This broken condition is likely too conservative. Feel free to loosen it if it works. 625 broken = 626 !canExecute && !canEmulate && (stdenv.buildPlatform.parsed.cpu != stdenv.hostPlatform.parsed.cpu); 627 mainProgram = "node"; 628 knownVulnerabilities = lib.optional (lib.versionOlder version "18") "This NodeJS release has reached its end of life. See https://nodejs.org/en/about/releases/."; 629 }; 630 631 passthru.python = python; # to ensure nodeEnv uses the same version 632 } 633 ); 634in 635package