Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 804 lines (711 sloc) 28.989 kb
fccc685 Initial open-source release
MLstate authored
1 (*
2 Copyright © 2011 MLstate
3
4 This file is part of OPA.
5
6 OPA is free software: you can redistribute it and/or modify it under the
7 terms of the GNU Affero General Public License, version 3, as published by
8 the Free Software Foundation.
9
10 OPA is distributed in the hope that it will be useful, but WITHOUT ANY
11 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12 FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for
13 more details.
14
15 You should have received a copy of the GNU Affero General Public License
16 along with OPA. If not, see <http://www.gnu.org/licenses/>.
17 *)
18 (* ------------------------------------------------------------ *)
19 (* Tags, flags, directory contexts and custom stuff *)
20 (* ------------------------------------------------------------ *)
21
22 (* -- Directory contexts -- *)
23
24 shared_namespace_dir "libqmlcompil";
25 shared_namespace_dir "database";
26 shared_namespace_dir "opa";
27 include_subdirs "opalib";
28 shared_namespace_dir "opalang";
29 shared_namespace_dir "appruntime";
30 shared_namespace_dir "libnet";
31 include_subdirs "qmlflat";
32
33 (* -- Stubs -- *)
34
35 def_stubs ~dir:"libbase" "stubs";
36 def_stubs ~dir:"libsecurity" "ssl_ext";
37 def_stubs ~dir:"appruntime" "io";
38 def_stubs ~dir:"libsecurity" "cryptokit2";
39
40 let root_ocamldir = Config.ocamllib in
41
42 let is_release () = Config.is_release in
43
44 let link_cmd = if windows_mode then S[Sh"cp";A"-r"] else S[Sh"ln";A"-s";A"-f"] in
45
46 let extralib_opt = function
47 | Some (lib,ldir,idir) ->
48 flag ["link"; "use_"^lib] (S [A "-ccopt"; P ("-L" ^ ldir); A"-cclib"; A ("-l" ^ lib)]);
49 flag ["compile"; "c"; "use_"^lib] (S [A"-I"; P idir])
50 | None -> ()
51 in
52 extralib_opt Config.libnatpmp;
53 extralib_opt Config.miniupnpc;
54
55
56 begin
57 match Config.camlidl with
58 | None -> ()
59 | Some camlidl ->
60 flag ["link"; "use_camlidl"] (S [A "-cclib"; P "-lcamlidl" ]);
61
62 rule "camlidl processing: .idl -> .ml .mli _stubs.c lib_stubs.clib"
63 ~deps:[ "%(dir)stubs%(name).idl" ]
64 ~prods:[ "%(dir:<**/>)stubs%(name:<*> and not <*.*> and not <>).mli";
65 "%(dir:<**/>)stubs%(name:<*> and not <*.*> and not <>).ml" ;
66 "%(dir:<**/>)stubs%(name:<*> and not <*.*> and not <>)_stubs.c" ]
67 ~insert:`top
68 (fun env _build ->
69 let dir = env "%(dir)" in
70 let name = env "%(name)" in
71
72 def_stubs ~dir (name ^ "_idl");
73
74 Cmd(S[Sh"cd"; P dir; Sh"&&";
75 P camlidl; A"-prepro"; P"/usr/bin/cpp"; A"-no-include"; P ("stubs" ^ name -.- "idl") ])
76 )
77 end;
78
79 (* -- Ocamldoc plugin -- *)
80
81 flag_and_dep ["ocaml"; "doc"] (S[A"-g";P"utils/ocamldoc_plugin.cmxs"]);
82
83 (* ------------------------------------------------------------ *)
84 (* Hacks *)
85 (* ------------------------------------------------------------ *)
86
87 (* opatop needs to link its serverLib *then* opabsl *then* the rest. We
88 cheat by copying the opabsl generated files so that they can be seen as
89 local by opatop. *)
90 let magic_import_from_opabsl dest f =
91 rule ("import from opabsl: "^f) ~deps:["opabsl/"^f] ~prod:(dest / f)
92 (fun env build ->
93 Seq[Cmd(S[Sh"mkdir";A"-p";P dest]);
94 if Pathname.exists "opabsl"
95 then (build_list build ["opabsl" / f]; cp ("opabsl"/ f) dest)
96 else cp (mlstatelibs/"opabsl"/ f) dest
97 ])
98 in
99 List.iter
100 (fun m -> magic_import_from_opabsl "opatop" (m ^ ".ml"))
101 [ "opabslgenMLRuntime"; "opabslgenLoader" ];
102
103
104 (* ------------------------------------------------------------ *)
105 (* Additional rules: internal *)
106 (* ------------------------------------------------------------ *)
107
108 (* -- static ppdebug -- *)
109 (* what happens here is:
110 * - generate the file _build/environment containing the environment vars used by ppdebug
111 * - make files tagged with with_static_proprecessing depend on _build/environment
112 * - tag any ml file containing some static ppdebug with the tag with_static_proprecessing
113 *)
114
115 let static_ppdebug_vars = [
116 "CPS_WITH_ML_CLOSURE"; (* disable the use of qml closures in cps continuations
117 * (for performance reasons) *)
118 "CPS_STACK_SIZE" ; (* observe the size of the stack @ cps return *)
119 ] in
120 let environment = "environment" in
121 let build_env_strings =
122 (List.map
123 (fun s ->
124 Printf.sprintf "let %s = %s\n"
125 s (try Printf.sprintf "Some %S" (Sys.getenv s)
126 with Not_found -> "None")
127 ) static_ppdebug_vars) in
128 dep ["with_static_preprocessing"] [environment];
129
130 rule "environment generation"
131 ~prods:[environment;"i_dont_exist"](* fake prod to make sure this rule is
132 * always called *)
133 (fun env build ->
134 Echo (build_env_strings, environment));
135
136 let generate_ocamldep_rule ml_or_mli =
137 rule ("ocaml dependencies " ^ ml_or_mli ^ " reloaded (deps of static ppdebug)")
138 ~prod:("%." ^ ml_or_mli ^ ".depends")
139 ~dep:("%." ^ ml_or_mli)
140 ~insert:`top (* need to be inserted before the real ocamldep rule *)
141 (fun env build ->
142 let ml = env "%." ^ ml_or_mli in
143 if Tags.mem "with_mlstate_debug" (tags_of_pathname ml) &&
144 Sys.command ("grep -q '#<Ifstatic:' " ^ Pathname.to_string ml) = 0
145 then
146 tag_file ml ["with_static_preprocessing"];
147 fail_rule build (* failing to that ocamlbuild calls the real ocamldep rule *)
148 ) in
149 generate_ocamldep_rule "ml";
150 generate_ocamldep_rule "mli";
151
152 (* -- Macro-rules generating mlstate_platform.h files -- *)
153 (* TODO BUG 2 : droits du script invalides *)
154 (* TODO BUG 3 : path du fichier généré foireux *)
155 rule "mlstate_platform: () -> libbase/mlstate_platform.h"
156 ~deps:(tool_deps "mlstate_platform")
157 ~prods:["libbase/mlstate_platform.h"]
158 (fun env build ->
159 Seq[
160 Cmd(S[Sh"chmod +x"; P "libbase/gen_platform"]);
161 Cmd(S[get_tool "mlstate_platform"; A (if windows_mode then "WIN" else "")]);
162 Cmd(S[Sh"mv mlstate_platform.h libbase/mlstate_platform.h"])
163 ]
164 );
165
166 (* -- Opa stdlib -- *)
167
168 (*
169 <!> Mathieu Fri Oct 22 10:54:50 CEST 2010
170 !! IF YOU NEED TO PATCH THE FOLLOWING RULE !!
171 ---> come to me, we have to talk first.
172 *)
173 let stdlib_files =
174 (* keep in sync with s3passes@pass_AddStdlibFiles*)
175 let core_dir = "stdlib/core" in
176 let tests_dir = "stdlib/tests" in
177 let dirs = core_dir :: tests_dir :: rec_subdirs [ core_dir ] in
178 let files = List.fold_right (fun dir acc -> dir_ext_files "js" dir @ dir_ext_files "opa" dir @ acc) dirs [] in
179 files
180 in
181 rule "stdlib embedded: stdlib_files -> opalib/staticsInclude.of"
182 ~deps:stdlib_files
183 ~prod:"opalib/staticsInclude.of"
184 (fun env build -> Echo (List.map (fun f -> f^"\n") stdlib_files, "opalib/staticsInclude.of"));
185
186 let opa_opacapi_files =
187 let dirs = rec_subdirs ["stdlib"] in
188 let files = List.fold_right (fun dir acc -> dir_ext_files "opa" dir @ acc) dirs [] in
189 files
190 in
191
192 (* used in mkinstall *)
193 let opacapi_validation = "opacapi.validation" in
194 rule "Opa Compiler Interface Validation (opacapi)"
195 ~deps:("opa/checkopacapi.native" :: opa_opacapi_files)
196 ~prod:opacapi_validation
197 (fun env build ->
198 Cmd(S ([
199 P "./opa/checkopacapi.native" ;
200 A "-o" ;
201 P opacapi_validation ;
202 ] @ (List.rev_map (fun file -> P file) opa_opacapi_files)));
203 );
204
205 (* -- Build infos and runtime version handling -- *)
206
207 (* TODO: probably same bugs than mlstate_platform *)
208 let generate_buildinfos = "buildinfos/generate_buildinfos.sh" in
209 let version_buildinfos = "buildinfos/version.txt" in
210 let pre_buildinfos = "buildinfos/buildInfos.ml.pre" in
211 let post_buildinfos = "buildinfos/buildInfos.ml.post" in
212 let buildinfos = "buildinfos/buildInfos.ml" in
213 rule "buildinfos: buildinfos/* -> buildinfos/buildInfos.ml"
214 ~deps:[version_buildinfos ; pre_buildinfos ; generate_buildinfos ; post_buildinfos]
215 ~prods:(buildinfos :: (if is_release() then ["always_rebuild"] else []))
216 (fun env build ->
217 let version = env version_buildinfos in
218 let pre_prod = env pre_buildinfos in
219 let prod = env buildinfos in
220 let post_prod = env post_buildinfos in
221 Seq[
222 Cmd(S[Sh "cat" ; P pre_prod ; Sh ">" ; P prod]);
223 Cmd(S[P "bash"; A "-e"; P generate_buildinfos; P Pathname.pwd;
224 if is_release () then A "--release" else N;
225 A "--version" ; P version ;
226 Sh ">>" ; P prod]);
227 Cmd(S[Sh "cat" ; P post_prod ; Sh ">>" ; P prod]);
228 ]
229 );
230
231 let parser_files =
232 let dir = ["opalang/syntax"] in
233 let files = List.fold_right (fun dir acc -> dir_ext_files "trx" dir @ dir_ext_files "ml" dir) dir ["general/surfaceAst.ml"] in
234 files
235 in
236 let opaParserVersion = "opalang"/"syntax"/"opaParserVersion.ml"
237 in
238 rule "opa parser version: opalang/syntax/* stdlib -> opalang/syntax/opaParserVersion.ml"
239 ~deps:parser_files
240 ~prod:opaParserVersion
241 (fun build env ->
242 let files = List.map (fun s-> P s) parser_files in
243 Seq[
244 Cmd(S ( [Sh"echo let hash = \\\" > "; P (opaParserVersion)]));
245 Cmd(S ( [Sh"cat"] @ files @ [Sh"|";Sh"md5sum";Sh">>";P opaParserVersion]));
246 Cmd(S ( [Sh"echo \\\" >>"; P opaParserVersion ] ))
247 ]
248 );
249
250 (* -- Internal use of built tools -- *)
251
252 rule " ofile"
253 ~deps:("%.of" :: tool_deps "ofile")
254 ~prod:"%.ml"
255 (fun env build ->
256 let dir = Pathname.dirname (env "%.of") in
257 build_list build (string_list_of_file (env "%.of"));
258 Cmd(S[get_tool "ofile"; A"-path"; P(Pathname.pwd / !Options.build_dir); P(env "%.of")]));
259
260 (* -- Proto rules -- *)
261
262 rule "proto_deps: proto -> proto.depends"
263 ~dep: "%.proto"
264 ~prod: "%.proto.depends"
265 (proto_deps "%.proto" "%.proto.depends");
266
267 rule "proto: proto & proto_depends -> ml & mli & trx_parse"
268 ~deps:("%.proto" :: "%.proto.depends" :: tool_deps "genproto")
269 ~prods: [ "%.ml" ; "%.mli" ; "%_parse.trx" ]
270 (fun env build ->
271 let dir = Pathname.dirname (env "%.proto") in
272 let proto_deps = (string_list_of_file (env "%.proto.depends")) in
273 if proto_deps <> [] then build_list build proto_deps;
274 Cmd(S[get_tool "genproto"
275 ; P (env "%.proto")
276 ; P dir
277 ; P (Pathname.basename (env "%"))
278 ; P (Pathname.basename (env "%") ^ "_parse")
279 ]));
280
281 (* -- Wsdl2ml rules -- *)
282
283 rule "wsdl2ml: wsdl -> types.ml"
284 ~deps:("%.wsdl" :: tool_deps "wsdl2ml")
285 ~prods: [ "%types.ml" ]
286 (fun env build ->
287 let dir = Pathname.dirname (env "%.wsdl") in
288 Cmd(S[get_tool "wsdl2ml"
289 ; P (env "%.wsdl")
290 ]));
291
292 (* -- Mlidl rules -- *)
293
294 rule "mlidl: mlidl -> types.ml & types.mli"
295 ~deps:("%.mlidl" :: tool_deps "mlidl")
296 ~prods: [ "%types.ml"; "%types.mli" ]
297 (fun env build ->
298 let dir = Pathname.dirname (env "%.mlidl") in
299 Cmd(S[get_tool "mlidl"
300 ; P (env "%.mlidl")
301 ]));
302
303 (* -- BSL compilation (using bslregister) -- *)
304
305
306 let ml_sources_bsl = dir_sources_bsl "opabsl/mlbsl" in
307 let js_sources_bsl = dir_sources_bsl "opabsl/jsbsl" in
308 let js_dest_bsl = dir_sources_bsl ~prefix:"opabslgen_" "opabsl/jsbsl" in
309 let mlstate_init_bsl = dir_sources_bsl "opabsl/mlstatebsl" in
310 let js_conf = "opabsl/jsbsl/bsl-sources.jsconf" in
311
312 (*
313 let rec ponctuate s f = function
314 | [] -> ""
315 | [ty] -> f ty
316 | ty::q -> ((f ty) ^ s) ^ ponctuate s f q
317 in
318
319 let _ = Printf.eprintf "js_sources_bsl: %s\n" (ponctuate ", " (fun x -> x) (List.map Ocamlbuild_plugin.Pathname.to_string js_sources_bsl)) in
320 let _ = Printf.eprintf "js_dest_bsl: %s\n" (ponctuate ", " (fun x -> x) (List.map Ocamlbuild_plugin.Pathname.to_string js_dest_bsl)) in
321 *)
322
323 (* TODO: this is not the way to LLVM, the C code is not usable as it is now *)
324 (* let c_sources_bsl = dir_sources_bsl "opabsl/cbsl" in *)
325
326 (* used for js-validation-only *)
327 rule "opabsl_sources"
328 ~deps: (js_conf :: ml_sources_bsl
329 @ js_sources_bsl
330 @ mlstate_init_bsl
331 @ tool_deps "opa-plugin-builder-bin")
332 ~prods: ((List.map (fun s -> "opabsl"/s)
333 ["opabslgenLoader.ml";"opabslgenPlugin.ml";
334 "opabslgen.bypass" ;
335 "opabslgenMLRuntime_x.ml";"opabslgenMLRuntime_x.mli";
336 "opabslgenJSkeys.js";
337 ])@js_dest_bsl)
338 begin fun env build ->
339 Seq[Cmd(S([Sh"cd opabsl && ";
340 get_tool "opa-plugin-builder-bin";
341 A"-o";P"opabslgen";
342 A"--no-opp";
343 A"--no-build";
344 A"--static";
345 ]
346 @special_bsl_options@
347 List.map (fun s -> P (".."/s)) (
348 js_conf ::
349 ml_sources_bsl
350 @js_sources_bsl
351 @mlstate_init_bsl
352 )));
353 mv "opabsl/opabslgenMLRuntime.ml" "opabsl/opabslgenMLRuntime_x.ml";
354 mv "opabsl/opabslgenMLRuntime.mli" "opabsl/opabslgenMLRuntime_x.mli";
355 ]
356 end;
357
358 rule "opa-bslgenMLRuntime interface validation"
359 ~deps: [
360 "opabsl/opabslgenMLRuntime_x.cmo";
361 "opabsl/js_validation/imp_client_lib.js";
362 "opabsl/js_validation/bsl.js";
363 ]
364 ~prod: "opabsl/opabslgenMLRuntime.ml"
365 (fun env build ->
366 Seq[
367 cp "opabsl/opabslgenMLRuntime_x.ml" "opabsl/opabslgenMLRuntime.ml";
368 ]
369 );
370
371 let js_pp_bsl = dir_sources_bsl ~prefix:"opabslgen_" ~suffix:".pp" "opabsl/jsbsl" in
372
373 rule "preprocess JS files for validation"
374 ~deps:((tool_deps "ppjs")@js_dest_bsl)
375 ~prods:js_pp_bsl
376 (fun env build ->
377 let ppjs = get_tool "ppjs" in
378 Cmd(S (ppjs::A"--output-suffix"::A ".pp"::List.map (fun x -> A x) js_dest_bsl))
379 );
380
381 (*
382 TODO: enable all of them as soon as possible.
383 *)
384 let google_closure_compiler_options =
385 A"--warning_level" :: A"VERBOSE"::
386 (*
387 Turn on every available warning as errors.
388 Keep synchronized with the checker.
389 *)
390 (
391 List.fold_left (fun acc s -> A"--jscomp_error" :: A s :: acc)
392 [] [
393 "accessControls" ;
394 "checkRegExp" ;
395 (* "checkTypes" ; *)
396 "checkVars" ;
397 "deprecated" ;
398 "fileoverviewTags" ;
399 "invalidCasts" ;
400 (* "missingProperties" ; *)
401 (* "nonStandardJsDocs" ; *)
402 "strictModuleDepCheck" ;
403 "undefinedVars" ;
404 "unknownDefines" ;
405 "visibility" ;
406 ]
407 ) in
408
409
410 rule "Client lib JS validation"
411 ~deps: (
412 "qmljsimp/qmlJsImpClientLib.js" ::
413 "qmlcps/qmlCpsClientLib.js" ::
414 (tool_deps "jschecker.jar") @
415 (tool_deps "jschecker_externals.js") @
416 (tool_deps "jschecker_clientliblib.js") @
417 (tool_deps "jschecker_jquery.js") )
418 ~prods:[
419 "opabsl/js_validation/imp_client_lib.js";
420 ]
421 (fun env build ->
422 let run_check clientlib output_file =
423 let local = windows_mode in
424 [
425 Cmd(S [Sh"mkdir"; A"-p";P "opabsl/js_validation"]);
426 Cmd(S(
427 A"java" :: A"-jar" :: (get_tool ~local "jschecker.jar") ::
428 A"--externs" :: (get_tool ~local "jschecker_externals.js") ::
429 A"--externs" :: (get_tool ~local "jschecker_jquery.js") ::
430 A"--externs" :: (get_tool ~local "jschecker_clientliblib.js") ::
431 A"--js_output_file" :: A output_file ::
432 google_closure_compiler_options @
433 A"--js" :: A clientlib ::
434 A"--js" :: A"qmlcps/qmlCpsClientLib.js" ::
435 []
436 ))
437 ]
438 in
439 Seq (
440 run_check "qmljsimp/qmlJsImpClientLib.js" "opabsl/js_validation/imp_client_lib.js"
441 )
442 );
443
444 rule "opa-bslgenMLRuntime JS validation"
445 ~deps: (
446 (tool_deps "jschecker.jar")
447 @ (tool_deps "jschecker_externals.js")
448 @ (tool_deps "jschecker_jquery.js")
449 @ (tool_deps "jschecker_clientlib.js")
450 @ (tool_deps "jschecker_clientliblib.js")
451 @ (tool_deps "jschecker_cpsclientlib.js")
452 @ js_pp_bsl
453 @ [ "opabsl/opabslgenJSkeys.js" ]
454 )
455 ~prods: ["opabsl/js_validation/bsl.js"]
456 (fun env build ->
457 let arg_of_file file acc = match file with (*A very dumb filter to get rid of files that we just can't fix in the first place*)
458 | "opabsl/jsbsl/opabslgen_jquery-1.6.1.js.pp" -> acc
459 | "opabsl/jsbsl/opabslgen_json2.js.pp" -> acc
460 | _ -> A "--js" :: A file :: acc
461 in
462 let get_tool = get_tool ~local:windows_mode in
463 Seq[
464 Cmd(S [Sh"mkdir";A"-p";P "opabsl/js_validation"]);
465 Cmd(S(
466 A"java" :: A"-jar" :: (get_tool "jschecker.jar") ::
467 A"--externs" :: (get_tool "jschecker_externals.js") ::
468 A"--externs" :: (get_tool "jschecker_clientliblib.js") ::
469 A"--externs" :: (get_tool "jschecker_clientlib.js") ::
470 A"--externs" :: (get_tool "jschecker_jquery.js") ::
471 A"--externs" :: (get_tool "jschecker_cpsclientlib.js") ::
472 A"--js_output_file" :: A"opabsl/js_validation/bsl.js" ::
473 google_closure_compiler_options @
474 (List.fold_right (fun s acc -> arg_of_file s acc) js_pp_bsl [])
475 @ [ A"--js" ; A "opabsl/opabslgenJSkeys.js" ]
476 ))]
477 );
478
479 (*
480 -The documentation generator does not work if files are not suffixed with '.js'
481 -But, we do not need to preprocess the opabslgen_ files with ppjs,
482 as for JS validation (files js_pp_bsl)
483 -We simply use the files opabslgen_ for generating the doc. It is obtained from
484 the origin js file, and with a resolution of bsl directives (+ generation of additionnal
485 type directive for the js validation
486
487 Configuration stuff for jsdoc generator.
488 Needs to access lots of files. Cf jsdocdir/README.txt
489 *)
490 let jsdocdir =
491 let opageneral = Pathname.to_string Pathname.pwd in
492 opageneral ^ "/tools/jsdoc-toolkit"
493 in
494
495 let jsdoc_target = "doc.jsbsl" in
496
497 rule "opa-bslgenMLRuntime JS documentation"
498 ~deps: (
499 js_dest_bsl
500 )
501 ~prods: (
502 [ jsdoc_target ^ "/index.html" ]
503 )
504 (fun env build ->
505 Cmd(S(
506 A"java" ::
507 A("-Djsdoc.dir="^jsdocdir) ::
508 A("-Djsdoc.template.dir="^jsdocdir^"/templates") ::
509 A"-jar" ::
510 A(jsdocdir^"/jsrun.jar") :: A(jsdocdir^"/app/run.js") ::
511 A("-t="^(jsdocdir^"/templates/jsdoc")) ::
512 A("--allfunctions") ::
513 (* Set the target directory *)
514 A("-d="^jsdoc_target) ::
515 (List.map (fun js -> A js) js_dest_bsl)
516 ))
517 );
518
519
520 (* ------------------------------------------------------------------ *)
521 (* Additional rules: final compilation (compiling using our backends) *)
522 (* ------------------------------------------------------------------ *)
523
524 (* -- OPA compiler rules -- *)
525
526 let stdlib_packages_dir = "stdlib" in
527
528 let opaopt = try Sh(Sys.getenv "OPAOPT") with Not_found -> N in
529
530 let opacomp_deps_js = string_list_of_file "opa-run-js-libs.itarget" in
531 let opacomp_deps_native = string_list_of_file "opa-run-libs.itarget" in
532 let opacomp_deps_byte = List.map (fun l -> Pathname.update_extension "cma" l) opacomp_deps_native in
533
534 let opacomp_deps_native = opacomp_deps_native @ opacomp_deps_js in
535 let opacomp_deps_byte = opacomp_deps_byte @ opacomp_deps_js in
536
537 let opa_prefix = Pathname.pwd / !Options.build_dir in
538
539 let opa_libs_dir = "lib" / "opa" / "static" in
540
541 let opa_share_dir = "share" / "opa" in
542
543 let copy_lib_to_runtime lib =
544 let modules = string_list_of_file (lib -.- "mllib") in
545 let files =
546 List.fold_left
547 (fun acc f ->
548 let dir, modl = Pathname.dirname f, Pathname.basename f -.- "cmi" in
549 List.filter (fun m -> Pathname.exists (opa_prefix / m))
550 [dir / String.uncapitalize modl; dir / String.capitalize modl] @ acc)
551 [] modules
552 in
553 let stubs =
554 List.map (Pathname.update_extension !Options.ext_lib) (dir_ext_files "clib" (mlstate_lib_dir lib))
555 in
556 let files = stubs @ files in
557 Cmd(S(link_cmd :: List.map (fun f -> P (opa_prefix / f)) files @ [ P (opa_prefix / opa_libs_dir) ]))
558 in
559
560 rule "opa run-time libraries"
561 ~deps:("libbase"/"mimetype_database.xml" :: opacomp_deps_native)
562 ~stamp:"runtime-libs.stamp"
563 (fun _env _build ->
564 let mllibs = List.filter (fun f -> Pathname.check_extension f "cmxa") opacomp_deps_native in
565 let mllibs = List.map Pathname.remove_extension mllibs in
566 let copylibs = List.map copy_lib_to_runtime mllibs in
567 Seq[
568 Cmd(S[Sh"rm"; A"-rf"; P (opa_prefix / opa_libs_dir)]);
569 Cmd(S[Sh"mkdir"; A"-p"; P (opa_prefix / opa_libs_dir)]);
570 Cmd(S[Sh"rm"; A"-rf"; P (opa_prefix / opa_share_dir)]);
571 Cmd(S[Sh"mkdir"; A"-p"; P (opa_prefix / opa_share_dir)]);
572 Cmd(S(link_cmd :: List.map (fun f -> P (opa_prefix / f)) opacomp_deps_native
573 @ [ P (opa_prefix / opa_libs_dir) ]));
574 Cmd(S(link_cmd :: List.map (fun f -> P (opa_prefix / f -.- !Options.ext_lib)) mllibs
575 @ [ P (opa_prefix / opa_libs_dir) ]));
576 Cmd(S(link_cmd :: P (opa_prefix / "libbase" / "mimetype_database.xml") :: [ P (opa_prefix / opa_share_dir / "mimetype_database.xml") ]));
577 Seq copylibs
578 ]
579 );
580
581 let opacomp build src dst_ext opt =
582 build_list build
583 (List.map ((/) (Pathname.dirname src)) (string_list_of_file (src-.-"depends")));
584 let dst = Pathname.update_extension dst_ext src in
585 Cmd(S[
586 Sh("MLSTATELIBS=\""^ opa_prefix ^"\"");
587 get_tool "opa-bin"; opt;
588 A"--verbose";(* A"--no-opa-walker"; *)
589 opaopt;
590 A"-o"; P dst; P src
591 ])
592 in
593
594 rule "opa and server dependencies"
595 ~deps:("runtime-libs.stamp" :: tool_deps "opa-bin")
596 ~stamp:"opacomp.stamp"
597 (fun env build -> Nop);
598
599 rule "opackdep: .opack -> .opack.depends"
600 ~dep:"%.opack"
601 ~prod:"%.opack.depends"
602 (fun env build ->
603 Cmd(S[P"grep"; A"-v"; A"^\\w*-"; P(env "%.opack"); Sh">"; P(env "%.opack.depends"); Sh"|| true"]));
604
605 (* A rule to build applications using the stdlib (e.g. opadoc) *)
606 rule "opacomp: .opack -> .native"
607 ~deps: ("%.opack"::"%.opack.depends"::"opa-packages.stamp"::"opacomp.stamp"::[])
608 ~prod: "%.native"
609 (fun env build ->
610 let dir = Pathname.dirname (env "%") in
611 let mano_depends = Pathname.pwd / (env "%.depends") in
612 if Pathname.exists mano_depends then (
613 build_list build (List.map ((/) dir) (string_list_of_file mano_depends))
614 );
615 build_list build (List.map ((/) dir) (string_list_of_file (env "%.opack.depends")));
616 opacomp build (env "%.opack") "native"
617 (S[ A"-I" ; P stdlib_packages_dir ; A"--project-root" ; P dir]));
618
619 rule "opacomp: .opack -> .byte"
620 ~deps: ("%.opack"::"%.opack.depends"::"opa-packages.stamp"::"opacomp-byte.stamp"::[])
621 ~prod: "%.byte"
622 (fun env build ->
623 let dir = Pathname.dirname (env "%") in
624 build_list build (List.map ((/) dir) (string_list_of_file (env "%.opack.depends")));
625 opacomp build (env "%.opack") "byte" (S[A"-I";P stdlib_packages_dir]));
626 (*
627 (A"--bytecode"));
628 Used to give this option to opa-bin, but since the opa package are build by ocamlbuild,
629 we do not generated bytecode version of opa-packages, making the bytecode compilation
630 of server not available anymore.
631 *)
632
633 (* temporary and unreliable *)
634 rule "opadep: .opa -> .opa.depends"
635 ~dep: "%.opa"
636 ~prod: "%.opa.depends"
637 (fun env build ->
638 let dep_regex = "^ *import \\+\\(.\\+\\)$" in
639 Cmd(S[sed; A("s%"^dep_regex^"%\\1.opx%; t OK; d; :OK s% %%g"); P(env "%.opa");
640 Sh">";P(env "%.opa.depends")]));
641
642 rule "opacomp: .opa -> .native"
643 ~deps: ("%.opa"::"%.opa.depends"::"opacomp.stamp"::[])
644 ~prod: "%.native"
645 (fun env build -> opacomp build (env "%.opa") "native" N);
646
647 rule "opacomp: .opa -> .byte"
648 ~deps: ("%.opa"::"%.opa.depends"::"opacomp-byte.stamp"::[])
649 ~prod: "%.byte"
650 (fun env build -> opacomp build (env "%.opa") "byte" (A"--bytecode"));
651
652 rule "opa bash_completion: opa-bin -> bash_completion"
653 ~deps: (tool_deps "opa-bin")
654 ~prod: "bash_completion"
655 (fun env build ->
656 Seq[Cmd(S[get_tool "opa-bin"; A"--bash-completion"])]);
657
658 (* -- OPA packages -- *)
659
660 let package_to_dir s0 =
661 let s = String.copy s0 in
662 for i = 0 to String.length s - 1 do
663 if s.[i] = '.' then s.[i] <- '/'
664 done;
665 s
666 in
667 let dir_to_package s0 =
668 let s = String.copy s0 in
669 let len_std = String.length stdlib_packages_dir in
670 let pfx,s = (* remove optional stdlib_packages_dir prefix *)
671 try
672 let pfx = String.sub s 0 len_std in
673 if pfx = stdlib_packages_dir
674 then pfx, String.sub s (len_std + 1) (String.length s - len_std - 1)
675 else "", s
676 with Invalid_argument _ -> "", s
677 in
678 for i = 0 to String.length s - 1 do
679 if s.[i] = '/' then s.[i] <- '.'
680 done;
681 pfx, s
682 in
683
684 let module RuleFailure = struct exception E end in
685 let files_of_package pkg =
686 let pkdir = package_to_dir pkg in
687 if not (Pathname.is_directory (Pathname.pwd / pkdir)) then
688 let () = Printf.eprintf "Error: can not find sources for package %s (directory %s does not exist)\n" pkg pkdir in
689 raise RuleFailure.E
690 else
691 let opack = dir_ext_files "opack" (Pathname.pwd / pkdir) in
692 let files = dir_ext_files "opa" (Pathname.pwd / pkdir) in
693 let files = files @ opack in
694 (*
695 return relative filenames
696 *)
697 let files =
698 let len = String.length Pathname.pwd + 1 in (* the additinal '/' *)
699 let relative_part s = String.sub s len (String.length s - len) in
700 List.map relative_part files
701 in
702 (*
703 When you compare 2 branches, if the order of opa sources is not deterministic, you can become crazy
704 *)
705 let files = List.sort String.compare files in
706 files in
707
708 let make_all_packages = stdlib_packages_dir/"all_packages.sh" in
709 let all_packages_file = stdlib_packages_dir/"all.packages" in
710
711 rule "all.packages"
712 ~dep: make_all_packages
713 ~prod: all_packages_file
714 (fun env build ->
715 Cmd(S[
716 Sh"cd"; P (Pathname.pwd / stdlib_packages_dir); Sh"&&";
717 P"./all_packages.sh"; Sh">"; P (Pathname.pwd / !Options.build_dir / all_packages_file);
718 ])
719 );
720
721 let package_building ~name ~stamp ~stdlib_only ~rebuild =
722 rule name
723 ~deps:[opacapi_validation;all_packages_file;"opacomp.stamp"]
724 ~stamp
725 ~prod:"i_dont_exist" (* forces ocamlbuild to always run the command *)
726 (fun env build ->
727 try
728 let packages = string_list_of_file all_packages_file in
729 let packages =
730 if stdlib_only
731 then
732 let stdlib = "stdlib.core" in
733 List.filter (fun package ->
734 String.length package > String.length stdlib &&
735 stdlib = String.sub package 0 (String.length stdlib)) packages
736 else packages in
737 let list_package_files = List.map
738 (fun pkg ->
739 let files = files_of_package pkg in
740 (*
741 Copy in _build the opa files of the packages.
742 In this way, files given to the compiler are relative,
743 and api files are generated in the _build
744 This makes also that the packages does not contain absolute filename,
745 which is not valid wrt the deb checker.
746 *)
747 build_list build files;
748 (pkg, files)) packages in
749 let conf =
750 List.concat (
751 List.map
752 (fun (pkg, files) ->
753 (pkg ^ ":\n") ::
754 (
755 (* auto import *)
756 let prefix = "stdlib.core" in
757 let len = String.length prefix in
758 if String.length pkg >= String.length prefix && String.sub pkg 0 len = prefix
759 then (
760 if pkg = prefix
761 then ""
762 else
763 (* subdirectory of stdlib.core import stdlib.core *)
764 "import stdlib.core"
765 )
766 else " import stdlib.core\n import stdlib.core.*\n"
767 ) ::
768 List.map (fun file -> " " ^ file ^ "\n") files)
769 list_package_files
770 ) in
771 let all_files = List.concat (List.map (fun (_,files) -> List.map (fun f -> P f) files) list_package_files) in
772 let rebuild_opt = if rebuild then [A"--rebuild"] else [] in
773 Seq[
774 Echo(conf, "conf");
775 Cmd(S([Sh("MLSTATELIBS=\""^ opa_prefix ^"\"");
776 get_tool "opa-bin";
777 A"--autocompile";
778 (* A"--verbose-build"; *)
779 A"--conf";P "conf";
780 A"--warn-error"; A"root";
781 A"--project-root"; P Pathname.pwd; (* because the @static_resource in the stdlib expect this *)
782 A"--no-stdlib";
783 opaopt;
784 S all_files;
785 ] @ rebuild_opt));
786 ]
787 with RuleFailure.E ->
788 fail_rule build
789 ) in
790
791 package_building
792 ~name:"opa-packages: meta-rule to build all .opx"
793 ~stamp:"opa-packages.stamp"
794 ~stdlib_only:false
795 ~rebuild:false;
796
797 package_building
798 ~name:"opa-stdlib-packages: meta-rule to build all the stdlib .opx"
799 ~stamp:"opa-stdlib-packages.stamp"
800 ~stdlib_only:true
801 ~rebuild:false;
802
803 () (* This file should be an expr of type unit *)
Something went wrong with that request. Please try again.