-
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
Adds support for findlib.dynload
#1172
Conversation
For simplicity I didn't try to add these features:
|
e8cfc43
to
2e2fe48
Compare
src/exe.ml
Outdated
in | ||
let basename = Format.asprintf "%s_findlib_initl_%a" name Mode.pp mode in | ||
let ml = Path.relative dir (basename ^ ".ml") in | ||
let mli = Path.relative dir (basename ^ ".mli") 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.
In general we try to put such generated modules outside of the source directory. Could you put it in the object directory instead? This is to avoid it being included in (glob_files *.ml)
.
Additionally, we don't generate a mli for other such generated modules (utop, inline tests, ...) so for consistency we shouldn't do it here either.
src/exe.ml
Outdated
let mli = Path.relative dir (basename ^ ".mli") in | ||
SC.add_rule sctx (Build.write_file ml s); | ||
SC.add_rule sctx (Build.write_file mli ""); | ||
let impl = Module.File.make Module.Syntax.OCaml ml 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.
We rely a lot on type-based disambiguation, you can drop the Module.Syntax.
here
src/exe.ml
Outdated
@@ -138,6 +143,72 @@ let link_exe | |||
Build.dyn_paths (Build.arr (fun (modules, _) -> | |||
artifacts modules ~ext:ctx.ext_obj)) | |||
in | |||
let link_flags_for_requires = | |||
Result.map requires ~f:(fun libs -> |
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.
Could you move this code to its own module? It's looks big enough and self-contained, and in the future I hope that we'll also support a generic method for link-time code generation (#594). So for instance you can move it to Link_time_code_gen
.
src/exe.ml
Outdated
let preds = Variant.Set.add preds (Mode.variant mode) in | ||
let s = | ||
Format.asprintf "%a@\nFindlib.record_package_predicates %a;;@." | ||
(Fmt.list ~pp_sep:Fmt.nl (fun fmt lib -> Format.fprintf fmt "Findlib.record_package Findlib.Record_core %S;;" (Lib.name lib))) |
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.
This line looks a bit long
Thanks, could you also add something in the manual about this? |
I think all the points have been fixed. Remain the documentation that I think I will put in the advanced section. For the question of
Currently the branch remove Another solution would be to force |
src/exe.ml
Outdated
let l = findlib_dynload ~name ~mode cctx l in | ||
let arg_spec = | ||
List.map l.libs_or_module ~f:(function | ||
| Libs l -> Lib.L.link_flags l ~mode ~stdlib_dir:ctx.stdlib_dir |
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.
link_flags
does some sharing of flags, so it doesn't seem right to call it multiple time. It should probably take the lib_or_module list
type directly.
src/link_time_code_gen.mli
Outdated
} | ||
|
||
|
||
val create: ?flags:Ocaml_flags.t -> Lib.L.t -> t |
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 we can do everything in one step. From the outside of this module, findlib.dynload
is basically just an implementation detail.
BTW, for multi-line function signatures, we use the following style in the code base:
val foo
: x
-> y
-> z
src/link_time_code_gen.mli
Outdated
(** {1 Handle link time code generation} *) | ||
|
||
type libs_or_module = | ||
| Libs of Lib.L.t |
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 would seem more natural to me to use Lib of Lib.t
BTW, the code looked simpler to me when we were doing everything in one step, i.e. without going through the |
The type Could you take a look at the documentation? Do you think the laïus about naming convention is interesting? |
@diml Why Module.t doesn't contains |
@bobot I've also considered adding obj_dir directly to the modules themselves as part of implementing private modules. I think this would be pretty useful. |
@rgrinberg I will not try it in this MR because in some place All the remarks of @diml except the renaming of What is the downside of always linking with |
doc/advanced-topics.rst
Outdated
=========================== | ||
|
||
Dune supports the ``findlib.dynload`` package that allows to dynamically | ||
load packages and their dependencies (using OCaml Dynlink modules). |
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.
s/modules/module/
Patch looks good. Giving an example in the documentation seems good as well. It might be worth adding a pointer to the documentation of findlib and in particular the dynload part. |
Note that we don't always link with threads, only when there is a dependency on it. What dune does is set the findlib predicates so that when a library has a threaded and non-threaded implementation, the threaded one is always selected. This was done this way for historical reasons. When we have library variants, we can arrange things so that it is possible to select the non-threaded version. Personally, I don't think it's worth writing two implementations, especially as we are planning to have OCaml support multicore one day. |
We should always link with thread when
It will also simplify the question about the predicate to use. I'm going to do the modification, but should I just make it an error to not use thread with |
9fd5d6e
to
2cb4dea
Compare
Now thread is required explicitly when |
This is not specific to threads though, it's only because OCaml doesn't build and install threads.cmxs, right? |
Oh perhaps, yes indeed 😭 I though threads was special because of the runtime, but it seems it just needs to register an hook. So if the compiler installs the cmxs, it should work while keeping all the predicates. So I can remove the requirement for the thread library in this PR, and we add to the compiler and previous version in opam the installation of the cmxs ? The META for the standard library are in ocamlfind, which would need an update. 👨🏭 |
Yep, that seems better. Findlib could also detect this case and report an error. |
BTW, the rest of the PR looks good, I'm happy to merge it if you remove the check for
I have been thinking that we should just move the META files to the compiler distribution. That would simplify things |
9a0b866
to
b563399
Compare
which allows to easily dynlink packages and their dependencies. Dune is needed for putting in the binary the list of package statically linked. Signed-off-by: François Bobot <francois.bobot@cea.fr>
It is removed, rebased and squashed. |
Thanks! |
CHANGES: - Ignore stderr output when trying to find out the number of jobs available (ocaml/dune#1118, fix ocaml/dune#1116, @diml) - Fix error message when the source directory of `copy_files` does not exist. (ocaml/dune#1120, fix ocaml/dune#1099, @emillon) - Highlight error locations in error messages (ocaml/dune#1121, @emillon) - Display actual stanza when package is ambiguous (ocaml/dune#1126, fix ocaml/dune#1123, @emillon) - Add `dune unstable-fmt` to format `dune` files. The interface and syntax are still subject to change, so use with caution. (ocaml/dune#1130, fix ocaml/dune#940, @emillon) - Improve error message for `dune utop` without a library name (ocaml/dune#1154, fix ocaml/dune#1149, @emillon) - Fix parsing `ocamllex` stanza in jbuild files (ocaml/dune#1150, @rgrinberg) - Highlight multi-line errors (ocaml/dune#1131, @anuragsoni) - Do no try to generate shared libraries when this is not supported by the OS (ocaml/dune#1165, fix ocaml/dune#1051, @diml) - Fix `Flags.write_{sexp,lines}` in configurator by avoiding the use of `Stdune.Path` (ocaml/dune#1175, fix ocaml/dune#1161, @rgrinberg) - Add support for `findlib.dynload`: when linking an executable using `findlib.dynload`, automatically record linked in libraries and findlib predicates (ocaml/dune#1172, @bobot) - Add support for promoting a selected list of files (ocaml/dune#1192, @diml) - Add an emacs mode providing helpers to promote correction files (ocaml/dune#1192, @diml) - Improve message suggesting to remove parentheses (ocaml/dune#1196, fix ocaml/dune#1173, @emillon) - Add `(wrapped (transition "..message.."))` as an option that will generate wrapped modules but keep unwrapped modules with a deprecation message to preserve compatibility. (ocaml/dune#1188, fix ocaml/dune#985, @rgrinberg) - Fix the flags passed to the ppx rewriter when using `staged_pps` (ocaml/dune#1218, @diml) - Add `(env var)` to add a dependency to an environment variable. (ocaml/dune#1186, @emillon) - Add a simple version of a polling mode: `dune build -w` keeps running and restarts the build when something change on the filesystem (ocaml/dune#1140, @kodek16) - Cleanup the way we detect the library search path. We no longer call `opam config var lib` in the default build context (ocaml/dune#1226, @diml) - Make test stanzas honor the -p flag. (ocaml/dune#1236, fix ocaml/dune#1231, @emillon) - Test stanzas take an optional (action) field to customize how they run (ocaml/dune#1248, ocaml/dune#1195, @emillon) - Add support for private modules via the `private_modules` field (ocaml/dune#1241, fix ocaml/dune#427, @rgrinberg) - Add support for passing arguments to the OCaml compiler via a response file when the list of arguments is too long (ocaml/dune#1256, @diml) - Do not print diffs by default when running inside dune (ocaml/dune#1260, @diml) - Interpret `$ dune build dir` as building the default alias in `dir`. (ocaml/dune#1259, @rgrinberg) - Make the `dynlink` library available without findlib installed (ocaml/dune#1270, fix ocaml/dune#1264, @rgrinberg)
It allows to easily dynlink packages and their dependencies. Dune is needed for specifying in the binary the list of packages statically linked.