lol
1{ pkgs
2, withDoc ? false
3}:
4
5# Here sage and its dependencies are put together. Some dependencies may be pinned
6# as a last resort. Patching sage for compatibility with newer dependency versions
7# is always preferred, see `sage-src.nix` for that.
8
9let
10 inherit (pkgs) symlinkJoin callPackage nodePackages;
11
12 python3 = pkgs.python3.override {
13 packageOverrides = self: super: {
14 # `sagelib`, i.e. all of sage except some wrappers and runtime dependencies
15 sagelib = self.callPackage ./sagelib.nix {
16 inherit flint arb;
17 inherit sage-src env-locations pynac singular;
18 ecl = maxima-ecl.ecl;
19 linbox = pkgs.linbox.override { withSage = true; };
20 pkg-config = pkgs.pkg-config; # not to confuse with pythonPackages.pkg-config
21 };
22
23 sage_docbuild = self.callPackage ./sage_docbuild.nix {
24 inherit sage-src;
25 };
26 };
27 };
28
29 jupyter-kernel-definition = {
30 displayName = "SageMath ${sage-src.version}";
31 argv = [
32 "${sage-with-env}/bin/sage" # FIXME which sage
33 "--python"
34 "-m"
35 "sage.repl.ipython_kernel"
36 "-f"
37 "{connection_file}"
38 ];
39 language = "sagemath";
40 # just one 16x16 logo is available
41 logo32 = "${sage-src}/src/doc/common/themes/sage/static/sageicon.png";
42 logo64 = "${sage-src}/src/doc/common/themes/sage/static/sageicon.png";
43 };
44
45 three = callPackage ./threejs-sage.nix { };
46
47 # A bash script setting various environment variables to tell sage where
48 # the files its looking fore are located. Also see `sage-env`.
49 env-locations = callPackage ./env-locations.nix {
50 inherit pari_data;
51 inherit singular maxima-ecl;
52 inherit three;
53 ecl = maxima-ecl.ecl;
54 cysignals = python3.pkgs.cysignals;
55 mathjax = nodePackages.mathjax;
56 };
57
58 # The shell file that gets sourced on every sage start. Will also source
59 # the env-locations file.
60 sage-env = callPackage ./sage-env.nix {
61 sagelib = python3.pkgs.sagelib;
62 sage_docbuild = python3.pkgs.sage_docbuild;
63 inherit env-locations;
64 inherit python3 singular palp flint pynac pythonEnv maxima-ecl;
65 ecl = maxima-ecl.ecl;
66 pkg-config = pkgs.pkg-config; # not to confuse with pythonPackages.pkg-config
67 };
68
69 # The documentation for sage, building it takes a lot of ram.
70 sagedoc = callPackage ./sagedoc.nix {
71 inherit sage-with-env;
72 inherit python3 maxima-ecl;
73 };
74
75 # sagelib with added wrappers and a dependency on sage-tests to make sure thet tests were run.
76 sage-with-env = callPackage ./sage-with-env.nix {
77 inherit python3 pythonEnv;
78 inherit sage-env;
79 inherit pynac singular maxima-ecl;
80 inherit three;
81 pkg-config = pkgs.pkg-config; # not to confuse with pythonPackages.pkg-config
82 };
83
84 # Doesn't actually build anything, just runs sages testsuite. This is a
85 # separate derivation to make it possible to re-run the tests without
86 # rebuilding sagelib (which takes ~30 minutes).
87 # Running the tests should take something in the order of 1h.
88 sage-tests = callPackage ./sage-tests.nix {
89 inherit sage-with-env;
90 };
91
92 sage-src = callPackage ./sage-src.nix {};
93
94 pythonRuntimeDeps = with python3.pkgs; [
95 sagelib
96 sage_docbuild
97 cvxopt
98 networkx
99 service-identity
100 psutil
101 sympy
102 fpylll
103 matplotlib
104 tkinter # optional, as a matplotlib backend (use with `%matplotlib tk`)
105 scipy
106 ipywidgets
107 rpy2
108 sphinx
109 pillow
110 ];
111
112 pythonEnv = python3.buildEnv.override {
113 extraLibs = pythonRuntimeDeps;
114 ignoreCollisions = true;
115 } // { extraLibs = pythonRuntimeDeps; }; # make the libs accessible
116
117 arb = pkgs.arb.override { inherit flint; };
118
119 singular = pkgs.singular.override { inherit flint; };
120
121 maxima-ecl = pkgs.maxima-ecl.override {
122 ecl = pkgs.ecl.override {
123 # "echo syntax error | ecl > /dev/full 2>&1" segfaults in
124 # ECL. We apply a patch to fix it (write_error.patch), but it
125 # only works if threads are disabled. sage 9.2 tests this
126 # (src/sage/interfaces/tests.py) and ships ecl like so.
127 # https://gitlab.com/embeddable-common-lisp/ecl/-/merge_requests/1#note_1657275
128 threadSupport = false;
129
130 # if we don't use the system boehmgc, sending a SIGINT to ecl
131 # can segfault if we it happens during memory allocation.
132 # src/sage/libs/ecl.pyx would intermittently fail in this case.
133 useBoehmgc = true;
134 };
135 };
136
137 # *not* to confuse with the python package "pynac"
138 pynac = pkgs.pynac.override { inherit singular flint; };
139
140 # With openblas (64 bit), the tests fail the same way as when sage is build with
141 # openblas instead of openblasCompat. Apparently other packages somehow use flints
142 # blas when it is available. Alternative would be to override flint to use
143 # openblasCompat.
144 flint = pkgs.flint.override { withBlas = false; };
145
146 # Multiple palp dimensions need to be available and sage expects them all to be
147 # in the same folder.
148 palp = symlinkJoin {
149 name = "palp-${pkgs.palp.version}";
150 paths = [
151 (pkgs.palp.override { dimensions = 4; doSymlink = false; })
152 (pkgs.palp.override { dimensions = 5; doSymlink = false; })
153 (pkgs.palp.override { dimensions = 6; doSymlink = true; })
154 (pkgs.palp.override { dimensions = 11; doSymlink = false; })
155 ];
156 };
157
158 # Sage expects those in the same directory.
159 pari_data = symlinkJoin {
160 name = "pari_data";
161 paths = with pkgs; [
162 pari-galdata
163 pari-seadata-small
164 ];
165 };
166in
167# A wrapper around sage that makes sure sage finds its docs (if they were build).
168callPackage ./sage.nix {
169 inherit sage-tests sage-with-env sagedoc jupyter-kernel-definition;
170 inherit withDoc;
171}