From fe30935fa290c6226ecacd865f3e36a8e99b6c8c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20Dimino?= Date: Fri, 19 May 2017 00:16:48 +0100 Subject: [PATCH] Rename 'extract-makefile' to 'rules' --- Makefile | 3 -- bin/main.ml | 88 +++++++++++++++++++++++++++++++++----------- doc/jbuild | 2 +- src/build_system.ml | 7 +++- src/build_system.mli | 10 ++++- 5 files changed, 81 insertions(+), 29 deletions(-) diff --git a/Makefile b/Makefile index 66604f80..4c32ded7 100644 --- a/Makefile +++ b/Makefile @@ -24,9 +24,6 @@ all-supported-ocaml-versions: clean: rm -rf _build -extract-makefile: - $(BIN) extract-makefile -o Makefile.extracted @install - doc: cd doc && sphinx-build . _build diff --git a/bin/main.ml b/bin/main.ml index 984f35ba..fc98c44e 100644 --- a/bin/main.ml +++ b/bin/main.ml @@ -513,15 +513,26 @@ let external_lib_deps = & Arg.info [] ~docv:"TARGET")) , Term.info "external-lib-deps" ~doc ~man) -let extract_makefile = - let doc = "Extract a makefile that can build the given targets." in +let rules = + let doc = "Dump internal rules." in let man = [ `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 ())\n\ + \ (targets ())\n\ + \ (context )\n\ + \ (action ))" + ; `P {|$(b,) is the context is which the action is executed. + It is omitted if the action is independant from the context.|} + ; `P {|$(b,) is the action following the same syntax as user actions, + as described in the manual.|} ; `Blocks help_secs ] in - let go common out targets = + let go common out recursive makefile_syntax targets = set_common common; let log = Log.create () in Future.Scheduler.go ~log @@ -532,31 +543,66 @@ let extract_makefile = | [] -> Build_system.all_targets setup.build_system | _ -> resolve_targets ~log common setup targets in - Build_system.build_rules setup.build_system targets >>= fun rules -> - Io.with_file_out out ~f:(fun oc -> + Build_system.build_rules setup.build_system targets ~recursive >>= fun rules -> + let print oc = let ppf = Format.formatter_of_out_channel oc in - List.iter rules ~f:(fun (rule : Build_system.Rule.t) -> - Format.fprintf ppf "%s:%s\n\t%s\n\n" - (Path.Set.elements rule.targets - |> 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.sexp_of_t rule.action |> Sexp.to_string)); - Format.pp_print_flush ppf ()); - Future.return ()) + let get_action (rule : Build_system.Rule.t) = + if Path.is_root rule.action.dir then + rule.action.action + else + Chdir (rule.action.dir, rule.action.action) + in + if makefile_syntax then begin + List.iter rules ~f:(fun (rule : Build_system.Rule.t) -> + Format.fprintf ppf "%s:%s\n\t%s\n\n" + (Path.Set.elements rule.targets + |> 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 ( Term.(const go $ common - $ Arg.(required + $ Arg.(value & opt (some string) None & 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 & pos_all string [] & Arg.info [] ~docv:"TARGET")) - , Term.info "extract-makefile" ~doc ~man) + , Term.info "rules" ~doc ~man) let opam_installer () = match Bin.which "opam-installer" with @@ -727,7 +773,7 @@ let all = ; uninstall ; exec ; subst - ; extract_makefile + ; rules ] let default = diff --git a/doc/jbuild b/doc/jbuild index 210d1c62..6f1be958 100644 --- a/doc/jbuild +++ b/doc/jbuild @@ -11,7 +11,7 @@ let commands = ; "uninstall" ; "exec" ; "subst" - ; "extract-makefile" + ; "rules" ] let jbuild = diff --git a/src/build_system.ml b/src/build_system.ml index 7b417bf0..07f53b5a 100644 --- a/src/build_system.ml +++ b/src/build_system.ml @@ -738,7 +738,7 @@ module Rule_closure = rules_for_files graph (Pset.elements t.deps) end) -let build_rules t targets = +let build_rules t ?(recursive=false) targets = let rules_seen = ref Id_set.empty in let rules = ref [] in let rec loop fn = @@ -763,7 +763,10 @@ let build_rules t targets = in rules := rule :: !rules; 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 in Future.all_unit (List.map targets ~f:loop) diff --git a/src/build_system.mli b/src/build_system.mli index 02a1feb8..f8b4a225 100644 --- a/src/build_system.mli +++ b/src/build_system.mli @@ -53,5 +53,11 @@ module Rule : sig } end -(** Build and the rules needed to build these targets *) -val build_rules : t -> Path.t list -> Rule.t list Future.t +(** Return the list of rules used to build the given targets. If + [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