diff options
Diffstat (limited to 'nixpkgs/pkgs/development/interpreters/python/cpython/default.nix')
-rw-r--r-- | nixpkgs/pkgs/development/interpreters/python/cpython/default.nix | 244 |
1 files changed, 140 insertions, 104 deletions
diff --git a/nixpkgs/pkgs/development/interpreters/python/cpython/default.nix b/nixpkgs/pkgs/development/interpreters/python/cpython/default.nix index 8e13ed51bc74..1eea842871fc 100644 --- a/nixpkgs/pkgs/development/interpreters/python/cpython/default.nix +++ b/nixpkgs/pkgs/development/interpreters/python/cpython/default.nix @@ -1,40 +1,55 @@ -{ lib, stdenv, fetchurl, fetchpatch, fetchgit +{ lib +, stdenv +, fetchurl +, fetchpatch +, fetchgit + +# build dependencies +, autoconf-archive +, autoreconfHook +, nukeReferences +, pkg-config +, python-setup-hook + +# runtime dependencies , bzip2 , expat , libffi -, gdbm -, xz -, mailcap, mimetypesSupport ? true +, libxcrypt +, mpdecimal , ncurses , openssl -, openssl_legacy -, readline , sqlite -, tcl ? null, tk ? null, tix ? null, libX11 ? null, xorgproto ? null, x11Support ? false -, bluez ? null, bluezSupport ? false +, xz , zlib -, tzdata ? null -, libxcrypt -, self + +# platform-specific dependencies +, bash , configd , darwin , windows -, autoreconfHook -, autoconf-archive -, pkg-config -, python-setup-hook -, nukeReferences -# For the Python package set -, packageOverrides ? (self: super: {}) + +# optional dependencies +, bluezSupport ? false, bluez +, mimetypesSupport ? true, mailcap +, tzdata +, withGdbm ? !stdenv.hostPlatform.isWindows, gdbm +, withReadline ? !stdenv.hostPlatform.isWindows, readline +, x11Support ? false, tcl, tk, tix, libX11, xorgproto + +# splicing/cross +, pythonAttr ? "python${sourceVersion.major}${sourceVersion.minor}" +, self , pkgsBuildBuild , pkgsBuildHost , pkgsBuildTarget , pkgsHostHost , pkgsTargetTarget + +# build customization , sourceVersion , hash , passthruFun -, bash , stripConfig ? false , stripIdlelib ? false , stripTests ? false @@ -44,21 +59,28 @@ , includeSiteCustomize ? true , static ? stdenv.hostPlatform.isStatic , enableFramework ? false +, noldconfigPatch ? ./. + "/${sourceVersion.major}.${sourceVersion.minor}/no-ldconfig.patch" + +# pgo (not reproducible) + -fno-semantic-interposition +# https://docs.python.org/3/using/configure.html#cmdoption-enable-optimizations , enableOptimizations ? false -# these dont build for windows -, withGdbm ? !stdenv.hostPlatform.isWindows -, withReadline ? !stdenv.hostPlatform.isWindows -# enableNoSemanticInterposition is a subset of the enableOptimizations flag that doesn't harm reproducibility. -# clang starts supporting `-fno-sematic-interposition` with version 10 -, enableNoSemanticInterposition ? (!stdenv.cc.isClang || (stdenv.cc.isClang && lib.versionAtLeast stdenv.cc.version "10")) -# enableLTO is a subset of the enableOptimizations flag that doesn't harm reproducibility. + +# improves performance, but remains reproducible +, enableNoSemanticInterposition ? true + # enabling LTO on 32bit arch causes downstream packages to fail when linking # enabling LTO on *-darwin causes python3 to fail when linking. , enableLTO ? stdenv.is64bit && stdenv.isLinux + +# enable asserts to ensure the build remains reproducible , reproducibleBuild ? false -, pythonAttr ? "python${sourceVersion.major}${sourceVersion.minor}" -, noldconfigPatch ? ./. + "/${sourceVersion.major}.${sourceVersion.minor}/no-ldconfig.patch" + +# for the Python package set +, packageOverrides ? (self: super: {}) + +# tests , testers + } @ inputs: # Note: this package is used for bootstrapping fetchurl, and thus @@ -73,7 +95,11 @@ assert x11Support -> tcl != null assert bluezSupport -> bluez != null; -assert enableFramework -> stdenv.isDarwin; +assert lib.assertMsg (bluezSupport -> stdenv.isLinux) + "Bluez support is only available on Linux."; + +assert lib.assertMsg (enableFramework -> stdenv.isDarwin) + "Framework builds are only supported on Darwin."; assert lib.assertMsg (reproducibleBuild -> stripBytecode) "Deterministic builds require stripping bytecode."; @@ -84,18 +110,21 @@ assert lib.assertMsg (reproducibleBuild -> (!enableOptimizations)) assert lib.assertMsg (reproducibleBuild -> (!rebuildBytecode)) "Deterministic builds are not achieved when (default unoptimized) bytecode is created."; -with lib; - let - # some python packages need legacy ciphers, so we're using openssl 3, but with that config - # null check for Minimal - openssl' = if openssl != null then openssl_legacy else null; + inherit (lib) + concatMapStringsSep + concatStringsSep + getDev + getLib + optionals + optionalString + replaceStrings + versionOlder + ; buildPackages = pkgsBuildHost; inherit (passthru) pythonOnBuildForHost; - inherit (darwin.apple_sdk.frameworks) Cocoa; - tzdataSupport = tzdata != null && passthru.pythonAtLeast "3.9"; passthru = let @@ -119,12 +148,12 @@ let version = with sourceVersion; "${major}.${minor}.${patch}${suffix}"; - nativeBuildInputs = optionals (!stdenv.isDarwin) [ + nativeBuildInputs = [ + nukeReferences + ] ++ optionals (!stdenv.isDarwin) [ + autoconf-archive # needed for AX_CHECK_COMPILE_FLAG autoreconfHook pkg-config - autoconf-archive # needed for AX_CHECK_COMPILE_FLAG - ] ++ [ - nukeReferences ] ++ optionals (stdenv.hostPlatform != stdenv.buildPlatform) [ buildPackages.stdenv.cc pythonOnBuildForHost @@ -132,19 +161,38 @@ let stdenv.cc.cc.libllvm.out ]; - buildInputs = filter (p: p != null) ([ - zlib bzip2 expat xz libffi libxcrypt ] - ++ optional withGdbm gdbm - ++ [ sqlite ] - ++ optional withReadline readline - ++ [ ncurses openssl' ] - ++ optionals x11Support [ tcl tk libX11 xorgproto ] - ++ optionals (bluezSupport && stdenv.isLinux) [ bluez ] - ++ optionals stdenv.isDarwin [ configd ]) - - ++ optionals enableFramework [ Cocoa ] - ++ optionals stdenv.hostPlatform.isMinGW [ windows.mingw_w64_pthreads windows.dlfcn ] - ++ optionals tzdataSupport [ tzdata ]; # `zoneinfo` module + buildInputs = lib.filter (p: p != null) ([ + bzip2 + expat + libffi + libxcrypt + mpdecimal + ncurses + openssl + sqlite + xz + zlib + ] ++ optionals bluezSupport [ + bluez + ] ++ optionals enableFramework [ + darwin.apple_sdk.frameworks.Cocoa + ] ++ optionals stdenv.hostPlatform.isMinGW [ + windows.dlfcn + windows.mingw_w64_pthreads + ] ++ optionals stdenv.isDarwin [ + configd + ] ++ optionals tzdataSupport [ + tzdata + ] ++ optionals withGdbm [ + gdbm + ] ++ optionals withReadline [ + readline + ] ++ optionals x11Support [ + libX11 + tcl + tk + xorgproto + ]); hasDistutilsCxxPatch = !(stdenv.cc.isGNU or false); @@ -207,7 +255,7 @@ let pythonAbi = nixpkgsPythonAbiMappings.${parsed.abi.name} or parsed.abi.name; in # Python <3.11 doesn't distinguish musl and glibc and always prefixes with "gnu" - if lib.versionOlder version "3.11" then + if versionOlder version "3.11" then replaceStrings [ "musl" ] [ "gnu" ] pythonAbi else pythonAbi; @@ -238,29 +286,18 @@ in with passthru; stdenv.mkDerivation (finalAttrs: { inherit src version; inherit nativeBuildInputs; - buildInputs = lib.optionals (!stdenv.hostPlatform.isWindows) [ bash ] ++ buildInputs; # bash is only used for patchShebangs - + buildInputs = lib.optionals (!stdenv.hostPlatform.isWindows) [ + bash # only required for patchShebangs + ] ++ buildInputs; prePatch = optionalString stdenv.isDarwin '' - substituteInPlace configure --replace '`/usr/bin/arch`' '"i386"' + substituteInPlace configure --replace-fail '`/usr/bin/arch`' '"i386"' '' + optionalString (pythonOlder "3.9" && stdenv.isDarwin && x11Support) '' # Broken on >= 3.9; replaced with ./3.9/darwin-tcl-tk.patch - substituteInPlace setup.py --replace /Library/Frameworks /no-such-path + substituteInPlace setup.py --replace-fail /Library/Frameworks /no-such-path ''; - patches = optionals (version == "3.10.9") [ - # https://github.com/python/cpython/issues/100160 - ./3.10/asyncio-deprecation.patch - ] ++ optionals (version == "3.11.1") [ - # https://github.com/python/cpython/issues/100160 - (fetchpatch { - name = "asyncio-deprecation-3.11.patch"; - url = "https://github.com/python/cpython/commit/3fae04b10e2655a20a3aadb5e0d63e87206d0c67.diff"; - revert = true; - excludes = [ "Misc/NEWS.d/*" ]; - hash = "sha256-PmkXf2D9trtW1gXZilRIWgdg2Y47JfELq1z4DuG3wJY="; - }) - ] ++ [ + patches = [ # Disable the use of ldconfig in ctypes.util.find_library (since # ldconfig doesn't work on NixOS), and don't use # ctypes.util.find_library during the loading of the uuid module @@ -282,7 +319,7 @@ in with passthru; stdenv.mkDerivation (finalAttrs: { ] ++ optionals (pythonAtLeast "3.9" && pythonOlder "3.11" && stdenv.isDarwin) [ # Stop checking for TCL/TK in global macOS locations ./3.9/darwin-tcl-tk.patch - ] ++ optionals (isPy3k && hasDistutilsCxxPatch && pythonOlder "3.12") [ + ] ++ optionals (hasDistutilsCxxPatch && pythonOlder "3.12") [ # Fix for http://bugs.python.org/issue1222585 # Upstream distutils is calling C compiler to compile C++ code, which # only works for GCC and Apple Clang. This makes distutils to call C++ @@ -323,12 +360,14 @@ in with passthru; stdenv.mkDerivation (finalAttrs: { postPatch = optionalString (!stdenv.hostPlatform.isWindows) '' substituteInPlace Lib/subprocess.py \ - --replace "'/bin/sh'" "'${bash}/bin/sh'" + --replace-fail "'/bin/sh'" "'${bash}/bin/sh'" '' + optionalString mimetypesSupport '' substituteInPlace Lib/mimetypes.py \ - --replace "@mime-types@" "${mailcap}" + --replace-fail "@mime-types@" "${mailcap}" '' + optionalString (pythonOlder "3.13" && x11Support && (tix != null)) '' - substituteInPlace "Lib/tkinter/tix.py" --replace "os.environ.get('TIX_LIBRARY')" "os.environ.get('TIX_LIBRARY') or '${tix}/lib'" + substituteInPlace "Lib/tkinter/tix.py" --replace-fail \ + "os.environ.get('TIX_LIBRARY')" \ + "os.environ.get('TIX_LIBRARY') or '${tix}/lib'" ''; env = { @@ -343,25 +382,30 @@ in with passthru; stdenv.mkDerivation (finalAttrs: { PYTHONHASHSEED=0; }; + # https://docs.python.org/3/using/configure.html configureFlags = [ "--without-ensurepip" "--with-system-expat" - "--with-system-ffi" + ] ++ optionals (!(stdenv.isDarwin && pythonAtLeast "3.12")) [ + # ./Modules/_decimal/_decimal.c:4673:6: error: "No valid combination of CONFIG_64, CONFIG_32 and _PyHASH_BITS" + # https://hydra.nixos.org/build/248410479/nixlog/2/tail + "--with-system-libmpdec" + ] ++ optionals (openssl != null) [ + "--with-openssl=${openssl.dev}" + ] ++ optionals tzdataSupport [ + "--with-tzpath=${tzdata}/share/zoneinfo" + ] ++ optionals (execSuffix != "") [ + "--with-suffix=${execSuffix}" + ] ++ optionals enableLTO [ + "--with-lto" ] ++ optionals (!static && !enableFramework) [ "--enable-shared" ] ++ optionals enableFramework [ "--enable-framework=${placeholder "out"}/Library/Frameworks" ] ++ optionals enableOptimizations [ "--enable-optimizations" - ] ++ optionals enableLTO [ - "--with-lto" - ] ++ optionals (pythonOlder "3.7") [ - # This is unconditionally true starting in CPython 3.7. - "--with-threads" - ] ++ optionals (sqlite != null && isPy3k) [ + ] ++ optionals (sqlite != null) [ "--enable-loadable-sqlite-extensions" - ] ++ optionals (openssl' != null) [ - "--with-openssl=${openssl'.dev}" ] ++ optionals (libxcrypt != null) [ "CFLAGS=-I${libxcrypt}/include" "LIBS=-L${libxcrypt}/lib" @@ -393,14 +437,14 @@ in with passthru; stdenv.mkDerivation (finalAttrs: { # Never even try to use lchmod on linux, # don't rely on detecting glibc-isms. "ac_cv_func_lchmod=no" - ] ++ optionals tzdataSupport [ - "--with-tzpath=${tzdata}/share/zoneinfo" - ] ++ optional static "LDFLAGS=-static" - ++ optional (execSuffix != "") "--with-suffix=${execSuffix}"; + ] ++ optionals static [ + "LDFLAGS=-static" + ]; preConfigure = optionalString (pythonOlder "3.12") '' - for i in /usr /sw /opt /pkg; do # improve purity - substituteInPlace ./setup.py --replace $i /no-such-path + # Improve purity + for path in /usr /sw /opt /pkg; do + substituteInPlace ./setup.py --replace-warn $path /no-such-path done '' + optionalString stdenv.isDarwin '' # Override the auto-detection in setup.py, which assumes a universal build @@ -408,10 +452,6 @@ in with passthru; stdenv.mkDerivation (finalAttrs: { '' + optionalString (stdenv.isDarwin && x11Support && pythonAtLeast "3.11") '' export TCLTK_LIBS="-L${tcl}/lib -L${tk}/lib -l${tcl.libPrefix} -l${tk.libPrefix}" export TCLTK_CFLAGS="-I${tcl}/include -I${tk}/include" - '' + optionalString (isPy3k && pythonOlder "3.7") '' - # Determinism: The interpreter is patched to write null timestamps when compiling Python files - # so Python doesn't try to update the bytecode when seeing frozen timestamps in Nix's store. - export DETERMINISTIC_BUILD=1; '' + optionalString stdenv.hostPlatform.isMusl '' export NIX_CFLAGS_COMPILE+=" -DTHREAD_STACK_SIZE=0x100000" '' + @@ -482,9 +522,6 @@ in with passthru; stdenv.mkDerivation (finalAttrs: { # This allows build Python to import host Python's sysconfigdata mkdir -p "$out/${sitePackages}" ln -s "$out/lib/${libPrefix}/"_sysconfigdata*.py "$out/${sitePackages}/" - '' + lib.optionalString (pythonOlder "3.8") '' - # This is gone in Python >= 3.8 - ln -s "$out/include/${executable}m" "$out/include/${executable}" '' + optionalString stripConfig '' rm -R $out/bin/python*-config $out/lib/python*/config-* '' + optionalString stripIdlelib '' @@ -498,7 +535,6 @@ in with passthru; stdenv.mkDerivation (finalAttrs: { '' + optionalString includeSiteCustomize '' # Include a sitecustomize.py file cp ${../sitecustomize.py} $out/${sitePackages}/sitecustomize.py - '' + optionalString stripBytecode '' # Determinism: deterministic bytecode # First we delete all old bytecode. @@ -556,9 +592,9 @@ in with passthru; stdenv.mkDerivation (finalAttrs: { # Enforce that we don't have references to the OpenSSL -dev package, which we # explicitly specify in our configure flags above. - disallowedReferences = - lib.optionals (openssl' != null && !static && !enableFramework) [ openssl'.dev ] - ++ lib.optionals (stdenv.hostPlatform != stdenv.buildPlatform) [ + disallowedReferences = lib.optionals (openssl != null && !static && !enableFramework) [ + openssl.dev + ] ++ lib.optionals (stdenv.hostPlatform != stdenv.buildPlatform) [ # Ensure we don't have references to build-time packages. # These typically end up in shebangs. pythonOnBuildForHost buildPackages.bash @@ -591,11 +627,11 @@ in with passthru; stdenv.mkDerivation (finalAttrs: { enableParallelBuilding = true; - meta = { + meta = with lib; { homepage = "https://www.python.org"; changelog = let - majorMinor = lib.versions.majorMinor version; - dashedVersion = lib.replaceStrings [ "." "a" ] [ "-" "-alpha-" ] version; + majorMinor = versions.majorMinor version; + dashedVersion = replaceStrings [ "." "a" ] [ "-" "-alpha-" ] version; in if sourceVersion.suffix == "" then "https://docs.python.org/release/${version}/whatsnew/changelog.html" |