Skip to content

Commit

Permalink
duplicate link_flags to handle cxx_default_flags
Browse files Browse the repository at this point in the history
Signed-off-by: Hugo Heuzard <[email protected]>
  • Loading branch information
hhugo committed Dec 14, 2021
1 parent 084a465 commit 68f1b2a
Show file tree
Hide file tree
Showing 18 changed files with 182 additions and 57 deletions.
15 changes: 4 additions & 11 deletions src/dune_rules/dune_env.ml
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,6 @@ module Stanza = struct
and+ cxx = Ordered_set_lang.Unexpanded.field "cxx_flags" ?check in
Foreign_language.Dict.make ~c ~cxx

let link_flags ~since =
let check =
Option.map since ~f:(fun since ->
Dune_lang.Syntax.since Stanza.syntax since)
in
Ordered_set_lang.Unexpanded.field "link_flags" ?check

let menhir_flags ~since =
let check =
Option.map since ~f:(fun since ->
Expand Down Expand Up @@ -81,7 +74,7 @@ module Stanza = struct
type config =
{ flags : Ocaml_flags.Spec.t
; foreign_flags : Ordered_set_lang.Unexpanded.t Foreign_language.Dict.t
; link_flags : Ordered_set_lang.Unexpanded.t
; link_flags : Link_flags.Spec.t
; env_vars : Env.t
; binaries : File_binding.Unexpanded.t list
; inline_tests : Inline_tests.t option
Expand All @@ -108,7 +101,7 @@ module Stanza = struct
Ocaml_flags.Spec.equal flags t.flags
&& Foreign_language.Dict.equal Ordered_set_lang.Unexpanded.equal
foreign_flags t.foreign_flags
&& Ordered_set_lang.Unexpanded.equal link_flags t.link_flags
&& Link_flags.Spec.equal link_flags t.link_flags
&& Env.equal env_vars t.env_vars
&& List.equal File_binding.Unexpanded.equal binaries t.binaries
&& Option.equal Inline_tests.equal inline_tests t.inline_tests
Expand All @@ -124,7 +117,7 @@ module Stanza = struct
{ flags = Ocaml_flags.Spec.standard
; foreign_flags =
Foreign_language.Dict.make_both Ordered_set_lang.Unexpanded.standard
; link_flags = Ordered_set_lang.Unexpanded.standard
; link_flags = Link_flags.Spec.standard
; env_vars = Env.empty
; binaries = []
; inline_tests = None
Expand Down Expand Up @@ -192,7 +185,7 @@ module Stanza = struct
let config =
let+ flags = Ocaml_flags.Spec.decode
and+ foreign_flags = foreign_flags ~since:(Some (1, 7))
and+ link_flags = link_flags ~since:(Some (3, 0))
and+ link_flags = Link_flags.Spec.decode ~since:(Some (3, 0))
and+ env_vars = env_vars_field
and+ binaries =
field ~default:[] "binaries"
Expand Down
2 changes: 1 addition & 1 deletion src/dune_rules/dune_env.mli
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ module Stanza : sig
type config =
{ flags : Ocaml_flags.Spec.t
; foreign_flags : Ordered_set_lang.Unexpanded.t Foreign_language.Dict.t
; link_flags : Ordered_set_lang.Unexpanded.t
; link_flags : Link_flags.Spec.t
; env_vars : Env.t
; binaries : File_binding.Unexpanded.t list
; inline_tests : Inline_tests.t option
Expand Down
6 changes: 3 additions & 3 deletions src/dune_rules/dune_file.ml
Original file line number Diff line number Diff line change
Expand Up @@ -1381,7 +1381,7 @@ module Executables = struct

type t =
{ names : (Loc.t * string) list
; link_flags : Ordered_set_lang.Unexpanded.t
; link_flags : Link_flags.Spec.t
; link_deps : Dep_conf.t list
; modes : Loc.t Link_mode.Map.t
; optional : bool
Expand Down Expand Up @@ -1411,7 +1411,7 @@ module Executables = struct
field "link_executables" ~default:true
(Dune_lang.Syntax.deleted_in Stanza.syntax (1, 0) >>> bool)
and+ link_deps = field "link_deps" (repeat Dep_conf.decode) ~default:[]
and+ link_flags = Ordered_set_lang.Unexpanded.field "link_flags"
and+ link_flags = Link_flags.Spec.decode ~since:None
and+ modes =
field "modes" Link_mode.Map.decode
~default:(Link_mode.Map.default_for_exes ~version:dune_version)
Expand Down Expand Up @@ -1941,7 +1941,7 @@ module Tests = struct
String_with_vars.add_user_vars_to_decoding_env (Bindings.var_names deps)
(let* dune_version = Dune_lang.Syntax.get_exn Stanza.syntax in
let+ buildable = Buildable.decode Executable
and+ link_flags = Ordered_set_lang.Unexpanded.field "link_flags"
and+ link_flags = Link_flags.Spec.decode ~since:None
and+ names = names
and+ package = field_o "package" Stanza_common.Pkg.decode
and+ locks =
Expand Down
2 changes: 1 addition & 1 deletion src/dune_rules/dune_file.mli
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,7 @@ module Executables : sig

type t =
{ names : (Loc.t * string) list
; link_flags : Ordered_set_lang.Unexpanded.t
; link_flags : Link_flags.Spec.t
; link_deps : Dep_conf.t list
; modes : Loc.t Link_mode.Map.t
; optional : bool
Expand Down
16 changes: 7 additions & 9 deletions src/dune_rules/env_node.ml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ type t =
; local_binaries : File_binding.Expanded.t list Memo.Lazy.t
; ocaml_flags : Ocaml_flags.t Memo.Lazy.t
; foreign_flags : string list Action_builder.t Foreign_language.Dict.t
; link_flags : string list Action_builder.t Memo.Lazy.t
; link_flags : Link_flags.t Memo.Lazy.t
; external_env : Env.t Memo.Lazy.t
; bin_artifacts : Artifacts.Bin.t Memo.Lazy.t
; inline_tests : Dune_env.Stanza.Inline_tests.t Memo.Lazy.t
Expand All @@ -37,8 +37,7 @@ let ocaml_flags t = Memo.Lazy.force t.ocaml_flags

let foreign_flags t = t.foreign_flags

let link_flags t =
Memo.Lazy.force t.link_flags |> Action_builder.memo_build_join
let link_flags t = Memo.Lazy.force t.link_flags

let external_env t = Memo.Lazy.force t.external_env

Expand All @@ -62,7 +61,7 @@ let coq t = Memo.Lazy.force t.coq

let make ~dir ~inherit_from ~scope ~config_stanza ~profile ~expander
~expander_for_artifacts ~default_context_flags ~default_env
~default_bin_artifacts =
~default_bin_artifacts ~default_cxx_link_flags =
let open Memo.Build.O in
let config = Dune_env.Stanza.find config_stanza ~profile in
let inherited ~field ~root extend =
Expand Down Expand Up @@ -172,13 +171,12 @@ let make ~dir ~inherit_from ~scope ~config_stanza ~profile ~expander
Foreign_language.Dict.make ~c:(foreign_flags C) ~cxx:(foreign_flags Cxx)
in
let link_flags =
inherited
~field:(fun t -> Memo.Build.return (link_flags t))
~root:(Action_builder.return [])
(fun flags ->
let default_link_flags = Link_flags.default ~default_cxx_link_flags in
inherited ~field:link_flags ~root:default_link_flags (fun link_flags ->
let+ expander = Memo.Lazy.force expander in
let expander = Expander.set_dir expander ~dir in
Expander.expand_and_eval_set expander config.link_flags ~standard:flags)
Link_flags.make ~spec:config.link_flags ~default:link_flags
~eval:(Expander.expand_and_eval_set expander))
in
let menhir_flags =
inherited
Expand Down
3 changes: 2 additions & 1 deletion src/dune_rules/env_node.mli
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ val make :
-> default_context_flags:string list Action_builder.t Foreign_language.Dict.t
-> default_env:Env.t
-> default_bin_artifacts:Artifacts.Bin.t
-> default_cxx_link_flags:string list Action_builder.t
-> t

val scope : t -> Scope.t
Expand All @@ -43,7 +44,7 @@ val js_of_ocaml :

val foreign_flags : t -> string list Action_builder.t Foreign_language.Dict.t

val link_flags : t -> string list Action_builder.t
val link_flags : t -> Link_flags.t Memo.Build.t

val local_binaries : t -> File_binding.Expanded.t list Memo.Build.t

Expand Down
8 changes: 6 additions & 2 deletions src/dune_rules/exe_rules.ml
Original file line number Diff line number Diff line change
Expand Up @@ -180,8 +180,12 @@ let executables_rules ~sctx ~dir ~expander ~dir_contents ~scope ~compile_info
in
let open Action_builder.O in
let link_flags =
link_deps
>>> Super_context.link_flags sctx ~dir ~expander ~use_standard_cxx_flags ~flags:exes.link_flags
let* () = link_deps in
let* link_flags =
Action_builder.memo_build
(Super_context.link_flags sctx ~dir exes.link_flags)
in
Link_flags.get ~use_standard_cxx_flags link_flags
in
let+ flags = link_flags
and+ ctypes_cclib_flags =
Expand Down
61 changes: 61 additions & 0 deletions src/dune_rules/link_flags.ml
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
open! Dune_engine
open! Stdune
open Import
open Action_builder.O

(* flags are duplicated because we want to have two sets of default (:standard)
flags. [link_flags_cxx] will be used for executable with foreign_cxx when
[use_standard_cxx_flags] is true *)
type 'a t' =
{ link_flags : 'a
; link_flags_cxx : 'a
}

module Spec = struct
type t = Ordered_set_lang.Unexpanded.t t'

let standard =
let standard = Ordered_set_lang.Unexpanded.standard in
{ link_flags = standard; link_flags_cxx = standard }

let decode ~since =
let open Dune_lang.Decoder in
let check =
Option.map since ~f:(fun since ->
Dune_lang.Syntax.since Stanza.syntax since)
in
let+ flags = Ordered_set_lang.Unexpanded.field "link_flags" ?check in
{ link_flags = flags; link_flags_cxx = flags }

let equal { link_flags; link_flags_cxx } t =
Ordered_set_lang.Unexpanded.equal link_flags t.link_flags
&& Ordered_set_lang.Unexpanded.equal link_flags_cxx t.link_flags_cxx
end

type t = string list Action_builder.t t'

let default ~default_cxx_link_flags =
let link_flags_cxx =
let+ flags = default_cxx_link_flags in
List.concat_map flags ~f:(fun f -> [ "-cclib"; f ])
in
{ link_flags = Action_builder.return []; link_flags_cxx }

let make ~spec ~default ~eval =
let f name x standard = Action_builder.memoize name (eval x ~standard) in
{ link_flags = f "link flags" spec.link_flags default.link_flags
; link_flags_cxx =
f "link flags cxx" spec.link_flags_cxx default.link_flags_cxx
}

let get ~use_standard_cxx_flags (t : t) =
if use_standard_cxx_flags then
t.link_flags_cxx
else
t.link_flags

let dump t =
let+ link_flags = t.link_flags in
List.map
~f:Dune_lang.Encoder.(pair string (list string))
[ ("link_flags", link_flags) ]
32 changes: 32 additions & 0 deletions src/dune_rules/link_flags.mli
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
(** OCaml flags *)
open! Dune_engine

open! Stdune

type t

module Spec : sig
type t

val equal : t -> t -> bool

val decode :
since:Dune_lang.Syntax.Version.t option -> t Dune_lang.Decoder.fields_parser

val standard : t
end

val make :
spec:Spec.t
-> default:t
-> eval:
( Ordered_set_lang.Unexpanded.t
-> standard:string list Action_builder.t
-> string list Action_builder.t)
-> t

val default : default_cxx_link_flags:string list Action_builder.t -> t

val get : use_standard_cxx_flags:bool -> t -> string list Action_builder.t

val dump : t -> Dune_lang.t list Action_builder.t
34 changes: 12 additions & 22 deletions src/dune_rules/super_context.ml
Original file line number Diff line number Diff line change
Expand Up @@ -145,10 +145,11 @@ end = struct
in
extend_expander t ~dir ~expander_for_artifacts)
in
let default_cxx_link_flags = Cxx_flags.get_flags ~for_:Link t.context in
Env_node.make ~dir ~scope ~config_stanza ~inherit_from:(Some inherit_from)
~profile:t.context.profile ~expander ~expander_for_artifacts
~default_context_flags ~default_env:t.context_env
~default_bin_artifacts:t.bin_artifacts
~default_bin_artifacts:t.bin_artifacts ~default_cxx_link_flags

(* Here we jump through some hoops to construct [t] as well as create a
memoization table that has access to [t] and is used in [t.get_node].
Expand Down Expand Up @@ -402,22 +403,11 @@ let foreign_flags t ~dir ~expander ~flags ~language =
in
Action_builder.memoize (sprintf "%s flags" name) flags

let link_flags t ~dir ~expander ~use_standard_cxx_flags ~flags =
let env_tree = t.env_tree in
let default =
get_node env_tree ~dir >>| Env_node.link_flags |> Action_builder.memo_build_join
in
let default =
if use_standard_cxx_flags
then
let open Action_builder.O in
let+ default = default
and+ flags = Cxx_flags.get_flags ~for_:Link (context t) in
default @ List.concat_map flags ~f:(fun f -> [ "-cclib"; f ])
else default
in
Action_builder.memoize "link flags"
(Expander.expand_and_eval_set expander flags ~standard:default)
let link_flags t ~dir (spec : Link_flags.Spec.t) =
let* expander = Env_tree.expander t.env_tree ~dir in
let+ link_flags = get_node t.env_tree ~dir >>= Env_node.link_flags in
Link_flags.make ~spec ~default:link_flags
~eval:(Expander.expand_and_eval_set expander)

let menhir_flags t ~dir ~expander ~flags =
let t = t.env_tree in
Expand All @@ -439,7 +429,7 @@ let dump_env t ~dir =
let t = t.env_tree in
let ocaml_flags = get_node t ~dir >>= Env_node.ocaml_flags in
let foreign_flags = get_node t ~dir >>| Env_node.foreign_flags in
let link_flags = get_node t ~dir >>| Env_node.link_flags in
let link_flags = get_node t ~dir >>= Env_node.link_flags in
let menhir_flags = get_node t ~dir >>| Env_node.menhir_flags in
let coq_flags = get_node t ~dir >>= Env_node.coq in
let js_of_ocaml = get_node t ~dir >>= Env_node.js_of_ocaml in
Expand All @@ -455,9 +445,8 @@ let dump_env t ~dir =
~f:Dune_lang.Encoder.(pair string (list string))
[ ("c_flags", c_flags); ("cxx_flags", cxx_flags) ]
and+ link_flags_dump =
let+ flags = Action_builder.memo_build_join link_flags in
[ ("link_flags", flags) ]
|> List.map ~f:Dune_lang.Encoder.(pair string (list string))
let* link_flags = Action_builder.memo_build link_flags in
Link_flags.dump link_flags
and+ menhir_dump =
let+ flags = Action_builder.memo_build_join menhir_flags in
[ ("menhir_flags", flags) ]
Expand Down Expand Up @@ -723,11 +712,12 @@ let create ~(context : Context.t) ~host ~projects ~packages ~stanzas =
Code_error.raise
"[expander_for_artifacts] in [default_env] is undefined" [])
in
let default_cxx_link_flags = Cxx_flags.get_flags ~for_:Link context in
let expander = Memo.Lazy.of_val root_expander in
Env_node.make ~dir ~scope ~inherit_from ~config_stanza
~profile:context.profile ~expander ~expander_for_artifacts
~default_context_flags ~default_env:context_env
~default_bin_artifacts:artifacts.bin
~default_bin_artifacts:artifacts.bin ~default_cxx_link_flags
in
Memo.Build.return
(make ~config_stanza:context.env_nodes.context
Expand Down
7 changes: 1 addition & 6 deletions src/dune_rules/super_context.mli
Original file line number Diff line number Diff line change
Expand Up @@ -87,12 +87,7 @@ val foreign_flags :
-> string list Action_builder.t

val link_flags :
t
-> dir:Path.Build.t
-> expander:Expander.t
-> use_standard_cxx_flags:bool
-> flags:Ordered_set_lang.Unexpanded.t
-> string list Action_builder.t
t -> dir:Path.Build.t -> Link_flags.Spec.t -> Link_flags.t Memo.Build.t

val menhir_flags :
t
Expand Down
2 changes: 1 addition & 1 deletion test/blackbox-tests/test-cases/cxx-flags.t/dune
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,4 @@
(name main)
(libraries quad)
(foreign_stubs (language cxx) (names bazexe))
(modules main))
(modules main))
25 changes: 25 additions & 0 deletions test/blackbox-tests/test-cases/cxx-flags.t/run.t
Original file line number Diff line number Diff line change
Expand Up @@ -106,8 +106,33 @@ With use_standard_c_and_cxx_flags = true
> grep -ce "Main.cmx$GCC_LF_LIB)\|Main.cmx$Clang_LF_LIB)\|Main.cmx$Msvc_LF_LIB)"
1

$ dune clean

$ dune exec ./main.exe
2046
4096
Hello World Baz!
Hello World Bazexe!

$ [ -f _build/default/.dune/ccomp/ccomp ]


ccomp is not computed if not required
=====================================
$ dune clean

$ dune exec ./sub/main_no_stubs.exe
OK

$ [ -f _build/default/.dune/ccomp/ccomp ]
[1]


one can extend link flags in env
================================

$ OTHER=" --other-flag --yet-some-other-flag)"

$ dune rules sub/main.exe --profile some-profile | tr -s '\n' ' ' |
> grep -ce "Main.cmx$GCC_LF_LIB$OTHER\|Main.cmx$Clang_LF_LIB$OTHER\|Main.cmx$Msvc_LF_LIB$OTHER"
1
Loading

0 comments on commit 68f1b2a

Please sign in to comment.