One binary does everything: compiling, linking, serving editors, cleaning up. Every flag has a short and a long spelling (-c and --compile are the same flag), values are case-insensitive where they name a choice, and flags that take a list separate its items with commas.

A representative build:

mica --compile --link --optimize release \
     --platform linux,amd64,utf-8 \
     --source Hello.mica --build build

Modes

FlagEffect
-c | --compilecompile source files to assembly
-l | --linklink the compiled objects into the output program or library — requires --compile
-r | --runcompile one source file and immediately execute it, like a script; --run - reads the source from standard input
--lsprun as a language server over standard input and output; the VS Code extension is the packaged client, and any LSP-capable editor can be pointed at the command
-p | --purgeempty the build directory first — requires --build, and may run without --compile
-v | --versionprint version information and exit
-h | --helpprint the flag summary and exit

At least one of --compile or --purge must be present; everything else qualifies them. --lsp stands alone: it claims standard output for the protocol and prints no banner.

The run mode

mica --run tool.mica compiles the file into a temporary directory at the debug tier — checks maximal, latency milliseconds — executes it, forwards the program’s exit code as its own, and cleans up. Nothing is cached and nothing lands beside your file.

mica --run tool.mica alpha beta      # everything after the file belongs to the program
mica tool.mica alpha beta            # the bare spelling means the same
mica --run - << 'EOF'                # a here-document is a program
program Hi; imp WriteLn : std; begin WriteLn("hi"); end.
EOF

The rules, each of which is the scripting convention:

  • Arguments. Everything after the source file belongs to the program (readable through the process unit’s ArgCount and Arg); an optional -- between file and arguments is accepted. Compiler flags come before --run.
  • Exit code. The program’s exit code is the process exit code — callers branch on it.
  • Streams. The program owns standard output. The compiler is silent on success, keeps warnings, and speaks on standard error only.
  • Shebang. A leading #! line belongs to the operating system, and the compiler’s source preparation removes it on every road — the build, the editor, and the run mode all read the file identically, with line numbers preserved. The bare spelling makes #!/usr/bin/env mica a working first line — chmod +x and the file runs — and it also accepts an existing file with no extension, so a script installed under a command name stays a command.
  • Projects. The nearest mica.project up the directory tree contributes its encoding and contracts — a script beside your project imports your libraries with no flags — and when the file is one of the project’s own sources, the whole source set compiles with it.
  • Flags. The run mode owns compilation, linking, and the build directory; it combines with --optimize, --stdlib, --memory-class, --tasking, and --stack-size, and refuses everything else with one line. It targets the host architecture; cross builds go through --compile.

Inputs and outputs

FlagValueEffect
-s | --sourcefile.mica,file.mica,…the source files of the build, comma-separated
-pj | --projectpath to mica.project or its directoryread the compilation’s facts — sources, encoding, consumed contracts — from a project file; every explicit flag overrides its entry
-b | --builddirectorywhere every generated file lands; the linked binary is named after the first source file’s program or library
-sl | --stdlibpath to an archivename a standard library explicitly; when omitted, the compiler resolves mica-stdlib-<arch>.a next to its own executable first, then under /usr/lib/
-xc | --external-contractone or more paths to mica.external or its directory, comma-separatedconsume external libraries’ interop contracts from explicit locations instead of the source-directory lookup; several paths let one program import several separately built libraries, each through its own emitted contract

The project file. A mica.project beside the sources states what belongs to the source tree rather than to any one invocation:

{
    "sources": ["Consumer.mica"],
    "encoding": "utf-8",
    "contracts": ["../build/Utilities", "../build/LibB"]
}

--project reads it, explicit flags override its entries one by one, and a --platform that names no encoding — linux,arm64 — completes its encoding from the file. The language server discovers the project on its own by walking up from the open file, so the editor analyzes each source under the same sources, encoding, and contracts the build uses, with no configuration. The file is ignored by compilers older than 6.12.5.

Naming a standard library explicitly is also a statement of trust: a mica-stdlib-<encoding>.external contract beside the named archive is used as that library’s import surface. An auto-resolved standard library uses only the surface embedded in the compiler binary — no file on disk changes what an installed compiler believes. One contradiction is refused rather than honoured: an archive that does not match the declared --memory-class — a hosted archive for a fixed-arena program, or the reverse — is refused with the consequence spelled out, because honouring it would link a fixed-arena program with no arena at all.

