1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99
|
(* Js_of_ocaml library
* http://www.ocsigen.org/js_of_ocaml/
* Copyright (C) 2013 Jacques-Pascal Deplaix
* Laboratoire PPS - CNRS Université Paris Diderot
*
* 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 exception;
* either version 2.1 of the License, or (at your option) any later version.
*
* 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.
*)
open Ocamlbuild_plugin
module Pack = Ocamlbuild_pack
let fold f =
let l = ref [] in
(try
while true do
l @:= [ f () ]
done
with _ -> ());
!l
let split_comma = Str.split_delim (Str.regexp " *[, ] *")
let fold_pflag scan =
List.fold_left
(fun acc x -> try split_comma (scan x (fun x -> x)) @ acc with _ -> acc)
[]
let ocamlfind cmd f =
let p = Printf.sprintf in
let cmd = List.map (p "\"%s\"") cmd in
let cmd = p "ocamlfind query %s" (String.concat " " cmd) in
Pack.My_unix.run_and_open cmd (fun ic -> fold (fun () -> f ic))
let link_opts prod =
let all_pkgs, predicates =
let tags = Tags.elements (tags_of_pathname prod) in
let pkgs = fold_pflag (fun x -> Scanf.sscanf x "package(%[^)])") tags in
let predicates = fold_pflag (fun x -> Scanf.sscanf x "predicate(%[^)])") tags in
"js_of_ocaml" :: pkgs, predicates
in
(* Findlib usually set pkg_* predicate for all selected packages *)
(* It doesn't do it with 'query' command, we have to it manually. *)
let cmd = "-format" :: "pkg_%p" :: "-r" :: all_pkgs in
let predicates_pkgs = ocamlfind cmd (fun ic -> input_line ic) in
let all_predicates =
String.concat "," (("javascript" :: predicates) @ predicates_pkgs)
in
(* query findlib for linking option *)
let cmd = "-o-format" :: "-r" :: "-predicates" :: all_predicates :: all_pkgs in
ocamlfind cmd (fun ic -> A (input_line ic))
let init () =
let dep = "%.byte" in
let prod = "%.js" in
let f env _ =
let dep = env dep in
let prod = env prod in
let link_opts = link_opts prod in
let tags = tags_of_pathname prod ++ "js_of_ocaml" in
Cmd
(S
[ A "js_of_ocaml"
; A "--no-runtime"
; T tags
; S link_opts
; A "-o"
; Px prod
; P dep
])
in
rule "js_of_ocaml: .byte -> .js" ~dep ~prod f;
flag [ "js_of_ocaml"; "debug" ] (S [ A "--pretty"; A "--debug-info"; A "--source-map" ]);
flag [ "js_of_ocaml"; "pretty" ] (A "--pretty");
flag [ "js_of_ocaml"; "debuginfo" ] (A "--debug-info");
flag [ "js_of_ocaml"; "noinline" ] (A "--no-inline");
flag [ "js_of_ocaml"; "sourcemap" ] (A "--source-map");
pflag [ "js_of_ocaml" ] "opt" (fun n -> S [ A "--opt"; A n ]);
pflag [ "js_of_ocaml" ] "set" (fun n -> S [ A "--set"; A n ])
let oasis_support ~executables =
let aux x = if List.mem x executables then Pathname.update_extension "js" x else x in
Options.targets := List.map aux !Options.targets
let dispatcher ?(oasis_executables = []) = function
| After_rules -> init ()
| After_options -> oasis_support ~executables:oasis_executables
| _ -> ()
|