this repo has no description
at main 139 lines 4.4 kB view raw
1{0 Dune and odoc} 2 3{1:using_dune Using Dune} 4 5To create docs with [odoc] and Dune is straightforward, but there is an important 6point to know: Dune only creates docs for {e public packages}, so you will need 7a [(public_name ...)] stanza in your libraries and a corresponding [lib.opam] 8file in the root of your project. 9 10The following files are a simple example: 11 12- [dune-project] 13{@text[ 14(lang dune 2.0) 15]} 16- [dune] 17{@text[ 18(library 19 (public_name lib)) 20]} 21- [a.ml] 22{[ 23(** Module A *) 24 25type t = int (** My type *) 26]} 27- [lib.opam] - this file need only {e exist}, i.e., [touch lib.opam] is sufficient. 28 29Dune creates the docs for these with this command: 30 31{@sh[ 32$ dune build @doc 33]} 34 35The results will be in [_build/default/_doc/_html/]. 36 37{1:library_wrapping Dune's Library Wrapping} 38 39Dune has a feature whereby a library may be exposed under a single top-level 40module. This employs an OCaml feature where using the compiler 41flag [-no-alias-deps] will avoid introducing dependencies between 42compilation units. 43 44We aim to reduce the potential name clashes of modules by 45only exposing one main module for library users, 46encapsulating all other modules as submodules, while 47still retaining the usual way of writing OCaml code with one module per 48file. These individual files are still compiled, installed, and 49available in the global namespace, but their names are prefixed with 50the library's name in order to reduce the possibility of clashes. These 51prefixed modules are not intended to be used directly, so 52Dune includes canonical tags for these modules for [odoc] to 53ensure they don't 'leak' into the documentation. 54 55{1 Example} 56 57Given two modules: [A] and [B], with [B] referencing types declared in module 58[A]: 59 60{[ 61(** Module A *) 62type t 63]} 64 65{[ 66(** Module B *) 67type t = A.t 68]} 69 70If these modules are to become part of a library called [Lib], then Dune will 71compile these two as if their names were [Lib__A] and [Lib__B] and also 72create a file [lib.ml] containing the following: 73 74{[ 75(** @canonical Lib.A *) 76module A = Lib__A 77 78(** @canonical Lib.B *) 79module B = Lib__B 80]} 81 82This will be the one module intended to be used directly by 83the library's users. This module is in fact compiled {e first}, using the 84compiler flag [--no-alias-deps], which allows it to be compiled without requiring 85[Lib__A] and [Lib__B] to be compiled first. 86 87Dune will then compile [a.ml] and [b.ml], in that order, but ask the compiler to 88name them [Lib__A] and [Lib__B]. It also 'opens' the module [Lib], which is what 89allows [B] to refer to [A.t]. 90 91When [odoc] is used to produce documentation for this, firstly all modules are 92compiled, but only one module is considered to be visible: [Lib]. All others 93have double underscores meaning they are hidden. Only the non-hidden module 94[Lib] is linked, and during this process, the 95the modules [A] and [B] are expanded because they are aliases of hidden 96modules. All references to [Lib__A] and [Lib__B] are replaced with the canonical 97paths [Lib.A] and [Lib.B], so in this way, [odoc] presents the library as entirely 98contained within the module [Lib]. 99 100{2 Hand-Written Top-Level Module} 101 102In some cases it's desirable to hand-write the top-level library module. This 103is usually done because some modules in the library are intended to be internal 104only and not exposed. Dune will notice that a module exists with the library's 105name ([lib.ml] in this case), so instead it will create the file 106[lib__.ml]. Its contents are identical to the previous section, with aliases 107for all modules. Like before, the canonical tags on these aliases are 108references to [Lib.A] and [Lib.B]. These module should be present in [lib.ml] 109as module aliases. If these are {e not} there, [odoc] won't be able to resolve 110the canonical references, and any items from these modules that are exposed 111elsewhere will be hidden. If the items are type aliases, they can be replaced, 112but otherwise they'll be rendered as unresolved links. 113 114For example, consider the following module structure. First, the module [Unexposed] 115in file [unexposed.mli]: 116 117{[ 118(** Unexposed module *) 119 120type t 121]} 122 123The module [Wrapping], in file [wrapping.mli]: 124 125{[ 126(** Example of Dune's wrapping *) 127 128type t = Unexposed.t 129 130val f : Unexposed.t 131]} 132 133The library module that only exposes the module [Wrapping]: 134 135{[ 136module Wrapping = Wrapping 137]} 138 139This structure is rendered {{!Odoc_examples.Wrapping}here}.