diff options
author | Nicolas Pouillard <np@nicolaspouillard.fr> | 2007-11-28 16:08:18 +0000 |
---|---|---|
committer | Nicolas Pouillard <np@nicolaspouillard.fr> | 2007-11-28 16:08:18 +0000 |
commit | 3a4356befd69933ea749e6f832dec91bbffc7ce8 (patch) | |
tree | 403c40b4dc8402c3400ea25e9e1e821720e06e87 /ocamlbuild/resource.ml | |
parent | 114db8aaeadd15a427ef0387e2397827e206709b (diff) | |
download | ocaml-3a4356befd69933ea749e6f832dec91bbffc7ce8.tar.gz |
[ocamlbuild] Move some functions from Pathname to Resource and use Digest_cache.
git-svn-id: http://caml.inria.fr/svn/ocaml/trunk@8668 f963ae5c-01c2-4b8c-9fe0-0dff7051ff02
Diffstat (limited to 'ocamlbuild/resource.ml')
-rw-r--r-- | ocamlbuild/resource.ml | 118 |
1 files changed, 75 insertions, 43 deletions
diff --git a/ocamlbuild/resource.ml b/ocamlbuild/resource.ml index 0d13e854e1..26fb5ba830 100644 --- a/ocamlbuild/resource.ml +++ b/ocamlbuild/resource.ml @@ -14,6 +14,7 @@ open My_std open Format open Log +open Pathname.Operators module Resources = Set.Make(Pathname) @@ -22,8 +23,48 @@ let print = Pathname.print let equal = (=) let compare = compare +let in_source_dir p = + if Pathname.is_implicit p then Pathname.pwd/p else invalid_arg (Printf.sprintf "in_source_dir: %S" p) + +let in_build_dir p = + if Pathname.is_relative p then p + else invalid_arg (Printf.sprintf "in_build_dir: %S" p) + +let clean_up_links entry = + if not !Options.make_links then entry else + Slurp.filter begin fun path name _ -> + let pathname = in_source_dir (path/name) in + if Pathname.link_to_dir pathname !Options.build_dir then + let z = Pathname.readlink pathname in + (* Here is one exception where one can use Sys.file_exists directly *) + (if not (Sys.file_exists z) then + Shell.rm pathname; false) + else true + end entry + +let clean_up_link_to_build () = + Options.entry := Some(clean_up_links (the !Options.entry)) + +let source_dir_path_set_without_links_to_build = + lazy begin + clean_up_link_to_build (); + Slurp.fold (fun path name _ -> StringSet.add (path/name)) + (the !Options.entry) StringSet.empty + end + +let clean_links () = + if !*My_unix.is_degraded then + () + else + ignore (clean_up_link_to_build ()) + +let exists_in_source_dir p = + if !*My_unix.is_degraded then sys_file_exists (in_source_dir p) + else StringSet.mem p !*source_dir_path_set_without_links_to_build + +let clean p = Shell.rm_f p + module Cache = struct - open Pathname.Operators let clean () = Shell.chdir Pathname.pwd; Shell.rm_rf !Options.build_dir @@ -97,6 +138,13 @@ module Cache = struct dprintf 10 "resource_changed:@ %a" print r; (get r).changed <- Yes + let source_is_up_to_date r_in_source_dir r_in_build_dir = + Pathname.exists r_in_build_dir && Digest.file r_in_build_dir = Digest.file r_in_source_dir + + let prod_is_up_to_date p = + let x = in_build_dir p in + not (exists_in_source_dir p) || Pathname.exists x && Pathname.same_contents x (in_source_dir p) + let rec resource_has_changed r = let cache_entry = get r in match cache_entry.changed with @@ -108,19 +156,32 @@ module Cache = struct | Bbuilt -> false | Bsuspension _ -> assert false | Bcannot_be_built -> false - | Bnot_built_yet -> not (Pathname.is_up_to_date false r) in + | Bnot_built_yet -> not (prod_is_up_to_date r) in let () = cache_entry.changed <- if res then Yes else No in res let resource_state r = (get r).built - let resource_is_built r = (get r).built = Bbuilt - let resource_built r = (get r).built <- Bbuilt - let resource_is_failed r = (get r).built = Bcannot_be_built - let resource_failed r = (get r).built <- Bcannot_be_built + let import_in_build_dir r = + if exists_in_source_dir r then begin + let cache_entry = get r in + let r_in_build_dir = in_build_dir r in + let r_in_source_dir = in_source_dir r in + if source_is_up_to_date r_in_source_dir r_in_build_dir then begin + dprintf 5 "%a exists and up to date" print r; + end else begin + dprintf 5 "%a exists in source dir -> import it" print r; + Shell.mkdir_p (Pathname.dirname r); + Pathname.copy r_in_source_dir r_in_build_dir; + cache_entry.changed <- Yes; + end; + cache_entry.built <- Bbuilt; + true + end else false + let suspend_resource r cmd kont prods = let cache_entry = get r in match cache_entry.built with @@ -165,43 +226,16 @@ module Cache = struct let print_dependencies = print_graph - let digest_resource p = - let f = Pathname.to_string (Pathname.in_build_dir p) in - let buf = Buffer.create 1024 in - Buffer.add_string buf f; - (if sys_file_exists f then Buffer.add_string buf (Digest.file f)); - Digest.string (Buffer.contents buf) - - let digests = Hashtbl.create 103 - - let get_digest_for name = - try Some (Hashtbl.find digests name) - with Not_found -> None - let store_digest name d = Hashtbl.replace digests name d - - let _digests = lazy (Pathname.pwd / !Options.build_dir / (Pathname.mk "_digests")) - - let finalize () = - with_output_file !*_digests begin fun oc -> - Hashtbl.iter begin fun name digest -> - Printf.fprintf oc "%S: %S\n" name digest - end digests - end - - let init () = - Shell.chdir !Options.build_dir; - if Pathname.exists !*_digests then - with_input_file !*_digests begin fun ic -> - try while true do - let l = input_line ic in - Scanf.sscanf l "%S: %S" store_digest - done with End_of_file -> () - end; - My_unix.at_exit_once finalize - end -let clean p = Shell.rm_f p +let digest p = + let f = Pathname.to_string (in_build_dir p) in + let buf = Buffer.create 1024 in + Buffer.add_string buf f; + (if sys_file_exists f then Buffer.add_string buf (Digest.file f)); + Digest.string (Buffer.contents buf) + +let exists_in_build_dir p = Pathname.exists (in_build_dir p) (* type env = string @@ -233,8 +267,6 @@ let rec subst percent r = let print_env = pp_print_string *) -let is_up_to_date path = Pathname.is_up_to_date true path - let import x = x module MetaPath : sig |