Rename 'extract-makefile' to 'rules'

This commit is contained in:
Jérémie Dimino 2017-05-19 00:16:48 +01:00
parent 1309a92ec5
commit fe30935fa2
5 changed files with 81 additions and 29 deletions

View File

@ -24,9 +24,6 @@ all-supported-ocaml-versions:
clean: clean:
rm -rf _build rm -rf _build
extract-makefile:
$(BIN) extract-makefile -o Makefile.extracted @install
doc: doc:
cd doc && sphinx-build . _build cd doc && sphinx-build . _build

View File

@ -513,15 +513,26 @@ let external_lib_deps =
& Arg.info [] ~docv:"TARGET")) & Arg.info [] ~docv:"TARGET"))
, Term.info "external-lib-deps" ~doc ~man) , Term.info "external-lib-deps" ~doc ~man)
let extract_makefile = let rules =
let doc = "Extract a makefile that can build the given targets." in let doc = "Dump internal rules." in
let man = let man =
[ `S "DESCRIPTION" [ `S "DESCRIPTION"
; `P {|Extract a makefile that can build the given targets.|} ; `P {|Dump Jbuilder internal rules for the given targets.
If no targets are given, dump all the internal rules.|}
; `P {|By default the output is a list of S-expressions,
one S-expression per rule. Each S-expression is of the form:|}
; `Pre " ((deps (<dependencies>))\n\
\ (targets (<targets>))\n\
\ (context <context-name>)\n\
\ (action <action>))"
; `P {|$(b,<context-name>) is the context is which the action is executed.
It is omitted if the action is independant from the context.|}
; `P {|$(b,<action>) is the action following the same syntax as user actions,
as described in the manual.|}
; `Blocks help_secs ; `Blocks help_secs
] ]
in in
let go common out targets = let go common out recursive makefile_syntax targets =
set_common common; set_common common;
let log = Log.create () in let log = Log.create () in
Future.Scheduler.go ~log Future.Scheduler.go ~log
@ -532,31 +543,66 @@ let extract_makefile =
| [] -> Build_system.all_targets setup.build_system | [] -> Build_system.all_targets setup.build_system
| _ -> resolve_targets ~log common setup targets | _ -> resolve_targets ~log common setup targets
in in
Build_system.build_rules setup.build_system targets >>= fun rules -> Build_system.build_rules setup.build_system targets ~recursive >>= fun rules ->
Io.with_file_out out ~f:(fun oc -> let print oc =
let ppf = Format.formatter_of_out_channel oc in let ppf = Format.formatter_of_out_channel oc in
List.iter rules ~f:(fun (rule : Build_system.Rule.t) -> let get_action (rule : Build_system.Rule.t) =
Format.fprintf ppf "%s:%s\n\t%s\n\n" if Path.is_root rule.action.dir then
(Path.Set.elements rule.targets rule.action.action
|> List.map ~f:Path.to_string else
|> String.concat ~sep:" ") Chdir (rule.action.dir, rule.action.action)
(Path.Set.elements rule.deps in
|> List.map ~f:(fun p -> " " ^ Path.to_string p) if makefile_syntax then begin
|> String.concat ~sep:"") List.iter rules ~f:(fun (rule : Build_system.Rule.t) ->
(Action.sexp_of_t rule.action |> Sexp.to_string)); Format.fprintf ppf "%s:%s\n\t%s\n\n"
Format.pp_print_flush ppf ()); (Path.Set.elements rule.targets
Future.return ()) |> List.map ~f:Path.to_string
|> String.concat ~sep:" ")
(Path.Set.elements rule.deps
|> List.map ~f:(fun p -> " " ^ Path.to_string p)
|> String.concat ~sep:"")
(Action.Mini_shexp.sexp_of_t (get_action rule) |> Sexp.to_string))
end else begin
List.iter rules ~f:(fun (rule : Build_system.Rule.t) ->
let sexp =
let paths ps = Sexp.To_sexp.list Path.sexp_of_t (Path.Set.elements ps) in
Sexp.To_sexp.record (
List.concat
[ [ "deps" , paths rule.deps
; "targets", paths rule.targets ]
; (match rule.action.context with
| None -> []
| Some c -> ["context", Atom c.name])
; [ "action" , Action.Mini_shexp.sexp_of_t (get_action rule) ]
])
in
Format.fprintf ppf "%s\n" (Sexp.to_string sexp))
end;
Format.pp_print_flush ppf ();
Future.return ()
in
match out with
| None -> print stdout
| Some fn -> Io.with_file_out fn ~f:print)
in in
( Term.(const go ( Term.(const go
$ common $ common
$ Arg.(required $ Arg.(value
& opt (some string) None & opt (some string) None
& info ["o"] ~docv:"FILE" & info ["o"] ~docv:"FILE"
~doc:"Output file.") ~doc:"Output to a file instead of stdout.")
$ Arg.(value
& flag
& info ["r"; "recursive"]
~doc:"Print all rules needed to build the transitive dependencies of the given targets.")
$ Arg.(value
& flag
& info ["m"; "makefile"]
~doc:"Output the rules in Makefile syntax.")
$ Arg.(value $ Arg.(value
& pos_all string [] & pos_all string []
& Arg.info [] ~docv:"TARGET")) & Arg.info [] ~docv:"TARGET"))
, Term.info "extract-makefile" ~doc ~man) , Term.info "rules" ~doc ~man)
let opam_installer () = let opam_installer () =
match Bin.which "opam-installer" with match Bin.which "opam-installer" with
@ -727,7 +773,7 @@ let all =
; uninstall ; uninstall
; exec ; exec
; subst ; subst
; extract_makefile ; rules
] ]
let default = let default =

View File

@ -11,7 +11,7 @@ let commands =
; "uninstall" ; "uninstall"
; "exec" ; "exec"
; "subst" ; "subst"
; "extract-makefile" ; "rules"
] ]
let jbuild = let jbuild =

View File

@ -738,7 +738,7 @@ module Rule_closure =
rules_for_files graph (Pset.elements t.deps) rules_for_files graph (Pset.elements t.deps)
end) end)
let build_rules t targets = let build_rules t ?(recursive=false) targets =
let rules_seen = ref Id_set.empty in let rules_seen = ref Id_set.empty in
let rules = ref [] in let rules = ref [] in
let rec loop fn = let rec loop fn =
@ -763,7 +763,10 @@ let build_rules t targets =
in in
rules := rule :: !rules; rules := rule :: !rules;
rule >>= fun rule -> rule >>= fun rule ->
Future.all_unit (List.map (Pset.elements rule.deps) ~f:loop) if recursive then
Future.all_unit (List.map (Pset.elements rule.deps) ~f:loop)
else
return ()
end end
in in
Future.all_unit (List.map targets ~f:loop) Future.all_unit (List.map targets ~f:loop)

View File

@ -53,5 +53,11 @@ module Rule : sig
} }
end end
(** Build and the rules needed to build these targets *) (** Return the list of rules used to build the given targets. If
val build_rules : t -> Path.t list -> Rule.t list Future.t [recursive] is [true], return all the rules needed to build the
given targets and their transitive dependencies. *)
val build_rules
: t
-> ?recursive:bool (* default false *)
-> Path.t list
-> Rule.t list Future.t