Skip to content

CLI reference

Generated by make doc-reference from fibc --help. The documentation gate requires exact equality.

usage: fibc <command>

Every command that reads a program (run, build, emit, emit-dump, explain, check, lsp) takes
-I dir (or -Idir), any number of times, anywhere before --: a module is found
beside the file, then under each -I dir in order, then under each directory of
$FIB_LIB, then in the library directory `lib` (spec/syntax.md §5).

commands:
  run [--trace] [--live [--live-deps] [--with SPEC]..] [-O N] <file> [-- arg..]
                         compile file through the JIT and run its main; the
                         args after -- are (args); --live (or FIB_LIVE=1)
                         compiles the program for live redefinition: its own
                         functions behind stubs and slots, and catching
                         (docs/design/live-repl.md); it runs as a live session
                         with an attach socket ($XDG_RUNTIME_DIR/fib-live/PID.sock,
                         printed on standard error) that `fibc repl --connect`
                         talks to; in a project its own modules (the :paths of
                         deps.fib) are live and its libraries are not unless
                         --live-deps (FIB_LIVE_DEPS=1, or --live-deps=NAME,.. for
                         some of them); outside a project every module not named
                         fib.* is live; each --with SPEC (a spec file) is loaded
                         beside the program as the module spec.NAME, so that the
                         session's `test` op (`:test` of the client) runs it
                         (docs/design/live-meshql.md 3)
  build <file> -o <out> [-O N] [-L dir].. [-l lib].. [--emit liro|obj|asm|llvm|ptx|wgsl|c]
                        [--kernel-target TRIPLE|none]
                         (the options may come before the file too)
                         compile file to an executable; each -l lib links
                         -llib, each -L dir is searched for libraries (-Ldir and
                         -llib are also taken); --emit writes the object, the
                         assembly or the LLVM IR instead and links nothing;
                         --emit ptx (a kernel target, --target nvptx64-nvidia-cuda)
                         writes the PTX of the program's kernels (docs/design/gpu.md);
                         --emit c writes the program as one C translation unit
                         (docs/design/lir2c.md); --via c (before --) builds it
                         through the C compiler --cc CC (default cc, FIB_CC)
                         instead of LLVM; --allow-plain-tail-calls turns the
                         error for a tail call C cannot guarantee into a warning
                         --kernel-target TRIPLE (or FIB_KERNEL_TARGET) builds the
                         executable with the PTX of its kernels embedded (gpu/program-ptx)
                         and beside it as OUT.ptx; a program with a defkernel and no
                         kernel target (or --kernel-target none) is refused
  targets                print the table of code generation targets (one row per
                         target, tab-separated; docs/design/targets.md)

--target TRIPLE (any command, before --) generates code for TRIPLE instead of
the host (FIB_TARGET_TRIPLE); build then needs --emit, and refuses a target
that `targets` does not list as supported or a portability target (riscv64 is
parked) unless --allow-unsupported is given (FIB_ALLOW_UNSUPPORTED=1)

