Targets
PXX can emit native and cross-target output from the same compiler invocation.
Supported target names
| Target | Output | Typical run path |
|---|---|---|
x86_64 |
Native Linux ELF executable (the default). | Run directly on x86-64 Linux. |
i386 |
32-bit Linux ELF executable. | Run directly on hosts with i386 support, or via qemu-i386. |
aarch64 |
64-bit ARM Linux ELF executable. | Run via qemu-aarch64 on non-ARM hosts. |
arm32 |
32-bit ARM Linux ELF executable. | Run via qemu-arm on non-ARM hosts. |
riscv32 |
32-bit RISC-V Linux ELF, or an ESP32-C3 object or bare-metal image. | Linux binaries run via qemu-riscv32; for ESP see ESP32. |
xtensa |
ESP32-S2/S3 object or bare-metal image. | See ESP32. |
wasm32 |
WebAssembly module. | Run with wasmtime. |
pxx --list-targets prints this list for your build. From pin v425 it
describes wasm32 as via wasmtime for Pascal, C and Nil Python; v424 wrongly
said "registered only — no codegen yet". The table below shows what wasm32
actually does.
ESP chip names are accepted as targets too. They imply the CPU and
--platform=esp: esp32, esp32s2 and esp32s3 are xtensa; esp32c2,
esp32c3, esp32c6, esp32h2 and esp32p4 are riscv32. Pin v445 compiles
an ESP-IDF object for every one of these names (re-checked 2026-09-27). The bare-metal profile supports
only esp32s3 and esp32c3, and says so for the others. It runs under QEMU
only; on a real board use the ESP-IDF profile (see
known issues). The ESP32-S3 and the
ESP32-C3 have been run on physical boards (with the ESP-IDF profile); the
rest have only been compiled.
Use --target=ARCH before the source file:
./pxx --target=aarch64 hello.pas hello.a64
For Linux cross-target executables, tools/run_target.sh chooses the right QEMU
user-mode runner when the host cannot execute the file directly.
tools/run_target.sh aarch64 ./hello.a64
For ESP32 targets, start with the board-specific examples under
examples/esp32/; the peripheral units are in
ESP32 peripherals.
What each target supports
Measured with pin v445 (compiler sha256 caf21ac399f1…) on 2026-09-27;
every cell is the same as with v425. Programs other than x86-64 ones were run
under QEMU user mode, and wasm32 under wasmtime; none of the Linux cross
targets was run on real hardware for this table. The probes: a class with an
exception caught and a line written; writeln(SizeOf(Real));
test/lib_classes_tthread.pas and test/c_pthread_detach.c; a threadvar
set and read; --emit-obj on test/c_obj_data_export.c; --shared on
test/test_library_exports.pas; a Nil Python sum of a list; and C's
sqrt(2.0).
| x86-64 | i386 | aarch64 | arm32 | riscv32 Linux | wasm32 | |
|---|---|---|---|---|---|---|
| Pascal classes, exceptions, console I/O | yes | yes | yes | yes | yes | yes |
SizeOf(Real) |
8 | 8 | 8 | 8 | 4 | 8 |
Threads (TThread, C pthread_create) with --threadsafe |
yes | yes | yes | yes | refused | refused |
Pascal threadvar |
yes | yes (from v446) | yes | yes | refused | refused |
--emit-obj (relocatable object) |
yes | yes | yes | yes | yes | refused |
--shared (shared library) |
yes | refused | refused | refused | refused | refused |
| Nil Python | yes | yes | yes | yes | refused | yes |
C with #include <math.h> |
yes | yes | yes | yes | yes | yes |
Compared with v424, one cell changed: wasm32 C with math.h was refused
there. Pascal threadvar on i386 is refused with v445 and works from
v446 (7dc976a8cc, which also gives each i386 thread its own C __thread
copies). On 2026-09-28, the two thread rows were measured again with pin v446
(ae3466a018d8) and with the compiler at e072d579b0, under QEMU: each
thread kept its own threadvar and __thread values on x86-64, i386,
aarch64 and arm32. See Threads & parallelism.
Every refused cell is a compile-time error that names the reason; none
produces a program that runs wrongly. Most messages say in plain words what is
unsupported, for example --threadsafe is available for x86-64, i386, aarch64 and arm32 only; it is refused for riscv32. and, for every target but x86-64,
--shared: shared-library output is x86-64 only. xtensa also has an object
writer; it is the ESP-IDF route.