diff options
Diffstat (limited to 'ocaml-binary-annot/ocamlbuild/options.ml')
| -rw-r--r-- | ocaml-binary-annot/ocamlbuild/options.ml | 289 |
1 files changed, 289 insertions, 0 deletions
diff --git a/ocaml-binary-annot/ocamlbuild/options.ml b/ocaml-binary-annot/ocamlbuild/options.ml new file mode 100644 index 0000000000..0256d43acb --- /dev/null +++ b/ocaml-binary-annot/ocamlbuild/options.ml @@ -0,0 +1,289 @@ +(***********************************************************************) +(* 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 *) + +let version = "ocamlbuild "^(Sys.ocaml_version);; + +type command_spec = Command.spec + +open My_std +open Arg +open Format +open Command + +let entry = ref None +let build_dir = ref "_build" +let include_dirs = ref [] +let exclude_dirs = ref [] +let nothing_should_be_rebuilt = ref false +let sanitize = ref true +let sanitization_script = ref "sanitize.sh" +let hygiene = ref true +let ignore_auto = ref true +let plugin = ref true +let just_plugin = ref false +let native_plugin = ref true +let make_links = ref true +let nostdlib = ref false +let use_menhir = ref false +let catch_errors = ref true +let use_ocamlfind = ref false + +let mk_virtual_solvers = + let dir = Ocamlbuild_where.bindir in + List.iter begin fun cmd -> + let opt = cmd ^ ".opt" in + let a_opt = A opt in + let a_cmd = A cmd in + let search_in_path = memo Command.search_in_path in + let solver () = + if sys_file_exists !dir then + let long = filename_concat !dir cmd in + let long_opt = long ^ ".opt" in + if sys_file_exists long_opt then A long_opt + else if sys_file_exists long then A long + else try let _ = search_in_path opt in a_opt + with Not_found -> a_cmd + else + try let _ = search_in_path opt in a_opt + with Not_found -> a_cmd + in Command.setup_virtual_command_solver (String.uppercase cmd) solver + end + +let () = + mk_virtual_solvers + ["ocamlc"; "ocamlopt"; "ocamldep"; "ocamldoc"; + "ocamlyacc"; "menhir"; "ocamllex"; "ocamlmklib"; "ocamlmktop"; "ocamlfind"] +let ocamlc = ref (V"OCAMLC") +let ocamlopt = ref (V"OCAMLOPT") +let ocamldep = ref (V"OCAMLDEP") +let ocamldoc = ref (V"OCAMLDOC") +let ocamlyacc = ref N +let ocamllex = ref (V"OCAMLLEX") +let ocamlmklib = ref (V"OCAMLMKLIB") +let ocamlmktop = ref (V"OCAMLMKTOP") +let ocamlrun = ref N +let ocamlfind x = S[V"OCAMLFIND"; x] +let program_to_execute = ref false +let must_clean = ref false +let show_documentation = ref false +let recursive = ref false +let ext_lib = ref Ocamlbuild_Myocamlbuild_config.a +let ext_obj = ref Ocamlbuild_Myocamlbuild_config.o +let ext_dll = ref Ocamlbuild_Myocamlbuild_config.so +let exe = ref Ocamlbuild_Myocamlbuild_config.exe + +let targets_internal = ref [] +let ocaml_libs_internal = ref [] +let ocaml_mods_internal = ref [] +let ocaml_pkgs_internal = ref [] +let ocaml_lflags_internal = ref [] +let ocaml_cflags_internal = ref [] +let ocaml_ppflags_internal = ref [] +let ocaml_yaccflags_internal = ref [] +let ocaml_lexflags_internal = ref [] +let program_args_internal = ref [] +let ignore_list_internal = ref [] +let tags_internal = ref [["quiet"]] +let tag_lines_internal = ref [] +let show_tags_internal = ref [] +let log_file_internal = ref "_log" + +let my_include_dirs = ref [[Filename.current_dir_name]] +let my_exclude_dirs = ref [[".svn"; "CVS"]] + +let dummy = "*invalid-dummy-string*";; (* Dummy string for delimiting the latest argument *) + +(* The JoCaml support will be in a plugin when the plugin system will support + * multiple/installed plugins *) +let use_jocaml () = + ocamlc := A "jocamlc"; + ocamlopt := A "jocamlopt"; + ocamldep := A "jocamldep"; + ocamlyacc := A "jocamlyacc"; + ocamllex := A "jocamllex"; + ocamlmklib := A "jocamlmklib"; + ocamlmktop := A "jocamlmktop"; + ocamlrun := A "jocamlrun"; +;; + +let add_to rxs x = + let xs = Lexers.comma_or_blank_sep_strings (Lexing.from_string x) in + rxs := xs :: !rxs +let add_to' rxs x = + if x <> dummy then + rxs := [x] :: !rxs + else + () +let set_cmd rcmd = String (fun s -> rcmd := Sh s) +let set_build_dir s = make_links := false; build_dir := s +let spec = + Arg.align + [ + "-version", Unit (fun () -> print_endline version; raise Exit_OK), " Display the version"; + "-vnum", Unit (fun () -> print_endline Sys.ocaml_version; raise Exit_OK), + " Display the version number"; + "-quiet", Unit (fun () -> Log.level := 0), " Make as quiet as possible"; + "-verbose", Int (fun i -> Log.level := i + 2), "<level> Set the verbosity level"; + "-documentation", Set show_documentation, " Show rules and flags"; + "-log", Set_string log_file_internal, "<file> Set log file"; + "-no-log", Unit (fun () -> log_file_internal := ""), " No log file"; + "-clean", Set must_clean, " Remove build directory and other files, then exit"; + "-r", Set recursive, " Traverse directories by default (true: traverse)"; + + "-I", String (add_to' my_include_dirs), "<path> Add to include directories"; + "-Is", String (add_to my_include_dirs), "<path,...> (same as above, but accepts a (comma or blank)-separated list)"; + "-X", String (add_to' my_exclude_dirs), "<path> Directory to ignore"; + "-Xs", String (add_to my_exclude_dirs), "<path,...> (idem)"; + + "-lib", String (add_to' ocaml_libs_internal), "<flag> Link to this ocaml library"; + "-libs", String (add_to ocaml_libs_internal), "<flag,...> (idem)"; + "-mod", String (add_to' ocaml_mods_internal), "<module> Link to this ocaml module"; + "-mods", String (add_to ocaml_mods_internal), "<module,...> (idem)"; + "-pkg", String (add_to' ocaml_pkgs_internal), "<package> Link to this ocaml findlib package"; + "-pkgs", String (add_to ocaml_pkgs_internal), "<package,...> (idem)"; + "-package", String (add_to' ocaml_pkgs_internal), "<package> (idem)"; + "-lflag", String (add_to' ocaml_lflags_internal), "<flag> Add to ocamlc link flags"; + "-lflags", String (add_to ocaml_lflags_internal), "<flag,...> (idem)"; + "-cflag", String (add_to' ocaml_cflags_internal), "<flag> Add to ocamlc compile flags"; + "-cflags", String (add_to ocaml_cflags_internal), "<flag,...> (idem)"; + "-yaccflag", String (add_to' ocaml_yaccflags_internal), "<flag> Add to ocamlyacc flags"; + "-yaccflags", String (add_to ocaml_yaccflags_internal), "<flag,...> (idem)"; + "-lexflag", String (add_to' ocaml_lexflags_internal), "<flag> Add to ocamllex flags"; + "-lexflags", String (add_to ocaml_lexflags_internal), "<flag,...> (idem)"; + "-ppflag", String (add_to' ocaml_ppflags_internal), "<flag> Add to ocaml preprocessing flags"; + "-pp", String (add_to ocaml_ppflags_internal), "<flag,...> (idem)"; + "-tag", String (add_to' tags_internal), "<tag> Add to default tags"; + "-tags", String (add_to tags_internal), "<tag,...> (idem)"; + "-tag-line", String (add_to' tag_lines_internal), "<tag> Use this line of tags (as in _tags)"; + "-show-tags", String (add_to' show_tags_internal), "<path> Show tags that applies on that pathname"; + + "-ignore", String (add_to ignore_list_internal), "<module,...> Don't try to build these modules"; + "-no-links", Clear make_links, " Don't make links of produced final targets"; + "-no-skip", Clear ignore_auto, " Don't skip modules that are requested by ocamldep but cannot be built"; + "-no-hygiene", Clear hygiene, " Don't apply sanity-check rules"; + "-no-plugin", Clear plugin, " Don't build myocamlbuild.ml"; + "-no-stdlib", Set nostdlib, " Don't ignore stdlib modules"; + "-dont-catch-errors", Clear catch_errors, " Don't catch and display exceptions (useful to display the call stack)"; + "-just-plugin", Set just_plugin, " Just build myocamlbuild.ml"; + "-byte-plugin", Clear native_plugin, " Don't use a native plugin but bytecode"; + "-sanitization-script", Set_string sanitization_script, " Change the file name for the generated sanitization script"; + "-no-sanitize", Clear sanitize, " Do not generate sanitization script"; + "-nothing-should-be-rebuilt", Set nothing_should_be_rebuilt, " Fail if something needs to be rebuilt"; + "-classic-display", Set Log.classic_display, " Display executed commands the old-fashioned way"; + "-use-menhir", Set use_menhir, " Use menhir instead of ocamlyacc"; + "-use-jocaml", Unit use_jocaml, " Use jocaml compilers instead of ocaml ones"; + "-use-ocamlfind", Set use_ocamlfind, " Use ocamlfind to call ocaml compilers"; + + "-j", Set_int Command.jobs, "<N> Allow N jobs at once (0 for unlimited)"; + + "-build-dir", String set_build_dir, "<path> Set build directory (implies no-links)"; + "-install-lib-dir", Set_string Ocamlbuild_where.libdir, "<path> Set the install library directory"; + "-install-bin-dir", Set_string Ocamlbuild_where.bindir, "<path> Set the install binary directory"; + "-where", Unit (fun () -> print_endline !Ocamlbuild_where.libdir; raise Exit_OK), " Display the install library directory"; + + "-ocamlc", set_cmd ocamlc, "<command> Set the OCaml bytecode compiler"; + "-ocamlopt", set_cmd ocamlopt, "<command> Set the OCaml native compiler"; + "-ocamldep", set_cmd ocamldep, "<command> Set the OCaml dependency tool"; + "-ocamlyacc", set_cmd ocamlyacc, "<command> Set the ocamlyacc tool"; + "-menhir", set_cmd ocamlyacc, "<command> Set the menhir tool (use it after -use-menhir)"; + "-ocamllex", set_cmd ocamllex, "<command> Set the ocamllex tool"; + (* Not set since we perhaps want to replace ocamlmklib *) + (* "-ocamlmklib", set_cmd ocamlmklib, "<command> Set the ocamlmklib tool"; *) + "-ocamlmktop", set_cmd ocamlmktop, "<command> Set the ocamlmktop tool"; + "-ocamlrun", set_cmd ocamlrun, "<command> Set the ocamlrun tool"; + + "--", Rest (fun x -> program_to_execute := true; add_to' program_args_internal x), + " Stop argument processing, remaining arguments are given to the user program"; + ] + +let targets = ref [] +let ocaml_libs = ref [] +let ocaml_mods = ref [] +let ocaml_pkgs = ref [] +let ocaml_lflags = ref [] +let ocaml_cflags = ref [] +let ocaml_ppflags = ref [] +let ocaml_yaccflags = ref [] +let ocaml_lexflags = ref [] +let program_args = ref [] +let ignore_list = ref [] +let tags = ref [] +let tag_lines = ref [] +let show_tags = ref [] + +let init () = + let anon_fun = add_to' targets_internal in + let usage_msg = sprintf "Usage %s [options] <target>" Sys.argv.(0) in + let argv' = Array.concat [Sys.argv; [|dummy|]] in + parse_argv argv' spec anon_fun usage_msg; + Shell.mkdir_p !build_dir; + + let () = + let log = !log_file_internal in + if log = "" then Log.init None + else if not (Filename.is_implicit log) then + failwith + (sprintf "Bad log file name: the file name must be implicit (not %S)" log) + else + let log = filename_concat !build_dir log in + Shell.mkdir_p (Filename.dirname log); + Shell.rm_f log; + let log = if !Log.level > 0 then Some log else None in + Log.init log + in + + if !use_ocamlfind then begin + (* TODO: warning message when using an option such as -ocamlc *) + (* Note that plugins can still modify these variables After_options. + This design decision can easily be changed. *) + ocamlc := ocamlfind & A"ocamlc"; + ocamlopt := ocamlfind & A"ocamlopt"; + ocamldep := ocamlfind & A"ocamldep"; + ocamldoc := ocamlfind & A"ocamldoc"; + ocamlmktop := ocamlfind & A"ocamlmktop"; + end; + + let reorder x y = x := !x @ (List.concat (List.rev !y)) in + reorder targets targets_internal; + reorder ocaml_libs ocaml_libs_internal; + reorder ocaml_mods ocaml_mods_internal; + reorder ocaml_pkgs ocaml_pkgs_internal; + reorder ocaml_cflags ocaml_cflags_internal; + reorder ocaml_lflags ocaml_lflags_internal; + reorder ocaml_ppflags ocaml_ppflags_internal; + reorder ocaml_yaccflags ocaml_yaccflags_internal; + reorder ocaml_lexflags ocaml_lexflags_internal; + reorder program_args program_args_internal; + reorder tags tags_internal; + reorder tag_lines tag_lines_internal; + reorder ignore_list ignore_list_internal; + reorder show_tags show_tags_internal; + + let check_dir dir = + if Filename.is_implicit dir then + sys_file_exists dir + else + failwith + (sprintf "Included or excluded directories must be implicit (not %S)" dir) + in + let dir_reorder my dir = + let d = !dir in + reorder dir my; + dir := List.filter check_dir (!dir @ d) + in + dir_reorder my_include_dirs include_dirs; + dir_reorder my_exclude_dirs exclude_dirs; + + ignore_list := List.map String.capitalize !ignore_list +;; |
