1{
2 gccStdenv,
3 lib,
4 coreutils,
5 openssl,
6 zlib,
7 sqlite,
8 version,
9 git-version,
10 src,
11 gambit-support,
12 gambit-git-version,
13 gambit-stampYmd,
14 gambit-stampHms,
15 gambit-params,
16}:
17
18# We use Gambit, that works 10x better with GCC than Clang. See ../gambit/build.nix
19let
20 stdenv = gccStdenv;
21in
22
23stdenv.mkDerivation rec {
24 pname = "gerbil";
25 inherit version;
26 inherit src;
27
28 buildInputs_libraries = [
29 openssl
30 zlib
31 sqlite
32 ];
33
34 # TODO: either fix all of Gerbil's dependencies to provide static libraries,
35 # or give up and delete all tentative support for static libraries.
36 #buildInputs_staticLibraries = map makeStaticLibraries buildInputs_libraries;
37
38 buildInputs = buildInputs_libraries;
39
40 postPatch = ''
41 patchShebangs . ;
42 grep -Fl '#!/usr/bin/env' `find . -type f -executable` | while read f ; do
43 substituteInPlace "$f" --replace '#!/usr/bin/env' '#!${coreutils}/bin/env' ;
44 done ;
45 cat > MANIFEST <<EOF
46 gerbil_stamp_version=v${git-version}
47 gambit_stamp_version=v${gambit-git-version}
48 gambit_stamp_ymd=${gambit-stampYmd}
49 gambit_stamp_hms=${gambit-stampHms}
50 EOF
51 for f in src/bootstrap/gerbil/compiler/driver__0.scm \
52 src/build/build-libgerbil.ss \
53 src/gerbil/compiler/driver.ss ; do
54 substituteInPlace "$f" --replace '"gcc"' '"${gccStdenv.cc}/bin/${gccStdenv.cc.targetPrefix}gcc"' ;
55 done
56 '';
57
58 ## TODO: make static compilation work.
59 ## For that, get all the packages below to somehow expose static libraries,
60 ## so we can offer users the option to statically link them into Gambit and/or Gerbil.
61 ## Then add the following to the postPatch script above:
62 # cat > etc/gerbil_static_libraries.sh <<EOF
63 # OPENSSL_LIBCRYPTO=${makeStaticLibraries openssl}/lib/libcrypto.a # MISSING!
64 # OPENSSL_LIBSSL=${makeStaticLibraries openssl}/lib/libssl.a # MISSING!
65 # ZLIB=${makeStaticLibraries zlib}/lib/libz.a
66 # SQLITE=${makeStaticLibraries sqlite}/lib/sqlite.a # MISSING!
67 # EOF
68
69 configureFlags = [
70 "--prefix=$out/gerbil"
71 "--enable-zlib"
72 "--enable-sqlite"
73 "--enable-shared"
74 "--enable-march=" # Avoid non-portable invalid instructions. Use =native if local build only.
75 ];
76
77 configurePhase = ''
78 export CC=${gccStdenv.cc}/bin/${gccStdenv.cc.targetPrefix}gcc \
79 CXX=${gccStdenv.cc}/bin/${gccStdenv.cc.targetPrefix}g++ \
80 CPP=${gccStdenv.cc}/bin/${gccStdenv.cc.targetPrefix}cpp \
81 CXXCPP=${gccStdenv.cc}/bin/${gccStdenv.cc.targetPrefix}cpp \
82 LD=${gccStdenv.cc}/bin/${gccStdenv.cc.targetPrefix}ld \
83 XMKMF=${coreutils}/bin/false
84 unset CFLAGS LDFLAGS LIBS CPPFLAGS CXXFLAGS
85 ./configure ${builtins.concatStringsSep " " configureFlags}
86 '';
87
88 extraLdOptions = [
89 "-L${zlib}/lib"
90 "-L${openssl.out}/lib"
91 "-L${sqlite.out}/lib"
92 ];
93
94 buildPhase = ''
95 runHook preBuild
96
97 # gxprof testing uses $HOME/.cache/gerbil/gxc
98 export HOME=$PWD
99 export GERBIL_BUILD_CORES=$NIX_BUILD_CORES
100 export GERBIL_GXC=$PWD/bin/gxc
101 export GERBIL_BASE=$PWD
102 export GERBIL_PREFIX=$PWD
103 export GERBIL_PATH=$PWD/lib
104 export PATH=$PWD/bin:$PATH
105 ${gambit-support.export-gambopt gambit-params}
106
107 # Build, replacing make by build.sh
108 ( cd src && sh build.sh )
109
110 f=build/lib/libgerbil.so.ldd ; [ -f $f ] && :
111 substituteInPlace "$f" --replace '(' \
112 '(${lib.strings.concatStrings (map (x: "\"${x}\" ") extraLdOptions)}'
113
114 runHook postBuild
115 '';
116
117 installPhase = ''
118 runHook preInstall
119 mkdir -p $out/gerbil $out/bin
120 ./install.sh
121 (cd $out/bin ; ln -s ../gerbil/bin/* .)
122 runHook postInstall
123 ''
124 + lib.optionalString stdenv.hostPlatform.isDarwin ''
125 libgerbil="$(realpath "$out/gerbil/lib/libgerbil.so")"
126 install_name_tool -id "$libgerbil" "$libgerbil"
127 '';
128
129 dontStrip = true;
130
131 meta = {
132 description = "Gerbil Scheme";
133 homepage = "https://github.com/vyzo/gerbil";
134 license = lib.licenses.lgpl21Only; # dual, also asl20, like Gambit
135 # NB regarding platforms: regularly tested on Linux and on macOS.
136 # Please report success and/or failure to fare.
137 platforms = lib.platforms.unix;
138 maintainers = with lib.maintainers; [ fare ];
139 };
140
141 outputsToInstall = [ "out" ];
142}