Skip to content

Compiler usage

This section covers driving the xcc toolchain: picking flags, choosing memory models, tuning the optimiser, configuring the allocator, and writing your own linker script when needed. It deals with what affects the binary rather than the source. Language details (syntax, types, classes) are in the Language reference, and standard-library APIs are under Standard library.

Terminal window
xcc -o game game.xc

This is a complete native build. With no -A the target is this machine, the standard library is found relative to the xcc binary, and the optimiser runs at -O3. Cross-compiling adds one flag:

Terminal window
xcc -A 6502 -Q loop -o game.xex game.xc
xcc: optimised -O3 (9877 → 9698 instructions)
xcc: compiled 'game.xc' -> 'game.xex' (0 warnings, 0 errors)
xcc-as: assembled -> 'game.xex' (19975 bytes, 1 segments)

By default the compiler prints a short summary of what the optimiser did, what was compiled, and what the assembler emitted. -q silences this informational output for build scripts.

  • Install: where make install puts things, and how xcc locates its own libraries. Read this first.
  • CLI flag reference: every command-line option, grouped by purpose. Start here to look up a specific flag.
  • Optimisation: what each -O level adds, the tuning knobs (-Fli, -Flu), and how to read the optimiser’s before/after instruction count.
  • Memory models: the xt6502 map, with two bank windows, the 4 KB hardware stack, and the on-demand banked heap. 6502 only; the native targets have no layout to choose.
  • Allocator & ARC: -falloc=bump vs -falloc=heap, and the -farc=on|off choice between automatic and manual reference counting.
  • Linker scripts (.lnk): the file format that defines a memory model. Customise an existing layout or write a new one for non-standard hardware.
  • Function annotations (:banked, :main, :shadow, :irq, :vbi, :naked, :hwStack, :xtcStack, :needsOS) are language-level placement and calling-convention markers. They are on the Functions page.
  • Memory-model implementation details (bank-switching mechanics, the _xcall trampoline, ZP byte allocation) are documented in the language pages where they affect semantics: Functions, Heap, ARC & weak refs, Inline assembly.
  • Standard-library APIs such as Heap.size() and Vbi.addDeferred() are under Standard library.

On a native target (arm64, x86_64, win64, arm9) the output is a runnable executable unless -o ends in .s (assembly) or .o (object). --emit-lib produces a shared library instead. xcc carries its own assembler and linker, so no system tools are involved.

On 6502 and m68k the -o extension picks the container, or the [output] section of the active .lnk file does:

ExtensionFormat
.asmassembly source (stops before the assembler)
.xex, .exe, .bin, .combanked 6502 executable (.xex)
.tos, .prgGEMDOS executable (m68k)

A wasm32 build emits a .wasm module, or WAT text when -o ends in .wat.

Asking for .asm or .s stops the pipeline after code generation, which lets you inspect what the compiler produced.

xcc locates its support tree (standard library, linker scripts, runtime asm) by probing each of these roots for lib/xc, then xc, then support:

-H <path> > $XCC_HOME > $XTC_HOME > the directory holding xcc, and its parent
> cwd > ~/xcc > ~/xtc > /opt/xcc/<version> > /opt/xcc
> /usr/local/xcc > /usr/local/xtc > /opt/xtc

The binary-relative step makes an install self-locating, so in normal use you set nothing. -H (or $XCC_HOME) points a specific compiler at a specific tree, most often when running one from a source checkout. -V prints which root was chosen. Details are on Install.