LEVIATHAN v962456e · 962456eee1

trident

Two tools: trident and leviathan

How the package manager and the compiler divide the work, what the build plan between them is, and the commands that build and run a project.

since 0.1.0-alpha.1linux

Description

The toolchain is two separate programs.

  • trident is the package manager and build driver, the program you normally run. It reads the project's manifest, trident.toml, resolves the dependencies, and writes a fully resolved build plan.
  • leviathan is the compiler. It compiles the source files a plan names, or a single source file you hand it. It never reads trident.toml, never resolves dependencies, and does not know that package repositories exist.

The build plan is the boundary between them. trident writes it, by default to build/plan.lvplan, and leviathan --plan <file> reads it. A plan lists every resolved source file with its absolute path, the project's entry point, the requested output name, target and optimisation level, and which dependency each file belongs to so that the compiler can enforce dependency visibility (see trident.dependencies). It is generated text for the compiler to read. You never write one by hand.

A project of one file does not need a manifest at all: leviathan --run main.lev works on a bare file. A manifest is for projects with several files, dependencies, assets or a named output.

A program a manifest can build

string name = "Leviathan";
console.writeln("hello from ${name}");
hello from Leviathan

Saved as main.lev beside this trident.toml, the program is a complete project:

name    = "hello"
entry   = "main.lev"
sources = ["main.lev"]

The project commands

trident build     [manifest-or-dir]   # resolve, write the plan, then leviathan --build-native
trident run       [manifest-or-dir]   # resolve, write the plan, then leviathan --run
trident check     [manifest-or-dir]   # resolve, then check the program without running it
trident emit-llvm [manifest-or-dir]   # resolve, then print the program as LLVM IR
trident plan      [manifest-or-dir]   # resolve and write the plan only; do not run the compiler
trident --version                     # trident's version, then the compiler's

[manifest-or-dir] is either a path to a trident.toml or a directory that contains one, and defaults to the current directory. The plan and the build/ directory are created in the directory you run trident from, and so is the executable that trident build writes. The executable is named after the manifest's out key, or its name when there is no out.

These flags apply to the five commands above:

Flag Meaning
--out <path> Name the executable instead of using the manifest's out or name.
--target <triple> Build for another machine, as leviathan --target does.
--opt-level <0|2> Optimisation level for build; --release is the same as --opt-level 2.
--plan <path> Write the plan to this file instead of build/plan.lvplan.
--leviathan <path> Use this compiler binary.
--vendor Read dependencies only from the project's vendor directory (see trident.versions-and-integrity).

trident finds the compiler by trying, in order, the --leviathan flag, the LEVIATHAN environment variable, the directory that holds the trident program itself, and finally the PATH. The commands that manage dependencies, such as add and lock, never start the compiler.

trident run does not pass arguments to the program. To run a project with arguments, build it with trident build and run the executable.

Rules

  • trident owns trident.toml; leviathan never reads it.
  • The plan is the only thing trident hands to the compiler. It is regenerated by every build, run, check, emit-llvm and plan.
  • trident plan prints the path of the plan it wrote and does not run the compiler. Use it to run leviathan modes such as --imports, --graph or --why against a whole project.
  • The exit status of build, run, check and emit-llvm is the compiler's exit status.
  • A directory without a trident.toml is an error: no manifest found.

Examples

Building and running the project above:

trident run .
trident build .
./hello

Asking the compiler questions about a whole project through its plan:

trident plan .
leviathan --imports --plan build/plan.lvplan
leviathan --graph --plan build/plan.lvplan

A debug build to a chosen name, and a release build for another machine:

trident build . --out hello-debug --opt-level 0
trident build . --release --target x86_64-pc-windows-gnu

Notes

The compiler works the same way with or without trident; the plan only tells it which files make up the program and where the program starts.

See also

  • The leviathan command line — Every option of the leviathan compiler, grouped by what it does, with the exit statuses and how arguments reach your program.
  • Implementation status and execution modes — What the reference promises, what unreleased means on a page, and the four ways to run a Leviathan program.
  • The manifest: trident.toml — Every key of trident.toml, how sources and assets are listed, and the three ways a project can choose its entry point.
  • The trident commands — Every trident subcommand with its arguments, grouped into building, managing dependencies, and publishing and auditing.