diff --git a/CHANGES.md b/CHANGES.md index 141eba7431a..d549b333efb 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -75,6 +75,9 @@ next * Allow setting environment variables in `findlib.conf` for cross compilation contexts. (#733, @rgrinberg) +- Add a `link_deps` field to executables, to specify link-time dependencies + like version scripts. (#879, fix #852, @emillon) + 1.0+beta20 (10/04/2018) ----------------------- diff --git a/doc/jbuild.rst b/doc/jbuild.rst index 1da079f7195..7506d4972eb 100644 --- a/doc/jbuild.rst +++ b/doc/jbuild.rst @@ -248,6 +248,10 @@ Executables can also be linked as object or shared object files. See - ``(link_flags )`` specifies additional flags to pass to the linker. This field supports ``(:include ...)`` forms +- ``(link_deps ())`` specifies the dependencies used only by the + linker, for example when using a version script. See the `Dependency + specification`_ section for more details. + - ``(modules )`` specifies which modules in the current directory Jbuilder should consider when building this executable. Modules not listed here will be ignored and cannot be used inside the executable described by diff --git a/src/gen_rules.ml b/src/gen_rules.ml index 8806b8853ef..ea02f97b523 100644 --- a/src/gen_rules.ml +++ b/src/gen_rules.ml @@ -857,7 +857,11 @@ module Gen(P : Install_rules.Params) = struct in let flags = SC.ocaml_flags sctx ~scope ~dir exes.buildable in + let link_deps = + SC.Deps.interpret sctx ~scope ~dir exes.link_deps + in let link_flags = + link_deps >>^ ignore >>> SC.expand_and_eval_set sctx exes.link_flags ~scope ~dir diff --git a/src/jbuild.ml b/src/jbuild.ml index 88571ccbd5f..4ca451fbe60 100644 --- a/src/jbuild.ml +++ b/src/jbuild.ml @@ -874,6 +874,7 @@ module Executables = struct type t = { names : (Loc.t * string) list ; link_flags : Ordered_set_lang.Unexpanded.t + ; link_deps : Dep_conf.t list ; modes : Link_mode.Set.t ; buildable : Buildable.t } @@ -887,6 +888,7 @@ module Executables = struct field "link_executables" bool ~default:true >>= fun _ -> return ()) >>= fun () -> + field "link_deps" (list Dep_conf.t) ~default:[] >>= fun link_deps -> field_oslu "link_flags" >>= fun link_flags -> field "modes" Link_mode.Set.t ~default:Link_mode.Set.default >>= fun modes -> @@ -902,6 +904,7 @@ module Executables = struct let t = { names ; link_flags + ; link_deps ; modes ; buildable } diff --git a/src/jbuild.mli b/src/jbuild.mli index 1e74bd3b124..7adf0077d24 100644 --- a/src/jbuild.mli +++ b/src/jbuild.mli @@ -256,10 +256,11 @@ module Executables : sig end type t = - { names : (Loc.t * string) list - ; link_flags : Ordered_set_lang.Unexpanded.t - ; modes : Link_mode.Set.t - ; buildable : Buildable.t + { names : (Loc.t * string) list + ; link_flags : Ordered_set_lang.Unexpanded.t + ; link_deps : Dep_conf.t list + ; modes : Link_mode.Set.t + ; buildable : Buildable.t } end diff --git a/test/blackbox-tests/dune.inc b/test/blackbox-tests/dune.inc index d40afb2c9e3..5641482175e 100644 --- a/test/blackbox-tests/dune.inc +++ b/test/blackbox-tests/dune.inc @@ -330,6 +330,14 @@ test-cases/lib-available (progn (run ${exe:cram.exe} -test run.t) (diff? run.t run.t.corrected)))))) +(alias + ((name link-deps) + (deps ((package dune) (files_recursively_in test-cases/link-deps))) + (action + (chdir + test-cases/link-deps + (progn (run ${exe:cram.exe} -test run.t) (diff? run.t run.t.corrected)))))) + (alias ((name loop) (deps ((package dune) (files_recursively_in test-cases/loop))) @@ -592,6 +600,7 @@ (alias installable-dup-private-libs) (alias intf-only) (alias lib-available) + (alias link-deps) (alias loop) (alias menhir) (alias merlin-tests) @@ -656,6 +665,7 @@ (alias installable-dup-private-libs) (alias intf-only) (alias lib-available) + (alias link-deps) (alias loop) (alias merlin-tests) (alias meta-gen) diff --git a/test/blackbox-tests/test-cases/link-deps/dune b/test/blackbox-tests/test-cases/link-deps/dune new file mode 100644 index 00000000000..bd3547de113 --- /dev/null +++ b/test/blackbox-tests/test-cases/link-deps/dune @@ -0,0 +1,11 @@ +(alias + ((name message) + (deps (.link_deps.eobjs/link_deps.cmo)) + (action (echo "link\n")) + )) + +(executable + ((name link_deps) + (link_deps ((alias message))) + ) + ) diff --git a/test/blackbox-tests/test-cases/link-deps/dune-project b/test/blackbox-tests/test-cases/link-deps/dune-project new file mode 100644 index 00000000000..de4fc209200 --- /dev/null +++ b/test/blackbox-tests/test-cases/link-deps/dune-project @@ -0,0 +1 @@ +(lang dune 1.0) diff --git a/test/blackbox-tests/test-cases/link-deps/link_deps.ml b/test/blackbox-tests/test-cases/link-deps/link_deps.ml new file mode 100644 index 00000000000..e69de29bb2d diff --git a/test/blackbox-tests/test-cases/link-deps/run.t b/test/blackbox-tests/test-cases/link-deps/run.t new file mode 100644 index 00000000000..c6bff626357 --- /dev/null +++ b/test/blackbox-tests/test-cases/link-deps/run.t @@ -0,0 +1,11 @@ +It is possible to add link-time dependencies. + +In particular, these can depend on the result of the compilation (like a .cmo +file) and be created just before linking. + + $ dune build --display short link_deps.exe + ocamldep link_deps.ml.d + ocamlc .link_deps.eobjs/link_deps.{cmi,cmo,cmt} + link + ocamlopt .link_deps.eobjs/link_deps.{cmx,o} + ocamlopt link_deps.exe