Unit_info(3)

πŸ’– NAME πŸ’–

Bestie, welcome to Unit_info(3) from the OCaml library! This is the module that centralizes the handling of compilation files and their metadata. It's giving organizational queen energy, no cap.


πŸ¦‹ Module πŸ¦‹

Module Unit_info


✨ Documentation ✨

The page spells the module header like this:

Module Unit_info
 : sig end

Okay so this module is the centralized handling HQ for compilation files and their metadata. And maybe even more importantly β€” honestly, main character energy β€” it gives you functions for deriving module names from strings or filenames. Slay.

πŸŽ€ Module name convention and computation πŸŽ€

Here are the type besties:

type intf_or_impl =
 | Intf
 | Impl

type modname = string

type filename = string

type file_prefix = string

type error =
 | Invalid_encoding of filename

exception Error of error
  • val modulize : string -> modname β€” modulize s capitalizes the first letter of s. Cute little glow-up for your string.
  • val normalize : string -> string β€” normalize s uncapitalizes the first letter of s. The reverse makeover.
  • val lax_modname_from_source : filename -> modname β€” lax_modname_from_source filename is modulize stem, where stem is the basename of the filename filename stripped from all its extensions. For instance, lax_modname_from_source "/pa.th/x.ml.pp" is "X". She strips everything, periodt.
  • val strict_modname_from_source : filename -> modname β€” same as Unit_info.lax_modname_from_source, but raises an Unit_info.error.Invalid_encoding error on filename with invalid utf8 encoding. Strict queen, no exceptions β€” well, except the exception. πŸ’€

🌸 Module name validation function 🌸

  • val is_unit_name : modname -> bool β€” is_unit_name name is true only if name can be used as a valid module name. It's the vibe check for module names.

🧚 Metadata for compilation unit 🧚

type t

Metadata for a compilation unit:

  • the module name associated to the unit
  • the filename prefix (dirname + basename with all extensions stripped) for compilation artifacts
  • the input source file

For instance, when calling ocamlopt dir/x.mli -o target/y.cmi,

  • the input source file is dir/x.mli
  • the module name is Y
  • the prefix is target/y
  • val source_file : t -> filename β€” source_file u is the source file of u. The origin story.
  • val prefix : t -> file_prefix β€” prefix u is the filename prefix of the unit. The path before the drama.
  • val modname : t -> modname β€” modname u or artifact_modname a is the module name of the unit or compilation artifact. Name reveal!
  • val kind : t -> intf_or_impl β€” kind u is the kind (interface or implementation) of the unit. Is it an Intf girlie or an Impl girlie? πŸ’…
  • val check_unit_name : t -> unit β€” check_unit_name u prints a warning if the derived module name modname u should not be used as a module name as specified by Unit_info.is_unit_name ~strict:true. It's the friendly warning bestie.
  • val make : ?check_modname:bool -> source_file:filename -> intf_or_impl -> file_prefix -> t

Signature in code block, because it's long and iconic:

val make : ?check_modname:bool -> source_file:filename -> intf_or_impl
     -> file_prefix -> t

make ~check ~source_file kind prefix associates both the source_file and the module name Unit_info.lax_modname_from_source target_prefix to the prefix filesystem path prefix.

If check_modname=true, this function emits a warning if the derived module name is not valid according to Unit_info.check_unit_name. Considerate and observant.

module Artifact : sig end

πŸ”₯ Build artifacts πŸ”₯

🌈 Derived build artifact metadata 🌈

Those functions derive a specific artifact metadata from an unit metadata. It's giving "one unit, many artifact eras."

  • val cmi : t -> Artifact.t
  • val cmo : t -> Artifact.t
  • val cmx : t -> Artifact.t
  • val obj : t -> Artifact.t
  • val cmt : t -> Artifact.t
  • val cmti : t -> Artifact.t
  • val annot : t -> Artifact.t
  • val companion_obj : Artifact.t -> Artifact.t

The functions below change the type of an artifact by updating the extension of its filename. Those functions purposefully do not cover all artifact kinds because we want to track which artifacts are assumed to be bundled together. iykyk.

  • val companion_cmt : Artifact.t -> Artifact.t
  • val companion_cmi : Artifact.t -> Artifact.t
Beware that companion_cmi a strips all extensions from the filename of a before adding the ".cmi" suffix, contrarily to the other functions which only remove the rightmost extension. In other words, the companion cmi of a file something.d.cmo is something.cmi and not something.d.cmi. This is a read-the-docs moment, bestie β€” do not skip. 🫢

πŸŽ€ Mli and cmi derived from implementation files πŸŽ€

The compilation of module implementation changes in presence of mli and cmi files β€” the function below help to handle this. Considerate little helpers.

  • val mli_from_source : t -> filename β€” mli_from_source u is the interface source filename associated to the unit u. The actual suffix depends on Config.interface_suffix. Config decides the accessory, basically.
  • val mli_from_artifact : Artifact.t -> filename β€” mli_from_artifact t is the name of the interface source file derived from the artifact t. This variant is necessary when handling artifacts derived from unknown source files (e.g. packed modules). Mystery source? She still finds the mli.
  • val is_cmi : Artifact.t -> bool β€” check if the artifact is a cmi. Simple vibe check.
  • val find_normalized_cmi : t -> Artifact.t β€” find_normalized_cmi u finds in the load_path a file matching the module name modname u.

Raises Not_found if no such cmi exists. And if it's not there, it's not there. 😭


This page was brought to you by OCamldoc, dated 2026-06-22, and it's the Unit_info(3) manpage. Bye bestie β€” go derive those module names and slay! πŸ’…βœ¨πŸŽ€

πŸ“¦ where this page comes from