File: plugin.ml

package info (click to toggle)
ocaml 3.11.2-2
  • links: PTS, VCS
  • area: main
  • in suites: squeeze
  • size: 18,536 kB
  • ctags: 25,262
  • sloc: ml: 160,855; ansic: 39,174; sh: 5,564; asm: 4,502; lisp: 3,998; makefile: 2,374; perl: 82; sed: 19; tcl: 2
file content (119 lines) | stat: -rw-r--r-- 4,834 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
(***********************************************************************)
(*                             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 spec = S[runner; P(!Options.build_dir/plugin^(!Options.exe));
                         A"-no-plugin"; atomize (List.tl (Array.to_list Sys.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 ()
;;