How to Integrate C++ Code with TypePHP Projects: A Complete Guide to External Import Stubs

To integrate C++ code with TypePHP, use the external import stub mechanism by declaring extern functions in PHP files wrapped in @import-library blocks, implementing them in C++ using the php:: namespace, and supplying the source files to the compiler via the TYPEPHP_GENERATED_SOURCE_LIST environment variable or the --extra-source flag.

TypePHP is an ahead-of-time compiler that transforms PHP source files into native C++ code, linking them into executables or WASI-compliant WebAssembly modules. While the transpilation process handles PHP logic automatically, developers often need to integrate hand-written C++ libraries for performance-critical operations or system-level access. According to the swoole/typephp source code, this integration is achieved through the external import stub system, which bridges PHP declarations with native C++ implementations by extracting signatures and linking them against custom object code.

Understanding the External Import Stub Mechanism

The integration relies on the LibraryImportStubGenerator class located in src/Generator/LibraryImportStubGenerator.php (lines 30-33). This generator scans PHP files for the @import-library docblock annotation, extracts extern function declarations, and produces stub files that the compiler treats as library imports.

When you compile a project, TypePHP parses these declarations to understand the expected C++ symbol signatures. The compiler then expects you to provide the actual implementations in separate C++ source files. During the final build phase in src/compiler.php (lines 108-112), the $translator->compile() method appends your custom C++ files to the compilation unit before $translator->build() links everything into the final binary.

Step-by-Step Integration Process

Declare External Symbols in PHP

Create a PHP file containing only extern declarations wrapped in an @import-library docblock. These declarations tell the compiler which C++ symbols to expect and their exact signatures.

<?php
/** @import-library */
extern php::Int my_ext_add(php::Int $a, php::Int $b);

/** @import-library */
extern php::String my_ext_greet(php::String $name);

The LibraryImportStubGenerator filters the AST to remove function bodies and retains only these signatures for the import stub.

Generate the Import Stub

Run the TypePHP compiler (tpc CLI) in normal compilation mode. The stub generator runs automatically, creating a proxy PHP file in the build directory that represents your C++ library interface. You do not need to manually invoke the generator; it triggers during the standard compilation pipeline when @import-library annotations are detected.

Implement Functions in C++

Create your C++ implementation files using the php:: namespace, as required by the extern declaration emission logic in src/Translator.php (lines 773-785). Use extern "C" linkage to prevent C++ name mangling and ensure symbol visibility matches the PHP declarations.

// my_ext.cpp
#include "php_namespace.h"  // Provides php::Int, php::String, etc.

extern "C" php::Int my_ext_add(php::Int a, php::Int b) {
    return a + b;
}

extern "C" php::String my_ext_greet(php::String name) {
    return php::String("Hello, " + name.c_str());
}

The generated C++ code expects symbols in the php:: namespace, so your hand-written functions must follow this convention exactly to link correctly.

Configure the Build System

You can supply custom C++ source files to the compiler using two methods:

Method 1: Command-line flag

php bin/tpc.php --extra-source path/to/my_ext.cpp my_project.php

Method 2: Environment variable Export TYPEPHP_GENERATED_SOURCE_LIST pointing to a text file containing absolute paths to all generated and custom C++ sources. The compiler reads this list at src/compiler.php (lines 95-101).

export TYPEPHP_GENERATED_SOURCE_LIST=$(pwd)/source.list
printf "%s\n" $(pwd)/my_ext.cpp >> $TYPEPHP_GENERATED_SOURCE_LIST
php bin/tpc.php my_project.php

Compile the Project

Execute the compiler as usual. The process executes three key phases:

  1. Parses PHP files and generates C++ code for them
  2. Invokes $translator->compile() (lines 108-112) to compile all source files, including your custom C++
  3. Invokes $translator->build() to link object files into the final executable
php bin/tpc.php my_project.php

Complete Working Example

The following demonstrates a minimal integration of a custom math library:

PHP Interface (extensions.php):

<?php
/** @import-library */
extern php::Int my_ext_add(php::Int $a, php::Int $b);
extern php::String my_ext_greet(php::String $name);

C++ Implementation (extensions_impl.cpp):

#include "php_namespace.h"

extern "C" php::Int my_ext_add(php::Int a, php::Int b) {
    return a + b;
}

extern "C" php::String my_ext_greet(php::String name) {
    return php::String("Hello, " + name.c_str());
}

Build Script:

#!/bin/bash
export TYPEPHP_GENERATED_SOURCE_LIST=$(pwd)/sources.txt

# List all C++ files to compile

find $(pwd) -name "*.cpp" > $TYPEPHP_GENERATED_SOURCE_LIST

# Compile the project

php bin/tpc.php main.php

WASM and WASI Considerations

If you target WebAssembly, the same stub mechanism applies. The compileWasmProgram function in src/compiler.php (lines 45-48) handles compilation with the WASI toolchain. Your C++ implementation files are compiled with the wasm32-wasi target alongside the generated TypePHP code, allowing seamless integration of native extensions into WebAssembly modules.

Summary

  • Use @import-library annotations to declare external C++ functions in PHP stub files.
  • Implement symbols in the php:: namespace using extern "C" linkage to match compiler expectations.
  • Supply source files via the TYPEPHP_GENERATED_SOURCE_LIST environment variable or the --extra-source CLI flag.
  • Reference key files: src/Generator/LibraryImportStubGenerator.php for stub generation, src/Translator.php for namespace requirements, and src/compiler.php for the build orchestration.

Frequently Asked Questions

What is the external import stub mechanism in TypePHP?

The external import stub mechanism is a compilation feature that allows developers to bridge PHP code with hand-written C++ implementations. The LibraryImportStubGenerator (located in src/Generator/LibraryImportStubGenerator.php) parses PHP files for @import-library annotations, extracts extern function signatures, and generates stub files that the compiler uses to link against native C++ object code during the build phase.

How do I declare external C++ functions in PHP?

Declare them as extern functions within a PHP file that includes the @import-library docblock annotation. These declarations must use TypePHP type hints such as php::Int or php::String to match the C++ namespace requirements defined in src/Translator.php. The function signatures in your C++ files must exactly match these PHP declarations, including parameter types and return types.

Where do I place my custom C++ source files?

You can place C++ source files (.cpp or .c) anywhere in your project directory. You must inform the compiler of their locations either by passing the --extra-source flag for individual files or by listing all paths in a file referenced by the TYPEPHP_GENERATED_SOURCE_LIST environment variable (as implemented in src/compiler.php lines 95-101).

Can I use this integration for WebAssembly targets?

Yes. The integration works identically for WASI/WebAssembly targets. When compiling with the WASM backend (see compileWasmProgram in src/compiler.php lines 45-48), the compiler includes your custom C++ files in the wasm32-wasi toolchain compilation. This allows you to embed native C++ logic into WebAssembly modules generated from TypePHP projects.

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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →