772 lines
26 KiB
OCaml
772 lines
26 KiB
OCaml
(* Lightweight thread library for Objective Caml
|
|
* http://www.ocsigen.org/lwt
|
|
* Module Myocamlbuild
|
|
* Copyright (C) 2010 Jérémie Dimino
|
|
*
|
|
* This program 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, with linking exceptions;
|
|
* either version 2.1 of the License, or (at your option) any later
|
|
* version. See COPYING file for details.
|
|
*
|
|
* This program 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 program; if not, write to the Free Software
|
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
|
* 02111-1307, USA.
|
|
*)
|
|
|
|
(* Keep that in sync with the list in discover.ml *)
|
|
let search_paths = [
|
|
"/usr";
|
|
"/usr/local";
|
|
"/opt";
|
|
"/opt/local";
|
|
"/sw";
|
|
"/mingw";
|
|
]
|
|
|
|
(* OASIS_START *)
|
|
(* DO NOT EDIT (digest: 4c177063a31680580ca13639e7a11972) *)
|
|
module OASISGettext = struct
|
|
# 21 "/home/chambart/bordel/oasis/oasis/src/oasis/OASISGettext.ml"
|
|
|
|
let ns_ str =
|
|
str
|
|
|
|
let s_ str =
|
|
str
|
|
|
|
let f_ (str : ('a, 'b, 'c, 'd) format4) =
|
|
str
|
|
|
|
let fn_ fmt1 fmt2 n =
|
|
if n = 1 then
|
|
fmt1^^""
|
|
else
|
|
fmt2^^""
|
|
|
|
let init =
|
|
[]
|
|
|
|
end
|
|
|
|
module OASISExpr = struct
|
|
# 21 "/home/chambart/bordel/oasis/oasis/src/oasis/OASISExpr.ml"
|
|
|
|
|
|
|
|
open OASISGettext
|
|
|
|
type test = string
|
|
|
|
type flag = string
|
|
|
|
type t =
|
|
| EBool of bool
|
|
| ENot of t
|
|
| EAnd of t * t
|
|
| EOr of t * t
|
|
| EFlag of flag
|
|
| ETest of test * string
|
|
|
|
|
|
type 'a choices = (t * 'a) list
|
|
|
|
let eval var_get t =
|
|
let rec eval' =
|
|
function
|
|
| EBool b ->
|
|
b
|
|
|
|
| ENot e ->
|
|
not (eval' e)
|
|
|
|
| EAnd (e1, e2) ->
|
|
(eval' e1) && (eval' e2)
|
|
|
|
| EOr (e1, e2) ->
|
|
(eval' e1) || (eval' e2)
|
|
|
|
| EFlag nm ->
|
|
let v =
|
|
var_get nm
|
|
in
|
|
assert(v = "true" || v = "false");
|
|
(v = "true")
|
|
|
|
| ETest (nm, vl) ->
|
|
let v =
|
|
var_get nm
|
|
in
|
|
(v = vl)
|
|
in
|
|
eval' t
|
|
|
|
let choose ?printer ?name var_get lst =
|
|
let rec choose_aux =
|
|
function
|
|
| (cond, vl) :: tl ->
|
|
if eval var_get cond then
|
|
vl
|
|
else
|
|
choose_aux tl
|
|
| [] ->
|
|
let str_lst =
|
|
if lst = [] then
|
|
s_ "<empty>"
|
|
else
|
|
String.concat
|
|
(s_ ", ")
|
|
(List.map
|
|
(fun (cond, vl) ->
|
|
match printer with
|
|
| Some p -> p vl
|
|
| None -> s_ "<no printer>")
|
|
lst)
|
|
in
|
|
match name with
|
|
| Some nm ->
|
|
failwith
|
|
(Printf.sprintf
|
|
(f_ "No result for the choice list '%s': %s")
|
|
nm str_lst)
|
|
| None ->
|
|
failwith
|
|
(Printf.sprintf
|
|
(f_ "No result for a choice list: %s")
|
|
str_lst)
|
|
in
|
|
choose_aux (List.rev lst)
|
|
|
|
end
|
|
|
|
|
|
module BaseEnvLight = struct
|
|
# 21 "/home/chambart/bordel/oasis/oasis/src/base/BaseEnvLight.ml"
|
|
|
|
module MapString = Map.Make(String)
|
|
|
|
type t = string MapString.t
|
|
|
|
let default_filename =
|
|
Filename.concat
|
|
(Sys.getcwd ())
|
|
"setup.data"
|
|
|
|
let load ?(allow_empty=false) ?(filename=default_filename) () =
|
|
if Sys.file_exists filename then
|
|
begin
|
|
let chn =
|
|
open_in_bin filename
|
|
in
|
|
let st =
|
|
Stream.of_channel chn
|
|
in
|
|
let line =
|
|
ref 1
|
|
in
|
|
let st_line =
|
|
Stream.from
|
|
(fun _ ->
|
|
try
|
|
match Stream.next st with
|
|
| '\n' -> incr line; Some '\n'
|
|
| c -> Some c
|
|
with Stream.Failure -> None)
|
|
in
|
|
let lexer =
|
|
Genlex.make_lexer ["="] st_line
|
|
in
|
|
let rec read_file mp =
|
|
match Stream.npeek 3 lexer with
|
|
| [Genlex.Ident nm; Genlex.Kwd "="; Genlex.String value] ->
|
|
Stream.junk lexer;
|
|
Stream.junk lexer;
|
|
Stream.junk lexer;
|
|
read_file (MapString.add nm value mp)
|
|
| [] ->
|
|
mp
|
|
| _ ->
|
|
failwith
|
|
(Printf.sprintf
|
|
"Malformed data file '%s' line %d"
|
|
filename !line)
|
|
in
|
|
let mp =
|
|
read_file MapString.empty
|
|
in
|
|
close_in chn;
|
|
mp
|
|
end
|
|
else if allow_empty then
|
|
begin
|
|
MapString.empty
|
|
end
|
|
else
|
|
begin
|
|
failwith
|
|
(Printf.sprintf
|
|
"Unable to load environment, the file '%s' doesn't exist."
|
|
filename)
|
|
end
|
|
|
|
let var_get name env =
|
|
let rec var_expand str =
|
|
let buff =
|
|
Buffer.create ((String.length str) * 2)
|
|
in
|
|
Buffer.add_substitute
|
|
buff
|
|
(fun var ->
|
|
try
|
|
var_expand (MapString.find var env)
|
|
with Not_found ->
|
|
failwith
|
|
(Printf.sprintf
|
|
"No variable %s defined when trying to expand %S."
|
|
var
|
|
str))
|
|
str;
|
|
Buffer.contents buff
|
|
in
|
|
var_expand (MapString.find name env)
|
|
|
|
let var_choose lst env =
|
|
OASISExpr.choose
|
|
(fun nm -> var_get nm env)
|
|
lst
|
|
end
|
|
|
|
|
|
module MyOCamlbuildFindlib = struct
|
|
# 21 "/home/chambart/bordel/oasis/oasis/src/plugins/ocamlbuild/MyOCamlbuildFindlib.ml"
|
|
|
|
(** OCamlbuild extension, copied from
|
|
* http://brion.inria.fr/gallium/index.php/Using_ocamlfind_with_ocamlbuild
|
|
* by N. Pouillard and others
|
|
*
|
|
* Updated on 2009/02/28
|
|
*
|
|
* Modified by Sylvain Le Gall
|
|
*)
|
|
open Ocamlbuild_plugin
|
|
|
|
(* these functions are not really officially exported *)
|
|
let run_and_read =
|
|
Ocamlbuild_pack.My_unix.run_and_read
|
|
|
|
let blank_sep_strings =
|
|
Ocamlbuild_pack.Lexers.blank_sep_strings
|
|
|
|
let split s ch =
|
|
let x =
|
|
ref []
|
|
in
|
|
let rec go s =
|
|
let pos =
|
|
String.index s ch
|
|
in
|
|
x := (String.before s pos)::!x;
|
|
go (String.after s (pos + 1))
|
|
in
|
|
try
|
|
go s
|
|
with Not_found -> !x
|
|
|
|
let split_nl s = split s '\n'
|
|
|
|
let before_space s =
|
|
try
|
|
String.before s (String.index s ' ')
|
|
with Not_found -> s
|
|
|
|
(* this lists all supported packages *)
|
|
let find_packages () =
|
|
List.map before_space (split_nl & run_and_read "ocamlfind list")
|
|
|
|
(* this is supposed to list available syntaxes, but I don't know how to do it. *)
|
|
let find_syntaxes () = ["camlp4o"; "camlp4r"]
|
|
|
|
(* ocamlfind command *)
|
|
let ocamlfind x = S[A"ocamlfind"; x]
|
|
|
|
let dispatch =
|
|
function
|
|
| Before_options ->
|
|
(* by using Before_options one let command line options have an higher priority *)
|
|
(* on the contrary using After_options will guarantee to have the higher priority *)
|
|
(* override default commands by ocamlfind ones *)
|
|
Options.ocamlc := ocamlfind & A"ocamlc";
|
|
Options.ocamlopt := ocamlfind & A"ocamlopt";
|
|
Options.ocamldep := ocamlfind & A"ocamldep";
|
|
Options.ocamldoc := ocamlfind & A"ocamldoc";
|
|
Options.ocamlmktop := ocamlfind & A"ocamlmktop"
|
|
|
|
| After_rules ->
|
|
|
|
(* When one link an OCaml library/binary/package, one should use -linkpkg *)
|
|
flag ["ocaml"; "link"; "program"] & A"-linkpkg";
|
|
|
|
(* For each ocamlfind package one inject the -package option when
|
|
* compiling, computing dependencies, generating documentation and
|
|
* linking. *)
|
|
List.iter
|
|
begin fun pkg ->
|
|
flag ["ocaml"; "compile"; "pkg_"^pkg] & S[A"-package"; A pkg];
|
|
flag ["ocaml"; "ocamldep"; "pkg_"^pkg] & S[A"-package"; A pkg];
|
|
flag ["ocaml"; "doc"; "pkg_"^pkg] & S[A"-package"; A pkg];
|
|
flag ["ocaml"; "link"; "pkg_"^pkg] & S[A"-package"; A pkg];
|
|
flag ["ocaml"; "infer_interface"; "pkg_"^pkg] & S[A"-package"; A pkg];
|
|
end
|
|
(find_packages ());
|
|
|
|
(* Like -package but for extensions syntax. Morover -syntax is useless
|
|
* when linking. *)
|
|
List.iter begin fun syntax ->
|
|
flag ["ocaml"; "compile"; "syntax_"^syntax] & S[A"-syntax"; A syntax];
|
|
flag ["ocaml"; "ocamldep"; "syntax_"^syntax] & S[A"-syntax"; A syntax];
|
|
flag ["ocaml"; "doc"; "syntax_"^syntax] & S[A"-syntax"; A syntax];
|
|
flag ["ocaml"; "infer_interface"; "syntax_"^syntax] & S[A"-syntax"; A syntax];
|
|
end (find_syntaxes ());
|
|
|
|
(* The default "thread" tag is not compatible with ocamlfind.
|
|
* Indeed, the default rules add the "threads.cma" or "threads.cmxa"
|
|
* options when using this tag. When using the "-linkpkg" option with
|
|
* ocamlfind, this module will then be added twice on the command line.
|
|
*
|
|
* To solve this, one approach is to add the "-thread" option when using
|
|
* the "threads" package using the previous plugin.
|
|
*)
|
|
flag ["ocaml"; "pkg_threads"; "compile"] (S[A "-thread"]);
|
|
flag ["ocaml"; "pkg_threads"; "link"] (S[A "-thread"]);
|
|
flag ["ocaml"; "pkg_threads"; "infer_interface"] (S[A "-thread"])
|
|
|
|
| _ ->
|
|
()
|
|
|
|
end
|
|
|
|
module MyOCamlbuildBase = struct
|
|
# 21 "/home/chambart/bordel/oasis/oasis/src/plugins/ocamlbuild/MyOCamlbuildBase.ml"
|
|
|
|
(** Base functions for writing myocamlbuild.ml
|
|
@author Sylvain Le Gall
|
|
*)
|
|
|
|
|
|
|
|
open Ocamlbuild_plugin
|
|
|
|
type dir = string
|
|
type file = string
|
|
type name = string
|
|
type tag = string
|
|
|
|
# 55 "/home/chambart/bordel/oasis/oasis/src/plugins/ocamlbuild/MyOCamlbuildBase.ml"
|
|
|
|
type t =
|
|
{
|
|
lib_ocaml: (name * dir list) list;
|
|
lib_c: (name * dir * file list) list;
|
|
flags: (tag list * (spec OASISExpr.choices)) list;
|
|
}
|
|
|
|
let env_filename =
|
|
Pathname.basename
|
|
BaseEnvLight.default_filename
|
|
|
|
let dispatch_combine lst =
|
|
fun e ->
|
|
List.iter
|
|
(fun dispatch -> dispatch e)
|
|
lst
|
|
|
|
let dispatch t e =
|
|
let env =
|
|
BaseEnvLight.load
|
|
~filename:env_filename
|
|
~allow_empty:true
|
|
()
|
|
in
|
|
match e with
|
|
| Before_options ->
|
|
let no_trailing_dot s =
|
|
if String.length s >= 1 && s.[0] = '.' then
|
|
String.sub s 1 ((String.length s) - 1)
|
|
else
|
|
s
|
|
in
|
|
List.iter
|
|
(fun (opt, var) ->
|
|
try
|
|
opt := no_trailing_dot (BaseEnvLight.var_get var env)
|
|
with Not_found ->
|
|
Printf.eprintf "W: Cannot get variable %s" var)
|
|
[
|
|
Options.ext_obj, "ext_obj";
|
|
Options.ext_lib, "ext_lib";
|
|
Options.ext_dll, "ext_dll";
|
|
]
|
|
|
|
| After_rules ->
|
|
(* Declare OCaml libraries *)
|
|
List.iter
|
|
(function
|
|
| lib, [] ->
|
|
ocaml_lib lib;
|
|
| lib, dir :: tl ->
|
|
ocaml_lib ~dir:dir lib;
|
|
List.iter
|
|
(fun dir ->
|
|
flag
|
|
["ocaml"; "use_"^lib; "compile"]
|
|
(S[A"-I"; P dir]))
|
|
tl)
|
|
t.lib_ocaml;
|
|
|
|
(* Declare C libraries *)
|
|
List.iter
|
|
(fun (lib, dir, headers) ->
|
|
(* Handle C part of library *)
|
|
flag ["link"; "library"; "ocaml"; "byte"; "use_lib"^lib]
|
|
(S[A"-dllib"; A("-l"^lib); A"-cclib"; A("-l"^lib)]);
|
|
|
|
flag ["link"; "library"; "ocaml"; "native"; "use_lib"^lib]
|
|
(S[A"-cclib"; A("-l"^lib)]);
|
|
|
|
flag ["link"; "program"; "ocaml"; "byte"; "use_lib"^lib]
|
|
(S[A"-dllib"; A("dll"^lib)]);
|
|
|
|
(* When ocaml link something that use the C library, then one
|
|
need that file to be up to date.
|
|
*)
|
|
dep ["link"; "ocaml"; "use_lib"^lib]
|
|
[dir/"lib"^lib^"."^(!Options.ext_lib)];
|
|
|
|
(* TODO: be more specific about what depends on headers *)
|
|
(* Depends on .h files *)
|
|
dep ["compile"; "c"]
|
|
headers;
|
|
|
|
(* Setup search path for lib *)
|
|
flag ["link"; "ocaml"; "use_"^lib]
|
|
(S[A"-I"; P(dir)]);
|
|
)
|
|
t.lib_c;
|
|
|
|
(* Add flags *)
|
|
List.iter
|
|
(fun (tags, cond_specs) ->
|
|
let spec =
|
|
BaseEnvLight.var_choose cond_specs env
|
|
in
|
|
flag tags & spec)
|
|
t.flags
|
|
| _ ->
|
|
()
|
|
|
|
let dispatch_default t =
|
|
dispatch_combine
|
|
[
|
|
dispatch t;
|
|
MyOCamlbuildFindlib.dispatch;
|
|
]
|
|
|
|
end
|
|
|
|
|
|
open Ocamlbuild_plugin;;
|
|
let package_default =
|
|
{
|
|
MyOCamlbuildBase.lib_ocaml =
|
|
[
|
|
("src/core/lwt", ["src/core"]);
|
|
("src/unix/lwt-unix", ["src/unix"]);
|
|
("src/react/lwt-react", ["src/react"]);
|
|
("tests/test", ["tests"]);
|
|
("src/text/lwt-text", ["src/text"]);
|
|
("syntax/lwt-syntax", ["syntax"]);
|
|
("src/top/lwt-top", ["src/top"]);
|
|
("src/preemptive/lwt-preemptive", ["src/preemptive"]);
|
|
("src/simple_top/lwt-simple-top", ["src/simple_top"]);
|
|
("src/glib/lwt-glib", ["src/glib"]);
|
|
("syntax/lwt-syntax-log", ["syntax"]);
|
|
("src/extra/lwt-extra", ["src/extra"]);
|
|
("syntax/optcomp", ["syntax"]);
|
|
("syntax/lwt-syntax-options", ["syntax"]);
|
|
("src/ssl/lwt-ssl", ["src/ssl"])
|
|
];
|
|
lib_c =
|
|
[
|
|
("lwt-unix",
|
|
"src/unix",
|
|
["src/unix/lwt_config.h"; "src/unix/lwt_unix.h"]);
|
|
("lwt-text", "src/text", []);
|
|
("lwt-glib", "src/glib", [])
|
|
];
|
|
flags =
|
|
[
|
|
(["oasis_library_lwt_unix_cclib"; "link"],
|
|
[
|
|
(OASISExpr.EBool true, S []);
|
|
(OASISExpr.EFlag "libev", S [A "-cclib"; A "-lev"]);
|
|
(OASISExpr.ENot (OASISExpr.ETest ("os_type", "Win32")),
|
|
S [A "-cclib"; A "-lpthread"]);
|
|
(OASISExpr.EAnd
|
|
(OASISExpr.ENot (OASISExpr.ETest ("os_type", "Win32")),
|
|
OASISExpr.EFlag "libev"),
|
|
S [A "-cclib"; A "-lpthread"; A "-cclib"; A "-lev"]);
|
|
(OASISExpr.ETest ("os_type", "Win32"),
|
|
S [A "-cclib"; A "ws2_32.lib"]);
|
|
(OASISExpr.EAnd
|
|
(OASISExpr.ETest ("os_type", "Win32"),
|
|
OASISExpr.EFlag "libev"),
|
|
S [A "-cclib"; A "ws2_32.lib"; A "-cclib"; A "-lev"]);
|
|
(OASISExpr.EAnd
|
|
(OASISExpr.ETest ("os_type", "Win32"),
|
|
OASISExpr.ENot (OASISExpr.ETest ("os_type", "Win32"))),
|
|
S [A "-cclib"; A "ws2_32.lib"; A "-cclib"; A "-lpthread"]);
|
|
(OASISExpr.EAnd
|
|
(OASISExpr.EAnd
|
|
(OASISExpr.ETest ("os_type", "Win32"),
|
|
OASISExpr.ENot (OASISExpr.ETest ("os_type", "Win32"))),
|
|
OASISExpr.EFlag "libev"),
|
|
S
|
|
[
|
|
A "-cclib";
|
|
A "ws2_32.lib";
|
|
A "-cclib";
|
|
A "-lpthread";
|
|
A "-cclib";
|
|
A "-lev"
|
|
])
|
|
]);
|
|
(["oasis_library_lwt_unix_cclib"; "ocamlmklib"; "c"],
|
|
[
|
|
(OASISExpr.EBool true, S []);
|
|
(OASISExpr.EFlag "libev", S [A "-lev"]);
|
|
(OASISExpr.ENot (OASISExpr.ETest ("os_type", "Win32")),
|
|
S [A "-lpthread"]);
|
|
(OASISExpr.EAnd
|
|
(OASISExpr.ENot (OASISExpr.ETest ("os_type", "Win32")),
|
|
OASISExpr.EFlag "libev"),
|
|
S [A "-lpthread"; A "-lev"]);
|
|
(OASISExpr.ETest ("os_type", "Win32"), S [A "ws2_32.lib"]);
|
|
(OASISExpr.EAnd
|
|
(OASISExpr.ETest ("os_type", "Win32"),
|
|
OASISExpr.EFlag "libev"),
|
|
S [A "ws2_32.lib"; A "-lev"]);
|
|
(OASISExpr.EAnd
|
|
(OASISExpr.ETest ("os_type", "Win32"),
|
|
OASISExpr.ENot (OASISExpr.ETest ("os_type", "Win32"))),
|
|
S [A "ws2_32.lib"; A "-lpthread"]);
|
|
(OASISExpr.EAnd
|
|
(OASISExpr.EAnd
|
|
(OASISExpr.ETest ("os_type", "Win32"),
|
|
OASISExpr.ENot (OASISExpr.ETest ("os_type", "Win32"))),
|
|
OASISExpr.EFlag "libev"),
|
|
S [A "ws2_32.lib"; A "-lpthread"; A "-lev"])
|
|
])
|
|
];
|
|
}
|
|
;;
|
|
|
|
let dispatch_default = MyOCamlbuildBase.dispatch_default package_default;;
|
|
|
|
(* OASIS_STOP *)
|
|
|
|
open Ocamlbuild_plugin
|
|
|
|
let pkg_config flags =
|
|
with_temp_file "lwt" "pkg-config"
|
|
(fun tmp ->
|
|
Command.execute ~quiet:true & Cmd(S[A "pkg-config"; S flags; Sh ">"; A tmp]);
|
|
List.map (fun arg -> A arg) (string_list_of_file tmp))
|
|
|
|
let define_c_library ?(msvc = false) ~name ~c_name () =
|
|
let tag = Printf.sprintf "use_C_%s" name in
|
|
|
|
(* Get compile flags. *)
|
|
let opt = pkg_config [A "--cflags"; A c_name] in
|
|
|
|
(* Get linking flags. *)
|
|
let lib =
|
|
if msvc then
|
|
(* With msvc we need to pass "glib-2.0.lib" instead of
|
|
"-lglib-2.0" otherwise executables will fail. *)
|
|
pkg_config [A "--libs-only-L"; A c_name] @ pkg_config [A "--libs-only-l"; A "--msvc-syntax"; A c_name]
|
|
else
|
|
pkg_config [A "--libs"; A c_name]
|
|
in
|
|
|
|
(* Add flags for linking with the C library: *)
|
|
flag ["ocamlmklib"; "c"; tag] & S lib;
|
|
|
|
(* C stubs using the C library must be compiled with the library
|
|
specifics flags: *)
|
|
flag ["c"; "compile"; tag] & S (List.map (fun arg -> S[A"-ccopt"; arg]) opt);
|
|
|
|
(* OCaml libraries must depends on the C library: *)
|
|
flag ["link"; "ocaml"; tag] & S (List.map (fun arg -> S[A"-cclib"; arg]) lib)
|
|
|
|
let () =
|
|
dispatch
|
|
(fun hook ->
|
|
dispatch_default hook;
|
|
match hook with
|
|
| Before_options ->
|
|
Options.make_links := false
|
|
|
|
| After_rules ->
|
|
dep ["file:src/unix/lwt_unix_stubs.c"] ["src/unix/lwt_unix_unix.c"; "src/unix/lwt_unix_windows.c"];
|
|
dep ["pa_optcomp"] ["src/unix/lwt_config.ml"];
|
|
|
|
(* Internal syntax extension *)
|
|
List.iter
|
|
(fun base ->
|
|
let tag = "pa_" ^ base and file = "syntax/pa_" ^ base ^ ".cmo" in
|
|
flag ["ocaml"; "compile"; tag] & S[A"-ppopt"; A file];
|
|
flag ["ocaml"; "ocamldep"; tag] & S[A"-ppopt"; A file];
|
|
flag ["ocaml"; "doc"; tag] & S[A"-ppopt"; A file];
|
|
dep ["ocaml"; "ocamldep"; tag] [file])
|
|
["lwt_options"; "lwt"; "lwt_log"; "optcomp"];
|
|
|
|
(* Optcomp for .mli *)
|
|
flag ["ocaml"; "compile"; "pa_optcomp_standalone"] & S[A"-pp"; A "./syntax/optcomp.byte"];
|
|
flag ["ocaml"; "ocamldep"; "pa_optcomp_standalone"] & S[A"-pp"; A "./syntax/optcomp.byte"];
|
|
flag ["ocaml"; "doc"; "pa_optcomp_standalone"] & S[A"-pp"; A "./syntax/optcomp.byte"];
|
|
dep ["ocaml"; "ocamldep"; "pa_optcomp_standalone"] ["syntax/optcomp.byte"];
|
|
|
|
(* Use an introduction page with categories *)
|
|
tag_file "lwt-api.docdir/index.html" ["apiref"];
|
|
dep ["apiref"] ["apiref-intro"];
|
|
flag ["apiref"] & S[A "-intro"; P "apiref-intro"; A"-colorize-code"];
|
|
|
|
(* Glib bindings: *)
|
|
let env = BaseEnvLight.load ~allow_empty:true ~filename:MyOCamlbuildBase.env_filename () in
|
|
let msvc = BaseEnvLight.var_get "ccomp_type" env = "msvc" in
|
|
if BaseEnvLight.var_get "glib" env = "true" || BaseEnvLight.var_get "all" env = "true" then
|
|
define_c_library ~msvc ~name:"glib" ~c_name:"glib-2.0" ();
|
|
|
|
let opts = S[A "-ppopt"; A "-let"; A "-ppopt"; A ("windows=" ^ if BaseEnvLight.var_get "os_type" env <> "Unix" then "true" else "false")] in
|
|
flag ["ocaml"; "compile"; "pa_optcomp"] & opts;
|
|
flag ["ocaml"; "ocamldep"; "pa_optcomp"] & opts;
|
|
(*flag ["ocaml"; "doc"; "pa_optcomp"] & opts; Does not work... *)
|
|
|
|
flag ["ocaml"; "link"; "toplevel"] & A"-linkpkg";
|
|
|
|
let env = BaseEnvLight.load () in
|
|
let stdlib_path = BaseEnvLight.var_get "standard_library" env in
|
|
|
|
(* Try to find the path where compiler libraries are: *)
|
|
let compiler_libs =
|
|
let stdlib = String.chomp stdlib_path in
|
|
try
|
|
let path =
|
|
List.find Pathname.exists [
|
|
stdlib / "compiler-libs";
|
|
stdlib / "compiler-lib";
|
|
stdlib / ".." / "compiler-libs";
|
|
stdlib / ".." / "compiler-lib";
|
|
]
|
|
in
|
|
path :: List.filter Pathname.exists [ path / "typing"; path / "utils"; path / "parsing" ]
|
|
with Not_found ->
|
|
[]
|
|
in
|
|
|
|
(* Add directories for compiler-libraries: *)
|
|
let paths = List.map (fun path -> S[A"-I"; A path]) compiler_libs in
|
|
List.iter
|
|
(fun stage -> flag ["ocaml"; stage; "use_compiler_libs"] & S paths)
|
|
["compile"; "ocamldep"; "doc"; "link"];
|
|
|
|
dep ["file:src/top/toplevel_temp.top"] ["src/core/lwt.cma";
|
|
"src/react/lwt-react.cma";
|
|
"src/unix/lwt-unix.cma";
|
|
"src/text/lwt-text.cma";
|
|
"src/top/lwt-top.cma"];
|
|
|
|
flag ["file:src/top/toplevel_temp.top"] & S[A"-I"; A"src/unix";
|
|
A"-I"; A"src/text";
|
|
A"src/core/lwt.cma";
|
|
A"src/react/lwt-react.cma";
|
|
A"src/unix/lwt-unix.cma";
|
|
A"src/text/lwt-text.cma";
|
|
A"src/top/lwt-top.cma"];
|
|
|
|
(* Expunge compiler modules *)
|
|
rule "toplevel expunge"
|
|
~dep:"src/top/toplevel_temp.top"
|
|
~prod:"src/top/lwt_toplevel.byte"
|
|
(fun _ _ ->
|
|
let directories =
|
|
stdlib_path
|
|
:: "src/core"
|
|
:: "src/react"
|
|
:: "src/unix"
|
|
:: "src/text"
|
|
:: "src/top"
|
|
:: (List.map
|
|
(fun lib ->
|
|
String.chomp
|
|
(run_and_read
|
|
("ocamlfind query " ^ lib)))
|
|
["findlib"; "react"; "unix"; "text"])
|
|
in
|
|
let modules =
|
|
List.fold_left
|
|
(fun set directory ->
|
|
List.fold_left
|
|
(fun set fname ->
|
|
if Pathname.check_extension fname "cmi" then
|
|
StringSet.add (module_name_of_pathname fname) set
|
|
else
|
|
set)
|
|
set
|
|
(Array.to_list (Pathname.readdir directory)))
|
|
StringSet.empty directories
|
|
in
|
|
Cmd(S[A(stdlib_path / "expunge");
|
|
A"src/top/toplevel_temp.top";
|
|
A"src/top/lwt_toplevel.byte";
|
|
A"outcometree"; A"topdirs"; A"toploop";
|
|
S(List.map (fun x -> A x) (StringSet.elements modules))]));
|
|
|
|
(* Search for a header file in standard directories. *)
|
|
let search_header header =
|
|
let rec loop = function
|
|
| [] ->
|
|
None
|
|
| dir :: dirs ->
|
|
if Sys.file_exists (dir ^ "/include/" ^ header) then
|
|
Some dir
|
|
else
|
|
loop dirs
|
|
in
|
|
loop search_paths
|
|
in
|
|
|
|
(* Add directories for libev and pthreads *)
|
|
let flags dir =
|
|
flag ["ocamlmklib"; "c"; "use_stubs"] & A("-L" ^ dir ^ "/lib");
|
|
flag ["c"; "compile"; "use_stubs"] & S[A"-ccopt"; A("-I" ^ dir ^ "/include")];
|
|
flag ["link"; "ocaml"; "use_stubs"] & S[A"-cclib"; A("-L" ^ dir ^ "/lib")]
|
|
in
|
|
begin
|
|
match search_header "ev.h", search_header "pthread.h" with
|
|
| None, None -> ()
|
|
| Some path, None | None, Some path -> flags path
|
|
| Some path1, Some path2 when path1 = path2 -> flags path1
|
|
| Some path1, Some path2 -> flags path1; flags path2
|
|
end
|
|
|
|
| _ ->
|
|
())
|
|
|