diff --git a/doc/jbuild.rst b/doc/jbuild.rst index 0f43a835..1d229a1c 100644 --- a/doc/jbuild.rst +++ b/doc/jbuild.rst @@ -1058,6 +1058,9 @@ syntax: universe. In any case, this is only for dependencies in the installed world, you must still specify all dependencies that come from the workspace. +- ``(package )`` depend on all files installed by ````, as well + as on the transitive package dependencies of ````. This can be used + to test a command against the files that will be installed In all these cases, the argument supports `Variables expansion`_. diff --git a/src/build.ml b/src/build.ml index 4902aba9..60a5fb1e 100644 --- a/src/build.ml +++ b/src/build.ml @@ -27,13 +27,14 @@ module Repr = struct | Split : ('a, 'b) t * ('c, 'd) t -> ('a * 'c, 'b * 'd) t | Fanout : ('a, 'b) t * ('a, 'c) t -> ('a, 'b * 'c) t | Paths : Pset.t -> ('a, 'a) t + | Paths_for_rule : Path.Set.t -> ('a, 'a) t | Paths_glob : glob_state ref -> ('a, Path.t list) t (* The reference gets decided in Build_interpret.deps *) | If_file_exists : Path.t * ('a, 'b) if_file_exists_state ref -> ('a, 'b) t | Contents : Path.t -> ('a, string) t | Lines_of : Path.t -> ('a, string list) t | Vpath : 'a Vspec.t -> (unit, 'a) t - | Dyn_paths : ('a, Path.t list) t -> ('a, 'a) t + | Dyn_paths : ('a, Path.Set.t) t -> ('a, 'a) t | Record_lib_deps : lib_deps -> ('a, 'a) t | Fail : fail -> (_, _) t | Memo : 'a memo -> (unit, 'a) t @@ -134,7 +135,9 @@ let paths ps = Paths (Pset.of_list ps) let path_set ps = Paths ps let paths_glob ~loc ~dir re = Paths_glob (ref (G_unevaluated (loc, dir, re))) let vpath vp = Vpath vp -let dyn_paths t = Dyn_paths t +let dyn_paths t = Dyn_paths (t >>^ Path.Set.of_list) +let dyn_path_set t = Dyn_paths t +let paths_for_rule ps = Paths_for_rule ps let catch t ~on_error = Catch (t, on_error) diff --git a/src/build.mli b/src/build.mli index 1dc7904e..7a73a3c1 100644 --- a/src/build.mli +++ b/src/build.mli @@ -71,6 +71,7 @@ val files_recursively_in (** Record dynamic dependencies *) val dyn_paths : ('a, Path.t list) t -> ('a, 'a) t +val dyn_path_set : ('a, Path.Set.t) t -> ('a, 'a) t val vpath : 'a Vspec.t -> (unit, 'a) t @@ -183,12 +184,13 @@ module Repr : sig | Split : ('a, 'b) t * ('c, 'd) t -> ('a * 'c, 'b * 'd) t | Fanout : ('a, 'b) t * ('a, 'c) t -> ('a, 'b * 'c) t | Paths : Path.Set.t -> ('a, 'a) t + | Paths_for_rule : Path.Set.t -> ('a, 'a) t | Paths_glob : glob_state ref -> ('a, Path.t list) t | If_file_exists : Path.t * ('a, 'b) if_file_exists_state ref -> ('a, 'b) t | Contents : Path.t -> ('a, string) t | Lines_of : Path.t -> ('a, string list) t | Vpath : 'a Vspec.t -> (unit, 'a) t - | Dyn_paths : ('a, Path.t list) t -> ('a, 'a) t + | Dyn_paths : ('a, Path.Set.t) t -> ('a, 'a) t | Record_lib_deps : lib_deps -> ('a, 'a) t | Fail : fail -> (_, _) t | Memo : 'a memo -> (unit, 'a) t @@ -220,3 +222,6 @@ end val repr : ('a, 'b) t -> ('a, 'b) Repr.t val merge_lib_deps : lib_deps -> lib_deps -> lib_deps + +(**/**) +val paths_for_rule : Path.Set.t -> ('a, 'a) t diff --git a/src/build_interpret.ml b/src/build_interpret.ml index 37c55471..59037a43 100644 --- a/src/build_interpret.ml +++ b/src/build_interpret.ml @@ -63,6 +63,8 @@ let static_deps t ~all_targets ~file_tree = | Split (a, b) -> loop a (loop b acc) | Fanout (a, b) -> loop a (loop b acc) | Paths fns -> { acc with action_deps = Pset.union fns acc.action_deps } + | Paths_for_rule fns -> + { acc with rule_deps = Pset.union fns acc.rule_deps } | Paths_glob state -> begin match !state with | G_evaluated l -> @@ -129,6 +131,7 @@ let lib_deps = | Split (a, b) -> loop a (loop b acc) | Fanout (a, b) -> loop a (loop b acc) | Paths _ -> acc + | Paths_for_rule _ -> acc | Vpath _ -> acc | Paths_glob _ -> acc | Dyn_paths t -> loop t acc @@ -156,6 +159,7 @@ let targets = | Split (a, b) -> loop a (loop b acc) | Fanout (a, b) -> loop a (loop b acc) | Paths _ -> acc + | Paths_for_rule _ -> acc | Vpath _ -> acc | Paths_glob _ -> acc | Dyn_paths t -> loop t acc diff --git a/src/build_system.ml b/src/build_system.ml index 275fed05..09eb0825 100644 --- a/src/build_system.ml +++ b/src/build_system.ml @@ -278,6 +278,10 @@ module Alias0 = struct let doc = make "doc" let private_doc = make "doc-private" let lint = make "lint" + + let package_install ~(context : Context.t) ~pkg = + make (sprintf ".%s-files" (Package.Name.to_string pkg)) + ~dir:context.build_dir end module Dir_status = struct @@ -297,8 +301,9 @@ module Dir_status = struct type alias = - { mutable deps : Pset.t - ; mutable actions : alias_action list + { mutable deps : Pset.t + ; mutable dyn_deps : (unit, Pset.t) Build.t + ; mutable actions : alias_action list } type rules_collector = @@ -349,6 +354,8 @@ type t = ; files_of : (Path.t, Files_of.t) Hashtbl.t ; mutable prefix : (unit, unit) Build.t option ; hook : hook -> unit + ; (* Package files are part of *) + packages : (Path.t, Package.Name.t) Hashtbl.t } let string_of_paths set = @@ -442,6 +449,7 @@ module Build_exec = struct let b = exec dyn_deps b x in (a, b) | Paths _ -> x + | Paths_for_rule _ -> x | Paths_glob state -> get_glob_result_exn state | Contents p -> Io.read_file (Path.to_string p) | Lines_of p -> Io.lines_of_file (Path.to_string p) @@ -450,7 +458,7 @@ module Build_exec = struct Option.value_exn file.data | Dyn_paths t -> let fns = exec dyn_deps t x in - dyn_deps := Pset.union !dyn_deps (Pset.of_list fns); + dyn_deps := Pset.union !dyn_deps fns; x | Record_lib_deps _ -> x | Fail { fail } -> fail () @@ -851,7 +859,7 @@ and load_dir_step2_exn t ~dir ~collector ~lazy_generators = let alias_rules, alias_stamp_files = let open Build.O in String_map.foldi collector.aliases ~init:([], Pset.empty) - ~f:(fun name { Dir_status. deps; actions } (rules, alias_stamp_files) -> + ~f:(fun name { Dir_status. deps; dyn_deps; actions } (rules, alias_stamp_files) -> let base_path = Path.relative alias_dir name in let rules, deps = List.fold_left actions ~init:(rules, deps) @@ -871,11 +879,14 @@ and load_dir_step2_exn t ~dir ~collector ~lazy_generators = (Pre_rule.make ~context:None (Build.path_set deps >>> - Build.action ~targets:[path] - (Redirect (Stdout, - path, - Digest_files - (Path.Set.to_list deps)))) + dyn_deps >>> + Build.dyn_path_set (Build.arr (fun x -> x)) + >>^ (fun dyn_deps -> + let deps = Pset.union deps dyn_deps in + Action.with_stdout_to path + (Action.digest_files (Pset.to_list deps))) + >>> + Build.action_dyn () ~targets:[path]) :: rules, Pset.add alias_stamp_files path)) in @@ -1142,6 +1153,7 @@ let create ~contexts ~file_tree ~hook = let t = { contexts ; files = Hashtbl.create 1024 + ; packages = Hashtbl.create 1024 ; trace = Trace.load () ; local_mkdirs = Path.Local.Set.empty ; dirs = Hashtbl.create 1024 @@ -1324,7 +1336,8 @@ let build_rules_internal ?(recursive=false) t ~request = else begin rules_seen := Id_set.add !rules_seen ir.id; (match ir.exec with - | Running { rule_evaluation; _ } | Evaluating_rule { rule_evaluation; _ } -> + | Running { rule_evaluation; _ } + | Evaluating_rule { rule_evaluation; _ } -> Fiber.return rule_evaluation | Not_started { eval_rule; exec_rule } -> Fiber.fork (fun () -> @@ -1381,6 +1394,46 @@ let build_rules ?recursive t ~request = entry_point t ~f:(fun () -> build_rules_internal ?recursive t ~request) +let set_package t file package = + Hashtbl.add t.packages file package + +let package_deps t pkg files = + let rules_seen = ref Id_set.empty in + let rec loop fn acc = + match Hashtbl.find_all t.packages fn with + | [] -> loop_deps fn acc + | [p] when p = pkg -> loop_deps fn acc + | pkgs -> + List.fold_left pkgs ~init:acc ~f:add_package + and add_package acc p = + if p = pkg then + acc + else + Package.Name.Set.add acc p + and loop_deps fn acc = + match Hashtbl.find t.files fn with + | None -> acc + | Some (File_spec.T { rule = ir; _ }) -> + if Id_set.mem !rules_seen ir.id then + acc + else 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.fold (Pset.union ir.static_deps dyn_deps) ~init:acc ~f:loop + end + in + let open Build.O in + Build.paths_for_rule files >>^ fun () -> + (* We know that at this point of execution, all the relevant ivars + have been filled *) + Pset.fold files ~init:Package.Name.Set.empty ~f:loop_deps + (* +-----------------------------------------------------------------+ | Adding rules to the system | +-----------------------------------------------------------------+ *) @@ -1472,14 +1525,27 @@ module Alias = struct let collector = get_collector build_system ~dir:t.dir in match String_map.find collector.aliases t.name with | None -> - let x = { Dir_status. deps = Pset.empty; actions = [] } in + let x = + { Dir_status. + deps = Pset.empty + ; dyn_deps = Build.return Pset.empty + ; actions = [] + } + in collector.aliases <- String_map.add collector.aliases t.name x; x | Some x -> x - let add_deps build_system t deps = + let add_deps build_system t ?dyn_deps deps = let def = get_alias_def build_system t in - def.deps <- Pset.union def.deps (Pset.of_list deps) + def.deps <- Pset.union def.deps deps; + match dyn_deps with + | None -> () + | Some build -> + let open Build.O in + def.dyn_deps <- + Build.fanout def.dyn_deps build >>^ fun (a, b) -> + Pset.union a b let add_action build_system t ~context ?(locks=[]) ~stamp action = let def = get_alias_def build_system t in diff --git a/src/build_system.mli b/src/build_system.mli index df6edbc5..82f99435 100644 --- a/src/build_system.mli +++ b/src/build_system.mli @@ -77,6 +77,18 @@ val on_load_dir : t -> dir:Path.t -> f:(unit -> unit) -> unit (** Stamp file that depends on all files of [dir] with extension [ext]. *) 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 + +(** 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 + (** {2 Aliases} *) module Alias : sig @@ -107,6 +119,10 @@ module Alias : sig val private_doc : dir:Path.t -> t val lint : dir:Path.t -> t + (** Alias for all the files in [_build/install] that belong to this + package *) + val package_install : context:Context.t -> pkg:Package.Name.t -> t + (** Return the underlying stamp file *) val stamp_file : t -> Path.t @@ -128,9 +144,15 @@ module Alias : sig -> contexts:string list -> (unit, unit) Build.t - (** [add_deps store alias deps] arrange things so that all [deps] - are built as part of the build of alias [alias]. *) - val add_deps : build_system -> t -> Path.t list -> unit + (** [add_deps store alias ?dyn_deps deps] arrange things so that all + [dyn_deps] and [deps] are built as part of the build of alias + [alias]. *) + val add_deps + : build_system + -> t + -> ?dyn_deps:(unit, Path.Set.t) Build.t + -> Path.Set.t + -> unit (** [add_action store alias ~stamp action] arrange things so that [action] is executed as part of the build of alias diff --git a/src/fiber/fiber.ml b/src/fiber/fiber.ml index 3903acd0..10fd3252 100644 --- a/src/fiber/fiber.ml +++ b/src/fiber/fiber.ml @@ -386,12 +386,18 @@ module Ivar = struct | Full x -> k x | Empty q -> Queue.push { Handler. run = k; ctx } q + + let peek t = + match t.state with + | Full x -> Some x + | Empty _ -> None end module Future = struct type 'a t = 'a Ivar.t let wait = Ivar.read + let peek = Ivar.peek end let fork f ctx k = diff --git a/src/fiber/fiber.mli b/src/fiber/fiber.mli index 9bbf1b0d..d1c7851d 100644 --- a/src/fiber/fiber.mli +++ b/src/fiber/fiber.mli @@ -40,6 +40,9 @@ module Future : sig (** Wait for the given future to yield a value. *) val wait : 'a t -> 'a fiber + + (** Return [Some x] if [t] has already returned. *) + val peek : 'a t -> 'a option end with type 'a fiber := 'a t (** [fork f] creates a sub-fiber and return a [Future.t] to wait its result. *) @@ -226,6 +229,9 @@ module Ivar : sig (** Fill the ivar with the following value. This can only be called once for a given ivar. *) val fill : 'a t -> 'a -> unit fiber + + (** Return [Some x] is [fill t x] has been called previously. *) + val peek : 'a t -> 'a option end with type 'a fiber := 'a t module Mutex : sig diff --git a/src/gen_rules.ml b/src/gen_rules.ml index ef0694a5..201c684e 100644 --- a/src/gen_rules.ml +++ b/src/gen_rules.ml @@ -708,17 +708,18 @@ module Gen(P : Install_rules.Params) = struct List.iter Cm_kind.all ~f:(fun cm_kind -> let files = - Module.Name.Map.fold modules ~init:[] ~f:(fun m acc -> + Module.Name.Map.fold modules ~init:Path.Set.empty ~f:(fun m acc -> match Module.cm_file m ~obj_dir cm_kind with | None -> acc - | Some fn -> fn :: acc) + | Some fn -> Path.Set.add acc fn) in SC.Libs.setup_file_deps_alias sctx ~dir lib ~ext:(Cm_kind.ext cm_kind) files); SC.Libs.setup_file_deps_group_alias sctx ~dir lib ~exts:[".cmi"; ".cmx"]; SC.Libs.setup_file_deps_alias sctx ~dir lib ~ext:".h" (List.map lib.install_c_headers ~f:(fun header -> - Path.relative dir (header ^ ".h"))); + Path.relative dir (header ^ ".h")) + |> Path.Set.of_list); let top_sorted_modules = Ocamldep.Dep_graph.top_closed_implementations dep_graphs.impl diff --git a/src/install_rules.ml b/src/install_rules.ml index 67a5f5b2..fed05398 100644 --- a/src/install_rules.ml +++ b/src/install_rules.ml @@ -203,8 +203,10 @@ module Gen(P : Install_params) = struct let install_dir = Config.local_install_dir ~context:ctx.name in List.map entries ~f:(fun entry -> let dst = - Path.append install_dir (Install.Entry.relative_installed_path entry ~package) + Path.append install_dir + (Install.Entry.relative_installed_path entry ~package) in + Build_system.set_package (SC.build_system sctx) entry.src package; SC.add_rule sctx (Build.symlink ~src:entry.src ~dst); Install.Entry.set_src entry dst) @@ -237,6 +239,19 @@ module Gen(P : Install_params) = struct (Utils.install_file ~package ~findlib_toolchain:ctx.findlib_toolchain) in let entries = local_install_rules entries ~package in + let files = Install.files entries in + SC.add_alias_deps sctx + (Alias.package_install ~context:ctx ~pkg:package) + files + ~dyn_deps: + (Build_system.package_deps (SC.build_system sctx) package files + >>^ fun packages -> + Package.Name.Set.to_list packages + |> List.map ~f:(fun pkg -> + Build_system.Alias.package_install + ~context:(SC.context sctx) ~pkg + |> Build_system.Alias.stamp_file) + |> Path.Set.of_list); SC.add_rule sctx ~mode:(if promote_install_file then Promote_but_delete_on_clean @@ -244,7 +259,7 @@ module Gen(P : Install_params) = struct (* We must ignore the source file since it might be copied to the source tree by another context. *) Ignore_source_files) - (Build.path_set (Install.files entries) + (Build.path_set files >>^ (fun () -> let entries = match ctx.findlib_toolchain with @@ -299,7 +314,7 @@ module Gen(P : Install_params) = struct let path = Path.append ctx.build_dir src_path in let install_alias = Alias.install ~dir:path in let install_file = Path.relative path install_fn in - SC.add_alias_deps sctx install_alias [install_file]) + SC.add_alias_deps sctx install_alias (Path.Set.singleton install_file)) let init () = init_meta (); diff --git a/src/jbuild.ml b/src/jbuild.ml index 303acd78..df692fb0 100644 --- a/src/jbuild.ml +++ b/src/jbuild.ml @@ -230,6 +230,7 @@ module Dep_conf = struct | Alias_rec of String_with_vars.t | Glob_files of String_with_vars.t | Files_recursively_in of String_with_vars.t + | Package of String_with_vars.t | Universe let t = @@ -243,6 +244,7 @@ module Dep_conf = struct ; cstr_sw "alias_rec" (fun x -> Alias_rec x) ; cstr_sw "glob_files" (fun x -> Glob_files x) ; cstr_sw "files_recursively_in" (fun x -> Files_recursively_in x) + ; cstr_sw "package" (fun x -> Package x) ; cstr "universe" nil Universe ] in @@ -266,6 +268,9 @@ module Dep_conf = struct | Files_recursively_in t -> List [Sexp.unsafe_atom_of_string "files_recursively_in" ; String_with_vars.sexp_of_t t] + | Package t -> + List [Sexp.unsafe_atom_of_string "package" ; + String_with_vars.sexp_of_t t] | Universe -> Sexp.unsafe_atom_of_string "universe" end diff --git a/src/jbuild.mli b/src/jbuild.mli index 82c5a64c..a5fa3a9c 100644 --- a/src/jbuild.mli +++ b/src/jbuild.mli @@ -125,6 +125,7 @@ module Dep_conf : sig | Alias_rec of String_with_vars.t | Glob_files of String_with_vars.t | Files_recursively_in of String_with_vars.t + | Package of String_with_vars.t | Universe val t : t Sexp.Of_sexp.t diff --git a/src/odoc.ml b/src/odoc.ml index ee8b4a19..131093d1 100644 --- a/src/odoc.ml +++ b/src/odoc.ml @@ -210,7 +210,8 @@ module Gen (S : sig val sctx : SC.t end) = struct compile_module ~dir ~obj_dir ~includes ~dep_graphs ~doc_dir ~pkg_or_lnu) in - Dep.setup_deps (Lib lib) (List.map modules_and_odoc_files ~f:snd) + Dep.setup_deps (Lib lib) (List.map modules_and_odoc_files ~f:snd + |> Path.Set.of_list) let setup_css_rule () = SC.add_rule sctx @@ -337,13 +338,13 @@ module Gen (S : sig val sctx : SC.t end) = struct :: List.map ~f:(fun lib -> Dep.html_alias (Lib lib)) libs ) ~f:(fun alias -> SC.add_alias_deps sctx alias - [ css_file - ; toplevel_index - ] + (Path.Set.of_list [ css_file + ; toplevel_index + ]) ); List.combine odocs html_files |> List.iter ~f:(fun (odoc, html) -> - SC.add_alias_deps sctx odoc.html_alias [html] + SC.add_alias_deps sctx odoc.html_alias (Path.Set.singleton html) ); end @@ -387,6 +388,7 @@ module Gen (S : sig val sctx : SC.t end) = struct |> Lib.Set.to_list |> List.map ~f:(fun lib -> Dep.html_alias (Lib lib))) |> List.map ~f:Build_system.Alias.stamp_file + |> Path.Set.of_list ) let pkg_odoc (pkg : Package.t) = Paths.odocs (Pkg pkg.name) @@ -449,7 +451,7 @@ module Gen (S : sig val sctx : SC.t end) = struct ~doc_dir:(Paths.odocs (Pkg pkg.name)) ~includes:(Build.arr (fun _ -> Arg_spec.As [])) ) in - Dep.setup_deps (Pkg pkg.name) odocs + Dep.setup_deps (Pkg pkg.name) (Path.Set.of_list odocs) let init ~modules_by_lib ~mlds_of_dir = let docs_by_package = @@ -529,6 +531,7 @@ module Gen (S : sig val sctx : SC.t end) = struct )) |> List.map ~f:(fun (lib : Lib.t) -> Build_system.Alias.stamp_file (Dep.alias (Lib lib))) + |> Path.Set.of_list ) end diff --git a/src/super_context.ml b/src/super_context.ml index 214c423a..0387b65b 100644 --- a/src/super_context.ml +++ b/src/super_context.ml @@ -41,6 +41,7 @@ let file_tree t = t.file_tree let stanzas_to_consider_for_install t = t.stanzas_to_consider_for_install let cxx_flags t = t.cxx_flags let build_dir t = t.context.build_dir +let build_system t = t.build_system let host t = Option.value t.host ~default:t @@ -236,8 +237,8 @@ let add_rule_get_targets t ?sandbox ?mode ?locks ?loc build = let add_rules t ?sandbox builds = List.iter builds ~f:(add_rule t ?sandbox) -let add_alias_deps t alias deps = - Alias.add_deps t.build_system alias deps +let add_alias_deps t alias ?dyn_deps deps = + Alias.add_deps t.build_system alias ?dyn_deps deps let add_alias_action t alias ?locks ~stamp action = Alias.add_action t.build_system ~context:t.context alias ?locks ~stamp action @@ -302,7 +303,8 @@ module Libs = struct ~ext:(String.concat exts ~sep:"-and-") (List.map exts ~f:(fun ext -> Alias.stamp_file - (lib_files_alias ~dir ~name:(Library.best_name lib) ~ext))) + (lib_files_alias ~dir ~name:(Library.best_name lib) ~ext)) + |> Path.Set.of_list) let file_deps t ~ext = Build.dyn_paths (Build.arr (fun libs -> @@ -351,6 +353,10 @@ module Deps = struct let path = Path.relative dir (expand_vars t ~scope ~dir s) in Build.files_recursively_in ~dir:path ~file_tree:t.file_tree >>^ Pset.to_list + | Package p -> + let pkg = Package.Name.of_string (expand_vars t ~scope ~dir p) in + Alias.dep (Alias.package_install ~context:t.context ~pkg) + >>^ fun () -> [] | Universe -> Build.path Build_system.universe_file >>^ fun () -> [] diff --git a/src/super_context.mli b/src/super_context.mli index 9921587c..dd6ded0f 100644 --- a/src/super_context.mli +++ b/src/super_context.mli @@ -41,6 +41,7 @@ val stanzas_to_consider_for_install : t -> (Path.t * Scope.t * Stanza.t) list val cxx_flags : t -> string list val build_dir : t -> Path.t val host : t -> t +val build_system : t -> Build_system.t (** All public libraries of the workspace *) val public_libs : t -> Lib.DB.t @@ -97,7 +98,8 @@ val add_rules val add_alias_deps : t -> Build_system.Alias.t - -> Path.t list + -> ?dyn_deps:(unit, Path.Set.t) Build.t + -> Path.Set.t -> unit val add_alias_action : t @@ -150,7 +152,7 @@ module Libs : sig -> dir:Path.t -> ext:string -> Library.t - -> Path.t list + -> Path.Set.t -> unit (** Setup an alias that depend on all files with the given extensions. diff --git a/test/blackbox-tests/jbuild b/test/blackbox-tests/jbuild index 4d3f6294..d08c7d37 100644 --- a/test/blackbox-tests/jbuild +++ b/test/blackbox-tests/jbuild @@ -440,3 +440,13 @@ (progn (run ${exe:cram.exe} run.t) (diff? run.t run.t.corrected))))))) + +(alias + ((name runtest) + (deps ((files_recursively_in test-cases/package-dep))) + (action + (chdir test-cases/package-dep + (setenv JBUILDER ${bin:jbuilder} + (progn + (run ${exe:cram.exe} run.t) + (diff? run.t run.t.corrected))))))) diff --git a/test/blackbox-tests/test-cases/package-dep/bar.opam b/test/blackbox-tests/test-cases/package-dep/bar.opam new file mode 100644 index 00000000..e69de29b diff --git a/test/blackbox-tests/test-cases/package-dep/foo.opam b/test/blackbox-tests/test-cases/package-dep/foo.opam new file mode 100644 index 00000000..e69de29b diff --git a/test/blackbox-tests/test-cases/package-dep/jbuild b/test/blackbox-tests/test-cases/package-dep/jbuild new file mode 100644 index 00000000..a311c774 --- /dev/null +++ b/test/blackbox-tests/test-cases/package-dep/jbuild @@ -0,0 +1,33 @@ +(jbuild_version 1) + +(library + ((name foo) + (public_name foo) + (modules (foo)))) + +(library + ((name bar) + (public_name bar) + (libraries (foo)) + (modules (bar)))) + +(rule + (with-stdout-to foo.ml + (echo "let x = 42"))) + +(rule + (with-stdout-to bar.ml + (echo "let x = string_of_int Foo.x"))) + +(rule + (with-stdout-to test.ml + (echo "let () = Printf.printf \"%d %s\" Foo.x Bar.x"))) + +(rule + ((deps (test.ml (package bar))) + (targets (test.exe)) + (action (run ocamlfind ocamlc -linkpkg -package bar -o test.exe test.ml)))) + +(alias + ((name runtest) + (action (run ./test.exe)))) diff --git a/test/blackbox-tests/test-cases/package-dep/run.t b/test/blackbox-tests/test-cases/package-dep/run.t new file mode 100644 index 00000000..1a4e219c --- /dev/null +++ b/test/blackbox-tests/test-cases/package-dep/run.t @@ -0,0 +1,16 @@ + $ $JBUILDER runtest -j1 --display short --root . + ocamldep bar.ml.d + ocamldep foo.ml.d + ocamlc .foo.objs/foo.{cmi,cmo,cmt} + ocamlc .bar.objs/bar.{cmi,cmo,cmt} + ocamlc bar.cma + ocamlopt .foo.objs/foo.{cmx,o} + ocamlopt .bar.objs/bar.{cmx,o} + ocamlopt bar.{a,cmxa} + ocamlopt bar.cmxs + ocamlopt foo.{a,cmxa} + ocamlopt foo.cmxs + ocamlc foo.cma + ocamlfind test.exe + test alias runtest + 42 42