-
Notifications
You must be signed in to change notification settings - Fork 0
Building and Usage
- Rust (stable; install via rustup)
- A C++98 toolchain to build the generated output. The development validation gate uses
g++ -std=c++98; the production target is Visual C++ 6.0 up.
cargo build # debug binary at target/debug/hatchet
cargo build --release # optimized binary at target/release/hatchet
cargo test # unit tests, header/body codegen checks, and the C++98 compile+run gates# Transpile a whole project — point --src at its root directory; Hatchet crawls it
# recursively for .hx. The C++ namespace of each file follows its Haxe `package`, and
# the project root is inferred from that package.
hatchet --src path/to/project --out path/to/output --force
# A glob works too (expanded by Hatchet itself, so quote it on shells that would
# otherwise expand it). Mix files, dirs, and globs freely:
hatchet --src src/*.hx --out path/to/output
# Transpile a single file — pass its dependencies too (superclasses, native stubs),
# since the listed sources are the entire resolution scope:
hatchet --src src/Button.hx src/Widget.hx --out path/to/output
# Resolve against native stubs without transpiling them (--include is resolve-only)
hatchet --src src --include native --out path/to/output
# Amalgamate everything into one self-contained, header-only library (no .cpp, no StdAfx.h)
hatchet --src src --header-only MyLib --out path/to/output
# Preview on stdout, or validate without writing anything:
hatchet --src src/Button.hx src/Widget.hx --stdout
hatchet --src . --dry-run
# Run interactively (prompts for a source and a target dir) when --src is omitted:
hatchet--src accepts any mix of single .hx files, directories (crawled recursively for .hx), and
globs (*, ?, ** — e.g. src/*.hx or src/**/*.hx). Globs are expanded by Hatchet itself,
so quoting them to bypass shell expansion works. The full expanded set, plus any --include
inputs, is the entire resolution scope, so a file's dependencies (superclasses, extern stubs)
must be reachable in it — crawl the project root to pull everything in. Each file's project root —
the base for the output layout and relative includes — is inferred from its package declaration (the
file's directory minus its package path).
Native stubs (extern / @:native declarations that name hand-written C++) are best supplied via
--include rather than --src: like --src it accepts files, directories, and globs and adds
them to the resolution scope, but the files it names are resolve-only — never transpiled (the Haxe
equivalent of passing a C/C++ header). Only their @:include directives propagate into the generated
output. Anything reached through --include is simply not a transpilation target, so a stray
non-extern class there is silently skipped, not emitted.
| Flag | Description |
|---|---|
--src, -s <PATH>... |
Haxe sources to transpile — any mix of .hx files, directories (crawled recursively), and globs (*/?/**); prompted if omitted. Together with --include, the full resolution scope |
--include <PATH>... |
Resolve-only inputs (files/dirs/globs, like --src): added to the resolution scope so the --src files' native references resolve and their @:include headers propagate, but never transpiled — the Haxe equivalent of a C/C++ header. A non-extern file reached here is silently not emitted (it is not a transpilation target) |
--header-only <NAME> |
Amalgamate all --src content into one self-contained header <NAME>.h (a trailing .h is stripped): the prelude is inlined, every class and module-level free function is emitted with inline bodies, and no .cpp or separate prelude header is produced — a drop-in single-header library. Resolve-only --include stubs are not folded in (only their @:includes are hoisted). Free-function names must be unique within a package (one shared namespace); only @cexport extern "C" exports remain unsupported (an exported symbol needs an object file) |
--out, -o <DIR> |
Output directory (defaults to the inferred project root; ignored with --dry-run/--stdout). Generated files mirror the source package layout; includes that point at external dependencies (a native library, a sibling project) are re-pointed at the dependency's real location when needed, so --out resolves from any directory |
--force |
Overwrite existing generated files (ignored with --dry-run) |
--dry-run |
Transpile and report info/warnings/errors only — write nothing. Takes precedence over --stdout/-o/--force
|
--stdout |
Write generated C++ to stdout instead of files (status goes to stderr) |
--stdafx <NAME> |
Stem of the prelude source/header (default StdAfx → StdAfx.h; e.g. MyGame → MyGame.h) |
--export-macro <PREFIX> |
Prefix for the portable export macros wrapped around @cexport functions and @libexport classes (default HATCHET → HATCHET_EXPORT/HATCHET_CALL/HATCHET_CLASS) |
--depth <N> |
Max expression-nesting depth at which a buried Null<T> call is auto-extracted into a freed local instead of warned about (default 1; e.g. 2 auto-extracts if (GetEdge(e) == null)) |
--no-traces |
Strip all trace(...) calls from the generated C++ (lowered to no-ops, arguments not evaluated), mirroring hxcpp's -D no-traces
|
Every generated file opens with a provenance comment naming the repository and the transpiler version —
// Generated by Hatchet (https://github.com/andrewglind/hatchet) v<version>, the same version string
--version reports. It is a // comment ahead of the include guard, so it never affects compilation.
A Main.hx is never transpiled — it is treated as the hxcpp entry point only.
Hatchet is licensed under the MIT License — see LICENSE. (c) 2026 Andrew Grant Lind
Getting Started
Language Support
- Declarations
- Value Types & Abstracts
- Members & Access
- Statements & Expressions
- Types & Nullability
- Conditional Compilation
- Memory Ownership
Semantics & Interop
Internals