What is built

FlagValuesEffect
-om | --output-modifiernone · archive · objectthe library output kind: archive produces a static library (.a), object a shared object (.so), none (default) an executable program — requires --link
-ext | --externalstatic · sharedhow external C libraries are linked; the default is static, which needs no rpath and ships as one artifact — requires --link
-ec | --emit-contractwhen linking a library, emit its interop contract (mica.external) beside the archive so other builds can import it — requires --link
-np | --no-piedisable position-independent-executable output — requires --link

Target selection

FlagValueEffect
-pf | --platformos,arch,encodingthe target platform, e.g. linux,arm64,utf-8 — requires --compile
-asm | --assemblyintel · attthe emitted assembly syntax; the default is intel — requires --compile

The accepted values: operating system linux; architecture amd64 or arm64; string encoding utf-32 or utf-8. All four Linux combinations are valid. The default platform is linux,amd64,utf-32. The string encoding is fixed per binary — utf-32 is the general-purpose default, utf-8 the interop-oriented choice; format specifiers follow it (%ls under utf-32, %s under utf-8), and the compiler checks them at compile time.

Optimization

FlagValueEffect
-o | --optimizecomma-separated setselect the optimization profile and passes — requires --compile; when the flag is omitted entirely, the build is a plain debug build

The three spellings almost everyone uses:

LevelExpands toMeaning
O0debugevery variable observable, every line breakable — the profile a debugger wants
O1release,standard_optimizationsthe release profile with the standard pass set
O2release,full_optimizationsthe release profile with the full optimizing set

O3 is refused by name, with an explanation: the transformations that would distinguish it from O2 — vectorization, loop unrolling — do not exist yet, and an alias that silently meant O2 would be a promise the compiler does not keep.

The set may also name its members directly: the profiles debug and release (mutually exclusive; naming neither in a non-empty set defaults to release), checked for the checked runtime diagnostics on top of the debug profile, the group names standard_optimizations and full_optimizations, and the individual pass names constant_folding, assembly_peephole, stub_allocator, graph_allocator, function_inlining, loop_optimization, fp_contract, heap_contract — plus the two code-generation modes il_static_single_assignment and il_direct_lowering, which are mutually exclusive and exist for differential testing of the middle end. Individually named passes are an instrument for working on the compiler; programs are shipped with O0, O1, or O2.

Deployment classes

FlagValuesEffect
-mc | --memory-classhosted · fixed-arena · fixed-arena=<bytes>the memory deployment class; selects the matching standard-library archive. hosted (default) uses the operating system’s heap; fixed-arena places the whole program heap in one arena of the given size, for deployments that must not allocate after start
-tk | --taskingsingle · multicore · multicore,<carriers>the tasking flavor. multicore runs tasks on a carrier pool whose size is fixed at compile time — one binary, one known parallelism; a count of 0 (or none) sizes the pool from the online processors at start — and links the multicore standard-library archive

Diagnostics and analysis

FlagValueEffect
-fb | --frame-budgetbyteswarn when a function’s stack frame exceeds the budget (default 1048576); frames no default stack could hold are always errors
-ss | --stack-sizebytesgive the program this many bytes of stack: the compile-time frame ceiling admits frames up to this size — in both directions, so a small embedded request tightens the ceiling — and a linked program raises its own stack limit before main runs (default: the platform’s 8 MiB). Combines with --run
-vb | --verbosereport the per-source optimization statistics beside the build: what each pass folded, inlined, forwarded, elided and declined — requires --compile
-exp | --exportwrite every intermediate representation to the build directory — requires --compile
-pr | --profileprint a per-phase and per-pass compile-time table and write profile.json to the build directory — requires --compile
-q | --qualitysemantic_analysis · intermediate_code · no_quality_gatesextra verification runs inside the compiler, for root-cause analysis of internal compiler errors — requires --compile
-cp | --cpu-profilefilewrite a CPU profile of the compiler itself to the file
-mp | --mem-profilefilewrite a memory profile of the compiler itself to the file

The combination rules

The compiler refuses inconsistent combinations rather than guessing: --link requires --compile; --no-pie, --emit-contract, --output-modifier and --external require --link; --optimize, --platform, --assembly, --export, --profile and --quality require --compile; --purge requires --build. Each refusal names the rule.