obazl / rules_ocaml

A Bazel Language Support Package for OCaml
https://obazl.github.io/docs_obazl
Apache License 2.0
32 stars 7 forks source link

ocaml_library aggregation #44

Open mobileink opened 2 years ago

mobileink commented 2 years ago

A Dune library (unwrapped) may include modules from multiple subdirectories. To support this in OBazl, we to be able to aggregate ocaml_library targets: if lib A depends on libs B and C, then A should provide all the deps of B and C.

Use case: the main dune file of the OCaml compiler:

(copy_files# utils/*.ml{,i})
(copy_files# parsing/*.ml{,i})
(copy_files# typing/*.ml{,i})
(copy_files# bytecomp/*.ml{,i})
(copy_files# driver/*.ml{,i})
(copy_files# asmcomp/*.ml{,i})
(copy_files# file_formats/*.ml{,i})
(copy_files# lambda/*.ml{,i})
(copy_files# middle_end/*.ml{,i})
(copy_files# middle_end/closure/*.ml{,i})
(copy_files# middle_end/flambda/*.ml{,i})
(copy_files# middle_end/flambda/base_types/*.ml{,i})

(library
 (name ocamlcommon)
 (wrapped false)
 (flags (:standard -principal -nostdlib))
 (libraries stdlib)
 (modules_without_implementation
   annot asttypes cmo_format outcometree parsetree)
 (modules
   ;; UTILS
   config build_path_prefix_map misc identifiable numbers arg_helper clflags
   profile terminfo ccomp warnings consistbl strongly_connected_components
   targetint load_path int_replace_polymorphic_compare binutils local_store
   lazy_backtrack diffing diffing_with_keys

   ;; PARSING
   location longident docstrings syntaxerr ast_helper camlinternalMenhirLib
   parser lexer parse printast pprintast ast_mapper ast_iterator attr_helper
   builtin_attributes ast_invariants depend
   ; manual update: mli only files
   asttypes parsetree

   ;; TYPING
   ident path primitive types btype oprint subst predef datarepr
   cmi_format persistent_env env type_immediacy errortrace
   typedtree printtyped ctype printtyp includeclass mtype envaux includecore
   tast_iterator tast_mapper signature_group cmt_format untypeast
   includemod includemod_errorprinter
   typetexp patterns printpat parmatch stypes typedecl typeopt rec_check
   typecore
   typeclass typemod typedecl_variance typedecl_properties typedecl_immediacy
   typedecl_unboxed typedecl_separability cmt2annot
   ; manual update: mli only files
   annot outcometree

   ;; lambda/
   debuginfo lambda matching printlambda runtimedef simplif switch
   translattribute translclass translcore translmod translobj translprim

   ;; bytecomp/
   meta opcodes bytesections dll symtable

   ;; some of COMP
   pparse main_args compenv compmisc makedepend compile_common
   ; manual update: mli only files
   cmo_format
   ; manual update: this is required.
   instruct
 ))

The Bazel version of this would have an ocaml_library target in each of the subdirectories, and the main build file would have:

ocaml_library(
  name = "ocamlcommon",
  ...
  modules = [
      "//utils:ocamlcommon",
      "//parsing:ocamlcommon",
      ...
  ]
)

and e.g. //utils:ocamlcommon would look like this:

ocaml_library(
  name = "ocamlcommon",
  modules = [
     ":Config", ":Build_path_prefix_map", ...
  ]
)
ocaml_module(
  name = "Config",
  struct = "config.ml"
  sig    = "config.mli"
  ...
)
...