#!/usr/bin/env ocaml
#use "myocamlbuild_config.ml"
-let valid_targets = [ "distclean"; "clean"; "all" ]
+let valid_targets = [ "distclean"; "clean"; "all" ]
module Cmdline =
struct
open Arg
let set r s () = r := s
+ let cons r s () = r := s :: !r
let targets = ref []
+ let tags = ref []
let flavor = ref "native"
- let debug = ref ""
- let profile = ref ""
let verbose = ref ""
let jobs = ref 0
let specs = align
- [ "-verbose", Unit (set verbose "-classic-display"),
+ [ "-verbose", Unit (set verbose "-verbose 10 -classic-display"),
" Display compilation commands";
- "-debug", Unit (set debug "-tag debug"),
+ "-debug", Unit (cons tags "-tag debug"),
" Build with debugging code";
- "-profile", Unit (set profile "-tag profile"),
+ "-profile", Unit (cons tags "-tag profile"),
" Build with profiling code";
+ "-trace", Unit (cons tags "-tag trace"),
+ " Build with tracing code enabled";
+
"-byte", Unit (set flavor "byte"),
" Produce bytecode instead of native code";
"-j", Int (fun i -> if i < 0 || i > 1024
let () = Cmdline.parse ()
let cmd_list =
let ocamlbuild =
- Printf.sprintf "ocamlbuild -no-hygiene %s %s %s -j %i "
- !Cmdline.verbose !Cmdline.profile !Cmdline.debug !Cmdline.jobs
+ Printf.sprintf "ocamlbuild -no-hygiene %s %s -j %i "
+ !Cmdline.verbose (String.concat " " !Cmdline.tags) !Cmdline.jobs
in
List.map begin function
- | "distclean" -> "rm myocamlbuild_config.ml; ocamlbuild -clean"
+ | "distclean" -> "rm -f myocamlbuild_config.ml; ocamlbuild -clean"
| "clean" -> "ocamlbuild -clean"
| "all" -> ocamlbuild ^ (List.assoc !Cmdline.flavor main_targets)
| test ->
open Format
let print_list l =
- Printf.eprintf "%![";
- List.iter (fun s -> Printf.eprintf " '%s' " s) l;
- Printf.eprintf "]\n%!"
-
+ eprintf "%![%s]%!\n" (String.concat ", " l)
(*let cxx_flags = S (List.map ( fun x -> A x) cxx_flags)*)
let _A x = A x
_ -> open_in (include_full_path / ml)
in
let includes = ref [] in
- try
- while true do
- let s = input_line ic in
- try
- if String.length s > 0 then sscanf s " INCLUDE \"%s@\"" ((=::) includes)
- with
- Scan_failure _ -> ()
- done; []
- with End_of_file -> close_in ic; !includes
+ let () =
+ try
+ while true do
+ let s = input_line ic in
+ if String.length s > 0 then
+ try sscanf s " INCLUDE \"%s@\"" ((=::) includes)
+ with Scan_failure _ -> ()
+ done
+ with End_of_file -> close_in ic
+ in
+ !includes
let ocaml ml =
let rec loop file =
let parse_depends file depfile =
let ichan = open_in depfile in
let iscan = Scanning.from_channel ichan in
- let () = bscanf iscan " %s@: " ignore in
- let () = bscanf iscan " %s " ignore in
let includes = ref [] in
- try
- while true do
- try
- let s = bscanf iscan " %s " (fun s -> s) in
- if s = "" then raise End_of_file;
- if s <> "\\" then includes =::s
- with
- Scan_failure _ -> ()
- done; []
- with
- End_of_file -> close_in ichan; !includes
+ begin
+ bscanf iscan " %s@: " ignore;
+ bscanf iscan " %s " ignore;
+ try
+ while true do
+ try
+ let s = bscanf iscan " %s " (fun s -> s) in
+ if s = "" then raise End_of_file;
+ if s <> "\\" then includes =::s
+ with
+ Scan_failure _ -> ()
+ done
+ with
+ End_of_file -> close_in ichan
+ end;
+ !includes
let uniq l =
let rec loop l acc =
let cxx cpp =
let depfile = ( cpp ^ ".depends") in
let cmd = Cmd (S[ A cxx_cmd ; S !cxx_flags; cxx_include_flags ; A"-MM";
- A "-MG"; A "-MF"; P depfile; P cpp])
+ A "-MF"; P depfile; P cpp])
in
let () = Command.execute ~quiet:true ~pretend:false cmd in
let includes = parse_depends cpp depfile in
- List.filter (Pathname.is_relative) (uniq includes)
+ let includes' = uniq (List.filter (Pathname.is_relative) includes) in
+ dep [ "compile"; "file:" ^ cpp ] includes'
end
let cxx_compile env build =
let src = env "%.cpp" and obj = env "%.o" in
- let local_include = Depends.cxx src in
- let local_dispatch = List.map (fun p -> List.map (fun p' -> p'/p) project_dirs) local_include in
- let () = ignore (build local_dispatch ) in
- Cmd(S[A cxx_cmd; A "-o" ; P obj; A "-c"; S !cxx_flags; cxx_include_flags; P src])
+ let tags = (tags_of_pathname src) ++ "compile" ++ "c++" in
+ Cmd(S[T tags; A cxx_cmd; A "-o" ; P obj; A "-c"; S !cxx_flags; cxx_include_flags; P src])
(* Native compile and link action *)
-let ocamlfind x = S[ A"ocamlfind"; x ; A "-package"; A ocamlfind_packages ]
+let ocamlfind x = S[ T (Tags.singleton "ocamlfind"); A"ocamlfind"; x ; A "-package"; A ocamlfind_packages ]
let ppopt l = List.map (fun e -> S[ A"-ppopt"; e ]) l
Options.ocamldoc := ocamlfind (A"ocamldoc");
Options.ocamlmktop := ocamlfind (A"ocamlmktop");
-
+ if (List.mem "trace" !Options.tags) then begin
+ pp_macro_options @= [ A "-DTRACE" ];
+ end;
if (List.mem "profile" !Options.tags) then begin
pp_macro_options @= [ A "-DPROFILE" ];
native_compile_flags @= [A "-p" ];
Array.iter (fun entry ->
if Pathname.check_extension entry "ml" then
Depends.ocaml (src_path / entry)
- (* else if Pathname.check_extension entry "cpp" then
- Depends.cxx (src_path / entry) *)
+ else if Pathname.check_extension entry "cpp" then
+ Depends.cxx (src_path / entry)
) dir;
| After_rules ->
dep [ "link" ] cstub_lib;
- rule "compile cpp -> o" ~prod:"%.o" ~deps:[ "%.cpp"] cxx_compile;
+ rule "compile cpp -> o" ~prod:"%.o" ~deps:[ "%.cpp" ] cxx_compile;
let syntax_flags = S ([ A "-syntax"; A "camlp4o";
S (ppopt [A "-printer" ; A"Camlp4OCamlAstDumper"]);