let ocaml_lib ?(extern=false) ?(byte=true) ?(native=true) ?dir ?tag_name libpath =
  let add_dir x =
    match dir with
    | Some dir -> S[A"-I"P dir; x]
    | None -> x
  in
  let tag_name =
    match tag_name with
    | Some x -> x
    | None -> "use_" ^ Pathname.basename libpath
  in
  let flag_and_dep tags lib =
    flag tags (add_dir (A lib));
    if not extern then dep tags [lib] (* cannot happen? *)
  in
  Hashtbl.replace info_libraries tag_name (libpath, extern);
  if extern then begin
    if byte then
      flag_and_dep ["ocaml"; tag_name; "link""byte"] (libpath^".cma");
    if native then
      flag_and_dep ["ocaml"; tag_name; "link""native"] (libpath^".cmxa");
  end else begin
    if not byte && not native then
      invalid_arg "ocaml_lib: ~byte:false or ~native:false only works with ~extern:true";
  end;
  match dir with
  | None -> ()
  | Some dir ->
      List.iter
        (fun x -> flag ["ocaml"; tag_name; x] (S[A"-I"P dir]))
        ["compile""doc""infer_interface"]