Compiling Overview
How the elephc command-line compiler turns a PHP file into a standalone native binary, and a map of the compilation documentation.
elephc is an ahead-of-time compiler: it reads a tagged .php or tagless .lfc
file and produces a
standalone native binary with no PHP, Zend Engine, or external virtual-machine
dependency. Ordinary source is machine code linked against a small hand-written
runtime baked into the executable. Experimental dynamic eval() is the explicit
exception: fragments that cannot be AOT-lowered embed the optional Magician
interpreter bridge in that same standalone binary.
Basic invocation
elephc hello.php
./hello
For extension-oriented programs, .lfc removes PHP’s opening and closing tags:
echo "Hello from tagless source!\n";
elephc hello.lfc
./hello
The compiler writes the output binary next to the source file, using the source
name without its extension (hello.php or hello.lfc → hello). Nothing else
is produced by default — no intermediate object files are left behind, no cache
pollution in your project directory. See
LFC source files for tags, mixed-project
includes/autoloading, and --strict-php.
elephc src/app.php # produces ./src/app
./src/app
What happens during a compile
A compile runs the source through a fixed sequence of phases — lexing, parsing,
name resolution, type checking, AST optimization, lowering to elephc’s
intermediate representation (EIR), EIR optimization, native code generation, and
linking. Each phase is described in
The compilation pipeline, and you can see how long
each one takes with --timings.
By default the compiler:
- targets the host platform (see Targets and cross-compilation),
- uses the EIR backend with the linear-scan register allocator and the EIR optimization passes enabled (see Optimization and codegen controls),
- emits a native executable (see Output formats and diagnostics),
- and uses an 8 MB heap (see Linking, heap, and conditional compilation).
Every one of these defaults can be changed with a command-line flag.
No runtime, one file
The runtime routines the program needs (string formatting, the allocator, reference-counting GC, hash tables, I/O, exception unwinding, and so on) are emitted as assembly and linked directly into the binary. The result is a single self-contained executable you can copy to another machine of the same target and run. See The Runtime for what those routines are.
Documentation map
| Page | Covers |
|---|---|
| The compilation pipeline | Every phase from source text to binary, in order |
| CLI reference | The complete, authoritative list of every flag |
| Targets and cross-compilation | The supported target matrix and --target |
| Native dependencies | elephc native, project manifests/locks, verified artifacts, cache identity, and toolchain selection |
| Optimization and codegen controls | --regalloc, --ir-opt, --null-repr, and what they do |
| Output formats and diagnostics | --emit, --emit-asm, --emit-ir, --check, --timings, --source-map, --gc-stats, --heap-debug |
| Linking, heap, and conditional compilation | --link, --link-path, --framework, --heap-size, --define |
For the internals behind these phases, see The Pipeline, The Code Generator, and The EIR Design.