1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
|
{ stdenv
, lib
, makeWrapper
, sage-env
, blas
, lapack
, pkg-config
, three
, singular
, gap
, giac
, maxima
, pari
, gmp
, gfan
, python3
, flintqs
, eclib
, ntl
, ecm
, pynac
, pythonEnv
}:
# lots of segfaults with (64 bit) blas
assert (!blas.isILP64) && (!lapack.isILP64);
# Wrapper that combined `sagelib` with `sage-env` to produce an actually
# executable sage. No tests are run yet and no documentation is built.
let
buildInputs = [
pythonEnv # for patchShebangs
makeWrapper
pkg-config
blas lapack
singular
three
pynac
giac
gap
pari
gmp
gfan
maxima
eclib
flintqs
ntl
ecm
];
# remove python prefix, replace "-" in the name by "_", apply patch_names
# python3.8-some-pkg-1.0 -> some_pkg-1.0
pkg_to_spkg_name = pkg: patch_names: let
parts = lib.splitString "-" pkg.name;
# remove python3.8-
stripped_parts = if (builtins.head parts) == python3.libPrefix then builtins.tail parts else parts;
version = lib.last stripped_parts;
orig_pkgname = lib.init stripped_parts;
pkgname = patch_names (lib.concatStringsSep "_" orig_pkgname);
in pkgname + "-" + version;
# return the names of all dependencies in the transitive closure
transitiveClosure = dep:
if dep == null then
# propagatedBuildInputs might contain null
# (although that might be considered a programming error in the derivation)
[]
else
[ dep ] ++ (
if builtins.hasAttr "propagatedBuildInputs" dep then
lib.unique (builtins.concatLists (map transitiveClosure dep.propagatedBuildInputs))
else
[]
);
allInputs = lib.remove null (buildInputs ++ pythonEnv.extraLibs);
transitiveDeps = lib.unique (builtins.concatLists (map transitiveClosure allInputs ));
# fix differences between spkg and sage names
# (could patch sage instead, but this is more lightweight and also works for packages depending on sage)
patch_names = builtins.replaceStrings [
"zope.interface"
"node_three"
] [
"zope_interface"
"threejs"
];
# spkg names (this_is_a_package-version) of all transitive deps
input_names = map (dep: pkg_to_spkg_name dep patch_names) transitiveDeps;
in
stdenv.mkDerivation rec {
version = src.version;
pname = "sage-with-env";
src = sage-env.lib.src;
inherit buildInputs;
configurePhase = "#do nothing";
buildPhase = ''
mkdir installed
for pkg in ${lib.concatStringsSep " " input_names}; do
touch "installed/$pkg"
done
# threejs version is in format 0.<version>.minor, but sage currently still
# relies on installed_packages for the online version of threejs to work
# and expects the format r<version>. This is a hotfix for now.
# upstream: https://trac.sagemath.org/ticket/26434
rm "installed/threejs"*
touch "installed/threejs-r${lib.versions.minor three.version}"
'';
installPhase = ''
mkdir -p "$out/var/lib/sage"
cp -r installed "$out/var/lib/sage"
mkdir -p "$out/etc"
# sage tests will try to create this file if it doesn't exist
touch "$out/etc/sage-started.txt"
mkdir -p "$out/build"
# the scripts in src/bin will find the actual sage source files using environment variables set in `sage-env`
cp -r src/bin "$out/bin"
cp -r build/bin "$out/build/bin"
cp -f '${sage-env}/sage-env' "$out/bin/sage-env"
substituteInPlace "$out/bin/sage-env" \
--subst-var-by sage-local "$out"
'';
passthru = {
env = sage-env;
};
}
|