Clone of https://github.com/NixOS/nixpkgs.git (to stress-test knotserver)
1{ 2 lib, 3 stdenv, 4 fetchurl, 5 fetchpatch, 6 fetchgit, 7 8 # build dependencies 9 autoconf-archive, 10 autoreconfHook, 11 nukeReferences, 12 pkg-config, 13 python-setup-hook, 14 15 # runtime dependencies 16 bzip2, 17 withExpat ? true, 18 expat, 19 libffi, 20 libuuid, 21 libxcrypt, 22 withMpdecimal ? true, 23 mpdecimal, 24 ncurses, 25 openssl, 26 sqlite, 27 xz, 28 zlib, 29 zstd, 30 31 # platform-specific dependencies 32 bashNonInteractive, 33 windows, 34 35 # optional dependencies 36 bluezSupport ? false, 37 bluez, 38 mimetypesSupport ? true, 39 mailcap, 40 tzdata, 41 withGdbm ? !stdenv.hostPlatform.isWindows, 42 gdbm, 43 withReadline ? !stdenv.hostPlatform.isWindows, 44 readline, 45 x11Support ? false, 46 tcl, 47 tk, 48 tclPackages, 49 libX11, 50 xorgproto, 51 52 # splicing/cross 53 pythonAttr ? "python${sourceVersion.major}${sourceVersion.minor}", 54 self, 55 pkgsBuildBuild, 56 pkgsBuildHost, 57 pkgsBuildTarget, 58 pkgsHostHost, 59 pkgsTargetTarget, 60 __splices ? { }, 61 62 # build customization 63 sourceVersion, 64 hash, 65 passthruFun, 66 stripConfig ? false, 67 stripIdlelib ? false, 68 stripTests ? false, 69 stripTkinter ? false, 70 rebuildBytecode ? true, 71 stripBytecode ? true, 72 includeSiteCustomize ? true, 73 static ? stdenv.hostPlatform.isStatic, 74 enableFramework ? false, 75 noldconfigPatch ? ./. + "/${sourceVersion.major}.${sourceVersion.minor}/no-ldconfig.patch", 76 enableGIL ? true, 77 enableDebug ? false, 78 79 # pgo (not reproducible) + -fno-semantic-interposition 80 # https://docs.python.org/3/using/configure.html#cmdoption-enable-optimizations 81 enableOptimizations ? false, 82 83 # improves performance, but remains reproducible 84 enableNoSemanticInterposition ? true, 85 86 # enabling LTO on 32bit arch causes downstream packages to fail when linking 87 enableLTO ? 88 stdenv.hostPlatform.isDarwin || (stdenv.hostPlatform.is64bit && stdenv.hostPlatform.isLinux), 89 90 # enable asserts to ensure the build remains reproducible 91 reproducibleBuild ? false, 92 93 # for the Python package set 94 packageOverrides ? (self: super: { }), 95 96 # tests 97 testers, 98 99 # allow pythonMinimal to prevent accidental dependencies it doesn't want 100 allowedReferenceNames ? [ ], 101 102}@inputs: 103 104# Note: this package is used for bootstrapping fetchurl, and thus 105# cannot use fetchpatch! All mutable patches (generated by GitHub or 106# cgit) that are needed here should be included directly in Nixpkgs as 107# files. 108 109assert x11Support -> tcl != null && tk != null && xorgproto != null && libX11 != null; 110 111assert bluezSupport -> bluez != null; 112 113assert lib.assertMsg ( 114 enableFramework -> stdenv.hostPlatform.isDarwin 115) "Framework builds are only supported on Darwin."; 116 117assert lib.assertMsg ( 118 reproducibleBuild -> stripBytecode 119) "Deterministic builds require stripping bytecode."; 120 121assert lib.assertMsg ( 122 reproducibleBuild -> (!enableOptimizations) 123) "Deterministic builds are not achieved when optimizations are enabled."; 124 125assert lib.assertMsg ( 126 reproducibleBuild -> (!rebuildBytecode) 127) "Deterministic builds are not achieved when (default unoptimized) bytecode is created."; 128 129let 130 inherit (lib) 131 concatMapStringsSep 132 concatStringsSep 133 enableFeature 134 getDev 135 getLib 136 optionals 137 optionalString 138 replaceStrings 139 versionOlder 140 ; 141 142 # mixes libc and libxcrypt headers and libs and causes segfaults on importing crypt 143 libxcrypt = if stdenv.hostPlatform.isFreeBSD then null else inputs.libxcrypt; 144 145 buildPackages = pkgsBuildHost; 146 inherit (passthru) pythonOnBuildForHost; 147 148 tzdataSupport = tzdata != null && passthru.pythonAtLeast "3.9"; 149 150 passthru = 151 let 152 # When we override the interpreter we also need to override the spliced versions of the interpreter 153 # bluez is excluded manually to break an infinite recursion. 154 inputs' = lib.filterAttrs (n: v: n != "bluez" && n != "passthruFun" && !lib.isDerivation v) inputs; 155 # Memoization of the splices to avoid re-evaluating this function for all combinations of splices e.g. 156 # python3.pythonOnBuildForHost.pythonOnBuildForTarget == python3.pythonOnBuildForTarget by consuming 157 # __splices as an arg and using the cache if populated. 158 splices = { 159 pythonOnBuildForBuild = override pkgsBuildBuild.${pythonAttr}; 160 pythonOnBuildForHost = override pkgsBuildHost.${pythonAttr}; 161 pythonOnBuildForTarget = override pkgsBuildTarget.${pythonAttr}; 162 pythonOnHostForHost = override pkgsHostHost.${pythonAttr}; 163 pythonOnTargetForTarget = lib.optionalAttrs (lib.hasAttr pythonAttr pkgsTargetTarget) ( 164 override pkgsTargetTarget.${pythonAttr} 165 ); 166 } 167 // __splices; 168 override = 169 attr: 170 let 171 python = attr.override ( 172 inputs' 173 // { 174 self = python; 175 __splices = splices; 176 } 177 ); 178 in 179 python; 180 in 181 passthruFun rec { 182 inherit self sourceVersion packageOverrides; 183 implementation = "cpython"; 184 libPrefix = "python${pythonVersion}${lib.optionalString (!enableGIL) "t"}"; 185 executable = libPrefix; 186 pythonVersion = with sourceVersion; "${major}.${minor}"; 187 sitePackages = "lib/${libPrefix}/site-packages"; 188 inherit hasDistutilsCxxPatch pythonAttr; 189 inherit (splices) 190 pythonOnBuildForBuild 191 pythonOnBuildForHost 192 pythonOnBuildForTarget 193 pythonOnHostForHost 194 pythonOnTargetForTarget 195 ; 196 }; 197 198 version = with sourceVersion; "${major}.${minor}.${patch}${suffix}"; 199 200 nativeBuildInputs = [ 201 nukeReferences 202 ] 203 ++ optionals (!stdenv.hostPlatform.isDarwin) [ 204 autoconf-archive # needed for AX_CHECK_COMPILE_FLAG 205 autoreconfHook 206 ] 207 ++ optionals (!stdenv.hostPlatform.isDarwin || passthru.pythonAtLeast "3.14") [ 208 pkg-config 209 ] 210 ++ optionals (stdenv.hostPlatform != stdenv.buildPlatform) [ 211 buildPackages.stdenv.cc 212 pythonOnBuildForHost 213 ] 214 ++ 215 optionals 216 ( 217 stdenv.cc.isClang 218 && (!stdenv.hostPlatform.useAndroidPrebuilt or false) 219 && (enableLTO || enableOptimizations) 220 ) 221 [ 222 stdenv.cc.cc.libllvm.out 223 ]; 224 225 buildInputs = lib.filter (p: p != null) ( 226 [ 227 bzip2 228 libffi 229 libuuid 230 libxcrypt 231 ncurses 232 openssl 233 sqlite 234 xz 235 zlib 236 ] 237 ++ optionals (passthru.pythonAtLeast "3.14") [ 238 zstd 239 ] 240 ++ optionals withMpdecimal [ 241 mpdecimal 242 ] 243 ++ optionals withExpat [ 244 expat 245 ] 246 ++ optionals bluezSupport [ 247 bluez 248 ] 249 ++ optionals stdenv.hostPlatform.isMinGW [ 250 windows.dlfcn 251 windows.pthreads 252 ] 253 ++ optionals tzdataSupport [ 254 tzdata 255 ] 256 ++ optionals withGdbm [ 257 gdbm 258 ] 259 ++ optionals withReadline [ 260 readline 261 ] 262 ++ optionals x11Support [ 263 libX11 264 tcl 265 tk 266 xorgproto 267 ] 268 ); 269 270 hasDistutilsCxxPatch = !(stdenv.cc.isGNU or false); 271 272 pythonOnBuildForHostInterpreter = 273 if stdenv.hostPlatform == stdenv.buildPlatform then 274 "$out/bin/python" 275 else 276 pythonOnBuildForHost.interpreter; 277 278 src = fetchurl { 279 url = 280 with sourceVersion; 281 "https://www.python.org/ftp/python/${major}.${minor}.${patch}/Python-${version}.tar.xz"; 282 inherit hash; 283 }; 284 285 # win32 is added by Fedora’s patch 286 machdep = if stdenv.hostPlatform.isWindows then "win32" else stdenv.hostPlatform.parsed.kernel.name; 287 288 # https://github.com/python/cpython/blob/e488e300f5c01289c10906c2e53a8e43d6de32d8/configure.ac#L428 289 # The configure script uses "arm" as the CPU name for all 32-bit ARM 290 # variants when cross-compiling, but native builds include the version 291 # suffix, so we do the same. 292 pythonHostPlatform = 293 let 294 cpu = 295 { 296 # According to PEP600, Python's name for the Power PC 297 # architecture is "ppc", not "powerpc". Without the Rosetta 298 # Stone below, the PEP600 requirement that "${ARCH} matches 299 # the return value from distutils.util.get_platform()" fails. 300 # https://peps.python.org/pep-0600/ 301 powerpc = "ppc"; 302 powerpcle = "ppcle"; 303 powerpc64 = "ppc64"; 304 powerpc64le = "ppc64le"; 305 } 306 .${stdenv.hostPlatform.parsed.cpu.name} or stdenv.hostPlatform.parsed.cpu.name; 307 in 308 "${machdep}-${cpu}"; 309 310 execSuffix = stdenv.hostPlatform.extensions.executable; 311in 312with passthru; 313stdenv.mkDerivation (finalAttrs: { 314 pname = "python3"; 315 inherit src version; 316 317 inherit nativeBuildInputs; 318 buildInputs = 319 lib.optionals (!stdenv.hostPlatform.isWindows) [ 320 bashNonInteractive # only required for patchShebangs 321 ] 322 ++ buildInputs; 323 324 prePatch = optionalString stdenv.hostPlatform.isDarwin '' 325 substituteInPlace configure --replace-fail '`/usr/bin/arch`' '"i386"' 326 ''; 327 328 patches = [ 329 # Disable the use of ldconfig in ctypes.util.find_library (since 330 # ldconfig doesn't work on NixOS), and don't use 331 # ctypes.util.find_library during the loading of the uuid module 332 # (since it will do a futile invocation of gcc (!) to find 333 # libuuid, slowing down program startup a lot). 334 noldconfigPatch 335 ] 336 ++ optionals (stdenv.hostPlatform != stdenv.buildPlatform && stdenv.hostPlatform.isFreeBSD) [ 337 # Cross compilation only supports a limited number of "known good" 338 # configurations. If you're reading this and it's been a long time 339 # since this diff, consider submitting this patch upstream! 340 ./freebsd-cross.patch 341 ] 342 ++ optionals (pythonOlder "3.13") [ 343 # Make sure that the virtualenv activation scripts are 344 # owner-writable, so venvs can be recreated without permission 345 # errors. 346 ./virtualenv-permissions.patch 347 ] 348 ++ optionals (pythonAtLeast "3.13") [ 349 ./3.13/virtualenv-permissions.patch 350 ] 351 ++ optionals mimetypesSupport [ 352 # Make the mimetypes module refer to the right file 353 ./mimetypes.patch 354 ] 355 ++ optionals (pythonAtLeast "3.9" && pythonOlder "3.11" && stdenv.hostPlatform.isDarwin) [ 356 # Stop checking for TCL/TK in global macOS locations 357 ./3.9/darwin-tcl-tk.patch 358 ] 359 ++ optionals (hasDistutilsCxxPatch && pythonOlder "3.12") [ 360 # Fix for http://bugs.python.org/issue1222585 361 # Upstream distutils is calling C compiler to compile C++ code, which 362 # only works for GCC and Apple Clang. This makes distutils to call C++ 363 # compiler when needed. 364 ( 365 if pythonAtLeast "3.7" && pythonOlder "3.11" then 366 ./3.7/python-3.x-distutils-C++.patch 367 else if pythonAtLeast "3.11" then 368 ./3.11/python-3.x-distutils-C++.patch 369 else 370 fetchpatch { 371 url = "https://bugs.python.org/file48016/python-3.x-distutils-C++.patch"; 372 sha256 = "1h18lnpx539h5lfxyk379dxwr8m2raigcjixkf133l4xy3f4bzi2"; 373 } 374 ) 375 ] 376 ++ optionals (pythonAtLeast "3.7" && pythonOlder "3.12") [ 377 # LDSHARED now uses $CC instead of gcc. Fixes cross-compilation of extension modules. 378 ./3.8/0001-On-all-posix-systems-not-just-Darwin-set-LDSHARED-if.patch 379 # Use sysconfigdata to find headers. Fixes cross-compilation of extension modules. 380 ./3.7/fix-finding-headers-when-cross-compiling.patch 381 ] 382 ++ optionals (pythonOlder "3.12") [ 383 # https://github.com/python/cpython/issues/90656 384 ./loongarch-support.patch 385 # fix failing tests with openssl >= 3.4 386 # https://github.com/python/cpython/pull/127361 387 ] 388 ++ optionals (pythonAtLeast "3.11" && pythonOlder "3.13") [ 389 # backport fix for https://github.com/python/cpython/issues/95855 390 ./platform-triplet-detection.patch 391 ] 392 ++ optionals (stdenv.hostPlatform.isMinGW) ( 393 let 394 # https://src.fedoraproject.org/rpms/mingw-python3 395 mingw-patch = fetchgit { 396 name = "mingw-python-patches"; 397 url = "https://src.fedoraproject.org/rpms/mingw-python3.git"; 398 rev = "3edecdbfb4bbf1276d09cd5e80e9fb3dd88c9511"; # for python 3.11.9 at the time of writing. 399 hash = "sha256-kpXoIHlz53+0FAm/fK99ZBdNUg0u13erOr1XP2FSkQY="; 400 }; 401 in 402 (builtins.map (f: "${mingw-patch}/${f}") [ 403 # The other patches in that repo are already applied to 3.11.10 404 "mingw-python3_distutils.patch" 405 "mingw-python3_frozenmain.patch" 406 "mingw-python3_make-sysconfigdata.py-relocatable.patch" 407 "mingw-python3_mods-failed.patch" 408 "mingw-python3_module-select.patch" 409 "mingw-python3_module-socket.patch" 410 "mingw-python3_modules.patch" 411 "mingw-python3_platform-mingw.patch" 412 "mingw-python3_posix-layout.patch" 413 "mingw-python3_pthread_threadid.patch" 414 "mingw-python3_pythonw.patch" 415 "mingw-python3_setenv.patch" 416 "mingw-python3_win-modules.patch" 417 ]) 418 ); 419 420 postPatch = 421 optionalString (!stdenv.hostPlatform.isWindows) '' 422 substituteInPlace Lib/subprocess.py \ 423 --replace-fail "'/bin/sh'" "'${bashNonInteractive}/bin/sh'" 424 '' 425 + optionalString mimetypesSupport '' 426 substituteInPlace Lib/mimetypes.py \ 427 --replace-fail "@mime-types@" "${mailcap}" 428 '' 429 + optionalString (pythonOlder "3.13" && x11Support && ((tclPackages.tix or null) != null)) '' 430 substituteInPlace "Lib/tkinter/tix.py" --replace-fail \ 431 "os.environ.get('TIX_LIBRARY')" \ 432 "os.environ.get('TIX_LIBRARY') or '${tclPackages.tix}/lib'" 433 ''; 434 435 env = { 436 CPPFLAGS = concatStringsSep " " (map (p: "-I${getDev p}/include") buildInputs); 437 LDFLAGS = concatStringsSep " " (map (p: "-L${getLib p}/lib") buildInputs); 438 LIBS = "${optionalString (!stdenv.hostPlatform.isDarwin && libxcrypt != null) "-lcrypt"}"; 439 NIX_LDFLAGS = lib.optionalString (stdenv.cc.isGNU && !stdenv.hostPlatform.isStatic) ( 440 { 441 "glibc" = "-lgcc_s"; 442 "musl" = "-lgcc_eh"; 443 } 444 ."${stdenv.hostPlatform.libc}" or "" 445 ); 446 # Determinism: We fix the hashes of str, bytes and datetime objects. 447 PYTHONHASHSEED = 0; 448 }; 449 450 # https://docs.python.org/3/using/configure.html 451 configureFlags = [ 452 "--without-ensurepip" 453 ] 454 ++ optionals withExpat [ 455 "--with-system-expat" 456 ] 457 ++ optionals withMpdecimal [ 458 "--with-system-libmpdec" 459 ] 460 ++ optionals (openssl != null) [ 461 "--with-openssl=${openssl.dev}" 462 ] 463 ++ optionals tzdataSupport [ 464 "--with-tzpath=${tzdata}/share/zoneinfo" 465 ] 466 ++ optionals (execSuffix != "") [ 467 "--with-suffix=${execSuffix}" 468 ] 469 ++ optionals enableLTO [ 470 "--with-lto" 471 ] 472 ++ optionals (!static && !enableFramework) [ 473 "--enable-shared" 474 ] 475 ++ optionals enableFramework [ 476 "--enable-framework=${placeholder "out"}/Library/Frameworks" 477 ] 478 ++ optionals (pythonAtLeast "3.13") [ 479 (enableFeature enableGIL "gil") 480 ] 481 ++ optionals enableOptimizations [ 482 "--enable-optimizations" 483 ] 484 ++ optionals enableDebug [ 485 "--with-pydebug" 486 ] 487 ++ optionals (sqlite != null) [ 488 "--enable-loadable-sqlite-extensions" 489 ] 490 ++ optionals (libxcrypt != null) [ 491 "CFLAGS=-I${libxcrypt}/include" 492 "LIBS=-L${libxcrypt}/lib" 493 ] 494 ++ optionals (stdenv.hostPlatform != stdenv.buildPlatform) [ 495 "ac_cv_buggy_getaddrinfo=no" 496 # Assume little-endian IEEE 754 floating point when cross compiling 497 "ac_cv_little_endian_double=yes" 498 "ac_cv_big_endian_double=no" 499 "ac_cv_mixed_endian_double=no" 500 "ac_cv_x87_double_rounding=yes" 501 "ac_cv_tanh_preserves_zero_sign=yes" 502 # Generally assume that things are present and work 503 "ac_cv_posix_semaphores_enabled=yes" 504 "ac_cv_broken_sem_getvalue=no" 505 "ac_cv_wchar_t_signed=yes" 506 "ac_cv_rshift_extends_sign=yes" 507 "ac_cv_broken_nice=no" 508 "ac_cv_broken_poll=no" 509 "ac_cv_working_tzset=yes" 510 "ac_cv_have_long_long_format=yes" 511 "ac_cv_have_size_t_format=yes" 512 "ac_cv_computed_gotos=yes" 513 # Both fail when building for windows, normally configure checks this by itself but on other platforms this is set to yes always. 514 "ac_cv_file__dev_ptmx=${if stdenv.hostPlatform.isWindows then "no" else "yes"}" 515 "ac_cv_file__dev_ptc=${if stdenv.hostPlatform.isWindows then "no" else "yes"}" 516 ] 517 ++ optionals (stdenv.hostPlatform != stdenv.buildPlatform && pythonAtLeast "3.11") [ 518 "--with-build-python=${pythonOnBuildForHostInterpreter}" 519 ] 520 ++ optionals stdenv.hostPlatform.isLinux [ 521 # Never even try to use lchmod on linux, 522 # don't rely on detecting glibc-isms. 523 "ac_cv_func_lchmod=no" 524 ] 525 ++ optionals static [ 526 "--disable-test-modules" 527 "LDFLAGS=-static" 528 "MODULE_BUILDTYPE=static" 529 ] 530 ++ optionals (stdenv.hostPlatform.isStatic && stdenv.hostPlatform.isMusl) [ 531 # dlopen is a no-op in static musl builds, and since we build everything without -fPIC it's better not to pretend. 532 "ac_cv_func_dlopen=no" 533 ]; 534 535 preConfigure = '' 536 # Attempt to purify some of the host info collection 537 sed -E -i -e 's/uname -r/echo/g' -e 's/uname -n/echo nixpkgs/g' config.guess 538 sed -E -i -e 's/uname -r/echo/g' -e 's/uname -n/echo nixpkgs/g' configure 539 '' 540 + optionalString (pythonOlder "3.12") '' 541 # Improve purity 542 for path in /usr /sw /opt /pkg; do 543 substituteInPlace ./setup.py --replace-warn $path /no-such-path 544 done 545 '' 546 + optionalString (stdenv.hostPlatform.isDarwin && pythonOlder "3.12") '' 547 # Fix _ctypes module compilation 548 export NIX_CFLAGS_COMPILE+=" -DUSING_APPLE_OS_LIBFFI=1" 549 '' 550 + optionalString stdenv.hostPlatform.isDarwin '' 551 # Override the auto-detection in setup.py, which assumes a universal build 552 export PYTHON_DECIMAL_WITH_MACHINE=${if stdenv.hostPlatform.isAarch64 then "uint128" else "x64"} 553 # Ensure that modern platform features are enabled on Darwin in spite of having no version suffix. 554 sed -E -i -e 's|Darwin/\[12\]\[0-9\]\.\*|Darwin/*|' configure 555 '' 556 + optionalString (pythonAtLeast "3.11") '' 557 # Also override the auto-detection in `configure`. 558 substituteInPlace configure \ 559 --replace-fail 'libmpdec_machine=universal' 'libmpdec_machine=${ 560 if stdenv.hostPlatform.isAarch64 then "uint128" else "x64" 561 }' 562 '' 563 + optionalString (stdenv.hostPlatform.isDarwin && x11Support && pythonAtLeast "3.11") '' 564 export TCLTK_LIBS="-L${tcl}/lib -L${tk}/lib -l${tcl.libPrefix} -l${tk.libPrefix}" 565 export TCLTK_CFLAGS="-I${tcl}/include -I${tk}/include" 566 '' 567 + optionalString stdenv.hostPlatform.isWindows '' 568 export NIX_CFLAGS_COMPILE+=" -Wno-error=incompatible-pointer-types" 569 '' 570 + optionalString stdenv.hostPlatform.isMusl '' 571 export NIX_CFLAGS_COMPILE+=" -DTHREAD_STACK_SIZE=0x100000" 572 '' 573 + 574 575 # enableNoSemanticInterposition essentially sets that CFLAG -fno-semantic-interposition 576 # which changes how symbols are looked up. This essentially means we can't override 577 # libpython symbols via LD_PRELOAD anymore. This is common enough as every build 578 # that uses --enable-optimizations has the same "issue". 579 # 580 # The Fedora wiki has a good article about their journey towards enabling this flag: 581 # https://fedoraproject.org/wiki/Changes/PythonNoSemanticInterpositionSpeedup 582 optionalString enableNoSemanticInterposition '' 583 export CFLAGS_NODIST="-fno-semantic-interposition" 584 ''; 585 586 setupHook = python-setup-hook sitePackages; 587 588 postInstall = 589 let 590 # References *not* to nuke from (sys)config files 591 keep-references = concatMapStringsSep " " (val: "-e ${val}") ( 592 [ 593 (placeholder "out") 594 ] 595 ++ lib.optional (libxcrypt != null) libxcrypt 596 ++ lib.optional tzdataSupport tzdata 597 ); 598 in 599 lib.optionalString enableFramework '' 600 for dir in include lib share; do 601 ln -s $out/Library/Frameworks/Python.framework/Versions/Current/$dir $out/$dir 602 done 603 '' 604 + '' 605 # needed for some packages, especially packages that backport functionality 606 # to 2.x from 3.x 607 for item in $out/lib/${libPrefix}/test/*; do 608 if [[ "$item" != */test_support.py* 609 && "$item" != */test/support 610 && "$item" != */test/libregrtest 611 && "$item" != */test/regrtest.py* ]]; then 612 rm -rf "$item" 613 else 614 echo $item 615 fi 616 done 617 '' 618 + lib.optionalString (!static) '' 619 touch $out/lib/${libPrefix}/test/__init__.py 620 '' 621 + '' 622 623 # Determinism: Windows installers were not deterministic. 624 # We're also not interested in building Windows installers. 625 find "$out" -name 'wininst*.exe' | xargs -r rm -f 626 627 # Use Python3 as default python 628 ln -s "$out/bin/idle3" "$out/bin/idle" 629 ln -s "$out/bin/pydoc3" "$out/bin/pydoc" 630 ln -s "$out/bin/python3${execSuffix}" "$out/bin/python${execSuffix}" 631 ln -s "$out/bin/python3-config" "$out/bin/python-config" 632 ln -s "$out/lib/pkgconfig/python3.pc" "$out/lib/pkgconfig/python.pc" 633 ln -sL "$out/share/man/man1/python3.1.gz" "$out/share/man/man1/python.1.gz" 634 635 # Get rid of retained dependencies on -dev packages, and remove 636 # some $TMPDIR references to improve binary reproducibility. 637 # Note that the .pyc file of _sysconfigdata.py should be regenerated! 638 for i in $out/lib/${libPrefix}/_sysconfigdata*.py $out/lib/${libPrefix}/config-${sourceVersion.major}${sourceVersion.minor}*/Makefile; do 639 sed -i $i -e "s|$TMPDIR|/no-such-path|g" 640 done 641 642 # Further get rid of references. https://github.com/NixOS/nixpkgs/issues/51668 643 find $out/lib/python*/config-* -type f -print -exec nuke-refs ${keep-references} '{}' + 644 find $out/lib -name '_sysconfigdata*.py*' -print -exec nuke-refs ${keep-references} '{}' + 645 646 # Make the sysconfigdata module accessible on PYTHONPATH 647 # This allows build Python to import host Python's sysconfigdata 648 mkdir -p "$out/${sitePackages}" 649 ln -s "$out/lib/${libPrefix}/"_sysconfigdata*.py "$out/${sitePackages}/" 650 '' 651 + optionalString (pythonAtLeast "3.14") '' 652 # Get rid of retained dependencies on -dev packages, and remove from _sysconfig_vars*.json introduced with Python3.14 653 for i in $out/lib/${libPrefix}/_sysconfig_vars*.json; do 654 sed -i $i -e "s|$TMPDIR|/no-such-path|g" 655 done 656 find $out/lib -name '_sysconfig_vars*.json*' -print -exec nuke-refs ${keep-references} '{}' + 657 ln -s "$out/lib/${libPrefix}/"_sysconfig_vars*.json "$out/${sitePackages}/" 658 '' 659 + optionalString stripConfig '' 660 rm -R $out/bin/python*-config $out/lib/python*/config-* 661 '' 662 + optionalString stripIdlelib '' 663 # Strip IDLE (and turtledemo, which uses it) 664 rm -R $out/bin/idle* $out/lib/python*/{idlelib,turtledemo} 665 '' 666 + optionalString stripTkinter '' 667 rm -R $out/lib/python*/tkinter 668 '' 669 + optionalString stripTests '' 670 # Strip tests 671 rm -R $out/lib/python*/test $out/lib/python*/**/test{,s} 672 '' 673 + optionalString includeSiteCustomize '' 674 # Include a sitecustomize.py file 675 cp ${../sitecustomize.py} $out/${sitePackages}/sitecustomize.py 676 '' 677 + optionalString stripBytecode '' 678 # Determinism: deterministic bytecode 679 # First we delete all old bytecode. 680 find $out -type d -name __pycache__ -print0 | xargs -0 -I {} rm -rf "{}" 681 '' 682 + optionalString rebuildBytecode '' 683 # Python 3.7 implements PEP 552, introducing support for deterministic bytecode. 684 # compileall uses the therein introduced checked-hash method by default when 685 # `SOURCE_DATE_EPOCH` is set. 686 # We exclude lib2to3 because that's Python 2 code which fails 687 # We build 3 levels of optimized bytecode. Note the default level, without optimizations, 688 # is not reproducible yet. https://bugs.python.org/issue29708 689 # Not creating bytecode will result in a large performance loss however, so we do build it. 690 find $out -name "*.py" | ${pythonOnBuildForHostInterpreter} -m compileall -q -f -x "lib2to3" -i - 691 find $out -name "*.py" | ${pythonOnBuildForHostInterpreter} -O -m compileall -q -f -x "lib2to3" -i - 692 find $out -name "*.py" | ${pythonOnBuildForHostInterpreter} -OO -m compileall -q -f -x "lib2to3" -i - 693 '' 694 + '' 695 # *strip* shebang from libpython gdb script - it should be dual-syntax and 696 # interpretable by whatever python the gdb in question is using, which may 697 # not even match the major version of this python. doing this after the 698 # bytecode compilations for the same reason - we don't want bytecode generated. 699 mkdir -p $out/share/gdb 700 sed '/^#!/d' Tools/gdb/libpython.py > $out/share/gdb/libpython.py 701 702 # Disable system-wide pip installation. See https://peps.python.org/pep-0668/. 703 cat <<'EXTERNALLY_MANAGED' > $out/lib/${libPrefix}/EXTERNALLY-MANAGED 704 [externally-managed] 705 Error=This command has been disabled as it tries to modify the immutable 706 `/nix/store` filesystem. 707 708 To use Python with Nix and nixpkgs, have a look at the online documentation: 709 <https://nixos.org/manual/nixpkgs/stable/#python>. 710 EXTERNALLY_MANAGED 711 '' 712 + optionalString stdenv.hostPlatform.isWindows '' 713 # Shebang files that link against the build python. Shebang dont work on windows 714 rm $out/bin/2to3* 715 rm $out/bin/idle* 716 rm $out/bin/pydoc* 717 718 echo linking DLLs for pythons compiled librairies 719 linkDLLsInfolder $out/lib/python*/lib-dynload/ 720 ''; 721 722 preFixup = lib.optionalString (stdenv.hostPlatform != stdenv.buildPlatform) '' 723 # Ensure patch-shebangs uses shebangs of host interpreter. 724 export PATH=${lib.makeBinPath [ "$out" ]}:$PATH 725 ''; 726 727 # Add CPython specific setup-hook that configures distutils.sysconfig to 728 # always load sysconfigdata from host Python. 729 postFixup = lib.optionalString (!stdenv.hostPlatform.isDarwin) '' 730 # https://github.com/python/cpython/blob/e488e300f5c01289c10906c2e53a8e43d6de32d8/configure.ac#L78 731 sysconfigdataName="$(make --eval $'print-sysconfigdata-name: 732 \t@echo _sysconfigdata_$(ABIFLAGS)_$(MACHDEP)_$(MULTIARCH) ' print-sysconfigdata-name)" 733 734 # The CPython interpreter contains a _sysconfigdata_<platform specific suffix> 735 # module that is imported by the sysconfig and distutils.sysconfig modules. 736 # The sysconfigdata module is generated at build time and contains settings 737 # required for building Python extension modules, such as include paths and 738 # other compiler flags. By default, the sysconfigdata module is loaded from 739 # the currently running interpreter (ie. the build platform interpreter), but 740 # when cross-compiling we want to load it from the host platform interpreter. 741 # This can be done using the _PYTHON_SYSCONFIGDATA_NAME environment variable. 742 # The _PYTHON_HOST_PLATFORM variable also needs to be set to get the correct 743 # platform suffix on extension modules. The correct values for these variables 744 # are not documented, and must be derived from the configure script (see links 745 # below). 746 cat <<EOF >> "$out/nix-support/setup-hook" 747 sysconfigdataHook() { 748 if [ "\$1" = '$out' ]; then 749 export _PYTHON_HOST_PLATFORM='${pythonHostPlatform}' 750 export _PYTHON_SYSCONFIGDATA_NAME='$sysconfigdataName' 751 fi 752 } 753 754 addEnvHooks "\$hostOffset" sysconfigdataHook 755 EOF 756 ''; 757 758 # Enforce that we don't have references to the OpenSSL -dev package, which we 759 # explicitly specify in our configure flags above. 760 disallowedReferences = 761 lib.optionals (openssl != null && !static && !enableFramework) [ 762 openssl.dev 763 ] 764 ++ lib.optionals (stdenv.hostPlatform != stdenv.buildPlatform) [ 765 # Ensure we don't have references to build-time packages. 766 # These typically end up in shebangs. 767 pythonOnBuildForHost 768 buildPackages.bashNonInteractive 769 ]; 770 771 # Optionally set allowedReferences to guarantee minimal dependencies 772 # Allows python3Minimal to stay minimal and not have deps added by accident 773 # Doesn't do anything if allowedReferenceNames is empty (was not set) 774 ${if allowedReferenceNames != [ ] then "allowedReferences" else null} = 775 # map allowed names to their derivations 776 (map (name: inputs.${name}) allowedReferenceNames) ++ [ 777 # any version of python depends on libc and libgcc 778 stdenv.cc.cc.lib 779 stdenv.cc.libc 780 # allows python referring to its own store path 781 "out" 782 ]; 783 784 separateDebugInfo = true; 785 __structuredAttrs = true; 786 787 passthru = passthru // { 788 doc = stdenv.mkDerivation { 789 inherit src; 790 name = "python${pythonVersion}-${version}-doc"; 791 792 postPatch = lib.optionalString (pythonAtLeast "3.9" && pythonOlder "3.11") '' 793 substituteInPlace Doc/tools/extensions/pyspecific.py \ 794 --replace-fail "from sphinx.util import status_iterator" "from sphinx.util.display import status_iterator" 795 ''; 796 797 dontConfigure = true; 798 799 dontBuild = true; 800 801 sphinxRoot = "Doc"; 802 803 postInstallSphinx = '' 804 mv $out/share/doc/* $out/share/doc/python${pythonVersion}-${version} 805 ''; 806 807 nativeBuildInputs = with pkgsBuildBuild.python3.pkgs; [ 808 sphinxHook 809 python-docs-theme 810 ]; 811 }; 812 813 tests = passthru.tests // { 814 pkg-config = testers.testMetaPkgConfig finalAttrs.finalPackage; 815 }; 816 }; 817 818 enableParallelBuilding = true; 819 820 meta = with lib; { 821 homepage = "https://www.python.org"; 822 changelog = 823 let 824 majorMinor = versions.majorMinor version; 825 dashedVersion = replaceStrings [ "." "a" "b" ] [ "-" "-alpha-" "-beta-" ] version; 826 in 827 if sourceVersion.suffix == "" then 828 "https://docs.python.org/release/${version}/whatsnew/changelog.html" 829 else 830 "https://docs.python.org/${majorMinor}/whatsnew/changelog.html#python-${dashedVersion}"; 831 description = "High-level dynamically-typed programming language"; 832 longDescription = '' 833 Python is a remarkably powerful dynamic programming language that 834 is used in a wide variety of application domains. Some of its key 835 distinguishing features include: clear, readable syntax; strong 836 introspection capabilities; intuitive object orientation; natural 837 expression of procedural code; full modularity, supporting 838 hierarchical packages; exception-based error handling; and very 839 high level dynamic data types. 840 ''; 841 license = licenses.psfl; 842 pkgConfigModules = [ "python3" ]; 843 platforms = platforms.linux ++ platforms.darwin ++ platforms.windows ++ platforms.freebsd; 844 mainProgram = executable; 845 teams = [ lib.teams.python ]; 846 # static build on x86_64-darwin/aarch64-darwin breaks with: 847 # configure: error: C compiler cannot create executables 848 849 # mingw patches only apply to Python 3.11 currently 850 broken = 851 (lib.versions.minor version != "11" && stdenv.hostPlatform.isWindows) 852 || (stdenv.hostPlatform.isStatic && stdenv.hostPlatform.isDarwin); 853 }; 854})