This commit is contained in:
parent
aa2ff7b2f0
commit
2f3113f55d
11742 changed files with 1223940 additions and 0 deletions
182
unikernel/duniverse/cmdliner/build.ml
Executable file
182
unikernel/duniverse/cmdliner/build.ml
Executable file
|
|
@ -0,0 +1,182 @@
|
|||
#!/usr/bin/env ocaml
|
||||
|
||||
(* Usage: ocaml build.ml [cma|cmxa|cmxs|clean] *)
|
||||
|
||||
let root_dir = Sys.getcwd ()
|
||||
let root_build_dir = Filename.concat root_dir "_build"
|
||||
let src_dir = "src"
|
||||
|
||||
type unit = Lib | Bin
|
||||
|
||||
let unit_dir = function Lib -> "src" | Bin -> "src/tool"
|
||||
let build_dir u = Filename.concat root_build_dir (unit_dir u)
|
||||
|
||||
let base_ocaml_opts =
|
||||
[ "-g"; "-bin-annot";
|
||||
"-safe-string"; (* Remove once we require >= 4.06 *) ]
|
||||
|
||||
(* Logging *)
|
||||
|
||||
let strf = Printf.sprintf
|
||||
let err fmt = Printf.kfprintf (fun oc -> flush oc; exit 1) stderr fmt
|
||||
let log fmt = Printf.kfprintf (fun oc -> flush oc) stdout fmt
|
||||
|
||||
(* The running joke *)
|
||||
|
||||
let rev_cut ~sep s = match String.rindex s sep with
|
||||
| exception Not_found -> None
|
||||
| i -> String.(Some (sub s 0 i, sub s (i + 1) (length s - (i + 1))))
|
||||
|
||||
let cuts ~sep s =
|
||||
let rec loop acc = function
|
||||
| "" -> acc
|
||||
| s ->
|
||||
match rev_cut ~sep s with
|
||||
| None -> s :: acc
|
||||
| Some (l, r) -> loop (r :: acc) l
|
||||
in
|
||||
loop [] s
|
||||
|
||||
(* Read, write and collect files *)
|
||||
|
||||
let fpath ~dir f = String.concat "" [dir; "/"; f]
|
||||
|
||||
let string_of_file f =
|
||||
let ic = open_in_bin f in
|
||||
let len = in_channel_length ic in
|
||||
let buf = Bytes.create len in
|
||||
really_input ic buf 0 len;
|
||||
close_in ic;
|
||||
Bytes.unsafe_to_string buf
|
||||
|
||||
let string_to_file f s =
|
||||
let oc = open_out_bin f in
|
||||
output_string oc s;
|
||||
close_out oc
|
||||
|
||||
let cp src dst = string_to_file dst (string_of_file src)
|
||||
|
||||
let ml_srcs dir =
|
||||
let add_file dir acc f = match rev_cut ~sep:'.' f with
|
||||
| Some (m, e) when e = "ml" || e = "mli" -> f :: acc
|
||||
| Some _ | None -> acc
|
||||
in
|
||||
Array.fold_left (add_file dir) [] (Sys.readdir dir)
|
||||
|
||||
(* Finding and running commands *)
|
||||
|
||||
let find_cmd cmds =
|
||||
let test, null = match Sys.win32 with
|
||||
| true -> "where", " NUL"
|
||||
| false -> "command -v", "/dev/null"
|
||||
in
|
||||
let cmd c = Sys.command (strf "%s %s 1>%s 2>%s" test c null null) = 0 in
|
||||
try Some (List.find cmd cmds) with Not_found -> None
|
||||
|
||||
let err_cmd exit cmd = err "exited with %d: %s\n" exit cmd
|
||||
let quote_cmd = match Sys.win32 with
|
||||
| false -> fun cmd -> cmd
|
||||
| true -> fun cmd -> strf "\"%s\"" cmd
|
||||
|
||||
let run_cmd args =
|
||||
let cmd = String.concat " " (List.map Filename.quote args) in
|
||||
(* log "[EXEC] %s\n" cmd; *)
|
||||
let exit = Sys.command (quote_cmd cmd) in
|
||||
if exit = 0 then () else err_cmd exit cmd
|
||||
|
||||
let read_cmd args =
|
||||
let stdout = Filename.temp_file (Filename.basename Sys.argv.(0)) "b00t" in
|
||||
at_exit (fun () -> try ignore (Sys.remove stdout) with _ -> ());
|
||||
let cmd = String.concat " " (List.map Filename.quote args) in
|
||||
let cmd = quote_cmd @@ strf "%s 1>%s" cmd (Filename.quote stdout) in
|
||||
let exit = Sys.command cmd in
|
||||
if exit = 0 then string_of_file stdout else err_cmd exit cmd
|
||||
|
||||
(* Create and delete directories *)
|
||||
|
||||
let rec mkdir dir =
|
||||
let parent = Filename.dirname dir in
|
||||
if String.equal dir parent then ()
|
||||
else mkdir (Filename.dirname dir);
|
||||
try match Sys.file_exists dir with
|
||||
| true -> ()
|
||||
| false -> run_cmd ["mkdir"; dir]
|
||||
with
|
||||
| Sys_error e -> err "%s: %s" dir e
|
||||
|
||||
let rec rmdir dir =
|
||||
try match Sys.file_exists dir with
|
||||
| false -> ()
|
||||
| true ->
|
||||
let rm f =
|
||||
let p = fpath ~dir f in
|
||||
if Sys.is_directory p
|
||||
then rmdir p
|
||||
else Sys.remove (fpath ~dir f)
|
||||
in
|
||||
Array.iter rm (Sys.readdir dir);
|
||||
run_cmd ["rmdir"; dir]
|
||||
with
|
||||
| Sys_error e -> err "%s: %s" dir e
|
||||
|
||||
(* Lookup OCaml compilers and ocamldep *)
|
||||
|
||||
let really_find_cmd alts = match find_cmd alts with
|
||||
| Some cmd -> cmd
|
||||
| None -> err "No %s found in PATH\n" (List.hd @@ List.rev alts)
|
||||
|
||||
let ocamlc () = really_find_cmd ["ocamlc.opt"; "ocamlc"]
|
||||
let ocamlopt () = really_find_cmd ["ocamlopt.opt"; "ocamlopt"]
|
||||
let ocamldep () = really_find_cmd ["ocamldep.opt"; "ocamldep"]
|
||||
|
||||
(* Build *)
|
||||
|
||||
let sort_srcs srcs =
|
||||
let srcs = List.sort String.compare srcs in
|
||||
read_cmd (ocamldep () :: "-slash" :: "-sort" :: srcs)
|
||||
|> String.trim |> cuts ~sep:' '
|
||||
|
||||
let common srcs = base_ocaml_opts @ sort_srcs srcs
|
||||
|
||||
let exe ar src =
|
||||
let lib = build_dir Lib in
|
||||
["-I"; lib; ar] @ common src
|
||||
|
||||
let build_natexe srcs =
|
||||
run_cmd ([ocamlopt ()] @ exe "cmdliner.cmxa" srcs @ ["-o"; "cmdliner"])
|
||||
|
||||
let build_bytexe srcs =
|
||||
run_cmd ([ocamlc ()] @ exe "cmdliner.cma" srcs @ ["-o"; "cmdliner"])
|
||||
|
||||
let build_cma srcs =
|
||||
run_cmd ([ocamlc ()] @ common srcs @ ["-a"; "-o"; "cmdliner.cma"])
|
||||
|
||||
let build_cmxa srcs =
|
||||
run_cmd ([ocamlopt ()] @ common srcs @ ["-a"; "-o"; "cmdliner.cmxa"])
|
||||
|
||||
let build_cmxs srcs =
|
||||
run_cmd ([ocamlopt ()] @ common srcs @ ["-shared"; "-o"; "cmdliner.cmxs"])
|
||||
|
||||
let clean () = rmdir root_build_dir
|
||||
|
||||
let in_build_dir u f =
|
||||
let src_dir = unit_dir u in
|
||||
let build_dir = build_dir u in
|
||||
let srcs = ml_srcs src_dir in
|
||||
let cp src = cp (fpath ~dir:src_dir src) (fpath ~dir:build_dir src) in
|
||||
mkdir build_dir;
|
||||
List.iter cp srcs;
|
||||
Sys.chdir build_dir; f srcs; Sys.chdir root_dir
|
||||
|
||||
let main () = match Array.to_list Sys.argv with
|
||||
| _ :: [ "natexe" ] -> in_build_dir Bin build_natexe
|
||||
| _ :: [ "bytexe" ] -> in_build_dir Bin build_bytexe
|
||||
| _ :: [ "cma" ] -> in_build_dir Lib build_cma
|
||||
| _ :: [ "cmxa" ] -> in_build_dir Lib build_cmxa
|
||||
| _ :: [ "cmxs" ] -> in_build_dir Lib build_cmxs
|
||||
| _ :: [ "clean" ] -> clean ()
|
||||
| [] | [_] -> err "Missing argument: cma, cmxa, cmxs or clean\n";
|
||||
| cmd :: args ->
|
||||
err "%s: Unknown argument(s): %s\n" cmd @@ String.concat " " args
|
||||
|
||||
let () = main ()
|
||||
Loading…
Add table
Add a link
Reference in a new issue