Clone of https://github.com/NixOS/nixpkgs.git (to stress-test knotserver)
at gcc-offload 421 lines 16 kB view raw
1{ lib, stdenv, fetchurl, openssl, python, zlib, libuv, http-parser, icu, bash 2, ninja, pkgconf, unixtools, runCommand, buildPackages 3, testers 4# for `.pkgs` attribute 5, callPackage 6# Updater dependencies 7, writeScript, coreutils, gnugrep, jq, curl, common-updater-scripts, nix, runtimeShell 8, gnupg 9, darwin 10, installShellFiles 11}: 12 13{ enableNpm ? true, version, sha256, patches ? [] } @args: 14 15let 16 inherit (darwin.apple_sdk.frameworks) CoreServices ApplicationServices; 17 18 majorVersion = lib.versions.major version; 19 minorVersion = lib.versions.minor version; 20 21 pname = if enableNpm then "nodejs" else "nodejs-slim"; 22 23 canExecute = stdenv.buildPlatform.canExecute stdenv.hostPlatform; 24 emulator = stdenv.hostPlatform.emulator buildPackages; 25 26 # See valid_os and valid_arch in configure.py. 27 destOS = 28 let 29 platform = stdenv.hostPlatform; 30 in 31 if platform.isiOS then 32 "ios" 33 else if platform.isAndroid then 34 "android" 35 else if platform.isWindows then 36 "win" 37 else if platform.isDarwin then 38 "mac" 39 else if platform.isLinux then 40 "linux" 41 else if platform.isOpenBSD then 42 "openbsd" 43 else if platform.isFreeBSD then 44 "freebsd" 45 else 46 throw "unsupported os ${platform.uname.system}"; 47 destCPU = 48 let 49 platform = stdenv.hostPlatform; 50 in 51 if platform.isAarch then 52 "arm" + lib.optionalString platform.is64bit "64" 53 else if platform.isMips32 then 54 "mips" + lib.optionalString platform.isLittleEndian "le" 55 else if platform.isMips64 && platform.isLittleEndian then 56 "mips64el" 57 else if platform.isPower then 58 "ppc" + lib.optionalString platform.is64bit "64" 59 else if platform.isx86_64 then 60 "x64" 61 else if platform.isx86_32 then 62 "ia32" 63 else if platform.isS390x then 64 "s390x" 65 else if platform.isRiscV64 then 66 "riscv64" 67 else if platform.isLoongArch64 then 68 "loong64" 69 else 70 throw "unsupported cpu ${platform.uname.processor}"; 71 destARMFPU = 72 let 73 platform = stdenv.hostPlatform; 74 in 75 if platform.isAarch32 && platform ? gcc.fpu then 76 lib.throwIfNot (builtins.elem platform.gcc.fpu [ 77 "vfp" 78 "vfpv2" 79 "vfpv3" 80 "vfpv3-d16" 81 "neon" 82 ]) "unsupported ARM FPU ${platform.gcc.fpu}" platform.gcc.fpu 83 else 84 null; 85 destARMFloatABI = 86 let 87 platform = stdenv.hostPlatform; 88 in 89 if platform.isAarch32 && platform ? gcc.float-abi then 90 lib.throwIfNot (builtins.elem platform.gcc.float-abi [ 91 "soft" 92 "softfp" 93 "hard" 94 ]) "unsupported ARM float ABI ${platform.gcc.float-abi}" platform.gcc.float-abi 95 else 96 null; 97 # TODO: also handle MIPS flags (mips_arch, mips_fpu, mips_float_abi). 98 99 useSharedHttpParser = !stdenv.hostPlatform.isDarwin && lib.versionOlder "${majorVersion}.${minorVersion}" "11.4"; 100 101 sharedLibDeps = { inherit openssl zlib libuv; } // (lib.optionalAttrs useSharedHttpParser { inherit http-parser; }); 102 103 copyLibHeaders = 104 map 105 (name: "${lib.getDev sharedLibDeps.${name}}/include/*") 106 (builtins.attrNames sharedLibDeps); 107 108 # Currently stdenv sets CC/LD/AR/etc environment variables to program names 109 # instead of absolute paths. If we add cctools to nativeBuildInputs, that 110 # would shadow stdenv’s bintools and potentially break other parts of the 111 # build. The correct behavior is to use absolute paths, and there is a PR for 112 # that, see https://github.com/NixOS/nixpkgs/pull/314920. As a temporary 113 # workaround, we use only a single program we need (and that is not part of 114 # the stdenv). 115 darwin-cctools-only-libtool = 116 # Would be nice to have onlyExe builder similar to onlyBin… 117 runCommand "darwin-cctools-only-libtool" { cctools = lib.getBin buildPackages.cctools; } '' 118 mkdir -p "$out/bin" 119 ln -s "$cctools/bin/libtool" "$out/bin/libtool" 120 ''; 121 122 package = stdenv.mkDerivation (finalAttrs: 123 let 124 /** the final package fixed point, after potential overrides */ 125 self = finalAttrs.finalPackage; 126 in 127 { 128 inherit pname version; 129 130 src = fetchurl { 131 url = "https://nodejs.org/dist/v${version}/node-v${version}.tar.xz"; 132 inherit sha256; 133 }; 134 135 strictDeps = true; 136 137 env = { 138 # Tell ninja to avoid ANSI sequences, otherwise we don’t see build 139 # progress in Nix logs. 140 # 141 # Note: do not set TERM=dumb environment variable globally, it is used in 142 # test-ci-js test suite to skip tests that otherwise run fine. 143 NINJA = "TERM=dumb ninja"; 144 } // lib.optionalAttrs (stdenv.hostPlatform.isDarwin && stdenv.hostPlatform.isx86_64) { 145 # Make sure libc++ uses `posix_memalign` instead of `aligned_alloc` on x86_64-darwin. 146 # Otherwise, nodejs would require the 11.0 SDK and macOS 10.15+. 147 NIX_CFLAGS_COMPILE = "-D__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__=101300 -Wno-macro-redefined"; 148 }; 149 150 # NB: technically, we do not need bash in build inputs since all scripts are 151 # wrappers over the corresponding JS scripts. There are some packages though 152 # that use bash wrappers, e.g. polaris-web. 153 buildInputs = lib.optionals stdenv.hostPlatform.isDarwin [ CoreServices ApplicationServices ] 154 ++ [ zlib libuv openssl http-parser icu bash ]; 155 156 nativeBuildInputs = 157 [ 158 installShellFiles 159 ninja 160 pkgconf 161 python 162 ] 163 ++ lib.optionals stdenv.buildPlatform.isDarwin [ 164 # gyp checks `sysctl -n hw.memsize` if `sys.platform == "darwin"`. 165 unixtools.sysctl 166 ] 167 ++ lib.optionals stdenv.hostPlatform.isDarwin [ 168 # For gyp-mac-tool if `flavor == "mac"`. 169 darwin-cctools-only-libtool 170 ]; 171 172 # We currently rely on Makefile and stdenv for build phases, so do not let 173 # ninja’s setup hook to override default stdenv phases. 174 dontUseNinjaBuild = true; 175 dontUseNinjaCheck = true; 176 dontUseNinjaInstall = true; 177 178 outputs = [ "out" "libv8" ]; 179 setOutputFlags = false; 180 moveToDev = false; 181 182 configureFlags = 183 [ 184 "--ninja" 185 "--with-intl=system-icu" 186 "--openssl-use-def-ca-store" 187 "--no-cross-compiling" 188 "--dest-os=${destOS}" 189 "--dest-cpu=${destCPU}" 190 ] 191 ++ lib.optionals (destARMFPU != null) [ "--with-arm-fpu=${destARMFPU}" ] 192 ++ lib.optionals (destARMFloatABI != null) [ "--with-arm-float-abi=${destARMFloatABI}" ] 193 ++ lib.optionals (!canExecute) [ 194 # Node.js requires matching bitness between build and host platforms, e.g. 195 # for V8 startup snapshot builder (see tools/snapshot) and some other 196 # tools. We apply a patch that runs these tools using a host platform 197 # emulator and avoid cross-compiling altogether (from the build system’s 198 # perspective). 199 "--emulator=${emulator}" 200 ] 201 ++ lib.optionals (lib.versionOlder version "19") [ "--without-dtrace" ] 202 ++ lib.optionals (!enableNpm) [ "--without-npm" ] 203 ++ lib.concatMap (name: [ 204 "--shared-${name}" 205 "--shared-${name}-libpath=${lib.getLib sharedLibDeps.${name}}/lib" 206 /** 207 Closure notes: we explicitly avoid specifying --shared-*-includes, 208 as that would put the paths into bin/nodejs. 209 Including pkg-config in build inputs would also have the same effect! 210 211 FIXME: the statement above is outdated, we have to include pkg-config 212 in build inputs for system-icu. 213 */ 214 ]) (builtins.attrNames sharedLibDeps); 215 216 configurePlatforms = [ ]; 217 218 dontDisableStatic = true; 219 220 configureScript = writeScript "nodejs-configure" '' 221 exec ${python.executable} configure.py "$@" 222 ''; 223 224 enableParallelBuilding = true; 225 226 # Don't allow enabling content addressed conversion as `nodejs` 227 # checksums it's image before conversion happens and image loading 228 # breaks: 229 # $ nix build -f. nodejs --arg config '{ contentAddressedByDefault = true; }' 230 # $ ./result/bin/node 231 # Check failed: VerifyChecksum(blob). 232 __contentAddressed = false; 233 234 passthru.interpreterName = "nodejs"; 235 236 passthru.pkgs = callPackage ../../node-packages/default.nix { 237 nodejs = self; 238 }; 239 240 setupHook = ./setup-hook.sh; 241 242 pos = builtins.unsafeGetAttrPos "version" args; 243 244 inherit patches; 245 246 __darwinAllowLocalNetworking = true; # for tests 247 248 doCheck = canExecute; 249 250 # See https://github.com/nodejs/node/issues/22006 251 enableParallelChecking = false; 252 253 # Some dependencies required for tools/doc/node_modules (and therefore 254 # test-addons, jstest and others) target are not included in the tarball. 255 # Run test targets that do not require network access. 256 checkTarget = lib.concatStringsSep " " ([ 257 "build-js-native-api-tests" 258 "build-node-api-tests" 259 "tooltest" 260 "cctest" 261 ] ++ lib.optionals (!stdenv.buildPlatform.isDarwin || lib.versionAtLeast version "20") [ 262 # There are some test failures on macOS before v20 that are not worth the 263 # time to debug for a version that would be eventually removed in less 264 # than a year (Node.js 18 will be EOL at 2025-04-30). Note that these 265 # failures are specific to Nix sandbox on macOS and should not affect 266 # actual functionality. 267 "test-ci-js" 268 ]); 269 270 checkFlags = [ 271 # Do not create __pycache__ when running tests. 272 "PYTHONDONTWRITEBYTECODE=1" 273 ] ++ lib.optionals (stdenv.buildPlatform.isDarwin && stdenv.buildPlatform.isx86_64) [ 274 # Python 3.12 introduced a warning for calling `os.fork()` in a 275 # multi‐threaded program. For some reason, the Node.js 276 # `tools/pseudo-tty.py` program used for PTY‐related tests 277 # triggers this warning on Hydra, on `x86_64-darwin` only, 278 # despite not creating any threads itself. This causes the 279 # Node.js test runner to misinterpret the warnings as part of the 280 # test output and fail. It does not reproduce reliably off Hydra 281 # on Intel Macs, or occur on the `aarch64-darwin` builds. 282 # 283 # This seems likely to be related to Rosetta 2, but it could also 284 # be some strange x86‐64‐only threading behaviour of the Darwin 285 # system libraries, or a bug in CPython, or something else 286 # haunted about the Nixpkgs/Hydra build environment. We silence 287 # the warnings in the hope that closing our eyes will make the 288 # ghosts go away. 289 "PYTHONWARNINGS=ignore::DeprecationWarning" 290 ] ++ lib.optionals (!stdenv.buildPlatform.isDarwin || lib.versionAtLeast version "20") [ 291 "FLAKY_TESTS=skip" 292 # Skip some tests that are not passing in this context 293 "CI_SKIP_TESTS=${lib.concatStringsSep "," ([ 294 "test-child-process-exec-env" 295 "test-child-process-uid-gid" 296 "test-fs-write-stream-eagain" 297 "test-process-euid-egid" 298 "test-process-initgroups" 299 "test-process-setgroups" 300 "test-process-uid-gid" 301 "test-setproctitle" 302 # This is a bit weird, but for some reason fs watch tests fail with 303 # sandbox. 304 "test-fs-promises-watch" 305 "test-fs-watch" 306 "test-fs-watch-encoding" 307 "test-fs-watch-non-recursive" 308 "test-fs-watch-recursive-add-file" 309 "test-fs-watch-recursive-add-file-to-existing-subfolder" 310 "test-fs-watch-recursive-add-file-to-new-folder" 311 "test-fs-watch-recursive-add-file-with-url" 312 "test-fs-watch-recursive-add-folder" 313 "test-fs-watch-recursive-assert-leaks" 314 "test-fs-watch-recursive-promise" 315 "test-fs-watch-recursive-symlink" 316 "test-fs-watch-recursive-sync-write" 317 "test-fs-watch-recursive-update-file" 318 "test-fs-watchfile" 319 "test-runner-run" 320 "test-runner-watch-mode" 321 "test-watch-mode-files_watcher" 322 ] ++ lib.optionals (!lib.versionAtLeast version "22") [ 323 "test-tls-multi-key" 324 ] ++ lib.optionals stdenv.hostPlatform.is32bit [ 325 # utime (actually utimensat) fails with EINVAL on 2038 timestamp 326 "test-fs-utimes-y2K38" 327 ] ++ lib.optionals stdenv.buildPlatform.isDarwin [ 328 # Disable tests that don’t work under macOS sandbox. 329 "test-macos-app-sandbox" 330 "test-os" 331 "test-os-process-priority" 332 ] ++ lib.optionals (stdenv.buildPlatform.isDarwin && stdenv.buildPlatform.isx86_64) [ 333 # These tests fail on x86_64-darwin (even without sandbox). 334 # TODO: revisit at a later date. 335 "test-fs-readv" 336 "test-fs-readv-sync" 337 "test-vm-memleak" 338 ])}" 339 ]; 340 341 postInstall = '' 342 HOST_PATH=$out/bin patchShebangs --host $out 343 344 ${lib.optionalString canExecute '' 345 $out/bin/node --completion-bash > node.bash 346 installShellCompletion node.bash 347 ''} 348 349 ${lib.optionalString enableNpm '' 350 mkdir -p $out/share/bash-completion/completions 351 ln -s $out/lib/node_modules/npm/lib/utils/completion.sh \ 352 $out/share/bash-completion/completions/npm 353 for dir in "$out/lib/node_modules/npm/man/"*; do 354 mkdir -p $out/share/man/$(basename "$dir") 355 for page in "$dir"/*; do 356 ln -rs $page $out/share/man/$(basename "$dir") 357 done 358 done 359 ''} 360 361 # install the missing headers for node-gyp 362 # TODO: add dev output and use propagatedBuildInputs instead of copying headers. 363 cp -r ${lib.concatStringsSep " " copyLibHeaders} $out/include/node 364 365 # assemble a static v8 library and put it in the 'libv8' output 366 mkdir -p $libv8/lib 367 pushd out/Release/obj 368 find . -path "**/torque_*/**/*.o" -or -path "**/v8*/**/*.o" \ 369 -and -not -name "torque.*" \ 370 -and -not -name "mksnapshot.*" \ 371 -and -not -name "gen-regexp-special-case.*" \ 372 -and -not -name "bytecode_builtins_list_generator.*" \ 373 | sort -u >files 374 test -s files # ensure that the list is not empty 375 $AR -cqs $libv8/lib/libv8.a @files 376 popd 377 378 # copy v8 headers 379 cp -r deps/v8/include $libv8/ 380 381 # create a pkgconfig file for v8 382 major=$(grep V8_MAJOR_VERSION deps/v8/include/v8-version.h | cut -d ' ' -f 3) 383 minor=$(grep V8_MINOR_VERSION deps/v8/include/v8-version.h | cut -d ' ' -f 3) 384 patch=$(grep V8_PATCH_LEVEL deps/v8/include/v8-version.h | cut -d ' ' -f 3) 385 mkdir -p $libv8/lib/pkgconfig 386 cat > $libv8/lib/pkgconfig/v8.pc << EOF 387 Name: v8 388 Description: V8 JavaScript Engine 389 Version: $major.$minor.$patch 390 Libs: -L$libv8/lib -lv8 -pthread -licui18n -licuuc 391 Cflags: -I$libv8/include 392 EOF 393 ''; 394 395 passthru.tests = { 396 version = testers.testVersion { 397 package = self; 398 version = "v${version}"; 399 }; 400 }; 401 402 passthru.updateScript = import ./update.nix { 403 inherit writeScript coreutils gnugrep jq curl common-updater-scripts gnupg nix runtimeShell; 404 inherit lib; 405 inherit majorVersion; 406 }; 407 408 meta = with lib; { 409 description = "Event-driven I/O framework for the V8 JavaScript engine"; 410 homepage = "https://nodejs.org"; 411 changelog = "https://github.com/nodejs/node/releases/tag/v${version}"; 412 license = licenses.mit; 413 maintainers = with maintainers; [ aduh95 ]; 414 platforms = platforms.linux ++ platforms.darwin; 415 mainProgram = "node"; 416 knownVulnerabilities = optional (versionOlder version "18") "This NodeJS release has reached its end of life. See https://nodejs.org/en/about/releases/."; 417 }; 418 419 passthru.python = python; # to ensure nodeEnv uses the same version 420 }); 421in package