parent
98c083db21
commit
951132023c
125
src/gen_rules.ml
125
src/gen_rules.ml
|
@ -301,22 +301,25 @@ module Gen(P : Params) = struct
|
||||||
end
|
end
|
||||||
|
|
||||||
let all_rules = ref []
|
let all_rules = ref []
|
||||||
let known_targets_by_dir_so_far = ref Path.Map.empty
|
let known_targets_by_src_dir_so_far = ref Path.Map.empty
|
||||||
|
|
||||||
let add_rule build =
|
let add_rule build =
|
||||||
let rule = Build_interpret.Rule.make build in
|
let rule = Build_interpret.Rule.make build in
|
||||||
all_rules := rule :: !all_rules;
|
all_rules := rule :: !all_rules;
|
||||||
known_targets_by_dir_so_far :=
|
known_targets_by_src_dir_so_far :=
|
||||||
List.fold_left rule.targets ~init:!known_targets_by_dir_so_far ~f:(fun acc target ->
|
List.fold_left rule.targets ~init:!known_targets_by_src_dir_so_far
|
||||||
let path = Build_interpret.Target.path target in
|
~f:(fun acc target ->
|
||||||
let dir = Path.parent path in
|
match Path.extract_build_context (Build_interpret.Target.path target) with
|
||||||
let fn = Path.basename path in
|
| None -> acc
|
||||||
let files =
|
| Some (_, path) ->
|
||||||
match Path.Map.find dir acc with
|
let dir = Path.parent path in
|
||||||
| None -> String_set.singleton fn
|
let fn = Path.basename path in
|
||||||
| Some set -> String_set.add fn set
|
let files =
|
||||||
in
|
match Path.Map.find dir acc with
|
||||||
Path.Map.add acc ~key:dir ~data:files)
|
| None -> String_set.singleton fn
|
||||||
|
| Some set -> String_set.add fn set
|
||||||
|
in
|
||||||
|
Path.Map.add acc ~key:dir ~data:files)
|
||||||
|
|
||||||
let sources_and_targets_known_so_far ~src_path =
|
let sources_and_targets_known_so_far ~src_path =
|
||||||
let sources =
|
let sources =
|
||||||
|
@ -324,7 +327,7 @@ module Gen(P : Params) = struct
|
||||||
| None -> String_set.empty
|
| None -> String_set.empty
|
||||||
| Some dir -> File_tree.Dir.files dir
|
| Some dir -> File_tree.Dir.files dir
|
||||||
in
|
in
|
||||||
match Path.Map.find src_path !known_targets_by_dir_so_far with
|
match Path.Map.find src_path !known_targets_by_src_dir_so_far with
|
||||||
| None -> sources
|
| None -> sources
|
||||||
| Some set -> String_set.union sources set
|
| Some set -> String_set.union sources set
|
||||||
|
|
||||||
|
@ -1454,62 +1457,74 @@ module Gen(P : Params) = struct
|
||||||
let impls = parse_one_set ml_files in
|
let impls = parse_one_set ml_files in
|
||||||
let intfs = parse_one_set mli_files in
|
let intfs = parse_one_set mli_files in
|
||||||
String_map.merge impls intfs ~f:(fun name ml_fname mli_fname ->
|
String_map.merge impls intfs ~f:(fun name ml_fname mli_fname ->
|
||||||
match ml_fname with
|
let ml_fname =
|
||||||
| None ->
|
match ml_fname with
|
||||||
die "module %s in %s doesn't have a corresponding .ml file"
|
| None ->
|
||||||
name (Path.to_string dir)
|
let mli_fname = Option.value_exn mli_fname in
|
||||||
| Some ml_fname ->
|
let ml_fname = String.sub mli_fname ~pos:0 ~len:(String.length mli_fname - 1) in
|
||||||
Some
|
Format.eprintf
|
||||||
{ Module.
|
"@{<warning>Warning@}: module %s in %s doesn't have a corresponding\
|
||||||
name
|
.ml file.\n\
|
||||||
; ml_fname = ml_fname
|
I'm setting up a rule for copying %s to %s.\n"
|
||||||
; mli_fname = mli_fname
|
name (Path.to_string dir)
|
||||||
; obj_name = ""
|
mli_fname ml_fname;
|
||||||
})
|
let dir = Path.append ctx.build_dir dir in
|
||||||
|
add_rule
|
||||||
|
(Build.copy
|
||||||
|
~src:(Path.relative dir mli_fname)
|
||||||
|
~dst:(Path.relative dir ml_fname));
|
||||||
|
ml_fname
|
||||||
|
| Some ml_fname -> ml_fname
|
||||||
|
in
|
||||||
|
Some
|
||||||
|
{ Module.
|
||||||
|
name
|
||||||
|
; ml_fname = ml_fname
|
||||||
|
; mli_fname = mli_fname
|
||||||
|
; obj_name = ""
|
||||||
|
})
|
||||||
|
|
||||||
(* +-----------------------------------------------------------------+
|
(* +-----------------------------------------------------------------+
|
||||||
| Stanza |
|
| Stanza |
|
||||||
+-----------------------------------------------------------------+ *)
|
+-----------------------------------------------------------------+ *)
|
||||||
|
|
||||||
let rules { src_dir; ctx_dir; stanzas } =
|
let rules { src_dir; ctx_dir; stanzas } =
|
||||||
|
(* Interpret user rules and other simple stanzas first in order to populate the known
|
||||||
|
target table, which is needed for guessing the list of modules. *)
|
||||||
|
List.iter stanzas ~f:(fun stanza ->
|
||||||
|
let dir = ctx_dir in
|
||||||
|
match (stanza : Stanza.t) with
|
||||||
|
| Rule rule -> user_rule rule ~dir
|
||||||
|
| Ocamllex conf -> ocamllex_rules conf ~dir
|
||||||
|
| Ocamlyacc conf -> ocamlyacc_rules conf ~dir
|
||||||
|
| Alias alias -> alias_rules alias ~dir
|
||||||
|
| Library _ | Executables _ | Provides _ | Install _ -> ());
|
||||||
let files = lazy (
|
let files = lazy (
|
||||||
let src_files =
|
let files = sources_and_targets_known_so_far ~src_path:src_dir in
|
||||||
match File_tree.find_dir P.file_tree src_dir with
|
(* Manually add files generated by the (select ...) dependencies since we haven't
|
||||||
| None -> String_set.empty
|
interpreted libraries and executables yet. *)
|
||||||
| Some dir -> File_tree.Dir.files dir
|
List.fold_left stanzas ~init:files ~f:(fun acc stanza ->
|
||||||
in
|
match (stanza : Stanza.t) with
|
||||||
let files_produced_by_rules =
|
| Library { buildable; _ } | Executables { buildable; _ } ->
|
||||||
List.concat_map stanzas ~f:(fun stanza ->
|
List.fold_left buildable.libraries ~init:acc ~f:(fun acc dep ->
|
||||||
match (stanza : Stanza.t) with
|
match (dep : Jbuild_types.Lib_dep.t) with
|
||||||
| Rule rule -> rule.targets
|
| Direct _ -> acc
|
||||||
| Ocamllex conf -> List.map conf.names ~f:(fun name -> name ^ ".ml")
|
| Select s -> String_set.add s.result_fn acc)
|
||||||
| Ocamlyacc conf -> List.concat_map conf.names ~f:(fun name ->
|
| _ -> acc)
|
||||||
[ name ^ ".ml"; name ^ ".mli" ])
|
) in
|
||||||
| Library { buildable; _ } | Executables { buildable; _ } ->
|
|
||||||
List.filter_map buildable.libraries ~f:(function
|
|
||||||
| Direct _ -> None
|
|
||||||
| Select s -> Some s.result_fn)
|
|
||||||
| _ -> [])
|
|
||||||
|> String_set.of_list
|
|
||||||
in
|
|
||||||
String_set.union src_files files_produced_by_rules)
|
|
||||||
in
|
|
||||||
let all_modules = lazy (
|
let all_modules = lazy (
|
||||||
guess_modules ~dir:src_dir
|
guess_modules ~dir:src_dir
|
||||||
~files:(Lazy.force files))
|
~files:(Lazy.force files))
|
||||||
in
|
in
|
||||||
let some x = Some x in
|
|
||||||
let none () = None in
|
|
||||||
List.filter_map stanzas ~f:(fun stanza ->
|
List.filter_map stanzas ~f:(fun stanza ->
|
||||||
let dir = ctx_dir in
|
let dir = ctx_dir in
|
||||||
match (stanza : Stanza.t) with
|
match (stanza : Stanza.t) with
|
||||||
| Library lib -> library_rules lib ~dir ~all_modules:(Lazy.force all_modules) ~files:(Lazy.force files) |> some
|
| Library lib ->
|
||||||
| Executables exes -> executables_rules exes ~dir ~all_modules:(Lazy.force all_modules) |> some
|
Some (library_rules lib ~dir
|
||||||
| Rule rule -> user_rule rule ~dir |> none
|
~all_modules:(Lazy.force all_modules) ~files:(Lazy.force files))
|
||||||
| Ocamllex conf -> ocamllex_rules conf ~dir |> none
|
| Executables exes ->
|
||||||
| Ocamlyacc conf -> ocamlyacc_rules conf ~dir |> none
|
Some (executables_rules exes ~dir ~all_modules:(Lazy.force all_modules))
|
||||||
| Alias alias -> alias_rules alias ~dir |> none
|
| _ -> None)
|
||||||
| Provides _ | Install _ -> () |> none)
|
|
||||||
|> merge_dot_merlin ~dir:ctx_dir
|
|> merge_dot_merlin ~dir:ctx_dir
|
||||||
|
|
||||||
let () = List.iter P.stanzas ~f:rules
|
let () = List.iter P.stanzas ~f:rules
|
||||||
|
|
Loading…
Reference in New Issue