summary refs log blame commit diff
path: root/pkgs/development/compilers/factor-lang/factor98.nix
blob: c4a9a075fdf6b74210f4e7095d4feb454f16b433 (plain) (tree)












































































































































































































                                                                                                           
{ stdenv
, lib
, git
, curl
, makeWrapper
, runtimeShell
, fetchurl
, unzip
, runCommand
, writeScriptBin
, interpreter
, glib
, pango
, cairo
, gtk2-x11
, gdk-pixbuf
, gnome2
, pcre
, libGL
, libGLU
, freealut
, openssl
, udis86
, openal
, libogg
, libvorbis
, graphviz
, librsvg
, zlib
, tzdata
, ncurses
}:
let
  runtimeLibs = [
    glib
    pango
    cairo
    gtk2-x11
    gdk-pixbuf
    gnome2.gtkglext
    pcre
    libGL
    libGLU
    freealut
    openssl
    udis86
    openal
    libogg
    libvorbis
    graphviz
    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
    ./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 = http://factorcode.org;
    license = licenses.bsd2;
    description = "A concatenative, stack-based programming language";
    maintainers = with maintainers; [ vrthra spacefrogg ];
    platforms = lib.intersectLists platforms.x86_64 platforms.linux;
  };
}