about summary refs log tree commit diff
path: root/nixpkgs/pkgs/development/tools/ocaml
diff options
context:
space:
mode:
authorAlyssa Ross <hi@alyssa.is>2019-01-07 02:18:36 +0000
committerAlyssa Ross <hi@alyssa.is>2019-01-07 02:18:47 +0000
commit36f56d99fa0a0765c9f1de4a5f17a9b05830c3f2 (patch)
treeb3faaf573407b32aa645237a4d16b82778a39a92 /nixpkgs/pkgs/development/tools/ocaml
parent4e31070265257dc67d120c27e0f75c2344fdfa9a (diff)
parentabf060725d7614bd3b9f96764262dfbc2f9c2199 (diff)
downloadnixlib-36f56d99fa0a0765c9f1de4a5f17a9b05830c3f2.tar
nixlib-36f56d99fa0a0765c9f1de4a5f17a9b05830c3f2.tar.gz
nixlib-36f56d99fa0a0765c9f1de4a5f17a9b05830c3f2.tar.bz2
nixlib-36f56d99fa0a0765c9f1de4a5f17a9b05830c3f2.tar.lz
nixlib-36f56d99fa0a0765c9f1de4a5f17a9b05830c3f2.tar.xz
nixlib-36f56d99fa0a0765c9f1de4a5f17a9b05830c3f2.tar.zst
nixlib-36f56d99fa0a0765c9f1de4a5f17a9b05830c3f2.zip
Add 'nixpkgs/' from commit 'abf060725d7614bd3b9f96764262dfbc2f9c2199'
git-subtree-dir: nixpkgs
git-subtree-mainline: 4e31070265257dc67d120c27e0f75c2344fdfa9a
git-subtree-split: abf060725d7614bd3b9f96764262dfbc2f9c2199
Diffstat (limited to 'nixpkgs/pkgs/development/tools/ocaml')
-rw-r--r--nixpkgs/pkgs/development/tools/ocaml/camlidl/default.nix51
-rw-r--r--nixpkgs/pkgs/development/tools/ocaml/camlp4/default.nix62
-rw-r--r--nixpkgs/pkgs/development/tools/ocaml/camlp5/META94
-rw-r--r--nixpkgs/pkgs/development/tools/ocaml/camlp5/default.nix57
-rw-r--r--nixpkgs/pkgs/development/tools/ocaml/cppo/default.nix51
-rw-r--r--nixpkgs/pkgs/development/tools/ocaml/dune/default.nix30
-rw-r--r--nixpkgs/pkgs/development/tools/ocaml/findlib/default.nix77
-rw-r--r--nixpkgs/pkgs/development/tools/ocaml/findlib/install_topfind.patch12
-rw-r--r--nixpkgs/pkgs/development/tools/ocaml/findlib/ldconf.patch8
-rw-r--r--nixpkgs/pkgs/development/tools/ocaml/js_of_ocaml/3.0.nix17
-rw-r--r--nixpkgs/pkgs/development/tools/ocaml/js_of_ocaml/Makefile.conf.diff10
-rw-r--r--nixpkgs/pkgs/development/tools/ocaml/js_of_ocaml/camlp4.nix13
-rw-r--r--nixpkgs/pkgs/development/tools/ocaml/js_of_ocaml/compiler.nix35
-rw-r--r--nixpkgs/pkgs/development/tools/ocaml/js_of_ocaml/default.nix39
-rw-r--r--nixpkgs/pkgs/development/tools/ocaml/js_of_ocaml/lwt.nix16
-rw-r--r--nixpkgs/pkgs/development/tools/ocaml/js_of_ocaml/ocamlbuild.nix15
-rw-r--r--nixpkgs/pkgs/development/tools/ocaml/js_of_ocaml/ppx.nix14
-rw-r--r--nixpkgs/pkgs/development/tools/ocaml/js_of_ocaml/ppx_deriving_json.nix15
-rw-r--r--nixpkgs/pkgs/development/tools/ocaml/js_of_ocaml/tyxml.nix16
-rw-r--r--nixpkgs/pkgs/development/tools/ocaml/merlin/default.nix22
-rw-r--r--nixpkgs/pkgs/development/tools/ocaml/oasis/default.nix34
-rw-r--r--nixpkgs/pkgs/development/tools/ocaml/obelisk/default.nix24
-rw-r--r--nixpkgs/pkgs/development/tools/ocaml/obuild/default.nix32
-rw-r--r--nixpkgs/pkgs/development/tools/ocaml/ocaml-top/default.nix25
-rw-r--r--nixpkgs/pkgs/development/tools/ocaml/ocamlbuild/default.nix35
-rw-r--r--nixpkgs/pkgs/development/tools/ocaml/ocamlformat/default.nix35
-rw-r--r--nixpkgs/pkgs/development/tools/ocaml/ocamlify/default.nix35
-rw-r--r--nixpkgs/pkgs/development/tools/ocaml/ocamlmod/default.nix32
-rw-r--r--nixpkgs/pkgs/development/tools/ocaml/ocamlscript/Makefile.patch70
-rw-r--r--nixpkgs/pkgs/development/tools/ocaml/ocamlscript/default.nix26
-rw-r--r--nixpkgs/pkgs/development/tools/ocaml/ocp-build/default.nix37
-rw-r--r--nixpkgs/pkgs/development/tools/ocaml/ocp-indent/default.nix31
-rw-r--r--nixpkgs/pkgs/development/tools/ocaml/ocp-index/default.nix29
-rw-r--r--nixpkgs/pkgs/development/tools/ocaml/ocsigen-i18n/default.nix31
-rw-r--r--nixpkgs/pkgs/development/tools/ocaml/omake/0.9.8.6-rc1.nix43
-rw-r--r--nixpkgs/pkgs/development/tools/ocaml/omake/default.nix24
-rw-r--r--nixpkgs/pkgs/development/tools/ocaml/omake/warn.patch10
-rw-r--r--nixpkgs/pkgs/development/tools/ocaml/opaline/default.nix27
-rw-r--r--nixpkgs/pkgs/development/tools/ocaml/opam/1.2.2.nix92
-rw-r--r--nixpkgs/pkgs/development/tools/ocaml/opam/default.nix114
-rw-r--r--nixpkgs/pkgs/development/tools/ocaml/opam/opam-mccs-darwin.patch18
-rw-r--r--nixpkgs/pkgs/development/tools/ocaml/opam/opam-pull-3487.patch23
-rw-r--r--nixpkgs/pkgs/development/tools/ocaml/opam/opam-shebangs.patch128
-rwxr-xr-xnixpkgs/pkgs/development/tools/ocaml/opam/opam.nix.pl130
-rw-r--r--nixpkgs/pkgs/development/tools/ocaml/utop/default.nix77
45 files changed, 1816 insertions, 0 deletions
diff --git a/nixpkgs/pkgs/development/tools/ocaml/camlidl/default.nix b/nixpkgs/pkgs/development/tools/ocaml/camlidl/default.nix
new file mode 100644
index 000000000000..7c7bf79acc7d
--- /dev/null
+++ b/nixpkgs/pkgs/development/tools/ocaml/camlidl/default.nix
@@ -0,0 +1,51 @@
+{ stdenv, fetchurl, ocaml, writeText }:
+
+let
+  pname = "camlidl";
+  webpage = "http://caml.inria.fr/pub/old_caml_site/camlidl/";
+in
+stdenv.mkDerivation rec {
+  name = "${pname}-${version}";
+  version = "1.05";
+
+  src = fetchurl {
+    url = "http://caml.inria.fr/pub/old_caml_site/distrib/bazar-ocaml/${pname}-${version}.tar.gz";
+    sha256 = "0483cs66zsxsavcllpw1qqvyhxb39ddil3h72clcd69g7fyxazl5";
+  };
+
+  buildInputs = [ ocaml ];
+
+  preBuild = ''
+    mv config/Makefile.unix config/Makefile
+    substituteInPlace config/Makefile --replace BINDIR=/usr/local/bin BINDIR=$out
+    substituteInPlace config/Makefile --replace OCAMLLIB=/usr/local/lib/ocaml OCAMLLIB=$out/lib/ocaml/${ocaml.version}/site-lib/camlidl
+    substituteInPlace config/Makefile --replace CPP=/lib/cpp CPP=${stdenv.cc}/bin/cpp
+    substituteInPlace config/Makefile --replace "OCAMLC=ocamlc -g" "OCAMLC=ocamlc -g -warn-error -31"
+    mkdir -p $out/lib/ocaml/${ocaml.version}/site-lib/camlidl/caml
+  '';
+
+  postInstall = ''
+    cat >$out/lib/ocaml/${ocaml.version}/site-lib/camlidl/META <<EOF
+    # Courtesy of GODI
+    description = "Stub generator"
+    version = "${version}"
+    archive(byte) = "com.cma"
+    archive(native) = "com.cmxa"
+    EOF
+    mkdir -p $out/bin
+    ln -s $out/camlidl $out/bin
+  '';
+
+  setupHook = writeText "setupHook.sh" ''
+    export CAML_LD_LIBRARY_PATH="''${CAML_LD_LIBRARY_PATH}''${CAML_LD_LIBRARY_PATH:+:}''$1/lib/ocaml/${ocaml.version}/site-lib/${name}/"
+    export NIX_CFLAGS_COMPILE+=" -isystem $1/lib/ocaml/${ocaml.version}/site-lib/camlidl"
+    export NIX_LDFLAGS+=" -L $1/lib/ocaml/${ocaml.version}/site-lib/camlidl"
+  '';
+
+  meta = {
+    description = "A stub code generator and COM binding for Objective Caml";
+    homepage = "${webpage}";
+    license = "LGPL";
+    maintainers = [ stdenv.lib.maintainers.roconnor ];
+  };
+}
diff --git a/nixpkgs/pkgs/development/tools/ocaml/camlp4/default.nix b/nixpkgs/pkgs/development/tools/ocaml/camlp4/default.nix
new file mode 100644
index 000000000000..2974ca965fdc
--- /dev/null
+++ b/nixpkgs/pkgs/development/tools/ocaml/camlp4/default.nix
@@ -0,0 +1,62 @@
+{ stdenv, fetchzip, which, ocaml, ocamlbuild }:
+
+let param = {
+  "4.02" = {
+     version = "4.02+6";
+     sha256 = "06yl4q0qazl7g25b0axd1gdkfd4qpqzs1gr5fkvmkrcbz113h1hj"; };
+  "4.03" = {
+     version = "4.03+1";
+     sha256 = "1f2ndch6f1m4fgnxsjb94qbpwjnjgdlya6pard44y6n0dqxi1wsq"; };
+  "4.04" = {
+     version = "4.04+1";
+     sha256 = "1ad7rygqjxrc1im95gw9lp8q83nhdaf383f2808f1p63yl42xm7k"; };
+  "4.05" = {
+     version = "4.05+1";
+     sha256 = "0wm795hpwvwpib9c9z6p8kw2fh7p7b2hml6g15z8zry3y7w738sv"; };
+  "4.06" = {
+     version = "4.06+1";
+     sha256 = "0fazfw2l7wdmbwnqc22xby5n4ri1wz27lw9pfzhsbcdrighykysf"; };
+  "4.07" = {
+     version = "4.07+1";
+     sha256 = "0cxl4hkqcvspvkx4f2k83217rh6051fll9i2yz7cw6m3bq57mdvl"; };
+  }."${ocaml.meta.branch}";
+in
+
+stdenv.mkDerivation rec {
+  name = "camlp4-${version}";
+  inherit (param) version;
+
+  src = fetchzip {
+    url = "https://github.com/ocaml/camlp4/archive/${version}.tar.gz";
+    inherit (param) sha256;
+  };
+
+  buildInputs = [ which ocaml ocamlbuild ];
+
+  dontAddPrefix = true;
+
+  preConfigure = ''
+    configureFlagsArray=(
+      --bindir=$out/bin
+      --libdir=$out/lib/ocaml/${ocaml.version}/site-lib
+      --pkgdir=$out/lib/ocaml/${ocaml.version}/site-lib
+    )
+  '';
+
+  postConfigure = ''
+    substituteInPlace camlp4/META.in \
+    --replace +camlp4 $out/lib/ocaml/${ocaml.version}/site-lib/camlp4
+  '';
+
+  makeFlags = "all";
+
+  installTargets = "install install-META";
+
+  dontStrip = true;
+
+  meta = with stdenv.lib; {
+    description = "A software system for writing extensible parsers for programming languages";
+    homepage = https://github.com/ocaml/camlp4;
+    platforms = ocaml.meta.platforms or [];
+  };
+}
diff --git a/nixpkgs/pkgs/development/tools/ocaml/camlp5/META b/nixpkgs/pkgs/development/tools/ocaml/camlp5/META
new file mode 100644
index 000000000000..e13b108ff247
--- /dev/null
+++ b/nixpkgs/pkgs/development/tools/ocaml/camlp5/META
@@ -0,0 +1,94 @@
+# Specifications for the "camlp5" preprocessor:
+requires = ""
+version = "[distributed with Ocaml]"
+description = "Base for camlp5 syntax extensions"
+
+# For the toploop:
+archive(byte,toploop,camlp5o) = "camlp5o.cma"
+archive(byte,toploop,camlp5r) = "camlp5r.cma"
+
+# Scheme-like syntax:
+# Do #predicates "syntax,camlp5scheme", followed by #require "camlp5"
+archive(byte,toploop,camlp5scheme) = "camlp5sch.cma"
+
+# Standard ML-like syntax:
+# Do #predicates "syntax,camlp5sml", followed by #require "camlp5"
+archive(byte,toploop,camlp5sml) = "gramlib.cma camlp5_top.cma pa_sml.cmo"
+
+# Lisp-like syntax:
+# Do #predicates "syntax,camlp5lisp", followed by #require "camlp5"
+archive(byte,toploop,camlp5lisp) = "gramlib.cma camlp5_top.cma pa_lisp.cmo"
+
+# For the preprocessor itself:
+archive(syntax,preprocessor,camlp5o) = "pa_o.cmo pa_op.cmo pr_dump.cmo"
+archive(syntax,preprocessor,camlp5r) = "pa_r.cmo pa_rp.cmo pr_dump.cmo"
+archive(syntax,preprocessor,camlp5sml) = "pa_sml.cmo pr_dump.cmo"
+archive(syntax,preprocessor,camlp5scheme) = "pa_scheme.cmo pr_dump.cmo"
+archive(syntax,preprocessor,camlp5lisp) = "pa_lisp.cmo pr_dump.cmo"
+preprocessor = "camlp5 -nolib"
+
+package "gramlib" (
+  requires(toploop) = "camlp5"
+  version = "[distributed with Ocaml]"
+  description = "Grammar library to create syntax extensions"
+  archive(byte) = "gramlib.cma"
+  archive(byte,toploop) = ""  # already contained in camlp5*.cma
+  archive(native) = "gramlib.cmxa"
+)
+
+package "quotations" (
+  requires = "camlp5"
+  version = "[distributed with Ocaml]"
+  description = "Syntax extension: Quotations to create AST nodes"
+  archive(syntax,preprocessor) = "q_MLast.cmo"
+  archive(syntax,toploop) = "q_MLast.cmo"
+)
+
+package "phony_quotations" (
+  requires = "camlp5"
+  version = "[distributed with Ocaml]"
+  description = "Syntax extension: Phony quotations"
+  archive(syntax,preprocessor) = "q_phony.cmo"
+  archive(syntax,toploop) = "q_phony.cmo"
+)
+
+package "extend" (
+  requires = "camlp5"
+  version = "[distributed with Ocaml]"
+  description = "Syntax extension: EXTEND the camlp5 grammar"
+  archive(syntax,preprocessor) = "pa_extend.cmo"
+  archive(syntax,toploop) = "pa_extend.cmo"
+)
+
+package "extfun" (
+  requires = "camlp5"
+  version = "[distributed with Ocaml]"
+  description = "Syntax extension: Extensible functions"
+  archive(syntax,preprocessor) = "pa_extfun.cmo"
+  archive(syntax,toploop) = "pa_extfun.cmo"
+)
+
+package "fstream" (
+  requires = "camlp5"
+  version = "[distributed with Ocaml]"
+  description = "Syntax extension: Functional stream parsers"
+  archive(syntax,preprocessor) = "pa_fstream.cmo"
+  archive(syntax,toploop) = "pa_fstream.cmo"
+)
+
+package "macro" (
+  requires = "camlp5"
+  version = "[distributed with Ocaml]"
+  description = "Syntax extension: Conditional compilation"
+  archive(syntax,preprocessor) = "pa_macro.cmo"
+  archive(syntax,toploop) = "pa_macro.cmo"
+)
+
+package "unit_constraints" (
+  requires = "camlp5"
+  version = "[distributed with Ocaml]"
+  description = "Syntax extension: Type constraints of type unit (revised syntax only)"
+  archive(syntax,preprocessor,camlp5r) = "pa_ru.cmo"
+  archive(syntax,toploop,camlp5r) = "pa_ru.cmo"
+  error(syntax,-camlp5r) = "Not available"
+)
diff --git a/nixpkgs/pkgs/development/tools/ocaml/camlp5/default.nix b/nixpkgs/pkgs/development/tools/ocaml/camlp5/default.nix
new file mode 100644
index 000000000000..ca053138d800
--- /dev/null
+++ b/nixpkgs/pkgs/development/tools/ocaml/camlp5/default.nix
@@ -0,0 +1,57 @@
+{ stdenv, fetchzip, ocaml, legacy ? false }:
+
+let params =
+  if legacy then {
+    minor-version = "06";
+    sha256 = "02zg6qjkzx58zmp79364s5jyqhh56nclcz1jzhh53hk37g9f96qf";
+  } else {
+    minor-version = "07";
+    sha256 = "1c8v45553ccbqha2ypfranqlgw06rr5wjr2hlnrx5bf9jfq0h0dn";
+  };
+  metafile = ./META;
+  opt = stdenv.lib.optionalString legacy;
+in
+
+stdenv.mkDerivation {
+
+  name = "camlp5-7.${params.minor-version}";
+
+  src = fetchzip {
+    url = "https://github.com/camlp5/camlp5/archive/rel7${params.minor-version}.tar.gz";
+    inherit (params) sha256;
+  };
+
+  buildInputs = [ ocaml ];
+
+  postPatch = opt ''
+    for p in compile/compile.sh config/Makefile.tpl test/Makefile test/check_ocaml_versions.sh
+    do
+      substituteInPlace $p --replace '/bin/rm' rm
+    done
+  '';
+
+  prefixKey = "-prefix ";
+
+  preConfigure = "configureFlagsArray=(--strict" +
+                  " --libdir $out/lib/ocaml/${ocaml.version}/site-lib)";
+
+  buildFlags = "world.opt";
+
+  postInstall = opt "cp ${metafile} $out/lib/ocaml/${ocaml.version}/site-lib/camlp5/META";
+
+  dontStrip = true;
+
+  meta = with stdenv.lib; {
+    description = "Preprocessor-pretty-printer for OCaml";
+    longDescription = ''
+      Camlp5 is a preprocessor and pretty-printer for OCaml programs.
+      It also provides parsing and printing tools.
+    '';
+    homepage = https://camlp5.github.io/;
+    license = licenses.bsd3;
+    platforms = ocaml.meta.platforms or [];
+    maintainers = with maintainers; [
+      z77z vbgl
+    ];
+  };
+}
diff --git a/nixpkgs/pkgs/development/tools/ocaml/cppo/default.nix b/nixpkgs/pkgs/development/tools/ocaml/cppo/default.nix
new file mode 100644
index 000000000000..0611ec8d3bbd
--- /dev/null
+++ b/nixpkgs/pkgs/development/tools/ocaml/cppo/default.nix
@@ -0,0 +1,51 @@
+{ stdenv, fetchFromGitHub, ocaml, findlib, ocamlbuild, dune }:
+let
+  pname = "cppo";
+  webpage = "http://mjambon.com/${pname}.html";
+in
+assert stdenv.lib.versionAtLeast ocaml.version "3.12";
+
+let param =
+  if stdenv.lib.versionAtLeast ocaml.version "4.02" then {
+    version = "1.6.4";
+    sha256 = "16mlwck0wngr5pmlr8dxc471zzhhcja3mv4xf4n8jm9nhb3iikvh";
+    buildInputs = [ dune ];
+    extra = {
+      inherit (dune) installPhase;
+    };
+  } else {
+    version = "1.5.0";
+    sha256 = "1xqldjz9risndnabvadw41fdbi5sa2hl4fnqls7j9xfbby1izbg8";
+    extra = {
+      createFindlibDestdir = true;
+      makeFlags = "PREFIX=$(out)";
+      preBuild = ''
+        mkdir $out/bin
+      '';
+    };
+  }
+; in
+
+stdenv.mkDerivation (rec {
+
+  name = "${pname}-${param.version}";
+
+  src = fetchFromGitHub {
+    owner = "mjambon";
+    repo = pname;
+    rev = "v${param.version}";
+    inherit (param) sha256;
+  };
+
+  buildInputs = [ ocaml findlib ocamlbuild ] ++ (param.buildInputs or []);
+
+  meta = with stdenv.lib; {
+    description = "The C preprocessor for OCaml";
+    longDescription = ''
+      Cppo is an equivalent of the C preprocessor targeted at the OCaml language and its variants.
+    '';
+    homepage = "${webpage}";
+    maintainers = [ maintainers.vbgl ];
+    license = licenses.bsd3;
+  };
+} // param.extra)
diff --git a/nixpkgs/pkgs/development/tools/ocaml/dune/default.nix b/nixpkgs/pkgs/development/tools/ocaml/dune/default.nix
new file mode 100644
index 000000000000..85fa76bb28e4
--- /dev/null
+++ b/nixpkgs/pkgs/development/tools/ocaml/dune/default.nix
@@ -0,0 +1,30 @@
+{ stdenv, fetchurl, ocamlPackages, opaline }:
+
+stdenv.mkDerivation rec {
+  name = "dune-${version}";
+  version = "1.6.2";
+  src = fetchurl {
+    url = "https://github.com/ocaml/dune/releases/download/${version}/dune-${version}.tbz";
+    sha256 = "1k675mfywmsj4v4z2f5a4vqinl1jbzzb7v5k6rzyfgvxzd7gil40";
+  };
+
+  buildInputs = with ocamlPackages; [ ocaml findlib ];
+
+  buildFlags = "release";
+
+  dontAddPrefix = true;
+
+  installPhase = ''
+    runHook preInstall
+    ${opaline}/bin/opaline -prefix $out -libdir $OCAMLFIND_DESTDIR
+    runHook postInstall
+  '';
+
+  meta = {
+    homepage = https://github.com/ocaml/dune;
+    description = "A composable build system";
+    maintainers = [ stdenv.lib.maintainers.vbgl ];
+    license = stdenv.lib.licenses.mit;
+    inherit (ocamlPackages.ocaml.meta) platforms;
+  };
+}
diff --git a/nixpkgs/pkgs/development/tools/ocaml/findlib/default.nix b/nixpkgs/pkgs/development/tools/ocaml/findlib/default.nix
new file mode 100644
index 000000000000..18b84e2c961d
--- /dev/null
+++ b/nixpkgs/pkgs/development/tools/ocaml/findlib/default.nix
@@ -0,0 +1,77 @@
+{ stdenv, fetchurl, fetchpatch, m4, ncurses, ocaml, writeText }:
+
+let param =
+  if stdenv.lib.versionAtLeast ocaml.version "4"
+  then {
+    version = "1.8.0";
+    sha256 = "1b97zqjdriqd2ikgh4rmqajgxwdwn013riji5j53y3xvcmnpsyrb";
+  } else {
+    version = "1.7.3";
+    sha256 = "12xx8si1qv3xz90qsrpazjjk4lc1989fzm97rsmc4diwla7n15ni";
+    patches = [ (fetchpatch {
+      url = "https://raw.githubusercontent.com/ocaml/opam-repository/1f29c5ef8eccd373e5ff2169a30bfd95a9ae6050/packages/ocamlfind/ocamlfind.1.7.3-1/files/threads.patch";
+      sha256 = "0cqgpjqpmfbr0ph3jr25gw8hgckj4qlfwmir6vkgi5hvn2qnjpx3";
+    }) ];
+  };
+in
+
+stdenv.mkDerivation rec {
+  name = "ocaml-findlib-${version}";
+  inherit (param) version;
+
+  src = fetchurl {
+    url = "http://download.camlcity.org/download/findlib-${version}.tar.gz";
+    inherit (param) sha256;
+  };
+
+  buildInputs = [m4 ncurses ocaml];
+
+  patches = [ ./ldconf.patch ./install_topfind.patch ]
+  ++ (param.patches or []);
+
+  dontAddPrefix=true;
+
+  preConfigure=''
+    configureFlagsArray=(
+      -bindir $out/bin
+      -mandir $out/share/man
+      -sitelib $out/lib/ocaml/${ocaml.version}/site-lib
+      -config $out/etc/findlib.conf
+    )
+  '';
+
+  buildPhase = ''
+    make all
+    make opt
+  '';
+
+  setupHook = writeText "setupHook.sh" ''
+    addOCamlPath () {
+        if test -d "''$1/lib/ocaml/${ocaml.version}/site-lib"; then
+            export OCAMLPATH="''${OCAMLPATH}''${OCAMLPATH:+:}''$1/lib/ocaml/${ocaml.version}/site-lib/"
+        fi
+        if test -d "''$1/lib/ocaml/${ocaml.version}/site-lib/stublibs"; then
+            export CAML_LD_LIBRARY_PATH="''${CAML_LD_LIBRARY_PATH}''${CAML_LD_LIBRARY_PATH:+:}''$1/lib/ocaml/${ocaml.version}/site-lib/stublibs"
+        fi
+        export OCAMLFIND_DESTDIR="''$out/lib/ocaml/${ocaml.version}/site-lib/"
+        if test -n "$createFindlibDestdir"; then
+          mkdir -p $OCAMLFIND_DESTDIR
+        fi
+    }
+
+    addEnvHooks "$targetOffset" addOCamlPath
+  '';
+
+  meta = {
+    homepage = http://projects.camlcity.org/projects/findlib.html;
+    description = "O'Caml library manager";
+    license = stdenv.lib.licenses.mit;
+    platforms = ocaml.meta.platforms or [];
+    maintainers = [
+      stdenv.lib.maintainers.z77z
+      stdenv.lib.maintainers.vbmithr
+    ];
+  };
+}
+
+
diff --git a/nixpkgs/pkgs/development/tools/ocaml/findlib/install_topfind.patch b/nixpkgs/pkgs/development/tools/ocaml/findlib/install_topfind.patch
new file mode 100644
index 000000000000..7cd32991d0eb
--- /dev/null
+++ b/nixpkgs/pkgs/development/tools/ocaml/findlib/install_topfind.patch
@@ -0,0 +1,12 @@
+--- a/src/findlib/Makefile
++++ b/src/findlib/Makefile
+@@ -123,7 +123,7 @@ clean:
+ install: all
+ 	mkdir -p "$(prefix)$(OCAML_SITELIB)/$(NAME)"
+ 	mkdir -p "$(prefix)$(OCAMLFIND_BIN)"
+-	test $(INSTALL_TOPFIND) -eq 0 || cp topfind "$(prefix)$(OCAML_CORE_STDLIB)"
++	test $(INSTALL_TOPFIND) -eq 0 || cp topfind "$(prefix)$(OCAML_SITELIB)"
+	files=`$(SH) $(TOP)/tools/collect_files $(TOP)/Makefile.config findlib.cmi findlib.mli findlib.cma findlib.cmxa findlib.a findlib.cmxs topfind.cmi topfind.mli fl_package_base.mli fl_package_base.cmi fl_metascanner.mli fl_metascanner.cmi fl_metatoken.cmi findlib_top.cma findlib_top.cmxa findlib_top.a findlib_top.cmxs findlib_dynload.cma findlib_dynload.cmxa findlib_dynload.a findlib_dynload.cmxs fl_dynload.mli fl_dynload.cmi META` && \
+	cp $$files "$(prefix)$(OCAML_SITELIB)/$(NAME)"
+	f="ocamlfind$(EXEC_SUFFIX)"; { test -f ocamlfind_opt$(EXEC_SUFFIX) && f="ocamlfind_opt$(EXEC_SUFFIX)"; }; \
+
diff --git a/nixpkgs/pkgs/development/tools/ocaml/findlib/ldconf.patch b/nixpkgs/pkgs/development/tools/ocaml/findlib/ldconf.patch
new file mode 100644
index 000000000000..7718cb673925
--- /dev/null
+++ b/nixpkgs/pkgs/development/tools/ocaml/findlib/ldconf.patch
@@ -0,0 +1,8 @@
+Setting paths to search for dnynmic libraries isn't very useful in Nix.
+
+--- findlib-1.2.6/findlib.conf.in	2010-08-17 14:50:28.000000000 -0400
++++ findlib-1.2.6/findlib.conf.in	2010-11-24 09:46:55.179648354 -0500
+@@ -1,2 +1,3 @@
+ destdir="@SITELIB@"
+ path="@SITELIB@"
++ldconf="ignore"
diff --git a/nixpkgs/pkgs/development/tools/ocaml/js_of_ocaml/3.0.nix b/nixpkgs/pkgs/development/tools/ocaml/js_of_ocaml/3.0.nix
new file mode 100644
index 000000000000..1307635abb99
--- /dev/null
+++ b/nixpkgs/pkgs/development/tools/ocaml/js_of_ocaml/3.0.nix
@@ -0,0 +1,17 @@
+{ stdenv, ocaml, findlib, dune, js_of_ocaml-compiler
+, ocaml-migrate-parsetree, ppx_tools_versioned, uchar
+}:
+
+stdenv.mkDerivation rec {
+	name = "js_of_ocaml-${version}"; 
+
+	inherit (js_of_ocaml-compiler) version src installPhase meta;
+
+	buildInputs = [ ocaml findlib dune ocaml-migrate-parsetree ppx_tools_versioned ];
+
+  postPatch = "patchShebangs lib/generate_stubs.sh";
+
+	propagatedBuildInputs = [ js_of_ocaml-compiler uchar ];
+
+	buildPhase = "dune build -p js_of_ocaml";
+}
diff --git a/nixpkgs/pkgs/development/tools/ocaml/js_of_ocaml/Makefile.conf.diff b/nixpkgs/pkgs/development/tools/ocaml/js_of_ocaml/Makefile.conf.diff
new file mode 100644
index 000000000000..e6fc96038ff8
--- /dev/null
+++ b/nixpkgs/pkgs/development/tools/ocaml/js_of_ocaml/Makefile.conf.diff
@@ -0,0 +1,10 @@
+--- old/Makefile.conf	2014-05-19 16:53:09.263564921 +0200
++++ new/Makefile.conf	2014-05-19 16:53:42.213152994 +0200
+@@ -1,6 +1,6 @@
+ 
+ # Where binaries are installed:
+-BINDIR := `dirname  \`which ocamlc\``
++BINDIR := $(out)/bin
+ 
+ ####
+ 
diff --git a/nixpkgs/pkgs/development/tools/ocaml/js_of_ocaml/camlp4.nix b/nixpkgs/pkgs/development/tools/ocaml/js_of_ocaml/camlp4.nix
new file mode 100644
index 000000000000..139ffef186b5
--- /dev/null
+++ b/nixpkgs/pkgs/development/tools/ocaml/js_of_ocaml/camlp4.nix
@@ -0,0 +1,13 @@
+{ stdenv, ocaml, findlib, dune, js_of_ocaml-compiler
+, camlp4, ocsigen_deriving
+}:
+
+stdenv.mkDerivation rec {
+	name = "js_of_ocaml-camlp4-${version}"; 
+
+	inherit (js_of_ocaml-compiler) version src installPhase meta;
+
+	buildInputs = [ ocaml findlib dune camlp4 ocsigen_deriving ];
+
+	buildPhase = "dune build -p js_of_ocaml-camlp4";
+}
diff --git a/nixpkgs/pkgs/development/tools/ocaml/js_of_ocaml/compiler.nix b/nixpkgs/pkgs/development/tools/ocaml/js_of_ocaml/compiler.nix
new file mode 100644
index 000000000000..94be7132b796
--- /dev/null
+++ b/nixpkgs/pkgs/development/tools/ocaml/js_of_ocaml/compiler.nix
@@ -0,0 +1,35 @@
+{ stdenv, fetchFromGitHub, ocaml, findlib, dune
+, cmdliner, cppo, yojson
+}:
+
+if !stdenv.lib.versionAtLeast ocaml.version "4.02"
+then throw "js_of_ocaml-compiler is not available for OCaml ${ocaml.version}"
+else
+
+stdenv.mkDerivation rec {
+	name = "js_of_ocaml-compiler-${version}";
+	version = "3.2.1";
+
+	src = fetchFromGitHub {
+		owner = "ocsigen";
+		repo = "js_of_ocaml";
+		rev = version;
+		sha256 = "1v2hfq0ra9j07yz6pj6m03hrvgys4vmx0gclchv94yywpb2wc7ik";
+	};
+
+	buildInputs = [ ocaml findlib dune cmdliner cppo ];
+
+	propagatedBuildInputs = [ yojson ];
+
+	buildPhase = "dune build -p js_of_ocaml-compiler";
+
+	inherit (dune) installPhase;
+
+	meta = {
+		description = "Compiler from OCaml bytecode to Javascript";
+		license = stdenv.lib.licenses.gpl2;
+		maintainers = [ stdenv.lib.maintainers.vbgl ];
+		inherit (src.meta) homepage;
+		inherit (ocaml.meta) platforms;
+	};
+}
diff --git a/nixpkgs/pkgs/development/tools/ocaml/js_of_ocaml/default.nix b/nixpkgs/pkgs/development/tools/ocaml/js_of_ocaml/default.nix
new file mode 100644
index 000000000000..f88811855a2e
--- /dev/null
+++ b/nixpkgs/pkgs/development/tools/ocaml/js_of_ocaml/default.nix
@@ -0,0 +1,39 @@
+{ stdenv, fetchurl, ocaml, findlib, lwt, menhir, ocsigen_deriving, ppx_deriving, camlp4, ocamlbuild
+, cmdliner, tyxml, reactivedata, cppo, which, base64, uchar, yojson
+}:
+
+let version = if stdenv.lib.versionAtLeast ocaml.version "4.02"
+  then "2.8.4" else "2.7";
+in
+
+stdenv.mkDerivation {
+  name = "js_of_ocaml-${version}";
+  src = fetchurl {
+    url = "https://github.com/ocsigen/js_of_ocaml/archive/${version}.tar.gz";
+    sha256 = {
+      "2.7" = "1dali1akyd4zmkwav0d957ynxq2jj6cc94r4xiaql7ca89ajz4jj";
+      "2.8.4" = "098ph50s9kqw6rc3qjn39zv9b5swdf4qr44afwqfkkjgjs5d7vbl";
+    }."${version}";
+  };
+
+  buildInputs = [ ocaml findlib menhir ocsigen_deriving ocamlbuild
+                 cmdliner reactivedata cppo which base64 ]
+  ++ stdenv.lib.optionals (stdenv.lib.versionAtLeast ocaml.version "4.02") [ yojson tyxml ];
+  propagatedBuildInputs = [ lwt camlp4 ppx_deriving ]
+  ++ stdenv.lib.optional (version == "2.8.4") uchar;
+
+  patches = [ ./Makefile.conf.diff ];
+
+  createFindlibDestdir = true;
+
+  meta = with stdenv.lib; {
+    homepage = http://ocsigen.org/js_of_ocaml/;
+    description = "Compiler of OCaml bytecode to Javascript. It makes it possible to run Ocaml programs in a Web browser";
+    license = licenses.lgpl2;
+    platforms = ocaml.meta.platforms or [];
+    maintainers = [
+      maintainers.gal_bolle
+    ];
+    broken = versionAtLeast ocaml.version "4.05";
+  };
+}
diff --git a/nixpkgs/pkgs/development/tools/ocaml/js_of_ocaml/lwt.nix b/nixpkgs/pkgs/development/tools/ocaml/js_of_ocaml/lwt.nix
new file mode 100644
index 000000000000..e7a31c1ce2e5
--- /dev/null
+++ b/nixpkgs/pkgs/development/tools/ocaml/js_of_ocaml/lwt.nix
@@ -0,0 +1,16 @@
+{ stdenv, ocaml, findlib, dune, js_of_ocaml-compiler, js_of_ocaml-ppx
+, ocaml-migrate-parsetree, ppx_tools_versioned
+, js_of_ocaml, ocaml_lwt, lwt_log
+}:
+
+stdenv.mkDerivation rec {
+	name = "js_of_ocaml-lwt-${version}"; 
+
+	inherit (js_of_ocaml-compiler) version src installPhase meta;
+
+	buildInputs = [ ocaml findlib dune js_of_ocaml-ppx ocaml-migrate-parsetree ppx_tools_versioned ];
+
+	propagatedBuildInputs = [ js_of_ocaml ocaml_lwt lwt_log ];
+
+	buildPhase = "dune build -p js_of_ocaml-lwt";
+}
diff --git a/nixpkgs/pkgs/development/tools/ocaml/js_of_ocaml/ocamlbuild.nix b/nixpkgs/pkgs/development/tools/ocaml/js_of_ocaml/ocamlbuild.nix
new file mode 100644
index 000000000000..bf33b4e59e52
--- /dev/null
+++ b/nixpkgs/pkgs/development/tools/ocaml/js_of_ocaml/ocamlbuild.nix
@@ -0,0 +1,15 @@
+{ stdenv, ocaml, findlib, dune, js_of_ocaml-compiler
+, ocamlbuild
+}:
+
+stdenv.mkDerivation rec {
+	name = "js_of_ocaml-ocamlbuild-${version}"; 
+
+	inherit (js_of_ocaml-compiler) version src installPhase meta;
+
+	buildInputs = [ ocaml findlib dune ];
+
+	propagatedBuildInputs = [ ocamlbuild ];
+
+	buildPhase = "dune build -p js_of_ocaml-ocamlbuild";
+}
diff --git a/nixpkgs/pkgs/development/tools/ocaml/js_of_ocaml/ppx.nix b/nixpkgs/pkgs/development/tools/ocaml/js_of_ocaml/ppx.nix
new file mode 100644
index 000000000000..0649aee162a5
--- /dev/null
+++ b/nixpkgs/pkgs/development/tools/ocaml/js_of_ocaml/ppx.nix
@@ -0,0 +1,14 @@
+{ stdenv, ocaml, findlib, dune, js_of_ocaml-compiler
+, ocaml-migrate-parsetree, ppx_tools_versioned
+, js_of_ocaml
+}:
+
+stdenv.mkDerivation rec {
+	name = "js_of_ocaml-ppx-${version}"; 
+
+	inherit (js_of_ocaml-compiler) version src installPhase meta;
+
+	buildInputs = [ ocaml findlib dune ocaml-migrate-parsetree ppx_tools_versioned js_of_ocaml ];
+
+	buildPhase = "dune build -p js_of_ocaml-ppx";
+}
diff --git a/nixpkgs/pkgs/development/tools/ocaml/js_of_ocaml/ppx_deriving_json.nix b/nixpkgs/pkgs/development/tools/ocaml/js_of_ocaml/ppx_deriving_json.nix
new file mode 100644
index 000000000000..ddea73b3c766
--- /dev/null
+++ b/nixpkgs/pkgs/development/tools/ocaml/js_of_ocaml/ppx_deriving_json.nix
@@ -0,0 +1,15 @@
+{ stdenv, ocaml, findlib, dune, js_of_ocaml-compiler
+, js_of_ocaml, ppx_deriving
+}:
+
+stdenv.mkDerivation rec {
+	name = "js_of_ocaml-ppx_deriving_json-${version}";
+
+	inherit (js_of_ocaml-compiler) version src installPhase meta;
+
+	buildInputs = [ ocaml findlib dune ];
+
+	propagatedBuildInputs = [ js_of_ocaml ppx_deriving ];
+
+	buildPhase = "dune build -p js_of_ocaml-ppx_deriving_json";
+}
diff --git a/nixpkgs/pkgs/development/tools/ocaml/js_of_ocaml/tyxml.nix b/nixpkgs/pkgs/development/tools/ocaml/js_of_ocaml/tyxml.nix
new file mode 100644
index 000000000000..1ba9ddd0ab7f
--- /dev/null
+++ b/nixpkgs/pkgs/development/tools/ocaml/js_of_ocaml/tyxml.nix
@@ -0,0 +1,16 @@
+{ stdenv, ocaml, findlib, dune, js_of_ocaml-compiler
+, js_of_ocaml-ppx, ocaml-migrate-parsetree, ppx_tools_versioned
+, js_of_ocaml, reactivedata, tyxml
+}:
+
+stdenv.mkDerivation rec {
+	name = "js_of_ocaml-tyxml-${version}";
+
+	inherit (js_of_ocaml-compiler) version src installPhase meta;
+
+	buildInputs = [ ocaml findlib dune js_of_ocaml-ppx ocaml-migrate-parsetree ppx_tools_versioned ];
+
+	propagatedBuildInputs = [ js_of_ocaml reactivedata tyxml ];
+
+	buildPhase = "dune build -p js_of_ocaml-tyxml";
+}
diff --git a/nixpkgs/pkgs/development/tools/ocaml/merlin/default.nix b/nixpkgs/pkgs/development/tools/ocaml/merlin/default.nix
new file mode 100644
index 000000000000..e059a5d6a76c
--- /dev/null
+++ b/nixpkgs/pkgs/development/tools/ocaml/merlin/default.nix
@@ -0,0 +1,22 @@
+{ stdenv, fetchzip, buildDunePackage, yojson }:
+
+buildDunePackage rec {
+  pname = "merlin";
+  version = "3.2.2";
+
+  minimumOCamlVersion = "4.02";
+
+  src = fetchzip {
+    url = "https://github.com/ocaml/merlin/archive/v${version}.tar.gz";
+    sha256 = "15ssgmwdxylbwhld9p1cq8x6kadxyhll5bfyf11dddj6cldna3hb";
+  };
+
+  buildInputs = [ yojson ];
+
+  meta = with stdenv.lib; {
+    description = "An editor-independent tool to ease the development of programs in OCaml";
+    homepage = "https://github.com/ocaml/merlin";
+    license = licenses.mit;
+    maintainers = [ maintainers.vbgl ];
+  };
+}
diff --git a/nixpkgs/pkgs/development/tools/ocaml/oasis/default.nix b/nixpkgs/pkgs/development/tools/ocaml/oasis/default.nix
new file mode 100644
index 000000000000..2364058729e8
--- /dev/null
+++ b/nixpkgs/pkgs/development/tools/ocaml/oasis/default.nix
@@ -0,0 +1,34 @@
+{ stdenv, fetchurl, ocaml, findlib, ocamlbuild, ocamlmod, ocamlify }:
+
+stdenv.mkDerivation rec {
+  version = "0.4.10";
+  name = "ocaml-oasis-${version}";
+
+  # You must manually update the url, not just the version. OCamlforge keys off
+  # the number after download.php, not the filename.
+  src = fetchurl {
+    url = https://forge.ocamlcore.org/frs/download.php/1694/oasis-0.4.10.tar.gz;
+    sha256 = "13ah03pbcvrjv5lmx971hvkm9rvbvimska5wmjfvgvd20ca0gn8w";
+  };
+
+  createFindlibDestdir = true;
+
+  buildInputs =
+    [
+      ocaml findlib ocamlbuild ocamlmod ocamlify
+    ];
+
+  configurePhase = "ocaml setup.ml -configure --prefix $out";
+  buildPhase     = "ocaml setup.ml -build";
+  installPhase   = "ocaml setup.ml -install";
+
+  meta = with stdenv.lib; {
+    homepage = http://oasis.forge.ocamlcore.org/;
+    description = "Configure, build and install system for OCaml projects";
+    license = licenses.lgpl21;
+    platforms = ocaml.meta.platforms or [];
+    maintainers = with maintainers; [
+      vbgl z77z
+    ];
+  };
+}
diff --git a/nixpkgs/pkgs/development/tools/ocaml/obelisk/default.nix b/nixpkgs/pkgs/development/tools/ocaml/obelisk/default.nix
new file mode 100644
index 000000000000..0f072c5dd931
--- /dev/null
+++ b/nixpkgs/pkgs/development/tools/ocaml/obelisk/default.nix
@@ -0,0 +1,24 @@
+{ stdenv, fetchFromGitHub, ocamlPackages }:
+
+stdenv.mkDerivation rec {
+	name = "obelisk-${version}";
+	version = "0.3.0";
+	src = fetchFromGitHub {
+		owner = "lelio-brun";
+		repo = "obelisk";
+		rev = "v${version}";
+		sha256 = "12gldzi1mp15vwkk6llz2ignpc8ndqlycm88njb4k7r9hpv59m97";
+	};
+
+	buildInputs = with ocamlPackages; [ ocaml findlib ocamlbuild menhir ];
+
+	installFlags = [ "BINDIR=$(out)/bin" ];
+
+	meta = {
+		description = "A simple tool which produces pretty-printed output from a Menhir parser file (.mly)";
+		license = stdenv.lib.licenses.mit;
+		maintainers = [ stdenv.lib.maintainers.vbgl ];
+		inherit (src.meta) homepage;
+		inherit (ocamlPackages.ocaml.meta) platforms;
+	};
+}
diff --git a/nixpkgs/pkgs/development/tools/ocaml/obuild/default.nix b/nixpkgs/pkgs/development/tools/ocaml/obuild/default.nix
new file mode 100644
index 000000000000..41cde6f8ab73
--- /dev/null
+++ b/nixpkgs/pkgs/development/tools/ocaml/obuild/default.nix
@@ -0,0 +1,32 @@
+{ stdenv, fetchzip, ocaml }:
+
+let version = "0.1.10"; in
+
+stdenv.mkDerivation {
+  name = "obuild-${version}";
+
+  src = fetchzip {
+    url = "https://github.com/ocaml-obuild/obuild/archive/obuild-v${version}.tar.gz";
+    sha256 = "15arsgbhk1c39vd8qhpa3pag94m44bwvzggdvkibx6hnpkv8z9bn";
+  };
+
+  buildInputs = [ ocaml ];
+
+  buildPhase = ''
+    patchShebangs ./bootstrap
+    ./bootstrap
+  '';
+
+  installPhase = ''
+    mkdir -p $out/bin
+    cp dist/build/obuild/obuild dist/build/obuild-from-oasis/obuild-from-oasis dist/build/obuild-simple/obuild-simple $out/bin/
+  '';
+
+  meta = {
+    homepage = https://github.com/ocaml-obuild/obuild;
+    platforms = ocaml.meta.platforms or [];
+    description = "Simple package build system for OCaml";
+    license = stdenv.lib.licenses.lgpl21;
+    maintainers = with stdenv.lib.maintainers; [ volth ];
+  };
+}
diff --git a/nixpkgs/pkgs/development/tools/ocaml/ocaml-top/default.nix b/nixpkgs/pkgs/development/tools/ocaml/ocaml-top/default.nix
new file mode 100644
index 000000000000..7336439240d5
--- /dev/null
+++ b/nixpkgs/pkgs/development/tools/ocaml/ocaml-top/default.nix
@@ -0,0 +1,25 @@
+{ stdenv, fetchzip, ncurses, ocamlPackages }:
+
+with ocamlPackages; buildDunePackage rec {
+  pname = "ocaml-top";
+  version = "1.1.5";
+
+  src = fetchzip {
+    url = "https://github.com/OCamlPro/ocaml-top/archive/${version}.tar.gz";
+    sha256 = "1d4i6aanrafgrgk4mh154k6lkwk0b6mh66rykz33awlf5pfqd8yv";
+  };
+
+  buildInputs = [ ncurses ocp-build lablgtk ocp-index ];
+
+  configurePhase = ''
+    export TERM=xterm
+    ocp-build -init
+  '';
+
+  meta = {
+    homepage = https://www.typerex.org/ocaml-top.html;
+    license = stdenv.lib.licenses.gpl3;
+    description = "A simple cross-platform OCaml code editor built for top-level evaluation";
+    maintainers = with stdenv.lib.maintainers; [ vbgl ];
+  };
+}
diff --git a/nixpkgs/pkgs/development/tools/ocaml/ocamlbuild/default.nix b/nixpkgs/pkgs/development/tools/ocaml/ocamlbuild/default.nix
new file mode 100644
index 000000000000..3f42e71e7783
--- /dev/null
+++ b/nixpkgs/pkgs/development/tools/ocaml/ocamlbuild/default.nix
@@ -0,0 +1,35 @@
+{ stdenv, fetchFromGitHub, ocaml, findlib }:
+let
+  version = "0.12.0";
+in
+stdenv.mkDerivation {
+  name = "ocamlbuild-${version}";
+  inherit version;
+
+  src = fetchFromGitHub {
+    owner = "ocaml";
+    repo = "ocamlbuild";
+    rev = version;
+    sha256 = "1shyim50ms0816fphc4mk0kldcx3pnba2i6m10q0cbm18m9d7chq";
+  };
+
+  createFindlibDestdir = true;
+
+  buildInputs = [ ocaml findlib ];
+
+  configurePhase = ''
+  make -f configure.make Makefile.config \
+    "OCAMLBUILD_PREFIX=$out" \
+    "OCAMLBUILD_BINDIR=$out/bin" \
+    "OCAMLBUILD_MANDIR=$out/share/man" \
+    "OCAMLBUILD_LIBDIR=$OCAMLFIND_DESTDIR"
+  '';
+
+  meta = with stdenv.lib; {
+    homepage = https://github.com/ocaml/ocamlbuild/;
+    description = "A build system with builtin rules to easily build most OCaml projects";
+    license = licenses.lgpl2;
+    inherit (ocaml.meta) platforms;
+    maintainers = with maintainers; [ vbgl ];
+  };
+}
diff --git a/nixpkgs/pkgs/development/tools/ocaml/ocamlformat/default.nix b/nixpkgs/pkgs/development/tools/ocaml/ocamlformat/default.nix
new file mode 100644
index 000000000000..694f4b6e89a0
--- /dev/null
+++ b/nixpkgs/pkgs/development/tools/ocaml/ocamlformat/default.nix
@@ -0,0 +1,35 @@
+{ stdenv, fetchFromGitHub, ocamlPackages }:
+
+with ocamlPackages; buildDunePackage rec {
+  pname = "ocamlformat";
+  version = "0.8";
+
+  minimumOCamlVersion = "4.05";
+
+  src = fetchFromGitHub {
+    owner = "ocaml-ppx";
+    repo = pname;
+    rev = version;
+    sha256 = "1i7rsbs00p43362yv7z7dw0qsnv7vjf630qk676qvfg7kg422w6j";
+  };
+
+  buildInputs = [
+    base
+    cmdliner
+    fpath
+    ocaml-migrate-parsetree
+    stdio
+  ];
+
+  configurePhase = ''
+    patchShebangs tools/gen_version.sh
+    tools/gen_version.sh src/Version.ml version
+  '';
+
+  meta = {
+    inherit (src.meta) homepage;
+    description = "Auto-formatter for OCaml code";
+    maintainers = [ stdenv.lib.maintainers.Zimmi48 ];
+    license = stdenv.lib.licenses.mit;
+  };
+}
diff --git a/nixpkgs/pkgs/development/tools/ocaml/ocamlify/default.nix b/nixpkgs/pkgs/development/tools/ocaml/ocamlify/default.nix
new file mode 100644
index 000000000000..df480903d154
--- /dev/null
+++ b/nixpkgs/pkgs/development/tools/ocaml/ocamlify/default.nix
@@ -0,0 +1,35 @@
+{ stdenv, fetchurl, ocaml, findlib, ocamlbuild }:
+
+stdenv.mkDerivation {
+  name = "ocamlify-0.0.2";
+
+  src = fetchurl {
+    url = http://forge.ocamlcore.org/frs/download.php/1209/ocamlify-0.0.2.tar.gz;
+    sha256 = "1f0fghvlbfryf5h3j4as7vcqrgfjb4c8abl5y0y5h069vs4kp5ii";
+  };
+
+  buildInputs = [ ocaml findlib ocamlbuild ];
+
+  configurePhase = ''
+    substituteInPlace src/ocamlify.ml --replace 'OCamlifyConfig.version' '"0.0.2"'
+  '';
+
+  buildPhase = "ocamlbuild src/ocamlify.native";
+
+  installPhase = ''
+    mkdir -p $out/bin
+    mv _build/src/ocamlify.native $out/bin/ocamlify
+  '';
+
+  dontStrip = true;
+
+  meta = {
+    homepage = http://forge.ocamlcore.org/projects/ocamlmod/ocamlmod;
+    description = "Generate OCaml modules from source files";
+    platforms = ocaml.meta.platforms or [];
+    license = stdenv.lib.licenses.lgpl21;
+    maintainers = with stdenv.lib.maintainers; [
+      z77z
+    ];
+  };
+}
diff --git a/nixpkgs/pkgs/development/tools/ocaml/ocamlmod/default.nix b/nixpkgs/pkgs/development/tools/ocaml/ocamlmod/default.nix
new file mode 100644
index 000000000000..74dee630d295
--- /dev/null
+++ b/nixpkgs/pkgs/development/tools/ocaml/ocamlmod/default.nix
@@ -0,0 +1,32 @@
+{ stdenv, fetchurl, ocaml, findlib, ocamlbuild, ounit }:
+
+stdenv.mkDerivation rec {
+  name = "ocamlmod-${version}";
+  version = "0.0.9";
+
+  src = fetchurl {
+    url = "https://forge.ocamlcore.org/frs/download.php/1702/ocamlmod-0.0.9.tar.gz";
+    sha256 = "0cgp9qqrq7ayyhddrmqmq1affvfqcn722qiakjq4dkywvp67h4aa";
+  };
+
+  buildInputs = [ ocaml findlib ocamlbuild ounit ];
+
+  configurePhase = "ocaml setup.ml -configure --prefix $out --enable-tests";
+  buildPhase     = "ocaml setup.ml -build";
+  installPhase   = "ocaml setup.ml -install";
+
+  doCheck = true;
+
+  checkPhase = "ocaml setup.ml -test";
+
+  dontStrip = true;
+
+  meta = {
+    homepage = http://forge.ocamlcore.org/projects/ocamlmod/ocamlmod;
+    description = "Generate OCaml modules from source files";
+    platforms = ocaml.meta.platforms or [];
+    maintainers = with stdenv.lib.maintainers; [
+      z77z
+    ];
+  };
+}
diff --git a/nixpkgs/pkgs/development/tools/ocaml/ocamlscript/Makefile.patch b/nixpkgs/pkgs/development/tools/ocaml/ocamlscript/Makefile.patch
new file mode 100644
index 000000000000..4fc887c070d7
--- /dev/null
+++ b/nixpkgs/pkgs/development/tools/ocaml/ocamlscript/Makefile.patch
@@ -0,0 +1,70 @@
+--- a/Makefile	2012-02-04 01:24:21.000000000 +0000
++++ b/Makefile	2014-10-29 14:42:08.690188302 +0000
+@@ -4,6 +4,8 @@
+   version.ml pipeline.mli pipeline.ml common.mli common.ml \
+   utils.mli utils.ml ocaml.mli ocaml.ml
+ 
++CAMLP4 := $(shell ocamlfind query camlp4)
++
+ STDBIN = $(shell dirname `which ocamlfind`)
+ ifndef PREFIX
+   PREFIX = $(shell dirname $(STDBIN))
+@@ -15,7 +17,7 @@
+ endif
+ export BINDIR
+ 
+-PACKS = unix str
++PACKS = unix str findlib
+ PP = camlp4o -I . -parser pa_tryfinally.cmo -parser pa_opt.cmo
+ export PP
+ 
+@@ -36,11 +38,11 @@
+ 
+ common: version.ml
+ 	ocamlc -pp 'camlp4orf -loc _loc' -c \
+-		-I +camlp4 pa_opt310.ml && \
++		-I $(CAMLP4) pa_opt310.ml && \
+ 		cp pa_opt310.cmo pa_opt.cmo && \
+ 		cp pa_opt310.cmi pa_opt.cmi
+ 	ocamlc -pp 'camlp4orf -loc _loc' -c \
+-		-I +camlp4 pa_tryfinally310.ml && \
++		-I $(CAMLP4) pa_tryfinally310.ml && \
+ 		cp pa_tryfinally310.cmo pa_tryfinally.cmo && \
+ 		cp pa_tryfinally310.cmi pa_tryfinally.cmi
+ 
+--- a/main.ml	2014-11-08 09:05:12.516401313 +0000
++++ b/main.ml	2014-11-08 09:09:59.801311230 +0000
+@@ -250,9 +250,15 @@
+ 			Sys.getcwd ())
+       | `File script_name -> "", get_dir script_name in
+ 
++  let findlibdir =
++    Filename.(
++      concat (Findlib.package_directory "findlib") parent_dir_name
++    ) in
++
+   let file, oc = Filename.open_temp_file "meta" ".ml" in
+   fprintf oc "\
+ #%i %S;;
++#directory \"%s\";;
+ #use \"topfind\";;
+ #require \"ocamlscript\";;
+ Ocamlscript.Common.verbose := %s;;
+@@ -261,7 +267,7 @@
+ open Ocamlscript;;
+ open Utils;;
+ #%i %S;;\n"
+-     pos source verbose script_dir extra_args trash pos source;
++     pos source findlibdir verbose script_dir extra_args trash pos source;
+   
+   List.iter (output_line oc) lines;
+ 
+@@ -544,6 +550,7 @@
+       exit compilation_status
+ 
+ let _ =
++  Findlib.init ();
+   try main ()
+   with Failure s ->
+     eprintf "ocamlscript: %s\n%!" s;
+ 
diff --git a/nixpkgs/pkgs/development/tools/ocaml/ocamlscript/default.nix b/nixpkgs/pkgs/development/tools/ocaml/ocamlscript/default.nix
new file mode 100644
index 000000000000..28efaf4cf3d2
--- /dev/null
+++ b/nixpkgs/pkgs/development/tools/ocaml/ocamlscript/default.nix
@@ -0,0 +1,26 @@
+{stdenv, fetchurl, ocaml, findlib, camlp4}:
+stdenv.mkDerivation {
+  name = "ocamlscript-2.0.3";
+  src = fetchurl {
+    url = http://mjambon.com/releases/ocamlscript/ocamlscript-2.0.3.tar.gz;
+    sha256 = "1v1i24gijxwris8w4hi95r9swld6dm7jbry0zp72767a3g5ivlrd";
+  };
+
+  propagatedBuildInputs = [ ocaml findlib camlp4 ];
+
+  patches = [ ./Makefile.patch ];
+
+  buildFlags = "PREFIX=$(out)";
+  installFlags = "PREFIX=$(out)";
+
+  preInstall = "mkdir $out/bin";
+  createFindlibDestdir = true;
+
+  meta = with stdenv.lib; {
+    homepage = http://martin.jambon.free.fr/ocamlscript.html;
+    license = licenses.boost;
+    platforms = ocaml.meta.platforms or [];
+    description = "Natively-compiled OCaml scripts";
+    maintainers = [ maintainers.vbgl ];
+  };
+}
diff --git a/nixpkgs/pkgs/development/tools/ocaml/ocp-build/default.nix b/nixpkgs/pkgs/development/tools/ocaml/ocp-build/default.nix
new file mode 100644
index 000000000000..0ed7312660a1
--- /dev/null
+++ b/nixpkgs/pkgs/development/tools/ocaml/ocp-build/default.nix
@@ -0,0 +1,37 @@
+{ stdenv, fetchFromGitHub, ocaml, findlib, ncurses }:
+let
+  version = "1.99.19-beta";
+in
+stdenv.mkDerivation rec {
+
+  name = "ocaml${ocaml.version}-ocp-build-${version}";
+
+  src = fetchFromGitHub {
+    owner = "OCamlPro";
+    repo = "ocp-build";
+    rev = version;
+    sha256 = "162k5l0cxyqanxlml5v8mqapdq5qbqc9m4b8wdjq7mf523b3h2zj";
+  };
+
+  buildInputs = [ ocaml findlib ];
+  propagatedBuildInputs = [ ncurses ];
+  preInstall = "mkdir -p $out/bin";
+  preConfigure = ''
+  export configureFlags="$configureFlags --with-metadir=$OCAMLFIND_DESTDIR"
+  '';
+
+  meta = with stdenv.lib; {
+    homepage = https://www.typerex.org/ocp-build.html;
+    description = "A build tool for OCaml";
+    longDescription = ''
+      ocp-build is a build system for OCaml application, based on simple
+      descriptions of packages. ocp-build combines the descriptions of
+      packages, and optimize the parallel compilation of files depending on
+      the number of cores and the automatically-inferred dependencies
+      between source files.
+    '';
+    license = licenses.gpl3;
+    platforms = ocaml.meta.platforms or [];
+    maintainers = [ maintainers.jirkamarsik ];
+  };
+}
diff --git a/nixpkgs/pkgs/development/tools/ocaml/ocp-indent/default.nix b/nixpkgs/pkgs/development/tools/ocaml/ocp-indent/default.nix
new file mode 100644
index 000000000000..2cffccdbfcdf
--- /dev/null
+++ b/nixpkgs/pkgs/development/tools/ocaml/ocp-indent/default.nix
@@ -0,0 +1,31 @@
+{ stdenv, fetchzip, ocaml, findlib, dune, ocp-build, cmdliner }:
+
+let inherit (stdenv.lib) getVersion versionAtLeast; in
+
+assert versionAtLeast (getVersion ocaml) "3.12.1";
+assert versionAtLeast (getVersion cmdliner) "1.0.0";
+assert versionAtLeast (getVersion ocp-build) "1.99.6-beta";
+
+stdenv.mkDerivation rec {
+
+  name = "ocaml${ocaml.version}-ocp-indent-${version}";
+  version = "1.6.1";
+
+  src = fetchzip {
+    url = "https://github.com/OCamlPro/ocp-indent/archive/${version}.tar.gz";
+    sha256 = "0rcaa11mjqka032g94wgw9llqpflyk3ywr3lr6jyxbh1rjvnipnw";
+  };
+
+  nativeBuildInputs = [ ocp-build ];
+  buildInputs = [ ocaml findlib cmdliner ];
+
+  inherit (dune) installPhase;
+
+  meta = with stdenv.lib; {
+    homepage = http://typerex.ocamlpro.com/ocp-indent.html;
+    description = "A customizable tool to indent OCaml code";
+    license = licenses.gpl3;
+    platforms = ocaml.meta.platforms or [];
+    maintainers = [ maintainers.jirkamarsik ];
+  };
+}
diff --git a/nixpkgs/pkgs/development/tools/ocaml/ocp-index/default.nix b/nixpkgs/pkgs/development/tools/ocaml/ocp-index/default.nix
new file mode 100644
index 000000000000..23aeceb41a75
--- /dev/null
+++ b/nixpkgs/pkgs/development/tools/ocaml/ocp-index/default.nix
@@ -0,0 +1,29 @@
+{ stdenv, fetchFromGitHub, ocaml, findlib, dune, ocp-build, ocp-indent, cmdliner, re }:
+
+stdenv.mkDerivation rec {
+
+  version = "1.1.7";
+  name = "ocaml${ocaml.version}-ocp-index-${version}";
+
+  src = fetchFromGitHub {
+    owner = "OCamlPro";
+    repo = "ocp-index";
+    rev = version;
+    sha256 = "0i50y033y78wcfgz3b81d34p98azahl94w4b63ac0zyczlwlhvkf";
+  };
+
+  buildInputs = [ ocaml findlib dune ocp-build cmdliner re ];
+  propagatedBuildInputs = [ ocp-indent ];
+
+  buildPhase = "dune build -p ocp-index";
+
+  inherit (dune) installPhase;
+
+  meta = {
+    homepage = http://typerex.ocamlpro.com/ocp-index.html;
+    description = "A simple and light-weight documentation extractor for OCaml";
+    license = stdenv.lib.licenses.lgpl3;
+    platforms = ocaml.meta.platforms or [];
+    maintainers = with stdenv.lib.maintainers; [ vbgl ];
+  };
+}
diff --git a/nixpkgs/pkgs/development/tools/ocaml/ocsigen-i18n/default.nix b/nixpkgs/pkgs/development/tools/ocaml/ocsigen-i18n/default.nix
new file mode 100644
index 000000000000..75e898fdb3fd
--- /dev/null
+++ b/nixpkgs/pkgs/development/tools/ocaml/ocsigen-i18n/default.nix
@@ -0,0 +1,31 @@
+{ stdenv, fetchurl, ocamlPackages }:
+
+stdenv.mkDerivation rec
+{
+  pname = "ocsigen-i18n";
+  name = "${pname}-${version}";
+  version = "3.1.0";
+
+  buildInputs = with ocamlPackages; [ ocaml findlib ];
+
+
+  dontStrip = true;
+
+  installPhase = ''
+    mkdir -p $out/bin
+    make bindir=$out/bin install
+  '';
+
+  src = fetchurl {
+    url = "https://github.com/besport/${pname}/archive/${version}.tar.gz";
+    sha256 = "0cw0mmr67wx03j4279z7ldxwb01smkqz9rbklx5lafrj5sf99178";
+  };
+
+  meta = {
+    homepage = https://github.com/besport/ocsigen-i18n;
+    description = "I18n made easy for web sites written with eliom";
+    license = stdenv.lib.licenses.lgpl21;
+    maintainers = [ stdenv.lib.maintainers.gal_bolle ];
+  };
+
+}
diff --git a/nixpkgs/pkgs/development/tools/ocaml/omake/0.9.8.6-rc1.nix b/nixpkgs/pkgs/development/tools/ocaml/omake/0.9.8.6-rc1.nix
new file mode 100644
index 000000000000..182250f9a744
--- /dev/null
+++ b/nixpkgs/pkgs/development/tools/ocaml/omake/0.9.8.6-rc1.nix
@@ -0,0 +1,43 @@
+{stdenv, fetchurl, makeWrapper, ocaml, ncurses}:
+let
+  pname = "omake";
+  version = "0.9.8.6-0.rc1";
+  webpage = "http://omake.metaprl.org";
+in
+
+if stdenv.lib.versionAtLeast ocaml.version "4.06"
+then throw "${pname}-${version} is not available for OCaml ${ocaml.version}"
+else
+
+stdenv.mkDerivation {
+
+  name = "${pname}-${version}";
+
+  src = fetchurl {
+    url = "https://src.fedoraproject.org/repo/pkgs/ocaml-omake/${pname}-${version}.tar.gz/fe39a476ef4e33b7ba2ca77a6bcaded2/${pname}-${version}.tar.gz";
+    sha256 = "1sas02pbj56m7wi5vf3vqrrpr4ynxymw2a8ybvfj2dkjf7q9ii13";
+  };
+  patchFlags = "-p0";
+  patches = [ ./warn.patch ];
+
+  buildInputs = [ ocaml makeWrapper ncurses ];
+
+  phases = "unpackPhase patchPhase buildPhase";
+  buildPhase = ''
+    make bootstrap
+    make PREFIX=$out all
+    make PREFIX=$out install
+  '';
+#  prefixKey = "-prefix ";
+#
+#  configureFlags = if transitional then "--transitional" else "--strict";
+#
+#  buildFlags = "world.opt";		
+
+  meta = {
+    description = "Omake build system";
+    homepage = "${webpage}";
+    license = "GPL";
+    platforms = ocaml.meta.platforms or [];
+  };
+}
diff --git a/nixpkgs/pkgs/development/tools/ocaml/omake/default.nix b/nixpkgs/pkgs/development/tools/ocaml/omake/default.nix
new file mode 100644
index 000000000000..0f536c489eb6
--- /dev/null
+++ b/nixpkgs/pkgs/development/tools/ocaml/omake/default.nix
@@ -0,0 +1,24 @@
+{ stdenv, fetchurl, ocaml, ncurses }:
+
+stdenv.mkDerivation rec {
+
+  name = "omake-${version}";
+  version = "0.10.3";
+
+  src = fetchurl {
+    url = "http://download.camlcity.org/download/${name}.tar.gz";
+    sha256 = "07bdg1h5i7qnlv9xq81ad5hfypl10hxm771h4rjyl5cn8plhfcgz";
+  };
+
+  buildInputs = [ ocaml ncurses ];
+
+  meta = {
+    description = "A build system designed for scalability and portability";
+    homepage = http://projects.camlcity.org/projects/omake.html;
+    license = with stdenv.lib.licenses; [
+      mit /* scripts */
+      gpl2 /* program */
+    ];
+    inherit (ocaml.meta) platforms;
+  };
+}
diff --git a/nixpkgs/pkgs/development/tools/ocaml/omake/warn.patch b/nixpkgs/pkgs/development/tools/ocaml/omake/warn.patch
new file mode 100644
index 000000000000..4459e89d7f9c
--- /dev/null
+++ b/nixpkgs/pkgs/development/tools/ocaml/omake/warn.patch
@@ -0,0 +1,10 @@
+diff -p1 -aur ../omake-0.9.8.6.ori/lib/build/OCaml.om ./lib/build/OCaml.om
+--- ../omake-0.9.8.6.ori/lib/build/OCaml.om	2008-03-05 01:07:25.000000000 +0000
++++ ./lib/build/OCaml.om	2013-06-01 15:52:37.000000000 +0000
+@@ -178,3 +178,3 @@ declare OCAMLDEPFLAGS
+ public.OCAMLPPFLAGS  =
+-public.OCAMLFLAGS    = -warn-error A
++public.OCAMLFLAGS    =
+ public.OCAMLCFLAGS   = -g
+Seulement dans ./lib/build: OCaml.om~
+Seulement dans .: warn.patch
diff --git a/nixpkgs/pkgs/development/tools/ocaml/opaline/default.nix b/nixpkgs/pkgs/development/tools/ocaml/opaline/default.nix
new file mode 100644
index 000000000000..10088cce4912
--- /dev/null
+++ b/nixpkgs/pkgs/development/tools/ocaml/opaline/default.nix
@@ -0,0 +1,27 @@
+{ stdenv, fetchFromGitHub, ocamlPackages }:
+
+stdenv.mkDerivation rec {
+  version = "0.3.1";
+  name = "opaline-${version}";
+
+  src = fetchFromGitHub {
+    owner = "jaapb";
+    repo = "opaline";
+    rev = "v${version}";
+    sha256 = "0vd5xaf272hk4iqfj347jvbppy7my5p5gz8yqpkvl1d1i6lzh08v";
+  };
+
+  buildInputs = with ocamlPackages; [ ocaml findlib ocamlbuild opam-file-format ];
+
+  preInstall = "mkdir -p $out/bin";
+
+  installFlags = [ "PREFIX=$(out)" ];
+
+  meta = {
+    description = "OPAm Light INstaller Engine";
+    license = stdenv.lib.licenses.mit;
+    maintainers = [ stdenv.lib.maintainers.vbgl ];
+    inherit (src.meta) homepage;
+    inherit (ocamlPackages.ocaml.meta) platforms;
+  };
+}
diff --git a/nixpkgs/pkgs/development/tools/ocaml/opam/1.2.2.nix b/nixpkgs/pkgs/development/tools/ocaml/opam/1.2.2.nix
new file mode 100644
index 000000000000..7e84719ae47d
--- /dev/null
+++ b/nixpkgs/pkgs/development/tools/ocaml/opam/1.2.2.nix
@@ -0,0 +1,92 @@
+{ stdenv, lib, fetchurl, makeWrapper,
+  ocaml, unzip, ncurses, curl, aspcud
+}:
+
+assert lib.versionAtLeast ocaml.version "3.12.1";
+
+let
+  srcs = {
+    cudf = fetchurl {
+      url = "https://gforge.inria.fr/frs/download.php/file/33593/cudf-0.7.tar.gz";
+      sha256 = "92c8a9ed730bbac73f3513abab41127d966c9b9202ab2aaffcd02358c030a701";
+    };
+    extlib = fetchurl {
+      url = "http://ocaml-extlib.googlecode.com/files/extlib-1.5.3.tar.gz";
+      sha256 = "c095eef4202a8614ff1474d4c08c50c32d6ca82d1015387785cf03d5913ec021";
+    };
+    ocaml_re = fetchurl {
+      url = "https://github.com/ocaml/ocaml-re/archive/ocaml-re-1.2.0.tar.gz";
+      sha256 = "a34dd9d6136731436a963bbab5c4bbb16e5d4e21b3b851d34887a3dec451999f";
+    };
+    ocamlgraph = fetchurl {
+      url = "http://ocamlgraph.lri.fr/download/ocamlgraph-1.8.5.tar.gz";
+      sha256 = "d167466435a155c779d5ec25b2db83ad851feb42ebc37dca8ffa345ddaefb82f";
+    };
+    dose3 = fetchurl {
+      url = "https://gforge.inria.fr/frs/download.php/file/34277/dose3-3.3.tar.gz";
+      sha256 = "8dc4dae9b1a81bb3a42abb283df785ba3eb00ade29b13875821c69f03e00680e";
+    };
+    cmdliner = fetchurl {
+      url = "http://erratique.ch/software/cmdliner/releases/cmdliner-0.9.7.tbz";
+      sha256 = "9c19893cffb5d3c3469ee0cce85e3eeeba17d309b33b9ace31aba06f68f0bf7a";
+    };
+    uutf = fetchurl {
+      url = "http://erratique.ch/software/uutf/releases/uutf-0.9.3.tbz";
+      sha256 = "1f364f89b1179e5182a4d3ad8975f57389d45548735d19054845e06a27107877";
+    };
+    jsonm = fetchurl {
+      url = "http://erratique.ch/software/jsonm/releases/jsonm-0.9.1.tbz";
+      sha256 = "3fd4dca045d82332da847e65e981d8b504883571d299a3f7e71447d46bc65f73";
+    };
+    opam = fetchurl {
+      url = "https://github.com/ocaml/opam/archive/1.2.2.zip";
+      sha256 = "c590ce55ae69ec74f46215cf16a156a02b23c5f3ecb22f23a3ad9ba3d91ddb6e";
+    };
+  };
+in stdenv.mkDerivation rec {
+  name = "opam-${version}";
+  version = "1.2.2";
+
+  buildInputs = [ unzip curl ncurses ocaml makeWrapper ];
+
+  src = srcs.opam;
+
+  postUnpack = ''
+    ln -sv ${srcs.cudf} $sourceRoot/src_ext/${srcs.cudf.name}
+    ln -sv ${srcs.extlib} $sourceRoot/src_ext/${srcs.extlib.name}
+    ln -sv ${srcs.ocaml_re} $sourceRoot/src_ext/${srcs.ocaml_re.name}
+    ln -sv ${srcs.ocamlgraph} $sourceRoot/src_ext/${srcs.ocamlgraph.name}
+    ln -sv ${srcs.dose3} $sourceRoot/src_ext/${srcs.dose3.name}
+    ln -sv ${srcs.cmdliner} $sourceRoot/src_ext/${srcs.cmdliner.name}
+    ln -sv ${srcs.uutf} $sourceRoot/src_ext/${srcs.uutf.name}
+    ln -sv ${srcs.jsonm} $sourceRoot/src_ext/${srcs.jsonm.name}
+  '';
+
+  preConfigure = ''
+    substituteInPlace ./src_ext/Makefile --replace "%.stamp: %.download" "%.stamp:"
+  '';
+
+  postConfigure = "make lib-ext";
+
+  # Dirty, but apparently ocp-build requires a TERM
+  makeFlags = ["TERM=screen"];
+
+  # change argv0 to "opam" as a workaround for
+  # https://github.com/ocaml/opam/issues/2142
+  postInstall = ''
+    mv $out/bin/opam $out/bin/.opam-wrapped
+    makeWrapper $out/bin/.opam-wrapped $out/bin/opam \
+      --argv0 "opam" \
+      --suffix PATH : ${aspcud}/bin:${unzip}/bin:${curl}/bin
+  '';
+
+  doCheck = false;
+
+  meta = with stdenv.lib; {
+    description = "A package manager for OCaml";
+    homepage = http://opam.ocamlpro.com/;
+    maintainers = [ maintainers.henrytill ];
+    platforms = platforms.all;
+    license = licenses.lgpl21Plus;
+  };
+}
diff --git a/nixpkgs/pkgs/development/tools/ocaml/opam/default.nix b/nixpkgs/pkgs/development/tools/ocaml/opam/default.nix
new file mode 100644
index 000000000000..8e89dd3fadd2
--- /dev/null
+++ b/nixpkgs/pkgs/development/tools/ocaml/opam/default.nix
@@ -0,0 +1,114 @@
+{ stdenv, lib, fetchurl, makeWrapper, getconf,
+  ocaml, unzip, ncurses, curl, aspcud, bubblewrap
+}:
+
+assert lib.versionAtLeast ocaml.version "4.02.3";
+
+let
+  srcs = {
+    cmdliner = fetchurl {
+      url = "http://erratique.ch/software/cmdliner/releases/cmdliner-1.0.2.tbz";
+      sha256 = "18jqphjiifljlh9jg8zpl6310p3iwyaqphdkmf89acyaix0s4kj1";
+    };
+    cppo = fetchurl {
+      url = "https://github.com/mjambon/cppo/archive/v1.6.4.tar.gz";
+      sha256 = "0jdb7d21lfa3ck4k59mrqs5pljzq5rb504jq57nnrc6klljm42j7";
+    };
+    cudf = fetchurl {
+      url = "https://gforge.inria.fr/frs/download.php/36602/cudf-0.9.tar.gz";
+      sha256 = "0771lwljqwwn3cryl0plny5a5dyyrj4z6bw66ha5n8yfbpcy8clr";
+    };
+    dose3 = fetchurl {
+      url = "https://gforge.inria.fr/frs/download.php/file/36063/dose3-5.0.1.tar.gz";
+      sha256 = "00yvyfm4j423zqndvgc1ycnmiffaa2l9ab40cyg23pf51qmzk2jm";
+    };
+    extlib = fetchurl {
+      url = "http://ygrek.org.ua/p/release/ocaml-extlib/extlib-1.7.5.tar.gz";
+      sha256 = "19slqf5bdj0rrph2w41giwmn6df2qm07942jn058pjkjrnk30d4s";
+    };
+    jbuilder = fetchurl {
+      url = "https://github.com/ocaml/dune/releases/download/1.0+beta20/jbuilder-1.0.beta20.tbz";
+      sha256 = "07hl9as5llffgd6hbw41rs76i1ibgn3n9r0dba5h0mdlkapcwb10";
+    };
+    mccs = fetchurl {
+      url = "https://github.com/AltGr/ocaml-mccs/archive/1.1+8.tar.gz";
+      sha256 = "0xavfvxfrcf3lmry8ymma1yzy0hw3ijbx94c9zq3pzlwnylrapa4";
+    };
+    ocamlgraph = fetchurl {
+      url = "http://ocamlgraph.lri.fr/download/ocamlgraph-1.8.8.tar.gz";
+      sha256 = "0m9g16wrrr86gw4fz2fazrh8nkqms0n863w7ndcvrmyafgxvxsnr";
+    };
+    opam-file-format = fetchurl {
+      url = "https://github.com/ocaml/opam-file-format/archive/2.0.0-rc2.tar.gz";
+      sha256 = "1mgk08msp7hxn0hs0m82vky3yv6hcq4pw5402b3vhx4c49431jsb";
+    };
+    re = fetchurl {
+      url = "https://github.com/ocaml/ocaml-re/releases/download/1.7.3/re-1.7.3.tbz";
+      sha256 = "0nv933qfl8y9i19cqvhsalwzif3dkm28vg478rpnr4hgfqjlfryr";
+    };
+    result = fetchurl {
+      url = "https://github.com/janestreet/result/releases/download/1.3/result-1.3.tbz";
+      sha256 = "1lrnbxdq80gbhnp85mqp1kfk0bkh6q1c93sfz2qgnq2qyz60w4sk";
+    };
+    opam = fetchurl {
+      url = "https://github.com/ocaml/opam/archive/2.0.0.zip";
+      sha256 = "0m4ilsldrfkkn0vlvl119bk76j2pwvqvdi8mpg957z4kqflfbfp8";
+    };
+  };
+in stdenv.mkDerivation rec {
+  name = "opam-${version}";
+  version = "2.0.0";
+
+  buildInputs = [ unzip curl ncurses ocaml makeWrapper getconf ] ++ lib.optional stdenv.isLinux bubblewrap;
+
+  src = srcs.opam;
+
+  postUnpack = ''
+    ln -sv ${srcs.cmdliner} $sourceRoot/src_ext/cmdliner.tbz
+    ln -sv ${srcs.cppo} $sourceRoot/src_ext/cppo.tar.gz
+    ln -sv ${srcs.cudf} $sourceRoot/src_ext/cudf.tar.gz
+    ln -sv ${srcs.dose3} $sourceRoot/src_ext/dose3.tar.gz
+    ln -sv ${srcs.extlib} $sourceRoot/src_ext/extlib.tar.gz
+    ln -sv ${srcs.jbuilder} $sourceRoot/src_ext/jbuilder.tbz
+    ln -sv ${srcs.mccs} $sourceRoot/src_ext/mccs.tar.gz
+    ln -sv ${srcs.ocamlgraph} $sourceRoot/src_ext/ocamlgraph.tar.gz
+    ln -sv ${srcs.opam-file-format} $sourceRoot/src_ext/opam-file-format.tar.gz
+    ln -sv ${srcs.re} $sourceRoot/src_ext/re.tbz
+    ln -sv ${srcs.result} $sourceRoot/src_ext/result.tbz
+  '';
+
+  patches = [ ./opam-pull-3487.patch ./opam-shebangs.patch ./opam-mccs-darwin.patch ];
+
+  preConfigure = ''
+    substituteInPlace ./src_ext/Makefile --replace "%.stamp: %.download" "%.stamp:"
+    patchShebangs src/state/shellscripts
+  '';
+
+  postConfigure = "make lib-ext";
+
+  # Dirty, but apparently ocp-build requires a TERM
+  makeFlags = ["TERM=screen"];
+
+  outputs = [ "out" "installer" ];
+  setOutputFlags = false;
+
+  # change argv0 to "opam" as a workaround for
+  # https://github.com/ocaml/opam/issues/2142
+  postInstall = ''
+    mv $out/bin/opam $out/bin/.opam-wrapped
+    makeWrapper $out/bin/.opam-wrapped $out/bin/opam \
+      --argv0 "opam" \
+      --suffix PATH : ${aspcud}/bin:${unzip}/bin:${curl}/bin:${lib.optionalString stdenv.isLinux "${bubblewrap}/bin:"}${getconf}/bin
+    $out/bin/opam-installer --prefix=$installer opam-installer.install
+  '';
+
+  doCheck = false;
+
+  meta = with stdenv.lib; {
+    description = "A package manager for OCaml";
+    homepage = http://opam.ocamlpro.com/;
+    maintainers = [ maintainers.henrytill ];
+    platforms = platforms.all;
+  };
+}
+# Generated by: ./opam.nix.pl -v 2.0.0 -p opam-pull-3487.patch,opam-shebangs.patch,opam-mccs-darwin.patch
diff --git a/nixpkgs/pkgs/development/tools/ocaml/opam/opam-mccs-darwin.patch b/nixpkgs/pkgs/development/tools/ocaml/opam/opam-mccs-darwin.patch
new file mode 100644
index 000000000000..501242c40a01
--- /dev/null
+++ b/nixpkgs/pkgs/development/tools/ocaml/opam/opam-mccs-darwin.patch
@@ -0,0 +1,18 @@
+diff --git a/src_ext/patches/mccs/build-on-darwin.patch b/src_ext/patches/mccs/build-on-darwin.patch
+new file mode 100644
+index 00000000..157e2094
+--- /dev/null
++++ b/src_ext/patches/mccs/build-on-darwin.patch
+@@ -0,0 +1,12 @@
++diff --git a/src/context_flags.ml b/src/context_flags.ml
++index 7470030..6e07370 100644
++--- a/src/context_flags.ml
+++++ b/src/context_flags.ml
++@@ -24,6 +24,7 @@ let ifc c x = if c then x else []
++ 
++ let cxxflags =
++   let flags =
+++    (ifc (Config.system = "macosx") ["-x"; "c++"]) @
++     (ifc (Sys.win32 && Config.ccomp_type = "msvc") ["/EHsc"]) @
++     (ifc useGLPK ["-DUSEGLPK"]) @
++     (ifc useCOIN ["-DUSECOIN"]) @
diff --git a/nixpkgs/pkgs/development/tools/ocaml/opam/opam-pull-3487.patch b/nixpkgs/pkgs/development/tools/ocaml/opam/opam-pull-3487.patch
new file mode 100644
index 000000000000..e047c8298bc3
--- /dev/null
+++ b/nixpkgs/pkgs/development/tools/ocaml/opam/opam-pull-3487.patch
@@ -0,0 +1,23 @@
+diff --git a/src/state/shellscripts/bwrap.sh b/src/state/shellscripts/bwrap.sh
+index 6f5d7dbea..3e1a3e1b4 100755
+--- a/src/state/shellscripts/bwrap.sh
++++ b/src/state/shellscripts/bwrap.sh
+@@ -1,4 +1,6 @@
+-#!/bin/bash -ue
++#!/usr/bin/env bash
++
++set -ue
+ 
+ if ! command -v bwrap >/dev/null; then
+     echo "The 'bwrap' command was not found. Install 'bubblewrap' on your system, or" >&2
+@@ -11,7 +13,9 @@ fi
+ 
+ ARGS=(--unshare-net --new-session)
+ ARGS=("${ARGS[@]}" --proc /proc --dev /dev)
+-ARGS=("${ARGS[@]}" --bind /tmp /tmp --tmpfs /run --tmpfs /var)
++ARGS=("${ARGS[@]}" --bind "${TMPDIR:-/tmp}" /tmp)
++ARGS=("${ARGS[@]}" --setenv TMPDIR /tmp --setenv TMP /tmp --setenv TEMPDIR /tmp --setenv TEMP /tmp)
++ARGS=("${ARGS[@]}" --tmpfs /run --tmpfs /var)
+ 
+ add_mounts() {
+     case "$1" in
diff --git a/nixpkgs/pkgs/development/tools/ocaml/opam/opam-shebangs.patch b/nixpkgs/pkgs/development/tools/ocaml/opam/opam-shebangs.patch
new file mode 100644
index 000000000000..f74ac84ca6b2
--- /dev/null
+++ b/nixpkgs/pkgs/development/tools/ocaml/opam/opam-shebangs.patch
@@ -0,0 +1,128 @@
+diff --git a/src/client/opamInitDefaults.ml b/src/client/opamInitDefaults.ml
+index eca13a7c..1fd66f43 100644
+--- a/src/client/opamInitDefaults.ml
++++ b/src/client/opamInitDefaults.ml
+@@ -35,11 +35,15 @@ let eval_variables = [
+ let os_filter os =
+   FOp (FIdent ([], OpamVariable.of_string "os", None), `Eq, FString os)
+ 
++let os_distribution_filter distro =
++  FOp (FIdent ([], OpamVariable.of_string "os-distribution", None), `Eq, FString distro)
++
+ let linux_filter = os_filter "linux"
+ let macos_filter = os_filter "macos"
+ let openbsd_filter = os_filter "openbsd"
+ let freebsd_filter = os_filter "freebsd"
+ let sandbox_filter = FOr (linux_filter, macos_filter)
++let nixos_filter = os_distribution_filter "nixos"
+ 
+ let gpatch_filter = FOr (openbsd_filter, freebsd_filter)
+ let patch_filter = FNot gpatch_filter
+@@ -50,6 +54,11 @@ let wrappers ~sandboxing () =
+     CString t, None;
+   ] in
+   let w = OpamFile.Wrappers.empty in
++  let w = { w with
++            OpamFile.Wrappers.
++            pre_build = [[CString "%{hooks}%/shebangs.sh", None], Some nixos_filter];
++          }
++  in
+   if sandboxing then
+     { w with
+       OpamFile.Wrappers.
+@@ -113,6 +122,7 @@ let required_tools ~sandboxing () =
+ let init_scripts () = [
+   ("sandbox.sh", OpamScript.bwrap), Some bwrap_filter;
+   ("sandbox.sh", OpamScript.sandbox_exec), Some macos_filter;
++  ("shebangs.sh", OpamScript.patch_shebangs), Some nixos_filter;
+ ]
+ 
+ module I = OpamFile.InitConfig
+diff --git a/src/state/opamScript.mli b/src/state/opamScript.mli
+index 03449970..83de0b53 100644
+--- a/src/state/opamScript.mli
++++ b/src/state/opamScript.mli
+@@ -20,3 +20,4 @@ val env_hook : string
+ val env_hook_zsh : string
+ val env_hook_csh : string
+ val env_hook_fish : string
++val patch_shebangs : string
+diff --git a/src/state/shellscripts/patch_shebangs.sh b/src/state/shellscripts/patch_shebangs.sh
+new file mode 100755
+index 00000000..3ea84e2d
+--- /dev/null
++++ b/src/state/shellscripts/patch_shebangs.sh
+@@ -0,0 +1,73 @@
++#!/usr/bin/env bash
++# This setup hook causes the fixup phase to rewrite all script
++# interpreter file names (`#!  /path') to paths found in $PATH.  E.g.,
++# /bin/sh will be rewritten to /nix/store/<hash>-some-bash/bin/sh.
++# /usr/bin/env gets special treatment so that ".../bin/env python" is
++# rewritten to /nix/store/<hash>/bin/python.  Interpreters that are
++# already in the store are left untouched.
++
++header() { echo "$1"; }
++stopNest() { true; }
++
++fixupOutputHooks+=('if [ -z "$dontPatchShebangs" -a -e "$prefix" ]; then patchShebangs "$prefix"; fi')
++
++patchShebangs() {
++    local dir="$1"
++    header "patching script interpreter paths in $dir"
++    local f
++    local oldPath
++    local newPath
++    local arg0
++    local args
++    local oldInterpreterLine
++    local newInterpreterLine
++
++    find "$dir" -type f -perm -0100 | while read f; do
++        if [ "$(head -1 "$f" | head -c+2)" != '#!' ]; then
++            # missing shebang => not a script
++            continue
++        fi
++
++        oldInterpreterLine=$(head -1 "$f" | tail -c+3)
++        read -r oldPath arg0 args <<< "$oldInterpreterLine"
++
++        if $(echo "$oldPath" | grep -q "/bin/env$"); then
++            # Check for unsupported 'env' functionality:
++            # - options: something starting with a '-'
++            # - environment variables: foo=bar
++            if $(echo "$arg0" | grep -q -- "^-.*\|.*=.*"); then
++                echo "unsupported interpreter directive \"$oldInterpreterLine\" (set dontPatchShebangs=1 and handle shebang patching yourself)"
++                exit 1
++            fi
++            newPath="$(command -v "$arg0" || true)"
++        else
++            if [ "$oldPath" = "" ]; then
++                # If no interpreter is specified linux will use /bin/sh. Set
++                # oldpath="/bin/sh" so that we get /nix/store/.../sh.
++                oldPath="/bin/sh"
++            fi
++            newPath="$(command -v "$(basename "$oldPath")" || true)"
++            args="$arg0 $args"
++        fi
++
++        # Strip trailing whitespace introduced when no arguments are present
++        newInterpreterLine="$(echo "$newPath $args" | sed 's/[[:space:]]*$//')"
++
++        if [ -n "$oldPath" -a "${oldPath:0:${#NIX_STORE}}" != "$NIX_STORE" ]; then
++            if [ -n "$newPath" -a "$newPath" != "$oldPath" ]; then
++                echo "$f: interpreter directive changed from \"$oldInterpreterLine\" to \"$newInterpreterLine\""
++                # escape the escape chars so that sed doesn't interpret them
++                escapedInterpreterLine=$(echo "$newInterpreterLine" | sed 's|\\|\\\\|g')
++                # Preserve times, see: https://github.com/NixOS/nixpkgs/pull/33281
++                touch -r "$f" "$f.timestamp"
++                sed -i -e "1 s|.*|#\!$escapedInterpreterLine|" "$f"
++                touch -r "$f.timestamp" "$f"
++                rm "$f.timestamp"
++            fi
++        fi
++    done
++
++    stopNest
++}
++
++patchShebangs .
diff --git a/nixpkgs/pkgs/development/tools/ocaml/opam/opam.nix.pl b/nixpkgs/pkgs/development/tools/ocaml/opam/opam.nix.pl
new file mode 100755
index 000000000000..1862add452d6
--- /dev/null
+++ b/nixpkgs/pkgs/development/tools/ocaml/opam/opam.nix.pl
@@ -0,0 +1,130 @@
+#!/usr/bin/env perl
+
+use strict;
+use warnings qw<all>;
+use Getopt::Std;
+
+my $gencmd = "# Generated by: " . join(" ", $0, @ARGV) . "\n";
+
+our $opt_v;
+our $opt_p;
+our $opt_r;
+our $opt_t;
+getopts "v:p:t:r:";
+
+my $OPAM_RELEASE = $opt_v // "2.0.0";
+my $OPAM_TAG = $opt_t // $OPAM_RELEASE;
+my $OPAM_GITHUB_REPO = $opt_r // "ocaml/opam";
+my $OPAM_RELEASE_URL = "https://github.com/$OPAM_GITHUB_REPO/archive/$OPAM_TAG.zip";
+my $OPAM_RELEASE_SHA256 = `nix-prefetch-url \Q$OPAM_RELEASE_URL\E`;
+chomp $OPAM_RELEASE_SHA256;
+
+my $OPAM_BASE_URL = "https://raw.githubusercontent.com/$OPAM_GITHUB_REPO/$OPAM_TAG";
+my $OPAM_OPAM = `curl -L --url \Q$OPAM_BASE_URL\E/opam-devel.opam`;
+my($OCAML_MIN_VERSION) = $OPAM_OPAM =~ /^available: ocaml-version >= "(.*)"$/m
+  or die "could not parse ocaml version bound\n";
+
+print <<"EOF";
+{ stdenv, lib, fetchurl, makeWrapper, getconf,
+  ocaml, unzip, ncurses, curl, aspcud, bubblewrap
+}:
+
+assert lib.versionAtLeast ocaml.version "$OCAML_MIN_VERSION";
+
+let
+  srcs = {
+EOF
+
+my %urls = ();
+my %md5s = ();
+
+open(SOURCES, "-|", "curl", "-L", "--url", "$OPAM_BASE_URL/src_ext/Makefile.sources");
+while (<SOURCES>) {
+  if (/^URL_(?!PKG_)([-\w]+)\s*=\s*(\S+)$/) {
+    $urls{$1} = $2;
+  } elsif (/^MD5_(?!PKG_)([-\w]+)\s*=\s*(\S+)$/) {
+    $md5s{$1} = $2;
+  }
+}
+for my $src (sort keys %urls) {
+  my ($sha256,$store_path) = split /\n/, `nix-prefetch-url --print-path \Q$urls{$src}\E`;
+  system "echo \Q$md5s{$src}\E' *'\Q$store_path\E | md5sum -c 1>&2";
+  die "md5 check failed for $urls{$src}\n" if $?;
+  print <<"EOF";
+    $src = fetchurl {
+      url = "$urls{$src}";
+      sha256 = "$sha256";
+    };
+EOF
+}
+
+print <<"EOF";
+    opam = fetchurl {
+      url = "$OPAM_RELEASE_URL";
+      sha256 = "$OPAM_RELEASE_SHA256";
+    };
+  };
+in stdenv.mkDerivation rec {
+  name = "opam-\${version}";
+  version = "$OPAM_RELEASE";
+
+  buildInputs = [ unzip curl ncurses ocaml makeWrapper getconf ] ++ lib.optional stdenv.isLinux bubblewrap;
+
+  src = srcs.opam;
+
+  postUnpack = ''
+EOF
+for my $src (sort keys %urls) {
+  my($ext) = $urls{$src} =~ /(\.(?:t(?:ar\.|)|)(?:gz|bz2?))$/
+    or die "could not find extension for $urls{$src}\n";
+  print <<"EOF";
+    ln -sv \${srcs.$src} \$sourceRoot/src_ext/$src$ext
+EOF
+}
+print <<'EOF';
+  '';
+
+EOF
+if (defined $opt_p) {
+  print "  patches = [ ";
+  for my $patch (split /[, ]/, $opt_p) {
+    $patch =~ s/^(?=[^\/]*$)/.\//;
+    print "$patch ";
+  }
+  print "];\n\n";
+}
+print <<'EOF';
+  preConfigure = ''
+    substituteInPlace ./src_ext/Makefile --replace "%.stamp: %.download" "%.stamp:"
+    patchShebangs src/state/shellscripts
+  '';
+
+  postConfigure = "make lib-ext";
+
+  # Dirty, but apparently ocp-build requires a TERM
+  makeFlags = ["TERM=screen"];
+
+  outputs = [ "out" "installer" ];
+  setOutputFlags = false;
+
+  # change argv0 to "opam" as a workaround for
+  # https://github.com/ocaml/opam/issues/2142
+  postInstall = ''
+    mv $out/bin/opam $out/bin/.opam-wrapped
+    makeWrapper $out/bin/.opam-wrapped $out/bin/opam \
+      --argv0 "opam" \
+      --suffix PATH : ${aspcud}/bin:${unzip}/bin:${curl}/bin:${lib.optionalString stdenv.isLinux "${bubblewrap}/bin:"}${getconf}/bin
+    $out/bin/opam-installer --prefix=$installer opam-installer.install
+  '';
+
+  doCheck = false;
+
+  meta = with stdenv.lib; {
+    description = "A package manager for OCaml";
+    homepage = http://opam.ocamlpro.com/;
+    maintainers = [ maintainers.henrytill ];
+    platforms = platforms.all;
+  };
+}
+EOF
+print $gencmd;
diff --git a/nixpkgs/pkgs/development/tools/ocaml/utop/default.nix b/nixpkgs/pkgs/development/tools/ocaml/utop/default.nix
new file mode 100644
index 000000000000..434f8b3af2ea
--- /dev/null
+++ b/nixpkgs/pkgs/development/tools/ocaml/utop/default.nix
@@ -0,0 +1,77 @@
+{ stdenv, fetchurl, ocaml, findlib, ocamlbuild, dune
+, lambdaTerm, cppo, makeWrapper
+}:
+
+if !stdenv.lib.versionAtLeast ocaml.version "4.02"
+then throw "utop is not available for OCaml ${ocaml.version}"
+else
+
+stdenv.mkDerivation rec {
+  version = "2.2.0";
+  name = "utop-${version}";
+
+  src = fetchurl {
+    url = "https://github.com/diml/utop/archive/${version}.tar.gz";
+    sha256 = "1414snwmqaxs1x8wbpjf6fn3jsl01hq0phrr7639xmb5vh15mgd4";
+  };
+
+  nativeBuildInputs = [ makeWrapper ];
+  buildInputs = [ ocaml findlib ocamlbuild cppo dune ];
+
+  propagatedBuildInputs = [ lambdaTerm ];
+
+  inherit (dune) installPhase;
+
+  postFixup =
+   let
+     path = "etc/utop/env";
+
+     # derivation of just runtime deps so env vars created by
+     # setup-hooks can be saved for use at runtime
+     runtime = stdenv.mkDerivation rec {
+       name = "utop-runtime-env-${version}";
+
+       buildInputs = [ findlib ] ++ propagatedBuildInputs;
+
+       phases = [ "installPhase" ];
+
+       installPhase = ''
+         mkdir -p "$out"/${path}
+         for e in OCAMLPATH CAML_LD_LIBRARY_PATH; do
+           printf %s "''${!e}" > "$out"/${path}/$e
+         done
+       '';
+     };
+
+     get = key: ''$(cat "${runtime}/${path}/${key}")'';
+   in ''
+   for prog in "$out"/bin/*
+   do
+
+    # Note: wrapProgram by default calls 'exec -a $0 ...', but this
+    # breaks utop on Linux with OCaml 4.04, and is disabled with
+    # '--argv0 ""' flag. See https://github.com/NixOS/nixpkgs/issues/24496
+    wrapProgram "$prog" \
+      --argv0 "" \
+      --prefix CAML_LD_LIBRARY_PATH ":" "${get "CAML_LD_LIBRARY_PATH"}" \
+      --prefix OCAMLPATH ":" "${get "OCAMLPATH"}" \
+      --prefix OCAMLPATH ":" $(unset OCAMLPATH; addOCamlPath "$out"; printf %s "$OCAMLPATH") \
+      --add-flags "-I ${findlib}/lib/ocaml/${stdenv.lib.getVersion ocaml}/site-lib"
+   done
+   '';
+
+  meta = {
+    description = "Universal toplevel for OCaml";
+    longDescription = ''
+    utop is an improved toplevel for OCaml. It can run in a terminal or in Emacs. It supports line edition, history, real-time and context sensitive completion, colors, and more.
+
+    It integrates with the tuareg mode in Emacs.
+    '';
+    homepage = https://github.com/diml/utop;
+    license = stdenv.lib.licenses.bsd3;
+    platforms = ocaml.meta.platforms or [];
+    maintainers = [
+      stdenv.lib.maintainers.gal_bolle
+    ];
+  };
+}