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";
  ]