configure.ml 9.32 KB
Newer Older
1
(*
2 3
#use "topfind";;
#require "findlib";;
4
*)
5

6 7
open Printf

8 9
let not_distrib = Sys.file_exists "Makefile.distrib"

10 11 12 13 14 15 16 17 18 19
let usage () =
  print_string "\
Configuration of CDuce.

Usage: ./configure [OPTION]...

Defaults for the options are specified in brackets.

Options:
 --help                display this help and exit
20
 --bytecode            compile CDuce in bytecode instead of native
21 22 23 24 25 26 27 28

Optional features:
 --with-FEATURE        force support for FEATURE [default: autodetect]
 --without-FEATURE     disable support for FEATURE [default: autodetect]

 Available features:
 ocamlopt              use ocamlopt instead of ocamlc to build CDuce
 pxp_wlex              use wlexers for parsing utf8 with PXP [default: false]
29
 pxp                   support for the PXP XML parser
30 31 32
 expat                 support for the expat XML parser
 curl                  support for the libcurl library
 netclient             support for the netclient library
33
 cgi                   support for the cgi library
34

35
OCaml/CDuce interface:
36
 --mliface=DIR         build the interface with the OCaml sources in DIR
37

38 39 40 41
Installation directories:
 --prefix=PREFIX       install files in PREFIX [/usr/local]
 --bindir=DIR          install user executables in DIR [PREFIX/bin]
 --mandir=DIR          install man documentation in DIR [PREFIX/man]
42 43 44
 --docdir=DIR          install the rest of the doc in DIR [PREFIX/doc/cduce]
";
if not_distrib then print_string "
45 46 47
 --wprefix=WPREFIX     root directory of the web-server [/var/www]
 --cgidir=DIR          install the cgi-bin interpreter in DIR [WPREFIX/cgi-bin]
 --htmldir=DIR         install the website in DIR [WPREFIX/html]
48
 --sessiondir=DIR      store the open sessions of the cgi-bin in DIR
49 50 51
                       [/tmp/cduce_sessions]
"

52
let features =
53 54
  [ "ocamlopt", ref `auto;
    "mliface", ref `auto;
55
    "pxp", ref `auto;
56 57 58
    "expat", ref `auto;
    "curl", ref `auto;
    "netclient", ref `auto;
59
    "cgi", ref `auto;
60
    "pxp_wlex", ref `no ]
61 62

let vars =
63 64 65
  [ "prefix", ref "/usr/local";
    "bindir", ref "";
    "mandir", ref "";
66
    "docdir", ref "";
67 68 69 70 71

    "wprefix", ref "/var/www";
    "cgidir", ref "";
    "htmldir", ref "";

72
    "sessiondir", ref "/tmp/cduce_sessions";
73
    "mliface", ref "";
74
  ]
75

76
let native = ref true
77

78
let src_dirs = ["/usr/src"; "/usr/local/src"; "/tmp"]
79

80 81 82
let fatal s = printf "*** Fatal error: %s\n" s; exit 1
let warning s = printf "* Warning: %s\n" s

83 84 85 86 87 88 89 90 91 92 93
let log s =
  let oc = open_out_gen [ Open_append; Open_creat ] 0o600 "configure.log" in
  output_string oc s;
  output_char oc '\n';
  close_out oc;
  flush stdout

let command s =
  log ("==> " ^ s);
  Sys.command (sprintf "%s 2>> configure.log" s) = 0

94 95 96 97
let start_with s p =
  let ls = String.length s and lp = String.length p in
  if (ls >= lp) && (String.sub s 0 lp = p)
  then Some (String.sub s lp (ls - lp)) else None
98

99 100
let parse_arg s =
  if s = "--help" then (usage (); exit 0)
101
  else if s = "--bytecode" then native := false
102 103 104 105 106 107 108 109 110 111 112 113 114 115
  else
    match start_with s "--with-" with
      | Some f -> (List.assoc f features) := `yes
      | None ->
    match start_with s "--without-" with
      | Some f -> (List.assoc f features) := `no
      | None ->
    let i = String.index s '=' in
    if i < 2 then raise Not_found;
    let n = String.sub s 2 (i - 2) in
    let v = String.sub s (succ i) (String.length s - i - 1) in
    (List.assoc n vars) := v

let () =
116
  print_endline "Configuring CDuce for compilation...\n";
