diff --git a/CHANGES.md b/CHANGES.md index 94a19b7f..ff40288c 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,3 +1,10 @@ +next +---- + +- Add a `(universe)` special dependency to specify that an action + depend on everything in the universe. Jbuilder cannot cache the + result of an action that depend on the universe (#603, fixes #255) + 1.0+beta19 (13/03/2018) ----------------------- diff --git a/doc/jbuild.rst b/doc/jbuild.rst index e3974c42..0f43a835 100644 --- a/doc/jbuild.rst +++ b/doc/jbuild.rst @@ -1052,6 +1052,12 @@ syntax: :ref:`glob ` for details - ``(files_recursively_in )``: depend on all files in the subtree with root ```` +- ``(universe)``: depend on everything in the universe. This is for + cases where dependencies are too hard to specify. Note that Jbuilder + will not be able to cache the result of actions that depend on the + universe. In any case, this is only for dependencies in the + installed world, you must still specify all dependencies that come + from the workspace. In all these cases, the argument supports `Variables expansion`_. diff --git a/src/build_system.ml b/src/build_system.ml index f10d0660..ac56495a 100644 --- a/src/build_system.ml +++ b/src/build_system.ml @@ -339,7 +339,8 @@ type t = ; file_tree : File_tree.t ; mutable local_mkdirs : Path.Local.Set.t ; mutable dirs : (Path.t, Dir_status.t) Hashtbl.t - ; mutable gen_rules : (dir:Path.t -> string list -> extra_sub_directories_to_keep) String_map.t + ; mutable gen_rules : + (dir:Path.t -> string list -> extra_sub_directories_to_keep) String_map.t ; mutable load_dir_stack : Path.t list ; (* Set of directories under _build that have at least one rule and all their ancestors. *) @@ -1173,8 +1174,24 @@ let eval_request t ~request ~process_target = let dyn_deps = Build_exec.exec_nop t request () in process_targets (Pset.diff dyn_deps static_deps)) +let universe_file = Path.relative Path.build_dir ".universe-state" + +let update_universe t = + (* To workaround the fact that [mtime] is not precise enough on OSX *) + Utils.Cached_digest.remove universe_file; + let fname = Path.to_string universe_file in + let n = + if Sys.file_exists fname then + Sexp.Of_sexp.int (Sexp.load ~mode:Single ~fname) + 1 + else + 0 + in + make_local_dirs t (Pset.singleton Path.build_dir); + Io.write_file fname (Sexp.to_string (Sexp.To_sexp.int n)) + let do_build t ~request = entry_point t ~f:(fun () -> + update_universe t; eval_request t ~request ~process_target:(wait_for_file t)) module Ir_set = Set.Make(Internal_rule) diff --git a/src/build_system.mli b/src/build_system.mli index 6b21b057..b10a10fc 100644 --- a/src/build_system.mli +++ b/src/build_system.mli @@ -159,6 +159,9 @@ val do_build (** {2 Other queries} *) +(** File for the [(universe)] dependency. *) +val universe_file : Path.t + val is_target : t -> Path.t -> bool (** Return all the library dependencies (as written by the user) diff --git a/src/jbuild.ml b/src/jbuild.ml index 43bdbb8b..3afc2053 100644 --- a/src/jbuild.ml +++ b/src/jbuild.ml @@ -230,18 +230,20 @@ 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 + | Universe let t = let t = - let cstr name f = + let cstr_sw name f = cstr name (String_with_vars.t @> nil) f in sum - [ cstr "file" (fun x -> File x) - ; cstr "alias" (fun x -> Alias x) - ; cstr "alias_rec" (fun x -> Alias_rec x) - ; cstr "glob_files" (fun x -> Glob_files x) - ; cstr "files_recursively_in" (fun x -> Files_recursively_in x) + [ cstr_sw "file" (fun x -> File x) + ; cstr_sw "alias" (fun x -> Alias x) + ; 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 "universe" nil Universe ] in fun sexp -> @@ -264,6 +266,8 @@ module Dep_conf = struct | Files_recursively_in t -> List [Sexp.unsafe_atom_of_string "files_recursively_in" ; String_with_vars.sexp_of_t t] + | Universe -> + Sexp.unsafe_atom_of_string "universe" end module Preprocess = struct diff --git a/src/jbuild.mli b/src/jbuild.mli index c3fdfa58..05a989b2 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 + | Universe val t : t Sexp.Of_sexp.t val sexp_of_t : t -> Sexp.t diff --git a/src/super_context.ml b/src/super_context.ml index 8bb6f1ce..ca13e310 100644 --- a/src/super_context.ml +++ b/src/super_context.ml @@ -338,6 +338,9 @@ 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 + | Universe -> + Build.path Build_system.universe_file + >>^ fun () -> [] let interpret t ~scope ~dir l = Build.all (List.map l ~f:(dep t ~scope ~dir)) diff --git a/test/blackbox-tests/jbuild b/test/blackbox-tests/jbuild index 727f140d..4d3f6294 100644 --- a/test/blackbox-tests/jbuild +++ b/test/blackbox-tests/jbuild @@ -430,3 +430,13 @@ (progn (run ${exe:cram.exe} run.t) (diff? run.t run.t.corrected))))))) + +(alias + ((name runtest) + (deps ((files_recursively_in test-cases/depend-on-the-universe))) + (action + (chdir test-cases/depend-on-the-universe + (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/depend-on-the-universe/jbuild b/test/blackbox-tests/test-cases/depend-on-the-universe/jbuild new file mode 100644 index 00000000..7669794b --- /dev/null +++ b/test/blackbox-tests/test-cases/depend-on-the-universe/jbuild @@ -0,0 +1,4 @@ +(alias + ((name x) + (deps ((universe))) + (action (echo "Hello, world!")))) diff --git a/test/blackbox-tests/test-cases/depend-on-the-universe/run.t b/test/blackbox-tests/test-cases/depend-on-the-universe/run.t new file mode 100644 index 00000000..3b51b455 --- /dev/null +++ b/test/blackbox-tests/test-cases/depend-on-the-universe/run.t @@ -0,0 +1,10 @@ + $ $JBUILDER build --root . -j 1 --display quiet @x + Hello, world! + $ $JBUILDER build --root . -j 1 --display quiet @x + Hello, world! + $ $JBUILDER build --root . -j 1 --display quiet @x + Hello, world! + $ $JBUILDER build --root . -j 1 --display quiet @x + Hello, world! + $ $JBUILDER build --root . -j 1 --display quiet @x + Hello, world!