2016-12-02 13:54:32 +00:00
|
|
|
open Import
|
|
|
|
|
2018-02-07 17:51:40 +00:00
|
|
|
module FP = Findlib.Package
|
|
|
|
|
2016-12-15 11:20:46 +00:00
|
|
|
module Internal = struct
|
2017-06-02 13:32:05 +00:00
|
|
|
type t = Path.t * Jbuild.Library.t
|
2016-12-15 11:20:46 +00:00
|
|
|
end
|
|
|
|
|
2016-12-02 13:54:32 +00:00
|
|
|
module T = struct
|
|
|
|
type t =
|
2016-12-15 11:20:46 +00:00
|
|
|
| Internal of Internal.t
|
2018-02-07 17:51:40 +00:00
|
|
|
| External of FP.t
|
2016-12-02 13:54:32 +00:00
|
|
|
|
2018-02-13 10:36:15 +00:00
|
|
|
let internal i = Internal i
|
|
|
|
let external_ i = External i
|
|
|
|
|
2016-12-02 13:54:32 +00:00
|
|
|
let best_name = function
|
2018-02-07 17:51:40 +00:00
|
|
|
| External pkg -> FP.name pkg
|
2017-12-17 14:56:05 +00:00
|
|
|
| Internal (_, lib) -> Jbuild.Library.best_name lib
|
2016-12-02 13:54:32 +00:00
|
|
|
|
|
|
|
let compare a b = String.compare (best_name a) (best_name b)
|
|
|
|
end
|
|
|
|
|
|
|
|
include T
|
|
|
|
module Set = Set.Make(T)
|
2017-05-18 12:49:56 +00:00
|
|
|
|
2018-01-21 21:36:30 +00:00
|
|
|
let lib_obj_dir dir lib =
|
|
|
|
Path.relative dir ("." ^ lib.Jbuild.Library.name ^ ".objs")
|
|
|
|
|
2018-02-13 10:36:15 +00:00
|
|
|
let get_internal = function
|
|
|
|
| Internal x -> Some x
|
|
|
|
| External _ -> None
|
|
|
|
|
|
|
|
let to_either = function
|
|
|
|
| Internal x -> Inl x
|
|
|
|
| External x -> Inr x
|
|
|
|
|
|
|
|
let src_dir = function
|
|
|
|
| External _ -> None
|
|
|
|
| Internal (dir, _) -> Some dir
|
2016-12-02 13:54:32 +00:00
|
|
|
|
2018-01-21 21:36:30 +00:00
|
|
|
let obj_dir = function
|
2018-02-07 17:51:40 +00:00
|
|
|
| External pkg -> FP.dir pkg
|
2018-02-13 10:36:15 +00:00
|
|
|
| Internal (dir, lib) -> lib_obj_dir dir lib
|
|
|
|
|
|
|
|
let src_or_obj_dir t =
|
|
|
|
match src_dir t with
|
|
|
|
| None -> obj_dir t
|
|
|
|
| Some dir -> dir
|
|
|
|
|
|
|
|
let is_local lib = Path.is_local (obj_dir lib)
|
2018-01-21 21:36:30 +00:00
|
|
|
|
2018-02-06 11:49:44 +00:00
|
|
|
let include_paths ts ~stdlib_dir =
|
2017-02-02 10:31:36 +00:00
|
|
|
List.fold_left ts ~init:Path.Set.empty ~f:(fun acc t ->
|
2018-01-21 21:36:30 +00:00
|
|
|
Path.Set.add (obj_dir t) acc)
|
2018-02-06 11:49:44 +00:00
|
|
|
|> Path.Set.remove stdlib_dir
|
2017-02-02 10:31:36 +00:00
|
|
|
|
2018-02-06 11:49:44 +00:00
|
|
|
let include_flags ts ~stdlib_dir =
|
|
|
|
let dirs = include_paths ts ~stdlib_dir in
|
2016-12-02 13:54:32 +00:00
|
|
|
Arg_spec.S (List.concat_map (Path.Set.elements dirs) ~f:(fun dir ->
|
|
|
|
[Arg_spec.A "-I"; Path dir]))
|
|
|
|
|
2018-01-21 21:36:30 +00:00
|
|
|
let c_include_flags ts ~stdlib_dir =
|
2016-12-15 11:20:46 +00:00
|
|
|
let dirs =
|
|
|
|
List.fold_left ts ~init:Path.Set.empty ~f:(fun acc t ->
|
2018-02-13 10:36:15 +00:00
|
|
|
Path.Set.add (src_or_obj_dir t) acc)
|
2018-01-21 21:36:30 +00:00
|
|
|
|> Path.Set.remove stdlib_dir
|
2016-12-15 11:20:46 +00:00
|
|
|
in
|
|
|
|
Arg_spec.S (List.concat_map (Path.Set.elements dirs) ~f:(fun dir ->
|
|
|
|
[Arg_spec.A "-I"; Path dir]))
|
|
|
|
|
2016-12-02 13:54:32 +00:00
|
|
|
let describe = function
|
|
|
|
| Internal (_, lib) ->
|
2017-03-01 15:03:09 +00:00
|
|
|
sprintf "%s (local)"
|
|
|
|
(match lib.public with
|
|
|
|
| Some p -> p.name
|
|
|
|
| None -> lib.name)
|
2016-12-02 13:54:32 +00:00
|
|
|
| External pkg ->
|
2018-02-07 17:51:40 +00:00
|
|
|
sprintf "%s (external)" (FP.name pkg)
|
2016-12-02 13:54:32 +00:00
|
|
|
|
2018-02-06 11:49:44 +00:00
|
|
|
let link_flags ts ~mode ~stdlib_dir =
|
2016-12-02 13:54:32 +00:00
|
|
|
Arg_spec.S
|
2018-01-21 21:36:30 +00:00
|
|
|
(c_include_flags ts ~stdlib_dir ::
|
2017-02-26 21:28:30 +00:00
|
|
|
List.map ts ~f:(fun t ->
|
2016-12-02 13:54:32 +00:00
|
|
|
match t with
|
|
|
|
| External pkg ->
|
2018-02-07 17:51:40 +00:00
|
|
|
Arg_spec.Deps (FP.archives pkg mode)
|
2016-12-02 13:54:32 +00:00
|
|
|
| Internal (dir, lib) ->
|
2017-07-25 13:08:39 +00:00
|
|
|
Dep (Path.relative dir (lib.name ^ Mode.compiled_lib_ext mode))))
|
2016-12-02 13:54:32 +00:00
|
|
|
|
2018-02-13 10:36:15 +00:00
|
|
|
let stub_archives t ~ext_lib =
|
|
|
|
match t with
|
|
|
|
| External _ -> None
|
|
|
|
| Internal (dir, lib) ->
|
|
|
|
if Jbuild.Library.has_stubs lib then
|
|
|
|
Some (Jbuild.Library.stubs_archive lib ~dir ~ext_lib)
|
|
|
|
else
|
|
|
|
None
|
|
|
|
|
|
|
|
let ml_archives t ~mode ~ext_lib =
|
|
|
|
match t with
|
|
|
|
| External pkg -> FP.archives pkg mode
|
|
|
|
| Internal (dir, lib) ->
|
|
|
|
let l =
|
|
|
|
[Path.relative dir (lib.name ^ Mode.compiled_lib_ext mode)]
|
|
|
|
in
|
|
|
|
match mode, ext_lib with
|
|
|
|
| Byte, _
|
|
|
|
| Native, None -> l
|
|
|
|
| Native, Some ext_lib -> Path.relative dir (lib.name ^ ext_lib) :: l
|
|
|
|
|
2016-12-31 13:26:29 +00:00
|
|
|
let archive_files ts ~mode ~ext_lib =
|
2018-02-13 10:36:15 +00:00
|
|
|
List.concat_map ts ~f:(fun lib ->
|
|
|
|
ml_archives lib ~mode ~ext_lib:(Some ext_lib) @
|
|
|
|
Option.to_list (stub_archives lib ~ext_lib))
|
|
|
|
|
|
|
|
let jsoo_archives t =
|
|
|
|
ml_archives t ~mode:Mode.Byte ~ext_lib:None
|
|
|
|
|> List.map ~f:(Path.extend_basename ~suffix:".js")
|
2017-05-02 10:25:37 +00:00
|
|
|
|
|
|
|
let jsoo_runtime_files ts =
|
|
|
|
List.concat_map ts ~f:(function
|
|
|
|
| External pkg ->
|
2018-02-07 17:51:40 +00:00
|
|
|
List.map (FP.jsoo_runtime pkg) ~f:(Path.relative (FP.dir pkg))
|
2017-05-02 10:25:37 +00:00
|
|
|
| Internal (dir, lib) ->
|
2017-05-02 12:30:58 +00:00
|
|
|
List.map lib.buildable.js_of_ocaml.javascript_files ~f:(Path.relative dir))
|
2018-02-13 10:36:15 +00:00
|
|
|
|
2018-02-13 17:49:07 +00:00
|
|
|
let ppx_runtime_libraries t ~required_by =
|
2018-02-13 10:36:15 +00:00
|
|
|
String_set.of_list (
|
2016-12-02 13:54:32 +00:00
|
|
|
match t with
|
2018-02-13 10:36:15 +00:00
|
|
|
| Internal (_, lib) -> lib.ppx_runtime_libraries
|
2018-02-13 17:49:07 +00:00
|
|
|
| External pkg -> List.map ~f:FP.name (FP.ppx_runtime_deps pkg ~required_by)
|
2018-02-13 10:36:15 +00:00
|
|
|
)
|
|
|
|
|
2018-02-13 17:49:07 +00:00
|
|
|
let requires t ~required_by =
|
|
|
|
match t with
|
2018-02-13 10:36:15 +00:00
|
|
|
| Internal (_, lib) ->
|
|
|
|
lib.buildable.libraries
|
|
|
|
| External pkg ->
|
2018-02-13 17:49:07 +00:00
|
|
|
List.map ~f:(fun fp -> Jbuild.Lib_dep.direct (FP.name fp))
|
|
|
|
(FP.requires pkg ~required_by)
|
2018-02-13 10:36:15 +00:00
|
|
|
|
|
|
|
let scope = function
|
|
|
|
| Internal (dir, _) -> `Dir dir
|
|
|
|
| External _ -> `External
|
2016-12-15 11:20:46 +00:00
|
|
|
|
|
|
|
let remove_dups_preserve_order libs =
|
|
|
|
let rec loop seen libs acc =
|
|
|
|
match libs with
|
|
|
|
| [] -> List.rev acc
|
|
|
|
| lib :: libs ->
|
|
|
|
let name = best_name lib in
|
|
|
|
if String_set.mem name seen then
|
|
|
|
loop seen libs acc
|
|
|
|
else
|
|
|
|
loop (String_set.add name seen) libs (lib :: acc)
|
|
|
|
in
|
|
|
|
loop String_set.empty libs []
|
|
|
|
;;
|
2018-01-30 12:12:38 +00:00
|
|
|
|
|
|
|
let public_name = function
|
2018-02-07 17:51:40 +00:00
|
|
|
| External pkg -> Some (FP.name pkg)
|
2018-01-30 12:12:38 +00:00
|
|
|
| Internal (_, lib) -> Option.map lib.public ~f:(fun p -> p.name)
|
2018-02-13 10:36:15 +00:00
|
|
|
|
|
|
|
let unique_id = function
|
|
|
|
| External pkg -> FP.name pkg
|
|
|
|
| Internal (dir, lib) ->
|
|
|
|
match lib.public with
|
|
|
|
| Some p -> p.name
|
|
|
|
| None -> Path.to_string dir ^ "\000" ^ lib.name
|
|
|
|
|
|
|
|
type local =
|
|
|
|
{ src: Path.t
|
|
|
|
; name: string
|
|
|
|
}
|
|
|
|
|
|
|
|
let local = function
|
|
|
|
| Internal (dir, lib) -> Some { src = dir; name = lib.name }
|
|
|
|
| External _ -> None
|
|
|
|
|
|
|
|
let exists_name t ~f =
|
|
|
|
match t with
|
|
|
|
| External pkg -> f (FP.name pkg)
|
|
|
|
| Internal (_, lib) ->
|
|
|
|
(f lib.name) || (
|
|
|
|
match lib.public with
|
|
|
|
| None -> false
|
|
|
|
| Some p -> f p.name
|
|
|
|
)
|