Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

melange: add melc_flags #6569

Merged
merged 8 commits into from
Nov 30, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/dune_rules/exe.ml
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ let link_exe ~loc ~name ~(linkage : Linkage.t) ~cm_files ~link_time_code_gen
let fdo_linker_script = Fdo.Linker_script.create cctx (Path.build exe) in
let open Memo.O in
let* action_with_targets =
let ocaml_flags = Ocaml_flags.get (CC.flags cctx) mode in
let ocaml_flags = Ocaml_flags.get (CC.flags cctx) (Ocaml mode) in
let prefix =
Cm_files.top_sorted_objects_and_cms cm_files ~mode
|> Action_builder.dyn_paths_unit
Expand Down
9 changes: 9 additions & 0 deletions src/dune_rules/lib_mode.ml
Original file line number Diff line number Diff line change
Expand Up @@ -66,9 +66,18 @@ module Map = struct
; ("melange", to_dyn melange)
]

let get t = function
| Ocaml k -> Ocaml.Mode.Dict.get t.ocaml k
| Melange -> t.melange

let map t ~f =
{ ocaml = Ocaml.Mode.Dict.map ~f t.ocaml; melange = f t.melange }

let make_all x = { ocaml = Ocaml.Mode.Dict.make_both x; melange = x }

let make ~byte ~native ~melange =
{ ocaml = Ocaml.Mode.Dict.make ~byte ~native; melange }

module Set = struct
type nonrec t = bool t

Expand Down
10 changes: 10 additions & 0 deletions src/dune_rules/lib_mode.mli
Original file line number Diff line number Diff line change
Expand Up @@ -32,15 +32,25 @@ end
val of_cm_kind : Cm_kind.t -> t

module Map : sig
type mode := t

type 'a t =
{ ocaml : 'a Ocaml.Mode.Dict.t
; melange : 'a
}

val equal : ('a -> 'a -> bool) -> 'a t -> 'a t -> bool

