Commit | Line | Data |
---|---|---|
feec80c3 C |
1 | (* |
2 | * Install - ExtLib installation | |
3 | * Copyright (C) 2003 Nicolas Cannasse | |
4 | * | |
5 | * This library is free software; you can redistribute it and/or | |
6 | * modify it under the terms of the GNU Lesser General Public | |
7 | * License as published by the Free Software Foundation; either | |
8 | * version 2.1 of the License, or (at your option) any later version, | |
9 | * with the special exception on linking described in file LICENSE. | |
10 | * | |
11 | * This library is distributed in the hope that it will be useful, | |
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
14 | * Lesser General Public License for more details. | |
15 | * | |
16 | * You should have received a copy of the GNU Lesser General Public | |
17 | * License along with this library; if not, write to the Free Software | |
18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
19 | *) | |
20 | ||
21 | open Printf | |
22 | ||
23 | type path = | |
24 | | PathUnix | |
25 | | PathDos | |
26 | ||
27 | let modules = [ | |
28 | "enum"; | |
29 | "bitSet"; | |
30 | "dynArray"; | |
31 | "extArray"; | |
32 | "extHashtbl"; | |
33 | "extList"; | |
34 | "extString"; | |
35 | "global"; | |
36 | "IO"; | |
37 | "option"; | |
38 | "pMap"; | |
39 | "std"; | |
40 | "uChar"; | |
41 | "uTF8"; | |
42 | "base64"; | |
43 | "unzip"; | |
44 | "refList"; | |
45 | "optParse"; | |
46 | "dllist"; | |
47 | ] | |
48 | ||
49 | let m_list suffix = | |
50 | String.concat " " (List.map (fun m -> m ^ suffix) modules) | |
51 | ||
52 | let obj_ext , lib_ext , cp_cmd , path_type = match Sys.os_type with | |
53 | | "Unix" | "Cygwin" | "MacOS" -> ".o" , ".a" , "cp", PathUnix | |
54 | | "Win32" -> ".obj" , ".lib" , "copy", PathDos | |
55 | | _ -> failwith "Unknown OS" | |
56 | ||
57 | let run cmd = | |
58 | print_endline cmd; | |
59 | let ecode = Sys.command cmd in | |
60 | if ecode <> 0 then failwith (sprintf "Exit Code %d - Stopped" ecode) | |
61 | ||
62 | let copy file dest = | |
63 | if dest <> "" && dest <> "." then begin | |
64 | print_endline ("Installing " ^ file); | |
65 | let path = dest ^ file in | |
66 | (try Sys.remove path with _ -> ()); | |
67 | try | |
68 | Sys.rename file path; | |
69 | with | |
70 | _ -> failwith "Aborted" | |
71 | end | |
72 | ||
73 | let complete_path p = | |
74 | if p = "" then | |
75 | p | |
76 | else | |
77 | let c = p.[String.length p - 1] in | |
78 | if c = '/' || c = '\\' then | |
79 | p | |
80 | else | |
81 | p ^ (match path_type with PathUnix -> "/" | PathDos -> "\\") | |
82 | ||
83 | let remove file = | |
84 | try | |
85 | Sys.remove file | |
86 | with | |
87 | _ -> prerr_endline ("Warning : failed to delete " ^ file) | |
88 | ||
89 | let is_findlib() = | |
90 | let findlib = Sys.command (if Sys.os_type = "Win32" then "ocamlfind printconf 2>NUL" else "ocamlfind printconf") = 0 in | |
91 | if findlib then print_endline "Using Findlib"; | |
92 | findlib | |
93 | ||
94 | type install_dir = Findlib | Dir of string | |
95 | ||
96 | let install() = | |
97 | let autodir = ref None in | |
98 | let docflag = ref None in | |
99 | let autodoc = ref false in | |
100 | let autobyte = ref false in | |
101 | let autonative = ref false in | |
102 | let usage = "ExtLib installation program v1.3\n(c)2003,2004 Nicolas Cannasse" in | |
103 | Arg.parse [ | |
104 | ("-d", Arg.String (fun s -> autodir := Some s) , "<dir> : install in target directory"); | |
105 | ("-b", Arg.Unit (fun () -> autobyte := true) , ": byte code installation"); | |
106 | ("-n", Arg.Unit (fun () -> autonative := true) , ": native code installation"); | |
107 | ("-doc", Arg.Unit (fun () -> docflag := Some true) , ": documentation installation"); | |
108 | ("-nodoc", Arg.Unit (fun () -> docflag := Some false) , ": documentation installation"); | |
109 | ] (fun s -> raise (Arg.Bad s)) usage; | |
110 | let findlib = is_findlib () in | |
111 | let install_dir = ( | |
112 | match !autodir with | |
113 | | Some dir -> | |
114 | if not !autobyte && not !autonative && not !autodoc then failwith "Nothing to do."; | |
115 | Dir (complete_path dir) | |
116 | | None -> | |
117 | let byte, native = | |
118 | if !autobyte || !autonative then | |
119 | (!autobyte, !autonative) | |
120 | else begin | |
121 | printf "Choose one of the following :\n1- Bytecode installation only\n2- Native installation only\n3- Both Native and Bytecode installation\n> "; | |
122 | (match read_line() with | |
123 | | "1" -> true, false | |
124 | | "2" -> false, true | |
125 | | "3" -> true, true | |
126 | | _ -> failwith "Invalid choice, exit.") | |
127 | end | |
128 | in | |
129 | let dest = | |
130 | if not findlib then begin | |
131 | printf "Choose installation directory :\n> "; | |
132 | let dest = complete_path (read_line()) in | |
133 | (try | |
134 | close_out (open_out (dest ^ "test.file")); | |
135 | Sys.remove (dest ^ "test.file"); | |
136 | with | |
137 | _ -> failwith ("Directory " ^ dest ^ " does not exists or cannot be written.")); | |
138 | Dir dest; | |
139 | end else Findlib in | |
140 | autobyte := byte; | |
141 | autonative := native; | |
142 | dest | |
143 | ) in | |
144 | let doc = | |
145 | match !docflag with | |
146 | Some doc -> doc | |
147 | | None -> | |
148 | printf "Do you want to generate ocamldoc documentation (Y/N) ?\n> "; | |
149 | (match read_line() with | |
150 | | "y" | "Y" -> true | |
151 | | "n" | "N" -> false | |
152 | | _ -> failwith "Invalid choice, exit.") | |
153 | in | |
154 | autodoc := doc; | |
155 | let doc_dir = | |
156 | match install_dir with | |
157 | Findlib -> "extlib-doc" | |
158 | | Dir install_dir -> | |
159 | sprintf "%sextlib-doc" install_dir in | |
160 | if !autodoc && not (Sys.file_exists doc_dir) then run (sprintf "mkdir %s" doc_dir); | |
161 | run (sprintf "ocamlc -c %s" (m_list ".mli")); | |
162 | if !autobyte then begin | |
163 | List.iter (fun m -> run (sprintf "ocamlc -c %s.ml" m)) modules; | |
164 | run (sprintf "ocamlc -a -o extLib.cma %s extLib.ml" (m_list ".cmo")); | |
165 | List.iter (fun m -> remove (m ^ ".cmo")) modules; | |
166 | remove "extLib.cmo"; | |
167 | end; | |
168 | if !autonative then begin | |
169 | List.iter (fun m -> run (sprintf "ocamlopt -c %s.ml" m)) modules; | |
170 | run (sprintf "ocamlopt -a -o extLib.cmxa %s extLib.ml" (m_list ".cmx")); | |
171 | List.iter (fun m -> remove (m ^ obj_ext)) modules; | |
172 | remove ("extLib" ^ obj_ext); | |
173 | end; | |
174 | if !autodoc then begin | |
175 | run (sprintf "ocamldoc -sort -html -d %s %s" doc_dir (m_list ".mli")); | |
176 | run ((match path_type with | |
177 | | PathDos -> sprintf "%s odoc_style.css %s\\style.css"; | |
178 | | PathUnix -> sprintf "%s odoc_style.css %s/style.css") cp_cmd doc_dir); | |
179 | end; | |
180 | match install_dir with | |
181 | Findlib -> | |
182 | let files = Buffer.create 0 in | |
183 | List.iter (fun m -> | |
184 | Buffer.add_string files (m ^ ".cmi"); | |
185 | Buffer.add_char files ' '; | |
186 | Buffer.add_string files (m ^ ".mli"); | |
187 | Buffer.add_char files ' ') | |
188 | modules; | |
189 | Buffer.add_string files "extLib.cmi "; | |
190 | if !autobyte then Buffer.add_string files "extLib.cma "; | |
191 | if !autonative then begin | |
192 | Buffer.add_string files "extLib.cmxa "; | |
193 | Buffer.add_string files ("extLib" ^ lib_ext^ " "); | |
194 | end; | |
195 | let files = Buffer.contents files in | |
196 | run (sprintf "ocamlfind install extlib %s META" files); | |
197 | | Dir install_dir -> | |
198 | List.iter (fun m -> | |
199 | copy (m ^ ".cmi") install_dir; | |
200 | if !autonative then copy (m ^ ".cmx") install_dir | |
201 | ) ("extLib" :: modules); | |
202 | if !autobyte then copy "extLib.cma" install_dir; | |
203 | if !autonative then begin | |
204 | copy "extLib.cmxa" install_dir; | |
205 | copy ("extLib" ^ lib_ext) install_dir; | |
206 | end; | |
207 | ;; | |
208 | try | |
209 | install(); | |
210 | printf "Done."; | |
211 | with | |
212 | Failure msg -> | |
213 | prerr_endline msg; | |
214 | exit 1 | |
215 | ||
216 |