diff --git a/src/build_system.ml b/src/build_system.ml index 515707e3..35e03d5c 100644 --- a/src/build_system.ml +++ b/src/build_system.ml @@ -1397,36 +1397,35 @@ let build_rules ?recursive t ~request = let set_package t file package = Hashtbl.add t.packages file package -let package_deps t files = +let package_deps t pkg files = let rules_seen = ref Id_set.empty in let packages = ref Package.Name.Set.empty in let rec loop fn = match Hashtbl.find t.packages fn with - | Some p -> + | Some p when p <> pkg -> packages := Package.Name.Set.add !packages p - | None -> - let dir = Path.parent fn in - if Path.is_in_build_dir dir then load_dir t ~dir; - match Hashtbl.find t.files fn with - | None -> () - | Some (File_spec.T { rule = ir; _ }) -> - if not (Id_set.mem !rules_seen ir.id) then begin - rules_seen := Id_set.add !rules_seen ir.id; - let _, dyn_deps = - match ir.exec with - | Running { rule_evaluation; _ } - | Evaluating_rule { rule_evaluation; _ } -> - Option.value_exn (Fiber.Future.peek rule_evaluation) - | Not_started _ -> assert false - in - Pset.iter (Pset.union ir.static_deps dyn_deps) ~f:loop - end + | _ -> loop_deps fn + and loop_deps fn = + match Hashtbl.find t.files fn with + | None -> () + | Some (File_spec.T { rule = ir; _ }) -> + if not (Id_set.mem !rules_seen ir.id) then begin + rules_seen := Id_set.add !rules_seen ir.id; + let _, dyn_deps = + match ir.exec with + | Running { rule_evaluation; _ } + | Evaluating_rule { rule_evaluation; _ } -> + Option.value_exn (Fiber.Future.peek rule_evaluation) + | Not_started _ -> assert false + in + Pset.iter (Pset.union ir.static_deps dyn_deps) ~f:loop + end in let open Build.O in Build.paths_for_rule files >>^ fun () -> - (* This is a bit ugly, we know that at this point of execution, all - the relevant ivars have been filled *) - Pset.iter files ~f:loop; + (* We know that at this point of execution, all the relevant ivars + have been filled *) + Pset.iter files ~f:loop_deps; !packages (* +-----------------------------------------------------------------+ diff --git a/src/build_system.mli b/src/build_system.mli index 61b66247..82f99435 100644 --- a/src/build_system.mli +++ b/src/build_system.mli @@ -80,11 +80,12 @@ val stamp_file_for_files_of : t -> dir:Path.t -> ext:string -> Path.t (** Sets the package this file is part of *) val set_package : t -> Path.t -> Package.Name.t -> unit -(** Scan the transitive dependencies of the following files and return - set of packages these files are part of. Do not scan packages - recursively. *) +(** Assuming [files] is the list of files in [_build/install] that + belong to package [pkg], [package_deps t pkg files] is the set of + direct package dependencies of [package]. *) val package_deps : t + -> Package.Name.t -> Path.Set.t -> (unit, Package.Name.Set.t) Build.t diff --git a/src/install_rules.ml b/src/install_rules.ml index 448f22af..fed05398 100644 --- a/src/install_rules.ml +++ b/src/install_rules.ml @@ -244,10 +244,9 @@ module Gen(P : Install_params) = struct (Alias.package_install ~context:ctx ~pkg:package) files ~dyn_deps: - (Build_system.package_deps (SC.build_system sctx) files + (Build_system.package_deps (SC.build_system sctx) package files >>^ fun packages -> - Package.Name.Set.remove packages package - |> Package.Name.Set.to_list + Package.Name.Set.to_list packages |> List.map ~f:(fun pkg -> Build_system.Alias.package_install ~context:(SC.context sctx) ~pkg diff --git a/test/blackbox-tests/test-cases/package-dep/jbuild b/test/blackbox-tests/test-cases/package-dep/jbuild index 30d1761f..a311c774 100644 --- a/test/blackbox-tests/test-cases/package-dep/jbuild +++ b/test/blackbox-tests/test-cases/package-dep/jbuild @@ -24,7 +24,7 @@ (echo "let () = Printf.printf \"%d %s\" Foo.x Bar.x"))) (rule - ((deps ((package bar))) + ((deps (test.ml (package bar))) (targets (test.exe)) (action (run ocamlfind ocamlc -linkpkg -package bar -o test.exe test.ml)))) diff --git a/test/blackbox-tests/test-cases/package-dep/run.t b/test/blackbox-tests/test-cases/package-dep/run.t index a3fa2bd7..1a4e219c 100644 --- a/test/blackbox-tests/test-cases/package-dep/run.t +++ b/test/blackbox-tests/test-cases/package-dep/run.t @@ -8,7 +8,9 @@ ocamlopt .bar.objs/bar.{cmx,o} ocamlopt bar.{a,cmxa} ocamlopt bar.cmxs - ocamlfind test.exe (exit 2) - (cd _build/default && /Users/rgrinberg/.opam/4.05.0/bin/ocamlfind ocamlc -linkpkg -package bar -o test.exe test.ml) - ocamlfind: Package `foo' not found - required by `bar' - [1] + ocamlopt foo.{a,cmxa} + ocamlopt foo.cmxs + ocamlc foo.cma + ocamlfind test.exe + test alias runtest + 42 42