#load "str.cma";; open StdLabels open Printf let ( ^/ ) = Filename.concat (* Topoligically sorted *) let modules = [ "Import" ; "Clflags" ; "Loc" ; "Sexp" ; "Sexp_lexer" ; "Future" ; "Kind" ; "Values" ; "Rule" ; "Jbuild_interpret" ; "Jbuild" ] let lexers = [ "sexp_lexer" ] let path = match Sys.getenv "PATH" with | exception Not_found -> [] | s -> let sep = if Sys.win32 then ";" else ":" in Str.split_delim (Str.regexp sep) s ;; let exe = if Sys.win32 then ".exe" else "" let prog_not_found prog = eprintf "Program %s not found in PATH" prog; exit 2 type mode = Native | Byte let best_prog dir prog = let fn = dir ^/ prog ^ ".opt" ^ exe in if Sys.file_exists fn then Some fn else let fn = dir ^/ prog ^ exe in if Sys.file_exists fn then Some fn else None let find_prog prog = let rec search = function | [] -> None | dir :: rest -> match best_prog dir prog with | None -> search rest | Some fn -> Some (dir, fn) in search path let get_prog dir prog = match best_prog dir prog with | None -> prog_not_found prog | Some fn -> fn let count_newlines s = let newlines = ref 0 in String.iter s ~f:(function | '\n' -> incr newlines | _ -> ()); !newlines let read_file fn = let ic = open_in fn in let data = really_input_string ic (in_channel_length ic) in close_in ic; data let generated_file = "jbuild.ml" let generate_file_with_all_the_sources () = let oc = open_out "jbuild.ml" in let pos_in_generated_file = ref 1 in let pr fmt = ksprintf (fun s -> output_string oc s; output_char oc '\n'; incr pos_in_generated_file) fmt in let dump fn = let s = read_file fn in pr "# 1 %S" fn; output_string oc s; let newlines = count_newlines s in let newlines = if s <> "" && s.[String.length s - 1] <> '\n' then begin output_char oc '\n'; newlines + 1 end else newlines in pos_in_generated_file := !pos_in_generated_file + newlines; pr "# %d %S" (!pos_in_generated_file + 1) generated_file in pr "module M : sig end = struct"; List.iter modules ~f:(fun m -> let base = String.uncapitalize m in let mli = sprintf "src/%s.mli" base in let ml = sprintf "src/%s.ml" base in if Sys.file_exists mli then begin pr "module %s : sig" m; dump mli; pr "end = struct"; dump ml; pr "end" end else begin pr "module %s = struct" m; dump ml; pr "end" end); pr "end"; close_out oc let exec fmt = ksprintf (fun cmd -> print_endline cmd; Sys.command cmd) fmt let () = let bin_dir, mode, compiler = match find_prog "ocamlopt" with | Some (bin_dir, prog) -> (bin_dir, Native, prog) | None -> match find_prog "ocamlc" with | Some (bin_dir, prog) -> (bin_dir, Byte, prog) | None -> prog_not_found "ocamlc" in let ocamllex = get_prog bin_dir "ocamllex" in List.iter lexers ~f:(fun name -> let src = "src" ^/ name ^ ".mll" in let dst = "src" ^/ name ^ ".ml" in let x = Sys.file_exists dst in let n = exec "%s %s" ocamllex src in if n <> 0 then exit n; if not x then at_exit (fun () -> try Sys.remove dst with _ -> ())); generate_file_with_all_the_sources (); let lib_ext = match mode with | Native -> "cmxa" | Byte -> "cma" in exit (exec "%s -w -40 -o jbuild unix.%s %s" compiler lib_ext generated_file)