diff options
Diffstat (limited to 'vendors/ocamlbuild/src/plugin.ml')
| -rw-r--r-- | vendors/ocamlbuild/src/plugin.ml | 121 |
1 files changed, 121 insertions, 0 deletions
diff --git a/vendors/ocamlbuild/src/plugin.ml b/vendors/ocamlbuild/src/plugin.ml new file mode 100644 index 0000000000..586b1ced17 --- /dev/null +++ b/vendors/ocamlbuild/src/plugin.ml @@ -0,0 +1,121 @@ +(***********************************************************************) +(* *) +(* ocamlbuild *) +(* *) +(* Nicolas Pouillard, Berke Durak, projet Gallium, INRIA Rocquencourt *) +(* *) +(* Copyright 2007 Institut National de Recherche en Informatique et *) +(* en Automatique. All rights reserved. This file is distributed *) +(* under the terms of the Q Public License version 1.0. *) +(* *) +(***********************************************************************) + + +(* Original author: Nicolas Pouillard *) +open My_std +open Format +open Log +open Pathname.Operators +open Tags.Operators +open Rule +open Tools +open Command +;; + +module Make(U:sig end) = + struct + let plugin = "myocamlbuild" + let plugin_file = plugin^".ml" + let plugin_config_file = plugin^"_config.ml" + let plugin_config_file_interface = plugin^"_config.mli" + + let we_have_a_config_file = sys_file_exists plugin_config_file + let we_need_a_plugin = !Options.plugin && sys_file_exists plugin_file + let we_have_a_plugin = sys_file_exists ((!Options.build_dir/plugin)^(!Options.exe)) + let we_have_a_config_file_interface = sys_file_exists plugin_config_file_interface + + let up_to_date_or_copy fn = + let fn' = !Options.build_dir/fn in + Pathname.exists fn && + begin + Pathname.exists fn' && Pathname.same_contents fn fn' || + begin + Shell.cp fn fn'; + false + end + end + + let profiling = Tags.mem "profile" (tags_of_pathname plugin_file) + + let debugging = Tags.mem "debug" (tags_of_pathname plugin_file) + + let rebuild_plugin_if_needed () = + let a = up_to_date_or_copy plugin_file in + let b = (not we_have_a_config_file) or up_to_date_or_copy plugin_config_file in + let c = (not we_have_a_config_file_interface) or up_to_date_or_copy plugin_config_file_interface in + if a && b && c && we_have_a_plugin then + () (* Up to date *) + (* FIXME: remove ocamlbuild_config.ml in _build/ if removed in parent *) + else begin + if !Options.native_plugin + && not (sys_file_exists ((!Ocamlbuild_where.libdir)/"ocamlbuildlib.cmxa")) then + begin + Options.native_plugin := false; + eprintf "Warning: Won't be able to compile a native plugin" + end; + let plugin_config = + if we_have_a_config_file then + if we_have_a_config_file_interface then + S[P plugin_config_file_interface; P plugin_config_file] + else P plugin_config_file + else N in + let cma, cmo, more_options, compiler = + if !Options.native_plugin then + "cmxa", "cmx", (if profiling then A"-p" else N), !Options.ocamlopt + else + "cma", "cmo", (if debugging then A"-g" else N), !Options.ocamlc + in + let ocamlbuildlib, ocamlbuild, libs = + if (not !Options.native_plugin) && !*My_unix.is_degraded then + "ocamlbuildlightlib", "ocamlbuildlight", N + else + "ocamlbuildlib", "ocamlbuild", A("unix"-.-cma) + in + let ocamlbuildlib = ocamlbuildlib-.-cma in + let ocamlbuild = ocamlbuild-.-cmo in + let dir = !Ocamlbuild_where.libdir in + if not (sys_file_exists (dir/ocamlbuildlib)) then + failwith (sprintf "Cannot find %S in ocamlbuild -where directory" ocamlbuildlib); + let dir = if Pathname.is_implicit dir then Pathname.pwd/dir else dir in + let cmd = + Cmd(S[compiler; A"-I"; P dir; libs; more_options; + P(dir/ocamlbuildlib); plugin_config; P plugin_file; + P(dir/ocamlbuild); A"-o"; Px (plugin^(!Options.exe))]) + in + Shell.chdir !Options.build_dir; + Shell.rm_f (plugin^(!Options.exe)); + Command.execute cmd + end + + let execute_plugin_if_needed () = + if we_need_a_plugin then + begin + rebuild_plugin_if_needed (); + Shell.chdir Pathname.pwd; + if not !Options.just_plugin then + let runner = if !Options.native_plugin then N else !Options.ocamlrun in + let argv = List.tl (Array.to_list Sys.argv) in + let spec = S[runner; P(!Options.build_dir/plugin^(!Options.exe)); + A"-no-plugin"; atomize (List.filter (fun s -> s <> "-plugin-option") argv)] in + let () = Log.finish () in + raise (Exit_silently_with_code (sys_command (Command.string_of_command_spec spec))) + end + else + () + end +;; + +let execute_plugin_if_needed () = + let module P = Make(struct end) in + P.execute_plugin_if_needed () +;; |
