Add (modes ...) for executables
This commit is contained in:
parent
b52d778d4c
commit
9f8803af67
|
@ -205,10 +205,11 @@ the ``ocamlrun`` virtual machine as well as the byte code. As such you
|
||||||
can always rely on ``<name>.exe`` being available.
|
can always rely on ``<name>.exe`` being available.
|
||||||
|
|
||||||
Native compilation is considered not available when there is no
|
Native compilation is considered not available when there is no
|
||||||
``ocamlopt`` binary at the same place as where ``ocamlc`` was found.
|
``ocamlopt`` binary at the same place as where ``ocamlc`` was found,
|
||||||
|
or when there is a ``(modes (...))`` field not listing ``native``.
|
||||||
|
|
||||||
``<optional-fields>`` are:
|
``<optional-fields>`` are:
|
||||||
|
0
|
||||||
- ``(public_name <public-name>)`` specifies that the executable
|
- ``(public_name <public-name>)`` specifies that the executable
|
||||||
should be installed under that name. It is the same as adding the
|
should be installed under that name. It is the same as adding the
|
||||||
following stanza to your ``jbuild`` file:
|
following stanza to your ``jbuild`` file:
|
||||||
|
@ -231,6 +232,11 @@ Native compilation is considered not available when there is no
|
||||||
the current stanza. It is interpreted in the same way as the ``(modules
|
the current stanza. It is interpreted in the same way as the ``(modules
|
||||||
...)`` field of `library`_
|
...)`` field of `library`_
|
||||||
|
|
||||||
|
- ``(modes (<modes>))`` modes (``byte`` and ``native``) which should be built by
|
||||||
|
default. If the stanza has a ``(public_name ...)`` field and
|
||||||
|
``native`` is not listed here, the byte-code version will be
|
||||||
|
installed instead.
|
||||||
|
|
||||||
- ``(preprocess <preprocess-spec>)`` is the same as the ``(preprocess ...)``
|
- ``(preprocess <preprocess-spec>)`` is the same as the ``(preprocess ...)``
|
||||||
field of `library`_
|
field of `library`_
|
||||||
|
|
||||||
|
|
|
@ -306,8 +306,8 @@ module Gen(P : Params) = struct
|
||||||
in
|
in
|
||||||
let static = stubs_archive lib ~dir in
|
let static = stubs_archive lib ~dir in
|
||||||
let dynamic = dll lib ~dir in
|
let dynamic = dll lib ~dir in
|
||||||
if List.mem Mode.Native ~set:lib.modes &&
|
if lib.modes.native &&
|
||||||
List.mem Mode.Byte ~set:lib.modes &&
|
lib.modes.byte &&
|
||||||
lib.dynlink
|
lib.dynlink
|
||||||
then begin
|
then begin
|
||||||
(* If we build for both modes and support dynlink, use a single invocation to
|
(* If we build for both modes and support dynlink, use a single invocation to
|
||||||
|
@ -384,12 +384,13 @@ module Gen(P : Params) = struct
|
||||||
| Executables stuff |
|
| Executables stuff |
|
||||||
+-----------------------------------------------------------------+ *)
|
+-----------------------------------------------------------------+ *)
|
||||||
|
|
||||||
let build_exe ~js_of_ocaml ~flags ~dir ~requires ~name ~mode ~modules ~dep_graph ~link_flags =
|
let build_exe ~js_of_ocaml ~flags ~dir ~requires ~name ~mode ~modules ~dep_graph
|
||||||
|
~link_flags ~force_custom_bytecode =
|
||||||
let exe_ext = Mode.exe_ext mode in
|
let exe_ext = Mode.exe_ext mode in
|
||||||
let mode, link_flags, compiler =
|
let mode, link_flags, compiler =
|
||||||
match Context.compiler ctx mode with
|
match force_custom_bytecode, Context.compiler ctx mode with
|
||||||
| Some compiler -> (mode, link_flags, compiler)
|
| false, Some compiler -> (mode, link_flags, compiler)
|
||||||
| None -> (Byte, "-custom" :: link_flags, ctx.ocamlc)
|
| _ -> (Byte, "-custom" :: link_flags, ctx.ocamlc)
|
||||||
in
|
in
|
||||||
let dep_graph = Ml_kind.Dict.get dep_graph Impl in
|
let dep_graph = Ml_kind.Dict.get dep_graph Impl in
|
||||||
let exe = Path.relative dir (name ^ exe_ext) in
|
let exe = Path.relative dir (name ^ exe_ext) in
|
||||||
|
@ -462,7 +463,8 @@ module Gen(P : Params) = struct
|
||||||
List.iter exes.names ~f:(fun name ->
|
List.iter exes.names ~f:(fun name ->
|
||||||
List.iter Mode.all ~f:(fun mode ->
|
List.iter Mode.all ~f:(fun mode ->
|
||||||
build_exe ~js_of_ocaml:exes.buildable.js_of_ocaml ~flags ~dir ~requires ~name
|
build_exe ~js_of_ocaml:exes.buildable.js_of_ocaml ~flags ~dir ~requires ~name
|
||||||
~mode ~modules ~dep_graph ~link_flags:exes.link_flags));
|
~mode ~modules ~dep_graph ~link_flags:exes.link_flags
|
||||||
|
~force_custom_bytecode:(mode = Native && not exes.modes.native)));
|
||||||
{ Merlin.
|
{ Merlin.
|
||||||
requires = real_requires
|
requires = real_requires
|
||||||
; flags = flags.common
|
; flags = flags.common
|
||||||
|
@ -770,8 +772,7 @@ module Gen(P : Params) = struct
|
||||||
Install.Entry.make section fn
|
Install.Entry.make section fn
|
||||||
?dst:(Option.map sub_dir ~f:(fun d -> sprintf "%s/%s" d (Path.basename fn)))
|
?dst:(Option.map sub_dir ~f:(fun d -> sprintf "%s/%s" d (Path.basename fn)))
|
||||||
in
|
in
|
||||||
let byte = List.mem Mode.Byte ~set:lib.modes in
|
let { Mode.Dict. byte; native } = lib.modes in
|
||||||
let native = List.mem Mode.Native ~set:lib.modes in
|
|
||||||
let if_ cond l = if cond then l else [] in
|
let if_ cond l = if cond then l else [] in
|
||||||
let files =
|
let files =
|
||||||
let modules =
|
let modules =
|
||||||
|
|
|
@ -512,7 +512,7 @@ module Library = struct
|
||||||
; synopsis : string option
|
; synopsis : string option
|
||||||
; install_c_headers : string list
|
; install_c_headers : string list
|
||||||
; ppx_runtime_libraries : string list
|
; ppx_runtime_libraries : string list
|
||||||
; modes : Mode.t list
|
; modes : Mode.Dict.Set.t
|
||||||
; kind : Kind.t
|
; kind : Kind.t
|
||||||
; c_flags : Ordered_set_lang.Unexpanded.t
|
; c_flags : Ordered_set_lang.Unexpanded.t
|
||||||
; c_names : string list
|
; c_names : string list
|
||||||
|
@ -544,7 +544,7 @@ module Library = struct
|
||||||
field "library_flags" (list String_with_vars.t) ~default:[] >>= fun library_flags ->
|
field "library_flags" (list String_with_vars.t) ~default:[] >>= fun library_flags ->
|
||||||
field_oslu "c_library_flags" >>= fun c_library_flags ->
|
field_oslu "c_library_flags" >>= fun c_library_flags ->
|
||||||
field "virtual_deps" (list string) ~default:[] >>= fun virtual_deps ->
|
field "virtual_deps" (list string) ~default:[] >>= fun virtual_deps ->
|
||||||
field "modes" (list Mode.t) ~default:Mode.all >>= fun modes ->
|
field "modes" Mode.Dict.Set.t ~default:Mode.Dict.Set.all >>= fun modes ->
|
||||||
field "kind" Kind.t ~default:Kind.Normal >>= fun kind ->
|
field "kind" Kind.t ~default:Kind.Normal >>= fun kind ->
|
||||||
field "wrapped" bool ~default:true >>= fun wrapped ->
|
field "wrapped" bool ~default:true >>= fun wrapped ->
|
||||||
field_b "optional" >>= fun optional ->
|
field_b "optional" >>= fun optional ->
|
||||||
|
@ -623,6 +623,7 @@ module Executables = struct
|
||||||
{ names : string list
|
{ names : string list
|
||||||
; link_executables : bool
|
; link_executables : bool
|
||||||
; link_flags : string list
|
; link_flags : string list
|
||||||
|
; modes : Mode.Dict.Set.t
|
||||||
; buildable : Buildable.t
|
; buildable : Buildable.t
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -630,19 +631,28 @@ module Executables = struct
|
||||||
Buildable.v1 >>= fun buildable ->
|
Buildable.v1 >>= fun buildable ->
|
||||||
field "link_executables" bool ~default:true >>= fun link_executables ->
|
field "link_executables" bool ~default:true >>= fun link_executables ->
|
||||||
field "link_flags" (list string) ~default:[] >>= fun link_flags ->
|
field "link_flags" (list string) ~default:[] >>= fun link_flags ->
|
||||||
|
map_validate (field "modes" Mode.Dict.Set.t ~default:Mode.Dict.Set.all)
|
||||||
|
~f:(fun modes ->
|
||||||
|
if Mode.Dict.Set.is_empty modes then
|
||||||
|
Error "No compilation mode defined."
|
||||||
|
else
|
||||||
|
Ok modes)
|
||||||
|
>>= fun modes ->
|
||||||
let t =
|
let t =
|
||||||
{ names
|
{ names
|
||||||
; link_executables
|
; link_executables
|
||||||
; link_flags
|
; link_flags
|
||||||
|
; modes
|
||||||
; buildable
|
; buildable
|
||||||
}
|
}
|
||||||
in
|
in
|
||||||
let to_install =
|
let to_install =
|
||||||
|
let ext = if modes.native then ".exe" else ".bc" in
|
||||||
List.map2 names public_names
|
List.map2 names public_names
|
||||||
~f:(fun name pub ->
|
~f:(fun name pub ->
|
||||||
match pub with
|
match pub with
|
||||||
| None -> None
|
| None -> None
|
||||||
| Some pub -> Some ({ Install_conf. src = name ^ ".exe"; dst = Some pub }))
|
| Some pub -> Some ({ Install_conf. src = name ^ ext; dst = Some pub }))
|
||||||
|> List.filter_map ~f:(fun x -> x)
|
|> List.filter_map ~f:(fun x -> x)
|
||||||
in
|
in
|
||||||
match to_install with
|
match to_install with
|
||||||
|
|
28
src/mode.ml
28
src/mode.ml
|
@ -47,4 +47,32 @@ module Dict = struct
|
||||||
{ byte = f a.byte b.byte
|
{ byte = f a.byte b.byte
|
||||||
; native = f a.native b.native
|
; native = f a.native b.native
|
||||||
}
|
}
|
||||||
|
|
||||||
|
module Set = struct
|
||||||
|
type nonrec t = bool t
|
||||||
|
|
||||||
|
let all =
|
||||||
|
{ byte = true
|
||||||
|
; native = true
|
||||||
|
}
|
||||||
|
|
||||||
|
let to_list t =
|
||||||
|
let l = [] in
|
||||||
|
let l = if t.native then Native :: l else l in
|
||||||
|
let l = if t.byte then Byte :: l else l in
|
||||||
|
l
|
||||||
|
|
||||||
|
let of_list l =
|
||||||
|
{ byte = List.mem Byte ~set:l
|
||||||
|
; native = List.mem Native ~set:l
|
||||||
|
}
|
||||||
|
|
||||||
|
let t sexp = of_list (Sexp.Of_sexp.list t sexp)
|
||||||
|
|
||||||
|
let is_empty t = not (t.byte || t.native)
|
||||||
|
|
||||||
|
let iter t ~f =
|
||||||
|
if t.byte then f Byte;
|
||||||
|
if t.native then f Native
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
10
src/mode.mli
10
src/mode.mli
|
@ -28,4 +28,14 @@ module Dict : sig
|
||||||
val of_func : (mode:mode -> 'a) -> 'a t
|
val of_func : (mode:mode -> 'a) -> 'a t
|
||||||
|
|
||||||
val map2 : 'a t -> 'b t -> f:('a -> 'b -> 'c) -> 'c t
|
val map2 : 'a t -> 'b t -> f:('a -> 'b -> 'c) -> 'c t
|
||||||
|
|
||||||
|
module Set : sig
|
||||||
|
type nonrec t = bool t
|
||||||
|
val t : t Sexp.Of_sexp.t
|
||||||
|
val all : t
|
||||||
|
val is_empty : t -> bool
|
||||||
|
val to_list : t -> mode list
|
||||||
|
val of_list : mode list -> t
|
||||||
|
val iter : t -> f:(mode -> unit) -> unit
|
||||||
|
end
|
||||||
end with type mode := t
|
end with type mode := t
|
||||||
|
|
|
@ -88,7 +88,8 @@ let build_module sctx ?sandbox ~dynlink ~js_of_ocaml ~flags m ~dir ~dep_graph
|
||||||
let src = Module.cm_file m ~dir Cm_kind.Cmo in
|
let src = Module.cm_file m ~dir Cm_kind.Cmo in
|
||||||
SC.add_rules sctx (Js_of_ocaml_rules.build_cm sctx ~dir ~js_of_ocaml ~src)
|
SC.add_rules sctx (Js_of_ocaml_rules.build_cm sctx ~dir ~js_of_ocaml ~src)
|
||||||
|
|
||||||
let build_modules sctx ~dynlink ~js_of_ocaml ~flags ~dir ~dep_graph ~modules ~requires ~alias_module =
|
let build_modules sctx ~dynlink ~js_of_ocaml ~flags ~dir ~dep_graph ~modules ~requires
|
||||||
|
~alias_module =
|
||||||
let cmi_requires =
|
let cmi_requires =
|
||||||
Build.memoize "cmi library dependencies"
|
Build.memoize "cmi library dependencies"
|
||||||
(requires
|
(requires
|
||||||
|
|
Loading…
Reference in New Issue