Add (modes ...) for executables

This commit is contained in:
Jeremie Dimino 2017-05-29 14:06:52 +01:00
parent b52d778d4c
commit 9f8803af67
6 changed files with 71 additions and 15 deletions

View File

@ -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.
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:
0
- ``(public_name <public-name>)`` specifies that the executable
should be installed under that name. It is the same as adding the
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
...)`` 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 ...)``
field of `library`_

View File

@ -306,8 +306,8 @@ module Gen(P : Params) = struct
in
let static = stubs_archive lib ~dir in
let dynamic = dll lib ~dir in
if List.mem Mode.Native ~set:lib.modes &&
List.mem Mode.Byte ~set:lib.modes &&
if lib.modes.native &&
lib.modes.byte &&
lib.dynlink
then begin
(* 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 |
+-----------------------------------------------------------------+ *)
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 mode, link_flags, compiler =
match Context.compiler ctx mode with
| Some compiler -> (mode, link_flags, compiler)
| None -> (Byte, "-custom" :: link_flags, ctx.ocamlc)
match force_custom_bytecode, Context.compiler ctx mode with
| false, Some compiler -> (mode, link_flags, compiler)
| _ -> (Byte, "-custom" :: link_flags, ctx.ocamlc)
in
let dep_graph = Ml_kind.Dict.get dep_graph Impl 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 Mode.all ~f:(fun mode ->
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.
requires = real_requires
; flags = flags.common
@ -770,8 +772,7 @@ module Gen(P : Params) = struct
Install.Entry.make section fn
?dst:(Option.map sub_dir ~f:(fun d -> sprintf "%s/%s" d (Path.basename fn)))
in
let byte = List.mem Mode.Byte ~set:lib.modes in
let native = List.mem Mode.Native ~set:lib.modes in
let { Mode.Dict. byte; native } = lib.modes in
let if_ cond l = if cond then l else [] in
let files =
let modules =

View File

@ -512,7 +512,7 @@ module Library = struct
; synopsis : string option
; install_c_headers : string list
; ppx_runtime_libraries : string list
; modes : Mode.t list
; modes : Mode.Dict.Set.t
; kind : Kind.t
; c_flags : Ordered_set_lang.Unexpanded.t
; c_names : string list
@ -544,7 +544,7 @@ module Library = struct
field "library_flags" (list String_with_vars.t) ~default:[] >>= fun library_flags ->
field_oslu "c_library_flags" >>= fun c_library_flags ->
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 "wrapped" bool ~default:true >>= fun wrapped ->
field_b "optional" >>= fun optional ->
@ -623,6 +623,7 @@ module Executables = struct
{ names : string list
; link_executables : bool
; link_flags : string list
; modes : Mode.Dict.Set.t
; buildable : Buildable.t
}
@ -630,19 +631,28 @@ module Executables = struct
Buildable.v1 >>= fun buildable ->
field "link_executables" bool ~default:true >>= fun link_executables ->
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 =
{ names
; link_executables
; link_flags
; modes
; buildable
}
in
let to_install =
let ext = if modes.native then ".exe" else ".bc" in
List.map2 names public_names
~f:(fun name pub ->
match pub with
| 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)
in
match to_install with

View File

@ -47,4 +47,32 @@ module Dict = struct
{ byte = f a.byte b.byte
; 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

View File

@ -28,4 +28,14 @@ module Dict : sig
val of_func : (mode:mode -> 'a) -> 'a 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

View File

@ -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
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 =
Build.memoize "cmi library dependencies"
(requires