Skip to content

Commit

Permalink
Allow to configure link_flags in env
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 e8d7f22 commit e741f6b
Show file tree
Hide file tree
Showing 13 changed files with 93 additions and 8 deletions.
2 changes: 2 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -298,6 +298,8 @@ Unreleased
- Delete old `promote-into`, `promote-until-clean` and `promote-until-clean-into`
syntax (#5091, Andrey Mokhov).

- Add link_flags in the env stanza (#5215)

2.9.2 (unreleased)
------------------

Expand Down
3 changes: 3 additions & 0 deletions doc/dune-files.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1540,6 +1540,9 @@ Fields supported in ``<settings>`` are:

- any OCaml flags field. See :ref:`ocaml-flags` for more details.

- ``(link_flags <flags>)`` to specify flags to ocaml when linking an
executable. See :ref:`executables stanza <shared-exe-fields>`.

- ``(c_flags <flags>)`` and ``(cxx_flags <flags>)``
to specify compilation flags for C and C++ stubs, respectively.
See `library`_ for more details.
Expand Down
13 changes: 13 additions & 0 deletions src/dune_rules/dune_env.ml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,13 @@ 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 @@ -74,6 +81,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
; env_vars : Env.t
; binaries : File_binding.Unexpanded.t list
; inline_tests : Inline_tests.t option
Expand All @@ -87,6 +95,7 @@ module Stanza = struct
let equal_config
{ flags
; foreign_flags
; link_flags
; env_vars
; binaries
; inline_tests
Expand All @@ -99,6 +108,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
&& 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 @@ -114,6 +124,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
; env_vars = Env.empty
; binaries = []
; inline_tests = None
Expand Down Expand Up @@ -181,6 +192,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+ env_vars = env_vars_field
and+ binaries =
field ~default:[] "binaries"
Expand All @@ -194,6 +206,7 @@ module Stanza = struct
and+ format_config = Format_config.field ~since:(2, 8) in
{ flags
; foreign_flags
; link_flags
; env_vars
; binaries
; inline_tests
Expand Down
1 change: 1 addition & 0 deletions src/dune_rules/dune_env.mli
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +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
; env_vars : Env.t
; binaries : File_binding.Unexpanded.t list
; inline_tests : Inline_tests.t option
Expand Down
14 changes: 14 additions & 0 deletions src/dune_rules/env_node.ml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +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
; 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 @@ -36,6 +37,9 @@ 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 external_env t = Memo.Lazy.force t.external_env

let bin_artifacts t = Memo.Lazy.force t.bin_artifacts
Expand Down Expand Up @@ -167,6 +171,15 @@ let make ~dir ~inherit_from ~scope ~config_stanza ~profile ~expander
let foreign_flags =
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+ 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)
in
let menhir_flags =
inherited
~field:(fun t -> Memo.Build.return (menhir_flags t))
Expand Down Expand Up @@ -208,6 +221,7 @@ let make ~dir ~inherit_from ~scope ~config_stanza ~profile ~expander
{ scope
; ocaml_flags
; foreign_flags
; link_flags
; external_env
; bin_artifacts
; local_binaries
Expand Down
2 changes: 2 additions & 0 deletions src/dune_rules/env_node.mli
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ 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 local_binaries : t -> File_binding.Expanded.t list Memo.Build.t

val bin_artifacts : t -> Artifacts.Bin.t Memo.Build.t
Expand Down
11 changes: 4 additions & 7 deletions src/dune_rules/exe_rules.ml
Original file line number Diff line number Diff line change
Expand Up @@ -173,18 +173,15 @@ let executables_rules ~sctx ~dir ~expander ~dir_contents ~scope ~compile_info
files directly to improve perf. *)
let link_deps, sandbox = Dep_conf_eval.unnamed ~expander exes.link_deps in
let link_args =
let standard =
let use_standard_cxx_flags =
match Dune_project.use_standard_c_and_cxx_flags project with
| Some true when Buildable.has_foreign_cxx exes.buildable ->
let open Action_builder.O in
let+ flags = Cxx_flags.get_flags ~for_:Link ctx in
List.concat_map flags ~f:(fun f -> [ "-cclib"; f ])
| _ -> Action_builder.return []
| Some true -> Buildable.has_foreign_cxx exes.buildable
| _ -> false
in
let open Action_builder.O in
let link_flags =
link_deps
>>> Expander.expand_and_eval_set expander exes.link_flags ~standard
>>> Super_context.link_flags sctx ~dir ~expander ~use_standard_cxx_flags ~flags:exes.link_flags
in
let+ flags = link_flags
and+ ctypes_cclib_flags =
Expand Down
25 changes: 24 additions & 1 deletion src/dune_rules/super_context.ml
Original file line number Diff line number Diff line change
Expand Up @@ -402,6 +402,23 @@ 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 menhir_flags t ~dir ~expander ~flags =
let t = t.env_tree in
let default =
Expand All @@ -422,6 +439,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 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 @@ -436,6 +454,10 @@ let dump_env t ~dir =
List.map
~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))
and+ menhir_dump =
let+ flags = Action_builder.memo_build_join menhir_flags in
[ ("menhir_flags", flags) ]
Expand All @@ -448,7 +470,8 @@ let dump_env t ~dir =
let* jsoo = Action_builder.memo_build js_of_ocaml in
Js_of_ocaml.Flags.dump jsoo.flags
in
List.concat [ o_dump; c_dump; menhir_dump; coq_dump; jsoo_dump ]
List.concat
[ o_dump; c_dump; link_flags_dump; menhir_dump; coq_dump; jsoo_dump ]

let resolve_program t ~dir ?hint ~loc bin =
let t = t.env_tree in
Expand Down
8 changes: 8 additions & 0 deletions src/dune_rules/super_context.mli
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,14 @@ val foreign_flags :
-> language:Foreign_language.t
-> 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

val menhir_flags :
t
-> dir:Path.Build.t
Expand Down
1 change: 1 addition & 0 deletions test/blackbox-tests/test-cases/env/env-link_flags.t/a.ml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
let () = print_endline "'A' was linked"
4 changes: 4 additions & 0 deletions test/blackbox-tests/test-cases/env/env-link_flags.t/main.ml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
let () = print_endline "Starting main"

let _ = `no_reference_to_A

16 changes: 16 additions & 0 deletions test/blackbox-tests/test-cases/env/env-link_flags.t/run.t
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
$ cat >> dune-project <<EOF
> (lang dune 3.0)
> EOF

$ cat >> dune << EOF
> (library (name a)(modules a))
> (executable (name main) (modules main) (libraries a))
> (env (linkall-profile (link_flags (:standard -linkall))))
> EOF

$ dune exec ./main.exe
Starting main

$ dune exec ./main.exe --profile linkall-profile
'A' was linked
Starting main
1 change: 1 addition & 0 deletions test/blackbox-tests/test-cases/workspaces.t/run.t
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ Workspaces also allow you to set the env for a context:
(ocamlopt_flags (-g))
(c_flags ())
(cxx_flags ())
(link_flags ())
(menhir_flags ())
(coq_flags (-q))
(js_of_ocaml_flags ())
Expand Down

0 comments on commit e741f6b

Please sign in to comment.