summary refs log tree commit diff
path: root/pkgs/applications/science/math/singular/default.nix
blob: 1f06f0d1aef37dac2ce574f32f7381aa0e09d753 (plain) (blame)
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
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
{ stdenv, fetchFromGitHub, gmp, bison, perl, ncurses, readline, coreutils, pkg-config
, lib
, autoreconfHook
, buildPackages
, sharutils
, file
, getconf
, flint
, ntl
, cddlib
, gfan
, lrcalc
, doxygen
, graphviz
, latex2html
# upstream generates docs with texinfo 4. later versions of texinfo
# use letters instead of numbers for post-appendix chapters, and we
# want it to match the upstream format because sage depends on it.
, texinfo4
, texlive
, enableDocs ? !stdenv.isDarwin
, enableGfanlib ? true
}:

stdenv.mkDerivation rec {
  pname = "singular";
  version = "4.3.2p2";

  # since the tarball does not contain tests, we fetch from GitHub.
  src = fetchFromGitHub {
    owner = "Singular";
    repo = "Singular";

    # if a release is tagged (which sometimes does not happen), it will
    # be in the format below.
    rev = "Release-${lib.replaceStrings ["."] ["-"] version}";
    sha256 = "sha256-dtZmN8xUCZ9eSgmtBxqfJeWsM4W5Baq7xWXuNAxNLjA=";

    # the repository's .gitattributes file contains the lines "/Tst/
    # export-ignore" and "/doc/ export-ignore" so some directories are
    # not included in the tarball downloaded by fetchzip.
    forceFetchGit = true;
  };

  configureFlags = [
    "--with-ntl=${ntl}"
    "--disable-pyobject-module"
  ] ++ lib.optionals enableDocs [
    "--enable-doc-build"
  ] ++ lib.optionals enableGfanlib [
    "--enable-gfanlib"
  ];

  prePatch = ''
    # don't let the tests depend on `hostname`
    substituteInPlace Tst/regress.cmd --replace 'mysystem_catch("hostname")' 'nix_test_runner'

    patchShebangs .
  '';

  # For reference (last checked on commit 75f460d):
  # https://github.com/Singular/Singular/blob/spielwiese/doc/Building-Singular-from-source.md
  # https://github.com/Singular/Singular/blob/spielwiese/doc/external-packages-dynamic-modules.md
  buildInputs = [
    # necessary
    gmp
    # by upstream recommended but optional
    ncurses
    readline
    ntl
    flint
    lrcalc
    gfan
  ] ++ lib.optionals enableGfanlib [
    cddlib
  ];

  nativeBuildInputs = [
    bison
    perl
    pkg-config
    autoreconfHook
    sharutils # needed for regress.cmd install checks
  ] ++ lib.optionals enableDocs [
    doxygen
    graphviz
    latex2html
    texinfo4
    texlive.combined.scheme-small
  ] ++ lib.optionals stdenv.isDarwin [ getconf ];
  depsBuildBuild = [ buildPackages.stdenv.cc ];

  preAutoreconf = ''
    find . -type f -readable -writable -exec sed \
      -e 's@/bin/rm@${coreutils}&@g' \
      -e 's@/bin/uname@${coreutils}&@g' \
      -e 's@/usr/bin/file@${file}/bin/file@g' \
      -i '{}' ';'
  '';

  hardeningDisable = lib.optional stdenv.isi686 "stackprotector";

  doCheck = true; # very basic checks, does not test any libraries

  installPhase = ''
    make install
  '' + lib.optionalString enableDocs ''
    # Sage uses singular.info, which is not installed by default
    mkdir -p $out/share/info
    cp doc/singular.info $out/share/info
  '' + ''
    # Make sure patchelf picks up the right libraries
    rm -rf libpolys factory resources omalloc Singular
  '';

  # singular tests are a bit complicated, see
  # https://github.com/Singular/Singular/tree/spielwiese/Tst
  # https://www.singular.uni-kl.de/forum/viewtopic.php?f=10&t=2773
  testsToRun = [
    "Old/universal.lst"
    "Buch/buch.lst"
    "Plural/short.lst"
    "Old/factor.tst"
  ] ++ lib.optionals enableGfanlib [
    # tests that require gfanlib
    "Short/ok_s.lst"
  ];

  # simple test to make sure singular starts and finds its libraries
  doInstallCheck = true;
  installCheckPhase = ''
    # Very basic sanity check to make sure singular starts and finds its libraries.
    # This is redundant with the below tests. It is only kept because the singular test
    # runner is a bit complicated. In case we decide to give up those tests in the future,
    # this will still be useful. It takes barely any time.
    "$out/bin/Singular" -c 'LIB "freegb.lib"; exit;'
    if [ $? -ne 0 ]; then
        echo >&2 "Error loading the freegb library in Singular."
        exit 1
    fi

    # Run the test suite
    cd Tst
    perl ./regress.cmd \
      -s "$out/bin/Singular" \
      ${lib.concatStringsSep " " (map lib.escapeShellArg testsToRun)} \
      2>"$TMPDIR/out-err.log"

    # unfortunately regress.cmd always returns exit code 0, so check stderr
    # https://www.singular.uni-kl.de/forum/viewtopic.php?f=10&t=2773
    if [[ -s "$TMPDIR/out-err.log" ]]; then
      cat "$TMPDIR/out-err.log"
      exit 1
    fi

    echo "Exit status $?"
  '';

  enableParallelBuilding = true;

  meta = with lib; {
    description = "A CAS for polynomial computations";
    maintainers = teams.sage.members;
    # 32 bit x86 fails with some link error: `undefined reference to `__divmoddi4@GCC_7.0.0'`
    # https://www.singular.uni-kl.de:8002/trac/ticket/837
    platforms = subtractLists platforms.i686 platforms.unix;
    license = licenses.gpl3; # Or GPLv2 at your option - but not GPLv4
    homepage = "https://www.singular.uni-kl.de";
    downloadPage = "http://www.mathematik.uni-kl.de/ftp/pub/Math/Singular/SOURCES/";
    mainProgram = "Singular";
  };
}