From 0823f9d803b9fe46b3083ffb288ecd90a187cb06 Mon Sep 17 00:00:00 2001 From: Rudi Grinberg Date: Mon, 12 Mar 2018 23:38:23 +0700 Subject: [PATCH 1/7] allow_private_deps flag Flag to guard public dependencies from acquiring private ones --- src/lib.ml | 80 ++++++++++++++++++++++++++++++++++++++++------------- src/lib.mli | 10 +++++++ 2 files changed, 71 insertions(+), 19 deletions(-) diff --git a/src/lib.ml b/src/lib.ml index 02db9ca1..dc83e14d 100644 --- a/src/lib.ml +++ b/src/lib.ml @@ -10,6 +10,18 @@ module Status = struct | Installed | Public | Private of Jbuild.Scope_info.Name.t + + let pp ppf t = + Format.pp_print_string ppf + (match t with + | Installed -> "installed" + | Public -> "public" + | Private s -> + sprintf "private (%s)" (Jbuild.Scope_info.Name.to_string s)) + + let is_private = function + | Private _ -> true + | Installed | Public -> false end module Info = struct @@ -254,6 +266,7 @@ and error = | Dependency_cycle of (Path.t * string) list | Conflict of conflict | Overlap of overlap + | Private_deps_not_allowed of private_deps_not_allowed and resolve_result = | Not_found @@ -271,6 +284,11 @@ and overlap = ; installed : t * Dep_path.Entry.t list } +and private_deps_not_allowed = + { private_dep : t + ; pd_loc : Loc.t + } + and 'a or_error = ('a, exn) result type lib = t @@ -292,12 +310,20 @@ module Error = struct } end + module Private_deps_not_allowed = struct + type nonrec t = private_deps_not_allowed = + { private_dep : t + ; pd_loc : Loc.t + } + end + type t = error = | Library_not_available of Library_not_available.t | No_solution_found_for_select of No_solution_found_for_select.t | Dependency_cycle of (Path.t * string) list | Conflict of Conflict.t | Overlap of Overlap.t + | Private_deps_not_allowed of Private_deps_not_allowed.t end exception Error of Error.t @@ -560,11 +586,13 @@ let rec instantiate db name (info : Info.t) ~stack ~hidden = (* Add [id] to the table, to detect loops *) Hashtbl.add db.table name (St_initializing id); + let allow_private_deps = Status.is_private info.status in + let requires, pps, resolved_selects = - resolve_user_deps db info.requires ~pps:info.pps ~stack + resolve_user_deps db info.requires ~allow_private_deps ~pps:info.pps ~stack in let ppx_runtime_deps = - resolve_simple_deps db info.ppx_runtime_deps ~stack + resolve_simple_deps db info.ppx_runtime_deps ~allow_private_deps ~stack in let map_error x = Result.map_error x ~f:(fun e -> @@ -572,7 +600,8 @@ let rec instantiate db name (info : Info.t) ~stack ~hidden = in let requires = map_error requires in let ppx_runtime_deps = map_error ppx_runtime_deps in - let resolve (loc, name) = resolve_dep db name ~loc ~stack in + let resolve (loc, name) = + resolve_dep db name ~allow_private_deps ~loc ~stack in let t = { loc = info.loc ; name = name @@ -633,12 +662,16 @@ and find_internal db name ~stack : status = | Some x -> x | None -> resolve_name db name ~stack -and resolve_dep db name ~loc ~stack : (t, exn) result = +and resolve_dep db name ~allow_private_deps ~loc ~stack : (t, exn) result = match find_internal db name ~stack with | St_initializing id -> Error (Dep_stack.dependency_cycle stack id) | St_found t -> - Ok t + if (not allow_private_deps) && Status.is_private t.status then ( + failwith "" + ) else ( + Ok t + ) | St_not_found -> Error (Error (Library_not_available { loc; name; reason = Not_found })) | St_hidden (_, hidden) -> @@ -677,27 +710,27 @@ and resolve_name db name ~stack = instantiate db name info ~stack ~hidden:(Some hidden) and available_internal db name ~stack = - match resolve_dep db name ~loc:Loc.none ~stack with + match resolve_dep db name ~allow_private_deps:true ~loc:Loc.none ~stack with | Ok _ -> true | Error _ -> false -and resolve_simple_deps db names ~stack = +and resolve_simple_deps db names ~allow_private_deps ~stack = let rec loop acc = function | [] -> Ok (List.rev acc) | (loc, name) :: names -> - resolve_dep db name ~loc ~stack >>= fun x -> + resolve_dep db name ~allow_private_deps ~loc ~stack >>= fun x -> loop (x :: acc) names in loop [] names -and resolve_complex_deps db deps ~stack = +and resolve_complex_deps db deps ~allow_private_deps ~stack = let res, resolved_selects = List.fold_left deps ~init:(Ok [], []) ~f:(fun (acc_res, acc_selects) dep -> let res, acc_selects = match (dep : Jbuild.Lib_dep.t) with | Direct (loc, name) -> let res = - resolve_dep db name ~loc ~stack >>| fun x -> [x] + resolve_dep db name ~allow_private_deps ~loc ~stack >>| fun x -> [x] in (res, acc_selects) | Select { result_fn; choices; loc } -> @@ -713,7 +746,7 @@ and resolve_complex_deps db deps ~stack = String_set.fold required ~init:[] ~f:(fun x acc -> (Loc.none, x) :: acc) in - resolve_simple_deps db deps ~stack + resolve_simple_deps ~allow_private_deps db deps ~stack with | Ok ts -> Some (ts, file) | Error _ -> None) @@ -742,20 +775,23 @@ and resolve_complex_deps db deps ~stack = in (res, resolved_selects) -and resolve_deps db deps ~stack = +and resolve_deps db deps ~allow_private_deps ~stack = match (deps : Info.Deps.t) with - | Simple names -> (resolve_simple_deps db names ~stack, []) - | Complex names -> resolve_complex_deps db names ~stack + | Simple names -> + (resolve_simple_deps db names ~allow_private_deps ~stack, []) + | Complex names -> + resolve_complex_deps ~allow_private_deps db names ~stack -and resolve_user_deps db deps ~pps ~stack = - let deps, resolved_selects = resolve_deps db deps ~stack in +and resolve_user_deps db deps ~allow_private_deps ~pps ~stack = + let deps, resolved_selects = + resolve_deps db deps ~allow_private_deps ~stack in let deps, pps = match pps with | [] -> (deps, Ok []) | pps -> let pps = let pps = (pps : (Loc.t * Jbuild.Pp.t) list :> (Loc.t * string) list) in - resolve_simple_deps db pps ~stack >>= fun pps -> + resolve_simple_deps db pps ~allow_private_deps ~stack >>= fun pps -> closure_with_overlap_checks None pps ~stack in let deps = @@ -996,7 +1032,7 @@ module DB = struct let resolve_user_written_deps t ?(allow_overlaps=false) deps ~pps = let res, pps, resolved_selects = resolve_user_deps t (Info.Deps.of_lib_deps deps) ~pps - ~stack:Dep_stack.empty + ~stack:Dep_stack.empty ~allow_private_deps:true in let requires = res @@ -1014,7 +1050,7 @@ module DB = struct } let resolve_pps t pps = - resolve_simple_deps t + resolve_simple_deps t ~allow_private_deps:true (pps : (Loc.t *Jbuild.Pp.t) list :> (Loc.t * string) list) ~stack:Dep_stack.empty @@ -1103,6 +1139,12 @@ let report_lib_error ppf (e : Error.t) = Format.fprintf ppf "-> %S in %s" name (Path.to_string_maybe_quoted path))) cycle + | Private_deps_not_allowed (t : private_deps_not_allowed) -> + Format.fprintf ppf + "%a@{Error@}: Public libraries may not have private dependencies.\ + \nPrivate dependency %S encountered in public library:\n" + Loc.print t.pd_loc + t.private_dep.name let () = Report_error.register (fun exn -> diff --git a/src/lib.mli b/src/lib.mli index 335cb65f..d35f55f3 100644 --- a/src/lib.mli +++ b/src/lib.mli @@ -37,6 +37,8 @@ module Status : sig | Installed | Public | Private of Jbuild.Scope_info.Name.t + + val pp : t Fmt.t end val status : t -> Status.t @@ -146,12 +148,20 @@ module Error : sig } end + module Private_deps_not_allowed : sig + type nonrec t = + { private_dep : t + ; pd_loc : Loc.t + } + end + type t = | Library_not_available of Library_not_available.t | No_solution_found_for_select of No_solution_found_for_select.t | Dependency_cycle of (Path.t * string) list | Conflict of Conflict.t | Overlap of Overlap.t + | Private_deps_not_allowed of Private_deps_not_allowed.t end exception Error of Error.t From b2258b6c98f92b123e0310af83ad1c5b72facb3c Mon Sep 17 00:00:00 2001 From: Rudi Grinberg Date: Mon, 12 Mar 2018 23:59:52 +0700 Subject: [PATCH 2/7] Remove private/public overlap from meta tests Those will go in their own test --- test/blackbox-tests/test-cases/meta-gen/jbuild | 5 +---- test/blackbox-tests/test-cases/meta-gen/run.t | 2 +- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/test/blackbox-tests/test-cases/meta-gen/jbuild b/test/blackbox-tests/test-cases/meta-gen/jbuild index 41c833fc..01bed966 100644 --- a/test/blackbox-tests/test-cases/meta-gen/jbuild +++ b/test/blackbox-tests/test-cases/meta-gen/jbuild @@ -6,13 +6,10 @@ (public_name foobar) (synopsis "contains \"quotes\""))) -(library - ((name privatelib))) - (library ((name foobar_baz) (public_name foobar.baz) - (libraries (bytes privatelib)) + (libraries (bytes)) (modes (byte)) (synopsis "sub library with modes set to byte"))) diff --git a/test/blackbox-tests/test-cases/meta-gen/run.t b/test/blackbox-tests/test-cases/meta-gen/run.t index 418b7965..bf5d1d34 100644 --- a/test/blackbox-tests/test-cases/meta-gen/run.t +++ b/test/blackbox-tests/test-cases/meta-gen/run.t @@ -8,7 +8,7 @@ package "baz" ( directory = "baz" description = "sub library with modes set to byte" - requires = "bytes privatelib" + requires = "bytes" archive(byte) = "foobar_baz.cma" archive(native) = "foobar_baz.cmxa" plugin(byte) = "foobar_baz.cma" From 753badd4815ad3cce8bf8ff3359b77e05f7e4acc Mon Sep 17 00:00:00 2001 From: Rudi Grinberg Date: Tue, 13 Mar 2018 00:02:28 +0700 Subject: [PATCH 3/7] Fix private deps check for ppx runtime dependencies --- src/lib.ml | 34 ++++++++++++------- .../test-cases/private-public-overlap/run.t | 22 ++++-------- 2 files changed, 28 insertions(+), 28 deletions(-) diff --git a/src/lib.ml b/src/lib.ml index dc83e14d..b7eb37b8 100644 --- a/src/lib.ml +++ b/src/lib.ml @@ -548,6 +548,14 @@ module Dep_stack = struct } end +let check_private_deps ~(lib : lib) ~loc ~allow_private_deps = + if (not allow_private_deps) && Status.is_private lib.status then ( + Result.Error (Error ( + Private_deps_not_allowed { private_dep = lib ; pd_loc = loc })) + ) else ( + Ok lib + ) + let already_in_table (info : Info.t) name x = let to_sexp = Sexp.To_sexp.(pair Path.sexp_of_t string) in let sexp = @@ -666,12 +674,7 @@ and resolve_dep db name ~allow_private_deps ~loc ~stack : (t, exn) result = match find_internal db name ~stack with | St_initializing id -> Error (Dep_stack.dependency_cycle stack id) - | St_found t -> - if (not allow_private_deps) && Status.is_private t.status then ( - failwith "" - ) else ( - Ok t - ) + | St_found lib -> check_private_deps ~lib ~loc ~allow_private_deps | St_not_found -> Error (Error (Library_not_available { loc; name; reason = Not_found })) | St_hidden (_, hidden) -> @@ -778,7 +781,7 @@ and resolve_complex_deps db deps ~allow_private_deps ~stack = and resolve_deps db deps ~allow_private_deps ~stack = match (deps : Info.Deps.t) with | Simple names -> - (resolve_simple_deps db names ~allow_private_deps ~stack, []) + (resolve_simple_deps db names ~allow_private_deps ~stack, []) | Complex names -> resolve_complex_deps ~allow_private_deps db names ~stack @@ -791,15 +794,21 @@ and resolve_user_deps db deps ~allow_private_deps ~pps ~stack = | pps -> let pps = let pps = (pps : (Loc.t * Jbuild.Pp.t) list :> (Loc.t * string) list) in - resolve_simple_deps db pps ~allow_private_deps ~stack >>= fun pps -> + resolve_simple_deps db pps ~allow_private_deps:true ~stack + >>= fun pps -> closure_with_overlap_checks None pps ~stack in let deps = - let rec loop acc = function + let rec check_deps acc pps ~loc = function + | [] -> loop acc pps + | lib :: ppx_rts -> + check_private_deps ~lib ~loc ~allow_private_deps >>= fun rt -> + check_deps (rt :: acc) pps ~loc ppx_rts + and loop acc = function | [] -> Ok acc | pp :: pps -> pp.ppx_runtime_deps >>= fun rt_deps -> - loop (List.rev_append rt_deps acc) pps + check_deps acc pps ~loc:pp.loc rt_deps in deps >>= fun deps -> pps >>= fun pps -> @@ -1141,10 +1150,11 @@ let report_lib_error ppf (e : Error.t) = cycle | Private_deps_not_allowed (t : private_deps_not_allowed) -> Format.fprintf ppf - "%a@{Error@}: Public libraries may not have private dependencies.\ - \nPrivate dependency %S encountered in public library:\n" + "%a@{Error@}: Library %S is private, it cannot be a dependency of\ + a public library.\nYou need to give %S a public name.\n" Loc.print t.pd_loc t.private_dep.name + t.private_dep.name let () = Report_error.register (fun exn -> diff --git a/test/blackbox-tests/test-cases/private-public-overlap/run.t b/test/blackbox-tests/test-cases/private-public-overlap/run.t index 436b2420..cf0acd4b 100644 --- a/test/blackbox-tests/test-cases/private-public-overlap/run.t +++ b/test/blackbox-tests/test-cases/private-public-overlap/run.t @@ -1,15 +1,10 @@ public libraries may not have private dependencies $ $JBUILDER build -j1 --display short --root private-dep 2>&1 | grep -v Entering + File "jbuild", line 1, characters 0-155: + Error: Library "privatelib" is private, it cannot be a dependency ofa public library. You need to give "privatelib" a public name + -> required by library "publiclib" in _build/default ocamldep publiclib.ml.d - ocamldep privatelib.ml.d - ocamlc .privatelib.objs/privatelib.{cmi,cmo,cmt} - ocamlc .publiclib.objs/publiclib.{cmi,cmo,cmt} - ocamlc publiclib.cma - ocamlopt .privatelib.objs/privatelib.{cmx,o} - ocamlopt .publiclib.objs/publiclib.{cmx,o} - ocamlopt publiclib.{a,cmxa} - ocamlopt publiclib.cmxs On the other hand, public libraries may have private preprocessors $ $JBUILDER build -j1 --display short --root private-rewriter 2>&1 | grep -v Entering @@ -27,20 +22,15 @@ On the other hand, public libraries may have private preprocessors Unless they introduce private runtime dependencies: $ $JBUILDER build -j1 --display short --root private-runtime-deps 2>&1 | grep -v Entering + File "jbuild", line 8, characters 1-143: + Error: Library "private_runtime_dep" is private, it cannot be a dependency ofa public library. You need to give "private_runtime_dep" a public name + -> required by library "mylib" in _build/default ocamlc .private_ppx.objs/private_ppx.{cmi,cmo,cmt} ocamlopt .private_ppx.objs/private_ppx.{cmx,o} ocamlopt private_ppx.{a,cmxa} ocamlopt .ppx/private_ppx@mylib/ppx.exe ppx mylib.pp.ml ocamldep mylib.pp.ml.d - ocamldep private_runtime_dep.ml.d - ocamlc .private_runtime_dep.objs/private_runtime_dep.{cmi,cmo,cmt} - ocamlc .mylib.objs/mylib.{cmi,cmo,cmt} - ocamlc mylib.cma - ocamlopt .private_runtime_dep.objs/private_runtime_dep.{cmx,o} - ocamlopt .mylib.objs/mylib.{cmx,o} - ocamlopt mylib.{a,cmxa} - ocamlopt mylib.cmxs However, public binaries may accept private dependencies $ $JBUILDER build -j1 --display short --root exes 2>&1 | grep -v Entering From 69209d72437b2e4a75e7778b20ead3c91f3b7100 Mon Sep 17 00:00:00 2001 From: Jeremie Dimino Date: Mon, 12 Mar 2018 17:53:00 +0000 Subject: [PATCH 4/7] Remove extra parentheses --- src/lib.ml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/lib.ml b/src/lib.ml index b7eb37b8..e47a0900 100644 --- a/src/lib.ml +++ b/src/lib.ml @@ -549,12 +549,11 @@ module Dep_stack = struct end let check_private_deps ~(lib : lib) ~loc ~allow_private_deps = - if (not allow_private_deps) && Status.is_private lib.status then ( + if (not allow_private_deps) && Status.is_private lib.status then Result.Error (Error ( Private_deps_not_allowed { private_dep = lib ; pd_loc = loc })) - ) else ( + else Ok lib - ) let already_in_table (info : Info.t) name x = let to_sexp = Sexp.To_sexp.(pair Path.sexp_of_t string) in From 178e26cfd956ddcec83f5aa3ea478e6ba13bbfc0 Mon Sep 17 00:00:00 2001 From: Jeremie Dimino Date: Mon, 12 Mar 2018 17:56:24 +0000 Subject: [PATCH 5/7] Use a more informative name --- src/lib.ml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/lib.ml b/src/lib.ml index e47a0900..0142797c 100644 --- a/src/lib.ml +++ b/src/lib.ml @@ -798,16 +798,16 @@ and resolve_user_deps db deps ~allow_private_deps ~pps ~stack = closure_with_overlap_checks None pps ~stack in let deps = - let rec check_deps acc pps ~loc = function + let rec check_runtime_deps acc pps ~loc = function | [] -> loop acc pps | lib :: ppx_rts -> check_private_deps ~lib ~loc ~allow_private_deps >>= fun rt -> - check_deps (rt :: acc) pps ~loc ppx_rts + check_runtime_deps (rt :: acc) pps ~loc ppx_rts and loop acc = function | [] -> Ok acc | pp :: pps -> pp.ppx_runtime_deps >>= fun rt_deps -> - check_deps acc pps ~loc:pp.loc rt_deps + check_runtime_deps acc pps ~loc:pp.loc rt_deps in deps >>= fun deps -> pps >>= fun pps -> From 7e361d596ee942ac3819f871973cc41ee6a483ef Mon Sep 17 00:00:00 2001 From: Jeremie Dimino Date: Mon, 12 Mar 2018 17:58:54 +0000 Subject: [PATCH 6/7] Let Report_error print the location for Private_deps_not_allowed --- src/lib.ml | 7 ++++--- .../test-cases/private-public-overlap/run.t | 8 ++++---- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/lib.ml b/src/lib.ml index 0142797c..6eb0bffb 100644 --- a/src/lib.ml +++ b/src/lib.ml @@ -1147,11 +1147,10 @@ let report_lib_error ppf (e : Error.t) = Format.fprintf ppf "-> %S in %s" name (Path.to_string_maybe_quoted path))) cycle - | Private_deps_not_allowed (t : private_deps_not_allowed) -> + | Private_deps_not_allowed t -> Format.fprintf ppf - "%a@{Error@}: Library %S is private, it cannot be a dependency of\ + "@{Error@}: Library %S is private, it cannot be a dependency of \ a public library.\nYou need to give %S a public name.\n" - Loc.print t.pd_loc t.private_dep.name t.private_dep.name @@ -1167,6 +1166,8 @@ let () = | [] -> (* during bootstrap *) None | l -> Some (List.map l ~f:quote_for_shell |> String.concat ~sep:" ")) + | Private_deps_not_allowed t -> + (Some t.pd_loc, None) | _ -> (None, None) in Some diff --git a/test/blackbox-tests/test-cases/private-public-overlap/run.t b/test/blackbox-tests/test-cases/private-public-overlap/run.t index cf0acd4b..d1719a24 100644 --- a/test/blackbox-tests/test-cases/private-public-overlap/run.t +++ b/test/blackbox-tests/test-cases/private-public-overlap/run.t @@ -2,8 +2,8 @@ public libraries may not have private dependencies $ $JBUILDER build -j1 --display short --root private-dep 2>&1 | grep -v Entering File "jbuild", line 1, characters 0-155: - Error: Library "privatelib" is private, it cannot be a dependency ofa public library. You need to give "privatelib" a public name - -> required by library "publiclib" in _build/default + Error: Library "privatelib" is private, it cannot be a dependency of a public library. + You need to give "privatelib" a public name. ocamldep publiclib.ml.d On the other hand, public libraries may have private preprocessors @@ -23,8 +23,8 @@ On the other hand, public libraries may have private preprocessors Unless they introduce private runtime dependencies: $ $JBUILDER build -j1 --display short --root private-runtime-deps 2>&1 | grep -v Entering File "jbuild", line 8, characters 1-143: - Error: Library "private_runtime_dep" is private, it cannot be a dependency ofa public library. You need to give "private_runtime_dep" a public name - -> required by library "mylib" in _build/default + Error: Library "private_runtime_dep" is private, it cannot be a dependency of a public library. + You need to give "private_runtime_dep" a public name. ocamlc .private_ppx.objs/private_ppx.{cmi,cmo,cmt} ocamlopt .private_ppx.objs/private_ppx.{cmx,o} ocamlopt private_ppx.{a,cmxa} From e57a7069607ba012573540f923bfdc7559eee246 Mon Sep 17 00:00:00 2001 From: Jeremie Dimino Date: Mon, 12 Mar 2018 18:06:58 +0000 Subject: [PATCH 7/7] Use the use-site location for errors from pps --- src/lib.ml | 13 +++++++++---- .../test-cases/private-public-overlap/run.t | 2 +- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/src/lib.ml b/src/lib.ml index 6eb0bffb..39573dbd 100644 --- a/src/lib.ml +++ b/src/lib.ml @@ -790,7 +790,12 @@ and resolve_user_deps db deps ~allow_private_deps ~pps ~stack = let deps, pps = match pps with | [] -> (deps, Ok []) - | pps -> + | first :: others as pps -> + (* Location of the list of ppx rewriters *) + let loc = + let last = Option.value (List.last others) ~default:first in + { (fst first) with stop = (fst last).stop } + in let pps = let pps = (pps : (Loc.t * Jbuild.Pp.t) list :> (Loc.t * string) list) in resolve_simple_deps db pps ~allow_private_deps:true ~stack @@ -798,16 +803,16 @@ and resolve_user_deps db deps ~allow_private_deps ~pps ~stack = closure_with_overlap_checks None pps ~stack in let deps = - let rec check_runtime_deps acc pps ~loc = function + let rec check_runtime_deps acc pps = function | [] -> loop acc pps | lib :: ppx_rts -> check_private_deps ~lib ~loc ~allow_private_deps >>= fun rt -> - check_runtime_deps (rt :: acc) pps ~loc ppx_rts + check_runtime_deps (rt :: acc) pps ppx_rts and loop acc = function | [] -> Ok acc | pp :: pps -> pp.ppx_runtime_deps >>= fun rt_deps -> - check_runtime_deps acc pps ~loc:pp.loc rt_deps + check_runtime_deps acc pps rt_deps in deps >>= fun deps -> pps >>= fun pps -> diff --git a/test/blackbox-tests/test-cases/private-public-overlap/run.t b/test/blackbox-tests/test-cases/private-public-overlap/run.t index d1719a24..555d7596 100644 --- a/test/blackbox-tests/test-cases/private-public-overlap/run.t +++ b/test/blackbox-tests/test-cases/private-public-overlap/run.t @@ -22,7 +22,7 @@ On the other hand, public libraries may have private preprocessors Unless they introduce private runtime dependencies: $ $JBUILDER build -j1 --display short --root private-runtime-deps 2>&1 | grep -v Entering - File "jbuild", line 8, characters 1-143: + File "jbuild", line 1, characters 0-327: Error: Library "private_runtime_dep" is private, it cannot be a dependency of a public library. You need to give "private_runtime_dep" a public name. ocamlc .private_ppx.objs/private_ppx.{cmi,cmo,cmt}