-
Notifications
You must be signed in to change notification settings - Fork 412
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
Add support for -H compiler flag #10644
Changes from 5 commits
a4a6bf9
663ec11
42f1798
1bf8bf8
1893536
0c07a77
366ca51
d9df9e4
9fae1f7
3607a91
923a0bc
8e1757f
cdd08f7
c8f4f7f
6ef7f54
51d6e2f
83bb651
2812ddb
80a1c02
9d8c029
c11722d
f1882cc
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -3,36 +3,51 @@ open Import | |||||
module Includes = struct | ||||||
type t = Command.Args.without_targets Command.Args.t Lib_mode.Cm_kind.Map.t | ||||||
|
||||||
let make ~project ~opaque ~requires : _ Lib_mode.Cm_kind.Map.t = | ||||||
let make | ||||||
~project | ||||||
~opaque | ||||||
~direct_requires | ||||||
~(hidden_requires : Lib_flags.L.t Resolve.Memo.t) | ||||||
: _ Lib_mode.Cm_kind.Map.t | ||||||
= | ||||||
(* TODO : some of the requires can filtered out using [ocamldep] info *) | ||||||
let open Resolve.Memo.O in | ||||||
let iflags libs mode = Lib_flags.L.include_flags ~project libs mode in | ||||||
let iflags direct_libs hidden_libs mode = | ||||||
Lib_flags.L.include_flags ~project direct_libs hidden_libs mode | ||||||
in | ||||||
let make_includes_args ~mode groups = | ||||||
Command.Args.memo | ||||||
(Resolve.Memo.args | ||||||
(let+ libs = requires in | ||||||
(let+ direct_libs = direct_requires | ||||||
and+ hidden_libs = hidden_requires in | ||||||
Command.Args.S | ||||||
[ iflags libs mode; Hidden_deps (Lib_file_deps.deps libs ~groups) ])) | ||||||
[ iflags direct_libs hidden_libs mode | ||||||
; Hidden_deps | ||||||
(Lib_file_deps.deps (List.concat [ direct_libs; hidden_libs ]) ~groups) | ||||||
])) | ||||||
in | ||||||
let cmi_includes = make_includes_args ~mode:(Ocaml Byte) [ Ocaml Cmi ] in | ||||||
let cmx_includes = | ||||||
Command.Args.memo | ||||||
(Resolve.Memo.args | ||||||
(let+ libs = requires in | ||||||
(let+ direct_libs = direct_requires | ||||||
and+ hidden_libs = hidden_requires in | ||||||
Command.Args.S | ||||||
[ iflags libs (Ocaml Native) | ||||||
[ iflags direct_libs hidden_libs (Ocaml Native) | ||||||
; Hidden_deps | ||||||
(if opaque | ||||||
then | ||||||
List.map libs ~f:(fun lib -> | ||||||
( lib | ||||||
, if Lib.is_local lib | ||||||
then [ Lib_file_deps.Group.Ocaml Cmi ] | ||||||
else [ Ocaml Cmi; Ocaml Cmx ] )) | ||||||
List.map | ||||||
(List.concat [ direct_libs; hidden_libs ]) | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
~f:(fun lib -> | ||||||
( lib | ||||||
, if Lib.is_local lib | ||||||
then [ Lib_file_deps.Group.Ocaml Cmi ] | ||||||
else [ Ocaml Cmi; Ocaml Cmx ] )) | ||||||
|> Lib_file_deps.deps_with_exts | ||||||
else | ||||||
Lib_file_deps.deps | ||||||
libs | ||||||
(List.concat [ direct_libs; hidden_libs ]) | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @MA0010 this can be committed, right? |
||||||
~groups:[ Lib_file_deps.Group.Ocaml Cmi; Ocaml Cmx ]) | ||||||
])) | ||||||
in | ||||||
|
@@ -74,6 +89,7 @@ type t = | |||||
; modules : modules | ||||||
; flags : Ocaml_flags.t | ||||||
; requires_compile : Lib.t list Resolve.Memo.t | ||||||
; requires_hidden : Lib.t list Resolve.Memo.t | ||||||
; requires_link : Lib.t list Resolve.t Memo.Lazy.t | ||||||
; includes : Includes.t | ||||||
; preprocessing : Pp_spec.t | ||||||
|
@@ -99,6 +115,7 @@ let obj_dir t = t.obj_dir | |||||
let modules t = t.modules.modules | ||||||
let flags t = t.flags | ||||||
let requires_compile t = t.requires_compile | ||||||
let requires_hidden t = t.requires_hidden | ||||||
let requires_link t = Memo.Lazy.force t.requires_link | ||||||
let includes t = t.includes | ||||||
let preprocessing t = t.preprocessing | ||||||
|
@@ -139,12 +156,26 @@ let create | |||||
= | ||||||
let open Memo.O in | ||||||
let project = Scope.project scope in | ||||||
let requires_compile = | ||||||
let context = Super_context.context super_context in | ||||||
let sandbox = Sandbox_config.no_special_requirements in | ||||||
let* ocaml = Context.ocaml context in | ||||||
let direct_requires, hidden_requires = | ||||||
if Dune_project.implicit_transitive_deps project | ||||||
then Memo.Lazy.force requires_link | ||||||
else requires_compile | ||||||
then Memo.Lazy.force requires_link, Resolve.Memo.return [] | ||||||
else if Version.supports_hidden_includes ocaml.version | ||||||
&& Dune_project.dune_version project >= (3, 17) | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think this mode still needs to be guarded behind There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sorry, but I do not seem to have understood well your point. The new feature is invoked only when Thanks for the review. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah, that wasn't very clear at all. Let me explain the behavior I would like to achieve: When we're using When we're using When we're using The issue with the current behavior is that users do expect upgrading to 3.17 to be relatively easy. With this change, they will now need to look at all their transitive deps. While I agree that it's a good thing, it's too much of a breakage to introduce in a minor version bump. Therefore, I suggest that we guard this behind a feature flag. We already have a feature flag though |
||||||
then ( | ||||||
let requires_hidden = | ||||||
let open Resolve.Memo.O in | ||||||
let+ requires = requires_compile | ||||||
and+ requires_link = Memo.Lazy.force requires_link in | ||||||
let requires_table = Table.create (module Lib) 500 in | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||||||
let () = List.iter ~f:(fun lib -> Table.set requires_table lib ()) requires in | ||||||
List.filter requires_link ~f:(fun l -> not (Table.mem requires_table l)) | ||||||
in | ||||||
requires_compile, requires_hidden) | ||||||
else requires_compile, Resolve.Memo.return [] | ||||||
in | ||||||
let sandbox = Sandbox_config.no_special_requirements in | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is this change needed? |
||||||
let modes = | ||||||
let default = | ||||||
{ Lib_mode.Map.ocaml = Mode.Dict.make_both (Some Mode_conf.Kind.Inherited) | ||||||
|
@@ -153,8 +184,6 @@ let create | |||||
in | ||||||
Option.value ~default modes |> Lib_mode.Map.map ~f:Option.is_some | ||||||
in | ||||||
let context = Super_context.context super_context in | ||||||
let* ocaml = Context.ocaml context in | ||||||
let opaque = | ||||||
let profile = Context.profile context in | ||||||
eval_opaque ocaml profile opaque | ||||||
|
@@ -180,9 +209,10 @@ let create | |||||
; obj_dir | ||||||
; modules = { modules; dep_graphs } | ||||||
; flags | ||||||
; requires_compile | ||||||
; requires_compile = direct_requires | ||||||
; requires_hidden = hidden_requires | ||||||
; requires_link | ||||||
; includes = Includes.make ~project ~opaque ~requires:requires_compile | ||||||
; includes = Includes.make ~project ~opaque ~direct_requires ~hidden_requires | ||||||
; preprocessing | ||||||
; opaque | ||||||
; stdlib | ||||||
|
@@ -263,8 +293,16 @@ let for_module_generated_at_link_time cctx ~requires ~module_ = | |||||
their implementation must also be compiled with -opaque *) | ||||||
Ocaml.Version.supports_opaque_for_mli cctx.ocaml.version | ||||||
in | ||||||
let direct_requires = requires in | ||||||
let hidden_requires = Resolve.Memo.return [] in | ||||||
let modules = singleton_modules module_ in | ||||||
let includes = Includes.make ~project:(Scope.project cctx.scope) ~opaque ~requires in | ||||||
let includes = | ||||||
Includes.make | ||||||
~project:(Scope.project cctx.scope) | ||||||
~opaque | ||||||
~direct_requires | ||||||
~hidden_requires | ||||||
in | ||||||
{ cctx with | ||||||
opaque | ||||||
; flags = Ocaml_flags.empty | ||||||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -92,6 +92,13 @@ module L = struct | |
|> List.rev) | ||
;; | ||
|
||
let to_hflags dirs = | ||
Command.Args.S | ||
(Path.Set.fold dirs ~init:[] ~f:(fun dir acc -> | ||
Command.Args.Path dir :: A "-H" :: acc) | ||
|> List.rev) | ||
;; | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Let's share the code with |
||
let remove_stdlib dirs libs = | ||
match libs with | ||
| [] -> dirs | ||
|
@@ -155,8 +162,16 @@ module L = struct | |
remove_stdlib dirs ts | ||
;; | ||
|
||
let include_flags ?project ts mode = | ||
to_iflags (include_paths ?project ts { lib_mode = mode; melange_emit = false }) | ||
let include_flags ?project ts_direct ts_hidden mode = | ||
let hidden_includes = | ||
to_hflags | ||
(include_paths ?project ts_hidden { lib_mode = mode; melange_emit = false }) | ||
in | ||
let direct_includes = | ||
to_iflags | ||
(include_paths ?project ts_direct { lib_mode = mode; melange_emit = false }) | ||
in | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Let's share the code for the two definitions. |
||
Command.Args.S [ direct_includes; hidden_includes ] | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Isn't this re-ordering the include flags? e.g. if we have There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If I understand things correctly, I don't think anything is being re-ordered; instead some extra
Do you agree with this understanding @MA0010? |
||
;; | ||
|
||
let melange_emission_include_flags ?project ts = | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -24,7 +24,7 @@ module L : sig | |
|
||
val to_iflags : Path.Set.t -> _ Command.Args.t | ||
val include_paths : ?project:Dune_project.t -> t -> Lib_mode.t -> Path.Set.t | ||
val include_flags : ?project:Dune_project.t -> t -> Lib_mode.t -> _ Command.Args.t | ||
val include_flags : ?project:Dune_project.t -> t -> t -> Lib_mode.t -> _ Command.Args.t | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Since it takes 2 arguments of type |
||
val melange_emission_include_flags : ?project:Dune_project.t -> t -> _ Command.Args.t | ||
val c_include_flags : t -> Super_context.t -> _ Command.Args.t | ||
val toplevel_ld_paths : t -> Path.Set.t | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -32,11 +32,9 @@ let cctx_rules cctx = | |
|
||
The implicit transitive libs correspond to the set: | ||
(requires_link \ req_compile) *) | ||
let* req_link = Compilation_context.requires_link cctx in | ||
let+ req_compile = Compilation_context.requires_compile cctx in | ||
List.filter req_link ~f:(fun l -> not (List.exists req_compile ~f:(Lib.equal l))) | ||
Compilation_context.requires_hidden cctx | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This doesn't seem quite right. For new versions of OCaml (>= 5.2) and version of the Dune language >= 3.17, Dune will pass There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @voodoos sounds OK? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, that's completely right. If Dune >= 3.17 there is no more additional flags to pass to the indexer. (Note that indexing is not available prior to OCaml 5.2, so there is no need to check that here.) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks for the confirmation! So only the check for OCaml lang version < 3.17 is needed. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done! There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks, the current version looks good to me |
||
in | ||
Lib_flags.L.include_flags non_compile_libs (Lib_mode.Ocaml Byte) | ||
Lib_flags.L.include_flags [] non_compile_libs (Lib_mode.Ocaml Byte) | ||
in | ||
(* Indexing depends (recursively) on [required_compile] libs: | ||
- These libs's cmt files should be built before indexing starts | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
let x = 5 | ||
|
||
let y = Foo.v | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. the newline at eof in this test (and others) need fixing |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
(library | ||
(name foo) | ||
(modules foo)) | ||
|
||
(library | ||
(name bar) | ||
(modules bar) | ||
(libraries foo)) | ||
|
||
(executable | ||
(name run) | ||
(modules run) | ||
(libraries bar)) | ||
|
||
(executable | ||
(name runf) | ||
(modules runf) | ||
(libraries bar)) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
let v = 9 | ||
|
||
let w = 4 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
let _ = Bar.y |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
Should include Foo with -H: | ||
|
||
$ getincludes () { | ||
> dune build --verbose ./run.exe 2>&1 | grep run.ml | grep -E -o "\-$1\s(.foo)\S*" | sed s/\-$1//g | tr -d '[:space:]' | ||
> } | ||
|
||
$ supports_H=$(if ocamlc -H x --help >/dev/null 2>&1; then echo true; else echo false; fi) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I would recommend doing that in 2 tests:
And then you can use "normal" cram tests, which would consist in just running There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hello, thanks for the review. I have tried to add the Do you have any suggestions on how one would use There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. sure! you can have a look at this for example: https://github.com/ocaml/dune/blob/3.16.0/test/blackbox-tests/test-cases/dune#L103-L107 |
||
$ fooincludes='.foo.objs/byte.foo.objs/byte.foo.objs/native' | ||
$ cat >dune-project <<EOF | ||
> (lang dune 3.17) | ||
> (implicit_transitive_deps true) | ||
> EOF | ||
|
||
$ if $supports_H; then [ "$(getincludes I)" = $fooincludes ]; fi | ||
$ if ! $supports_H; then [ "$(getincludes I)" = $fooincludes ]; fi | ||
|
||
$ cat >dune-project <<EOF | ||
> (lang dune 3.17) | ||
> (implicit_transitive_deps false) | ||
> EOF | ||
|
||
$ if $supports_H; then [ "$(getincludes H)" = $fooincludes ]; fi | ||
$ if ! $supports_H; then [ "$(getincludes I)" = '' ]; fi | ||
|
||
|
||
Test transitive deps can not be directly accessed, both for compiler versions supporting -H or not: | ||
$ cat >dune-project <<EOF | ||
> (lang dune 3.17) | ||
> (implicit_transitive_deps false) | ||
> EOF | ||
|
||
$ dune build ./runf.exe 2>&1 | grep -v ocamlc | ||
File "runf.ml", line 1, characters 16-21: | ||
1 | let a = Bar.y + Foo.v | ||
^^^^^ | ||
Error: Unbound module Foo |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
let a = Bar.y + Foo.v |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
(executable | ||
(name run) | ||
(libraries tyxml)) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
(lang dune 3.17) | ||
(implicit_transitive_deps false) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
open Tyxml.Html | ||
let _ = p [ a [ txt "a" ] ] |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
Test if the issue #274 is solved: the tyxml.functor is included with -H flag in | ||
ITD = false case, and thus no type abstraction happens when it is used. | ||
|
||
$ ocamlc -H x --help > /dev/null | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. same here, you can guard the test behind |
||
$ if [ $? = 0 ]; then dune build fi |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.