@mbacarella wrote:
If you use Jane’s
Core.Command
for command line parsing (and if not, why aren’t you?), it can take arguments like-version
and-build-info
which are super useful if you want to bake in important build information.Aside: why does anyone want this? One excellent release engineer use-case is to figure out which binaries are more than, say, 6 months out of date and schedule them for a refresh. Another one is if you want to hotfix a bug in a binary, but not introduce all of the changes made in the main repo, you can git checkout the version baked into some ad-hoc binary that nobody is quite sure when it was released, and then roll a new release of that which only contains your fix.
Anyway, to get this, you have to have your build system generate some info that you then pass into
Core.Command
.I’m having a bit of trouble doing this with
dune
. I can follow these directions and get pretty close to what I want: https://github.com/ocaml/dune/tree/master/example/sample-projects/with-configure-stepI can stick a dune stanza like this into my
dune
file:(rule (target build_info_gen.ml) (action (run ocaml %{dep:gen_build_info.ml})))m
which runs an script called
gen_build_info.ml
beaver$ cat gen_build_info.ml #load "unix.cma" let sh_line s = let ic = Unix.open_process_in s in let line = input_line ic in close_in ic; line ;; let () = let oc = open_out_bin "build_info_gen.ml" in Printf.fprintf oc {| let git_revision = "%s" ;; let build_host = "%s" ;; let build_user = "%s" ;; let build_time = "%s" ;; let ocamlopt_version = "%s" ;; |} (sh_line "git describe --always --dirty") (sh_line "hostname") (sh_line "whoami") (sh_line "date") (sh_line "ocamlopt --version"); close_out oc ;;
What that will do is generate a module called
build_info_gen.ml
, which I can use in a module calledbuild_info.ml
with sexp to make auto-generation easy.$ cat build_info.ml open! Core type t = { git_revision : string ; build_user : string ; build_host : string ; build_time : string ; ocamlopt_version : string } [@@deriving sexp] let t = { git_revision = Build_info_gen.git_revision ; build_user = Build_info_gen.build_user ; build_host = Build_info_gen.build_host ; build_time = Build_info_gen.build_time ; ocamlopt_version = Build_info_gen.ocamlopt_version } let version = t.git_revision let build_info = sexp_of_t t |> Sexp.to_string_hum
Which I can feed into
Command
inmymain.ml
and get cool stuff to happen:open! Core (*...*) let () = Command.run ~version:Build_info.version ~build_info:Build_info.build_info cmd
Cool stuff:
beaver$ mymain.exe -build-info | sexp pp ((git_revision 095e463-dirty) (build_user mbac) (build_host beaver) (build_time "Fri Jan 3 10:10:44 PST 2020") (ocamlopt_version 4.08.1))
(You can get the
sexp
tool withopam install sexp
if you don’t already have it)This almost works perfectly. What I’m having trouble doing is convincing
dune
it should regeneratebuild_info_gen.ml
every time it tries to build an executable, not just the first time I build the executable.Any pointers on this?
Posts: 2
Participants: 2