Skip to content

The Prelude

Andrew Lind edited this page Jun 19, 2026 · 3 revisions

Hatchet transpiles a standalone project — plain Haxe with no extern interop layer — with no special setup: cross-file types resolve, a type used without an explicit import (legal for same-package Haxe) still has its header pulled in, and the standard-library prelude is generated automatically.

Hatchet owns that prelude — it knows which headers its supported idioms need (NULL/<stdlib.h>, sprintf/<stdio.h>, <math.h>, std::string/std::vector/std::map, …) — so it always emits a prelude header into each output directory and includes it from every generated header. A standalone project therefore compiles out of the box. The prelude header is named StdAfx.h by default; --stdafx MyGame renames the source/header pair.

If you provide a prelude source (StdAfx.hx, or the configured name), its @:headerCode is merged with the required headers (de-duplicated), so your custom pragmas/includes are kept and nothing is doubled. @:include is still available on any file — @:native or not — for headers beyond the prelude; a system header in angle brackets is emitted verbatim (#include <string>), a project header stays relative and quoted.

Header-only output

With --header-only <NAME> the prelude is inlined at the top of the single amalgamated <NAME>.h instead of emitted as a separate StdAfx.h — so the result is one self-contained header (prelude, every class declaration, and every method body inline) with no .cpp and nothing to #include. Any StdAfx.hx @:headerCode in scope is still merged into that inlined prelude, and the native @:includes of all amalgamated modules are hoisted to the top, de-duplicated. See Building & Usage for the flag.

Because everything lands in one file with no includes to resolve the order, Hatchet topologically sorts the modules: whenever one needs a type from another complete — a base class (extends/implements) or a value (non-pointer) field — the defining module is emitted first (pointer cross-references are covered by a global forward-declaration block, so they impose no order). The original --src order is preserved wherever it is not constrained. A genuine cross-module dependency cycle (a base class or by-value field that loops back across modules) is reported as a hard error rather than emitted as non-compiling C++.

Clone this wiki locally