Build/link options (before --):
  --cache-dir DIR        keep compiled lIR objects under DIR (FIB_LIRO_CACHE)
  --no-cache             compile without reading or writing the object cache
  --whole-program        optimize the program as one compilation unit
  --cache-stats          report object hits, misses and backend compilations
  --time                 report compilation phase timings on standard error
                         --emit liro writes OUT and OUT.meta; build OUT.liro
                         -o EXE validates and links the supplied object
  --static               link a static Linux executable with musl (FIB_MUSL_DIR)
  --link NAME=static|dynamic
                         choose the link mode of a declared native library; repeatable
  --link-mode static|dynamic
                         default mode for declared native libraries (default dynamic)
  --export NAME[=SYMBOL] export a named function as a C symbol; repeatable (FIB_EXPORTS); integers, floats, bool and
                         ptr cross as they are, a str parameter as (const uint8_t *p, int64_t len), a str result
                         through a caller buffer (uint8_t *out, int64_t cap) and the returned length it needs
  --shared               build a shared library (libX.so; libX.dylib on macOS) of the --export functions, with -o: only
                         the exports are visible; refused without an export. It is not safe for a host yet: a trap
                         aborts the host and a deep recursion overflows its stack (docs/design/shared-libraries.md, host-threads.md)
  --header FILE.h        write the C header of the exports (extern C guard, one prototype each) and module.modulemap
                         beside it, for --shared or --emit obj
  --exe                  emit executable-style lIR with emit (main's result is not printed)

-O N (N from 0 to 3, or -ON) is the LLVM optimisation level of run and build:
build defaults to 2, run to 0.
  emit <file>            print the lIR module of file
  emit-dump [--sections LIST | --fn PREFIX | --layout | --macro NAME] [--] <file>..
                         print the lIR module of each file in its sections, or
                         the layout of its types, or one macro module (spec/bootstrap.md
                         section 8); exit 0, 1 a record, 2 unreadable, 3 unsupported
  explain <file>         print the ownership checker's decisions (types §9)
  explain unsafe <file>  list every unsafe block, extern call and lir form of the program and its libraries, with the atomics each lir form uses
  check <module>..       load the modules and type-check and ownership-check EVERY definition of
                         them and of the modules they use, called or not (run, build and emit check
                         a library definition only when the program reaches it); exit 0 all
                         checked, 3 one was rejected (each failing module named), 2 not loadable
  lsp                    serve the language server (LSP over standard input and
                         output: completion, hover, diagnostics, definition,
                         document symbols); takes -I; exit 0 after shutdown, 1 without
  help                   print this message
  --version, -V          print the version

  cases [dir [--only prefix..]] [-j N]
                         run each case of dir (default cases/ownership) against the verdict
                         in its header, compiled, and print the table; exit 1 if one failed;
                         -j N runs N cases at a time (default 1), the table the same

  test [PATH..] [--only SUBSTR] [--seed N] [--jobs N] [--format plain|tap|json] [--list]
       [--isolate task|fork|none] [--timeout SECS]
                         run the specs (fib.test) of each spec file, or of every *-spec.fib below a
                         directory (default `specs`), each as `fibc run`; exit 0 all held, 1 a scenario
                         failed, trapped or timed out, 2 usage, no spec, a spec that does not compile,
                         or nothing selected; takes -I
  test --live [PATH..]   make the spec files resident in one live process with no app (their
                         front end and JIT paid once) and print its socket; `test --connect
                         SOCK|PID [PATH..] [options]` runs them there instead of a process per
                         file, the report and status as above (no --timeout, no --isolate fork)

  serve [--socket PATH]  keep the front end's state in a process and answer requests (one JSON
                         line each) over a unix socket: check, emit, run, test, eval; takes -I
  --server VERB ..       send check|emit|run|test FILE.., or ping|stats|reset|shutdown, to the
                         server; runs the ordinary command here when none answers; [--socket
                         PATH] [--json] [-q]
  repl [--socket PATH]   read-eval-print loop over the same engine: definitions persist; takes -I
                         (:help in the loop; docs/design/dev-loop.md section 9)
  repl --connect SOCK|PID [--json]
                         attach to a program started with `run --live`: inputs are evaluated
                         in it and its values persist; --json is one JSON request per line in,
                         one answer per line out (docs/design/live-repl.md 2.3, 2.4)

  new NAME [--lib]       make a project directory NAME: deps.fib, src/NAME/core.fib,
                         specs/NAME-spec.fib (and src/main.fib without --lib)
  deps tree|fetch|update [NAME..]|add NAME ..|path
                         the project's libraries (git commits and directories):
                         `fibc deps` alone prints its usage

Projects (docs/design/packages.md): where a deps.fib is in the working directory or
above it, run, build, emit, explain and test resolve its :deps (pinned by deps.lock,
which they write when it changes) and add the project's :paths and every library's
to the module roots after the -I dirs; --locked refuses a missing or stale
deps.lock, --offline never fetches, --frozen is both.