1{
2 stdenv,
3 fetchFromGitHub,
4 fetchpatch,
5 gmp,
6 bison,
7 perl,
8 ncurses,
9 readline,
10 coreutils,
11 pkg-config,
12 lib,
13 autoreconfHook,
14 buildPackages,
15 sharutils,
16 file,
17 getconf,
18 flint3,
19 ntl,
20 mpfr,
21 cddlib,
22 gfan,
23 lrcalc,
24 doxygen,
25 graphviz,
26 latex2html,
27 texinfo,
28 texliveSmall,
29 enableDocs ? true,
30}:
31
32stdenv.mkDerivation rec {
33 pname = "singular";
34 version = "4.4.1";
35
36 # since the tarball does not contain tests, we fetch from GitHub.
37 src = fetchFromGitHub {
38 owner = "Singular";
39 repo = "Singular";
40
41 # if a release is tagged (which sometimes does not happen), it will
42 # be in the format below.
43 rev = "Release-${lib.replaceStrings [ "." ] [ "-" ] version}";
44 hash = "sha256-vrRIirWQLbbe1l07AqqHK/StWo0egKuivdKT5R8Rx58=";
45
46 # the repository's .gitattributes file contains the lines "/Tst/
47 # export-ignore" and "/doc/ export-ignore" so some directories are
48 # not included in the tarball downloaded by fetchzip.
49 forceFetchGit = true;
50 };
51
52 configureFlags = [
53 "--enable-gfanlib"
54 "--with-ntl=${ntl}"
55 "--with-flint=${flint3}"
56 ]
57 ++ lib.optionals enableDocs [
58 "--enable-doc-build"
59 ];
60
61 prePatch = ''
62 # don't let the tests depend on `hostname`
63 substituteInPlace Tst/regress.cmd \
64 --replace-fail 'mysystem_catch("hostname")' 'nix_test_runner'
65
66 # ld: file not found: @rpath/libquadmath.0.dylib
67 substituteInPlace m4/p-procs.m4 \
68 --replace-fail "-flat_namespace" ""
69
70 patchShebangs .
71 '';
72
73 # Use fq_nmod_mat_entry instead of row pointer (removed in flint 3.3.0)
74 patches = [
75 (fetchpatch {
76 url = "https://github.com/Singular/Singular/commit/05f5116e13c8a4f5f820c78c35944dd6d197d442.patch";
77 hash = "sha256-4l7JaCCFzE+xINU+E92eBN5CJKIdtQHly4Ed3ZwbKTA=";
78 })
79 (fetchpatch {
80 url = "https://github.com/Singular/Singular/commit/595d7167e6e019d45d9a4f1e18ae741df1f3c41d.patch";
81 hash = "sha256-hpTZy/eAiHAaleasWPAenxM35aqeNAZ//o6OqqdGOJ4=";
82 })
83 ];
84
85 # For reference (last checked on commit 75f460d):
86 # https://github.com/Singular/Singular/blob/spielwiese/doc/Building-Singular-from-source.md
87 # https://github.com/Singular/Singular/blob/spielwiese/doc/external-packages-dynamic-modules.md
88 buildInputs = [
89 # necessary
90 gmp
91 flint3
92 # by upstream recommended but optional
93 ncurses
94 readline
95 ntl
96 mpfr
97 lrcalc
98 # for gfanlib
99 gfan
100 cddlib
101 ];
102
103 nativeBuildInputs = [
104 bison
105 perl
106 pkg-config
107 autoreconfHook
108 sharutils # needed for regress.cmd install checks
109 ]
110 ++ lib.optionals enableDocs [
111 doxygen
112 graphviz
113 latex2html
114 texinfo
115 texliveSmall
116 ]
117 ++ lib.optionals stdenv.hostPlatform.isDarwin [ getconf ];
118 depsBuildBuild = [ buildPackages.stdenv.cc ];
119
120 preAutoreconf = ''
121 find . -type f -readable -writable -exec sed \
122 -e 's@/bin/rm@${coreutils}&@g' \
123 -e 's@/bin/uname@${coreutils}&@g' \
124 -e 's@/usr/bin/file@${file}/bin/file@g' \
125 -i '{}' ';'
126 '';
127
128 hardeningDisable = lib.optional stdenv.hostPlatform.isi686 "stackprotector";
129
130 doCheck = true; # very basic checks, does not test any libraries
131
132 installPhase = ''
133 # clean up any artefacts a previous non-sandboxed docbuild may have left behind
134 rm /tmp/conic.log /tmp/conic.tex /tmp/tropicalcurve*.tex || true
135 make install
136 ''
137 + lib.optionalString enableDocs ''
138 # Sage uses singular.info, which is not installed by default
139 mkdir -p $out/share/info
140 cp doc/singular.info $out/share/info
141 ''
142 + ''
143 # Make sure patchelf picks up the right libraries
144 rm -rf libpolys factory resources omalloc Singular
145 '';
146
147 # singular tests are a bit complicated, see
148 # https://github.com/Singular/Singular/tree/spielwiese/Tst
149 # https://www.singular.uni-kl.de/forum/viewtopic.php?f=10&t=2773
150 testsToRun = [
151 "Old/universal.lst"
152 "Buch/buch.lst"
153 "Plural/short.lst"
154 "Old/factor.tst"
155 # tests that require gfanlib
156 # requires "DivRemIdU", a syzextra (undocumented) command
157 "Short/ok_s.lst"
158 ];
159
160 # simple test to make sure singular starts and finds its libraries
161 doInstallCheck = true;
162 installCheckPhase = ''
163 # Very basic sanity check to make sure singular starts and finds its libraries.
164 # This is redundant with the below tests. It is only kept because the singular test
165 # runner is a bit complicated. In case we decide to give up those tests in the future,
166 # this will still be useful. It takes barely any time.
167 "$out/bin/Singular" -c 'LIB "freegb.lib"; exit;'
168 if [ $? -ne 0 ]; then
169 echo >&2 "Error loading the freegb library in Singular."
170 exit 1
171 fi
172
173 # Run the test suite
174 cd Tst
175 perl ./regress.cmd \
176 -s "$out/bin/Singular" \
177 ${lib.concatStringsSep " " (map lib.escapeShellArg testsToRun)} \
178 2>"$TMPDIR/out-err.log"
179
180 # unfortunately regress.cmd always returns exit code 0, so check stderr
181 # https://www.singular.uni-kl.de/forum/viewtopic.php?f=10&t=2773
182 if [[ -s "$TMPDIR/out-err.log" ]]; then
183 cat "$TMPDIR/out-err.log"
184 exit 1
185 fi
186
187 echo "Exit status $?"
188 '';
189
190 enableParallelBuilding = true;
191 __darwinAllowLocalNetworking = true;
192
193 meta = with lib; {
194 description = "CAS for polynomial computations";
195 teams = [ teams.sage ];
196 # 32 bit x86 fails with some link error: `undefined reference to `__divmoddi4@GCC_7.0.0'`
197 # https://www.singular.uni-kl.de:8002/trac/ticket/837
198 platforms = subtractLists platforms.i686 platforms.unix;
199 license = licenses.gpl3; # Or GPLv2 at your option - but not GPLv4
200 homepage = "https://www.singular.uni-kl.de";
201 downloadPage = "http://www.mathematik.uni-kl.de/ftp/pub/Math/Singular/SOURCES/";
202 mainProgram = "Singular";
203 };
204}