Add target support
* Create targets from findlib toolchains by reading findlib configs * Define targets inside workspace files * Set cross compilation targets with -x argument
This commit is contained in:
parent
afb602d7ef
commit
6e64156913
17
bin/main.ml
17
bin/main.ml
|
@ -21,6 +21,7 @@ type common =
|
||||||
; target_prefix : string
|
; target_prefix : string
|
||||||
; only_packages : String_set.t option
|
; only_packages : String_set.t option
|
||||||
; capture_outputs : bool
|
; capture_outputs : bool
|
||||||
|
; x : string option
|
||||||
; (* Original arguments for the external-lib-deps hint *)
|
; (* Original arguments for the external-lib-deps hint *)
|
||||||
orig_args : string list
|
orig_args : string list
|
||||||
}
|
}
|
||||||
|
@ -74,7 +75,9 @@ module Main = struct
|
||||||
?unlink_aliases
|
?unlink_aliases
|
||||||
?workspace_file:common.workspace_file
|
?workspace_file:common.workspace_file
|
||||||
?only_packages:common.only_packages
|
?only_packages:common.only_packages
|
||||||
?filter_out_optional_stanzas_with_missing_deps ()
|
?filter_out_optional_stanzas_with_missing_deps
|
||||||
|
?x:common.x
|
||||||
|
()
|
||||||
end
|
end
|
||||||
|
|
||||||
type target =
|
type target =
|
||||||
|
@ -154,6 +157,7 @@ let common =
|
||||||
no_buffer
|
no_buffer
|
||||||
workspace_file
|
workspace_file
|
||||||
(root, only_packages, orig)
|
(root, only_packages, orig)
|
||||||
|
x
|
||||||
=
|
=
|
||||||
let root, to_cwd =
|
let root, to_cwd =
|
||||||
match root with
|
match root with
|
||||||
|
@ -181,6 +185,7 @@ let common =
|
||||||
; only_packages =
|
; only_packages =
|
||||||
Option.map only_packages
|
Option.map only_packages
|
||||||
~f:(fun s -> String_set.of_list (String.split s ~on:','))
|
~f:(fun s -> String_set.of_list (String.split s ~on:','))
|
||||||
|
; x
|
||||||
}
|
}
|
||||||
in
|
in
|
||||||
let docs = copts_sect in
|
let docs = copts_sect in
|
||||||
|
@ -304,6 +309,12 @@ let common =
|
||||||
$ only_packages
|
$ only_packages
|
||||||
$ frop))
|
$ frop))
|
||||||
in
|
in
|
||||||
|
let x =
|
||||||
|
Arg.(value
|
||||||
|
& opt (some string) None
|
||||||
|
& info ["x"] ~docs
|
||||||
|
~doc:{|Cross-compile using this toolchain.|})
|
||||||
|
in
|
||||||
Term.(const make
|
Term.(const make
|
||||||
$ concurrency
|
$ concurrency
|
||||||
$ ddep_path
|
$ ddep_path
|
||||||
|
@ -314,6 +325,7 @@ let common =
|
||||||
$ no_buffer
|
$ no_buffer
|
||||||
$ workspace_file
|
$ workspace_file
|
||||||
$ root_and_only_packages
|
$ root_and_only_packages
|
||||||
|
$ x
|
||||||
)
|
)
|
||||||
|
|
||||||
let installed_libraries =
|
let installed_libraries =
|
||||||
|
@ -321,7 +333,8 @@ let installed_libraries =
|
||||||
let go common na =
|
let go common na =
|
||||||
set_common common ~targets:[];
|
set_common common ~targets:[];
|
||||||
Future.Scheduler.go ~log:(Log.create ())
|
Future.Scheduler.go ~log:(Log.create ())
|
||||||
(Context.default () >>= fun ctx ->
|
(Context.create (Default [Native]) >>= fun ctxs ->
|
||||||
|
let ctx = List.hd ctxs in
|
||||||
let findlib = ctx.findlib in
|
let findlib = ctx.findlib in
|
||||||
if na then begin
|
if na then begin
|
||||||
let pkgs = Findlib.all_unavailable_packages findlib in
|
let pkgs = Findlib.all_unavailable_packages findlib in
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
;; This file is used by `make all-supported-ocaml-versions`
|
;; This file is used by `make all-supported-ocaml-versions`
|
||||||
(context ((switch 4.02.3)))
|
(context (opam (switch 4.02.3)))
|
||||||
(context ((switch 4.03.0)))
|
(context (opam (switch 4.03.0)))
|
||||||
(context ((switch 4.04.2)))
|
(context (opam (switch 4.04.2)))
|
||||||
(context ((switch 4.05.0)))
|
(context (opam (switch 4.05.0)))
|
||||||
(context ((switch 4.06.0)))
|
(context (opam (switch 4.06.0)))
|
||||||
(context ((switch 4.07.0+trunk)))
|
(context (opam (switch 4.07.0+trunk)))
|
||||||
|
|
124
src/context.ml
124
src/context.ml
|
@ -34,6 +34,7 @@ type t =
|
||||||
; kind : Kind.t
|
; kind : Kind.t
|
||||||
; merlin : bool
|
; merlin : bool
|
||||||
; for_host : t option
|
; for_host : t option
|
||||||
|
; implicit : bool
|
||||||
; build_dir : Path.t
|
; build_dir : Path.t
|
||||||
; path : Path.t list
|
; path : Path.t list
|
||||||
; toplevel_path : Path.t option
|
; toplevel_path : Path.t option
|
||||||
|
@ -46,6 +47,7 @@ type t =
|
||||||
; env : string array
|
; env : string array
|
||||||
; env_extra : string Env_var_map.t
|
; env_extra : string Env_var_map.t
|
||||||
; findlib : Findlib.t
|
; findlib : Findlib.t
|
||||||
|
; findlib_toolchain : string option
|
||||||
; arch_sixtyfour : bool
|
; arch_sixtyfour : bool
|
||||||
; opam_var_cache : (string, string) Hashtbl.t
|
; opam_var_cache : (string, string) Hashtbl.t
|
||||||
; natdynlink_supported : bool
|
; natdynlink_supported : bool
|
||||||
|
@ -175,7 +177,8 @@ let extend_env ~vars ~env =
|
||||||
imported
|
imported
|
||||||
|> Array.of_list
|
|> Array.of_list
|
||||||
|
|
||||||
let create ~(kind : Kind.t) ~path ~base_env ~env_extra ~name ~merlin ~use_findlib =
|
let create ~(kind : Kind.t) ~path ~base_env ~env_extra ~name ~merlin
|
||||||
|
~use_findlib ~targets () =
|
||||||
let env = extend_env ~env:base_env ~vars:env_extra in
|
let env = extend_env ~env:base_env ~vars:env_extra in
|
||||||
let opam_var_cache = Hashtbl.create 128 in
|
let opam_var_cache = Hashtbl.create 128 in
|
||||||
(match kind with
|
(match kind with
|
||||||
|
@ -187,37 +190,83 @@ let create ~(kind : Kind.t) ~path ~base_env ~env_extra ~name ~merlin ~use_findli
|
||||||
in
|
in
|
||||||
let which_cache = Hashtbl.create 128 in
|
let which_cache = Hashtbl.create 128 in
|
||||||
let which x = which ~cache:which_cache ~path x in
|
let which x = which ~cache:which_cache ~path x in
|
||||||
|
let findlib_config_path = lazy (
|
||||||
|
match which "ocamlfind" with
|
||||||
|
| None -> prog_not_found_in_path "ocamlfind"
|
||||||
|
| Some fn ->
|
||||||
|
(* When OCAMLFIND_CONF is set, "ocamlfind printconf" does print the contents of the
|
||||||
|
variable, but "ocamlfind printconf conf" still prints the configuration file set
|
||||||
|
at the configuration time of ocamlfind, sigh... *)
|
||||||
|
match Sys.getenv "OCAMLFIND_CONF" with
|
||||||
|
| s -> Future.return (Path.absolute s)
|
||||||
|
| exception Not_found ->
|
||||||
|
Future.run_capture_line ~env Strict
|
||||||
|
(Path.to_string fn) ["printconf"; "conf"]
|
||||||
|
>>| Path.absolute)
|
||||||
|
in
|
||||||
|
|
||||||
|
let create_one ~name ~implicit ?findlib_toolchain ?host ~merlin () =
|
||||||
|
(match findlib_toolchain with
|
||||||
|
| None -> Future.return None
|
||||||
|
| Some toolchain ->
|
||||||
|
Lazy.force findlib_config_path >>| fun path ->
|
||||||
|
Some (Findlib.Config.load path ~toolchain ~context:name))
|
||||||
|
>>= fun findlib_config ->
|
||||||
|
|
||||||
|
let get_tool_using_findlib_config prog =
|
||||||
|
match findlib_config with
|
||||||
|
| None -> None
|
||||||
|
| Some conf ->
|
||||||
|
match Findlib.Config.get conf prog with
|
||||||
|
| "" -> None
|
||||||
|
| s ->
|
||||||
|
match Filename.analyze_program_name s with
|
||||||
|
| In_path | Relative_to_current_dir -> which s
|
||||||
|
| Absolute -> Some (Path.absolute s)
|
||||||
|
in
|
||||||
|
|
||||||
let ocamlc =
|
let ocamlc =
|
||||||
match which "ocamlc" with
|
match get_tool_using_findlib_config "ocamlc" with
|
||||||
| None -> prog_not_found_in_path "ocamlc"
|
|
||||||
| Some x -> x
|
| Some x -> x
|
||||||
|
| None ->
|
||||||
|
match which "ocamlc" with
|
||||||
|
| Some x -> x
|
||||||
|
| None -> prog_not_found_in_path "ocamlc"
|
||||||
in
|
in
|
||||||
let dir = Path.parent ocamlc in
|
let dir = Path.parent ocamlc in
|
||||||
let prog_not_found prog =
|
let ocaml_tool_not_found prog =
|
||||||
die "ocamlc found in %s, but %s/%s doesn't exist (context: %s)"
|
die "ocamlc found in %s, but %s/%s doesn't exist (context: %s)"
|
||||||
(Path.to_string dir) (Path.to_string dir) prog name
|
(Path.to_string dir) (Path.to_string dir) prog name
|
||||||
in
|
in
|
||||||
let best_prog prog = Bin.best_prog dir prog in
|
let get_ocaml_tool prog =
|
||||||
let get_prog prog =
|
match get_tool_using_findlib_config prog with
|
||||||
match best_prog prog with
|
| None -> Bin.best_prog dir prog
|
||||||
| None -> prog_not_found prog
|
| Some _ as x -> x
|
||||||
|
in
|
||||||
|
let get_ocaml_tool_exn prog =
|
||||||
|
match get_ocaml_tool prog with
|
||||||
|
| None -> ocaml_tool_not_found prog
|
||||||
| Some fn -> fn
|
| Some fn -> fn
|
||||||
in
|
in
|
||||||
let build_dir =
|
|
||||||
Path.of_string (sprintf "_build/%s" name)
|
let build_dir = Path.of_string (sprintf "_build/%s" name) in
|
||||||
in
|
|
||||||
let ocamlc_config_cmd = sprintf "%s -config" (Path.to_string ocamlc) in
|
let ocamlc_config_cmd = sprintf "%s -config" (Path.to_string ocamlc) in
|
||||||
let findlib_path =
|
let findlib_path =
|
||||||
if use_findlib then
|
if use_findlib then
|
||||||
(* If ocamlfind is present, it has precedence over everything else. *)
|
(* If ocamlfind is present, it has precedence over everything else. *)
|
||||||
match which "ocamlfind" with
|
match which "ocamlfind" with
|
||||||
| Some fn ->
|
| Some fn ->
|
||||||
(Future.run_capture_lines ~env Strict
|
let args =
|
||||||
(Path.to_string fn) ["printconf"; "path"]
|
let args = ["printconf"; "path"] in
|
||||||
>>| List.map ~f:Path.absolute)
|
match findlib_toolchain with
|
||||||
|
| None -> args
|
||||||
|
| Some s -> "-toolchain" :: s :: args
|
||||||
|
in
|
||||||
|
Future.run_capture_lines ~env Strict (Path.to_string fn) args
|
||||||
|
>>| List.map ~f:Path.absolute
|
||||||
| None ->
|
| None ->
|
||||||
(* If there no ocamlfind in the PATH, check if we have opam and assume a stan opam
|
(* If there no ocamlfind in the PATH, check if we have opam
|
||||||
setup *)
|
and assume a standard opam setup *)
|
||||||
opam_config_var ~env ~cache:opam_var_cache "lib"
|
opam_config_var ~env ~cache:opam_var_cache "lib"
|
||||||
>>| function
|
>>| function
|
||||||
| Some s -> [Path.absolute s]
|
| Some s -> [Path.absolute s]
|
||||||
|
@ -232,6 +281,7 @@ let create ~(kind : Kind.t) ~path ~base_env ~env_extra ~name ~merlin ~use_findli
|
||||||
findlib_path
|
findlib_path
|
||||||
(Future.run_capture_lines ~env Strict (Path.to_string ocamlc) ["-config"])
|
(Future.run_capture_lines ~env Strict (Path.to_string ocamlc) ["-config"])
|
||||||
>>= fun (findlib_path, ocamlc_config) ->
|
>>= fun (findlib_path, ocamlc_config) ->
|
||||||
|
|
||||||
let ocamlc_config =
|
let ocamlc_config =
|
||||||
List.map ocamlc_config ~f:(fun line ->
|
List.map ocamlc_config ~f:(fun line ->
|
||||||
match String.index line ':' with
|
match String.index line ':' with
|
||||||
|
@ -317,23 +367,25 @@ let create ~(kind : Kind.t) ~path ~base_env ~env_extra ~name ~merlin ~use_findli
|
||||||
in
|
in
|
||||||
return
|
return
|
||||||
{ name
|
{ name
|
||||||
|
; implicit
|
||||||
; kind
|
; kind
|
||||||
; merlin
|
; merlin
|
||||||
; for_host = None
|
; for_host = host
|
||||||
; build_dir
|
; build_dir
|
||||||
; path
|
; path
|
||||||
; toplevel_path = Option.map (get_env env "OCAML_TOPLEVEL_PATH") ~f:Path.absolute
|
; toplevel_path = Option.map (get_env env "OCAML_TOPLEVEL_PATH") ~f:Path.absolute
|
||||||
|
|
||||||
; ocaml_bin = dir
|
; ocaml_bin = dir
|
||||||
; ocaml = Path.relative dir ("ocaml" ^ Bin.exe)
|
; ocaml = (match which "ocaml" with Some p -> p | None -> prog_not_found_in_path "ocaml")
|
||||||
; ocamlc
|
; ocamlc
|
||||||
; ocamlopt = best_prog "ocamlopt"
|
; ocamlopt = get_ocaml_tool "ocamlopt"
|
||||||
; ocamldep = get_prog "ocamldep"
|
; ocamldep = get_ocaml_tool_exn "ocamldep"
|
||||||
; ocamlmklib = get_prog "ocamlmklib"
|
; ocamlmklib = get_ocaml_tool_exn "ocamlmklib"
|
||||||
|
|
||||||
; env
|
; env
|
||||||
; env_extra
|
; env_extra
|
||||||
; findlib = Findlib.create ~stdlib_dir ~path:findlib_path
|
; findlib = Findlib.create ~stdlib_dir ~path:findlib_path
|
||||||
|
; findlib_toolchain
|
||||||
; arch_sixtyfour
|
; arch_sixtyfour
|
||||||
|
|
||||||
; opam_var_cache
|
; opam_var_cache
|
||||||
|
@ -376,6 +428,20 @@ let create ~(kind : Kind.t) ~path ~base_env ~env_extra ~name ~merlin ~use_findli
|
||||||
|
|
||||||
; which_cache
|
; which_cache
|
||||||
}
|
}
|
||||||
|
in
|
||||||
|
|
||||||
|
let implicit = not (List.mem ~set:targets Workspace.Context.Target.Native) in
|
||||||
|
create_one () ~implicit ~name ~merlin >>= fun native ->
|
||||||
|
Future.all (
|
||||||
|
List.filter_map targets ~f:(function
|
||||||
|
| Native -> None
|
||||||
|
| Named findlib_toolchain ->
|
||||||
|
let name = sprintf "%s.%s" name findlib_toolchain in
|
||||||
|
Some (create_one () ~implicit:false ~name ~findlib_toolchain ~host:native
|
||||||
|
~merlin:false)
|
||||||
|
)
|
||||||
|
) >>| fun others ->
|
||||||
|
native :: others
|
||||||
|
|
||||||
let opam_config_var t var = opam_config_var ~env:t.env ~cache:t.opam_var_cache var
|
let opam_config_var t var = opam_config_var ~env:t.env ~cache:t.opam_var_cache var
|
||||||
|
|
||||||
|
@ -383,7 +449,7 @@ let initial_env = lazy (
|
||||||
Lazy.force Ansi_color.setup_env_for_colors;
|
Lazy.force Ansi_color.setup_env_for_colors;
|
||||||
Unix.environment ())
|
Unix.environment ())
|
||||||
|
|
||||||
let default ?(merlin=true) ?(use_findlib=true) () =
|
let default ?(merlin=true) ?(use_findlib=true) ~targets () =
|
||||||
let env = Lazy.force initial_env in
|
let env = Lazy.force initial_env in
|
||||||
let path =
|
let path =
|
||||||
match get_env env "PATH" with
|
match get_env env "PATH" with
|
||||||
|
@ -391,9 +457,9 @@ let default ?(merlin=true) ?(use_findlib=true) () =
|
||||||
| None -> []
|
| None -> []
|
||||||
in
|
in
|
||||||
create ~kind:Default ~path ~base_env:env ~env_extra:Env_var_map.empty
|
create ~kind:Default ~path ~base_env:env ~env_extra:Env_var_map.empty
|
||||||
~name:"default" ~merlin ~use_findlib
|
~name:"default" ~merlin ~use_findlib ~targets ()
|
||||||
|
|
||||||
let create_for_opam ?root ~switch ~name ?(merlin=false) () =
|
let create_for_opam ?root ~targets ~switch ~name ?(merlin=false) () =
|
||||||
match Bin.opam with
|
match Bin.opam with
|
||||||
| None -> Utils.program_not_found "opam"
|
| None -> Utils.program_not_found "opam"
|
||||||
| Some fn ->
|
| Some fn ->
|
||||||
|
@ -430,8 +496,14 @@ let create_for_opam ?root ~switch ~name ?(merlin=false) () =
|
||||||
| Some s -> Bin.parse_path s
|
| Some s -> Bin.parse_path s
|
||||||
in
|
in
|
||||||
let env = Lazy.force initial_env in
|
let env = Lazy.force initial_env in
|
||||||
create ~kind:(Opam { root; switch }) ~path ~base_env:env ~env_extra:vars
|
create ~kind:(Opam { root; switch }) ~targets
|
||||||
~name ~merlin ~use_findlib:true
|
~path ~base_env:env ~env_extra:vars ~name ~merlin ~use_findlib:true ()
|
||||||
|
|
||||||
|
let create ?use_findlib ?merlin def =
|
||||||
|
match (def : Workspace.Context.t) with
|
||||||
|
| Default targets -> default ~targets ?merlin ?use_findlib ()
|
||||||
|
| Opam { name; switch; root; targets; _ } ->
|
||||||
|
create_for_opam ?root ~switch ~name ?merlin ~targets ()
|
||||||
|
|
||||||
let which t s = which ~cache:t.which_cache ~path:t.path s
|
let which t s = which ~cache:t.which_cache ~path:t.path s
|
||||||
|
|
||||||
|
|
|
@ -48,6 +48,10 @@ type t =
|
||||||
building tools used for the compilation that run on the host. *)
|
building tools used for the compilation that run on the host. *)
|
||||||
for_host : t option
|
for_host : t option
|
||||||
|
|
||||||
|
; (** [false] if a user explicitly listed this context in the workspace.
|
||||||
|
Controls whether we add artifacts from this context @install *)
|
||||||
|
implicit : bool
|
||||||
|
|
||||||
; (** Directory where artifact are stored, for instance "_build/default" *)
|
; (** Directory where artifact are stored, for instance "_build/default" *)
|
||||||
build_dir : Path.t
|
build_dir : Path.t
|
||||||
|
|
||||||
|
@ -72,6 +76,7 @@ type t =
|
||||||
env_extra : string Env_var_map.t
|
env_extra : string Env_var_map.t
|
||||||
|
|
||||||
; findlib : Findlib.t
|
; findlib : Findlib.t
|
||||||
|
; findlib_toolchain : string option
|
||||||
|
|
||||||
; (** Misc *)
|
; (** Misc *)
|
||||||
arch_sixtyfour : bool
|
arch_sixtyfour : bool
|
||||||
|
@ -124,18 +129,14 @@ val sexp_of_t : t -> Sexp.t
|
||||||
(** Compare the context names *)
|
(** Compare the context names *)
|
||||||
val compare : t -> t -> int
|
val compare : t -> t -> int
|
||||||
|
|
||||||
val create_for_opam
|
|
||||||
: ?root:string
|
|
||||||
-> switch:string
|
|
||||||
-> name:string
|
|
||||||
-> ?merlin:bool
|
|
||||||
-> unit
|
|
||||||
-> t Future.t
|
|
||||||
|
|
||||||
(** If [use_findlib] is [false], don't try to guess the library search path with opam or
|
(** If [use_findlib] is [false], don't try to guess the library search path with opam or
|
||||||
ocamlfind. This is only for building jbuilder itself, so that its build is completely
|
ocamlfind. This is only for building jbuilder itself, so that its build is completely
|
||||||
independent of the user setup. *)
|
independent of the user setup. *)
|
||||||
val default : ?merlin:bool -> ?use_findlib:bool -> unit -> t Future.t
|
val create
|
||||||
|
: ?use_findlib:bool
|
||||||
|
-> ?merlin:bool
|
||||||
|
-> Workspace.Context.t
|
||||||
|
-> t list Future.t
|
||||||
|
|
||||||
val which : t -> string -> Path.t option
|
val which : t -> string -> Path.t option
|
||||||
|
|
||||||
|
|
38
src/main.ml
38
src/main.ml
|
@ -12,7 +12,8 @@ type setup =
|
||||||
let package_install_file { packages; _ } pkg =
|
let package_install_file { packages; _ } pkg =
|
||||||
match String_map.find pkg packages with
|
match String_map.find pkg packages with
|
||||||
| None -> Error ()
|
| None -> Error ()
|
||||||
| Some p -> Ok (Path.relative p.path (p.name ^ ".install"))
|
| Some p ->
|
||||||
|
Ok (Path.relative p.path (Utils.install_file ~package:p.name ~findlib_toolchain:None))
|
||||||
|
|
||||||
let setup ?(log=Log.no_log) ?unlink_aliases
|
let setup ?(log=Log.no_log) ?unlink_aliases
|
||||||
?filter_out_optional_stanzas_with_missing_deps
|
?filter_out_optional_stanzas_with_missing_deps
|
||||||
|
@ -20,6 +21,7 @@ let setup ?(log=Log.no_log) ?unlink_aliases
|
||||||
?(use_findlib=true)
|
?(use_findlib=true)
|
||||||
?only_packages
|
?only_packages
|
||||||
?extra_ignored_subtrees
|
?extra_ignored_subtrees
|
||||||
|
?x
|
||||||
() =
|
() =
|
||||||
let conf = Jbuild_load.load ?extra_ignored_subtrees () in
|
let conf = Jbuild_load.load ?extra_ignored_subtrees () in
|
||||||
Option.iter only_packages ~f:(fun set ->
|
Option.iter only_packages ~f:(fun set ->
|
||||||
|
@ -33,26 +35,34 @@ let setup ?(log=Log.no_log) ?unlink_aliases
|
||||||
| Some w -> w
|
| Some w -> w
|
||||||
| None ->
|
| None ->
|
||||||
if Sys.file_exists workspace_file then
|
if Sys.file_exists workspace_file then
|
||||||
Workspace.load workspace_file
|
Workspace.load ?x workspace_file
|
||||||
else
|
else
|
||||||
{ merlin_context = Some "default"; contexts = [Default] }
|
{ merlin_context = Some "default"
|
||||||
|
; contexts = [Default [
|
||||||
|
match x with
|
||||||
|
| None -> Native
|
||||||
|
| Some x -> Named x
|
||||||
|
]]
|
||||||
|
}
|
||||||
in
|
in
|
||||||
Future.all
|
|
||||||
(List.map workspace.contexts ~f:(function
|
Future.all (
|
||||||
| Workspace.Context.Default ->
|
List.map workspace.contexts ~f:(fun ctx_def ->
|
||||||
Context.default ~merlin:(workspace.merlin_context = Some "default")
|
let name = Workspace.Context.name ctx_def in
|
||||||
~use_findlib ()
|
Context.create ctx_def ~merlin:(workspace.merlin_context = Some name) ~use_findlib)
|
||||||
| Opam { name; switch; root; merlin } ->
|
)
|
||||||
Context.create_for_opam ~name ~switch ?root ~merlin ()))
|
|
||||||
>>= fun contexts ->
|
>>= fun contexts ->
|
||||||
List.iter contexts ~f:(fun ctx ->
|
let contexts = List.concat contexts in
|
||||||
|
List.iter contexts ~f:(fun (ctx : Context.t) ->
|
||||||
Log.infof log "@[<1>Jbuilder context:@,%a@]@." Sexp.pp (Context.sexp_of_t ctx));
|
Log.infof log "@[<1>Jbuilder context:@,%a@]@." Sexp.pp (Context.sexp_of_t ctx));
|
||||||
Gen_rules.gen conf ~contexts
|
Gen_rules.gen conf
|
||||||
|
~contexts
|
||||||
?unlink_aliases
|
?unlink_aliases
|
||||||
?only_packages
|
?only_packages
|
||||||
?filter_out_optional_stanzas_with_missing_deps
|
?filter_out_optional_stanzas_with_missing_deps
|
||||||
>>= fun (rules, stanzas) ->
|
>>= fun (rules, stanzas) ->
|
||||||
let build_system = Build_system.create ~contexts ~file_tree:conf.file_tree ~rules in
|
let build_system = Build_system.create ~contexts
|
||||||
|
~file_tree:conf.file_tree ~rules in
|
||||||
return { build_system
|
return { build_system
|
||||||
; stanzas
|
; stanzas
|
||||||
; contexts
|
; contexts
|
||||||
|
@ -211,7 +221,7 @@ let bootstrap () =
|
||||||
Clflags.debug_dep_path := true;
|
Clflags.debug_dep_path := true;
|
||||||
let log = Log.create () in
|
let log = Log.create () in
|
||||||
Future.Scheduler.go ~log
|
Future.Scheduler.go ~log
|
||||||
(setup ~log ~workspace:{ merlin_context = Some "default"; contexts = [Default] }
|
(setup ~log ~workspace:{ merlin_context = Some "default"; contexts = [Default [Native]] }
|
||||||
~use_findlib:false
|
~use_findlib:false
|
||||||
~extra_ignored_subtrees:ignored_during_bootstrap
|
~extra_ignored_subtrees:ignored_during_bootstrap
|
||||||
()
|
()
|
||||||
|
|
|
@ -22,6 +22,7 @@ val setup
|
||||||
-> ?workspace:Workspace.t
|
-> ?workspace:Workspace.t
|
||||||
-> ?workspace_file:string
|
-> ?workspace_file:string
|
||||||
-> ?only_packages:String_set.t
|
-> ?only_packages:String_set.t
|
||||||
|
-> ?x:string
|
||||||
-> unit
|
-> unit
|
||||||
-> setup Future.t
|
-> setup Future.t
|
||||||
val external_lib_deps
|
val external_lib_deps
|
||||||
|
|
|
@ -2,36 +2,69 @@ open Import
|
||||||
open Sexp.Of_sexp
|
open Sexp.Of_sexp
|
||||||
|
|
||||||
module Context = struct
|
module Context = struct
|
||||||
|
module Target = struct
|
||||||
|
type t =
|
||||||
|
| Native
|
||||||
|
| Named of string
|
||||||
|
|
||||||
|
let t sexp =
|
||||||
|
match string sexp with
|
||||||
|
| "native" -> Native
|
||||||
|
| s -> Named s
|
||||||
|
end
|
||||||
|
|
||||||
module Opam = struct
|
module Opam = struct
|
||||||
type t =
|
type t =
|
||||||
{ name : string
|
{ name : string
|
||||||
; switch : string
|
; switch : string
|
||||||
; root : string option
|
; root : string option
|
||||||
; merlin : bool
|
; merlin : bool
|
||||||
|
; targets : Target.t list
|
||||||
}
|
}
|
||||||
|
|
||||||
let t =
|
let t =
|
||||||
record
|
field "switch" string >>= fun switch ->
|
||||||
(field "switch" string >>= fun switch ->
|
|
||||||
field "name" string ~default:switch >>= fun name ->
|
field "name" string ~default:switch >>= fun name ->
|
||||||
|
field "targets" (list Target.t) ~default:[Target.Native] >>= fun targets ->
|
||||||
field_o "root" string >>= fun root ->
|
field_o "root" string >>= fun root ->
|
||||||
field_b "merlin" >>= fun merlin ->
|
field_b "merlin" >>= fun merlin ->
|
||||||
return { switch
|
return { switch
|
||||||
; name
|
; name
|
||||||
; root
|
; root
|
||||||
; merlin
|
; merlin
|
||||||
})
|
; targets
|
||||||
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
type t = Default | Opam of Opam.t
|
type t = Default of Target.t list | Opam of Opam.t
|
||||||
|
|
||||||
let t = function
|
let t = function
|
||||||
| Atom (_, "default") -> Default
|
| Atom (_, "default") -> Default [Native]
|
||||||
| sexp -> Opam (Opam.t sexp)
|
| List (_, List _ :: _) as sexp -> Opam (record Opam.t sexp)
|
||||||
|
| sexp ->
|
||||||
|
sum
|
||||||
|
[ cstr_record "default"
|
||||||
|
(field "targets" (list Target.t) ~default:[Target.Native]
|
||||||
|
>>= fun targets ->
|
||||||
|
return (Default targets))
|
||||||
|
; cstr_record "opam"
|
||||||
|
(Opam.t >>= fun x -> return (Opam x))
|
||||||
|
]
|
||||||
|
sexp
|
||||||
|
|
||||||
let name = function
|
let name = function
|
||||||
| Default -> "default"
|
| Default _ -> "default"
|
||||||
| Opam o -> o.name
|
| Opam o -> o.name
|
||||||
|
|
||||||
|
let targets = function
|
||||||
|
| Default l -> l
|
||||||
|
| Opam o -> o.targets
|
||||||
|
|
||||||
|
let all_names t =
|
||||||
|
let n = name t in
|
||||||
|
n :: List.filter_map (targets t) ~f:(function
|
||||||
|
| Native -> None
|
||||||
|
| Named s -> Some (n ^ "." ^ s))
|
||||||
end
|
end
|
||||||
|
|
||||||
type t =
|
type t =
|
||||||
|
@ -39,7 +72,8 @@ type t =
|
||||||
; contexts : Context.t list
|
; contexts : Context.t list
|
||||||
}
|
}
|
||||||
|
|
||||||
let t sexps =
|
let t ?x sexps =
|
||||||
|
let defined_names = ref String_set.empty in
|
||||||
let merlin_ctx, contexts =
|
let merlin_ctx, contexts =
|
||||||
List.fold_left sexps ~init:(None, []) ~f:(fun (merlin_ctx, ctxs) sexp ->
|
List.fold_left sexps ~init:(None, []) ~f:(fun (merlin_ctx, ctxs) sexp ->
|
||||||
let ctx =
|
let ctx =
|
||||||
|
@ -47,6 +81,21 @@ let t sexps =
|
||||||
[ cstr "context" (Context.t @> nil) (fun x -> x) ]
|
[ cstr "context" (Context.t @> nil) (fun x -> x) ]
|
||||||
sexp
|
sexp
|
||||||
in
|
in
|
||||||
|
let ctx =
|
||||||
|
match x with
|
||||||
|
| None -> ctx
|
||||||
|
| Some s ->
|
||||||
|
let target = Context.Target.Named s in
|
||||||
|
let add_target target targets =
|
||||||
|
if List.mem target ~set:targets then
|
||||||
|
targets
|
||||||
|
else
|
||||||
|
targets @ [target]
|
||||||
|
in
|
||||||
|
match ctx with
|
||||||
|
| Default targets -> Default (add_target target targets)
|
||||||
|
| Opam o -> Opam { o with targets = add_target target o.targets }
|
||||||
|
in
|
||||||
let name = Context.name ctx in
|
let name = Context.name ctx in
|
||||||
if name = "" ||
|
if name = "" ||
|
||||||
String.is_prefix name ~prefix:"." ||
|
String.is_prefix name ~prefix:"." ||
|
||||||
|
@ -55,8 +104,9 @@ let t sexps =
|
||||||
String.contains name '/' ||
|
String.contains name '/' ||
|
||||||
String.contains name '\\' then
|
String.contains name '\\' then
|
||||||
of_sexp_errorf sexp "%S is not allowed as a build context name" name;
|
of_sexp_errorf sexp "%S is not allowed as a build context name" name;
|
||||||
if List.exists ctxs ~f:(fun c -> Context.name c = name) then
|
if String_set.mem name !defined_names then
|
||||||
of_sexp_errorf sexp "second definition of build context %S" name;
|
of_sexp_errorf sexp "second definition of build context %S" name;
|
||||||
|
defined_names := String_set.union !defined_names (String_set.of_list (Context.all_names ctx));
|
||||||
match ctx, merlin_ctx with
|
match ctx, merlin_ctx with
|
||||||
| Opam { merlin = true; _ }, Some _ ->
|
| Opam { merlin = true; _ }, Some _ ->
|
||||||
of_sexp_errorf sexp "you can only have one context for merlin"
|
of_sexp_errorf sexp "you can only have one context for merlin"
|
||||||
|
@ -67,14 +117,14 @@ let t sexps =
|
||||||
in
|
in
|
||||||
let contexts =
|
let contexts =
|
||||||
match contexts with
|
match contexts with
|
||||||
| [] -> [Context.Default]
|
| [] -> [Context.Default [Native]]
|
||||||
| _ -> contexts
|
| _ -> contexts
|
||||||
in
|
in
|
||||||
let merlin_ctx =
|
let merlin_ctx =
|
||||||
match merlin_ctx with
|
match merlin_ctx with
|
||||||
| Some _ -> merlin_ctx
|
| Some _ -> merlin_ctx
|
||||||
| None ->
|
| None ->
|
||||||
if List.mem Context.Default ~set:contexts then
|
if List.exists contexts ~f:(function Context.Default _ -> true | _ -> false) then
|
||||||
Some "default"
|
Some "default"
|
||||||
else
|
else
|
||||||
None
|
None
|
||||||
|
@ -83,4 +133,4 @@ let t sexps =
|
||||||
; contexts = List.rev contexts
|
; contexts = List.rev contexts
|
||||||
}
|
}
|
||||||
|
|
||||||
let load fname = t (Sexp.load ~fname ~mode:Many)
|
let load ?x fname = t ?x (Sexp.load ~fname ~mode:Many)
|
||||||
|
|
|
@ -3,16 +3,24 @@
|
||||||
open! Import
|
open! Import
|
||||||
|
|
||||||
module Context : sig
|
module Context : sig
|
||||||
|
module Target : sig
|
||||||
|
type t =
|
||||||
|
| Native
|
||||||
|
| Named of string
|
||||||
|
end
|
||||||
module Opam : sig
|
module Opam : sig
|
||||||
type t =
|
type t =
|
||||||
{ name : string
|
{ name : string
|
||||||
; switch : string
|
; switch : string
|
||||||
; root : string option
|
; root : string option
|
||||||
; merlin : bool
|
; merlin : bool
|
||||||
|
; targets : Target.t list
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
type t = Default | Opam of Opam.t
|
type t = Default of Target.t list | Opam of Opam.t
|
||||||
|
|
||||||
|
val name : t -> string
|
||||||
end
|
end
|
||||||
|
|
||||||
type t =
|
type t =
|
||||||
|
@ -20,4 +28,4 @@ type t =
|
||||||
; contexts : Context.t list
|
; contexts : Context.t list
|
||||||
}
|
}
|
||||||
|
|
||||||
val load : string -> t
|
val load : ?x:string -> string -> t
|
||||||
|
|
Loading…
Reference in New Issue