nixpkgs mirror (for testing)
github.com/NixOS/nixpkgs
nix
1{ lib
2, stdenv
3, cairo
4, curl
5, fetchurl
6, freealut
7, gdk-pixbuf
8, git
9, glib
10, gnome2
11, graphviz
12, gtk2-x11
13, interpreter
14, libGL
15, libGLU
16, libogg
17, librsvg
18, libvorbis
19, makeWrapper
20, ncurses
21, openal
22, openssl
23, pango
24, pcre
25, runCommand
26, runtimeShell
27, tzdata
28, udis86
29, unzip
30, writeScriptBin
31, zlib
32}:
33let
34 runtimeLibs = [
35 cairo
36 freealut
37 gdk-pixbuf
38 glib
39 gnome2.gtkglext
40 graphviz
41 gtk2-x11
42 libGL
43 libGLU
44 libogg
45 libvorbis
46 openal
47 openssl
48 pango
49 pcre
50 udis86
51 zlib
52 ];
53
54 wrapFactorScript = { from, to ? false, runtimeLibs }: ''
55 # Set Gdk pixbuf loaders file to the one from the build dependencies here
56 unset GDK_PIXBUF_MODULE_FILE
57 # Defined in gdk-pixbuf setup hook
58 findGdkPixbufLoaders "${librsvg}"
59
60 ${if to then "makeWrapper ${from} ${to}" else "wrapProgram ${from}"} \
61 --set GDK_PIXBUF_MODULE_FILE "$GDK_PIXBUF_MODULE_FILE" \
62 --argv0 factor \
63 --prefix LD_LIBRARY_PATH : /run/opengl-driver/lib:${lib.makeLibraryPath runtimeLibs} \
64 --prefix PATH : ${lib.makeBinPath [ graphviz ]}
65 '';
66
67 wrapFactor = runtimeLibs:
68 runCommand (lib.appendToName "with-libs" interpreter).name
69 {
70 nativeBuildInputs = [ makeWrapper ];
71 buildInputs = [ gdk-pixbuf ];
72 passthru.runtimeLibs = runtimeLibs ++ interpreter.runtimeLibs;
73 }
74 (wrapFactorScript {
75 from = "${interpreter}/lib/factor/.factor.wrapped";
76 to = "$out/bin/factor";
77 runtimeLibs = (runtimeLibs ++ interpreter.runtimeLibs);
78 });
79
80 # Development helper for use in nix shell
81 wrapLocalFactor = writeScriptBin "wrapFactor" ''
82 #!${runtimeShell}
83 ${wrapFactorScript { from = "./factor"; inherit runtimeLibs; }}
84 ln -sf factor.image .factor-wrapped.image
85 '';
86 rev = "7999e72aecc3c5bc4019d43dc4697f49678cc3b4";
87 version = "0.98";
88
89in
90stdenv.mkDerivation {
91 pname = "factor-lang";
92 inherit version;
93
94 src = fetchurl {
95 url = "https://downloads.factorcode.org/releases/${version}/factor-src-${version}.zip";
96 sha256 = "01ip9mbnar4sv60d2wcwfz62qaamdvbykxw3gbhzqa25z36vi3ri";
97 };
98
99 patches = [
100 ./staging-command-line-0.98-pre.patch
101 ./workdir-0.98-pre.patch
102 ./adjust-paths-in-unit-tests.patch
103 ];
104
105 nativeBuildInputs = [ git makeWrapper curl unzip wrapLocalFactor ];
106 buildInputs = runtimeLibs;
107
108 postPatch = ''
109 sed -ie '4i GIT_LABEL = heads/master-${rev}' GNUmakefile
110
111 # There is no ld.so.cache in NixOS so we patch out calls to that completely.
112 # This should work as long as no application code relies on `find-library*`
113 # to return a match, which currently is the case and also a justified assumption.
114
115 sed -ie "s#/sbin/ldconfig -p#cat $out/lib/factor/ld.so.cache#g" \
116 basis/alien/libraries/finder/linux/linux.factor
117
118 # Some other hard-coded paths to fix:
119 sed -i 's#/usr/share/zoneinfo/#${tzdata}/share/zoneinfo/#g' \
120 extra/tzinfo/tzinfo.factor
121
122 sed -i 's#/usr/share/terminfo#${ncurses.out}/share/terminfo#g' \
123 extra/terminfo/terminfo.factor
124
125 # De-memoize xdg-* functions, otherwise they break the image.
126 sed -ie 's/^MEMO:/:/' basis/xdg/xdg.factor
127
128 # update default paths in factor-listener.el for fuel mode
129 substituteInPlace misc/fuel/fuel-listener.el \
130 --replace '(defcustom fuel-factor-root-dir nil' "(defcustom fuel-factor-root-dir \"$out/lib/factor\""
131 '';
132
133 buildPhase = ''
134 runHook preBuild
135 # Necessary here, because ld.so.cache is needed in its final location during rebuild.
136 mkdir -p $out/bin $out/lib/factor
137 patchShebangs ./build.sh
138 # Factor uses XDG_CACHE_HOME for cache during compilation.
139 # We can't have that. So, set it to $TMPDIR/.cache
140 export XDG_CACHE_HOME=$TMPDIR/.cache && mkdir -p $XDG_CACHE_HOME
141
142 # There is no ld.so.cache in NixOS so we construct one
143 # out of known libraries. The side effect is that find-lib
144 # will work only on the known libraries. There does not seem
145 # to be a generic solution here.
146 find $(echo ${lib.makeLibraryPath runtimeLibs} | sed -e 's#:# #g') -name \*.so.\* > $TMPDIR/so.lst
147 (echo $(cat $TMPDIR/so.lst | wc -l) "libs found in cache \`/etc/ld.so.cache'";
148 for l in $(<$TMPDIR/so.lst); do
149 echo " $(basename $l) (libc6,x86-64) => $l";
150 done)> $out/lib/factor/ld.so.cache
151
152 make -j$NIX_BUILD_CORES linux-x86-64
153 ./build.sh bootstrap
154 runHook postBuild
155 '';
156
157 # For now, the check phase runs, but should always return 0. This way the logs
158 # contain the test failures until all unit tests are fixed. Then, it should
159 # return 1 if any test failures have occured.
160 doCheck = false;
161 checkPhase = ''
162 runHook preCheck
163 set +e
164 ./factor -e='USING: tools.test zealot.factor sequences namespaces formatting ;
165 zealot-core-vocabs "compiler" suffix [ test ] each :test-failures
166 test-failures get length "Number of failed Tests: %d\n" printf'
167 [ $? -eq 0 ] || {
168 mkdir -p "$out/nix-support"
169 touch "$out/nix-support/failed"
170 }
171 set -e
172 runHook postCheck
173 '';
174
175 installPhase = ''
176 runHook preInstall
177 cp -r factor factor.image LICENSE.txt README.md basis core extra misc $out/lib/factor
178
179 # Create a wrapper in bin/ and lib/factor/
180 ${wrapFactorScript { from = "$out/lib/factor/factor"; inherit runtimeLibs; }}
181 mv $out/lib/factor/factor.image $out/lib/factor/.factor-wrapped.image
182 cp $out/lib/factor/factor $out/bin/
183
184 # Emacs fuel expects the image being named `factor.image` in the factor base dir
185 ln -s $out/lib/factor/.factor-wrapped.image $out/lib/factor/factor.image
186
187 # install fuel mode for emacs
188 mkdir -p $out/share/emacs/site-lisp
189 ln -s $out/lib/factor/misc/fuel/*.el $out/share/emacs/site-lisp/
190 runHook postInstall
191 '';
192
193 passthru = {
194 inherit runtimeLibs wrapFactorScript;
195 withLibs = wrapFactor;
196 };
197
198 meta = with lib; {
199 homepage = "https://factorcode.org/";
200 description = "A concatenative, stack-based programming language";
201 longDescription = ''
202 The Factor programming language is a concatenative, stack-based
203 programming language with high-level features including dynamic types,
204 extensible syntax, macros, and garbage collection. On a practical side,
205 Factor has a full-featured library, supports many different platforms, and
206 has been extensively documented.
207
208 The implementation is fully compiled for performance, while still
209 supporting interactive development. Factor applications are portable
210 between all common platforms. Factor can deploy stand-alone applications
211 on all platforms. Full source code for the Factor project is available
212 under a BSD license.
213 '';
214 license = licenses.bsd2;
215 maintainers = with maintainers; [ vrthra spacefrogg ];
216 platforms = lib.intersectLists platforms.x86_64 platforms.linux;
217 };
218}