Nix flake for RPython interpreters
Revisão | 7b3772359ebdd00dcc62b1e54c83384ae60d6343 (tree) |
---|---|
Hora | 2024-05-24 16:11:57 |
Autor | Corbin <cds@corb...> |
Commiter | Corbin |
Uniformly build all three PyPys from a single file.
We no longer pass through any nixpkgs derivation directly. Instead,
everything is built via bootstrapped RPython.
@@ -6,12 +6,11 @@ Language | Attribute | ||
6 | 6 | ---|--- |
7 | 7 | Brainfuck | `bf` |
8 | 8 | DIVSPL | `divspl` |
9 | -Game Boy LR35902 | `pygirl` | |
9 | +LR35902 "Game Boy" | `pygirl` | |
10 | 10 | Nix | `regiux` |
11 | 11 | Prolog | `pyrolog` |
12 | -Python 2.7 | `pypy27` | |
13 | -Python 3.8 | `pypy38` | |
14 | -Python 3.9 | `pypy39` | |
12 | +Python 2.7 | `pypy2` | |
13 | +Python 3.10 | `pypy3` | |
15 | 14 | Ruby | `topaz` |
16 | 15 | |
17 | 16 | And its helpers are used by the following flakes: |
@@ -31,6 +30,11 @@ This flake supports fifteen different systems covering all supported upstream | ||
31 | 30 | system configurations. If PyPy officially supports a system, then this flake |
32 | 31 | should support it as well. |
33 | 32 | |
33 | +This flake bootstraps RPython semi-independently of `nixpkgs`. It uses `stdenv` | |
34 | +to build a CPython for Python 2.7, then uses CPython to build PyPy for Python | |
35 | +2.7 with minimal dependencies. This PyPy is then used to run RPython for all | |
36 | +other builds. | |
37 | + | |
34 | 38 | ## Limitations |
35 | 39 | |
36 | 40 | This flake does not support cross-compilation. This may be a permanent |
@@ -40,4 +44,5 @@ only. | ||
40 | 44 | ## Contributions |
41 | 45 | |
42 | 46 | There is not yet a contribution workflow; contact Corbin directly to send |
43 | -patches or pull requests. | |
47 | +patches or pull requests. Individual interpreters can be added to collaborative | |
48 | +organizations on forges; inquire for details. |
@@ -57,15 +57,30 @@ | ||
57 | 57 | optLevel ? "jit", |
58 | 58 | binInstallName ? binName, |
59 | 59 | transFlags ? "", |
60 | - }: attrs: pkgs.stdenv.mkDerivation (attrs // { | |
60 | + }: attrs: let | |
61 | + buildInputs = builtins.concatLists [ | |
62 | + (attrs.buildInputs or []) | |
63 | + ([ pkgs.libffi ]) | |
64 | + (pkgs.lib.optionals pkgs.stdenv.isDarwin (with pkgs; [ libunwind Security ])) | |
65 | + ]; | |
66 | + in pkgs.stdenv.mkDerivation (attrs // { | |
67 | + # Ensure that RPython binaries don't have Python runtime dependencies. | |
68 | + # disallowedReferences = [ py2 ]; | |
69 | + # To that end, don't automatically add references to Python modules! | |
70 | + # dontPatchShebangs = true; | |
71 | + | |
72 | + inherit buildInputs; | |
61 | 73 | nativeBuildInputs = builtins.concatLists [ |
62 | 74 | (attrs.nativeBuildInputs or []) |
63 | 75 | (withLibs libs) |
76 | + ([ pkgs.pkg-config ]) | |
64 | 77 | ]; |
65 | - buildInputs = builtins.concatLists [ | |
66 | - (attrs.buildInputs or []) | |
67 | - (with pkgs; [ pkg-config libffi ]) | |
68 | - ]; | |
78 | + | |
79 | + # Set up library search paths for translation. | |
80 | + C_INCLUDE_PATH = pkgs.lib.makeSearchPathOutput "dev" "include" buildInputs; | |
81 | + LIBRARY_PATH = pkgs.lib.makeLibraryPath buildInputs; | |
82 | + LD_LIBRARY_PATH = pkgs.lib.makeLibraryPath | |
83 | + (builtins.filter (x : x.outPath != pkgs.stdenv.cc.libc.outPath or "") buildInputs); | |
69 | 84 | |
70 | 85 | # conftest patches are required to build without pytest. |
71 | 86 | # sre patches are required to build without pypy/ src. |
@@ -80,13 +95,19 @@ | ||
80 | 95 | ''; |
81 | 96 | |
82 | 97 | # https://github.com/pypy/pypy/blob/main/rpython/translator/goal/translate.py |
98 | + # For rply, set XDG cache to someplace writeable. | |
99 | + # Don't run debugger on failure. | |
100 | + # Use as many cores as Nix tells us to use. | |
83 | 101 | buildPhase = '' |
84 | 102 | runHook preBuild |
85 | 103 | |
86 | - # For rply, set XDG cache to someplace writeable. | |
87 | 104 | export XDG_CACHE_HOME=$TMPDIR |
88 | 105 | |
89 | - ${py2} rpython/bin/rpython --batch -O${optLevel} ${entrypoint} ${transFlags} | |
106 | + ${py2} rpython/bin/rpython \ | |
107 | + --batch \ | |
108 | + --make-jobs="$NIX_BUILD_CORES" \ | |
109 | + -O${optLevel} \ | |
110 | + ${entrypoint} ${transFlags} | |
90 | 111 | |
91 | 112 | runHook postBuild |
92 | 113 | ''; |
@@ -105,34 +126,15 @@ | ||
105 | 126 | mkRPythonBootstrap = mkRPythonMaker { |
106 | 127 | py2 = "${cpython2}/bin/python"; |
107 | 128 | }; |
108 | - pypy2Minimal = mkRPythonBootstrap { | |
109 | - entrypoint = "pypy/goal/targetpypystandalone.py"; | |
110 | - binName = "pypy-c"; | |
111 | - optLevel = "jit"; | |
112 | - withLibs = ls: [ ls.pycparser ]; | |
113 | - transFlags = "--translationmodules"; | |
114 | - } { | |
115 | - pname = "pypy2"; | |
129 | + mkPyPy = import ./make-pypy.nix; | |
130 | + pypy2Minimal = mkPyPy { | |
131 | + inherit pkgs; | |
132 | + rpyMaker = mkRPythonBootstrap; | |
133 | + pyVersion = "2.7"; | |
116 | 134 | version = "7.3.15"; |
117 | - | |
135 | + binName = "pypy-c"; | |
136 | + minimal = true; | |
118 | 137 | src = pypySrc; |
119 | - buildInputs = with pkgs; [ ncurses zlib ]; | |
120 | - | |
121 | - # PyPy has a hardcoded stdlib search routine, so the tree has to look | |
122 | - # something like this, including symlinks. | |
123 | - postInstall = '' | |
124 | - mkdir -p $out/pypy-c/ | |
125 | - cp -R {include,lib_pypy,lib-python} $out/pypy-c/ | |
126 | - mv $out/bin/pypy-c $out/pypy-c/ | |
127 | - ln -s $out/pypy-c/pypy-c $out/bin/pypy | |
128 | - | |
129 | - mkdir -p $out/lib/ | |
130 | - cp libpypy-c${pkgs.stdenv.hostPlatform.extensions.sharedLibrary} $out/lib/ | |
131 | - ln -s $out/pypy-c/lib-python/2.7 $out/lib/pypy2.7 | |
132 | - | |
133 | - mkdir -p $out/include/ | |
134 | - ln -s $out/pypy-c/include $out/include/pypy2.7 | |
135 | - ''; | |
136 | 138 | }; |
137 | 139 | |
138 | 140 | # Phase 2: Build everything else using PyPy. |
@@ -200,33 +202,24 @@ | ||
200 | 202 | license = pkgs.lib.licenses.agpl3; |
201 | 203 | }; |
202 | 204 | }; |
203 | - pypy2 = mkRPythonDerivation { | |
204 | - entrypoint = "pypy/goal/targetpypystandalone.py"; | |
205 | - binName = "pypy-c"; | |
206 | - optLevel = "jit"; | |
207 | - withLibs = ls: [ ls.pycparser ]; | |
208 | - } { | |
209 | - pname = "pypy2"; | |
205 | + pypy2 = mkPyPy { | |
206 | + inherit pkgs; | |
207 | + rpyMaker = mkRPythonDerivation; | |
208 | + pyVersion = "2.7"; | |
210 | 209 | version = "7.3.15"; |
211 | - | |
210 | + binName = "pypy-c"; | |
212 | 211 | src = pypySrc; |
213 | - buildInputs = with pkgs; [ bzip2 expat gdbm ncurses openssl sqlite xz zlib ]; | |
214 | - | |
215 | - # PyPy has a hardcoded stdlib search routine, so the tree has to look | |
216 | - # something like this, including symlinks. | |
217 | - postInstall = '' | |
218 | - mkdir -p $out/pypy-c/ | |
219 | - cp -R {include,lib_pypy,lib-python} $out/pypy-c/ | |
220 | - mv $out/bin/pypy-c $out/pypy-c/ | |
221 | - ln -s $out/pypy-c/pypy-c $out/bin/pypy | |
222 | - | |
223 | - mkdir -p $out/lib/ | |
224 | - cp libpypy-c${pkgs.stdenv.hostPlatform.extensions.sharedLibrary} $out/lib/ | |
225 | - ln -s $out/pypy-c/lib-python/2.7 $out/lib/pypy2.7 | |
226 | - | |
227 | - mkdir -p $out/include/ | |
228 | - ln -s $out/pypy-c/include $out/include/pypy2.7 | |
229 | - ''; | |
212 | + }; | |
213 | + pypy3 = mkPyPy rec { | |
214 | + inherit pkgs; | |
215 | + rpyMaker = mkRPythonDerivation; | |
216 | + binName = "pypy3-c"; | |
217 | + pyVersion = "3.10"; | |
218 | + version = "7.3.15"; | |
219 | + src = pkgs.fetchurl { | |
220 | + url = "https://downloads.python.org/pypy/pypy3.10-v${version}-src.tar.bz2"; | |
221 | + hash = "sha256-g3YiEws2YDoYk4mb2fUplhqOSlbJ62cmjXLd+JIMlXk="; | |
222 | + }; | |
230 | 223 | }; |
231 | 224 | topaz = mkRPythonDerivation { |
232 | 225 | entrypoint = "targettopaz.py"; |
@@ -366,8 +359,7 @@ | ||
366 | 359 | checks = { inherit divspl; }; |
367 | 360 | lib = { inherit mkRPythonDerivation; }; |
368 | 361 | packages = { |
369 | - inherit (pkgs) pypy3 pypy38 pypy39; | |
370 | - inherit bf divspl hippyvm topaz pygirl pypy2 pysom pyrolog regiux; | |
362 | + inherit bf divspl hippyvm topaz pygirl pypy2 pypy3 pysom pyrolog regiux; | |
371 | 363 | # Export bootstrap PyPy. It is just as fast as standard PyPy, but |
372 | 364 | # missing some parts of the stdlib. |
373 | 365 | inherit pypy2Minimal; |
@@ -375,7 +367,7 @@ | ||
375 | 367 | devShells.default = pkgs.mkShell { |
376 | 368 | packages = builtins.filter (p: !p.meta.broken) (with pkgs; [ |
377 | 369 | cachix nix-tree |
378 | - pypy2Minimal | |
370 | + # pypy2Minimal | |
379 | 371 | ]); |
380 | 372 | }; |
381 | 373 | } |
@@ -0,0 +1,35 @@ | ||
1 | +{ pkgs, rpyMaker, | |
2 | + src, pyVersion, version, binName, | |
3 | + minimal ? false }: | |
4 | +rpyMaker { | |
5 | + inherit binName; | |
6 | + entrypoint = "pypy/goal/targetpypystandalone.py"; | |
7 | + optLevel = "jit"; | |
8 | + withLibs = ls: [ ls.pycparser ]; | |
9 | + transFlags = pkgs.lib.optionalString minimal "--translationmodules"; | |
10 | +} { | |
11 | + pname = if minimal then "pypy-${pyVersion}-minimal" else "pypy-${pyVersion}"; | |
12 | + | |
13 | + inherit version src; | |
14 | + buildInputs = with pkgs; [ | |
15 | + ncurses zlib | |
16 | + ] ++ lib.optionals (!minimal) (with pkgs; [ | |
17 | + bzip2 expat gdbm openssl sqlite xz | |
18 | + ]); | |
19 | + | |
20 | + # PyPy has a hardcoded stdlib search routine, so the tree has to look | |
21 | + # something like this, including symlinks. | |
22 | + postInstall = '' | |
23 | + mkdir -p $out/pypy-c/ | |
24 | + cp -R {include,lib_pypy,lib-python} $out/pypy-c/ | |
25 | + mv $out/bin/${binName} $out/pypy-c/ | |
26 | + ln -s $out/pypy-c/${binName} $out/bin/pypy | |
27 | + | |
28 | + mkdir -p $out/lib/ | |
29 | + cp libpypy-c${pkgs.stdenv.hostPlatform.extensions.sharedLibrary} $out/lib/ | |
30 | + ln -s $out/pypy-c/lib-python/${pyVersion} $out/lib/pypy${pyVersion} | |
31 | + | |
32 | + mkdir -p $out/include/ | |
33 | + ln -s $out/pypy-c/include $out/include/pypy${pyVersion} | |
34 | + ''; | |
35 | +} |