···23Sage is a pretty complex package that depends on many other complex packages and patches some of those. As a result, the sage nix package is also quite complex.
45-Don't feel discouraged to fix, simplify or improve things though. Here's a quick overview over the functions of the individual files:
6-7-- `sage-src.nix`
8- Downloads the source code and applies patches. This makes sure that all the other files work with the same sage source. If you want to apply a patch to sage or update sage to a new version, this is the place to do it.
9-10-- `env-locations.nix`
11- Creates a bash file that sets a bunch of environment variables telling sage where to find various packages and files. The definitions of those environment variables can be found in the sage source in the `src/env.py` file. This bash file needs to be sourced before sage is started (done in `sage-env.nix` and `sagedoc.nix`).
12-13-- `sage-env.nix`
14- Sets all environment variables sage needs to run. This includes the package locations defined in `env-locations.nix` as well as the location of sage itself and its various subdirectories.
15-16-- `sagelib.nix`
17- Defines the main sage package (without setting the necessary environments or running any tests).
18-19-- `sage-with-env.nix`
20- Wraps sage in the necessary environment.
21-22-- `sage.nix`
23- Runs sages doctests.
24-25-- `sage-wrapper.nix`
26- Optionally tells sage where do find the docs.
27-28-- `sagedoc.nix`
29- Builds and tests the sage html documentation. Can be used for offline documentation viewing as well as the sage `browse_sage_doc` and `search_doc` functions.
30-31-- `sagenb.nix`
32- The (semi deprecated) sage notebook.
33-34-- `default.nix`
35- Introduces necessary overrides, defines new packages and ties everything together (returning the `sage` package).
36-37-- `flask-oldsessions.nix`, `flask-openid.nix`, `python-openid.nix`
38- These are python packages that were rejected from the main nixpkgs tree because they appear unmaintained. They are needed for the (semi-deprecated) sage notebook. Since that notebook is still needed to run the sage doctests, these packages are included but not exposed to the rest of nixpkgs.
39-40-- `pybrial.nix`
41- pybrial is a dependency of sage. However, pybrial itself also has sage as a dependency. Because of that circular dependency, pybrial is hidden from the rest of nixpkgs (just as the flask packages and python-openid.
42-43-- `openblas-pc.nix`
44- This creates a `.pc` file to be read by `pkg-config` that allows openblas to take on different roles, like `cblas` or `lapack`.
4546## The sage build is broken
47
···23Sage is a pretty complex package that depends on many other complex packages and patches some of those. As a result, the sage nix package is also quite complex.
45+Don't feel discouraged to fix, simplify or improve things though. The individual files have comments explaining their purpose. The most importent ones are `default.nix` linking everything together, `sage-src.nix` adding patches and `sagelib.nix` building the actual sage package.
00000000000000000000000000000000000000067## The sage build is broken
8
+73-50
pkgs/applications/science/math/sage/default.nix
···1-{ nixpkgs
2, withDoc ? false
3}:
400005let
6- inherit (nixpkgs) fetchpatch fetchurl symlinkJoin callPackage nodePackages;
78 # https://trac.sagemath.org/ticket/15980 for tracking of python3 support
9- python = nixpkgs.python2.override {
10 packageOverrides = self: super: {
11 # python packages that appear unmaintained and were not accepted into the nixpkgs
12 # tree because of that. These packages are only dependencies of the more-or-less
13 # deprecated sagenb. However sagenb is still a default dependency and the doctests
14 # depend on it.
15 # See https://github.com/NixOS/nixpkgs/pull/38787 for a discussion.
00016 flask-oldsessions = self.callPackage ./flask-oldsessions.nix {};
17 flask-openid = self.callPackage ./flask-openid.nix {};
18 python-openid = self.callPackage ./python-openid.nix {};
00019020 pybrial = self.callPackage ./pybrial.nix {};
21022 sagelib = self.callPackage ./sagelib.nix {
23 inherit flint ecl arb;
24 inherit sage-src openblas-blas-pc openblas-cblas-pc openblas-lapack-pc pynac singular;
25- linbox = nixpkgs.linbox.override { withSage = true; };
26 };
002728- sagenb = self.callPackage ./sagenb.nix {
29- mathjax = nodePackages.mathjax;
30- };
0000003132- sagedoc = self.callPackage ./sagedoc.nix {
33- inherit sage-src;
34- };
000003536- env-locations = self.callPackage ./env-locations.nix {
37- inherit pari_data ecl;
38- inherit singular;
39- three = nodePackages.three;
40- mathjax = nodePackages.mathjax;
41- };
4243- sage-env = self.callPackage ./sage-env.nix {
44- inherit sage-src python rWrapper openblas-cblas-pc ecl singular palp flint pynac pythonEnv;
45- pkg-config = nixpkgs.pkgconfig; # not to confuse with pythonPackages.pkgconfig
46- };
47-48- sage-with-env = self.callPackage ./sage-with-env.nix {
49- inherit pythonEnv;
50- inherit sage-src openblas-blas-pc openblas-cblas-pc openblas-lapack-pc pynac singular;
51- pkg-config = nixpkgs.pkgconfig; # not to confuse with pythonPackages.pkgconfig
52- three = nodePackages.three;
53- };
54-55- sage = self.callPackage ./sage.nix { };
5657- sage-wrapper = self.callPackage ./sage-wrapper.nix {
58- inherit sage-src withDoc;
59- };
60- };
0061 };
62063 openblas-blas-pc = callPackage ./openblas-pc.nix { name = "blas"; };
64 openblas-cblas-pc = callPackage ./openblas-pc.nix { name = "cblas"; };
65 openblas-lapack-pc = callPackage ./openblas-pc.nix { name = "lapack"; };
···91 } // { extraLibs = pythonRuntimeDeps; }; # make the libs accessible
9293 # needs to be rWrapper, standard "R" doesn't include default packages
94- rWrapper = nixpkgs.rWrapper.override {
95 # https://trac.sagemath.org/ticket/25674
96- R = nixpkgs.R.overrideAttrs (attrs: rec {
97 name = "R-3.4.4";
98 src = fetchurl {
99 url = "http://cran.r-project.org/src/base/R-3/${name}.tar.gz";
···102 });
103 };
104105- arb = nixpkgs.arb.override { inherit flint; };
106107- singular = nixpkgs.singular.override { inherit flint; };
108109 # *not* to confuse with the python package "pynac"
110- pynac = nixpkgs.pynac.override { inherit singular flint; };
111112 # With openblas (64 bit), the tests fail the same way as when sage is build with
113 # openblas instead of openblasCompat. Apparently other packages somehow use flints
114 # blas when it is available. Alternative would be to override flint to use
115 # openblasCompat.
116- flint = nixpkgs.flint.override { withBlas = false; };
117118 # Multiple palp dimensions need to be available and sage expects them all to be
119 # in the same folder.
120 palp = symlinkJoin {
121- name = "palp-${nixpkgs.palp.version}";
122 paths = [
123- (nixpkgs.palp.override { dimensions = 4; doSymlink = false; })
124- (nixpkgs.palp.override { dimensions = 5; doSymlink = false; })
125- (nixpkgs.palp.override { dimensions = 6; doSymlink = true; })
126- (nixpkgs.palp.override { dimensions = 11; doSymlink = false; })
127 ];
128 };
129130 # Sage expects those in the same directory.
131 pari_data = symlinkJoin {
132 name = "pari_data";
133- paths = with nixpkgs; [
134 pari-galdata
135 pari-seadata-small
136 ];
137 };
138139 # https://trac.sagemath.org/ticket/22191
140- ecl = nixpkgs.ecl_16_1_2;
141in
142- python.pkgs.sage-wrapper // {
143- doc = python.pkgs.sagedoc;
144- lib = python.pkgs.sagelib;
145- }
0
···1+{ pkgs
2, withDoc ? false
3}:
45+# 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) fetchurl symlinkJoin callPackage nodePackages_8_x;
1112 # https://trac.sagemath.org/ticket/15980 for tracking of python3 support
13+ python = pkgs.python2.override {
14 packageOverrides = self: super: {
15 # python packages that appear unmaintained and were not accepted into the nixpkgs
16 # tree because of that. These packages are only dependencies of the more-or-less
17 # deprecated sagenb. However sagenb is still a default dependency and the doctests
18 # depend on it.
19 # See https://github.com/NixOS/nixpkgs/pull/38787 for a discussion.
20+ # The dependency on the sage notebook (and therefore these packages) will be
21+ # removed in the future:
22+ # https://trac.sagemath.org/ticket/25837
23 flask-oldsessions = self.callPackage ./flask-oldsessions.nix {};
24 flask-openid = self.callPackage ./flask-openid.nix {};
25 python-openid = self.callPackage ./python-openid.nix {};
26+ sagenb = self.callPackage ./sagenb.nix {
27+ mathjax = nodePackages_8_x.mathjax;
28+ };
2930+ # Package with a cyclic dependency with sage
31 pybrial = self.callPackage ./pybrial.nix {};
3233+ # `sagelib`, i.e. all of sage except some wrappers and runtime dependencies
34 sagelib = self.callPackage ./sagelib.nix {
35 inherit flint ecl arb;
36 inherit sage-src openblas-blas-pc openblas-cblas-pc openblas-lapack-pc pynac singular;
37+ linbox = pkgs.linbox.override { withSage = true; };
38 };
39+ };
40+ };
4142+ # A bash script setting various environment variables to tell sage where
43+ # the files its looking fore are located. Also see `sage-env`.
44+ env-locations = callPackage ./env-locations.nix {
45+ inherit pari_data ecl;
46+ inherit singular;
47+ cysignals = python.pkgs.cysignals;
48+ three = nodePackages_8_x.three;
49+ mathjax = nodePackages_8_x.mathjax;
50+ };
5152+ # The shell file that gets sourced on every sage start. Will also source
53+ # the env-locations file.
54+ sage-env = callPackage ./sage-env.nix {
55+ sagelib = python.pkgs.sagelib;
56+ inherit env-locations;
57+ inherit python rWrapper openblas-cblas-pc ecl singular palp flint pynac pythonEnv;
58+ pkg-config = pkgs.pkgconfig; # not to confuse with pythonPackages.pkgconfig
59+ };
6061+ # The documentation for sage, building it takes a lot of ram.
62+ sagedoc = callPackage ./sagedoc.nix {
63+ inherit sage-with-env;
64+ inherit python;
65+ };
06667+ # sagelib with added wrappers and a dependency on sage-tests to make sure thet tests were run.
68+ sage-with-env = callPackage ./sage-with-env.nix {
69+ inherit pythonEnv;
70+ inherit sage-env;
71+ inherit openblas-blas-pc openblas-cblas-pc openblas-lapack-pc pynac singular;
72+ pkg-config = pkgs.pkgconfig; # not to confuse with pythonPackages.pkgconfig
73+ three = nodePackages_8_x.three;
74+ };
000007576+ # Doesn't actually build anything, just runs sages testsuite. This is a
77+ # separate derivation to make it possible to re-run the tests without
78+ # rebuilding sagelib (which takes ~30 minutes).
79+ # Running the tests should take something in the order of 1h.
80+ sage-tests = callPackage ./sage-tests.nix {
81+ inherit sage-with-env;
82 };
8384+ # FIXME
85 openblas-blas-pc = callPackage ./openblas-pc.nix { name = "blas"; };
86 openblas-cblas-pc = callPackage ./openblas-pc.nix { name = "cblas"; };
87 openblas-lapack-pc = callPackage ./openblas-pc.nix { name = "lapack"; };
···113 } // { extraLibs = pythonRuntimeDeps; }; # make the libs accessible
114115 # needs to be rWrapper, standard "R" doesn't include default packages
116+ rWrapper = pkgs.rWrapper.override {
117 # https://trac.sagemath.org/ticket/25674
118+ R = pkgs.R.overrideAttrs (attrs: rec {
119 name = "R-3.4.4";
120 src = fetchurl {
121 url = "http://cran.r-project.org/src/base/R-3/${name}.tar.gz";
···124 });
125 };
126127+ arb = pkgs.arb.override { inherit flint; };
128129+ singular = pkgs.singular.override { inherit flint; };
130131 # *not* to confuse with the python package "pynac"
132+ pynac = pkgs.pynac.override { inherit singular flint; };
133134 # With openblas (64 bit), the tests fail the same way as when sage is build with
135 # openblas instead of openblasCompat. Apparently other packages somehow use flints
136 # blas when it is available. Alternative would be to override flint to use
137 # openblasCompat.
138+ flint = pkgs.flint.override { withBlas = false; };
139140 # Multiple palp dimensions need to be available and sage expects them all to be
141 # in the same folder.
142 palp = symlinkJoin {
143+ name = "palp-${pkgs.palp.version}";
144 paths = [
145+ (pkgs.palp.override { dimensions = 4; doSymlink = false; })
146+ (pkgs.palp.override { dimensions = 5; doSymlink = false; })
147+ (pkgs.palp.override { dimensions = 6; doSymlink = true; })
148+ (pkgs.palp.override { dimensions = 11; doSymlink = false; })
149 ];
150 };
151152 # Sage expects those in the same directory.
153 pari_data = symlinkJoin {
154 name = "pari_data";
155+ paths = with pkgs; [
156 pari-galdata
157 pari-seadata-small
158 ];
159 };
160161 # https://trac.sagemath.org/ticket/22191
162+ ecl = pkgs.ecl_16_1_2;
163in
164+# A wrapper around sage that makes sure sage finds its docs (if they were build).
165+callPackage ./sage.nix {
166+ inherit sage-tests sage-with-env sagedoc;
167+ inherit withDoc;
168+}
···16, cysignals
17}:
1819+# A bash script setting various environment variables to tell sage where
20+# the files its looking fore are located. Also see `sage-env`.
21writeTextFile rec {
22 name = "sage-env-locations";
23 destination = "/${name}";
···2, lib
3, writeTextFile
4, python
05, sagelib
6, env-locations
7, gfortran
···45, gsl
46, ntl
47}:
48+49+# This generates a `sage-env` shell file that will be sourced by sage on startup.
50+# It sets up various environment variables, telling sage where to find its
51+# dependencies.
5253let
54 runtimepath = (lib.makeBinPath ([
···106 openblas-cblas-pc
107 ])
108 }'
109+ export SAGE_ROOT='${sagelib.src}'
110 export SAGE_LOCAL='@sage-local@'
111 export SAGE_SHARE='${sagelib}/share'
112 orig_path="$PATH"
113 export PATH='${runtimepath}'
114115 # set dependent vars, like JUPYTER_CONFIG_DIR
116+ source "${sagelib.src}/src/bin/sage-env"
117 export PATH="${runtimepath}:$orig_path" # sage-env messes with PATH
118119 export SAGE_LOGS="$TMPDIR/sage-logs"
120 export SAGE_DOC="''${SAGE_DOC_OVERRIDE:-doc-placeholder}"
121+ export SAGE_DOC_SRC="''${SAGE_DOC_SRC_OVERRIDE:-${sagelib.src}/src/doc}"
122123 # set locations of dependencies
124 . ${env-locations}/sage-env-locations
···157158 export SAGE_LIB='${sagelib}/${python.sitePackages}'
159160+ export SAGE_EXTCODE='${sagelib.src}/src/ext'
161162+ # for find_library
163 export DYLD_LIBRARY_PATH="${lib.makeLibraryPath [stdenv.cc.libc singular]}:$DYLD_LIBRARY_PATH"
164 '';
165+} // {
166+ lib = sagelib; # equivalent of `passthru`, which `writeTextFile` doesn't support
167}
+19-5
pkgs/applications/science/math/sage/sage-src.nix
···2, fetchFromGitHub
3, fetchpatch
4}:
0000005stdenv.mkDerivation rec {
6 version = "8.4";
7 name = "sage-src-${version}";
···13 sha256 = "0gips1hagiz9m7s21bg5as8hrrm2x5k47h1bsq0pc46iplfwmv2d";
14 };
150016 nixPatches = [
17 # https://trac.sagemath.org/ticket/25358
18 (fetchpatch {
···40 ./patches/Only-test-py2-py3-optional-tests-when-all-of-sage-is.patch
41 ];
4200000043 packageUpgradePatches = let
44- # fetch a diff between base and rev on sage's git server
45- # used to fetch trac tickets by setting the base to the release and the
46- # revision to the last commit that should be included
47 fetchSageDiff = { base, rev, ...}@args: (
48 fetchpatch ({
49 url = "https://git.sagemath.org/sage.git/patch?id2=${base}&id=${rev}";
···65 # https://trac.sagemath.org/ticket/25260
66 ./patches/numpy-1.15.1.patch
6768- # ntl upgrade
69- # https://trac.sagemath.org/ticket/25532#comment:29
70 (fetchpatch {
71 name = "lcalc-c++11.patch";
72 url = "https://git.archlinux.org/svntogit/community.git/plain/trunk/sagemath-lcalc-c++11.patch?h=packages/sagemath&id=0e31ae526ab7c6b5c0bfacb3f8b1c4fd490035aa";
···2, fetchFromGitHub
3, fetchpatch
4}:
5+6+# This file is responsible for fetching the sage source and adding necessary patches.
7+# It does not actually build anything, it just copies the patched sources to $out.
8+# This is done because multiple derivations rely on these sources and they should
9+# all get the same sources with the same patches applied.
10+11stdenv.mkDerivation rec {
12 version = "8.4";
13 name = "sage-src-${version}";
···19 sha256 = "0gips1hagiz9m7s21bg5as8hrrm2x5k47h1bsq0pc46iplfwmv2d";
20 };
2122+ # Patches needed because of particularities of nix or the way this is packaged.
23+ # The goal is to upstream all of them and get rid of this list.
24 nixPatches = [
25 # https://trac.sagemath.org/ticket/25358
26 (fetchpatch {
···48 ./patches/Only-test-py2-py3-optional-tests-when-all-of-sage-is.patch
49 ];
5051+ # Patches needed because of package updates. We could just pin the versions of
52+ # dependencies, but that would lead to rebuilds, confusion and the burdons of
53+ # maintaining multiple versions of dependencies. Instead we try to make sage
54+ # compatible with never dependency versions when possible. All these changes
55+ # should come from or be proposed to upstream. This list will probably never
56+ # be empty since dependencies update all the time.
57 packageUpgradePatches = let
58+ # Fetch a diff between `base` and `rev` on sage's git server.
59+ # Used to fetch trac tickets by setting the `base` to the last release and the
60+ # `rev` to the last commit of the ticket.
61 fetchSageDiff = { base, rev, ...}@args: (
62 fetchpatch ({
63 url = "https://git.sagemath.org/sage.git/patch?id2=${base}&id=${rev}";
···79 # https://trac.sagemath.org/ticket/25260
80 ./patches/numpy-1.15.1.patch
8182+ # needed for ntl update
83+ # https://trac.sagemath.org/ticket/25532
84 (fetchpatch {
85 name = "lcalc-c++11.patch";
86 url = "https://git.archlinux.org/svntogit/community.git/plain/trunk/sagemath-lcalc-c++11.patch?h=packages/sagemath&id=0e31ae526ab7c6b5c0bfacb3f8b1c4fd490035aa";
···51, libbraiding
52}:
5354+# This is the core sage python package. Everything else is just wrappers gluing
55+# stuff together. It is not very useful on its own though, since it will not
56+# find many of its dependencies without `sage-env`, will not be tested without
57+# `sage-tests` and will not have html docs without `sagedoc`.
58+59buildPythonPackage rec {
60 format = "other";
61+ version = src.version;
62+ name = "sagelib-${version}";
063 src = sage-src;
6465 nativeBuildInputs = [
+4-1
pkgs/applications/science/math/sage/sagenb.nix
···1-# Has a cyclic dependency with sage (not expressed here) and is not useful outside of sage
2{ stdenv
3, fetchpatch
4, python
···12, flask-autoindex
13, flask-babel
14}:
00001516buildPythonPackage rec {
17 pname = "sagenb";
···01{ stdenv
2, fetchpatch
3, python
···11, flask-autoindex
12, flask-babel
13}:
14+15+# Has a cyclic dependency with sage (not expressed here) and is not useful outside of sage.
16+# Deprecated, hopefully soon to be removed. See
17+# https://trac.sagemath.org/ticket/25837
1819buildPythonPackage rec {
20 pname = "sagenb";