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 runHook preInstall
92 ''
93 + optionalString guiSupport ''
94 # Set Gdk pixbuf loaders file to the one from the build dependencies here
95 unset GDK_PIXBUF_MODULE_FILE
96 # Defined in gdk-pixbuf setup hook
97 findGdkPixbufLoaders "${librsvg}"
98 makeWrapperArgs+=(--set GDK_PIXBUF_MODULE_FILE "$GDK_PIXBUF_MODULE_FILE")
99 ''
100 + ''
101 makeWrapperArgs+=(
102 --prefix LD_LIBRARY_PATH : /run/opengl-driver/lib:${lib.makeLibraryPath runtimeLibs}
103 --prefix PATH : ${lib.makeBinPath bins})
104 mkdir -p "$out/bin" "$out/share"
105 cp -r "${factor-unwrapped}/lib" "$out/"
106 cp -r "${factor-unwrapped}/share/emacs" "$out/share/"
107 chmod -R u+w "$out/lib" "$out/share"
108 (
109 cd ${vocabTree}
110 for f in "lib/factor/"* ; do
111 rm -r "$out/$f"
112 ln -s "${vocabTree}/$f" "$out/$f"
113 done
114 )
115
116 # There is no ld.so.cache in NixOS so we construct one
117 # out of known libraries. The side effect is that find-lib
118 # will work only on the known libraries. There does not seem
119 # to be a generic solution here.
120 find $(echo ${
121 lib.makeLibraryPath ([ stdenv.cc.libc ] ++ runtimeLibs)
122 } | sed -e 's#:# #g') -name \*.so.\* > $TMPDIR/so.lst
123 (echo $(cat $TMPDIR/so.lst | wc -l) "libs found in cache \`/etc/ld.so.cache'";
124 for l in $(<$TMPDIR/so.lst); do
125 echo " $(basename $l) (libc6,x86-64) => $l";
126 done)> $out/lib/factor/ld.so.cache
127
128 # Create a wrapper in bin/ and lib/factor/
129 wrapProgram "$out/lib/factor/factor" \
130 --argv0 factor \
131 --set FACTOR_LD_SO_CACHE "$out/lib/factor/ld.so.cache" \
132 "''${makeWrapperArgs[@]}"
133 mv $out/lib/factor/factor.image $out/lib/factor/.factor-wrapped.image
134 cp $out/lib/factor/factor $out/bin/
135
136 # Emacs fuel expects the image being named `factor.image` in the factor base dir
137 ln -rs $out/lib/factor/.factor-wrapped.image $out/lib/factor/factor.image
138
139 # Update default paths in fuel-listener.el to new output
140 sed -E -i -e 's#(\(defcustom fuel-factor-root-dir ").*(")#'"\1$out/lib/factor\2#" \
141 "$out/share/emacs/site-lisp/fuel-listener.el"
142 runHook postInstall
143 '';
144
145 inherit doInstallCheck;
146 disabledTests = toFactorArgs [
147 "io.files.info.unix"
148 "io.launcher.unix"
149 "io.ports"
150 "io.sockets"
151 "io.sockets.unix"
152 "io.sockets.secure.openssl"
153 "io.sockets.secure.unix"
154 ];
155 installCheckPhase = ''
156 runHook preInstallCheck
157
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
167 runHook postInstallCheck
168 '';
169
170 passthru = {
171 inherit
172 defaultLibs
173 defaultBins
174 extraLibs
175 runtimeLibs
176 binPackages
177 extraVocabs
178 ;
179 };
180
181 meta = factor-unwrapped.meta // {
182 mainProgram = "factor";
183 };
184})