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