-
Notifications
You must be signed in to change notification settings - Fork 413
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
Opaque Mode #1079
Opaque Mode #1079
Conversation
What is the rationale for adding an |
If the plan is to add the option to env, then I think it makes sense from a consistency point of view to add the option to individual stanzas. I agree with your point from the other thread that anything that can be set in a stanza shouldn't necessarily exist in env. But I think the converse should always hold. |
Alright, I don't have a strong opinion on this question. I'm happy to go ahead with this. For the name, it feels like it should be something like BTW, it feels unnecessarily painful to add such an option through the |
Yeah, that would be fine. I'll try doing this separately first. |
For the name, it feels like it should be something like
`(compilation_mode <fast_exe|fast_build>)`. That should be intuitive.
Just my 2 cents on terminology: `(compilation_mode
<fast_exe|fast_build>)` seems too general a name for such a specific
compiler flag. The fast_exe vs fast_build distinction is basically the
same as the dev vs release profiles.
Also, perhaps I'm odd, but I generally start with the compiler man page
to find the options I need, and then hunt through the build system docs
to figure out how to get it to pass them. From that perspective, this
proposal isn't a very discoverable name.
|
Well, we might actually put more options under this umbrella name later. In which case, we'd of course need a proper This seems like one of those situations where we can't really win with the names. We can have a name that reflects what is the source in the compiler ( |
Note that yet another possibility would be to analyze the compilation flags and act accordingly. For instance if we see If we expose the functionality at the dune level via a library field, it seems to me that we should abstract away from the low-level details. |
src/inline_tests.ml
Outdated
@@ -233,6 +233,7 @@ include Sub_system.Register_end_point( | |||
~scope | |||
~dir:inline_test_dir | |||
~modules | |||
~opaque:true |
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.
Not entirely sure that this is correct, but it seems like we'd want the tests to compiler as fast as possible. @diml?
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.
It's not going to make much difference as this context is only used to build the test runner which contains the entry point and so is not used by anything else. Given that we should stick to the default, i.e. opaque=false
.
I'd prefer not to do this as I agree that this isn't as straight forward as it may seem initially. We'd have to do the same trade off that we'd do in menhir and resort to only statically provided options. Im menhir, that seems inevitable, but let's try to avoid this necessary evil here. It would also have the small disadvantage of not being able to disable as easily anymore. Removing something from a set of flags can't be done reliably, and the user would have to set the flags from scratch.
As I mentioned before, this would also give us the freedom to add additional meaning to this option in the future. |
If we don't want to analyze the arguments too hard, maybe we do the following:
This approach can also be used if we want to provide a DSL to express warning arguments, for example ( |
What's the use case for the user ever using -opaque without making use of the better build rules? If there's a valid use case for this then I agree, otherwise if anything we should just error if the user tries to pass this manually. |
@@ -197,6 +197,8 @@ module Libs : sig | |||
all the files with extension [ext] of libraries [libs]. *) | |||
val file_deps : t -> Lib.L.t -> ext:string -> Path.t list | |||
|
|||
val file_deps_with_exts : t -> (Lib.t * string) list -> Path.t list |
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.
A suggestion for a better name/implementation would be appreciated. I could also implement file_deps
on top of this function, but don't see the point of making the code slower for no reason.
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.
The name is not too much of a problem, but I agree that duplicating is not ideal.
Fortunately, you can extract the body of List.map
into private function val file_deps_for_lib : Lib.t -> ext:string -> Build_system.t -> Path.t
. That way, the two functions file_deps
& file_deps_with_exts
become one-liners.
FTR, since dependencies can be specified dynamically, we could take into account |
When we calculate the includes, don't we have to know whether the library is opaque statically? |
I believe the include directories won't change since we still need them for the cmi files |
Okay, I see. Btw, I referred to |
Another issue with inferring this property from |
@jberdine @emillon @diml I honestly have a hard time seeing the need for a fine grained customization option for this flag btw. I see 2 use cases:
In summary, I think the benefit of this option is miniscule. |
I agree. That's why I was surprised it ended up in library stanzas. |
Yeah, although I think it's just as marginally useful in the env stanza. My arguments for adding it to the env stanza are purely from a consistency stand point with env. But now that I'm thinking that this option is barely useful on any level customization, we should wait until users demand it before adding it. Also note that it's no longer in the Library stanza. We could remove this option from the Lib.t, since we can simply infer what it's going to be based on the profile and on whether the library is internal/external. Do you think we should make this simplification? |
I think so yes. It seems better to me if the implementation is close to the high-level design |
Okay, I will remove it from |
I agree. The knob we have for fast compilation vs fast binary is the profile so it makes sense to support it only there. |
Signed-off-by: Rudi Grinberg <rudi.grinberg@gmail.com>
Do you have some benchmarks to see if it's actually faster? |
@@ -197,6 +197,8 @@ module Libs : sig | |||
all the files with extension [ext] of libraries [libs]. *) | |||
val file_deps : t -> Lib.L.t -> ext:string -> Path.t list | |||
|
|||
val file_deps_with_exts : t -> (Lib.t * string) list -> Path.t list |
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.
The name is not too much of a problem, but I agree that duplicating is not ideal.
Fortunately, you can extract the body of List.map
into private function val file_deps_for_lib : Lib.t -> ext:string -> Build_system.t -> Path.t
. That way, the two functions file_deps
& file_deps_with_exts
become one-liners.
src/module_compilation.ml
Outdated
@@ -58,13 +58,14 @@ let build_cm cctx ?sandbox ?(dynlink=true) ~dep_graphs ~cm_kind (m : Module.t) = | |||
| Cmi | Cmo -> other_targets | |||
in | |||
let dep_graph = Ml_kind.Dict.get dep_graphs ml_kind in | |||
let opaque = CC.opaque cctx && ctx.version >= (4, 03, 0) in |
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.
I think that this kind of test should be done in Context
, like Context.supports_opaque_option
. There's a similar code path for keep_locs
, if you agree with that I can extract the relevant functions in a separate PR.
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.
Yeah, feel free to do it post this PR. I don't have a strong preference where the check should be done but I suppose that diml should have a loc b/c I just kept things as is.
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.
Actually, this made me realize that we should turn off the option everywhere altogether if the OCaml version is below 4.03.0. This is not the only place we should be doing this.
Yup. I've noticed an a speed up on on clean builds for cohttp-lwt-unix for example. It's a bit hard to test apples to apples here b/c what we want is to just build a big binary, since that should reduce building non native dependencies. Let me try and setup another little test. By the way, the certainty in the speed up comes more from observing the rules themselves. There are far less inter cmx dependencies which should result in more paralallization and less recompilation. |
Subsequently, use it as a flag when calculating rules and includes Signed-off-by: Rudi Grinberg <rudi.grinberg@gmail.com>
Signed-off-by: Rudi Grinberg <rudi.grinberg@gmail.com>
Only use Compilation_context.t for controlling this Signed-off-by: Rudi Grinberg <rudi.grinberg@gmail.com>
Signed-off-by: Rudi Grinberg <rudi.grinberg@gmail.com>
Signed-off-by: Rudi Grinberg <rudi.grinberg@gmail.com>
@emillon have another look |
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.
Great, thanks. Some figures would be nice but as you say it's hard to imagine how it could make things worse.
Oh and don't forget to update the changelog! |
Here are some numbers:
The second run is with |
Signed-off-by: Rudi Grinberg <rudi.grinberg@gmail.com>
CHANGES: - Fix lookup of command line specified files when `--root` is given. Previously, passing in `--root` in conjunction with `--workspace` or `--config` would not work correctly (ocaml/dune#997, @rgrinberg) - Add support for customizing env nodes in workspace files. The `env` stanza is now allowed in toplevel position in the workspace file, or for individual contexts. This feature requires `(dune lang 1.1)` (ocaml/dune#1038, @rgrinberg) - Add `enabled_if` field for aliases and tests. This field controls whether the test will be ran using a boolean expression language. (ocaml/dune#819, @rgrinberg) - Make `name`, `names` fields optional when a `public_name`, `public_names` field is provided. (ocaml/dune#1041, fix ocaml/dune#1000, @rgrinberg) - Interpret `X` in `--libdir X` as relative to `PREFIX` when `X` is relative (ocaml/dune#1072, fix ocaml/dune#1070, @diml) - Add support for multi directory libraries by writing `(include_subdirs unqualified)` (ocaml/dune#1034, @diml) - Add `(staged_pps ...)` to support staged ppx rewriters such as ones using the OCaml typer like `ppx_import` (ocaml/dune#1080, fix ocaml/dune#193, @diml) - Use `-opaque` in the `dev` profile. This option trades off binary quality for compilation speed when compiling .cmx files. (ocaml/dune#1079, fix ocaml/dune#1058, @rgrinberg) - Fix placeholders in `dune subst` documentation (ocaml/dune#1090, @emillon, thanks @trefis for the bug report) - Add locations to errors when a missing binary in PATH comes from a dune file (ocaml/dune#1096, fixes ocaml/dune#1095, @rgrinberg)
Implement #1058
For now, this is just a cleaned up version of my WIP. What remains is:
Implement better user customization. Env & Stanza level. I'm hoping that resolving [PROPOSAL] Env Defaults #1073 first will address this.
Cleaning up some duplication. I have a few hard coded
profile = "dev"
in some places for example.Choosing good names. I know that @diml has suggested
cross_module_inlining
, but IMHO the effect that this has on compilation speed isn't all that intuitive for users.Update the documentation