1{
2 lib,
3 stdenv,
4 makeWrapper,
5 buildEnv,
6 factor-unwrapped,
7 cairo,
8 freealut,
9 gdk-pixbuf,
10 glib,
11 gnome2,
12 gtk2-x11,
13 libGL,
14 libGLU,
15 librsvg,
16 graphviz,
17 libogg,
18 libvorbis,
19 openal,
20 openssl,
21 pango,
22 pcre,
23 udis86,
24 zlib,
25 # Enable factor GUI support
26 guiSupport ? true,
27 # Libraries added to ld.so.cache
28 extraLibs ? [ ],
29 # Packages added to path (and ld.so.cache)
30 binPackages ? [ ],
31 # Extra vocabularies added to out/lib/factor
32 extraVocabs ? [ ],
33 # Enable default libs and bins to run most of the standard library code.
34 enableDefaults ? true,
35 doInstallCheck ? true,
36}:
37let
38 inherit (lib) optional optionals optionalString;
39 # missing from lib/strings
40 escapeNixString = s: lib.escape [ "$" ] (builtins.toJSON s);
41 toFactorArgs = x: lib.concatStringsSep " " (map escapeNixString x);
42 defaultLibs = optionals enableDefaults [
43 libogg
44 libvorbis
45 openal
46 openssl
47 pcre
48 udis86
49 zlib
50 ];
51 defaultBins = optionals enableDefaults [ graphviz ];
52 runtimeLibs =
53 defaultLibs
54 ++ extraLibs
55 ++ binPackages
56 ++ (lib.flatten (map (v: v.extraLibs or [ ]) extraVocabs))
57 ++ optionals guiSupport [
58 cairo
59 freealut
60 gdk-pixbuf
61 glib
62 gnome2.gtkglext
63 gtk2-x11
64 libGL
65 libGLU
66 pango
67 ];
68 bins = binPackages ++ defaultBins ++ (lib.flatten (map (v: v.extraPaths or [ ]) extraVocabs));
69 vocabTree = buildEnv {
70 name = "${factor-unwrapped.pname}-vocabs";
71 ignoreCollisions = true;
72 pathsToLink = map (r: "/lib/factor/${r}") [
73 "basis"
74 "core"
75 "extra"
76 ];
77 paths = [ factor-unwrapped ] ++ extraVocabs;
78 };
79
80in
81stdenv.mkDerivation (finalAttrs: {
82 pname = "${factor-unwrapped.pname}-env";
83 inherit (factor-unwrapped) version;
84
85 nativeBuildInputs = [ makeWrapper ];
86 buildInputs = optional guiSupport gdk-pixbuf;
87
88 dontUnpack = true;
89
90 installPhase =
91 ''
92 runHook preInstall
93 ''
94 + optionalString guiSupport ''
95 # Set Gdk pixbuf loaders file to the one from the build dependencies here
96 unset GDK_PIXBUF_MODULE_FILE
97 # Defined in gdk-pixbuf setup hook
98 findGdkPixbufLoaders "${librsvg}"
99 makeWrapperArgs+=(--set GDK_PIXBUF_MODULE_FILE "$GDK_PIXBUF_MODULE_FILE")
100 ''
101 + ''
102 makeWrapperArgs+=(
103 --prefix LD_LIBRARY_PATH : /run/opengl-driver/lib:${lib.makeLibraryPath runtimeLibs}
104 --prefix PATH : ${lib.makeBinPath bins})
105 mkdir -p "$out/bin" "$out/share"
106 cp -r "${factor-unwrapped}/lib" "$out/"
107 cp -r "${factor-unwrapped}/share/emacs" "$out/share/"
108 chmod -R u+w "$out/lib" "$out/share"
109 (
110 cd ${vocabTree}
111 for f in "lib/factor/"* ; do
112 rm -r "$out/$f"
113 ln -s "${vocabTree}/$f" "$out/$f"
114 done
115 )
116
117 # There is no ld.so.cache in NixOS so we construct one
118 # out of known libraries. The side effect is that find-lib
119 # will work only on the known libraries. There does not seem
120 # to be a generic solution here.
121 find $(echo ${
122 lib.makeLibraryPath ([ stdenv.cc.libc ] ++ runtimeLibs)
123 } | sed -e 's#:# #g') -name \*.so.\* > $TMPDIR/so.lst
124 (echo $(cat $TMPDIR/so.lst | wc -l) "libs found in cache \`/etc/ld.so.cache'";
125 for l in $(<$TMPDIR/so.lst); do
126 echo " $(basename $l) (libc6,x86-64) => $l";
127 done)> $out/lib/factor/ld.so.cache
128
129 # Create a wrapper in bin/ and lib/factor/
130 wrapProgram "$out/lib/factor/factor" \
131 --argv0 factor \
132 --set FACTOR_LD_SO_CACHE "$out/lib/factor/ld.so.cache" \
133 "''${makeWrapperArgs[@]}"
134 mv $out/lib/factor/factor.image $out/lib/factor/.factor-wrapped.image
135 cp $out/lib/factor/factor $out/bin/
136
137 # Emacs fuel expects the image being named `factor.image` in the factor base dir
138 ln -rs $out/lib/factor/.factor-wrapped.image $out/lib/factor/factor.image
139
140 # Update default paths in fuel-listener.el to new output
141 sed -E -i -e 's#(\(defcustom fuel-factor-root-dir ").*(")#'"\1$out/lib/factor\2#" \
142 "$out/share/emacs/site-lisp/fuel-listener.el"
143 runHook postInstall
144 '';
145
146 inherit doInstallCheck;
147 disabledTests = toFactorArgs [
148 "io.files.info.unix"
149 "io.launcher.unix"
150 "io.ports"
151 "io.sockets"
152 "io.sockets.unix"
153 "io.sockets.secure.openssl"
154 "io.sockets.secure.unix"
155 ];
156 installCheckPhase = ''
157 runHook preCheck
158 export HOME=$TMPDIR
159 $out/bin/factor -e='USING: tools.test tools.test.private
160 zealot.factor sequences namespaces formatting ;
161 zealot-core-vocabs
162 { ${finalAttrs.disabledTests} } without
163 "compiler" suffix
164 [ test-vocab ] each :test-failures
165 test-failures get length "Number of failed tests: %d\n" printf'
166 runHook postCheck
167 '';
168
169 passthru = {
170 inherit
171 defaultLibs
172 defaultBins
173 extraLibs
174 runtimeLibs
175 binPackages
176 extraVocabs
177 ;
178 };
179
180 meta = factor-unwrapped.meta // {
181 mainProgram = "factor";
182 };
183})