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