val to_dyn : ('a -> Dyn.t) -> 'a t -> Dyn.t

val get : 'a t -> mode -> 'a

val map : 'a t -> f:('a -> 'b) -> 'b t

val make_all : 'a -> 'a t

val make : byte:'a -> native:'a -> melange:'a -> 'a t

module Set : sig
type nonrec t = bool t

Expand Down
4 changes: 2 additions & 2 deletions src/dune_rules/lib_rules.ml
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ let build_lib (lib : Library.t) ~native_archives ~sctx ~expander ~flags ~dir
let obj_deps =
Action_builder.paths (Cm_files.unsorted_objects_and_cms cm_files ~mode)
in
let ocaml_flags = Ocaml_flags.get flags mode in
let ocaml_flags = Ocaml_flags.get flags (Ocaml mode) in
let* standard =
let+ project = Scope.DB.find_by_dir dir |> Memo.map ~f:Scope.project in
match Dune_project.use_standard_c_and_cxx_flags project with
Expand Down Expand Up @@ -339,7 +339,7 @@ let build_shared lib ~native_archives ~sctx ~dir ~flags =
~for_mode:Mode.Select.All
|> List.map ~f:Path.build))
>>> Command.run ~dir:(Path.build ctx.build_dir) (Ok ocamlopt)
[ Command.Args.dyn (Ocaml_flags.get flags Native)
[ Command.Args.dyn (Ocaml_flags.get flags (Ocaml Native))
; A "-shared"
; A "-linkall"
; A "-I"
Expand Down
17 changes: 16 additions & 1 deletion src/dune_rules/melange_rules.ml
Original file line number Diff line number Diff line change
@@ -1,6 +1,21 @@
open Import
module CC = Compilation_context

let ocaml_flags sctx ~dir melange =
let open Memo.O in
let open Super_context in
let* expander = expander sctx ~dir in
let* flags =
let+ ocaml_flags = env_node sctx ~dir >>= Env_node.ocaml_flags in
Ocaml_flags.make_with_melange ~melange ~default:ocaml_flags
~eval:(Expander.expand_and_eval_set expander)
in
build_dir_is_vendored dir >>| function
| true ->
let ocaml_version = (context sctx).version in
with_vendored_flags ~ocaml_version flags
| false -> flags

let lib_output_dir ~target_dir ~lib_dir =
Path.Build.append_source target_dir
(Path.Build.drop_build_context_exn lib_dir)
Expand Down Expand Up @@ -97,7 +112,7 @@ let add_rules_for_entries ~sctx ~dir ~expander ~dir_contents ~scope
>>| Ml_sources.modules_and_obj_dir ~for_:(Melange { target = mel.target })
in
let* () = Check_rules.add_obj_dir sctx ~obj_dir in
let* flags = Super_context.ocaml_flags sctx ~dir mel.flags in
let* flags = ocaml_flags sctx ~dir mel.compile_flags in
let requires_link = Lib.Compile.requires_link compile_info in
let direct_requires = Lib.Compile.direct_requires compile_info in
let* modules, pp =
Expand Down
6 changes: 3 additions & 3 deletions src/dune_rules/melange_stanzas.ml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ module Emit = struct
; preprocess : Preprocess.With_instrumentation.t Preprocess.Per_module.t
; preprocessor_deps : Dep_conf.t list
; promote : Rule.Promote.t option
; flags : Ocaml_flags.Spec.t
; compile_flags : Ordered_set_lang.Unexpanded.t
; root_module : (Loc.t * Module_name.t) option
; javascript_extension : string
}
Expand Down Expand Up @@ -88,7 +88,7 @@ module Emit = struct
and+ preprocess, preprocessor_deps = Stanza_common.preprocess_fields
and+ promote = field_o "promote" Rule_mode_decoder.Promote.decode
and+ loc_instrumentation, instrumentation = Stanza_common.instrumentation
and+ flags = Ocaml_flags.Spec.decode
and+ compile_flags = Ordered_set_lang.Unexpanded.field "compile_flags"
and+ root_module = field_o "root_module" Module_name.decode_loc
and+ javascript_extension = extension_field "javascript_extension" in
let preprocess =
Expand All @@ -111,7 +111,7 @@ module Emit = struct
; preprocess
; preprocessor_deps
; promote
; flags
; compile_flags
; root_module
; javascript_extension
})
Expand Down
2 changes: 1 addition & 1 deletion src/dune_rules/melange_stanzas.mli
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ module Emit : sig
; preprocess : Preprocess.With_instrumentation.t Preprocess.Per_module.t
; preprocessor_deps : Dep_conf.t list
; promote : Rule.Promote.t option
; flags : Ocaml_flags.Spec.t
; compile_flags : Ordered_set_lang.Unexpanded.t
; root_module : (Loc.t * Module_name.t) option
; javascript_extension : string
}
Expand Down
12 changes: 2 additions & 10 deletions src/dune_rules/module_compilation.ml
Original file line number Diff line number Diff line change
Expand Up @@ -190,15 +190,7 @@ let build_cm cctx ~force_write_cmi ~precompiled_cmi ~cm_kind (m : Module.t)
else Command.Args.empty
in
let flags, sandbox =
let flags =
Ocaml_flags.get (CC.flags cctx)
(match mode with
| Ocaml m -> m
| Melange ->
(* TODO: define Melange default flags somewhere, should melange rules
read from [flags] stanza as well? *)
Byte)
in
let flags = Ocaml_flags.get (CC.flags cctx) mode in
match Module.pp_flags m with
| None -> (flags, sandbox)
| Some (pp, sandbox') ->
Expand Down Expand Up @@ -335,7 +327,7 @@ let ocamlc_i ~deps cctx (m : Module.t) ~output =
[ Path.build (Obj_dir.Module.cm_file_exn obj_dir m ~kind:(Ocaml Cmi))
]))
in
let ocaml_flags = Ocaml_flags.get (CC.flags cctx) Mode.Byte in
let ocaml_flags = Ocaml_flags.get (CC.flags cctx) (Ocaml Byte) in
let modules = Compilation_context.modules cctx in
Super_context.add_rule sctx ~dir
(Action_builder.With_targets.add ~file_targets:[ output ]
Expand Down
61 changes: 47 additions & 14 deletions src/dune_rules/ocaml_flags.ml
Original file line number Diff line number Diff line change
Expand Up @@ -71,11 +71,11 @@ let default_flags ~dune_version ~profile =

type 'a t' =
{ common : 'a
; specific : 'a Mode.Dict.t
; specific : 'a Lib_mode.Map.t
}

let equal f { common; specific } t =
f common t.common && Mode.Dict.equal f specific t.specific
f common t.common && Lib_mode.Map.equal f specific t.specific

module Spec = struct
type t = Ordered_set_lang.Unexpanded.t t'
Expand All @@ -84,32 +84,40 @@ module Spec = struct

let standard =
{ common = Ordered_set_lang.Unexpanded.standard
; specific = Mode.Dict.make_both Ordered_set_lang.Unexpanded.standard
; specific = Lib_mode.Map.make_all Ordered_set_lang.Unexpanded.standard
}

let decode =
let open Dune_lang.Decoder in
let field_oslu = Ordered_set_lang.Unexpanded.field in
let+ common = field_oslu "flags"
and+ byte = field_oslu "ocamlc_flags"
and+ native = field_oslu "ocamlopt_flags" in
let specific = Mode.Dict.make ~native ~byte in
and+ native = field_oslu "ocamlopt_flags"
and+ melange =
field_oslu
~check:(Dune_lang.Syntax.since Dune_project.Melange_syntax.t (0, 1))
"melange.compile_flags"
in
let specific = Lib_mode.Map.make ~byte ~native ~melange in
{ common; specific }
end

type t = string list Action_builder.t t'

let empty =
let build = Action_builder.return [] in
{ common = build; specific = Mode.Dict.make_both build }
{ common = build; specific = Lib_mode.Map.make_all build }

let of_list l = { empty with common = Action_builder.return l }

let default ~dune_version ~profile =
{ common = Action_builder.return (default_flags ~dune_version ~profile)
; specific =
{ byte = Action_builder.return default_ocamlc_flags
; native = Action_builder.return default_ocamlopt_flags
{ ocaml =
{ byte = Action_builder.return default_ocamlc_flags
; native = Action_builder.return default_ocamlopt_flags
}
; melange = Action_builder.return default_ocamlc_flags
}
}

Expand All @@ -120,14 +128,34 @@ let make ~spec ~default ~eval =
in
{ common = f "common flags" spec.common default.common
; specific =
{ byte = f "ocamlc flags" spec.specific.byte default.specific.byte
; native = f "ocamlopt flags" spec.specific.native default.specific.native
{ ocaml =
{ byte =
f "ocamlc flags" spec.specific.ocaml.byte
default.specific.ocaml.byte
; native =
f "ocamlopt flags" spec.specific.ocaml.native
default.specific.ocaml.native
}
; melange =
f "melange compile_flags" spec.specific.melange
default.specific.melange
}
}

let make_with_melange ~melange ~default ~eval =
{ common = default.common
; specific =
{ ocaml = default.specific.ocaml
; melange =
Action_builder.memoize ~cutoff:(List.equal String.equal)
"melange compile_flags"
(eval melange ~standard:default.specific.melange)
}
}

let get t mode =
let+ common = t.common
and+ specific = Mode.Dict.get t.specific mode in
and+ specific = Lib_mode.Map.get t.specific mode in
common @ specific

let map_common t ~f =
Expand All @@ -149,8 +177,13 @@ let common t = t.common

let dump t =
let+ common = t.common
and+ byte = t.specific.byte
and+ native = t.specific.native in
and+ byte = t.specific.ocaml.byte
and+ native = t.specific.ocaml.native
and+ melange = t.specific.melange in
List.map
~f:Dune_lang.Encoder.(pair string (list string))
[ ("flags", common); ("ocamlc_flags", byte); ("ocamlopt_flags", native) ]
[ ("flags", common)
; ("ocamlc_flags", byte)
; ("ocamlopt_flags", native)
; ("melange.compile_flags", melange)
]
11 changes: 10 additions & 1 deletion src/dune_rules/ocaml_flags.mli
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,22 @@ val make :
-> string list Action_builder.t)
-> t

val make_with_melange :
melange:Ordered_set_lang.Unexpanded.t
-> default:t
-> eval:
( Ordered_set_lang.Unexpanded.t
-> standard:string list Action_builder.t
-> string list Action_builder.t)
-> t

val default : dune_version:Dune_lang.Syntax.Version.t -> profile:Profile.t -> t

val empty : t

val of_list : string list -> t

val get : t -> Mode.t -> string list Action_builder.t
val get : t -> Lib_mode.t -> string list Action_builder.t

val append_common : t -> string list -> t

Expand Down
5 changes: 5 additions & 0 deletions src/dune_rules/super_context.mli
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,11 @@ val context : t -> Context.t
(** Context env with additional variables computed from packages *)
val context_env : t -> Env.t

val build_dir_is_vendored : Path.Build.t -> bool Memo.t

val with_vendored_flags :
ocaml_version:Version.t -> Ocaml_flags.t -> Ocaml_flags.t

(** Compute the ocaml flags based on the directory environment and a buildable
stanza *)
val ocaml_flags :
Expand Down
22 changes: 20 additions & 2 deletions test/blackbox-tests/test-cases/melange/flags.t
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
Test (flags) field on melange.emit stanza
Test flags and compile_flags fields on melange.emit stanza

$ cat > dune-project <<EOF
> (lang dune 3.6)
> (using melange 0.1)
> EOF

Using flags field in melange.emit stanzas is not supported

$ cat > dune <<EOF
> (melange.emit
> (target output)
Expand All @@ -22,7 +24,23 @@ The code in main contains unused var (warning 26) and illegal backlash (warning

Building should not fail as warnings are silenced

$ dune build output/main.js
File "dune", line 5, characters 2-7:
5 | (flags -w -14-26))
^^^^^
Error: Unknown field flags
[1]

Should use compile_flags

$ cat > dune <<EOF
> (melange.emit
> (target output)
> (entries main)
> (module_system commonjs)
> (compile_flags -w -14-26))
> EOF

$ dune build output/main.js
$ node _build/default/output/main.js
hello

Loading