nodejs: fix cross compilation for non-emulatable platforms (#384413)

authored by Audrey Dutcher and committed by GitHub 6a8334df 157cb194

+88 -9
+44 -5
pkgs/development/web/nodejs/nodejs.nix
··· 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 = ··· 126 ln -s "$cctools/bin/libtool" "$out/bin/libtool" 127 ''; 128 129 package = stdenv.mkDerivation (finalAttrs: 130 let 131 /** the final package fixed point, after potential overrides */ ··· 148 # Note: do not set TERM=dumb environment variable globally, it is used in 149 # test-ci-js test suite to skip tests that otherwise run fine. 150 NINJA = "TERM=dumb ninja"; 151 }; 152 153 # NB: technically, we do not need bash in build inputs since all scripts are ··· 179 dontUseNinjaCheck = true; 180 dontUseNinjaInstall = true; 181 182 - outputs = [ "out" "libv8" ]; 183 setOutputFlags = false; 184 moveToDev = false; 185 ··· 188 "--ninja" 189 "--with-intl=system-icu" 190 "--openssl-use-def-ca-store" 191 - "--no-cross-compiling" 192 "--dest-os=${destOS}" 193 "--dest-cpu=${destCPU}" 194 ] 195 ++ lib.optionals (destARMFPU != null) [ "--with-arm-fpu=${destARMFPU}" ] 196 ++ lib.optionals (destARMFloatABI != null) [ "--with-arm-float-abi=${destARMFloatABI}" ] 197 - ++ lib.optionals (!canExecute) [ 198 # Node.js requires matching bitness between build and host platforms, e.g. 199 # for V8 startup snapshot builder (see tools/snapshot) and some other 200 # tools. We apply a patch that runs these tools using a host platform ··· 225 exec ${python.executable} configure.py "$@" 226 ''; 227 228 enableParallelBuilding = true; 229 230 # Don't allow enabling content addressed conversion as `nodejs` ··· 343 ])}" 344 ]; 345 346 - postInstall = '' 347 HOST_PATH=$out/bin patchShebangs --host $out 348 349 ${lib.optionalString canExecute '' ··· 416 changelog = "https://github.com/nodejs/node/releases/tag/v${version}"; 417 license = licenses.mit; 418 maintainers = with maintainers; [ aduh95 ]; 419 - platforms = platforms.linux ++ platforms.darwin; 420 mainProgram = "node"; 421 knownVulnerabilities = optional (versionOlder version "18") "This NodeJS release has reached its end of life. See https://nodejs.org/en/about/releases/."; 422 };
··· 22 23 canExecute = stdenv.buildPlatform.canExecute stdenv.hostPlatform; 24 emulator = stdenv.hostPlatform.emulator buildPackages; 25 + canEmulate = stdenv.hostPlatform.emulatorAvailable buildPackages; 26 + buildNode = buildPackages."${pname}_${majorVersion}"; 27 28 # See valid_os and valid_arch in configure.py. 29 destOS = ··· 128 ln -s "$cctools/bin/libtool" "$out/bin/libtool" 129 ''; 130 131 + # a script which claims to be a different script but switches to simply touching its output 132 + # when an environment variable is set. See CC_host, --cross-compiling, and postConfigure. 133 + touchScript = real: writeScript "touch-script" '' 134 + #!${stdenv.shell} 135 + if [ -z "$FAKE_TOUCH" ]; then 136 + exec "${real}" "$@" 137 + fi 138 + while [ "$#" != "0" ]; do 139 + if [ "$1" == "-o" ]; then 140 + shift 141 + touch "$1" 142 + fi 143 + shift 144 + done 145 + ''; 146 + 147 package = stdenv.mkDerivation (finalAttrs: 148 let 149 /** the final package fixed point, after potential overrides */ ··· 166 # Note: do not set TERM=dumb environment variable globally, it is used in 167 # test-ci-js test suite to skip tests that otherwise run fine. 168 NINJA = "TERM=dumb ninja"; 169 + } // lib.optionalAttrs (!canExecute && !canEmulate) { 170 + # these are used in the --cross-compiling case. see comment at postConfigure. 171 + CC_host = touchScript "${buildPackages.stdenv.cc}/bin/cc"; 172 + CXX_host = touchScript "${buildPackages.stdenv.cc}/bin/c++"; 173 + AR_host = touchScript "${buildPackages.stdenv.cc}/bin/ar"; 174 }; 175 176 # NB: technically, we do not need bash in build inputs since all scripts are ··· 202 dontUseNinjaCheck = true; 203 dontUseNinjaInstall = true; 204 205 + outputs = [ "out" "libv8" ] ++ lib.optionals (stdenv.hostPlatform == stdenv.buildPlatform) [ "dev" ]; 206 setOutputFlags = false; 207 moveToDev = false; 208 ··· 211 "--ninja" 212 "--with-intl=system-icu" 213 "--openssl-use-def-ca-store" 214 + # --cross-compiling flag enables use of CC_host et. al 215 + (if canExecute || canEmulate then "--no-cross-compiling" else "--cross-compiling") 216 "--dest-os=${destOS}" 217 "--dest-cpu=${destCPU}" 218 ] 219 ++ lib.optionals (destARMFPU != null) [ "--with-arm-fpu=${destARMFPU}" ] 220 ++ lib.optionals (destARMFloatABI != null) [ "--with-arm-float-abi=${destARMFloatABI}" ] 221 + ++ lib.optionals (!canExecute && canEmulate) [ 222 # Node.js requires matching bitness between build and host platforms, e.g. 223 # for V8 startup snapshot builder (see tools/snapshot) and some other 224 # tools. We apply a patch that runs these tools using a host platform ··· 249 exec ${python.executable} configure.py "$@" 250 ''; 251 252 + # In order to support unsupported cross configurations, we copy some intermediate executables 253 + # from a native build and replace all the build-system tools with a script which simply touches 254 + # its outfile. We have to indiana-jones-swap the build-system-targeted tools since they are 255 + # tested for efficacy at configure time. 256 + postConfigure = lib.optionalString (!canEmulate && !canExecute) '' 257 + cp ${buildNode.dev}/bin/* out/Release 258 + export FAKE_TOUCH=1 259 + ''; 260 + 261 enableParallelBuilding = true; 262 263 # Don't allow enabling content addressed conversion as `nodejs` ··· 376 ])}" 377 ]; 378 379 + postInstall = lib.optionalString (stdenv.hostPlatform == stdenv.buildPlatform) '' 380 + mkdir -p $dev/bin 381 + cp out/Release/{bytecode_builtins_list_generator,mksnapshot,torque,node_js2c,gen-regexp-special-case} $dev/bin 382 + '' + '' 383 + 384 HOST_PATH=$out/bin patchShebangs --host $out 385 386 ${lib.optionalString canExecute '' ··· 453 changelog = "https://github.com/nodejs/node/releases/tag/v${version}"; 454 license = licenses.mit; 455 maintainers = with maintainers; [ aduh95 ]; 456 + platforms = platforms.linux ++ platforms.darwin ++ platforms.freebsd; 457 + # This broken condition is likely too conservative. Feel free to loosen it if it works. 458 + broken = !canExecute && !canEmulate && (stdenv.buildPlatform.parsed.cpu != stdenv.hostPlatform.parsed.cpu); 459 mainProgram = "node"; 460 knownVulnerabilities = optional (versionOlder version "18") "This NodeJS release has reached its end of life. See https://nodejs.org/en/about/releases/."; 461 };
+18 -2
pkgs/development/web/nodejs/v22.nix
··· 1 - { callPackage, openssl, python3, enableNpm ? true }: 2 3 let 4 buildNodejs = callPackage ./nodejs.nix { ··· 10 inherit enableNpm; 11 version = "22.14.0"; 12 sha256 = "c609946bf793b55c7954c26582760808d54c16185d79cb2fb88065e52de21914"; 13 - patches = [ 14 ./configure-emulator.patch 15 ./configure-armv6-vfpv2.patch 16 ./disable-darwin-v8-system-instrumentation-node19.patch 17 ./bypass-darwin-xcrun-node16.patch
··· 1 + { lib, stdenv, buildPackages, callPackage, fetchpatch2, openssl, python3, enableNpm ? true }: 2 3 let 4 buildNodejs = callPackage ./nodejs.nix { ··· 10 inherit enableNpm; 11 version = "22.14.0"; 12 sha256 = "c609946bf793b55c7954c26582760808d54c16185d79cb2fb88065e52de21914"; 13 + patches = (if (stdenv.hostPlatform.emulatorAvailable buildPackages) then [ 14 ./configure-emulator.patch 15 + ] else [ 16 + (fetchpatch2 { 17 + url = "https://raw.githubusercontent.com/buildroot/buildroot/2f0c31bffdb59fb224387e35134a6d5e09a81d57/package/nodejs/nodejs-src/0003-include-obj-name-in-shared-intermediate.patch"; 18 + hash = "sha256-3g4aS+NmmUYNOYRNc6UMJKYoaTlpP5Knt9UHegx+o0Y="; 19 + }) 20 + ]) ++ lib.optionals (stdenv.hostPlatform != stdenv.buildPlatform && stdenv.hostPlatform.isFreeBSD) [ 21 + # This patch is concerning. 22 + # https://github.com/nodejs/node/issues/54576 23 + # It is only supposed to affect clang >= 17, but I'm seeing it on clang 19. 24 + # I'm keeping the predicate for this patch pretty strict out of caution, 25 + # so if you see the error it's supposed to prevent, feel free to loosen it. 26 + (fetchpatch2 { 27 + url = "https://raw.githubusercontent.com/rubyjs/libv8-node/62476a398d4c9c1a670240a3b070d69544be3761/patch/v8-no-assert-trivially-copyable.patch"; 28 + hash = "sha256-hSTLljmVzYmc3WAVeRq9EPYluXGXFeWVXkykufGQPVw="; 29 + }) 30 + ] ++ [ 31 ./configure-armv6-vfpv2.patch 32 ./disable-darwin-v8-system-instrumentation-node19.patch 33 ./bypass-darwin-xcrun-node16.patch
+26 -2
pkgs/development/web/nodejs/v23.nix
··· 1 { 2 lib, 3 stdenv, 4 callPackage, 5 fetchpatch2, 6 openssl, ··· 19 version = "23.10.0"; 20 sha256 = "b39e5fbd3debb8318ddea6af3e89b07dafb891421fb7ca99fbe19c99adabe5fd"; 21 patches = 22 - [ 23 - ./configure-emulator.patch 24 ./configure-armv6-vfpv2.patch 25 ./disable-darwin-v8-system-instrumentation-node19.patch 26 ./bypass-darwin-xcrun-node16.patch
··· 1 { 2 lib, 3 stdenv, 4 + buildPackages, 5 callPackage, 6 fetchpatch2, 7 openssl, ··· 20 version = "23.10.0"; 21 sha256 = "b39e5fbd3debb8318ddea6af3e89b07dafb891421fb7ca99fbe19c99adabe5fd"; 22 patches = 23 + ( 24 + if (stdenv.hostPlatform.emulatorAvailable buildPackages) then 25 + [ 26 + ./configure-emulator.patch 27 + ] 28 + else 29 + [ 30 + (fetchpatch2 { 31 + url = "https://raw.githubusercontent.com/buildroot/buildroot/2f0c31bffdb59fb224387e35134a6d5e09a81d57/package/nodejs/nodejs-src/0003-include-obj-name-in-shared-intermediate.patch"; 32 + hash = "sha256-3g4aS+NmmUYNOYRNc6UMJKYoaTlpP5Knt9UHegx+o0Y="; 33 + }) 34 + ] 35 + ) 36 + ++ lib.optionals (stdenv.hostPlatform != stdenv.buildPlatform && stdenv.hostPlatform.isFreeBSD) [ 37 + # This patch is concerning. 38 + # https://github.com/nodejs/node/issues/54576 39 + # It is only supposed to affect clang >= 17, but I'm seeing it on clang 19. 40 + # I'm keeping the predicate for this patch pretty strict out of caution, 41 + # so if you see the error it's supposed to prevent, feel free to loosen it. 42 + (fetchpatch2 { 43 + url = "https://raw.githubusercontent.com/rubyjs/libv8-node/62476a398d4c9c1a670240a3b070d69544be3761/patch/v8-no-assert-trivially-copyable.patch"; 44 + hash = "sha256-hSTLljmVzYmc3WAVeRq9EPYluXGXFeWVXkykufGQPVw="; 45 + }) 46 + ] 47 + ++ [ 48 ./configure-armv6-vfpv2.patch 49 ./disable-darwin-v8-system-instrumentation-node19.patch 50 ./bypass-darwin-xcrun-node16.patch