Skip to content

feat: static build support (--enable-php-debugger) - #47

Merged
pronskiy merged 6 commits into
mainfrom
feature/static-build
May 3, 2026
Merged

pronskiy merged 6 commits into
mainfrom
feature/static-build

Conversation

@pronskiy

@pronskiy pronskiy commented Apr 14, 2026 •

Copy link
Copy Markdown
Member

Adds support for compiling php_debugger as a static extension into php-src, producing a single binary with the debugger built in — no .so required.

Fixes #40

Usage

In-tree (php-src)

# Symlink or copy into php-src/ext/
ln -s /path/to/php-debugger ext/php_debugger

# Build
./buildconf --force
./configure --enable-php-debugger [other flags...]
make -j$(nproc)

# Verify
./sapi/cli/php -m | grep php_debugger

static-php-cli

Also verified with static-php-cli — produces a fully static, zero-dependency binary:

$ file php
ELF 64-bit LSB executable, x86-64, statically linked, stripped

$ ls -lh php
4.6M

$ ./php -v
PHP 8.4.20 (cli) (NTS x86_64-linux-musl-gcc)
Built by static-php-cli 2.8.5
Zend Engine v4.4.20
    with PHP Debugger v0.1.0-dev

$ ./php -r "var_dump(extension_loaded('php_debugger'), extension_loaded('xdebug'));"
bool(true)
bool(true)

static-php-cli recipe will be submitted as a separate PR.

Changes

  • MINIT self-registration — In static builds, zend_startup_extensions() has already run by MINIT time, so we register the Zend extension manually from PHP_MINIT_FUNCTION and call the startup functions inline
  • xdebug_zend_startup() guard — Early return in static builds to prevent double module registration when zend_startup_extensions() calls it after MINIT
  • php_php_debugger.h — Bridge header providing phpext_php_debugger_ptr for PHP's static extension table (main/internal_functions.c)
  • config.m4 — Add PHP_ADD_INCLUDE for header discovery
  • ZTS fix — COMPILE_DL_XDEBUG → COMPILE_DL_PHP_DEBUGGER in RINIT
  • CI — Dedicated static-build.yml workflow: builds PHP from source with --enable-php-debugger, runs smoke tests. Only triggers on changes to static-build-related files.

Benchmark (PHP 8.6.0-dev, bench.php, Linux x86_64)

Config Time Overhead
Vanilla PHP (no ext) 0.573s baseline
Static php_debugger (loaded, no client) 0.605s ~5.6%

Same observer API floor as the shared build.

Compatibility

  • extension_loaded("php_debugger") ✅
  • extension_loaded("xdebug") ✅ (compat alias)
  • All php_debugger.* and xdebug.* INI settings work
  • Shared builds (zend_extension=php_debugger.so) unaffected
  • Verified with static-php-cli (musl, fully static, 4.6 MB)

@pronskiy

pronskiy commented Apr 14, 2026 •

Copy link
Copy Markdown
Member Author

I want to add some automated test, but don't want to slow down the whole CI for that. Any suggestions?

Upd: added test

@pronskiy pronskiy added enhancement New feature or request static-build Static compilation, FrankenPHP, static-php-cli labels Apr 14, 2026
@pronskiy
pronskiy force-pushed the feature/static-build branch from 9ab4c01 to 6cb250d Compare April 14, 2026 19:15

@carlos-granados carlos-granados left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is brilliant @pronskiy

pronskiy added 5 commits May 2, 2026 23:49
Add support for compiling php_debugger as a static extension into php-src
using ./configure --enable-php-debugger (without --enable-shared).

Changes:
- MINIT self-registration: in static builds, the Zend extension is registered
  from PHP_MINIT_FUNCTION since zend_startup_extensions() has already run by
  the time MINIT fires. Manually calls xdebug_library_zend_startup() and
  xdebug_debugger_zend_startup() to replicate xdebug_zend_startup() logic.
- xdebug_zend_startup() early return: prevents double module registration
  when zend_startup_extensions() calls it after MINIT already initialized.
- php_php_debugger.h: bridge header providing phpext_php_debugger_ptr for
  PHP's static extension table (main/internal_functions.c).
- config.m4: add PHP_ADD_INCLUDE($ext_srcdir) for header discovery.
- Fix COMPILE_DL_XDEBUG -> COMPILE_DL_PHP_DEBUGGER in RINIT ZTS guard.

Benchmark (PHP 8.6.0-dev, bench.php):
  Vanilla PHP:           0.573s (baseline)
  Static php_debugger:   0.605s (~5.6% overhead, observer API floor)
Dedicated CI job that builds PHP from source with --enable-php-debugger
and verifies the extension loads correctly as a static build.

Only triggers on changes to config.m4, php_php_debugger.h, xdebug.c,
or the workflow itself — does not slow down the main test suite.

Smoke tests:
- Module list (php_debugger + xdebug compat)
- Zend extension registration
- extension_loaded() for both names
- INI settings (both prefixes)
- Function existence (both aliases)
config.m4 includes m4/pkg.m4 and m4/clocks.m4 which resolve relative
to the php-src root, not the extension directory.
Remove cache step (not worth complexity for a rarely-triggered workflow).
Always clone fresh — simpler and more reliable.
@pronskiy
pronskiy force-pushed the feature/static-build branch from dd6d678 to 14bc967 Compare May 2, 2026 21:49
Registers php_debugger_info as a ZEND_FALIAS of xdebug_info so the
php_debugger_* function namespace has at least one user-visible entry
point alongside the php_debugger.* INI namespace.

Updates the static-build smoke test to assert php_debugger_info()
exists, replacing a stale assertion for php_debugger_break() (an alias
that was removed when arginfo got regenerated in #48).
@pronskiy
pronskiy merged commit 1a27e5b into main May 3, 2026
16 checks passed
@carlos-granados
carlos-granados deleted the feature/static-build branch May 3, 2026 19:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request static-build Static compilation, FrankenPHP, static-php-cli

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Allow compiling this debugger statically into the php core

2 participants