CLI reference¶
postc is the command-line entry point of the POST Compiler (console script postc = postc.cli:main). It exposes four subcommands over the compilation pipeline:
| Command | Purpose |
|---|---|
check |
Check files against the POST Python subset |
build |
Compile a POST Python file (and its POST imports) to native code |
backends |
List registered backends and their availability |
backend-info |
Show one backend's capabilities and tool status |
A subcommand is required. Every parser accepts -h / --help (postc build --help prints the build flags below).
postc check¶
Structurally checks each file against the POST Python subset — the same gate build runs first — and prints every violation with source context.
check accepts one or more FILE arguments. It exits 0 when all files are clean and 1 when any violations are found (the total count is printed to stderr).
postc build¶
Compiles the entry FILE and every POST module it imports through the selected backend, then links the objects into one native shared library (.so, or .dylib on macOS). A directory target builds its package entry — __post__.py if present, otherwise __init__.py.
Options¶
| Flag | Argument | Description |
|---|---|---|
--output, -o |
PATH |
Output artifact path. Defaults to <FILE> with the platform library suffix beside the source (or <name><EXT_SUFFIX> for --ext-module). |
--prefix |
DIR |
Install the libpp<name> layout under DIR: lib/lib<name>.so, include/<name>.h, share/postc/<name>.json. Always emits the header and manifest. |
--ext-module |
(flag) | Build an importable CPython extension module instead of a plain shared library (registers each public ufunc as a real numpy.ufunc). Requires a backend with the ext_module capability — C only. |
--module-name |
NAME |
Artifact / importable module name. Defaults to the file stem, or the package directory's name when the entry is __init__.py / __post__.py. |
--emit-header |
(flag) | Also write the C ABI header next to the output as <output>.h. |
--emit-manifest |
(flag) | Also write the JSON export manifest next to the output as <output>.json. |
--search-path |
DIR |
Additional POST module source root for resolving imports. Repeatable. |
--backend |
{c,qbe,llvm} |
Code-generation backend. Default: c, or $POSTC_BACKEND (see precedence). |
--mode |
{debug,release} |
Build mode (see Build modes). Default: debug, or $POSTC_MODE. |
--release / --debug |
(flag) | Shorthand for --mode release / --mode debug. |
--no-overflow-checks |
(flag) | In a debug build, keep bounds checks and assertions but drop integer-overflow diagnosis (for code that relies on modular arithmetic). |
--cc |
CMD |
C compiler command. Default: cc. |
--cflags |
FLAG... |
Extra flags passed to both the compile and link steps. |
--keep-c |
(flag) | Keep the intermediate build directory (emitted .c / .ssa sources and objects) instead of deleting it. |
build prints the artifact path on stdout, followed by the header and/or manifest paths when those flags are set (--prefix prints all three). It exits 0 on success, 1 on a build error (subset violation, IR/ABI error, or toolchain failure), and 2 for a misused invocation — an unknown $POSTC_BACKEND, or combining --prefix with --ext-module.
--prefix and --ext-module are separate build targets
They cannot be combined. Build the extension with --output pointing into
the recipe's site-packages instead.
Examples¶
# Explicit output path
postc build examples/gaussian.py -o build/gaussian.so
# Emit the stable C ABI header and JSON manifest alongside the library
postc build src/lib.py --emit-header --emit-manifest
# Importable CPython extension module (C backend)
postc build mypkg/ --ext-module --module-name mypkg
# Lower the scalar/array kernel subset through QBE
postc build examples/blur.py --backend qbe
# Extra POST source root + a custom compiler and flags
postc build src/app.py --search-path vendor/ --cc clang --cflags -O3 -march=native
# Packaging layout: lib/, include/, share/postc/ under $PREFIX
postc build src/lib.py --prefix "$PREFIX"
Build modes¶
postc build defaults to a debug build — the mode that cannot silently disagree with CPython. --release (or --mode release) elides the runtime checks and is what the published benchmark numbers measure. The mode also honours $POSTC_MODE, with --mode/--release/--debug taking precedence.
| Construct | Debug (default) | Release |
|---|---|---|
| Array subscript | per-axis bounds check on the normalized index | no check |
assert |
evaluated; a failure reports and aborts | not lowered, as python -O does |
Integer + - * ** // %, unary -, abs |
overflow and division-by-zero diagnosed (the program aborts) | wraps at the declared width |
range(a, b, step) with a runtime step |
traps if step is zero |
no check |
| Float→int cast of NaN or ±infinity | reports and aborts | returns 0 |
The build mode is a frontend parameter: no backend branches on it, so a release artifact's IR is byte-identical to what it would have been without the modes existing. That invariant is what keeps a debug check from perturbing the QBE backend's loop optimizations in release. Integer arithmetic wraps in release and traps in debug — postc's answer to §4.1.1's requirement that a compiler document its overflow behaviour. See ADR-0002 for the full rationale and the measured cost (bounds checks are hoisted out of loops, so array code pays almost nothing).
postc build kernels.py # debug: checked
postc build kernels.py --release # release: elided, benchmarked
postc build kernels.py --no-overflow-checks # debug, minus only the overflow diagnosis
postc backends¶
Lists every registered backend with its availability on this machine, the source it emits, and its capabilities.
c available emits .c caps: complex, ext_module
llvm available emits .ll caps: (base)
qbe available emits .ssa caps: (base)
available means the backend's external tools are present: a C compiler for c; the qbe binary and a C compiler for qbe; llvmlite and a C compiler for llvm. Capabilities are drawn from complex, ext_module, and float16; (base) means none of those optional features (the scalar/array kernel subset the QBE and LLVM backends share).
postc backend-info¶
Shows one backend's name, emitted source extension, availability, and the full capability triple.
Exits 2 if BACKEND is not a registered name.
Backend selection¶
The build backend is chosen at runtime with a fixed precedence:
- an explicit
--backend {c,qbe,llvm}on the command line; - otherwise the
POSTC_BACKENDenvironment variable; - otherwise the default,
c.
POSTC_BACKEND=qbe postc build examples/gaussian.py # env selects qbe
postc build examples/gaussian.py --backend c # flag overrides env
--backend is validated against the registered backends. An invalid POSTC_BACKEND is not caught by that validation, so build reports it explicitly and exits 2:
See the C, QBE, and LLVM backend pages for what each lowers, and the backend protocol for the registry.