# Module Fl_package_base

    module Fl_package_base: sig .. end

Direct access to the package graph and package files

    type package = {

`` | `package_name : `string`;` | `(*` | The fully qualified package name, i.e. for subpackages the names of the containing packages are prepended and the name components are separated by '.' | `*)`
`` | `package_dir : `string`;` | `(*` | The directory where to lookup package files | `*)`
`` | `package_meta : `string`;` | `(*` | The path to the META file | `*)`
`` | `package_defs : `Fl_metascanner.pkg_definition list`;` | `(*` | The definitions in the META file | `*)`
`` | `package_priv : `package_priv`;` | `(*` | Private part of the definition | `*)`

`}`

The definition of a package

    type package_priv

    val init : string list -> string -> string list -> unit

This function must be called before `Fl_package_base` can be used. The first string corresponds to the `OCAMLPATH` setting, the second string is the location of the standard library. The second is the list of directories with ignored duplicate cmi files.

This function is called by `Findlib.init` and `Findlib.init_manually`, so it is already sufficient to initialize the `Findlib` module.

## The package graph

The functions in this section operate on a representation of the package graph in memory. The graph is usually only partially available, as only packages are loaded that are queried for.

    exception No_such_package of string * string

First arg is the package name not found, second arg contains additional info for the user. - This is the same exception as in `Findlib`.

    exception Package_loop of string

A package is required by itself. The arg is the name of the package. - This is the same exception as in `Findlib`.

    val query : string -> package

Returns the `package` definition for the fully-qualified package name, or raises `No_such_package`. It is allowed to query for subpackages.

This function loads package definitions into the graph kept in memory.

    val requires : preds:string list -> string -> string list

Analyzes the direct requirements of the package whose name is passed as second argument under the assumption that the predicates `preds` hold. The function returns the names of the required packages. It is checked whether these packages exist.

If there is the "mt" predicate, missing dependencies on "threads" are silently added.

The function may raise `No_such_package` or `Package_loop`.

This function loads package definitions into the graph kept in memory.

    val requires_deeply : preds:string list -> string list -> string list

Analyzes the direct or indirect requirements of the packages whose names are passed as second argument under the assumption that the predicates `preds` hold. The function returns the names of the required packages. It is checked whether these packages exist.

If there is the "mt" predicate, missing dependencies on "threads" are silently added.

The function may raise `No_such_package` or `Package_loop`.

This function loads package definitions into the graph kept in memory.

    val package_conflict_report : ?identify_dir:(string -> 'a) -> unit -> unit

Checks whether there are several META files for the same main packages. Complaints are printed to stderr.

Only packages in the loaded part of the package graph are checked (i.e. packages for which there was a query).

It is recommended to pass the ~identify_dir function whose task it is to return a unique value for every existing directory. For example,

     fun d ->
            let s = Unix.stat d in
            (s.Unix.st_dev, s.Unix.st_ino)

could be an implementation for this function. The default is the identity (and not this nice implementation to avoid dependencies on the Unix module).

    val module_conflict_report : ?identify_dir:(string -> 'a) -> string list -> unit

Checks whether there are cmi files for the same modules. The directories passed as first argument are checked. (Note: Neither the '+' nor the '@' notation are recognized.) Complaints about double cmi files are printed to stderr.

`identify_dir` : See `package_conflict_report`.

    val load_base : ?prefix:string -> unit -> unit

Ensures that the complete package graph is loaded into memory. This is a time-consuming operation. Warnings may be printed to stderr.

`prefix` : Limit to the packages that starts with it. Default: unlimited

    val list_packages : ?prefix:string -> unit -> string list

Ensures that the complete package graph is loaded into memory (like `load_base`), and returns the (unsorted) list of all packages.

`prefix` : Limit to the packages that starts with it. Default: unlimited

    val package_users : preds:string list -> string list -> string list

Ensures that the complete package graph is loaded into memory (like `load_base`), and determines the packages using one of the packages passed as second argument. The `preds` are assumed for the evaluation of the `requires` directives. The returned list is sorted in ascending order.

If there is the "mt" predicate, missing dependencies on "threads" are silently added.

Raises `No_such_package` if one of the passed packages cannot be found.

## Parsing META files

The functions in this section access directly files and directories. The package graph is unknown.

    val packages_in_meta_file : ?directory_required:bool ->
           name:string ->
           dir:string -> meta_file:string -> unit -> package list

Parses the META file whose name is `meta_file`. In `name`, the name of the main package must be passed. `dir` is the directory associated with the package by default (i.e. before it is overridden by the "directory" directive).

Returns the package records found in this file. The "directory" directive is already applied.

`directory_required` : If true, it is checked whether there is a "directory" directive in the main package. If this directive is missing, the function will fail.

    val package_definitions : search_path:string list -> string -> string list

Return all META files defining this package that occur in the directories mentioned in `search_path`. The package name must be fully-qualified. For simplicity, however, only the name of the main package is taken into account (so it is a good idea to call this function only for main packages).