(* * Install - ExtLib installation * Copyright (C) 2003 Nicolas Cannasse * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version, * with the special exception on linking described in file LICENSE. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *) open Printf type path = | PathUnix | PathDos let modules = [ "enum"; "bitSet"; "dynArray"; "extArray"; "extHashtbl"; "extList"; "extString"; "global"; "IO"; "option"; "pMap"; "std"; "uChar"; "uTF8"; "base64"; "unzip"; "refList"; "optParse"; "dllist"; ] let m_list suffix = String.concat " " (List.map (fun m -> m ^ suffix) modules) let obj_ext , lib_ext , cp_cmd , path_type = match Sys.os_type with | "Unix" | "Cygwin" | "MacOS" -> ".o" , ".a" , "cp", PathUnix | "Win32" -> ".obj" , ".lib" , "copy", PathDos | _ -> failwith "Unknown OS" let run cmd = print_endline cmd; let ecode = Sys.command cmd in if ecode <> 0 then failwith (sprintf "Exit Code %d - Stopped" ecode) let copy file dest = if dest <> "" && dest <> "." then begin print_endline ("Installing " ^ file); let path = dest ^ file in (try Sys.remove path with _ -> ()); try Sys.rename file path; with _ -> failwith "Aborted" end let complete_path p = if p = "" then p else let c = p.[String.length p - 1] in if c = '/' || c = '\\' then p else p ^ (match path_type with PathUnix -> "/" | PathDos -> "\\") let remove file = try Sys.remove file with _ -> prerr_endline ("Warning : failed to delete " ^ file) let is_findlib() = let findlib = Sys.command (if Sys.os_type = "Win32" then "ocamlfind printconf 2>NUL" else "ocamlfind printconf") = 0 in if findlib then print_endline "Using Findlib"; findlib type install_dir = Findlib | Dir of string let install() = let autodir = ref None in let docflag = ref None in let autodoc = ref false in let autobyte = ref false in let autonative = ref false in let usage = "ExtLib installation program v1.3\n(c)2003,2004 Nicolas Cannasse" in Arg.parse [ ("-d", Arg.String (fun s -> autodir := Some s) , " : install in target directory"); ("-b", Arg.Unit (fun () -> autobyte := true) , ": byte code installation"); ("-n", Arg.Unit (fun () -> autonative := true) , ": native code installation"); ("-doc", Arg.Unit (fun () -> docflag := Some true) , ": documentation installation"); ("-nodoc", Arg.Unit (fun () -> docflag := Some false) , ": documentation installation"); ] (fun s -> raise (Arg.Bad s)) usage; let findlib = is_findlib () in let install_dir = ( match !autodir with | Some dir -> if not !autobyte && not !autonative && not !autodoc then failwith "Nothing to do."; Dir (complete_path dir) | None -> let byte, native = if !autobyte || !autonative then (!autobyte, !autonative) else begin printf "Choose one of the following :\n1- Bytecode installation only\n2- Native installation only\n3- Both Native and Bytecode installation\n> "; (match read_line() with | "1" -> true, false | "2" -> false, true | "3" -> true, true | _ -> failwith "Invalid choice, exit.") end in let dest = if not findlib then begin printf "Choose installation directory :\n> "; let dest = complete_path (read_line()) in (try close_out (open_out (dest ^ "test.file")); Sys.remove (dest ^ "test.file"); with _ -> failwith ("Directory " ^ dest ^ " does not exists or cannot be written.")); Dir dest; end else Findlib in autobyte := byte; autonative := native; dest ) in let doc = match !docflag with Some doc -> doc | None -> printf "Do you want to generate ocamldoc documentation (Y/N) ?\n> "; (match read_line() with | "y" | "Y" -> true | "n" | "N" -> false | _ -> failwith "Invalid choice, exit.") in autodoc := doc; let doc_dir = match install_dir with Findlib -> "extlib-doc" | Dir install_dir -> sprintf "%sextlib-doc" install_dir in if !autodoc && not (Sys.file_exists doc_dir) then run (sprintf "mkdir %s" doc_dir); run (sprintf "ocamlc -c %s" (m_list ".mli")); if !autobyte then begin List.iter (fun m -> run (sprintf "ocamlc -c %s.ml" m)) modules; run (sprintf "ocamlc -a -o extLib.cma %s extLib.ml" (m_list ".cmo")); List.iter (fun m -> remove (m ^ ".cmo")) modules; remove "extLib.cmo"; end; if !autonative then begin List.iter (fun m -> run (sprintf "ocamlopt -c %s.ml" m)) modules; run (sprintf "ocamlopt -a -o extLib.cmxa %s extLib.ml" (m_list ".cmx")); List.iter (fun m -> remove (m ^ obj_ext)) modules; remove ("extLib" ^ obj_ext); end; if !autodoc then begin run (sprintf "ocamldoc -sort -html -d %s %s" doc_dir (m_list ".mli")); run ((match path_type with | PathDos -> sprintf "%s odoc_style.css %s\\style.css"; | PathUnix -> sprintf "%s odoc_style.css %s/style.css") cp_cmd doc_dir); end; match install_dir with Findlib -> let files = Buffer.create 0 in List.iter (fun m -> Buffer.add_string files (m ^ ".cmi"); Buffer.add_char files ' '; Buffer.add_string files (m ^ ".mli"); Buffer.add_char files ' ') modules; Buffer.add_string files "extLib.cmi "; if !autobyte then Buffer.add_string files "extLib.cma "; if !autonative then begin Buffer.add_string files "extLib.cmxa "; Buffer.add_string files ("extLib" ^ lib_ext^ " "); end; run (sprintf "%s META.txt META" cp_cmd); let files = Buffer.contents files in run (sprintf "ocamlfind install extlib %s META" files); | Dir install_dir -> List.iter (fun m -> copy (m ^ ".cmi") install_dir; if !autonative then copy (m ^ ".cmx") install_dir ) ("extLib" :: modules); if !autobyte then copy "extLib.cma" install_dir; if !autonative then begin copy "extLib.cmxa" install_dir; copy ("extLib" ^ lib_ext) install_dir; end; ;; try install(); printf "Done."; with Failure msg -> prerr_endline msg; exit 1