When Is `main()` Required for a TypePHP Build? Executable vs Library Guide
In TypePHP, a main() function is required only when compiling to an executable target—either a native binary or a WASI WebAssembly module—while library and test builds compile successfully without this entry point.
The swoole/typephp compiler uses the presence of a function main(...): void declaration to determine the artifact type it will produce. Understanding this distinction ensures you implement the correct entry point for your use case and avoid compilation errors in executable builds.
Executable Builds That Require main()
TypePHP mandates a main() function whenever the compilation target is an executable, as the runtime needs a defined entry point to begin execution.
Native Stand-Alone Executables
When running the compiler in default mode (without special flags), TypePHP generates a native binary that starts execution at your user-defined main() function. The compiler expects the exact signature function main(int $argc, array $argv): void to properly handle command-line arguments.
<?php
function main(int $argc, array $argv): void
{
echo "Hello from TypePHP!\n";
// Application logic receives $argv via the parameter
}
According to the source code in src/Translator.php, the compilation process validates that this entry point exists before generating the binary artifact. The src/compiler.php file itself implements this pattern, containing a function main(int $argc, array $argv) that serves as the CLI entry point for the compiler tool.
WASI and WebAssembly Targets (--wasm)
When targeting WebAssembly with the --wasm flag, TypePHP produces a WASI program that still requires an exported main function. As documented in docs/en/wasm.md, the WASI runtime expects this specific function to serve as the module entry point.
<?php
function main(): void
{
// WASI programs start here; access stdin/stdout via WASI APIs
echo "Running inside WASI\n";
}
While the parameter signature can be flexible for WASI builds, the function name must be main for the WebAssembly module to initialize correctly when loaded by the host runtime.
Builds That Omit main()
Not every TypePHP project requires an entry point. Library and test builds skip the main() requirement entirely since they produce code invoked by other systems rather than standing alone.
Library Builds (--library)
When compiling with the --library flag (or equivalent), TypePHP generates only object files or a static archive. Since library code is linked into other applications rather than executed directly, no entry point is necessary.
<?php
// Compiled into a library archive without a main function
function add(int $a, int $b): int
{
return $a + $b;
}
The src/Translator.php logic bypasses entry point validation when operating in library mode, focusing instead on exporting the public API defined in your source files.
Test Harnesses and Internal Scripts
Test builds executed through the built-in test runner (run-tests.php) or PHPUnit do not require a main() function. The test harness invokes your code directly, making an entry point unnecessary. Files like phpunit/src/Testing/TestCoverageAnalyzerTest.php demonstrate this pattern, containing test logic without a main() implementation.
How the Compiler Detects the Entry Point
The TypePHP build system inspects your source code during the translation phase to determine output type. In src/Translator.php, the project parsing logic checks for the existence of a global main() function to decide whether to produce a binary executable or a library archive.
This detection happens early in the compilation pipeline. If the compiler targets an executable format (native or WASI) and cannot locate a main() function in the global scope, it will report an error before code generation begins. For library builds, this check is skipped entirely, allowing the compilation to proceed with only utility functions and classes.
Summary
- Executable builds require
main(): Native binaries and WASI WebAssembly modules must definefunction main(int $argc, array $argv): void(orfunction main(): voidfor WASI) to provide an entry point. - Library builds skip
main(): Compiling with--libraryproduces object files or archives without needing an entry point. - Test builds don't need
main(): The test runner invokes code directly, eliminating the requirement for amain()function. - Compiler validation: The logic in
src/Translator.phpenforces these requirements based on CLI flags passed to the compiler.
Frequently Asked Questions
What happens if I forget to include main() in an executable build?
The TypePHP compiler will fail with a compilation error during the translation phase. As implemented in src/Translator.php, the build system explicitly verifies that a main() function exists when targeting executable output, ensuring the generated binary has a valid entry point to begin execution.
Can I name my entry point something other than main()?
No. TypePHP follows the C convention and requires the entry point to be named exactly main. The compilerlooks for this specific function name when determining build type and generating the executable bootstrap code in src/compiler.php.
Do I need parameters in my main() function for WASI builds?
While native executable builds require the signature function main(int $argc, array $argv): void, WASI builds documented in docs/en/wasm.md are more flexible. You can define function main(): void without parameters and still access WASI APIs for input/output, though including the parameters is also valid if you need argument access.
How do I access command-line arguments in a TypePHP application?
For native executable builds, access command-line arguments through the $argc (argument count) and $argv (argument array) parameters passed to your main() function. This mirrors the C convention and is the standard method implemented in the TypePHP runtime as shown in the src/compiler.php implementation.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →