Project

General

Profile

Revision 3f823d04 myocamlbuild.ml

View differences:

myocamlbuild.ml
1 1
(* OASIS_START *)
2
(* DO NOT EDIT (digest: 00359f2e15a7ed8f31f1d7ce086345f9) *)
2
(* DO NOT EDIT (digest: 5a9a2168dcb86db37476d58b8c0e25b3) *)
3 3
module OASISGettext = struct
4
(* # 21 "/build/buildd/oasis-0.3.0/src/oasis/OASISGettext.ml" *)
4
(* # 22 "src/oasis/OASISGettext.ml" *)
5

  
5 6

  
6 7
  let ns_ str =
7 8
    str
8 9

  
10

  
9 11
  let s_ str =
10 12
    str
11 13

  
12
  let f_ (str : ('a, 'b, 'c, 'd) format4) =
14

  
15
  let f_ (str: ('a, 'b, 'c, 'd) format4) =
13 16
    str
14 17

  
18

  
15 19
  let fn_ fmt1 fmt2 n =
16 20
    if n = 1 then
17 21
      fmt1^^""
18 22
    else
19 23
      fmt2^^""
20 24

  
25

  
21 26
  let init =
22 27
    []
23 28

  
29

  
24 30
end
25 31

  
26 32
module OASISExpr = struct
27
(* # 21 "/build/buildd/oasis-0.3.0/src/oasis/OASISExpr.ml" *)
33
(* # 22 "src/oasis/OASISExpr.ml" *)
34

  
35

  
28 36

  
29 37

  
30 38

  
31 39
  open OASISGettext
32 40

  
33
  type test = string 
34 41

  
35
  type flag = string 
42
  type test = string
43

  
44

  
45
  type flag = string
46

  
36 47

  
37 48
  type t =
38 49
    | EBool of bool
......
41 52
    | EOr of t * t
42 53
    | EFlag of flag
43 54
    | ETest of test * string
44
    
45 55

  
46
  type 'a choices = (t * 'a) list 
56

  
57

  
58
  type 'a choices = (t * 'a) list
59

  
47 60

  
48 61
  let eval var_get t =
49 62
    let rec eval' =
......
75 88
    in
76 89
      eval' t
77 90

  
91

  
78 92
  let choose ?printer ?name var_get lst =
79 93
    let rec choose_aux =
80 94
      function
......
111 125
    in
112 126
      choose_aux (List.rev lst)
113 127

  
128

  
114 129
end
115 130

  
116 131

  
117
# 117 "myocamlbuild.ml"
132
# 132 "myocamlbuild.ml"
118 133
module BaseEnvLight = struct
119
(* # 21 "/build/buildd/oasis-0.3.0/src/base/BaseEnvLight.ml" *)
134
(* # 22 "src/base/BaseEnvLight.ml" *)
135

  
120 136

  
121 137
  module MapString = Map.Make(String)
122 138

  
139

  
123 140
  type t = string MapString.t
124 141

  
142

  
125 143
  let default_filename =
126 144
    Filename.concat
127 145
      (Sys.getcwd ())
128 146
      "setup.data"
129 147

  
148

  
130 149
  let load ?(allow_empty=false) ?(filename=default_filename) () =
131 150
    if Sys.file_exists filename then
132 151
      begin
......
184 203
             filename)
185 204
      end
186 205

  
187
  let var_get name env =
188
    let rec var_expand str =
189
      let buff =
190
        Buffer.create ((String.length str) * 2)
191
      in
192
        Buffer.add_substitute
193
          buff
194
          (fun var ->
195
             try
196
               var_expand (MapString.find var env)
197
             with Not_found ->
198
               failwith
199
                 (Printf.sprintf
200
                    "No variable %s defined when trying to expand %S."
201
                    var
202
                    str))
203
          str;
204
        Buffer.contents buff
206

  
207
  let rec var_expand str env =
208
    let buff =
209
      Buffer.create ((String.length str) * 2)
205 210
    in
206
      var_expand (MapString.find name env)
211
      Buffer.add_substitute
212
        buff
213
        (fun var ->
214
           try
215
             var_expand (MapString.find var env) env
216
           with Not_found ->
217
             failwith
218
               (Printf.sprintf
219
                  "No variable %s defined when trying to expand %S."
220
                  var
221
                  str))
222
        str;
223
      Buffer.contents buff
224

  
225

  
226
  let var_get name env =
227
    var_expand (MapString.find name env) env
228

  
207 229

  
208 230
  let var_choose lst env =
209 231
    OASISExpr.choose
......
212 234
end
213 235

  
214 236

  
215
# 215 "myocamlbuild.ml"
237
# 237 "myocamlbuild.ml"
216 238
module MyOCamlbuildFindlib = struct
217
(* # 21 "/build/buildd/oasis-0.3.0/src/plugins/ocamlbuild/MyOCamlbuildFindlib.ml" *)
239
(* # 22 "src/plugins/ocamlbuild/MyOCamlbuildFindlib.ml" *)
240

  
218 241

  
219
  (** OCamlbuild extension, copied from 
242
  (** OCamlbuild extension, copied from
220 243
    * http://brion.inria.fr/gallium/index.php/Using_ocamlfind_with_ocamlbuild
221 244
    * by N. Pouillard and others
222 245
    *
223 246
    * Updated on 2009/02/28
224 247
    *
225
    * Modified by Sylvain Le Gall 
248
    * Modified by Sylvain Le Gall
226 249
    *)
227 250
  open Ocamlbuild_plugin
228 251

  
252

  
229 253
  (* these functions are not really officially exported *)
230
  let run_and_read = 
254
  let run_and_read =
231 255
    Ocamlbuild_pack.My_unix.run_and_read
232 256

  
233
  let blank_sep_strings = 
257

  
258
  let blank_sep_strings =
234 259
    Ocamlbuild_pack.Lexers.blank_sep_strings
235 260

  
236
  let split s ch =
237
    let x = 
238
      ref [] 
261

  
262
  let exec_from_conf exec =
263
    let exec =
264
      let env_filename = Pathname.basename BaseEnvLight.default_filename in
265
      let env = BaseEnvLight.load ~filename:env_filename ~allow_empty:true () in
266
      try
267
        BaseEnvLight.var_get exec env
268
      with Not_found ->
269
        Printf.eprintf "W: Cannot get variable %s\n" exec;
270
        exec
271
    in
272
    let fix_win32 str =
273
      if Sys.os_type = "Win32" then begin
274
        let buff = Buffer.create (String.length str) in
275
        (* Adapt for windowsi, ocamlbuild + win32 has a hard time to handle '\\'.
276
         *)
277
        String.iter
278
          (fun c -> Buffer.add_char buff (if c = '\\' then '/' else c))
279
          str;
280
        Buffer.contents buff
281
      end else begin
282
        str
283
      end
239 284
    in
240
    let rec go s =
241
      let pos = 
242
        String.index s ch 
243
      in
244
        x := (String.before s pos)::!x;
245
        go (String.after s (pos + 1))
285
      fix_win32 exec
286

  
287
  let split s ch =
288
    let buf = Buffer.create 13 in
289
    let x = ref [] in
290
    let flush () =
291
      x := (Buffer.contents buf) :: !x;
292
      Buffer.clear buf
246 293
    in
247
      try
248
        go s
249
      with Not_found -> !x
294
      String.iter
295
        (fun c ->
296
           if c = ch then
297
             flush ()
298
           else
299
             Buffer.add_char buf c)
300
        s;
301
      flush ();
302
      List.rev !x
303

  
250 304

  
251 305
  let split_nl s = split s '\n'
252 306

  
307

  
253 308
  let before_space s =
254 309
    try
255 310
      String.before s (String.index s ' ')
256 311
    with Not_found -> s
257 312

  
258
  (* this lists all supported packages *)
313
  (* ocamlfind command *)
314
  let ocamlfind x = S[Sh (exec_from_conf "ocamlfind"); x]
315

  
316
  (* This lists all supported packages. *)
259 317
  let find_packages () =
260 318
    List.map before_space (split_nl & run_and_read "ocamlfind list")
261 319

  
262
  (* this is supposed to list available syntaxes, but I don't know how to do it. *)
320

  
321
  (* Mock to list available syntaxes. *)
263 322
  let find_syntaxes () = ["camlp4o"; "camlp4r"]
264 323

  
265
  (* ocamlfind command *)
266
  let ocamlfind x = S[A"ocamlfind"; x]
324

  
325
  let well_known_syntax = [
326
    "camlp4.quotations.o";
327
    "camlp4.quotations.r";
328
    "camlp4.exceptiontracer";
329
    "camlp4.extend";
330
    "camlp4.foldgenerator";
331
    "camlp4.listcomprehension";
332
    "camlp4.locationstripper";
333
    "camlp4.macro";
334
    "camlp4.mapgenerator";
335
    "camlp4.metagenerator";
336
    "camlp4.profiler";
337
    "camlp4.tracer"
338
  ]
339

  
267 340

  
268 341
  let dispatch =
269 342
    function
270
      | Before_options ->
271
          (* by using Before_options one let command line options have an higher priority *)
272
          (* on the contrary using After_options will guarantee to have the higher priority *)
273
          (* override default commands by ocamlfind ones *)
343
      | After_options ->
344
          (* By using Before_options one let command line options have an higher
345
           * priority on the contrary using After_options will guarantee to have
346
           * the higher priority override default commands by ocamlfind ones *)
274 347
          Options.ocamlc     := ocamlfind & A"ocamlc";
275 348
          Options.ocamlopt   := ocamlfind & A"ocamlopt";
276 349
          Options.ocamldep   := ocamlfind & A"ocamldep";
277 350
          Options.ocamldoc   := ocamlfind & A"ocamldoc";
278
          Options.ocamlmktop := ocamlfind & A"ocamlmktop"
279
                                  
351
          Options.ocamlmktop := ocamlfind & A"ocamlmktop";
352
          Options.ocamlmklib := ocamlfind & A"ocamlmklib"
353

  
280 354
      | After_rules ->
281
          
282
          (* When one link an OCaml library/binary/package, one should use -linkpkg *)
355

  
356
          (* When one link an OCaml library/binary/package, one should use
357
           * -linkpkg *)
283 358
          flag ["ocaml"; "link"; "program"] & A"-linkpkg";
284
          
359

  
285 360
          (* For each ocamlfind package one inject the -package option when
286 361
           * compiling, computing dependencies, generating documentation and
287 362
           * linking. *)
288
          List.iter 
363
          List.iter
289 364
            begin fun pkg ->
290
              flag ["ocaml"; "compile";  "pkg_"^pkg] & S[A"-package"; A pkg];
291
              flag ["ocaml"; "ocamldep"; "pkg_"^pkg] & S[A"-package"; A pkg];
292
              flag ["ocaml"; "doc";      "pkg_"^pkg] & S[A"-package"; A pkg];
293
              flag ["ocaml"; "link";     "pkg_"^pkg] & S[A"-package"; A pkg];
294
              flag ["ocaml"; "infer_interface"; "pkg_"^pkg] & S[A"-package"; A pkg];
295
            end 
365
              let base_args = [A"-package"; A pkg] in
366
              (* TODO: consider how to really choose camlp4o or camlp4r. *)
367
              let syn_args = [A"-syntax"; A "camlp4o"] in
368
              let args =
369
              (* Heuristic to identify syntax extensions: whether they end in
370
                 ".syntax"; some might not.
371
               *)
372
                if Filename.check_suffix pkg "syntax" ||
373
                   List.mem pkg well_known_syntax then
374
                  syn_args @ base_args
375
                else
376
                  base_args
377
              in
378
              flag ["ocaml"; "compile";  "pkg_"^pkg] & S args;
379
              flag ["ocaml"; "ocamldep"; "pkg_"^pkg] & S args;
380
              flag ["ocaml"; "doc";      "pkg_"^pkg] & S args;
381
              flag ["ocaml"; "link";     "pkg_"^pkg] & S base_args;
382
              flag ["ocaml"; "infer_interface"; "pkg_"^pkg] & S args;
383
            end
296 384
            (find_packages ());
297 385

  
298 386
          (* Like -package but for extensions syntax. Morover -syntax is useless
......
301 389
          flag ["ocaml"; "compile";  "syntax_"^syntax] & S[A"-syntax"; A syntax];
302 390
          flag ["ocaml"; "ocamldep"; "syntax_"^syntax] & S[A"-syntax"; A syntax];
303 391
          flag ["ocaml"; "doc";      "syntax_"^syntax] & S[A"-syntax"; A syntax];
304
          flag ["ocaml"; "infer_interface"; "syntax_"^syntax] & S[A"-syntax"; A syntax];
392
          flag ["ocaml"; "infer_interface"; "syntax_"^syntax] &
393
                S[A"-syntax"; A syntax];
305 394
          end (find_syntaxes ());
306 395

  
307 396
          (* The default "thread" tag is not compatible with ocamlfind.
308 397
           * Indeed, the default rules add the "threads.cma" or "threads.cmxa"
309 398
           * options when using this tag. When using the "-linkpkg" option with
310 399
           * ocamlfind, this module will then be added twice on the command line.
311
           *                        
400
           *
312 401
           * To solve this, one approach is to add the "-thread" option when using
313 402
           * the "threads" package using the previous plugin.
314 403
           *)
315 404
          flag ["ocaml"; "pkg_threads"; "compile"] (S[A "-thread"]);
316 405
          flag ["ocaml"; "pkg_threads"; "doc"] (S[A "-I"; A "+threads"]);
317 406
          flag ["ocaml"; "pkg_threads"; "link"] (S[A "-thread"]);
318
          flag ["ocaml"; "pkg_threads"; "infer_interface"] (S[A "-thread"])
407
          flag ["ocaml"; "pkg_threads"; "infer_interface"] (S[A "-thread"]);
408
          flag ["ocaml"; "package(threads)"; "compile"] (S[A "-thread"]);
409
          flag ["ocaml"; "package(threads)"; "doc"] (S[A "-I"; A "+threads"]);
410
          flag ["ocaml"; "package(threads)"; "link"] (S[A "-thread"]);
411
          flag ["ocaml"; "package(threads)"; "infer_interface"] (S[A "-thread"]);
319 412

  
320
      | _ -> 
413
      | _ ->
321 414
          ()
322

  
323 415
end
324 416

  
325 417
module MyOCamlbuildBase = struct
326
(* # 21 "/build/buildd/oasis-0.3.0/src/plugins/ocamlbuild/MyOCamlbuildBase.ml" *)
418
(* # 22 "src/plugins/ocamlbuild/MyOCamlbuildBase.ml" *)
419

  
327 420

  
328 421
  (** Base functions for writing myocamlbuild.ml
329 422
      @author Sylvain Le Gall
......
331 424

  
332 425

  
333 426

  
427

  
428

  
334 429
  open Ocamlbuild_plugin
335 430
  module OC = Ocamlbuild_pack.Ocaml_compiler
336 431

  
337
  type dir = string 
338
  type file = string 
339
  type name = string 
340
  type tag = string 
341 432

  
342
(* # 56 "/build/buildd/oasis-0.3.0/src/plugins/ocamlbuild/MyOCamlbuildBase.ml" *)
433
  type dir = string
434
  type file = string
435
  type name = string
436
  type tag = string
437

  
438

  
439
(* # 62 "src/plugins/ocamlbuild/MyOCamlbuildBase.ml" *)
440

  
343 441

  
344 442
  type t =
345 443
      {
346
        lib_ocaml: (name * dir list) list;
347
        lib_c:     (name * dir * file list) list; 
444
        lib_ocaml: (name * dir list * string list) list;
445
        lib_c:     (name * dir * file list) list;
348 446
        flags:     (tag list * (spec OASISExpr.choices)) list;
349 447
        (* Replace the 'dir: include' from _tags by a precise interdepends in
350 448
         * directory.
351 449
         *)
352
        includes:  (dir * dir list) list; 
353
      } 
450
        includes:  (dir * dir list) list;
451
      }
452

  
354 453

  
355 454
  let env_filename =
356
    Pathname.basename 
455
    Pathname.basename
357 456
      BaseEnvLight.default_filename
358 457

  
458

  
359 459
  let dispatch_combine lst =
360 460
    fun e ->
361
      List.iter 
461
      List.iter
362 462
        (fun dispatch -> dispatch e)
363
        lst 
463
        lst
464

  
364 465

  
365 466
  let tag_libstubs nm =
366 467
    "use_lib"^nm^"_stubs"
367 468

  
469

  
368 470
  let nm_libstubs nm =
369 471
    nm^"_stubs"
370 472

  
371
  let dispatch t e = 
372
    let env = 
373
      BaseEnvLight.load 
374
        ~filename:env_filename 
473

  
474
  let dispatch t e =
475
    let env =
476
      BaseEnvLight.load
477
        ~filename:env_filename
375 478
        ~allow_empty:true
376 479
        ()
377 480
    in
378
      match e with 
481
      match e with
379 482
        | Before_options ->
380 483
            let no_trailing_dot s =
381 484
              if String.length s >= 1 && s.[0] = '.' then
......
385 488
            in
386 489
              List.iter
387 490
                (fun (opt, var) ->
388
                   try 
491
                   try
389 492
                     opt := no_trailing_dot (BaseEnvLight.var_get var env)
390 493
                   with Not_found ->
391
                     Printf.eprintf "W: Cannot get variable %s" var)
494
                     Printf.eprintf "W: Cannot get variable %s\n" var)
392 495
                [
393 496
                  Options.ext_obj, "ext_obj";
394 497
                  Options.ext_lib, "ext_lib";
395 498
                  Options.ext_dll, "ext_dll";
396 499
                ]
397 500

  
398
        | After_rules -> 
501
        | After_rules ->
399 502
            (* Declare OCaml libraries *)
400
            List.iter 
503
            List.iter
401 504
              (function
402
                 | nm, [] ->
403
                     ocaml_lib nm
404
                 | nm, dir :: tl ->
505
                 | nm, [], intf_modules ->
506
                     ocaml_lib nm;
507
                     let cmis =
508
                       List.map (fun m -> (String.uncapitalize m) ^ ".cmi")
509
                                intf_modules in
510
                     dep ["ocaml"; "link"; "library"; "file:"^nm^".cma"] cmis
511
                 | nm, dir :: tl, intf_modules ->
405 512
                     ocaml_lib ~dir:dir (dir^"/"^nm);
406
                     List.iter 
407
                       (fun dir -> 
513
                     List.iter
514
                       (fun dir ->
408 515
                          List.iter
409 516
                            (fun str ->
410 517
                               flag ["ocaml"; "use_"^nm; str] (S[A"-I"; P dir]))
411 518
                            ["compile"; "infer_interface"; "doc"])
412
                       tl)
519
                       tl;
520
                     let cmis =
521
                       List.map (fun m -> dir^"/"^(String.uncapitalize m)^".cmi")
522
                                intf_modules in
523
                     dep ["ocaml"; "link"; "library"; "file:"^dir^"/"^nm^".cma"]
524
                         cmis)
413 525
              t.lib_ocaml;
414 526

  
415 527
            (* Declare directories dependencies, replace "include" in _tags. *)
416
            List.iter 
528
            List.iter
417 529
              (fun (dir, include_dirs) ->
418 530
                 Pathname.define_context dir include_dirs)
419 531
              t.includes;
......
428 540

  
429 541
                   flag ["link"; "library"; "ocaml"; "native"; tag_libstubs lib]
430 542
                     (S[A"-cclib"; A("-l"^(nm_libstubs lib))]);
431
                        
543

  
432 544
                   flag ["link"; "program"; "ocaml"; "byte"; tag_libstubs lib]
433 545
                     (S[A"-dllib"; A("dll"^(nm_libstubs lib))]);
434 546

  
......
443 555

  
444 556
                   (* TODO: be more specific about what depends on headers *)
445 557
                   (* Depends on .h files *)
446
                   dep ["compile"; "c"] 
558
                   dep ["compile"; "c"]
447 559
                     headers;
448 560

  
449 561
                   (* Setup search path for lib *)
450
                   flag ["link"; "ocaml"; "use_"^lib] 
562
                   flag ["link"; "ocaml"; "use_"^lib]
451 563
                     (S[A"-I"; P(dir)]);
452 564
              )
453 565
              t.lib_c;
......
455 567
              (* Add flags *)
456 568
              List.iter
457 569
              (fun (tags, cond_specs) ->
458
                 let spec = 
459
                   BaseEnvLight.var_choose cond_specs env
570
                 let spec = BaseEnvLight.var_choose cond_specs env in
571
                 let rec eval_specs =
572
                   function
573
                     | S lst -> S (List.map eval_specs lst)
574
                     | A str -> A (BaseEnvLight.var_expand str env)
575
                     | spec -> spec
460 576
                 in
461
                   flag tags & spec)
577
                   flag tags & (eval_specs spec))
462 578
              t.flags
463
        | _ -> 
579
        | _ ->
464 580
            ()
465 581

  
582

  
466 583
  let dispatch_default t =
467
    dispatch_combine 
584
    dispatch_combine
468 585
      [
469 586
        dispatch t;
470 587
        MyOCamlbuildFindlib.dispatch;
471 588
      ]
472 589

  
590

  
473 591
end
474 592

  
475 593

  
476
# 476 "myocamlbuild.ml"
594
# 594 "myocamlbuild.ml"
477 595
open Ocamlbuild_plugin;;
478 596
let package_default =
479
  {MyOCamlbuildBase.lib_ocaml = []; lib_c = []; flags = []; includes = []; }
597
  {MyOCamlbuildBase.lib_ocaml = []; lib_c = []; flags = []; includes = []}
480 598
  ;;
481 599

  
482 600
let dispatch_default = MyOCamlbuildBase.dispatch_default package_default;;
483 601

  
484
# 485 "myocamlbuild.ml"
602
# 603 "myocamlbuild.ml"
485 603
(* OASIS_STOP *)
486 604
Ocamlbuild_plugin.dispatch dispatch_default;;

Also available in: Unified diff