Dune Build System

repository·main·Indexed 23 days ago

https://github.com/ocaml/dune

A composable build system for OCaml that manages compilation, dependency resolution, and development tool configuration using S-expression-based metadata files. It supports parallel builds, watch mode via RPC, and sandboxing on Linux (via bubblewrap) and macOS (via sandbox-exec). Key commands include `dune build` for target execution, `dune runtest` for testing, and `dune clean` for removing generated files.

Tokens
119.4K
Snippets
367
Records
854
Agent score
84%

What's inside Dune

  1. Summary of core Dune features covered in tutorials

    main

    Dune provides several key stanzas and workflows for managing OCaml projects:

    • Stanzas: Use executable, library, and test stanzas to define the primary components of your build.
    • Testing: Implement cram tests for integration testing and use the promotion workflow to manage build artifacts across different environments.
    • C Interop: Use foreign stubs to create bindings between OCaml and C code.
    • Metaprogramming: Utilize ppx derivers to extend the OCaml language during the compilation process.
  2. Understand the roles of OCaml ecosystem tools

    main

    The OCaml ecosystem consists of several distinct layers that work together to manage code from source to package:

    • OCaml Compiler (ocamlc, ocamlopt): The low-level tool that converts source files (.ml, .mli) into executables and libraries. It operates at the module level.
    • Findlib (ocamlfind): Manages library metadata via META files, allowing libraries to depend on one another. It provides a wrapper around the compilers to handle linking with external libraries.
    • Opam: The package manager. It handles dependency resolution, fetching, and building. It manages environments called switches and uses an opam-repository to find package definitions.
    • Dune: The build system. It orchestrates the compilation process by mapping your project's structure (executables, libraries, tests) to the underlying compiler and ecosystem tools.
  3. How Dune Package Management works

    main

    Dune's package management provides a local, reproducible, and project-scoped way to manage OCaml dependencies. Unlike opam, which relies on global state, Dune manages everything within the project using configuration files (dune-project and optionally dune-workspace).

    Core Principles:

    • No global state: Everything is local to the project.
    • Single source of truth: Dependencies are primarily declared in dune-project (though .opam files are still supported for compatibility).
    • Reproducibility: Uses lockfiles (stored in a lock directory) to ensure consistent builds.
    • Isolation: Builds can only access packages explicitly declared as dependencies.
    • Compatibility: Uses the same opam repositories, meaning Dune packages remain installable via opam.
  4. Manage developer tools with `dune tools`

    main

    The dune tools command group allows you to manage developer tools (like ocamlformat, ocamllsp, or utop) that are useful for development but not required for building or deploying the project. Dune automatically handles resolving, locking, building, and running these tools in a separate lock directory (typically _build/.dev-tools.locks) to avoid polluting your project environment.

    Warning: The dune tools command group is experimental. Its subcommands, flags, and behavior may change in future versions without notice.

  5. Project structure of hello_world

    main

    The hello_world project follows a standard layout where components are organized into subdirectories:

    • lib/: Contains the hello_world library definition.
    • bin/: Contains the hello_world executable definition.
    • test/: Contains the project tests.
    • hello_world.opam: A required file at the project toplevel that allows Dune to recognize the directory as the hello_world project.
  6. What is the Dune engine?

    main

    The engine is the core, reusable component of Dune that provides the composable primitives required for a build system. It is decoupled from the rule generation logic (the rules part), allowing it to serve as a backend for other build systems.

    In a standard Dune installation, the engine is responsible for:

    • Tracking directories and the rules contained within them.
    • Executing builds using those rules.
    • Managing various caches, including the local _build directory and the shared cache.
  7. What is a dune-workspace file?

    main

    A dune-workspace file marks the root of a Dune workspace. It allows you to define compilation contexts and specify settings that are common to all Dune projects contained within that workspace.

    By default, a workspace contains a single build context named default, which corresponds to the environment in which dune is executed. To define multiple contexts, you must use a dune-workspace file.

  8. Understand package kinds in install layouts

    main

    When using (deps (package ...)), Dune classifies packages into three categories which affect how they are handled:

    • Local: Workspace packages defined in your dune-project. These receive both layout file dependencies and environment variables.
    • Build: Lock-dir packages from dune.lock. Using (deps (package foo)) will run the package's build action, but (currently) does not set up environment variables for the consuming action.
    • Installed: Externally installed packages (found via findlib). These are depended on directly and are already present in the system OCAMLPATH. In a lock-dir context, these resolve as Build packages if they are in dune.lock, or are not found otherwise.
  9. Notes on using revdep aliases

    main

    When using @revdep aliases, keep the following in mind:

    • No Overhead: These aliases only perform work when explicitly requested; they do not add overhead to regular builds.
    • Directory Scoping: If multiple libraries are defined within the same dune file, the @dir/revdep alias covers the dependents of any library in that directory.
  10. What are sites in Dune?

    main
    Sites are locations used when a package requires additional resources outside its primary binary. A site can be defined by a package and corresponds to a list of directories that act like layers; the first directories in the list have higher priority. This mechanism is useful for plugins or packages that need to add resources to other packages.
  11. Use special variables to refer to compilation artifacts

    main

    Dune provides special variables to refer to individual compilation artifacts without needing to know Dune's internal naming conventions or directory layouts. These variables follow the format %{<ext>:<path>}, where <path> is interpreted relative to the current directory.

    Usage Rules:

    • They can be used anywhere a dependency specification is expected.
    • They can be used inside actions (e.g., in a post or pre stanza). When used inside an action, they implicitly declare a dependency on that artifact.
    • The expanded path always points inside the build context (e.g., _build/<context>).