";
+ "-ignore-error", Arg.Set ignore_error,
+ " Ignore the 'error' directive in META files";
+ "-xdot", Arg.Set xdot,
+ " invoke ``xdot'' on .dot file";
+ "-verbose", Arg.Unit (fun () -> verbose := Verbose),
+ " Only show the constructed command, but do not exec it\nSTANDARD OPTIONS:";
+ ] in
+
+ let (current,args) =
+ (current, !argv) in
+
+ parse_args
+ ~current
+ ~args
+ arg_spec
+ (fun s -> failwith (Printf.sprintf "Should not provide any files to the package-graph subcommand (only packages): %s" s))
+ ("usage: not-ocamlfind package-graph [options] -package ");
+
+ (* ---- Start requirements analysis ---- *)
+
+ if not (List.mem "native" !predicates) && not (List.mem "byte" !predicates) then
+ predicates := "byte" :: !predicates;
+
+ if !syntax_preds <> [] then begin
+ predicates := "syntax" :: !predicates;
+ syntax_preds := "preprocessor" :: "syntax" :: !syntax_preds;
+ end;
+
+ (* check packages: *)
+ check_package_list !packages;
+
+ let eff_packages =
+ package_deep_ancestors !predicates !packages in
+
+ (* ---- End of requirements analysis ---- *)
+
+ (* Check on [warning] directives: *)
+ List.iter
+ (fun pkg ->
+ try
+ let warning = package_property !predicates pkg "warning" in
+ prerr_endline("ocamlfind: [WARNING] Package `" ^ pkg ^
+ "': " ^ warning)
+ with
+ Not_found -> ()
+ )
+ eff_packages;
+
+ (* Check on [error] directives: *)
+ List.iter
+ (fun pkg ->
+ try
+ let error = package_property !predicates pkg "error" in
+ if !ignore_error then
+ prerr_endline("ocamlfind: [WARNING] Package `" ^ pkg ^
+ "' signals error: " ^ error)
+ else
+ failwith ("Error from package `" ^ pkg ^ "': " ^ error)
+ with
+ Not_found -> ()
+ )
+ eff_packages;
+
+ if !verbose = Verbose then begin
+ if !syntax_preds <> [] then
+ print_string ("Effective set of preprocessor predicates: " ^
+ String.concat "," !syntax_preds ^ "\n");
+ print_string ("Effective set of compiler predicates: " ^
+ String.concat "," !predicates ^ "\n");
+ end;
+
+ (* initl_file_name: the initialization code inserted at the end of
+ * the cma/cmo list (initl = init last)
+ *)
+
+ let package_graph = List.map (fun p ->
+ (p, package_ancestors !predicates p)) eff_packages in
+
+ let name2vertex = List.map (fun (p,_) ->
+ let size = size_of_package !predicates p in
+ let rhs = if size = 0 then
+ Fmt.(str "\"%s\"" p)
+ else Fmt.(str "\"%s: %a\"" p bi_byte_size size) in
+ (p, rhs)) package_graph in
+(*
+ let name2vertex = List.map (fun (p, _) -> (p, Printf.sprintf "\"%s\"" p)) package_graph in
+*)
+ let n2v n = match List.assoc n name2vertex with
+ v -> v | exception Not_found -> failwith (Printf.sprintf "package %s not in name2vertex map" n) in
+
+ let g2 = List.map (fun (s,dl) -> (n2v s, List.map n2v dl)) package_graph in
+ let dominator_from = match !dominator_from with "" -> None | s -> Some (n2v s) in
+
+ if !xdot then begin
+ let tmpfile = Filename.temp_file "graph" ".dot" in
+ let oc = open_out tmpfile in
+ PackageGraph.to_dot ~dominator_from:dominator_from oc g2 ;
+ close_out oc ;
+ ignore (Unix.system (Printf.sprintf "xdot %s" tmpfile)) ;
+ ignore (Unix.unlink tmpfile)
+ end
+ else
+ PackageGraph.to_dot ~dominator_from:dominator_from stdout g2
+;;
+
+(************************************************************************)
+
+let format_owner_file pkg file =
+ let outpath = file ^ ".owner" in
+ let contents = (pkg ^ "\n") in
+ (outpath, contents)
+;;
+
+let trim_cr s =
+ let len = String.length s in
+ if len > 0 && String.get s (len-1) = '\r' then
+ String.sub s 0 (len-1)
+ else
+ s
+
+let find_owned_files pkg dir =
+ let files = Array.to_list(Sys.readdir dir) in
+ List.filter
+ (fun file ->
+ let owner_file =
+ if Filename.check_suffix file ".owner" then
+ file
+ else
+ file ^ ".owner" in
+ (List.mem owner_file files) && (
+ try
+ let fd =
+ Unix.openfile (Filename.concat dir owner_file) [Unix.O_RDONLY] 0 in
+ let f =
+ Unix.in_channel_of_descr fd in
+ try
+ let line = trim_cr (input_line f) in
+ let is_my_file = (line = pkg) in
+ close_in f;
+ is_my_file
+ with
+ | End_of_file -> close_in f; false
+ | exc -> close_in f; raise exc
+ with
+ | Unix.Unix_error(Unix.ENOENT,_,_) ->
+ (* the owner file might have been removed by a package
+ removal that is being done in parallel
+ *)
+ false
+ | Unix.Unix_error(code, _, arg) ->
+ raise(sys_error code arg)
+ )
+ )
+ files
+;;
+
+
+
+exception Missing_archives of Fl_metascanner.pkg_expr
+
+let rec patch_archives pkgdir pkg =
+ (* First remove all missing files from archive variables: *)
+ let defs' =
+ List.map
+ (fun def ->
+ if def.Fl_metascanner.def_var = "archive" then (
+ let files = Fl_split.in_words def.Fl_metascanner.def_value in
+ let files' =
+ List.filter
+ (fun file ->
+ let p = Findlib.resolve_path ~base:pkgdir file in
+ Sys.file_exists p)
+ files in
+ { def with
+ Fl_metascanner.def_value = String.concat " " files'
+ }
+ )
+ else def
+ )
+ pkg.Fl_metascanner.pkg_defs in
+ (* Remove empty archive variables: *)
+ let defs'' =
+ List.filter
+ (fun def ->
+ def.Fl_metascanner.def_var <> "archive" ||
+ Fl_split.in_words def.Fl_metascanner.def_value <> []
+ )
+ defs' in
+ (* Return the package or raise Not_found if all archives vanished: *)
+ let children =
+ (* Recursive patch, remove all Not_found packages: *)
+ List.flatten
+ (List.map
+ (fun (name, child) ->
+ try [ name, patch_archives pkgdir child ]
+ with Missing_archives _ -> []
+ )
+ pkg.Fl_metascanner.pkg_children) in
+ let pkg' =
+ { Fl_metascanner.pkg_defs = defs'';
+ pkg_children = children
+ } in
+ if List.exists (fun def -> def.Fl_metascanner.def_var = "archive") defs'' then
+ pkg'
+ else
+ raise (Missing_archives pkg')
+;;
+
+
+let rec patch_pkg pkgdir pkg patches =
+ match patches with
+ | [] -> pkg
+ | (`Version v) :: patches' ->
+ let def =
+ { Fl_metascanner.def_var = "version";
+ def_flav = `BaseDef;
+ def_preds = [];
+ def_value = v
+ } in
+ let defs =
+ List.filter
+ (fun d -> d.Fl_metascanner.def_var <> "version")
+ pkg.Fl_metascanner.pkg_defs in
+ let pkg' =
+ { pkg with
+ Fl_metascanner.pkg_defs = def :: defs
+ } in
+ patch_pkg pkgdir pkg' patches'
+ | (`Rmpkg n) :: patches' ->
+ let children =
+ List.filter
+ (fun (name,_) -> name <> n)
+ pkg.Fl_metascanner.pkg_children in
+ let pkg' =
+ { pkg with
+ Fl_metascanner.pkg_children = children
+ } in
+ patch_pkg pkgdir pkg' patches'
+ | `Archives :: patches' ->
+ let pkg' =
+ try patch_archives pkgdir pkg
+ with
+ Missing_archives p -> p in
+ patch_pkg pkgdir pkg' patches'
+;;
+
+
+exception Skip_file;;
+
+type which = Auto | Dll | No_dll;;
+
+let meta_pkg meta_name =
+ let f = open_in meta_name in
+ try
+ let pkg = Fl_metascanner.parse f in
+ close_in f;
+ pkg
+ with
+ | Failure s
+ | Stream.Error s ->
+ close_in f;
+ failwith ("Cannot parse '" ^ meta_name ^ "': " ^ s)
+
+let char_lowercase_ascii c =
+ (* Char.lowercase_ascii and String.lowercase_ascii first available in
+ OCaml-4.03, but we want to support earlier versions too
+ *)
+ if (c >= 'A' && c <= 'Z')
+ then Char.unsafe_chr(Char.code c + 32)
+ else c
+
+let string_lowercase_ascii =
+ String.map char_lowercase_ascii
+
+open Fsmod
+
+let prepare_remove_package ~destdir ~metadir ~ldconf ~pkgname =
+
+ let meta_dot_pkg = "META." ^ pkgname in
+ let has_metadir = metadir <> "" in
+ let pkgdir = Filename.concat destdir pkgname in
+ let dlldir = Filename.concat destdir Findlib_config.libexec_name in
+ let have_libexec = Sys.file_exists dlldir in
+
+ (* First remove the META file. If it is already gone, assume that a
+ parallel running removal removed it already.
+ *)
+
+ let mods = ref [] in
+
+ let push_rm f =
+ if Sys.file_exists f then
+ let digest = Digest.(f |> file |> to_hex) in
+ mods := (f, FM_delete { name = f; checksum = digest }) :: !mods in
+
+ let push_update f bytes =
+ if Sys.file_exists f then
+ let digest = Digest.(f |> file |> to_hex) in
+ mods := (f, FM_update ({ name = f; checksum = digest}, bytes)) :: !mods in
+
+ if has_metadir then push_rm (Filename.concat metadir meta_dot_pkg)
+ else push_rm (Filename.concat pkgdir "META") ;
+
+ (* Remove files from libexec directory: *)
+ if have_libexec then begin
+ let dll_files = find_owned_files pkgname dlldir in
+ List.iter
+ (fun file ->
+ let absfile = Filename.concat dlldir file in
+ push_rm absfile
+ )
+ dll_files
+ end;
+
+ (* Remove the files from the package directory: *)
+ if Sys.file_exists pkgdir then begin
+ let files = Sys.readdir pkgdir in
+ Array.iter (fun f ->
+ if f <> "META" then
+ push_rm (Filename.concat pkgdir f)) files;
+ end
+ else
+ prerr_endline("ocamlfind: [WARNING] No such directory: " ^ pkgdir);
+
+
+ (* Modify ld.conf *)
+ if ldconf <> "ignore" && Sys.file_exists ldconf then
+ begin
+ let lines = read_ldconf ldconf in
+ let d = Fl_split.norm_dir pkgdir in
+ let exists = List.exists (fun p -> Fl_split.norm_dir p = d) lines in
+ if exists then begin
+ let lines' = List.filter (fun p -> Fl_split.norm_dir p <> d) lines in
+ push_update ldconf (format_ldconf lines' [])
+ end
+ end;
+
+ (* Check if there is a postremove script: *)
+ let postremove = Filename.concat destdir "postremove" in
+ if Sys.file_exists postremove then
+ failwith "cannot reinstall-if-diff a package with a postremove script" ;
+
+ List.rev !mods
+;;
+
+let prepare_reinstall_if_diff_package () =
+ let destdir = ref (default_location()) in
+ let metadir = ref (meta_directory()) in
+ let ldconf = ref (ocaml_ldconf()) in
+ let don't_add_directory_directive = ref false in
+ let pkgname = ref "" in
+ let auto_files = ref [] in
+ let dll_files = ref [] in
+ let nodll_files = ref [] in
+ let which = ref Auto in
+ let debug = ref false in
+
+ let keywords =
+ [ "-destdir", (Arg.String (fun s -> destdir := s)),
+ (" Set the destination directory (default: " ^
+ !destdir ^ ")");
+ "-metadir", (Arg.String (fun s -> metadir := s)),
+ (" Install the META file into this directory (default: "^
+ (if !metadir = "" then "none" else !metadir) ^ ")");
+ "-ldconf", (Arg.String (fun s -> ldconf := s)),
+ (" Update this ld.conf file (default: " ^ !ldconf ^ ")");
+ "-dont-add-directory-directive", (Arg.Set don't_add_directory_directive),
+ " never append directory='...' to META";
+ "-dll", Arg.Unit (fun () -> which := Dll),
+ " The following files are DLLs";
+ "-nodll", Arg.Unit (fun () -> which := No_dll),
+ " The following files are not DLLs";
+ "-debug", Arg.Set debug,
+ " Enable massive debug-logging";
+ ] in
+ let errmsg = "usage: ocamlfind reinstall-if-diff [options] ..." in
+
+ let install_args = except "-debug" (List.tl (remaining_args ())) in
+ parse_args
+ keywords
+ (fun s ->
+ if !pkgname = ""
+ then pkgname := s
+ else
+ if Sys.file_exists s then
+ match !which with
+ Auto -> auto_files := s :: !auto_files
+ | Dll -> dll_files := s :: !dll_files
+ | No_dll -> nodll_files := s :: !nodll_files
+ else failwith Fmt.(str "reinstall-if-diff: file (to be installed) %s does not exist" s)
+ )
+ errmsg;
+ if !pkgname = "" then (Arg.usage keywords errmsg; exit 1);
+ if not (Fl_split.is_valid_package_name !pkgname) then
+ failwith "Package names must not contain the character '.'!";
+
+ if !debug then Fmt.(pf stderr "removal_mods: START\n%!");
+ let removal_mods = prepare_remove_package ~destdir:!destdir ~metadir:!metadir ~ldconf:!ldconf ~pkgname:!pkgname in
+ if !debug then Fmt.(pf stderr "removal_mods:\n%a\n%!"
+ pp_t_pair_list removal_mods
+ ) ;
+
+ (* if this file is listed in the removal-mods, then we pretend it doesn't exist;
+ otherwise we pass it along to Sys.file_exists *)
+ let file_exists f =
+ if List.mem_assoc f removal_mods then false
+ else Sys.file_exists f in
+
+ let read_file f =
+ match List.assoc f removal_mods with
+ FM_update (_, contents) -> contents
+ | _ -> failwith "Internal error: can only read_file on a file that we're going to update"
+ | exception Not_found ->
+ failwith "Internal error: can only read_file on a file that we're going to update" in
+
+ let install_mods = ref [] in
+ let push_install ~srcf ~dstf =
+ let digest = Digest.(srcf |> file |> to_hex) in
+ install_mods := (dstf, FM_install { name = srcf; checksum = digest }) :: !install_mods in
+
+ let push_create ~dstf ~contents =
+ let digest = Digest.(contents |> string |> to_hex) in
+ install_mods := (dstf, FM_create ({ name = dstf; checksum = digest }, contents)) :: !install_mods in
+
+ let push_update f b =
+ let digest = Digest.(f |> file |> to_hex) in
+ install_mods := (f, FM_update ({ name = f; checksum = digest}, b)) :: !install_mods in
+
+
+ let pkgdir = Filename.concat !destdir !pkgname in
+ let dlldir = Filename.concat !destdir Findlib_config.libexec_name in
+ let has_metadir = !metadir <> "" in
+ let meta_dot_pkg = "META." ^ !pkgname in
+
+ (* The list of all files to install: *)
+ let full_list = !auto_files @ !dll_files @ !nodll_files in
+ (* Check whether there are DLLs: *)
+ let (l1,l2) = List.partition is_dll !auto_files in
+ let dll_list = l1 @ !dll_files in
+ let nodll_list = l2 @ !nodll_files in
+ let have_libexec = Sys.file_exists dlldir in
+ let pkgdir_list = if have_libexec then nodll_list else full_list in
+ let pkgdir_eff_list =
+ (* The files that will be placed into pkgdir: *)
+ List.map
+ (fun f ->
+ if f = meta_dot_pkg then "META" else f)
+ (List.filter
+ (fun f ->
+ not has_metadir ||
+ (f <> "META" && f <> meta_dot_pkg))
+ pkgdir_list) in
+
+ (* Check whether META exists: (And check syntax) *)
+ let meta_name =
+ try
+ List.find
+ (fun p ->
+ let b = Filename.basename p in
+ b = "META" || b = meta_dot_pkg)
+ nodll_list
+ with
+ | Not_found ->
+ failwith "The META file is missing" in
+
+ (* Check for frequent reasons why installation can go wrong *)
+ if file_exists (Filename.concat !metadir meta_dot_pkg) then
+ failwith ("Package " ^ !pkgname ^ " is already installed\n - (file " ^ Filename.concat !metadir meta_dot_pkg ^ " already exists)");
+
+ if file_exists (Filename.concat pkgdir "META") then
+ failwith ("Package " ^ !pkgname ^ " is already installed\n - (file " ^ pkgdir ^ "/META already exists)");
+
+ List.iter
+ (fun f ->
+ let f' = Filename.concat pkgdir f in
+ if file_exists f' then
+ failwith ("Conflict with file: " ^ f'))
+ pkgdir_eff_list;
+
+ if have_libexec then begin
+ List.iter
+ (fun dll ->
+ let b = Filename.basename dll in
+ if file_exists (Filename.concat dlldir b) then
+ failwith ("Conflict with another package: Library " ^ b ^
+ " is already installed");
+ )
+ dll_list
+ end;
+
+ (* Now copy the files into the package directory (except META): *)
+ List.iter
+ (fun srcf ->
+ try
+ let dstf = Filename.concat pkgdir srcf in
+ if srcf = "META" || srcf = meta_dot_pkg then raise Skip_file ;
+ if srcf = "postremove" then failwith "cannot reinstall-if-diff a package with a postremove script" ;
+ if srcf = "postinstall" then failwith "cannot reinstall-if-diff a package with a postinstall script" ;
+ push_install ~srcf ~dstf
+ with
+ Skip_file -> ()
+ )
+ pkgdir_list;
+
+ (* Copy the DLLs into the libexec directory if necessary *)
+ if have_libexec then begin
+ List.iter
+ (fun srcf ->
+ let dstf = Filename.concat pkgdir srcf in
+ push_install ~srcf ~dstf ;
+ let (owner_file, contents) = format_owner_file !pkgname
+ (Filename.concat dlldir (Filename.basename srcf)) in
+ push_create ~dstf:owner_file ~contents
+ )
+ dll_list
+ end;
+
+ (* Extend ld.conf if necessary: *)
+ if dll_list <> [] && !ldconf <> "ignore" && not have_libexec then begin
+ if Sys.file_exists !ldconf then
+ begin
+ let contents = read_file !ldconf in
+ let lines = parse_ldconf contents in
+ push_update !ldconf (format_ldconf lines [ pkgdir ])
+ end
+ else
+ prerr_endline("ocamlfind: [WARNING] You have installed DLLs but there is no ld.conf")
+ end;
+
+ if dll_list <> [] && have_libexec && !ldconf <> "ignore" then begin
+ (* Check whether libexec is mentioned in ldconf *)
+ (* FIXME: We have to be careful with case-insensitive filesystems.
+ Currently, we only check for Win32, but also OS X may have ci
+ filesystems. So some better check would be nice.
+ *)
+ let lines = read_ldconf !ldconf in
+ let dlldir_norm = Fl_split.norm_dir dlldir in
+ let dlldir_norm_lc = string_lowercase_ascii dlldir_norm in
+ let ci_filesys = (Sys.os_type = "Win32") in
+ let check_dir d =
+ let d' = Fl_split.norm_dir d in
+ (d' = dlldir_norm) ||
+ (ci_filesys && string_lowercase_ascii d' = dlldir_norm_lc) in
+ if not (List.exists check_dir lines) then
+ prerr_endline("ocamlfind: [WARNING] You have installed DLLs but the directory " ^ dlldir_norm ^ " is not mentioned in ld.conf");
+ end;
+
+ (* Finally, write the META file: *)
+ let write_meta append_directory dir name =
+ let contents = file_contents meta_name in
+ let contents = if append_directory then
+ contents ^ "\ndirectory=\"" ^ pkgdir ^ "\" # auto-added by ocamlfind\n"
+ else contents in
+ push_create ~dstf:(Filename.concat dir name) ~contents
+ in
+ if has_metadir then
+ write_meta true !metadir meta_dot_pkg
+ else
+ write_meta false pkgdir "META";
+
+ let remove_args = ["-destdir"; !destdir; !pkgname] in
+ (!debug, List.rev !install_mods, install_args, removal_mods, remove_args)
+;;
+
+let same_action (ifname, iact) (rfname, ract) =
+ if ifname <> rfname then (
+ Fmt.(pf stderr "Files %s, %s at same position in sorted list of actions\n%!"
+ ifname rfname) ;
+ false
+ )
+ else
+ match iact, ract with
+ FM_install {name=s2; checksum=sum2}, FM_delete { name=s1; checksum=sum1}
+ when sum1=sum2 -> true
+ | FM_create ({name=s2; checksum=sum2}, _), FM_delete { name=s1; checksum=sum1}
+ when s1=s2 && sum1=sum2 -> true
+ | _ ->
+ Fmt.(pf stderr "File %s has incompatible {install, remove} actions: (%a,%, %a)\n%!"
+ ifname pp iact pp ract) ;
+ false
+;;
+
+let is_same (install_mods, removal_mods) =
+ let imap = List.sort Stdlib.compare install_mods in
+ let rmap = List.sort Stdlib.compare removal_mods in
+ let rec rerec = function
+ ((ifname, iact)::it, (rfname, ract)::rt) ->
+ if not (same_action (ifname, iact) (rfname, ract)) then false
+ else rerec (it, rt)
+ | ([], []) -> true
+ | _ ->
+ Fmt.(pf stderr "reinstall-if-diff: remove and install lists have differing lengths\n%!") ;
+ false
+ in
+ rerec (imap, rmap)
+;;
+
+let reinstall_if_diff () =
+ let (debug, install_mods, install_args, removal_mods, remove_args) = prepare_reinstall_if_diff_package() in
+ if debug then Fmt.(pf stderr "reinstall_if_diff\ninstall_mods:\n%a\ninstall_args: [%a]\nremoval_mods:\n%a\nremove_args: [%a]\n%!"
+ pp_t_pair_list install_mods
+ (list ~sep:(const string " ") string) install_args
+ pp_t_pair_list removal_mods
+ (list ~sep:(const string " ") string) remove_args
+ ) ;
+ if not (is_same (install_mods, removal_mods)) then begin
+ run_command Verbose "ocamlfind" ("remove" :: remove_args) ;
+ run_command Verbose "ocamlfind" ("install" :: install_args)
+ end
+;;
+
+let passthru () =
+ run_command Normal "ocamlfind" (List.tl (Array.to_list !argv))
+;;
+
+
+let rec select_mode () =
+ let k = !current in
+ let m_string = try arg (k+1) with Not_found -> raise Usage in
+ let m =
+ match m_string with
+ ("reinstall-if-diff") -> incr current; M_reinstall_if_diff
+ | ("preprocess") -> incr current; M_preprocess
+ | ("package-graph") -> incr current; M_package_graph
+ | _ -> M_passthru
+ in
+
+ m
+;;
+
+
+let _main av curr () =
+ argv := av ; current := curr ;
+ try
+ let m = select_mode() in
+ match m with
+ M_reinstall_if_diff -> reinstall_if_diff()
+ | M_preprocess -> preprocess ()
+ | M_package_graph -> package_graph ()
+ | M_passthru -> passthru()
+ with
+ Failure f ->
+ prerr_endline ("ocamlfind: " ^ f);
+ exit 2
+ | Sys_error f ->
+ prerr_endline ("ocamlfind: " ^ f);
+ exit 2
+ | Findlib.No_such_package(pkg,info) ->
+ prerr_endline ("ocamlfind: Package `" ^ pkg ^ "' not found" ^
+ (if info <> "" then " - " ^ info else ""));
+ exit 2
+ | Findlib.Package_loop pkg ->
+ prerr_endline ("ocamlfind: Package `" ^ pkg ^ "' requires itself");
+ exit 2
+ | Silent_error ->
+ exit 2
+;;
+
+let main ?(argv = Sys.argv) ?(current = !Arg.current) () =
+ _main argv current () ;;
diff --git a/fsmod.ORIG.ml b/fsmod.ORIG.ml
new file mode 100644
index 0000000..d2bf7ed
--- /dev/null
+++ b/fsmod.ORIG.ml
@@ -0,0 +1,16 @@
+
+module Pa_ppx_runtime = struct
+ module Runtime = struct
+ module Fmt = Fmt
+ end
+end
+
+type file_t = { name : string ; checksum : string }[@@deriving show]
+type t =
+ FM_delete of file_t
+ | FM_install of file_t
+ | FM_update of file_t * string
+ | FM_create of file_t * string[@@deriving show]
+
+type t_pair = string * t[@@deriving show]
+type t_pair_list = t_pair list[@@deriving show]
diff --git a/fsmod.ml b/fsmod.ml
new file mode 100644
index 0000000..14b1343
--- /dev/null
+++ b/fsmod.ml
@@ -0,0 +1,81 @@
+
+module Pa_ppx_runtime =
+ struct
+ module Runtime = struct module Fmt = Fmt end
+ end
+
+type file_t = { name : string; checksum : string }[@@deriving_inline show]
+
+let rec (pp_file_t : file_t Fmt.t) =
+ fun (ofmt : Format.formatter) arg ->
+ (fun ofmt ({name = v_name; checksum = v_checksum} : file_t) ->
+ let open Pa_ppx_runtime.Runtime.Fmt in
+ pf ofmt "@[<2>{ @[Fsmod.name =@ %a@];@ @[checksum =@ %a@] }@]"
+ (fun ofmt arg ->
+ let open Pa_ppx_runtime.Runtime.Fmt in pf ofmt "%S" arg)
+ v_name
+ (fun ofmt arg ->
+ let open Pa_ppx_runtime.Runtime.Fmt in pf ofmt "%S" arg)
+ v_checksum)
+ ofmt arg[@@ocaml.warning "-39"] [@@ocaml.warning "-33"]
+and (show_file_t : file_t -> Stdlib.String.t) =
+ fun arg -> Format.asprintf "%a" pp_file_t arg[@@ocaml.warning "-39"] [@@ocaml.warning "-33"]
+
+[@@@end]
+type t =
+ FM_delete of file_t
+ | FM_install of file_t
+ | FM_update of file_t * string
+ | FM_create of file_t * string[@@deriving_inline show]
+let rec (pp : t Fmt.t) =
+ fun (ofmt : Format.formatter) arg ->
+ (fun ofmt ->
+ function
+ FM_delete v0 ->
+ let open Pa_ppx_runtime.Runtime.Fmt in
+ pf ofmt "(@[<2>Fsmod.FM_delete@ %a)@]" pp_file_t v0
+ | FM_install v0 ->
+ let open Pa_ppx_runtime.Runtime.Fmt in
+ pf ofmt "(@[<2>Fsmod.FM_install@ %a)@]" pp_file_t v0
+ | FM_update (v0, v1) ->
+ let open Pa_ppx_runtime.Runtime.Fmt in
+ pf ofmt "(@[<2>Fsmod.FM_update@ (@,%a,@ %a@,))@]" pp_file_t v0
+ (fun ofmt arg ->
+ let open Pa_ppx_runtime.Runtime.Fmt in pf ofmt "%S" arg)
+ v1
+ | FM_create (v0, v1) ->
+ let open Pa_ppx_runtime.Runtime.Fmt in
+ pf ofmt "(@[<2>Fsmod.FM_create@ (@,%a,@ %a@,))@]" pp_file_t v0
+ (fun ofmt arg ->
+ let open Pa_ppx_runtime.Runtime.Fmt in pf ofmt "%S" arg)
+ v1)
+ ofmt arg[@@ocaml.warning "-39"] [@@ocaml.warning "-33"]
+and (show : t -> Stdlib.String.t) =
+ fun arg -> Format.asprintf "%a" pp arg[@@ocaml.warning "-39"] [@@ocaml.warning "-33"]
+[@@@end]
+
+type t_pair = string * t[@@deriving_inline show]
+
+let rec (pp_t_pair : t_pair Fmt.t) =
+ fun (ofmt : Format.formatter) arg ->
+ (fun (ofmt : Format.formatter) (v0, v1) ->
+ let open Pa_ppx_runtime.Runtime.Fmt in
+ pf ofmt "(@[%a,@ %a@])"
+ (fun ofmt arg ->
+ let open Pa_ppx_runtime.Runtime.Fmt in pf ofmt "%S" arg)
+ v0 pp v1)
+ ofmt arg[@@ocaml.warning "-39"] [@@ocaml.warning "-33"]
+and (show_t_pair : t_pair -> Stdlib.String.t) =
+ fun arg -> Format.asprintf "%a" pp_t_pair arg[@@ocaml.warning "-39"] [@@ocaml.warning "-33"]
+
+[@@@end]
+type t_pair_list = t_pair list[@@deriving_inline show]
+let rec (pp_t_pair_list : t_pair_list Fmt.t) =
+ fun (ofmt : Format.formatter) arg ->
+ (fun (ofmt : Format.formatter) arg ->
+ let open Pa_ppx_runtime.Runtime.Fmt in
+ pf ofmt "@[<2>[%a@,]@]" (list ~sep:semi pp_t_pair) arg)
+ ofmt arg[@@ocaml.warning "-39"] [@@ocaml.warning "-33"]
+and (show_t_pair_list : t_pair_list -> Stdlib.String.t) =
+ fun arg -> Format.asprintf "%a" pp_t_pair_list arg[@@ocaml.warning "-39"] [@@ocaml.warning "-33"]
+[@@@end]
diff --git a/local-packages/ocamlfind/0001-Fix-bug-when-installing-with-a-system-compiler.patch b/local-packages/ocamlfind/0001-Fix-bug-when-installing-with-a-system-compiler.patch
new file mode 100644
index 0000000..c050899
--- /dev/null
+++ b/local-packages/ocamlfind/0001-Fix-bug-when-installing-with-a-system-compiler.patch
@@ -0,0 +1,26 @@
+From f53247f546375972789b96c3f612cd7f524bf2aa Mon Sep 17 00:00:00 2001
+From: Louis Gesbert
+Date: Mon, 11 Jul 2022 18:12:18 +0200
+Subject: [PATCH] Fix bug when installing with a system compiler
+
+See https://discuss.ocaml.org/t/problem-installing-ocamlfind-on-latest-ocamlpro-alpine-docker-image/10147
+---
+ src/findlib/Makefile | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/src/findlib/Makefile b/src/findlib/Makefile
+index 84514b6f22..ea23f4a10c 100644
+--- a/src/findlib/Makefile
++++ b/src/findlib/Makefile
+@@ -123,7 +123,7 @@ clean:
+ install: all
+ $(INSTALLDIR) "$(DESTDIR)$(prefix)$(OCAML_SITELIB)/$(NAME)"
+ $(INSTALLDIR) "$(DESTDIR)$(prefix)$(OCAMLFIND_BIN)"
+- $(INSTALLDIR) "$(DESTDIR)$(prefix)$(OCAML_CORE_STDLIB)"
++ test $(INSTALL_TOPFIND) -eq 0 || $(INSTALLDIR) "$(DESTDIR)$(prefix)$(OCAML_CORE_STDLIB)"
+ test $(INSTALL_TOPFIND) -eq 0 || $(INSTALLFILE) topfind "$(DESTDIR)$(prefix)$(OCAML_CORE_STDLIB)/"
+ files=`$(SH) $(TOP)/tools/collect_files $(TOP)/Makefile.config \
+ findlib.cmi findlib.mli findlib.cma findlib.cmxa findlib$(LIB_SUFFIX) findlib.cmxs \
+--
+2.35.1
+
diff --git a/local-packages/ocamlfind/INSTALL b/local-packages/ocamlfind/INSTALL
new file mode 100644
index 0000000..c3a83cc
--- /dev/null
+++ b/local-packages/ocamlfind/INSTALL
@@ -0,0 +1,187 @@
+The installation procedure consists of the steps:
+
+1) configure the "findlib" library
+2) compile "findlib" and the "ocamlfind" frontend of "findlib"
+3) install "findlib" and the core library configuration
+
+Optionally, you can run ./itest after step 2 to check the
+configuration. Problems with the configuration are unlikely, however.
+
+At the end of this file you find notes about MacOS and Windows.
+
+
+----------------------------------------------------------------------
+
+STEP 1: DEFAULT CONFIGURATION
+
+The findlib module and its ocamlfind frontend come with a "configure"
+script that should almost always be able to figure out a good
+configuration.
+
+Just type:
+
+ ./configure
+
+First the linker options for the various core libraries are figured
+out, then reasonable installation paths are checked.
+
+If the results are not ok, you can modify them using the following
+options:
+
+ -bindir
+
+ set the location where the ocamlfind command should be
+ installed.
+ Default: same location as "ocamlc"
+
+ -mandir
+
+ set the location where the man page should be installed.
+ Default: a heuristics, and "/usr/local/man" as fallback.
+
+ -sitelib
+
+ set the default "site-lib" directory.
+ Default: For installations in the /usr hierarchy,
+ "$stdlib/site-lib", where $stdlib is the location of
+ Ocaml's standard library.
+
+ For installations in the /opt hierarchy,
+ "$stdlib/../site-lib", i.e. parallel to $stdlib.
+
+ -config
+
+ set the location of the configuration file.
+ Default: /../etc/findlib.conf
+
+ -no-topfind
+
+ the "topfind" script is not installed in the standard
+ library directory. (This is not a good idea in general,
+ because #use "topfind" will not work when this option
+ is enabled.)
+
+ -with-toolbox
+ also compile and install the "toolbox". This requires
+ that labltk is available. The toolbox contains the
+ "make_wizard" to easily create findlib-enabled Makefiles.
+
+ -cygpath
+ Cygwin environment only: If "ocamlc -where" does not
+ output a Unix-style path, this option can be used
+ to apply the "cygpath" command to it. Use this option
+ if you see backslashes or drive letters in Makefile.config.
+
+ALTERNATIVES:
+
+If the "configure" script does not work properly (very unlikely), do
+
+ cp Makefile.config.pattern Makefile.config
+
+and edit Makefile.config by hand.
+
+If the generated META files do not work, edit them (this is very very unlikely).
+
+Note: The META files are generated from the META.in files in the same
+directories by sed:
+
+ sed -e 's/%%os%%//g' site-lib//META.in
+ >site-lib//META
+
+You may invoke sed manually to create different META files, but this
+is currently not documented.
+
+
+
+----------------------------------------------------------------------
+
+STEP 2: COMPILATION
+
+After configuration has been done, compile with
+
+ make all
+
+This creates findlib.cma, findlib_mt.cma (the thread-safe version),
+and ocamlfind.
+
+If you have ocamlopt, do also
+
+ make opt
+
+This creates findlib.cmxa, findlib_mt.cmxa, and ocamlfind_opt.
+
+----------------------------------------------------------------------
+
+STEP 3: INSTALLATION
+
+Install the findlib library, the ocamlfind frontend, and the core library
+configurations with:
+
+ make install
+
+(A "make uninstall" removes them.)
+
+With
+ make clean
+
+the build directory is cleaned up.
+
+
+OPTIONAL (BUT RECOMMENDED):
+
+If you want a separate directory for DLLs, create this directory
+now:
+
+mkdir `ocamlfind printconf destdir`/stublibs
+
+If you do this, you must also tell OCaml that DLLs can be found in
+this directory: Add the absolute path of this directory to
+the ld.conf file (type "ocamlfind printconf ldconf" to get the
+location of the ld.conf file). Every line of this text file lists
+one possible directory for DLLs.
+
+----------------------------------------------------------------------
+
+MACOS X:
+
+Findlib can be installed as described. There is even a script to
+create a MacOS X package, use "make package-macosx" to invoke it. As I
+do not have access to a Mac box, I cannot test this script, but I
+fully trust the author that it works.
+
+----------------------------------------------------------------------
+
+WINDOWS:
+
+Ocaml for Windows exists in three flavours:
+
+(1) Ocaml as Cygwin program
+(2) Ocaml as Mingw program (i.e. the gcc toolchain is used but
+ Ocaml is a native Windows program)
+(3) Ocaml as VC program
+
+In all three cases you need Cygwin to build and install findlib,
+because "configure" and the Makefile are both Cygwin scripts. The
+golden rule to make everything work is this:
+
+PASS CYGWIN-STYLE PATHS TO CONFIGURE!
+
+Even in cases (2) and (3)! That means use something like
+/cygdrive/c/path and not c:\path when you specify where -bindir,
+-config etc. are. The point is that "configure" itself is a Cygwin
+script, and therefore expects Cygwin input. At the right moment, the
+paths are back-translated to their Windows counterparts.
+
+Until OCaml 3.08 you must specify whether you have (2) or (3) by
+the configure switches
+
+- "-system mingw" for (2)
+- "-system win32" for (3)
+- nothing for (1)
+
+Since OCaml 3.09 this is no longer necessary because "ocamlc -config"
+outputs the required information.
+
+In previous versions of Findlib there was a single switch -cygpath
+for both (2) and (3). It is now interpreted as -system mingw (as
+it was meant as that).
diff --git a/local-packages/ocamlfind/LICENSE b/local-packages/ocamlfind/LICENSE
new file mode 100644
index 0000000..5d2bcbe
--- /dev/null
+++ b/local-packages/ocamlfind/LICENSE
@@ -0,0 +1,22 @@
+Copyright 1999 by Gerd Stolpmann
+
+The package "findlib" is copyright by Gerd Stolpmann.
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this document and the "findlib" software (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+The Software is provided ``as is'', without warranty of any kind, express
+or implied, including but not limited to the warranties of
+merchantability, fitness for a particular purpose and noninfringement.
+In no event shall Gerd Stolpmann be liable for any claim, damages or
+other liability, whether in an action of contract, tort or otherwise,
+arising from, out of or in connection with the Software or the use or
+other dealings in the software.
diff --git a/local-packages/ocamlfind/Makefile b/local-packages/ocamlfind/Makefile
new file mode 100644
index 0000000..f2f1df6
--- /dev/null
+++ b/local-packages/ocamlfind/Makefile
@@ -0,0 +1,152 @@
+# make all: compile to bytecode
+# make opt: compile to native code
+# make install: install bytecode and/or native code
+#----------------------------------------------------------------------
+
+include Makefile.config
+-include Makefile.packages
+
+TOP=.
+
+.PHONY: all opt install uninstall clean
+
+all:
+ for p in $(PARTS); do ( cd src/$$p; $(MAKE) all ) || exit; done
+ $(MAKE) all-config
+
+opt:
+ for p in $(PARTS); do ( cd src/$$p; $(MAKE) opt ) || exit; done
+
+install: check-installation
+ $(INSTALLDIR) "$(DESTDIR)$(prefix)$(OCAMLFIND_BIN)"
+ $(INSTALLDIR) "$(DESTDIR)$(prefix)$(OCAMLFIND_MAN)"
+ $(MAKE) install-config
+ for p in $(PARTS); do ( cd src/$$p; $(MAKE) install ); done
+ $(MAKE) install-meta
+ test ! -f 'site-lib-src/num-top/META' || { cd src/findlib; $(MAKE) install-num-top; }
+ test ! -f 'site-lib-src/camlp4/META' || $(INSTALLFILE) tools/safe_camlp4 "$(DESTDIR)$(prefix)$(OCAMLFIND_BIN)"
+ $(MAKE) install-doc
+
+uninstall: check-installation
+ $(MAKE) uninstall-doc
+ $(MAKE) uninstall-meta
+ for p in `cd src; echo *`; do ( cd src/$$p; $(MAKE) uninstall ); done
+ $(MAKE) uninstall-config
+
+clean:
+ for p in `cd src; echo *`; do ( cd src/$$p; $(MAKE) clean ); done
+ (cd itest-aux; $(MAKE) clean)
+ (cd tools/extract_args; $(MAKE) clean)
+ rm -f findlib.conf Makefile.packages
+
+.PHONY: release
+release: README
+ ./release
+
+README: doc/README
+ ln -s doc/README .
+
+
+.PHONY: all-config
+all-config: findlib.conf
+
+findlib.conf: findlib.conf.in
+ USE_CYGPATH="$(USE_CYGPATH)"; \
+ export USE_CYGPATH; \
+ cat findlib.conf.in | \
+ $(SH) tools/patch '@SITELIB@' '$(OCAML_SITELIB)' >findlib.conf
+ if ./tools/cmd_from_same_dir ocamlc; then \
+ echo 'ocamlc="ocamlc.opt"' >>findlib.conf; \
+ fi
+ if ./tools/cmd_from_same_dir ocamlopt; then \
+ echo 'ocamlopt="ocamlopt.opt"' >>findlib.conf; \
+ fi
+ if ./tools/cmd_from_same_dir ocamldep; then \
+ echo 'ocamldep="ocamldep.opt"' >>findlib.conf; \
+ fi
+ if ./tools/cmd_from_same_dir ocamldoc; then \
+ echo 'ocamldoc="ocamldoc.opt"' >>findlib.conf; \
+ fi
+
+.PHONY: install-doc
+install-doc:
+ $(INSTALLDIR) "$(DESTDIR)$(prefix)$(OCAMLFIND_MAN)/man1" "$(DESTDIR)$(prefix)$(OCAMLFIND_MAN)/man3" "$(DESTDIR)$(prefix)$(OCAMLFIND_MAN)/man5"
+ -$(INSTALLFILE) doc/ref-man/ocamlfind.1 "$(DESTDIR)$(prefix)$(OCAMLFIND_MAN)/man1"
+ -$(INSTALLFILE) doc/ref-man/META.5 doc/ref-man/site-lib.5 doc/ref-man/findlib.conf.5 "$(DESTDIR)$(prefix)$(OCAMLFIND_MAN)/man5"
+
+.PHONY: uninstall-doc
+uninstall-doc:
+ rm -f "$(DESTDIR)$(prefix)$(OCAMLFIND_MAN)/man1/ocamlfind.1"
+ rm -f "$(DESTDIR)$(prefix)$(OCAMLFIND_MAN)/man3/Findlib.3"
+ rm -f "$(DESTDIR)$(prefix)$(OCAMLFIND_MAN)/man3/Topfind.3"
+ rm -f "$(DESTDIR)$(prefix)$(OCAMLFIND_MAN)/man5/META.5"
+ rm -f "$(DESTDIR)$(prefix)$(OCAMLFIND_MAN)/man5/site-lib.5"
+
+
+.PHONY: check-installation
+check-installation:
+ if [ "$(CHECK_BEFORE_INSTALL)" -eq 1 ]; then \
+ for x in camlp4 dbm graphics labltk num ocamlbuild; do \
+ if [ -f "$(prefix)$(OCAML_SITELIB)/$$x/META" ]; then \
+ if ! grep -Fq '[distributed with Ocaml]' "$(prefix)/$(OCAML_SITELIB)/$$x/META"; then \
+ rm -f site-lib-src/$$x/META; \
+ fi; \
+ fi; \
+ done; \
+ test -f "site-lib-src/num/META" || rm -f "site-lib-src/num-top/META"; \
+ fi
+ echo 'SITELIB_META =' > Makefile.packages.in
+ for x in `ls site-lib-src`; do test ! -f "site-lib-src/$$x/META" || echo $$x >> Makefile.packages.in; done
+ tr '\n' ' ' < Makefile.packages.in > Makefile.packages
+ rm Makefile.packages.in
+
+.PHONY: install-meta
+install-meta:
+ for x in $(SITELIB_META); do $(INSTALLDIR) "$(DESTDIR)$(prefix)$(OCAML_SITELIB)/$$x"; $(INSTALLFILE) site-lib-src/$$x/META "$(DESTDIR)$(prefix)$(OCAML_SITELIB)/$$x/META.tmp" && mv "$(DESTDIR)$(prefix)$(OCAML_SITELIB)/$$x/META.tmp" "$(DESTDIR)$(prefix)$(OCAML_SITELIB)/$$x/META"; done
+ $(INSTALLDIR) "$(DESTDIR)$(prefix)$(OCAML_SITELIB)/findlib"; $(INSTALLFILE) Makefile.packages "$(DESTDIR)$(prefix)$(OCAML_SITELIB)/findlib/Makefile.packages"
+
+.PHONY: uninstall-meta
+uninstall-meta:
+ for x in $(SITELIB_META); do rm -rf "$(DESTDIR)$(prefix)$(OCAML_SITELIB)/$$x"; done
+
+.PHONY: install-config
+install-config:
+ $(INSTALLDIR) "`dirname \"$(DESTDIR)$(prefix)$(OCAMLFIND_CONF)\"`"
+ @if [ -f "$(DESTDIR)$(prefix)$(OCAMLFIND_CONF)" ]; then echo "!!! Keeping old $(DESTDIR)$(prefix)$(OCAMLFIND_CONF) !!!"; fi
+ test -f "$(DESTDIR)$(prefix)$(OCAMLFIND_CONF)" || $(INSTALLFILE) findlib.conf "$(DESTDIR)$(prefix)$(OCAMLFIND_CONF)"
+
+.PHONY: uninstall-config
+uninstall-config:
+ @echo Leaving "$(OCAMLFIND_CONF)" installed, consider manual removal
+
+.PHONY: interface-lists
+interface-lists:
+ d=`ocamlc -where`; \
+ for x in `ls site-lib-src`; do \
+ iflist=""; \
+ if [ ! -f "site-lib-src/$$x/interfaces.in" ]; then continue; fi; \
+ cma_spec=`cat site-lib-src/$$x/interfaces.in`; \
+ for cma in $$d/$$cma_spec; do \
+ intf=`ocamlobjinfo $$cma | \
+ grep 'Unit name:' | \
+ sed -e 's/^ Unit name: //' | \
+ sort | \
+ tr '\n' ' '`; \
+ iflist="$$iflist $$intf"; \
+ done; \
+ echo "$$iflist" >"site-lib-src/$$x/interfaces.out"; \
+ done
+
+######################################################################
+# The following is from Pietro Abata
+# to create MacOS X packages. I did not test it, just include it.
+
+.PHONY: package-macosx
+
+package-macosx: all opt
+ $(INSTALLDIR) package-macosx/root
+ export prefix=`pwd`/package-macosx/root && make install
+ export VERSION=1.1.2 && sh tools/make-package-macosx
+
+clean-macosx:
+ sudo rm -rf package-macosx
diff --git a/local-packages/ocamlfind/Makefile.config b/local-packages/ocamlfind/Makefile.config
new file mode 100644
index 0000000..ed6da21
--- /dev/null
+++ b/local-packages/ocamlfind/Makefile.config
@@ -0,0 +1,31 @@
+# Makefile.config written by configure
+OCAML_CORE_STDLIB=/home/chet/Hack/Opam-2.1.2/GENERIC/5.0.0~rc1/lib/ocaml
+OCAML_CORE_BIN=/home/chet/Hack/Opam-2.1.2/GENERIC/5.0.0~rc1/bin
+OCAML_CORE_MAN=/home/chet/Hack/Opam-2.1.2/GENERIC/5.0.0~rc1/man
+OCAML_SITELIB=/home/chet/Hack/Opam-2.1.2/GENERIC/5.0.0~rc1/lib/ocaml/site-lib
+OCAML_THREADS=posix
+OCAMLFIND_BIN=/home/chet/Hack/Opam-2.1.2/GENERIC/5.0.0~rc1/bin
+OCAMLFIND_MAN=/home/chet/Hack/Opam-2.1.2/GENERIC/5.0.0~rc1/man
+OCAMLFIND_CONF=/home/chet/Hack/Opam-2.1.2/GENERIC/5.0.0~rc1/lib/findlib.conf
+OCAMLFIND_OCAMLFLAGS=-I +unix -I +dynlink
+OCAMLFIND_ARCHIVES=findlib.cma unix.cma
+OCAML_AUTOLINK=true
+OCAML_REMOVE_DIRECTORY=1
+EXEC_SUFFIX=
+LIB_SUFFIX=.a
+CUSTOM=-custom
+PARTS=findlib
+INSTALL_TOPFIND=1
+USE_CYGPATH=0
+HAVE_NATDYNLINK=1
+VERSION=1.9.5
+ENABLE_TOPFIND_PPXOPT=true
+SYSTEM=linux
+NUMTOP=
+SH=
+OPAQUE=-opaque
+CHECK_BEFORE_INSTALL=0
+INSTALLDIR = install -d
+# change to INSTALLDIR = mkdir -p when BSD install is unavavailable
+INSTALLFILE = install -c
+# change to INSTALLFILE = cp when BSD install is unavailable
diff --git a/local-packages/ocamlfind/Makefile.config.pattern b/local-packages/ocamlfind/Makefile.config.pattern
new file mode 100644
index 0000000..bf894e9
--- /dev/null
+++ b/local-packages/ocamlfind/Makefile.config.pattern
@@ -0,0 +1,67 @@
+# You can manually set up your configuration using this
+# pattern. The final name of the file must be "Makefile.config".
+# Note that there are other files containing parts of the
+# configuration, especially the site-lib/*/META files.
+#
+#----------------------------------------------------------------------
+# Where the OCAML core is installed:
+#----------------------------------------------------------------------
+OCAML_CORE_STDLIB=/usr/local/lib/ocaml
+OCAML_CORE_BIN=/usr/local/bin
+OCAML_CORE_MAN=/usr/local/man
+
+#----------------------------------------------------------------------
+# Type of multi-threading support: either vm or posix
+# (Note: Since OCaml 3.07, "posix" includes "vm", because a build
+# supporting posix also supports vm.)
+#----------------------------------------------------------------------
+OCAML_THREADS=vm
+#OCAML_THREADS=posix
+
+#----------------------------------------------------------------------
+# Where the site-lib directory will be
+#----------------------------------------------------------------------
+OCAML_SITELIB=/usr/local/lib/ocaml/site-lib
+
+#----------------------------------------------------------------------
+# Where binaries and manual pages will be installed
+#----------------------------------------------------------------------
+OCAMLFIND_BIN=/usr/local/bin
+OCAMLFIND_MAN=/usr/local/man
+
+#----------------------------------------------------------------------
+# The absolute location of the configuration file
+#----------------------------------------------------------------------
+OCAMLFIND_CONF=/usr/local/etc/ocamlfind.conf
+
+#----------------------------------------------------------------------
+# Autolinking is usually on
+#----------------------------------------------------------------------
+OCAML_AUTOLINK=true
+
+#----------------------------------------------------------------------
+# Windows only: set this to .exe
+#----------------------------------------------------------------------
+EXEC_SUFFIX=
+
+#----------------------------------------------------------------------
+# Windows MSVC port: set this to .lib
+#----------------------------------------------------------------------
+LIB_SUFFIX=.a
+
+#----------------------------------------------------------------------
+# Which parts are to be built: findlib, findlib-toolbox (space-separated
+# list)
+#----------------------------------------------------------------------
+PARTS=findlib findlib-toolbox
+
+#----------------------------------------------------------------------
+# Whether the "topfind" script is installed in $(OCAML_CORE_STDLIB):
+#----------------------------------------------------------------------
+INSTALL_TOPFIND=1
+
+#----------------------------------------------------------------------
+# Whether make install should update Makefile.packages just before
+# running
+#----------------------------------------------------------------------
+CHECK_BEFORE_INSTALL=0
diff --git a/local-packages/ocamlfind/configure b/local-packages/ocamlfind/configure
new file mode 100755
index 0000000..71ec745
--- /dev/null
+++ b/local-packages/ocamlfind/configure
@@ -0,0 +1,788 @@
+#! /bin/sh
+# $Id$
+# ----------------------------------------------------------------------
+#
+
+# Some functions
+
+#set -x
+
+version="$(sed -ne 's/^version: *"\(.*\)\.git".*/\1/p' opam)"
+
+if test -z "$version"; then
+ echo "Internal error: failed to parse version number from opam file" 1>&2
+ exit 1
+fi
+
+# Remember the old IFS value:
+oldifs="$IFS"
+
+
+in_path () {
+ # Does $1 exist in $PATH?
+ IFS=":"
+ for d in $PATH; do
+ if test -x "$d/$1"; then
+ IFS="$oldifs"
+ return 0
+ fi
+ done
+ IFS="$oldifs"
+ return 1
+#--- The following is not portable enough:
+# if test -x `type -p ls`; then
+# # type -p works!
+# type -p $1 >/dev/null
+# else
+# # use 'which' instead
+# p=`which $1`
+# test -x "$p"
+# fi
+}
+
+
+get_path () {
+ IFS=":"
+ for d in $PATH; do
+ if test -x "$d/$1"; then
+ IFS="$oldifs"
+ echo "$d/$1"
+ return
+ fi
+ done
+ IFS="$oldifs"
+#--- The following is not portable enough:
+# if test -x `type -p ls`; then
+# # type -p works!
+# type -p $1
+# else
+# # use 'which' instead
+# p=`which $1`
+# test -x "$p" && echo $p
+# fi
+}
+
+
+get_stdlib () {
+ # Older versions of ocamlc do not accept -where, so there is a fallback
+ # method:
+ ocamlc -where 2>/dev/null | tr -d '\015' || {
+ ocamlc -v | sed -n -e "/Standard library directory/s/.*: \(.*\)/\1/p"; }
+}
+
+
+get_lib () {
+ # $1: name of a library to search for
+ # $2...: places to test
+ libname="$1"
+ while [ "$#" != "0" ]; do
+ if [ -f "$1/lib${libname}.so" ] || [ -f "$1/lib${libname}.a" ]; then
+ echo "$1"
+ return 0
+ fi
+ shift
+ done
+ return 1
+}
+
+
+get_lib_file () {
+ # $1: name of library without "lib" and suffix
+ # $2: directory
+ # returns full path of library
+ if [ -f "$2/lib$1.so" ]; then
+ echo "$2/lib$1.so"
+ elif [ -f "$2/lib$1.a" ]; then
+ echo "$2/lib$1.a"
+ else
+ echo ""
+ fi
+}
+
+
+cygpath_to_unix () {
+ v=$1
+ eval "p=\"\$$v\""
+ p="`cygpath -w -s \"$p\"`"
+ p="`cygpath -u \"$p\"`"
+ eval "$v=\"$p\""
+}
+
+
+######################################################################
+# Here the main program begins:
+
+######################################################################
+# Interpret the command line
+
+ocamlfind_bin=""
+ocamlfind_man=""
+ocaml_sitelib=""
+ocamlfind_config=""
+with_toolbox=0
+with_topfind=1
+with_camlp4=1
+custom=-custom
+system=""
+sh=""
+
+while [ "$#" != "0" ]; do
+ case "$1" in
+ -bindir) ocamlfind_bin=$2
+ shift 2
+ ;;
+ -mandir) ocamlfind_man=$2
+ shift 2
+ ;;
+ -sitelib) ocaml_sitelib=$2
+ shift 2
+ ;;
+ -config) ocamlfind_config=$2
+ shift 2
+ ;;
+ -no-custom) custom=
+ shift
+ ;;
+ -cygpath) system=mingw
+ shift
+ ;;
+ -system) system=$2
+ shift 2
+ ;;
+ -with-toolbox) with_toolbox=1
+ shift
+ ;;
+ -no-topfind) with_topfind=0
+ shift
+ ;;
+ -no-camlp4) with_camlp4=0
+ shift
+ ;;
+ -version)
+ echo "$version"
+ exit 0
+ ;;
+ -h|-help|--help) echo "usage: configure [options]" 1>&2
+ echo " -bindir path where binaries are installed" 1>&2
+ echo " -mandir path where manual pages are installed" 1>&2
+ echo " -sitelib path set the location of the site-specific packages" 1>&2
+ echo " -config path set the location of the configuration file" 1>&2
+ echo " -no-custom don't link in custom runtime mode" 1>&2
+ echo " -system override system type (esp. mingw and win32)" 1>&2
+ echo " -with-toolbox also build the toolbox" 1>&2
+ echo " -no-topfind don't install topfind script into stdlib directory" 1>&2
+ echo " -no-camlp4 don't install the camlp4 META file" 1>&2
+ exit
+ ;;
+ *) echo "configure: run 'configure -h' to get help" 1>&2
+ exit 1
+ ;;
+ esac
+done
+
+echo "Welcome to findlib version $version"
+echo "Configuring core..."
+
+
+#######################################################################
+# inspect the system
+
+# Some standard Unix tools must be available:
+
+for tool in sed ocaml ocamlc uname rm make cat dirname basename; do
+ if in_path $tool; then true; else
+ echo "configure: $tool not in PATH; this is required" 1>&2
+ exit 1
+ fi
+done
+
+lib_suffix=`ocamlc -config 2>/dev/null|tr -d '\015'|sed -n -e 's/^ext_lib: //p'`
+
+# Check for Cygwin:
+
+exec_suffix=
+pure_mingw="no"
+mingw_lib=
+case `uname` in
+ CYGWIN*)
+ exec_suffix=.exe
+ echo "Cygwin build environment found; using .exe as suffix for binaries"
+ ;;
+ MSYS_NT*)
+ exec_suffix=.exe
+ echo "MSYS_NT build environment found; using .exe as suffix for binaries"
+ ;;
+ MINGW*)
+ exec_suffix=.exe
+ pure_mingw="yes"
+ echo "MinGW build environment found; using .exe as suffix for binaries"
+ mingw_lib=`get_path gcc`
+ mingw_lib=`dirname "$mingw_lib"`/../lib
+ ;;
+ *)
+ true ;;
+esac
+
+######################################################################
+# Is the target Win32?
+
+use_cygpath=0
+# Whether we have to translate Unix paths to/from Windows paths.
+
+if [ -z "$system" ]; then
+ system=`ocamlc -config 2>/dev/null|tr -d '\015'|sed -n -e 's/^system: //p'`
+ # This may be
+ # - mingw or mingw64
+ # - win32
+ # - win64
+ # - cygwin
+ # - some other string means Unix
+ # - empty means ocamlc does not support -config
+fi
+
+case "$system" in
+ mingw|mingw64)
+ if [ "$pure_mingw" = "no" ]; then
+ # CYGWIN
+ use_cygpath=1
+ fi
+ ;;
+ win32) use_cygpath=1;;
+ win64) use_cygpath=1;;
+esac
+
+######################################################################
+# check for presence of /bin/sh
+
+if [ ! -f /bin/sh ]; then
+ sh=sh
+fi
+
+######################################################################
+# Find out standard library location
+
+ocaml_core_stdlib=`get_stdlib`
+if [ ! -d "$ocaml_core_stdlib" ]; then
+ echo "configure: cannot determine ocaml's standard library directory" 1>&2
+ exit 1
+fi
+
+if [ ${use_cygpath} -gt 0 ]; then
+ cygpath_to_unix ocaml_core_stdlib
+ # This makes ocaml_core_stdlib a Unix-type path
+fi
+
+# Set site-lib directory:
+
+if [ -z "$ocaml_sitelib" ]; then
+ case "$ocaml_core_stdlib" in
+ /opt/*) ocaml_sitelib=`dirname "${ocaml_core_stdlib}"`/site-lib
+ ;;
+ *) ocaml_sitelib="${ocaml_core_stdlib}/site-lib"
+ ;;
+ esac
+fi
+
+# Find out the directory where ocamlc is:
+
+ocamlc=`get_path ocamlc`
+ocaml_core_bin=`dirname "${ocamlc}"`
+
+# Set the directory of ocamlfind:
+
+test -n "$ocamlfind_bin" || ocamlfind_bin="$ocaml_core_bin"
+
+# Find the directory for the manual:
+
+# Fallback:
+ocaml_core_man=/usr/local/man
+
+d="$ocaml_core_bin"
+while [ "$d" != '/' ]; do
+ f=0
+ if [ -d "$d/man/man1" ]; then
+ if [ -f "$d/man/man1/ocamlc.1" ] ||
+ [ -f "$d/man/man1/ocamlc.1.gz" ] ||
+ [ -f "$d/man/man1/ocamlc.1.Z" ]; then
+ f=1
+ fi
+ else
+ if [ -d "$d/man/mann" ]; then
+ if [ -f "$d/man/mann/ocamlc.n" ] ||
+ [ -f "$d/man/mann/ocamlc.n.gz" ] ||
+ [ -f "$d/man/mann/ocamlc.n.Z" ]; then
+ f=1
+ fi
+ fi
+ fi
+ if [ "$f" = "1" ]; then
+ ocaml_core_man="$d/man"
+ d="/"
+ else
+ d=`dirname "$d"`
+ fi
+done
+
+# Set the directory for ocamlfind's manuals:
+
+test -n "$ocamlfind_man" || ocamlfind_man="$ocaml_core_man"
+
+# Guess the right directory for the configuration file:
+
+if [ -z "${ocamlfind_config}" ]; then
+ d="$ocaml_core_bin"
+ case "$d" in
+ */bin)
+ if [ -f `dirname "$d"`/lib/findlib.conf ]; then
+ ocamlfind_config=`dirname "$d"`/lib/findlib.conf
+ else
+ ocamlfind_config=`dirname "$d"`/etc/findlib.conf
+ fi
+ ;;
+ *)
+ ocamlfind_config=/usr/local/etc/findlib.conf
+ # Fallback value
+ ;;
+ esac
+fi
+
+######################################################################
+# do we have #remove_directory?
+
+echo "Checking for #remove_directory..."
+have_remdir=1
+ocaml itest-aux/remdir.ml >/dev/null 2>/dev/null || have_remdir=0
+
+######################################################################
+# Test the threading model
+
+echo "Testing threading model..."
+
+if ocamlc -vmthread >/dev/null 2>/dev/null; then
+ ocaml_threads="vm"
+else
+ ocaml_threads="none"
+fi
+
+if ocamlc -config >/dev/null 2>/dev/null; then
+ # Good. ocamlc tells us the threading model.
+ if ocamlc -config | grep 'systhread_supported: true'; then
+ ocaml_threads="posix"
+ fi
+else
+ # Old ocamlc do not have -config.
+ rm -f itest-aux/simple
+ ocamlc -w a -custom -thread -o itest-aux/simple -I +unix unix.cma threads.cma itest-aux/simple_threads.ml \
+ >itest-aux/err.out 2>&1
+ output=`cat itest-aux/err.out`
+
+ if [ -z "$output" ]; then
+ ocaml_threads="posix"
+ fi
+fi
+
+######################################################################
+# Does this version of OCaml support autolinking?
+
+# Works for OCaml >= 3.00 on. Because findlib can only be compiled
+# with these OCaml versions, we can safely assume that autolinking
+# is enabled.
+
+ocaml_autolink="true"
+
+######################################################################
+# Does this version of OCaml support DLLs?
+
+echo "Testing DLLs..."
+
+have_dlls="yes"
+
+ocaml -I +unix unix.cma itest-aux/simple.ml >/dev/null || have_dlls="no"
+
+######################################################################
+# Does this version of OCaml support extension points?
+
+echo "Testing whether ppxopt can be supported..."
+
+with_ppxopt=1
+enable_topfind_ppxopt=true
+
+ocaml -I +compiler-libs itest-aux/ppx.ml >/dev/null || {
+ with_ppxopt=0
+ enable_topfind_ppxopt=false
+}
+
+######################################################################
+# Check for -opaque
+
+echo "Checking for ocamlc -opaque..."
+
+opaque="-opaque"
+ocamlc -opaque >/dev/null 2>/dev/null || opaque=""
+
+######################################################################
+# Configure libraries
+
+check_before_install=0
+findlib_installed_meta=''
+if [ -d "${ocaml_sitelib}" ]; then
+ previous_config="${ocaml_sitelib}/findlib/Makefile.packages"
+ if [ -f "${previous_config}" ]; then
+ echo "Querying installation: found list of findlib-generated META files"
+ eval "$(sed -ne 's/ /,/g' -e 's/^SITELIB_META,*=,*\([^,].*[^,]\),*/findlib_installed_meta="\1"/p' "$previous_config")"
+ echo "Installation has: $findlib_installed_meta"
+ else
+ previous_config=''
+ check_before_install=1
+ echo "Querying installation: META list not found"
+ echo "make install will double-check installed META files"
+ fi
+else
+ previous_config=''
+fi
+
+echo "Configuring libraries..."
+
+# Only succeeds if ${ocaml_sitelib}/$1/META exists and we're **certain**
+# it wasn't installed by a previous findlib installation.
+is_third_party_META () {
+ if [ $check_before_install -eq 0 ]; then
+ if [ -f "${ocaml_sitelib}/$1/META" ]; then
+ case ",$findlib_installed_meta," in
+ *,$1,*)
+ return 1;;
+ *)
+ return 0;;
+ esac
+ else
+ return 1
+ fi
+ else
+ return 1
+ fi
+}
+
+check_library () {
+ if is_third_party_META $1; then
+ echo "$1: package already present"
+ # Library is present - exit code is 0 because the library is found
+ # (e.g. detection for Unix) but we don't actually add it to the
+ # generated_META list.
+ return 0
+ fi
+
+ if [ -z "$3" ]; then
+ check_library "$1" "$2" "$1.cmi"
+ return $?
+ fi
+
+ package="$1"
+ if [ -z "$2" ]; then
+ msg=''
+ else
+ msg=" ($2)"
+ fi
+
+ shift 2
+ for file; do
+ if [ -e "${ocaml_core_stdlib}/${file}" ]; then
+ package_dir="$(dirname "${file}")"
+ if [ "${package_dir}" = '.' ]; then
+ echo "${package}: found"
+ package_subdir='.'
+ package_dir='^'
+ else
+ package_subdir="${package_dir}"
+ package_dir="+${package_dir}"
+ echo "${package}: found (in ${package_dir})"
+ fi
+ package_key="$(echo "${package}" | tr - _)"
+ eval "${package_key}_dir=\"${package_dir}\""
+ eval "${package_key}_subdir=\"${package_subdir}\""
+ if [ "$package" = 'num' ]; then
+ generated_META="${generated_META} num num-top"
+ numtop='num-top'
+ else
+ generated_META="${generated_META} ${package}"
+ fi
+ return 0
+ fi
+ done
+
+ echo "$package: not present${msg}"
+ return 1
+}
+
+generated_META='stdlib'
+numtop=''
+
+if ! check_library unix 'possible since 4.08' unix/unix.cmi unix.cmi; then
+ echo "configure: ocamlfind requires OCaml's Unix library" 1>&2
+ exit 1
+fi
+
+check_library dynlink '' dynlink/dynlink.cmi dynlink.cmi
+check_library bigarray 'possible since 4.08'
+check_library compiler-libs '' 'compiler-libs'
+check_library dbm 'normal since 4.00'
+check_library graphics 'normal since 4.09'
+check_library num 'normal since 4.06'
+check_library ocamlbuild 'normal since 4.03' ocamlbuild/ocamlbuildlib.cma
+check_library ocamldoc '' ocamldoc/odoc.cmi
+check_library raw_spacetime 'normal since 4.12' raw_spacetime_lib.cmxa
+check_library threads '' threads/thread.cmi vmthreads/thread.cmi;
+check_library runtime_events '' runtime_events/runtime_events.cmi
+
+# Need to know if str and labltk are available for the toolbox
+if check_library str 'possible since 4.08' str/str.cmi str.cmi; then
+ have_str=1
+else
+ have_str=0
+fi
+
+if check_library labltk 'normal since 4.02' labltk/labltk.cma; then
+ have_labltk=1
+else
+ have_labltk=0
+fi
+
+# Dynlink check.
+
+have_natdynlink=0
+natdynlink=""
+camlp4_dynlink=""
+if [ -f "${ocaml_core_stdlib}/${dynlink_subdir}/dynlink.cmxa" ]; then
+ have_natdynlink=1
+ natdynlink="archive(native) = \"dynlink.cmxa\""
+ camlp4_dynlink="dynlink"
+ echo "native dynlink: found"
+else
+ natdynlink="archive(native) = \"\""
+ echo "native dynlink: not found"
+fi
+
+# Check on camlp4:
+
+if [ $with_camlp4 -eq 0 ]; then
+ echo "camlp4: disabled"
+else if in_path camlp4; then
+ if is_third_party_META camlp4; then
+ echo "camlp4: third-party"
+ fi
+ camlp4_dir=`camlp4 -where | tr -d '\015'`
+ if [ ${use_cygpath} -gt 0 ]; then
+ camlp4_dir=`echo x | env USE_CYGPATH=1 tools/patch x "$camlp4_dir"`
+ # This makes camlp4_dir a windows path
+ elif [ "${pure_mingw}" = "yes" ]; then
+ # Must double the backslahes
+ camlp4_dir="$(echo "${camlp4_dir}" | sed -e 's;\\;\\\\;g')"
+ fi
+ camlp4_version=`camlp4 -v 2>&1`
+ if [ "$have_dlls" = "yes" ]; then
+ camlp4_cmd="camlp4"
+ else
+ camlp4_cmd="safe_camlp4"
+ fi
+ # Check whether 3.09 or 3.10 style:
+ if camlp4 -loaded-modules >/dev/null 2>/dev/null; then
+ camlp4style=310
+ else
+ camlp4style=309
+ fi
+ generated_META="${generated_META} camlp4"
+ rm -rf "site-lib-src/camlp4"
+ mkdir "site-lib-src/camlp4"
+ cp "site-lib-src/camlp4.$camlp4style/META.in" "site-lib-src/camlp4/"
+ echo "camlp4: using $camlp4_cmd, style $camlp4style"
+else
+ with_camlp4=0
+ echo "camlp4: not present (normal since OCaml-4.02)"
+fi
+fi
+
+# bytes?
+# (NB. This is always ours, and it doesn't go into generated_META)
+
+req_bytes=""
+if [ -f "${ocaml_core_stdlib}/bytes.cmi" ] ||
+ [ -f "${ocaml_core_stdlib}/stdlib__bytes.cmi" ] ||
+ [ -f "${ocaml_core_stdlib}/stdlib__Bytes.cmi" ]; then
+ echo "bytes: found, installing fake library"
+ lbytes="bytes"
+ cbytes=0
+else
+ echo "bytes: not found, installing compat library"
+ lbytes=""
+ req_bytes="bytes"
+ cbytes=1
+fi
+
+
+if [ $with_toolbox -gt 0 ]; then
+ if [ $have_str -eq 0 ] || [ $have_labltk -eq 0 ]; then
+ echo "Sorry, toolbox requires str and labltk - omitting toolbox."
+ with_toolbox=0
+ fi
+fi
+
+# Generate the META files now.
+
+for dir in site-lib-src/*; do
+ # We do not really know if $dir is a directory.
+ rm -f $dir/META
+done
+
+for lib in $generated_META $lbytes; do
+ if=""
+ if [ -f site-lib-src/$lib/interfaces.out ]; then
+ if=`cat site-lib-src/$lib/interfaces.out`
+ fi
+ sed -e "s|%%os%%|${os}|g" \
+ -e "s|%%type_of_threads%%|${ocaml_threads}|g" \
+ -e "s|%%camlp4_dir%%|${camlp4_dir}|g" \
+ -e "s|%%camlp4_version%%|${camlp4_version}|g" \
+ -e "s|%%camlp4_cmd%%|${camlp4_cmd}|g" \
+ -e "s|%%camlp4_dynlink%%|${camlp4_dynlink}|g" \
+ -e "s|%%interfaces%%|${if}|g" \
+ -e "s|%%findlib_version%%|${version}|g" \
+ -e "s|%%natdynlink%%|${natdynlink}|g" \
+ -e "s|%%dynlink_dir%%|${dynlink_dir}|g" \
+ -e "s|%%unix_dir%%|${unix_dir}|g" \
+ -e "s|%%str_dir%%|${str_dir}|g" \
+ site-lib-src/$lib/META.in > site-lib-src/$lib/META
+
+ echo "Configuration for $lib written to site-lib-src/$lib/META"
+done
+
+for part in `cd src; echo *`; do
+ if [ -f "src/$part/META.in" ]; then
+ sed -e "s/@VERSION@/$version/g" \
+ -e "s/@REQUIRES@/${req_bytes}/g" \
+ src/$part/META.in >src/$part/META
+ fi
+done
+
+######################################################################
+
+printf "Detecting compiler arguments: "
+
+( cd tools/extract_args && make ) >ocargs.log 2>&1
+if [ "$?" -eq 0 ]; then
+ printf "(extractor built) "
+ tools/extract_args/extract_args -o src/findlib/ocaml_args.ml ocamlc ocamlcp ocamloptp ocamlmklib ocamlmktop ocamlopt ocamldep ocamldoc >>ocargs.log 2>&1
+ # ocamlbrowser does not work!
+ if [ $? -eq 0 ]; then
+ echo "ok"
+ else
+ echo "FAILED (see the file ocargs.log for details)"
+ exit 1
+ fi
+else
+ echo "FAILED (see the file ocargs.log for details)"
+ exit 1
+fi
+
+######################################################################
+# Write Makefile.config
+
+parts="findlib"
+ocamlfind_ocamlflags="-I +unix -I +dynlink"
+ocamlfind_archives="findlib.cma unix.cma"
+if [ $with_toolbox -gt 0 ]; then
+ parts="$parts findlib-toolbox"
+fi
+if [ $cbytes -gt 0 ]; then
+ # bytes first, because findlib needs it
+ parts="bytes $parts"
+ ocamlfind_ocamlflags="${ocamlfind_archives} -I ../bytes"
+ ocamlfind_archives="bytes.cma ${ocamlfind_archives}"
+fi
+
+echo "# Makefile.config written by configure" >Makefile.config
+echo "OCAML_CORE_STDLIB=${ocaml_core_stdlib}" >>Makefile.config
+echo "OCAML_CORE_BIN=${ocaml_core_bin}" >>Makefile.config
+echo "OCAML_CORE_MAN=${ocaml_core_man}" >>Makefile.config
+echo "OCAML_SITELIB=${ocaml_sitelib}" >>Makefile.config
+echo "OCAML_THREADS=${ocaml_threads}" >>Makefile.config
+echo "OCAMLFIND_BIN=${ocamlfind_bin}" >>Makefile.config
+echo "OCAMLFIND_MAN=${ocamlfind_man}" >>Makefile.config
+echo "OCAMLFIND_CONF=${ocamlfind_config}" >>Makefile.config
+echo "OCAMLFIND_OCAMLFLAGS=${ocamlfind_ocamlflags}" >>Makefile.config
+echo "OCAMLFIND_ARCHIVES=${ocamlfind_archives}" >>Makefile.config
+echo "OCAML_AUTOLINK=${ocaml_autolink}" >>Makefile.config
+echo "OCAML_REMOVE_DIRECTORY=${have_remdir}" >>Makefile.config
+echo "EXEC_SUFFIX=${exec_suffix}" >>Makefile.config
+echo "LIB_SUFFIX=${lib_suffix}" >>Makefile.config
+echo "CUSTOM=${custom}" >>Makefile.config
+echo "PARTS=${parts}" >>Makefile.config
+echo "INSTALL_TOPFIND=${with_topfind}" >>Makefile.config
+echo "USE_CYGPATH=${use_cygpath}" >>Makefile.config
+echo "HAVE_NATDYNLINK=${have_natdynlink}" >>Makefile.config
+echo "VERSION=${version}" >>Makefile.config
+echo "ENABLE_TOPFIND_PPXOPT=${enable_topfind_ppxopt}" >>Makefile.config
+echo "SYSTEM=${system}" >>Makefile.config
+echo "NUMTOP=${numtop}" >>Makefile.config
+echo "SH=${sh}" >>Makefile.config
+if [ "$mingw_lib" != "" ]; then
+ echo "OCAMLC_FLAGS=-I \"${mingw_lib}\"" >>Makefile.config
+ echo "OCAMLOPT_FLAGS=-I \"${mingw_lib}\"" >>Makefile.config
+fi
+echo "OPAQUE=${opaque}" >>Makefile.config
+echo "CHECK_BEFORE_INSTALL=${check_before_install}" >>Makefile.config
+echo "INSTALLDIR = install -d" >>Makefile.config
+echo "# change to INSTALLDIR = mkdir -p when BSD install is unavavailable" >>Makefile.config
+echo "INSTALLFILE = install -c" >>Makefile.config
+echo "# change to INSTALLFILE = cp when BSD install is unavailable" >>Makefile.config
+echo "SITELIB_META=${generated_META}" >Makefile.packages
+
+# All OK
+
+echo
+echo "About the OCAML core installation:"
+echo " Standard library: ${ocaml_core_stdlib}"
+echo " Binaries: ${ocaml_core_bin}"
+echo " Manual pages: ${ocaml_core_man}"
+echo " Multi-threading type: ${ocaml_threads}"
+echo "The directory of site-specific packages will be"
+echo " site-lib: ${ocaml_sitelib}"
+echo "The configuration file is written to:"
+echo " findlib config file: ${ocamlfind_config}"
+echo "Software will be installed:"
+echo " Libraries: in /findlib"
+echo " Binaries: ${ocamlfind_bin}"
+echo " Manual pages: ${ocamlfind_man}"
+if [ $with_topfind -gt 0 ]; then
+ echo " topfind script: ${ocaml_core_stdlib}"
+else
+ echo " topfind script: omitted"
+fi
+
+if [ $with_ppxopt -gt 0 ]; then
+ echo "Topfind ppxopt support: yes"
+else
+ echo "Topfind ppxopt support: no"
+fi
+
+if [ $with_toolbox -gt 0 ]; then
+ echo "Toolbox: yes"
+else
+ echo "Toolbox: no"
+fi
+
+if [ -z "$custom" ]; then
+ echo "Link custom runtime: no"
+else
+ echo "Link custom runtime: yes"
+fi
+
+if [ $cbytes -gt 0 ]; then
+ echo "Need bytes compatibility: yes"
+else
+ echo "Need bytes compatibility: no"
+fi
+
+echo
+echo "Configuration has been written to Makefile.config"
+echo
+echo "You can now do 'make all', and optionally 'make opt', to build ocamlfind."
+
diff --git a/local-packages/ocamlfind/doc/DOCINFO b/local-packages/ocamlfind/doc/DOCINFO
new file mode 100644
index 0000000..e5e07dc
--- /dev/null
+++ b/local-packages/ocamlfind/doc/DOCINFO
@@ -0,0 +1,15 @@
+To build the html and manual pages from the SGML sources, you need the
+following tools:
+
+- The DocBook DTD
+ (http://www.davenport.com)
+- James Clark's SGML tools (jade, sx suffice)
+ (http://www.jclark.com)
+- Normal Walsh's DSSSL stylesheets to make the HTML pages
+ (http://nwalsh.com/docbook/dsssl)
+- My db2man tool to make the manual pages
+ (http://www.ocaml-programming.de/packages)
+
+The latter also requires Christian Lindig's XML parser
+(//http://www.cs.tu-bs.de/softech/people/lindig/software/tony.html).
+
diff --git a/local-packages/ocamlfind/doc/Makefile b/local-packages/ocamlfind/doc/Makefile
new file mode 100644
index 0000000..62a4914
--- /dev/null
+++ b/local-packages/ocamlfind/doc/Makefile
@@ -0,0 +1,73 @@
+DOCBOOK_HTML = /usr/share/sgml/docbook/stylesheet/dsssl/modular/html
+DOCBOOK_PRINT = /usr/share/sgml/docbook/stylesheet/dsssl/modular/print
+SRC = $(PWD)/src
+
+EXPORTED = findlib.mli fl_package_base.mli fl_metascanner.mli \
+ fl_dynload.mli topfind.mli
+
+.PHONY: guide-html ref-html ref-man
+
+default: guide-html ref-html ref-man README QUICKSTART
+
+guide-html: guide-html/TIMESTAMP
+ref-html: ref-html/TIMESTAMP
+ref-man: ref-man/TIMESTAMP
+
+guide-html/TIMESTAMP: src/*.sgml src/*.mod QUICKSTART.xml common.xml config.xml
+ mkdir -p guide-html
+ cd guide-html; \
+ rm -f *.htm*; \
+ openjade -t sgml -D$(DOCBOOK_HTML) -D$(SRC) findlib.sgml; \
+ true
+ readme -html QUICKSTART.xml >guide-html/quickstart.html
+ touch guide-html/TIMESTAMP
+
+ref-html/TIMESTAMP: src/*.sgml src/*.mod common.xml config.xml $(EXPORTED:%=../src/findlib/%)
+ mkdir -p ref-html
+ cd ref-html; \
+ rm -f *.htm*; \
+ openjade -t sgml -D$(DOCBOOK_HTML) -D$(SRC) findlib_ref.sgml; \
+ true
+ mkdir -p ref-html/lib
+ cd ../src/findlib && \
+ ocamldoc -html -d $(PWD)/ref-html/lib -stars -t "The Findlib Library" $(EXPORTED)
+ touch ref-html/TIMESTAMP
+
+src/findlib_reference.xml: src/*.sgml src/*.mod
+ osx -D$(DOCBOOK_HTML) -D$(SRC) \
+ findlib_reference.sgml >src/findlib_reference.xml ; \
+ true
+
+ref-man/TIMESTAMP: src/findlib_reference.xml
+ mkdir -p ref-man
+ cd ref-man; \
+ rm -f *.[0-9] TIMESTAMP; \
+ db2man <../src/findlib_reference.xml
+ touch ref-man/TIMESTAMP
+
+# Unfortunately, output of ocamldoc -man is too bad to be useful.
+# cd ../src/findlib && \
+# ocamldoc -man -man-mini -d $(PWD)/ref-man -man-suffix 3 -stars -t "The Findlib Library" $(EXPORTED)
+
+.SUFFIXES: .xml .sgml
+
+.sgml.xml:
+ sx -xndata $< >$@; true
+
+
+
+clean:
+ rm -rf guide-html guide-man ref-html/TIMESTAMP
+ rm -f src/*.xml
+
+distclean:
+ rm -f src/*.xml
+ rm -f src/*~
+ rm -f *~
+
+QUICKSTART: QUICKSTART.xml
+ readme -text QUICKSTART.xml >QUICKSTART
+
+README: README.xml
+ readme -text README.xml >README
+
diff --git a/local-packages/ocamlfind/doc/QUICKSTART b/local-packages/ocamlfind/doc/QUICKSTART
new file mode 100644
index 0000000..582dbb2
--- /dev/null
+++ b/local-packages/ocamlfind/doc/QUICKSTART
@@ -0,0 +1,247 @@
+******************************************************************************
+QUICKSTART - The most important ways to use findlib
+******************************************************************************
+
+
+==============================================================================
+Intro
+==============================================================================
+
+See the file INSTALL for instructions how to build and install findlib.
+
+==============================================================================
+Findlib and the toploop
+==============================================================================
+
+For a number of platforms, OCaml can load bytecode-compiled libraries
+dynamically. For these platforms, findlib is very simple to use as explained in
+the following. For other platforms, see the paragraph below about "custom
+toploops".
+
+After the toploop has been started, it is possible to load the special findlib
+support: [1]
+
+$ ocaml
+ Objective Caml version 3.07
+
+# #use "topfind";;
+Findlib has been successfully loaded. Additional directives:
+ #require "package";; to load a package
+ #list;; to list the available packages
+ #camlp4o;; to load camlp4 (standard syntax)
+ #camlp4r;; to load camlp4 (revised syntax)
+ #predicates "p,q,...";; to set these predicates
+ Topfind.reset();; to force that packages will be reloaded
+ #thread;; to enable threads
+
+- : unit = ()
+
+You can now list the available packages:
+
+# #list;;
+bigarray (version: [distributed with Ocaml])
+camlp4 (version: Camlp4 version 3.03 ALPHA)
+dbm (version: [distributed with Ocaml])
+dynlink (version: [distributed with Ocaml])
+findlib (version: 0.6)
+graphics (version: [distributed with Ocaml])
+labltk (version: [distributed with Ocaml])
+netstring (version: 0.10)
+num (version: [distributed with Ocaml])
+stdlib (version: [distributed with Ocaml])
+str (version: [distributed with Ocaml])
+threads (version: [distributed with Ocaml])
+unix (version: [distributed with Ocaml])
+xstrp4 (version: 1.1)
+
+and load packages by simply typing:
+
+# #require "netstring";;
+Loading /opt/ocaml/lib/unix.cma
+Loading /opt/ocaml/lib/str.cma
+Loading /opt/ocaml/site-lib/netstring/netstring.cma
+Loading /opt/ocaml/site-lib/netstring/netstring_top.cmo
+
+Findlib takes care to load packages that are required by loaded packages first.
+For example, "netstring" uses "unix" and "str" internally, but you do not need
+to load them because findlib does it for you. In this example you can also see
+that findlib loads netstring_top.cmo containing printers for the toploop.
+
+You can also enable the Camlp4 parsers by simply typing
+
+# #camlp4o;;
+Loading /opt/ocaml-3.03a/lib/camlp4/camlp4o.cma
+ Camlp4 Parsing version 3.03 ALPHA
+
+for the standard syntax or
+
+# #camlp4r;;
+Loading /opt/ocaml-3.03a/lib/camlp4/camlp4r.cma
+ Camlp4 Parsing version 3.03 ALPHA
+
+for the revised syntax. (But you cannot switch between the syntaxes.)
+
+==============================================================================
+Custom Toploops
+==============================================================================
+
+For some platforms, OCaml does not implement loading external libraries (e.g.
+Cygwin). One has to create a so-called custom toploop that statically links
+with these libraries. Example:
+
+$ ocamlfind ocamlmktop -o mytop -package findlib,unix -linkpkg
+$ ./mytop
+ Objective Caml version 3.07
+
+# #use "topfind";;
+Findlib has been successfully loaded. Additional directives:
+ #require "package";; to load a package
+ #list;; to list the available packages
+ #camlp4o;; to load camlp4 (standard syntax)
+ #camlp4r;; to load camlp4 (revised syntax)
+ #predicates "p,q,...";; to set these predicates
+ Topfind.reset();; to force that packages will be reloaded
+ #thread;; to enable threads
+
+- : unit = ()
+
+Now "#require" works for all libraries referring to the special "unix"
+functions.
+
+==============================================================================
+Findlib and scripts
+==============================================================================
+
+The #require directive can also be used in scripts. Example:
+
+#use "topfind";;
+#require "netstring";;
+
+open Cgi;;
+...
+
+This makes it possible to write scripts that do not contain #directory
+directives that are specific for certain installations.
+
+For Unix environments, you can start scripts directly if you apply the
+following trick:
+
+#! /bin/sh
+# (*
+exec ocaml "$0" "$@"
+*) use "topfind";;
+#require "netstring";;
+
+open Cgi;;
+...
+
+This works wherever OCaml is installed.
+
+==============================================================================
+Compiling programs
+==============================================================================
+
+Assumed you want to compile a program that uses the Netstring package. Do it
+the following way:
+
+$ ocamlfind ocamlc -package netstring -c myprogram.ml
+
+This way you do not need to add "-I" options to locate Netstring.
+
+If you want to create an executable, do not forget to add the -linkpkg switch:
+
+$ ocamlfind ocamlc -o myprogram -package netstring -linkpkg myprogram.cmo
+
+This switch causes that the mentioned packages are added to the resulting
+executable.
+
+If you want to include several packages, you can either add several "-package"
+options, or you can enumerate the packages separated by commas: -package
+netstring,labltk.
+
+==============================================================================
+Camlp4
+==============================================================================
+
+If you add a -syntax option, the compiler will be told to parse the source file
+using camlp4:
+
+$ ocamlfind ocamlc -package netstring -syntax camlp4o -c myprogram.ml
+
+Use -syntax camlp4o for the standard syntax or -syntax camlp4r for the revised
+syntax.
+
+Additionally, you can mention packages that add new syntax features. The
+package xstrp4 is an example of this:
+
+$ ocamlfind ocamlc -package xstrp4,netstring -syntax camlp4o -c myprogram.ml
+
+Now you can use the $ notation that is implemented by xstrp4 in the source file
+myprogram.ml.
+
+Note that you can also invoke ocamldep from ocamlfind:
+
+$ ocamlfind ocamldep -package xstrp4 -syntax camlp4o *.ml *.mli >.depend
+
+This enables the syntax extensions, too.
+
+==============================================================================
+ocamlbrowser
+==============================================================================
+
+Since findlib-0.7, it is also possible to start ocamlbrowser from ocamlfind.
+For example,
+
+$ ocamlfind browser -package xstrp4
+
+adds the correct path specification such that the modules contained in the
+package xstrp4 are also displayed. With
+
+$ ocamlfind browser -all
+
+all package are added to the path spec.
+
+==============================================================================
+The Makefile wizard
+==============================================================================
+
+There is a wizard that makes it very easy to write Makefiles. Call the wizard
+by
+
+$ ocamlfind findlib/make_wizard
+
+(the wizard requires that the labltk library is available). A new window pops
+up, and by very few clicks you can describe your own library. Finally, a
+Makefile is written.
+
+==============================================================================
+There is no magic!
+==============================================================================
+
+Findlib is neither a patch of OCaml nor uses it internal features of the OCaml
+programming environment. It is only a convention to install software components
+in filesystem hierarchies, a library interpreting this convention, and some
+frontend applications making the library useable for you.
+
+One important consequence is that you can only refer to those software
+components that have previously been installed in a way findlib understands.
+This convention is beyond the scope of this QUICKSTART guide, see the reference
+manual for details. You can always check whether findlib accepts a component as
+"findlib package" by the command
+
+$ ocamlfind list
+
+(this is the same as the #list directive in the toploop). If the package occurs
+in the list, it is found, otherwise not.
+
+
+--------------------------
+
+[1] In previous versions, #use "findlib" loaded the library. However, this
+ caused a name conflict for a certain type of installation. Because of
+ this, the name of the loader script has been changed to "topfind", but
+ "findlib", and "ocamlfind" (Debian) are also available for backwards
+ compatibility.
+
+
+
diff --git a/local-packages/ocamlfind/doc/QUICKSTART.xml b/local-packages/ocamlfind/doc/QUICKSTART.xml
new file mode 100644
index 0000000..b00a51d
--- /dev/null
+++ b/local-packages/ocamlfind/doc/QUICKSTART.xml
@@ -0,0 +1,288 @@
+
+
+%common;
+
+
+up'>
+
+
+%config;
+
+]>
+
+
+
+ Intro
+
See the file INSTALL for instructions how to build and install
+findlib.
+
+
+
+ Findlib and the toploop
+
+
For a number of platforms, OCaml can load bytecode-compiled
+libraries dynamically. For these platforms, findlib is very simple to
+use as explained in the following. For other platforms, see the paragraph
+below about "custom toploops".
+
+
After the toploop has been started, it is possible to load the special
+findlib support:In previous versions, #use "findlib" loaded the
+library. However, this caused a name conflict for a certain type of
+installation. Because of this, the name of the loader script has been changed
+to "topfind", but "findlib", and "ocamlfind" (Debian) are also available
+for backwards compatibility.
+
+
+$ ocaml
+ Objective Caml version 3.07
+
+# #use "topfind";;
+Findlib has been successfully loaded. Additional directives:
+ #require "package";; to load a package
+ #list;; to list the available packages
+ #camlp4o;; to load camlp4 (standard syntax)
+ #camlp4r;; to load camlp4 (revised syntax)
+ #predicates "p,q,...";; to set these predicates
+ Topfind.reset();; to force that packages will be reloaded
+ #thread;; to enable threads
+
+- : unit = ()
+
+
+You can now list the available packages:
+
+
+# #list;;
+bigarray (version: [distributed with Ocaml])
+camlp4 (version: Camlp4 version 3.03 ALPHA)
+dbm (version: [distributed with Ocaml])
+dynlink (version: [distributed with Ocaml])
+findlib (version: 0.6)
+graphics (version: [distributed with Ocaml])
+labltk (version: [distributed with Ocaml])
+netstring (version: 0.10)
+num (version: [distributed with Ocaml])
+stdlib (version: [distributed with Ocaml])
+str (version: [distributed with Ocaml])
+threads (version: [distributed with Ocaml])
+unix (version: [distributed with Ocaml])
+xstrp4 (version: 1.1)
+
+
+and load packages by simply typing:
+
+
+# #require "netstring";;
+Loading /opt/ocaml/lib/unix.cma
+Loading /opt/ocaml/lib/str.cma
+Loading /opt/ocaml/site-lib/netstring/netstring.cma
+Loading /opt/ocaml/site-lib/netstring/netstring_top.cmo
+
+
+Findlib takes care to load packages that are required by loaded packages
+first. For example, "netstring" uses "unix" and "str" internally, but you
+do not need to load them because findlib does it for you. In this example
+you can also see that findlib loads netstring_top.cmo containing printers
+for the toploop.
+
+
You can also enable the Camlp4 parsers by simply typing
+
+
+# #camlp4o;;
+Loading /opt/ocaml-3.03a/lib/camlp4/camlp4o.cma
+ Camlp4 Parsing version 3.03 ALPHA
+
+
+for the standard syntax or
+
+
+# #camlp4r;;
+Loading /opt/ocaml-3.03a/lib/camlp4/camlp4r.cma
+ Camlp4 Parsing version 3.03 ALPHA
+
+
+for the revised syntax. (But you cannot switch between the syntaxes.)
+
+
+
+
+ Custom Toploops
+
+
For some platforms, OCaml does not implement loading external
+libraries (e.g. Cygwin). One has to create a so-called custom toploop
+that statically links with these libraries. Example:
+
+
+$ ocamlfind ocamlmktop -o mytop -package findlib,unix -linkpkg
+$ ./mytop
+ Objective Caml version 3.07
+
+# #use "topfind";;
+Findlib has been successfully loaded. Additional directives:
+ #require "package";; to load a package
+ #list;; to list the available packages
+ #camlp4o;; to load camlp4 (standard syntax)
+ #camlp4r;; to load camlp4 (revised syntax)
+ #predicates "p,q,...";; to set these predicates
+ Topfind.reset();; to force that packages will be reloaded
+ #thread;; to enable threads
+
+- : unit = ()
+
+
+Now "#require" works for all libraries referring to the special "unix"
+functions.
+
+
+
+
+ Findlib and scripts
+
+
The #require directive can also be used in scripts. Example:
+
+
+#use "topfind";;
+#require "netstring";;
+
+open Cgi;;
+...
+
+
+This makes it possible to write scripts that do not contain #directory
+directives that are specific for certain installations.
+
+
For Unix environments, you can start scripts directly if you
+apply the following trick:
+
+
+#! /bin/sh
+# (*
+exec ocaml "$0" "$@"
+*) use "topfind";;
+#require "netstring";;
+
+open Cgi;;
+...
+
+
+This works wherever OCaml is installed.
+
+
+
+ Compiling programs
+
+
Assumed you want to compile a program that uses the Netstring package.
+Do it the following way:
+
+
+$ ocamlfind ocamlc -package netstring -c myprogram.ml
+
+
+This way you do not need to add "-I" options to locate Netstring.
+
+
If you want to create an executable, do not forget to add the
+-linkpkg switch:
+
+
+$ ocamlfind ocamlc -o myprogram -package netstring -linkpkg myprogram.cmo
+
+
+This switch causes that the mentioned packages are added to the resulting
+executable.
+
+
If you want to include several packages, you can either add several
+"-package" options, or you can enumerate the packages separated by commas:
+-package netstring,labltk.
+
+
+
+ Camlp4
+
+
If you add a -syntax option, the compiler will be told to parse the
+source file using camlp4:
+
+
+$ ocamlfind ocamlc -package netstring -syntax camlp4o -c myprogram.ml
+
+
+Use -syntax camlp4o for the standard syntax or -syntax camlp4r for the
+revised syntax.
+
+
Additionally, you can mention packages that add new syntax features.
+The package xstrp4 is an example of this:
+
+
+$ ocamlfind ocamlc -package xstrp4,netstring -syntax camlp4o -c myprogram.ml
+
+
+Now you can use the $ notation that is implemented by xstrp4 in the
+source file myprogram.ml.
+
+
Note that you can also invoke ocamldep from ocamlfind:
+
+
+$ ocamlfind ocamldep -package xstrp4 -syntax camlp4o *.ml *.mli >.depend
+
+
+This enables the syntax extensions, too.
+
+
+
+ ocamlbrowser
+
Since findlib-0.7, it is also possible to start ocamlbrowser from
+ocamlfind. For example,
+
+
+$ ocamlfind browser -package xstrp4
+
+
+adds the correct path specification such that the modules contained in the
+package xstrp4 are also displayed. With
+
+
+$ ocamlfind browser -all
+
+
+all package are added to the path spec.
+
+
+
+
+ The Makefile wizard
+
There is a wizard that makes it very easy to write Makefiles. Call the
+wizard by
+
+$ ocamlfind findlib/make_wizard
+
+(the wizard requires that the labltk library is available). A new window
+pops up, and by very few clicks you can describe your own library. Finally,
+a Makefile is written.
+
+
+
+
+ There is no magic!
+
+
Findlib is neither a patch of OCaml nor uses it internal features of
+the OCaml programming environment. It is only a convention to install
+software components in filesystem hierarchies, a library interpreting
+this convention, and some frontend applications making the library useable for
+you.
+
+
One important consequence is that you can only refer to those
+software components that have previously been installed in a way findlib
+understands. This convention is beyond the scope of this QUICKSTART guide,
+see the reference manual for details. You can always check whether findlib
+accepts a component as "findlib package" by the command
+
+
+$ ocamlfind list
+
+
+(this is the same as the #list directive in the toploop). If the package
+occurs in the list, it is found, otherwise not.
+
+
+
diff --git a/local-packages/ocamlfind/doc/README b/local-packages/ocamlfind/doc/README
new file mode 100644
index 0000000..3385211
--- /dev/null
+++ b/local-packages/ocamlfind/doc/README
@@ -0,0 +1,470 @@
+******************************************************************************
+README - The findlib library manager
+******************************************************************************
+
+
+==============================================================================
+Introduction
+==============================================================================
+
+The "findlib" software provides a scheme to manage reusable software components
+in the form of libraries, and includes tools that support this scheme. A
+library installed as a findlib component is also called a package. The point is
+that the findlib scheme allows it to store metainformation about the library,
+especially how it can be used in programs. The packages are kept in the
+filesystem hierarchy, but the directory structure is defined by findlib, and
+there is no way to deviate from this standard. The library contains functions
+to look the directory up that stores a package, to query metainformation about
+a package, and to retrieve dependency information about multiple packages.
+There is also a tool that allows the user to enter queries on the command-line.
+In order to simplify compilation and linkage, there are new frontends of the
+various OCaml compilers that can directly deal with packages.
+
+It is important to understand that findlib is not a general-purpose package
+manager (like rpm for Linux), and does not support the management of arbitrary
+files, but only OCaml libraries. However, there are lots of special functions
+for libraries. findlib is more comparable with Gnome's pkg-config and Perl's
+MakeMaker, but of course there are language-specific differences.
+
+The metainformation includes:
+
+- The necessary command-line arguments to use a library.
+
+- Dependencies on other packages.
+
+- Version strings.
+
+These data can be conditional. Possible conditions are certain environmental
+settings, such as whether the bytecode or the native code compiler is used, or
+whether the application is multi-threaded. It is also possible that a package
+behaves differently when a certain other package is selected.
+
+There is special support for scripts. It is possible to load libraries into
+toploops, including all dependent libraries, with only one command.
+
+Findlib has been developed since March 1999, and has matured for more than four
+years until the release of version 1.0. One of the important questions during
+this long period of development was which features are necessary and which not.
+The result is a utility that follows still simple concepts, but is flexible
+enough to allow even the description of complex libraries and complex
+interdependencies.
+
+==============================================================================
+Documentation
+==============================================================================
+
+See the file QUICKSTART for the most important findlib commands.
+
+There is a User's Guide introducing into the concepts of findlib, especially
+explaining how to create packages.
+
+The Reference Manual describes commands, directory structure, configuration
+files, and library routines in detail.
+
+==============================================================================
+Installation
+==============================================================================
+
+See the file INSTALL.
+
+==============================================================================
+Download
+==============================================================================
+
+The current version is announced in the Objective Caml Link Database [1].
+
+==============================================================================
+Copyright and License Conditions
+==============================================================================
+
+Findlib is copyright 1999-2012 by Gerd Stolpmann. See the file LICENSE for the
+MIT/X11 style license conditions. Contact me at gerd@gerd-stolpmann.de in case
+of questions.
+
+==============================================================================
+List of Changes
+==============================================================================
+
+- 1.9.5:: fixes a bug in the scripting that slipped into 1.9.4
+
+- 1.9.4: Also finds the libraries str.cm(x)a, unix.cm(x)a, and dynlink.cm(x)a
+ in subdirectories of the OCaml standard library, as needed for OCaml-4.14
+ (David Allsopp).
+ Support for runtime_events (Patrick Ferris)
+ Fix spelling of "OCaml" everywhere (Marek Kubica)
+ Work around the deprecation of a POSIX shell feature (Issam Maghni)
+ Support DESTDIR, and favor the "install" command for installation (Gerd
+ Stolpmann on suggestion of Thomas Klausner)
+
+- 1.9.3: Fixes another build problem regarding OCaml-5.00
+
+- 1.9.2: Fixes a build problem regarding OCaml-5.00
+
+- 1.9.1: Fixes a few install-related issues, like missing files.
+
+- 1.9: Overhaul how separately installed packages (e.g. num) are handled (by
+ David Allsopp).
+ Switch to opam-2.0 file format (by David Allsopp).
+ Fix an incomaptibility with ocaml-4.13 (by David Allsopp).
+ Expose the native toplevel (by Louis Gesbert).
+ Fix an incompatibility with "Jane Street Style" (by Mark Laws).
+ Switch from m4 to sed (by kit-ty-kate).
+
+- 1.8.1: Adapted to upcoming ocaml-4.09.
+ New API Findlib.list_packages' can specify a package prefix.
+
+- 1.8.0: Fix reinstallation of "num" for OCaml-4.06.
+ Fix build with OCaml-4.07.
+ The installation of graphics/META is now optional.
+ Fix "ocamlfind query -d".
+ The environment variable OCAMLFIND_IGNORE_DUPS_IN is now interpreted as a
+ list of directories.
+ Packages for "ocamlfind query" may now be separated by commas, too.
+ New "warning" property for packages.
+ Forgetting to pass -thread/-vmthread only prints a warning now, but doesn't
+ stop the build.
+ For dealing with case-sensitive filesystems it is now only tried to match
+ ASCII characters, but not encoding-dependent characters.
+
+- 1.7.3: Fix regarding num-top: this library is now also optional, as num.
+
+- 1.7.2: Trying to protect against failures when several package installs are
+ done in parallel.
+ New subpackage "findlib.top" for the toploop (Jeremie Dimino).
+ The "num" library is now optional.
+ Shell scripts are started via "sh" command when there is no /bin/sh (ygrek)
+
+- 1.7.1: added missing file to tarball
+
+- 1.7.0: New command "ocamlfind printppx" that outputs how the ppx
+ preprocessor would be called (Hendrik Tews).
+ Support for the raw_spacetime library that comes with OCaml 4.04 (Gerd
+ Stolpmann with help from Mark Shinwell).
+ Require that ocamlc and ocamlc.opt are installed to the same directory for
+ emitting the "opt" setting in the generated config file - same for
+ ocamlopt.opt, ocamldep.opt, ocamldoc.opt.
+
+- 1.6.3:Fix: "ocamlfind printconf" respects the environment variable
+ OCAMLFIND_CONF (reported by Andre)
+ Build with -opaque (reported by hhugo)
+ Preliminary support for native toplevel so far the toplevel is implemented
+ symmetrically to the bytecode case (this is not correct in vanilla ocaml)
+ New options: ocamlfind query -qe -qo
+
+- 1.6.2:Uninstalling findlib no longer uninstalls the ocamlbuild library by
+ accident (Gabriel Scherer, Edwin Török)
+ Adding an "ocamldoc" library, providing the cmi's for ocamldoc plugins
+ (suggested by Armaël Guéneau)
+ Support for OCaml-4.03: recognize that the new -color option has an argument
+ (reported by Guillaume Bury)
+
+- 1.6.1: Just an important doc fix.
+
+- 1.6.0: Adding support for dynamically loading packages (François Bobot):
+ new "plugin" variable, new Fl_dynload module.
+ New command "ocamlfind lint" for checking META files (François Bobot).
+ Also support MSYS_NT on Windows. Permit spaces in install paths (Christophe
+ Troestler).
+ Allow to query the location of the META file of a package: "ocamlfind query
+ -format '%m'" (Gerd Stolpmann).
+ Get the install path for the META file of packages: "ocamlfind printconf
+ metapath" (Gerd Stolpmann).
+
+- 1.5.6: for MSVC build fixing bad filename suffix (Dmitry Bely).
+ The switch -only-show did not work as described. (Error report from Bob
+ Atkey.)
+ Also support mingw64 as system type (Matthieu Dubuget).
+
+- 1.5.5: fixes a build problem for BSD systens
+
+- 1.5.4: New ppxopt META variables (Peter Zotov).
+ Support for OCAMLFIND_TOOLCHAIN environment variable (Peter Zotov).
+
+- 1.5.3: The installation of "bytes" respects now $prefix and the configured
+ destination.
+ New option -pp for "ocamlfind query", to get preprocessor packages.
+ Updated the compatibility Bytes module to support extend, init, mapi,
+ blit_string (Gabriel Scherer).
+
+- 1.5.2: support for the query formats "%+a" and "%+A".
+ Fix: the "ppx" property is now also path-expanded when interpreted in a
+ toploop.
+ Fix: implicit "ppx" is not path-expanded anymore.
+ Fix: Build bytes.cmxs only if natdynlink is enabled (Andy Ray).
+
+- 1.5.1: includes a file that was missing in 1.5
+
+- 1.5: Including the "bytes" package that is either a compat package for ocaml
+ < 4.02 or a fake package for ocaml >= 4.02. The package aims at helping to
+ support the transition to the new "bytes" type for mutable strings.
+ Also installing findlib.cmxs if OCaml supports it.
+ Allowing to disable camlp4 (in prep for OCaml-4.02).
+ The "ppx" package property can be specified for constructing ppx-type
+ preprocessors (patches from Peter Zotov).
+
+- 1.4.1:ocamldoc: The order of -ppopt arguments was changed by ocamlfind,
+ which is not correct. (Sylvain Le Gall and Jérémie Dimino.)
+
+- 1.4: Fixed performance bug when many arguments need to be processed (Jérôme
+ Vouillon).
+ Auto-configuring ocamldoc.opt if it is found (Christopher Zimmermann).
+ New config switch -no-custom to prevent that "ocamlfind" is linked in
+ custom-runtime mode (bytecode only) (Christopher Zimmermann).
+ The library dbm is no longer part of OCaml, and now optional in findlib
+ (Ashish Argawal).
+ Support for ocamloptp.
+ New function Topfind.log for controlling the verbosity (Jeremie Dimino).
+ Rewritten Fl_metascanner without camlp4 (patch from Gabriel Scherer)
+
+- 1.3.3: OCaml-4: using the new #remove_directory directive if present.
+ Better compatibility with the OCaml version from Homebrew.
+
+- 1.3.2: Handling of empty arguments (Wojciech Meyer).
+ Added entry for camlp4.fulllib.
+ New switch -add for "ocamlfind install" (Hans Ole Rafaelsen).
+ Further fixes for ocaml-4.00.
+ Fixing the recognition of double .cmi interface files.
+ Fixing -dontlink (it is now deeply interpreted).
+
+- 1.3.1: Fixing a bug with ocamlmklib that slipped through in 1.3.0
+
+- 1.3.0: Fixes for ocaml-4.00 (especially topfind).
+ Emitting an error if the configuration file does not exist.
+ Emitting a warning if the selected toolchain does not exist.
+ camlp4 is referenced by "+camlp4" in META.
+ Including the sources for the documentation in the tarball.
+ License change (simplification) for num_top_printers.mli.
+ Fix ocamlmklib wrapper: processing contracted args (like -L/dir) correctly.
+ Many wrappers get a new option -passrest instructing to pass all remaining
+ options on the command-line unchanged to the invoked tool.
+ Prettified -help output.
+
+- 1.2.8: Adding support for ocamlmklib (B. Meurer's patches)
+ Fix for win32 in the configure script.
+
+- 1.2.7: Fix: if a META file defines several packages, and one of the packages
+ has a broken dependency, ocamlfind used to report all errors even if the
+ broken packages were not used. This is now changed - broken subpackages are
+ ignored when they are not needed, in the same way as broken top-level
+ packages are ignored when not needed. (Thanks to Sylvain Le Gall for
+ reporting the problem.)
+ Added -thread and -vmthread switches to "ocamlfind ocamldoc". These actually
+ only add the right predicates. (Thanks to Vladimir Ivanov for pointing this
+ problem out.)
+ Package warnings can be emitted by "ocamlfind ocamldoc".
+
+- 1.2.6: adding META for ocamlbuild.
+ Fixes for MinGW/MSYS platform.
+ Improved messages.
+
+- 1.2.5: Fix: Again CR deletion... Turns out some OS do not understand '\r'
+ but only '\015' (thanks to Isaiah Weiner).
+ Support for Win64 (untested; thanks to David Allsopp).
+ ocamlfind no longer emits auto-generated -ccopt options. These tend to
+ accumulate, and it is possible that for large projects the maximum command
+ line length is exceeded. Current versions of the OCaml compilers do not
+ need these extra -ccopt anyway, so this code is completely dropped.
+
+- 1.2.4: Fix: Bigarray needs unix (Thanks to Markus Mottl).
+ Fix: In the version of camlp4 provided by OCaml 3.11 various libraries do
+ not contain dynlink anymore. Because of this, dynlink becomes a
+ prerequisite of camlp4. (Thanks to Martin Jambon).
+ Attempt: Fixing the space issue for paths (Win32). It is unclear whether it
+ is solved. (Thanks to Christophe Troestler).
+
+- 1.2.3: Solving the CR deletion differently, to make OS X happy.
+
+- 1.2.2: Fix: Problem with CR character (Cygwin) (Thanks to David Allsopp).
+ Fix: Case-insensitive filesystems (partially solved) (Thanks to David
+ Allsopp).
+ Fix: File name with backslashes at the end (Win32; thanks to Dmitry
+ Grebeniuk).
+
+- 1.2.1: Fix: Camlp4 rules now activate the stream parser extension
+
+- 1.2: Fix in build scripts: Prepending $(prefix) when installing safe_camlp4
+ (thanks to Daniel Janus)
+ Non-existing -I directories are ignored (thanks to Nicolas Pouillard)
+ A script to create a MacOS X package (thanks to Pietro Abate)
+ Better support for Windows (with help from Robert Roessler and David
+ Allsopp)
+ Support for camlp4 on OCaml 3.10
+ Fix: "ocamlfind install" with "-patch" option writes now correct META file
+ for the case that subpackages occur
+ Adding environment variable OCAMLFIND_IGNORE_DUPS_IN to reduce the number of
+ warnings ocamlfind emits
+
+- 1.1.2: Bugfix in the META parser: Backslashes are now correctly parsed.
+ (Thanks to Martin Jambon for finding this problem.)
+ Fixes for platforms that do not support dynamic loading of DLLs.
+ Fixed extraction of camlp4 parameters from packages.
+
+- 1.1.1: Bugfixes only: Fixed detection of threading model for OCaml 3.09.
+ Fixed alternate configuration files.
+
+- 1.1: Automatic detection of standard compiler options.
+ Liberated the checks whether a package is already installed.
+ The .opt compilers are entered into findlib.conf if available.
+ New: "install" has -optional switch for optional files.
+ New: "install" has -patch-version to patch the version into the installed
+ META file.
+ New: "install" has -patch-rmpkg to remove subpackages from the installed
+ META file.
+ New: "install" has -patch-archives which removes non-existing files from
+ "archive" variables. This is experimental.
+ New: subpackages can be disabled by exists_if.
+ New: Support for toolchains.
+ Fix for "remove": -destdir works again.
+ Fix for "call": CTRL-C works when calling interactive commands.
+ Fix for preprocessor packages: Dependencies on normal packages are resolved.
+
+- 1.0.4: Fix: In previous versions, "ocamlmktop" set the "toploop" predicate.
+ It turned out, however, that the toploops generated in this way did not work
+ properly. For this reason, "ocamlmktop" does not set "toploop" any more for
+ link time, but instead a new predicate "create_toploop". When the toploop is
+ executed, the predicate "toploop" is again added.
+
+- 1.0.3: Fix: The relative position of "-cclib -l" options on the command
+ line is preserved. In previous versions, these options were moved to the
+ beginning of the argument list. This did not work for static link editing;
+ dynamic link editing was not affected.
+ Fix: The automatic fixup of "threads" dependencies works again. In the
+ previous version, this was broken.
+ Addition: -format '%(name)' for ocamlfind query.
+ Some minor improvements of the documentation.
+
+- 1.0.2: Fix: The alternate package layout did not fully work. This is
+ repaired now, and there are some clarifications about relative directory
+ paths in the documentation.
+
+- 1.0.1: Fix: Forgot to install some .cmi files
+
+- 1.0: It is now possible to divide the description of a package into
+ subpackages (but there is still only one META file, but with enhanced
+ syntax). This allows it to describe intra-package dependencies.
+ Predicates in META files can be negated.
+ The "error" variable allows you to detect conditions under which the library
+ would not work, and to generate error messages.
+ It is possible to refer to archive files installed in other packages.
+ The set of predicates is extended by "package predicates" after the
+ dependency analysis, making conditions expressable that depend on whether
+ other packages are selected.
+ The "+=" operator in META files adds words to variables rather than setting
+ them.
+ The "#thread" directive enables multi-threading in toploops and scripts, if
+ possible.
+ The "#predicates" directive simplifies the addition of predicates.
+ Queries: The format specifier %D prints the description of the package.
+ -long-format includes the description. Short options -r, -l, -d.
+ ocamlfind list -describe prints package descriptions.
+ Support for "ocamlfind ocamldoc". However, the implementation is quite
+ sloppy.
+ The configuration file is called "findlib.conf" by default, not
+ "ocamlfind.conf".
+ Removal of "ocamlfind guess".
+ Support for #use "findlib" and #use "ocamlfind" has been removed. The only
+ remaining way to load findlib is by #use "topfind".
+ There is no longer a thread-safe version of findlib. The user has to ensure
+ that only one thread uses findlib (which is usually trivial to achieve).
+ ocamlmktop: Directories are no longer automatically added to the search
+ path. This did not work anyway, and this change forces scripts to always
+ invoke "#require" to load/enable libraries, for better uniformity.
+ Fixes: num-top works. "ocamlfind ocamlopt -thread" generates a better error
+ message on non-POSIX systems. "ocamlfind query -descendants" takes
+ predicates into account (it did not do that in previous versions of
+ findlib).
+
+- 0.9: Changes for OCaml 3.07 (-thread, -vmthread). Includes Zack's toploop
+ printers for bigints.
+
+- 0.8 - 0.8.1: Renamed a lot of modules to avoid name clashes with OCaml core
+ modules. Cygwin: Additional option -cygpath for "configure". The man pages
+ have a NAME section. Bugfix in Makefile wizard.
+
+- 0.7 - 0.7.2: DLLs: There are now two styles of installation: DLLs can be
+ installed in the package directories (like before), or in a shared
+ directory "stublibs". For the first style, there is now an option "ldconf"
+ that determines whether the ld.conf file is to be updated, and if so, which
+ file. The latter style is enabled by simply creating a directory "stublibs"
+ in the site-lib directory. (In the first version the directory was called
+ "libexec". By user request, the name of the DLL directory has been changed
+ to "stublibs".)
+ "ocamlfind install" preserves now the mtime of the files.
+ "ocamlfind printconf" is more flexible, and easier to call from scripts.
+ "ocamlfind browser" calls ocamlbrowser with the right -I options.
+ "ocamlfind query": -descendants implies now -recursive.
+ "ocamlfind ocamldep": -native-filter and -bytecode-filter for more exact
+ dependency generation.
+ There may be now postinstall and postremove scripts.
+ "ocamlfind pkg/cmd": This syntax can be used to call the program cmd that
+ is installed in the package directory for pkg. Intended to simplify the
+ invocation of programs that are installed in package directories and not in
+ XXX/bin, which may be useful for package- related tools.
+ Findlib has now a toolbox containing helpful programs besides ocamlfind.
+ For the beginning, there is a Makefile wizard that can be called by
+ "ocamlfind findlib/make_wizard".
+ #use "topfind" instead of #use "findlib" to avoid name clashes in a certain
+ configuration. #use "findlib" and #use "ocamlfind" are still supported for
+ backward compatibility if the name clash does not occur.
+ Fix: bytecode threads work again. (The wrong unix library was linked for
+ recent OCaml versions.)
+ Many smaller improvements; the docs have been updated.
+
+- 0.6 - 0.6.2: Minor changes for Ocaml-3.03-alpha (and later for 3.04). New
+ #list directive. New: #use "findlib" loads the findlib directives into
+ every toploop (Ocaml-3.03-alpha).
+ The file ld.conf is automatically updated when DLLs are installed or
+ removed.
+ Fix: /tmp/findlib_initf* no longer overflows. The thread library is now
+ always the first linked library.
+
+- 0.5 - 0.5.4: Findlib has now a configuration file (see documentation under
+ findlib.conf). Much more environment variables. The location of the
+ standard library is now configurable at runtime.
+ The package search path can now be selected independently of the package
+ installation directory.
+ New commands: ocamlfind list, ocamlfind printconf, ocamlfind guess (See
+ documentation under ocamlfind)
+ Optional alternate directory layout: All META files go into a separate
+ directory (see documentation under site-lib).
+ Findlib works now only for OCaml 3; support for OCaml 2 has been dropped.
+ As a consequence, the "configure" script could be simplified; it is no
+ longer necessary to figure out the linker options.
+ Improved support for camlp4: New directives #camlp4o and #camlp4r for the
+ toploop.
+ ocamlfind now detects whether two selected packages have equally named
+ toplevel modules, and prints a warning in this case.
+ There is a downstripped version ocamlfind-mini (see directory "mini"). This
+ is a one-file script that can be easily distributed with any software.
+ ocamlfind-mini has reduced functionality, but it is sufficient to compile
+ and install a library. (But it does not support using a library.)
+ Support for the Cygwin port of OCaml.
+ Installation of packages: The file permissions are preserved when files are
+ installed. However, the umask is applied. The "install" and "remove"
+ subcommands have better diagnostics.
+ ocamlfind ocamlmktop: Generates now initialization code for the include
+ path. You don't need to call your toploop with -I options any more.
+ Furthermore, this fixes some problems with packages that add printers to
+ the toploop.
+ New: ocamlfind ocamldep. ocamlfind is now prepared for the new -pp option
+ of ocamldep (upcoming Ocaml 3.03).
+ Installation of findlib: New PREFIX variable in Makefile to install
+ locally.
+ Fixes: itest. ocamlfind query -descendants works again.
+
+- 0.4: Experimental support for camlp4 (see FAQ section in the manual). New
+ environment variable OCAMLFIND_COMMANDS (see ocamlfind(1)).
+
+- 0.3 - 0.3.1: Necessary updates for OCaml 3. Bugfix: Findlib did not work for
+ bytecode threads. The reason was that findlib added the directory of the
+ stdlib to the search path. Works now.
+
+Older changes are no longer documented.
+
+
+--------------------------
+
+[1] see http://links.camlcity.org
+
+
+
diff --git a/local-packages/ocamlfind/doc/README.xml b/local-packages/ocamlfind/doc/README.xml
new file mode 100644
index 0000000..c399b02
--- /dev/null
+++ b/local-packages/ocamlfind/doc/README.xml
@@ -0,0 +1,685 @@
+
+
+%common;
+
+
+up'>
+
+
+%config;
+
+]>
+
+
+
+ Introduction
+
+
The "findlib" software provides a scheme to manage reusable software
+components in the form of libraries, and includes tools that support
+this scheme. A library installed as a findlib component is also called
+a package. The point is that the findlib scheme allows it to store
+metainformation about the library, especially how it can be used in
+programs. The packages are kept in the filesystem hierarchy, but the
+directory structure is defined by findlib, and there is no way to
+deviate from this standard. The library contains functions to look the
+directory up that stores a package, to query metainformation about a
+package, and to retrieve dependency information about multiple
+packages. There is also a tool that allows the user to enter queries
+on the command-line. In order to simplify compilation and linkage,
+there are new frontends of the various OCaml compilers that can
+directly deal with packages.
+
+
+
It is important to understand that findlib is not a
+general-purpose package manager (like rpm for Linux), and does not
+support the management of arbitrary files, but only OCaml libraries.
+However, there are lots of special functions for libraries. findlib
+is more comparable with Gnome's pkg-config and Perl's MakeMaker, but
+of course there are language-specific differences.
+
+
The metainformation includes:
+
+
+
The necessary command-line arguments to use a library.
+
+
Dependencies on other packages.
+
+
Version strings.
+
+
+
+
These data can be conditional. Possible conditions are certain
+environmental settings, such as whether the bytecode or the native code
+compiler is used, or whether the application is multi-threaded. It is
+also possible that a package behaves differently when a certain other
+package is selected.
+
+
There is special support for scripts. It is possible to load
+libraries into toploops, including all dependent libraries, with only
+one command.
+
+
Findlib has been developed since March 1999, and has matured
+for more than four years until the release of version 1.0. One of the
+important questions during this long period of development was which
+features are necessary and which not. The result is a utility that
+follows still simple concepts, but is flexible enough to allow even
+the description of complex libraries and complex interdependencies.
+
+
+
+
+ Documentation
+
+
See the file QUICKSTART for the most important findlib commands.
+
+
There is a User's Guide introducing into the concepts of findlib,
+especially explaining how to create packages.
+
+
The Reference Manual describes commands, directory structure,
+configuration files, and library routines in detail.
+ Findlib is copyright 1999-2012 by Gerd Stolpmann. See the file LICENSE
+ for the MIT/X11 style license conditions.
+
+ Contact me at gerd@gerd-stolpmann.de in case of questions.
+
+
+
+
+ List of Changes
+
+
+
+
1.9.5:: fixes a bug in the scripting that
+ slipped into 1.9.4
+
+
+
+
1.9.4: Also finds the libraries str.cm(x)a, unix.cm(x)a,
+ and dynlink.cm(x)a in subdirectories of the OCaml standard library,
+ as needed for OCaml-4.14 (David Allsopp).
+
Support for runtime_events (Patrick Ferris)
+
Fix spelling of "OCaml" everywhere (Marek Kubica)
+
Work around the deprecation of a POSIX shell feature
+ (Issam Maghni)
+
Support DESTDIR, and favor the "install" command for installation
+ (Gerd Stolpmann on suggestion of Thomas Klausner)
+
+
+
1.9.3: Fixes another build problem regarding OCaml-5.00
+
+
1.9.2: Fixes a build problem regarding OCaml-5.00
+
+
1.9.1: Fixes a few install-related issues, like missing files.
+
+
+
1.9: Overhaul how separately installed packages (e.g. num)
+ are handled (by David Allsopp).
+
Switch to opam-2.0 file format (by David Allsopp).
+
Fix an incomaptibility with ocaml-4.13 (by David Allsopp).
+
Expose the native toplevel (by Louis Gesbert).
+
Fix an incompatibility with "Jane Street Style" (by Mark Laws).
+
Switch from m4 to sed (by kit-ty-kate).
+
+
+
+
1.8.1: Adapted to upcoming ocaml-4.09.
+
New API Findlib.list_packages' can specify a package prefix.
+
+
+
+
1.8.0: Fix reinstallation of "num" for OCaml-4.06.
+
+
Fix build with OCaml-4.07.
+
The installation of graphics/META is now optional.
+
Fix "ocamlfind query -d".
+
The environment variable OCAMLFIND_IGNORE_DUPS_IN is now interpreted
+ as a list of directories.
+
Packages for "ocamlfind query" may now be separated by commas, too.
+
New "warning" property for packages.
+
Forgetting to pass -thread/-vmthread only prints a warning now,
+ but doesn't stop the build.
+
For dealing with case-sensitive filesystems it is now only tried to
+ match ASCII characters, but not encoding-dependent characters.
+
+
+
+
1.7.3: Fix regarding num-top: this library is now also
+ optional, as num.
+
+
+
+
1.7.2: Trying to protect against failures when
+ several package installs are done in parallel.
+
+
New subpackage "findlib.top" for the toploop (Jeremie Dimino).
+
+
The "num" library is now optional.
+
+
Shell scripts are started via "sh" command when there is no
+ /bin/sh (ygrek)
+
+
+
+
1.7.1: added missing file to tarball
+
+
+
+
1.7.0: New command "ocamlfind printppx" that outputs
+ how the ppx preprocessor would be called (Hendrik Tews).
+
Support for the raw_spacetime library that comes with
+ OCaml 4.04 (Gerd Stolpmann with help from Mark Shinwell).
+
Require that ocamlc and ocamlc.opt are installed to the
+ same directory for emitting the "opt" setting in the generated
+ config file - same for ocamlopt.opt, ocamldep.opt, ocamldoc.opt.
+
+
+
+
1.6.3:Fix: "ocamlfind printconf" respects the
+ environment variable OCAMLFIND_CONF (reported by Andre)
+
Build with -opaque (reported by hhugo)
+
Preliminary support for native toplevel so far the toplevel
+ is implemented symmetrically to the bytecode case (this is not
+ correct in vanilla ocaml)
+
New options: ocamlfind query -qe -qo
+
+
+
+
1.6.2:Uninstalling findlib no longer uninstalls the
+ocamlbuild library by accident (Gabriel Scherer, Edwin Török)
Support for OCaml-4.03: recognize that the new -color option
+has an argument (reported by Guillaume Bury)
+
+
+
+
1.6.1: Just an important doc fix.
+
+
+
+
1.6.0: Adding support for dynamically loading
+ packages (François Bobot): new "plugin" variable, new
+ Fl_dynload module.
+
New command "ocamlfind lint" for checking META files
+ (François Bobot).
+
Also support MSYS_NT on Windows. Permit spaces in install
+ paths (Christophe Troestler).
+
Allow to query the location of the META file of a package:
+ "ocamlfind query -format '%m'" (Gerd Stolpmann).
+
Get the install path for the META file of packages:
+ "ocamlfind printconf metapath" (Gerd Stolpmann).
+
+
+
+
1.5.6: for MSVC build fixing bad filename suffix
+ (Dmitry Bely).
+
The switch -only-show did not work as described.
+ (Error report from Bob Atkey.)
+
Also support mingw64 as system type (Matthieu Dubuget).
+
+
+
+
1.5.5: fixes a build problem for BSD systens
+
+
+
+
1.5.4: New ppxopt META variables (Peter Zotov).
+
Support for OCAMLFIND_TOOLCHAIN environment variable (Peter Zotov).
+
+
+
+
+
1.5.3: The installation of "bytes" respects now $prefix and
+ the configured destination.
+
New option -pp for "ocamlfind query", to get preprocessor packages.
+
Updated the compatibility Bytes module to support extend, init, mapi,
+ blit_string (Gabriel Scherer).
+
+
+
+
1.5.2: support for the query formats "%+a" and "%+A".
+
Fix: the "ppx" property is now also path-expanded when interpreted
+in a toploop.
+
Fix: implicit "ppx" is not path-expanded anymore.
+
Fix: Build bytes.cmxs only if natdynlink is enabled (Andy Ray).
+
+
+
1.5.1: includes a file that was missing in 1.5
+
+
+
1.5: Including the "bytes" package that is either
+a compat package for ocaml < 4.02 or a fake package for ocaml >= 4.02.
+The package aims at helping to support the transition to the new
+"bytes" type for mutable strings.
+
Also installing findlib.cmxs if OCaml supports it.
+
Allowing to disable camlp4 (in prep for OCaml-4.02).
+
The "ppx" package property can be specified for constructing
+ppx-type preprocessors (patches from Peter Zotov).
Many wrappers get a new option -passrest instructing to pass all
+remaining options on the command-line unchanged to the invoked tool.
+
Prettified -help output.
+
+
+
+
1.2.8:
+Adding support for ocamlmklib (B. Meurer's patches)
+
Fix for win32 in the configure script.
+
+
+
1.2.7:
+Fix: if a META file defines several packages, and one of the packages
+has a broken dependency, ocamlfind used to report all errors even if
+the broken packages were not used. This is now changed - broken
+subpackages are ignored when they are not needed, in the same way as
+broken top-level packages are ignored when not needed. (Thanks to
+Sylvain Le Gall for reporting the problem.)
+
Added -thread and -vmthread switches to "ocamlfind ocamldoc".
+These actually only add the right predicates. (Thanks to Vladimir
+Ivanov for pointing this problem out.)
+
Package warnings can be emitted by "ocamlfind ocamldoc".
+
+
+
1.2.6: adding META for ocamlbuild.
+
Fixes for MinGW/MSYS platform.
+
Improved messages.
+
+
+
1.2.5: Fix: Again CR deletion... Turns out some OS do not
+ understand '\r' but only '\015' (thanks to Isaiah Weiner).
+
Support for Win64 (untested; thanks to David Allsopp).
+
ocamlfind no longer emits auto-generated -ccopt options. These
+ tend to accumulate, and it is possible that for large projects
+ the maximum command line length is exceeded. Current versions of
+ the OCaml compilers do not need these extra -ccopt anyway, so
+ this code is completely dropped.
+
+
+
+
1.2.4: Fix: Bigarray needs unix (Thanks to Markus Mottl).
+
Fix: In the version of camlp4 provided by OCaml 3.11 various
+ libraries do not contain dynlink anymore. Because of this, dynlink
+ becomes a prerequisite of camlp4. (Thanks to Martin Jambon).
+
Attempt: Fixing the space issue for paths (Win32). It is unclear
+ whether it is solved. (Thanks to Christophe Troestler).
+
+
+
+
1.2.3: Solving the CR deletion differently, to
+ make OS X happy.
+
+
+
+
1.2.2: Fix: Problem with CR character (Cygwin)
+ (Thanks to David Allsopp).
+
+
Fix: Case-insensitive filesystems (partially solved)
+ (Thanks to David Allsopp).
+
+
Fix: File name with backslashes at the end (Win32;
+ thanks to Dmitry Grebeniuk).
+
+
+
+
1.2.1: Fix: Camlp4 rules now activate the
+stream parser extension
+
+
+
+
1.2: Fix in build scripts: Prepending $(prefix)
+when installing safe_camlp4 (thanks to Daniel Janus)
+
Non-existing -I directories are ignored
+(thanks to Nicolas Pouillard)
+
A script to create a MacOS X package (thanks to
+Pietro Abate)
+
Better support for Windows (with help from Robert
+Roessler and David Allsopp)
+
Support for camlp4 on OCaml 3.10
+
Fix: "ocamlfind install" with "-patch" option writes
+now correct META file for the case that subpackages occur
+
Adding environment variable OCAMLFIND_IGNORE_DUPS_IN
+to reduce the number of warnings ocamlfind emits
+
+
+
+
1.1.2: Bugfix in the META parser: Backslashes are now
+correctly parsed. (Thanks to Martin Jambon for finding this problem.)
+
Fixes for platforms that do not support dynamic loading of
+DLLs.
+
Fixed extraction of camlp4 parameters from packages.
+
+
+
+
1.1.1: Bugfixes only: Fixed detection of threading model
+for OCaml 3.09. Fixed alternate configuration files.
+
+
+
+
1.1: Automatic detection of standard compiler options.
+
+
Liberated the checks whether a package is already installed.
+
+
The .opt compilers are entered into findlib.conf if available.
+
+
New: "install" has -optional switch for optional files.
+
+
New: "install" has -patch-version to patch the version into
+the installed META file.
+
+
New: "install" has -patch-rmpkg to remove subpackages from
+the installed META file.
+
+
New: "install" has -patch-archives which removes non-existing
+files from "archive" variables. This is experimental.
+
+
New: subpackages can be disabled by exists_if.
+
+
New: Support for toolchains.
+
+
Fix for "remove": -destdir works again.
+
+
Fix for "call": CTRL-C works when calling interactive commands.
+
+
Fix for preprocessor packages: Dependencies on normal packages
+are resolved.
+
+
+
+
1.0.4: Fix: In previous versions, "ocamlmktop"
+set the "toploop" predicate. It turned out, however, that the toploops
+generated in this way did not work properly. For this reason,
+"ocamlmktop" does not set "toploop" any more for link time, but
+instead a new predicate "create_toploop". When the toploop is
+executed, the predicate "toploop" is again added.
+
+
+
1.0.3: Fix: The relative position of "-cclib -l"
+ options on the command line is preserved. In previous versions,
+these options were moved to the beginning of the argument list. This
+did not work for static link editing; dynamic link editing was not
+affected.
+
Fix: The automatic fixup of "threads" dependencies
+works again. In the previous version, this was broken.
+
Addition: -format '%(name)' for ocamlfind query.
+
Some minor improvements of the documentation.
+
+
+
1.0.2: Fix: The alternate package layout did
+not fully work. This is repaired now, and there are some clarifications
+about relative directory paths in the documentation.
+
+
+
1.0.1: Fix: Forgot to install some .cmi
+files
+
+
+
1.0: It is now possible to divide the
+description of a package into subpackages (but there is still only one
+META file, but with enhanced syntax). This allows it to describe
+intra-package dependencies.
+
+
Predicates in META files can be negated.
+
+
The "error" variable allows you to detect conditions under which
+the library would not work, and to generate error messages.
+
+
It is possible to refer to archive files installed in other
+packages.
+
+
The set of predicates is extended by "package predicates"
+after the dependency analysis, making conditions expressable that
+depend on whether other packages are selected.
+
+
The "+=" operator in META files adds words to variables rather
+than setting them.
+
+
The "#thread" directive enables multi-threading in toploops and
+scripts, if possible.
+
+
The "#predicates" directive simplifies the addition of predicates.
+
+
+
Queries: The format specifier %D prints the description of
+the package. -long-format includes the description. Short options
+-r, -l, -d.
+
+
ocamlfind list -describe prints package descriptions.
+
+
Support for "ocamlfind ocamldoc". However, the implementation is
+quite sloppy.
+
+
The configuration file is called "findlib.conf" by default,
+not "ocamlfind.conf".
+
+
Removal of "ocamlfind guess".
+
+
Support for #use "findlib" and #use "ocamlfind" has been
+removed. The only remaining way to load findlib is by #use "topfind".
+
+
There is no longer a thread-safe version of findlib. The user
+has to ensure that only one thread uses findlib (which is usually trivial
+to achieve).
+
+
ocamlmktop: Directories are no longer automatically added
+to the search path. This did not work anyway, and this change forces
+scripts to always invoke "#require" to load/enable libraries, for
+better uniformity.
+
+
Fixes: num-top works. "ocamlfind ocamlopt -thread" generates
+a better error message on non-POSIX systems. "ocamlfind query -descendants"
+takes predicates into account (it did not do that in previous versions of
+findlib).
+
+
+
0.9: Changes for OCaml 3.07 (-thread,
+ -vmthread). Includes Zack's toploop printers for bigints.
+
+
+
0.8 - 0.8.1: Renamed a lot of modules to avoid name
+ clashes with OCaml core modules. Cygwin: Additional option
+ -cygpath for "configure". The man pages have a NAME
+ section. Bugfix in Makefile wizard.
+
+
+
0.7 - 0.7.2: DLLs: There are now two styles of
+ installation: DLLs can be installed in the package
+ directories (like before), or in a shared directory
+ "stublibs". For the first style, there is now an option
+ "ldconf" that determines whether the ld.conf file is to be
+ updated, and if so, which file. The latter style is enabled
+ by simply creating a directory "stublibs" in the site-lib
+ directory. (In the first version the directory was called
+ "libexec". By user request, the name of the DLL directory
+ has been changed to "stublibs".)
+
+
"ocamlfind install" preserves now the mtime of the files.
+
+
"ocamlfind printconf" is more flexible, and easier to call
+ from scripts.
+
+
"ocamlfind browser" calls ocamlbrowser with the right -I
+ options.
+
+
"ocamlfind query": -descendants implies now -recursive.
+
+
"ocamlfind ocamldep": -native-filter and -bytecode-filter for more
+ exact dependency generation.
+
+
There may be now postinstall and postremove scripts.
+
+
"ocamlfind pkg/cmd": This syntax can be used to call the program cmd
+ that is installed in the package directory for pkg. Intended to
+ simplify the invocation of programs that are installed in package
+ directories and not in XXX/bin, which may be useful for package-
+ related tools.
+
+
Findlib has now a toolbox containing helpful programs besides
+ ocamlfind. For the beginning, there is a Makefile wizard that
+ can be called by "ocamlfind findlib/make_wizard".
+
+
#use "topfind" instead of #use "findlib" to avoid name clashes
+ in a certain configuration. #use "findlib" and #use "ocamlfind"
+ are still supported for backward compatibility if the name clash
+ does not occur.
+
+
Fix: bytecode threads work again. (The wrong unix library was
+ linked for recent OCaml versions.)
+
+
Many smaller improvements; the docs have been updated.
+
+
+
0.6 - 0.6.2: Minor changes for Ocaml-3.03-alpha
+ (and later for 3.04). New #list directive. New: #use
+ "findlib" loads the findlib directives into every toploop
+ (Ocaml-3.03-alpha).
+
+
The file ld.conf is automatically updated when DLLs are
+ installed or removed.
+
+
Fix: /tmp/findlib_initf* no longer overflows. The thread
+ library is now always the first linked library.
+
+
+
0.5 - 0.5.4: Findlib has now a configuration
+ file (see documentation under findlib.conf). Much more
+ environment variables. The location of the standard library is
+ now configurable at runtime.
+
+
+
The package search path can now be selected independently
+ of the package installation directory.
+
+
New commands: ocamlfind list, ocamlfind printconf, ocamlfind guess
+ (See documentation under ocamlfind)
+
+
Optional alternate directory layout: All META files go into
+ a separate directory (see documentation under site-lib).
+
+
Findlib works now only for OCaml 3; support for OCaml 2 has been
+ dropped. As a consequence, the "configure" script could be
+ simplified; it is no longer necessary to figure out the
+ linker options.
+
+
Improved support for camlp4: New directives #camlp4o and
+ #camlp4r for the toploop.
+
+
ocamlfind now detects whether two selected packages have
+ equally named toplevel modules, and prints a warning in this case.
+
+
There is a downstripped version ocamlfind-mini (see directory
+ "mini"). This is a one-file script that can be easily
+ distributed with any software. ocamlfind-mini has reduced
+ functionality, but it is sufficient to compile and install a
+ library. (But it does not support using a library.)
+
+
Support for the Cygwin port of OCaml.
+
+
Installation of packages: The file permissions are
+ preserved when files are installed. However, the umask is
+ applied. The "install" and "remove" subcommands have better
+ diagnostics.
+
+
ocamlfind ocamlmktop: Generates now initialization code for the
+ include path. You don't need to call your toploop with -I
+ options any more. Furthermore, this fixes some problems with
+ packages that add printers to the toploop.
+
+
New: ocamlfind ocamldep. ocamlfind is now prepared for the new
+ -pp option of ocamldep (upcoming Ocaml 3.03).
+
+
Installation of findlib: New PREFIX variable in Makefile to
+ install locally.
+
+
Fixes: itest. ocamlfind query -descendants works again.
+
+
+
0.4: Experimental support for camlp4 (see FAQ
+ section in the manual). New environment variable
+ OCAMLFIND_COMMANDS (see ocamlfind(1)).
+
+
+
+
0.3 - 0.3.1: Necessary updates for OCaml
+3. Bugfix: Findlib did not work for bytecode threads. The reason was
+that findlib added the directory of the stdlib to the search
+path. Works now.
+
Every package denotes in its META file only the list of direct
+ancestors. The theoretical model of the dependency relation is a
+directed acyclic graph (DAG), with the packages as vertices and edges
+from packages to their direct ancestors. The graph must be acyclic
+because OCaml does not allow cyclic dependencies between modules.
What happens if you query something like
ocamlfind query -recursive p1 p2 ... pN
is that the named packages p1 to pN are marked in the graph, and that
+repeatedly all direct ancestors of marked packages are marked, too,
+until there is not any marked package remaining with an unmarked
+ancestor. All marked packages are then printed in topological
+order. This simply means that for the printed packages p1 to pM holds
+that if pI is printed before pJ then pI is a (possibly indirect)
+ancestor of pJ.
The topological order plays a role when the link command is
+constructed by "ocamlfind ocamlc", as Ocaml requires that archives
+must be linked in topological order. For example, the link statement
ocamlfind ocamlc -o another -package q -linkpkg another.ml
must be turned into the effective command
ocamlc -o another [...more options...] p.cma q.cma another.ml
and not
ocamlc -o another [...more options...] q.cma p.cma another.ml
because there are references from q.cma to p.cma.
In C, there is a similar requirement when linking static archives. The
+linker backend ld wants the archives in reversed
+topological order, i.e. the deepest ancestor must come last in the
+list of linked archives. Because of this, the additional linker
+options specified in the "linkopts" variable are passed in reversed
+order to the underlying linker. This means that you can refer to C
+libraries of ancestor packages of p in C libraries provided in p.
Note that most operating systems do not require any specific order for
+dynamically linked C libraries (the exception is, surprise!, AIX).
\ No newline at end of file
diff --git a/local-packages/ocamlfind/doc/guide-html/c192.html b/local-packages/ocamlfind/doc/guide-html/c192.html
new file mode 100644
index 0000000..982a1b4
--- /dev/null
+++ b/local-packages/ocamlfind/doc/guide-html/c192.html
@@ -0,0 +1,300 @@
+
+A new frontend for ocamlc
There are compiler frontends for the four compilers ocamlc, ocamlopt,
+ocamlmktop, and ocamlcp. They are simply called by specifying the name
+of the compiler as first argument to ocamlfind, i.e.
In addition to the compiler options handled by the compilers
+themselves, the following options are available:
-package <name>: Causes that the package <name> is added to
+the package list, and that -I options are added for every package, and
+all direct or indirect ancestors.
-linkpkg: Causes that the archives of the packages in the package list
+and all their direct or indirect ancestors are added in topological
+order to the command line before the first file to compile or to
+link. Packages specified by -dontlink are not linked in, though.
+Furthermore, the linker options of these packages are added in
+reverse topological order at the end of the command line.
-predicates <predicate-list>: The named predicates are included
+in the list of predicates. Note that there are some predicates set by
+default, see below.
-dontlink <name>: Specifies that the package <name> and
+all its direct or indirect ancestors should not be linked in.
-passopt <opt>: The option <opt> is passed directly to the
+underlying compiler. This is especially needed to pass undocumented
+options to the compiler.
If you only want to compile, i.e. the -c option is in effect, you
+normally only need the -package option.
Depending on the compiler and on the given options, some predicates
+are set by default:
byte: The predicate "byte" is set when ocamlc, ocamlcp, or ocamlmktop
+is used to compile or link.
native: The predicate "native" is set when ocamlopt is used to compile
+or to link.
toploop: The predicate "toploop" is set when a toploop is being executed
create_toploop: The predicate "toploop" is set when ocamlmktop is used to
+compile or to link a toploop
gprof: The predicate "gprof" is set when ocamlopt with -p option is
+invoked.
mt: The predicate "mt" is set when the -thread or the -vmthread option is in effect.
mt_posix: The predicate "mt_posix" is set together with "mt" if the
+POSIX thread implementation is selected.
mt_vm: The predicate "mt_vm" is set together with "mt" if the bytecode
+thread implementation is selected.
autolink: The predicate "autolink" is set if the OCaml compiler can perform
+automatic linking. This predicate is never set if the -noautolink option is
+in effect.
\ No newline at end of file
diff --git a/local-packages/ocamlfind/doc/guide-html/c278.html b/local-packages/ocamlfind/doc/guide-html/c278.html
new file mode 100644
index 0000000..fc07768
--- /dev/null
+++ b/local-packages/ocamlfind/doc/guide-html/c278.html
@@ -0,0 +1,308 @@
+
+Complex packages
The names in the parantheses are called formal
+predicates and express a condition which must hold such
+that the value on the right side is selected. When querying
+information you can specify a set of actual
+predicates that are assumed to be true. There are the
+following standard predicates:
The "byte" predicate means that the bytecode compiler is used.
The "native" predicate means that the native compiler is used.
The "toploop" predicate means that the toploop is available in the
+linked program.
The "mt" predicate means that the program is multi-threaded.
The "mt_posix" predicate means that in the case "mt" is set, too, the
+POSIX libraries are used to implement threads.
The "mt_vm" predicate means that in the case "mt" is set, too, the
+VM-based libraries are used to implement threads.
The "gprof" predicate means that in the case "native" is set, too, the
+program is compiled for profiling
The "autolink" predicate indicates that ocamlc is able to perform
+automatic linking.
It is possible to have more predicates indicating different
+environments; just use them, it is not necessary to declare them
+anywhere.
The value which is selected for a variable depends on the set of
+assumed predicates. In order to get selected, all formal predicates
+must be included in the set of actual predicates; if still
+multiple values fulfill this condition, the value with the maximum
+number of formal predicates is used; and if still in doubt, the first
+of these in the META file is taken.
It is possible to negate a formal predicate: Just prepend a minus
+sign to it, e.g. var(p,-q). In this case, it is required that the
+negated predicates are false (not contained in the set of actual predicates).
For all variables that are evaluated after the dependency analysis,
+findlib adds the so-called package predicates to the set of actual
+predicates. For every selected package p the predicate pkg_p
+(with the fixed prefix "pkg_") is added. One application of this
+are compatibility checks: The special error variable
+is evaluated after dependency analysis, but before anything else
+is done. For example, to state that package p is incompatible with
+package q one can add to the META file of p:
+
+
error(pkg_q) = "Package p is incompatible with q"
+
+The value of error is printed as message in the
+case the condition is true.
\ No newline at end of file
diff --git a/local-packages/ocamlfind/doc/guide-html/c37.html b/local-packages/ocamlfind/doc/guide-html/c37.html
new file mode 100644
index 0000000..0212e14
--- /dev/null
+++ b/local-packages/ocamlfind/doc/guide-html/c37.html
@@ -0,0 +1,309 @@
+
+Libraries and Packages
Reusability is one of the keywords in software engineering
+today. It simply means to have source code that can be shared by
+several programs. Usually, modules are combined to libraries, and the
+library archive files can be linked into programs. As the idea might
+be simple, its practical implementation is complex because sharing of
+source code has an impact on all steps and phases in software
+production. This document only addresses the following administrative
+problems:
Storing the libraries in file hierarchies
Compiling and linking programs using such libraries
Managing dependencies between libraries
Objective Caml has a variety of language means to support
+reusability. Most important, polymorphic functions can be written
+which generalize the types of input arguments and the
+type of the result value. There are many examples in the core library
+such that I assume that the reader is familiar with this
+feature. Second, modules and functors must be mentioned which not only
+generalize types of values, but can even generalize structures,
+i.e. types with associated operations. Third, the class construct
+allows us to adopt the object-oriented techniques of abstraction such
+as inheritage and dynamic method lookup.
In the following, we are only analyzing the problem of making and
+using libraries from a purely software-technical point of view. This
+means, we ignore how to make functions polymorphic, and how to create
+functors and classes. Instead, we only look at how to invoke the
+OCaml compiler to create, manage, and use libraries. Especially, we
+are interested in the administration of systems of libraries that
+have dependencies.
One of the complex operations on such a system is the replacement of
+a library by a newer version. Because of the strict compatibility
+checks of OCaml, it is usually necessary to rebuild and reinstall
+all dependent libraries as well. With the help of findlib, one can
+find out which are the dependent libraries. (However, findlib does
+not provide a framework to rebuild them. For example, the GODI
+system includes such a framework.)
The library is also called a "package" when it is seen as a removeable
+and replaceable set of files. Findlib requires that there is a
+certain directory structure; it is not possible to install the files
+at arbitrary places (findlib does not even maintain a file list).
+For simplicity, every library is usually stored into its own
+directory, i.e. the library archive files and the interface files.
From the perspective of the compiler, the library is made
+accessible by adding the package directory to the search path
+of the compiler. By doing so, the modules of the library are
+added to the namespace universe, and thus can be opened by
+modules using them. This means that the approach "one package
+= one directory" can be naturally translated into language
+operations modifying the namespace scope.
When linking a program, it must be specified which link operation is
+necessary to use a certain library. Often, only a single archive file
+needs to be linked in, but sometimes additional archives or system
+libraries must be linked, too. Furthermore, the link operations
+often depends on certain conditions, e.g. whether a single- or
+multi-threaded program is being created.
The findlib library is my suggestion for a
+package manager suitable for Objective Caml. It is a library (stored
+as a package itself) which can answer the following questions:
If I want to use a package, which is the directory containing
+the compiled interfaces and implementations? - The package directory
+may vary from system to system, and this feature makes it easier to
+write Makefiles that run everywhere. Furthermore, OCaml can load
+modules dynamically, and it is not a good practice to compile in the
+location of such modules. The better way is to ask findlib where the
+module resides today.
Which other packages must be linked in, too, if I want to use a
+certain package?
Which archives need to be linked in, and which compiler options
+are necessary?
If there is a version of the archive with additional properties,
+which file should I use? - Additional properties are at least:
+Thread-safety, using POSIX threads, and being gprof-enabled. It is
+simple to add more criterions.
Furthermore, there is a frontend for this library called
+ocamlfind. It is a command-line interface for the
+library, but has also some additional abilities:
It can invoke ocamlc, ocamlopt, ocamlmktop, and ocamlcp such
+that compiler arguments necessary to use a package or link it in are
+automatically added.
It can install and uninstall packages.
It can find out dependent packages.
As you'll see in the following chapters, the usage of this library is
+really simple. If you want only to link in packages written by other
+people, you must only change the command that invokes the compiler,
+e.g. instead of calling "ocamlc program.ml" invoke "ocamlfind ocamlc
+-package name_of_package_to_use -linkpkg program.ml", and you can
+refer to the named package within program.ml. If you want to turn your
+collection of modules into a package, you need only to write one
+adminstrative file (META) containing all extra information such as
+required other packages.
\ No newline at end of file
diff --git a/local-packages/ocamlfind/doc/guide-html/c395.html b/local-packages/ocamlfind/doc/guide-html/c395.html
new file mode 100644
index 0000000..9d679e5
--- /dev/null
+++ b/local-packages/ocamlfind/doc/guide-html/c395.html
@@ -0,0 +1,204 @@
+
+How to create your own packages
The ocamlfind command can install and remove packages. For example,
+to install a package p containing the files META, m1.cmi, m2.cmi, p.cma,
+run
+
+
ocamlfind install p META m1.cmi m2.cmi p.cma
+
+This installs the files into the default location for new packages
+(set in ocamlfind.conf). If you have files that are not always built,
+add these after the -optional switch:
+
+
ocamlfind install p META m1.cmi m2.cmi p.cma -optional p.cmxa p.cmxs
+
+To remove the package, run
+
+
ocamlfind remove p
+
+Note that every package must have a META file, it is not possible to
+omit it.
\ No newline at end of file
diff --git a/local-packages/ocamlfind/doc/guide-html/c429.html b/local-packages/ocamlfind/doc/guide-html/c429.html
new file mode 100644
index 0000000..df63bf6
--- /dev/null
+++ b/local-packages/ocamlfind/doc/guide-html/c429.html
@@ -0,0 +1,250 @@
+
+FAQs
The new archive format introduced with OCaml 3 can store the linker options
+that are necessary to link an archive. For example:
+
+
ocamlc -a -o myarchive.cma mymodule.cmo -cclib -lmylibrary
+
+This command does not only create the new archive
+myarchive.cma, but it also writes into a special section of
+that file that the linker option -cclib -lmylibrary is
+necessary to link this archive.
This means for findlib that most of the "linkopts" attributes in META files
+have become superflous: The compiler itself already knows the linker options,
+we do not need to tell the compiler the options. We could simply leave all
+"linkopts" attributes out.
Of course, the "linkopts" feature of findlib still works. This is necessary
+because findlib should keep the compatibility with older software, and because
+"linkopts" is more powerful (you can have conditional linker options).
If you have software that must run in both OCaml 2 and OCaml 3 environments,
+you can make your "linkopts" attribute dependent on the "autolink"
+predicate. For example:
+
+
+
+The findlib installation for OCaml 3 will take the second line which is
+reasonable because ocamlc already knows how to link; the installation for
+OCaml 2 never sets the "autolink" predicate and therefore uses the first line.
Why does findlib not automatically include the -custom option if
+linked with C code?
\ No newline at end of file
diff --git a/local-packages/ocamlfind/doc/guide-html/c74.html b/local-packages/ocamlfind/doc/guide-html/c74.html
new file mode 100644
index 0000000..c672d81
--- /dev/null
+++ b/local-packages/ocamlfind/doc/guide-html/c74.html
@@ -0,0 +1,211 @@
+
+Using packages
\ No newline at end of file
diff --git a/local-packages/ocamlfind/doc/guide-html/index.html b/local-packages/ocamlfind/doc/guide-html/index.html
new file mode 100644
index 0000000..0843076
--- /dev/null
+++ b/local-packages/ocamlfind/doc/guide-html/index.html
@@ -0,0 +1,430 @@
+
+The findlib User's Guide
The "findlib" library provides a scheme to manage reusable software
+components (packages), and includes tools that support this
+scheme. Packages are collections of OCaml modules for which
+metainformation can be stored. The packages are kept in the filesystem
+hierarchy, but with strict directory structure. The library contains
+functions to look the directory up that stores a package, to query
+metainformation about a package, and to retrieve dependency
+information about multiple packages. There is also a tool that allows
+the user to enter queries on the command-line. In order to simplify
+compilation and linkage, there are new frontends of the various OCaml
+compilers that can directly deal with packages.
Together with the packages metainformation is stored. This includes a
+version string, the archives the package consists of, and additional
+linker options. Packages can also be dependent on other
+packages. There is a query which finds out all predecessors of a list
+of packages and sorts them topologically. The new compiler frontends
+do this implicitly.
Metainformation can be conditional, i.e. depend on a set of
+predicates. This is mainly used to be able to react on certain
+properties of the environment, such as if the bytecode or the native
+compiler is invoked, if the application is multi-threaded, and a few
+more. If the new compiler frontends are used, most predicates are
+found out automatically.
There is special support for scripts. A new directive, "#require",
+loads packages into scripts.
Download findlib. This manual describes version 1.5 of the software
+package. It can be downloaded at
+http://download.camlcity.org/download. The user's guide and the reference manual are included.
+Newest releases of "findlib" will be announced in
+The OCaml Link
+Database.
Quickstart. See also the Quickstart page
+for instructions for the most common
+cases.
License
This document, and the described software, "findlib", are copyright by
+Gerd Stolpmann.
Permission is hereby granted, free of charge, to any person obtaining
+a copy of this document and the "findlib" software (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
The Software is provided ``as is'', without warranty of any kind, express
+or implied, including but not limited to the warranties of
+merchantability, fitness for a particular purpose and noninfringement.
+In no event shall Gerd Stolpmann be liable for any claim, damages or
+other liability, whether in an action of contract, tort or otherwise,
+arising from, out of or in connection with the Software or the use or
+other dealings in the software.
\ No newline at end of file
diff --git a/local-packages/ocamlfind/doc/guide-html/p35.html b/local-packages/ocamlfind/doc/guide-html/p35.html
new file mode 100644
index 0000000..93ab443
--- /dev/null
+++ b/local-packages/ocamlfind/doc/guide-html/p35.html
@@ -0,0 +1,184 @@
+
+User's Guide
\ No newline at end of file
diff --git a/local-packages/ocamlfind/doc/guide-html/quickstart.html b/local-packages/ocamlfind/doc/guide-html/quickstart.html
new file mode 100644
index 0000000..10d3656
--- /dev/null
+++ b/local-packages/ocamlfind/doc/guide-html/quickstart.html
@@ -0,0 +1,278 @@
+
+
+QUICKSTART - The most important ways to use findlib
+
+
QUICKSTART - The most important ways to use findlib
+
+Intro
+
+See the file INSTALL for instructions how to build and install
+findlib.
+
+Findlib and the toploop
+
+For a number of platforms, OCaml can load bytecode-compiled
+libraries dynamically. For these platforms, findlib is very simple to
+use as explained in the following. For other platforms, see the paragraph
+below about "custom toploops".
+
+After the toploop has been started, it is possible to load the special
+findlib support:[1]
+
+
+$ ocaml
+ Objective Caml version 3.07
+
+# #use "topfind";;
+Findlib has been successfully loaded. Additional directives:
+ #require "package";; to load a package
+ #list;; to list the available packages
+ #camlp4o;; to load camlp4 (standard syntax)
+ #camlp4r;; to load camlp4 (revised syntax)
+ #predicates "p,q,...";; to set these predicates
+ Topfind.reset();; to force that packages will be reloaded
+ #thread;; to enable threads
+
+- : unit = ()
+
+
+You can now list the available packages:
+
+
+# #list;;
+bigarray (version: [distributed with Ocaml])
+camlp4 (version: Camlp4 version 3.03 ALPHA)
+dbm (version: [distributed with Ocaml])
+dynlink (version: [distributed with Ocaml])
+findlib (version: 0.6)
+graphics (version: [distributed with Ocaml])
+labltk (version: [distributed with Ocaml])
+netstring (version: 0.10)
+num (version: [distributed with Ocaml])
+stdlib (version: [distributed with Ocaml])
+str (version: [distributed with Ocaml])
+threads (version: [distributed with Ocaml])
+unix (version: [distributed with Ocaml])
+xstrp4 (version: 1.1)
+
+
+Findlib takes care to load packages that are required by loaded packages
+first. For example, "netstring" uses "unix" and "str" internally, but you
+do not need to load them because findlib does it for you. In this example
+you can also see that findlib loads netstring_top.cmo containing printers
+for the toploop.
+
+You can also enable the Camlp4 parsers by simply typing
+
+
+
+for the revised syntax. (But you cannot switch between the syntaxes.)
+
+
+Custom Toploops
+
+For some platforms, OCaml does not implement loading external
+libraries (e.g. Cygwin). One has to create a so-called custom toploop
+that statically links with these libraries. Example:
+
+
+$ ocamlfind ocamlmktop -o mytop -package findlib,unix -linkpkg
+$ ./mytop
+ Objective Caml version 3.07
+
+# #use "topfind";;
+Findlib has been successfully loaded. Additional directives:
+ #require "package";; to load a package
+ #list;; to list the available packages
+ #camlp4o;; to load camlp4 (standard syntax)
+ #camlp4r;; to load camlp4 (revised syntax)
+ #predicates "p,q,...";; to set these predicates
+ Topfind.reset();; to force that packages will be reloaded
+ #thread;; to enable threads
+
+- : unit = ()
+
+
+Now "#require" works for all libraries referring to the special "unix"
+functions.
+
+
+Findlib and scripts
+
+The #require directive can also be used in scripts. Example:
+
+
+
+This switch causes that the mentioned packages are added to the resulting
+executable.
+
+If you want to include several packages, you can either add several
+"-package" options, or you can enumerate the packages separated by commas:
+-package netstring,labltk.
+
+Camlp4
+
+If you add a -syntax option, the compiler will be told to parse the
+source file using camlp4:
+
+
+Since findlib-0.7, it is also possible to start ocamlbrowser from
+ocamlfind. For example,
+
+
+$ ocamlfind browser -package xstrp4
+
+
+adds the correct path specification such that the modules contained in the
+package xstrp4 are also displayed. With
+
+
+$ ocamlfind browser -all
+
+
+all package are added to the path spec.
+
+
+The Makefile wizard
+
+There is a wizard that makes it very easy to write Makefiles. Call the
+wizard by
+
+$ ocamlfind findlib/make_wizard
+
+(the wizard requires that the labltk library is available). A new window
+pops up, and by very few clicks you can describe your own library. Finally,
+a Makefile is written.
+
+
+There is no magic!
+
+Findlib is neither a patch of OCaml nor uses it internal features of
+the OCaml programming environment. It is only a convention to install
+software components in filesystem hierarchies, a library interpreting
+this convention, and some frontend applications making the library useable for
+you.
+
+One important consequence is that you can only refer to those
+software components that have previously been installed in a way findlib
+understands. This convention is beyond the scope of this QUICKSTART guide,
+see the reference manual for details. You can always check whether findlib
+accepts a component as "findlib package" by the command
+
+
+$ ocamlfind list
+
+
+(this is the same as the #list directive in the toploop). If the package
+occurs in the list, it is found, otherwise not.
+
+
In previous versions, #use "findlib" loaded the
+library. However, this caused a name conflict for a certain type of
+installation. Because of this, the name of the loader script has been changed
+to "topfind", but "findlib", and "ocamlfind" (Debian) are also available
+for backwards compatibility.
+
diff --git a/local-packages/ocamlfind/doc/guide-html/x108.html b/local-packages/ocamlfind/doc/guide-html/x108.html
new file mode 100644
index 0000000..81fdd1a
--- /dev/null
+++ b/local-packages/ocamlfind/doc/guide-html/x108.html
@@ -0,0 +1,178 @@
+
+Querying information stored in META files
By setting some options of ocamlfind you can query the variables from
+the META files. For example, -long-format (or short -l) selects all
+interesting variables:
The values of the "archive" variable are missing because no predicate
+has been set, without further options "ocamlfind query" operates with
+an empty set of predicates. To get the bytecode archive, run:
ocamlfind query -long-format -predicates byte p
You can set more than one predicate. It usually does not make sense, but
+you could for example select both bytecode and native archives by:
ocamlfind query -long-format -predicates byte,native p
As both settings for "archive" are now equally like, the extraction
+mechnism chooses simply the first. The general rule is that the first
+most special value is selected.
How to compile and link a program that uses a package
\ No newline at end of file
diff --git a/local-packages/ocamlfind/doc/guide-html/x119.html b/local-packages/ocamlfind/doc/guide-html/x119.html
new file mode 100644
index 0000000..c655269
--- /dev/null
+++ b/local-packages/ocamlfind/doc/guide-html/x119.html
@@ -0,0 +1,255 @@
+
+How to compile and link a program that uses a package
Now suppose you want to compile a program which calls functions of
+your new package p. If prog1.ml, prog2.ml, and prog3.ml are the three
+source files the program consists of, compile them with the commands
ocamlfind ocamlc -package p -c prog1.ml
+ocamlfind ocamlc -package p -c prog2.ml
+ocamlfind ocamlc -package p -c prog3.ml
The "ocamlfind ocamlc" invocation is a frontend to "ocamlc". Most
+arguments are directly passed to "ocamlc", but there are a few new
+options, and often some new options are implicitly added. Here, the
+new -package option is used, which adds search paths such that the
+modules of package p are found. Effectively, the following direct
+ocamlc invocations would be equivalent
+[1]:
The -I option has the effect that the named directory is also searched
+when looking up cmi files. Because of this you can refer directly to
+the modules M1 and M2 in the program sources.
In order to link the program use the following command:
ocamlfind ocamlc -o program -package p -linkpkg prog1.cmo prog2.cmo prog3.cmo
The -linkpkg option causes some more arguments to be added to the
+constructed ocamlc command. Especially, the name of the archive of p
+is extracted from the META file, and automatically inserted before the
+prog1.cmo argument. The resulting command looks like[2]:
ocamlc -o program -I /usr/local/lib/ocaml/site-lib/p p.cma prog1.cmo prog2.cmo prog3.cmo
Please note that the bytecode archive p.cma has been selected, and not
+the native archive p.cmxa. As it is known that the bytecode compiler
+is used, the predicate "byte" is automatically set.
If you specify the -verbose option, the constructed
+command is printed to the terminal. Actually, there are some more
+implicitly added options, especially -ccopt -I<dir> for every
+package directory <dir>. This means that you can compile C
+programs accessing header files stored in the package directory.
\ No newline at end of file
diff --git a/local-packages/ocamlfind/doc/guide-html/x135.html b/local-packages/ocamlfind/doc/guide-html/x135.html
new file mode 100644
index 0000000..de8a756
--- /dev/null
+++ b/local-packages/ocamlfind/doc/guide-html/x135.html
@@ -0,0 +1,213 @@
+
+Dependencies
Often packages use other packages themselves. Let q be another package
+consisting of the single module M3 which contains references to M1 and
+M2. At the first glance, we can ignore this when describing the
+package, as we could always add "-package p" and "-package q" options
+when compiling programs using q. This solution is not optimal, as the
+user of a package must have knowlege about details of the package that
+should normally be hidden. When we introduced the notion of packages,
+one of the most important properties was that we can replace packages
+by improved versions. Imagine that q is replaced by q', but q' uses
+not only p but also r. Every program that used q and is now forced to
+use q' must be changed (at least in the Makefile) in order to link r,
+too. This is clearly not what is intended by packages.
The far better solution is to store dependency information in the META
+files. The "requires" variable can list names of packages that are
+direct ancestors, i.e. referred directly. (Do not put indirect
+ancestors into this variable, for example further packages required by
+r when describing q - these are found out automatically.) The META
+file of q looks like:
If you want to put several package names into "requires", separate
+them with commas or spaces.
The "ocamlfind query" command ignores the "requires" value by default,
+you must add the -recursive option. In this case, all direct or
+indirect ancestors of the packages given on the command line are
+selected, too, and printed in topological order. For example, the
+command
package: p
+description: Our super-duper package
+version: 1
+archive(s): p.cma
+linkopts:
+location: /usr/local/lib/ocaml/site-lib/p
+
+package: q
+description: Something that needs p
+version: 1
+archive(s): q.cma
+linkopts:
+location: /usr/local/lib/ocaml/site-lib/p
Without -recursive, only q would have been printed.
The compiler frontend provided with ocamlfind always works
+recursively. In order to compile and link another.ml that uses q, the
+following command is sufficient:
ocamlfind ocamlc -o another -package q -linkpkg another.ml
It is not necessary to specify -package p in this statement as the
+dependency relation is always used to find out the actually meant
+set of packages.
\ No newline at end of file
diff --git a/local-packages/ocamlfind/doc/guide-html/x149.html b/local-packages/ocamlfind/doc/guide-html/x149.html
new file mode 100644
index 0000000..fb4dcd0
--- /dev/null
+++ b/local-packages/ocamlfind/doc/guide-html/x149.html
@@ -0,0 +1,200 @@
+
+Linker options
Beginning with OCaml 3.00, the compiler itself has an interesting feature
+called "automatic linking" that makes the following mechanism superflous in
+most cases. Automatic linking means that it is possible to store the linker
+options into the cma or cmxa file such that the compiler itself knows which
+options are necessary. Of course, the following mechanism still works, and it
+is still helpful when conditional linking is required.
OCaml has a C interface which means that C libraries can be linked in
+and C functions can be declared as new language primitives. Using such
+libraries requires special linker options. Some of the core libraries
+distributed with OCaml are partly implemented in C and thus additional
+libraries must be specified in the linking phase of the program.
For example, the "str" library providing regular expressions requires
+to be linked as follows:
The -cclib option passes the following argument directly to the
+underlying C linker which has the effect that libstr.a is linked in,
+too. The "-cclib -lstr" is directly associated with str.cma as the
+latter simply cannot be used without the former. Assume you would
+write a META file describing str. That "str.cma" should be linked in
+as archive is clear; the "-cclib -lstr" can be specified in another
+variable called "linkopts". The META file would look like:
This has the effect that specifying -linkpkg in one of the compiler
+frontends not only chooses one of the archive files, but also extracts
+the necessary linker options from the META file. The above example can
+also be compiled with:
Most people will never write META files with "linkopts" settings. But
+this feature is very useful at least for the core libraries such as
+str. Because of this, the "findlib" distribution comes with META files
+for the core libraries in order to hide the linker options. This
+means that you can already use the packages "str", "dbm", "dynlink",
+"graphics", "num", "threads", "unix", and "camltk", and that the
+appropriate archives and linker options are automatically extracted.
\ No newline at end of file
diff --git a/local-packages/ocamlfind/doc/guide-html/x180.html b/local-packages/ocamlfind/doc/guide-html/x180.html
new file mode 100644
index 0000000..24670f6
--- /dev/null
+++ b/local-packages/ocamlfind/doc/guide-html/x180.html
@@ -0,0 +1,184 @@
+
+Querying descendants
It is often useful to find out the descendants of a package, i.e. all
+direct or indirect users of the package. There is another "ocamlfind"
+subcommand that allows us to query descendants. For example, to get
+the direct and indirect users of p, type in
ocamlfind query -descendants p
The set of packages that are possible descendants is determined as
+follows:
+
+
All packages located in directories mentioned in the environment
+variable OCAMLPATH are candidates. Note that only package directories
+containing META files are taken.
The packages in the default package directory are candidates, too.
If there are two packages with the same name, only the first
+counts, i.e. the first in OCAMLPATH, then the one in the default directory.
+
+After this set has been determined, the complete dependency graph is
+constructed on it. As the descendants are queried, the dependencies
+are read in the inverse way compared with queries of the ancestors.
\ No newline at end of file
diff --git a/local-packages/ocamlfind/doc/guide-html/x231.html b/local-packages/ocamlfind/doc/guide-html/x231.html
new file mode 100644
index 0000000..fff0942
--- /dev/null
+++ b/local-packages/ocamlfind/doc/guide-html/x231.html
@@ -0,0 +1,302 @@
+
+Toploops and runtime systems
Recent versions of OCaml support dynamic loading of stub libraries
+(but only for the more widely used operating systems). This means
+that one can start a toploop by running
+
+
$ ocaml
+ Objective Caml version 3.07+2
+
+# _
+
+and that it is now possible to load .cma archive files referring to
+shared C libraries ("DLLs"). In older versions of OCaml this was
+not possible and one had to create a so-called custom toploop
+with the ocamlmktop command. This method is still supported and
+explained below; however, nowadays it is often not necessary to
+do so. For the modern way, findlib includes a small script called
+"topfind" (i.e. "ocamlfind for the toploop") that can be directly
+loaded into the toploop:
+
+
# #use "topfind";;
+- : unit = ()
+Findlib has been successfully loaded. Additional directives:
+ #require "package";; to load a package
+ #list;; to list the available packages
+ #camlp4o;; to load camlp4 (standard syntax)
+ #camlp4r;; to load camlp4 (revised syntax)
+ #predicates "p,q,...";; to set these predicates
+ Topfind.reset();; to force that packages will be reloaded
+ #thread;; to enable threads
+
+- : unit = ()
+# _
A number of additional directives are now available. The "#require"
+directive loads additional packages (with all dependencies):
# #require "q1,q2,...,qM";;
"#require" loads the listed packages and all their ancestors in the
+right order, but leaves packages out that have already been loaded.
+Scripts can now simply load and document which packages are used by a
+"#require" directive right at the beginning of the script.
The #list directive lists the available packages as "ocamlfind list"
+would do it.
If you need additional predicates, you can set them with #predicates.
+Note that this should be done before the first package is loaded in
+order to ensure a consistent library system.
The #thread directive enables multi-threading if possible. Note that
+this is only supported for installations basing on the POSIX thread
+library. (However, if you have only have VM threads, you can still
+create a custom toploop supporting threads. See below.) Furthermore,
+the #thread directive should be executed before any packages are
+loaded.
The #camlp4o and #camlp4r directives load the camlp4 syntax parsers
+for the standard and the revised syntax, respectively.
Especially when developing packages, it is sometimes necessary to
+reload all dynamically loaded packages in the toploop. This can be
+forced by
Topfind.reset();;
which causes the "#require" directive to load all packages again. The
+Topfind module implements all the mentioned directives.
It is very simple to create toploops. In order to make a toploop
+executable that includes directly the packages p1,p2,..,pN simply
+execute the command
(Maybe you have to add the -custom switch.) Note that one of the
+packages should be "findlib" itself, because this adds the
+additional directives mentioned above, i.e. you can directly use
+these directives without #use "topfind" (but running "topfind"
+is harmless).
Note that such a toploop includes the code of the packages given
+on the commmand line, but that it does not automatically add the
+package directories to the search path (in previous versions of
+findlib this was tried, but it never really worked). To do so,
+you still have to #require the packages.
In order to create a toploop supporting VM-style threads, use the
+command
+
+
it would be tried to link the archives from the packages again into
+the bytecode binary. Because of this, it is necessary to suppress
+linking in packages of the runtime system when linking binaries for a
+runtime system. The -dontlink option can be used for this:
Note that the -package option can enumerate more packages than
+-dontlink, and in this case the additional packages are actually
+linked in as they are not contained in the runtime system.
\ No newline at end of file
diff --git a/local-packages/ocamlfind/doc/guide-html/x265.html b/local-packages/ocamlfind/doc/guide-html/x265.html
new file mode 100644
index 0000000..01b294b
--- /dev/null
+++ b/local-packages/ocamlfind/doc/guide-html/x265.html
@@ -0,0 +1,182 @@
+
+Multi-threaded applications
If an already existing package is planned to be used in a
+multi-threaded environment, some language constructs must be replaced
+by different ones. For example, global variables must be protected by
+locks (mutexes). Because of
+this it is common practice to provide two versions of such packages,
+one for single-, one for multi-threaded applications (or, another
+technique, there is a special add-on module that initializes a
+library for multi-threaded usage).
The predicate "mt" should be used to recognize multi-threaded
+applications. For example, a package could consist of two archives,
+p.cma, and p_mt.cma, where the latter archive is designed for
+multi-threaded execution. The META file would contain the following
+lines causing that always the appropriate archive is linked:
When querying the package database the option "-predicates mt" must be
+included in the commands in order to select the appropriate entries.
When compiling or linking it is necessary to specify either the
+"-thread" or the "-vmthread" option anyway. The compiler frontends
+detects these options, and automatically set the "mt"
+predicate. The following command is an example for this; note that the
+"threads" package means the standard library of Ocaml providing thread
+support:
For some operating systems, Ocaml supports the native multithreading
+libraries conforming to the POSIX interface. As the linker options are
+generally different, another predicate must be set to get these
+libraries linked in. The predicate "mt_posix" indicates POSIX
+threads while "mt_vm" indicates bytecode (virtual machine) threads.
\ No newline at end of file
diff --git a/local-packages/ocamlfind/doc/guide-html/x274.html b/local-packages/ocamlfind/doc/guide-html/x274.html
new file mode 100644
index 0000000..9111256
--- /dev/null
+++ b/local-packages/ocamlfind/doc/guide-html/x274.html
@@ -0,0 +1,152 @@
+
+Support for gprof-enabled modules
When a program is compiled and linked with ocamlopt, gprof-style
+profiling can be enabled by selecting the -p option. This means that
+the resulting archives are different, and that it would be useful if
+there were another predicate in order to select such archives.
The predicate "gprof" can be used for this. It is automatically set if
+the -p option turns on the gprof-mode in an ocamlopt invocation.
\ No newline at end of file
diff --git a/local-packages/ocamlfind/doc/guide-html/x311.html b/local-packages/ocamlfind/doc/guide-html/x311.html
new file mode 100644
index 0000000..66713f0
--- /dev/null
+++ b/local-packages/ocamlfind/doc/guide-html/x311.html
@@ -0,0 +1,210 @@
+
+Defining additional predicates
Additional predicates can be simply used without any declaration,
+i.e. you can freely invent new predicates. One application of them
+is to express conditional linkage. For example, one may provide archives
+for various conditions, such as a production archive, and a
+development archive. A single new predicate, "development", would be
+sufficient to express this:
When linking, include a "-predicates development" argument in the
+compiler command to select the development archive, otherwise the
+production archive is taken.
Predicates could also be used to select among several implementations
+of the same module. Define simply one predicate per implementation,
+e.g. "p_impl1", "p_impl2", and "p_impl3", and specify the archives for
+every implementation separately:
Sometimes, the implementations require different linker options. In
+this case, define several versions of the "linkopts" variable just
+like in the "requires" example.
Note that predicates are global identifiers that can be potentially
+applied to every selected package. In the case that a predicate is
+only meaningful for a single package, it is common practice to
+choose the package name as prefix of the predicate name (e.g.
+"netstring_minimum" is a predicate usually only applied to the "netstring"
+package).
Predicates could be used to select which features of a library are
+linked. For example,
+
+
+
+would add the p_ext.cma archive only if the p_extension predicate
+were set. It is considered as bad practice to select
+extensions of libraries by predicates. Findlib provides the construct
+of subpackages for this purpose.
\ No newline at end of file
diff --git a/local-packages/ocamlfind/doc/guide-html/x326.html b/local-packages/ocamlfind/doc/guide-html/x326.html
new file mode 100644
index 0000000..2294b27
--- /dev/null
+++ b/local-packages/ocamlfind/doc/guide-html/x326.html
@@ -0,0 +1,208 @@
+
+Appending to variables
+
+(note the "+=" operator) can be used to append values to variables
+depending on whether predicates are true. The "+=" lines in the META
+file are evaluated one after the other, and every
+line is selected for which the formal predicates are satisfied,
+and these lines are added to the current value of the variable. This is
+different from the "=" operator where only the most specific
+assignment is taken.
The values are considered as space-separated words when they
+are appended, i.e. the new words are added to the list of current
+words.
For example, in the hypothetic META file
+
+
var(p) += "a"
+var(p,q) += "b"
+
+the value of var is "a b" if both p and q are true, and the value is
+only "a" is only p is true (and the value is empty otherwise). If
+the operator "=" had been used, the value would have been only "b"
+when both p and q are true.
In the case that there both "=" and "+=" settings for
+the same variable, a special algorithm is used: First the most specific
+"=" setting is determined, and second all matching "+=" settings are
+appended in the order they appear in the file.
Finally, here is a real-world example. Imagine you have an
+archive p.cma and a special extension for the toploop, p_top.cma.
+Furthermore, there is a special debugging version p_dev.cma that
+replaces p.cma during development. You can now simply write
+
+
\ No newline at end of file
diff --git a/local-packages/ocamlfind/doc/guide-html/x338.html b/local-packages/ocamlfind/doc/guide-html/x338.html
new file mode 100644
index 0000000..34cd860
--- /dev/null
+++ b/local-packages/ocamlfind/doc/guide-html/x338.html
@@ -0,0 +1,199 @@
+
+Subpackages
Sometimes a package consists of several archive files that are closely
+related. It is now possible to express dependencies between these
+archives by splitting the package into several parts called subpackages.
+For example, package p consists of a base archive p_base.cma, and two
+extensions p_ext1.cma and p_ext2.cma that both require the base archive
+but are independent of each other. This META file expresses this
+dependency directly:
+
+
+
+If installed as package "p", this definition actually defines four
+logical packages: "p" (the main package), "p.base", "p.ext1", and
+"p.ext2" (the subpackages). These four entities only share the META
+file in which they are declared, and the directory where the archive
+files are stored, but all other properties can be individually set
+for each package. This also means that all package dependencies
+must explicitly added by "requires" variables, as there are no
+implied dependencies. In this example, the main package and "p.ext1"
+and "p.ext2" are all dependent on "p.base".
The users of this installation can refer to all four packages. This
+means that
+
+
ocamlfind ocamlc -package p -linkpkg ...
+
+links only p_base.cma into the final program, while
+
+
\ No newline at end of file
diff --git a/local-packages/ocamlfind/doc/guide-html/x345.html b/local-packages/ocamlfind/doc/guide-html/x345.html
new file mode 100644
index 0000000..845402c
--- /dev/null
+++ b/local-packages/ocamlfind/doc/guide-html/x345.html
@@ -0,0 +1,191 @@
+
+Glue code
Imagine we have two packages p and q that are normally
+independent, i.e. one can link p without q, and q without p. However,
+when both p and q are used in the same program, it is expected that
+they cooperate with each other. Of course, this situation can be
+modeled with the help of subpackages (a real-world example of this are
+p=lablgtk and q=lablgl).
The idea is as follows: p has a subpackage p.for_q that contains
+code with special features for q, and q has a subpackage q.use_p that
+depends on p, p.for_q, and q, and that contains the code using the
+special features of p. Expressed in META files, p would define
+
+
+
+Of couse, the program using both libraries must explicitly enable
+the subpackages by mentioning "q.use_p" on the ocamlfind command line,
+otherwise the glue code would be omitted.
Unfortunately, it is not possible to use the package predicates
+pkg_p and pkg_q to add archives depending on whether the other
+package is also selected. The problem is that the order cannot
+be specified, i.e. whether p must be linked first or q.
\ No newline at end of file
diff --git a/local-packages/ocamlfind/doc/guide-html/x352.html b/local-packages/ocamlfind/doc/guide-html/x352.html
new file mode 100644
index 0000000..8a3f912
--- /dev/null
+++ b/local-packages/ocamlfind/doc/guide-html/x352.html
@@ -0,0 +1,295 @@
+
+Plugins
Plugins are packages that can be loaded at runtime. Plugins are
+intended as a mechanism for loading add-on code into
+executables. Technically, there is some overlap with the concept of a
+"shared library". Note, however, that there is no universal support
+for plugins, as it is unimplemented on some platforms, and only
+poorly on some others (including x86 in the 32 bit case). Also, there
+must always be an explicit "load" statement in the loading executable.
+You cannot link an executable directly against plugins.
Plugins can be, of course, be dependent on other
+plugins. You run into a problem, though, when you make a plugin dependent
+on a package that doesn't qualify as plugin (i.e. lacks the "plugin"
+definition). In this case, the loader simply skips the dependency,
+and you cannot load the plugin.
Because of this dependency issue, it is recommended to add the
+"plugin" variable to all packages that are installed on a system,
+because this does not only allow it to load all packages at runtime, but
+also to use these packages as dependency of the actual plugin code.
That said, you just need to add a "requires" directive, e.g.
+
+
Linking an executable that can load a plugin: An executable
+must link the package "findlib.dynload". This does not only add
+the loader, but also special initialization code to the executable:
ocamlfind ocamlopt -o program -package findlib.dynload -linkpkg ...
In particular, this records the packages that are already included
+into the executable (in-core packages). If a plugin is now dependent
+on such a package, this is recognized, and the package is not loaded
+(which would not work anyway).
Now, you can load a plugin "foo" with:
Fl_dynload.load_packages ["foo"]
This loads the cma or cmxs files, and runs the initialization code
+of all top-level definitions of the included modules.
Of course, you can also call load_packages from
+a library if "findlib.dynload" is a required package of the library
+package.
Sometimes it is handy to create plugins that already include all
+the required packages. The plugin acts more like a dynamically loadable
+executable that already includes whatever it needs. You can create such
+a "fat" plugin with:
+
+
+
+In this case, the "requires" line in the META file should remain empty.
Note, however, that you cannot handle packages this way that are already
+linked into the main program, because it is invalid to load a module that
+is already part of the main executable. Let's assume that the executable
+links in q1, q2, and q3. Then, you need to exclude these packages from the
+plugin. The -dont-link option comes handy in this case:
+
+
+
+This excludes q1,q2,q3 even if these packages occur as dependencies of
+p1,p2,p3. In this case, though, you need to put q1,q2,q3 into the "requires"
+field of META.
\ No newline at end of file
diff --git a/local-packages/ocamlfind/doc/guide-html/x388.html b/local-packages/ocamlfind/doc/guide-html/x388.html
new file mode 100644
index 0000000..47a06bf
--- /dev/null
+++ b/local-packages/ocamlfind/doc/guide-html/x388.html
@@ -0,0 +1,172 @@
+
+Lint
As it has become more and more complicated to write correct META files
+there is now some support for recognizing typical problems. Just use
+
+
ocamlfind lint META
+
+to check the file META in the current directory. The tool reports problematic
+lines in META, e.g.
+
+
archive(byte,plugin) = "oUnit.cma"
+This specification of dynamic loading is deprecated, you should add a "plugin(...)" variable.
+
+archive(native,plugin) = "oUnit.cmxs"
+This specification of dynamic loading is deprecated, you should add a "plugin(...)" variable.
\ No newline at end of file
diff --git a/local-packages/ocamlfind/doc/guide-html/x403.html b/local-packages/ocamlfind/doc/guide-html/x403.html
new file mode 100644
index 0000000..e8aaa69
--- /dev/null
+++ b/local-packages/ocamlfind/doc/guide-html/x403.html
@@ -0,0 +1,248 @@
+
+Change your Makefile
Here is a commented version of a Makefile that may be used to compile
+and link a package. It describes the frequent case that the package
+simply consists of a bundle of modules that are dependent on other
+packages.
First, some general definitions. NAME is the name of the package. The
+OBJECTS variable enumerates the bytecode objects, whereas XOBJECTS
+names the native objects. The same naming convention is used for
+ARCHIVE and XARCHIVE, specifying the resulting bytecode, resp. native
+archive file. The REQUIRES variable lists the names of the packages
+that are needed for this package. If you need additional predicates,
+put them into the PREDICATES variable.
The default goal is "all", causing the bytecode archive to be
+created. In order to get a native archive, choose "opt" as second goal.
+(The ".PHONY" line is a declaration meaningful for GNU-make; "all" and
+"opt" are only virtual goals as there no files "all", or "opt" which
+is indicated by making them dependents of ".PHONY".)
.PHONY: all opt
+all: $(ARCHIVE)
+opt: $(XARCHIVE) $(SARCHIVE)
The following two rules create the bytecode resp. native archive from
+the objects.
Note that the cmxs archive is optional: we just ignore the error
+when it cannot be built.
These rules compile the modules independently. The lines similar to
+".ml.cmo" must be read: "How to transform files with suffix .ml into
+files with suffix .cmo". The corresponding command can refer to the
+input file as "$<" and to the output file(s) as "$@".
The "install" rule is a bit tricky. First it is tested if there is a
+native archive to install, and if so, the variable "extra" contains
+the corresponding files. The "ocamlfind install" command creates a new
+package directory and puts the given files into it.
\ No newline at end of file
diff --git a/local-packages/ocamlfind/doc/guide-html/x421.html b/local-packages/ocamlfind/doc/guide-html/x421.html
new file mode 100644
index 0000000..54991f4
--- /dev/null
+++ b/local-packages/ocamlfind/doc/guide-html/x421.html
@@ -0,0 +1,188 @@
+
+Using the Makefile wizard
Especially for beginners, the findlib distribution includes a GUI to
+create Makefiles. As this is an optional feature, it must have been
+selected when findlib was built (option -with-toolbox). To invoke the
+GUI, run the command
+
+
$ ocamlfind findlib/make_wizard
+
+(Btw, this is the general syntax to run executables installed in
+package directories.) The wizard starts, and allows you to describe
+your project. When you save the result, not only a "Makefile" is
+created, but also the file ".make-wizard" containing the state.
+If you later start the wizard again, this file will be automatically
+loaded, and you can modify your definition.
The wizard consists of seven (hopefully self-explanatory) pages
+you can fill out. The basic idea is that the .ml, .mli, .mly, and .mll
+files in the current directory are compiled to a .cma or .cmxa
+archive, and that optionally executables are created from this archive
+and from additional modules (main programs). This scheme can be both
+used for libraries and application programs.
You can choose packages you want to use in your library or
+program by clicking at them in a selection box. The camlp4 syntax
+parsers can be optionally enabled. The modules to be compiled can
+be picked from the current directory, they must be selected in the
+right order, however.
The generated "Makefile" defines a number of logical targets
+(like "all", "opt", etc) that are explained at the beginning of the
+file. The file is fully commented, and not very difficult to understand.
+Only traditional Makefile syntax is used, so it is expected that it
+works for every version of the "make" utility.
When you build the project, the META file is created
+dynamically. If you do not like this, set the variable MAKE_META to
+the empty string. (It is a good idea to put such setting into a
+second file, and enter the name of this file into the box "Local
+extensions in" of the wizard, so you can generate the "Makefile" again
+without overwriting your own modifications. This second file can
+override the setting in the generated "Makefile".)
\ No newline at end of file
diff --git a/local-packages/ocamlfind/doc/guide-html/x443.html b/local-packages/ocamlfind/doc/guide-html/x443.html
new file mode 100644
index 0000000..038269d
--- /dev/null
+++ b/local-packages/ocamlfind/doc/guide-html/x443.html
@@ -0,0 +1,170 @@
+
+Why does findlib not automatically include the -custom option if
+linked with C code?
Short answer:
+Because there are several ways of linking, and findlib is not the
+right instance to find out the right way
Recent versions of OCaml support DLLs, at least for some
+platforms. Here, the option -custom is not necessary at all, because the
+C libraries can be looked up and loaded at runtime. The option -custom
+would have the effect of forcing static linking.
But even for platforms without DLL support, there are two
+alternatives. One possibility is to use -custom, and the other is to
+create runtime systems with -make-runtime, and reference them with
+-use-runtime. Fortunately, recent versions of OCaml select now themselves
+-custom automatically if -make-runtime is omitted, so findlib needs not to
+bother with it.
Does findlib support linking of applications as well as
+packages?
\ No newline at end of file
diff --git a/local-packages/ocamlfind/doc/guide-html/x449.html b/local-packages/ocamlfind/doc/guide-html/x449.html
new file mode 100644
index 0000000..a9e45d4
--- /dev/null
+++ b/local-packages/ocamlfind/doc/guide-html/x449.html
@@ -0,0 +1,211 @@
+
+Does findlib support linking of applications as well as
+packages?
Applications also depend on other components, they have predicates, sometimes
+they need linker options; there seems to be only little difference between
+applications (stand-alone programs) and packages. If you want to use the
+findlib mechanisms for applications, too, the following trick helps.
The environment variable OCAMLPATH may contain a
+colon-separated path of possible sitelib locations. It is allowed to include
+"." into the path (Shell commands follow):
+
+
OCAMLPATH=.
+export OCAMLPATH
+
+This makes ".", i.e. your current directory, another sitelib location. You may
+now put the components of your applications into subdirectories together with
+META files; the hierarchy might look as follows:
+
+
./Makefile global Makefile
+./localpkg1/META first local package directory: Contains META
+./localpkg1/... ... and more
+./localpkg2/META second local package dir: Contains META
+./localpkg2/... ... and more
+...
+
+From findlib's point of view, these directories are now package directories,
+and you can refer to them on the command line:
+
+
\ No newline at end of file
diff --git a/local-packages/ocamlfind/doc/guide-html/x461.html b/local-packages/ocamlfind/doc/guide-html/x461.html
new file mode 100644
index 0000000..c38e1a7
--- /dev/null
+++ b/local-packages/ocamlfind/doc/guide-html/x461.html
@@ -0,0 +1,384 @@
+
+ Does Findlib support camlp4?
+
From the toploop, the following commands work:
+
+
$ ocaml
+ Objective Caml version 3.07+2
+
+# #use "./topfind";;
+- : unit = ()
+Findlib has been successfully loaded. Additional directives:
+ #require "package";; to load a package
+ #list;; to list the available packages
+ #camlp4o;; to load camlp4 (standard syntax)
+ #camlp4r;; to load camlp4 (revised syntax)
+ #predicates "p,q,...";; to set these predicates
+ Topfind.reset();; to force that packages will be reloaded
+ #thread;; to enable threads
+
+- : unit = ()
+# #camlp4o;; (* or camlp4r *)
+/opt/godi/lib/ocaml/std-lib/camlp4: added to search path
+/opt/godi/lib/ocaml/std-lib/camlp4/camlp4o.cma: loaded
+ Camlp4 Parsing version 3.07+2
+
+# _
If you have a -syntax option on the command line,
+ocamlfind will generate a -pp parameter and pass it to the
+invoked compiler. This is performed as follows: The specified packages are
+inspected under a certain set of predicates, the syntax
+predicates. The syntax predicates are syntax,
+preprocessor, and the predicates following
+-syntax. The predicate syntax simply
+means that the -syntax option has been specified.
+The predicate preprocessor means that the preprocessor
+command is being constructed. The predicates added by
+-syntax may be used to distinguish between syntax variants
+(currently camlp4o and camlp4r).
The packages are searched for a variable preprocessor;
+normally the camlp4 package defines it as (see its META
+file):
+
+
preprocessor = "camlp4 -nolib"
+
+Now that the name of the preprocessor command is known, the arguments of the
+command are looked up. The META files are evaluated under the syntax
+predicates, and all archive variables are collected and
+passed as arguments to the preprocessor. For example, the camlp4 package
+defines:
+
+
Suppose you have two archives: pa_myext.cma contains the
+extension code of camlp4, and run_myext.cma contains runtime
+material that must be present in programs compiled with your extensions. Your
+META file should look as follows:
+
+
The package xstrp4 defines a syntax extension allowing
+$-substitutions in OCaml strings. Version 1.0 of this package takes advantage
+from the new camlp4 support of findlib; you may have a look at it for an
+example.
\ No newline at end of file
diff --git a/local-packages/ocamlfind/doc/guide-html/x513.html b/local-packages/ocamlfind/doc/guide-html/x513.html
new file mode 100644
index 0000000..e394f7c
--- /dev/null
+++ b/local-packages/ocamlfind/doc/guide-html/x513.html
@@ -0,0 +1,198 @@
+
+ Does Findlib support ppx-style preprocessors?
+
Short answer: Yes, but there is only little
+ documentation.
Since findlib-1.5, ppx-style preprocessors are supported
+to some extent. A package can now define a "ppx" property which is simply
+a command to run as preprocessor (the command gets the marshalled AST
+as input, and must generate the transformed AST in its output; see the
+-ppx option of ocamlc/ocamlopt). A META file can simply look like:
+
+
ppx = "./command"
+
+when "command" is installed in the package directory (but you can also
+omit "./" to search it, and you can prefix it with "@name/" if the command
+is taken from another package "name").
For more complex scenarios, additional options or
+arguments for the ppx preprocessor can be specified in descendant
+packages with the "ppxopt" property. Package "A" might provide a
+generic ppx preprocessor with a META file containing
+
+
ppx = "./generic_ppx"
+
+Package B might instantiate that preprocessor with
+
+
requires = "A"
+ppxopt = "A,ppx_b.cmo"
+
+In this case "ocamlfind ocamlc -package B" would
+add -ppx "path_to_A/genric_ppx ppx_b.cmo" to
+the ocamlc invocation. The format of the "ppxopt" property is
+specified in the findlib reference manual.
\ No newline at end of file
diff --git a/local-packages/ocamlfind/doc/guide-html/x524.html b/local-packages/ocamlfind/doc/guide-html/x524.html
new file mode 100644
index 0000000..e590331
--- /dev/null
+++ b/local-packages/ocamlfind/doc/guide-html/x524.html
@@ -0,0 +1,162 @@
+
+Why do some people install the .cmx files?
In principle, it is not necessary to install the .cmx
+files created by the ocamlopt compiler, as the .a and .cmxa files
+already contain the assembly code and all needed auxiliary information.
+However, it may be sensible to install the .cmx files, too. They
+contain the intermediate code of small functions that are candidates
+for inlining, and installing them allows the compiler to do inlining
+even across library boundaries. Note that only very small functions
+can be inlined at all, and that there are language elements that
+prevent inlining (e.g. raising an exception with an argument), so
+it makes only sense when the library actually has such functions
+and really profits from inlining.
Inlining has also disadvantages: The library can no
+longer be replaced by a different version even if the interface
+remains exactly the same, because code using the library may have
+inlined code of the old version.
\ No newline at end of file
diff --git a/local-packages/ocamlfind/doc/guide-html/x528.html b/local-packages/ocamlfind/doc/guide-html/x528.html
new file mode 100644
index 0000000..94aae6b
--- /dev/null
+++ b/local-packages/ocamlfind/doc/guide-html/x528.html
@@ -0,0 +1,198 @@
+
+How do I express conflicts?
A conflict means that a certain combination of packages
+and package features will not work. A number of conflict conditions
+can be expressed:
To state that a package will not work if a certain
+predicate is set, use the error variable. For example,
+when package p does not work for multi-threaded programs:
+
+
error(mt) = "Package p is incompatible with multi-threaded programs"
+
+This works for other standard predicates, too.
To state that a package will not work together with
+another package, it is possible to make error dependent
+on package predicates. For example, when package p does not work
+together with q:
+
+
error(pkg_q) = "Package p is incompatible with package q"
+
+This also works with subpackages (e.g. pkg_q.q_sub).
+
If an error is too much, it might be a good idea to
+ just inform the user about possible problems. In this case
+ you can emit a warning instead:
+
warning(pkg_q) = "Using package p and q together is a really bad idea"
Note that such error conditions should only be added if there is
+absolutely no chance to get the combination of packages and features running.
+For example, in the case of multi-threaded programs it is often possible
+to add wrappers around unsafe libraries to fix the incompatibility.
+
It is not possible to express incompatibilities between package
+versions. Such incompatibilities should be detected when software is
+installed, not when it is used.
\ No newline at end of file
diff --git a/local-packages/ocamlfind/doc/guide-html/x81.html b/local-packages/ocamlfind/doc/guide-html/x81.html
new file mode 100644
index 0000000..7728d8d
--- /dev/null
+++ b/local-packages/ocamlfind/doc/guide-html/x81.html
@@ -0,0 +1,170 @@
+
+Looking up package directories
The package manager knows the preferred location for packages (this
+location is compiled in), which is usually
+/usr/local/lib/ocaml/site-lib. You can ask the package manager where
+package p is stored by simply typing
ocamlfind query p
and it will answer something like
/usr/local/lib/ocaml/site-lib/p
There is an environment variable OCAMLPATH which can specify further
+directories where packages are stored. (The search order is: first
+the directories in OCAMLPATH in turn, then the default path
+set in ocamlfind.conf)
Historically, this kind of query was the first and only way of using
+ocamlfind, and because of the similiarity to the Unix find command it
+got its name. Finding out package locations is a basic but
+nethertheless important feature because it hides the details of the
+filesystem hierarchy. It is sufficient only to know the name of the
+package, and if needed, you can use the lookup mechanism implemented
+in ocamlfind to get the concrete directory.
\ No newline at end of file
diff --git a/local-packages/ocamlfind/doc/guide-html/x89.html b/local-packages/ocamlfind/doc/guide-html/x89.html
new file mode 100644
index 0000000..3865b63
--- /dev/null
+++ b/local-packages/ocamlfind/doc/guide-html/x89.html
@@ -0,0 +1,255 @@
+
+How a package directory looks like
Let us assume that the package p implements the modules M1 and M2. If
+you compile m1.mli and m2.mli you get the corresponding binary files
+m1.cmi and m2.cmi describing the interfaces of the modules. Of course,
+these cmi files must go into the package directory. It is recommended
+to put the source mli files into the directory, too, as they document
+the interface.
Another product of the compilation are two cmo files, m1.cmo and
+m2.cmo (we assume the bytecode compiler, the native compiler would
+create m1.cmx and m2.cmx). It is possible to put these files directly
+into the directory, but there is a better way. As it makes only sense
+to use both modules (a very common assumption), they should first be
+archived by doing
ocamlc -a -o p.cma m1.cmo m2.cmo
The archive p.cma contains both cmo files, and preserves the order of
+the files. Assumed that in M2 there is a reference to an entity in M1,
+M2 depends on M1 and when linking a program using these modules, M1
+must be mentioned first (e.g. ocamlc m1.cmo m2.cmo
+program.ml)[1]. If you create the archive p.cma it contains already
+this dependency, and you need not to remember it when linking in the
+p.cma.
So far the files m1.cmi, m2.cmi, and p.cma are needed, and m1.mli and
+m2.mli are recommended. Usually there is another file in the
+directory, META, containing additional information about the package.
+In our example, META looks like
The variable "requires" contains a list of packages that are
+required by this package (the names may be separated by commas or
+spaces). As our package, p, does not depend on any other package, this
+list is empty. I'll explain what happens with non-empty lists below.
The variable "version" is simply a version string, and "description"
+is a short comment on the package.
The variable "archive" denotes the files that have to be
+actually linked in if the package is used. This is again a list of
+(file) names. In contrast to the other variables, "archive" has a
+condition, written in parantheses. This value of "archive" will only
+be used if the predicate "byte" is true; this predicate is usually
+given if the program is compiled to bytecode. If you have a native
+archive, p.cmxa, of the two modules M1 and M2, you can add another
+line to META:
archive(native) = "p.cmxa"
The correct value for the "archive" variable is selected upon the
+given set of predicates.
Many packages can also be loaded at runtime with the
+Fl_dynload module. In this case, though, the
+variable "plugin" is used instead of "archive", e.g.
plugin(byte) = "p.cma"
+plugin(native) = "p.cmxs"
(You can create p.cmxs from p.cmxa with
+"ocamlopt -shared -linkall -o p.cmxs p.cmxa".) Note that "plugin" is entirely optional.
\ No newline at end of file
diff --git a/local-packages/ocamlfind/doc/readme.dtd b/local-packages/ocamlfind/doc/readme.dtd
new file mode 100644
index 0000000..8ff6a9f
--- /dev/null
+++ b/local-packages/ocamlfind/doc/readme.dtd
@@ -0,0 +1,38 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/local-packages/ocamlfind/doc/ref-man/META.5 b/local-packages/ocamlfind/doc/ref-man/META.5
new file mode 100644
index 0000000..13380ec
--- /dev/null
+++ b/local-packages/ocamlfind/doc/ref-man/META.5
@@ -0,0 +1,613 @@
+.TH "META" "5" "The findlib package manager for OCaml" "User Manual"
+.SH "NAME"
+.ft R
+META - [File that specifies metainformation of OCaml packages]\c
+.SH "GRAMMAR"
+.ft R
+.ft R
+.ft B
+.nf
+\&\ \ \ \ \ \ \ \ \ metafile\ ::=\ entry*\c
+\&
+.br
+\&\ \ \ \ \ \ \ \ \ \ \ \ entry\ ::=\ assignment\ |\ addition\ |\ subpackage\c
+\&
+.br
+\&\ \ \ \ \ \ \ subpackage\ ::=\ "package"\ pkgname\ '('\ metafile\ ')'\c
+\&
+.br
+\&\ \ \ \ \ \ \ assignment\ ::=\ variable_name\ [\ formal_predicates\ ]\ '='\ \ value\c
+\&
+.br
+\&\ \ \ \ \ \ \ \ \ addition\ ::=\ variable_name\ [\ formal_predicates\ ]\ '+='\ value\c
+\&
+.br
+formal_predicates\ ::=\ '('\ formal_predicate\ {\ ','\ formal_predicate\ }\ ')'\c
+\&
+.br
+\&\ \ \ \ variable_name\ ::=\ name\c
+\&
+.br
+\&\ formal_predicate\ ::=\ name\ |\ '-'\ name\c
+\&
+.br
+\&\ \ \ \ \ \ \ \ \ \ \ \ \ name\ ::=\ [\ 'A'-'Z'\ 'a'-'z'\ '0'-'9'\ '_'\ '.'\ ]+\c
+\&
+.br
+\&\ \ \ \ \ \ \ \ \ \ pkgname\ ::=\ '"'\ (character\ but\ not\ '.')*\ '"'\c
+\&
+.br
+\&\ \ \ \ \ \ \ \ \ \ \ \ value\ ::=\ '"'\ character*\ '"'\c
+.ft R
+.fi
+.SH "DESCRIPTION"
+.ft R
+.ft R
+If a package directory contains a file with the fixed name "META" it\c
+\&
+is interpreted as described here. The file is a sequence of entries\c
+\&
+following the given grammar; every entry defines a variable under a\c
+\&
+certain condition given by the list of formal predicates, or it\c
+\&
+introduces a subpackage.\c
+.PP
+.ft R
+There is a list of predefined variables and a list of standard\c
+\&
+predicates. These variables define: required packages, description, version\c
+\&
+information, directories, archive files, and linker options. The\c
+\&
+predicates denote circumstances of the application of the variables:\c
+\&
+whether the bytecode or the native compiler is used, if there is a\c
+\&
+toploop compiled in, details of multi-threading execution, details of\c
+\&
+profiling.
+.SH "DETAILS OF THE FILE FORMAT"
+.ft R
+.ft R
+The file consists of a sequence of entries which must be formed as the\c
+\&
+grammar prescribes. The lexical tokens are names, values, and\c
+\&
+interpunctuation like '(', ',' and so on. Note that linefeeds do not\c
+\&
+play a special role, i.e. an entry definition may be given in more than\c
+\&
+one line, or several definitions may occur on a single line. There may\c
+\&
+be comments which begin with '#' and run until the end of the line.\c
+.PP
+.ft R
+Names are sequences of the characters A-Z, a-z, 0-9, or _. Names\c
+\&
+containing capital letters and names beginning with digits are\c
+\&
+allowed but not recommended.\c
+.PP
+.ft R
+Values are enclosed between double quotes. Values may contain any\c
+\&
+character. The characters " and \e must be preceded by backslashes.
+.PP
+.ft R
+Package names must not contain the '.' character because it is used\c
+\&
+as delimiter of compound names.\c
+.SH "MAIN PACKAGES AND SUBPACKAGES"
+.ft R
+.ft R
+The outermost variable assignments and additions belong to the main\c
+\&
+package. The name of the main package is not defined within META;\c
+\&
+it is either the name of the directory containing META or the suffix\c
+\&
+of the META file (if the name of the META file is formed like\c
+\&
+META.name).\c
+.PP
+.ft R
+The keyword
+package\c
+\& starts the definition\c
+\&
+of a subpackage. There must not be two such definitions with the\c
+\&
+same name. Within the parantheses, the variable assignments and\c
+\&
+additions refer to the subpackage. It is allowed that a subpackage\c
+\&
+contains further subpackages.\c
+.PP
+.ft R
+The package name following
+package\c
+\&
+is the local name relative to the main package, i.e. the\c
+\&
+name of the main package is not mentioned. At all other places,\c
+\&
+however, the subpackage must be prefixed by the name of the\c
+\&
+containing package, separated by a '.'.\c
+.PP
+.ft R
+Subpackages are independent of the containing package, except\c
+\&
+that the subpackage points to the same installation directory as\c
+\&
+the containing package (i.e. the location of the installation directory\c
+\&
+is inherited from the containing package).\c
+.SH "SEMANTICS OF VARIABLE DEFINITIONS"
+.ft R
+.ft R
+In order to determine the value of a variable, first all assignments\c
+\&
+are inspected, and the most specific assignment is taken (if there is\c
+\&
+none, the empty string will be taken as value). In a second step,\c
+\&
+all additions are gone through one after the other in the order\c
+\&
+they occur in the file, and the values of all matching additions are\c
+\&
+appended to the current value. In the following, it is further\c
+\&
+clarified which assignment is the most specific, which additions\c
+\&
+actually match, and how the details of the value addition look like.\c
+.PP
+.ft R
+The most specific assignment is selected upon a set of actual\c
+\&
+predicates, i.e. the set of predicates that are assumed to be true.\c
+\&
+The predicates occuring in the definitions of assignments and\c
+\&
+additions are called formal predicates. They may be positive or\c
+\&
+negative; the latter are prepended by a '-' sign. In order to\c
+\&
+determine the value after the evaluation of the assignments, the\c
+\&
+following rules apply:
+.PP
+.ft R
+.RS "7m"
+.ft R
+\&\h'-3m'\z\(bu\h'3m'\c
+.ft R
+An assignment can only be used if all positive formal\c
+\&
+predicates are included in the set of actual predicates, and if all\c
+\&
+negative formal predicates are not included in the set of actual\c
+\&
+predicates. Such an assignment is called\c
+\&
+.ft B
+applicable\c
+.ft R
+\&. If there is no such assignment, the\c
+\&
+variable will have no value.
+.RE
+.ft R
+.sp
+.RS "7m"
+.ft R
+\&\h'-3m'\z\(bu\h'3m'\c
+.ft R
+If there is more than one applicable assignment, the definition with\c
+\&
+the biggest number of formal predicates is selected.\c
+.RE
+.ft R
+.sp
+.RS "7m"
+.ft R
+\&\h'-3m'\z\(bu\h'3m'\c
+.ft R
+If there is still more than one applicable assignment, both applicable
+\&
+and with a maximum number of formal predicates, the definition that is defined\c
+\&
+first is selected.\c
+.RE
+.ft R
+.PP
+.ft R
+.ft R
+An addition is matching when all positive formal predicates are\c
+\&
+included in the set of actual predicates, and all negative formal\c
+\&
+predicates are not included.\c
+.PP
+.ft R
+The value of an addition is appended to the current value with\c
+\&
+implicit white space as separator.\c
+.SH "VARIABLES"
+.ft R
+.ft R
+There is a set of variables with predefined meaning:\c
+.PP
+.ft R
+.RS "7m"
+.ft R
+\&\h'-3m'\z\(bu\h'3m'\c
+.ft R
+The\c
+\&
+variable "directory" redefines the location of the package\c
+\&
+directory. Normally, the META file is the first file read in the\c
+\&
+package directory, and before any other file is read, the "directory"\c
+\&
+variable is evaluated in order to see if the package directory must be\c
+\&
+changed. The value of the "directory" variable is determined with an\c
+\&
+empty set of actual predicates. The value must be either: an absolute\c
+\&
+path name of the alternate directory, or a path name relative to the\c
+\&
+stdlib directory of OCaml (written "+path"), or a normal relative path\c
+\&
+name (without special syntax). In the latter case, the interpretation\c
+\&
+depends on whether it is contained in a main or sub package, and\c
+\&
+whether the standard repository layout or the alternate layout is in\c
+\&
+effect (see
+site-lib\c
+\& for these terms).\c
+\&
+For a main package in standard layout the base directory is the\c
+\&
+directory physically containing the META file, and the relative path\c
+\&
+is interpreted for this base directory. For a main package in\c
+\&
+alternate layout the base directory is the directory physically\c
+\&
+containing the META.pkg files. The base directory for subpackages is\c
+\&
+the package directory of the containing package. (In the case\c
+\&
+that a subpackage definition does not have a "directory" setting,\c
+\&
+the subpackage simply inherits the package directory of the containing\c
+\&
+package. By writing a "directory" directive one can change this\c
+\&
+location again.)\c
+.RE
+.ft R
+.sp
+.RS "7m"
+.ft R
+\&\h'-3m'\z\(bu\h'3m'\c
+.ft R
+The variable "requires" specifies the list of required packages. The\c
+\&
+names of the packages must be separated by white space and/or commas.\c
+\&
+The names must be fully qualified (i.e. when they refer to a subpackage,\c
+\&
+the names of all containing packages must be prepended, separated by\c
+\&
+\&'.').\c
+.RE
+.ft R
+.sp
+.RS "7m"
+.ft R
+\&\h'-3m'\z\(bu\h'3m'\c
+.ft R
+The variable "description" may include a short description of the\c
+\&
+package (displayed by
+ocamlfind list\c
+).\c
+.RE
+.ft R
+.sp
+.RS "7m"
+.ft R
+\&\h'-3m'\z\(bu\h'3m'\c
+.ft R
+The variable "version" specifies the version string.\c
+.RE
+.ft R
+.sp
+.RS "7m"
+.ft R
+\&\h'-3m'\z\(bu\h'3m'\c
+.ft R
+The variable "archive" specifies the list of archive files. These\c
+\&
+files should be given either as (1) plain names without any directory\c
+\&
+information; they are only searched in the package directory.\c
+\&
+(2) Or they have the form "+path" in which case the files are looked up\c
+\&
+relative to the standard library. (3) Or they have the form "@name/file"\c
+\&
+in which case the files are looked up in the package directory\c
+\&
+of another package. (4) Or they are given as absolute paths.\c
+.PP
+.ft R
+The\c
+\&
+names of the files must be separated by white space and/or commas.\c
+\&
+In the preprocessor stage, the archive files are passed as extensions\c
+\&
+to the preprocessor (camlp4) call. In the linker stage (-linkpkg), the archive\c
+\&
+files are linked. In the compiler stage, the archive files are ignored.\c
+.PP
+.ft R
+Note that "archive" should only be used for archive files that are\c
+\&
+intended to be included in executables or loaded into toploops. For\c
+\&
+modules loaded at runtime there is the separate variable "plugin".\c
+.RE
+.ft R
+.sp
+.RS "7m"
+.ft R
+\&\h'-3m'\z\(bu\h'3m'\c
+.ft R
+The variable "plugin" specifies the plugin archives of the package.\c
+\&
+These can be dynamically loaded with the
+Fl_dynload\c
+\&
+module. The plugin archives can have ".cmo", ".cma", or ".cmxs" suffix.\c
+.RE
+.ft R
+.sp
+.RS "7m"
+.ft R
+\&\h'-3m'\z\(bu\h'3m'\c
+.ft R
+The variable "linkopts" specifies additional linker options.\c
+.RE
+.ft R
+.sp
+.RS "7m"
+.ft R
+\&\h'-3m'\z\(bu\h'3m'\c
+.ft R
+The variable "error" can be used to signal error conditions. When\c
+\&
+this variable is applicable, the ocaml compilers are stopped, and\c
+\&
+an error message is printed. The message is the value of the variable.\c
+.RE
+.ft R
+.sp
+.RS "7m"
+.ft R
+\&\h'-3m'\z\(bu\h'3m'\c
+.ft R
+The variable "warning" can be used to signal warnings. When\c
+\&
+this variable is applicable, the warning is printed, but the\c
+\&
+compilation continues. The message is the value of the variable.\c
+.RE
+.ft R
+.sp
+.RS "7m"
+.ft R
+\&\h'-3m'\z\(bu\h'3m'\c
+.ft R
+The variable "exists_if" can be used to disable subpackages. The\c
+\&
+value of "exists_if" is a file; the subpackage is hidden if this\c
+\&
+file does not exist. You can also enumerate several files, and the\c
+\&
+subpackage is hidden if none of the files exist.\c
+.RE
+.ft R
+.sp
+.RS "7m"
+.ft R
+\&\h'-3m'\z\(bu\h'3m'\c
+.ft R
+The variable "ppx" is a command that is added to the compiler invocation\c
+\&
+via the -ppx option (available since OCaml-4.01). If the command is\c
+\&
+relative to the current directory (e.g. ./cmd), the command is expected\c
+\&
+in the package directory. The special forms as defined for "archive"\c
+\&
+are also available (e.g. @otherpkg/cmd). Additional arguments can be\c
+\&
+specified on the ocamlfind command line with the -ppxopt option\c
+\&
+or the "ppxopt" variable.\c
+.RE
+.ft R
+.sp
+.RS "7m"
+.ft R
+\&\h'-3m'\z\(bu\h'3m'\c
+.ft R
+The variable "ppxopt" is a set of options that are added to the ppx\c
+\&
+rewriter invocation. The contents of the variable consists of one or\c
+\&
+several whitespace-separated parts. Every part consists of several\c
+\&
+comma-separated subparts; the first subpart indicates the package\c
+\&
+that contains the ppx rewriter invocation, the rest contain the options\c
+\&
+to be appended. If the option is a path relative to the current directory\c
+\&
+(e.g. ./foo.cma), the path is expanded relative to the package directory.\c
+\&
+The special forms as defined for "archive" are also available\c
+\&
+(e.g. @otherpkg/foo.cma).\c
+.RE
+.ft R
+.PP
+.ft R
+.ft R
+It is possible to define additional variables but there is currently\c
+\&
+no software interpreting them.\c
+.SH "PREDICATES"
+.ft R
+.ft R
+There is a list of standard predicates:\c
+.PP
+.ft R
+.RS "7m"
+.ft R
+\&\h'-3m'\z\(bu\h'3m'\c
+.ft R
+The "byte" predicate means that the bytecode compiler is used.\c
+.RE
+.ft R
+.sp
+.RS "7m"
+.ft R
+\&\h'-3m'\z\(bu\h'3m'\c
+.ft R
+The "native" predicate means that the native compiler is used.\c
+.RE
+.ft R
+.sp
+.RS "7m"
+.ft R
+\&\h'-3m'\z\(bu\h'3m'\c
+.ft R
+The "toploop" predicate means that the toploop is available in the\c
+\&
+linked program. It is only set when the toploop is running, not when\c
+\&
+the toploop is generated.\c
+.RE
+.ft R
+.sp
+.RS "7m"
+.ft R
+\&\h'-3m'\z\(bu\h'3m'\c
+.ft R
+The "create_toploop" predicate means that a toploop is created (using\c
+\&
+ocamlmktop).\c
+.RE
+.ft R
+.sp
+.RS "7m"
+.ft R
+\&\h'-3m'\z\(bu\h'3m'\c
+.ft R
+The "mt" predicate means that the program is multi-threaded.\c
+.RE
+.ft R
+.sp
+.RS "7m"
+.ft R
+\&\h'-3m'\z\(bu\h'3m'\c
+.ft R
+The "mt_posix" predicate means that in the case "mt" is set, too, the\c
+\&
+POSIX libraries are used to implement threads.\c
+.RE
+.ft R
+.sp
+.RS "7m"
+.ft R
+\&\h'-3m'\z\(bu\h'3m'\c
+.ft R
+The "mt_vm" predicate means that in the case "mt" is set, too, the\c
+\&
+VM-based libraries are used to implement threads.\c
+.RE
+.ft R
+.sp
+.RS "7m"
+.ft R
+\&\h'-3m'\z\(bu\h'3m'\c
+.ft R
+The "gprof" predicate means that in the case "native" is set, too, the\c
+\&
+program is compiled for profiling\c
+.RE
+.ft R
+.sp
+.RS "7m"
+.ft R
+\&\h'-3m'\z\(bu\h'3m'\c
+.ft R
+The "autolink" predicate means that ocamlc can/will perform automatic linking.\c
+.RE
+.ft R
+.sp
+.RS "7m"
+.ft R
+\&\h'-3m'\z\(bu\h'3m'\c
+.ft R
+The "preprocessor" predicate means that the META variables are scanned for\c
+\&
+preprocessor options.\c
+.RE
+.ft R
+.sp
+.RS "7m"
+.ft R
+\&\h'-3m'\z\(bu\h'3m'\c
+.ft R
+The "syntax" predicate means that the -syntax option is present on the\c
+\&
+command line.\c
+.RE
+.ft R
+.sp
+.RS "7m"
+.ft R
+\&\h'-3m'\z\(bu\h'3m'\c
+.ft R
+Legacy: The "plugin" predicate could be used in some versions of findlib\c
+\&
+to select cmxs archives instead of cmxa archives. This use is still possible\c
+\&
+but discouraged.\c
+.RE
+.ft R
+.PP
+.ft R
+.ft R
+In addition to these predicates, there are package predicates\c
+\&
+for every package that is finally selected. Of course, this kind of\c
+\&
+predicate must not be used to select "directory" and "requires"\c
+\&
+variables, but for the other variables they are perfectly valid.\c
+\&
+The package predicates have the form "pkg_" plus the name of the\c
+\&
+package (fully qualified).\c
diff --git a/local-packages/ocamlfind/doc/ref-man/TIMESTAMP b/local-packages/ocamlfind/doc/ref-man/TIMESTAMP
new file mode 100644
index 0000000..e69de29
diff --git a/local-packages/ocamlfind/doc/ref-man/findlib.conf.5 b/local-packages/ocamlfind/doc/ref-man/findlib.conf.5
new file mode 100644
index 0000000..3a70319
--- /dev/null
+++ b/local-packages/ocamlfind/doc/ref-man/findlib.conf.5
@@ -0,0 +1,787 @@
+.TH "findlib.conf" "5" "The findlib package manager for OCaml" "User Manual"
+.SH "NAME"
+.ft R
+findlib.conf - [Configuration of findlib/ocamlfind]\c
+.SH "GENERAL"
+.ft R
+.ft R
+There are three possibilities to configure the findlib library:\c
+\&
+\&
+.PP
+.ft R
+.RS "2m"
+.ft R
+Build time:\c
+.RE
+.ft R
+.sp
+.RS "7m"
+.ft R
+.ft R
+Before findlib is compiled, a "configure" script is invoked to figure\c
+\&
+\& out the settings that are most likely to work on the system. Most\c
+\&
+\& settings are simply entered into text files and can easily be changed\c
+\&
+\& after installation. The following properties cannot be changed later\c
+\&
+\& because they are compiled into the resulting binaries:\c
+\&
+\&
+\&
+.PP
+.ft R
+.RS "7m"
+.ft R
+\&\h'-3m'\z\(bu\h'3m'\c
+.ft R
+The default location of the configuration file findlib.conf. However,\c
+\&
+\& you can set a different location by the environment variable\c
+\&
+\&
+OCAMLFIND_CONF\c
+\&.\c
+\&
+\&
+.RE
+.ft R
+.sp
+.RS "7m"
+.ft R
+\&\h'-3m'\z\(bu\h'3m'\c
+.ft R
+Whether the installed OCaml version supports autolinking or not.\c
+\&
+\&
+.RE
+.ft R
+.PP
+.ft R
+.RE
+.ft R
+.sp
+.RS "2m"
+.ft R
+Configuration file findlib.conf:\c
+.RE
+.ft R
+.sp
+.RS "7m"
+.ft R
+.ft R
+An initial version of this file is generated by the configure script,\c
+\&
+\& but you are free to modify it later. Most important, this file\c
+\&
+\& contains the system-wide search path used to look up packages, and the\c
+\&
+\& default location where to install new packages.\c
+\&
+\&
+.PP
+.ft R
+All files with the suffix ".conf" found in the directory\c
+\&
+\& findlib.conf.d are also scanned for parameters.\c
+\&
+\&
+.RE
+.ft R
+.sp
+.RS "2m"
+.ft R
+Environment variables:\c
+.RE
+.ft R
+.sp
+.RS "7m"
+.ft R
+.ft R
+The settings of findlib.conf can be overridden by environment variables.\c
+\&
+\&
+.RE
+.ft R
+.PP
+.ft R
+Last but not least, several settings can also be passed as\c
+\&
+command-line options, or by invoking the function\c
+\&
+Findlib.init\c
+\&.
+.SH "findlib.conf"
+.ft R
+.ft R
+The directory containing findlib.conf is determined at build time (by\c
+\&
+running the configure script), the fallback default is\c
+\&
+/usr/local/etc\c
+\&. You can set a different location by\c
+\&
+changing the environment variable
+OCAMLFIND_CONF\c
+\&
+which must contain the absolute path of findlib.conf.\c
+.PP
+.ft R
+The file has the same syntax as
+META\c
+, i.e. it consists of a\c
+\&
+number of lines with the format\c
+\&
+\&
+.PP
+.ft R
+.ft B
+.nf
+.ft I
+variable\c
+.ft B
+\&\ =\ "\c
+.ft I
+value\c
+.ft B
+"\c
+.ft R
+.fi
+.PP
+.ft R
+Here is the list of allowed variables:\c
+\&
+\&
+.PP
+.ft R
+.RS "2m"
+.ft R
+path\c
+.RE
+.ft R
+.sp
+.RS "7m"
+.ft R
+.ft R
+The search path for META files/package directories. The variable\c
+\&
+\& enumerates directories which are separated by colons (Windows:\c
+\&
+\& semicolons), and these directories are tried in turn to find a certain\c
+\&
+\& package. More exactly, if d is such a directory and p the searched\c
+\&
+\& package, the search algorithm will first check whether d/p/META\c
+\&
+\& exists. In this case, this META file is taken, and d/p is the package\c
+\&
+\& directory. Second, the algorithm tries d/META.p, but the package\c
+\&
+\& directory must be specified in this META.p file by a\c
+\&
+\&
+directory\c
+\& directive.\c
+\&
+\&
+.PP
+.ft R
+Note that the first found META file is taken, so the order of the\c
+\&
+\& directories in the search path counts.\c
+\&
+\&
+.PP
+.ft R
+This variable is required.\c
+\&
+\&
+.PP
+.ft R
+Example:\c
+\&
+\&
+\&
+.PP
+.ft R
+.ft B
+.nf
+path\ =\ "/usr/local/lib/ocaml/site-lib:/usr/lib/ocaml/site-lib"\c
+.ft R
+.fi
+\&
+\&
+.RE
+.ft R
+.PP
+.ft R
+.ft R
+.RS "2m"
+.ft R
+destdir\c
+.RE
+.ft R
+.sp
+.RS "7m"
+.ft R
+.ft R
+This variable determines the location where
+ocamlfind\c
+\&
+\& install\c
+\& puts the packages by default: If d is this\c
+\&
+\& directory, and p the package to install, a new subdirectory d/p will\c
+\&
+\& be created containing all the files of the package.\c
+\&
+\&
+.PP
+.ft R
+Example:\c
+\&
+\&
+.PP
+.ft R
+.ft B
+.nf
+destdir\ =\ "/usr/local/lib/ocaml/site-lib"\c
+.ft R
+.fi
+\&
+\&
+.PP
+.ft R
+This variable is required.\c
+\&
+\&
+.RE
+.ft R
+.PP
+.ft R
+.ft R
+.RS "2m"
+.ft R
+metadir\c
+.RE
+.ft R
+.sp
+.RS "7m"
+.ft R
+.ft R
+If set, the command
+ocamlfind install\c
+\& will put the\c
+\&
+\& META files of packages into this directory (files are named META.p\c
+\&
+\& where p=package name); otherwise the META files are put into the\c
+\&
+\& package directories like any other file.\c
+\&
+\&
+.PP
+.ft R
+Example:\c
+\&
+\&
+.PP
+.ft R
+.ft B
+.nf
+metadir\ =\ "/var/lib/findlib/metaregistry"\c
+.ft R
+.fi
+\&
+\&
+.PP
+.ft R
+This variable is optional. It is not used by default.\c
+\&
+\&
+.RE
+.ft R
+.PP
+.ft R
+.ft R
+.RS "2m"
+.ft R
+ocamlc\c
+,\c
+\&
+\&
+ocamlopt\c
+,\c
+\&
+\&
+ocamlcp\c
+,\c
+\&
+\&
+ocamlmktop\c
+,\c
+\&
+\&
+ocamldoc\c
+,\c
+\&
+\&
+ocamldep\c
+,\c
+\&
+\&
+ocamlbrowser\c
+\&
+\&
+.RE
+.ft R
+.sp
+.RS "7m"
+.ft R
+.ft R
+If you want to call other executables than "ocamlc", "ocamlopt",\c
+\&
+\& "ocamlcp", "ocamlmktop", "ocamldoc", "ocamldep", and\c
+\&
+\& "ocamlbrowser", you can\c
+\&
+\& set the names of\c
+\&
+\& the executables here. The command
+ocamlfind\c
+\& looks\c
+\&
+\& into these four variables to determine the names of the compilers to\c
+\&
+\& call.\c
+\&
+\&
+.PP
+.ft R
+Example:\c
+\&
+\&
+.PP
+.ft R
+.ft B
+.nf
+ocamlc\ \ \ \ \ =\ "ocamlc.opt"\c
+\&
+.br
+ocamlopt\ \ \ =\ "ocamlopt.opt"\c
+\&
+.br
+ocamlcp\ \ \ \ =\ "ocamlcp.opt"\c
+\&
+.br
+ocamlmktop\ =\ "ocamlmktop.opt"\c
+.ft R
+.fi
+\&
+\&
+.PP
+.ft R
+This variable is optional. It is not used by default.\c
+\&
+\&
+.RE
+.ft R
+.PP
+.ft R
+.ft R
+.RS "2m"
+.ft R
+stdlib\c
+.RE
+.ft R
+.sp
+.RS "7m"
+.ft R
+.ft R
+This variable determines the location of the standard library. This must\c
+\&
+\& be the same directory for which the OCaml compilers are configured.\c
+\&
+\&
+.PP
+.ft R
+This variable is optional. It is not recommend to set this variable\c
+\&
+\& unless you know what you are doing!\c
+\&
+\&
+.RE
+.ft R
+.PP
+.ft R
+.ft R
+.RS "2m"
+.ft R
+ldconf\c
+.RE
+.ft R
+.sp
+.RS "7m"
+.ft R
+.ft R
+This variable determines the location of the ld.conf file. This must\c
+\&
+\& be the same file the OCaml compilers read in; it is updated by
+\&
+\& ocamlfind when installing and removing packages. You can set this\c
+\&
+\& variable to the special value "\c
+ignore\c
+" to disable\c
+\&
+\& the automatic modification of the ld.conf file.\c
+\&
+\&
+.PP
+.ft R
+If not set, the ld.conf file is assumed to reside in the OCaml\c
+\&
+\& standard library directory.\c
+\&
+\&
+.PP
+.ft R
+This variable is optional. It is not recommended to set this variable\c
+\&
+\& unless you know what you are doing!\c
+\&
+\&
+.RE
+.ft R
+.PP
+.ft R
+.ft R
+Toolchains: It is possible to have variants of the original configuration.\c
+\&
+These variants are called "toolchains" because they are intended to\c
+\&
+select different compilers, e.g. patched compilers. In order to\c
+\&
+set a variable for a certain toolchain, use the syntax\c
+\&
+\&
+.PP
+.ft R
+.ft B
+.nf
+.ft I
+variable\c
+.ft B
+(\c
+.ft I
+toolchain\c
+.ft B
+)\ =\ "\c
+.ft I
+value\c
+.ft B
+"\c
+.ft R
+.fi
+\&
+\&
+For example:\c
+\&
+\&
+.PP
+.ft R
+.ft B
+.nf
+ocamlc(mypatch)\ =\ "ocamlc-mypatch"\c
+.ft R
+.fi
+\&
+\&
+When the toolchain "mypatch" is selected, this compiler will be used instead\c
+\&
+of the standard one.\c
+.PP
+.ft R
+In order to switch to a certain toolchain, use the -toolchain\c
+\&
+option of
+ocamlfind\c
+\&.\c
+.SH "Environment"
+.ft R
+.ft R
+A number of environment variables modifies the behaviour of\c
+\&
+findlib/ocamlfind:\c
+\&
+\&
+.PP
+.ft R
+.RS "2m"
+.ft R
+OCAMLFIND_CONF\c
+.RE
+.ft R
+.sp
+.RS "7m"
+.ft R
+.ft R
+This variable overrides the location of the configuration file\c
+\&
+\& findlib.conf. It must contain the absolute path name of this file.\c
+\&
+\&
+.RE
+.ft R
+.PP
+.ft R
+.ft R
+.RS "2m"
+.ft R
+OCAMLFIND_TOOLCHAIN\c
+.RE
+.ft R
+.sp
+.RS "7m"
+.ft R
+.ft R
+This variable sets the currently selected toolchain when\c
+\&
+\& a
+-toolchain\c
+\& option is not passed\c
+\&
+\& on the command line.\c
+\&
+\&
+.RE
+.ft R
+.PP
+.ft R
+.ft R
+.RS "2m"
+.ft R
+OCAMLPATH\c
+.RE
+.ft R
+.sp
+.RS "7m"
+.ft R
+.ft R
+This variable may contain an additional search path for package\c
+\&
+\& directories. It is treated as if the directories were prepended to\c
+\&
+\& the configuration variable
+path\c
+\&.\c
+\&
+\&
+.RE
+.ft R
+.PP
+.ft R
+.ft R
+.RS "2m"
+.ft R
+OCAMLFIND_DESTDIR\c
+.RE
+.ft R
+.sp
+.RS "7m"
+.ft R
+.ft R
+This variable overrides the configuration variable\c
+\&
+\&
+destdir\c
+\&.
+\&
+\&
+.RE
+.ft R
+.PP
+.ft R
+.ft R
+.RS "2m"
+.ft R
+OCAMLFIND_METADIR\c
+.RE
+.ft R
+.sp
+.RS "7m"
+.ft R
+.ft R
+This variable overrides the configuration variable\c
+\&
+\&
+metadir\c
+\&.
+\&
+\&
+.RE
+.ft R
+.PP
+.ft R
+.ft R
+.RS "2m"
+.ft R
+OCAMLFIND_COMMANDS\c
+.RE
+.ft R
+.sp
+.RS "7m"
+.ft R
+.ft R
+This variable overrides the configuration variables\c
+\&
+\&
+ocamlc\c
+,
+ocamlopt\c
+,\c
+\&
+\&
+ocamlcp\c
+,
+ocamlmktop\c
+,\c
+\&
+\&
+ocamldoc\c
+,
+ocamldep\c
+, and/or\c
+\&
+\&
+ocamlbrowser\c
+\&.
+\&
+\& Its value must conform to the syntax\c
+\&
+\&
+\&
+.PP
+.ft R
+.ft B
+.nf
+ocamlc=\c
+.ft I
+name\c
+.ft B
+\&\ ocamlopt=\c
+.ft I
+name\c
+.ft B
+\&\ ocamlcp=\c
+.ft I
+name\c
+.ft B
+\&\ ocamlmktop=\c
+.ft I
+name\c
+.ft B
+\&\ ocamldoc=\c
+.ft I
+name\c
+.ft B
+\&\ ocamldep=\c
+.ft I
+name\c
+.ft B
+\&\ ocamlbrowser=\c
+.ft I
+name\c
+.ft B
+.ft R
+.fi
+\&
+\&
+.PP
+.ft R
+Example:\c
+\&
+\&
+.PP
+.ft R
+.ft B
+.nf
+ocamlc=ocamlc-3.00\ ocamlopt=ocamlopt-3.00\ ocamlcp=ocamlcp-3.00\ ocamlmktop=ocamlmktop-3.00\c
+.ft R
+.fi
+\&
+\&
+.RE
+.ft R
+.PP
+.ft R
+.ft R
+.RS "2m"
+.ft R
+CAMLLIB\c
+\& or
+OCAMLLIB\c
+.RE
+.ft R
+.sp
+.RS "7m"
+.ft R
+.ft R
+This variable overrides the configuration variable\c
+\&
+\&
+stdlib\c
+\&.
+\&
+\&
+.RE
+.ft R
+.PP
+.ft R
+.ft R
+.RS "2m"
+.ft R
+OCAMLFIND_LDCONF\c
+.RE
+.ft R
+.sp
+.RS "7m"
+.ft R
+.ft R
+This variable overrides the configuration variable\c
+\&
+\&
+ldconf\c
+\&.
+\&
+\&
+.RE
+.ft R
+.PP
+.ft R
+.ft R
+.RS "2m"
+.ft R
+OCAMLFIND_IGNORE_DUPS_IN\c
+.RE
+.ft R
+.sp
+.RS "7m"
+.ft R
+.ft R
+This variable instructs findlib not to emit warnings that packages\c
+\&
+\& or module occur several times. The variable must be set to the\c
+\&
+\& directory where the packages reside that are to be ignored for this\c
+\&
+\& warning.\c
+\&
+\&
+.RE
+.ft R
+.PP
+.ft R
diff --git a/local-packages/ocamlfind/doc/ref-man/ocamlfind.1 b/local-packages/ocamlfind/doc/ref-man/ocamlfind.1
new file mode 100644
index 0000000..ac59463
--- /dev/null
+++ b/local-packages/ocamlfind/doc/ref-man/ocamlfind.1
@@ -0,0 +1,2853 @@
+.TH "ocamlfind" "1" "The findlib package manager for OCaml" "User Manual"
+.SH "NAME"
+.ft R
+ocamlfind - [Command-line interface of the Package manager]\c
+.SH "SYNOPSIS"
+.ft R
+.ft R
+.ft B
+.nf
+\&\ \ \ \ \ \ \ ocamlfind\ query\ [-help\ |\ other\ options]\ \c
+.ft I
+package_name\c
+.ft B
+\&\ ...\c
+\&
+.br
+\&\ \ \ or:\ ocamlfind\ ocamlc\ [-help\ |\ other\ options]\ \c
+.ft I
+file\c
+.ft B
+\&\ ...\c
+\&
+.br
+\&\ \ \ or:\ ocamlfind\ ocamlcp\ [-help\ |\ other\ options]\ \c
+.ft I
+file\c
+.ft B
+\&\ ...\c
+\&
+.br
+\&\ \ \ or:\ ocamlfind\ ocamlmktop\ [-help\ |\ other\ options]\ \c
+.ft I
+file\c
+.ft B
+\&\ ...\c
+\&
+.br
+\&\ \ \ or:\ ocamlfind\ ocamlopt\ [-help\ |\ other\ options]\ \c
+.ft I
+file\c
+.ft B
+\&\ ...\c
+\&
+.br
+\&\ \ \ or:\ ocamlfind\ ocamldoc\ [-help\ |\ other\ options]\ \c
+.ft I
+file\c
+.ft B
+\&\ ...\c
+\&
+.br
+\&\ \ \ or:\ ocamlfind\ ocamldep\ [-help\ |\ other\ options]\ \c
+.ft I
+file\c
+.ft B
+\&\ ...\c
+\&
+.br
+\&\ \ \ or:\ ocamlfind\ ocamlmklib\ [-help\ |\ other\ options]\ \c
+.ft I
+file\c
+.ft B
+\&\ ...\c
+\&
+.br
+\&\ \ \ or:\ ocamlfind\ ocamlbrowser\ [-help\ |\ other\ options]\c
+\&
+.br
+\&\ \ \ or:\ ocamlfind\ install\ [-help\ |\ other\ options]\ \c
+.ft I
+package_name\c
+.ft B
+\&\ \c
+.ft I
+file\c
+.ft B
+\&\ ...\c
+\&
+.br
+\&\ \ \ or:\ ocamlfind\ remove\ [-help\ |\ other\ options]\ \c
+.ft I
+package_name\c
+.ft B
+\&
+.br
+\&\ \ \ or:\ ocamlfind\ lint\ \c
+.ft I
+META\c
+.ft B
+\&
+.br
+\&\ \ \ or:\ ocamlfind\ list\ [-describe]\c
+\&
+.br
+\&\ \ \ or:\ ocamlfind\ printppx\ [-help\ |\ other\ options]\ \c
+.ft I
+package_name\c
+.ft B
+\&\ ...\c
+\&
+.br
+\&\ \ \ or:\ ocamlfind\ printconf\ [\ variable\ ]\c
+\&
+.br
+\&\ \ \ or:\ ocamlfind\ \c
+.ft I
+package\c
+.ft B
+/\c
+.ft I
+command\c
+.ft B
+\&\ \c
+.ft I
+arg\c
+.ft B
+\&\ ...\c
+\&
+.br
+\&
+.br
+Optional\ toolchain\ selection\ by:\c
+\&
+.br
+\&\ \ ocamlfind\ -toolchain\ \c
+.ft I
+name\c
+.ft B
+\&\ ...\c
+.ft R
+.fi
+.SH "THE 'query' SUBCOMMAND"
+.ft R
+.SS "Synopsis"
+.ft R
+.ft R
+.ft B
+.nf
+ocamlfind\ query\ [\ -predicates\ \c
+.ft I
+p\c
+.ft B
+\&\ \ |\ \c
+\&
+.br
+\&\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ -format\ \c
+.ft I
+f\c
+.ft B
+\&\ |\c
+\&
+.br
+\&\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ -long-format\ |\ -l\ |\c
+\&
+.br
+\&\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ -i-format\ |\c
+\&
+.br
+\&\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ -l-format\ |\ \c
+\&
+.br
+\&\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ -a-format\ |\c
+\&
+.br
+\&\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ -o-format\ |\ \c
+\&
+.br
+\&\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ -p-format\ |\c
+\&
+.br
+\&\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ -prefix\ \c
+.ft I
+p\c
+.ft B
+\&\ |\c
+\&
+.br
+\&\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ -separator\ \c
+.ft I
+s\c
+.ft B
+\&\ |\ \c
+\&
+.br
+\&\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ -suffix\ \c
+.ft I
+s\c
+.ft B
+\&\ |\c
+\&
+.br
+\&\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ -pp\ |\c
+\&
+.br
+\&\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ -descendants\ |\ -d\ |\c
+\&
+.br
+\&\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ -recursive\ \ |\ -r\c
+\&
+.br
+\&\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ -qe\ |\ -qo]\ \c
+.ft I
+package\c
+.ft B
+\&\ ...\c
+.ft R
+.fi
+.SS "Description"
+.ft R
+.ft R
+This command looks packages up, sorts them optionally, and\c
+\&
+prints attributes of them. If the option -recursive (short: -r) is not\c
+\&
+specified, exactly the packages given on the command line are looked\c
+\&
+up; if -recursive is present, the packages and all their ancestors, or\c
+\&
+if -descendants (short: -d) is present, too, all their descendants are printed.\c
+.PP
+.ft R
+Package lookup and the selection of the attributes of the packages can\c
+\&
+be modified by specifying predicates; without a -predicates option the\c
+\&
+empty set of predicates is used. Note that even the lookup is\c
+\&
+influenced by the set of actual predicates as the "requires" variables\c
+\&
+may be conditional.\c
+.PP
+.ft R
+What is printed about a package depends on the specified format; there\c
+\&
+are a number of options that modify the format. Some formats denote\c
+\&
+sets of values (such as -format %a), in which case multiple output\c
+\&
+records are printed for every package. (It is even possible to specify\c
+\&
+formats denoting the Cartesian product of sets, such as -format %a%o,\c
+\&
+but this does not make sense.) Before the first output record the\c
+\&
+prefix is printed, and the suffix after the last record. Between two\c
+\&
+records the separator is printed.\c
+.SS "Options"
+.ft R
+.ft R
+.RS "2m"
+.ft R
+-predicates
+.ft I
+p\c
+.ft R
+.RE
+.ft R
+.sp
+.RS "7m"
+.ft R
+.ft R
+Sets the set of actual predicates. The argument\c
+\&
+\&
+.ft I
+p\c
+.ft R
+\& is a list of predicate names separated\c
+\&
+\& by commas and/or whitespace. If multiple -predicates options are\c
+\&
+\& given, the union of all specified sets is effectively used.\c
+.RE
+.ft R
+.sp
+.RS "2m"
+.ft R
+-format
+.ft I
+f\c
+.ft R
+.RE
+.ft R
+.sp
+.RS "7m"
+.ft R
+.ft R
+Sets the format to the string\c
+\&
+\&
+.ft I
+f\c
+.ft R
+\&. Characters preceded by a percent sign\c
+\&
+\& are interpreted as placeholders; all other characters mean\c
+\&
+\& themselves. The defined placeholders are listed below.\c
+\&
+\& The default format is "%d".\c
+.RE
+.ft R
+.sp
+.RS "2m"
+.ft R
+-long-format or -l\c
+.RE
+.ft R
+.sp
+.RS "7m"
+.ft R
+.ft R
+Sets the format such that all relevant variables are printed.\c
+.RE
+.ft R
+.sp
+.RS "2m"
+.ft R
+-i-format\c
+.RE
+.ft R
+.sp
+.RS "7m"
+.ft R
+.ft R
+Same as -format "-I %d", i.e. directory options for ocamlc are printed.\c
+.RE
+.ft R
+.sp
+.RS "2m"
+.ft R
+-l-format\c
+.RE
+.ft R
+.sp
+.RS "7m"
+.ft R
+.ft R
+Same as -format "-ccopt -L%d", i.e. directory options for the\c
+\&
+linker backend are printed.\c
+.RE
+.ft R
+.sp
+.RS "2m"
+.ft R
+-a-format\c
+.RE
+.ft R
+.sp
+.RS "7m"
+.ft R
+.ft R
+Same as -format "%+a", i.e. archive file names are printed.\c
+.RE
+.ft R
+.sp
+.RS "2m"
+.ft R
+-o-format\c
+.RE
+.ft R
+.sp
+.RS "7m"
+.ft R
+.ft R
+Same as -format "%o", i.e. linker options are printed.\c
+.RE
+.ft R
+.sp
+.RS "2m"
+.ft R
+-p-format\c
+.RE
+.ft R
+.sp
+.RS "7m"
+.ft R
+.ft R
+Same as -format "%p", i.e. package names are printed.\c
+.RE
+.ft R
+.sp
+.RS "2m"
+.ft R
+-prefix
+.ft I
+p\c
+.ft R
+.RE
+.ft R
+.sp
+.RS "7m"
+.ft R
+.ft R
+Sets the prefix that is printed before the first output record\c
+\&
+\& to the given string. The default prefix is the empty string.\c
+.RE
+.ft R
+.sp
+.RS "2m"
+.ft R
+-suffix
+.ft I
+s\c
+.ft R
+.RE
+.ft R
+.sp
+.RS "7m"
+.ft R
+.ft R
+Sets the suffix that is printed after the last output record\c
+\&
+\& to the given string. The default suffix is the empty string.\c
+.RE
+.ft R
+.sp
+.RS "2m"
+.ft R
+-separator
+.ft I
+s\c
+.ft R
+.RE
+.ft R
+.sp
+.RS "7m"
+.ft R
+.ft R
+Sets the separator that is printed between output records to\c
+\&
+\& the given string. The default separator is a linefeed character.\c
+.RE
+.ft R
+.sp
+.RS "2m"
+.ft R
+-recursive or -r\c
+.RE
+.ft R
+.sp
+.RS "7m"
+.ft R
+.ft R
+Not only the packages given on the command line are queried\c
+\&
+\& but also all ancestors or descendants. If the option -descendants is\c
+\&
+\& specified, too, the descendants are printed, otherwise the\c
+\&
+\& ancestors. The packages are topologically sorted.\c
+.RE
+.ft R
+.sp
+.RS "2m"
+.ft R
+-descendants -d\c
+.RE
+.ft R
+.sp
+.RS "7m"
+.ft R
+.ft R
+Instead of the ancestors the descendants of the\c
+\&
+\& given packages are queried. This option implies
+-recursive\c
+\&.\c
+.RE
+.ft R
+.sp
+.RS "2m"
+.ft R
+-pp\c
+.RE
+.ft R
+.sp
+.RS "7m"
+.ft R
+.ft R
+Query preprocessor packages (camlp4 syntax extensions). Normally\c
+\&
+it is not needed to set -predicates, except you need the archives (then add\c
+\&
+-predicates byte). This option implies
+-recursive\c
+\&.\c
+.RE
+.ft R
+.sp
+.RS "2m"
+.ft R
+-qe\c
+.RE
+.ft R
+.sp
+.RS "7m"
+.ft R
+.ft R
+Do not print most errors to stderr, just set the exit code\c
+.RE
+.ft R
+.sp
+.RS "2m"
+.ft R
+-qo\c
+.RE
+.ft R
+.sp
+.RS "7m"
+.ft R
+.ft R
+Do not print the regular output.\c
+.RE
+.ft R
+.PP
+.ft R
+.SS "Placeholders meaningful in the -format option"
+.ft R
+.ft R
+.RS "2m"
+.ft R
+%%\c
+.RE
+.ft R
+.sp
+.RS "7m"
+.ft R
+.ft R
+Replaced by a single percent sign\c
+.RE
+.ft R
+.sp
+.RS "2m"
+.ft R
+%p\c
+.RE
+.ft R
+.sp
+.RS "7m"
+.ft R
+.ft R
+Replaced by the package name\c
+.RE
+.ft R
+.sp
+.RS "2m"
+.ft R
+%d\c
+.RE
+.ft R
+.sp
+.RS "7m"
+.ft R
+.ft R
+Replaced by the package directory\c
+.RE
+.ft R
+.sp
+.RS "2m"
+.ft R
+%m\c
+.RE
+.ft R
+.sp
+.RS "7m"
+.ft R
+.ft R
+Replaced by the path to the META file (new since findlib-1.6)\c
+.RE
+.ft R
+.sp
+.RS "2m"
+.ft R
+%D\c
+.RE
+.ft R
+.sp
+.RS "7m"
+.ft R
+.ft R
+Replaced by the package description\c
+.RE
+.ft R
+.sp
+.RS "2m"
+.ft R
+%v\c
+.RE
+.ft R
+.sp
+.RS "7m"
+.ft R
+.ft R
+Replaced by the version string\c
+.RE
+.ft R
+.sp
+.RS "2m"
+.ft R
+%a\c
+.RE
+.ft R
+.sp
+.RS "7m"
+.ft R
+.ft R
+Replaced by the archive filename. If there is more\c
+\&
+\& than one archive, a separate output record is printed for every archive.\c
+.RE
+.ft R
+.sp
+.RS "2m"
+.ft R
+%+a\c
+.RE
+.ft R
+.sp
+.RS "7m"
+.ft R
+.ft R
+Like %a, but the filenames are converted to absolute\c
+\&
+\& paths ("+" and "@" notations are resolved)\c
+.RE
+.ft R
+.sp
+.RS "2m"
+.ft R
+%A\c
+.RE
+.ft R
+.sp
+.RS "7m"
+.ft R
+.ft R
+Replaced by the list of archive filenames.\c
+.RE
+.ft R
+.sp
+.RS "2m"
+.ft R
+%+A\c
+.RE
+.ft R
+.sp
+.RS "7m"
+.ft R
+.ft R
+Like %A, but the filenames are converted to absolute\c
+\&
+\& paths ("+" and "@" notations are resolved)\c
+.RE
+.ft R
+.sp
+.RS "2m"
+.ft R
+%o\c
+.RE
+.ft R
+.sp
+.RS "7m"
+.ft R
+.ft R
+Replaced by one linker option. If there is more than\c
+\&
+\& one option, a separate output record is printed for every option.\c
+.RE
+.ft R
+.sp
+.RS "2m"
+.ft R
+%O\c
+.RE
+.ft R
+.sp
+.RS "7m"
+.ft R
+.ft R
+Replaced by the list of linker options.\c
+.RE
+.ft R
+.sp
+.RS "2m"
+.ft R
+%(\c
+.ft I
+property\c
+.ft R
+)\c
+.RE
+.ft R
+.sp
+.RS "7m"
+.ft R
+.ft R
+Replaced by the value of the property named in parentheses,\c
+\&
+or the empty string if not defined.\c
+.RE
+.ft R
+.PP
+.ft R
+.SH "THE SUBCOMMANDS 'ocamlc', 'ocamlcp', 'ocamlopt', and 'ocamlmktop'"
+.ft R
+.SS "Synopsis"
+.ft R
+.ft R
+.ft B
+.nf
+ocamlfind\ (\ ocamlc\ |\ ocamlcp\ |\ ocamlopt\ |\ ocamlmktop\ )\c
+\&
+.br
+\&\ \ \ \ \ \ \ \ \ \ [\ -package\ \c
+.ft I
+package-name-list\c
+.ft B
+\&\ |\c
+\&
+.br
+\&\ \ \ \ \ \ \ \ \ \ \ \ -linkpkg\ |\c
+\&
+.br
+\&\ \ \ \ \ \ \ \ \ \ \ \ -predicates\ \c
+.ft I
+pred-name-list\c
+.ft B
+\&\ |\c
+\&
+.br
+\&\ \ \ \ \ \ \ \ \ \ \ \ -dontlink\ \c
+.ft I
+package-name-list\c
+.ft B
+\&\ |\c
+\&
+.br
+\&\ \ \ \ \ \ \ \ \ \ \ \ -syntax\ \c
+.ft I
+pred-name-list\c
+.ft B
+\&\ |\c
+\&
+.br
+\&\ \ \ \ \ \ \ \ \ \ \ \ -ppopt\ \c
+.ft I
+camlp4-arg\c
+.ft B
+\&\ |\c
+\&
+.br
+\&\ \ \ \ \ \ \ \ \ \ \ \ -ppxopt\ \c
+.ft I
+package\c
+.ft B
+,\c
+.ft I
+arg\c
+.ft B
+\&\ |\c
+\&
+.br
+\&\ \ \ \ \ \ \ \ \ \ \ \ -dllpath-pkg\ \c
+.ft I
+package-name-list\c
+.ft B
+\&\ |\c
+\&
+.br
+\&\ \ \ \ \ \ \ \ \ \ \ \ -dllpath-all\ |\c
+\&
+.br
+\&\ \ \ \ \ \ \ \ \ \ \ \ -passopt\ \c
+.ft I
+arg\c
+.ft B
+\&\ |\c
+\&
+.br
+\&\ \ \ \ \ \ \ \ \ \ \ \ -passrest\ \c
+.ft I
+arg...\c
+.ft B
+\&\ |\c
+\&
+.br
+\&\ \ \ \ \ \ \ \ \ \ \ \ -only-show\ |\c
+\&
+.br
+\&\ \ \ \ \ \ \ \ \ \ \ \ \c
+.ft I
+standard-option\c
+.ft B
+\&\ ]\c
+\&
+.br
+\&\ \ \ \ \ \ \ \ \ \ \c
+.ft I
+file\c
+.ft B
+\&\ ...\c
+.ft R
+.fi
+.SS "Description"
+.ft R
+.ft R
+These subcommands are drivers for the compilers with the same names,\c
+\&
+i.e. "ocamlfind ocamlc" is a driver for "ocamlc", and so on. The\c
+\&
+subcommands understand all documented options of the compilers (here\c
+\&
+called
+.ft I
+standard-options\c
+.ft R
+), but also a few\c
+\&
+more options. If these subcommands are invoked only with standard\c
+\&
+options, they behave as if the underlying compiler had been called\c
+\&
+directly. The extra options modify this.\c
+.PP
+.ft R
+Internally, these subcommands transform the given list of options and\c
+\&
+file arguments into an invocation of the driven compiler. This\c
+\&
+transformation only adds options and files, and the relative order of\c
+\&
+the options and files passed directly is unchanged.\c
+.PP
+.ft R
+If there are -package options, additional directory search specifiers\c
+\&
+will be included ("-I", and "-ccopt -I"), such that files of all named\c
+\&
+packages and all ancestors can be found.\c
+.PP
+.ft R
+The -linkpkg option causes that the packages listed in the -package\c
+\&
+options and all necessary ancestors are linked in. This means that the\c
+\&
+archive files implementing the packages are inserted into the list of\c
+\&
+file arguments.\c
+.PP
+.ft R
+As the package database is queried a set of predicates is needed. Most\c
+\&
+predicates are set automatically, see below, but additional predicates\c
+\&
+can be given by a -predicates option.\c
+.PP
+.ft R
+If there is a
+-syntax\c
+\& option, the drivers assume that\c
+\&
+a preprocessor is to be used. In this case, the preprocessor command\c
+\&
+is built first in a preprocessor stage, and this command is passed to the\c
+\&
+compiler using the
+-pp\c
+\& option. The set of predicates\c
+\&
+in the preprocessor stage is different from the set in the compiler/linker\c
+\&
+stage.\c
+.SS "Options for compiling and linking"
+.ft R
+.ft R
+Here, only the additional options not interpreted by the compiler but\c
+\&
+by the driver itself, and options with additional effects are explained.\c
+\&
+Some options are only meaningful for the preprocessor call, and are\c
+\&
+explained below.\c
+.PP
+.ft R
+.RS "2m"
+.ft R
+-package
+.ft I
+package-name-list\c
+.ft R
+.RE
+.ft R
+.sp
+.RS "7m"
+.ft R
+.ft R
+Adds the listed package names to the set of included\c
+\&
+\& packages. The package names may be separated by commas and/or\c
+\&
+\& whitespace. In the transformed command, for every package of the set\c
+\&
+\& of included packages and for any ancestor a directory search option\c
+\&
+\& is inserted after the already given options. This means that\c
+\&
+\& "-I" and "-ccopt -I" options are added for every package directory.\c
+\&
+\&
+.RE
+.ft R
+.sp
+.RS "2m"
+.ft R
+-linkpkg\c
+.RE
+.ft R
+.sp
+.RS "7m"
+.ft R
+.ft R
+Causes that in the transformed command all archives\c
+\&
+\& of the packages specified by -packages and all their ancestors are\c
+\&
+\& added to the file arguments. More precisely, these archives are\c
+\&
+\& inserted before the first given file argument. Furthermore, "-ccopt\c
+\&
+\& -L" options for all package directories, and the linker options of\c
+\&
+\& the selected packages are added, too. Note that the archives are\c
+\&
+\& inserted in topological order while the linker options are added in\c
+\&
+\& reverse toplogical order.\c
+.RE
+.ft R
+.sp
+.RS "2m"
+.ft R
+-predicates
+.ft I
+pred-name-list\c
+.ft R
+.RE
+.ft R
+.sp
+.RS "7m"
+.ft R
+.ft R
+Adds the given predicates to the set of actual\c
+\&
+\& predicates. The predicates must be separated by commas and/or\c
+\&
+\& whitespace.
+.RE
+.ft R
+.sp
+.RS "2m"
+.ft R
+-dontlink
+.ft I
+package-name-list\c
+.ft R
+.RE
+.ft R
+.sp
+.RS "7m"
+.ft R
+.ft R
+This option modifies the behaviour of\c
+\&
+\& -linkpkg. Packages specified here and all ancestors are not linked\c
+\&
+\& in. Again the packages are separated by commas and/or whitespace.\c
+.RE
+.ft R
+.sp
+.RS "2m"
+.ft R
+-dllpath-pkg
+.ft I
+package-name-list\c
+.ft R
+.RE
+.ft R
+.sp
+.RS "7m"
+.ft R
+.ft R
+For these packages
+-dllpath\c
+\& options\c
+\&
+\& are added to the compiler command. This may be useful when the ld.conf\c
+\&
+\& file is not properly configured.\c
+.RE
+.ft R
+.sp
+.RS "2m"
+.ft R
+-dllpath-all\c
+.RE
+.ft R
+.sp
+.RS "7m"
+.ft R
+.ft R
+For all linked packages
+-dllpath\c
+\& options\c
+\&
+\& are added to the compiler command. This may be useful when the ld.conf\c
+\&
+\& file is not properly configured.\c
+.RE
+.ft R
+.sp
+.RS "2m"
+.ft R
+-passopt
+.ft I
+arg\c
+.ft R
+.RE
+.ft R
+.sp
+.RS "7m"
+.ft R
+.ft R
+The argument
+.ft I
+arg\c
+.ft R
+\& is\c
+\&
+\& passed directly to the underlying compiler. This is needed to\c
+\&
+\& specify undocumented compiler options.\c
+.RE
+.ft R
+.sp
+.RS "2m"
+.ft R
+-passrest
+.ft I
+arg...\c
+.ft R
+.RE
+.ft R
+.sp
+.RS "7m"
+.ft R
+.ft R
+All following arguments
+.ft I
+arg...\c
+.ft R
+\& are\c
+\&
+\& passed directly to the underlying compiler. This is needed to\c
+\&
+\& specify undocumented compiler options.\c
+.RE
+.ft R
+.sp
+.RS "2m"
+.ft R
+-only-show\c
+.RE
+.ft R
+.sp
+.RS "7m"
+.ft R
+.ft R
+Only prints the constructed command (ocamlc/ocamlopt) to\c
+\&
+\& stdout, but does not execute the command. (This is for the unlikely event\c
+\&
+\& that you need a wrapper around ocamlfind.)\c
+.RE
+.ft R
+.sp
+.RS "2m"
+.ft R
+-verbose\c
+.RE
+.ft R
+.sp
+.RS "7m"
+.ft R
+.ft R
+This standard option is interpreted by the driver, too.\c
+.RE
+.ft R
+.sp
+.RS "2m"
+.ft R
+-thread\c
+.RE
+.ft R
+.sp
+.RS "7m"
+.ft R
+.ft R
+This standard option causes that the predicate "mt"\c
+\&
+\& is added to the set of actual predicates. If POSIX threads are available,\c
+\&
+\& the predicate "mt_posix" is selected, too. If only VM threads are\c
+\&
+\& available, the predicate "mt_vm" is included into the set, and the\c
+\&
+\& compiler switch is changed into -vmthread.\c
+.PP
+.ft R
+Note that the presence of the "mt" predicate triggers special\c
+\&
+fixup of the dependency graph (see below).\c
+.RE
+.ft R
+.sp
+.RS "2m"
+.ft R
+-vmthread\c
+.RE
+.ft R
+.sp
+.RS "7m"
+.ft R
+.ft R
+This standard option causes that the predicates "mt"\c
+\&
+\& and "mt_vm" are added to the set of actual predicates.\c
+.PP
+.ft R
+Note that the presence of the "mt" predicate triggers special\c
+\&
+fixup of the dependency graph (see below).\c
+.RE
+.ft R
+.sp
+.RS "2m"
+.ft R
+-p\c
+.RE
+.ft R
+.sp
+.RS "7m"
+.ft R
+.ft R
+This standard option of "ocamlopt" causes that the\c
+\&
+\& predicate "gprof" is added to the set of actual predicates.\c
+.RE
+.ft R
+.PP
+.ft R
+.SS "Options for preprocessing"
+.ft R
+.ft R
+The options relevant for the preprocessor are the following:\c
+.PP
+.ft R
+.RS "2m"
+.ft R
+-package
+.ft I
+package-name-list\c
+.ft R
+.RE
+.ft R
+.sp
+.RS "7m"
+.ft R
+.ft R
+These packages are considered while looking up the\c
+\&
+\& preprocessor arguments. (It does not cause problems that the same\c
+\&
+\& -package option is used for this purpose, because the set of predicates\c
+\&
+\& is different.) It is recommended to mention at least
+camlp4\c
+\&
+\& here if the preprocessor is going to be used.\c
+\&
+\&
+.RE
+.ft R
+.sp
+.RS "2m"
+.ft R
+-syntax
+.ft I
+pred-name-list\c
+.ft R
+.RE
+.ft R
+.sp
+.RS "7m"
+.ft R
+.ft R
+These predicates are assumed to be true in addition\c
+\&
+\& to the standard preprocessor predicates. See below for a list.\c
+.RE
+.ft R
+.sp
+.RS "2m"
+.ft R
+-ppopt
+.ft I
+camlp4-arg\c
+.ft R
+.RE
+.ft R
+.sp
+.RS "7m"
+.ft R
+.ft R
+This argument is passed to the camlp4 call.\c
+\&
+\&
+.RE
+.ft R
+.sp
+.RS "2m"
+.ft R
+-ppxopt
+.ft I
+package\c
+.ft R
+,\c
+.ft I
+arg\c
+.ft R
+.RE
+.ft R
+.sp
+.RS "7m"
+.ft R
+.ft R
+Add
+.ft I
+arg\c
+.ft R
+\& to the ppx\c
+\&
+\& preprocessor invocation specified via the "ppx" property in\c
+\&
+\& the META file of
+.ft I
+package\c
+.ft R
+\&.\c
+\&
+\&
+.RE
+.ft R
+.PP
+.ft R
+.SS "Predicates for compiling and linking"
+.ft R
+.ft R
+.RS "2m"
+.ft R
+byte\c
+.RE
+.ft R
+.sp
+.RS "7m"
+.ft R
+.ft R
+The "byte" predicate means that one of the bytecode compilers is\c
+\&
+used. It is automatically included into the predicate set if the\c
+\&
+"ocamlc", "ocamlcp", or "ocamlmktop" compiler is used.\c
+.RE
+.ft R
+.sp
+.RS "2m"
+.ft R
+native\c
+.RE
+.ft R
+.sp
+.RS "7m"
+.ft R
+.ft R
+The "native" predicate means that the native compiler is used. It is\c
+\&
+automatically included into the predicate set if the "ocamlopt"\c
+\&
+compiler is used.\c
+.RE
+.ft R
+.sp
+.RS "2m"
+.ft R
+toploop\c
+.RE
+.ft R
+.sp
+.RS "7m"
+.ft R
+.ft R
+The "toploop" predicate means that the toploop is available in the\c
+\&
+linked program. This predicate is only set when the toploop is actually\c
+\&
+being executed, not when the toploop is created (this changed in version\c
+\&
+1.0.4 of findlib).\c
+.RE
+.ft R
+.sp
+.RS "2m"
+.ft R
+create_toploop\c
+.RE
+.ft R
+.sp
+.RS "7m"
+.ft R
+.ft R
+This predicate means that a toploop is being created (using\c
+\&
+ocamlmktop).\c
+.RE
+.ft R
+.sp
+.RS "2m"
+.ft R
+mt\c
+.RE
+.ft R
+.sp
+.RS "7m"
+.ft R
+.ft R
+The "mt" predicate means that the program is multi-threaded. It is\c
+\&
+automatically included into the predicate set if the -thread option is\c
+\&
+given.
+.RE
+.ft R
+.sp
+.RS "2m"
+.ft R
+mt_posix\c
+.RE
+.ft R
+.sp
+.RS "7m"
+.ft R
+.ft R
+The "mt_posix" predicate means that in the case "mt" is set, too, the\c
+\&
+POSIX libraries are used to implement threads. "mt_posix" is automatically\c
+\&
+included into the predicate set if the variable "type_of_threads" in the\c
+\&
+META description of the "threads" package has the value "posix". This\c
+\&
+is normally the case if "findlib" is configured for POSIX threads.\c
+.RE
+.ft R
+.sp
+.RS "2m"
+.ft R
+mt_vm\c
+.RE
+.ft R
+.sp
+.RS "7m"
+.ft R
+.ft R
+The "mt_vm" predicate means that in the case "mt" is set, too, the\c
+\&
+VM thread emulation is used to implement multi-threading.\c
+.RE
+.ft R
+.sp
+.RS "2m"
+.ft R
+gprof\c
+.RE
+.ft R
+.sp
+.RS "7m"
+.ft R
+.ft R
+The "gprof" predicate means that in the case "native" is set, too, the\c
+\&
+program is compiled for profiling. It is automatically included into\c
+\&
+the predicate set if "ocamlopt" is used and the -p option is in\c
+\&
+effect.\c
+.RE
+.ft R
+.sp
+.RS "2m"
+.ft R
+autolink\c
+.RE
+.ft R
+.sp
+.RS "7m"
+.ft R
+.ft R
+The "autolink" predicate means that ocamlc is able to perform automatic\c
+\&
+linking. It is automatically included into the predicate set if ocamlc\c
+\&
+knows automatic linking (from version 3.00), but it is not set if the\c
+\&
+-noautolink option is set.\c
+.RE
+.ft R
+.sp
+.RS "2m"
+.ft R
+syntax\c
+.RE
+.ft R
+.sp
+.RS "7m"
+.ft R
+.ft R
+This predicate is set if there is a
+-syntax\c
+\&
+\& option. It is set both for the preprocessor and the compiler/linker stage,\c
+\&
+\& and it can be used to find out whether the preprocessor is enabled or not.\c
+\&
+\&
+.RE
+.ft R
+.PP
+.ft R
+.SS "Predicates for preprocessing"
+.ft R
+.ft R
+.RS "2m"
+.ft R
+preprocessor\c
+.RE
+.ft R
+.sp
+.RS "7m"
+.ft R
+.ft R
+This predicate is always set while looking up the\c
+\&
+\& preprocessor arguments. It can be used to distinguish between the\c
+\&
+\& preprocessor stage and the compiler/linker stage.\c
+.RE
+.ft R
+.sp
+.RS "2m"
+.ft R
+syntax\c
+.RE
+.ft R
+.sp
+.RS "7m"
+.ft R
+.ft R
+This predicate is set if there is a
+-syntax\c
+\&
+\& option. It is set both for the preprocessor and the compiler/linker stage,\c
+\&
+\& and it can be used to find out whether the preprocessor is enabled or not.\c
+\&
+\&
+.RE
+.ft R
+.sp
+.RS "2m"
+.ft R
+camlp4o\c
+.RE
+.ft R
+.sp
+.RS "7m"
+.ft R
+.ft R
+This is the reserved predicate for the standard OCaml syntax.\c
+\&
+\& It can be used in the
+-syntax\c
+\& predicate list.\c
+\&
+\&
+.RE
+.ft R
+.sp
+.RS "2m"
+.ft R
+camlp4r\c
+.RE
+.ft R
+.sp
+.RS "7m"
+.ft R
+.ft R
+This is the reserved predicate for the revised OCaml syntax.\c
+\&
+\& It can be used in the
+-syntax\c
+\& predicate list.\c
+\&
+\&
+.RE
+.ft R
+.PP
+.ft R
+.SS "Special behaviour of 'ocamlmktop'"
+.ft R
+.ft R
+As there is a special module
+Topfind\c
+\& that\c
+\&
+supports loading of packages in scripts, the "ocamlmktop" subcommand\c
+\&
+can add initialization code for this module. This extra code is\c
+\&
+linked into the executable if "findlib" is in the set of effectively\c
+\&
+linked packages.
+.SS "Fixup of the dependency graph for multi-threading"
+.ft R
+.ft R
+For a number of reasons the presence of the "mt" predicate triggers\c
+\&
+that (1) the package "threads" is added to the list of required packages\c
+\&
+and (2) the package "threads" becomes prerequisite of all other packages\c
+\&
+(except of itself and a few hardcoded exceptions). The effect is that\c
+\&
+the options -thread and -vmthread automatically select the "threads"\c
+\&
+package, and that "threads" is inserted at the right position in the\c
+\&
+package list.\c
+.SS "Extended file naming"
+.ft R
+.ft R
+At a number of places one can not only refer to files by absolute\c
+\&
+or relative path names, but also by extended names. These have two\c
+\&
+major forms: "+\c
+.ft I
+name\c
+.ft R
+"\c
+\&
+refers to the subdirectory
+.ft I
+name\c
+.ft R
+\& of the\c
+\&
+standard library directory, and "@\c
+.ft I
+name\c
+.ft R
+"\c
+\&
+refers to the package directory of the package
+.ft I
+name\c
+.ft R
+\&.\c
+\&
+Both forms can be continued by a path, e.g. "@netstring/netstring_top.cma".\c
+.PP
+.ft R
+You can use extended names: (1) With
+-I\c
+\& options,\c
+\&
+(2) as normal file arguments of the compiler, (3) in the
+\&
+"archive" property of packages.\c
+.SS "How to set the names of the compiler executables"
+.ft R
+.ft R
+Normally, the OCaml bytecode compiler can be called under the name\c
+\&
+ocamlc\c
+\&. However, this is not always true; sometimes a\c
+\&
+different name is chosen.\c
+.PP
+.ft R
+You can instruct ocamlfind to call executables with other names than\c
+\&
+ocamlc\c
+,
+ocamlopt\c
+,\c
+\&
+ocamlmktop\c
+, and
+ocamlcp\c
+\&. If present,\c
+\&
+the environment variable
+OCAMLFIND_COMMANDS\c
+\& is interpreted\c
+\&
+as a mapping from the standard names to the actual names of the executables. It\c
+\&
+must have the following format:\c
+\&
+\&
+.PP
+.ft R
+.ft B
+.nf
+.ft I
+standardname1\c
+.ft B
+=\c
+.ft I
+actualname1\c
+.ft B
+\&\ \c
+.ft I
+standardname2\c
+.ft B
+=\c
+.ft I
+actualname2\c
+.ft B
+\&\ ...\c
+.ft R
+.fi
+.PP
+.ft R
+Example: You may set
+OCAMLFIND_COMMANDS\c
+\& as follows:\c
+\&
+\&
+.PP
+.ft R
+.ft B
+.nf
+OCAMLFIND_COMMANDS='ocamlc=ocamlc-3.00\ ocamlopt=ocamlopt-3.00'\c
+\&
+.br
+export\ OCAMLFIND_COMMANDS\c
+.ft R
+.fi
+.PP
+.ft R
+Alternatively, you can change the configuration file\c
+\&
+findlib.conf\c
+\&.\c
+.SH "THE SUBCOMMAND 'ocamlmklib'"
+.ft R
+.SS "Synopsis"
+.ft R
+.ft R
+.ft B
+.nf
+ocamlfind\ ocamlmklib\c
+\&
+.br
+\&\ \ \ \ \ \ \ \ \ \ [\ -package\ \c
+.ft I
+package-name-list\c
+.ft B
+\&\ |\c
+\&
+.br
+\&\ \ \ \ \ \ \ \ \ \ \ \ -predicates\ \c
+.ft I
+pred-name-list\c
+.ft B
+\&\ |\c
+\&
+.br
+\&\ \ \ \ \ \ \ \ \ \ \ \ -dllpath-pkg\ \c
+.ft I
+package-name-list\c
+.ft B
+\&\ |\c
+\&
+.br
+\&\ \ \ \ \ \ \ \ \ \ \ \ -dllpath-all\ |\c
+\&
+.br
+\&\ \ \ \ \ \ \ \ \ \ \ \ -passopt\ \c
+.ft I
+arg\c
+.ft B
+\&\ |\c
+\&
+.br
+\&\ \ \ \ \ \ \ \ \ \ \ \ -passrest\ \c
+.ft I
+arg...\c
+.ft B
+\&\ |\c
+\&
+.br
+\&\ \ \ \ \ \ \ \ \ \ \ \ \c
+.ft I
+standard-option\c
+.ft B
+\&\ ]\c
+\&
+.br
+\&\ \ \ \ \ \ \ \ \ \ \ \ \c
+.ft I
+file\c
+.ft B
+\&\ ...\c
+.ft R
+.fi
+.SS "Description"
+.ft R
+.ft R
+This is a wrapper around ocamlmklib, and creates library archives and\c
+\&
+DLLs. In addition to the standard options, one can use -package to\c
+\&
+add the search path of packages. Note that no predicates are set by default -\c
+\&
+the wrapper does not know whether this is about byte or native code linking.\c
+.PP
+.ft R
+This wrapper is mostly provided for completeness.\c
+.SH "THE 'ocamldep' SUBCOMMAND"
+.ft R
+.SS "Synopsis"
+.ft R
+.ft R
+.ft B
+.nf
+ocamlfind\ ocamldep\ [-package\ \c
+.ft I
+package-name-list\c
+.ft B
+\&\ |\c
+\&
+.br
+\&\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ -syntax\ \c
+.ft I
+pred-name-list\c
+.ft B
+\&\ |\c
+\&
+.br
+\&\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ -ppopt\ \c
+.ft I
+camlp4-arg\c
+.ft B
+\&\ |\c
+\&
+.br
+\&\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ -passopt\ \c
+.ft I
+arg\c
+.ft B
+\&\ |\c
+\&
+.br
+\&\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ -passrest\ \c
+.ft I
+arg...\c
+.ft B
+\&\ |\c
+\&
+.br
+\&\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ -verbose\ |\c
+\&
+.br
+\&\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \c
+.ft I
+standard-option\c
+.ft B
+]\ \c
+.ft I
+file\c
+.ft B
+\&\ ...\c
+.ft R
+.fi
+.SS "Description"
+.ft R
+.ft R
+This command is a driver for the tool
+ocamldep\c
+\& of the\c
+\&
+OCaml distribution. This driver is only useful in conjunction with\c
+\&
+the preprocessor camlp4; otherwise it does not provide more functions\c
+\&
+than
+ocamldep\c
+\& itself.\c
+.SS "Options"
+.ft R
+.ft R
+Here, only the additional options not interpreted by
+ocamldep\c
+\&
+but\c
+\&
+by the driver itself, and options with additional effects are explained.\c
+.PP
+.ft R
+.RS "2m"
+.ft R
+-package
+.ft I
+package-name-list\c
+.ft R
+.RE
+.ft R
+.sp
+.RS "7m"
+.ft R
+.ft R
+The packages named here are only used to look up the\c
+\&
+preprocessor options. The package
+camlp4\c
+\& should be\c
+\&
+specified anyway, but further packages that add capabilities to the\c
+\&
+preprocessor can also be passed.\c
+.RE
+.ft R
+.sp
+.RS "2m"
+.ft R
+-syntax
+.ft I
+pred-name-list\c
+.ft R
+.RE
+.ft R
+.sp
+.RS "7m"
+.ft R
+.ft R
+The predicates that are in effect during the look-up\c
+\&
+of the preprocessor options. At least, either
+camlp4o\c
+\&
+(selecting the normal syntax), or
+camlp4r\c
+\& (selecting\c
+\&
+the revised syntax) should be specified.\c
+.RE
+.ft R
+.sp
+.RS "2m"
+.ft R
+-ppopt
+.ft I
+camlp4-arg\c
+.ft R
+.RE
+.ft R
+.sp
+.RS "7m"
+.ft R
+.ft R
+An option that is passed through to the camlp4 call.\c
+.RE
+.ft R
+.sp
+.RS "2m"
+.ft R
+-passopt
+.ft I
+arg\c
+.ft R
+.RE
+.ft R
+.sp
+.RS "7m"
+.ft R
+.ft R
+An option that is passed through to the ocamldep call.\c
+.RE
+.ft R
+.sp
+.RS "2m"
+.ft R
+-passrest
+.ft I
+arg...\c
+.ft R
+.RE
+.ft R
+.sp
+.RS "7m"
+.ft R
+.ft R
+All further arguments are passed down to ocamldep\c
+\&
+\& unprocessed\c
+.RE
+.ft R
+.sp
+.RS "2m"
+.ft R
+-verbose\c
+.RE
+.ft R
+.sp
+.RS "7m"
+.ft R
+.ft R
+Displays the resulting ocamldep command (for debugging)\c
+.RE
+.ft R
+.PP
+.ft R
+.SS "Example"
+.ft R
+.ft R
+A typical way of using this driver:\c
+\&
+\&
+.PP
+.ft R
+.ft B
+.nf
+ocamlfind\ ocamldep\ -package\ camlp4,xstrp4\ -syntax\ camlp4r\ file1.ml\ file2.ml\c
+.ft R
+.fi
+\&
+\&
+This command outputs the dependencies of
+file1.ml\c
+\& and\c
+\&
+file2.ml\c
+, although these modules make use of the\c
+\&
+syntax extensions provided by
+xstrp4\c
+\& and are written\c
+\&
+in revised syntax.\c
+.SH "THE 'ocamlbrowser' SUBCOMMAND"
+.ft R
+.SS "Synopsis"
+.ft R
+.ft R
+.ft B
+.nf
+ocamlfind\ ocamlbrowser\ [-package\ \c
+.ft I
+package-name-list\c
+.ft B
+\&\ |\c
+\&
+.br
+\&\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ -all\ |\c
+\&
+.br
+\&\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ -passopt\ \c
+.ft I
+arg\c
+.ft B
+\&\ \c
+\&
+.br
+\&\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ -passrest\ ]\c
+.ft R
+.fi
+.SS "Description"
+.ft R
+.ft R
+This driver calls the
+ocamlbrowser\c
+\& with package options.\c
+\&
+With
+-package\c
+, the specified packages are included into\c
+\&
+the search path of the browser, and the modules of these packages become\c
+\&
+visible (in addition to the standard library). The option
+-all\c
+\& causes that all packages are selected that are managed by findlib.\c
+.PP
+.ft R
+As for other drivers, the options
+-passopt\c
+\& and\c
+\&
+-passrest\c
+\& can be used\c
+\&
+to pass arguments directly to the
+ocamlbrowser\c
+\& program.\c
+.SH "THE SUBCOMMAND 'ocamldoc'"
+.ft R
+.SS "Synopsis"
+.ft R
+.ft R
+.ft B
+.nf
+ocamlfind\ ocamldoc\c
+\&
+.br
+\&\ \ \ \ \ \ \ \ \ \ [\ -package\ \c
+.ft I
+package-name-list\c
+.ft B
+\&\ |\c
+\&
+.br
+\&\ \ \ \ \ \ \ \ \ \ \ \ -predicates\ \c
+.ft I
+pred-name-list\c
+.ft B
+\&\ |\c
+\&
+.br
+\&\ \ \ \ \ \ \ \ \ \ \ \ -syntax\ \c
+.ft I
+pred-name-list\c
+.ft B
+\&\ |\c
+\&
+.br
+\&\ \ \ \ \ \ \ \ \ \ \ \ -ppopt\ \c
+.ft I
+camlp4-arg\c
+.ft B
+\&\ |\c
+\&
+.br
+\&\ \ \ \ \ \ \ \ \ \ \ \ \c
+.ft I
+standard-option\c
+.ft B
+\&\ ]\c
+\&
+.br
+\&\ \ \ \ \ \ \ \ \ \ \c
+.ft I
+file\c
+.ft B
+\&\ ...\c
+.ft R
+.fi
+.SS "Description"
+.ft R
+.ft R
+This subcommand is a driver for ocamldoc. It undestands all options\c
+\&
+ocamldoc supports plus the mentioned findlib options. Basically,\c
+\&
+the -package options are translated into -I options, and the selected\c
+\&
+syntax options are translated into camlp4 options.\c
+.SS "Options"
+.ft R
+.ft R
+Here, only the additional options not interpreted by
+ocamldep\c
+\&
+but\c
+\&
+by the driver itself, and options with additional effects are explained.\c
+.PP
+.ft R
+.RS "2m"
+.ft R
+-package
+.ft I
+package-name-list\c
+.ft R
+.RE
+.ft R
+.sp
+.RS "7m"
+.ft R
+.ft R
+Adds the listed package names to the set of included\c
+\&
+\& packages. The package names may be separated by commas and/or\c
+\&
+\& whitespace. In the transformed command, for every package of the set\c
+\&
+\& of included packages and for any ancestor a directory search option\c
+\&
+\& is inserted after the already given options. This means that\c
+\&
+\& "-I" options are added for every package directory.\c
+\&
+\&
+.RE
+.ft R
+.sp
+.RS "2m"
+.ft R
+-predicates
+.ft I
+pred-name-list\c
+.ft R
+.RE
+.ft R
+.sp
+.RS "7m"
+.ft R
+.ft R
+Adds the given predicates to the set of actual\c
+\&
+\& predicates. The predicates must be separated by commas and/or\c
+\&
+\& whitespace.
+.RE
+.ft R
+.sp
+.RS "2m"
+.ft R
+-syntax
+.ft I
+pred-name-list\c
+.ft R
+.RE
+.ft R
+.sp
+.RS "7m"
+.ft R
+.ft R
+The predicates that are in effect during the look-up\c
+\&
+of the preprocessor options. At least, either
+camlp4o\c
+\&
+(selecting the normal syntax), or
+camlp4r\c
+\& (selecting\c
+\&
+the revised syntax) should be specified.\c
+.RE
+.ft R
+.sp
+.RS "2m"
+.ft R
+-ppopt
+.ft I
+camlp4-arg\c
+.ft R
+.RE
+.ft R
+.sp
+.RS "7m"
+.ft R
+.ft R
+An option that is passed through to the camlp4 call.\c
+.RE
+.ft R
+.PP
+.ft R
+.SH "THE 'install' SUBCOMMAND"
+.ft R
+.SS "Synopsis"
+.ft R
+.ft R
+.ft B
+.nf
+ocamlfind\ install\ [\ -destdir\ \c
+.ft I
+directory\c
+.ft B
+\&\ ]\c
+\&
+.br
+\&\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ [\ -metadir\ \c
+.ft I
+directory\c
+.ft B
+\&\ ]\c
+\&
+.br
+\&\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ [\ -ldconf\ \c
+.ft I
+path\c
+.ft B
+\&\ ]\c
+\&
+.br
+\&\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ [\ -dont-add-directory-directive\ ]\c
+\&
+.br
+\&\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ [\ -patch-version\ \c
+.ft I
+string\c
+.ft B
+\&\ ]\c
+\&
+.br
+\&\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ [\ -patch-rmpkg\ \c
+.ft I
+name\c
+.ft B
+\&\ ]\c
+\&
+.br
+\&\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ [\ -patch-archives\ ]\c
+\&
+.br
+\&\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ [\ -dll\ ]\ [\ -nodll\ ]\ [\ -optional\ ]\ [\ -add\ ]\c
+\&
+.br
+\&\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \c
+.ft I
+package_name\c
+.ft B
+\&\ \c
+.ft I
+file\c
+.ft B
+\&\ ...\c
+.ft R
+.fi
+.SS "Description"
+.ft R
+.ft R
+This subcommand installs a new package either at the default location\c
+\&
+(see the variable
+destdir\c
+\& of\c
+\&
+findlib.conf\c
+), or in the directory\c
+\&
+specified by the -destdir option. This\c
+\&
+means that a new package directory is created and that the files on\c
+\&
+the command line are copied to this directory. It is required that a\c
+\&
+META\c
+\& file is one of the files copied to the target\c
+\&
+directory.\c
+.PP
+.ft R
+Note that package directories should be flat (no\c
+\&
+subdirectories). Existing packages are never overwritten.\c
+.PP
+.ft R
+It is possible to have a separate directory for all the META files. If\c
+\&
+you want that, you have either to set the variable\c
+\&
+metadir\c
+\& of
+\&
+findlib.conf\c
+, or to specify the\c
+\&
+-metadir option. In this case, the file called META is copied to the\c
+\&
+specified directory and renamed to META.p (where p is the package\c
+\&
+name), while all the other files are copied to the package\c
+\&
+directory as usual. Furthermore, the META file is modified such that the\c
+\&
+directory\c
+\& variable contains the path of the package\c
+\&
+directory.
+.PP
+.ft R
+The option -dont-add-directory-directive prevents the installer from\c
+\&
+adding a
+directory\c
+\& variable.\c
+.PP
+.ft R
+If there are files ending in the suffixes
+\&.so\c
+\& or\c
+\&
+\&.dll\c
+, the package directory will be added to the\c
+\&
+DLL configuration file
+ld.conf\c
+, such that the dynamic\c
+\&
+loader can find the DLL. The location of this file can be overriden by\c
+\&
+the -ldconf option. To turn this feature off, use "-ldconf ignore";\c
+\&
+this causes that the ld.conf file is not modified.\c
+.PP
+.ft R
+However, if there is a stublibs directory in site-lib, the DLLs are not\c
+\&
+installed in the package directory, but in this directory that is\c
+\&
+shared by all packages that are installed at the same location.\c
+\&
+In this case, the configuration file
+ld.conf\c
+\& is\c
+\&
+not modified, so you do not need to say "-ldconf ignore" if you\c
+\&
+prefer this style of installation.\c
+.PP
+.ft R
+The options -dll and -nodll can be used to control exactly which files\c
+\&
+are considered as DLLs and which not. By default, the mentioned\c
+\&
+suffix rule is in effect: files ending in ".so" (Unix) or ".dll"\c
+\&
+(Windows) are DLLs. The switch -dll changes this, and all following\c
+\&
+files are considered as DLLs, regardless of their suffix. The switch
+\&
+-nodll expresses that the following files are not DLLs, even if they\c
+\&
+have a DLL-like suffix. For example, in the following call the files\c
+\&
+f1 and f2 are handled by the suffix rule; f3 and f4 are DLLs anyway;\c
+\&
+and f5 and f6 are not DLLs:\c
+\&
+\&
+.PP
+.ft R
+.ft B
+.nf
+ocamlfind\ install\ p\ f1\ f2\ -dll\ f3\ f4\ -nodll\ f5\ f6\c
+.ft R
+.fi
+.PP
+.ft R
+The switch -optional declares that all following files are optional,\c
+\&
+i.e. the command will not fail if files do not exist.\c
+.PP
+.ft R
+The -patch options may be used to change the contents of the META files\c
+\&
+while it is being installed. The option -patch-version changes the\c
+\&
+contents of the top-level "version" variable. The option -patch-rmpkg\c
+\&
+removes the given subpackage. The option -patch-archives is experimental,\c
+\&
+in particular it removes all non-existing files from "archive" variables,\c
+\&
+and even whole subpackages if the archives are missing.\c
+.PP
+.ft R
+The effect of -add is to add further files to an already installed\c
+\&
+packages.\c
+.SH "THE 'remove' SUBCOMMAND"
+.ft R
+.SS "Synopsis"
+.ft R
+.ft R
+.ft B
+.nf
+ocamlfind\ remove\ [\ -destdir\ \c
+.ft I
+directory\c
+.ft B
+\&\ ]\c
+\&
+.br
+\&\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ [\ -metadir\ \c
+.ft I
+directory\c
+.ft B
+\&\ ]\c
+\&
+.br
+\&\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ [\ -ldconf\ \c
+.ft I
+path\c
+.ft B
+\&\ ]\c
+\&
+.br
+\&\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \c
+.ft I
+package_name\c
+.ft B
+.ft R
+.fi
+.SS "Description"
+.ft R
+.ft R
+The package will removed if it is installed at the default location
+\&
+(see the variable
+destdir\c
+\& of\c
+\&
+findlib.conf\c
+). If the package\c
+\&
+resides at a different location, it will not be removed by default;\c
+\&
+however, you can pass an alternate directory for packages by the\c
+\&
+-destdir option. (This must be the same directory as specified at\c
+\&
+installation time.)\c
+.PP
+.ft R
+Note that package directories should be flat (no subdirectories); this\c
+\&
+subcommand cannot remove deep package directories.
+.PP
+.ft R
+If you have a separate directory for META files, you must either\c
+\&
+configure this directory by the
+metadir\c
+\& variable\c
+\&
+of
+findlib.conf\c
+, or by specifying\c
+\&
+the -metadir option.\c
+.PP
+.ft R
+The command does not fail if the package and/or the META\c
+\&
+file cannot be located. You will get a warning only in this case.\c
+.PP
+.ft R
+If the package directory is mentioned in the
+ld.conf\c
+\&
+configuration file for DLLs, it will be tried to remove this entry\c
+\&
+from the file. The location of this file can be overriden by\c
+\&
+the -ldconf option. To turn this feature off, use "-ldconf ignore";\c
+\&
+this causes that the ld.conf file is not modified.\c
+.PP
+.ft R
+If there is a stublibs directory, it is checked whether the package\c
+\&
+owns any of the files in this directory, and the owned files will\c
+\&
+be deleted.\c
+.SH "THE 'list' SUBCOMMAND"
+.ft R
+.SS "Synopsis"
+.ft R
+.ft R
+.ft B
+.nf
+ocamlfind\ list\ [-describe]\c
+.ft R
+.fi
+.SS "Description"
+.ft R
+.ft R
+This command lists all packages in the search path. The option -describe\c
+\&
+outputs the package descriptions, too.\c
+.SH "THE 'printppx' SUBCOMMAND"
+.ft R
+.SS "Synopsis"
+.ft R
+.ft R
+.ft B
+.nf
+ocamlfind\ printppx\c
+\&
+.br
+\&\ \ \ \ \ \ \ \ \ \ [\ -predicates\ \c
+.ft I
+pred-name-list\c
+.ft B
+\&\ ]\c
+\&
+.br
+\&\ \ \ \ \ \ \ \ \ \ [\ -ppxopt\ \c
+.ft I
+package\c
+.ft B
+,\c
+.ft I
+arg\c
+.ft B
+\&\ ]\c
+\&
+.br
+\&\ \ \ \ \ \ \ \ \ \ \c
+.ft I
+package\c
+.ft B
+\&\ ...\c
+.ft R
+.fi
+.SS "Description"
+.ft R
+.ft R
+This command prints the ppx preprocessor options as they would\c
+\&
+occur in an OCaml compiler invocation for the packages listed in\c
+\&
+the command. The output includes one "-ppx" option for each\c
+\&
+preprocessor. The possible options have the same meaning as for\c
+\&
+"ocamlfind ocamlc". The option "-predicates" adds assumed\c
+\&
+predicates and\c
+\&
+"-ppxopt
+.ft I
+package\c
+.ft R
+,\c
+.ft I
+arg\c
+.ft R
+"\c
+\&
+adds "\c
+.ft I
+arg\c
+.ft R
+" to the ppx invocation of\c
+\&
+package
+.ft I
+package\c
+.ft R
+\&.\c
+.PP
+.ft R
+The output of "ocamlfind printppx" will contain quotes\c
+\&
+"\c
+"\c
+" for ppx commands that contain\c
+\&
+space-separated arguments. In this case
+$(ocamlfind\c
+\&
+printppx ...)\c
+\& won't work as naively expected, because\c
+\&
+many shells (including bash and dash) perform field splitting on\c
+\&
+the result of command substitutions without honoring quotes.\c
+.SH "THE 'lint' SUBCOMMAND"
+.ft R
+.SS "Synopsis"
+.ft R
+.ft R
+.ft B
+.nf
+ocamlfind\ lint\ \c
+.ft I
+file\c
+.ft B
+.ft R
+.fi
+.SS "Description"
+.ft R
+.ft R
+Checks the META file, and reports possible problems.\c
+.SH "THE 'printconf' SUBCOMMAND"
+.ft R
+.SS "Synopsis"
+.ft R
+.ft R
+.ft B
+.nf
+ocamlfind\ printconf\ [\ conf\ |\ path\ |\ destdir\ |\ metadir\ |\ metapath\ |\ stdlib\ |\ ldconf\ ]\c
+.ft R
+.fi
+.SS "Description"
+.ft R
+.ft R
+This command prints the effective configuration after reading the\c
+\&
+configuration file, and after applying the various environment\c
+\&
+variables overriding settings. When called without arguments, the command\c
+\&
+prints all configuration options in a human-readable form. When called\c
+\&
+with an argument, only the value of the requested option is printed without\c
+\&
+explaining texts:\c
+.PP
+.ft R
+.RS "2m"
+.ft R
+conf\c
+.RE
+.ft R
+.sp
+.RS "7m"
+.ft R
+.ft R
+Prints the location of the configuration file findlib.conf\c
+\&
+\&
+.RE
+.ft R
+.sp
+.RS "2m"
+.ft R
+path\c
+.RE
+.ft R
+.sp
+.RS "7m"
+.ft R
+.ft R
+Prints the search path for packages. The members of the\c
+\&
+\& path are separated by linefeeds.\c
+.RE
+.ft R
+.sp
+.RS "2m"
+.ft R
+destdir\c
+.RE
+.ft R
+.sp
+.RS "7m"
+.ft R
+.ft R
+Prints the location where package are installed and\c
+\&
+\& removed by default.\c
+.RE
+.ft R
+.sp
+.RS "2m"
+.ft R
+metadir\c
+.RE
+.ft R
+.sp
+.RS "7m"
+.ft R
+.ft R
+Prints the location where META files are installed and\c
+\&
+\& removed (if the alternative layout is used).\c
+.RE
+.ft R
+.sp
+.RS "2m"
+.ft R
+metapath\c
+.RE
+.ft R
+.sp
+.RS "7m"
+.ft R
+.ft R
+Prints the path where the META file is installed for\c
+\&
+a fictive package. The name of the package is marked with '%s' in the\c
+\&
+path. For instance, this command could output "/some/path/%s/META" or\c
+\&
+"/some/path/META.%s", depending on the layout.\c
+.RE
+.ft R
+.sp
+.RS "2m"
+.ft R
+stdlib\c
+.RE
+.ft R
+.sp
+.RS "7m"
+.ft R
+.ft R
+Prints the location of the standard library.\c
+.RE
+.ft R
+.sp
+.RS "2m"
+.ft R
+ldconf\c
+.RE
+.ft R
+.sp
+.RS "7m"
+.ft R
+.ft R
+Prints the location of the ld.conf file\c
+.RE
+.ft R
+.PP
+.ft R
+.SH "THE SUBCOMMAND CALLING PACKAGE PROGRAMS"
+.ft R
+.SS "Synopsis"
+.ft R
+.ft R
+.ft B
+.nf
+ocamlfind\ \c
+.ft I
+pkg\c
+.ft B
+/\c
+.ft I
+cmd\c
+.ft B
+\&\ \c
+.ft I
+argument\c
+.ft B
+\&\ ...\c
+.ft R
+.fi
+.SS "Description"
+.ft R
+.ft R
+This subcommand is useful to call programs that are installed in\c
+\&
+package directories. It looks up the directory for
+\&
+.ft I
+pkg\c
+.ft R
+\& and calls the command named\c
+\&
+.ft I
+cmd\c
+.ft R
+\& in this directory. The remaining arguments\c
+\&
+are passed to this command.\c
+.PP
+.ft R
+argv(0) contains the absolute path to the command, and argv(1) and\c
+\&
+the following argv entries contain the arguments. The working directory\c
+\&
+is not changed.\c
+.PP
+.ft R
+Example: To call the program "x" that is installed in package "p",\c
+\&
+with arguments "y" and "z", run:\c
+.PP
+.ft R
+.ft B
+.nf
+ocamlfind\ p/x\ y\ z\c
+.ft R
+.fi
+.SH "CONFIGURATION FILE, ENVIRONMENT VARIABLES"
+.ft R
+.ft R
+The configuration file and environment variables are documented\c
+\&
+in the manual page for\c
+\&
+\&
+findlib.conf\c
+\&.\c
+.SH "HOW TO SET THE TOOLCHAIN"
+.ft R
+.SS "Synopsis"
+.ft R
+.ft R
+.ft B
+.nf
+ocamlfind\ -toolchain\ \c
+.ft I
+name\c
+.ft B
+\&\ ...\c
+.ft R
+.fi
+.SS "Description"
+.ft R
+.ft R
+The -toolchain option can be given before any other command,\c
+\&
+e.g.\c
+\&
+.PP
+.ft R
+.ft B
+.nf
+ocamlfind\ -toolchain\ foo\ ocamlc\ -c\ file.ml\c
+.ft R
+.fi
+\&
+compiles file.ml with toolchain "foo". By selecting toolchains one\c
+\&
+can switch to different command sets. For instance, the toolchain\c
+\&
+"foo" may consist of a patched ocamlc compiler.
+\&
+See
+findlib.conf\c
+\& how to\c
+\&
+configure toolchains.\c
diff --git a/local-packages/ocamlfind/doc/ref-man/site-lib.5 b/local-packages/ocamlfind/doc/ref-man/site-lib.5
new file mode 100644
index 0000000..883dbb9
--- /dev/null
+++ b/local-packages/ocamlfind/doc/ref-man/site-lib.5
@@ -0,0 +1,338 @@
+.TH "site-lib" "5" "The findlib package manager for OCaml" "User Manual"
+.SH "NAME"
+.ft R
+site-lib - [Location of package directories]\c
+.SH "STANDARD LAYOUT"
+.ft R
+.ft R
+.ft B
+.nf
+\&...somewhere\ in\ the\ filesystem\ hierarchy...\c
+\&
+.br
+\&\ \ \ |\c
+\&
+.br
+\&\ \ \ \e\ \c
+\&
+.br
+\&\ \ \ \ \ site-lib\c
+\&
+.br
+\&\ \ \ \ \ |\c
+\&
+.br
+\&\ \ \ \ \ +-\ (optional)\ stublibs\c
+\&
+.br
+\&\ \ \ \ \ +-\ (optional)\ postinstall\c
+\&
+.br
+\&\ \ \ \ \ +-\ (optional)\ postremove\c
+\&
+.br
+\&\ \ \ \ \ |\c
+\&
+.br
+\&\ \ \ \ \ +-\ \c
+.ft I
+package1\c
+.ft B
+\&
+.br
+\&\ \ \ \ \ |\ \ |\c
+\&
+.br
+\&\ \ \ \ \ |\ \ +-\ META\c
+\&
+.br
+\&\ \ \ \ \ |\ \ +-\ \c
+.ft I
+archive\ files\c
+.ft B
+\&
+.br
+\&\ \ \ \ \ |\ \ +-\ \c
+.ft I
+interface\ definitions\c
+.ft B
+\&
+.br
+\&\ \ \ \ \ |\c
+\&
+.br
+\&\ \ \ \ \ +-\ \c
+.ft I
+package2\c
+.ft B
+\&
+.br
+\&\ \ \ \ \ +\c
+\&
+.br
+\&\ \ \ \ \ :\c
+\&
+.br
+\&\ \ \ \ \ :\c
+\&
+.br
+\&\ \ \ \ \ \e\c
+\&
+.br
+\&\ \ \ \ \ \ \ \ \c
+.ft I
+packageN\c
+.ft B
+.ft R
+.fi
+.SH "DESCRIPTION"
+.ft R
+.ft R
+Every installation of "findlib" has a default location for package\c
+\&
+directories, which is normally a directory called "site-lib". The\c
+\&
+location can be set by the configuration variables\c
+\&
+path\c
+\& (used to look up packages), and\c
+\&
+destdir\c
+\& (used to install new packages);\c
+\&
+see
+findlib.conf\c
+\&.\c
+.PP
+.ft R
+The name of a package is the name of the package directory. For\c
+\&
+example, if
+destdir=/usr/local/lib/ocaml/site-lib\c
+, the\c
+\&
+package p will be installed in the subdirectory\c
+\&
+/usr/local/lib/ocaml/site-lib/p\c
+\&. This subdirectory\c
+\&
+must contain the META file and all other files belonging to the package.\c
+\&
+Package names must not contain the '.' character.\c
+.PP
+.ft R
+The variable
+destdir\c
+\& specifies the directory for\c
+\&
+new packages. You can only have one such directory at a time; but of\c
+\&
+course you can change this directory in findlib.conf. The command\c
+\&
+ocamlfind install\c
+\& puts new packages into this\c
+\&
+directory; it is recommended to use this command for installation\c
+\&
+because it ensures that the directory layout is right.\c
+.PP
+.ft R
+For searching packages, findlib uses (only) the variable\c
+\&
+path\c
+\& which may name several locations to look at.\c
+.PP
+.ft R
+For systems with DLL support another directory may exist: stublibs.
+\&
+If present, findlib will install DLLs into this directory that is\c
+\&
+shared by all packages at the same site-lib location. Findlib remembers\c
+\&
+which DLL belongs to which package by special files with the suffix\c
+\&
+".owner"; e.g. for the DLL "dllpcre.so" there is another file\c
+\&
+"dllpcre.so.owner" containing the string "pcre", so findlib knows\c
+\&
+that the package "pcre" owns this DLL. It is not possible that a DLL\c
+\&
+is owned by several packages.\c
+.PP
+.ft R
+If the stublibs directory does not exist, DLLs are installed regularly\c
+\&
+in the package directories like any other file.\c
+.PP
+.ft R
+For special needs, a postinstall and/or a postremove script may be\c
+\&
+installed in the site-lib directory. These scripts are invoked after\c
+\&
+installation or removal of a package, respectively.\c
+.SH "ALTERNATE LAYOUT"
+.ft R
+.ft R
+.ft R
+.ft B
+.nf
+\&...somewhere\ in\ the\ filesystem\ hierarchy...\c
+\&
+.br
+\&\ \ \ |\c
+\&
+.br
+\&\ \ \ \e\ \c
+\&
+.br
+\&\ \ \ \ \ site-lib\c
+\&
+.br
+\&\ \ \ \ \ |\c
+\&
+.br
+\&\ \ \ \ \ +-\ (optional)\ stublibs\c
+\&
+.br
+\&\ \ \ \ \ +-\ (optional)\ postinstall\c
+\&
+.br
+\&\ \ \ \ \ +-\ (optional)\ postremove\c
+\&
+.br
+\&\ \ \ \ \ |\c
+\&
+.br
+\&\ \ \ \ \ +-\ \c
+.ft I
+package1\c
+.ft B
+\&
+.br
+\&\ \ \ \ \ |\ \ |\c
+\&
+.br
+\&\ \ \ \ \ |\ \ +-\ \c
+.ft I
+archive\ files\c
+.ft B
+\&
+.br
+\&\ \ \ \ \ |\ \ +-\ \c
+.ft I
+interface\ definitions\c
+.ft B
+\&
+.br
+\&\ \ \ \ \ |\c
+\&
+.br
+\&\ \ \ \ \ +-\ \c
+.ft I
+package2\c
+.ft B
+\&
+.br
+\&\ \ \ \ \ +\c
+\&
+.br
+\&\ \ \ \ \ :\c
+\&
+.br
+\&\ \ \ \ \ :\c
+\&
+.br
+\&\ \ \ \ \ \e\c
+\&
+.br
+\&\ \ :\ \ \ \ \ \c
+.ft I
+packageN\c
+.ft B
+\&
+.br
+\&\ \ |\c
+\&
+.br
+\&\ \ \e\c
+\&
+.br
+\&\ \ \ \ metaregistry\c
+\&
+.br
+\&\ \ \ \ |\c
+\&
+.br
+\&\ \ \ \ +-\ META.package1\c
+\&
+.br
+\&\ \ \ \ +-\ META.package2\c
+\&
+.br
+\&\ \ \ \ +\c
+\&
+.br
+\&\ \ \ \ :\c
+\&
+.br
+\&\ \ \ \ \e\c
+\&
+.br
+\&\ \ \ \ \ \ \ META.packageN\c
+.ft R
+.fi
+.PP
+.ft R
+This is an alternate directory layout collecting all META files in one\c
+\&
+directory. You can configure this layout by setting\c
+\&
+path\c
+\& to the absolute location of\c
+\&
+metaregistry\c
+\&. Findlib recognizes that there are\c
+\&
+META files in this directory and uses them; it is not necessary to\c
+\&
+include
+site-lib\c
+\& into the
+path\c
+\&.\c
+.PP
+.ft R
+In order to work, the META files must contain a\c
+\&
+directory\c
+\& directive pointing to the corresponding\c
+\&
+package directory that resides below
+site-lib\c
+\&.\c
+.PP
+.ft R
+The command
+ocamlfind install\c
+\& copes with this\c
+\&
+layout, too. The variable
+destdir\c
+\& must contain the\c
+\&
+absolute location of
+site-lib\c
+, and the variable\c
+\&
+metadir\c
+\& must contain the absolute location of\c
+\&
+metaregistry\c
+\&. Note that
+ocamlfind\c
+\&
+install\c
+\& automatically adds a
+directory\c
+\&
+directive to the META file, so you need not do it manually.\c
diff --git a/local-packages/ocamlfind/doc/src/findlib.dsl b/local-packages/ocamlfind/doc/src/findlib.dsl
new file mode 100644
index 0000000..4b2f063
--- /dev/null
+++ b/local-packages/ocamlfind/doc/src/findlib.dsl
@@ -0,0 +1,24 @@
+
+]>
+
+
+
+
+
+(define %footnotes-at-end%
+ ;; Should footnotes appear at the end of HTML pages?
+ #t)
+
+(define %html-ext%
+ ;; Default extension for HTML output files
+ ".html")
+
+(define %root-filename%
+ ;; Name for the root HTML document
+ "index")
+
+
+
+
+
diff --git a/local-packages/ocamlfind/doc/src/findlib.sgml b/local-packages/ocamlfind/doc/src/findlib.sgml
new file mode 100644
index 0000000..d2c4752
--- /dev/null
+++ b/local-packages/ocamlfind/doc/src/findlib.sgml
@@ -0,0 +1,2476 @@
+
+
+
+
+
+
+
+ %gps.common;
+]>
+
+
+
+The findlib User's Guide
+
+
+
+
+ Gerd
+ Stolpmann
+
+
+
+ gerd@gerd-stolpmann.de
+
+
+
+
+
+
+
+1999-2014Gerd Stolpmann
+
+
+
+
+
+The "findlib" library provides a scheme to manage reusable software
+components (packages), and includes tools that support this
+scheme. Packages are collections of OCaml modules for which
+metainformation can be stored. The packages are kept in the filesystem
+hierarchy, but with strict directory structure. The library contains
+functions to look the directory up that stores a package, to query
+metainformation about a package, and to retrieve dependency
+information about multiple packages. There is also a tool that allows
+the user to enter queries on the command-line. In order to simplify
+compilation and linkage, there are new frontends of the various OCaml
+compilers that can directly deal with packages.
+
+
+
+Together with the packages metainformation is stored. This includes a
+version string, the archives the package consists of, and additional
+linker options. Packages can also be dependent on other
+packages. There is a query which finds out all predecessors of a list
+of packages and sorts them topologically. The new compiler frontends
+do this implicitly.
+
+
+
+Metainformation can be conditional, i.e. depend on a set of
+predicates. This is mainly used to be able to react on certain
+properties of the environment, such as if the bytecode or the native
+compiler is invoked, if the application is multi-threaded, and a few
+more. If the new compiler frontends are used, most predicates are
+found out automatically.
+
+
+
+There is special support for scripts. A new directive, "#require",
+loads packages into scripts.
+
+
+
+Download findlib
+
+This manual describes version &release.findlib; of the software
+package. It can be downloaded at
+
+&url.gps-ocaml-download;
+. The user's guide and the reference manual are included.
+Newest releases of "findlib" will be announced in
+The OCaml Link
+Database.
+
+
+
+
+Quickstart
+
+See also the Quickstart page
+for instructions for the most common
+cases.
+
+
+
+
+License
+
+This document, and the described software, "findlib", are copyright by
+Gerd Stolpmann.
+
+
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this document and the "findlib" software (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+
+
+The Software is provided ``as is'', without warranty of any kind, express
+or implied, including but not limited to the warranties of
+merchantability, fitness for a particular purpose and noninfringement.
+In no event shall Gerd Stolpmann be liable for any claim, damages or
+other liability, whether in an action of contract, tort or otherwise,
+arising from, out of or in connection with the Software or the use or
+other dealings in the software.
+
+
+
+
+
+
+
+
+
+
+
+
+User's Guide
+
+
+Libraries and Packages
+
+ Reusability is one of the keywords in software engineering
+today. It simply means to have source code that can be shared by
+several programs. Usually, modules are combined to libraries, and the
+library archive files can be linked into programs. As the idea might
+be simple, its practical implementation is complex because sharing of
+source code has an impact on all steps and phases in software
+production. This document only addresses the following administrative
+problems:
+
+
+
+
+
+Storing the libraries in file hierarchies
+
+
+
+
+
+Compiling and linking programs using such libraries
+
+
+
+
+
+Managing dependencies between libraries
+
+
+
+
+
+Objective Caml has a variety of language means to support
+reusability. Most important, polymorphic functions can be written
+which generalize the types of input arguments and the
+type of the result value. There are many examples in the core library
+such that I assume that the reader is familiar with this
+feature. Second, modules and functors must be mentioned which not only
+generalize types of values, but can even generalize structures,
+i.e. types with associated operations. Third, the class construct
+allows us to adopt the object-oriented techniques of abstraction such
+as inheritage and dynamic method lookup.
+
+
+
+In the following, we are only analyzing the problem of making and
+using libraries from a purely software-technical point of view. This
+means, we ignore how to make functions polymorphic, and how to create
+functors and classes. Instead, we only look at how to invoke the
+OCaml compiler to create, manage, and use libraries. Especially, we
+are interested in the administration of systems of libraries that
+have dependencies.
+
+
+One of the complex operations on such a system is the replacement of
+a library by a newer version. Because of the strict compatibility
+checks of OCaml, it is usually necessary to rebuild and reinstall
+all dependent libraries as well. With the help of findlib, one can
+find out which are the dependent libraries. (However, findlib does
+not provide a framework to rebuild them. For example, the GODI
+system includes such a framework.)
+
+
+
+The library is also called a "package" when it is seen as a removeable
+and replaceable set of files. Findlib requires that there is a
+certain directory structure; it is not possible to install the files
+at arbitrary places (findlib does not even maintain a file list).
+For simplicity, every library is usually stored into its own
+directory, i.e. the library archive files and the interface files.
+
+
+From the perspective of the compiler, the library is made
+accessible by adding the package directory to the search path
+of the compiler. By doing so, the modules of the library are
+added to the namespace universe, and thus can be opened by
+modules using them. This means that the approach "one package
+= one directory" can be naturally translated into language
+operations modifying the namespace scope.
+
+
+When linking a program, it must be specified which link operation is
+necessary to use a certain library. Often, only a single archive file
+needs to be linked in, but sometimes additional archives or system
+libraries must be linked, too. Furthermore, the link operations
+often depends on certain conditions, e.g. whether a single- or
+multi-threaded program is being created.
+
+
+
+The findlib library is my suggestion for a
+package manager suitable for Objective Caml. It is a library (stored
+as a package itself) which can answer the following questions:
+
+
+
+
+If I want to use a package, which is the directory containing
+the compiled interfaces and implementations? - The package directory
+may vary from system to system, and this feature makes it easier to
+write Makefiles that run everywhere. Furthermore, OCaml can load
+modules dynamically, and it is not a good practice to compile in the
+location of such modules. The better way is to ask findlib where the
+module resides today.
+
+
+
+
+Which other packages must be linked in, too, if I want to use a
+certain package?
+
+
+
+
+Which archives need to be linked in, and which compiler options
+are necessary?
+
+
+
+
+If there is a version of the archive with additional properties,
+which file should I use? - Additional properties are at least:
+Thread-safety, using POSIX threads, and being gprof-enabled. It is
+simple to add more criterions.
+
+
+
+
+
+
+Furthermore, there is a frontend for this library called
+ocamlfind. It is a command-line interface for the
+library, but has also some additional abilities:
+
+
+
+
+
+It can invoke ocamlc, ocamlopt, ocamlmktop, and ocamlcp such
+that compiler arguments necessary to use a package or link it in are
+automatically added.
+
+
+
+
+It can install and uninstall packages.
+
+
+
+
+It can find out dependent packages.
+
+
+
+
+
+As you'll see in the following chapters, the usage of this library is
+really simple. If you want only to link in packages written by other
+people, you must only change the command that invokes the compiler,
+e.g. instead of calling "ocamlc program.ml" invoke "ocamlfind ocamlc
+-package name_of_package_to_use -linkpkg program.ml", and you can
+refer to the named package within program.ml. If you want to turn your
+collection of modules into a package, you need only to write one
+adminstrative file (META) containing all extra information such as
+required other packages.
+
+
+
+
+
+
+
+
+Using packages
+
+
+Listing the installed packages
+
+
+You can list which packages are installed by executing
+
+
+ocamlfind list
+
+
+You will get a list of names and version numbers. You can get a bit
+more information by passing the -describe option:
+
+
+ocamlfind list -describe
+
+
+
+
+
+
+Looking up package directories
+
+
+The package manager knows the preferred location for packages (this
+location is compiled in), which is usually
+/usr/local/lib/ocaml/site-lib. You can ask the package manager where
+package p is stored by simply typing
+
+
+
+ocamlfind query p
+
+
+
+and it will answer something like
+
+
+
+/usr/local/lib/ocaml/site-lib/p
+
+
+
+There is an environment variable OCAMLPATH which can specify further
+directories where packages are stored. (The search order is: first
+the directories in OCAMLPATH in turn, then the default path
+set in ocamlfind.conf)
+
+
+
+Historically, this kind of query was the first and only way of using
+ocamlfind, and because of the similiarity to the Unix find command it
+got its name. Finding out package locations is a basic but
+nethertheless important feature because it hides the details of the
+filesystem hierarchy. It is sufficient only to know the name of the
+package, and if needed, you can use the lookup mechanism implemented
+in ocamlfind to get the concrete directory.
+
+
+
+
+
+How a package directory looks like
+
+
+Let us assume that the package p implements the modules M1 and M2. If
+you compile m1.mli and m2.mli you get the corresponding binary files
+m1.cmi and m2.cmi describing the interfaces of the modules. Of course,
+these cmi files must go into the package directory. It is recommended
+to put the source mli files into the directory, too, as they document
+the interface.
+
+
+
+Another product of the compilation are two cmo files, m1.cmo and
+m2.cmo (we assume the bytecode compiler, the native compiler would
+create m1.cmx and m2.cmx). It is possible to put these files directly
+into the directory, but there is a better way. As it makes only sense
+to use both modules (a very common assumption), they should first be
+archived by doing
+
+
+
+ocamlc -a -o p.cma m1.cmo m2.cmo
+
+
+
+The archive p.cma contains both cmo files, and preserves the order of
+the files. Assumed that in M2 there is a reference to an entity in M1,
+M2 depends on M1 and when linking a program using these modules, M1
+must be mentioned first (e.g. ocamlc m1.cmo m2.cmo
+program.ml)Note that C linkers usually require the reverse
+order, but only for archive elements, i.e. files with suffix
+.a.. If you create the archive p.cma it contains already
+this dependency, and you need not to remember it when linking in the
+p.cma.
+
+
+
+So far the files m1.cmi, m2.cmi, and p.cma are needed, and m1.mli and
+m2.mli are recommended. Usually there is another file in the
+directory, META, containing additional information about the package.
+In our example, META looks like
+
+
+
+description = "Our super-duper package"
+requires = ""
+version = "1"
+archive(byte) = "p.cma"
+
+
+The variable "requires" contains a list of packages that are
+required by this package (the names may be separated by commas or
+spaces). As our package, p, does not depend on any other package, this
+list is empty. I'll explain what happens with non-empty lists below.
+
+
+
+The variable "version" is simply a version string, and "description"
+is a short comment on the package.
+
+
+The variable "archive" denotes the files that have to be
+actually linked in if the package is used. This is again a list of
+(file) names. In contrast to the other variables, "archive" has a
+condition, written in parantheses. This value of "archive" will only
+be used if the predicate "byte" is true; this predicate is usually
+given if the program is compiled to bytecode. If you have a native
+archive, p.cmxa, of the two modules M1 and M2, you can add another
+line to META:
+
+
+
+archive(native) = "p.cmxa"
+
+
+
+The correct value for the "archive" variable is selected upon the
+given set of predicates.
+
+
+Many packages can also be loaded at runtime with the
+Fl_dynload module. In this case, though, the
+variable "plugin" is used instead of "archive", e.g.
+
+
+plugin(byte) = "p.cma"
+plugin(native) = "p.cmxs"
+
+
+(You can create p.cmxs from p.cmxa with
+"ocamlopt -shared -linkall -o p.cmxs p.cmxa".) Note that "plugin" is entirely optional.
+
+
+
+
+Querying information stored in META files
+
+
+By setting some options of ocamlfind you can query the variables from
+the META files. For example, -long-format (or short -l) selects all
+interesting variables:
+
+
+
+ocamlfind query -long-format p
+
+
+
+This would answer something like:
+
+
+
+package: p
+description: Our super-duper package
+version: 1
+archive(s):
+linkopts:
+location: /usr/local/lib/ocaml/site-lib/p
+
+
+
+The values of the "archive" variable are missing because no predicate
+has been set, without further options "ocamlfind query" operates with
+an empty set of predicates. To get the bytecode archive, run:
+
+
+
+ocamlfind query -long-format -predicates byte p
+
+
+
+You can set more than one predicate. It usually does not make sense, but
+you could for example select both bytecode and native archives by:
+
+
+
+ocamlfind query -long-format -predicates byte,native p
+
+
+
+As both settings for "archive" are now equally like, the extraction
+mechnism chooses simply the first. The general rule is that the first
+most special value is selected.
+
+
+
+
+
+How to compile and link a program that uses a package
+
+
+Now suppose you want to compile a program which calls functions of
+your new package p. If prog1.ml, prog2.ml, and prog3.ml are the three
+source files the program consists of, compile them with the commands
+
+
+
+ocamlfind ocamlc -package p -c prog1.ml
+ocamlfind ocamlc -package p -c prog2.ml
+ocamlfind ocamlc -package p -c prog3.ml
+
+
+
+The "ocamlfind ocamlc" invocation is a frontend to "ocamlc". Most
+arguments are directly passed to "ocamlc", but there are a few new
+options, and often some new options are implicitly added. Here, the
+new -package option is used, which adds search paths such that the
+modules of package p are found. Effectively, the following direct
+ocamlc invocations would be equivalent
+If you specify the -verbose option, the constructed
+command is printed to the terminal. Actually, there are some more
+implicitly added options, especially -ccopt -I<dir> for every
+package directory <dir>. This means that you can compile C
+programs accessing header files stored in the package directory.
+:
+
+
+
+ocamlc -I /usr/local/lib/ocaml/site-lib/p -c prog1.ml
+ocamlc -I /usr/local/lib/ocaml/site-lib/p -c prog2.ml
+ocamlc -I /usr/local/lib/ocaml/site-lib/p -c prog3.ml
+
+
+
+The -I option has the effect that the named directory is also searched
+when looking up cmi files. Because of this you can refer directly to
+the modules M1 and M2 in the program sources.
+
+
+
+In order to link the program use the following command:
+
+
+
+ocamlfind ocamlc -o program -package p -linkpkg prog1.cmo prog2.cmo prog3.cmo
+
+
+
+The -linkpkg option causes some more arguments to be added to the
+constructed ocamlc command. Especially, the name of the archive of p
+is extracted from the META file, and automatically inserted before the
+prog1.cmo argument. The resulting command looks like
+Again, the actual command contains even some more arguments...
+:
+
+
+
+ocamlc -o program -I /usr/local/lib/ocaml/site-lib/p p.cma prog1.cmo prog2.cmo prog3.cmo
+
+
+
+Please note that the bytecode archive p.cma has been selected, and not
+the native archive p.cmxa. As it is known that the bytecode compiler
+is used, the predicate "byte" is automatically set.
+
+
+
+
+
+
+Dependencies
+
+
+Often packages use other packages themselves. Let q be another package
+consisting of the single module M3 which contains references to M1 and
+M2. At the first glance, we can ignore this when describing the
+package, as we could always add "-package p" and "-package q" options
+when compiling programs using q. This solution is not optimal, as the
+user of a package must have knowlege about details of the package that
+should normally be hidden. When we introduced the notion of packages,
+one of the most important properties was that we can replace packages
+by improved versions. Imagine that q is replaced by q', but q' uses
+not only p but also r. Every program that used q and is now forced to
+use q' must be changed (at least in the Makefile) in order to link r,
+too. This is clearly not what is intended by packages.
+
+
+
+The far better solution is to store dependency information in the META
+files. The "requires" variable can list names of packages that are
+direct ancestors, i.e. referred directly. (Do not put indirect
+ancestors into this variable, for example further packages required by
+r when describing q - these are found out automatically.) The META
+file of q looks like:
+
+
+
+description = "Something that needs p"
+requires = "p"
+version = "1"
+archive(byte) = q.cma
+archive(native) = q.cmxa
+
+
+
+If you want to put several package names into "requires", separate
+them with commas or spaces.
+
+
+
+The "ocamlfind query" command ignores the "requires" value by default,
+you must add the -recursive option. In this case, all direct or
+indirect ancestors of the packages given on the command line are
+selected, too, and printed in topological order. For example, the
+command
+
+
+
+ocamlfind query -recursive -long-format -predicate byte q
+
+
+
+prints two records:
+
+
+
+package: p
+description: Our super-duper package
+version: 1
+archive(s): p.cma
+linkopts:
+location: /usr/local/lib/ocaml/site-lib/p
+
+package: q
+description: Something that needs p
+version: 1
+archive(s): q.cma
+linkopts:
+location: /usr/local/lib/ocaml/site-lib/p
+
+
+
+Without -recursive, only q would have been printed.
+
+
+
+The compiler frontend provided with ocamlfind always works
+recursively. In order to compile and link another.ml that uses q, the
+following command is sufficient:
+
+
+
+ocamlfind ocamlc -o another -package q -linkpkg another.ml
+
+
+
+It is not necessary to specify -package p in this statement as the
+dependency relation is always used to find out the actually meant
+set of packages.
+
+
+
+
+
+
+Linker options
+
+
+
+Beginning with OCaml 3.00, the compiler itself has an interesting feature
+called "automatic linking" that makes the following mechanism superflous in
+most cases. Automatic linking means that it is possible to store the linker
+options into the cma or cmxa file such that the compiler itself knows which
+options are necessary. Of course, the following mechanism still works, and it
+is still helpful when conditional linking is required.
+
+
+
+
+OCaml has a C interface which means that C libraries can be linked in
+and C functions can be declared as new language primitives. Using such
+libraries requires special linker options. Some of the core libraries
+distributed with OCaml are partly implemented in C and thus additional
+libraries must be specified in the linking phase of the program.
+
+
+
+For example, the "str" library providing regular expressions requires
+to be linked as follows:
+
+
+
+ocamlc -o prog str.cma my_file1.cmo my_file2.cmo -cclib -lstr
+
+
+
+The -cclib option passes the following argument directly to the
+underlying C linker which has the effect that libstr.a is linked in,
+too. The "-cclib -lstr" is directly associated with str.cma as the
+latter simply cannot be used without the former. Assume you would
+write a META file describing str. That "str.cma" should be linked in
+as archive is clear; the "-cclib -lstr" can be specified in another
+variable called "linkopts". The META file would look like:
+
+
+
+requires = ""
+version = "str from ocaml 2.02"
+archive(byte) = "str.cma"
+archive(native) = "str.cmxa"
+linkopts = "-cclib -lstr"
+
+
+
+This has the effect that specifying -linkpkg in one of the compiler
+frontends not only chooses one of the archive files, but also extracts
+the necessary linker options from the META file. The above example can
+also be compiled with:
+
+
+
+ocamlfind ocamlc -o prog -package str -linkpkg my_file1.cmo my_file2.cmo
+
+
+
+Most people will never write META files with "linkopts" settings. But
+this feature is very useful at least for the core libraries such as
+str. Because of this, the "findlib" distribution comes with META files
+for the core libraries in order to hide the linker options. This
+means that you can already use the packages "str", "dbm", "dynlink",
+"graphics", "num", "threads", "unix", and "camltk", and that the
+appropriate archives and linker options are automatically extracted.
+
+
+
+
+
+
+
+
+
+Dependency analysis of packages
+
+
+Querying ancestors
+
+
+Every package denotes in its META file only the list of direct
+ancestors. The theoretical model of the dependency relation is a
+directed acyclic graph (DAG), with the packages as vertices and edges
+from packages to their direct ancestors. The graph must be acyclic
+because OCaml does not allow cyclic dependencies between modules.
+
+
+
+What happens if you query something like
+
+
+
+ocamlfind query -recursive p1 p2 ... pN
+
+
+
+is that the named packages p1 to pN are marked in the graph, and that
+repeatedly all direct ancestors of marked packages are marked, too,
+until there is not any marked package remaining with an unmarked
+ancestor. All marked packages are then printed in topological
+order. This simply means that for the printed packages p1 to pM holds
+that if pI is printed before pJ then pI is a (possibly indirect)
+ancestor of pJ.
+
+
+
+The topological order plays a role when the link command is
+constructed by "ocamlfind ocamlc", as Ocaml requires that archives
+must be linked in topological order. For example, the link statement
+
+
+
+ocamlfind ocamlc -o another -package q -linkpkg another.ml
+
+
+
+must be turned into the effective command
+
+
+
+ocamlc -o another [...more options...] p.cma q.cma another.ml
+
+
+
+and not
+
+
+
+ocamlc -o another [...more options...] q.cma p.cma another.ml
+
+
+
+because there are references from q.cma to p.cma.
+
+
+
+In C, there is a similar requirement when linking static archives. The
+linker backend ld wants the archives in reversed
+topological order, i.e. the deepest ancestor must come last in the
+list of linked archives. Because of this, the additional linker
+options specified in the "linkopts" variable are passed in reversed
+order to the underlying linker. This means that you can refer to C
+libraries of ancestor packages of p in C libraries provided in p.
+
+
+
+Note that most operating systems do not require any specific order for
+dynamically linked C libraries (the exception is, surprise!, AIX).
+
+
+
+
+
+
+Querying descendants
+
+
+It is often useful to find out the descendants of a package, i.e. all
+direct or indirect users of the package. There is another "ocamlfind"
+subcommand that allows us to query descendants. For example, to get
+the direct and indirect users of p, type in
+
+
+
+ocamlfind query -descendants p
+
+
+
+The set of packages that are possible descendants is determined as
+follows:
+
+
+
+
+All packages located in directories mentioned in the environment
+variable OCAMLPATH are candidates. Note that only package directories
+containing META files are taken.
+
+
+
+
+
+The packages in the default package directory are candidates, too.
+
+
+
+
+
+If there are two packages with the same name, only the first
+counts, i.e. the first in OCAMLPATH, then the one in the default directory.
+
+
+
+
+After this set has been determined, the complete dependency graph is
+constructed on it. As the descendants are queried, the dependencies
+are read in the inverse way compared with queries of the ancestors.
+
+
+
+
+
+
+
+
+
+
+A new frontend for ocamlc
+
+
+Compiling and linking
+
+
+There are compiler frontends for the four compilers ocamlc, ocamlopt,
+ocamlmktop, and ocamlcp. They are simply called by specifying the name
+of the compiler as first argument to ocamlfind, i.e.
+
+
+
+ocamlfind ocamlc ...arguments...
+ocamlfind ocamlopt ...arguments...
+ocamlfind ocamlmktop ...arguments...
+ocamlfind ocamlcp ...arguments...
+
+
+
+In addition to the compiler options handled by the compilers
+themselves, the following options are available:
+
+
+
+
+
+-package <name>: Causes that the package <name> is added to
+the package list, and that -I options are added for every package, and
+all direct or indirect ancestors.
+
+
+
+
+
+-linkpkg: Causes that the archives of the packages in the package list
+and all their direct or indirect ancestors are added in topological
+order to the command line before the first file to compile or to
+link. Packages specified by -dontlink are not linked in, though.
+Furthermore, the linker options of these packages are added in
+reverse topological order at the end of the command line.
+
+
+
+
+
+-predicates <predicate-list>: The named predicates are included
+in the list of predicates. Note that there are some predicates set by
+default, see below.
+
+
+
+
+
+-dontlink <name>: Specifies that the package <name> and
+all its direct or indirect ancestors should not be linked in.
+
+
+
+
+
+
+-passopt <opt>: The option <opt> is passed directly to the
+underlying compiler. This is especially needed to pass undocumented
+options to the compiler.
+
+
+
+
+
+If you only want to compile, i.e. the -c option is in effect, you
+normally only need the -package option.
+
+
+
+Depending on the compiler and on the given options, some predicates
+are set by default:
+
+
+
+
+
+byte: The predicate "byte" is set when ocamlc, ocamlcp, or ocamlmktop
+is used to compile or link.
+
+
+
+
+
+native: The predicate "native" is set when ocamlopt is used to compile
+or to link.
+
+
+
+
+
+toploop: The predicate "toploop" is set when a toploop is being executed
+
+
+
+
+
+create_toploop: The predicate "toploop" is set when ocamlmktop is used to
+compile or to link a toploop
+
+
+
+
+
+
+gprof: The predicate "gprof" is set when ocamlopt with -p option is
+invoked.
+
+
+
+
+
+mt: The predicate "mt" is set when the -thread or the -vmthread option is in effect.
+
+
+
+
+
+mt_posix: The predicate "mt_posix" is set together with "mt" if the
+POSIX thread implementation is selected.
+
+
+
+
+
+mt_vm: The predicate "mt_vm" is set together with "mt" if the bytecode
+thread implementation is selected.
+
+
+
+
+
+autolink: The predicate "autolink" is set if the OCaml compiler can perform
+automatic linking. This predicate is never set if the -noautolink option is
+in effect.
+
+
+
+
+
+
+
+
+
+Toploops and runtime systems
+
+
+Dynamic toploops
+
+
+Recent versions of OCaml support dynamic loading of stub libraries
+(but only for the more widely used operating systems). This means
+that one can start a toploop by running
+
+
+$ ocaml
+ Objective Caml version 3.07+2
+
+# _
+
+
+and that it is now possible to load .cma archive files referring to
+shared C libraries ("DLLs"). In older versions of OCaml this was
+not possible and one had to create a so-called custom toploop
+with the ocamlmktop command. This method is still supported and
+explained below; however, nowadays it is often not necessary to
+do so. For the modern way, findlib includes a small script called
+"topfind" (i.e. "ocamlfind for the toploop") that can be directly
+loaded into the toploop:
+
+
+# #use "topfind";;
+- : unit = ()
+Findlib has been successfully loaded. Additional directives:
+ #require "package";; to load a package
+ #list;; to list the available packages
+ #camlp4o;; to load camlp4 (standard syntax)
+ #camlp4r;; to load camlp4 (revised syntax)
+ #predicates "p,q,...";; to set these predicates
+ Topfind.reset();; to force that packages will be reloaded
+ #thread;; to enable threads
+
+- : unit = ()
+# _
+
+
+
+
+A number of additional directives are now available. The "#require"
+directive loads additional packages (with all dependencies):
+
+
+
+# #require "q1,q2,...,qM";;
+
+
+
+"#require" loads the listed packages and all their ancestors in the
+right order, but leaves packages out that have already been loaded.
+Scripts can now simply load and document which packages are used by a
+"#require" directive right at the beginning of the script.
+
+
+
+The #list directive lists the available packages as "ocamlfind list"
+would do it.
+
+
+If you need additional predicates, you can set them with #predicates.
+Note that this should be done before the first package is loaded in
+order to ensure a consistent library system.
+
+
+The #thread directive enables multi-threading if possible. Note that
+this is only supported for installations basing on the POSIX thread
+library. (However, if you have only have VM threads, you can still
+create a custom toploop supporting threads. See below.) Furthermore,
+the #thread directive should be executed before any packages are
+loaded.
+
+
+
+The #camlp4o and #camlp4r directives load the camlp4 syntax parsers
+for the standard and the revised syntax, respectively.
+
+
+
+Especially when developing packages, it is sometimes necessary to
+reload all dynamically loaded packages in the toploop. This can be
+forced by
+
+
+
+Topfind.reset();;
+
+
+
+which causes the "#require" directive to load all packages again. The
+Topfind module implements all the mentioned directives.
+
+
+
+
+Custom toploops
+
+
+It is very simple to create toploops. In order to make a toploop
+executable that includes directly the packages p1,p2,..,pN simply
+execute the command
+
+
+
+ocamlfind ocamlmktop -o toploop -package p1,p2,...,pN,findlib -linkpkg
+
+
+
+(Maybe you have to add the -custom switch.) Note that one of the
+packages should be "findlib" itself, because this adds the
+additional directives mentioned above, i.e. you can directly use
+these directives without #use "topfind" (but running "topfind"
+is harmless).
+
+
+
+Note that such a toploop includes the code of the packages given
+on the commmand line, but that it does not automatically add the
+package directories to the search path (in previous versions of
+findlib this was tried, but it never really worked). To do so,
+you still have to #require the packages.
+
+
+
+In order to create a toploop supporting VM-style threads, use the
+command
+
+
+ocamlfind ocamlmktop -o toploop -package p1,p2,...,pN,findlib,threads -vmthread -linkpkg
+
+
+Now the #thread directive will work and enable the access to the
+multi-threading modules.
+
+
+
+
+Runtime systems
+
+
+Building of runtime systems is supported, too. For example, you can run
+
+
+
+ocamlfind ocamlc -o runtime -make-runtime -package p1,p2,...,pN -linkpkg
+
+
+
+but the problem is which options to specify when a program is linked
+for this runtime system. If you executed
+
+
+
+ocamlfind ocamlc -o program -use-runtime runtime -package p1,p2,...,pN\
+ -linkpkg m1.cmo ... mM.cmo
+
+
+
+it would be tried to link the archives from the packages again into
+the bytecode binary. Because of this, it is necessary to suppress
+linking in packages of the runtime system when linking binaries for a
+runtime system. The -dontlink option can be used for this:
+
+
+
+ocamlfind ocamlc -o program -use-runtime runtime -package p1,p2,...,pN\
+ -dontlink p1,p2,...,pN -linkpkg m1.cmo ... mM.cmo
+
+
+
+Note that the -package option can enumerate more packages than
+-dontlink, and in this case the additional packages are actually
+linked in as they are not contained in the runtime system.
+
+
+
+
+
+
+
+Multi-threaded applications
+
+
+If an already existing package is planned to be used in a
+multi-threaded environment, some language constructs must be replaced
+by different ones. For example, global variables must be protected by
+locks (mutexes). Because of
+this it is common practice to provide two versions of such packages,
+one for single-, one for multi-threaded applications (or, another
+technique, there is a special add-on module that initializes a
+library for multi-threaded usage).
+
+
+
+The predicate "mt" should be used to recognize multi-threaded
+applications. For example, a package could consist of two archives,
+p.cma, and p_mt.cma, where the latter archive is designed for
+multi-threaded execution. The META file would contain the following
+lines causing that always the appropriate archive is linked:
+
+
+
+archive(byte) = "p.cma"
+archive(byte,mt) = "p_mt.cma"
+
+
+
+When querying the package database the option "-predicates mt" must be
+included in the commands in order to select the appropriate entries.
+
+
+
+When compiling or linking it is necessary to specify either the
+"-thread" or the "-vmthread" option anyway. The compiler frontends
+detects these options, and automatically set the "mt"
+predicate. The following command is an example for this; note that the
+"threads" package means the standard library of Ocaml providing thread
+support:
+
+
+
+ocamlfind ocamlc -thread -package threads,p,q -c x.ml
+
+
+
+For some operating systems, Ocaml supports the native multithreading
+libraries conforming to the POSIX interface. As the linker options are
+generally different, another predicate must be set to get these
+libraries linked in. The predicate "mt_posix" indicates POSIX
+threads while "mt_vm" indicates bytecode (virtual machine) threads.
+
+
+
+
+
+
+Support for gprof-enabled modules
+
+
+When a program is compiled and linked with ocamlopt, gprof-style
+profiling can be enabled by selecting the -p option. This means that
+the resulting archives are different, and that it would be useful if
+there were another predicate in order to select such archives.
+
+
+
+The predicate "gprof" can be used for this. It is automatically set if
+the -p option turns on the gprof-mode in an ocamlopt invocation.
+
+
+
+
+
+
+
+
+
+Complex packages
+
+
+The standard predicates
+
+
+Settings in the META file have usually the form:
+
+
+
+varname ( predname1, predname2, ... ) = "value"
+
+
+
+The names in the parantheses are called formal
+predicates and express a condition which must hold such
+that the value on the right side is selected. When querying
+information you can specify a set of actual
+predicates that are assumed to be true. There are the
+following standard predicates:
+
+
+
+
+
+The "byte" predicate means that the bytecode compiler is used.
+
+
+
+
+
+The "native" predicate means that the native compiler is used.
+
+
+
+
+
+The "toploop" predicate means that the toploop is available in the
+linked program.
+
+
+
+
+
+The "mt" predicate means that the program is multi-threaded.
+
+
+
+
+
+The "mt_posix" predicate means that in the case "mt" is set, too, the
+POSIX libraries are used to implement threads.
+
+
+
+
+
+The "mt_vm" predicate means that in the case "mt" is set, too, the
+VM-based libraries are used to implement threads.
+
+
+
+
+
+The "gprof" predicate means that in the case "native" is set, too, the
+program is compiled for profiling
+
+
+
+
+
+The "autolink" predicate indicates that ocamlc is able to perform
+automatic linking.
+
+
+
+
+
+
+
+It is possible to have more predicates indicating different
+environments; just use them, it is not necessary to declare them
+anywhere.
+
+
+
+The value which is selected for a variable depends on the set of
+assumed predicates. In order to get selected, all formal predicates
+must be included in the set of actual predicates; if still
+multiple values fulfill this condition, the value with the maximum
+number of formal predicates is used; and if still in doubt, the first
+of these in the META file is taken.
+
+
+
+It is possible to negate a formal predicate: Just prepend a minus
+sign to it, e.g. var(p,-q). In this case, it is required that the
+negated predicates are false (not contained in the set of actual predicates).
+
+
+
+For all variables that are evaluated after the dependency analysis,
+findlib adds the so-called package predicates to the set of actual
+predicates. For every selected package p the predicate pkg_p
+(with the fixed prefix "pkg_") is added. One application of this
+are compatibility checks: The special error variable
+is evaluated after dependency analysis, but before anything else
+is done. For example, to state that package p is incompatible with
+package q one can add to the META file of p:
+
+
+error(pkg_q) = "Package p is incompatible with q"
+
+
+The value of error is printed as message in the
+case the condition is true.
+
+
+
+
+
+Defining additional predicates
+
+
+Additional predicates can be simply used without any declaration,
+i.e. you can freely invent new predicates. One application of them
+is to express conditional linkage. For example, one may provide archives
+for various conditions, such as a production archive, and a
+development archive. A single new predicate, "development", would be
+sufficient to express this:
+
+
+
+archive(byte) = "p_production.cma"
+archive(byte,development) = "p_development.cma"
+
+
+
+When linking, include a "-predicates development" argument in the
+compiler command to select the development archive, otherwise the
+production archive is taken.
+
+
+
+Predicates could also be used to select among several implementations
+of the same module. Define simply one predicate per implementation,
+e.g. "p_impl1", "p_impl2", and "p_impl3", and specify the archives for
+every implementation separately:
+
+
+
+archive(byte,p_impl1) = "p_impl1.cma"
+archive(byte,p_impl2) = "p_impl2.cma"
+archive(byte,p_impl3) = "p_impl3.cma"
+
+
+
+In the case that the implementations have different dependencies,
+simply provide multiple "requires" variables:
+
+
+
+requires(p_impl1) = "q"
+requires(p_impl2) = "q,r"
+requires(p_impl3) = "r,s"
+
+
+
+Sometimes, the implementations require different linker options. In
+this case, define several versions of the "linkopts" variable just
+like in the "requires" example.
+
+
+
+Note that predicates are global identifiers that can be potentially
+applied to every selected package. In the case that a predicate is
+only meaningful for a single package, it is common practice to
+choose the package name as prefix of the predicate name (e.g.
+"netstring_minimum" is a predicate usually only applied to the "netstring"
+package).
+
+
+
+Predicates could be used to select which features of a library are
+linked. For example,
+
+
+archive(byte) = "p_basic.cma"
+archive(byte,p_extension) = "p_basic.cma p_ext.cma"
+
+
+would add the p_ext.cma archive only if the p_extension predicate
+were set. It is considered as bad practice to select
+extensions of libraries by predicates. Findlib provides the construct
+of subpackages for this purpose.
+
+
+
+
+
+ Appending to variables
+
+The syntax
+
+
+varname ( predname1, predname2, ... ) += "value"
+
+
+(note the "+=" operator) can be used to append values to variables
+depending on whether predicates are true. The "+=" lines in the META
+file are evaluated one after the other, and every
+line is selected for which the formal predicates are satisfied,
+and these lines are added to the current value of the variable. This is
+different from the "=" operator where only the most specific
+assignment is taken.
+
+
+The values are considered as space-separated words when they
+are appended, i.e. the new words are added to the list of current
+words.
+
+For example, in the hypothetic META file
+
+
+var(p) += "a"
+var(p,q) += "b"
+
+
+the value of var is "a b" if both p and q are true, and the value is
+only "a" is only p is true (and the value is empty otherwise). If
+the operator "=" had been used, the value would have been only "b"
+when both p and q are true.
+
+In the case that there both "=" and "+=" settings for
+the same variable, a special algorithm is used: First the most specific
+"=" setting is determined, and second all matching "+=" settings are
+appended in the order they appear in the file.
+
+Finally, here is a real-world example. Imagine you have an
+archive p.cma and a special extension for the toploop, p_top.cma.
+Furthermore, there is a special debugging version p_dev.cma that
+replaces p.cma during development. You can now simply write
+
+
+archive(byte) = "p.cma"
+archive(byte,development) = "p_dev.cma"
+archive(byte,toploop) += "p_top.cma"
+
+
+to select either p.cma or p_dev.cma, and append
+p_top.cma for toploops to whatever was selected in the first step.
+
+
+
+
+
+ Subpackages
+
+
+Sometimes a package consists of several archive files that are closely
+related. It is now possible to express dependencies between these
+archives by splitting the package into several parts called subpackages.
+For example, package p consists of a base archive p_base.cma, and two
+extensions p_ext1.cma and p_ext2.cma that both require the base archive
+but are independent of each other. This META file expresses this
+dependency directly:
+
+
+# META file of package p:
+requires = "p.base"
+
+package "base" (
+ archive(byte) = "p_base.cma"
+)
+
+package "ext1" (
+ requires = "p.base"
+ archive(byte) = "p_ext1.cma"
+)
+
+package "ext2" (
+ requires = "p.base"
+ archive(byte) = "p_ext2.cma"
+)
+
+
+If installed as package "p", this definition actually defines four
+logical packages: "p" (the main package), "p.base", "p.ext1", and
+"p.ext2" (the subpackages). These four entities only share the META
+file in which they are declared, and the directory where the archive
+files are stored, but all other properties can be individually set
+for each package. This also means that all package dependencies
+must explicitly added by "requires" variables, as there are no
+implied dependencies. In this example, the main package and "p.ext1"
+and "p.ext2" are all dependent on "p.base".
+
+
+
+The users of this installation can refer to all four packages. This
+means that
+
+
+ocamlfind ocamlc -package p -linkpkg ...
+
+
+links only p_base.cma into the final program, while
+
+
+ocamlfind ocamlc -package p.ext1 -linkpkg ...
+
+
+selects both p_base.cma and p_ext1.cma.
+
+
+
+
+
+ Glue code
+
+Imagine we have two packages p and q that are normally
+independent, i.e. one can link p without q, and q without p. However,
+when both p and q are used in the same program, it is expected that
+they cooperate with each other. Of course, this situation can be
+modeled with the help of subpackages (a real-world example of this are
+p=lablgtk and q=lablgl).
+
+The idea is as follows: p has a subpackage p.for_q that contains
+code with special features for q, and q has a subpackage q.use_p that
+depends on p, p.for_q, and q, and that contains the code using the
+special features of p. Expressed in META files, p would define
+
+
+# META file for p:
+requires = "..."
+archive = "..."
+
+package "for_q" (
+ requires = "p"
+ archive = "..."
+)
+
+
+and q would define
+
+
+# META file for q:
+requires = "..."
+archive = "..."
+
+package "use_p" (
+ requires = "q,p.for_q"
+ archive = "..."
+)
+
+
+Of couse, the program using both libraries must explicitly enable
+the subpackages by mentioning "q.use_p" on the ocamlfind command line,
+otherwise the glue code would be omitted.
+
+
+
+Unfortunately, it is not possible to use the package predicates
+pkg_p and pkg_q to add archives depending on whether the other
+package is also selected. The problem is that the order cannot
+be specified, i.e. whether p must be linked first or q.
+
+
+
+
+
+
+Plugins
+
+(Since findlib-1.6.)
+
+
+Plugins are packages that can be loaded at runtime. Plugins are
+intended as a mechanism for loading add-on code into
+executables. Technically, there is some overlap with the concept of a
+"shared library". Note, however, that there is no universal support
+for plugins, as it is unimplemented on some platforms, and only
+poorly on some others (including x86 in the 32 bit case). Also, there
+must always be an explicit "load" statement in the loading executable.
+You cannot link an executable directly against plugins.
+
+
+Preparing a plugin
+
+For bytecode there is no problem to load cma files at runtime.
+For native-code, though, you need to convert cmxa files into cmxs
+files first:
+
+
+ocamlopt -shared -linkall -o m.cmxs m.cmxa
+
+
+As mentioned, be prepared that this command fails on platforms where
+plugins are unavailable.
+
+The cmxs files can then be referenced from META. We don't use
+the "archive" variable in this case but "plugin":
+
+
+plugin(byte) = "m.cma"
+plugin(native) = "m.cmxs"
+
+
+Before findlib-1.6, there was some half-official convention using the
+"plugin" predicate. This is still supported, but deprecated:
+
+
+archive(byte) = "m.cma"
+archive(native,plugin) = "m.cmxs"
+
+
+
+Load-time dependencies
+Plugins can be, of course, be dependent on other
+plugins. You run into a problem, though, when you make a plugin dependent
+on a package that doesn't qualify as plugin (i.e. lacks the "plugin"
+definition). In this case, the loader simply skips the dependency,
+and you cannot load the plugin.
+
+Because of this dependency issue, it is recommended to add the
+"plugin" variable to all packages that are installed on a system,
+because this does not only allow it to load all packages at runtime, but
+also to use these packages as dependency of the actual plugin code.
+
+That said, you just need to add a "requires" directive, e.g.
+
+
+requires = "pkg1"
+plugin(byte) = "m.cma"
+plugin(native) = "m.cmxs"
+
+
+
+
+How to load a plugin
+Linking an executable that can load a plugin: An executable
+must link the package "findlib.dynload". This does not only add
+the loader, but also special initialization code to the executable:
+
+
+ocamlfind ocamlopt -o program -package findlib.dynload -linkpkg ...
+
+
+In particular, this records the packages that are already included
+into the executable (in-core packages). If a plugin is now dependent
+on such a package, this is recognized, and the package is not loaded
+(which would not work anyway).
+
+Now, you can load a plugin "foo" with:
+
+
+Fl_dynload.load_packages ["foo"]
+
+
+This loads the cma or cmxs files, and runs the initialization code
+of all top-level definitions of the included modules.
+
+Of course, you can also call load_packages from
+a library if "findlib.dynload" is a required package of the library
+package.
+
+
+Fat plugins
+Sometimes it is handy to create plugins that already include all
+the required packages. The plugin acts more like a dynamically loadable
+executable that already includes whatever it needs. You can create such
+a "fat" plugin with:
+
+
+ocamlfind ocamlopt -shared -linkpkg -linkall -o m.cmxs -package p1,p2,p3 m.cmxa
+
+
+In this case, the "requires" line in the META file should remain empty.
+
+
+
+Note, however, that you cannot handle packages this way that are already
+linked into the main program, because it is invalid to load a module that
+is already part of the main executable. Let's assume that the executable
+links in q1, q2, and q3. Then, you need to exclude these packages from the
+plugin. The -dont-link option comes handy in this case:
+
+
+ocamlfind ocamlopt -shared -linkpkg -linkall -o m.cmxs -package p1,p2,p3 -dont-link q1,q2,q3 m.cmxa
+
+
+This excludes q1,q2,q3 even if these packages occur as dependencies of
+p1,p2,p3. In this case, though, you need to put q1,q2,q3 into the "requires"
+field of META.
+
+
+
+
+
+
+
+Lint
+
+(Since findlib-1.6.)
+
+
+As it has become more and more complicated to write correct META files
+there is now some support for recognizing typical problems. Just use
+
+
+ocamlfind lint META
+
+
+to check the file META in the current directory. The tool reports problematic
+lines in META, e.g.
+
+
+archive(byte,plugin) = "oUnit.cma"
+This specification of dynamic loading is deprecated, you should add a "plugin(...)" variable.
+
+archive(native,plugin) = "oUnit.cmxs"
+This specification of dynamic loading is deprecated, you should add a "plugin(...)" variable.
+
+
+
+
+
+
+
+
+
+
+How to create your own packages
+
+
+Installing and removing packages
+
+
+The ocamlfind command can install and remove packages. For example,
+to install a package p containing the files META, m1.cmi, m2.cmi, p.cma,
+run
+
+
+ocamlfind install p META m1.cmi m2.cmi p.cma
+
+
+This installs the files into the default location for new packages
+(set in ocamlfind.conf). If you have files that are not always built,
+add these after the -optional switch:
+
+
+ocamlfind install p META m1.cmi m2.cmi p.cma -optional p.cmxa p.cmxs
+
+
+To remove the package, run
+
+
+ocamlfind remove p
+
+
+Note that every package must have a META file, it is not possible to
+omit it.
+
+
+
+
+
+Change your Makefile
+
+
+Here is a commented version of a Makefile that may be used to compile
+and link a package. It describes the frequent case that the package
+simply consists of a bundle of modules that are dependent on other
+packages.
+
+
+
+First, some general definitions. NAME is the name of the package. The
+OBJECTS variable enumerates the bytecode objects, whereas XOBJECTS
+names the native objects. The same naming convention is used for
+ARCHIVE and XARCHIVE, specifying the resulting bytecode, resp. native
+archive file. The REQUIRES variable lists the names of the packages
+that are needed for this package. If you need additional predicates,
+put them into the PREDICATES variable.
+
+
+
+NAME = p
+
+OCAMLC = ocamlfind ocamlc
+OCAMLOPT = ocamlfind ocamlopt
+OCAMLDEP = ocamldep
+
+OBJECTS = p1.cmo p2.cmo
+XOBJECTS = p1.cmx p2.cmx
+
+ARCHIVE = $(NAME).cma
+XARCHIVE = $(NAME).cmxa
+SARCHIVE = $(NAME).cmxs
+
+REQUIRES = unix str q r s
+PREDICATES =
+
+
+
+The default goal is "all", causing the bytecode archive to be
+created. In order to get a native archive, choose "opt" as second goal.
+(The ".PHONY" line is a declaration meaningful for GNU-make; "all" and
+"opt" are only virtual goals as there no files "all", or "opt" which
+is indicated by making them dependents of ".PHONY".)
+
+
+
+.PHONY: all opt
+all: $(ARCHIVE)
+opt: $(XARCHIVE) $(SARCHIVE)
+
+
+
+The following two rules create the bytecode resp. native archive from
+the objects.
+
+
+
+$(ARCHIVE): $(OBJECTS)
+ $(OCAMLC) -a -o $(ARCHIVE) -package "$(REQUIRES)" -linkpkg \
+ -predicates "$(PREDICATES)" $(OBJECTS)
+$(XARCHIVE): $(XOBJECTS)
+ $(OCAMLOPT) -a -o $(XARCHIVE) -package "$(REQUIRES)" -linkpkg \
+ -predicates "$(PREDICATES)" $(XOBJECTS)
+
+$(SARCHIVE): $(XARCHIVE)
+ $(OCAMLOPT) -shared -o $(SARCHIVE) $(XARCHIVE) || true
+
+
+
+Note that the cmxs archive is optional: we just ignore the error
+when it cannot be built.
+
+
+
+These rules compile the modules independently. The lines similar to
+".ml.cmo" must be read: "How to transform files with suffix .ml into
+files with suffix .cmo". The corresponding command can refer to the
+input file as "$<" and to the output file(s) as "$@".
+
+
+
+.SUFFIXES: .cmo .cmi .cmx .ml .mli
+
+.ml.cmo:
+ $(OCAMLC) -package "$(REQUIRES)" -predicates "$(PREDICATES)" \
+ -c $<
+.mli.cmi:
+ $(OCAMLC) -package "$(REQUIRES)" -predicates "$(PREDICATES)" \
+ -c $<
+.ml.cmx:
+ $(OCAMLOPT) -package "$(REQUIRES)" -predicates "$(PREDICATES)" \
+ -c $<
+
+
+
+The "depend" goal is the file describing the dependencies within the
+package; it is created by ocamldep.
+
+
+
+depend: *.ml *.mli
+ $(OCAMLDEP) *.ml *.mli >depend
+include depend
+
+
+
+The "install" rule is a bit tricky. First it is tested if there is a
+native archive to install, and if so, the variable "extra" contains
+the corresponding files. The "ocamlfind install" command creates a new
+package directory and puts the given files into it.
+
+
+
+.PHONY: install uninstall
+install: all
+ ocamlfind install $(NAME) *.mli *.cmi $(ARCHIVE) META \
+ -optional $(XARCHIVE) $(SARCHIVE)
+
+uninstall:
+ ocamlfind remove $(NAME)
+
+
+
+Last but not least a cleanup rule:
+
+
+
+.PHONY: clean
+ rm -f *.cmi *.cmo *.cmx *.cma *.cmxa *.a
+
+
+
+
+
+Using the Makefile wizard
+
+
+Especially for beginners, the findlib distribution includes a GUI to
+create Makefiles. As this is an optional feature, it must have been
+selected when findlib was built (option -with-toolbox). To invoke the
+GUI, run the command
+
+
+$ ocamlfind findlib/make_wizard
+
+
+(Btw, this is the general syntax to run executables installed in
+package directories.) The wizard starts, and allows you to describe
+your project. When you save the result, not only a "Makefile" is
+created, but also the file ".make-wizard" containing the state.
+If you later start the wizard again, this file will be automatically
+loaded, and you can modify your definition.
+
+The wizard consists of seven (hopefully self-explanatory) pages
+you can fill out. The basic idea is that the .ml, .mli, .mly, and .mll
+files in the current directory are compiled to a .cma or .cmxa
+archive, and that optionally executables are created from this archive
+and from additional modules (main programs). This scheme can be both
+used for libraries and application programs.
+
+You can choose packages you want to use in your library or
+program by clicking at them in a selection box. The camlp4 syntax
+parsers can be optionally enabled. The modules to be compiled can
+be picked from the current directory, they must be selected in the
+right order, however.
+
+The generated "Makefile" defines a number of logical targets
+(like "all", "opt", etc) that are explained at the beginning of the
+file. The file is fully commented, and not very difficult to understand.
+Only traditional Makefile syntax is used, so it is expected that it
+works for every version of the "make" utility.
+
+
+When you build the project, the META file is created
+dynamically. If you do not like this, set the variable MAKE_META to
+the empty string. (It is a good idea to put such setting into a
+second file, and enter the name of this file into the box "Local
+extensions in" of the wizard, so you can generate the "Makefile" again
+without overwriting your own modifications. This second file can
+override the setting in the generated "Makefile".)
+
+
+
+
+
+
+
+
+
+
+FAQs
+
+
+Does findlib support the autolink feature of OCaml 3?
+
+
+Short answer: Findlib is compatible with autolink
+
+
+
+The new archive format introduced with OCaml 3 can store the linker options
+that are necessary to link an archive. For example:
+
+
+ocamlc -a -o myarchive.cma mymodule.cmo -cclib -lmylibrary
+
+
+This command does not only create the new archive
+myarchive.cma, but it also writes into a special section of
+that file that the linker option -cclib -lmylibrary is
+necessary to link this archive.
+
+
+
+This means for findlib that most of the "linkopts" attributes in META files
+have become superflous: The compiler itself already knows the linker options,
+we do not need to tell the compiler the options. We could simply leave all
+"linkopts" attributes out.
+
+
+
+Of course, the "linkopts" feature of findlib still works. This is necessary
+because findlib should keep the compatibility with older software, and because
+"linkopts" is more powerful (you can have conditional linker options).
+
+
+
+If you have software that must run in both OCaml 2 and OCaml 3 environments,
+you can make your "linkopts" attribute dependent on the "autolink"
+predicate. For example:
+
+
+linkopts = "-cclib -lmylibrary"
+linkopts(autolink) = ""
+
+
+The findlib installation for OCaml 3 will take the second line which is
+reasonable because ocamlc already knows how to link; the installation for
+OCaml 2 never sets the "autolink" predicate and therefore uses the first line.
+
+
+
+
+
+
+ Why does findlib not automatically include the -custom option if
+linked with C code?
+
+ Short answer:
+Because there are several ways of linking, and findlib is not the
+right instance to find out the right way
+
+ Recent versions of OCaml support DLLs, at least for some
+platforms. Here, the option -custom is not necessary at all, because the
+C libraries can be looked up and loaded at runtime. The option -custom
+would have the effect of forcing static linking.
+
+ But even for platforms without DLL support, there are two
+alternatives. One possibility is to use -custom, and the other is to
+create runtime systems with -make-runtime, and reference them with
+-use-runtime. Fortunately, recent versions of OCaml select now themselves
+-custom automatically if -make-runtime is omitted, so findlib needs not to
+bother with it.
+
+
+
+
+
+
+ Does findlib support linking of applications as well as
+packages?
+
+
+Short answer: Yes, but it is not very obvious
+
+
+Applications also depend on other components, they have predicates, sometimes
+they need linker options; there seems to be only little difference between
+applications (stand-alone programs) and packages. If you want to use the
+findlib mechanisms for applications, too, the following trick helps.
+
+
+
+The environment variable OCAMLPATH may contain a
+colon-separated path of possible sitelib locations. It is allowed to include
+"." into the path (Shell commands follow):
+
+
+OCAMLPATH=.
+export OCAMLPATH
+
+
+This makes ".", i.e. your current directory, another sitelib location. You may
+now put the components of your applications into subdirectories together with
+META files; the hierarchy might look as follows:
+
+
+./Makefile global Makefile
+./localpkg1/META first local package directory: Contains META
+./localpkg1/... ... and more
+./localpkg2/META second local package dir: Contains META
+./localpkg2/... ... and more
+...
+
+
+From findlib's point of view, these directories are now package directories,
+and you can refer to them on the command line:
+
+
+ocamlfind ocamlc -o ... -linkpkg -package localpkg1,localpkg2,...
+
+
+If you do not want subdirectories, you can also refer to the META file in the
+same directory by the name ".", e.g.:
+
+
+ocamlfind ocamlc -o ... -linkpkg -package .
+
+
+In this case, the linking information will be taken from
+./META.
+
+
+
+
+
+
+ Does Findlib support camlp4?
+
+
+
+ Short answer: Yes, but there is only little
+ documentation.
+
+
+ Since Findlib-0.4, there is some experimental camlp4 support. For
+example, the following compiler invocation chooses the revised syntax:
+
+
+ocamlfind ocamlc -syntax camlp4r -package camlp4 -c file.ml
+
+
+ As you can see, camlp4 must be included as package, and the
+-syntax option must specify which syntax is selected (either
+camlp4o or camlp4r).
+
+
+ If you want to pass additional options to the preprocessor,
+you can use the -ppopt option:
+
+
+ocamlfind ocamlc -syntax camlp4r -package camlp4 -ppopt pa_ifdef.cmo -c file.ml
+
+
+
+
+From the toploop, the following commands work:
+
+
+$ ocaml
+ Objective Caml version 3.07+2
+
+# #use "./topfind";;
+- : unit = ()
+Findlib has been successfully loaded. Additional directives:
+ #require "package";; to load a package
+ #list;; to list the available packages
+ #camlp4o;; to load camlp4 (standard syntax)
+ #camlp4r;; to load camlp4 (revised syntax)
+ #predicates "p,q,...";; to set these predicates
+ Topfind.reset();; to force that packages will be reloaded
+ #thread;; to enable threads
+
+- : unit = ()
+# #camlp4o;; (* or camlp4r *)
+/opt/godi/lib/ocaml/std-lib/camlp4: added to search path
+/opt/godi/lib/ocaml/std-lib/camlp4/camlp4o.cma: loaded
+ Camlp4 Parsing version 3.07+2
+
+# _
+
+
+
+The concept
+
+If you have a -syntax option on the command line,
+ocamlfind will generate a -pp parameter and pass it to the
+invoked compiler. This is performed as follows: The specified packages are
+inspected under a certain set of predicates, the syntax
+predicates. The syntax predicates are syntax,
+preprocessor, and the predicates following
+-syntax. The predicate syntax simply
+means that the -syntax option has been specified.
+The predicate preprocessor means that the preprocessor
+command is being constructed. The predicates added by
+-syntax may be used to distinguish between syntax variants
+(currently camlp4o and camlp4r).
+
+
+The packages are searched for a variable preprocessor;
+normally the camlp4 package defines it as (see its META
+file):
+
+
+preprocessor = "camlp4 -nolib"
+
+
+Now that the name of the preprocessor command is known, the arguments of the
+command are looked up. The META files are evaluated under the syntax
+predicates, and all archive variables are collected and
+passed as arguments to the preprocessor. For example, the camlp4 package
+defines:
+
+
+archive(syntax,preprocessor,camlp4o) = "pa_o.cmo pa_op.cmo pr_dump.cmo"
+archive(syntax,preprocessor,camlp4r) = "pa_r.cmo pa_rp.cmo pr_dump.cmo"
+
+
+Note that the predicate preprocessor prevents ocamlfind from
+including these archives into the regular list of archives to link.
+
+
+
+How to write a META file for your own syntax extension
+
+Suppose you have two archives: pa_myext.cma contains the
+extension code of camlp4, and run_myext.cma contains runtime
+material that must be present in programs compiled with your extensions. Your
+META file should look as follows:
+
+
+requires = "camlp4"
+archive(syntax,toploop) = "pa_myext.cma run_myext.cma"
+archive(syntax,preprocessor) = "pa_myext.cma"
+archive(syntax,byte) = "run_myext.cma"
+archive(syntax,native) = "run_myext.cmxa"
+
+
+You may add dependencies on camlp4o or
+camlp4r if you have archives only working for one of the two
+syntax variants.
+
+
+To compile a program using your syntax extension package, one should use:
+
+
+ocamlfind ocamlc -package yourname -syntax variant ...
+
+
+
+
+
+ Example
+
+The package xstrp4 defines a syntax extension allowing
+$-substitutions in OCaml strings. Version 1.0 of this package takes advantage
+from the new camlp4 support of findlib; you may have a look at it for an
+example.
+
+You can find xstrp4
+here.
+
+
+
+
+
+
+ Does Findlib support ppx-style preprocessors?
+
+
+
+ Short answer: Yes, but there is only little
+ documentation.
+
+ Since findlib-1.5, ppx-style preprocessors are supported
+to some extent. A package can now define a "ppx" property which is simply
+a command to run as preprocessor (the command gets the marshalled AST
+as input, and must generate the transformed AST in its output; see the
+-ppx option of ocamlc/ocamlopt). A META file can simply look like:
+
+
+ppx = "./command"
+
+
+when "command" is installed in the package directory (but you can also
+omit "./" to search it, and you can prefix it with "@name/" if the command
+is taken from another package "name").
+
+
+ For more complex scenarios, additional options or
+arguments for the ppx preprocessor can be specified in descendant
+packages with the "ppxopt" property. Package "A" might provide a
+generic ppx preprocessor with a META file containing
+
+
+ppx = "./generic_ppx"
+
+
+Package B might instantiate that preprocessor with
+
+
+requires = "A"
+ppxopt = "A,ppx_b.cmo"
+
+
+In this case "ocamlfind ocamlc -package B" would
+add -ppx "path_to_A/genric_ppx ppx_b.cmo" to
+the ocamlc invocation. The format of the "ppxopt" property is
+specified in the findlib reference manual.
+
+
+
+ This feature is still a bit experimental.
+
+
+
+
+
+ Why do some people install the .cmx files?
+
+ In principle, it is not necessary to install the .cmx
+files created by the ocamlopt compiler, as the .a and .cmxa files
+already contain the assembly code and all needed auxiliary information.
+However, it may be sensible to install the .cmx files, too. They
+contain the intermediate code of small functions that are candidates
+for inlining, and installing them allows the compiler to do inlining
+even across library boundaries. Note that only very small functions
+can be inlined at all, and that there are language elements that
+prevent inlining (e.g. raising an exception with an argument), so
+it makes only sense when the library actually has such functions
+and really profits from inlining.
+
+ Inlining has also disadvantages: The library can no
+longer be replaced by a different version even if the interface
+remains exactly the same, because code using the library may have
+inlined code of the old version.
+
+
+
+
+ How do I express conflicts?
+
+ A conflict means that a certain combination of packages
+and package features will not work. A number of conflict conditions
+can be expressed:
+
+
+
+ To state that a package will not work if a certain
+predicate is set, use the error variable. For example,
+when package p does not work for multi-threaded programs:
+
+
+error(mt) = "Package p is incompatible with multi-threaded programs"
+
+
+This works for other standard predicates, too.
+
+
+
+ To state that a package will not work together with
+another package, it is possible to make error dependent
+on package predicates. For example, when package p does not work
+together with q:
+
+
+error(pkg_q) = "Package p is incompatible with package q"
+
+
+This also works with subpackages (e.g. pkg_q.q_sub).
+
+
+
+
+ If an error is too much, it might be a good idea to
+ just inform the user about possible problems. In this case
+ you can emit a warning instead:
+
+
+
+warning(pkg_q) = "Using package p and q together is a really bad idea"
+
+
+
+
+Note that such error conditions should only be added if there is
+absolutely no chance to get the combination of packages and features running.
+For example, in the case of multi-threaded programs it is often possible
+to add wrappers around unsafe libraries to fix the incompatibility.
+
+
+It is not possible to express incompatibilities between package
+versions. Such incompatibilities should be detected when software is
+installed, not when it is used.
+
+
+
+
diff --git a/local-packages/ocamlfind/doc/src/findlib_conf.mod b/local-packages/ocamlfind/doc/src/findlib_conf.mod
new file mode 100644
index 0000000..3960f1e
--- /dev/null
+++ b/local-packages/ocamlfind/doc/src/findlib_conf.mod
@@ -0,0 +1,427 @@
+
+
+
+ findlib.conf
+ 5
+ The findlib package manager for OCaml
+
+
+
+ findlib.conf
+ [Configuration of findlib/ocamlfind]
+
+
+
+
+GENERAL
+
+
+There are three possibilities to configure the findlib library:
+
+
+
+ Build time:
+
+ Before findlib is compiled, a "configure" script is invoked to figure
+ out the settings that are most likely to work on the system. Most
+ settings are simply entered into text files and can easily be changed
+ after installation. The following properties cannot be changed later
+ because they are compiled into the resulting binaries:
+
+
+
+
+ The default location of the configuration file findlib.conf. However,
+ you can set a different location by the environment variable
+ OCAMLFIND_CONF.
+
+
+
+
+
+ Whether the installed OCaml version supports autolinking or not.
+
+
+
+
+
+
+
+
+
+ Configuration file findlib.conf:
+
+ An initial version of this file is generated by the configure script,
+ but you are free to modify it later. Most important, this file
+ contains the system-wide search path used to look up packages, and the
+ default location where to install new packages.
+
+
+ All files with the suffix ".conf" found in the directory
+ findlib.conf.d are also scanned for parameters.
+
+
+
+
+
+ Environment variables:
+
+ The settings of findlib.conf can be overridden by environment variables.
+
+
+
+
+
+Last but not least, several settings can also be passed as
+command-line options, or by invoking the function
+Findlib.init.
+
+
+
+
+
+
+
+
+findlib.conf
+
+
+The directory containing findlib.conf is determined at build time (by
+running the configure script), the fallback default is
+/usr/local/etc. You can set a different location by
+changing the environment variable OCAMLFIND_CONF
+which must contain the absolute path of findlib.conf.
+
+
+
+The file has the same syntax as META, i.e. it consists of a
+number of lines with the format
+
+
+variable = "value"
+
+
+
+Here is the list of allowed variables:
+
+
+
+ path
+
+ The search path for META files/package directories. The variable
+ enumerates directories which are separated by colons (Windows:
+ semicolons), and these directories are tried in turn to find a certain
+ package. More exactly, if d is such a directory and p the searched
+ package, the search algorithm will first check whether d/p/META
+ exists. In this case, this META file is taken, and d/p is the package
+ directory. Second, the algorithm tries d/META.p, but the package
+ directory must be specified in this META.p file by a
+ directory directive.
+
+
+
+ Note that the first found META file is taken, so the order of the
+ directories in the search path counts.
+
+
+
+ This variable is required.
+
+
+
+ Example:
+
+
+path = "/usr/local/lib/ocaml/site-lib:/usr/lib/ocaml/site-lib"
+
+
+
+
+
+
+
+
+
+ destdir
+
+ This variable determines the location where ocamlfind
+ install puts the packages by default: If d is this
+ directory, and p the package to install, a new subdirectory d/p will
+ be created containing all the files of the package.
+
+
+ Example:
+
+destdir = "/usr/local/lib/ocaml/site-lib"
+
+
+
+
+ This variable is required.
+
+
+
+
+
+
+
+
+ metadir
+
+ If set, the command ocamlfind install will put the
+ META files of packages into this directory (files are named META.p
+ where p=package name); otherwise the META files are put into the
+ package directories like any other file.
+
+
+ Example:
+
+metadir = "/var/lib/findlib/metaregistry"
+
+
+
+
+ This variable is optional. It is not used by default.
+
+
+
+
+
+
+
+
+ ocamlc,
+ ocamlopt,
+ ocamlcp,
+ ocamlmktop,
+ ocamldoc,
+ ocamldep,
+ ocamlbrowser
+
+
+ If you want to call other executables than "ocamlc", "ocamlopt",
+ "ocamlcp", "ocamlmktop", "ocamldoc", "ocamldep", and
+ "ocamlbrowser", you can
+ set the names of
+ the executables here. The command ocamlfind looks
+ into these four variables to determine the names of the compilers to
+ call.
+
+
+ Example:
+
+ocamlc = "ocamlc.opt"
+ocamlopt = "ocamlopt.opt"
+ocamlcp = "ocamlcp.opt"
+ocamlmktop = "ocamlmktop.opt"
+
+
+
+
+ This variable is optional. It is not used by default.
+
+
+
+
+
+
+
+ stdlib
+
+ This variable determines the location of the standard library. This must
+ be the same directory for which the OCaml compilers are configured.
+
+
+
+ This variable is optional. It is not recommend to set this variable
+ unless you know what you are doing!
+
+
+
+
+
+
+
+ ldconf
+
+ This variable determines the location of the ld.conf file. This must
+ be the same file the OCaml compilers read in; it is updated by
+ ocamlfind when installing and removing packages. You can set this
+ variable to the special value "ignore" to disable
+ the automatic modification of the ld.conf file.
+
+
+
+ If not set, the ld.conf file is assumed to reside in the OCaml
+ standard library directory.
+
+
+
+ This variable is optional. It is not recommended to set this variable
+ unless you know what you are doing!
+
+
+
+
+
+
+
+Toolchains: It is possible to have variants of the original configuration.
+These variants are called "toolchains" because they are intended to
+select different compilers, e.g. patched compilers. In order to
+set a variable for a certain toolchain, use the syntax
+
+
+variable(toolchain) = "value"
+
+
+For example:
+
+
+ocamlc(mypatch) = "ocamlc-mypatch"
+
+
+When the toolchain "mypatch" is selected, this compiler will be used instead
+of the standard one.
+
+In order to switch to a certain toolchain, use the -toolchain
+option of ocamlfind.
+
+
+
+
+
+
+
+
+
+Environment
+
+
+A number of environment variables modifies the behaviour of
+findlib/ocamlfind:
+
+
+
+ OCAMLFIND_CONF
+
+ This variable overrides the location of the configuration file
+ findlib.conf. It must contain the absolute path name of this file.
+
+
+
+
+
+
+
+ OCAMLFIND_TOOLCHAIN
+
+ This variable sets the currently selected toolchain when
+ a -toolchain option is not passed
+ on the command line.
+
+
+
+
+
+
+
+ OCAMLPATH
+
+ This variable may contain an additional search path for package
+ directories. It is treated as if the directories were prepended to
+ the configuration variable path.
+
+
+
+
+
+
+
+ OCAMLFIND_DESTDIR
+
+ This variable overrides the configuration variable
+ destdir.
+
+
+
+
+
+
+
+ OCAMLFIND_METADIR
+
+ This variable overrides the configuration variable
+ metadir.
+
+
+
+
+
+
+
+ OCAMLFIND_COMMANDS
+ This variable overrides the configuration variables
+ ocamlc, ocamlopt,
+ ocamlcp, ocamlmktop,
+ ocamldoc, ocamldep, and/or
+ ocamlbrowser.
+ Its value must conform to the syntax
+
+
+ocamlc=name ocamlopt=name ocamlcp=name ocamlmktop=name ocamldoc=name ocamldep=name ocamlbrowser=name
+
+
+
+ Example:
+
+ocamlc=ocamlc-3.00 ocamlopt=ocamlopt-3.00 ocamlcp=ocamlcp-3.00 ocamlmktop=ocamlmktop-3.00
+
+
+
+
+
+
+
+
+
+ CAMLLIB or OCAMLLIB
+
+ This variable overrides the configuration variable
+ stdlib.
+
+
+
+
+
+
+
+ OCAMLFIND_LDCONF
+
+ This variable overrides the configuration variable
+ ldconf.
+
+
+
+
+
+
+
+ OCAMLFIND_IGNORE_DUPS_IN
+
+ This variable instructs findlib not to emit warnings that packages
+ or module occur several times. The variable must be set to the
+ directory where the packages reside that are to be ignored for this
+ warning.
+
+
+
+
+
+
+
+
+
+
+
diff --git a/local-packages/ocamlfind/doc/src/findlib_meta.mod b/local-packages/ocamlfind/doc/src/findlib_meta.mod
new file mode 100644
index 0000000..8924f1c
--- /dev/null
+++ b/local-packages/ocamlfind/doc/src/findlib_meta.mod
@@ -0,0 +1,420 @@
+
+
+
+ META
+ 5
+ The findlib package manager for OCaml
+
+
+
+ META
+ [File that specifies metainformation of OCaml packages]
+
+
+
+
+GRAMMAR
+
+ metafile ::= entry*
+ entry ::= assignment | addition | subpackage
+ subpackage ::= "package" pkgname '(' metafile ')'
+ assignment ::= variable_name [ formal_predicates ] '=' value
+ addition ::= variable_name [ formal_predicates ] '+=' value
+formal_predicates ::= '(' formal_predicate { ',' formal_predicate } ')'
+ variable_name ::= name
+ formal_predicate ::= name | '-' name
+ name ::= [ 'A'-'Z' 'a'-'z' '0'-'9' '_' '.' ]+
+ pkgname ::= '"' (character but not '.')* '"'
+ value ::= '"' character* '"'
+
+
+
+
+DESCRIPTION
+
+If a package directory contains a file with the fixed name "META" it
+is interpreted as described here. The file is a sequence of entries
+following the given grammar; every entry defines a variable under a
+certain condition given by the list of formal predicates, or it
+introduces a subpackage.
+
+
+
+There is a list of predefined variables and a list of standard
+predicates. These variables define: required packages, description, version
+information, directories, archive files, and linker options. The
+predicates denote circumstances of the application of the variables:
+whether the bytecode or the native compiler is used, if there is a
+toploop compiled in, details of multi-threading execution, details of
+profiling.
+
+
+
+
+DETAILS OF THE FILE FORMAT
+
+The file consists of a sequence of entries which must be formed as the
+grammar prescribes. The lexical tokens are names, values, and
+interpunctuation like '(', ',' and so on. Note that linefeeds do not
+play a special role, i.e. an entry definition may be given in more than
+one line, or several definitions may occur on a single line. There may
+be comments which begin with '#' and run until the end of the line.
+
+
+
+Names are sequences of the characters A-Z, a-z, 0-9, or _. Names
+containing capital letters and names beginning with digits are
+allowed but not recommended.
+
+
+
+Values are enclosed between double quotes. Values may contain any
+character. The characters " and \ must be preceded by backslashes.
+
+
+
+Package names must not contain the '.' character because it is used
+as delimiter of compound names.
+
+
+
+
+
+MAIN PACKAGES AND SUBPACKAGES
+
+The outermost variable assignments and additions belong to the main
+package. The name of the main package is not defined within META;
+it is either the name of the directory containing META or the suffix
+of the META file (if the name of the META file is formed like
+META.name).
+
+The keyword package starts the definition
+of a subpackage. There must not be two such definitions with the
+same name. Within the parantheses, the variable assignments and
+additions refer to the subpackage. It is allowed that a subpackage
+contains further subpackages.
+
+The package name following package
+is the local name relative to the main package, i.e. the
+name of the main package is not mentioned. At all other places,
+however, the subpackage must be prefixed by the name of the
+containing package, separated by a '.'.
+
+Subpackages are independent of the containing package, except
+that the subpackage points to the same installation directory as
+the containing package (i.e. the location of the installation directory
+is inherited from the containing package).
+
+
+
+
+SEMANTICS OF VARIABLE DEFINITIONS
+
+
+In order to determine the value of a variable, first all assignments
+are inspected, and the most specific assignment is taken (if there is
+none, the empty string will be taken as value). In a second step,
+all additions are gone through one after the other in the order
+they occur in the file, and the values of all matching additions are
+appended to the current value. In the following, it is further
+clarified which assignment is the most specific, which additions
+actually match, and how the details of the value addition look like.
+
+ The most specific assignment is selected upon a set of actual
+predicates, i.e. the set of predicates that are assumed to be true.
+The predicates occuring in the definitions of assignments and
+additions are called formal predicates. They may be positive or
+negative; the latter are prepended by a '-' sign. In order to
+determine the value after the evaluation of the assignments, the
+following rules apply:
+
+
+
+ An assignment can only be used if all positive formal
+predicates are included in the set of actual predicates, and if all
+negative formal predicates are not included in the set of actual
+predicates. Such an assignment is called
+applicable. If there is no such assignment, the
+variable will have no value.
+
+
+
+
+
+If there is more than one applicable assignment, the definition with
+the biggest number of formal predicates is selected.
+
+
+
+
+
+If there is still more than one applicable assignment, both applicable
+and with a maximum number of formal predicates, the definition that is defined
+first is selected.
+
+
+
+
+An addition is matching when all positive formal predicates are
+included in the set of actual predicates, and all negative formal
+predicates are not included.
+
+The value of an addition is appended to the current value with
+implicit white space as separator.
+
+
+
+
+VARIABLES
+
+
+There is a set of variables with predefined meaning:
+
+
+ The
+variable "directory" redefines the location of the package
+directory. Normally, the META file is the first file read in the
+package directory, and before any other file is read, the "directory"
+variable is evaluated in order to see if the package directory must be
+changed. The value of the "directory" variable is determined with an
+empty set of actual predicates. The value must be either: an absolute
+path name of the alternate directory, or a path name relative to the
+stdlib directory of OCaml (written "+path"), or a normal relative path
+name (without special syntax). In the latter case, the interpretation
+depends on whether it is contained in a main or sub package, and
+whether the standard repository layout or the alternate layout is in
+effect (see site-lib for these terms).
+For a main package in standard layout the base directory is the
+directory physically containing the META file, and the relative path
+is interpreted for this base directory. For a main package in
+alternate layout the base directory is the directory physically
+containing the META.pkg files. The base directory for subpackages is
+the package directory of the containing package. (In the case
+that a subpackage definition does not have a "directory" setting,
+the subpackage simply inherits the package directory of the containing
+package. By writing a "directory" directive one can change this
+location again.)
+
+
+
+
+The variable "requires" specifies the list of required packages. The
+names of the packages must be separated by white space and/or commas.
+The names must be fully qualified (i.e. when they refer to a subpackage,
+the names of all containing packages must be prepended, separated by
+'.').
+
+
+
+
+
+The variable "description" may include a short description of the
+package (displayed by ocamlfind list).
+
+
+
+
+
+The variable "version" specifies the version string.
+
+
+
+
+
+The variable "archive" specifies the list of archive files. These
+files should be given either as (1) plain names without any directory
+information; they are only searched in the package directory.
+(2) Or they have the form "+path" in which case the files are looked up
+relative to the standard library. (3) Or they have the form "@name/file"
+in which case the files are looked up in the package directory
+of another package. (4) Or they are given as absolute paths.
+
+
+The
+names of the files must be separated by white space and/or commas.
+In the preprocessor stage, the archive files are passed as extensions
+to the preprocessor (camlp4) call. In the linker stage (-linkpkg), the archive
+files are linked. In the compiler stage, the archive files are ignored.
+
+
+
+Note that "archive" should only be used for archive files that are
+intended to be included in executables or loaded into toploops. For
+modules loaded at runtime there is the separate variable "plugin".
+
+
+
+
+The variable "plugin" specifies the plugin archives of the package.
+These can be dynamically loaded with the Fl_dynload
+module. The plugin archives can have ".cmo", ".cma", or ".cmxs" suffix.
+
+
+
+
+
+The variable "linkopts" specifies additional linker options.
+
+
+
+
+
+The variable "error" can be used to signal error conditions. When
+this variable is applicable, the ocaml compilers are stopped, and
+an error message is printed. The message is the value of the variable.
+
+
+
+
+
+The variable "warning" can be used to signal warnings. When
+this variable is applicable, the warning is printed, but the
+compilation continues. The message is the value of the variable.
+
+
+
+
+
+The variable "exists_if" can be used to disable subpackages. The
+value of "exists_if" is a file; the subpackage is hidden if this
+file does not exist. You can also enumerate several files, and the
+subpackage is hidden if none of the files exist.
+
+
+
+
+
+The variable "ppx" is a command that is added to the compiler invocation
+via the -ppx option (available since OCaml-4.01). If the command is
+relative to the current directory (e.g. ./cmd), the command is expected
+in the package directory. The special forms as defined for "archive"
+are also available (e.g. @otherpkg/cmd). Additional arguments can be
+specified on the ocamlfind command line with the -ppxopt option
+or the "ppxopt" variable.
+
+
+
+
+
+The variable "ppxopt" is a set of options that are added to the ppx
+rewriter invocation. The contents of the variable consists of one or
+several whitespace-separated parts. Every part consists of several
+comma-separated subparts; the first subpart indicates the package
+that contains the ppx rewriter invocation, the rest contain the options
+to be appended. If the option is a path relative to the current directory
+(e.g. ./foo.cma), the path is expanded relative to the package directory.
+The special forms as defined for "archive" are also available
+(e.g. @otherpkg/foo.cma).
+
+
+
+
+
+
+It is possible to define additional variables but there is currently
+no software interpreting them.
+
+
+
+
+
+PREDICATES
+
+
+There is a list of standard predicates:
+
+
+
+
+
+The "byte" predicate means that the bytecode compiler is used.
+
+
+
+
+
+The "native" predicate means that the native compiler is used.
+
+
+
+
+
+The "toploop" predicate means that the toploop is available in the
+linked program. It is only set when the toploop is running, not when
+the toploop is generated.
+
+
+
+
+
+The "create_toploop" predicate means that a toploop is created (using
+ocamlmktop).
+
+
+
+
+
+The "mt" predicate means that the program is multi-threaded.
+
+
+
+
+
+The "mt_posix" predicate means that in the case "mt" is set, too, the
+POSIX libraries are used to implement threads.
+
+
+
+
+
+The "mt_vm" predicate means that in the case "mt" is set, too, the
+VM-based libraries are used to implement threads.
+
+
+
+
+
+The "gprof" predicate means that in the case "native" is set, too, the
+program is compiled for profiling
+
+
+
+
+
+The "autolink" predicate means that ocamlc can/will perform automatic linking.
+
+
+
+
+
+The "preprocessor" predicate means that the META variables are scanned for
+preprocessor options.
+
+
+
+
+The "syntax" predicate means that the -syntax option is present on the
+command line.
+
+
+
+
+Legacy: The "plugin" predicate could be used in some versions of findlib
+to select cmxs archives instead of cmxa archives. This use is still possible
+but discouraged.
+
+
+
+
+
+In addition to these predicates, there are package predicates
+for every package that is finally selected. Of course, this kind of
+predicate must not be used to select "directory" and "requires"
+variables, but for the other variables they are perfectly valid.
+The package predicates have the form "pkg_" plus the name of the
+package (fully qualified).
+
+
+
+
+
diff --git a/local-packages/ocamlfind/doc/src/findlib_mli.mod b/local-packages/ocamlfind/doc/src/findlib_mli.mod
new file mode 100644
index 0000000..12fd0d4
--- /dev/null
+++ b/local-packages/ocamlfind/doc/src/findlib_mli.mod
@@ -0,0 +1,181 @@
+
+
+
+ Findlib
+ 3
+ The findlib package manager for OCaml
+
+
+
+ Findlib
+ [Module for package management]
+
+
+
+
+SIGNATURE
+
+module Findlib :
+ sig
+
+
+
+
+
+
+ (* Note: This signature is incomplete. See findlib.mli for the
+ * full signature.
+ *)
+
+ end
+
+
+
+
+
+PACKAGING
+
+
+The Findlib module is part of the "findlib" package. In order to link
+it in, it is sufficient to link "findlib" in, e.g.
+
+
+
+ocamlfind ocamlc options -package findlib -linkpkg options
+
+
+
+There are archives for the bytecode compiler and for the native
+compiler; for single-threaded and for multi-threaded applications, and
+there is a special addition for toploops.
+
+
+
+
+
+DESCRIPTION
+
+
+The Findlib module is the primary interface of the findlib library. It
+contains functions to lookup packages, to interpret files, and to determine the ancestors of
+packages.
+
+
+
+
+
+Findlib.package_directory pkg
+
+val package_directory : string -> string
+
+
+Gets the absolute path of the directory where the package
+pkg is stored. The exception Not_found is
+raised if the package could not be found.
+Other exceptions may occur as file I/O is done.
+
+
+
+
+
+
+
+Findlib.package_property predicates
+pkgvariable
+
+
+val package_property : string list -> string -> string -> string
+
+
+Determines the value of the variable
+defined in the file of package
+pkg with the given set of
+predicates. The exception Not_found is
+raised if the package or the variable could not be found. Other
+exceptions may occur as file I/O is done.
+
+
+Examples
+
+Get the value of the "requires" variable of package "p" with an empty
+set of predicates:
+
+
+Findlib.package_property [] "p" "requires"
+
+
+Get the value of the "archive" variable of package "p" for
+multi-threaded bytecode applications:
+
+
+Findlib.package_property [ "mt"; "byte" ] "p" "archive"
+
+
+
+
+
+
+
+
+Findlib.package_ancestors predicates
+ pkg
+
+
+val package_ancestors : string list -> string -> string list
+
+
+Determines the direct ancestors of package
+pkg for the set of
+predicates. The returned list has no
+specific order. The exception Not_found is raised if the package could
+not be found. The exception Failure is raised if one of the ancestors
+could not be found, or if a circular dependency has been
+detected. Other exceptions may occur as file I/O is done.
+
+
+
+
+
+
+
+Findlib.package_deep_ancestors predicates
+ pkglist
+
+
+val package_deep_ancestors : string list -> string list -> string list
+
+
+Determines the list of direct or indirect ancestors of the packages in
+pkglist for the set of
+predicates. The returned list is
+topologically sorted.
+The exception Not_found is raised if the package could
+not be found. The exception Failure is raised if one of the ancestors
+could not be found, or if a circular dependency has been
+detected. Other exceptions may occur as file I/O is done.
+
+
+
+
+
+
+
+Findlib.default_location ()
+
+val default_location : unit -> string
+
+
+Gets the default location where new packages will be installed.
+
+
+
+
+
+
+
diff --git a/local-packages/ocamlfind/doc/src/findlib_ocamlfind.mod b/local-packages/ocamlfind/doc/src/findlib_ocamlfind.mod
new file mode 100644
index 0000000..2e03a05
--- /dev/null
+++ b/local-packages/ocamlfind/doc/src/findlib_ocamlfind.mod
@@ -0,0 +1,1436 @@
+
+
+
+ ocamlfind
+ 1
+ The findlib package manager for OCaml
+
+
+
+ ocamlfind
+ [Command-line interface of the Package manager]
+
+
+
+
+SYNOPSIS
+
+ ocamlfind query [-help | other options] package_name ...
+ or: ocamlfind ocamlc [-help | other options] file ...
+ or: ocamlfind ocamlcp [-help | other options] file ...
+ or: ocamlfind ocamlmktop [-help | other options] file ...
+ or: ocamlfind ocamlopt [-help | other options] file ...
+ or: ocamlfind ocamldoc [-help | other options] file ...
+ or: ocamlfind ocamldep [-help | other options] file ...
+ or: ocamlfind ocamlmklib [-help | other options] file ...
+ or: ocamlfind ocamlbrowser [-help | other options]
+ or: ocamlfind install [-help | other options] package_namefile ...
+ or: ocamlfind remove [-help | other options] package_name
+ or: ocamlfind lint META
+ or: ocamlfind list [-describe]
+ or: ocamlfind printppx [-help | other options] package_name ...
+ or: ocamlfind printconf [ variable ]
+ or: ocamlfind package/commandarg ...
+
+Optional toolchain selection by:
+ ocamlfind -toolchain name ...
+
+
+
+
+
+
+
+
+ THE "query" SUBCOMMAND
+
+
+
+Synopsis
+
+ocamlfind query [ -predicates p |
+ -format f |
+ -long-format | -l |
+ -i-format |
+ -l-format |
+ -a-format |
+ -o-format |
+ -p-format |
+ -prefix p |
+ -separator s |
+ -suffix s |
+ -pp |
+ -descendants | -d |
+ -recursive | -r
+ -qe | -qo] package ...
+
+
+
+Description
+
+ This command looks packages up, sorts them optionally, and
+prints attributes of them. If the option -recursive (short: -r) is not
+specified, exactly the packages given on the command line are looked
+up; if -recursive is present, the packages and all their ancestors, or
+if -descendants (short: -d) is present, too, all their descendants are printed.
+
+
+
+Package lookup and the selection of the attributes of the packages can
+be modified by specifying predicates; without a -predicates option the
+empty set of predicates is used. Note that even the lookup is
+influenced by the set of actual predicates as the "requires" variables
+may be conditional.
+
+
+
+What is printed about a package depends on the specified format; there
+are a number of options that modify the format. Some formats denote
+sets of values (such as -format %a), in which case multiple output
+records are printed for every package. (It is even possible to specify
+formats denoting the Cartesian product of sets, such as -format %a%o,
+but this does not make sense.) Before the first output record the
+prefix is printed, and the suffix after the last record. Between two
+records the separator is printed.
+
+
+
+
+Options
+
+
+
+-predicates p
+Sets the set of actual predicates. The argument
+ p is a list of predicate names separated
+ by commas and/or whitespace. If multiple -predicates options are
+ given, the union of all specified sets is effectively used.
+
+
+
+-format f
+Sets the format to the string
+ f. Characters preceded by a percent sign
+ are interpreted as placeholders; all other characters mean
+ themselves. The defined placeholders are listed below.
+ The default format is "%d".
+
+
+
+-long-format or -l
+Sets the format such that all relevant variables are printed.
+
+
+
+-i-format
+Same as -format "-I %d", i.e. directory options for ocamlc are printed.
+
+
+
+-l-format
+Same as -format "-ccopt -L%d", i.e. directory options for the
+linker backend are printed.
+
+
+
+-a-format
+Same as -format "%+a", i.e. archive file names are printed.
+
+
+
+-o-format
+Same as -format "%o", i.e. linker options are printed.
+
+
+
+-p-format
+Same as -format "%p", i.e. package names are printed.
+
+
+
+-prefix p
+Sets the prefix that is printed before the first output record
+ to the given string. The default prefix is the empty string.
+
+
+
+-suffix s
+Sets the suffix that is printed after the last output record
+ to the given string. The default suffix is the empty string.
+
+
+
+-separator s
+Sets the separator that is printed between output records to
+ the given string. The default separator is a linefeed character.
+
+
+
+-recursive or -r
+Not only the packages given on the command line are queried
+ but also all ancestors or descendants. If the option -descendants is
+ specified, too, the descendants are printed, otherwise the
+ ancestors. The packages are topologically sorted.
+
+
+
+-descendants -d
+Instead of the ancestors the descendants of the
+ given packages are queried. This option implies -recursive.
+
+
+
+-pp
+Query preprocessor packages (camlp4 syntax extensions). Normally
+it is not needed to set -predicates, except you need the archives (then add
+-predicates byte). This option implies -recursive.
+
+
+
+-qe
+Do not print most errors to stderr, just set the exit code
+
+
+
+-qo
+Do not print the regular output.
+
+
+
+
+
+
+
+Placeholders meaningful in the -format option
+
+
+
+%%
+ Replaced by a single percent sign
+
+
+%p
+ Replaced by the package name
+
+
+%d
+ Replaced by the package directory
+
+
+%m
+ Replaced by the path to the META file (new since findlib-1.6)
+
+
+
+%D
+ Replaced by the package description
+
+
+%v
+ Replaced by the version string
+
+
+%a
+ Replaced by the archive filename. If there is more
+ than one archive, a separate output record is printed for every archive.
+
+
+
+%+a
+ Like %a, but the filenames are converted to absolute
+ paths ("+" and "@" notations are resolved)
+
+
+
+%A
+ Replaced by the list of archive filenames.
+
+
+%+A
+ Like %A, but the filenames are converted to absolute
+ paths ("+" and "@" notations are resolved)
+
+
+%o
+ Replaced by one linker option. If there is more than
+ one option, a separate output record is printed for every option.
+
+
+
+%O
+ Replaced by the list of linker options.
+
+
+%(property)
+ Replaced by the value of the property named in parentheses,
+or the empty string if not defined.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ THE SUBCOMMANDS "ocamlc", "ocamlcp", "ocamlopt", and "ocamlmktop"
+
+
+
+Synopsis
+
+ocamlfind ( ocamlc | ocamlcp | ocamlopt | ocamlmktop )
+ [ -package package-name-list |
+ -linkpkg |
+ -predicates pred-name-list |
+ -dontlink package-name-list |
+ -syntax pred-name-list |
+ -ppopt camlp4-arg |
+ -ppxopt package,arg |
+ -dllpath-pkg package-name-list |
+ -dllpath-all |
+ -passopt arg |
+ -passrest arg... |
+ -only-show |
+ standard-option ]
+ file ...
+
+
+
+
+Description
+
+
+These subcommands are drivers for the compilers with the same names,
+i.e. "ocamlfind ocamlc" is a driver for "ocamlc", and so on. The
+subcommands understand all documented options of the compilers (here
+called standard-options), but also a few
+more options. If these subcommands are invoked only with standard
+options, they behave as if the underlying compiler had been called
+directly. The extra options modify this.
+
+
+
+Internally, these subcommands transform the given list of options and
+file arguments into an invocation of the driven compiler. This
+transformation only adds options and files, and the relative order of
+the options and files passed directly is unchanged.
+
+
+
+If there are -package options, additional directory search specifiers
+will be included ("-I", and "-ccopt -I"), such that files of all named
+packages and all ancestors can be found.
+
+
+
+The -linkpkg option causes that the packages listed in the -package
+options and all necessary ancestors are linked in. This means that the
+archive files implementing the packages are inserted into the list of
+file arguments.
+
+
+
+As the package database is queried a set of predicates is needed. Most
+predicates are set automatically, see below, but additional predicates
+can be given by a -predicates option.
+
+
+
+If there is a -syntax option, the drivers assume that
+a preprocessor is to be used. In this case, the preprocessor command
+is built first in a preprocessor stage, and this command is passed to the
+compiler using the -pp option. The set of predicates
+in the preprocessor stage is different from the set in the compiler/linker
+stage.
+
+
+
+
+Options for compiling and linking
+
+
+Here, only the additional options not interpreted by the compiler but
+by the driver itself, and options with additional effects are explained.
+Some options are only meaningful for the preprocessor call, and are
+explained below.
+
+
+
+
+-package package-name-list
+ Adds the listed package names to the set of included
+ packages. The package names may be separated by commas and/or
+ whitespace. In the transformed command, for every package of the set
+ of included packages and for any ancestor a directory search option
+ is inserted after the already given options. This means that
+ "-I" and "-ccopt -I" options are added for every package directory.
+
+
+
+-linkpkg
+ Causes that in the transformed command all archives
+ of the packages specified by -packages and all their ancestors are
+ added to the file arguments. More precisely, these archives are
+ inserted before the first given file argument. Furthermore, "-ccopt
+ -L" options for all package directories, and the linker options of
+ the selected packages are added, too. Note that the archives are
+ inserted in topological order while the linker options are added in
+ reverse toplogical order.
+
+
+
+-predicates pred-name-list
+ Adds the given predicates to the set of actual
+ predicates. The predicates must be separated by commas and/or
+ whitespace.
+
+
+
+-dontlink package-name-list
+ This option modifies the behaviour of
+ -linkpkg. Packages specified here and all ancestors are not linked
+ in. Again the packages are separated by commas and/or whitespace.
+
+
+
+-dllpath-pkg package-name-list
+ For these packages -dllpath options
+ are added to the compiler command. This may be useful when the ld.conf
+ file is not properly configured.
+
+
+-dllpath-all
+ For all linked packages -dllpath options
+ are added to the compiler command. This may be useful when the ld.conf
+ file is not properly configured.
+
+
+-passopt arg
+ The argument arg is
+ passed directly to the underlying compiler. This is needed to
+ specify undocumented compiler options.
+
+
+
+-passrest arg...
+ All following arguments arg... are
+ passed directly to the underlying compiler. This is needed to
+ specify undocumented compiler options.
+
+
+-only-show
+ Only prints the constructed command (ocamlc/ocamlopt) to
+ stdout, but does not execute the command. (This is for the unlikely event
+ that you need a wrapper around ocamlfind.)
+
+
+
+
+-verbose
+ This standard option is interpreted by the driver, too.
+
+
+
+-thread
+ This standard option causes that the predicate "mt"
+ is added to the set of actual predicates. If POSIX threads are available,
+ the predicate "mt_posix" is selected, too. If only VM threads are
+ available, the predicate "mt_vm" is included into the set, and the
+ compiler switch is changed into -vmthread.
+
+ Note that the presence of the "mt" predicate triggers special
+fixup of the dependency graph (see below).
+
+
+
+-vmthread
+ This standard option causes that the predicates "mt"
+ and "mt_vm" are added to the set of actual predicates.
+
+ Note that the presence of the "mt" predicate triggers special
+fixup of the dependency graph (see below).
+
+
+
+-p
+ This standard option of "ocamlopt" causes that the
+ predicate "gprof" is added to the set of actual predicates.
+
+
+
+
+
+
+
+
+Options for preprocessing
+
+
+The options relevant for the preprocessor are the following:
+
+
+
+
+-package package-name-list
+ These packages are considered while looking up the
+ preprocessor arguments. (It does not cause problems that the same
+ -package option is used for this purpose, because the set of predicates
+ is different.) It is recommended to mention at least camlp4
+ here if the preprocessor is going to be used.
+
+
+
+-syntax pred-name-list
+ These predicates are assumed to be true in addition
+ to the standard preprocessor predicates. See below for a list.
+
+
+
+ -ppopt camlp4-arg
+ This argument is passed to the camlp4 call.
+
+
+
+ -ppxopt package,arg
+ Add arg to the ppx
+ preprocessor invocation specified via the "ppx" property in
+ the META file of package.
+
+
+
+
+
+
+Predicates for compiling and linking
+
+
+
+byte
+
+
+The "byte" predicate means that one of the bytecode compilers is
+used. It is automatically included into the predicate set if the
+"ocamlc", "ocamlcp", or "ocamlmktop" compiler is used.
+
+
+
+
+
+native
+
+
+The "native" predicate means that the native compiler is used. It is
+automatically included into the predicate set if the "ocamlopt"
+compiler is used.
+
+
+
+
+
+toploop
+
+
+The "toploop" predicate means that the toploop is available in the
+linked program. This predicate is only set when the toploop is actually
+being executed, not when the toploop is created (this changed in version
+1.0.4 of findlib).
+
+
+
+
+
+create_toploop
+
+
+This predicate means that a toploop is being created (using
+ocamlmktop).
+
+
+
+
+
+mt
+
+
+The "mt" predicate means that the program is multi-threaded. It is
+automatically included into the predicate set if the -thread option is
+given.
+
+
+
+
+
+mt_posix
+
+
+The "mt_posix" predicate means that in the case "mt" is set, too, the
+POSIX libraries are used to implement threads. "mt_posix" is automatically
+included into the predicate set if the variable "type_of_threads" in the
+META description of the "threads" package has the value "posix". This
+is normally the case if "findlib" is configured for POSIX threads.
+
+
+
+
+
+mt_vm
+
+
+The "mt_vm" predicate means that in the case "mt" is set, too, the
+VM thread emulation is used to implement multi-threading.
+
+
+
+
+
+gprof
+
+
+The "gprof" predicate means that in the case "native" is set, too, the
+program is compiled for profiling. It is automatically included into
+the predicate set if "ocamlopt" is used and the -p option is in
+effect.
+
+
+
+
+
+autolink
+
+
+The "autolink" predicate means that ocamlc is able to perform automatic
+linking. It is automatically included into the predicate set if ocamlc
+knows automatic linking (from version 3.00), but it is not set if the
+-noautolink option is set.
+
+
+
+
+
+ syntax
+ This predicate is set if there is a -syntax
+ option. It is set both for the preprocessor and the compiler/linker stage,
+ and it can be used to find out whether the preprocessor is enabled or not.
+
+
+
+
+
+
+
+
+Predicates for preprocessing
+
+
+
+ preprocessor
+ This predicate is always set while looking up the
+ preprocessor arguments. It can be used to distinguish between the
+ preprocessor stage and the compiler/linker stage.
+
+
+ syntax
+ This predicate is set if there is a -syntax
+ option. It is set both for the preprocessor and the compiler/linker stage,
+ and it can be used to find out whether the preprocessor is enabled or not.
+
+
+
+ camlp4o
+ This is the reserved predicate for the standard OCaml syntax.
+ It can be used in the -syntax predicate list.
+
+
+
+ camlp4r
+ This is the reserved predicate for the revised OCaml syntax.
+ It can be used in the -syntax predicate list.
+
+
+
+
+
+
+
+Special behaviour of "ocamlmktop"
+
+ As there is a special module Topfind that
+supports loading of packages in scripts, the "ocamlmktop" subcommand
+can add initialization code for this module. This extra code is
+linked into the executable if "findlib" is in the set of effectively
+linked packages.
+
+
+
+
+
+
+Fixup of the dependency graph for multi-threading
+For a number of reasons the presence of the "mt" predicate triggers
+that (1) the package "threads" is added to the list of required packages
+and (2) the package "threads" becomes prerequisite of all other packages
+(except of itself and a few hardcoded exceptions). The effect is that
+the options -thread and -vmthread automatically select the "threads"
+package, and that "threads" is inserted at the right position in the
+package list.
+
+
+
+
+Extended file naming
+At a number of places one can not only refer to files by absolute
+or relative path names, but also by extended names. These have two
+major forms: "+name"
+refers to the subdirectory name of the
+standard library directory, and "@name"
+refers to the package directory of the package name.
+Both forms can be continued by a path, e.g. "@netstring/netstring_top.cma".
+
+
+
+You can use extended names: (1) With -I options,
+(2) as normal file arguments of the compiler, (3) in the
+"archive" property of packages.
+
+
+
+
+
+How to set the names of the compiler executables
+
+ Normally, the OCaml bytecode compiler can be called under the name
+ocamlc. However, this is not always true; sometimes a
+different name is chosen.
+
+ You can instruct ocamlfind to call executables with other names than
+ocamlc, ocamlopt,
+ocamlmktop, and ocamlcp. If present,
+the environment variable OCAMLFIND_COMMANDS is interpreted
+as a mapping from the standard names to the actual names of the executables. It
+must have the following format:
+
+
+standardname1=actualname1standardname2=actualname2 ...
+
+
+
+Example: You may set OCAMLFIND_COMMANDS as follows:
+
+
+OCAMLFIND_COMMANDS='ocamlc=ocamlc-3.00 ocamlopt=ocamlopt-3.00'
+export OCAMLFIND_COMMANDS
+
+
+
+Alternatively, you can change the configuration file
+findlib.conf.
+
+
+
+
+
+
+
+
+ THE SUBCOMMAND "ocamlmklib"
+
+
+
+Synopsis
+
+ocamlfind ocamlmklib
+ [ -package package-name-list |
+ -predicates pred-name-list |
+ -dllpath-pkg package-name-list |
+ -dllpath-all |
+ -passopt arg |
+ -passrest arg... |
+ standard-option ]
+ file ...
+
+
+
+
+Description
+
+
+This is a wrapper around ocamlmklib, and creates library archives and
+DLLs. In addition to the standard options, one can use -package to
+add the search path of packages. Note that no predicates are set by default -
+the wrapper does not know whether this is about byte or native code linking.
+
+
+
+This wrapper is mostly provided for completeness.
+
+
+
+
+
+
+
+
+
+
+
+ THE "ocamldep" SUBCOMMAND
+
+
+
+Synopsis
+
+ocamlfind ocamldep [-package package-name-list |
+ -syntax pred-name-list |
+ -ppopt camlp4-arg |
+ -passopt arg |
+ -passrest arg... |
+ -verbose |
+ standard-option] file ...
+
+
+
+Description
+
+This command is a driver for the tool ocamldep of the
+OCaml distribution. This driver is only useful in conjunction with
+the preprocessor camlp4; otherwise it does not provide more functions
+than ocamldep itself.
+
+
+
+
+Options
+
+
+Here, only the additional options not interpreted by ocamldep
+but
+by the driver itself, and options with additional effects are explained.
+
+
+
+
+ -package package-name-list
+ The packages named here are only used to look up the
+preprocessor options. The package camlp4 should be
+specified anyway, but further packages that add capabilities to the
+preprocessor can also be passed.
+
+
+
+ -syntax pred-name-list
+ The predicates that are in effect during the look-up
+of the preprocessor options. At least, either camlp4o
+(selecting the normal syntax), or camlp4r (selecting
+the revised syntax) should be specified.
+
+
+
+ -ppopt camlp4-arg
+ An option that is passed through to the camlp4 call.
+
+
+
+
+ -passopt arg
+ An option that is passed through to the ocamldep call.
+
+
+
+
+ -passrest arg...
+ All further arguments are passed down to ocamldep
+ unprocessed
+
+
+
+
+ -verbose
+ Displays the resulting ocamldep command (for debugging)
+
+
+
+
+
+
+
+Example
+
+A typical way of using this driver:
+
+
+ocamlfind ocamldep -package camlp4,xstrp4 -syntax camlp4r file1.ml file2.ml
+
+
+This command outputs the dependencies of file1.ml and
+file2.ml, although these modules make use of the
+syntax extensions provided by xstrp4 and are written
+in revised syntax.
+
+
+
+
+
+
+
+
+
+
+ THE "ocamlbrowser" SUBCOMMAND
+
+
+
+Synopsis
+
+ocamlfind ocamlbrowser [-package package-name-list |
+ -all |
+ -passopt arg
+ -passrest ]
+
+
+
+Description
+
+This driver calls the ocamlbrowser with package options.
+With -package, the specified packages are included into
+the search path of the browser, and the modules of these packages become
+visible (in addition to the standard library). The option -all causes that all packages are selected that are managed by findlib.
+
+
+As for other drivers, the options -passopt and
+-passrest can be used
+to pass arguments directly to the ocamlbrowser program.
+
+
+
+
+
+
+
+
+ THE SUBCOMMAND "ocamldoc"
+
+
+
+Synopsis
+
+ocamlfind ocamldoc
+ [ -package package-name-list |
+ -predicates pred-name-list |
+ -syntax pred-name-list |
+ -ppopt camlp4-arg |
+ standard-option ]
+ file ...
+
+
+
+
+Description
+
+
+This subcommand is a driver for ocamldoc. It undestands all options
+ocamldoc supports plus the mentioned findlib options. Basically,
+the -package options are translated into -I options, and the selected
+syntax options are translated into camlp4 options.
+
+
+
+
+Options
+
+
+Here, only the additional options not interpreted by ocamldep
+but
+by the driver itself, and options with additional effects are explained.
+
+
+
+
+-package package-name-list
+ Adds the listed package names to the set of included
+ packages. The package names may be separated by commas and/or
+ whitespace. In the transformed command, for every package of the set
+ of included packages and for any ancestor a directory search option
+ is inserted after the already given options. This means that
+ "-I" options are added for every package directory.
+
+
+
+
+-predicates pred-name-list
+ Adds the given predicates to the set of actual
+ predicates. The predicates must be separated by commas and/or
+ whitespace.
+
+
+
+
+ -syntax pred-name-list
+ The predicates that are in effect during the look-up
+of the preprocessor options. At least, either camlp4o
+(selecting the normal syntax), or camlp4r (selecting
+the revised syntax) should be specified.
+
+
+
+ -ppopt camlp4-arg
+ An option that is passed through to the camlp4 call.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ THE "install" SUBCOMMAND
+
+
+
+Synopsis
+
+ocamlfind install [ -destdir directory ]
+ [ -metadir directory ]
+ [ -ldconf path ]
+ [ -dont-add-directory-directive ]
+ [ -patch-version string ]
+ [ -patch-rmpkg name ]
+ [ -patch-archives ]
+ [ -dll ] [ -nodll ] [ -optional ] [ -add ]
+ package_namefile ...
+
+
+
+
+Description
+
+This subcommand installs a new package either at the default location
+(see the variable destdir of
+findlib.conf), or in the directory
+specified by the -destdir option. This
+means that a new package directory is created and that the files on
+the command line are copied to this directory. It is required that a
+META file is one of the files copied to the target
+directory.
+
+
+
+Note that package directories should be flat (no
+subdirectories). Existing packages are never overwritten.
+
+
+
+It is possible to have a separate directory for all the META files. If
+you want that, you have either to set the variable
+metadir of
+findlib.conf, or to specify the
+-metadir option. In this case, the file called META is copied to the
+specified directory and renamed to META.p (where p is the package
+name), while all the other files are copied to the package
+directory as usual. Furthermore, the META file is modified such that the
+directory variable contains the path of the package
+directory.
+
+
+
+The option -dont-add-directory-directive prevents the installer from
+adding a directory variable.
+
+
+
+If there are files ending in the suffixes .so or
+.dll, the package directory will be added to the
+DLL configuration file ld.conf, such that the dynamic
+loader can find the DLL. The location of this file can be overriden by
+the -ldconf option. To turn this feature off, use "-ldconf ignore";
+this causes that the ld.conf file is not modified.
+
+
+
+However, if there is a stublibs directory in site-lib, the DLLs are not
+installed in the package directory, but in this directory that is
+shared by all packages that are installed at the same location.
+In this case, the configuration file ld.conf is
+not modified, so you do not need to say "-ldconf ignore" if you
+prefer this style of installation.
+
+
+
+The options -dll and -nodll can be used to control exactly which files
+are considered as DLLs and which not. By default, the mentioned
+suffix rule is in effect: files ending in ".so" (Unix) or ".dll"
+(Windows) are DLLs. The switch -dll changes this, and all following
+files are considered as DLLs, regardless of their suffix. The switch
+-nodll expresses that the following files are not DLLs, even if they
+have a DLL-like suffix. For example, in the following call the files
+f1 and f2 are handled by the suffix rule; f3 and f4 are DLLs anyway;
+and f5 and f6 are not DLLs:
+
+
+ocamlfind install p f1 f2 -dll f3 f4 -nodll f5 f6
+
+
+
+
+The switch -optional declares that all following files are optional,
+i.e. the command will not fail if files do not exist.
+
+
+
+The -patch options may be used to change the contents of the META files
+while it is being installed. The option -patch-version changes the
+contents of the top-level "version" variable. The option -patch-rmpkg
+removes the given subpackage. The option -patch-archives is experimental,
+in particular it removes all non-existing files from "archive" variables,
+and even whole subpackages if the archives are missing.
+
+
+
+The effect of -add is to add further files to an already installed
+packages.
+
+
+
+
+
+
+
+
+
+
+
+ THE "remove" SUBCOMMAND
+
+
+
+Synopsis
+
+ocamlfind remove [ -destdir directory ]
+ [ -metadir directory ]
+ [ -ldconf path ]
+ package_name
+
+
+
+
+Description
+
+The package will removed if it is installed at the default location
+(see the variable destdir of
+findlib.conf). If the package
+resides at a different location, it will not be removed by default;
+however, you can pass an alternate directory for packages by the
+-destdir option. (This must be the same directory as specified at
+installation time.)
+
+
+
+Note that package directories should be flat (no subdirectories); this
+subcommand cannot remove deep package directories.
+
+
+
+If you have a separate directory for META files, you must either
+configure this directory by the metadir variable
+of findlib.conf, or by specifying
+the -metadir option.
+
+
+
+The command does not fail if the package and/or the META
+file cannot be located. You will get a warning only in this case.
+
+
+
+If the package directory is mentioned in the ld.conf
+configuration file for DLLs, it will be tried to remove this entry
+from the file. The location of this file can be overriden by
+the -ldconf option. To turn this feature off, use "-ldconf ignore";
+this causes that the ld.conf file is not modified.
+
+
+
+If there is a stublibs directory, it is checked whether the package
+owns any of the files in this directory, and the owned files will
+be deleted.
+
+
+
+
+
+
+
+
+
+
+ THE "list" SUBCOMMAND
+
+
+
+Synopsis
+
+ocamlfind list [-describe]
+
+
+
+
+Description
+
+This command lists all packages in the search path. The option -describe
+outputs the package descriptions, too.
+
+
+
+
+
+
+
+
+ THE "printppx" SUBCOMMAND
+
+
+
+Synopsis
+
+ocamlfind printppx
+ [ -predicates pred-name-list ]
+ [ -ppxopt package,arg ]
+ package ...
+
+
+
+
+Description
+
+This command prints the ppx preprocessor options as they would
+occur in an OCaml compiler invocation for the packages listed in
+the command. The output includes one "-ppx" option for each
+preprocessor. The possible options have the same meaning as for
+"ocamlfind ocamlc". The option "-predicates" adds assumed
+predicates and
+"-ppxopt package,arg"
+adds "arg" to the ppx invocation of
+package package.
+
+
+
+The output of "ocamlfind printppx" will contain quotes
+""" for ppx commands that contain
+space-separated arguments. In this case $(ocamlfind
+printppx ...) won't work as naively expected, because
+many shells (including bash and dash) perform field splitting on
+the result of command substitutions without honoring quotes.
+
+
+
+
+
+
+
+
+ THE "lint" SUBCOMMAND
+
+
+
+Synopsis
+
+ocamlfind lint file
+
+
+
+
+Description
+
+Checks the META file, and reports possible problems.
+
+
+
+
+
+
+
+
+ THE "printconf" SUBCOMMAND
+
+
+
+Synopsis
+
+ocamlfind printconf [ conf | path | destdir | metadir | metapath | stdlib | ldconf ]
+
+
+
+
+Description
+
+This command prints the effective configuration after reading the
+configuration file, and after applying the various environment
+variables overriding settings. When called without arguments, the command
+prints all configuration options in a human-readable form. When called
+with an argument, only the value of the requested option is printed without
+explaining texts:
+
+
+
+
+ conf
+ Prints the location of the configuration file findlib.conf
+
+
+
+ path
+ Prints the search path for packages. The members of the
+ path are separated by linefeeds.
+
+
+ destdir
+ Prints the location where package are installed and
+ removed by default.
+
+
+ metadir
+ Prints the location where META files are installed and
+ removed (if the alternative layout is used).
+
+
+ metapath
+ Prints the path where the META file is installed for
+a fictive package. The name of the package is marked with '%s' in the
+path. For instance, this command could output "/some/path/%s/META" or
+"/some/path/META.%s", depending on the layout.
+
+
+ stdlib
+ Prints the location of the standard library.
+
+
+
+ ldconf
+ Prints the location of the ld.conf file
+
+
+
+
+
+
+
+
+
+
+
+
+ THE SUBCOMMAND CALLING PACKAGE PROGRAMS
+
+
+
+Synopsis
+
+ocamlfind pkg/cmdargument ...
+
+
+
+
+Description
+This subcommand is useful to call programs that are installed in
+package directories. It looks up the directory for
+pkg and calls the command named
+cmd in this directory. The remaining arguments
+are passed to this command.
+
+argv(0) contains the absolute path to the command, and argv(1) and
+the following argv entries contain the arguments. The working directory
+is not changed.
+
+Example: To call the program "x" that is installed in package "p",
+with arguments "y" and "z", run:
+
+
+ocamlfind p/x y z
+
+
+
+
+
+
+
+
+ CONFIGURATION FILE, ENVIRONMENT VARIABLES
+
+
+ The configuration file and environment variables are documented
+in the manual page for
+ findlib.conf.
+
+
+
+
+
+
+
+ HOW TO SET THE TOOLCHAIN
+
+
+
+Synopsis
+
+ocamlfind -toolchain name ...
+
+
+
+
+Description
+The -toolchain option can be given before any other command,
+e.g.
+
+ocamlfind -toolchain foo ocamlc -c file.ml
+
+compiles file.ml with toolchain "foo". By selecting toolchains one
+can switch to different command sets. For instance, the toolchain
+"foo" may consist of a patched ocamlc compiler.
+See findlib.conf how to
+configure toolchains.
+
+
+
+
+
+
+
+
+
diff --git a/local-packages/ocamlfind/doc/src/findlib_ref.dsl b/local-packages/ocamlfind/doc/src/findlib_ref.dsl
new file mode 100644
index 0000000..4b2f063
--- /dev/null
+++ b/local-packages/ocamlfind/doc/src/findlib_ref.dsl
@@ -0,0 +1,24 @@
+
+]>
+
+
+
+
+
+(define %footnotes-at-end%
+ ;; Should footnotes appear at the end of HTML pages?
+ #t)
+
+(define %html-ext%
+ ;; Default extension for HTML output files
+ ".html")
+
+(define %root-filename%
+ ;; Name for the root HTML document
+ "index")
+
+
+
+
+
diff --git a/local-packages/ocamlfind/doc/src/findlib_ref.sgml b/local-packages/ocamlfind/doc/src/findlib_ref.sgml
new file mode 100644
index 0000000..0d5ffa1
--- /dev/null
+++ b/local-packages/ocamlfind/doc/src/findlib_ref.sgml
@@ -0,0 +1,61 @@
+
+
+
+
+
+
+
+ %gps.common;
+]>
+
+
+
+The findlib Reference Manual
+
+
+
+
+ Gerd
+ Stolpmann
+
+
+
+ gerd@gerd-stolpmann.de
+
+
+
+
+
+
+
+1999-2003Gerd Stolpmann
+
+
+
+
+
+Commands
+&findlibocamlfind;
+
+
+
+Files
+&findlibmeta;
+
+&findlibconf;
+
+&findlibsitelib;
+
+
+
+Library
+
+ The findlib library
+
+ The findlib library
+
+
+
+
+
diff --git a/local-packages/ocamlfind/doc/src/findlib_reference.sgml b/local-packages/ocamlfind/doc/src/findlib_reference.sgml
new file mode 100644
index 0000000..2150d52
--- /dev/null
+++ b/local-packages/ocamlfind/doc/src/findlib_reference.sgml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+]>
+
+
+Reference
+&findlibocamlfind;
+&findlibmeta;
+&findlibconf;
+&findlibsitelib;
+
+
diff --git a/local-packages/ocamlfind/doc/src/findlib_reference.xml b/local-packages/ocamlfind/doc/src/findlib_reference.xml
new file mode 100644
index 0000000..35a07e9
--- /dev/null
+++ b/local-packages/ocamlfind/doc/src/findlib_reference.xml
@@ -0,0 +1,2153 @@
+
+Referenceocamlfind1The findlib package manager for OCamlocamlfind[Command-line interface of the Package manager]SYNOPSIS ocamlfind query [-help | other options] package_name ...
+ or: ocamlfind ocamlc [-help | other options] file ...
+ or: ocamlfind ocamlcp [-help | other options] file ...
+ or: ocamlfind ocamlmktop [-help | other options] file ...
+ or: ocamlfind ocamlopt [-help | other options] file ...
+ or: ocamlfind ocamldoc [-help | other options] file ...
+ or: ocamlfind ocamldep [-help | other options] file ...
+ or: ocamlfind ocamlmklib [-help | other options] file ...
+ or: ocamlfind ocamlbrowser [-help | other options]
+ or: ocamlfind install [-help | other options] package_namefile ...
+ or: ocamlfind remove [-help | other options] package_name
+ or: ocamlfind lint META
+ or: ocamlfind list [-describe]
+ or: ocamlfind printppx [-help | other options] package_name ...
+ or: ocamlfind printconf [ variable ]
+ or: ocamlfind package/commandarg ...
+
+Optional toolchain selection by:
+ ocamlfind -toolchain name ...
+ THE "query" SUBCOMMANDSynopsisocamlfind query [ -predicates p |
+ -format f |
+ -long-format | -l |
+ -i-format |
+ -l-format |
+ -a-format |
+ -o-format |
+ -p-format |
+ -prefix p |
+ -separator s |
+ -suffix s |
+ -pp |
+ -descendants | -d |
+ -recursive | -r
+ -qe | -qo] package ...Description This command looks packages up, sorts them optionally, and
+prints attributes of them. If the option -recursive (short: -r) is not
+specified, exactly the packages given on the command line are looked
+up; if -recursive is present, the packages and all their ancestors, or
+if -descendants (short: -d) is present, too, all their descendants are printed.Package lookup and the selection of the attributes of the packages can
+be modified by specifying predicates; without a -predicates option the
+empty set of predicates is used. Note that even the lookup is
+influenced by the set of actual predicates as the "requires" variables
+may be conditional.What is printed about a package depends on the specified format; there
+are a number of options that modify the format. Some formats denote
+sets of values (such as -format %a), in which case multiple output
+records are printed for every package. (It is even possible to specify
+formats denoting the Cartesian product of sets, such as -format %a%o,
+but this does not make sense.) Before the first output record the
+prefix is printed, and the suffix after the last record. Between two
+records the separator is printed.Options-predicates pSets the set of actual predicates. The argument
+ p is a list of predicate names separated
+ by commas and/or whitespace. If multiple -predicates options are
+ given, the union of all specified sets is effectively used.-format fSets the format to the string
+ f. Characters preceded by a percent sign
+ are interpreted as placeholders; all other characters mean
+ themselves. The defined placeholders are listed below.
+ The default format is "%d".-long-format or -lSets the format such that all relevant variables are printed.-i-formatSame as -format "-I %d", i.e. directory options for ocamlc are printed.-l-formatSame as -format "-ccopt -L%d", i.e. directory options for the
+linker backend are printed.-a-formatSame as -format "%+a", i.e. archive file names are printed.-o-formatSame as -format "%o", i.e. linker options are printed.-p-formatSame as -format "%p", i.e. package names are printed.-prefix pSets the prefix that is printed before the first output record
+ to the given string. The default prefix is the empty string.-suffix sSets the suffix that is printed after the last output record
+ to the given string. The default suffix is the empty string.-separator sSets the separator that is printed between output records to
+ the given string. The default separator is a linefeed character.-recursive or -rNot only the packages given on the command line are queried
+ but also all ancestors or descendants. If the option -descendants is
+ specified, too, the descendants are printed, otherwise the
+ ancestors. The packages are topologically sorted.-descendants -dInstead of the ancestors the descendants of the
+ given packages are queried. This option implies -recursive.-ppQuery preprocessor packages (camlp4 syntax extensions). Normally
+it is not needed to set -predicates, except you need the archives (then add
+-predicates byte). This option implies -recursive.-qeDo not print most errors to stderr, just set the exit code-qoDo not print the regular output.Placeholders meaningful in the -format option%%Replaced by a single percent sign%pReplaced by the package name%dReplaced by the package directory%mReplaced by the path to the META file (new since findlib-1.6)%DReplaced by the package description%vReplaced by the version string%aReplaced by the archive filename. If there is more
+ than one archive, a separate output record is printed for every archive.%+aLike %a, but the filenames are converted to absolute
+ paths ("+" and "@" notations are resolved)%AReplaced by the list of archive filenames.%+ALike %A, but the filenames are converted to absolute
+ paths ("+" and "@" notations are resolved)%oReplaced by one linker option. If there is more than
+ one option, a separate output record is printed for every option.%OReplaced by the list of linker options.%(property)Replaced by the value of the property named in parentheses,
+or the empty string if not defined.
+
+
+
+ THE SUBCOMMANDS "ocamlc", "ocamlcp", "ocamlopt", and "ocamlmktop"Synopsisocamlfind ( ocamlc | ocamlcp | ocamlopt | ocamlmktop )
+ [ -package package-name-list |
+ -linkpkg |
+ -predicates pred-name-list |
+ -dontlink package-name-list |
+ -syntax pred-name-list |
+ -ppopt camlp4-arg |
+ -ppxopt package,arg |
+ -dllpath-pkg package-name-list |
+ -dllpath-all |
+ -passopt arg |
+ -passrest arg... |
+ -only-show |
+ standard-option ]
+ file ...DescriptionThese subcommands are drivers for the compilers with the same names,
+i.e. "ocamlfind ocamlc" is a driver for "ocamlc", and so on. The
+subcommands understand all documented options of the compilers (here
+called standard-options), but also a few
+more options. If these subcommands are invoked only with standard
+options, they behave as if the underlying compiler had been called
+directly. The extra options modify this.Internally, these subcommands transform the given list of options and
+file arguments into an invocation of the driven compiler. This
+transformation only adds options and files, and the relative order of
+the options and files passed directly is unchanged.If there are -package options, additional directory search specifiers
+will be included ("-I", and "-ccopt -I"), such that files of all named
+packages and all ancestors can be found.The -linkpkg option causes that the packages listed in the -package
+options and all necessary ancestors are linked in. This means that the
+archive files implementing the packages are inserted into the list of
+file arguments.As the package database is queried a set of predicates is needed. Most
+predicates are set automatically, see below, but additional predicates
+can be given by a -predicates option.If there is a -syntax option, the drivers assume that
+a preprocessor is to be used. In this case, the preprocessor command
+is built first in a preprocessor stage, and this command is passed to the
+compiler using the -pp option. The set of predicates
+in the preprocessor stage is different from the set in the compiler/linker
+stage.Options for compiling and linkingHere, only the additional options not interpreted by the compiler but
+by the driver itself, and options with additional effects are explained.
+Some options are only meaningful for the preprocessor call, and are
+explained below.-package package-name-listAdds the listed package names to the set of included
+ packages. The package names may be separated by commas and/or
+ whitespace. In the transformed command, for every package of the set
+ of included packages and for any ancestor a directory search option
+ is inserted after the already given options. This means that
+ "-I" and "-ccopt -I" options are added for every package directory.
+ -linkpkgCauses that in the transformed command all archives
+ of the packages specified by -packages and all their ancestors are
+ added to the file arguments. More precisely, these archives are
+ inserted before the first given file argument. Furthermore, "-ccopt
+ -L" options for all package directories, and the linker options of
+ the selected packages are added, too. Note that the archives are
+ inserted in topological order while the linker options are added in
+ reverse toplogical order.-predicates pred-name-listAdds the given predicates to the set of actual
+ predicates. The predicates must be separated by commas and/or
+ whitespace. -dontlink package-name-listThis option modifies the behaviour of
+ -linkpkg. Packages specified here and all ancestors are not linked
+ in. Again the packages are separated by commas and/or whitespace.-dllpath-pkg package-name-listFor these packages -dllpath options
+ are added to the compiler command. This may be useful when the ld.conf
+ file is not properly configured.-dllpath-allFor all linked packages -dllpath options
+ are added to the compiler command. This may be useful when the ld.conf
+ file is not properly configured.-passopt argThe argument arg is
+ passed directly to the underlying compiler. This is needed to
+ specify undocumented compiler options.-passrest arg...All following arguments arg... are
+ passed directly to the underlying compiler. This is needed to
+ specify undocumented compiler options.-only-showOnly prints the constructed command (ocamlc/ocamlopt) to
+ stdout, but does not execute the command. (This is for the unlikely event
+ that you need a wrapper around ocamlfind.)-verboseThis standard option is interpreted by the driver, too.-threadThis standard option causes that the predicate "mt"
+ is added to the set of actual predicates. If POSIX threads are available,
+ the predicate "mt_posix" is selected, too. If only VM threads are
+ available, the predicate "mt_vm" is included into the set, and the
+ compiler switch is changed into -vmthread.Note that the presence of the "mt" predicate triggers special
+fixup of the dependency graph (see below).-vmthreadThis standard option causes that the predicates "mt"
+ and "mt_vm" are added to the set of actual predicates.Note that the presence of the "mt" predicate triggers special
+fixup of the dependency graph (see below).-pThis standard option of "ocamlopt" causes that the
+ predicate "gprof" is added to the set of actual predicates.Options for preprocessingThe options relevant for the preprocessor are the following:-package package-name-listThese packages are considered while looking up the
+ preprocessor arguments. (It does not cause problems that the same
+ -package option is used for this purpose, because the set of predicates
+ is different.) It is recommended to mention at least camlp4
+ here if the preprocessor is going to be used.
+ -syntax pred-name-listThese predicates are assumed to be true in addition
+ to the standard preprocessor predicates. See below for a list.-ppopt camlp4-argThis argument is passed to the camlp4 call.
+ -ppxopt package,argAdd arg to the ppx
+ preprocessor invocation specified via the "ppx" property in
+ the META file of package.
+ Predicates for compiling and linkingbyteThe "byte" predicate means that one of the bytecode compilers is
+used. It is automatically included into the predicate set if the
+"ocamlc", "ocamlcp", or "ocamlmktop" compiler is used.nativeThe "native" predicate means that the native compiler is used. It is
+automatically included into the predicate set if the "ocamlopt"
+compiler is used.toploopThe "toploop" predicate means that the toploop is available in the
+linked program. This predicate is only set when the toploop is actually
+being executed, not when the toploop is created (this changed in version
+1.0.4 of findlib).create_toploopThis predicate means that a toploop is being created (using
+ocamlmktop).mtThe "mt" predicate means that the program is multi-threaded. It is
+automatically included into the predicate set if the -thread option is
+given. mt_posixThe "mt_posix" predicate means that in the case "mt" is set, too, the
+POSIX libraries are used to implement threads. "mt_posix" is automatically
+included into the predicate set if the variable "type_of_threads" in the
+META description of the "threads" package has the value "posix". This
+is normally the case if "findlib" is configured for POSIX threads.mt_vmThe "mt_vm" predicate means that in the case "mt" is set, too, the
+VM thread emulation is used to implement multi-threading.gprofThe "gprof" predicate means that in the case "native" is set, too, the
+program is compiled for profiling. It is automatically included into
+the predicate set if "ocamlopt" is used and the -p option is in
+effect.autolinkThe "autolink" predicate means that ocamlc is able to perform automatic
+linking. It is automatically included into the predicate set if ocamlc
+knows automatic linking (from version 3.00), but it is not set if the
+-noautolink option is set.syntaxThis predicate is set if there is a -syntax
+ option. It is set both for the preprocessor and the compiler/linker stage,
+ and it can be used to find out whether the preprocessor is enabled or not.
+ Predicates for preprocessingpreprocessorThis predicate is always set while looking up the
+ preprocessor arguments. It can be used to distinguish between the
+ preprocessor stage and the compiler/linker stage.syntaxThis predicate is set if there is a -syntax
+ option. It is set both for the preprocessor and the compiler/linker stage,
+ and it can be used to find out whether the preprocessor is enabled or not.
+ camlp4oThis is the reserved predicate for the standard OCaml syntax.
+ It can be used in the -syntax predicate list.
+ camlp4rThis is the reserved predicate for the revised OCaml syntax.
+ It can be used in the -syntax predicate list.
+ Special behaviour of "ocamlmktop" As there is a special module Topfind that
+supports loading of packages in scripts, the "ocamlmktop" subcommand
+can add initialization code for this module. This extra code is
+linked into the executable if "findlib" is in the set of effectively
+linked packages. Fixup of the dependency graph for multi-threadingFor a number of reasons the presence of the "mt" predicate triggers
+that (1) the package "threads" is added to the list of required packages
+and (2) the package "threads" becomes prerequisite of all other packages
+(except of itself and a few hardcoded exceptions). The effect is that
+the options -thread and -vmthread automatically select the "threads"
+package, and that "threads" is inserted at the right position in the
+package list.Extended file namingAt a number of places one can not only refer to files by absolute
+or relative path names, but also by extended names. These have two
+major forms: "+name"
+refers to the subdirectory name of the
+standard library directory, and "@name"
+refers to the package directory of the package name.
+Both forms can be continued by a path, e.g. "@netstring/netstring_top.cma".You can use extended names: (1) With -I options,
+(2) as normal file arguments of the compiler, (3) in the
+"archive" property of packages.How to set the names of the compiler executables Normally, the OCaml bytecode compiler can be called under the name
+ocamlc. However, this is not always true; sometimes a
+different name is chosen. You can instruct ocamlfind to call executables with other names than
+ocamlc, ocamlopt,
+ocamlmktop, and ocamlcp. If present,
+the environment variable OCAMLFIND_COMMANDS is interpreted
+as a mapping from the standard names to the actual names of the executables. It
+must have the following format:
+
+standardname1=actualname1standardname2=actualname2 ...Example: You may set OCAMLFIND_COMMANDS as follows:
+
+OCAMLFIND_COMMANDS='ocamlc=ocamlc-3.00 ocamlopt=ocamlopt-3.00'
+export OCAMLFIND_COMMANDSAlternatively, you can change the configuration file
+findlib.conf.
+ THE SUBCOMMAND "ocamlmklib"Synopsisocamlfind ocamlmklib
+ [ -package package-name-list |
+ -predicates pred-name-list |
+ -dllpath-pkg package-name-list |
+ -dllpath-all |
+ -passopt arg |
+ -passrest arg... |
+ standard-option ]
+ file ...DescriptionThis is a wrapper around ocamlmklib, and creates library archives and
+DLLs. In addition to the standard options, one can use -package to
+add the search path of packages. Note that no predicates are set by default -
+the wrapper does not know whether this is about byte or native code linking.This wrapper is mostly provided for completeness.
+ THE "ocamldep" SUBCOMMANDSynopsisocamlfind ocamldep [-package package-name-list |
+ -syntax pred-name-list |
+ -ppopt camlp4-arg |
+ -passopt arg |
+ -passrest arg... |
+ -verbose |
+ standard-option] file ...DescriptionThis command is a driver for the tool ocamldep of the
+OCaml distribution. This driver is only useful in conjunction with
+the preprocessor camlp4; otherwise it does not provide more functions
+than ocamldep itself.OptionsHere, only the additional options not interpreted by ocamldep
+but
+by the driver itself, and options with additional effects are explained.-package package-name-listThe packages named here are only used to look up the
+preprocessor options. The package camlp4 should be
+specified anyway, but further packages that add capabilities to the
+preprocessor can also be passed.-syntax pred-name-listThe predicates that are in effect during the look-up
+of the preprocessor options. At least, either camlp4o
+(selecting the normal syntax), or camlp4r (selecting
+the revised syntax) should be specified.-ppopt camlp4-argAn option that is passed through to the camlp4 call.-passopt argAn option that is passed through to the ocamldep call.-passrest arg...All further arguments are passed down to ocamldep
+ unprocessed-verboseDisplays the resulting ocamldep command (for debugging)ExampleA typical way of using this driver:
+
+ocamlfind ocamldep -package camlp4,xstrp4 -syntax camlp4r file1.ml file2.ml
+
+This command outputs the dependencies of file1.ml and
+file2.ml, although these modules make use of the
+syntax extensions provided by xstrp4 and are written
+in revised syntax.
+ THE "ocamlbrowser" SUBCOMMANDSynopsisocamlfind ocamlbrowser [-package package-name-list |
+ -all |
+ -passopt arg
+ -passrest ]DescriptionThis driver calls the ocamlbrowser with package options.
+With -package, the specified packages are included into
+the search path of the browser, and the modules of these packages become
+visible (in addition to the standard library). The option -all causes that all packages are selected that are managed by findlib.As for other drivers, the options -passopt and
+-passrest can be used
+to pass arguments directly to the ocamlbrowser program.
+ THE SUBCOMMAND "ocamldoc"Synopsisocamlfind ocamldoc
+ [ -package package-name-list |
+ -predicates pred-name-list |
+ -syntax pred-name-list |
+ -ppopt camlp4-arg |
+ standard-option ]
+ file ...DescriptionThis subcommand is a driver for ocamldoc. It undestands all options
+ocamldoc supports plus the mentioned findlib options. Basically,
+the -package options are translated into -I options, and the selected
+syntax options are translated into camlp4 options.OptionsHere, only the additional options not interpreted by ocamldep
+but
+by the driver itself, and options with additional effects are explained.-package package-name-listAdds the listed package names to the set of included
+ packages. The package names may be separated by commas and/or
+ whitespace. In the transformed command, for every package of the set
+ of included packages and for any ancestor a directory search option
+ is inserted after the already given options. This means that
+ "-I" options are added for every package directory.
+ -predicates pred-name-listAdds the given predicates to the set of actual
+ predicates. The predicates must be separated by commas and/or
+ whitespace. -syntax pred-name-listThe predicates that are in effect during the look-up
+of the preprocessor options. At least, either camlp4o
+(selecting the normal syntax), or camlp4r (selecting
+the revised syntax) should be specified.-ppopt camlp4-argAn option that is passed through to the camlp4 call.
+ THE "install" SUBCOMMANDSynopsisocamlfind install [ -destdir directory ]
+ [ -metadir directory ]
+ [ -ldconf path ]
+ [ -dont-add-directory-directive ]
+ [ -patch-version string ]
+ [ -patch-rmpkg name ]
+ [ -patch-archives ]
+ [ -dll ] [ -nodll ] [ -optional ] [ -add ]
+ package_namefile ...DescriptionThis subcommand installs a new package either at the default location
+(see the variable destdir of
+findlib.conf), or in the directory
+specified by the -destdir option. This
+means that a new package directory is created and that the files on
+the command line are copied to this directory. It is required that a
+META file is one of the files copied to the target
+directory.Note that package directories should be flat (no
+subdirectories). Existing packages are never overwritten.It is possible to have a separate directory for all the META files. If
+you want that, you have either to set the variable
+metadir of
+findlib.conf, or to specify the
+-metadir option. In this case, the file called META is copied to the
+specified directory and renamed to META.p (where p is the package
+name), while all the other files are copied to the package
+directory as usual. Furthermore, the META file is modified such that the
+directory variable contains the path of the package
+directory.
+The option -dont-add-directory-directive prevents the installer from
+adding a directory variable.If there are files ending in the suffixes .so or
+.dll, the package directory will be added to the
+DLL configuration file ld.conf, such that the dynamic
+loader can find the DLL. The location of this file can be overriden by
+the -ldconf option. To turn this feature off, use "-ldconf ignore";
+this causes that the ld.conf file is not modified.However, if there is a stublibs directory in site-lib, the DLLs are not
+installed in the package directory, but in this directory that is
+shared by all packages that are installed at the same location.
+In this case, the configuration file ld.conf is
+not modified, so you do not need to say "-ldconf ignore" if you
+prefer this style of installation.The options -dll and -nodll can be used to control exactly which files
+are considered as DLLs and which not. By default, the mentioned
+suffix rule is in effect: files ending in ".so" (Unix) or ".dll"
+(Windows) are DLLs. The switch -dll changes this, and all following
+files are considered as DLLs, regardless of their suffix. The switch
+-nodll expresses that the following files are not DLLs, even if they
+have a DLL-like suffix. For example, in the following call the files
+f1 and f2 are handled by the suffix rule; f3 and f4 are DLLs anyway;
+and f5 and f6 are not DLLs:
+
+ocamlfind install p f1 f2 -dll f3 f4 -nodll f5 f6The switch -optional declares that all following files are optional,
+i.e. the command will not fail if files do not exist.The -patch options may be used to change the contents of the META files
+while it is being installed. The option -patch-version changes the
+contents of the top-level "version" variable. The option -patch-rmpkg
+removes the given subpackage. The option -patch-archives is experimental,
+in particular it removes all non-existing files from "archive" variables,
+and even whole subpackages if the archives are missing.The effect of -add is to add further files to an already installed
+packages.
+ THE "remove" SUBCOMMANDSynopsisocamlfind remove [ -destdir directory ]
+ [ -metadir directory ]
+ [ -ldconf path ]
+ package_nameDescriptionThe package will removed if it is installed at the default location
+(see the variable destdir of
+findlib.conf). If the package
+resides at a different location, it will not be removed by default;
+however, you can pass an alternate directory for packages by the
+-destdir option. (This must be the same directory as specified at
+installation time.)Note that package directories should be flat (no subdirectories); this
+subcommand cannot remove deep package directories. If you have a separate directory for META files, you must either
+configure this directory by the metadir variable
+of findlib.conf, or by specifying
+the -metadir option.
+The command does not fail if the package and/or the META
+file cannot be located. You will get a warning only in this case.If the package directory is mentioned in the ld.conf
+configuration file for DLLs, it will be tried to remove this entry
+from the file. The location of this file can be overriden by
+the -ldconf option. To turn this feature off, use "-ldconf ignore";
+this causes that the ld.conf file is not modified.If there is a stublibs directory, it is checked whether the package
+owns any of the files in this directory, and the owned files will
+be deleted.
+ THE "list" SUBCOMMANDSynopsisocamlfind list [-describe]DescriptionThis command lists all packages in the search path. The option -describe
+outputs the package descriptions, too.
+ THE "printppx" SUBCOMMANDSynopsisocamlfind printppx
+ [ -predicates pred-name-list ]
+ [ -ppxopt package,arg ]
+ package ...DescriptionThis command prints the ppx preprocessor options as they would
+occur in an OCaml compiler invocation for the packages listed in
+the command. The output includes one "-ppx" option for each
+preprocessor. The possible options have the same meaning as for
+"ocamlfind ocamlc". The option "-predicates" adds assumed
+predicates and
+"-ppxopt package,arg"
+adds "arg" to the ppx invocation of
+package package.The output of "ocamlfind printppx" will contain quotes
+""" for ppx commands that contain
+space-separated arguments. In this case $(ocamlfind
+printppx ...) won't work as naively expected, because
+many shells (including bash and dash) perform field splitting on
+the result of command substitutions without honoring quotes.
+ THE "lint" SUBCOMMANDSynopsisocamlfind lint fileDescriptionChecks the META file, and reports possible problems.
+ THE "printconf" SUBCOMMANDSynopsisocamlfind printconf [ conf | path | destdir | metadir | metapath | stdlib | ldconf ]DescriptionThis command prints the effective configuration after reading the
+configuration file, and after applying the various environment
+variables overriding settings. When called without arguments, the command
+prints all configuration options in a human-readable form. When called
+with an argument, only the value of the requested option is printed without
+explaining texts:confPrints the location of the configuration file findlib.conf
+ pathPrints the search path for packages. The members of the
+ path are separated by linefeeds.destdirPrints the location where package are installed and
+ removed by default.metadirPrints the location where META files are installed and
+ removed (if the alternative layout is used).metapathPrints the path where the META file is installed for
+a fictive package. The name of the package is marked with '%s' in the
+path. For instance, this command could output "/some/path/%s/META" or
+"/some/path/META.%s", depending on the layout.stdlibPrints the location of the standard library.ldconfPrints the location of the ld.conf file
+ THE SUBCOMMAND CALLING PACKAGE PROGRAMSSynopsisocamlfind pkg/cmdargument ...DescriptionThis subcommand is useful to call programs that are installed in
+package directories. It looks up the directory for
+pkg and calls the command named
+cmd in this directory. The remaining arguments
+are passed to this command.argv(0) contains the absolute path to the command, and argv(1) and
+the following argv entries contain the arguments. The working directory
+is not changed.Example: To call the program "x" that is installed in package "p",
+with arguments "y" and "z", run:ocamlfind p/x y z CONFIGURATION FILE, ENVIRONMENT VARIABLES The configuration file and environment variables are documented
+in the manual page for
+ findlib.conf.
+ HOW TO SET THE TOOLCHAINSynopsisocamlfind -toolchain name ...DescriptionThe -toolchain option can be given before any other command,
+e.g.
+ocamlfind -toolchain foo ocamlc -c file.ml
+compiles file.ml with toolchain "foo". By selecting toolchains one
+can switch to different command sets. For instance, the toolchain
+"foo" may consist of a patched ocamlc compiler.
+See findlib.conf how to
+configure toolchains.META5The findlib package manager for OCamlMETA[File that specifies metainformation of OCaml packages]GRAMMAR metafile ::= entry*
+ entry ::= assignment | addition | subpackage
+ subpackage ::= "package" pkgname '(' metafile ')'
+ assignment ::= variable_name [ formal_predicates ] '=' value
+ addition ::= variable_name [ formal_predicates ] '+=' value
+formal_predicates ::= '(' formal_predicate { ',' formal_predicate } ')'
+ variable_name ::= name
+ formal_predicate ::= name | '-' name
+ name ::= [ 'A'-'Z' 'a'-'z' '0'-'9' '_' '.' ]+
+ pkgname ::= '"' (character but not '.')* '"'
+ value ::= '"' character* '"'DESCRIPTIONIf a package directory contains a file with the fixed name "META" it
+is interpreted as described here. The file is a sequence of entries
+following the given grammar; every entry defines a variable under a
+certain condition given by the list of formal predicates, or it
+introduces a subpackage.There is a list of predefined variables and a list of standard
+predicates. These variables define: required packages, description, version
+information, directories, archive files, and linker options. The
+predicates denote circumstances of the application of the variables:
+whether the bytecode or the native compiler is used, if there is a
+toploop compiled in, details of multi-threading execution, details of
+profiling. DETAILS OF THE FILE FORMATThe file consists of a sequence of entries which must be formed as the
+grammar prescribes. The lexical tokens are names, values, and
+interpunctuation like '(', ',' and so on. Note that linefeeds do not
+play a special role, i.e. an entry definition may be given in more than
+one line, or several definitions may occur on a single line. There may
+be comments which begin with '#' and run until the end of the line.Names are sequences of the characters A-Z, a-z, 0-9, or _. Names
+containing capital letters and names beginning with digits are
+allowed but not recommended.Values are enclosed between double quotes. Values may contain any
+character. The characters " and \ must be preceded by backslashes. Package names must not contain the '.' character because it is used
+as delimiter of compound names.MAIN PACKAGES AND SUBPACKAGESThe outermost variable assignments and additions belong to the main
+package. The name of the main package is not defined within META;
+it is either the name of the directory containing META or the suffix
+of the META file (if the name of the META file is formed like
+META.name).The keyword package starts the definition
+of a subpackage. There must not be two such definitions with the
+same name. Within the parantheses, the variable assignments and
+additions refer to the subpackage. It is allowed that a subpackage
+contains further subpackages.The package name following package
+is the local name relative to the main package, i.e. the
+name of the main package is not mentioned. At all other places,
+however, the subpackage must be prefixed by the name of the
+containing package, separated by a '.'.Subpackages are independent of the containing package, except
+that the subpackage points to the same installation directory as
+the containing package (i.e. the location of the installation directory
+is inherited from the containing package).SEMANTICS OF VARIABLE DEFINITIONSIn order to determine the value of a variable, first all assignments
+are inspected, and the most specific assignment is taken (if there is
+none, the empty string will be taken as value). In a second step,
+all additions are gone through one after the other in the order
+they occur in the file, and the values of all matching additions are
+appended to the current value. In the following, it is further
+clarified which assignment is the most specific, which additions
+actually match, and how the details of the value addition look like. The most specific assignment is selected upon a set of actual
+predicates, i.e. the set of predicates that are assumed to be true.
+The predicates occuring in the definitions of assignments and
+additions are called formal predicates. They may be positive or
+negative; the latter are prepended by a '-' sign. In order to
+determine the value after the evaluation of the assignments, the
+following rules apply: An assignment can only be used if all positive formal
+predicates are included in the set of actual predicates, and if all
+negative formal predicates are not included in the set of actual
+predicates. Such an assignment is called
+applicable. If there is no such assignment, the
+variable will have no value. If there is more than one applicable assignment, the definition with
+the biggest number of formal predicates is selected.If there is still more than one applicable assignment, both applicable
+and with a maximum number of formal predicates, the definition that is defined
+first is selected.An addition is matching when all positive formal predicates are
+included in the set of actual predicates, and all negative formal
+predicates are not included.The value of an addition is appended to the current value with
+implicit white space as separator.VARIABLESThere is a set of variables with predefined meaning: The
+variable "directory" redefines the location of the package
+directory. Normally, the META file is the first file read in the
+package directory, and before any other file is read, the "directory"
+variable is evaluated in order to see if the package directory must be
+changed. The value of the "directory" variable is determined with an
+empty set of actual predicates. The value must be either: an absolute
+path name of the alternate directory, or a path name relative to the
+stdlib directory of OCaml (written "+path"), or a normal relative path
+name (without special syntax). In the latter case, the interpretation
+depends on whether it is contained in a main or sub package, and
+whether the standard repository layout or the alternate layout is in
+effect (see site-lib for these terms).
+For a main package in standard layout the base directory is the
+directory physically containing the META file, and the relative path
+is interpreted for this base directory. For a main package in
+alternate layout the base directory is the directory physically
+containing the META.pkg files. The base directory for subpackages is
+the package directory of the containing package. (In the case
+that a subpackage definition does not have a "directory" setting,
+the subpackage simply inherits the package directory of the containing
+package. By writing a "directory" directive one can change this
+location again.)
+The variable "requires" specifies the list of required packages. The
+names of the packages must be separated by white space and/or commas.
+The names must be fully qualified (i.e. when they refer to a subpackage,
+the names of all containing packages must be prepended, separated by
+'.').
+The variable "description" may include a short description of the
+package (displayed by ocamlfind list).
+The variable "version" specifies the version string.
+The variable "archive" specifies the list of archive files. These
+files should be given either as (1) plain names without any directory
+information; they are only searched in the package directory.
+(2) Or they have the form "+path" in which case the files are looked up
+relative to the standard library. (3) Or they have the form "@name/file"
+in which case the files are looked up in the package directory
+of another package. (4) Or they are given as absolute paths.The
+names of the files must be separated by white space and/or commas.
+In the preprocessor stage, the archive files are passed as extensions
+to the preprocessor (camlp4) call. In the linker stage (-linkpkg), the archive
+files are linked. In the compiler stage, the archive files are ignored.Note that "archive" should only be used for archive files that are
+intended to be included in executables or loaded into toploops. For
+modules loaded at runtime there is the separate variable "plugin".
+The variable "plugin" specifies the plugin archives of the package.
+These can be dynamically loaded with the Fl_dynload
+module. The plugin archives can have ".cmo", ".cma", or ".cmxs" suffix.
+The variable "linkopts" specifies additional linker options.The variable "error" can be used to signal error conditions. When
+this variable is applicable, the ocaml compilers are stopped, and
+an error message is printed. The message is the value of the variable.The variable "warning" can be used to signal warnings. When
+this variable is applicable, the warning is printed, but the
+compilation continues. The message is the value of the variable.
+The variable "exists_if" can be used to disable subpackages. The
+value of "exists_if" is a file; the subpackage is hidden if this
+file does not exist. You can also enumerate several files, and the
+subpackage is hidden if none of the files exist.The variable "ppx" is a command that is added to the compiler invocation
+via the -ppx option (available since OCaml-4.01). If the command is
+relative to the current directory (e.g. ./cmd), the command is expected
+in the package directory. The special forms as defined for "archive"
+are also available (e.g. @otherpkg/cmd). Additional arguments can be
+specified on the ocamlfind command line with the -ppxopt option
+or the "ppxopt" variable.The variable "ppxopt" is a set of options that are added to the ppx
+rewriter invocation. The contents of the variable consists of one or
+several whitespace-separated parts. Every part consists of several
+comma-separated subparts; the first subpart indicates the package
+that contains the ppx rewriter invocation, the rest contain the options
+to be appended. If the option is a path relative to the current directory
+(e.g. ./foo.cma), the path is expanded relative to the package directory.
+The special forms as defined for "archive" are also available
+(e.g. @otherpkg/foo.cma).It is possible to define additional variables but there is currently
+no software interpreting them.PREDICATESThere is a list of standard predicates:The "byte" predicate means that the bytecode compiler is used.The "native" predicate means that the native compiler is used.The "toploop" predicate means that the toploop is available in the
+linked program. It is only set when the toploop is running, not when
+the toploop is generated.The "create_toploop" predicate means that a toploop is created (using
+ocamlmktop).The "mt" predicate means that the program is multi-threaded.The "mt_posix" predicate means that in the case "mt" is set, too, the
+POSIX libraries are used to implement threads.The "mt_vm" predicate means that in the case "mt" is set, too, the
+VM-based libraries are used to implement threads.The "gprof" predicate means that in the case "native" is set, too, the
+program is compiled for profilingThe "autolink" predicate means that ocamlc can/will perform automatic linking.The "preprocessor" predicate means that the META variables are scanned for
+preprocessor options.The "syntax" predicate means that the -syntax option is present on the
+command line.Legacy: The "plugin" predicate could be used in some versions of findlib
+to select cmxs archives instead of cmxa archives. This use is still possible
+but discouraged.In addition to these predicates, there are package predicates
+for every package that is finally selected. Of course, this kind of
+predicate must not be used to select "directory" and "requires"
+variables, but for the other variables they are perfectly valid.
+The package predicates have the form "pkg_" plus the name of the
+package (fully qualified).findlib.conf5The findlib package manager for OCamlfindlib.conf[Configuration of findlib/ocamlfind]GENERALThere are three possibilities to configure the findlib library:
+
+Build time: Before findlib is compiled, a "configure" script is invoked to figure
+ out the settings that are most likely to work on the system. Most
+ settings are simply entered into text files and can easily be changed
+ after installation. The following properties cannot be changed later
+ because they are compiled into the resulting binaries:
+
+ The default location of the configuration file findlib.conf. However,
+ you can set a different location by the environment variable
+ OCAMLFIND_CONF.
+ Whether the installed OCaml version supports autolinking or not.
+
+ Configuration file findlib.conf: An initial version of this file is generated by the configure script,
+ but you are free to modify it later. Most important, this file
+ contains the system-wide search path used to look up packages, and the
+ default location where to install new packages.
+ All files with the suffix ".conf" found in the directory
+ findlib.conf.d are also scanned for parameters.
+ Environment variables: The settings of findlib.conf can be overridden by environment variables.
+
+
+Last but not least, several settings can also be passed as
+command-line options, or by invoking the function
+Findlib.init. findlib.confThe directory containing findlib.conf is determined at build time (by
+running the configure script), the fallback default is
+/usr/local/etc. You can set a different location by
+changing the environment variable OCAMLFIND_CONF
+which must contain the absolute path of findlib.conf.The file has the same syntax as META, i.e. it consists of a
+number of lines with the format
+
+variable = "value"Here is the list of allowed variables:
+
+path The search path for META files/package directories. The variable
+ enumerates directories which are separated by colons (Windows:
+ semicolons), and these directories are tried in turn to find a certain
+ package. More exactly, if d is such a directory and p the searched
+ package, the search algorithm will first check whether d/p/META
+ exists. In this case, this META file is taken, and d/p is the package
+ directory. Second, the algorithm tries d/META.p, but the package
+ directory must be specified in this META.p file by a
+ directory directive.
+ Note that the first found META file is taken, so the order of the
+ directories in the search path counts.
+ This variable is required.
+ Example:
+
+ path = "/usr/local/lib/ocaml/site-lib:/usr/lib/ocaml/site-lib"
+
+
+
+destdir This variable determines the location where ocamlfind
+ install puts the packages by default: If d is this
+ directory, and p the package to install, a new subdirectory d/p will
+ be created containing all the files of the package.
+ Example:
+ destdir = "/usr/local/lib/ocaml/site-lib"
+ This variable is required.
+
+
+
+metadir If set, the command ocamlfind install will put the
+ META files of packages into this directory (files are named META.p
+ where p=package name); otherwise the META files are put into the
+ package directories like any other file.
+ Example:
+ metadir = "/var/lib/findlib/metaregistry"
+ This variable is optional. It is not used by default.
+
+
+
+ocamlc,
+ ocamlopt,
+ ocamlcp,
+ ocamlmktop,
+ ocamldoc,
+ ocamldep,
+ ocamlbrowser
+ If you want to call other executables than "ocamlc", "ocamlopt",
+ "ocamlcp", "ocamlmktop", "ocamldoc", "ocamldep", and
+ "ocamlbrowser", you can
+ set the names of
+ the executables here. The command ocamlfind looks
+ into these four variables to determine the names of the compilers to
+ call.
+ Example:
+ ocamlc = "ocamlc.opt"
+ocamlopt = "ocamlopt.opt"
+ocamlcp = "ocamlcp.opt"
+ocamlmktop = "ocamlmktop.opt"
+ This variable is optional. It is not used by default.
+
+
+stdlib This variable determines the location of the standard library. This must
+ be the same directory for which the OCaml compilers are configured.
+ This variable is optional. It is not recommend to set this variable
+ unless you know what you are doing!
+
+
+ldconf This variable determines the location of the ld.conf file. This must
+ be the same file the OCaml compilers read in; it is updated by
+ ocamlfind when installing and removing packages. You can set this
+ variable to the special value "ignore" to disable
+ the automatic modification of the ld.conf file.
+ If not set, the ld.conf file is assumed to reside in the OCaml
+ standard library directory.
+ This variable is optional. It is not recommended to set this variable
+ unless you know what you are doing!
+ Toolchains: It is possible to have variants of the original configuration.
+These variants are called "toolchains" because they are intended to
+select different compilers, e.g. patched compilers. In order to
+set a variable for a certain toolchain, use the syntax
+
+variable(toolchain) = "value"
+
+For example:
+
+ocamlc(mypatch) = "ocamlc-mypatch"
+
+When the toolchain "mypatch" is selected, this compiler will be used instead
+of the standard one.In order to switch to a certain toolchain, use the -toolchain
+option of ocamlfind.EnvironmentA number of environment variables modifies the behaviour of
+findlib/ocamlfind:
+
+OCAMLFIND_CONF This variable overrides the location of the configuration file
+ findlib.conf. It must contain the absolute path name of this file.
+
+
+OCAMLFIND_TOOLCHAIN This variable sets the currently selected toolchain when
+ a -toolchain option is not passed
+ on the command line.
+
+
+OCAMLPATH This variable may contain an additional search path for package
+ directories. It is treated as if the directories were prepended to
+ the configuration variable path.
+
+
+OCAMLFIND_DESTDIR This variable overrides the configuration variable
+ destdir.
+
+
+OCAMLFIND_METADIR This variable overrides the configuration variable
+ metadir.
+
+
+OCAMLFIND_COMMANDS This variable overrides the configuration variables
+ ocamlc, ocamlopt,
+ ocamlcp, ocamlmktop,
+ ocamldoc, ocamldep, and/or
+ ocamlbrowser.
+ Its value must conform to the syntax
+
+ ocamlc=name ocamlopt=name ocamlcp=name ocamlmktop=name ocamldoc=name ocamldep=name ocamlbrowser=name
+ Example:
+ ocamlc=ocamlc-3.00 ocamlopt=ocamlopt-3.00 ocamlcp=ocamlcp-3.00 ocamlmktop=ocamlmktop-3.00
+
+
+CAMLLIB or OCAMLLIB This variable overrides the configuration variable
+ stdlib.
+
+
+OCAMLFIND_LDCONF This variable overrides the configuration variable
+ ldconf.
+
+
+OCAMLFIND_IGNORE_DUPS_IN This variable instructs findlib not to emit warnings that packages
+ or module occur several times. The variable must be set to the
+ directory where the packages reside that are to be ignored for this
+ warning.
+
+
+site-lib5The findlib package manager for OCamlsite-lib[Location of package directories]STANDARD LAYOUT...somewhere in the filesystem hierarchy...
+ |
+ \
+ site-lib
+ |
+ +- (optional) stublibs
+ +- (optional) postinstall
+ +- (optional) postremove
+ |
+ +- package1
+ | |
+ | +- META
+ | +- archive files
+ | +- interface definitions
+ |
+ +- package2
+ +
+ :
+ :
+ \
+ packageNDESCRIPTIONEvery installation of "findlib" has a default location for package
+directories, which is normally a directory called "site-lib". The
+location can be set by the configuration variables
+path (used to look up packages), and
+destdir (used to install new packages);
+see findlib.conf.The name of a package is the name of the package directory. For
+example, if destdir=/usr/local/lib/ocaml/site-lib, the
+package p will be installed in the subdirectory
+/usr/local/lib/ocaml/site-lib/p. This subdirectory
+must contain the META file and all other files belonging to the package.
+Package names must not contain the '.' character.The variable destdir specifies the directory for
+new packages. You can only have one such directory at a time; but of
+course you can change this directory in findlib.conf. The command
+ocamlfind install puts new packages into this
+directory; it is recommended to use this command for installation
+because it ensures that the directory layout is right.For searching packages, findlib uses (only) the variable
+path which may name several locations to look at.For systems with DLL support another directory may exist: stublibs.
+If present, findlib will install DLLs into this directory that is
+shared by all packages at the same site-lib location. Findlib remembers
+which DLL belongs to which package by special files with the suffix
+".owner"; e.g. for the DLL "dllpcre.so" there is another file
+"dllpcre.so.owner" containing the string "pcre", so findlib knows
+that the package "pcre" owns this DLL. It is not possible that a DLL
+is owned by several packages.If the stublibs directory does not exist, DLLs are installed regularly
+in the package directories like any other file.For special needs, a postinstall and/or a postremove script may be
+installed in the site-lib directory. These scripts are invoked after
+installation or removal of a package, respectively.ALTERNATE LAYOUT
+...somewhere in the filesystem hierarchy...
+ |
+ \
+ site-lib
+ |
+ +- (optional) stublibs
+ +- (optional) postinstall
+ +- (optional) postremove
+ |
+ +- package1
+ | |
+ | +- archive files
+ | +- interface definitions
+ |
+ +- package2
+ +
+ :
+ :
+ \
+ : packageN
+ |
+ \
+ metaregistry
+ |
+ +- META.package1
+ +- META.package2
+ +
+ :
+ \
+ META.packageNThis is an alternate directory layout collecting all META files in one
+directory. You can configure this layout by setting
+path to the absolute location of
+metaregistry. Findlib recognizes that there are
+META files in this directory and uses them; it is not necessary to
+include site-lib into the path.In order to work, the META files must contain a
+directory directive pointing to the corresponding
+package directory that resides below site-lib.The command ocamlfind install copes with this
+layout, too. The variable destdir must contain the
+absolute location of site-lib, and the variable
+metadir must contain the absolute location of
+metaregistry. Note that ocamlfind
+install automatically adds a directory
+directive to the META file, so you need not do it manually.
diff --git a/local-packages/ocamlfind/doc/src/findlib_sitelib.mod b/local-packages/ocamlfind/doc/src/findlib_sitelib.mod
new file mode 100644
index 0000000..c1fdd87
--- /dev/null
+++ b/local-packages/ocamlfind/doc/src/findlib_sitelib.mod
@@ -0,0 +1,165 @@
+
+
+
+ site-lib
+ 5
+ The findlib package manager for OCaml
+
+
+
+ site-lib
+ [Location of package directories]
+
+
+
+
+STANDARD LAYOUT
+
+...somewhere in the filesystem hierarchy...
+ |
+ \
+ site-lib
+ |
+ +- (optional) stublibs
+ +- (optional) postinstall
+ +- (optional) postremove
+ |
+ +- package1
+ | |
+ | +- META
+ | +- archive files
+ | +- interface definitions
+ |
+ +- package2
+ +
+ :
+ :
+ \
+ packageN
+
+
+
+
+DESCRIPTION
+
+Every installation of "findlib" has a default location for package
+directories, which is normally a directory called "site-lib". The
+location can be set by the configuration variables
+path (used to look up packages), and
+destdir (used to install new packages);
+see findlib.conf.
+
+
+
+The name of a package is the name of the package directory. For
+example, if destdir=/usr/local/lib/ocaml/site-lib, the
+package p will be installed in the subdirectory
+/usr/local/lib/ocaml/site-lib/p. This subdirectory
+must contain the META file and all other files belonging to the package.
+Package names must not contain the '.' character.
+
+
+
+The variable destdir specifies the directory for
+new packages. You can only have one such directory at a time; but of
+course you can change this directory in findlib.conf. The command
+ocamlfind install puts new packages into this
+directory; it is recommended to use this command for installation
+because it ensures that the directory layout is right.
+
+
+
+For searching packages, findlib uses (only) the variable
+path which may name several locations to look at.
+
+
+
+For systems with DLL support another directory may exist: stublibs.
+If present, findlib will install DLLs into this directory that is
+shared by all packages at the same site-lib location. Findlib remembers
+which DLL belongs to which package by special files with the suffix
+".owner"; e.g. for the DLL "dllpcre.so" there is another file
+"dllpcre.so.owner" containing the string "pcre", so findlib knows
+that the package "pcre" owns this DLL. It is not possible that a DLL
+is owned by several packages.
+
+
+
+If the stublibs directory does not exist, DLLs are installed regularly
+in the package directories like any other file.
+
+
+
+For special needs, a postinstall and/or a postremove script may be
+installed in the site-lib directory. These scripts are invoked after
+installation or removal of a package, respectively.
+
+
+
+
+
+
+ALTERNATE LAYOUT
+
+
+
+...somewhere in the filesystem hierarchy...
+ |
+ \
+ site-lib
+ |
+ +- (optional) stublibs
+ +- (optional) postinstall
+ +- (optional) postremove
+ |
+ +- package1
+ | |
+ | +- archive files
+ | +- interface definitions
+ |
+ +- package2
+ +
+ :
+ :
+ \
+ : packageN
+ |
+ \
+ metaregistry
+ |
+ +- META.package1
+ +- META.package2
+ +
+ :
+ \
+ META.packageN
+
+
+
+
+This is an alternate directory layout collecting all META files in one
+directory. You can configure this layout by setting
+path to the absolute location of
+metaregistry. Findlib recognizes that there are
+META files in this directory and uses them; it is not necessary to
+include site-lib into the path.
+
+
+
+In order to work, the META files must contain a
+directory directive pointing to the corresponding
+package directory that resides below site-lib.
+
+
+
+The command ocamlfind install copes with this
+layout, too. The variable destdir must contain the
+absolute location of site-lib, and the variable
+metadir must contain the absolute location of
+metaregistry. Note that ocamlfind
+install automatically adds a directory
+directive to the META file, so you need not do it manually.
+
+
+
+
diff --git a/local-packages/ocamlfind/doc/src/findlib_topfind.mod b/local-packages/ocamlfind/doc/src/findlib_topfind.mod
new file mode 100644
index 0000000..e35840a
--- /dev/null
+++ b/local-packages/ocamlfind/doc/src/findlib_topfind.mod
@@ -0,0 +1,333 @@
+
+
+
+ Topfind
+ 3
+ The findlib package manager for OCaml
+
+
+
+ Topfind
+ [Module to load packages into toploops]
+
+
+
+
+SIGNATURE
+
+module Topfind :
+ sig
+
+
+
+
+
+
+
+
+
+
+ end
+
+
+
+
+
+DIRECTIVES
+
+
+
+
+
+
+
+
+
+
+PACKAGING
+
+
+The Topfind module is part of the "findlib" package. The module
+depends on the presence of a toploop. When building a toploop, it is
+automatically linked in if "findlib" is linked in, e.g.
+
+
+
+ocamlfind ocamlmktop options -package findlib -linkpkg options
+
+
+
+When the platform supports DLLs, another possibility to get a toploop
+with findlib directives is to load the file "topfind" (normally installed
+in the standard library directory):
+
+
+
+~ > ocaml
+ Objective Caml version 3.04
+
+# #use "topfind";;
+Findlib has been successfully loaded. Additional directives:
+ #require "package";; to load a package
+ #list;; to list the available packages
+ #camlp4o;; to load camlp4 (standard syntax)
+ #camlp4r;; to load camlp4 (revised syntax)
+ Topfind.reset();; to force that packages will be reloaded
+
+- : unit = ()
+# _
+
+
+
+This works even in scripts (but the startup message is suppressed in this
+case).
+
+
+
+The module is not thread-safe; if used in a multi-threaded script, all
+packgage loading must have happened before the first thread forks.
+
+
+
+
+
+DESCRIPTION
+
+
+The Topfind module contains some functions simplifying package loading
+in scripts. Most important, there is a new directive "#require" for
+the same purpose.
+
+
+
+The Topfind module needs some initialization, in particular the predicates variable needs to be
+set, and the packages already compiled into the toploop needs to be
+declared by the don't_load
+function. If the toploop has been built by , the necessary initialization is
+automatically compiled in.
+
+
+
+
+
+The variable Topfind.predicates
+
+
+val predicates : string list ref
+
+
+The variable contains the set of predicates that is assumed when
+packages are loaded.
+
+
+
+
+
+
+Topfind.add_predicates predlist
+
+
+val add_predicates : string list -> unit
+
+
+This function adds the passed predicates predlist
+to the variable
+predicates.
+
+
+
+
+
+
+Topfind.syntax variant
+
+
+val syntax : string -> unit
+
+
+This function emulates the -syntax command line
+switch of ocamlfind.
+
+
+
+
+
+
+Topfind.standard_syntax ()
+
+
+val standard_syntax : unit -> unit
+
+
+The same as syntax "camlp4o".
+
+
+
+
+
+
+Topfind.revised_syntax ()
+
+
+val revised_syntax : unit -> unit
+
+
+The same as syntax "camlp4r".
+
+
+
+
+
+
+Topfind.don't_load pkglist
+
+
+val don't_load : string list -> unit
+
+
+Declares the packages enumerated in pkglist
+as being linked into the toploop.
+
+
+
+
+
+
+Topfind.don't_load_deeply pkglist
+
+
+val don't_load_deeply : string list -> unit
+
+
+Declares the packages enumerated in pkglist
+and all direct and indirect ancestors as being linked into the toploop.
+
+
+
+
+
+
+Topfind.load pkglist
+
+
+val load : string list -> unit
+
+
+The packages enumerated in pkglist are
+loaded in turn; packages that have already been loaded or that have
+been declared as linked in are skipped.
+
+
+
+
+
+
+Topfind.load_deeply pkglist
+
+
+val load_deeply : string list -> unit
+
+
+The packages enumerated in pkglist and all
+direct or indirect ancestors are loaded in topological order;
+packages that have already been loaded or that have
+been declared as linked in are skipped.
+
+
+
+
+
+
+Topfind.reset ()
+
+
+val reset : unit -> unit
+
+
+This function causes that Topfind forgets that any package has already
+been loaded. Infomation about packages linked into the toploop remain
+intact. The effect of this function is that all dynamically loaded
+packages will be loaded again when load, load_deeply functions, or the
+#require directive are executed.
+
+
+
+
+
+
+
+#require "package-name-list";;
+
+
+#require "package-name-list";;
+
+
+The argument of the directive is a list of package names, separated by
+commas and/or whitespace. The directive has the same effect as load_deeply, i.e. the listed
+packages and all
+direct or indirect ancestors are loaded in topological order;
+packages that have already been loaded or that have
+been declared as linked in are skipped.
+
+
+
+
+
+
+#camlp4o ;;
+
+
+#camlp4o ;;
+
+
+Selects the standard syntax and loads the camlp4 preprocessor.
+
+
+
+
+
+
+#camlp4r ;;
+
+
+#camlp4r ;;
+
+
+Selects the revised syntax and loads the camlp4 preprocessor.
+
+
+
+
+
+#list ;;
+
+
+#list ;;
+
+
+Lists the packages that are in the search path.
+
+
+
+
+
+
diff --git a/local-packages/ocamlfind/findlib.conf.in b/local-packages/ocamlfind/findlib.conf.in
new file mode 100644
index 0000000..261d2c8
--- /dev/null
+++ b/local-packages/ocamlfind/findlib.conf.in
@@ -0,0 +1,2 @@
+destdir="@SITELIB@"
+path="@SITELIB@"
diff --git a/local-packages/ocamlfind/itest b/local-packages/ocamlfind/itest
new file mode 100755
index 0000000..6aa0137
--- /dev/null
+++ b/local-packages/ocamlfind/itest
@@ -0,0 +1,101 @@
+#! /bin/sh
+# $Id$
+# ----------------------------------------------------------------------
+#
+
+case `uname` in
+ CYGWIN*)
+ execsuffix=.exe ;;
+ *)
+ execsuffix= ;;
+esac
+ocamlfind="src/findlib/ocamlfind${execsuffix}"
+
+PATH="./tools:$PATH"
+export PATH
+
+check_linkage () {
+ p=$1
+ shift
+ rm -f itest-aux/simple
+ $ocamlfind ocamlc -linkall -linkpkg -custom "$@" -o itest-aux/simple itest-aux/simple_$p.ml >itest-aux/err.out 2>&1
+ output=`cat itest-aux/err.out | sed -e '/WARNING.*/ d'`
+ error=0
+ if [ -n "$output" ]; then
+ echo "* When trying to compile with"
+ echo " $ocamlfind ocamlc -linkall -linkpkg -custom "$@" -o itest-aux/simple itest-aux/simple_$p.ml"
+ echo " an error has occurred. The error error message has been written"
+ echo " to itest-aux/err.out."
+ error=1
+ fi
+ if [ "$error" = "0" ]; then
+ result=`itest-aux/simple${execsuffix}`
+ [ "x$result" = "xOK" ]
+ else
+ return $error
+ fi
+}
+
+problems () {
+ echo "* This test failed. Please check the settings in site-lib-src/$1/META,"
+ echo " especially the 'linkopts' variable, and try again. You can invoke"
+ echo " this test directly by: ./itest $1"
+}
+
+
+do_test () {
+ case "$1" in
+ dbm|graphics|num|str|unix|bigarray|labltk)
+ echo "* Checking linker options for $1 library"
+ rm -f itest-aux/testdb*
+ if check_linkage $1 -package $1; then
+ echo "ok"
+ else
+ problems $1
+ fi
+ ;;
+ threads)
+ echo "* Checking linker options for threads library"
+ if check_linkage $1 -package $1 -thread; then
+ echo "ok"
+ else
+ problems $1
+ fi
+ ;;
+
+ camlp4)
+ echo "* Checking options for camlp4 preprocessor"
+ if check_linkage $1 -package $1 -syntax camlp4r; then
+ echo "ok"
+ else
+ problems $1
+ fi
+ ;;
+
+ *)
+ echo "unknown test: $1"
+ ;;
+ esac
+}
+
+
+OCAMLPATH="./site-lib-src"
+export OCAMLPATH
+
+if [ ! -f "$ocamlfind" ]; then
+ echo "Sorry, you must first compile the library before you can invoke" 1>&2
+ echo "the integration test." 1>&2
+ exit 1
+fi
+
+if [ "$#" = "0" ]; then
+ for t in unix str dbm graphics num threads bigarray labltk camlp4; do
+ if [ -f "site-lib-src/$t/META" ]; then
+ echo "------------------------------------------------------------------------------"
+ do_test $t
+ echo
+ fi
+ done
+else
+ do_test $1
+fi
diff --git a/local-packages/ocamlfind/itest-aux/Makefile b/local-packages/ocamlfind/itest-aux/Makefile
new file mode 100644
index 0000000..5b17cf7
--- /dev/null
+++ b/local-packages/ocamlfind/itest-aux/Makefile
@@ -0,0 +1,7 @@
+all:
+
+clean:
+ rm -f simple simple.exe *.cmi *.cmo *.cma *.cmx *.o *.obj *.a *.lib
+ rm -f err.out
+ rm -f testdb*
+
diff --git a/local-packages/ocamlfind/itest-aux/os_type.ml b/local-packages/ocamlfind/itest-aux/os_type.ml
new file mode 100644
index 0000000..ece0739
--- /dev/null
+++ b/local-packages/ocamlfind/itest-aux/os_type.ml
@@ -0,0 +1,2 @@
+print_endline Sys.os_type
+;;
diff --git a/local-packages/ocamlfind/itest-aux/ppx.ml b/local-packages/ocamlfind/itest-aux/ppx.ml
new file mode 100644
index 0000000..73ce200
--- /dev/null
+++ b/local-packages/ocamlfind/itest-aux/ppx.ml
@@ -0,0 +1 @@
+Toploop.preprocess_phrase;;
diff --git a/local-packages/ocamlfind/itest-aux/remdir.ml b/local-packages/ocamlfind/itest-aux/remdir.ml
new file mode 100644
index 0000000..2808172
--- /dev/null
+++ b/local-packages/ocamlfind/itest-aux/remdir.ml
@@ -0,0 +1,2 @@
+#remove_directory ".";;
+
diff --git a/local-packages/ocamlfind/itest-aux/simple.ml b/local-packages/ocamlfind/itest-aux/simple.ml
new file mode 100644
index 0000000..5002c72
--- /dev/null
+++ b/local-packages/ocamlfind/itest-aux/simple.ml
@@ -0,0 +1,2 @@
+print_string "OK\n";;
+
diff --git a/local-packages/ocamlfind/itest-aux/simple_bigarray.ml b/local-packages/ocamlfind/itest-aux/simple_bigarray.ml
new file mode 100644
index 0000000..76e7a55
--- /dev/null
+++ b/local-packages/ocamlfind/itest-aux/simple_bigarray.ml
@@ -0,0 +1,7 @@
+open Bigarray.Array1;;
+let a = create Bigarray.int Bigarray.c_layout 4 in
+a.{0} <- 5
+;;
+
+print_endline "OK";;
+
diff --git a/local-packages/ocamlfind/itest-aux/simple_camlp4.ml b/local-packages/ocamlfind/itest-aux/simple_camlp4.ml
new file mode 100644
index 0000000..27b2ac1
--- /dev/null
+++ b/local-packages/ocamlfind/itest-aux/simple_camlp4.ml
@@ -0,0 +1,5 @@
+(* This is revised syntax: *)
+
+value x = 1;
+
+print_endline "OK";
diff --git a/local-packages/ocamlfind/itest-aux/simple_camltk.ml b/local-packages/ocamlfind/itest-aux/simple_camltk.ml
new file mode 100644
index 0000000..cd7dbdb
--- /dev/null
+++ b/local-packages/ocamlfind/itest-aux/simple_camltk.ml
@@ -0,0 +1,11 @@
+open Tk;;
+
+let top = openTk() in
+Frx_after.idle
+ closeTk;
+mainLoop()
+;;
+
+print_string "OK\n"
+;;
+
diff --git a/local-packages/ocamlfind/itest-aux/simple_dbm.ml b/local-packages/ocamlfind/itest-aux/simple_dbm.ml
new file mode 100644
index 0000000..13a6be3
--- /dev/null
+++ b/local-packages/ocamlfind/itest-aux/simple_dbm.ml
@@ -0,0 +1,10 @@
+(try
+ Sys.remove "itest-aux/testdb.db"
+with
+ _ -> ());
+
+let _ =
+ Dbm.opendbm "itest-aux/testdb" [ Dbm.Dbm_rdwr; Dbm.Dbm_create ] 0o777 in
+
+print_string "OK\n";;
+
diff --git a/local-packages/ocamlfind/itest-aux/simple_graphics.ml b/local-packages/ocamlfind/itest-aux/simple_graphics.ml
new file mode 100644
index 0000000..0e47fe8
--- /dev/null
+++ b/local-packages/ocamlfind/itest-aux/simple_graphics.ml
@@ -0,0 +1,4 @@
+Graphics.open_graph "";
+
+print_string "OK\n";;
+
diff --git a/local-packages/ocamlfind/itest-aux/simple_labltk.ml b/local-packages/ocamlfind/itest-aux/simple_labltk.ml
new file mode 100644
index 0000000..e3ffc00
--- /dev/null
+++ b/local-packages/ocamlfind/itest-aux/simple_labltk.ml
@@ -0,0 +1,10 @@
+open Tk;;
+
+let _ = openTk() in
+update();
+closeTk()
+;;
+
+print_string "OK\n"
+;;
+
diff --git a/local-packages/ocamlfind/itest-aux/simple_num.ml b/local-packages/ocamlfind/itest-aux/simple_num.ml
new file mode 100644
index 0000000..36f09d8
--- /dev/null
+++ b/local-packages/ocamlfind/itest-aux/simple_num.ml
@@ -0,0 +1,4 @@
+let _ = Num.num_of_int 5 in
+
+print_string "OK\n";;
+
diff --git a/local-packages/ocamlfind/itest-aux/simple_str.ml b/local-packages/ocamlfind/itest-aux/simple_str.ml
new file mode 100644
index 0000000..63cdff7
--- /dev/null
+++ b/local-packages/ocamlfind/itest-aux/simple_str.ml
@@ -0,0 +1,4 @@
+let _ = Str.regexp ".*" in
+
+print_string "OK\n";;
+
diff --git a/local-packages/ocamlfind/itest-aux/simple_threads.ml b/local-packages/ocamlfind/itest-aux/simple_threads.ml
new file mode 100644
index 0000000..73a1933
--- /dev/null
+++ b/local-packages/ocamlfind/itest-aux/simple_threads.ml
@@ -0,0 +1,17 @@
+let tl =
+ List.map
+ (fun _ ->
+ Thread.create
+ (fun () ->
+ for i = 1 to 1000 do
+ let _ = 1+1 in ()
+ done)
+ ())
+ [ (); (); (); (); () ]
+ in
+
+ List.iter Thread.join tl
+;;
+
+print_string "OK\n";;
+
diff --git a/local-packages/ocamlfind/itest-aux/simple_unix.ml b/local-packages/ocamlfind/itest-aux/simple_unix.ml
new file mode 100644
index 0000000..bdb373d
--- /dev/null
+++ b/local-packages/ocamlfind/itest-aux/simple_unix.ml
@@ -0,0 +1,4 @@
+let _ = Unix.getpid() in
+
+print_string "OK\n";;
+
diff --git a/local-packages/ocamlfind/mini/README b/local-packages/ocamlfind/mini/README
new file mode 100644
index 0000000..f2688b5
--- /dev/null
+++ b/local-packages/ocamlfind/mini/README
@@ -0,0 +1,104 @@
+----------------------------------------------------------------------
+ocamlfind-mini
+----------------------------------------------------------------------
+
+ocamlfind-mini is an OCaml script that implements a subset of the
+full functionality of ocamlfind. It consists only of one file, so it
+is easy to distribute it with any software.
+
+The subset is normally sufficient to compile a library and to
+install the library; but it is insufficient to link the library
+into an executable.
+
+----------------------------------------------------------------------
+SUPPORTED OPERATING SYSTEMS:
+----------------------------------------------------------------------
+
+For Unixes, the script runs out of the box. It uses the ocaml system
+found in the command path.
+
+I think the script also runs in Windows, but I have not yet checked that.
+Anyway, you cannot call it directly, but by doing
+ocaml ocamlfind-mini ...
+
+Macintosh is not supported; I don't have enough knowledge for a Mac port.
+
+----------------------------------------------------------------------
+FUNCTIONALITY:
+----------------------------------------------------------------------
+
+Overall: The configuration file ocamlfind.conf is ignored. However,
+some environment variables are respected (see below).
+
+A package directory is recognized by checking whether there is a META
+file in it. However, the contents of that file are ignored.
+
+The following subset has been implemented:
+
+- ocamlfind-mini [ocamlc|ocamlopt|ocamlcp|ocamlmktop] ...
+
+ The -package option works, but you must set the environment variable
+ OCAMLPATH (see below).
+
+ The options -linkpkg, -predicates, -dontlink, -syntax, -ppopt are
+ rejected.
+
+ This normally means that you can compile modules as in:
+
+ ocamlfind-mini ocamlc -c -package p1,p2,p3 my_module.ml
+
+ However, you cannot create executables because -linkpkg is not
+ supported.
+
+ Note that ocamlfind-mini is unable to figure out the prerequisite
+ packages, so the -package option must enumerate _all_ needed packages.
+
+ Note that ocamlfind-mini does not support the alternate directory
+ layout where all META files are collected in one directory.
+
+- ocamlfind-mini install ...
+
+ Installs the files in the package directory for . You must help
+ ocamlfind-mini by specifying the destination directory:
+
+ * Setting the -destdir option:
+
+ ocamlfind-mini install -destdir ...
+
+ This command installs the new package into /.
+
+ * Setting the OCAMLFIND_DESTDIR variable:
+
+ export OCAMLFIND_DESTDIR=
+ ocamlfind-mini install ...
+
+ This command installs the new package into /, too.
+
+- ocamlfind-mini remove
+
+ Removes the package . Again, you must specify the destination
+ directory by either setting the -destdir option or by setting the
+ OCAMLFIND_DESTDIR variable.
+
+----------------------------------------------------------------------
+ENVIRONMENT:
+----------------------------------------------------------------------
+
+The following variables are supported:
+
+- OCAMLPATH
+
+ A colon (Win: semicolon)-separated list of directories:
+ OCAMLPATH=::...
+
+ When ocamlfind-mini searches a package , it checks whether
+ //META exists for K=1, 2, ...
+
+- OCAMLFIND_DESTDIR
+
+ The destination directory for "install" and "remove".
+
+- OCAMLFIND_METADIR
+
+ The destination directory for META files. It is not recommended to set
+ this variable.
diff --git a/local-packages/ocamlfind/mini/ocamlfind-mini b/local-packages/ocamlfind/mini/ocamlfind-mini
new file mode 100755
index 0000000..288fa15
--- /dev/null
+++ b/local-packages/ocamlfind/mini/ocamlfind-mini
@@ -0,0 +1,851 @@
+#! /bin/sh
+# (*
+exec ocaml "$0" "$@"
+*) directory ".";;
+
+(* $Id$
+ * ----------------------------------------------------------------------
+ *
+ *)
+
+(**********************************************************************)
+
+(* Module split, rev. 1.2 *)
+
+module Split = struct
+let in_words s =
+ (* splits s in words separated by commas and/or whitespace *)
+ let l = String.length s in
+ let rec split i j =
+ if j < l then
+ match s.[j] with
+ (' '|'\t'|'\n'|'\r'|',') ->
+ if i
+ split i (j+1)
+ else
+ if i
+ if i
+ split i (j+1)
+ else
+ if i ':'
+ | "Cygwin" -> ';' (* You might want to change this *)
+ | "Win32" -> ';'
+ | "MacOS" -> failwith "Findlib: I do not know what is the correct path separator for MacOS. If you can help me, write a mail to gerd@gerd-stolpmann.de"
+ | _ -> failwith "Findlib: unknown operating system"
+;;
+
+
+let path str =
+ (* split "str" into parts separated by "path_separator" *)
+ let l = String.length str in
+ let rec split_up j k =
+ if k < l then begin
+ let c = str.[k] in
+ if c = path_separator then begin
+ if k - j > 0 then
+ String.sub str j (k-j) :: split_up (k+1) (k+1)
+ else
+ split_up (k+1) (k+1)
+ end
+ else
+ split_up j (k+1)
+ end
+ else
+ if k - j > 0 then
+ [ String.sub str j (k-j) ]
+ else
+ []
+ in
+ split_up 0 0
+;;
+end;;
+
+(**********************************************************************)
+
+
+
+exception Usage;;
+
+type mode =
+ M_use | M_query | M_install | M_remove | M_compiler of string
+ | M_printconf | M_guess | M_list
+;;
+
+
+let rec remove_dups l =
+ match l with
+ x :: l' ->
+ if List.mem x l' then remove_dups l' else x::remove_dups l'
+ | [] -> []
+;;
+
+
+let arg n =
+ if n < Array.length Sys.argv then Sys.argv.(n) else raise Not_found
+;;
+
+
+(**********************************************************************)
+
+let ocaml_stdlib_default = "/usr/local/lib/ocaml";;
+
+let ocaml_stdlib =
+ begin
+ (* Execute "ocamlc -v" and read the stdlib directory *)
+ let filename = Filename.temp_file "ocamlfind." ".dat" in
+ let command = "ocamlc -v >" ^ filename in (* SYS *)
+ let n = Sys.command command in
+ if n <> 0 then begin
+ prerr_endline ("ocamlfind-mini: [WARNING] Cannot determine directory of stdlib; using " ^ ocaml_stdlib_default ^ " by default");
+ ocaml_stdlib_default
+ end
+ else begin
+ (* Search the line "Standard library directory: " *)
+ let tag = "Standard library directory: " in
+ let taglen = String.length tag in
+ let f = open_in filename in
+ let dir = ref ocaml_stdlib_default in
+ try
+ while true do
+ let s = input_line f in
+ if String.length s >= taglen && String.sub s 0 taglen = tag then begin
+ dir := String.sub s taglen (String.length s - taglen);
+ raise Exit;
+ end
+ done;
+ assert false
+ with
+ Exit ->
+ close_in f;
+ (try Sys.remove filename with _ -> ());
+ !dir
+ | End_of_file ->
+ close_in f;
+ prerr_endline ("ocamlfind-mini: [WARNING] Cannot determine directory of stdlib; using " ^ ocaml_stdlib_default ^ " by default");
+ ocaml_stdlib_default
+ end
+ end
+;;
+
+
+let ocamlpath =
+ try
+ Split.path (Sys.getenv "OCAMLPATH")
+ with
+ Not_found ->
+ (* Use stdlib as default: *)
+ [ ocaml_stdlib ]
+;;
+
+
+let env_destdir =
+ try Sys.getenv "OCAMLFIND_DESTDIR" with Not_found -> "";;
+
+
+let env_metadir =
+ try Sys.getenv "OCAMLFIND_METADIR" with Not_found -> "";;
+
+
+let core_packages =
+ [ "bigarray", ocaml_stdlib;
+ "dbm", ocaml_stdlib;
+ "dynlink", ocaml_stdlib;
+ "graphics", ocaml_stdlib;
+ "labltk", (Filename.concat ocaml_stdlib "labltk");
+ "num", ocaml_stdlib;
+ "stdlib", ocaml_stdlib;
+ "str", ocaml_stdlib;
+ "threads", (Filename.concat ocaml_stdlib "threads");
+ "unix", ocaml_stdlib;
+ ]
+;;
+
+
+(**********************************************************************)
+
+let package_directory pkg =
+ let rec lookup path =
+ match path with
+ | [] -> raise Not_found
+ | dir :: path' ->
+ let pkgdir = Filename.concat dir pkg in
+ let meta = Filename.concat pkgdir "META" in
+ if Sys.file_exists meta then
+ pkgdir
+ else
+ lookup path'
+ in
+
+ try
+ List.assoc pkg core_packages
+ with
+ Not_found ->
+ lookup ocamlpath
+;;
+
+
+(**********************************************************************)
+
+let use_package prefix pkgnames =
+ let pdirs =
+ List.map
+ (fun pname ->
+ try
+ "-I " ^ package_directory pname
+ with
+ Not_found -> failwith ("Cannot find package " ^ pname ^ " (check environment variable OCAMLPATH)"))
+ pkgnames
+ in
+
+ print_endline (prefix ^ String.concat " " pdirs)
+;;
+
+
+(**************** OCAMLC/OCAMLMKTOP/OCAMLOPT subcommands ****************)
+
+type pass_file_t =
+ Pass of string
+ | Impl of string
+ | Intf of string
+;;
+
+
+let ocamlc which () =
+ Arg.current := 1;
+
+ let switches = ref [] in
+ let pass_options = ref [] in
+ let pass_files = ref [] in
+ let incpath = ref [] in
+
+ let packages = ref [] in
+
+ let add_switch name =
+ Arg.Unit (fun () ->
+ switches := name :: !switches;
+ pass_options := !pass_options @ [name]) in
+ let add_spec_fn name s =
+ pass_options := !pass_options @ [name; s] in
+ let add_spec name = Arg.String (add_spec_fn name) in
+ let add_pkg =
+ Arg.String (fun s -> packages := !packages @ (Split.in_words s)) in
+
+
+ Arg.parse
+ (List.flatten
+ [ [
+ "-package", add_pkg,
+ " Refer to package when compiling";
+ "-linkpkg", Arg.Unit(fun _ -> raise (Arg.Bad "Not supported: -linkpkg")),
+ " Link the packages in (NOT SUPPORTED)";
+ "-predicates", Arg.String(fun _ -> raise (Arg.Bad "Not supported: -predicates")),
+ "
Add predicate
when resolving package properties (NOT SUPPORTED)";
+ "-dontlink", Arg.String(fun _ -> raise (Arg.Bad "Not supported: -dontlink")),
+ " Do not link in package and its ancestors (NOT SUPPORTED)";
+ "-syntax", Arg.String(fun _ -> raise (Arg.Bad "Not supported: -syntax")),
+ "
Use preprocessor with predicate
(NOT SUPPORTED)";
+ "-ppopt", Arg.String(fun _ -> raise (Arg.Bad "Not supported: -ppopt")),
+ " Append option to preprocessor invocation (NOT SUPPORTED)";
+ "-passopt", Arg.String (fun s -> pass_options := !pass_options @ [s]),
+ " Pass option directly to ocamlc/opt/mktop\nSTANDARD OPTIONS:";
+
+ "-a", add_switch "-a",
+ " Build a library";
+ "-c", add_switch "-c",
+ " Compile only (do not link)";
+ "-cc", add_spec "-cc",
+ " Use as the C compiler and linker";
+ "-cclib", add_spec "-cclib",
+ " Pass option to the C linker";
+ "-ccopt", add_spec "-ccopt",
+ " Pass option to the C compiler and linker";
+ ];
+ if which = "ocamlopt" then [
+ "-compact", add_switch "-compact",
+ " Optimize code size rather than speed"
+ ]
+ else [];
+ if which <> "ocamlopt" then [
+ "-custom", add_switch "-custom",
+ " Link in custom mode";
+ "-g", add_switch "-g",
+ " Save debugging information";
+ ] else [];
+ [
+ "-i", add_switch "-i",
+ " Print the types";
+ "-I", (Arg.String
+ (fun s ->
+ incpath := s :: !incpath;
+ add_spec_fn "-I" s)),
+ " Add to the list of include directories";
+ "-impl", Arg.String (fun s -> pass_files := !pass_files @ [ Impl s ]),
+ " Compile as a .ml file";
+ ] ;
+ if which = "ocamlopt" then [
+ "-inline", add_spec "-inline",
+ " Set aggressiveness of inlining to ";
+ ] else [];
+ [
+ "-intf", Arg.String (fun s -> pass_files := !pass_files @ [ Intf s ]),
+ " Compile as a .mli file";
+ "-intf-suffix", add_spec "-intf-suffix",
+ " Suffix for interface file (default: .mli)";
+ "-intf_suffix", add_spec "-intf_suffix",
+ " same as -intf-suffix";
+ "-labels", add_switch "-labels",
+ " Use commuting label mode";
+ "-linkall", add_switch "-linkall",
+ " Link all modules, even unused ones";
+ ] ;
+ if which <> "ocamlopt" then [
+ "-make-runtime", add_switch "-make-runtime",
+ " Build a runtime system";
+ "-make_runtime", add_switch "-make_runtime",
+ " same as -make-runtime";
+ ] else [];
+ [
+ "-noautolink", add_switch "-noautolink",
+ " Don't automatically link C libraries specif'd in .cma files";
+ "-noassert", add_switch "-noassert",
+ " Do not compile assertion checks";
+ "-o", add_spec "-o",
+ " Set output file name to ";
+ "-output-obj", add_switch "-output-obj",
+ " Output a C object file instead of an executable";
+ ];
+ if which = "ocamlopt" then [
+ "-p", add_switch "-p",
+ " Compile/link with profiling support for \"gprof\"
+ (implies -predicates gprof)";
+ ] else if which = "ocamlcp" then [
+ "-p", add_spec "-p",
+ " [afilmt] Profile constructs specified by argument:
+ a Everything
+ f Function calls
+ i if ... then ... else
+ l while, for
+ m match ... with
+ t try ... with";
+ ] else [];
+ [
+ "-pp", Arg.String (fun s -> add_spec_fn "-pp" s),
+ " Pipe sources through preprocessor ";
+ "-rectypes", add_switch "-rectypes",
+ " Allow arbitrary recursive types";
+ ] ;
+ if which = "ocamlopt" then [
+ "-S", add_switch "-S",
+ " Keep intermediate assembly file";
+ ] else [];
+ [
+ "-thread", add_switch "-thread",
+ " Use thread-safe standard library (implies -predicate mt)";
+ "-unsafe", add_switch "-unsafe",
+ " No bounds checking on array and string access";
+ ] ;
+ if which <> "ocamlopt" then [
+ "-use-runtime", add_spec "-use-runtime",
+ " Generate bytecode for the given runtime system";
+ "-use_runtime", add_spec "-use_runtime",
+ " same as -use-runtime";
+ ] else [];
+ [
+ "-v", add_switch "-v",
+ " Print compiler version number";
+ "-verbose", add_switch "-verbose",
+ " Print calls to external commands";
+ "-w", add_spec "-w",
+ " Enable or disable warnings according to :
+ A/a enable/disable all warnings
+ C/c enable/disable suspicious comment
+ F/f enable/disable partially applied function
+ M/m enable/disable overriden methods
+ P/p enable/disable partial match
+ S/s enable/disable non-unit statement
+ U/u enable/disable unused match case
+ V/v enable/disable hidden instance variables
+ X/x enable/disable all other warnings
+ default setting is A (all warnings enabled)";
+ "-warn-error", add_spec "-warn-error",
+ " Turn these warnings into errors";
+ "-where", add_switch "-where",
+ " Print standard library directory";
+ "-", Arg.String (fun s -> pass_files := !pass_files @ [ Pass s ]),
+ " Treat as a file name (even if it starts with `-')";
+ ]
+ ])
+ (fun s -> pass_files := !pass_files @ [ Pass s])
+ ("usage: ocamlfind-mini " ^ which ^ " [options] file ...");
+
+ begin match which with
+ "ocamlc"
+ | "ocamlcp"
+ | "ocamlmktop"
+ | "ocamlopt" -> ()
+ | _ -> failwith "unsupported backend"
+ end;
+
+ let verbose = List.mem "-verbose" !switches in
+
+ (* check packages: *)
+ List.iter
+ (fun pkg ->
+ try
+ let _ = package_directory pkg in
+ ()
+ with
+ Not_found ->
+ failwith ("package '" ^ pkg ^ "' not found (check environment variable OCAMLPATH)"))
+ !packages;
+
+ let eff_packages = !packages in
+
+ let eff_packages_dl =
+ remove_dups (List.map package_directory eff_packages) in
+
+ let stdlibdir =
+ (* normalized form of the stdlib directory *)
+ let d = ocaml_stdlib in
+ if d <> "" & d.[String.length d - 1] = '/' then
+ String.sub d 0 (String.length d - 1)
+ else
+ d
+ in
+ let stdlibdirslash = stdlibdir ^ "/" in
+
+ let i_options =
+ List.flatten
+ (List.map
+ (fun pkgdir ->
+ if pkgdir = stdlibdir or pkgdir = stdlibdirslash then
+ []
+ else
+ [ "-I"; pkgdir;
+ "-ccopt"; "-I" ^ pkgdir; ])
+ eff_packages_dl) in
+
+ let pass_files' =
+ List.flatten
+ (List.map
+ (function
+ Pass s ->
+ if s.[0] = '-'
+ then [ "-"; String.sub s 1 (String.length s - 1) ]
+ else [ s ]
+ | Impl s ->
+ [ "-impl"; s ]
+ | Intf s ->
+ [ "-intf"; s ]
+ )
+ !pass_files)
+ in
+
+ let arguments =
+ !pass_options @
+ i_options @
+ pass_files'
+ in
+
+ let actual_command = which in
+
+ if verbose then
+ print_string ("+ " ^ actual_command ^ " " ^
+ String.concat " " arguments ^ "\n");
+
+ flush stdout;
+
+ let argstring =
+ String.concat " "
+ (List.map Filename.quote arguments)
+ in
+
+ let status = Sys.command (actual_command ^ " " ^ argstring) in
+
+ begin
+ match status with
+ 0 -> ()
+ | n ->
+ if verbose then
+ print_string (actual_command ^ " returned with exit code " ^ string_of_int n ^ "\n");
+ exit n
+ end;
+;;
+
+
+(************************************************************************)
+
+let make_directory dirname =
+ (* Invoke the mkdir command *)
+ let cmd =
+ match Sys.os_type with
+ "Unix" -> "mkdir"
+ | "Cygwin" -> "mkdir" (* don't really know *)
+ | "Win32" -> "md"
+ | "MacOS" -> failwith "make_directory not implemented for MacOS"
+ | _ -> failwith "Findlib: unknown operating system"
+ in
+ let c = Sys.command (cmd ^ " " ^ Filename.quote dirname) in
+ if c <> 0 then
+ failwith ("Cannot make directory " ^ dirname)
+;;
+
+
+let remove_directory dirname =
+ (* Invoke the rmdir command *)
+ let cmd =
+ match Sys.os_type with
+ "Unix" -> "rmdir"
+ | "Cygwin" -> "rmdir" (* don't really know *)
+ | "Win32" -> "rd"
+ | "MacOS" -> failwith "remove_directory not implemented for MacOS"
+ | _ -> failwith "Findlib: unknown operating system"
+ in
+ let c = Sys.command (cmd ^ " " ^ Filename.quote dirname) in
+ if c <> 0 then
+ failwith ("Cannot remove directory " ^ dirname)
+;;
+
+
+let list_dir dirname =
+ let rec rd_dir f =
+ try
+ let s = input_line f in
+ if s = "" then rd_dir f else s::rd_dir f
+ with
+ End_of_file ->
+ close_in f;
+ []
+ in
+
+ (* Invoke the ls command *)
+ let cmd =
+ match Sys.os_type with
+ "Unix" -> "ls -1"
+ | "Cygwin" -> "ls -1" (* don't really know *)
+ | "Win32" -> "dir /b"
+ | "MacOS" -> failwith "list_dir not implemented for MacOS"
+ | _ -> failwith "Findlib: unknown operating system"
+ in
+ let filename = Filename.temp_file "ocamlfind." ".dat" in
+ let fullcmd = cmd ^ " " ^ Filename.quote dirname ^ " >" ^ filename in
+ let n = Sys.command fullcmd in
+ if n <> 0 then
+ failwith ("Cannot execute: " ^ fullcmd);
+ let f = open_in filename in
+ let l = rd_dir f in
+ close_in f;
+ (try Sys.remove filename with _ -> ());
+ l
+;;
+
+
+let copy_file ?(rename = (fun name -> name)) ?(append = "") src dstdir =
+ (* A system-independent function to copy the file src to dstdir *)
+ let outname = rename (Filename.basename src) in
+ let ch_in = open_in_bin src in
+ try
+ let outpath = Filename.concat dstdir outname in
+ if Sys.file_exists outpath then
+ prerr_endline ("ocamlfind-mini: [WARNING] Overwriting file " ^ outpath);
+ let ch_out = open_out_bin outpath in
+ try
+ let buflen = 4096 in
+ let buf = Bytes.create buflen in
+ let pos = ref 0 in
+ let len = ref (input ch_in buf 0 buflen) in
+ while !len > 0 do
+ output ch_out buf !pos !len;
+ len := input ch_in buf !pos buflen;
+ done;
+ output_string ch_out append;
+ close_out ch_out;
+ close_in ch_in;
+ prerr_endline("Installed " ^ outpath);
+ with
+ exc -> close_out ch_out; raise exc
+ with
+ exc -> close_in ch_in; raise exc
+;;
+
+
+let install_create_directory pkgname dstdir =
+ if Sys.file_exists dstdir then
+ failwith ("Package " ^ pkgname ^ " is already installed; please remove it first");
+ make_directory dstdir
+;;
+
+
+exception Skip_file;;
+
+let install_package () =
+ let destdir = ref (env_destdir) in
+ let metadir = ref (env_metadir) in
+ let don't_add_directory_directive = ref false in
+ let pkgname = ref "" in
+ let files = ref [] in
+
+ let keywords =
+ [ "-destdir", (Arg.String (fun s -> destdir := s)),
+ " Set the destination directory";
+ "-metadir", (Arg.String (fun s -> metadir := s)),
+ " Install the META file into this directory";
+ "-dont-add-directory-directive", (Arg.Set don't_add_directory_directive),
+ " never append directory='...' to META";
+ ] in
+ let errmsg = "usage: ocamlfind-mini install [options] ..." in
+
+ Arg.current := 1;
+ Arg.parse
+ keywords
+ (fun s ->
+ if !pkgname = ""
+ then pkgname := s
+ else files := s :: !files
+ )
+ errmsg;
+ if !pkgname = "" then (Arg.usage keywords errmsg; exit 1);
+
+ (* Check destdir: *)
+ if !destdir = "" then
+ failwith ("No destination directory. Either specify the -destdir option, or set the environment variable OCAMLFIND_DESTDIR");
+ if not (Sys.file_exists !destdir) then
+ failwith ("The destination directory " ^ !destdir ^ " does not exist");
+
+ (* Check whether META exists: *)
+ let meta_dot_pkg = "META." ^ !pkgname in
+ let has_meta =
+ List.exists
+ (fun p ->
+ let b = Filename.basename p in
+ b = "META" || b = meta_dot_pkg)
+ !files
+ in
+ if not has_meta then
+ failwith "The META file is missing";
+
+ (* Check that there is no meta_dot_pkg: *)
+ if Sys.file_exists (Filename.concat !metadir meta_dot_pkg) then
+ failwith ("Package " ^ !pkgname ^ " is already installed; please remove it first");
+
+ (* Create the package directory: *)
+ let pkgdir = Filename.concat !destdir !pkgname in
+ install_create_directory !pkgname pkgdir;
+
+ (* Now copy the files into the package directory: *)
+ let has_metadir = !metadir <> "" in
+ List.iter
+ (fun p ->
+ try
+ copy_file
+ ~rename: (fun f ->
+ if has_metadir then begin
+ if f = "META" || f = meta_dot_pkg
+ then raise Skip_file
+ else f
+ end
+ else
+ if f = meta_dot_pkg then "META" else f)
+ p
+ pkgdir
+ with
+ Skip_file -> ()
+ )
+ !files;
+
+ (* Finally copy META into metadir, if this has been requested *)
+ if has_metadir then begin
+ List.iter
+ (fun p ->
+ let b = Filename.basename p in
+ if b = "META" || b = meta_dot_pkg then
+ copy_file
+ ~rename: (fun f ->
+ if f = "META" then meta_dot_pkg else f)
+ ~append: ("\ndirectory=\"" ^ pkgdir ^ "\" # auto-added by ocamlfind-mini\n")
+ p
+ !metadir
+ )
+ !files
+ end
+;;
+
+
+let remove_package () =
+ let destdir = ref (env_destdir) in
+ let metadir = ref (env_metadir) in
+ let pkgname = ref "" in
+
+ let keywords =
+ [ "-destdir", (Arg.String (fun s -> destdir := s)),
+ " Set the destination directory";
+ "-metadir", (Arg.String (fun s -> metadir := s)),
+ " Remove the META file from this directory";
+ ] in
+ let errmsg = "usage: ocamlfind-mini remove [options] " in
+
+ Arg.current := 1;
+ Arg.parse
+ keywords
+ (fun s ->
+ if !pkgname = ""
+ then pkgname := s
+ else raise (Arg.Bad "too many arguments")
+ )
+ errmsg;
+ if !pkgname = "" then (Arg.usage keywords errmsg; exit 1);
+
+ (* Check destdir: *)
+ if !destdir = "" then
+ failwith ("No destination directory. Either specify the -destdir option, or set the environment variable OCAMLFIND_DESTDIR");
+ if not (Sys.file_exists !destdir) then
+ failwith ("The destination directory " ^ !destdir ^ " does not exist");
+
+ let meta_dot_pkg = "META." ^ !pkgname in
+ let has_metadir = !metadir <> "" in
+
+ (* If there is a metadir, remove the META file from it: *)
+ if has_metadir then begin
+ let f = Filename.concat !metadir meta_dot_pkg in
+ if Sys.file_exists f then begin
+ Sys.remove f;
+ prerr_endline ("Removed " ^ f);
+ end
+ else
+ prerr_endline ("ocamlfind-mini: [WARNING] No such file: " ^ f)
+ end;
+
+ (* Remove the files from the package directory: *)
+ let pkgdir = Filename.concat !destdir !pkgname in
+
+ if Sys.file_exists pkgdir then begin
+ let files = list_dir pkgdir in
+ List.iter (fun f -> Sys.remove (Filename.concat pkgdir f)) files;
+ remove_directory pkgdir;
+ prerr_endline ("Removed " ^ pkgdir)
+ end
+ else
+ prerr_endline("ocamlfind-mini: [WARNING] No such directory: " ^ pkgdir);
+;;
+
+
+let select_mode() =
+ let m_string = try arg 1 with Not_found -> raise Usage in
+ let m =
+ match m_string with
+ ("use"|"-use") -> M_use
+ | ("query"|"-query") -> M_query
+ | ("install"|"-install") -> M_install
+ | ("remove"|"-remove") -> M_remove
+ | ("ocamlc"|"-ocamlc") -> M_compiler "ocamlc"
+ | ("ocamlcp"|"-ocamlcp") -> M_compiler "ocamlcp"
+ | ("ocamlmktop"|"-ocamlmktop") -> M_compiler "ocamlmktop"
+ | ("ocamlopt"|"-ocamlopt") -> M_compiler "ocamlopt"
+ | ("printconf"|"-printconf") -> M_printconf
+ | ("guess"|"-guess") -> M_guess
+ | ("list"|"-list") -> M_list
+ | _ -> raise Usage
+ in
+
+ m
+;;
+
+
+let sorry() =
+ prerr_endline "ocamlfind-mini: sorry, this function is not implemented in the reduced version of ocamlfind";
+ exit 1
+;;
+
+
+let main() =
+ try
+ let m = select_mode() in
+ let l = Array.length Sys.argv in
+ let rest = Array.sub Sys.argv 2 (l-2) in
+ match m with
+ M_use -> if rest = [| |] then raise Usage;
+ if rest.(0) = "-p" then begin
+ if l<4 then raise Usage;
+ use_package rest.(1)
+ (List.tl(List.tl(Array.to_list rest)))
+ end
+ else
+ use_package "" (Array.to_list rest)
+ | M_query -> sorry()
+ | M_install -> install_package()
+ | M_remove -> remove_package ()
+ | M_printconf -> sorry()
+ | M_guess -> sorry()
+ | M_list -> sorry()
+ | M_compiler which -> ocamlc which ()
+ with
+ Usage ->
+ prerr_endline "usage: ocamlfind-mini ocamlc [-help | other options] ...";
+ prerr_endline " or: ocamlfind-mini ocamlcp [-help | other options] ...";
+ prerr_endline " or: ocamlfind-mini ocamlmktop [-help | other options] ...";
+ prerr_endline " or: ocamlfind-mini ocamlopt [-help | other options] ...";
+ prerr_endline " or: ocamlfind-mini install [-help | other options] ...";
+ prerr_endline " or: ocamlfind-mini remove [-help | other options] ";
+ exit 2
+ | Failure f ->
+ prerr_endline ("ocamlfind-mini: " ^ f);
+ exit 2
+;;
+
+
+try
+ Sys.catch_break true;
+ main()
+with
+ any ->
+ prerr_endline ("Uncaught exception: " ^ Printexc.to_string any);
+ let raise_again =
+ try ignore(Sys.getenv "OCAMLFIND_DEBUG"); true
+ with Not_found -> false
+ in
+ if raise_again then raise any;
+ exit 3
+;;
+
+
+(* ======================================================================
+ * History:
+ *
+ * $Log: ocamlfind-mini,v $
+ * Revision 1.4 2001/03/10 08:15:24 gerd
+ * -warn-error
+ *
+ * Revision 1.3 2001/03/06 20:18:03 gerd
+ * Option -where.
+ *
+ * Revision 1.2 2001/03/04 19:03:56 gerd
+ * list_dir: deletes the temp file after use
+ *
+ * Revision 1.1 2001/03/04 19:01:21 gerd
+ * Initial revision.
+ *
+ *)
diff --git a/local-packages/ocamlfind/ocaml-stub b/local-packages/ocamlfind/ocaml-stub
new file mode 100755
index 0000000..e5ad990
--- /dev/null
+++ b/local-packages/ocamlfind/ocaml-stub
@@ -0,0 +1,4 @@
+#!/bin/sh
+
+BINDIR=$(dirname "$(command -v ocamlc)")
+"$BINDIR/ocaml" -I "$OCAML_TOPLEVEL_PATH" "$@"
diff --git a/local-packages/ocamlfind/ocamlfind.install b/local-packages/ocamlfind/ocamlfind.install
new file mode 100644
index 0000000..295c625
--- /dev/null
+++ b/local-packages/ocamlfind/ocamlfind.install
@@ -0,0 +1,6 @@
+bin: [
+ "src/findlib/ocamlfind" {"ocamlfind"}
+ "?src/findlib/ocamlfind_opt" {"ocamlfind"}
+ "?tools/safe_camlp4"
+]
+toplevel: ["src/findlib/topfind"]
diff --git a/local-packages/ocamlfind/ocargs.log b/local-packages/ocamlfind/ocargs.log
new file mode 100644
index 0000000..f2bb219
--- /dev/null
+++ b/local-packages/ocamlfind/ocargs.log
@@ -0,0 +1,4 @@
+ocamllex -o extract_args.ml extract_args.mll
+17 states, 566 transitions, table size 2366 bytes
+2076 additional bytes used for bindings
+ocamlc -o extract_args extract_args.ml
diff --git a/local-packages/ocamlfind/opam b/local-packages/ocamlfind/opam
new file mode 100644
index 0000000..a008a71
--- /dev/null
+++ b/local-packages/ocamlfind/opam
@@ -0,0 +1,39 @@
+opam-version: "2.0"
+name: "ocamlfind"
+version: "1.9.5.git"
+license: "MIT"
+synopsis: "A library manager for OCaml"
+maintainer: "Thomas Gazagnaire "
+authors: "Gerd Stolpmann "
+homepage: "http://projects.camlcity.org/projects/findlib.html"
+bug-reports: "https://github.com/ocaml/ocamlfind/issues"
+dev-repo: "git+https://github.com/ocaml/ocamlfind.git"
+description: """
+Findlib is a library manager for OCaml. It provides a convention how
+to store libraries, and a file format ("META") to describe the
+properties of libraries. There is also a tool (ocamlfind) for
+interpreting the META files, so that it is very easy to use libraries
+in programs and scripts.
+"""
+build: [
+ [
+ "./configure"
+ "-bindir" bin
+ "-sitelib" lib
+ "-mandir" man
+ "-config" "%{lib}%/findlib.conf"
+ "-no-custom"
+ "-no-camlp4" {!ocaml:preinstalled & ocaml:version >= "4.02.0"}
+ "-no-topfind" {ocaml:preinstalled}
+ ]
+ [make "all"]
+ [make "opt"] {ocaml:native}
+]
+install: [
+ [make "install"]
+ ["install" "-m" "0755" "ocaml-stub" "%{bin}%/ocaml"] {ocaml:preinstalled}
+]
+depends: [
+ "ocaml" {>= "4.00.0"} # ocamlfind uses String.map
+]
+depopts: ["graphics"]
diff --git a/local-packages/ocamlfind/site-lib-src/bigarray/META.in b/local-packages/ocamlfind/site-lib-src/bigarray/META.in
new file mode 100644
index 0000000..86dd27a
--- /dev/null
+++ b/local-packages/ocamlfind/site-lib-src/bigarray/META.in
@@ -0,0 +1,11 @@
+# Specifications for the "bigarray" library:
+requires = "unix"
+version = "[distributed with Ocaml]"
+description = "Large statically allocated arrays"
+directory = "^"
+browse_interfaces = "%%interfaces%%"
+archive(byte) = "bigarray.cma"
+archive(native) = "bigarray.cmxa"
+plugin(byte) = "bigarray.cma"
+plugin(native) = "bigarray.cmxs"
+linkopts = ""
diff --git a/local-packages/ocamlfind/site-lib-src/bigarray/interfaces.in b/local-packages/ocamlfind/site-lib-src/bigarray/interfaces.in
new file mode 100644
index 0000000..56a108e
--- /dev/null
+++ b/local-packages/ocamlfind/site-lib-src/bigarray/interfaces.in
@@ -0,0 +1 @@
+bigarray.cma
diff --git a/local-packages/ocamlfind/site-lib-src/bytes/META b/local-packages/ocamlfind/site-lib-src/bytes/META
new file mode 100644
index 0000000..690ae48
--- /dev/null
+++ b/local-packages/ocamlfind/site-lib-src/bytes/META
@@ -0,0 +1,4 @@
+name="bytes"
+version="[distributed with OCaml 4.02 or above]"
+description="dummy backward-compatibility package for mutable strings"
+requires=""
diff --git a/local-packages/ocamlfind/site-lib-src/bytes/META.in b/local-packages/ocamlfind/site-lib-src/bytes/META.in
new file mode 100644
index 0000000..690ae48
--- /dev/null
+++ b/local-packages/ocamlfind/site-lib-src/bytes/META.in
@@ -0,0 +1,4 @@
+name="bytes"
+version="[distributed with OCaml 4.02 or above]"
+description="dummy backward-compatibility package for mutable strings"
+requires=""
diff --git a/local-packages/ocamlfind/site-lib-src/bytes/interfaces.in b/local-packages/ocamlfind/site-lib-src/bytes/interfaces.in
new file mode 100644
index 0000000..b33f0c9
--- /dev/null
+++ b/local-packages/ocamlfind/site-lib-src/bytes/interfaces.in
@@ -0,0 +1,2 @@
+bytes.cmo
+
diff --git a/local-packages/ocamlfind/site-lib-src/camlp4.309/META.in b/local-packages/ocamlfind/site-lib-src/camlp4.309/META.in
new file mode 100644
index 0000000..92907f0
--- /dev/null
+++ b/local-packages/ocamlfind/site-lib-src/camlp4.309/META.in
@@ -0,0 +1,95 @@
+# Specifications for the "camlp4" preprocessor:
+requires = ""
+version = "[distributed with Ocaml]"
+description = "Base for Camlp4 syntax extensions"
+directory = "%%camlp4_dir%%"
+
+# For the toploop:
+archive(byte,toploop,camlp4o) = "camlp4o.cma"
+archive(byte,toploop,camlp4r) = "camlp4r.cma"
+
+# Scheme-like syntax:
+# Do #predicates "syntax,camlp4scheme", followed by #require "camlp4"
+archive(byte,toploop,camlp4scheme) = "camlp4sch.cma"
+
+# Standard ML-like syntax:
+# Do #predicates "syntax,camlp4sml", followed by #require "camlp4"
+archive(byte,toploop,camlp4sml) = "gramlib.cma camlp4_top.cma pa_sml.cmo"
+
+# Lisp-like syntax:
+# Do #predicates "syntax,camlp4lisp", followed by #require "camlp4"
+archive(byte,toploop,camlp4lisp) = "gramlib.cma camlp4_top.cma pa_lisp.cmo"
+
+# For the preprocessor itself:
+archive(syntax,preprocessor,camlp4o) = "pa_o.cmo pa_op.cmo pr_dump.cmo"
+archive(syntax,preprocessor,camlp4r) = "pa_r.cmo pa_rp.cmo pr_dump.cmo"
+archive(syntax,preprocessor,camlp4sml) = "pa_sml.cmo pr_dump.cmo"
+archive(syntax,preprocessor,camlp4scheme) = "pa_scheme.cmo pr_dump.cmo"
+archive(syntax,preprocessor,camlp4lisp) = "pa_lisp.cmo pr_dump.cmo"
+preprocessor = "%%camlp4_cmd%% -nolib"
+
+package "gramlib" (
+ requires(toploop) = "camlp4"
+ version = "[distributed with Ocaml]"
+ description = "Grammar library to create syntax extensions"
+ archive(byte) = "gramlib.cma"
+ archive(byte,toploop) = "" # already contained in camlp4*.cma
+ archive(native) = "gramlib.cmxa"
+)
+
+package "quotations" (
+ requires = "camlp4"
+ version = "[distributed with Ocaml]"
+ description = "Syntax extension: Quotations to create AST nodes"
+ archive(syntax,preprocessor) = "q_MLast.cmo"
+ archive(syntax,toploop) = "q_MLast.cmo"
+)
+
+package "phony_quotations" (
+ requires = "camlp4"
+ version = "[distributed with Ocaml]"
+ description = "Syntax extension: Phony quotations"
+ archive(syntax,preprocessor) = "q_phony.cmo"
+ archive(syntax,toploop) = "q_phony.cmo"
+)
+
+package "extend" (
+ requires = "camlp4"
+ version = "[distributed with Ocaml]"
+ description = "Syntax extension: EXTEND the camlp4 grammar"
+ archive(syntax,preprocessor) = "pa_extend.cmo"
+ archive(syntax,toploop) = "pa_extend.cmo"
+)
+
+package "extfun" (
+ requires = "camlp4"
+ version = "[distributed with Ocaml]"
+ description = "Syntax extension: Extensible functions"
+ archive(syntax,preprocessor) = "pa_extfun.cmo"
+ archive(syntax,toploop) = "pa_extfun.cmo"
+)
+
+package "fstream" (
+ requires = "camlp4"
+ version = "[distributed with Ocaml]"
+ description = "Syntax extension: Functional stream parsers"
+ archive(syntax,preprocessor) = "pa_fstream.cmo"
+ archive(syntax,toploop) = "pa_fstream.cmo"
+)
+
+package "macro" (
+ requires = "camlp4"
+ version = "[distributed with Ocaml]"
+ description = "Syntax extension: Conditional compilation"
+ archive(syntax,preprocessor) = "pa_macro.cmo"
+ archive(syntax,toploop) = "pa_macro.cmo"
+)
+
+package "unit_constraints" (
+ requires = "camlp4"
+ version = "[distributed with Ocaml]"
+ description = "Syntax extension: Type constraints of type unit (revised syntax only)"
+ archive(syntax,preprocessor,camlp4r) = "pa_ru.cmo"
+ archive(syntax,toploop,camlp4r) = "pa_ru.cmo"
+ error(syntax,-camlp4r) = "Not available"
+)
diff --git a/local-packages/ocamlfind/site-lib-src/camlp4.310/META.in b/local-packages/ocamlfind/site-lib-src/camlp4.310/META.in
new file mode 100644
index 0000000..2449a73
--- /dev/null
+++ b/local-packages/ocamlfind/site-lib-src/camlp4.310/META.in
@@ -0,0 +1,147 @@
+# Specifications for the "camlp4" preprocessor:
+requires = ""
+version = "[distributed with Ocaml]"
+description = "Base for Camlp4 syntax extensions"
+directory = "+camlp4"
+
+# For the toploop:
+requires(byte,toploop) = "%%camlp4_dynlink%%"
+archive(byte,toploop,camlp4o) = "camlp4o.cma"
+archive(byte,toploop,camlp4r) = "camlp4r.cma"
+
+# For the preprocessor itself:
+archive(syntax,preprocessor,camlp4o) = "-parser o -parser op -printer p"
+archive(syntax,preprocessor,camlp4r) = "-parser r -parser rp -printer p"
+preprocessor = "%%camlp4_cmd%%"
+
+package "lib" (
+ requires = "camlp4 %%camlp4_dynlink%%"
+ version = "[distributed with Ocaml]"
+ description = "Camlp4 library"
+ archive(byte) = "camlp4lib.cma"
+ archive(byte,toploop) = "" # already contained in camlp4*.cma
+ archive(native) = "camlp4lib.cmxa"
+)
+
+package "gramlib" (
+ requires = "camlp4.lib"
+ version = "[distributed with Ocaml]"
+ description = "Compatibilty name for camlp4.lib"
+)
+
+# don't use camlp4.lib and camlp4.fulllib together
+package "fulllib" (
+ requires = "camlp4 %%camlp4_dynlink%%"
+ version = "[distributed with Ocaml]"
+ description = "Camlp4 library"
+ error(pkg_camlp4.lib) = "camlp4.lib and camlp4.fulllib are incompatible"
+ archive(byte) = "camlp4fulllib.cma"
+ archive(byte,toploop) = "" # already contained in camlp4*.cma
+ archive(native) = "camlp4fulllib.cmxa"
+)
+
+package "quotations" (
+ version = "[distributed with Ocaml]"
+ description = "Syntax extension: Quotations to create AST nodes"
+ requires = "camlp4.quotations.r" # backward compat
+# We must have a non-empty archive, otherwise this pkg is ignored
+# for constructing the preprocessor command. We can pass -ignore arg
+# to camlp4 as dummy argument:
+ archive(syntax,preprocessor) = "-ignore foo"
+ package "o" (
+ requires = "camlp4"
+ version = "[distributed with Ocaml]"
+ description = "Syntax extension: Quotations to create AST nodes (original syntax)"
+ archive(syntax,preprocessor) = "-parser Camlp4QuotationCommon -parser Camlp4OCamlOriginalQuotationExpander"
+ archive(syntax,toploop) = "Camlp4Parsers/Camlp4QuotationCommon.cmo Camlp4Parsers/Camlp4OCamlOriginalQuotationExpander.cmo"
+ )
+ package "r" (
+ requires = "camlp4"
+ version = "[distributed with Ocaml]"
+ description = "Syntax extension: Quotations to create AST nodes (revised syntax)"
+ archive(syntax,preprocessor) = "-parser Camlp4QuotationCommon -parser Camlp4OCamlRevisedQuotationExpander"
+ archive(syntax,toploop) = "Camlp4Parsers/Camlp4QuotationCommon.cmo Camlp4Parsers/Camlp4OCamlRevisedQuotationExpander.cmo"
+ )
+)
+
+package "extend" (
+ requires = "camlp4"
+ version = "[distributed with Ocaml]"
+ description = "Syntax extension: EXTEND the camlp4 grammar"
+ archive(syntax,preprocessor) = "-parser Camlp4GrammarParser"
+ archive(syntax,toploop) = "Camlp4Parsers/Camlp4GrammarParser.cmo"
+)
+
+package "listcomprehension" (
+ requires = "camlp4"
+ version = "[distributed with Ocaml]"
+ description = "Syntax extension for list comprehensions"
+ archive(syntax,preprocessor) = "-parser Camlp4ListComprehension"
+ archive(syntax,toploop) = "Camlp4Parsers/Camlp4ListComprehension.cmo"
+)
+
+package "macro" (
+ requires = "camlp4"
+ version = "[distributed with Ocaml]"
+ description = "Syntax extension: Conditional compilation"
+ archive(syntax,preprocessor) = "-parser Camlp4MacroParser"
+ archive(syntax,toploop) = "Camlp4Parsers/Camlp4MacroParser.cmo"
+)
+
+package "mapgenerator" (
+ requires = "camlp4"
+ version = "[distributed with Ocaml]"
+ description = "Syntax filter: Traverse data structure (map style)"
+ archive(syntax,preprocessor) = "-filter Camlp4MapGenerator"
+ archive(syntax,toploop) = "Camlp4Filters/Camlp4MapGenerator.cmo"
+)
+
+package "foldgenerator" (
+ requires = "camlp4"
+ version = "[distributed with Ocaml]"
+ description = "Syntax filter: Traverse data structure (fold style)"
+ archive(syntax,preprocessor) = "-filter Camlp4FoldGenerator"
+ archive(syntax,toploop) = "Camlp4Filters/Camlp4FoldGenerator.cmo"
+)
+
+package "metagenerator" (
+ requires = "camlp4"
+ version = "[distributed with Ocaml]"
+ description = "Syntax filter: Generate AST generator for data structure"
+ archive(syntax,preprocessor) = "-filter Camlp4MetaGenerator"
+ archive(syntax,toploop) = "Camlp4Filters/Camlp4MetaGenerator.cmo"
+)
+
+package "locationstripper" (
+ requires = "camlp4"
+ version = "[distributed with Ocaml]"
+ description = "Syntax filter: Remove location info from AST"
+ archive(syntax,preprocessor) = "-filter Camlp4LocationStripper"
+ archive(syntax,toploop) = "Camlp4Filters/Camlp4LocationStripper.cmo"
+)
+
+package "tracer" (
+ requires = "camlp4"
+ version = "[distributed with Ocaml]"
+ description = "Syntax filter: Trace execution"
+ archive(syntax,preprocessor) = "-filter Camlp4Tracer"
+ archive(syntax,toploop) = "Camlp4Filters/Camlp4Tracer.cmo"
+)
+
+package "exceptiontracer" (
+ requires = "camlp4"
+ version = "[distributed with Ocaml]"
+ description = "Syntax filter: Trace exception execution"
+ archive(syntax,preprocessor) = "-filter Camlp4ExceptionTracer"
+ archive(syntax,toploop) = "Camlp4Filters/Camlp4ExceptionTracer.cmo"
+)
+
+package "profiler" (
+ requires = "camlp4"
+ version = "[distributed with Ocaml]"
+ description = "Syntax filter: Count events during execution"
+ archive(syntax,preprocessor) = "-filter Camlp4Profiler"
+ archive(syntax,toploop) = "Camlp4Filters/Camlp4Profiler.cmo"
+ archive(byte) = "camlp4prof.cmo"
+ archive(native) = "camlp4prof.cmx"
+)
diff --git a/local-packages/ocamlfind/site-lib-src/compiler-libs/META b/local-packages/ocamlfind/site-lib-src/compiler-libs/META
new file mode 100644
index 0000000..f70902f
--- /dev/null
+++ b/local-packages/ocamlfind/site-lib-src/compiler-libs/META
@@ -0,0 +1,45 @@
+# The compiler itself
+requires = ""
+version = "[distributed with Ocaml]"
+description = "compiler-libs support library"
+directory= "+compiler-libs"
+
+package "common" (
+ requires = "compiler-libs"
+ version = "[distributed with Ocaml]"
+ description = "Common compiler routines"
+ archive(byte) = "ocamlcommon.cma"
+ archive(native) = "ocamlcommon.cmxa"
+)
+
+package "bytecomp" (
+ requires = "compiler-libs.common"
+ version = "[distributed with Ocaml]"
+ description = "Bytecode compiler"
+ archive(byte) = "ocamlbytecomp.cma"
+ archive(native) = "ocamlbytecomp.cmxa"
+)
+
+package "optcomp" (
+ requires = "compiler-libs.common"
+ version = "[distributed with Ocaml]"
+ description = "Native-code compiler"
+ archive(byte) = "ocamloptcomp.cma"
+ archive(native) = "ocamloptcomp.cmxa"
+ exists_if = "ocamloptcomp.cma"
+)
+
+package "toplevel" (
+ requires = "compiler-libs.bytecomp"
+ version = "[distributed with Ocaml]"
+ description = "Toplevel interactions"
+ archive(byte) = "ocamltoplevel.cma"
+)
+
+package "native-toplevel" (
+ requires = "compiler-libs.optcomp dynlink"
+ version = "[distributed with Ocaml]"
+ description = "Toplevel interactions"
+ archive(native) = "ocamltoplevel.cmxa"
+ exists_if = "ocamltoplevel.cmxa"
+)
diff --git a/local-packages/ocamlfind/site-lib-src/compiler-libs/META.in b/local-packages/ocamlfind/site-lib-src/compiler-libs/META.in
new file mode 100644
index 0000000..f70902f
--- /dev/null
+++ b/local-packages/ocamlfind/site-lib-src/compiler-libs/META.in
@@ -0,0 +1,45 @@
+# The compiler itself
+requires = ""
+version = "[distributed with Ocaml]"
+description = "compiler-libs support library"
+directory= "+compiler-libs"
+
+package "common" (
+ requires = "compiler-libs"
+ version = "[distributed with Ocaml]"
+ description = "Common compiler routines"
+ archive(byte) = "ocamlcommon.cma"
+ archive(native) = "ocamlcommon.cmxa"
+)
+
+package "bytecomp" (
+ requires = "compiler-libs.common"
+ version = "[distributed with Ocaml]"
+ description = "Bytecode compiler"
+ archive(byte) = "ocamlbytecomp.cma"
+ archive(native) = "ocamlbytecomp.cmxa"
+)
+
+package "optcomp" (
+ requires = "compiler-libs.common"
+ version = "[distributed with Ocaml]"
+ description = "Native-code compiler"
+ archive(byte) = "ocamloptcomp.cma"
+ archive(native) = "ocamloptcomp.cmxa"
+ exists_if = "ocamloptcomp.cma"
+)
+
+package "toplevel" (
+ requires = "compiler-libs.bytecomp"
+ version = "[distributed with Ocaml]"
+ description = "Toplevel interactions"
+ archive(byte) = "ocamltoplevel.cma"
+)
+
+package "native-toplevel" (
+ requires = "compiler-libs.optcomp dynlink"
+ version = "[distributed with Ocaml]"
+ description = "Toplevel interactions"
+ archive(native) = "ocamltoplevel.cmxa"
+ exists_if = "ocamltoplevel.cmxa"
+)
diff --git a/local-packages/ocamlfind/site-lib-src/dbm/META.in b/local-packages/ocamlfind/site-lib-src/dbm/META.in
new file mode 100644
index 0000000..f42e437
--- /dev/null
+++ b/local-packages/ocamlfind/site-lib-src/dbm/META.in
@@ -0,0 +1,10 @@
+# Specification for the "dbm" library
+requires = ""
+version = "[distributed with Ocaml]"
+description = "Access to NDBM databases"
+directory = "^"
+browse_interfaces = "%%interfaces%%"
+archive(byte) = "dbm.cma"
+archive(native) = "dbm.cmxa"
+plugin(byte) = "dbm.cma"
+plugin(native) = "dbm.cmxs"
diff --git a/local-packages/ocamlfind/site-lib-src/dbm/interfaces.in b/local-packages/ocamlfind/site-lib-src/dbm/interfaces.in
new file mode 100644
index 0000000..194b097
--- /dev/null
+++ b/local-packages/ocamlfind/site-lib-src/dbm/interfaces.in
@@ -0,0 +1 @@
+dbm.cma
diff --git a/local-packages/ocamlfind/site-lib-src/dynlink/META b/local-packages/ocamlfind/site-lib-src/dynlink/META
new file mode 100644
index 0000000..d9fda09
--- /dev/null
+++ b/local-packages/ocamlfind/site-lib-src/dynlink/META
@@ -0,0 +1,8 @@
+# Specifications for the "dynlink" library:
+requires = ""
+version = "[distributed with Ocaml]"
+description = "Dynamic loading and linking of object files"
+directory = "+dynlink"
+browse_interfaces = ""
+archive(byte) = "dynlink.cma"
+archive(native) = "dynlink.cmxa"
diff --git a/local-packages/ocamlfind/site-lib-src/dynlink/META.in b/local-packages/ocamlfind/site-lib-src/dynlink/META.in
new file mode 100644
index 0000000..fc483b8
--- /dev/null
+++ b/local-packages/ocamlfind/site-lib-src/dynlink/META.in
@@ -0,0 +1,8 @@
+# Specifications for the "dynlink" library:
+requires = ""
+version = "[distributed with Ocaml]"
+description = "Dynamic loading and linking of object files"
+directory = "%%dynlink_dir%%"
+browse_interfaces = "%%interfaces%%"
+archive(byte) = "dynlink.cma"
+%%natdynlink%%
diff --git a/local-packages/ocamlfind/site-lib-src/dynlink/interfaces.in b/local-packages/ocamlfind/site-lib-src/dynlink/interfaces.in
new file mode 100644
index 0000000..ba9a8e1
--- /dev/null
+++ b/local-packages/ocamlfind/site-lib-src/dynlink/interfaces.in
@@ -0,0 +1 @@
+dynlink.cma
diff --git a/local-packages/ocamlfind/site-lib-src/graphics/META.in b/local-packages/ocamlfind/site-lib-src/graphics/META.in
new file mode 100644
index 0000000..c039d8e
--- /dev/null
+++ b/local-packages/ocamlfind/site-lib-src/graphics/META.in
@@ -0,0 +1,10 @@
+# Specifications for the "graphics" library:
+requires = ""
+version = "[distributed with Ocaml]"
+description = "Portable drawing primitives"
+directory = "^"
+browse_interfaces = "%%interfaces%%"
+archive(byte) = "graphics.cma"
+archive(native) = "graphics.cmxa"
+plugin(byte) = "graphics.cma"
+plugin(native) = "graphics.cmxs"
diff --git a/local-packages/ocamlfind/site-lib-src/graphics/interfaces.in b/local-packages/ocamlfind/site-lib-src/graphics/interfaces.in
new file mode 100644
index 0000000..c01117a
--- /dev/null
+++ b/local-packages/ocamlfind/site-lib-src/graphics/interfaces.in
@@ -0,0 +1,2 @@
+graphics.cma
+
diff --git a/local-packages/ocamlfind/site-lib-src/labltk/META.in b/local-packages/ocamlfind/site-lib-src/labltk/META.in
new file mode 100644
index 0000000..efbd3ed
--- /dev/null
+++ b/local-packages/ocamlfind/site-lib-src/labltk/META.in
@@ -0,0 +1,10 @@
+# Specifications for the "labltk" library:
+requires = ""
+version = "[distributed with Ocaml]"
+description = "The Tk windowing toolkit"
+directory = "+labltk"
+browse_interfaces = "%%interfaces%%"
+archive(byte) = "labltk.cma"
+archive(native) = "labltk.cmxa"
+linkopts = ""
+
diff --git a/local-packages/ocamlfind/site-lib-src/labltk/interfaces.in b/local-packages/ocamlfind/site-lib-src/labltk/interfaces.in
new file mode 100644
index 0000000..0f0d0d5
--- /dev/null
+++ b/local-packages/ocamlfind/site-lib-src/labltk/interfaces.in
@@ -0,0 +1,2 @@
+labltk/*.cma
+
diff --git a/local-packages/ocamlfind/site-lib-src/num-top/META.in b/local-packages/ocamlfind/site-lib-src/num-top/META.in
new file mode 100644
index 0000000..4f9d9d0
--- /dev/null
+++ b/local-packages/ocamlfind/site-lib-src/num-top/META.in
@@ -0,0 +1,6 @@
+# Specification for the "num-top" library add-on:
+requires = "num.core"
+version = "%%findlib_version%%"
+description = "Add-on for num inside toploops"
+archive(byte,toploop) = "num_top.cma"
+
diff --git a/local-packages/ocamlfind/site-lib-src/num/META.in b/local-packages/ocamlfind/site-lib-src/num/META.in
new file mode 100644
index 0000000..c47d0d5
--- /dev/null
+++ b/local-packages/ocamlfind/site-lib-src/num/META.in
@@ -0,0 +1,14 @@
+# Specification for the "num" library:
+requires = "num.core"
+requires(toploop) = "num.core,num-top"
+version = "[distributed with Ocaml]"
+description = "Arbitrary-precision rational arithmetic"
+package "core" (
+ directory = "^"
+ version = "[internal]"
+ browse_interfaces = "%%interfaces%%"
+ archive(byte) = "nums.cma"
+ archive(native) = "nums.cmxa"
+ plugin(byte) = "nums.cma"
+ plugin(native) = "nums.cmxs"
+)
diff --git a/local-packages/ocamlfind/site-lib-src/num/interfaces.in b/local-packages/ocamlfind/site-lib-src/num/interfaces.in
new file mode 100644
index 0000000..e72911a
--- /dev/null
+++ b/local-packages/ocamlfind/site-lib-src/num/interfaces.in
@@ -0,0 +1 @@
+nums.cma
diff --git a/local-packages/ocamlfind/site-lib-src/ocamlbuild/META.in b/local-packages/ocamlfind/site-lib-src/ocamlbuild/META.in
new file mode 100644
index 0000000..1edcf21
--- /dev/null
+++ b/local-packages/ocamlfind/site-lib-src/ocamlbuild/META.in
@@ -0,0 +1,8 @@
+# Specification for the "ocamlbuild" library
+requires = "unix"
+version = "[distributed with Ocaml]"
+description = "ocamlbuild support library"
+directory= "^ocamlbuild"
+archive(byte) = "ocamlbuildlib.cma"
+archive(native) = "ocamlbuildlib.cmxa"
+
diff --git a/local-packages/ocamlfind/site-lib-src/ocamldoc/META b/local-packages/ocamlfind/site-lib-src/ocamldoc/META
new file mode 100644
index 0000000..bbd49f8
--- /dev/null
+++ b/local-packages/ocamlfind/site-lib-src/ocamldoc/META
@@ -0,0 +1,5 @@
+# Specification for the "ocamldoc" library
+requires = "compiler-libs"
+version = "[distributed with Ocaml]"
+description = "ocamldoc plugin interface"
+directory= "^ocamldoc"
diff --git a/local-packages/ocamlfind/site-lib-src/ocamldoc/META.in b/local-packages/ocamlfind/site-lib-src/ocamldoc/META.in
new file mode 100644
index 0000000..bbd49f8
--- /dev/null
+++ b/local-packages/ocamlfind/site-lib-src/ocamldoc/META.in
@@ -0,0 +1,5 @@
+# Specification for the "ocamldoc" library
+requires = "compiler-libs"
+version = "[distributed with Ocaml]"
+description = "ocamldoc plugin interface"
+directory= "^ocamldoc"
diff --git a/local-packages/ocamlfind/site-lib-src/raw_spacetime/META.in b/local-packages/ocamlfind/site-lib-src/raw_spacetime/META.in
new file mode 100644
index 0000000..58b1df7
--- /dev/null
+++ b/local-packages/ocamlfind/site-lib-src/raw_spacetime/META.in
@@ -0,0 +1,11 @@
+# Specifications for the "spacetime" library:
+requires = ""
+description = "Support library for the spacetime profiler"
+version = "[distributed with Ocaml]"
+directory = "^"
+browse_interfaces = "%%interfaces%%"
+archive(byte) = "raw_spacetime_lib.cma"
+archive(native) = "raw_spacetime_lib.cmxa"
+plugin(byte) = "raw_spacetime_lib.cma"
+plugin(native) = "raw_spacetime_lib.cmxs"
+
diff --git a/local-packages/ocamlfind/site-lib-src/raw_spacetime/interfaces.in b/local-packages/ocamlfind/site-lib-src/raw_spacetime/interfaces.in
new file mode 100644
index 0000000..af44828
--- /dev/null
+++ b/local-packages/ocamlfind/site-lib-src/raw_spacetime/interfaces.in
@@ -0,0 +1 @@
+raw_spacetime_lib.cma
diff --git a/local-packages/ocamlfind/site-lib-src/runtime_events/META b/local-packages/ocamlfind/site-lib-src/runtime_events/META
new file mode 100644
index 0000000..ee81017
--- /dev/null
+++ b/local-packages/ocamlfind/site-lib-src/runtime_events/META
@@ -0,0 +1,11 @@
+# Specifications for the "runtime_events" library:
+requires = ""
+description = "Runtime events"
+version = "[distributed with OCaml]"
+directory = "+runtime_events"
+browse_interfaces = ""
+archive(byte) = "runtime_events.cma"
+archive(native) = "runtime_events.cmxa"
+plugin(byte) = "runtime_events.cma"
+plugin(native) = "runtime_events.cmxs"
+
diff --git a/local-packages/ocamlfind/site-lib-src/runtime_events/META.in b/local-packages/ocamlfind/site-lib-src/runtime_events/META.in
new file mode 100644
index 0000000..cc81334
--- /dev/null
+++ b/local-packages/ocamlfind/site-lib-src/runtime_events/META.in
@@ -0,0 +1,11 @@
+# Specifications for the "runtime_events" library:
+requires = ""
+description = "Runtime events"
+version = "[distributed with OCaml]"
+directory = "+runtime_events"
+browse_interfaces = "%%interfaces%%"
+archive(byte) = "runtime_events.cma"
+archive(native) = "runtime_events.cmxa"
+plugin(byte) = "runtime_events.cma"
+plugin(native) = "runtime_events.cmxs"
+
diff --git a/local-packages/ocamlfind/site-lib-src/runtime_events/interfaces.in b/local-packages/ocamlfind/site-lib-src/runtime_events/interfaces.in
new file mode 100644
index 0000000..b6df842
--- /dev/null
+++ b/local-packages/ocamlfind/site-lib-src/runtime_events/interfaces.in
@@ -0,0 +1 @@
+runtime_events.cma
diff --git a/local-packages/ocamlfind/site-lib-src/stdlib/META b/local-packages/ocamlfind/site-lib-src/stdlib/META
new file mode 100644
index 0000000..f391afc
--- /dev/null
+++ b/local-packages/ocamlfind/site-lib-src/stdlib/META
@@ -0,0 +1,9 @@
+# Specifications for the standard library:
+# (Only included because of findlib-browser)
+requires = ""
+description = "Standard library"
+version = "[distributed with Ocaml]"
+directory = "^"
+browse_interfaces = ""
+
+
diff --git a/local-packages/ocamlfind/site-lib-src/stdlib/META.in b/local-packages/ocamlfind/site-lib-src/stdlib/META.in
new file mode 100644
index 0000000..a0d2977
--- /dev/null
+++ b/local-packages/ocamlfind/site-lib-src/stdlib/META.in
@@ -0,0 +1,9 @@
+# Specifications for the standard library:
+# (Only included because of findlib-browser)
+requires = ""
+description = "Standard library"
+version = "[distributed with Ocaml]"
+directory = "^"
+browse_interfaces = "%%interfaces%%"
+
+
diff --git a/local-packages/ocamlfind/site-lib-src/stdlib/interfaces.in b/local-packages/ocamlfind/site-lib-src/stdlib/interfaces.in
new file mode 100644
index 0000000..bed1dcb
--- /dev/null
+++ b/local-packages/ocamlfind/site-lib-src/stdlib/interfaces.in
@@ -0,0 +1 @@
+stdlib.cma
diff --git a/local-packages/ocamlfind/site-lib-src/str/META b/local-packages/ocamlfind/site-lib-src/str/META
new file mode 100644
index 0000000..68783b4
--- /dev/null
+++ b/local-packages/ocamlfind/site-lib-src/str/META
@@ -0,0 +1,12 @@
+# Specifications for the "str" library:
+requires = ""
+description = "Regular expressions and string processing"
+version = "[distributed with Ocaml]"
+directory = "+str"
+browse_interfaces = ""
+archive(byte) = "str.cma"
+archive(native) = "str.cmxa"
+plugin(byte) = "str.cma"
+plugin(native) = "str.cmxs"
+
+
diff --git a/local-packages/ocamlfind/site-lib-src/str/META.in b/local-packages/ocamlfind/site-lib-src/str/META.in
new file mode 100644
index 0000000..f557229
--- /dev/null
+++ b/local-packages/ocamlfind/site-lib-src/str/META.in
@@ -0,0 +1,12 @@
+# Specifications for the "str" library:
+requires = ""
+description = "Regular expressions and string processing"
+version = "[distributed with Ocaml]"
+directory = "%%str_dir%%"
+browse_interfaces = "%%interfaces%%"
+archive(byte) = "str.cma"
+archive(native) = "str.cmxa"
+plugin(byte) = "str.cma"
+plugin(native) = "str.cmxs"
+
+
diff --git a/local-packages/ocamlfind/site-lib-src/str/interfaces.in b/local-packages/ocamlfind/site-lib-src/str/interfaces.in
new file mode 100644
index 0000000..e3b926f
--- /dev/null
+++ b/local-packages/ocamlfind/site-lib-src/str/interfaces.in
@@ -0,0 +1 @@
+str.cma
diff --git a/local-packages/ocamlfind/site-lib-src/threads/META b/local-packages/ocamlfind/site-lib-src/threads/META
new file mode 100644
index 0000000..331a5eb
--- /dev/null
+++ b/local-packages/ocamlfind/site-lib-src/threads/META
@@ -0,0 +1,37 @@
+# Specifications for the "threads" library:
+version = "[distributed with Ocaml]"
+description = "Multi-threading"
+requires(mt,mt_vm) = "threads.vm"
+requires(mt,mt_posix) = "threads.posix"
+directory = "^"
+type_of_threads = "posix"
+
+browse_interfaces = ""
+
+warning(-mt) = "Linking problems may arise because of the missing -thread or -vmthread switch"
+warning(-mt_vm,-mt_posix) = "Linking problems may arise because of the missing -thread or -vmthread switch"
+
+package "vm" (
+ # --- Bytecode-only threads:
+ requires = "unix"
+ directory = "+vmthreads"
+ exists_if = "threads.cma"
+ archive(byte,mt,mt_vm) = "threads.cma"
+ version = "[internal]"
+)
+
+package "posix" (
+ # --- POSIX-threads:
+ requires = "unix"
+ directory = "+threads"
+ exists_if = "threads.cma"
+ archive(byte,mt,mt_posix) = "threads.cma"
+ archive(native,mt,mt_posix) = "threads.cmxa"
+ version = "[internal]"
+)
+
+package "none" (
+ error = "threading is not supported on this platform"
+ version = "[internal]"
+)
+
diff --git a/local-packages/ocamlfind/site-lib-src/threads/META.in b/local-packages/ocamlfind/site-lib-src/threads/META.in
new file mode 100644
index 0000000..6ccfb58
--- /dev/null
+++ b/local-packages/ocamlfind/site-lib-src/threads/META.in
@@ -0,0 +1,37 @@
+# Specifications for the "threads" library:
+version = "[distributed with Ocaml]"
+description = "Multi-threading"
+requires(mt,mt_vm) = "threads.vm"
+requires(mt,mt_posix) = "threads.posix"
+directory = "^"
+type_of_threads = "%%type_of_threads%%"
+
+browse_interfaces = "%%interfaces%%"
+
+warning(-mt) = "Linking problems may arise because of the missing -thread or -vmthread switch"
+warning(-mt_vm,-mt_posix) = "Linking problems may arise because of the missing -thread or -vmthread switch"
+
+package "vm" (
+ # --- Bytecode-only threads:
+ requires = "unix"
+ directory = "+vmthreads"
+ exists_if = "threads.cma"
+ archive(byte,mt,mt_vm) = "threads.cma"
+ version = "[internal]"
+)
+
+package "posix" (
+ # --- POSIX-threads:
+ requires = "unix"
+ directory = "+threads"
+ exists_if = "threads.cma"
+ archive(byte,mt,mt_posix) = "threads.cma"
+ archive(native,mt,mt_posix) = "threads.cmxa"
+ version = "[internal]"
+)
+
+package "none" (
+ error = "threading is not supported on this platform"
+ version = "[internal]"
+)
+
diff --git a/local-packages/ocamlfind/site-lib-src/threads/interfaces.in b/local-packages/ocamlfind/site-lib-src/threads/interfaces.in
new file mode 100644
index 0000000..b3c6481
--- /dev/null
+++ b/local-packages/ocamlfind/site-lib-src/threads/interfaces.in
@@ -0,0 +1,2 @@
+vmthreads/threads.cma
+
diff --git a/local-packages/ocamlfind/site-lib-src/unix/META b/local-packages/ocamlfind/site-lib-src/unix/META
new file mode 100644
index 0000000..3955cca
--- /dev/null
+++ b/local-packages/ocamlfind/site-lib-src/unix/META
@@ -0,0 +1,13 @@
+# Specifications for the "unix" library:
+requires = ""
+description = "Unix system calls"
+version = "[distributed with Ocaml]"
+directory = "+unix"
+browse_interfaces = ""
+archive(byte) = "unix.cma"
+archive(native) = "unix.cmxa"
+archive(byte,mt_vm) = "vmthreads/unix.cma"
+plugin(byte) = "unix.cma"
+plugin(native) = "unix.cmxs"
+plugin(byte,mt_vm) = "vmthreads/unix.cma"
+
diff --git a/local-packages/ocamlfind/site-lib-src/unix/META.in b/local-packages/ocamlfind/site-lib-src/unix/META.in
new file mode 100644
index 0000000..020c083
--- /dev/null
+++ b/local-packages/ocamlfind/site-lib-src/unix/META.in
@@ -0,0 +1,13 @@
+# Specifications for the "unix" library:
+requires = ""
+description = "Unix system calls"
+version = "[distributed with Ocaml]"
+directory = "%%unix_dir%%"
+browse_interfaces = "%%interfaces%%"
+archive(byte) = "unix.cma"
+archive(native) = "unix.cmxa"
+archive(byte,mt_vm) = "vmthreads/unix.cma"
+plugin(byte) = "unix.cma"
+plugin(native) = "unix.cmxs"
+plugin(byte,mt_vm) = "vmthreads/unix.cma"
+
diff --git a/local-packages/ocamlfind/site-lib-src/unix/interfaces.in b/local-packages/ocamlfind/site-lib-src/unix/interfaces.in
new file mode 100644
index 0000000..5984298
--- /dev/null
+++ b/local-packages/ocamlfind/site-lib-src/unix/interfaces.in
@@ -0,0 +1 @@
+unix.cma
diff --git a/local-packages/ocamlfind/src/bytes/META b/local-packages/ocamlfind/src/bytes/META
new file mode 100644
index 0000000..dd96130
--- /dev/null
+++ b/local-packages/ocamlfind/src/bytes/META
@@ -0,0 +1,9 @@
+name="bytes"
+version="[OCaml strictly before 4.02]"
+description="backward-compatibility package for mutable strings"
+requires=""
+browse_interfaces = "String"
+archive(byte)="bytes.cma"
+archive(native)="bytes.cmxa"
+plugin(byte)="bytes.cma"
+plugin(native)="bytes.cmxs"
diff --git a/local-packages/ocamlfind/src/bytes/Makefile b/local-packages/ocamlfind/src/bytes/Makefile
new file mode 100644
index 0000000..dd5b9b9
--- /dev/null
+++ b/local-packages/ocamlfind/src/bytes/Makefile
@@ -0,0 +1,40 @@
+BYTE_FILES=bytes.cmi bytes.cma
+NATIVE_FILES=bytes.cmx bytes$(LIB_SUFFIX) bytes.cmxa
+NATIVE_FILES_DYNLINK=bytes.cmxs
+
+TOP=../..
+include $(TOP)/Makefile.config
+
+OCAMLC = ocamlc
+OCAMLOPT = ocamlopt -g
+
+build: all opt
+
+all:
+ $(OCAMLC) -a -o bytes.cma bytes.ml
+
+opt:
+ $(OCAMLOPT) -a -o bytes.cmxa bytes.ml
+ if [ $(HAVE_NATDYNLINK) -gt 0 ]; then \
+ $(OCAMLOPT) -shared -o bytes.cmxs bytes.cmxa; \
+ fi
+
+install: all
+ $(INSTALLDIR) "$(DESTDIR)$(prefix)$(OCAML_SITELIB)/bytes"
+ $(INSTALLFILE) META $(BYTE_FILES) "$(DESTDIR)$(prefix)$(OCAML_SITELIB)/bytes/"
+ for f in $(NATIVE_FILES) $(NATIVE_FILES_DYNLINK); do if [ -f "$$f" ]; then $(INSTALLFILE) $$f "$(DESTDIR)$(prefix)$(OCAML_SITELIB)/bytes/"; fi; done
+
+uninstall:
+ rm -rf "$(DESTDIR)$(prefix)$(OCAML_SITELIB)/bytes"
+
+# install-self and uninstall-self use ocamlfind already. This is a bit
+# questionable here.
+
+install-self: all
+ ocamlfind install bytes META $(BYTE_FILES) -optional $(NATIVE_FILES) $(NATIVE_FILES_DYNLINK)
+
+uninstall-self:
+ ocamlfind remove bytes
+
+clean:
+ ocamlbuild -clean
diff --git a/local-packages/ocamlfind/src/bytes/README b/local-packages/ocamlfind/src/bytes/README
new file mode 100644
index 0000000..5cd9900
--- /dev/null
+++ b/local-packages/ocamlfind/src/bytes/README
@@ -0,0 +1,7 @@
+backward-compatibility package for the standard Bytes module of 4.02
+
+Starting from 4.02, the OCaml standard library splits String into two
+modules, String for now-immutable strings and Bytes for mutable byte
+sequences. This package exports a Bytes package mimicking the new
+interface to older OCaml version, letting you write code using Bytes
+that works with OCaml < 4.02.
diff --git a/local-packages/ocamlfind/src/bytes/bytes.ml b/local-packages/ocamlfind/src/bytes/bytes.ml
new file mode 100644
index 0000000..127519f
--- /dev/null
+++ b/local-packages/ocamlfind/src/bytes/bytes.ml
@@ -0,0 +1,36 @@
+include String
+
+let empty = ""
+let of_string = copy
+let to_string = copy
+
+let sub_string = sub
+let blit_string = blit
+
+let unsafe_to_string : t -> string = fun s -> s
+let unsafe_of_string : string -> t = fun s -> s
+
+let extend s left right =
+ (* length of the final string *)
+ let dstlen = left + length s + right in
+ (* length of the included portion of the input string *)
+ let srclen = min 0 left + length s + min 0 right in
+ let t = create dstlen in
+ if srclen > 0 then blit s (max 0 (-left)) t (max 0 left) srclen;
+ t
+
+let init len f =
+ let s = create len in
+ for i = 0 to len - 1 do
+ set s i (f i);
+ done;
+ s
+
+let mapi f input =
+ let output = create (length input) in
+ for i = 0 to length input - 1 do
+ output.[i] <- f i input.[i];
+ done;
+ output
+
+let cat = (^)
diff --git a/local-packages/ocamlfind/src/findlib-toolbox/Makefile b/local-packages/ocamlfind/src/findlib-toolbox/Makefile
new file mode 100644
index 0000000..e8bfdb5
--- /dev/null
+++ b/local-packages/ocamlfind/src/findlib-toolbox/Makefile
@@ -0,0 +1,37 @@
+TOP=../..
+include $(TOP)/Makefile.config
+
+.PHONY: all opt install uninstall clean
+
+all: make_wizard$(EXEC_SUFFIX)
+
+opt:
+ true
+
+make_wizard$(EXEC_SUFFIX): make_wizard.ml
+ ocamlc -o make_wizard$(EXEC_SUFFIX) -I +unix -I +labltk -I ../findlib \
+ unix.cma str.cma labltk.cma findlib.cma make_wizard.ml
+
+install:
+ $(INSTALLFILE) make_wizard$(EXEC_SUFFIX) make_wizard.pattern $(DESTDIR)$(prefix)$(OCAML_SITELIB)/findlib/
+
+# uninstall: Nothing to do, because the removal of the findlib core also
+# deinstalls the make_wizard
+uninstall:
+ true
+
+# ----------------------------------------------------------------------
+
+tree: lx_spots.mli lx_spots.ml lx_tree.mli lx_tree.ml test_tree.ml
+ ocamlfind ocamlc -o tree -package labltk,unix,str -linkpkg \
+ lx_spots.mli lx_spots.ml lx_tree.mli lx_tree.ml test_tree.ml
+
+tree_editor: lx_spots.mli lx_spots.ml lx_tree.mli lx_tree.ml tree_editor.ml
+ ocamlfind ocamlc -o tree_editor -package labltk,unix,str -linkpkg \
+ lx_spots.mli lx_spots.ml lx_tree.mli lx_tree.ml tree_editor.ml
+
+# ----------------------------------------------------------------------
+
+clean:
+ rm -f *.cmi *.cmo
+ rm -f make_wizard$(EXEC_SUFFIX) # tree tree_editor
diff --git a/local-packages/ocamlfind/src/findlib-toolbox/make_wizard.ml b/local-packages/ocamlfind/src/findlib-toolbox/make_wizard.ml
new file mode 100644
index 0000000..574c23c
--- /dev/null
+++ b/local-packages/ocamlfind/src/findlib-toolbox/make_wizard.ml
@@ -0,0 +1,1559 @@
+(* $Id$
+ * ----------------------------------------------------------------------
+ *
+ *)
+
+
+open Tk;;
+open Widget;;
+
+(**********************************************************************)
+(* GLOBAL VARIABLES *)
+(**********************************************************************)
+
+(* General *)
+
+let wiz_package_name = ref "";;
+let wiz_package_version = ref "";;
+let wiz_package_description = ref "";;
+
+(* Preprocessor *)
+
+let wiz_enable_camlp4 = ref false;;
+let wiz_camlp4_syntax = ref "camlp4o";;
+let wiz_camlp4_extensions = ref [];; (* list of package names *)
+let wiz_camlp4_selected = ref [];; (* subset of wiz_camlp4_extensions *)
+let wiz_camlp4_options = ref "";;
+
+(* Prerequisites *)
+
+let wiz_all_packages = ref [];; (* list of package names *)
+let wiz_required_packages = ref [];; (* subset of wiz_all_packages *)
+
+(* Build Library *)
+
+let wiz_available = ref [];; (* list of module names *)
+let wiz_byte_enable = ref true;;
+let wiz_nat_enable = ref true;;
+let wiz_objects = ref [];; (* subset of wiz_available *)
+let wiz_source_suffixes = ref ".ml .mli .mll .mly";;
+
+(* Build Executables *)
+
+let wiz_executables = ref [];; (* list of executable names *)
+let wiz_exec_objects = (ref [] : (string * (string list ref)) list ref);;
+ (* an alist: for every executable, the corresponding list of modules is
+ * stored.
+ *)
+let wiz_exec_native = (ref [] : (string * bool ref) list ref);;
+ (* an alist: for every executable, whether it is natively compiled or not *)
+
+(* Generate *)
+
+let wiz_makefile_name = ref "Makefile";;
+let wiz_local_makefile_name = ref "";;
+let wiz_make_default = ref "byte" ;;
+
+
+(**********************************************************************)
+(* AUXILIARY FUNCTIONS *)
+(**********************************************************************)
+
+let find_pos x l =
+ let rec find k l =
+ match l with
+ h :: l' ->
+ if x = h then k else find (k+1) l'
+ | [] ->
+ raise Not_found
+ in
+ find 0 l
+;;
+
+
+let rec delete_at k l =
+ match l with
+ h :: l' -> if k <= 0 then l' else h :: (delete_at (k-1) l')
+ | [] -> []
+;;
+
+
+let rec insert_at k x l =
+ if k <= 0 then
+ x :: l
+ else
+ match l with
+ h :: l' -> h :: (insert_at (k-1) x l')
+ | [] -> [] (* insert beyond end *)
+;;
+
+
+let rec remove_dups l =
+ (* Remove duplicate members in a sorted list *)
+ match l with
+ x :: (y :: l' as l1) when x = y ->
+ remove_dups l1
+ | x :: l' ->
+ x :: remove_dups l'
+ | [] ->
+ []
+;;
+
+
+(**********************************************************************)
+(* SAVE/LOAD STATE *)
+(**********************************************************************)
+
+let save_var name printer out var =
+ output_string out ("V" ^ name ^ "\n");
+ printer out var
+;;
+
+let save_string out var =
+ (* [var] must not contain linefeeds *)
+ output_string out ("S" ^ var ^ "\n")
+;;
+
+let save_bool out var =
+ output_string out ("B" ^ string_of_bool var ^ "\n")
+;;
+
+let save_list printer out var =
+ output_string out ("L" ^ string_of_int (List.length var) ^ "\n");
+ List.iter (printer out) var
+;;
+
+let save_pair lprinter rprinter out (lvar,rvar) =
+ output_string out "P\n";
+ lprinter out lvar;
+ rprinter out rvar
+;;
+
+let save_ref printer out var =
+ (* Actually doesn't save the reference! *)
+ printer out !var
+;;
+
+let save_state out =
+ save_var "wiz_package_name" save_string out !wiz_package_name;
+ save_var "wiz_package_version" save_string out !wiz_package_version;
+ save_var "wiz_package_description" save_string out !wiz_package_description;
+ save_var "wiz_enable_camlp4" save_bool out !wiz_enable_camlp4;
+ save_var "wiz_camlp4_syntax" save_string out !wiz_camlp4_syntax;
+ save_var "wiz_camlp4_extensions" (save_list save_string) out
+ !wiz_camlp4_extensions;
+ save_var "wiz_camlp4_selected" (save_list save_string) out
+ !wiz_camlp4_selected;
+ save_var "wiz_camlp4_options" save_string out !wiz_camlp4_options;
+ save_var "wiz_all_packages" (save_list save_string) out
+ !wiz_all_packages;
+ save_var "wiz_required_packages" (save_list save_string) out
+ !wiz_required_packages;
+ save_var "wiz_available" (save_list save_string) out
+ !wiz_available;
+ save_var "wiz_byte_enable" save_bool out !wiz_byte_enable;
+ save_var "wiz_nat_enable" save_bool out !wiz_nat_enable;
+ save_var "wiz_objects" (save_list save_string) out
+ !wiz_objects;
+ save_var "wiz_source_suffixes" save_string out !wiz_source_suffixes;
+ save_var "wiz_executables" (save_list save_string) out
+ !wiz_executables;
+ save_var "wiz_exec_objects"
+ (save_list (save_pair save_string (save_ref (save_list save_string))))
+ out
+ !wiz_exec_objects;
+ save_var "wiz_exec_native"
+ (save_list (save_pair save_string (save_ref save_bool)))
+ out
+ !wiz_exec_native;
+ save_var "wiz_makefile_name" save_string out !wiz_makefile_name;
+ save_var "wiz_local_makefile_name" save_string out !wiz_local_makefile_name;
+ save_var "wiz_make_default" save_string out !wiz_make_default;
+;;
+
+let save() =
+ let f = open_out ".make-wizard" in
+ save_state f;
+ close_out f
+;;
+
+let check_char inch c_expected =
+ let c = input_char inch in
+ if c <> c_expected then failwith "Cannot read .make-wizard"
+;;
+
+let load_string inch =
+ check_char inch 'S';
+ let line = input_line inch in
+ (* prerr_endline ("String = " ^ line); *)
+ line
+;;
+
+let load_bool inch =
+ check_char inch 'B';
+ bool_of_string(input_line inch)
+;;
+
+let load_list parse inch =
+ check_char inch 'L';
+ let n = int_of_string(input_line inch) in
+ let l = ref [] in
+ for i = 1 to n do
+ l := parse inch :: !l;
+ done;
+ List.rev !l
+;;
+
+let load_pair lparse rparse inch =
+ check_char inch 'P';
+ ignore(input_line inch);
+ let l = lparse inch in
+ let r = rparse inch in
+ (l,r)
+;;
+
+let load_ref parse inch =
+ ref(parse inch)
+;;
+
+let load_var var parse inch =
+ let value = parse inch in
+ var := value
+;;
+
+let load_variables spec inch =
+ try
+ while true do
+ try
+ check_char inch 'V';
+ let name = input_line inch in
+ (* prerr_endline name;*)
+ let loader = List.assoc name spec in (* or Not_found *)
+ loader inch
+ with
+ Not_found ->
+ ()
+ done;
+ assert false
+ with
+ End_of_file ->
+ ()
+;;
+
+let load_state inch =
+ load_variables
+ [ "wiz_package_name",
+ (load_var wiz_package_name load_string);
+ "wiz_package_version",
+ (load_var wiz_package_version load_string);
+ "wiz_package_description",
+ (load_var wiz_package_description load_string);
+ "wiz_enable_camlp4",
+ (load_var wiz_enable_camlp4 load_bool);
+ "wiz_camlp4_syntax",
+ (load_var wiz_camlp4_syntax load_string);
+ "wiz_camlp4_extensions",
+ (load_var wiz_camlp4_extensions (load_list load_string));
+ "wiz_camlp4_selected",
+ (load_var wiz_camlp4_selected (load_list load_string));
+ "wiz_camlp4_options",
+ (load_var wiz_camlp4_options load_string);
+ "wiz_all_packages",
+ (load_var wiz_all_packages (load_list load_string));
+ "wiz_required_packages",
+ (load_var wiz_required_packages (load_list load_string));
+ "wiz_available",
+ (load_var wiz_available (load_list load_string));
+ "wiz_byte_enable",
+ (load_var wiz_byte_enable load_bool);
+ "wiz_nat_enable",
+ (load_var wiz_nat_enable load_bool);
+ "wiz_objects",
+ (load_var wiz_objects (load_list load_string));
+ "wiz_source_suffixes",
+ (load_var wiz_source_suffixes load_string);
+ "wiz_executables",
+ (load_var wiz_executables (load_list load_string));
+ "wiz_exec_objects",
+ (load_var wiz_exec_objects (load_list
+ (load_pair
+ load_string
+ (load_ref (load_list load_string)))));
+ "wiz_exec_native",
+ (load_var wiz_exec_native (load_list
+ (load_pair
+ load_string
+ (load_ref load_bool))));
+ "wiz_makefile_name",
+ (load_var wiz_makefile_name load_string);
+ "wiz_local_makefile_name",
+ (load_var wiz_local_makefile_name load_string);
+ "wiz_make_default",
+ (load_var wiz_make_default load_string);
+ ]
+ inch
+;;
+
+
+let load() =
+ let f = open_in ".make-wizard" in
+ load_state f;
+ close_in f
+;;
+
+
+(**********************************************************************)
+(* PARSE PATTERN FILE *)
+(**********************************************************************)
+
+type sectiondata =
+ Sect_const of string
+ | Sect_var of string
+
+let section_re = Str.regexp "^\\[\\([A-Za-z_0-9-]+\\)\\]$" ;;
+let var_re = Str.regexp "\\[\\([A-Za-z_0-9-]+\\)\\]" ;;
+
+let parse_pattern inch =
+ let rec parse_section name sect =
+ try
+ let line = input_line inch in
+ if String.length line >= 2 && line.[0] = '#' && line.[1] = '#' then
+ (* Comment line *)
+ parse_section name sect
+ else
+ if Str.string_match section_re line 0 then
+ (* New section begins *)
+ let name' = Str.matched_group 1 line in
+ (name, List.rev sect) :: parse_section name' []
+ else
+ (* Normal data region *)
+ let plist = Str.full_split var_re line in
+ let slist =
+ List.map
+ (function
+ Str.Text t -> Sect_const t
+ | Str.Delim d -> Sect_var (String.sub d 1 (String.length d - 2))
+ )
+ plist @ [ Sect_const "\n" ] in
+ parse_section name (List.rev slist @ sect)
+ with
+ End_of_file ->
+ [ name, List.rev sect ]
+ in
+
+ parse_section "_preamble_" []
+;;
+
+let load_pattern() =
+ let where = Filename.dirname (Sys.argv.(0)) in
+ let name = Filename.concat where "make_wizard.pattern" in
+ let f = open_in name in
+ let p = parse_pattern f in
+ close_in f;
+ p
+;;
+
+(**********************************************************************)
+(* MAKEFILE GENERATOR *)
+(**********************************************************************)
+
+let dollar_re = Str.regexp "\\$";;
+let meta_re = Str.regexp "[\\\\\\\"]";;
+
+let mkquote s =
+ (* Quote "$" *)
+ Str.global_replace dollar_re "$$" s
+;;
+
+let metaquote s =
+ (* Quote backslash and double quotes for META files *)
+ Str.global_replace meta_re "\\\\0" s
+;;
+
+let makemake() =
+ let b = Buffer.create 1024 in
+ let sections = load_pattern() in
+
+ let write section vars =
+ let sectlist =
+ try List.assoc section sections
+ with Not_found -> failwith ("Cannot find section: " ^ section) in
+ List.iter
+ (function
+ Sect_const s ->
+ Buffer.add_string b s
+ | Sect_var v ->
+ let s =
+ try List.assoc v vars
+ with Not_found -> failwith ("No such variable: " ^ v) in
+ Buffer.add_string b s
+ )
+ sectlist
+ in
+
+ let is_byte_exec execname =
+ try not (!(List.assoc execname !wiz_exec_native))
+ with Not_found -> true
+ in
+
+ let byte_execs =
+ List.map
+ fst
+ (List.filter
+ (fun (execname,_) -> is_byte_exec execname)
+ !wiz_exec_objects
+ )
+ in
+
+ let nat_execs =
+ List.map
+ fst
+ (List.filter
+ (fun (execname,_) -> not(is_byte_exec execname))
+ !wiz_exec_objects
+ )
+ in
+
+ let byte_exec_modules =
+ remove_dups
+ (List.sort compare
+ (List.flatten
+ (List.map
+ (fun (_, l) -> !l)
+ (List.filter
+ (fun (execname, _) -> is_byte_exec execname)
+ !wiz_exec_objects
+ )
+ )
+ )
+ )
+ in
+
+ let nat_exec_modules =
+ remove_dups
+ (List.sort compare
+ (List.flatten
+ (List.map
+ (fun (_, l) -> !l)
+ (List.filter
+ (fun (execname, _) -> not(is_byte_exec execname))
+ !wiz_exec_objects
+ )
+ )
+ )
+ )
+ in
+
+ let required_packages =
+ (* magically add "camlp4" if missing *)
+ if !wiz_enable_camlp4 then (
+ ( if not (List.mem "camlp4" !wiz_required_packages) then
+ [ "camlp4" ]
+ else
+ []
+ ) @ !wiz_camlp4_selected @ !wiz_required_packages
+ )
+ else
+ !wiz_required_packages
+ in
+
+ let variables =
+ [ "name",
+ mkquote !wiz_package_name;
+ "makefile_name",
+ mkquote !wiz_makefile_name;
+ "version",
+ mkquote(metaquote !wiz_package_version);
+ "description",
+ mkquote(metaquote !wiz_package_description);
+ "byte_objects",
+ String.concat " " (List.map
+ (fun m -> String.uncapitalize m ^ ".cmo")
+ !wiz_objects);
+ "nat_objects",
+ String.concat " " (List.map
+ (fun m -> String.uncapitalize m ^ ".cmx")
+ !wiz_objects);
+ "byte_executables",
+ String.concat " " byte_execs;
+ "byte_exec_objects",
+ String.concat " " (List.map
+ (fun m -> String.uncapitalize m ^ ".cmo")
+ byte_exec_modules);
+ "nat_executables",
+ String.concat " " nat_execs;
+ "nat_exec_objects",
+ String.concat " " (List.map
+ (fun m -> String.uncapitalize m ^ ".cmx")
+ nat_exec_modules);
+ "prereqs",
+ String.concat " " required_packages;
+ "ppopts",
+ if !wiz_enable_camlp4 then
+ "-syntax " ^ !wiz_camlp4_syntax ^
+ (String.concat " "
+ (List.map
+ (fun opt -> " -ppopt " ^ mkquote(Filename.quote opt))
+ (Fl_split.in_words_ws !wiz_camlp4_options)
+ ))
+ else
+ "";
+ "mtopts",
+ if List.mem "threads" !wiz_required_packages then "-thread" else "";
+ "default_target",
+ !wiz_make_default;
+ ] in
+
+ write "intro" variables;
+ write "def_general" variables;
+ if !wiz_byte_enable then write "def_byte_archive" variables;
+ if !wiz_nat_enable then write "def_native_archive" variables;
+ write "def_byte_exec" variables;
+ write "def_nat_exec" variables;
+ write "def_props" variables;
+ write "def_tools" variables;
+ write "rules" variables;
+ write "default_target" variables;
+ write "suffix_rules" variables;
+ write "generate" variables;
+ List.iter
+ (fun (execname, modlist) ->
+ let switches =
+ if is_byte_exec execname then
+ "-bytecode-filter"
+ else
+ "-native-filter" in
+ let deptargets =
+ String.concat " " (List.map
+ (fun m ->
+ let m' = String.uncapitalize m in
+ m' ^ ".ml " ^ m' ^ ".mli")
+ !modlist) in
+ write "makemake_exec" ( [ "switches", switches;
+ "execname", execname;
+ "deptargets", deptargets ] @ variables )
+ )
+ !wiz_exec_objects;
+ write "byte" variables;
+ write "opt" variables;
+ if !wiz_byte_enable then write "byte_archive" variables;
+ if !wiz_nat_enable then write "native_archive" variables;
+ List.iter
+ (fun (execname, modlist) ->
+ if is_byte_exec execname then begin
+ let execobjs =
+ String.concat " " (List.map
+ (fun m -> String.uncapitalize m ^ ".cmo")
+ !modlist) in
+ write "byte_exec" ( ["execname", execname;
+ "execobjs", execobjs ] @ variables )
+ end
+ )
+ !wiz_exec_objects;
+ List.iter
+ (fun (execname, modlist) ->
+ if not (is_byte_exec execname) then begin
+ let execobjs =
+ String.concat " " (List.map
+ (fun m -> String.uncapitalize m ^ ".cmx")
+ !modlist) in
+ write "nat_exec" ( ["execname", execname;
+ "execobjs", execobjs ] @ variables )
+ end
+ )
+ !wiz_exec_objects;
+ write "clean" variables;
+ write "install" variables;
+
+ if !wiz_local_makefile_name<> "" &&
+ Sys.file_exists !wiz_local_makefile_name then
+ begin
+ write "local" variables;
+ let f = open_in !wiz_local_makefile_name in
+ try
+ while true do
+ let s = input_line f in
+ Buffer.add_string b s;
+ Buffer.add_char b '\n';
+ done;
+ assert false
+ with
+ End_of_file ->
+ close_in f
+ end;
+
+ Buffer.contents b
+;;
+
+(**********************************************************************)
+(* GUI *)
+(**********************************************************************)
+
+let headline_font = "-*-helvetica-bold-r-normal-*-*-140-*-*-*-*-iso8859-1" ;;
+let font = "-*-helvetica-medium-r-normal-*-*-120-*-*-*-*-iso8859-1" ;;
+
+(**********************************************************************)
+
+let top = ref Widget.default_toplevel;;
+let topframe = ref Widget.dummy;;
+let screens = ref [];;
+let current_screen = ref 0;;
+
+let ( !! ) = fun x -> !(!x);;
+
+let add_screen func =
+ screens := !screens @ [ func ]
+;;
+
+let add_headline frame text =
+ let s1 = Frame.create ~height:15 frame in
+ let w = Label.create ~text ~font:headline_font ~anchor:`W frame in
+ let s2 = Frame.create ~height:10 frame in
+ pack [ s1 ];
+ pack ~anchor:`W [ w ];
+ pack [ s2 ]
+;;
+
+let add_para frame text =
+ let s1 = Frame.create ~height:5 frame in
+ let w = Message.create ~padx:0 ~text ~font ~anchor:`W ~width:(pixels (`Pt 400.0)) frame in
+ let s2 = Frame.create ~height:5 frame in
+ pack [ s1 ];
+ pack ~anchor:`W [ w ];
+ pack [ s2 ]
+;;
+
+
+let dialog ~parent ~title ~message ~buttons ?(default = (-1)) () =
+ (* Like Dialog.create, but our own style. *)
+ let popup = Toplevel.create parent in
+ Wm.title_set popup title;
+ Wm.transient_set popup ~master:(Winfo.toplevel parent);
+ add_headline popup title;
+ add_para popup message;
+ let f_buttons = Frame.create popup in
+ let n = ref 0 in
+ let r = ref (-1) in
+ List.iter
+ (fun text ->
+ let k = !n in
+ let b =
+ Button.create ~font ~text ~command:(fun () -> r := k; destroy popup)
+ f_buttons in
+ (* --- Default buttons not yet supported because of deficiency in
+ * labltk:
+ if k = default then Button.configure ~default:`Active b;
+ *)
+ pack ~side:`Left [b];
+ incr n;
+ )
+ buttons;
+ pack [f_buttons];
+ Grab.set popup;
+ Tkwait.window popup;
+ !r
+;;
+
+
+let ask_and_save frame =
+ let reply =
+ dialog ~parent:frame ~title:"Save .make-wizard?"
+ ~message:"Do you want to save the current state in the file .make-wizard?"
+ ~buttons:["Yes"; "No"; "Cancel"]
+ ~default:0
+ ()
+ in
+ if reply = 0 then save();
+ reply < 2
+;;
+
+
+let string_tv ?(onchange = fun () -> ()) frame v =
+ let textvariable = Textvariable.create ~on:frame () in
+ Textvariable.set textvariable !v;
+ let rec set_handle() =
+ Textvariable.handle textvariable
+ ~callback:(fun () ->
+ v := Textvariable.get textvariable;
+ onchange();
+ set_handle());
+ in
+ set_handle();
+ textvariable
+;;
+
+
+let bool_tv ?(onchange = fun () -> ()) frame v =
+ let textvariable = Textvariable.create ~on:frame () in
+ Textvariable.set textvariable (if !v then "1" else "0");
+ let rec set_handle() =
+ Textvariable.handle textvariable
+ ~callback:(fun () ->
+ v := Textvariable.get textvariable = "1";
+ onchange();
+ set_handle());
+ in
+ set_handle();
+ textvariable
+;;
+
+
+let label_box frame box =
+ let sub = Frame.create frame in
+ let row = ref 0 in
+ List.iter
+ (fun (l, v) ->
+ let label = Label.create ~font ~text:l ~anchor:`E sub in
+ let textvariable = string_tv frame v in
+ let var = Entry.create ~font ~textvariable ~width:40 sub in
+ grid ~row:!row ~column:0 ~sticky:"e" [ label ];
+ grid ~row:!row ~column:1 ~sticky:"w" [ var ];
+ incr row;
+ )
+ box;
+ pack ~anchor:`W [ sub ]
+;;
+
+
+let scrolled_listbox ?(click = fun _ _ -> ()) ?(context = fun _ _ -> ())
+ ?(separator = true) ?(height = 8) frame =
+ let f = Frame.create frame in
+ let lb = Listbox.create ~selectmode:`Multiple ~width:20 ~height
+ ~exportselection:false f in
+ let sb = Scrollbar.create ~orient:`Vertical
+ ~command:(Listbox.yview lb)
+ f in
+ Listbox.configure ~yscrollcommand:(Scrollbar.set sb) ~font lb;
+ let sep = Frame.create ~width:30 f in
+ pack ~side:`Left [ lb ];
+ pack ~side:`Left ~fill:`Y [ sb ];
+ if separator then pack ~side:`Left [ sep ];
+
+ bind ~events:[ `ButtonPressDetail 1 ] ~fields:[ `MouseY ]
+ ~action:(fun einfo ->
+ let `Num row = Listbox.nearest lb ~y:(einfo.Tk.ev_MouseY) in
+ Timer.set ~ms:0 ~callback:(fun () -> click lb row)
+ )
+ lb;
+ bind ~events:[ `ButtonPressDetail 3 ] ~fields:[ `MouseY ]
+ ~action:(fun einfo ->
+ let `Num row = Listbox.nearest lb ~y:(einfo.Tk.ev_MouseY) in
+ Timer.set ~ms:0 ~callback:(fun () -> context lb row)
+ )
+ lb;
+
+ (f, lb)
+;;
+
+
+let listbox_select lb selection =
+ Listbox.selection_clear lb ~first:(`Num 0) ~last:`End;
+ for i = 0 to Listbox.size lb do
+ let s = Listbox.get lb (`Num i) in
+ if List.mem s selection then
+ Listbox.selection_set lb ~first:(`Num i) ~last:(`Num i)
+ done
+;;
+
+
+let listbox_get_selection lb =
+ List.map
+ (fun index -> Listbox.get lb ~index)
+ (Listbox.curselection lb)
+;;
+
+
+let indented_cond_frame frame enablers =
+ (* Returns a subframe of [frame] that is only mapped if the boolean
+ * variable [!enable] is true. [enable_text] is the text for the
+ * checkbox that toggles [!enable].
+ *)
+ let onchange_enable = ref (fun () -> ()) in
+
+ List.iter
+ (fun (enable, enable_text) ->
+ let enable_tv = bool_tv
+ ~onchange:(fun () -> !onchange_enable())
+ frame enable in
+ let cb = Checkbutton.create
+ ~font ~text:enable_text ~variable:enable_tv frame in
+ pack ~anchor:`W [cb];
+ )
+ enablers;
+
+ let is_enabled() =
+ let p = ref false in
+ List.iter (fun (enable, _) -> p := !p || !enable) enablers;
+ !p
+ in
+
+ let frame' = Frame.create frame in
+ let indent = Frame.create ~width:30 frame' in
+ let frame'' = Frame.create frame' in
+ pack ~anchor:`W [frame'];
+
+ let frame''_is_packed = ref false in
+ let frame''_pack b =
+ if b <> !frame''_is_packed then begin
+ if b then
+ pack ~side:`Left [indent; frame'']
+ else
+ Pack.forget [ frame'' ];
+ frame''_is_packed := b
+ end
+ in
+ frame''_pack (is_enabled());
+ onchange_enable := (fun () -> frame''_pack (is_enabled()));
+ frame''
+;;
+
+
+let double_listbox frame available objects scan =
+ let boxes = Frame.create frame in
+ let (f_left,lb_left) = scrolled_listbox boxes in
+ let (f_right,lb_right) = scrolled_listbox ~separator:false boxes in
+ let f_buttons = Frame.create boxes in
+ let b_add = Button.create ~font ~text:"Add >>" f_buttons in
+ let b_del = Button.create ~font ~text:"<< Del" f_buttons in
+ let b_up = Button.create ~font ~text:"Up ^" f_buttons in
+ let b_down= Button.create ~font ~text:"Down v" f_buttons in
+ let b_scan= Button.create ~font ~text:"Rescan" f_buttons in
+ let f_sep = Frame.create ~width:30 boxes in
+ pack ~fill:`X [ b_add; b_del; b_up; b_down; b_scan ];
+ pack ~side:`Left [ coe f_left; coe f_buttons; coe f_sep; coe f_right ];
+ pack [ boxes ];
+
+ let update() =
+ let still_available = (* available - objects *)
+ List.filter (fun m -> not (List.mem m !!objects)) !!available in
+ Listbox.delete lb_left ~first:(`Num 0) ~last:`End;
+ Listbox.insert lb_left ~index:`End ~texts:still_available;
+ Listbox.delete lb_right ~first:(`Num 0) ~last:`End;
+ Listbox.insert lb_right ~index:`End ~texts:!!objects;
+ in
+
+ let rescan() =
+ !available := scan();
+ update()
+ in
+
+ let add() =
+ if Listbox.curselection lb_left = [] then begin
+ let popup = Toplevel.create frame in
+ Wm.title_set popup "Add File";
+ Wm.transient_set popup ~master:(Winfo.toplevel frame);
+ add_headline popup "Add File";
+ add_para popup "Enter the name of the module to add. Note that you can also select the modules in the left box and press 'Add' to quickly move the modules to the right box.";
+
+ let modname = ref "" in
+ label_box popup [ "Name of new module: ", modname ];
+
+ let p_buttons = Frame.create popup in
+ let b_ok = Button.create ~font ~text:"OK"
+ ~command:(fun () ->
+ if !modname <> "" then
+ !objects := !!objects @ [ !modname ];
+ update();
+ destroy popup) p_buttons in
+ let b_cancel = Button.create ~font ~text:"Cancel"
+ ~command:(fun () -> destroy popup) p_buttons in
+ pack ~side:`Left [b_ok; b_cancel];
+
+ add_para popup "";
+
+ pack [p_buttons];
+ end
+ else begin
+ let items =
+ List.map
+ (fun index -> Listbox.get lb_left ~index)
+ (Listbox.curselection lb_left)
+ in
+ !objects := !!objects @ items;
+ update()
+ end
+ in
+
+ let del() =
+ if Listbox.curselection lb_right = [] then begin
+ ignore
+ (dialog
+ ~parent:!top
+ ~title:"Nothing selected"
+ ~message:"Please select the modules you want to delete in the right box!"
+ ~buttons:[ "OK" ]
+ ~default:0
+ ())
+ end
+ else begin
+ let items =
+ List.map
+ (fun index -> Listbox.get lb_right ~index)
+ (Listbox.curselection lb_right)
+ in
+ !objects := List.filter (fun m -> not (List.mem m items)) !!objects;
+ update()
+ end
+ in
+
+ let move_dlg() =
+ ignore
+ (dialog
+ ~parent:!top
+ ~title:"Bad Selection"
+ ~message:"Please select the (single) module you want to move in the right box!"
+ ~buttons:[ "OK" ]
+ ~default:0
+ ())
+ in
+
+ let move g () =
+ if List.length (Listbox.curselection lb_right) <> 1 then
+ move_dlg()
+ else begin
+ let index = List.hd (Listbox.curselection lb_right) in
+ let `Num n = index in
+ let n' = g n in
+ if n' >= 0 && n' < List.length !!objects then begin
+ let item = Listbox.get lb_right ~index:(index :> Tk.listbox_index) in
+ !objects := delete_at n !!objects;
+ !objects := insert_at n' item !!objects;
+ update();
+ Listbox.selection_set lb_right ~first:(`Num n') ~last:(`Num n');
+ end
+ end
+ in
+
+ if !!available = [] then rescan() else update();
+ Button.configure ~command:add b_add;
+ Button.configure ~command:del b_del;
+ Button.configure ~command:(move pred) b_up;
+ Button.configure ~command:(move succ) b_down;
+ Button.configure ~command:rescan b_scan;
+
+ (* Returns the [update] function *)
+ update
+;;
+
+
+let redraw() =
+ destroy !topframe;
+ let f = Frame.create !top in
+ let f1 = Frame.create ~width:5 f in
+ let f2 = Frame.create f in
+ let f3 = Frame.create ~width:5 f in
+ pack ~expand:true ~fill:`Y [f];
+ pack ~side:`Left [f1];
+ pack ~side:`Left ~fill:`Y [f2];
+ pack ~side:`Left [f3];
+ let func = List.nth !screens !current_screen in
+ topframe := coe f;
+ func f2
+;;
+
+
+let footer frame =
+ let box = Frame.create frame in
+ pack ~side:`Bottom ~fill:`X [box];
+ let sep1 = Frame.create ~height:15 box in
+ let b = Frame.create ~height:1 ~background:`Black box in
+ let sep2 = Frame.create ~height:15 box in
+ pack [ sep1 ];
+ pack ~fill:`X ~expand:true [b];
+ pack [ sep2 ];
+
+ let f = Frame.create box in
+ let m1 = Frame.create f in
+ pack ~fill:`X ~expand:true ~side:`Left [ m1 ];
+ let prev_b =
+ Button.create ~font ~text:"Previous" ~state:`Disabled
+ ~command:(fun () -> decr current_screen; redraw()) m1 in
+ pack ~side:`Left [prev_b];
+ if !current_screen > 0 then
+ Button.configure ~state:`Normal prev_b;
+ let m2 = Frame.create f in
+ let k = ref 0 in
+ List.iter
+ (fun scr ->
+ let k' = !k in
+ let b =
+ Button.create ~font ~text:(string_of_int (!k+1))
+ ~command:(fun () -> current_screen := k'; redraw()) m2 in
+ if k' = !current_screen then
+ Button.configure
+ ~background:`Blue ~activebackground:`Blue ~foreground:`White b;
+ pack ~side:`Left [b];
+ incr k
+ )
+ !screens;
+ pack ~side:`Left [m2];
+ let m3 = Frame.create f in
+ pack ~fill:`X ~expand:true ~side:`Left [ m3 ];
+ let next_b =
+ Button.create ~font ~text:"Next" ~state:`Disabled
+ ~command:(fun () -> incr current_screen; redraw()) m3 in
+ pack ~side:`Right [next_b];
+ if !current_screen < List.length !screens - 1 then
+ Button.configure ~state:`Normal next_b;
+ pack ~fill:`X [ f ]
+;;
+
+
+(**********************************************************************)
+
+let first_time = ref true;;
+
+let intro_screen frame =
+ add_headline frame "The Makefile and META wizard";
+ add_para frame "This wizard helps you creating Makefiles and META \
+files for simple projects. It assumes that all your source files \
+reside in a single directory, and that all source files are OCaml \
+files (no support for mixed OCaml/C projects). ocamllex, ocamlyacc, \
+and camlp4 are supported.";
+ add_para frame "The wizard generates a Makefile, and the Makefile \
+produces the META file. The Makefile is not perfect, and is not the ideal \
+choice for everybody, but it is a starting point for your project. \
+You can later fine-tune the contents of the Makefile by adding your own rules, \
+and by overriding the definitions. The Makefile is commented, and not \
+overly complicated.";
+ add_para frame "The settings you enter here can be stored in a file \
+containing the state of the wizard. This file is called .make-wizard. \
+It is recommended to use this feature to save the state between the \
+wizard sessions.";
+ (* "" *)
+
+ footer frame;
+ update();
+
+ if !first_time && Sys.file_exists ".make-wizard" then begin
+ match dialog ~parent:frame ~title:"Load .make-wizard?"
+ ~message:"Do you want to load the file .make-wizard, and continue your last session?"
+ ~buttons:[ "Yes, please load the file"; "No, start with empty fields" ]
+ ~default:0
+ ()
+ with
+ 0 -> load()
+ | _ -> ()
+ end;
+ first_time := false;
+
+;;
+
+
+add_screen intro_screen;;
+
+(**********************************************************************)
+
+let general_screen frame =
+ add_headline frame "General";
+ add_para frame "Please enter the name of the package, the version number, \
+and the description first. The name must be a single, alphanumeric string \
+(including _ and -). The version is an arbitrary string, like the description. \
+All fields are mandatory."; (* "" *)
+
+ label_box frame
+ [ "Package name: ", wiz_package_name;
+ "Package version: ", wiz_package_version;
+ "Package description: ", wiz_package_description ];
+ footer frame
+;;
+
+add_screen general_screen;;
+
+(**********************************************************************)
+
+let pkginfo lb row = (* when the user right-clicks at a listbox row *)
+ let pkg = Listbox.get lb (`Num row) in
+ let version =
+ try Findlib.package_property [] pkg "version" with Not_found -> "N/A" in
+ let description =
+ try Findlib.package_property [] pkg "description" with Not_found -> "N/A"
+ in
+ let popup = Toplevel.create !top in
+ Wm.transient_set popup ~master:(Winfo.toplevel !top);
+ let f = Frame.create popup in
+ let title = "About " ^ pkg ^ " (" ^ version ^ ")" in
+ add_headline f title;
+ Wm.title_set popup title;
+ add_para f ("Description: " ^ description);
+ add_para f "Modules:";
+ let click sublb _ =
+ Listbox.selection_clear sublb ~first:(`Num 0) ~last:`End in
+ let (f_sublb, sublb) = scrolled_listbox ~click f in
+ let modules =
+ try
+ Fl_split.in_words
+ (Findlib.package_property [] pkg "browse_interfaces")
+ with
+ Not_found ->
+ let dir = Findlib.package_directory pkg in
+ let files = Array.to_list(Sys.readdir dir) in
+ List.map
+ (fun name ->
+ String.capitalize (Filename.chop_suffix name ".cmi"))
+ (List.filter
+ (fun name ->
+ Filename.check_suffix name ".cmi")
+ files
+ )
+ in
+ Listbox.insert sublb ~index:`End ~texts:modules;
+ pack ~anchor:`W [ f_sublb ];
+ pack ~anchor:`W [ f ];
+ let close = Button.create ~text:"Close" ~font
+ ~command:(fun () -> destroy popup) f_sublb in
+ pack ~anchor:`Nw ~fill:`X [close]
+;;
+
+(**********************************************************************)
+
+let preprocessor_scan_extensions() =
+ (* Find out all packages with a "preprocessor" predicate *)
+ let packages = Fl_package_base.list_packages() in
+ let plist =
+ List.filter
+ (fun pkg ->
+ try
+ let _ =
+ Findlib.package_property [ "preprocessor"; "syntax" ] pkg "archive"
+ in true
+ with
+ Not_found -> false
+ )
+ packages in
+ (* Add all selected extensions, if they do not occur yet: *)
+ let plist' =
+ List.filter
+ (fun pkg ->
+ not (List.mem pkg plist)
+ )
+ !wiz_camlp4_selected in
+ List.sort Pervasives.compare (plist @ plist')
+;;
+
+
+let preprocessor_screen frame =
+ add_headline frame "Preprocessing";
+ add_para frame "Here you can specify whether your source files are \
+preprocessed by camlp4. Simply skip this page if you do not want to \
+invoke a preprocessor, or if you don't know what this means."; (* "" *)
+
+ let frame'' = indented_cond_frame frame
+ [ wiz_enable_camlp4, "Enable camlp4" ] in
+
+ let tv = string_tv frame'' wiz_camlp4_syntax in
+ let rb_o = Radiobutton.create
+ ~font ~text:"Standard syntax" ~variable:tv ~value:"camlp4o"
+ frame'' in
+ let rb_r = Radiobutton.create
+ ~font ~text:"Revised syntax" ~variable:tv ~value:"camlp4r"
+ frame'' in
+ pack ~anchor:`W [rb_o; rb_r];
+
+ add_para frame'' "Use the following packaged syntax extensions (click the \
+right mouse button to find out more about a package):"; (* "" *)
+
+ if !wiz_camlp4_extensions = [] then
+ wiz_camlp4_extensions := preprocessor_scan_extensions();
+
+ let click lb row = (* when the user clicks at a listbox row *)
+ wiz_camlp4_selected := listbox_get_selection lb;
+ in
+
+ let (f_lb,lb) = scrolled_listbox ~click ~context:pkginfo frame'' in
+ Listbox.insert lb ~index:`End ~texts:!wiz_camlp4_extensions;
+ listbox_select lb !wiz_camlp4_selected;
+ pack ~anchor:`W [f_lb];
+
+ let rescan = Button.create ~text:"Rescan" ~font
+ ~command:(fun () ->
+ wiz_camlp4_extensions := preprocessor_scan_extensions();
+ Listbox.delete lb ~first:(`Num 0) ~last:`End;
+ Listbox.insert lb ~index:`End ~texts:!wiz_camlp4_extensions;
+ listbox_select lb !wiz_camlp4_selected;
+ )
+ f_lb in
+ let clear = Button.create ~text:"Clear" ~font
+ ~command:(fun () ->
+ wiz_camlp4_selected := [];
+ listbox_select lb [])
+ f_lb in
+
+ pack ~anchor:`Nw ~fill:`X [ rescan; clear ];
+
+ add_para frame'' "Specify here further options to the camlp4 invocation. \
+For example, you can load camlp4 modules like pa_ifdef.cmo, and pass the -D \
+options to it."; (* "" *)
+
+ label_box frame'' [ "Camlp4 options: ", wiz_camlp4_options ];
+
+ footer frame
+;;
+
+add_screen preprocessor_screen;;
+
+(**********************************************************************)
+
+let prerequisites_scan_packages() =
+ (* Find out all packages *)
+ List.sort Pervasives.compare (Fl_package_base.list_packages())
+;;
+
+
+let prerequisites_screen frame =
+ add_headline frame "Prerequisites";
+ add_para frame "If your modules use packages, you can specify these \
+prerequisites here. It is sufficient to select the packages on which \
+your modules depend directly. Indirect dependencies can be resolved \
+by findlib automatically. Click the right mouse button to find out \
+more about a package."; (* "" *)
+
+ if !wiz_all_packages = [] then
+ wiz_all_packages := prerequisites_scan_packages();
+
+ let click lb row = (* when the user clicks at a listbox row *)
+ wiz_required_packages := listbox_get_selection lb;
+ in
+
+ let (f_lb,lb) = scrolled_listbox ~height:18 ~click ~context:pkginfo frame in
+ Listbox.insert lb ~index:`End ~texts:!wiz_all_packages;
+ listbox_select lb !wiz_required_packages;
+ pack ~anchor:`W [f_lb];
+
+ let rescan = Button.create ~text:"Rescan" ~font
+ ~command:(fun () ->
+ wiz_all_packages := prerequisites_scan_packages();
+ Listbox.delete lb ~first:(`Num 0) ~last:`End;
+ Listbox.insert lb ~index:`End ~texts:!wiz_all_packages;
+ listbox_select lb !wiz_required_packages;
+ )
+ f_lb in
+ let clear = Button.create ~text:"Clear" ~font
+ ~command:(fun () ->
+ wiz_required_packages := [];
+ listbox_select lb [])
+ f_lb in
+
+ pack ~anchor:`Nw ~fill:`X [ rescan; clear ];
+
+ footer frame
+;;
+
+add_screen prerequisites_screen;;
+
+(**********************************************************************)
+
+let buildlib_scan_modules() =
+ let files = Array.to_list(Sys.readdir ".") in
+ let suffixes = Fl_split.in_words_ws !wiz_source_suffixes in
+ let files' =
+ List.filter
+ (fun f ->
+ List.exists (Filename.check_suffix f) suffixes
+ )
+ files in
+ let files'' =
+ List.map
+ (fun f ->
+ String.capitalize (Filename.chop_extension f)
+ )
+ files' in
+ remove_dups (List.sort Pervasives.compare files'')
+;;
+
+
+let buildlib_screen frame =
+ add_headline frame "Build Library";
+ add_para frame "The next question is how to build the library, i.e. the \
+cma or cmxa archive. It is recommended to create such an archive even if \
+the real target of the build process is an executable, because you can load \
+it into the toploop at once. However, make sure that you do not put the \
+main program of the executable into the archive, as it is usually stripped \
+off from the executable, and nothing would happen when you start it.";
+(*
+ add_para frame "You can select whether you want to create only a bytecode \
+archive, a native archive, or both. In the latter case, the simplest way \
+is to begin with the bytecode archive, and to copy your specification to \
+the native box by pressing the button \"Like bytecode\".";
+ add_para frame "If you do not want to create an archive at all, \
+skip this page.";
+*)
+(* "" *)
+
+ let frame' = indented_cond_frame frame
+ [ wiz_byte_enable, "Enable bytecode archive";
+ wiz_nat_enable, "Enable native archive"; ] in
+ add_para frame' "Move the available modules to the right-hand box in the required order.";
+
+ let update =
+ double_listbox frame' (ref wiz_available) (ref wiz_objects) buildlib_scan_modules in
+
+ add_para frame "By default, only the suffixes .ml, .mli, .mll, and .mly are used to recognize source code files. You can add here additional suffixes (this requires that you extend the Makefile by your own rules).";
+
+ label_box frame [ "Source code suffixes: ", wiz_source_suffixes ];
+
+ footer frame
+;;
+
+add_screen buildlib_screen;;
+
+(**********************************************************************)
+
+let enter_name parent followup =
+ let popup = Toplevel.create parent in
+ let title = "New Executable" in
+ Wm.transient_set popup ~master:(Winfo.toplevel parent);
+ Wm.title_set popup title;
+ let frame = Frame.create popup in
+ pack [frame];
+ add_headline frame title;
+ add_para frame "Of course, the new executable must have a name.";
+ let name = ref "" in
+ label_box frame [ "Name: ", name ];
+ pack [ Frame.create ~height:10 frame ];
+ let buttons = Frame.create frame in
+ let ok_b = Button.create ~font ~text:"OK"
+ ~command:(fun () -> destroy popup; followup !name) buttons in
+ let cancel_b = Button.create ~font ~text:"Cancel"
+ ~command:(fun () -> destroy popup) buttons in
+ pack ~side:`Left [ ok_b; cancel_b ];
+ pack [buttons]
+;;
+
+
+let buildexec_screen frame =
+ add_headline frame "Build Executables";
+ add_para frame "You can specify the executables to build in the following \
+way. Press \"New\" and enter the name of the excutable, then add the modules \
+to link in the box that appears. The cma/cmxa archive from the previous \
+screen is linked anyway, so its modules cannot be selected again.";
+ add_para frame "Leave the list of executables empty if you do not want to \
+build any.";
+ (* "" *)
+
+ let update_listbox = ref (fun () -> ()) in
+ let show = ref (fun _ -> ()) in
+ let hide = ref (fun _ -> ()) in
+
+ let click lb row =
+ let name = Listbox.get lb ~index:(`Num row) in
+ !show name
+ in
+
+ let newexec() =
+ enter_name
+ frame
+ (fun name ->
+ (* This function is called after the user pressed "OK" *)
+ if List.mem name !wiz_executables then begin
+ (* It is not allowed to enter the same name twice *)
+ ignore(
+ dialog ~parent:frame ~title:"Already exists"
+ ~message:"This name already exists!" ~buttons:["OK"] ())
+ end
+ else begin
+ wiz_executables :=
+ List.sort Pervasives.compare (name :: !wiz_executables);
+ wiz_exec_objects := (name, ref []) :: !wiz_exec_objects;
+ wiz_exec_native := (name, ref false) :: !wiz_exec_native;
+ !update_listbox();
+ !show name
+ end
+ )
+ in
+
+ let remexec lb () =
+ let sel = listbox_get_selection lb in
+ if sel = [] then begin
+ ignore(
+ dialog ~parent:frame ~title:"Nothing selected"
+ ~message:"Select the executable to remove first!" ~buttons:["OK"] ())
+ end
+ else begin
+ wiz_executables :=
+ List.filter (fun n -> not (List.mem n sel)) !wiz_executables;
+ wiz_exec_objects :=
+ List.filter (fun (n,_) -> not (List.mem n sel)) !wiz_exec_objects;
+ wiz_exec_native :=
+ List.filter (fun (n,_) -> not (List.mem n sel)) !wiz_exec_native;
+ !update_listbox();
+ !hide()
+ end
+ in
+
+ let (f_lb,lb) = scrolled_listbox ~click ~height:3 frame in
+ Listbox.configure ~selectmode:`Single lb;
+ Listbox.insert lb ~index:`End ~texts:!wiz_executables;
+ pack ~anchor:`W [f_lb];
+
+ let new_b =
+ Button.create ~font ~text:"New" ~command:newexec f_lb in
+ let remove_b =
+ Button.create ~font ~text:"Remove" ~command:(remexec lb) f_lb in
+
+ pack ~anchor:`Nw ~fill:`X [ new_b; remove_b ];
+
+ let f1 = Frame.create frame in
+ pack [f1];
+ let frame' = Frame.create f1 in
+ let frame'_packed = ref false in
+ let modbox_available = ref (ref []) in
+ let modbox_objects = ref (ref []) in
+ let modbox_scan() =
+ let mlist = buildlib_scan_modules() in
+ List.filter
+ (fun m -> not (List.mem m !wiz_objects)) mlist
+ in
+ add_para frame' "Move the available modules to the right-hand box in the required order.";
+ let update_modbox =
+ double_listbox frame' modbox_available modbox_objects modbox_scan in
+
+ add_para frame' "Select the type of the executable:";
+ let radio = Frame.create frame' in
+ let type_ref = ref false in
+ let type_ref_ref = ref type_ref in
+ let type_tv = bool_tv
+ ~onchange:(fun () -> !type_ref_ref := !type_ref)
+ frame' type_ref in
+ let byte_r = Radiobutton.create ~font ~text:"Bytecode executable"
+ ~variable:type_tv ~value:"0" radio in
+ let nat_r = Radiobutton.create ~font ~text:"Native executable"
+ ~variable:type_tv ~value:"1" radio in
+ pack ~side:`Left [byte_r; nat_r ];
+ pack ~anchor:`W [radio];
+ let update_radio() =
+ Textvariable.set type_tv (if !!type_ref_ref then "1" else "0")
+ in
+
+ footer frame;
+
+ update_listbox := (fun () ->
+ Listbox.delete lb ~first:(`Num 0) ~last:`End;
+ Listbox.insert lb ~index:`End ~texts:!wiz_executables;
+ );
+ show := (fun name ->
+ let k = find_pos name !wiz_executables in
+ Listbox.selection_clear lb ~first:( `Num 0 ) ~last:`End;
+ Listbox.selection_set lb ~first:(`Num k) ~last:(`Num k);
+ if not !frame'_packed then (
+ pack [frame'];
+ frame'_packed := true;
+ );
+ modbox_objects := List.assoc name !wiz_exec_objects;
+ type_ref_ref := List.assoc name !wiz_exec_native;
+ update_modbox();
+ update_radio()
+ );
+ hide := (fun () ->
+ if !frame'_packed then (
+ Pack.forget [frame'];
+ frame'_packed := false;
+ );
+ )
+;;
+
+add_screen buildexec_screen;;
+
+(**********************************************************************)
+
+let generate_screen frame =
+ add_headline frame "Generate Makefile";
+ add_para frame "Finally, the Makefile can be generated from your inputs. \
+You can set the name of the Makefile to a non-standard name. Furthermore, \
+you can specify a second file that will be appended to the generated Makefile, \
+this is useful to extend the Makefile rules by your own additions.";
+ (* "" *)
+
+ label_box frame [ "Name of Makefile: ", wiz_makefile_name;
+ "Local extensions in: ", wiz_local_makefile_name ;
+ "Default target of 'make': ", wiz_make_default;
+ ];
+
+ add_para frame "";
+
+ let show_b =
+ Button.create ~font ~text:"Show Makefile"
+ ~command:(fun () ->
+ let maketext = makemake() in
+ let popup = Toplevel.create frame in
+ Wm.title_set popup "Generated Makefile";
+ add_headline popup "Generated Makefile";
+ let t = Text.create ~width:80 ~height:25 popup in
+ pack [t];
+ Text.insert ~index:(`End,[]) ~text:maketext t;
+ )
+ frame in
+ let save_b =
+ Button.create ~font ~text:"Save Makefile"
+ ~command:(fun () ->
+ let maketext = makemake() in
+ let cont =
+ not (Sys.file_exists !wiz_makefile_name) || (
+ dialog ~parent:frame ~title:"File already exists"
+ ~message:("The file " ^ !wiz_makefile_name ^
+ " already exists. Overwrite?")
+ ~buttons:[ "OK"; "Cancel" ] () = 0) in
+ if cont then begin
+ let f = open_out !wiz_makefile_name in
+ output_string f maketext;
+ close_out f
+ end
+ )
+ frame in
+
+ pack [show_b; save_b];
+
+ add_headline frame "Quit";
+
+ add_para frame "The following button quits the wizard. You are asked whether you want to save the state first.";
+
+ let quit_b =
+ Button.create ~font ~text:"Finish & Quit"
+ ~command:(fun () ->
+ if ask_and_save frame then destroy !top)
+ frame in
+
+
+
+ pack [show_b; quit_b];
+
+ footer frame
+;;
+
+add_screen generate_screen;;
+
+
+(**********************************************************************)
+
+Findlib.init();
+top := openTk();
+(* current_screen := 5; *)
+Wm.title_set !top "findlib/make-wizard";
+Wm.protocol_set !top ~name:"WM_DELETE_WINDOW"
+ ~command:(fun () -> if ask_and_save !top then destroy !top);
+Toplevel.configure ~width:(pixels(`Pt 450.0))
+ ~height:(pixels (`Pt 650.0)) (Winfo.toplevel !top);
+Pack.propagate_set !top false;
+topframe := coe(Frame.create !top);
+redraw();
+mainLoop();;
+
+
+(* ======================================================================
+ * History:
+ *
+ * $Log: make_wizard.ml,v $
+ * Revision 1.3 2002/09/22 20:12:35 gerd
+ * Renamed modules (prefix fl_)
+ *
+ * Revision 1.2 2002/07/29 19:52:23 gerd
+ * Fixes for OCaml 3.05
+ *
+ * Revision 1.1 2002/05/26 14:09:07 gerd
+ * Renaming
+ *
+ * Revision 1.1 2002/05/05 20:40:26 gerd
+ * Initial revision
+ *
+ *
+ *)
diff --git a/local-packages/ocamlfind/src/findlib-toolbox/make_wizard.pattern b/local-packages/ocamlfind/src/findlib-toolbox/make_wizard.pattern
new file mode 100644
index 0000000..90116e9
--- /dev/null
+++ b/local-packages/ocamlfind/src/findlib-toolbox/make_wizard.pattern
@@ -0,0 +1,494 @@
+## $Id$
+## ----------------------------------------------------------------------
+##
+
+## This is the pattern for the Makefile. It consists of several sections,
+## every section begins with [name] on a single line, and ends where the
+## next section starts. Inside the sections, variables are written as
+## [name], too.
+## Comments that must not be copied to the output file begin with two
+## hash marks.
+
+[intro]
+# ----------------------------------------------------------------------
+# How to build the package [name]:
+# ----------------------------------------------------------------------
+#
+# make: Same as "make all"
+# make all: Normally "make byte", but can also be set to "make opt"
+# make byte: Makes the bytecode archive and the bytecode executables
+# make opt: Makes the native archive and the native executable
+# make install: Install all installable files as package
+# make uninstall: Uninstall the package
+# make clean: Delete all files that can be remade
+#
+# The usual order of invocation is:
+# - make byte
+# - (optionally) make opt
+# - make install
+# - make clean
+#
+# You may want to give the -s option if you do not want to see the details
+# of the build process (e.g. make -s all).
+#
+# ----------------------------------------------------------------------
+# Important for developers
+# ----------------------------------------------------------------------
+#
+# This Makefile writes a copy of itself with appended dependencies.
+# The copy is usually stored in the file .make-wizard.[makefile_name].
+# If you want to invoke "make" for targets where the dependencies are
+# involved, you have to specify -f .make-wizard.[makefile_name] on
+# the command line, e.g.
+#
+# make -f .make-wizard.[makefile_name] sample.cmo
+#
+# Otherwise, the dependencies are ignored, and you get errors that are
+# hard to explain.
+#
+# If you want to modify this Makefile, it is a good idea to put the
+# modifications into a second file, and to enable the local Makefile
+# extension in the wizard. This effects that the modifications are appended
+# to this Makefile, so you can add rules and override variables without
+# coming into conflict with the wizard.
+
+[def_general]
+# ----------------------------------------------------------------------
+# Definitions
+# ----------------------------------------------------------------------
+
+NAME = [name]
+# The name of the package.
+
+MFNAME = [makefile_name]
+# The name of this Makefile. (You must change this definition if you rename
+# the Makefile!)
+
+MF2NAME = .make-wizard.$(MFNAME)
+# The name of the generated Makefile (a copy of this Makefile plus the
+# dependencies)
+
+TEMPNAME = .make-wizard.temps
+# The name of a file containing the names of temporary files
+
+VERSION = [version]
+# The version of this package
+
+DESCRIPTION = [description]
+# The description of this package
+
+GENERATOR_EXTS = .mll .mly
+# These suffixes indicate that a generator must be called for them
+
+MAKE_META = _meta
+# Make the META file by this rule. (An empty definition turns META generation
+# off.)
+
+INSTALL = _findlib_install
+# Which rule to use for installation
+
+UNINSTALL = _findlib_uninstall
+# Which rule to use for deinstallation
+
+MAKEMAKE_HOOK =
+# Set this to the name of a rule to add your own definitions to $(MF2NAME)
+
+
+## The def_byte_archive section is only included if the byte archive is
+## enabled:
+
+[def_byte_archive]
+BYTE_ARCHIVE = $(NAME).cma
+# The name of the resulting bytecode archive.
+
+BYTE_OBJECTS = [byte_objects]
+# The cmo objects that are linked together, and are put into the byte archive.
+
+BYTE_FILES = $(BYTE_OBJECTS) $(BYTE_OBJECTS:.cmo=.cmi) $(BYTE_ARCHIVE)
+# The files that are generated in order to make the byte archive. Note
+# that .ml and .mli files are missing that are generated from
+# .mly and .mll files.
+
+BYTE_INST = $(BYTE_OBJECTS:cmo=cmi) $(BYTE_OBJECTS:.cmo=.mli) $(BYTE_ARCHIVE)
+# The files that will be installed after the byte archive is made. Not
+# every file exists.
+
+
+## The def_native_archive section is only included if the native archive is
+## enabled:
+
+[def_native_archive]
+NAT_ARCHIVE = $(NAME).cmxa
+# The name of the resulting native archive.
+
+NAT_OBJECTS = [nat_objects]
+# The cmx objects that are linked together, and are put into the native archive.
+
+NAT_FILES = $(NAT_OBJECTS) $(NAT_OBJECTS:.cmx=.o) $(NAT_OBJECTS:.cmo=.cmi) \
+ $(NAT_ARCHIVE) $(NAT_ARCHIVE:.cmxa=.a)
+# The files that are generated in order to make the native archive. Note
+# that .ml and .mli files are missing that are generated from
+# .mly and .mll files.
+
+NAT_INST = $(NAT_OBJECTS:.cmo=.cmi) $(NAT_OBJECTS:.cmo=.mli) $(NAT_ARCHIVE) \
+ $(NAT_ARCHIVE:.cmxa=.a)
+# The files that will be installed after the native archive is made. Not
+# every file exists.
+
+
+[def_byte_exec]
+BYTE_EXEC_TARGETS = [byte_executables]
+# The list of bytecode executables.
+
+BYTE_EXEC_OBJECTS = [byte_exec_objects]
+# The list of cmo modules that are linked into bytecode executables
+
+BYTE_EXEC_FILES = $(BYTE_EXEC_OBJECTS) $(BYTE_EXEC_OBJECTS:.cmo=.cmi) \
+ $(BYTE_EXEC_TARGETS)
+# The list of files that are generated in order to make the bytecode
+# executables. Note that .ml and .mli files are missing that are generated
+# from .mly and .mll files.
+
+BYTE_EXEC_INST = $(BYTE_EXEC_TARGETS)
+# The files to install as bytecode executables.
+
+
+[def_nat_exec]
+NAT_EXEC_TARGETS = [nat_executables]
+# The list of native executables.
+
+NAT_EXEC_OBJECTS = [nat_exec_objects]
+# The list of cmx modules that are linked into native executables
+
+NAT_EXEC_FILES = $(NAT_EXEC_OBJECTS) $(NAT_EXEC_OBJECTS:.cmx=.cmi) \
+ $(NAT_EXEC_OBJECTS:.cmx=.o) $(NAT_EXEC_TARGETS)
+# The list of files that are generated in order to make the native
+# executables. Note that .ml and .mli files are missing that are generated
+# from .mly and .mll files.
+
+NAT_EXEC_INST = $(NAT_EXEC_TARGETS)
+# The files to install as native executables.
+
+
+[def_props]
+PREREQUISITES = [prereqs]
+# The required packages.
+
+PPOPTS = [ppopts]
+# Preprocessor options.
+
+MTOPTS = [mtopts]
+# Multi-threading options
+
+INCOPTS =
+# -I options (currently unused, but this may change in the future)
+
+OTHER_INST = META
+# Files to install that are not mentioned in the other XXX_INST variables
+
+#TASKBYTELINKOPTS = -custom
+# Uncomment this line to create stand-alone executables
+
+[def_tools]
+# Tools and tasks: "Tools" are the commands to call, and "tasks" are the tools
+# to use for certain situations.
+
+OCAMLFIND = ocamlfind
+OCAMLLEX = ocamllex
+OCAMLYACC = ocamlyacc
+OCAMLDEP = $(OCAMLFIND) ocamldep
+OCAMLC = $(OCAMLFIND) ocamlc
+OCAMLCP = $(OCAMLFIND) ocamlcp
+OCAMLOPT = $(OCAMLFIND) ocamlopt
+#
+# These are the tools.
+
+TASKLEX = $(OCAMLLEX) $(TASKLEXOPTS)
+TASKYACC = $(OCAMLYACC) $(TASKYACCOPTS)
+TASKDEP = $(OCAMLDEP) $(INCOPTS) $(PPOPTS) -package "$(PREREQUISITES)" $(TASKDEPOPTS)
+TASKCI = $(OCAMLC) $(INCOPTS) $(PPOPTS) -package "$(PREREQUISITES)" -c $(TASKCIOPTS)
+TASKBYTECO = $(OCAMLC) $(INCOPTS) $(PPOPTS) $(MTOPTS) -package "$(PREREQUISITES)" -c -g $(TASKBYTECOOPTS)
+TASKBYTELINK = $(OCAMLC) $(INCOPTS) $(PPOPTS) $(MTOPTS) -package "$(PREREQUISITES)" -linkpkg $(TASKBYTELINKOPTS)
+TASKBYTEAR = $(OCAMLC) -a $(TASKBYTEAROPTS)
+TASKNATCO = $(OCAMLOPT) $(INCOPTS) $(PPOPTS) $(MTOPTS) -package "$(PREREQUISITES)" -c $(TASKNATCOOPTS)
+TASKNATLINK = $(OCAMLOPT) $(INCOPTS) $(PPOPTS) $(MTOPTS) -package "$(PREREQUISITES)" -linkpkg $(TASKNATLINKOPTS)
+TASKNATAR = $(OCAMLOPT) -a $(TASKNATAROPTS)
+TASKINSTALL = $(OCAMLFIND) install $(NAME) $(TASKINSTALLOPTS)
+TASKREMOVE = $(OCAMLFIND) remove $(NAME) $(TASKREMOVEOPTS)
+#
+# These are the tasks. The names mean the following:
+# TASKLEX: Used to create a lexer
+# TASKYACC: Used to create a parser
+# TASKDEP: Used to analyze the dependencies
+# TASKCI: Used to compile interface files
+# TASKBYTECO, TASKNATCO: Used to compile implementation files
+# TASKBYTELINK, TASKNATLINK: Used to create executables
+# TASKBYTEAR, TASKNATAR: Used to create archives
+# TASKINSTALL: Used to install the package
+# TASKREMOVE: Used to remove the package
+# INCOPTS: -I options
+# PPOPTS: Options to specify the preprocessor
+# MTOPTS: -thread (if necessary)
+# NATONLY: -native (if necessary)
+# For every task , there is a variable for task-specific options OPTS.
+
+
+[rules]
+# ----------------------------------------------------------------------
+# Rules
+# ----------------------------------------------------------------------
+
+
+[default_target]
+.PHONY: all
+all: [default_target]
+
+
+[suffix_rules]
+# The suffix rules: They specify how to make a file ending in suffix X from
+# a source file ending in suffix Y. For every suffix rule, there is a task
+# defining what to do.
+
+.SUFFIXES: .ml .mli .cmo .cmx .cmi .mll .mly
+
+.mli.cmi:
+ @echo ""
+ $(TASKCI) $<
+
+.ml.cmo:
+ @echo ""
+ $(TASKBYTECO) $<
+
+.ml.cmx:
+ @echo ""
+ $(TASKNATCO) $<
+
+# The generator rules record the generated files: The "grep" checks whether
+# the filename already occurs in $(TEMPNAME), and the "echo" appends the
+# filename when missing.
+
+.mll.ml:
+ @echo ""
+ $(TASKLEX) $<
+ touch $(TEMPNAME)
+ grep -F -x -q -e "$@" $(TEMPNAME) || echo "$@" >>$(TEMPNAME)
+
+.mly.ml:
+ @echo ""
+ $(TASKYACC) $<
+ touch $(TEMPNAME)
+ grep -F -x -q -e "$@" $(TEMPNAME) || echo "$@" >>$(TEMPNAME)
+
+# The _dummy rule does nothing:
+
+_dummy:
+ :
+
+[generate]
+# The following rule checks which lex and yacc targets exist, and calls
+# MAKE recursively.
+
+.PHONY: _meta
+_meta:
+ @echo ""
+ echo "name = \"$(NAME)\"" >META
+ echo "version = \"$(VERSION)\"" >>META
+ echo "description = \"$(DESCRIPTION)\"" >>META
+ echo "requires = \"$(PREREQUISITES)\"" >>META
+ test -z "$(BYTE_ARCHIVE)" || \
+ echo "archive(byte) = \"$(BYTE_ARCHIVE)\"" >>META
+ test -z "$(NAT_ARCHIVE)" || \
+ echo "archive(native) = \"$(NAT_ARCHIVE)\"" >>META
+
+.PHONY: _generator
+_generator: $(MAKE_META)
+ @echo ""
+ targets=$$( \
+ { \
+ for obj in _dummy $(BYTE_OBJECTS) $(BYTE_EXEC_OBJECTS); do \
+ test "_dummy" != "$$obj" || continue; \
+ for ext in $(GENERATOR_EXTS); do \
+ if [ -f "$${obj%.cmo}$$ext" ]; then \
+ echo "$${obj%.cmo}.ml"; \
+ fi; \
+ done; \
+ done && \
+ for obj in _dummy $(NAT_OBJECTS) $(NAT_EXEC_OBJECTS); do \
+ test "_dummy" != "$$obj" || continue; \
+ for ext in $(GENERATOR_EXTS); do \
+ if [ -f "$${obj%.cmx}$$ext" ]; then \
+ echo "$${obj%.cmx}.ml"; \
+ fi; \
+ done; \
+ done; \
+ } | sort | uniq \
+ ) && \
+ { test -z "$$targets" || $(MAKE) -f $(MFNAME) $$targets; }
+
+# The following rule calls ocamldep for the right files, and creates
+# a file that consists of the contents of this Makefile, and of the output
+# of ocamldep.
+
+.PHONY: _makemake
+_makemake: _generator
+ @echo ""
+ cat $(MFNAME) >$(MF2NAME)
+ test -z "$(MAKEMAKE_HOOK)" || $(MAKE) -f $(MFNAME) $(MAKEMAKE_HOOK)
+ echo "# ---------------------------------------- dependencies:" >>$(MF2NAME)
+ targets=$$( \
+ { \
+ nat=-native-filter && \
+ byte=-bytecode-filter && \
+ for obj in _dummy $(BYTE_OBJECTS); do \
+ test "_dummy" != "$$obj" || continue; \
+ echo "$${obj%.cmo}.ml"; \
+ echo "$${obj%.cmo}.mli"; \
+ nat=""; \
+ done && \
+ for obj in _dummy $(NAT_OBJECTS); do \
+ test "_dummy" != "$$obj" || continue; \
+ echo "$${obj%.cmx}.ml"; \
+ echo "$${obj%.cmx}.mli"; \
+ byte=""; \
+ done; \
+ echo "$$byte $$nat"; \
+ } | sort | uniq \
+ ) && \
+ $(TASKDEP) $$targets >>$(MF2NAME)
+## The following section is appended to _makemake for every executable:
+[makemake_exec]
+ echo "# --- dependencies for [execname]:" >>$(MF2NAME)
+ $(TASKDEP) [switches] [deptargets] >>$(MF2NAME)
+## Begin next section immediately to avoid empty lines:
+[dummy]
+
+[byte]
+
+
+.PHONY: byte
+byte: _byte
+
+.PHONY: _byte
+_byte: _makemake
+ @echo ""
+ if [ -n "$(BYTE_ARCHIVE)" ]; then \
+ $(MAKE) -f $(MF2NAME) $(BYTE_ARCHIVE); \
+ fi
+ if [ -n "$(BYTE_EXEC_TARGETS)" ]; then \
+ $(MAKE) -f $(MF2NAME) $(BYTE_EXEC_TARGETS); \
+ fi
+ @echo ""
+
+
+[opt]
+.PHONY: opt
+opt: _opt
+
+.PHONY: _opt
+_opt: _makemake
+ @echo ""
+ if [ -n "$(NAT_ARCHIVE)" ]; then \
+ $(MAKE) -f $(MF2NAME) $(NAT_ARCHIVE); \
+ fi
+ if [ -n "$(NAT_EXEC_TARGETS)" ]; then \
+ $(MAKE) -f $(MF2NAME) $(NAT_EXEC_TARGETS); \
+ fi
+ @echo ""
+
+
+[byte_archive]
+$(BYTE_ARCHIVE): $(BYTE_OBJECTS)
+ @echo ""
+ $(TASKBYTEAR) -o $(BYTE_ARCHIVE) $(BYTE_OBJECTS)
+
+
+[native_archive]
+$(NAT_ARCHIVE): $(NAT_OBJECTS)
+ @echo ""
+ $(TASKNATAR) -o $(NAT_ARCHIVE) $(NAT_OBJECTS)
+
+
+## The following section is included for every bytecode executable again.
+
+[byte_exec]
+[execname]: $(BYTE_ARCHIVE) [execobjs]
+ @echo ""
+ $(TASKBYTELINK) -o [execname] $(BYTE_ARCHIVE) [execobjs]
+
+
+[nat_exec]
+[execname]: $(NAT_ARCHIVE) [execobjs]
+ @echo ""
+ $(TASKNATLINK) -o [execname] $(NAT_ARCHIVE) [execobjs]
+
+
+[clean]
+.PHONY: clean
+clean:
+ @echo ""
+ touch $(TEMPNAME)
+ rm -f $(BYTE_FILES) $(NAT_FILES) $(BYTE_EXEC_FILES) $(NAT_EXEC_FILES)
+ rm -f $(MF2NAME)
+ cat $(TEMPNAME) | xargs rm -f
+ rm -f $(TEMPNAME)
+
+.PHONY: CLEAN
+CLEAN: clean
+
+.PHONY: distclean
+distclean: clean
+
+
+[install]
+.PHONY: install
+install: $(INSTALL)
+
+.PHONY: _findlib_install
+_findlib_install:
+ @echo ""
+ files=$$( \
+ for f in $(BYTE_INST) $(NAT_INST) $(BYTE_EXEC_INST) $(NAT_EXEC_INST) $(OTHER_INST); do \
+ if [ -f "$$f" ]; then echo $$f; fi; \
+ done; \
+ ) && \
+ $(TASKINSTALL) $$files
+
+.PHONY: uninstall
+uninstall: $(UNINSTALL)
+
+.PHONY: _findlib_uninstall
+_findlib_uninstall:
+ @echo ""
+ $(TASKREMOVE)
+
+# The following rules just print some variables.
+
+.PHONY: _print_name
+_print_name:
+ echo "$(NAME)"
+
+.PHONY: _print_version
+_print_version:
+ echo "$(VERSION)"
+
+[local]
+# ----------------------------------------------------------------------
+# Local additions
+# ----------------------------------------------------------------------
+
+[trailer]
+## ======================================================================
+## History:
+##
+## $Log: make_wizard.pattern,v $
+## Revision 1.2 2003/01/13 00:37:45 gerd
+## Bugfix NATIVE_ARCHIVE ==> NAT_ARCHIVE (reported by
+## Matt Gushee)
+##
+## Revision 1.1 2002/05/26 14:09:07 gerd
+## Renaming
+##
+## Revision 1.1 2002/05/05 20:40:26 gerd
+## Initial revision
+##
+##
diff --git a/local-packages/ocamlfind/src/findlib/META b/local-packages/ocamlfind/src/findlib/META
new file mode 100644
index 0000000..ce39190
--- /dev/null
+++ b/local-packages/ocamlfind/src/findlib/META
@@ -0,0 +1,36 @@
+# specifications for "findlib":
+description = "Package manager"
+requires = "findlib.internal"
+requires(toploop) += "findlib.top"
+requires(create_toploop) += "findlib.top"
+version = "1.9.5"
+
+package "internal" (
+ version = "1.9.5"
+ description = "Package manager"
+ requires = ""
+ archive(byte) = "findlib.cma"
+ archive(native) = "findlib.cmxa"
+ plugin(byte) = "findlib.cma"
+ plugin(native) = "findlib.cmxs"
+)
+
+package "dynload" (
+ version = "1.9.5"
+ description = "Package manager dynamic loader"
+ requires = "findlib dynlink"
+ archive(byte) = "findlib_dynload.cma"
+ archive(native) = "findlib_dynload.cmxa"
+#Even if it strange and discouraged to dynload this package
+ plugin(byte) = "findlib_dynload.cma"
+ plugin(native) = "findlib_dynload.cmxs"
+ linkopts = "-linkall"
+)
+
+package "top" (
+ version = "1.9.5"
+ description = "Package manager toplevel support"
+ requires = "findlib.internal"
+ archive(byte) = "findlib_top.cma"
+ archive(native) = "findlib_top.cmxa"
+)
diff --git a/local-packages/ocamlfind/src/findlib/META.in b/local-packages/ocamlfind/src/findlib/META.in
new file mode 100644
index 0000000..6b473c0
--- /dev/null
+++ b/local-packages/ocamlfind/src/findlib/META.in
@@ -0,0 +1,36 @@
+# specifications for "findlib":
+description = "Package manager"
+requires = "findlib.internal"
+requires(toploop) += "findlib.top"
+requires(create_toploop) += "findlib.top"
+version = "@VERSION@"
+
+package "internal" (
+ version = "@VERSION@"
+ description = "Package manager"
+ requires = "@REQUIRES@"
+ archive(byte) = "findlib.cma"
+ archive(native) = "findlib.cmxa"
+ plugin(byte) = "findlib.cma"
+ plugin(native) = "findlib.cmxs"
+)
+
+package "dynload" (
+ version = "@VERSION@"
+ description = "Package manager dynamic loader"
+ requires = "findlib dynlink"
+ archive(byte) = "findlib_dynload.cma"
+ archive(native) = "findlib_dynload.cmxa"
+#Even if it strange and discouraged to dynload this package
+ plugin(byte) = "findlib_dynload.cma"
+ plugin(native) = "findlib_dynload.cmxs"
+ linkopts = "-linkall"
+)
+
+package "top" (
+ version = "@VERSION@"
+ description = "Package manager toplevel support"
+ requires = "findlib.internal"
+ archive(byte) = "findlib_top.cma"
+ archive(native) = "findlib_top.cmxa"
+)
diff --git a/local-packages/ocamlfind/src/findlib/Makefile b/local-packages/ocamlfind/src/findlib/Makefile
new file mode 100644
index 0000000..ea23f4a
--- /dev/null
+++ b/local-packages/ocamlfind/src/findlib/Makefile
@@ -0,0 +1,193 @@
+# make all: compile to bytecode
+# make opt: compile to native code
+# make install: install bytecode and/or native code
+#
+# See Makefile.config for configurable variables.
+# Runtime configurations might also be necessary in the site-lib/*/META
+# files.
+#----------------------------------------------------------------------
+
+TOP=../..
+include $(TOP)/Makefile.config
+
+NAME = findlib
+
+# Need compiler-libs since ocaml-4.00
+OCAMLC = ocamlc -I +compiler-libs
+OCAMLOPT = ocamlopt -I +compiler-libs -g
+OCAMLDEP = ocamldep
+OCAMLLEX = ocamllex
+#CAMLP4O = camlp4 pa_o.cmo pa_op.cmo pr_o.cmo --
+#CAMLP4O = camlp4 pa_o.cmo pa_op.cmo pr_dump.cmo --
+
+
+OBJECTS = findlib_config.cmo fl_split.cmo fl_metatoken.cmo fl_meta.cmo \
+ fl_metascanner.cmo fl_topo.cmo fl_package_base.cmo \
+ findlib.cmo fl_args.cmo fl_lint.cmo
+TOBJECTS = topfind.cmo
+
+XOBJECTS = $(OBJECTS:.cmo=.cmx)
+TXOBJECTS = topfind.cmx
+
+OCAMLFIND_OBJECTS = ocaml_args.cmo frontend.cmo
+OCAMLFIND_XOBJECTS = ocaml_args.cmx frontend.cmx
+
+# OCAMLFIND_ARCHIVES: set in Makefile.config
+OCAMLFIND_XARCHIVES = $(OCAMLFIND_ARCHIVES:.cma=.cmxa)
+
+NUMTOP_OBJECTS = num_top_printers.cmo num_top.cmo
+
+DYNLOAD_OBJECTS = fl_dynload.cmo
+DYNLOAD_XOBJECTS = $(DYNLOAD_OBJECTS:.cmo=.cmx)
+
+
+all: ocamlfind$(EXEC_SUFFIX) findlib.cma findlib_top.cma topfind $(NUMTOP) \
+ findlib_dynload.cma
+
+opt: ocamlfind_opt$(EXEC_SUFFIX) findlib.cmxa findlib_top.cmxa topfind \
+ findlib_dynload.cmxa
+
+num-top: num_top.cma
+
+ocamlfind$(EXEC_SUFFIX): findlib.cma $(OCAMLFIND_OBJECTS)
+ $(OCAMLC) $(CUSTOM) -o ocamlfind$(EXEC_SUFFIX) -g $(OCAMLFIND_ARCHIVES) \
+ $(OCAMLC_FLAGS) $(OCAMLFIND_OCAMLFLAGS) $(OCAMLFIND_OBJECTS)
+
+ocamlfind_opt$(EXEC_SUFFIX): findlib.cmxa $(OCAMLFIND_XOBJECTS)
+ $(OCAMLOPT) -o ocamlfind_opt$(EXEC_SUFFIX) $(OCAMLFIND_XARCHIVES) \
+ $(OCAMLOPT_FLAGS) $(OCAMLFIND_OCAMLFLAGS) $(OCAMLFIND_XOBJECTS)
+
+test_parser$(EXEC_SUFFIX): fl_metascanner.cmx test_parser.cmx fl_metatoken.cmx fl_meta.cmx
+ $(OCAMLOPT) -o test_parser$(EXEC_SUFFIX) fl_meta.cmx fl_metatoken.cmx fl_metascanner.cmx test_parser.cmx
+
+findlib.cma: $(OBJECTS)
+ $(OCAMLC) -a -o findlib.cma $(OBJECTS)
+
+findlib_top.cma: $(TOBJECTS)
+ $(OCAMLC) -a -o findlib_top.cma $(TOBJECTS)
+
+findlib.cmxa: $(XOBJECTS)
+ $(OCAMLOPT) -a -o findlib.cmxa $(XOBJECTS)
+ if [ $(HAVE_NATDYNLINK) -gt 0 ]; then \
+ $(OCAMLOPT) -shared -o findlib.cmxs $(XOBJECTS); \
+ fi
+
+findlib_top.cmxa: $(TXOBJECTS)
+ $(OCAMLOPT) -a -o findlib_top.cmxa $(TXOBJECTS)
+ if [ $(HAVE_NATDYNLINK) -gt 0 ]; then \
+ $(OCAMLOPT) -shared -o findlib_top.cmxs $(TXOBJECTS); \
+ fi
+
+findlib_dynload.cma: $(DYNLOAD_OBJECTS)
+ $(OCAMLC) -a -o findlib_dynload.cma $(DYNLOAD_OBJECTS)
+
+findlib_dynload.cmxa: $(DYNLOAD_XOBJECTS)
+ $(OCAMLOPT) -a -o findlib_dynload.cmxa $(DYNLOAD_XOBJECTS)
+ if [ $(HAVE_NATDYNLINK) -gt 0 ]; then \
+ $(OCAMLOPT) -shared -o findlib_dynload.cmxs $(DYNLOAD_XOBJECTS); \
+ fi
+
+findlib_config.ml: findlib_config.mlp $(TOP)/Makefile.config
+ USE_CYGPATH="$(USE_CYGPATH)"; \
+ export USE_CYGPATH; \
+ cat findlib_config.mlp | \
+ $(SH) $(TOP)/tools/patch '@CONFIGFILE@' '$(OCAMLFIND_CONF)' | \
+ $(SH) $(TOP)/tools/patch '@STDLIB@' '$(OCAML_CORE_STDLIB)' | \
+ sed -e 's;@AUTOLINK@;$(OCAML_AUTOLINK);g' \
+ -e 's;@SYSTEM@;$(SYSTEM);g' \
+ >findlib_config.ml
+
+topfind.ml: topfind.ml.in
+ if [ "$(ENABLE_TOPFIND_PPXOPT)" = "true" ]; then \
+ cp topfind.ml.in topfind.ml; \
+ else \
+ sed -e '/PPXOPT_BEGIN/,/PPXOPT_END/ d' topfind.ml.in \
+ > topfind.ml ; \
+ fi
+
+topfind: topfind_rd$(OCAML_REMOVE_DIRECTORY).p
+ USE_CYGPATH="$(USE_CYGPATH)"; \
+ export USE_CYGPATH; \
+ cat topfind_rd$(OCAML_REMOVE_DIRECTORY).p | \
+ $(SH) $(TOP)/tools/patch '@SITELIB@' '$(OCAML_SITELIB)' \
+ >topfind
+
+num_top.cma: $(NUMTOP_OBJECTS)
+ $(OCAMLC) -a -o num_top.cma $(NUMTOP_OBJECTS)
+
+clean:
+ rm -f *.cmi *.cmo *.cma *.cmx *.a *.lib *.o *.obj *.cmxa \
+ fl_meta.ml findlib_config.ml findlib.mml topfind.ml topfind \
+ ocamlfind$(EXEC_SUFFIX) ocamlfind_opt$(EXEC_SUFFIX)
+
+install: all
+ $(INSTALLDIR) "$(DESTDIR)$(prefix)$(OCAML_SITELIB)/$(NAME)"
+ $(INSTALLDIR) "$(DESTDIR)$(prefix)$(OCAMLFIND_BIN)"
+ test $(INSTALL_TOPFIND) -eq 0 || $(INSTALLDIR) "$(DESTDIR)$(prefix)$(OCAML_CORE_STDLIB)"
+ test $(INSTALL_TOPFIND) -eq 0 || $(INSTALLFILE) topfind "$(DESTDIR)$(prefix)$(OCAML_CORE_STDLIB)/"
+ files=`$(SH) $(TOP)/tools/collect_files $(TOP)/Makefile.config \
+ findlib.cmi findlib.mli findlib.cma findlib.cmxa findlib$(LIB_SUFFIX) findlib.cmxs \
+ findlib_config.cmi findlib_config.ml topfind.cmi topfind.mli \
+ fl_args.cmi fl_lint.cmi fl_meta.cmi fl_split.cmi fl_topo.cmi ocaml_args.cmi \
+ fl_package_base.mli fl_package_base.cmi fl_metascanner.mli fl_metascanner.cmi \
+ fl_metatoken.cmi findlib_top.cma findlib_top.cmxa findlib_top$(LIB_SUFFIX) findlib_top.cmxs \
+ findlib_dynload.cma findlib_dynload.cmxa findlib_dynload$(LIB_SUFFIX) findlib_dynload.cmxs fl_dynload.mli fl_dynload.cmi \
+ META` && \
+ $(INSTALLFILE) $$files "$(DESTDIR)$(prefix)$(OCAML_SITELIB)/$(NAME)/"
+ f="ocamlfind$(EXEC_SUFFIX)"; { test -f ocamlfind_opt$(EXEC_SUFFIX) && f="ocamlfind_opt$(EXEC_SUFFIX)"; }; \
+ $(INSTALLFILE) $$f "$(DESTDIR)$(prefix)$(OCAMLFIND_BIN)/ocamlfind$(EXEC_SUFFIX)"
+ # the following "if" block is only needed for 4.00beta2
+ if [ $(OCAML_REMOVE_DIRECTORY) -eq 0 -a -f "$(OCAML_CORE_STDLIB)/compiler-libs/topdirs.cmi" ]; then \
+ cd "$(OCAML_CORE_STDLIB)/compiler-libs/"; \
+ $(INSTALLFILE) topdirs.cmi toploop.cmi "$(DESTDIR)$(prefix)$(OCAML_SITELIB)/$(NAME)/"; \
+ fi
+
+install-num-top:
+ $(INSTALLDIR) "$(DESTDIR)$(prefix)$(OCAML_SITELIB)/num-top"
+ $(INSTALLFILE) num_top.cma num_top.cmi num_top_printers.cmi \
+ "$(DESTDIR)$(prefix)$(OCAML_SITELIB)/num-top/"
+
+# Note: uninstall-num-top is part of the removal of the META files.
+
+uninstall:
+ rm -f $(DESTDIR)$(prefix)$(OCAML_CORE_STDLIB)/findlib
+ rm -rf $(DESTDIR)$(prefix)$(OCAML_SITELIB)/$(NAME)
+ rm -f $(DESTDIR)$(prefix)$(OCAMLFIND_BIN)/ocamlfind$(EXEC_SUFFIX)
+
+
+depend: *.ml *.mli fl_meta.ml fl_metascanner.ml findlib_config.ml topfind.ml
+ $(OCAMLDEP) *.ml *.mli >depend
+
+# Some 'make' implementations require that .SUFFIXES must occur before
+# the first suffix rule. (E.g. AIX)
+.SUFFIXES: .mll .cmo .cmi .cmx .ml .mli .mml
+# .src
+
+.mml.cmo:
+ $(OCAMLC) $(OPAQUE) $(OCAMLC_FLAGS) $(OCAMLFIND_OCAMLFLAGS) -g -vmthread -c -impl $<
+
+.mml.cmx:
+ $(OCAMLOPT) $(OPAQUE) $(OCAMLOPT_FLAGS) $(OCAMLFIND_OCAMLFLAGS) -thread -c -impl $<
+
+.ml.cmx:
+ $(OCAMLOPT) $(OPAQUE) $(OCAMLOPT_FLAGS) $(OCAMLFIND_OCAMLFLAGS) -c $<
+
+.ml.cmo:
+ $(OCAMLC) $(OPAQUE) $(OCAMLC_FLAGS) $(OCAMLFIND_OCAMLFLAGS) -g -c $<
+
+.mli.cmi:
+ $(OCAMLC) $(OPAQUE) $(OCAMLC_FLAGS) $(OCAMLFIND_OCAMLFLAGS) -c $<
+
+#.src.ml:
+# $(CAMLP4O) -impl $< -o $@
+
+# Solaris make does not like the suffix rule .mll.ml,
+# so I replaced it by its single application:
+fl_meta.ml: fl_meta.mll
+ $(OCAMLLEX) fl_meta.mll
+
+# Don't remove fl_metascanner.ml:
+.PRECIOUS: fl_metascanner.ml
+
+include depend
+
diff --git a/local-packages/ocamlfind/src/findlib/depend b/local-packages/ocamlfind/src/findlib/depend
new file mode 100644
index 0000000..6eef2d3
--- /dev/null
+++ b/local-packages/ocamlfind/src/findlib/depend
@@ -0,0 +1,112 @@
+findlib.cmo : \
+ fl_split.cmo \
+ fl_package_base.cmi \
+ fl_metascanner.cmi \
+ findlib_config.cmo \
+ findlib.cmi
+findlib.cmx : \
+ fl_split.cmx \
+ fl_package_base.cmx \
+ fl_metascanner.cmx \
+ findlib_config.cmx \
+ findlib.cmi
+findlib.cmi :
+findlib_config.cmo :
+findlib_config.cmx :
+fl_args.cmo :
+fl_args.cmx :
+fl_dynload.cmo : \
+ fl_split.cmo \
+ findlib.cmi \
+ fl_dynload.cmi
+fl_dynload.cmx : \
+ fl_split.cmx \
+ findlib.cmx \
+ fl_dynload.cmi
+fl_dynload.cmi :
+fl_lint.cmo : \
+ fl_metascanner.cmi
+fl_lint.cmx : \
+ fl_metascanner.cmx
+fl_meta.cmo : \
+ fl_metatoken.cmo
+fl_meta.cmx : \
+ fl_metatoken.cmx
+fl_metascanner.cmo : \
+ fl_metatoken.cmo \
+ fl_meta.cmo \
+ fl_metascanner.cmi
+fl_metascanner.cmx : \
+ fl_metatoken.cmx \
+ fl_meta.cmx \
+ fl_metascanner.cmi
+fl_metascanner.cmi : \
+ fl_metatoken.cmo
+fl_metatoken.cmo :
+fl_metatoken.cmx :
+fl_ocaml_args.cmo :
+fl_ocaml_args.cmx :
+fl_package_base.cmo : \
+ fl_topo.cmi \
+ fl_split.cmo \
+ fl_metascanner.cmi \
+ fl_package_base.cmi
+fl_package_base.cmx : \
+ fl_topo.cmx \
+ fl_split.cmx \
+ fl_metascanner.cmx \
+ fl_package_base.cmi
+fl_package_base.cmi : \
+ fl_metascanner.cmi
+fl_split.cmo :
+fl_split.cmx :
+fl_topo.cmo : \
+ fl_topo.cmi
+fl_topo.cmx : \
+ fl_topo.cmi
+fl_topo.cmi :
+frontend.cmo : \
+ ocaml_args.cmo \
+ fl_split.cmo \
+ fl_package_base.cmi \
+ fl_metascanner.cmi \
+ fl_lint.cmo \
+ fl_args.cmo \
+ findlib_config.cmo \
+ findlib.cmi
+frontend.cmx : \
+ ocaml_args.cmx \
+ fl_split.cmx \
+ fl_package_base.cmx \
+ fl_metascanner.cmx \
+ fl_lint.cmx \
+ fl_args.cmx \
+ findlib_config.cmx \
+ findlib.cmx
+num_top.cmo : \
+ num_top.cmi
+num_top.cmx : \
+ num_top.cmi
+num_top.cmi :
+num_top_printers.cmo : \
+ num_top_printers.cmi
+num_top_printers.cmx : \
+ num_top_printers.cmi
+num_top_printers.cmi :
+ocaml_args.cmo :
+ocaml_args.cmx :
+test_parser.cmo : \
+ fl_metascanner.cmi
+test_parser.cmx : \
+ fl_metascanner.cmx
+topfind.cmo : \
+ fl_split.cmo \
+ fl_package_base.cmi \
+ findlib.cmi \
+ topfind.cmi
+topfind.cmx : \
+ fl_split.cmx \
+ fl_package_base.cmx \
+ findlib.cmx \
+ topfind.cmi
+topfind.cmi :
diff --git a/local-packages/ocamlfind/src/findlib/findlib.ml b/local-packages/ocamlfind/src/findlib/findlib.ml
new file mode 100644
index 0000000..dc9b2b4
--- /dev/null
+++ b/local-packages/ocamlfind/src/findlib/findlib.ml
@@ -0,0 +1,524 @@
+(* $Id$
+ * ----------------------------------------------------------------------
+ *
+ *)
+
+module StrSet = Set.Make(String)
+
+exception No_such_package
+ = Fl_package_base.No_such_package
+
+
+exception Package_loop
+ = Fl_package_base.Package_loop
+
+type formal_pred =
+ [ `Pred of string
+ | `NegPred of string
+ ]
+
+let init_called = ref false ;;
+
+let conf_config_file = ref "";;
+let conf_default_location = ref "";;
+let conf_meta_directory = ref "";;
+let conf_search_path = ref [];;
+let conf_command = ref [];;
+let conf_stdlib = ref "";;
+let conf_ldconf = ref "";;
+let conf_ignore_dups_in = ref ([] : string list);;
+
+let ocamlc_default = "ocamlc";;
+let ocamlopt_default = "ocamlopt";;
+let ocamlcp_default = "ocamlcp";;
+let ocamloptp_default = "ocamloptp";;
+let ocamlmklib_default = "ocamlmklib";;
+let ocamlmktop_default = "ocamlmktop";;
+let ocamldep_default = "ocamldep";;
+let ocamlbrowser_default = "ocamlbrowser";;
+let ocamldoc_default = "ocamldoc";;
+
+
+let init_manually
+ ?(ocamlc_command = ocamlc_default)
+ ?(ocamlopt_command = ocamlopt_default)
+ ?(ocamlcp_command = ocamlcp_default)
+ ?(ocamloptp_command = ocamloptp_default)
+ ?(ocamlmklib_command = ocamlmklib_default)
+ ?(ocamlmktop_command = ocamlmktop_default)
+ ?(ocamldep_command = ocamldep_default)
+ ?(ocamlbrowser_command = ocamlbrowser_default)
+ ?(ocamldoc_command = ocamldoc_default)
+ ?ignore_dups_in
+ ?(ignore_dups_in_list = [])
+ ?(stdlib = Findlib_config.ocaml_stdlib)
+ ?(ldconf = Findlib_config.ocaml_ldconf)
+ ?(config = Findlib_config.config_file)
+ ~install_dir
+ ~meta_dir
+ ~search_path () =
+ conf_command := [ `ocamlc, ocamlc_command;
+ `ocamlopt, ocamlopt_command;
+ `ocamlcp, ocamlcp_command;
+ `ocamloptp, ocamloptp_command;
+ `ocamlmklib, ocamlmklib_command;
+ `ocamlmktop, ocamlmktop_command;
+ `ocamldep, ocamldep_command;
+ `ocamlbrowser, ocamlbrowser_command;
+ `ocamldoc, ocamldoc_command;
+ ];
+ conf_config_file := config;
+ conf_search_path := search_path;
+ conf_default_location := install_dir;
+ conf_meta_directory := meta_dir;
+ conf_stdlib := stdlib;
+ conf_ldconf := ldconf;
+ conf_ignore_dups_in :=
+ ( match ignore_dups_in with
+ | None -> []
+ | Some d -> [d]
+ ) @ ignore_dups_in_list;
+ Fl_package_base.init !conf_search_path stdlib !conf_ignore_dups_in;
+ init_called := true
+;;
+
+
+let command_names cmd_spec =
+ try
+ let cmd_list = Fl_split.in_words cmd_spec in
+ List.map
+ (fun cmd_setting ->
+ try
+ (* cmd_setting: formal_name=actual_name *)
+ let l = String.length cmd_setting in
+ let n = String.index cmd_setting '=' in
+ let cmd_formal_name = String.sub cmd_setting 0 n in
+ let cmd_actual_name = String.sub cmd_setting (n+1) (l-n-1) in
+ cmd_formal_name, cmd_actual_name
+ with
+ Not_found ->
+ prerr_endline ("Warning: Please check the environment variable OCAMLFIND_COMMANDS");
+ "", ""
+ )
+ cmd_list
+ with
+ Not_found ->
+ []
+;;
+
+let auto_config_file() =
+ let p =
+ ( try Sys.getenv "OCAMLFIND_CONF" with Not_found -> "") in
+ if p = "" then Findlib_config.config_file else p
+
+
+let init
+ ?env_ocamlpath ?env_ocamlfind_destdir ?env_ocamlfind_metadir
+ ?env_ocamlfind_commands ?env_ocamlfind_ignore_dups_in
+ ?env_ocamlfind_ignore_dups_in_list ?env_camllib ?env_ldconf
+ ?config ?toolchain () =
+
+ let config_file =
+ match config with
+ Some f -> f
+ | None -> auto_config_file()
+ in
+
+ let configd_file =
+ config_file ^ ".d" in
+
+ let vars_of_file f =
+ let ch = open_in f in
+ try
+ let vars =
+ (Fl_metascanner.parse ch).Fl_metascanner.pkg_defs in
+ close_in ch;
+ vars
+ with
+ | error -> close_in ch; raise error in
+
+ let vars_of_dir d =
+ let files = Array.to_list (Sys.readdir d) in
+ List.flatten
+ (List.map
+ (fun file ->
+ if Filename.check_suffix file ".conf" then
+ vars_of_file (Filename.concat d file)
+ else
+ []
+ )
+ files)
+ in
+
+ let config_preds =
+ match toolchain with
+ | None -> (try [Sys.getenv "OCAMLFIND_TOOLCHAIN"] with Not_found -> [])
+ | Some p -> [p] in
+
+ let sys_ocamlc, sys_ocamlopt, sys_ocamlcp, sys_ocamloptp, sys_ocamlmklib,
+ sys_ocamlmktop, sys_ocamldep, sys_ocamlbrowser, sys_ocamldoc,
+ sys_search_path, sys_destdir, sys_metadir, sys_stdlib, sys_ldconf =
+ (
+ let config_vars =
+ if config_file <> "" &&
+ not(Sys.file_exists config_file) && not(Sys.file_exists configd_file)
+ then
+ failwith("Config file not found - neither " ^
+ config_file ^ " nor the directory " ^
+ configd_file);
+ if Sys.file_exists config_file then
+ vars_of_file config_file
+ else
+ [] in
+ let configd_vars =
+ if Sys.file_exists configd_file then
+ vars_of_dir configd_file
+ else
+ [] in
+ let vars = config_vars @ configd_vars in
+ if vars <> [] then (
+ let found = ref false in
+ let lookup name default =
+ let explicit_preds =
+ List.for_all
+ (fun p -> Fl_metascanner.predicate_exists p vars)
+ config_preds in
+ found := !found || explicit_preds;
+ try
+ Fl_metascanner.lookup name config_preds vars
+ with Not_found -> default
+ in
+ let config_tuple =
+ ( (lookup "ocamlc" ocamlc_default),
+ (lookup "ocamlopt" ocamlopt_default),
+ (lookup "ocamlcp" ocamlcp_default),
+ (lookup "ocamloptp" ocamloptp_default),
+ (lookup "ocamlmklib" ocamlmklib_default),
+ (lookup "ocamlmktop" ocamlmktop_default),
+ (lookup "ocamldep" ocamldep_default),
+ (lookup "ocamlbrowser" ocamlbrowser_default),
+ (lookup "ocamldoc" ocamldoc_default),
+ Fl_split.path (lookup "path" ""),
+ (lookup "destdir" ""),
+ (lookup "metadir" "none"),
+ (lookup "stdlib" Findlib_config.ocaml_stdlib),
+ (lookup "ldconf" Findlib_config.ocaml_ldconf)
+ ) in
+ if not !found && config_preds <> [] then
+ prerr_endline("ocamlfind: [WARNING] Undefined toolchain: " ^
+ String.concat "" config_preds);
+ config_tuple
+ )
+ else
+ ( ocamlc_default, ocamlopt_default, ocamlcp_default, ocamloptp_default,
+ ocamlmklib_default,
+ ocamlmktop_default, ocamldep_default, ocamlbrowser_default,
+ ocamldoc_default,
+ [],
+ "",
+ "none",
+ Findlib_config.ocaml_stdlib,
+ Findlib_config.ocaml_ldconf
+ )
+ )
+ in
+
+ let env_commands =
+ match env_ocamlfind_commands with
+ Some x -> command_names x
+ | None -> command_names (try Sys.getenv "OCAMLFIND_COMMANDS"
+ with Not_found -> "")
+ in
+ let env_destdir =
+ match env_ocamlfind_destdir with
+ Some x -> x
+ | None ->
+ try Sys.getenv "OCAMLFIND_DESTDIR" with Not_found -> ""
+ in
+ let env_metadir =
+ match env_ocamlfind_metadir with
+ Some x -> x
+ | None ->
+ try Sys.getenv "OCAMLFIND_METADIR" with Not_found -> ""
+ in
+ let env_search_path =
+ Fl_split.path
+ (match env_ocamlpath with
+ Some x -> x
+ | None ->
+ try Sys.getenv "OCAMLPATH" with Not_found -> ""
+ )
+ in
+ let env_stdlib =
+ match env_camllib with
+ Some x -> x
+ | None ->
+ ( try Sys.getenv "OCAMLLIB"
+ with
+ Not_found ->
+ (try Sys.getenv "CAMLLIB" with Not_found -> "" )
+ )
+ in
+ let env_ldconf =
+ match env_ldconf with
+ Some x -> x
+ | None ->
+ try Sys.getenv "OCAMLFIND_LDCONF" with Not_found -> ""
+ in
+ let ignore_dups_in_list =
+ match env_ocamlfind_ignore_dups_in, env_ocamlfind_ignore_dups_in_list with
+ | Some x0, Some l -> x0 :: l
+ | None, Some l -> l
+ | Some x0, None -> [x0]
+ | None, None ->
+ try Fl_split.path (Sys.getenv "OCAMLFIND_IGNORE_DUPS_IN")
+ with Not_found -> [] in
+
+ let ocamlc, ocamlopt, ocamlcp, ocamloptp, ocamlmklib, ocamlmktop,
+ ocamldep, ocamlbrowser, ocamldoc,
+ search_path, destdir, metadir, stdlib, ldconf =
+ (try List.assoc "ocamlc" env_commands with Not_found -> sys_ocamlc),
+ (try List.assoc "ocamlopt" env_commands with Not_found -> sys_ocamlopt),
+ (try List.assoc "ocamlcp" env_commands with Not_found -> sys_ocamlcp),
+ (try List.assoc "ocamloptp" env_commands with Not_found -> sys_ocamloptp),
+ (try List.assoc "ocamlmklib" env_commands with Not_found -> sys_ocamlmklib),
+ (try List.assoc "ocamlmktop" env_commands with Not_found -> sys_ocamlmktop),
+ (try List.assoc "ocamldep" env_commands with Not_found -> sys_ocamldep),
+ (try List.assoc "ocamlbrowser" env_commands with Not_found -> sys_ocamlbrowser),
+ (try List.assoc "ocamldoc" env_commands with Not_found -> sys_ocamldoc),
+ (env_search_path @ sys_search_path),
+ (if env_destdir = "" then sys_destdir else env_destdir),
+ (if env_metadir = "" then sys_metadir else env_metadir),
+ (if env_stdlib = "" then sys_stdlib else env_stdlib),
+ (if env_ldconf = "" then sys_ldconf else env_ldconf)
+ in
+
+ init_manually
+ ~ocamlc_command: ocamlc
+ ~ocamlopt_command: ocamlopt
+ ~ocamlcp_command: ocamlcp
+ ~ocamloptp_command: ocamloptp
+ ~ocamlmklib_command: ocamlmklib
+ ~ocamlmktop_command: ocamlmktop
+ ~ocamldep_command: ocamldep
+ ~ocamlbrowser_command: ocamlbrowser
+ ~ocamldoc_command: ocamldoc
+ ~ignore_dups_in_list
+ ~stdlib: stdlib
+ ~ldconf: ldconf
+ ~config: config_file
+ ~install_dir: destdir
+ ~meta_dir: metadir
+ ~search_path: search_path
+ ()
+;;
+
+
+let lazy_init() =
+ if not !init_called then init()
+
+let config_file() =
+ lazy_init();
+ !conf_config_file;;
+
+
+let default_location() =
+ lazy_init();
+ !conf_default_location;;
+
+
+let meta_directory() =
+ lazy_init();
+ if !conf_meta_directory = "none" then "" else !conf_meta_directory;;
+
+
+let search_path() =
+ lazy_init();
+ !conf_search_path;;
+
+
+let command which =
+ lazy_init();
+ try
+ List.assoc which !conf_command
+ with
+ Not_found -> assert false
+;;
+
+
+let ocaml_stdlib() =
+ lazy_init();
+ !conf_stdlib;;
+
+
+let ocaml_ldconf() =
+ lazy_init();
+ !conf_ldconf;;
+
+let ignore_dups_in() =
+ lazy_init();
+ !conf_ignore_dups_in;;
+
+let package_directory pkg =
+ lazy_init();
+ (Fl_package_base.query pkg).Fl_package_base.package_dir
+;;
+
+
+let package_meta_file pkg =
+ lazy_init();
+ (Fl_package_base.query pkg).Fl_package_base.package_meta
+;;
+
+
+let package_property_2 predlist pkg propname =
+ lazy_init();
+ let l = Fl_package_base.query pkg in
+ Fl_metascanner.lookup_2 propname predlist l.Fl_package_base.package_defs
+;;
+
+
+let package_property predlist pkg propname =
+ lazy_init();
+ let l = Fl_package_base.query pkg in
+ Fl_metascanner.lookup propname predlist l.Fl_package_base.package_defs
+;;
+
+
+let package_ancestors predlist pkg =
+ lazy_init();
+ Fl_package_base.requires predlist pkg
+;;
+
+
+let package_deep_ancestors predlist pkglist =
+ lazy_init();
+ Fl_package_base.requires_deeply predlist pkglist
+;;
+
+
+let resolve_path ?base ?(explicit=false) p =
+ lazy_init();
+ if p = "" then "" else (
+ match p.[0] with
+ '^' | '+' ->
+ let stdlibdir = Fl_split.norm_dir (ocaml_stdlib()) in
+ Filename.concat
+ stdlibdir
+ (String.sub p 1 (String.length p - 1))
+ | '@' ->
+ (* Search slash *)
+ ( try
+ let k = String.index p '/' in (* or Not_found *)
+ let pkg = String.sub p 1 (k-1) in
+ let p' = String.sub p (k+1) (String.length p - k - 1) in
+ let pkgdir = package_directory pkg in
+ Filename.concat pkgdir p'
+ with
+ Not_found ->
+ let pkg = String.sub p 1 (String.length p - 1) in
+ package_directory pkg
+ )
+ | _ ->
+ ( match base with
+ None -> p
+ | Some b ->
+ if Filename.is_relative p &&
+ (not explicit || not (Filename.is_implicit p))
+ then
+ Filename.concat b p
+ else
+ p
+ )
+ )
+;;
+
+
+let list_packages ?(tab = 20) ?(descr = false) ch =
+ lazy_init();
+ let packages = Fl_package_base.list_packages() in
+ let packages_sorted = List.sort compare packages in
+
+ List.iter
+ (fun p ->
+ let v_string =
+ try
+ let v = package_property [] p "version" in
+ "(version: " ^ v ^ ")"
+ with
+ Not_found -> "(version: n/a)"
+ in
+ let descr_string =
+ try package_property [] p "description"
+ with Not_found -> "(no description)" in
+ let spaces1 = String.make (max 1 (tab-String.length p)) ' ' in
+ let spaces2 = String.make tab ' ' in
+
+ if descr then (
+ output_string ch (p ^ spaces1 ^ descr_string ^ "\n");
+ output_string ch (spaces2 ^ v_string ^ "\n")
+ )
+ else
+ output_string ch (p ^ spaces1 ^ v_string ^ "\n");
+ )
+ packages_sorted
+;;
+
+let list_packages' ?prefix () =
+ lazy_init();
+ Fl_package_base.list_packages ?prefix ()
+
+
+type rectype =
+ | Record_core
+ | Record_load
+
+let rec_core = ref StrSet.empty
+let rec_load = ref StrSet.empty
+let rec_preds = ref []
+
+let record_package (rt:rectype) (p:string) =
+ match rt with
+ | Record_core ->
+ rec_core := StrSet.add p !rec_core
+ | Record_load ->
+ rec_load := StrSet.add p !rec_load
+
+let recorded_packages rt =
+ match rt with
+ | Record_core ->
+ StrSet.elements !rec_core
+ | Record_load ->
+ StrSet.elements (StrSet.diff !rec_load !rec_core)
+
+let reset_recordings() =
+ rec_load := StrSet.empty
+
+let type_of_recorded_package p =
+ if StrSet.mem p !rec_core then
+ Record_core
+ else
+ if StrSet.mem p !rec_load then
+ Record_load
+ else
+ raise Not_found
+
+let is_recorded_package p =
+ try ignore(type_of_recorded_package p); true with Not_found -> false
+
+
+let rm_preds =
+ [ "create_toploop"; "toploop"; "executable"; "plugin"; "autolink";
+ "preprocessor"; "syntax" ]
+
+let rm_preds_set =
+ List.fold_right StrSet.add rm_preds StrSet.empty
+
+let record_package_predicates preds =
+ let preds' =
+ List.filter (fun p -> not(StrSet.mem p rm_preds_set)) preds in
+ rec_preds := preds'
+
+let recorded_predicates() =
+ !rec_preds
+
diff --git a/local-packages/ocamlfind/src/findlib/findlib.mli b/local-packages/ocamlfind/src/findlib/findlib.mli
new file mode 100644
index 0000000..b6073fa
--- /dev/null
+++ b/local-packages/ocamlfind/src/findlib/findlib.mli
@@ -0,0 +1,276 @@
+(* $Id$
+ * ----------------------------------------------------------------------
+ *
+ *)
+
+(** The primary findlib interface
+ *
+ * The Findlib module is the primary interface of the findlib library. It
+ * contains functions to look up packages, to interpret META
+ * files, and to determine the ancestors of packages.
+ *
+ * This module must be initialized before it can be used: Call either
+ * [init] or [init_manually] for this.
+ *)
+
+exception No_such_package of string * string
+ (** First arg is the package name not found, second arg contains additional
+ * info for the user
+ *)
+
+exception Package_loop of string
+ (** A package is required by itself. The arg is the name of the
+ * package
+ *)
+
+
+type formal_pred =
+ [ `Pred of string (** Positive occurence of a formal predicate var *)
+ | `NegPred of string (** Negative occurence of a formal predicate var *)
+ ]
+ (** A formal predicate as it occurs in a package definition *)
+
+val init :
+ ?env_ocamlpath: string ->
+ ?env_ocamlfind_destdir: string ->
+ ?env_ocamlfind_metadir: string ->
+ ?env_ocamlfind_commands: string ->
+ ?env_ocamlfind_ignore_dups_in: string ->
+ ?env_ocamlfind_ignore_dups_in_list: string list ->
+ ?env_camllib: string ->
+ ?env_ldconf: string ->
+ ?config: string ->
+ ?toolchain: string ->
+ unit ->
+ unit
+ (** Initializes the library from the configuration file and the environment.
+ * By default the
+ * function reads the file specified at compile time, but you can also
+ * pass a different file name in the [config] argument.
+ * Furthermore, the environment variables OCAMLPATH, OCAMLFIND_DESTDIR,
+ * OCAMLFIND_COMMANDS, OCAMLFIND_IGNORE_DUPS_IN, and CAMLLIB are interpreted.
+ * By default, the function takes
+ * the values found in the environment, but you can pass different values
+ * using the [env_*] arguments. By setting these values to empty strings
+ * they are no longer considered.
+ * The result of the initialization is determined as follows:
+ * - The default installation directory is the env variable OCAMLFIND_DESTDIR
+ * (if present and non-empty), and otherwise the variable [destdir] of the
+ * configuration file.
+ * - The installation directory for META files is read from the env
+ * variable OCAMLFIND_METADIR (if present and non-empty), and otherwise
+ * from the variable [metadir] of the configuration file, and otherwise
+ * no such directory is used.
+ * The special value ["none"] turns this feature off.
+ * - The search path is the concatenation of the env variable OCAMLPATH
+ * and the variable [path] of the config file
+ * - The executables of (ocamlc|ocamlopt|ocamlcp|ocamlmklib|ocamlmktop) are
+ * determined as follows: if the env variable OCAMLFIND_COMMANDS is set
+ * and non-empty, its contents specify the executables. Otherwise, if the
+ * config file variables [ocamlc], [ocamlopt], [ocamlcp], [ocamlmklib] and
+ * [ocamlmktop] are set, their contents specify the executables. Otherwise,
+ * the obvious default values are chosen: ["ocamlc"] for [ocamlc],
+ * ["ocamlopt"] for [ocamlopt], and so on.
+ * - The directory of the standard library is the value of the environment
+ * variable CAMLLIB (or OCAMLLIB), or if unset or empty, the value of
+ * the configuration variable [stdlib], or if unset the built-in location
+ * - The [ld.conf] file (configuring the dynamic loader) is the value of
+ * the environment variable OCAMLFIND_LDCONF, or if unset or empty, the
+ * value of the configuration variable [ldconf], or if unset the
+ * built-in location.
+ * - The ocamlfind tool doesn't emit warnings about double cmi files
+ * for the directories listed in OCAMLFIND_IGNORE_DUPS_IN. Since
+ * findlib-1.8 this variable is interpreted as colon-separated path.
+ * (Before, only one directory could be given.) If the variable is not
+ * set there are no exceptions, and the warnings are always printed.
+ * Note that both the parameters [env_ocamlfind_ignore_dups_in] (a
+ * single directory) and [env_ocamlfind_ignore_dups_in_list] (a list
+ * of directories) override the default.
+ *)
+
+
+val init_manually :
+ ?ocamlc_command: string -> (* default: "ocamlc" *)
+ ?ocamlopt_command: string -> (* default: "ocamlopt" *)
+ ?ocamlcp_command: string -> (* default: "ocamlcp" *)
+ ?ocamloptp_command: string -> (* default: "ocamloptp" *)
+ ?ocamlmklib_command: string -> (* default: "ocamlmklib" *)
+ ?ocamlmktop_command: string -> (* default: "ocamlmktop" *)
+ ?ocamldep_command: string -> (* default: "ocamldep" *)
+ ?ocamlbrowser_command: string -> (* default: "ocamlbrowser" *)
+ ?ocamldoc_command: string -> (* default: "ocamldoc" *)
+ ?ignore_dups_in:string -> (* default: None *)
+ ?ignore_dups_in_list:string list -> (* default: [] *)
+ ?stdlib: string -> (* default: taken from Findlib_config *)
+ ?ldconf: string ->
+ ?config: string ->
+ install_dir: string ->
+ meta_dir: string ->
+ search_path: string list ->
+ unit ->
+ unit
+ (** This is an alternate way to initialize the library directly.
+ * Environment variables and configuration files are ignored. The
+ * parameter [config] just sets the file name reported by the
+ * [config_file] function below.
+ *)
+
+
+val config_file : unit -> string
+ (** The location of the configuration file *)
+
+val default_location : unit -> string
+ (** Get the default installation directory for packages *)
+
+val meta_directory : unit -> string
+ (** Get the META installation directory for packages.
+ * Returns [""] if no such directory is configured.
+ *)
+
+val search_path : unit -> string list
+ (** Get the search path for packages *)
+
+val command : [ `ocamlc | `ocamlopt | `ocamlcp | `ocamloptp | `ocamlmklib
+ | `ocamlmktop | `ocamldep | `ocamlbrowser | `ocamldoc
+ ] ->
+ string
+ (** Get the name/path of the executable *)
+
+val ocaml_stdlib : unit -> string
+ (** Get the directory of the standard library *)
+
+val ocaml_ldconf : unit -> string
+ (** Get the file name of [ld.conf] *)
+
+val package_directory : string -> string
+ (** Get the absolute path of the directory where the given package is
+ * stored.
+ *
+ * Raises [No_such_package] if the package cannot be found.
+ *)
+
+val package_meta_file : string -> string
+ (** Get the absolute path of the META file of the given package *)
+
+val ignore_dups_in : unit -> string list
+ (** If [Some d], duplicate packages below [d] are ignored, and do not
+ * produce warnings. (Only affects the generation of warnings.)
+ *
+ * Since findlib-1.8 this configuration is a list. Before, it was a
+ * [string option].
+ *)
+
+val package_property : string list -> string -> string -> string
+ (** [package_property predlist pkg propname]:
+ * Looks up the property [propname] of package [pkg] under the assumption
+ * that the predicates in [predlist] are true.
+ *
+ * Raises [No_such_package] if the package, and [Not_found] if the property
+ * cannot be found.
+ *
+ * EXAMPLES:
+ * - [package_property [] "p" "requires":]
+ * get the value of the [requires] clause of package [p]
+ * - [package_property [ "mt"; "byte" ] "p" "archive":]
+ * get the value of the [archive] property of package [p] for multi-
+ * threaded bytecode applications.
+ *)
+
+val package_property_2 : string list -> string -> string ->
+ string * formal_pred list
+ (** [package_property_2 predlist pkg propname]: This returns two values
+ [(v, preds)]. The first one, [v], is computed as in [package_property].
+ The other list, [preds], contains the predicates that actually had to
+ be set or not set in order to select the particular variable definition.
+ *)
+
+
+val package_ancestors : string list -> string -> string list
+ (** [package_ancestors predlist pkg:]
+ * Determines the direct ancestors of package [pkg] under the assumption
+ * that the predicates in [predlist] are true, i.e. the names of the
+ * packages required by [pkg].
+ * The returned list is unsorted.
+ *
+ * Raises [No_such_package] if the package [pkg] or one of its ancestors
+ * could not be found.
+ *)
+
+val package_deep_ancestors : string list -> string list -> string list
+ (** [package_deep_ancestors predlist pkglist:]
+ * determines the list of direct or indirect ancestors of the packages
+ * named in [pkglist] under the assumption that the predicates in [predlist]
+ * are true.
+ *
+ * The returned list is topologically sorted: The first element is the
+ * deepest ancestor; the last element is one of [pkglist].
+ *
+ * Raises [No_such_package] if one of the packages in [pkglist] or one of
+ * the ancestors cannot be found. Raises [Package_loop] if there is a
+ * cyclic dependency.
+ *)
+
+val resolve_path : ?base:string -> ?explicit:bool -> string -> string
+ (** Resolves findlib notation in filename paths. The notation
+ * [ +name/path ] can be used to refer to the subdirectory [name]
+ * of the standard library directory; the continuation [ /path ] is
+ * optional. The notation [ \@name/path ] can be used to refer to
+ * the directory of the package [name]; the continuation [ /path ]
+ * is optional. For these two notations, absolute paths are returned.
+ *
+ * @param base When the function is applied on a relative path, the
+ * [base] path is prepended. Otherwise, the path is returned as
+ * it is.
+ * @param explicit Changes the meaning of [base] so that only paths
+ * count as relative that include at least one slash.
+ *)
+
+val list_packages : ?tab:int -> ?descr:bool -> out_channel -> unit
+ (** Prints the list of available packages to the [out_channel].
+ *
+ * @param tab The tabulator width, by default 20
+ * @param descr Whether package descriptions are printed. Default: false
+ *)
+
+val list_packages' : ?prefix:string -> unit -> string list
+ (** Returns the (unsorted) list of all packages.
+ *
+ * @param prefix Limit to the packages that starts with it. Default: unlimited
+ *)
+
+(** Managing dynamically loaded packages *)
+
+(** This is a registry of packages that are available in-core. This is both
+ used for toploops and for plugins.
+ *)
+
+type rectype =
+ | Record_core (** The package is part of the executable core *)
+ | Record_load (** The package has been dynamically loaded *)
+
+val record_package : rectype -> string -> unit
+ (** Record this package *)
+
+val record_package_predicates : string list -> unit
+ (** Record the predicates to be used for package loading. Certain predicates
+ are automatically filtered out if inappropriate. A call of
+ [record_package_predicates] replaces the set of predicates that was
+ installed beforehand.
+ *)
+
+val recorded_packages : rectype -> string list
+ (** The list of packages recorded with [record_package] *)
+
+val is_recorded_package : string -> bool
+ (** Whether there is a recording for this package *)
+
+val type_of_recorded_package : string -> rectype
+ (** Returns the type, or raises [Not_found] *)
+
+val recorded_predicates : unit -> string list
+ (** The most recent version of the recorded predicate list *)
+
+val reset_recordings : unit -> unit
+ (** Removes all [Record_load] packages from the list of recordings.
+ This forces that the packages are loaded again.
+ *)
diff --git a/local-packages/ocamlfind/src/findlib/findlib_config.mlp b/local-packages/ocamlfind/src/findlib/findlib_config.mlp
new file mode 100644
index 0000000..3177de6
--- /dev/null
+++ b/local-packages/ocamlfind/src/findlib/findlib_config.mlp
@@ -0,0 +1,25 @@
+(* $Id$
+ * ----------------------------------------------------------------------
+ *
+ *)
+
+let config_file = "@CONFIGFILE@";;
+
+let ocaml_stdlib = "@STDLIB@";;
+
+let ocaml_ldconf = Filename.concat ocaml_stdlib "ld.conf";;
+
+let ocaml_has_autolinking = @AUTOLINK@;;
+
+let libexec_name = "stublibs";;
+
+let system = "@SYSTEM@";;
+(* - "mingw", "mingw64", "win32", "cygwin", "linux_elf", ... *)
+
+let dll_suffix =
+ match Sys.os_type with
+ | "Unix" | "BeOS" -> ".so"
+ | "Win32" | "Cygwin" -> ".dll"
+ | "MacOS" -> "" (* don't know *)
+ | _ -> failwith "Unknown Sys.os_type"
+;;
diff --git a/local-packages/ocamlfind/src/findlib/fl_args.ml b/local-packages/ocamlfind/src/findlib/fl_args.ml
new file mode 100644
index 0000000..2bca50c
--- /dev/null
+++ b/local-packages/ocamlfind/src/findlib/fl_args.ml
@@ -0,0 +1,104 @@
+(* $Id$ *)
+
+(* Rewrite a list of arguments args (from Sys.args) so that contracted
+ options like -L are transformed to -L , and become parseable
+ by Arg.
+ *)
+
+let make_ht (l:string list) =
+ let ht = Hashtbl.create 10 in
+ List.iter (fun x -> Hashtbl.add ht x ()) l;
+ ht
+
+let is_prefix s1 s2 =
+ let l1 = String.length s1 in
+ let l2 = String.length s2 in
+ l2 >= l1 && String.sub s2 0 l1 = s1
+
+let rewrite_contracted_args spec contracted_opts args =
+ let args = Array.to_list args in
+ let switches =
+ List.map
+ (fun (name,kind,text) -> name)
+ (List.filter
+ (fun (name,kind,text) ->
+ match kind with
+ | Arg.Unit _
+ | Arg.Set _
+ | Arg.Clear _ -> true
+ | Arg.Tuple _ ->
+ failwith
+ "Fl_args.rewrite_for_contracted_args: Arg.Tuple unsupported"
+ | _ -> false
+ )
+ spec
+ ) in
+ let unary_opts =
+ List.map
+ (fun (name,kind,text) -> name)
+ (List.filter
+ (fun (name,kind,text) ->
+ match kind with
+ | Arg.String _
+ | Arg.Set_string _
+ | Arg.Int _
+ | Arg.Set_int _
+ | Arg.Float _
+ | Arg.Set_float _ -> true
+ | _ -> false
+ )
+ spec
+ ) in
+ let rest_opts =
+ List.map
+ (fun (name,kind,text) -> name)
+ (List.filter
+ (fun (name,kind,text) ->
+ match kind with
+ | Arg.Rest _ -> true
+ | _ -> false
+ )
+ spec
+ ) in
+
+ let sw_ht = make_ht switches in
+ let unary_ht = make_ht unary_opts in
+ let rest_ht = make_ht rest_opts in
+
+ let rec rewrite (args:string list) =
+ match args with
+ | arg :: args_rest when Hashtbl.mem sw_ht arg ->
+ arg :: rewrite args_rest
+ | arg :: args_rest when Hashtbl.mem rest_ht arg ->
+ args
+ | arg1 :: arg2 :: args_rest when Hashtbl.mem unary_ht arg1 ->
+ arg1 :: arg2 :: rewrite args_rest
+ | arg :: args_rest ->
+ ( try
+ let args1 = expand arg contracted_opts in
+ let args2 = rewrite args_rest in
+ args1 @ args2
+ with
+ | Not_found ->
+ arg :: rewrite args_rest
+ )
+ | [] ->
+ []
+
+ and expand arg olo =
+ match olo with
+ | olo1 :: olo_rest ->
+ if is_prefix olo1 arg then
+ let p = String.length olo1 in
+ let l = String.length arg in
+ [ olo1;
+ String.sub arg p (l-p)
+ ]
+ else
+ expand arg olo_rest
+ | [] ->
+ raise Not_found
+
+ in
+
+ Array.of_list (rewrite args)
diff --git a/local-packages/ocamlfind/src/findlib/fl_dynload.ml b/local-packages/ocamlfind/src/findlib/fl_dynload.ml
new file mode 100644
index 0000000..ece81fe
--- /dev/null
+++ b/local-packages/ocamlfind/src/findlib/fl_dynload.ml
@@ -0,0 +1,55 @@
+(* $Id$ *)
+
+(* Utilities for loading dynamically packages *)
+
+open Printf
+
+let load_pkg ~debug pkg =
+ if not (Findlib.is_recorded_package pkg) then (
+ if debug then
+ eprintf "[DEBUG] Fl_dynload: about to load: %s\n%!" pkg;
+ (* Determine the package directory: *)
+ let d = Findlib.package_directory pkg in
+ (* First try the new "plugin" variable: *)
+ let preds = Findlib.recorded_predicates() in
+ let archive =
+ try
+ Findlib.package_property preds pkg "plugin"
+ with
+ | Not_found ->
+ (* Legacy: use "archive" but require that the predicate
+ "plugin" is mentioned in the definition
+ *)
+ try
+ let v, fpreds =
+ Findlib.package_property_2 ("plugin"::preds) pkg "archive" in
+ let need_plugin =
+ List.mem "native" preds in
+ if need_plugin && not (List.mem (`Pred "plugin") fpreds) then
+ ""
+ else
+ v
+ with Not_found -> "" in
+ (* Split the plugin/archive property and resolve the files: *)
+ let files = Fl_split.in_words archive in
+ if debug then
+ eprintf "[DEBUG] Fl_dynload: files=%S\n%!" archive;
+ List.iter
+ (fun file ->
+ if debug then
+ eprintf "[DEBUG] Fl_dynload: loading %S\n%!" file;
+ let file = Findlib.resolve_path ~base:d file in
+ Dynlink.loadfile file
+ ) files;
+ Findlib.record_package Findlib.Record_load pkg
+ )
+ else
+ if debug then
+ eprintf "[DEBUG] Fl_dynload: not loading: %s\n%!" pkg
+
+
+let load_packages ?(debug=false) pkgs =
+ let preds = Findlib.recorded_predicates() in
+ let eff_pkglist =
+ Findlib.package_deep_ancestors preds pkgs in
+ List.iter (load_pkg ~debug) eff_pkglist
diff --git a/local-packages/ocamlfind/src/findlib/fl_dynload.mli b/local-packages/ocamlfind/src/findlib/fl_dynload.mli
new file mode 100644
index 0000000..56282fb
--- /dev/null
+++ b/local-packages/ocamlfind/src/findlib/fl_dynload.mli
@@ -0,0 +1,37 @@
+(* $Id$ *)
+
+(** Utilities for loading dynamically packages *)
+
+val load_packages : ?debug:bool -> string list -> unit
+(** Load the given packages and all their dependencies dynamically. Packages
+ already loaded or already in-core are not loaded again. The predicates
+ are taken from {!Findlib.recorded_predicates}, which are normally the
+ predicates from the link-time of the executable.
+
+ In order to initialize this module correctly, you need to link the
+ executable in a special way. This is done by including "findlib.dynload"
+ in the [ocamlfind] command, e.g.
+
+ {[ ocamlfind ocamlopt -o program -package findlib.dynload -linkpkg m.ml ]}
+
+ It is not sufficient to just link [findlib_dynload.cm(x)a] into the
+ executable. The above command adds special initialization code that
+ (a) records the predicates and (b) records the packages already present
+ in the executable. Also [-linkall] is implicitly added.
+
+ The dynamic package loader works both for bytecode and native code.
+ The META files of the packages need to specify the cma or cmxs files
+ in the following way:
+
+ - First, the "plugin" variable is checked (instead of "archive"), e.g.
+ {[
+plugin(byte) = "my_plugin.cma"
+plugin(native) = "my_plugin.cmxs"
+ ]}
+ This is the preferred style.
+ - Second, for bytecode only, the normal "archive" variable is
+ also accepted if "plugin" is not present. (Because bytecode archives
+ can normally be dynamically loaded without special preparation.)
+ - Third, for native-code only, the "archive(plugin)" variable
+ is also accepted. This is for legacy packages.
+ *)
diff --git a/local-packages/ocamlfind/src/findlib/fl_lint.ml b/local-packages/ocamlfind/src/findlib/fl_lint.ml
new file mode 100644
index 0000000..160cdfb
--- /dev/null
+++ b/local-packages/ocamlfind/src/findlib/fl_lint.ml
@@ -0,0 +1,113 @@
+(* $Id$ -*- tuareg -*-
+ * ----------------------------------------------------------------------
+ *
+ *)
+
+open Fl_metascanner
+
+module Have = struct
+ module T = struct
+ type mode = [`Byte | `Native | `Toploop | `Preprocessor | `Ppx_driver]
+ type t = [
+ `Mode of [ `TooMany | `None]
+ (** problem in the number of mode (byte,native,syntax,...)
+ in the variable *)
+ | `Archive of [`Plugin|`NoPlugin] * mode
+ (** archive(plugin,...) or archive(...)) *)
+ | `Plugin of [`Plugin|`NoPlugin] * mode
+ (** plugin(...) *)
+ | `Description
+ | `Requires
+ | `Version
+ ]
+ let compare = compare
+ end
+ include T
+ module Set = Set.Make(T)
+ module Map = Map.Make(T)
+end
+
+let scan_def acc def =
+ let add have = Have.Map.add have def acc in
+ let has_plugin_pred = List.mem (`Pred "plugin") def.def_preds in
+ let plugin = if has_plugin_pred then `Plugin else `NoPlugin in
+ let modes = [ "byte", `Byte;
+ "native", `Native;
+ "toploop", `Toploop;
+ "preprocessor", `Preprocessor;
+ "ppx_driver", `Ppx_driver
+ ] in
+ let modes =
+ List.filter
+ (fun (p,_) -> List.mem (`Pred p) def.def_preds)
+ modes
+ in
+ let modes = List.map snd modes in
+ match def.def_var, modes with
+ (** For archive the modes are used in multiple ways, so we can't
+ check exhaustiveness or presence.
+ *)
+ | "plugin", [] -> add (`Mode(`None))
+ | "plugin", _::_::_ -> add (`Mode(`TooMany))
+
+ | "archive", [mode] -> add (`Archive(plugin,mode))
+ | "plugin", [mode] -> add (`Plugin(plugin,mode))
+ | "description", _ -> add `Description
+ | "requires", _ -> add `Requires
+ | "version", _ -> add `Version
+ | _ -> acc
+
+
+let warn_def ~warned pkg =
+ let haves =
+ List.fold_left scan_def Have.Map.empty pkg.pkg_defs
+ in
+ let mem x = Have.Map.mem x haves in
+ let find x = Have.Map.find x haves in
+ let warning fmt = warned := true; Printf.printf fmt in
+ let if_ ?has ?(has_not=[]) msg =
+ match has, has_not with
+ | Some has, [] when mem has ->
+ warning "%a%s\n\n" print_def (find has) msg;
+ | Some has, has_not when mem has && not (List.exists mem has_not) ->
+ warning "%a%s\n\n" print_def (find has) msg;
+ | None, has_not when not (List.exists mem has_not) ->
+ warning "%s\n\n" msg;
+ | _ -> ()
+ in
+ if_ ~has_not:[`Description]
+ "You should add a description.";
+ if_ ~has_not:[`Version]
+ "You should add a version.";
+ if_ ~has_not:[`Requires]
+ "You should add the required libraries. You can silent this \
+ warning by using the empty string.";
+ if_ ~has:(`Mode(`TooMany))
+ "This variable should have only one mode
+ (\"byte\", \"native\").";
+ if_ ~has:(`Mode(`None))
+ "This variable should have at least the predicate \
+ \"byte\" or \"native\".";
+ let with_mode mode =
+ if_ ~has:(`Plugin (`Plugin,mode))
+ "You must not add the predicate \"plugin\" to the variable \
+ \"plugin\".";
+ if_ ~has:(`Archive (`Plugin,mode)) ~has_not:[`Plugin (`NoPlugin,mode)]
+ "This specification of dynamic loading is deprecated, you should add a \
+ \"plugin(...)\" variable.";
+ if_ ~has:(`Archive (`NoPlugin,mode))
+ ~has_not:[`Plugin (`NoPlugin,mode);`Archive (`Plugin,mode)]
+ "This variable indicates how to link statically, you should add a \
+ \"plugin(...)\" variable for linking dynamically.";
+ in
+ with_mode `Byte;
+ with_mode `Native
+
+let warn pkg =
+ let warned = ref false in
+ let rec aux pkg =
+ warn_def ~warned pkg;
+ List.iter (fun (_,pkg) -> aux pkg) pkg.pkg_children;
+ in
+ aux pkg;
+ !warned
diff --git a/local-packages/ocamlfind/src/findlib/fl_meta.mll b/local-packages/ocamlfind/src/findlib/fl_meta.mll
new file mode 100644
index 0000000..b0737a1
--- /dev/null
+++ b/local-packages/ocamlfind/src/findlib/fl_meta.mll
@@ -0,0 +1,90 @@
+(* $Id$
+ * ----------------------------------------------------------------------
+ *
+ *)
+
+{ open Fl_metatoken }
+
+rule token =
+ parse [ 'A'-'Z' 'a'-'z' '_' '0'-'9' '.' ]+
+ {
+ Name (Lexing.lexeme lexbuf)
+ }
+
+ | '('
+ {
+ LParen
+ }
+
+ | ')'
+ {
+ RParen
+ }
+
+ | "+="
+ {
+ PlusEqual
+ }
+
+ | '='
+ {
+ Equal
+ }
+
+ | '-'
+ {
+ Minus
+ }
+
+ | ','
+ {
+ Comma
+ }
+
+ | '"' [^ '"' '\\' ]* ( ( "\\\\" | "\\\"" ) [^ '"' '\\' ]* )* '"'
+ {
+ let s1 = Lexing.lexeme lexbuf in
+ let s2 = String.sub s1 1 (String.length s1 - 2) in
+ let l2 = String.length s2 in
+ let b = Buffer.create 80 in
+ let rec fill i =
+ if i Buffer.add_char b s2.[i+1]; fill (i+2)
+ | c -> Buffer.add_char b c; fill (i+1) in
+ fill 0;
+ String (Buffer.contents b)
+ }
+
+ | [ ' ' '\t' '\r' ]
+ {
+ Space
+ }
+
+ | '\n'
+ {
+ Newline
+ }
+
+ | '#' [^ '\n']* '\n'
+ {
+ Newline
+ }
+
+ | '#' [^ '\n']* eof
+ {
+ Eof
+ }
+
+ | eof
+ {
+ Eof
+ }
+
+ | _
+ {
+ Unknown
+ }
+
+{}
+
diff --git a/local-packages/ocamlfind/src/findlib/fl_metascanner.ml b/local-packages/ocamlfind/src/findlib/fl_metascanner.ml
new file mode 100644
index 0000000..2dff2bd
--- /dev/null
+++ b/local-packages/ocamlfind/src/findlib/fl_metascanner.ml
@@ -0,0 +1,310 @@
+(* $Id$ -*- tuareg -*-
+ * ----------------------------------------------------------------------
+ *
+ *)
+open Fl_metatoken
+
+open Printf
+
+type formal_pred = [ | `Pred of string | `NegPred of string ]
+
+type flavour = [ | `BaseDef | `Appendix ]
+
+type pkg_definition =
+ { def_var : string; def_flav : flavour; def_preds : formal_pred list;
+ def_value : string
+ }
+
+type pkg_expr =
+ { pkg_defs : pkg_definition list; pkg_children : (string * pkg_expr) list
+ }
+
+exception Error of string
+
+let string_of_preds pl =
+ let print = function | `Pred n -> n | `NegPred n -> "-" ^ n
+ in
+ if pl = []
+ then ""
+ else "(" ^ ((String.concat "," (List.map print pl)) ^ ")")
+
+
+let scan_lexing buf =
+ (* transform an in_channel to a token stream; 'Space' tokens are left
+ * out.
+ *)
+ let (line_ref, pos0_ref, eof_found) = ((ref 1), (ref 0), (ref false))
+ in
+ fun () ->
+ let rec next line pos0 =
+ let t = Fl_meta.token buf
+ in
+ match t with
+ | Space -> next line pos0
+ | Newline -> next (line + 1) (Lexing.lexeme_end buf)
+ | Eof -> (eof_found := true; produce line pos0 Eof)
+ | _ -> produce line pos0 t
+ and produce line pos0 t =
+ (line_ref := line;
+ pos0_ref := pos0;
+ let pos = (Lexing.lexeme_start buf) - pos0 in (line, pos, t))
+ in
+ if !eof_found
+ then produce !line_ref !pos0_ref Eof
+ else next !line_ref !pos0_ref
+
+let scan ch = scan_lexing (Lexing.from_channel ch)
+
+let parse_lexing lexbuf =
+ let rec mk_set l =
+ match l with
+ | x :: l' -> if List.mem x l' then mk_set l' else x :: (mk_set l')
+ | [] -> [] in
+ let error_msg msg line col =
+ Printf.sprintf "%s at line %d position %d" msg line col in
+ let next_token = scan_lexing lexbuf in
+ let raise_err error_fun line col =
+ raise (Error (error_fun line col)) in
+ let get_tok test error_fun =
+ let (line, col, tok) = next_token ()
+ in
+ match test tok with
+ | None -> raise_err error_fun line col
+ | Some result -> result in
+ let get_rule rule arg error_fmt line col =
+ try rule arg with | Error _ -> raise_err error_fmt line col in
+ let rec parse_all need_rparen =
+ match next_token () with
+ | (line, col, Name "package") ->
+ let n =
+ get_tok string_tok
+ (error_msg "String literal expected after 'package'") in
+ let () =
+ get_tok (const_tok LParen) (error_msg "'(' expected after string") in
+ let subpkg =
+ get_rule parse_all true
+ (error_msg "Error in subpackage definition") line col in
+ let rest = parse_all need_rparen
+ in
+ {
+ pkg_defs = rest.pkg_defs;
+ pkg_children = (n, subpkg) :: rest.pkg_children;
+ }
+ | (line, col, Name n) ->
+ let (args, flav, value) =
+ get_rule parse_properties ()
+ (error_msg "Error in 'name = value' clause") line col in
+ let rest = parse_all need_rparen in (* TODO: Check args *)
+ let args' = List.sort compare (mk_set args) in
+ let def =
+ {
+ def_var = n;
+ def_flav = flav;
+ def_preds = args';
+ def_value = value;
+ }
+ in
+ {
+ pkg_defs = def :: rest.pkg_defs;
+ pkg_children = rest.pkg_children;
+ }
+ | (line, col, Eof) ->
+ (if need_rparen
+ then
+ raise_err
+ (Printf.sprintf "Unexpected end of file in line %d position %d")
+ line col
+ else ();
+ { pkg_defs = []; pkg_children = []; })
+ | (line, col, RParen) ->
+ (if not need_rparen
+ then
+ raise_err
+ (Printf.sprintf "Unexpected end of file in line %d position %d")
+ line col
+ else ();
+ { pkg_defs = []; pkg_children = []; })
+ | (line, col, _) ->
+ raise_err (error_msg "Expected 'name = value' clause") line col
+ and parse_properties () =
+ match next_token () with
+ | (line, col, LParen) ->
+ let arg1 = parse_argument () in
+ let args = parse_arguments () in
+ let flav = parse_flavour () in
+ let s =
+ get_tok string_tok (error_msg "Expected string constant after '='")
+ in ((arg1 :: args), flav, s)
+ | (line, col, Equal) ->
+ let s =
+ get_tok string_tok
+ (error_msg "'=' must be followed by a string constant")
+ in ([], `BaseDef, s)
+ | (line, col, PlusEqual) ->
+ let s =
+ get_tok string_tok
+ (error_msg "'+=' must be followed by a string constant")
+ in ([], `Appendix, s)
+ | (line, col, _) ->
+ raise_err (error_msg "Expected a '=' or a '(arguments,...)=' clause")
+ line col
+ and parse_arguments () =
+ match next_token () with
+ | (line, col, Comma) ->
+ let arg = parse_argument () in
+ let args = parse_arguments () in arg :: args
+ | (_, _, RParen) -> []
+ | (line, col, _) ->
+ raise_err (error_msg "Another predicate or a ')' expected") line col
+ and parse_argument () =
+ match next_token () with
+ | (line, col, Name n) -> `Pred n
+ | (line, col, Minus) ->
+ let n = get_tok name_tok (error_msg "Name expected after '-'")
+ in `NegPred n
+ | (line, col, _) ->
+ raise_err (error_msg "Name or -Name expected") line col
+ and parse_flavour () =
+ match next_token () with
+ | (line, col, Equal) -> `BaseDef
+ | (line, col, PlusEqual) -> `Appendix
+ | (line, col, _) -> raise_err (error_msg "'+' or '+=' expected") line col in
+ let rec check_defs p l =
+ match l with
+ | [] -> ()
+ | def :: l' ->
+ (List.iter
+ (fun def' ->
+ if
+ (def.def_var = def'.def_var) &&
+ ((def.def_preds = def'.def_preds) &&
+ ((def.def_flav = `BaseDef) && (def'.def_flav = `BaseDef)))
+ then
+ (let prefix =
+ if p = "" then "" else "In subpackage " ^ (p ^ ": ") in
+ let args = string_of_preds def.def_preds
+ in
+ raise
+ (Error
+ (prefix ^
+ ("Double definition of '" ^
+ (def.def_var ^ (args ^ "'"))))))
+ else ())
+ l';
+ check_defs p l') in
+ let rec check_pkg p pkg =
+ (check_defs p pkg.pkg_defs;
+ let l = ref []
+ in
+ List.iter
+ (fun (n, subpkg) ->
+ let p' = if p = "" then n else p ^ ("." ^ n)
+ in
+ (if List.mem n !l
+ then
+ raise
+ (Error ("Double definition for subpackage " ^ p'))
+ else ();
+ if String.contains n '.'
+ then
+ raise
+ (Error
+ ("Subpackage name must not contain '.': \"" ^
+ (n ^ "\"")))
+ else ();
+ check_pkg p' subpkg;
+ l := n :: !l))
+ pkg.pkg_children)
+ in
+ try let pkg = parse_all false in (check_pkg "" pkg; pkg)
+ with | Error "" -> raise (Error "Syntax Error")
+
+let parse ch = parse_lexing (Lexing.from_channel ch)
+
+let escape s = (* no Str available :-( *)
+ let b = Buffer.create (String.length s)
+ in
+ (for k = 0 to (String.length s) - 1 do
+ (match s.[k] with
+ | '\\' -> Buffer.add_string b "\\\\"
+ | '"' -> Buffer.add_string b "\\\""
+ | c -> Buffer.add_char b c)
+ done;
+ Buffer.contents b)
+
+let print_def f def =
+ let format_pred = function | `Pred s -> s | `NegPred s -> "-" ^ s in
+ fprintf f "%s%s %s \"%s\"\n" def.def_var
+ (match def.def_preds with
+ | [] -> ""
+ | l -> "(" ^ ((String.concat "," (List.map format_pred l)) ^ ")"))
+ (match def.def_flav with | `BaseDef -> "=" | `Appendix -> "+=")
+ (escape def.def_value)
+
+
+let rec print f pkg =
+ (List.iter (print_def f) pkg.pkg_defs;
+ List.iter
+ (fun (name, child) ->
+ (fprintf f "\npackage \"%s\" (\n" (escape name);
+ print f child;
+ fprintf f ")\n"))
+ pkg.pkg_children)
+
+let rec remove_dups l =
+ (* FIXME: O(n^2) *)
+ match l with
+ x :: l' ->
+ if List.mem x l' then remove_dups l' else x::remove_dups l'
+ | [] -> []
+
+let lookup_2 name predicate_list def =
+ let fulfills actual_preds formal_preds =
+ List.for_all
+ (function
+ | `Pred n -> List.mem n predicate_list
+ | `NegPred n -> not (List.mem n predicate_list))
+ formal_preds in
+ let rec search_base best_n best_value l =
+ match l with
+ | [] -> if best_n >= 0 then best_value else raise Not_found
+ | def :: l' ->
+ if
+ (name = def.def_var) &&
+ ((def.def_flav = `BaseDef) &&
+ ((fulfills predicate_list def.def_preds) &&
+ ((List.length def.def_preds) > best_n)))
+ then search_base
+ (List.length def.def_preds)
+ (def.def_value, def.def_preds)
+ l'
+ else search_base best_n best_value l' in
+ let rec search_appdx l =
+ match l with
+ | [] -> []
+ | def :: l' ->
+ if
+ (name = def.def_var) &&
+ ((def.def_flav = `Appendix) &&
+ (fulfills predicate_list def.def_preds))
+ then (def.def_value, def.def_preds) :: (search_appdx l')
+ else search_appdx l' in
+ let value_a, preds_a = search_base (-1) ("",[]) def in
+ let additions = search_appdx def in
+ let values_b = List.map fst additions in
+ let preds_b = List.flatten (List.map snd additions) in
+ let value = String.concat " " (value_a :: values_b) in
+ let preds = remove_dups (preds_a @ preds_b) in
+ (value, preds)
+
+let lookup name predicate_list def =
+ fst(lookup_2 name predicate_list def)
+
+let predicate_exists p defs =
+ List.exists
+ (fun def ->
+ List.exists (function | `Pred n -> n = p | `NegPred n -> n = p)
+ def.def_preds)
+ defs
+
+
diff --git a/local-packages/ocamlfind/src/findlib/fl_metascanner.mli b/local-packages/ocamlfind/src/findlib/fl_metascanner.mli
new file mode 100644
index 0000000..903f4f8
--- /dev/null
+++ b/local-packages/ocamlfind/src/findlib/fl_metascanner.mli
@@ -0,0 +1,107 @@
+(* $Id$
+ * ----------------------------------------------------------------------
+ *
+ *)
+
+(** Parses META files *)
+
+open Fl_metatoken
+
+type formal_pred =
+ [ `Pred of string (** Positive occurence of a formal predicate var *)
+ | `NegPred of string (** Negative occurence of a formal predicate var *)
+ ]
+
+type flavour =
+ [ `BaseDef
+ | `Appendix
+ ]
+ (** [`BaseDef] refers to META definitions using the "=" operator,
+ * and [`Appendix] refers to definitions using the "+=" operator.
+ *)
+
+type pkg_definition =
+ { def_var : string; (** The name of the defined variable *)
+ def_flav : flavour; (** The flavour of the definition *)
+ def_preds : formal_pred list; (** The formal predicates of the def *)
+ def_value : string; (** The value assigned to the variable *)
+ }
+ (** A [pkg_definition] is expressed by the syntax
+ * {[ var(p1,p2,...) = "value" ]} (flavour `BaseDef),
+ * or the syntax
+ * {[ var(p1,p2,...) += "value" ]} (flavour `Appendix)
+ * in the META file. The list of predicates may be omitted. Predicates
+ * may be negated by using "-", e.g. "-x".
+ *)
+
+type pkg_expr =
+ { pkg_defs : pkg_definition list;
+ pkg_children : (string * pkg_expr) list;
+ }
+ (** A value of type [pkg_expr] denotes the contents of a META file.
+ * The component [pkg_defs] are the variable definitions.
+ * The component [pkg_children] contains
+ * the definitions of the subpackages.
+ *)
+
+exception Error of string
+
+
+val parse : in_channel -> pkg_expr
+ (** [parse ch:]
+ * scans and parses the file connected with channel [ch]. The file must
+ * have a syntax compatible with the META format. The return value
+ * contains the found definitions for the package and all subpackages.
+ *
+ * [exception Error of string:] is
+ * raised on syntax errors. The string explains the error.
+ *)
+
+val parse_lexing : Lexing.lexbuf -> pkg_expr
+
+
+val print_def : out_channel -> pkg_definition -> unit
+ (** [print_def ch def]:
+ * Outputs the definition to a channel.
+ *)
+
+val print : out_channel -> pkg_expr -> unit
+ (** [print ch expr]:
+ * Outputs the package expression to a channel.
+ *)
+
+
+val lookup :
+ string -> string list -> pkg_definition list -> string
+ (** [lookup variable_name predicate_list def]:
+ *
+ * Returns the value of [variable_name] in [def] under the assumption
+ * that the predicates in [predicate_list] hold, but no other predicates.
+ *
+ * The rules are as follows: In the step (A), only the [`BaseDef]
+ * definitions are considered. The first base definition is determined where
+ * all predicates are satisfied and that has the longest predicate list.
+ * In the step (B) only the [`Appendix] definitions are considered.
+ * All definitions are determined where all predicates are satisfied.
+ * The final result is the concatenation of the single result of (A)
+ * and all results of (B) (in the order they are defined). A space
+ * character is inserted between two concatenated strings.
+ *
+ * When step (A) does not find any matching definition, the exception
+ * [Not_found] is raised.
+ *)
+
+
+val lookup_2 :
+ string -> string list -> pkg_definition list -> string * formal_pred list
+ (** Like [lookup], but also returns the list of predicates that had to
+ be considered to select the particular variable definition.
+ *)
+
+
+val predicate_exists :
+ string -> pkg_definition list -> bool
+ (** [predicate_exists variable_name def]:
+
+ Whether [variable_name] is explicitly mentioned in [def].
+ *)
diff --git a/local-packages/ocamlfind/src/findlib/fl_metatoken.ml b/local-packages/ocamlfind/src/findlib/fl_metatoken.ml
new file mode 100644
index 0000000..6a2483f
--- /dev/null
+++ b/local-packages/ocamlfind/src/findlib/fl_metatoken.ml
@@ -0,0 +1,37 @@
+(* $Id$
+ * ----------------------------------------------------------------------
+ *
+ *)
+
+
+type token =
+ Name of string
+ | LParen
+ | RParen
+ | Equal
+ | PlusEqual
+ | Minus
+ | Comma
+ | String of string
+ | Space
+ | Newline
+ | Eof
+ | Unknown
+;;
+
+
+let name_tok = function
+ | Name s -> Some s
+ | _ -> None
+
+let string_tok = function
+ | String s -> Some s
+ | _ -> None
+
+let const_tok constant tok =
+ match constant with
+ | Name _ | String _ -> failwith "expect: only for constant tokens"
+ | LParen | RParen | Equal | PlusEqual | Minus
+ | Comma | Space | Newline | Eof | Unknown ->
+ if constant = tok then Some ()
+ else None
diff --git a/local-packages/ocamlfind/src/findlib/fl_ocaml_args.ml b/local-packages/ocamlfind/src/findlib/fl_ocaml_args.ml
new file mode 100644
index 0000000..f1d38c5
--- /dev/null
+++ b/local-packages/ocamlfind/src/findlib/fl_ocaml_args.ml
@@ -0,0 +1,2623 @@
+let ocamlc_spec = Some [
+ "-a",
+ false,
+ " Build a library";
+
+ "-alert",
+ true,
+ " Enable or disable alerts according to :\n + enable alert \n - disable alert \n ++ treat as fatal error";
+
+ "--",
+ true,
+ " treat as non-fatal\n @ enable and treat it as fatal error\n can be 'all' to refer to all alert names";
+
+ "-absname",
+ false,
+ " Show absolute filenames in error messages";
+
+ "-annot",
+ false,
+ " Save information in .annot";
+
+ "-assume-require",
+ true,
+ " for linking, assume is required and already looked up";
+
+ "-bin-annot",
+ false,
+ " Save typedtree in .cmt";
+
+ "-c",
+ false,
+ " Compile only (do not link)";
+
+ "-cc",
+ true,
+ " Use as the C compiler and linker";
+
+ "-cclib",
+ true,
+ " Pass option to the C linker";
+
+ "-ccopt",
+ true,
+ " Pass option to the C compiler and linker";
+
+ "-color",
+ true,
+ "{auto|always|never} Enable or disable colors in compiler messages\n The following settings are supported:\n auto use heuristics to enable colors only if supported\n always enable colors\n never disable colors\n The default setting is 'auto', and the current heuristic\n checks that the TERM environment variable exists and is\n not empty or \"dumb\", and that isatty(stderr) holds.\n If the option is not specified, these setting can alternatively\n be set through the OCAML_COLOR environment variable.";
+
+ "-error-style",
+ true,
+ "{contextual|short} Control the way error messages and warnings are printed\n The following settings are supported:\n short only print the error and its location\n contextual like \"short\", but also display the source code\n snippet corresponding to the location of the error\n The default setting is 'contextual'.\n If the option is not specified, these setting can alternatively\n be set through the OCAML_ERROR_STYLE environment variable.";
+
+ "-compat-32",
+ false,
+ " Check that generated bytecode can run on 32-bit platforms";
+
+ "-config",
+ false,
+ " Print configuration values and exit";
+
+ "-config-var",
+ false,
+ " Print the value of a configuration variable, a newline, and exit\n (print nothing and exit with error value if the variable does not exist)";
+
+ "-custom",
+ false,
+ " Link in custom mode";
+
+ "-dllib",
+ true,
+ " Use the dynamically-loaded library ";
+
+ "-dllpath",
+ true,
+ " Add to the run-time search path for shared libraries";
+
+ "-dtypes",
+ false,
+ " (deprecated) same as -annot";
+
+ "-for-pack",
+ true,
+ " Generate code that can later be `packed' with\n ocamlc -pack -o .cmo";
+
+ "-g",
+ false,
+ " Save debugging information";
+
+ "-stop-after",
+ true,
+ "{parsing|typing} Stop after the given compilation pass.";
+
+ "-i",
+ false,
+ " Print inferred interface";
+
+ "-I",
+ true,
+ " Add to the list of include directories";
+
+ "-impl",
+ true,
+ " Compile as a .ml file";
+
+ "-intf",
+ true,
+ " Compile as a .mli file";
+
+ "-intf-suffix",
+ true,
+ " Suffix for interface files (default: .mli)";
+
+ "-intf_suffix",
+ true,
+ " (deprecated) same as -intf-suffix";
+
+ "-keep-docs",
+ false,
+ " Keep documentation strings in .cmi files";
+
+ "-no-keep-docs",
+ false,
+ " Do not keep documentation strings in .cmi files (default)";
+
+ "-keep-locs",
+ false,
+ " Keep locations in .cmi files (default)";
+
+ "-no-keep-locs",
+ false,
+ " Do not keep locations in .cmi files";
+
+ "-labels",
+ false,
+ " Use commuting label mode";
+
+ "-linkall",
+ false,
+ " Link all modules, even unused ones";
+
+ "-make-runtime",
+ false,
+ " Build a runtime system with given C objects and libraries";
+
+ "-make_runtime",
+ false,
+ " (deprecated) same as -make-runtime";
+
+ "-modern",
+ false,
+ " (deprecated) same as -labels";
+
+ "-alias-deps",
+ false,
+ " Do record dependencies for module aliases";
+
+ "-no-alias-deps",
+ false,
+ " Do not record dependencies for module aliases";
+
+ "-app-funct",
+ false,
+ " Activate applicative functors";
+
+ "-no-app-funct",
+ false,
+ " Deactivate applicative functors";
+
+ "-no-check-prims",
+ false,
+ " Do not check runtime for primitives";
+
+ "-noassert",
+ false,
+ " Do not compile assertion checks";
+
+ "-noautoliblink",
+ false,
+ " Do not automatically link OCaml libraries specified in .cma files";
+
+ "-noautolink",
+ false,
+ " Do not automatically link C libraries specified in .cma files";
+
+ "-nolabels",
+ false,
+ " Ignore non-optional labels in types";
+
+ "-nostdlib",
+ false,
+ " Do not add default directory to the list of include directories";
+
+ "-nopervasives",
+ false,
+ " (undocumented)";
+
+ "-o",
+ true,
+ " Set output file name to ";
+
+ "-opaque",
+ false,
+ " Does not generate cross-module optimization information\n (reduces necessary recompilation on module change)";
+
+ "-open",
+ true,
+ " Opens the module before typing";
+
+ "-output-obj",
+ false,
+ " Output an object file instead of an executable";
+
+ "-output-complete-obj",
+ false,
+ " Output an object file, including runtime, instead of an executable";
+
+ "-output-complete-exe",
+ false,
+ " Output a self-contained executable, including runtime and C stubs";
+
+ "-pack",
+ false,
+ " Package the given .cmo files into one .cmo";
+
+ "-pp",
+ true,
+ " Pipe sources through preprocessor ";
+
+ "-ppx",
+ true,
+ " Pipe abstract syntax trees through preprocessor ";
+
+ "-plugin",
+ true,
+ " (no longer supported)";
+
+ "-principal",
+ false,
+ " Check principality of type inference";
+
+ "-no-principal",
+ false,
+ " Do not check principality of type inference (default)";
+
+ "-rectypes",
+ false,
+ " Allow arbitrary recursive types";
+
+ "-no-rectypes",
+ false,
+ " Do not allow arbitrary recursive types (default)";
+
+ "-require",
+ true,
+ " Add to the list of required libraries";
+
+ "-runtime-variant",
+ true,
+ " Use the variant of the run-time system";
+
+ "-with-runtime",
+ false,
+ "Include the runtime system in the generated program (default)";
+
+ "-without-runtime",
+ false,
+ "Do not include the runtime system in the generated program.";
+
+ "-safe-string",
+ false,
+ " (was set when configuring the compiler)";
+
+ "-short-paths",
+ false,
+ " Shorten paths in types";
+
+ "-strict-sequence",
+ false,
+ " Left-hand part of a sequence must have type unit";
+
+ "-no-strict-sequence",
+ false,
+ " Left-hand part of a sequence need not have type unit (default)";
+
+ "-strict-formats",
+ false,
+ " Reject invalid formats accepted by legacy implementations\n (Warning: Invalid formats may behave differently from\n previous OCaml versions, and will become always-rejected\n in future OCaml versions. You should always use this flag\n to detect invalid formats so you can fix them.)";
+
+ "-no-strict-formats",
+ false,
+ " Accept invalid formats accepted by legacy implementations (default)\n (Warning: Invalid formats may behave differently from\n previous OCaml versions, and will become always-rejected\n in future OCaml versions. You should never use this flag\n and instead fix invalid formats.)";
+
+ "-thread",
+ false,
+ " (deprecated) same as -I +threads";
+
+ "-unboxed-types",
+ false,
+ " unannotated unboxable types will be unboxed";
+
+ "-no-unboxed-types",
+ false,
+ " unannotated unboxable types will not be unboxed (default)";
+
+ "-unsafe",
+ false,
+ " Do not compile bounds checking on array and string access";
+
+ "-unsafe-string",
+ false,
+ " (option not available)";
+
+ "-use-runtime",
+ true,
+ " Generate bytecode for the given runtime system";
+
+ "-use_runtime",
+ true,
+ " (deprecated) same as -use-runtime";
+
+ "-v",
+ false,
+ " Print compiler version and location of standard library and exit";
+
+ "-verbose",
+ false,
+ " Print calls to external commands";
+
+ "-version",
+ false,
+ " Print version and exit";
+
+ "--version",
+ false,
+ " Print version and exit";
+
+ "-vmthread",
+ false,
+ " (no longer supported)";
+
+ "-vnum",
+ false,
+ " Print version number and exit";
+
+ "-w",
+ true,
+ " Enable or disable warnings according to :\n + enable warnings in \n - disable warnings in \n @ enable warnings in and treat them as errors\n can be:\n a single warning number\n .. a range of consecutive warning numbers\n a predefined set\n default setting is \"+a-4-6-7-9-27-29-30-32..42-44-45-48-50-60-66-67\"";
+
+ "-warn-error",
+ true,
+ " Enable or disable error status for warnings according\n to . See option -w for the syntax of .\n Default setting is \"-a+31\"";
+
+ "-warn-help",
+ false,
+ " Show description of warning numbers";
+
+ "-where",
+ false,
+ " Print location of standard library and exit";
+
+ "-",
+ true,
+ " Treat as a file name (even if it starts with `-')";
+
+ "-match-context-rows",
+ true,
+ " (advanced, see manual section 9.2.)";
+
+ "-use-prims",
+ true,
+ " (undocumented)";
+
+ "-dno-unique-ids",
+ false,
+ " (undocumented)";
+
+ "-dunique-ids",
+ false,
+ " (undocumented)";
+
+ "-dno-locations",
+ false,
+ " (undocumented)";
+
+ "-dlocations",
+ false,
+ " (undocumented)";
+
+ "-dsource",
+ false,
+ " (undocumented)";
+
+ "-dparsetree",
+ false,
+ " (undocumented)";
+
+ "-dtypedtree",
+ false,
+ " (undocumented)";
+
+ "-drawlambda",
+ false,
+ " (undocumented)";
+
+ "-dlambda",
+ false,
+ " (undocumented)";
+
+ "-dinstr",
+ false,
+ " (undocumented)";
+
+ "-dcamlprimc",
+ false,
+ " (undocumented)";
+
+ "-dtimings",
+ false,
+ " Print timings information for each pass";
+
+ "-dprofile",
+ false,
+ " Print performance information for each pass\n The columns are: time alloc top-heap absolute-top-heap.";
+
+ "-dump-into-file",
+ false,
+ " dump output like -dlambda into .dump";
+
+ "-args",
+ true,
+ " Read additional newline-terminated command line arguments\n from ";
+
+ "-args0",
+ true,
+ " Read additional null character terminated command line arguments\nfrom ";
+
+ "-depend",
+ true,
+ " Compute dependencies (use 'ocamlc -depend -help' for details)";
+
+];;
+
+let ocamlcp_spec = Some [
+ "-P",
+ true,
+ "[afilmt] Profile constructs specified by argument (default fm):\n a Everything\n f Function calls and method calls\n i if ... then ... else\n l while and for loops\n m match ... with\n t try ... with";
+
+ "-p",
+ true,
+ "[afilmt] Same as option -P";
+
+ "-a",
+ false,
+ " Build a library";
+
+ "-alert",
+ true,
+ " Enable or disable alerts according to :\n + enable alert \n - disable alert \n ++ treat as fatal error";
+
+ "--",
+ true,
+ " treat as non-fatal\n @ enable and treat it as fatal error\n can be 'all' to refer to all alert names";
+
+ "-absname",
+ false,
+ " Show absolute filenames in error messages";
+
+ "-annot",
+ false,
+ " Save information in .annot";
+
+ "-assume-require",
+ true,
+ " for linking, assume is required and already looked up";
+
+ "-bin-annot",
+ false,
+ " Save typedtree in .cmt";
+
+ "-c",
+ false,
+ " Compile only (do not link)";
+
+ "-cc",
+ true,
+ " Use as the C compiler and linker";
+
+ "-cclib",
+ true,
+ " Pass option to the C linker";
+
+ "-ccopt",
+ true,
+ " Pass option to the C compiler and linker";
+
+ "-color",
+ true,
+ "{auto|always|never} Enable or disable colors in compiler messages\n The following settings are supported:\n auto use heuristics to enable colors only if supported\n always enable colors\n never disable colors\n The default setting is 'auto', and the current heuristic\n checks that the TERM environment variable exists and is\n not empty or \"dumb\", and that isatty(stderr) holds.\n If the option is not specified, these setting can alternatively\n be set through the OCAML_COLOR environment variable.";
+
+ "-error-style",
+ true,
+ "{contextual|short} Control the way error messages and warnings are printed\n The following settings are supported:\n short only print the error and its location\n contextual like \"short\", but also display the source code\n snippet corresponding to the location of the error\n The default setting is 'contextual'.\n If the option is not specified, these setting can alternatively\n be set through the OCAML_ERROR_STYLE environment variable.";
+
+ "-compat-32",
+ false,
+ " Check that generated bytecode can run on 32-bit platforms";
+
+ "-config",
+ false,
+ " Print configuration values and exit";
+
+ "-config-var",
+ false,
+ " Print the value of a configuration variable, a newline, and exit\n (print nothing and exit with error value if the variable does not exist)";
+
+ "-custom",
+ false,
+ " Link in custom mode";
+
+ "-dllib",
+ true,
+ " Use the dynamically-loaded library ";
+
+ "-dllpath",
+ true,
+ " Add to the run-time search path for shared libraries";
+
+ "-dtypes",
+ false,
+ " (deprecated) same as -annot";
+
+ "-for-pack",
+ true,
+ " Generate code that can later be `packed' with\n ocamlc -pack -o .cmo";
+
+ "-g",
+ false,
+ " Save debugging information";
+
+ "-stop-after",
+ true,
+ "{parsing|typing} Stop after the given compilation pass.";
+
+ "-i",
+ false,
+ " Print inferred interface";
+
+ "-I",
+ true,
+ " Add to the list of include directories";
+
+ "-impl",
+ true,
+ " Compile as a .ml file";
+
+ "-intf",
+ true,
+ " Compile as a .mli file";
+
+ "-intf-suffix",
+ true,
+ " Suffix for interface files (default: .mli)";
+
+ "-intf_suffix",
+ true,
+ " (deprecated) same as -intf-suffix";
+
+ "-keep-docs",
+ false,
+ " Keep documentation strings in .cmi files";
+
+ "-no-keep-docs",
+ false,
+ " Do not keep documentation strings in .cmi files (default)";
+
+ "-keep-locs",
+ false,
+ " Keep locations in .cmi files (default)";
+
+ "-no-keep-locs",
+ false,
+ " Do not keep locations in .cmi files";
+
+ "-labels",
+ false,
+ " Use commuting label mode";
+
+ "-linkall",
+ false,
+ " Link all modules, even unused ones";
+
+ "-make-runtime",
+ false,
+ " Build a runtime system with given C objects and libraries";
+
+ "-make_runtime",
+ false,
+ " (deprecated) same as -make-runtime";
+
+ "-modern",
+ false,
+ " (deprecated) same as -labels";
+
+ "-alias-deps",
+ false,
+ " Do record dependencies for module aliases";
+
+ "-no-alias-deps",
+ false,
+ " Do not record dependencies for module aliases";
+
+ "-app-funct",
+ false,
+ " Activate applicative functors";
+
+ "-no-app-funct",
+ false,
+ " Deactivate applicative functors";
+
+ "-no-check-prims",
+ false,
+ " Do not check runtime for primitives";
+
+ "-noassert",
+ false,
+ " Do not compile assertion checks";
+
+ "-noautoliblink",
+ false,
+ " Do not automatically link OCaml libraries specified in .cma files";
+
+ "-noautolink",
+ false,
+ " Do not automatically link C libraries specified in .cma files";
+
+ "-nolabels",
+ false,
+ " Ignore non-optional labels in types";
+
+ "-nostdlib",
+ false,
+ " Do not add default directory to the list of include directories";
+
+ "-nopervasives",
+ false,
+ " (undocumented)";
+
+ "-o",
+ true,
+ " Set output file name to ";
+
+ "-opaque",
+ false,
+ " Does not generate cross-module optimization information\n (reduces necessary recompilation on module change)";
+
+ "-open",
+ true,
+ " Opens the module before typing";
+
+ "-output-obj",
+ false,
+ " Output an object file instead of an executable";
+
+ "-output-complete-obj",
+ false,
+ " Output an object file, including runtime, instead of an executable";
+
+ "-output-complete-exe",
+ false,
+ " Output a self-contained executable, including runtime and C stubs";
+
+ "-pack",
+ false,
+ " Package the given .cmo files into one .cmo";
+
+ "-pp",
+ true,
+ " Pipe sources through preprocessor ";
+
+ "-ppx",
+ true,
+ " Pipe abstract syntax trees through preprocessor ";
+
+ "-plugin",
+ true,
+ " (no longer supported)";
+
+ "-principal",
+ false,
+ " Check principality of type inference";
+
+ "-no-principal",
+ false,
+ " Do not check principality of type inference (default)";
+
+ "-rectypes",
+ false,
+ " Allow arbitrary recursive types";
+
+ "-no-rectypes",
+ false,
+ " Do not allow arbitrary recursive types (default)";
+
+ "-require",
+ true,
+ " Add to the list of required libraries";
+
+ "-runtime-variant",
+ true,
+ " Use the variant of the run-time system";
+
+ "-with-runtime",
+ false,
+ "Include the runtime system in the generated program (default)";
+
+ "-without-runtime",
+ false,
+ "Do not include the runtime system in the generated program.";
+
+ "-safe-string",
+ false,
+ " (was set when configuring the compiler)";
+
+ "-short-paths",
+ false,
+ " Shorten paths in types";
+
+ "-strict-sequence",
+ false,
+ " Left-hand part of a sequence must have type unit";
+
+ "-no-strict-sequence",
+ false,
+ " Left-hand part of a sequence need not have type unit (default)";
+
+ "-strict-formats",
+ false,
+ " Reject invalid formats accepted by legacy implementations\n (Warning: Invalid formats may behave differently from\n previous OCaml versions, and will become always-rejected\n in future OCaml versions. You should always use this flag\n to detect invalid formats so you can fix them.)";
+
+ "-no-strict-formats",
+ false,
+ " Accept invalid formats accepted by legacy implementations (default)\n (Warning: Invalid formats may behave differently from\n previous OCaml versions, and will become always-rejected\n in future OCaml versions. You should never use this flag\n and instead fix invalid formats.)";
+
+ "-thread",
+ false,
+ " (deprecated) same as -I +threads";
+
+ "-unboxed-types",
+ false,
+ " unannotated unboxable types will be unboxed";
+
+ "-no-unboxed-types",
+ false,
+ " unannotated unboxable types will not be unboxed (default)";
+
+ "-unsafe",
+ false,
+ " Do not compile bounds checking on array and string access";
+
+ "-unsafe-string",
+ false,
+ " (option not available)";
+
+ "-use-runtime",
+ true,
+ " Generate bytecode for the given runtime system";
+
+ "-use_runtime",
+ true,
+ " (deprecated) same as -use-runtime";
+
+ "-v",
+ false,
+ " Print compiler version and location of standard library and exit";
+
+ "-verbose",
+ false,
+ " Print calls to external commands";
+
+ "-version",
+ false,
+ " Print version and exit";
+
+ "--version",
+ false,
+ " Print version and exit";
+
+ "-vmthread",
+ false,
+ " (no longer supported)";
+
+ "-vnum",
+ false,
+ " Print version number and exit";
+
+ "-w",
+ true,
+ " Enable or disable warnings according to :\n + enable warnings in \n - disable warnings in \n @ enable warnings in and treat them as errors\n can be:\n a single warning number\n .. a range of consecutive warning numbers\n a predefined set\n default setting is \"+a-4-6-7-9-27-29-30-32..42-44-45-48-50-60-66-67\"";
+
+ "-warn-error",
+ true,
+ " Enable or disable error status for warnings according\n to . See option -w for the syntax of .\n Default setting is \"-a+31\"";
+
+ "-warn-help",
+ false,
+ " Show description of warning numbers";
+
+ "-where",
+ false,
+ " Print location of standard library and exit";
+
+ "-",
+ true,
+ " Treat as a file name (even if it starts with `-')";
+
+ "-match-context-rows",
+ true,
+ " (advanced, see manual section 9.2.)";
+
+ "-use-prims",
+ true,
+ " (undocumented)";
+
+ "-dno-unique-ids",
+ false,
+ " (undocumented)";
+
+ "-dunique-ids",
+ false,
+ " (undocumented)";
+
+ "-dno-locations",
+ false,
+ " (undocumented)";
+
+ "-dlocations",
+ false,
+ " (undocumented)";
+
+ "-dsource",
+ false,
+ " (undocumented)";
+
+ "-dparsetree",
+ false,
+ " (undocumented)";
+
+ "-dtypedtree",
+ false,
+ " (undocumented)";
+
+ "-drawlambda",
+ false,
+ " (undocumented)";
+
+ "-dlambda",
+ false,
+ " (undocumented)";
+
+ "-dinstr",
+ false,
+ " (undocumented)";
+
+ "-dcamlprimc",
+ false,
+ " (undocumented)";
+
+ "-dtimings",
+ false,
+ " Print timings information for each pass";
+
+ "-dprofile",
+ false,
+ " Print performance information for each pass\n The columns are: time alloc top-heap absolute-top-heap.";
+
+ "-dump-into-file",
+ false,
+ " dump output like -dlambda into .dump";
+
+ "-args",
+ true,
+ " Read additional newline-terminated command line arguments\n from ";
+
+ "-args0",
+ true,
+ " Read additional null character terminated command line arguments\nfrom ";
+
+];;
+
+let ocamloptp_spec = None;;
+
+let ocamlmklib_spec = Some [
+ "-args",
+ true,
+ "