1{ lib
2, stdenv
3, fetchurl
4, autoPatchelfHook
5, python-setup-hook
6, self
7# Dependencies
8, bzip2
9, expat
10, gdbm
11, ncurses6
12, sqlite
13, tcl-8_5
14, tk-8_5
15, tcl-8_6
16, tk-8_6
17, zlib
18# For the Python package set
19, packageOverrides ? (self: super: {})
20, sourceVersion
21, pythonVersion
22, hash
23, passthruFun
24}:
25
26# This version of PyPy is primarily added to speed-up translation of
27# our PyPy source build when developing that expression.
28
29let
30 isPy3k = majorVersion == "3";
31 passthru = passthruFun rec {
32 inherit self sourceVersion pythonVersion packageOverrides;
33 implementation = "pypy";
34 libPrefix = "pypy${pythonVersion}";
35 executable = "pypy${lib.optionalString isPy3k "3"}";
36 sitePackages = "lib/${libPrefix}/site-packages";
37 hasDistutilsCxxPatch = false;
38
39 # Not possible to cross-compile with.
40 pythonOnBuildForBuild = throw "${pname} does not support cross compilation";
41 pythonOnBuildForHost = self;
42 pythonOnBuildForTarget = throw "${pname} does not support cross compilation";
43 pythonOnHostForHost = throw "${pname} does not support cross compilation";
44 pythonOnTargetForTarget = throw "${pname} does not support cross compilation";
45 };
46 pname = "${passthru.executable}_prebuilt";
47 version = with sourceVersion; "${major}.${minor}.${patch}";
48
49 majorVersion = lib.versions.major pythonVersion;
50
51 downloadUrls = {
52 aarch64-linux = "https://downloads.python.org/pypy/pypy${pythonVersion}-v${version}-aarch64.tar.bz2";
53 x86_64-linux = "https://downloads.python.org/pypy/pypy${pythonVersion}-v${version}-linux64.tar.bz2";
54 aarch64-darwin = "https://downloads.python.org/pypy/pypy${pythonVersion}-v${version}-macos_arm64.tar.bz2";
55 x86_64-darwin = "https://downloads.python.org/pypy/pypy${pythonVersion}-v${version}-macos_x86_64.tar.bz2";
56 };
57
58in with passthru; stdenv.mkDerivation {
59 inherit pname version;
60
61 src = fetchurl {
62 url = downloadUrls.${stdenv.system} or (throw "Unsupported system: ${stdenv.system}");
63 inherit hash;
64 };
65
66 buildInputs = [
67 bzip2
68 expat
69 gdbm
70 ncurses6
71 sqlite
72 zlib
73 stdenv.cc.cc.libgcc or null
74 ] ++ lib.optionals stdenv.isLinux [
75 tcl-8_5
76 tk-8_5
77 ] ++ lib.optionals stdenv.isDarwin [
78 tcl-8_6
79 tk-8_6
80 ];
81
82 nativeBuildInputs = lib.optionals stdenv.isLinux [ autoPatchelfHook ];
83
84 installPhase = ''
85 runHook preInstall
86
87 mkdir -p $out
88 echo "Moving files to $out"
89 mv -t $out bin include lib
90 mv $out/bin/libpypy*-c${stdenv.hostPlatform.extensions.sharedLibrary} $out/lib/
91 ${lib.optionalString stdenv.isLinux ''
92 rm $out/bin/*.debug
93 ''}
94
95 echo "Removing bytecode"
96 find . -name "__pycache__" -type d -depth -delete
97
98 # Include a sitecustomize.py file
99 cp ${../sitecustomize.py} $out/${sitePackages}/sitecustomize.py
100
101 runHook postInstall
102 '';
103
104 preFixup = lib.optionalString stdenv.isLinux ''
105 find $out/{lib,lib_pypy*} -name "*.so" \
106 -exec patchelf \
107 --replace-needed libtinfow.so.6 libncursesw.so.6 \
108 --replace-needed libgdbm.so.4 libgdbm_compat.so.4 {} \;
109 '' + lib.optionalString stdenv.isDarwin ''
110 install_name_tool \
111 -change \
112 @rpath/lib${libPrefix}-c.dylib \
113 $out/lib/lib${libPrefix}-c.dylib \
114 $out/bin/${executable}
115 install_name_tool \
116 -change \
117 @rpath/lib${libPrefix}-c.dylib \
118 $out/lib/lib${libPrefix}-c.dylib \
119 $out/bin/${libPrefix}
120 install_name_tool \
121 -change \
122 /opt/homebrew${lib.optionalString stdenv.isx86_64 "_x86_64"}/opt/tcl-tk/lib/libtcl8.6.dylib \
123 ${tcl-8_6}/lib/libtcl8.6.dylib \
124 $out/lib/${libPrefix}/_tkinter/*.so
125 install_name_tool \
126 -change \
127 /opt/homebrew${lib.optionalString stdenv.isx86_64 "_x86_64"}/opt/tcl-tk/lib/libtk8.6.dylib \
128 ${tk-8_6}/lib/libtk8.6.dylib \
129 $out/lib/${libPrefix}/_tkinter/*.so
130 '';
131
132 doInstallCheck = true;
133
134 # Check whether importing of (extension) modules functions
135 installCheckPhase = let
136 modules = [
137 "ssl"
138 "sys"
139 "curses"
140 ] ++ lib.optionals (!isPy3k) [
141 "Tkinter"
142 ] ++ lib.optionals isPy3k [
143 "tkinter"
144 ];
145 imports = lib.concatMapStringsSep "; " (x: "import ${x}") modules;
146 in ''
147 echo "Testing whether we can import modules"
148 $out/bin/${executable} -c '${imports}'
149 '';
150
151 setupHook = python-setup-hook sitePackages;
152
153 donPatchElf = true;
154 dontStrip = true;
155
156 inherit passthru;
157
158 meta = with lib; {
159 homepage = "http://pypy.org/";
160 description = "Fast, compliant alternative implementation of the Python language (${pythonVersion})";
161 license = licenses.mit;
162 platforms = lib.mapAttrsToList (arch: _: arch) downloadUrls;
163 };
164
165}