117 118 119 120 121 122
  (try for i = 1 to Array.length Sys.argv - 1 do parse_arg Sys.argv.(i) done
  with Not_found -> usage (); fatal "Incorrect command line");
  (try Sys.remove "configure.log" with Sys_error _ -> ());
  ignore (Sys.command "uname -a >> configure.log")

let print s = print_string s; flush stdout
123 124 125 126

let check_feature f p =
  printf "%s: " f;
  match !(List.assoc f features) with
127
    | `no ->
128
	print "disabled\n"; false
129
    | `yes ->
130
	print "checking... ";
131 132
	if p ()
	then (print "ok\n"; true)
133
	else (print "failed !\n"; fatal "Required feature is not available")
134
    | `auto ->
135
	print "autodetecting... ";
136
	if p ()
137 138 139
	then (print "enabled\n"; true)
	else (print "disabled\n"; false)

140
let native =
141
  check_feature "ocamlopt" (fun () -> command "ocamlfind ocamlopt")
142 143

let check_pkg p () =
144 145 146 147
  try
(*    ignore (Findlib.package_property
      [ (if native then "native" else "bytecode") ]
      p "archive"); *)
148 149
    command
      (sprintf
150
	 "ocamlfind ocaml%s -package %s -linkpkg -o configure.try && rm -f configure.try"
151 152 153
	 (if native then "opt" else "c")
	 p)
  with Not_found -> false
154 155

let need_pkg p =
156
  printf "Checking for package %s... " p; flush stdout;
157
  if not (check_pkg p ())
158 159
  then (print "failed !\n"; fatal "Required package is not available")
  else (print "ok\n")
160

161
let dir ?def d =
162 163
  let s = !(List.assoc d vars) in
  if s <> "" then s
164 165
  else match def with
    | Some x -> x
166 167 168
    | None -> fatal (sprintf "%s cannot be empty" d)


169
let exe = match Sys.os_type with
Karoline Malmkjaer's avatar
Karoline Malmkjaer committed
170
  | "Win32" ->
171
      print "Win32 detected... executable will have .exe extension\n"; ".exe"
172
  | "Cygwin" ->
173
      print "Cygwin detected... executable will have .exe extension\n"; ".exe"
174 175
  | _ -> ""

176
let add_icon = match Sys.os_type with
177 178 179
  | "Win32" | "Cygwin" -> true
  | _ -> false

180
let check_mliface dir =
Karoline Malmkjaer's avatar
Karoline Malmkjaer committed
181
(*  Sys.file_exists (Filename.concat dir "typing/types.ml") *)
182 183 184 185 186 187 188 189 190 191 192
  List.for_all (fun f ->
    Sys.file_exists (Filename.concat dir f))
    [ "typing/types.ml"; "VERSION" ]

let mliface_version dir =
  let ic = open_in (Filename.concat dir "VERSION") in
  let s = input_line ic in
  close_in ic;
  if s < "4" then "3.x"
  else if s < "4.02" then "4.01"
  else "4.02"
193

194
let ocaml_stdlib () =
195 196 197
  if (Sys.command "ocamlc -where > ocaml_stdlib" <> 0) then
    fatal "Can't run ocamlc to get OCaml standard library path";
  let ic = open_in "ocaml_stdlib" in
198 199
  let s = input_line ic in
  close_in ic;
200
  Sys.remove "ocaml_stdlib";
201
  s
202

203
let make_absolute dir =
204
  if Filename.is_relative dir
205 206 207
  then Filename.concat (Sys.getcwd ()) dir
  else dir

208
let ml_interface, mliface_version =
209
  let dir1 = !(List.assoc "mliface" vars) in
210
  let dirs = if dir1 = "" then [] else [ make_absolute dir1 ] in
211
  print "ocaml sources... ";
212
  let rec loop = function
213
    | [] ->
214
	print "not found (the interface will not be built)\n";
215
	None, ""
216
    | d::dirs ->
217
	if check_mliface d then
218 219 220
          let version = mliface_version d in
	  (print ("found: " ^ d ^ ", version " ^ version ^ "\n");
           Some d, version)
221
	else loop dirs
222 223
  in
  loop dirs
224

225
let pxp = check_feature "pxp" (check_pkg "pxp")
226 227
let expat = check_feature "expat" (check_pkg "expat")
let curl = check_feature "curl" (check_pkg "curl")
228
let netclient = check_feature "netclient" (check_pkg "netclient")
229
let cgi = check_feature "cgi" (check_pkg "netcgi2")
230 231 232 233
let pxp_wlex = check_feature "pxp_wlex" (check_pkg "pxp-wlex-utf8")
let prefix = dir "prefix"
let bindir = dir ~def:(prefix^"/bin") "bindir"
let mandir = dir ~def:(prefix^"/man") "mandir"
234
let docdir = dir ~def:(prefix^"/doc/cduce") "docdir"
235 236 237 238 239
let wprefix = dir "wprefix"
let cgidir = dir ~def:(wprefix^"/cgi-bin") "cgidir"
let htmldir = dir ~def:(wprefix^"/html") "htmldir"
let sessiondir = dir "sessiondir"

240
let curl,netclient =
241
  match curl,netclient with
242
    | true,true ->
243 244 245 246 247 248 249
	warning "Both netclient and curl are available. Will use curl.";
	true,false
    | false,false ->
	warning "No package for loading external URLs.";
	false,false
    | c,n -> c,n

250
let pxp,expat =
251
  match pxp,expat with
252
    | true,true ->
253
	warning "Both PXP and expat are available. Will build both and use expat by default.";
254
	true,true
255 256 257 258 259
    | false,false ->
	warning "No package for parsing XML documents.";
	false,false
    | c,n -> c,n

260 261
let cgi =
    if not(cgi) then
262
        (warning "No cgi package found: dtd2cduce and the web interface won't be built";
263 264 265 266
        false)
    else true

let required_packages = ["camlp4"; "num"; "pcre"; "ulex"; "netstring"]
267

268 269
let has_forpack =
  print "testing for -for-pack option: ";
Karoline Malmkjaer's avatar
Karoline Malmkjaer committed
270 271 272 273 274 275 276 277
  let comm =
    match Sys.os_type with
      | "Win32" -> "ocamlc -for-pack foo"
      | _ -> "ocamlc -for-pack foo 2> /dev/null" in
    if Sys.command comm = 0 then
      (print "available\n"; true)
    else
      (print "not available\n"; false)
278

279 280 281 282 283 284 285
let has_natdynlink =
  print "testing for native dynlink: ";
  if Sys.command "ocamlopt -o foo dynlink.cmxa && rm -f foo" = 0 then
    (printf "available\n"; true)
  else
    (print "not available\n"; false)

286 287
let () =
  List.iter need_pkg required_packages;
288 289
  if pxp then (
    need_pkg "pxp-engine";
290
    need_pkg "pxp-lex-iso88591";
291 292
    if not pxp_wlex then need_pkg "pxp-lex-utf8";
  );
293

294
  print "Creating Makefile.conf...\n";
295 296 297 298

  let out = open_out "Makefile.conf" in
  fprintf out "# This file has been generated by the configure script\n";
  fprintf out "NATIVE=%b\n" native;
299
  (match ml_interface with
300
    | Some d -> fprintf out "ML_INTERFACE=true\nOCAML_SRC=%s\nML_INTERFACE_VERSION=%s\n" d mliface_version
301
    | None -> fprintf out "ML_INTERFACE=false\n");
302
  fprintf out "PXP=%b\n" pxp;
303 304 305
  fprintf out "EXPAT=%b\n" expat;
  fprintf out "CURL=%b\n" curl;
  fprintf out "NETCLIENT=%b\n" netclient;
306
  fprintf out "CGI=%b\n" cgi;
307 308 309
  fprintf out "PXP_WLEX=%b\n" pxp_wlex;
  fprintf out "BINDIR=%s\n" bindir;
  fprintf out "MANDIR=%s\n" mandir;
310
  fprintf out "DOCDIR=%s\n" docdir;
311 312 313 314
  fprintf out "CGI_DIR=%s\n" cgidir;
  fprintf out "HTML_DIR=%s\n" htmldir;
  fprintf out "SESSION_DIR=%s\n" sessiondir;
  fprintf out "EXE=%s\n" exe;
315
  fprintf out "ADDICON=%b\n" add_icon;
316
  fprintf out "PROFILE=false\n";
317
  fprintf out "FORPACK=%b\n" has_forpack;
318
  fprintf out "NATDYNLINK=%b\n" has_natdynlink;
319
  close_out out