summary refs log tree commit diff
path: root/pkgs/development/interpreters/racket/default.nix
blob: 451910e192a8f7b5cb240da0c4af2d1782040214 (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
{ lib, stdenv, fetchurl, makeFontsConf
, cacert
, cairo, coreutils, fontconfig, freefont_ttf
, glib, gmp
, gtk3
, libedit, libffi
, libiconv
, libGL
, libGLU
, libjpeg
, xorg
, ncurses
, libpng, libtool, mpfr, openssl, pango, poppler
, readline, sqlite
, disableDocs ? false
, CoreFoundation
, gsettings-desktop-schemas
, wrapGAppsHook
}:

let

  fontsConf = makeFontsConf {
    fontDirectories = [ freefont_ttf ];
  };

  libPath = lib.makeLibraryPath [
    cairo
    fontconfig
    glib
    gmp
    gtk3
    gsettings-desktop-schemas
    libedit
    libGL
    libGLU
    libjpeg
    libpng
    mpfr
    ncurses
    openssl
    pango
    poppler
    readline
    sqlite
  ];

in

stdenv.mkDerivation rec {
  pname = "racket";
  version = "8.5"; # always change at once with ./minimal.nix

  src = (lib.makeOverridable ({ name, sha256 }:
    fetchurl {
      url = "https://mirror.racket-lang.org/installers/${version}/${name}-src.tgz";
      inherit sha256;
    }
  )) {
    name = "${pname}-${version}";
    sha256 = "sha256-dWnOnpxh5zmou9eqVdcfhuCr8ts1CTqqEF1j/dk0jhs=";
  };

  FONTCONFIG_FILE = fontsConf;
  LD_LIBRARY_PATH = libPath;
  NIX_LDFLAGS = lib.concatStringsSep " " [
    (lib.optionalString (stdenv.cc.isGNU && ! stdenv.isDarwin) "-lgcc_s")
    (lib.optionalString stdenv.isDarwin "-framework CoreFoundation")
  ];

  nativeBuildInputs = [ cacert wrapGAppsHook ];

  buildInputs = [ fontconfig libffi libtool sqlite gsettings-desktop-schemas gtk3 ncurses ]
    ++ lib.optionals stdenv.isDarwin [ libiconv CoreFoundation ];

  patches = [
    # Hardcode variant detection because we wrap the Racket binary making it
    # fail to detect its variant at runtime.
    # See: https://github.com/NixOS/nixpkgs/issues/114993#issuecomment-812951247
    ./force-cs-variant.patch

    # The entry point binary $out/bin/racket is codesigned at least once. The
    # following error is triggered as a result.
    # (error 'add-ad-hoc-signature "file already has a signature")
    # We always remove the existing signature then call add-ad-hoc-signature to
    # circumvent this error.
    ./force-remove-codesign-then-add.patch
  ];

  preConfigure = ''
    unset AR
    for f in src/lt/configure src/cs/c/configure src/bc/src/string.c src/ChezScheme/workarea; do
      substituteInPlace "$f" \
        --replace /usr/bin/uname ${coreutils}/bin/uname \
        --replace /bin/cp ${coreutils}/bin/cp \
        --replace /bin/ln ${coreutils}/bin/ln \
        --replace /bin/rm ${coreutils}/bin/rm \
        --replace /bin/true ${coreutils}/bin/true
    done

    # The configure script forces using `libtool -o` as AR on Darwin. But, the
    # `-o` option is only available from Apple libtool. GNU ar works here.
    substituteInPlace src/ChezScheme/zlib/configure \
        --replace 'ARFLAGS="-o"' 'AR=ar; ARFLAGS="rc"'

    mkdir src/build
    cd src/build

  '' + lib.optionalString stdenv.isLinux ''
    gappsWrapperArgs+=("--prefix"   "LD_LIBRARY_PATH" ":" ${libPath})
  '' + lib.optionalString stdenv.isDarwin ''
    gappsWrapperArgs+=("--prefix" "DYLD_LIBRARY_PATH" ":" ${libPath})
  ''
  ;

  preBuild = lib.optionalString stdenv.isDarwin ''
    # Cannot set DYLD_LIBRARY_PATH as an attr of this drv, becasue dynamic
    # linker environment variables like this are purged.
    # See: https://apple.stackexchange.com/a/212954/167199

    # Make builders feed it to dlopen(...). Do not expose all of $libPath to
    # DYLD_LIBRARY_PATH as the order of looking up symbols like
    # `__cg_jpeg_resync_to_restart` will be messed up. Our libJPEG.dyllib
    # expects it from our libTIFF.dylib, but instead it could not be found from
    # the system `libTIFF.dylib`. DYLD_FALLBACK_LIBRARY_PATH has its own problem
    # , too.
    export DYLD_FALLBACK_LIBRARY_PATH="${libPath}"
  '';

  shared = if stdenv.isDarwin then "dylib" else "shared";
  configureFlags = [ "--enable-${shared}"  "--enable-lt=${libtool}/bin/libtool" ]
                   ++ lib.optional disableDocs [ "--disable-docs" ]
                   ++ lib.optional stdenv.isDarwin [ "--enable-xonx" ];

  configureScript = "../configure";

  enableParallelBuilding = false;

  meta = with lib; {
    broken = stdenv.isDarwin;
    description = "A programmable programming language";
    longDescription = ''
      Racket is a full-spectrum programming language. It goes beyond
      Lisp and Scheme with dialects that support objects, types,
      laziness, and more. Racket enables programmers to link
      components written in different dialects, and it empowers
      programmers to create new, project-specific dialects. Racket's
      libraries support applications from web servers and databases to
      GUIs and charts.
    '';
    homepage = "https://racket-lang.org/";
    license = with licenses; [ asl20 /* or */ mit ];
    maintainers = with maintainers; [ kkallio henrytill vrthra ];
    platforms = [ "x86_64-darwin" "x86_64-linux" "aarch64-linux" "aarch64-darwin" ];
  };
}