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