[v3] - feat(windows): static embed SAPI build support#1176
Closed
luthermonson wants to merge 1 commit into
Closed
Conversation
Enable building and validating php8embed as a fat static library on
Windows (no DLL dependency at runtime). This consists of three Makefile
patches and a rewritten compile-time smoke test.
1. CFLAGS_EMBED export defines
Embed SAPI objects are compiled as DLL consumers by default, so calls
into PHP/Zend APIs go through __imp_ thunks. For a fat static lib
they need direct linkage. Inject PHP_EXPORTS, LIBZEND_EXPORTS,
SAPI_EXPORTS, TSRM_EXPORTS into CFLAGS_EMBED so php_embed.obj
references symbols directly.
2. Strip duplicate TSRM cache definition from php_embed.c
In DLL builds each SAPI has its own _tsrm_ls_cache via
TSRMLS_CACHE_DEFINE(). In our fat static lib all objects share one
binary, so php_embed.c's definition collides with zend.c's, producing
LNK4006 and a corrupt binary. Remove the duplicate in-source so
php_embed.obj uses zend.c's copy.
3. Rewrite embed smoke test
The PHP_EMBED_START_BLOCK/END_BLOCK macros expand to setjmp/longjmp
and a zend_first_try wrapper that doesn't work cleanly when the
embed lib's TSRM cache was stripped above. Use the explicit
php_embed_init / zend_first_try / php_embed_shutdown form instead.
Also:
- Add PHP_EXPORTS/LIBZEND_EXPORTS/SAPI_EXPORTS/TSRM_EXPORTS to the
test compile flags (mirroring CFLAGS_EMBED).
- Add pathcch.lib (PHP 8.x main/streams calls PathCchCanonicalizeEx).
- Remove /FORCE:MULTIPLE from the link line - no longer needed since
the TSRM cache duplicate is fixed at source above.
- Use str_contains() for output validation instead of exact match,
so optional stderr noise from the loaded extensions doesn't break
the test.
henderkes
reviewed
May 28, 2026
henderkes
reviewed
May 28, 2026
henderkes
reviewed
May 28, 2026
Contributor
Author
|
We are going to do this upstream 😨 ill post linked PRs when I get them up and close |
Contributor
Author
|
php/php-src#22166 thanks again for the help @henderkes i think this is right based on the hacks that worked here to get builds working again. let's see if they get through. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
From the beginning I couldn't really get windows static builds to work in v3 as you can probably tell by my 4 PRs tonight, if for some reason these changes are not welcome because I'm missing something that already works in v3 please let me know.
Enable building and validating php8embed as a fat static library on Windows (no DLL dependency at runtime). This consists of three Makefile patches and a rewritten compile-time smoke test.
CFLAGS_EMBED export defines
Embed SAPI objects are compiled as DLL consumers by default, so calls into PHP/Zend APIs go through _imp thunks. For a fat static lib they need direct linkage. Inject PHP_EXPORTS, LIBZEND_EXPORTS, SAPI_EXPORTS, TSRM_EXPORTS into CFLAGS_EMBED so php_embed.obj references symbols directly.
Strip duplicate TSRM cache definition from php_embed.c
In DLL builds each SAPI has its own _tsrm_ls_cache via TSRMLS_CACHE_DEFINE(). In our fat static lib all objects share one binary, so php_embed.c's definition collides with zend.c's, producing LNK4006 and a corrupt binary. Remove the duplicate in-source so php_embed.obj uses zend.c's copy.
Rewrite embed smoke test
The PHP_EMBED_START_BLOCK/END_BLOCK macros expand to setjmp/longjmp and a zend_first_try wrapper that doesn't work cleanly when the embed lib's TSRM cache was stripped above. Use the explicit php_embed_init / zend_first_try / php_embed_shutdown form instead.
Also: