Merge commit 'ocaml3102'
[ocaml.git] / ocamlbuild / plugin.ml
blobd72b920497cc42a26efa2a94bf213be09d00abea
1 (***********************************************************************)
2 (* ocamlbuild *)
3 (* *)
4 (* Nicolas Pouillard, Berke Durak, projet Gallium, INRIA Rocquencourt *)
5 (* *)
6 (* Copyright 2007 Institut National de Recherche en Informatique et *)
7 (* en Automatique. All rights reserved. This file is distributed *)
8 (* under the terms of the Q Public License version 1.0. *)
9 (* *)
10 (***********************************************************************)
12 (* $Id$ *)
13 (* Original author: Nicolas Pouillard *)
14 open My_std
15 open Format
16 open Log
17 open Pathname.Operators
18 open Tags.Operators
19 open Rule
20 open Tools
21 open Command
24 module Make(U:sig end) =
25 struct
26 let plugin = "myocamlbuild"
27 let plugin_file = plugin^".ml"
28 let plugin_config_file = plugin^"_config.ml"
29 let plugin_config_file_interface = plugin^"_config.mli"
31 let we_have_a_config_file = sys_file_exists plugin_config_file
32 let we_need_a_plugin = !Options.plugin && sys_file_exists plugin_file
33 let we_have_a_plugin = sys_file_exists (!Options.build_dir/plugin)
34 let we_have_a_config_file_interface = sys_file_exists plugin_config_file_interface
36 let up_to_date_or_copy fn =
37 let fn' = !Options.build_dir/fn in
38 Pathname.exists fn &&
39 begin
40 Pathname.exists fn' && Pathname.same_contents fn fn' ||
41 begin
42 Shell.cp fn fn';
43 false
44 end
45 end
47 let profiling = Tags.mem "profile" (tags_of_pathname plugin_file)
49 let debugging = Tags.mem "debug" (tags_of_pathname plugin_file)
51 let rebuild_plugin_if_needed () =
52 let a = up_to_date_or_copy plugin_file in
53 let b = (not we_have_a_config_file) or up_to_date_or_copy plugin_config_file in
54 let c = (not we_have_a_config_file_interface) or up_to_date_or_copy plugin_config_file_interface in
55 if a && b && c && we_have_a_plugin then
56 () (* Up to date *)
57 (* FIXME: remove ocamlbuild_config.ml in _build/ if removed in parent *)
58 else begin
59 let plugin_config =
60 if we_have_a_config_file then
61 if we_have_a_config_file_interface then
62 S[P plugin_config_file_interface; P plugin_config_file]
63 else P plugin_config_file
64 else N in
65 let cma, cmo, more_options, compiler =
66 if !Options.native_plugin then
67 "cmxa", "cmx", (if profiling then A"-p" else N), !Options.ocamlopt
68 else
69 "cma", "cmo", (if debugging then A"-g" else N), !Options.ocamlc
71 let ocamlbuildlib, ocamlbuild, libs =
72 if (not !Options.native_plugin) && !*My_unix.is_degraded then
73 "ocamlbuildlightlib", "ocamlbuildlight", N
74 else
75 "ocamlbuildlib", "ocamlbuild", A("unix"-.-cma)
77 let ocamlbuildlib = ocamlbuildlib-.-cma in
78 let ocamlbuild = ocamlbuild-.-cmo in
79 let dir = !Ocamlbuild_where.libdir in
80 if not (sys_file_exists (dir/ocamlbuildlib)) then
81 failwith (sprintf "Cannot find %S in ocamlbuild -where directory" ocamlbuildlib);
82 let dir = if Pathname.is_implicit dir then Pathname.pwd/dir else dir in
83 let cmd =
84 Cmd(S[compiler; A"-I"; P dir; libs; more_options;
85 P(dir/ocamlbuildlib); plugin_config; P plugin_file;
86 P(dir/ocamlbuild); A"-o"; Px plugin])
88 Shell.chdir !Options.build_dir;
89 Shell.rm_f plugin;
90 Command.execute cmd
91 end
93 let execute_plugin_if_needed () =
94 if we_need_a_plugin then
95 begin
96 rebuild_plugin_if_needed ();
97 Shell.chdir Pathname.pwd;
98 if not !Options.just_plugin then
99 let spec = S[!Options.ocamlrun; P(!Options.build_dir/plugin);
100 A"-no-plugin"; atomize (List.tl (Array.to_list Sys.argv))] in
101 raise (Exit_silently_with_code (sys_command (Command.string_of_command_spec spec)))
103 else
108 let execute_plugin_if_needed () =
109 let module P = Make(struct end) in
110 P.execute_plugin_if_needed ()