docs: add libVCT public specification set (000-015)
This commit is contained in:
@@ -0,0 +1,223 @@
|
||||
# 010 — Driver & CLI
|
||||
|
||||
- **Status:** Draft
|
||||
- **Normative language:** `MUST`, `MUST NOT`, `SHOULD`, `SHOULD NOT`, and `MAY` are to
|
||||
be interpreted as described in RFC 2119.
|
||||
|
||||
## 1. Purpose
|
||||
|
||||
libVCT splits orchestration across two layers. The driver (`vct.driver`) is the
|
||||
library-level orchestrator: it takes emitted C translation units, invokes the system C
|
||||
compiler, and collects object files. The CLI (`vct.cli`) is a thin wrapper that parses
|
||||
command-line flags into a `Config`, drives the whole pipeline, formats diagnostics, and
|
||||
sets exit codes. The CLI holds no optimizer state and adds no compilation logic of its
|
||||
own.
|
||||
|
||||
## 2. Scope
|
||||
|
||||
This file specifies the driver/CLI role split, the pipeline order, the full flag
|
||||
surface, the exact C compiler invocation, compiler discovery and probing, error
|
||||
handling, determinism, `-mangled` mode, and object-file emission and merging. The
|
||||
compiler-facing backends are specified in [008 — C Backend](008-c-backend.md) and
|
||||
[009 — LLVM Backend](009-llvm-backend.md). Diagnostics, remarks, and exit codes are
|
||||
specified in [011 — Diagnostics](011-diagnostics.md).
|
||||
|
||||
## 3. Definitions
|
||||
|
||||
| Term | Meaning |
|
||||
|---|---|
|
||||
| `Config` | One struct holding opt level, target, budgets, pass toggles, warning policy, compiler selection, and mode. |
|
||||
| TU | Translation unit: one emitted C file. |
|
||||
| `cc` | The discovered system C compiler. |
|
||||
| APE | Actually Portable Executable, the output of cosmopolitan tooling. |
|
||||
| Fat LTO object | An object that carries both native machine code and LTO bitcode. |
|
||||
| Response file | A file listing arguments for a linker or compiler, referenced by `@file`. |
|
||||
|
||||
## 4. Model
|
||||
|
||||
`vct.cli` is GC-allocated and cold-path only. It converts `argv` into a `Config`, runs
|
||||
the pipeline, forwards every diagnostic to the configured consumer, and returns an exit
|
||||
code. `vct.driver` owns process invocation. Any embedder that has already constructed a
|
||||
`Config` can call the driver directly and skip the CLI entirely.
|
||||
|
||||
The driver also owns the `-llvm` path, which returns textual LLVM IR and never touches
|
||||
`cc`, and the `-mangled` path, which switches to the cosmopolitan toolchain.
|
||||
|
||||
## 5. Normative requirements
|
||||
|
||||
### 5.1 Role split
|
||||
|
||||
**R1.** `vct.cli` MUST be a thin wrapper. It MUST NOT contain optimization, lowering, or
|
||||
backend logic, and it MUST NOT hold optimizer state.
|
||||
|
||||
**R2.** `vct.cli` MUST be a pure function from `argv` to `Config` plus pipeline
|
||||
invocation. The library entry point MUST accept a `Config`; programmatic callers MUST be
|
||||
able to bypass the CLI.
|
||||
|
||||
**R3.** `vct.driver` MUST own all invocation of the system C compiler.
|
||||
|
||||
**R4.** `vct.cli` MUST be GC-allocated and MUST be usable on the cold path only.
|
||||
|
||||
### 5.2 Pipeline
|
||||
|
||||
**R5.** The default pipeline order MUST be: read input, then HIR optimization if enabled,
|
||||
then lowering, then VIR optimization if enabled, then the C backend, then the driver.
|
||||
|
||||
```
|
||||
read input
|
||||
-> (HIR opt if enabled)
|
||||
-> lower
|
||||
-> (VIR opt if enabled)
|
||||
-> backend.c -> driver -> .o
|
||||
```
|
||||
|
||||
**R6.** `-S` MUST stop after C emission and MUST NOT invoke `cc`.
|
||||
|
||||
**R7.** `-emit-llvm` and `-llvm` MUST stop after LLVM IR emission and MUST NOT invoke
|
||||
`cc`.
|
||||
|
||||
### 5.3 Flag surface
|
||||
|
||||
**R8.** The CLI MUST accept the flags listed in Table 1.
|
||||
|
||||
**Table 1. v1 flag surface**
|
||||
|
||||
| Group | Flags | Meaning |
|
||||
|---|---|---|
|
||||
| Optimize | `-O0` `-O1` `-O2` `-O3` `-Ofast` `-Oz` | Optimization level. |
|
||||
| Target | `-march=<arch>`, `-mcpu=<cpu>`, `-target <triple>` | Target selection; `-march`/`-mcpu` forward to `cc` as cflags. |
|
||||
| Modes | `-S`, `-emit-llvm`, `-llvm`, `-mangled` | Stop point or alternate mode. |
|
||||
| Toolchain | `-cc=<gcc\|clang>`, `-cflags="..."`, `-j<N>`, `-save-temps` | Compiler selection, extra flags, parallelism, temp retention. |
|
||||
| LTO | `-flto[=full\|thin]`, `-ffat-lto-objects` | Link-time optimization control. |
|
||||
| Debug | `-g`, `--dump-hir`, `--dump-vir`, `--verify`, `--time-passes`, `--stats` | Debug output and instrumentation. |
|
||||
| Output | `-o <path>` | Output path. |
|
||||
| Warnings | `-Wall`, `-Werror`, `-Wextra`, `-Wno-error[=<category>]`, `-w` | Warning policy. |
|
||||
| Diagnostics | `--remarks`, `--diagnostics=json` | Remark and diagnostic channel selection. |
|
||||
| Pass toggles | `-f<pass>`, `-fno-<pass>` | Enable or disable an individual pass. |
|
||||
|
||||
**R9.** `-Wall`, `-Werror`, and `-Wextra` MUST be on by default. A bare `-Wno-error` MUST
|
||||
disable every promotion, `-Wno-error=<category>` MUST disable the promotion of that
|
||||
category, and `-w` MUST silence warnings.
|
||||
|
||||
**R10.** `-Werror` MUST apply to the C source that libVCT generates, not only to
|
||||
frontend input.
|
||||
|
||||
**R11.** Every pass MUST be exposed as both `-f<pass>` and `-fno-<pass>`.
|
||||
|
||||
### 5.4 C compiler invocation
|
||||
|
||||
**R12.** For each emitted TU, the driver MUST invoke the compiler as:
|
||||
|
||||
```
|
||||
cc -std=c17 -c <tu.c> -o <tu.o> <cflags> <march> -Wall -Werror -Wextra <g> <flto>
|
||||
```
|
||||
|
||||
where `<g>` is `-g` when debug is enabled, and `<flto>` is the LTO flag when LTO is
|
||||
requested.
|
||||
|
||||
**R13.** The driver MUST run one compiler process per TU, with concurrency bounded by
|
||||
`-j`.
|
||||
|
||||
**R14.** The driver MUST discover the compiler via the `$CC` environment variable first,
|
||||
then by searching `PATH`, unless `-cc=<gcc|clang>` forces a selection.
|
||||
|
||||
**R15.** The driver MUST probe the discovered compiler's version and dialect exactly
|
||||
once per run. The probed dialect MUST drive the backend's choice of pragmas and builtins
|
||||
(see [008 — C Backend](008-c-backend.md)).
|
||||
|
||||
**R16.** The driver MUST NOT pass `-march`/`-mcpu` values to `cc` that the probed
|
||||
compiler does not accept; it MUST diagnose an unsupported target value.
|
||||
|
||||
### 5.5 Error handling
|
||||
|
||||
**R17.** The driver MUST capture the compiler's stderr.
|
||||
|
||||
**R18.** The driver MUST use the `#line` directives emitted by the C backend (see
|
||||
[008 — C Backend](008-c-backend.md)) to map C compiler errors back to VIR and frontend
|
||||
source positions, then re-emit them through the diagnostics service (see
|
||||
[011 — Diagnostics](011-diagnostics.md)).
|
||||
|
||||
**R19.** A compiler failure MUST produce a diagnostic and MUST cause a nonzero exit.
|
||||
|
||||
**R20.** The driver MUST NOT discard compiler diagnostics silently.
|
||||
|
||||
### 5.6 Determinism
|
||||
|
||||
**R21.** The driver MUST order TUs and flags deterministically. For a fixed `Config` and
|
||||
input, the sequence of compiler invocations and their argument order MUST be identical
|
||||
across runs and independent of thread count.
|
||||
|
||||
**R22.** The driver MUST place temporary files under a GC-managed temporary directory.
|
||||
|
||||
**R23.** The temporary directory MUST be cleaned up after the run unless `-save-temps`
|
||||
is given.
|
||||
|
||||
### 5.7 `-mangled` mode
|
||||
|
||||
**R24.** `-mangled` MUST switch the toolchain to `cosmocc` and the cosmopolitan libc.
|
||||
|
||||
**R25.** `-mangled` MUST produce an Actually Portable Executable.
|
||||
|
||||
**R26.** `-mangled` is the one mode in which libVCT links. In every other mode libVCT
|
||||
produces object files and leaves linking to the caller (see
|
||||
[000 — Overview](000-overview.md)).
|
||||
|
||||
### 5.8 Object emission and merging
|
||||
|
||||
**R27.** In the default path, the driver MUST produce object files only. It MUST NOT link
|
||||
a final executable.
|
||||
|
||||
**R28.** When a single `-o` path is requested and the module produced multiple
|
||||
per-function objects, the driver MUST merge them with a relocatable link
|
||||
(`ld -r -o <out> <tu>.o ...`).
|
||||
|
||||
**R29.** The driver MUST emit, for the caller, a recommended link line or response file
|
||||
listing the produced objects and any needed libraries.
|
||||
|
||||
## 6. Invariants
|
||||
|
||||
- **I1.** A fixed `Config` and input produce byte-identical outputs and an identical
|
||||
sequence of compiler invocations.
|
||||
- **I2.** `vct.cli` holds no optimizer state.
|
||||
- **I3.** The `-llvm` path never spawns `cc`.
|
||||
- **I4.** The temporary directory is removed unless `-save-temps` is set.
|
||||
- **I5.** Flag assembly order is stable.
|
||||
- **I6.** Every captured compiler error is re-emitted through the diagnostics service.
|
||||
- **I7.** `-mangled` is the only mode that links.
|
||||
|
||||
## 7. Examples
|
||||
|
||||
Default compile of a single source to an object:
|
||||
|
||||
```
|
||||
vct -O2 -march=native -cc=clang -j8 -o out.o input.vir
|
||||
```
|
||||
|
||||
Stop after emitting C, without invoking `cc`:
|
||||
|
||||
```
|
||||
vct -O2 -S -o out.c input.vir
|
||||
```
|
||||
|
||||
Emit textual LLVM IR instead of C:
|
||||
|
||||
```
|
||||
vct -O3 -emit-llvm -target x86_64-unknown-linux-gnu -o out.ll input.vir
|
||||
```
|
||||
|
||||
Produce a portable executable:
|
||||
|
||||
```
|
||||
vct -O2 -mangled -o app.com input.vir
|
||||
```
|
||||
|
||||
## 8. Cross-references
|
||||
|
||||
- [000 — Overview](000-overview.md) for determinism and the no-linking rule.
|
||||
- [001 — Architecture](001-architecture.md) for module boundaries.
|
||||
- [002 — Traits](002-traits.md) for the trait vocabulary.
|
||||
- [007 — VIR Optimizer](007-vir-optimizer.md) for pass toggles and the pipeline.
|
||||
- [008 — C Backend](008-c-backend.md) for `#line` and compiler dialect use.
|
||||
- [009 — LLVM Backend](009-llvm-backend.md) for `-target` and the `-llvm` path.
|
||||
- [011 — Diagnostics](011-diagnostics.md) for diagnostics, remarks, and exit codes.
|
||||
- [013 — Build & Packaging](013-build-packaging.md) for `Config` and the C API.
|
||||
Reference in New Issue
Block a user