1{ stdenv, buildPackages, fetchurl 2, bzip2 3, gdbm 4, fetchpatch 5, ncurses 6, openssl 7, readline 8, sqlite 9, tcl ? null, tk ? null, tix ? null, xlibsWrapper ? null, libX11 ? null, x11Support ? false 10, zlib 11, callPackage 12, self 13, db 14, expat 15, libffi 16, CF, configd, coreutils 17, python-setup-hook 18# Some proprietary libs assume UCS2 unicode, especially on darwin :( 19, ucsEncoding ? 4 20# For the Python package set 21, packageOverrides ? (self: super: {}) 22}: 23 24assert x11Support -> tcl != null 25 && tk != null 26 && xlibsWrapper != null 27 && libX11 != null; 28 29with stdenv.lib; 30 31let 32 majorVersion = "2.7"; 33 minorVersion = "15"; 34 minorVersionSuffix = ""; 35 version = "${majorVersion}.${minorVersion}${minorVersionSuffix}"; 36 libPrefix = "python${majorVersion}"; 37 sitePackages = "lib/${libPrefix}/site-packages"; 38 39 src = fetchurl { 40 url = "https://www.python.org/ftp/python/${majorVersion}.${minorVersion}/Python-${version}.tar.xz"; 41 sha256 = "0x2mvz9dp11wj7p5ccvmk9s0hzjk2fa1m462p395l4r6bfnb3n92"; 42 }; 43 44 hasDistutilsCxxPatch = !(stdenv.cc.isGNU or false); 45 patches = 46 [ # Look in C_INCLUDE_PATH and LIBRARY_PATH for stuff. 47 ./search-path.patch 48 49 # Python recompiles a Python if the mtime stored *in* the 50 # pyc/pyo file differs from the mtime of the source file. This 51 # doesn't work in Nix because Nix changes the mtime of files in 52 # the Nix store to 1. So treat that as a special case. 53 ./nix-store-mtime.patch 54 55 # patch python to put zero timestamp into pyc 56 # if DETERMINISTIC_BUILD env var is set 57 ./deterministic-build.patch 58 59 # Fix python bug #27177 (https://bugs.python.org/issue27177) 60 # The issue is that `match.group` only recognizes python integers 61 # instead of everything that has `__index__`. 62 # This bug was fixed upstream, but not backported to 2.7 63 (fetchpatch { 64 name = "re_match_index.patch"; 65 url = "https://bugs.python.org/file43084/re_match_index.patch"; 66 sha256 = "0l9rw6r5r90iybdkp3hhl2pf0h0s1izc68h5d3ywrm92pq32wz57"; 67 }) 68 69 # "`type_getattro()` calls `tp_descr_get(self, obj, type)` without actually owning a reference to "self". 70 # In very rare cases, this can cause a segmentation fault if "self" is deleted by the descriptor." 71 # https://github.com/python/cpython/pull/6118 72 (fetchpatch { 73 name = "type_getattro.patch"; 74 url = "file://${./type_getattro.patch}"; 75 sha256 = "11v9yx20hs3jmw0wggzvmw39qs4mxay4kb8iq2qjydwy9ya61nrd"; 76 }) 77 ] ++ optionals (x11Support && stdenv.isDarwin) [ 78 ./use-correct-tcl-tk-on-darwin.patch 79 ] ++ optionals stdenv.isLinux [ 80 81 # Disable the use of ldconfig in ctypes.util.find_library (since 82 # ldconfig doesn't work on NixOS), and don't use 83 # ctypes.util.find_library during the loading of the uuid module 84 # (since it will do a futile invocation of gcc (!) to find 85 # libuuid, slowing down program startup a lot). 86 ./no-ldconfig.patch 87 88 ] ++ optionals stdenv.hostPlatform.isCygwin [ 89 ./2.5.2-ctypes-util-find_library.patch 90 ./2.5.2-tkinter-x11.patch 91 ./2.6.2-ssl-threads.patch 92 ./2.6.5-export-PySignal_SetWakeupFd.patch 93 ./2.6.5-FD_SETSIZE.patch 94 ./2.6.5-ncurses-abi6.patch 95 ./2.7.3-dbm.patch 96 ./2.7.3-dylib.patch 97 ./2.7.3-getpath-exe-extension.patch 98 ./2.7.3-no-libm.patch 99 ] ++ optionals hasDistutilsCxxPatch [ 100 101 # Patch from http://bugs.python.org/issue1222585 adapted to work with 102 # `patch -p1' and with a last hunk removed 103 # Upstream distutils is calling C compiler to compile C++ code, which 104 # only works for GCC and Apple Clang. This makes distutils to call C++ 105 # compiler when needed. 106 ./python-2.7-distutils-C++.patch 107 ]; 108 109 preConfigure = '' 110 # Purity. 111 for i in /usr /sw /opt /pkg; do 112 substituteInPlace ./setup.py --replace $i /no-such-path 113 done 114 '' + optionalString (stdenv ? cc && stdenv.cc.libc != null) '' 115 for i in Lib/plat-*/regen; do 116 substituteInPlace $i --replace /usr/include/ ${stdenv.cc.libc}/include/ 117 done 118 '' + optionalString stdenv.isDarwin '' 119 substituteInPlace configure --replace '`/usr/bin/arch`' '"i386"' 120 substituteInPlace Lib/multiprocessing/__init__.py \ 121 --replace 'os.popen(comm)' 'os.popen("${coreutils}/bin/nproc")' 122 ''; 123 124 configureFlags = [ 125 "--enable-shared" 126 "--with-threads" 127 "--enable-unicode=ucs${toString ucsEncoding}" 128 ] ++ optionals (stdenv.hostPlatform.isCygwin || stdenv.hostPlatform.isAarch64) [ 129 "--with-system-ffi" 130 ] ++ optionals stdenv.hostPlatform.isCygwin [ 131 "--with-system-expat" 132 "ac_cv_func_bind_textdomain_codeset=yes" 133 ] ++ optionals stdenv.isDarwin [ 134 "--disable-toolbox-glue" 135 ] ++ optionals (stdenv.hostPlatform != stdenv.buildPlatform) [ 136 "PYTHON_FOR_BUILD=${getBin buildPackages.python}/bin/python" 137 "ac_cv_buggy_getaddrinfo=no" 138 # Assume little-endian IEEE 754 floating point when cross compiling 139 "ac_cv_little_endian_double=yes" 140 "ac_cv_big_endian_double=no" 141 "ac_cv_mixed_endian_double=no" 142 "ac_cv_x87_double_rounding=yes" 143 "ac_cv_tanh_preserves_zero_sign=yes" 144 # Generally assume that things are present and work 145 "ac_cv_posix_semaphores_enabled=yes" 146 "ac_cv_broken_sem_getvalue=no" 147 "ac_cv_wchar_t_signed=yes" 148 "ac_cv_rshift_extends_sign=yes" 149 "ac_cv_broken_nice=no" 150 "ac_cv_broken_poll=no" 151 "ac_cv_working_tzset=yes" 152 "ac_cv_have_long_long_format=yes" 153 "ac_cv_have_size_t_format=yes" 154 "ac_cv_computed_gotos=yes" 155 "ac_cv_file__dev_ptmx=yes" 156 "ac_cv_file__dev_ptc=yes" 157 ] 158 # Never even try to use lchmod on linux, 159 # don't rely on detecting glibc-isms. 160 ++ optional stdenv.hostPlatform.isLinux "ac_cv_func_lchmod=no"; 161 162 buildInputs = 163 optional (stdenv ? cc && stdenv.cc.libc != null) stdenv.cc.libc ++ 164 [ bzip2 openssl zlib ] 165 ++ optional (stdenv.hostPlatform.isCygwin || stdenv.hostPlatform.isAarch64) libffi 166 ++ optional stdenv.hostPlatform.isCygwin expat 167 ++ [ db gdbm ncurses sqlite readline ] 168 ++ optionals x11Support [ tcl tk xlibsWrapper libX11 ] 169 ++ optionals stdenv.isDarwin ([ CF ] ++ optional (configd != null) configd); 170 nativeBuildInputs = 171 optionals (stdenv.hostPlatform != stdenv.buildPlatform) 172 [ buildPackages.stdenv.cc buildPackages.python ]; 173 174 mkPaths = paths: { 175 C_INCLUDE_PATH = makeSearchPathOutput "dev" "include" paths; 176 LIBRARY_PATH = makeLibraryPath paths; 177 }; 178 179 # Build the basic Python interpreter without modules that have 180 # external dependencies. 181 182in stdenv.mkDerivation { 183 name = "python-${version}"; 184 pythonVersion = majorVersion; 185 186 inherit majorVersion version src patches buildInputs nativeBuildInputs 187 preConfigure configureFlags; 188 189 LDFLAGS = stdenv.lib.optionalString (!stdenv.isDarwin) "-lgcc_s"; 190 inherit (mkPaths buildInputs) C_INCLUDE_PATH LIBRARY_PATH; 191 192 NIX_CFLAGS_COMPILE = optionalString stdenv.isDarwin "-msse2" 193 + optionalString stdenv.hostPlatform.isMusl " -DTHREAD_STACK_SIZE=0x100000"; 194 DETERMINISTIC_BUILD = 1; 195 196 setupHook = python-setup-hook sitePackages; 197 198 postPatch = optionalString (x11Support && (tix != null)) '' 199 substituteInPlace "Lib/lib-tk/Tix.py" --replace "os.environ.get('TIX_LIBRARY')" "os.environ.get('TIX_LIBRARY') or '${tix}/lib'" 200 ''; 201 202 postInstall = 203 '' 204 # needed for some packages, especially packages that backport 205 # functionality to 2.x from 3.x 206 for item in $out/lib/python${majorVersion}/test/*; do 207 if [[ "$item" != */test_support.py* 208 && "$item" != */test/support 209 && "$item" != */test/regrtest.py* ]]; then 210 rm -rf "$item" 211 else 212 echo $item 213 fi 214 done 215 touch $out/lib/python${majorVersion}/test/__init__.py 216 ln -s $out/lib/python${majorVersion}/pdb.py $out/bin/pdb 217 ln -s $out/lib/python${majorVersion}/pdb.py $out/bin/pdb${majorVersion} 218 ln -s $out/share/man/man1/{python2.7.1.gz,python.1.gz} 219 220 paxmark E $out/bin/python${majorVersion} 221 222 # Python on Nix is not manylinux1 compatible. https://github.com/NixOS/nixpkgs/issues/18484 223 echo "manylinux1_compatible=False" >> $out/lib/${libPrefix}/_manylinux.py 224 225 rm "$out"/lib/python*/plat-*/regen # refers to glibc.dev 226 227 # Determinism: Windows installers were not deterministic. 228 # We're also not interested in building Windows installers. 229 find "$out" -name 'wininst*.exe' | xargs -r rm -f 230 '' + optionalString (stdenv.hostPlatform == stdenv.buildPlatform) 231 '' 232 # Determinism: rebuild all bytecode 233 # We exclude lib2to3 because that's Python 2 code which fails 234 # We rebuild three times, once for each optimization level 235 find $out -name "*.py" | $out/bin/python -m compileall -q -f -x "lib2to3" -i - 236 find $out -name "*.py" | $out/bin/python -O -m compileall -q -f -x "lib2to3" -i - 237 find $out -name "*.py" | $out/bin/python -OO -m compileall -q -f -x "lib2to3" -i - 238 '' + optionalString stdenv.hostPlatform.isCygwin '' 239 cp libpython2.7.dll.a $out/lib 240 ''; 241 242 passthru = let 243 pythonPackages = callPackage ../../../../../top-level/python-packages.nix {python=self; overrides=packageOverrides;}; 244 in rec { 245 inherit libPrefix sitePackages x11Support hasDistutilsCxxPatch ucsEncoding; 246 executable = libPrefix; 247 buildEnv = callPackage ../../wrapper.nix { python = self; inherit (pythonPackages) requiredPythonModules; }; 248 withPackages = import ../../with-packages.nix { inherit buildEnv pythonPackages;}; 249 pkgs = pythonPackages; 250 isPy2 = true; 251 isPy27 = true; 252 interpreter = "${self}/bin/${executable}"; 253 }; 254 255 enableParallelBuilding = true; 256 257 doCheck = false; # expensive, and fails 258 259 meta = { 260 homepage = http://python.org; 261 description = "A high-level dynamically-typed programming language"; 262 longDescription = '' 263 Python is a remarkably powerful dynamic programming language that 264 is used in a wide variety of application domains. Some of its key 265 distinguishing features include: clear, readable syntax; strong 266 introspection capabilities; intuitive object orientation; natural 267 expression of procedural code; full modularity, supporting 268 hierarchical packages; exception-based error handling; and very 269 high level dynamic data types. 270 ''; 271 license = stdenv.lib.licenses.psfl; 272 platforms = stdenv.lib.platforms.all; 273 maintainers = with stdenv.lib.maintainers; [ fridh ]; 274 # Higher priority than Python 3.x so that `/bin/python` points to `/bin/python2` 275 # in case both 2 and 3 are installed. 276 priority = -100; 277 }; 278 }