summary refs log tree commit diff
path: root/pkgs/development/compilers/factor-lang/factor99.nix
diff options
context:
space:
mode:
Diffstat (limited to 'pkgs/development/compilers/factor-lang/factor99.nix')
-rw-r--r--pkgs/development/compilers/factor-lang/factor99.nix224
1 files changed, 224 insertions, 0 deletions
diff --git a/pkgs/development/compilers/factor-lang/factor99.nix b/pkgs/development/compilers/factor-lang/factor99.nix
new file mode 100644
index 00000000000..85ff98a28ba
--- /dev/null
+++ b/pkgs/development/compilers/factor-lang/factor99.nix
@@ -0,0 +1,224 @@
+{ 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 = "e10b64dbc53a8583098e73580a1eb9ff4ce0c709";
+  version = "0.99";
+
+in
+stdenv.mkDerivation {
+  pname = "factor-lang";
+  inherit version;
+
+  src = fetchurl {
+    url = "https://downloads.factorcode.org/releases/${version}/factor-src-${version}.zip";
+    sha256 = "f5626bb3119bd77de9ac3392fdbe188bffc26557fab3ea34f7ca21e372a8443e";
+  };
+
+  patches = [
+    ./staging-command-line-0.99-pre.patch
+    ./workdir-0.99-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";
+  };
+}