Do not compute external library dependencies eagerly

This commit is contained in:
Jeremie Dimino 2017-03-02 11:34:13 +00:00
parent 084baba117
commit 16bd433e4e
2 changed files with 47 additions and 7 deletions

View File

@ -62,7 +62,8 @@ format and the third one describes how to use the =jbuilder= command.
- *root*: the root is the directory from where Jbuilder can build
things. Jbuilder knows how to build target that are descendant of
the root. Anything outside of the tree starting from the root is
considered part of the *installed world*
considered part of the *installed world*. How the root is determined
is explained in [[Finding the root][this section]].
- *workspace*: a workspace is the sub-tree starting from the root. It
can contain any number of projects that will be built simultaneously
@ -875,9 +876,44 @@ the root of your project. What you should write instead is:
(action (chdir ${ROOT} (ocamllex -o ${@} ${<})))))
#+end_src
** jbuild-ignore
By default Jbuilder traverses the whole source tree. To ignore a
sub-tree, simply write a =jbuild-ignore= file in the parent directory
containing the name of the sub-directories to ignore.
So for instance, if you write =foo= in =src/jbuild-ignore=, then
=src/foo= won't be traversed and any =jbuild= file it contains will be
ignored.
=jbuild-ignore= files contain a list of directory names, one per
line.
* Usage
TODO
This section describe usage of Jbuilder from the shell.
** Finding the root
The root of the current workspace is determined by looking up specific
files/directories in the current directory and parent directories.
More precisely, consider the current directory and all its
ancestors. For instance if you are in =/home/me/code/myproject/src=,
then this is this set:
- =/home/me/code/myproject/src=
- =/home/me/code/myproject=
- =/home/me/code=
- =/home/me=
- =/home=
- =/=
Jbuilder looks for the following entries in all these directories:
1. jbuild-workspace
2. any file ending with =.install=
3. =.git= or =.hg=
* Advanced topics

View File

@ -22,7 +22,9 @@ module Rule = struct
type t =
{ deps : Pset.t
; targets : Pset.t
; lib_deps : Build.lib_deps Pmap.t
; (* Keep the arrow around so that we can do more query, such as for finding external
library dependencies *)
build : (unit, unit) Build.t
; mutable exec : Exec_status.t
}
end
@ -213,7 +215,6 @@ let compile_rule t ~all_targets_by_dir ?(allow_override=false) pre_rule =
let { Pre_rule. build; targets = target_specs } = pre_rule in
let deps = Build_interpret.deps build ~all_targets_by_dir in
let targets = Target.paths target_specs in
let lib_deps = Build_interpret.lib_deps build in
if !Clflags.debug_rules then begin
let f set =
@ -221,6 +222,7 @@ let compile_rule t ~all_targets_by_dir ?(allow_override=false) pre_rule =
|> List.map ~f:Path.to_string
|> String.concat ~sep:", "
in
let lib_deps = Build_interpret.lib_deps build in
if Pmap.is_empty lib_deps then
Printf.eprintf "{%s} -> {%s}\n" (f deps) (f targets)
else
@ -251,7 +253,7 @@ let compile_rule t ~all_targets_by_dir ?(allow_override=false) pre_rule =
{ Rule.
deps = deps
; targets = targets
; lib_deps
; build
; exec
}
in
@ -384,7 +386,8 @@ let rules_for_targets t targets =
let all_lib_deps t targets =
List.fold_left (rules_for_targets t targets) ~init:Pmap.empty
~f:(fun acc (_, rule) ->
Pmap.merge acc rule.Rule.lib_deps ~f:(fun _ a b ->
let lib_deps = Build_interpret.lib_deps rule.Rule.build in
Pmap.merge acc lib_deps ~f:(fun _ a b ->
match a, b with
| None, None -> None
| Some a, None -> Some a
@ -393,7 +396,8 @@ let all_lib_deps t targets =
let all_lib_deps_by_context t targets =
List.fold_left (rules_for_targets t targets) ~init:[] ~f:(fun acc (_, rule) ->
Path.Map.fold rule.Rule.lib_deps ~init:acc ~f:(fun ~key:path ~data:lib_deps acc ->
let lib_deps = Build_interpret.lib_deps rule.Rule.build in
Path.Map.fold lib_deps ~init:acc ~f:(fun ~key:path ~data:lib_deps acc ->
match Path.extract_build_context path with
| None -> acc
| Some (context, _) -> (context, lib_deps) :: acc))