{ lib , stdenv , cairo , curl , fetchurl , freealut , gdk-pixbuf , git , glib , gnome2 , graphviz , gtk2-x11 , interpreter , libGL , libGLU , libogg , librsvg , libvorbis , makeWrapper , ncurses , openal , openssl , pango , pcre , runCommand , runtimeShell , tzdata , udis86 , unzip , writeScriptBin , zlib }: let runtimeLibs = [ cairo freealut gdk-pixbuf glib gnome2.gtkglext graphviz gtk2-x11 libGL libGLU libogg libvorbis openal openssl pango pcre udis86 zlib ]; wrapFactorScript = { from, to ? false, runtimeLibs }: '' # Set Gdk pixbuf loaders file to the one from the build dependencies here unset GDK_PIXBUF_MODULE_FILE # Defined in gdk-pixbuf setup hook findGdkPixbufLoaders "${librsvg}" ${if to then "makeWrapper ${from} ${to}" else "wrapProgram ${from}"} \ --set GDK_PIXBUF_MODULE_FILE "$GDK_PIXBUF_MODULE_FILE" \ --argv0 factor \ --prefix LD_LIBRARY_PATH : /run/opengl-driver/lib:${lib.makeLibraryPath runtimeLibs} \ --prefix PATH : ${lib.makeBinPath [ graphviz ]} ''; wrapFactor = runtimeLibs: runCommand (lib.appendToName "with-libs" interpreter).name { nativeBuildInputs = [ makeWrapper ]; buildInputs = [ gdk-pixbuf ]; passthru.runtimeLibs = runtimeLibs ++ interpreter.runtimeLibs; } (wrapFactorScript { from = "${interpreter}/lib/factor/.factor.wrapped"; to = "$out/bin/factor"; runtimeLibs = (runtimeLibs ++ interpreter.runtimeLibs); }); # Development helper for use in nix shell wrapLocalFactor = writeScriptBin "wrapFactor" '' #!${runtimeShell} ${wrapFactorScript { from = "./factor"; inherit runtimeLibs; }} ln -sf factor.image .factor-wrapped.image ''; rev = "7999e72aecc3c5bc4019d43dc4697f49678cc3b4"; version = "0.98"; in stdenv.mkDerivation { pname = "factor-lang"; inherit version; src = fetchurl { url = "https://downloads.factorcode.org/releases/${version}/factor-src-${version}.zip"; sha256 = "01ip9mbnar4sv60d2wcwfz62qaamdvbykxw3gbhzqa25z36vi3ri"; }; patches = [ ./staging-command-line-0.98-pre.patch ./workdir-0.98-pre.patch ./adjust-paths-in-unit-tests.patch ]; nativeBuildInputs = [ git makeWrapper curl unzip wrapLocalFactor ]; buildInputs = runtimeLibs; postPatch = '' sed -ie '4i GIT_LABEL = heads/master-${rev}' GNUmakefile # There is no ld.so.cache in NixOS so we patch out calls to that completely. # This should work as long as no application code relies on `find-library*` # to return a match, which currently is the case and also a justified assumption. sed -ie "s#/sbin/ldconfig -p#cat $out/lib/factor/ld.so.cache#g" \ basis/alien/libraries/finder/linux/linux.factor # Some other hard-coded paths to fix: sed -i 's#/usr/share/zoneinfo/#${tzdata}/share/zoneinfo/#g' \ extra/tzinfo/tzinfo.factor sed -i 's#/usr/share/terminfo#${ncurses.out}/share/terminfo#g' \ extra/terminfo/terminfo.factor # De-memoize xdg-* functions, otherwise they break the image. sed -ie 's/^MEMO:/:/' basis/xdg/xdg.factor # update default paths in factor-listener.el for fuel mode substituteInPlace misc/fuel/fuel-listener.el \ --replace '(defcustom fuel-factor-root-dir nil' "(defcustom fuel-factor-root-dir \"$out/lib/factor\"" ''; buildPhase = '' runHook preBuild # Necessary here, because ld.so.cache is needed in its final location during rebuild. mkdir -p $out/bin $out/lib/factor patchShebangs ./build.sh # Factor uses XDG_CACHE_HOME for cache during compilation. # We can't have that. So, set it to $TMPDIR/.cache export XDG_CACHE_HOME=$TMPDIR/.cache && mkdir -p $XDG_CACHE_HOME # There is no ld.so.cache in NixOS so we construct one # out of known libraries. The side effect is that find-lib # will work only on the known libraries. There does not seem # to be a generic solution here. find $(echo ${lib.makeLibraryPath runtimeLibs} | sed -e 's#:# #g') -name \*.so.\* > $TMPDIR/so.lst (echo $(cat $TMPDIR/so.lst | wc -l) "libs found in cache \`/etc/ld.so.cache'"; for l in $(<$TMPDIR/so.lst); do echo " $(basename $l) (libc6,x86-64) => $l"; done)> $out/lib/factor/ld.so.cache make -j$NIX_BUILD_CORES linux-x86-64 printf "First build from upstream boot image\n" >&2 ./build.sh bootstrap printf "Rebuild boot image\n" >&2 ./factor -script -e='"unix-x86.64" USING: system bootstrap.image memory ; make-image save 0 exit' printf "Second build from local boot image\n" >&2 ./build.sh bootstrap runHook postBuild ''; # For now, the check phase runs, but should always return 0. This way the logs # contain the test failures until all unit tests are fixed. Then, it should # return 1 if any test failures have occured. doCheck = false; checkPhase = '' runHook preCheck set +e ./factor -e='USING: tools.test zealot.factor sequences namespaces formatting ; zealot-core-vocabs "compiler" suffix [ test ] each :test-failures test-failures get length "Number of failed Tests: %d\n" printf' [ $? -eq 0 ] || { mkdir -p "$out/nix-support" touch "$out/nix-support/failed" } set -e runHook postCheck ''; installPhase = '' runHook preInstall cp -r factor factor.image LICENSE.txt README.md basis core extra misc $out/lib/factor # Create a wrapper in bin/ and lib/factor/ ${wrapFactorScript { from = "$out/lib/factor/factor"; inherit runtimeLibs; }} mv $out/lib/factor/factor.image $out/lib/factor/.factor-wrapped.image cp $out/lib/factor/factor $out/bin/ # Emacs fuel expects the image being named `factor.image` in the factor base dir ln -s $out/lib/factor/.factor-wrapped.image $out/lib/factor/factor.image # install fuel mode for emacs mkdir -p $out/share/emacs/site-lisp ln -s $out/lib/factor/misc/fuel/*.el $out/share/emacs/site-lisp/ runHook postInstall ''; passthru = { inherit runtimeLibs wrapFactorScript; withLibs = wrapFactor; }; meta = with lib; { homepage = "https://factorcode.org/"; description = "A concatenative, stack-based programming language"; longDescription = '' The Factor programming language is a concatenative, stack-based programming language with high-level features including dynamic types, extensible syntax, macros, and garbage collection. On a practical side, Factor has a full-featured library, supports many different platforms, and has been extensively documented. The implementation is fully compiled for performance, while still supporting interactive development. Factor applications are portable between all common platforms. Factor can deploy stand-alone applications on all platforms. Full source code for the Factor project is available under a BSD license. ''; license = licenses.bsd2; maintainers = with maintainers; [ vrthra spacefrogg ]; platforms = lib.intersectLists platforms.x86_64 platforms.linux; mainProgram = "factor"; }; }