File: bootstrap.ml

package info (click to toggle)
ocaml-dune 3.21.1-2
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 37,948 kB
  • sloc: ml: 189,514; asm: 28,570; ansic: 15,173; sh: 1,448; lisp: 625; makefile: 160; python: 143; cpp: 48; javascript: 10
file content (118 lines) | stat: -rw-r--r-- 3,767 bytes parent folder | download | duplicates (4)
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
open StdLabels
open Printf

(* This program performs version checking of the compiler and switches to the
   secondary compiler if necessary. The script should execute in OCaml 4.02! *)

let min_supported_natively = 4, 08, 0

let keep_generated_files =
  let anon s = raise (Arg.Bad (sprintf "don't know what to do with %s\n" s)) in
  let keep_generated_files = ref false in
  Arg.parse
    [ "-j", Arg.Int ignore, "JOBS Concurrency"
    ; "--verbose", Arg.Unit ignore, " Set the display mode"
    ; "--keep-generated-files", Arg.Set keep_generated_files, " Keep generated files"
    ; "--debug", Arg.Unit ignore, " Enable various debugging options"
    ; ( "--force-byte-compilation"
      , Arg.Unit ignore
      , " Force bytecode compilation even if ocamlopt is available" )
    ; "--static", Arg.Unit ignore, " Build a static binary"
    ; "--boot-dir", Arg.String (fun _ -> ()), " set the boot directory"
    ]
    anon
    "Usage: ocaml bootstrap.ml <options>\nOptions are:";
  !keep_generated_files
;;

let modules = [ "boot/types"; "boot/libs"; "boot/duneboot" ]
let duneboot = ".duneboot"
let prog = duneboot ^ ".exe"

let () =
  at_exit (fun () ->
    Array.iter (Sys.readdir "boot") ~f:(fun fn ->
      let fn = Filename.concat "boot" fn in
      if Filename.check_suffix fn ".cmi" || Filename.check_suffix fn ".cmo"
      then (
        try Sys.remove fn with
        | Sys_error _ -> ())));
  if not keep_generated_files
  then
    at_exit (fun () ->
      Array.iter (Sys.readdir ".") ~f:(fun fn ->
        if
          String.length fn >= String.length duneboot
          && String.sub fn ~pos:0 ~len:(String.length duneboot) = duneboot
        then (
          try Sys.remove fn with
          | Sys_error _ -> ())))
;;

let runf fmt =
  ksprintf
    (fun cmd ->
       prerr_endline cmd;
       Sys.command cmd)
    fmt
;;

let exit_if_non_zero = function
  | 0 -> ()
  | n -> exit n
;;

let read_file fn =
  let ic = open_in_bin fn in
  let s = really_input_string ic (in_channel_length ic) in
  close_in ic;
  s
;;

let () =
  let v = Scanf.sscanf Sys.ocaml_version "%d.%d.%d" (fun a b c -> a, b, c) in
  let compiler, which =
    if v >= min_supported_natively
    then "ocamlc", None
    else (
      let compiler = "ocamlfind -toolchain secondary ocamlc" in
      let output_fn, out = Filename.open_temp_file "duneboot" "ocamlfind-output" in
      let n = runf "%s 2>%s" compiler output_fn in
      let s = read_file output_fn in
      close_out out;
      prerr_endline s;
      if n <> 0 || s <> ""
      then (
        Format.eprintf
          "@[%a@]@."
          Format.pp_print_text
          (let a, b, _ = min_supported_natively in
           sprintf
             "The ocamlfind's secondary toolchain does not seem to be correctly installed.\n\
              Dune requires OCaml %d.%02d or later to compile.\n\
              Please either upgrade your compile or configure a secondary OCaml compiler \
              (in opam, this can be done by installing the ocamlfind-secondary package)."
             a
             b);
        exit 2);
      compiler, Some "--secondary")
  in
  exit_if_non_zero
    (runf
       "%s %s -intf-suffix .dummy -g -o %s -I boot %sunix.cma %s"
       compiler
       (* Make sure to produce a self-contained binary as dlls tend to cause
          issues *)
       (if v < (4, 10, 1) then "-custom" else "-output-complete-exe")
       prog
       (if v >= (5, 0, 0) then "-I +unix " else "")
       (List.map modules ~f:(fun m -> m ^ ".ml") |> String.concat ~sep:" "));
  let args = List.tl (Array.to_list Sys.argv) in
  let args =
    match which with
    | None -> args
    | Some x -> x :: args
  in
  let args = Filename.concat "." prog :: args in
  exit (runf "%s" (String.concat ~sep:" " args))
;;