Skip to content

Getting Windows Embed Working#1079

Open
luthermonson wants to merge 3 commits intocrazywhalecc:mainfrom
luthermonson:embed-windows
Open

Getting Windows Embed Working#1079
luthermonson wants to merge 3 commits intocrazywhalecc:mainfrom
luthermonson:embed-windows

Conversation

@luthermonson
Copy link
Copy Markdown

Add Windows embed SAPI support & fix archive extraction

Embed SAPI (WindowsBuilder.php)

Implements the buildEmbed() method that was previously stubbed out with a TODO. Windows can now build php8embed.lib and php8embed.dll via --build-embed.

What changed:

  • Removed the "Windows does not currently support embed SAPI" warning and uncommented the buildEmbed() call
  • buildEmbed() now generates an nmake wrapper that passes the correct linker libs (ws2_32.lib, shell32.lib, plus any SPC_EXTRA_LIBS), invokes nmake php8embed.lib, and deploys the output
  • When --no-strip is set, injects /Zi (debug info) and /DEBUG /LTCG linker flags into the nmake wrapper so PDB files are produced
  • deploySAPIBinary() updated to handle BUILD_TARGET_EMBED -- places php8embed.lib in buildroot/lib/ (not bin/), copies php8embed.dll alongside it, and handles the fact that embed has no PDB
  • After building, installs PHP headers (main/, Zend/, TSRM/, sapi/, ext/) and config.w32.h into buildroot/include/php/ so downstream consumers (e.g. ephpm's Rust FFI build) have a complete SDK

Archive extraction fix (FileSystem.php)

Fixes extractArchive() on Windows where the 7za-to-tar pipe breaks with "The pipe has been ended" for large archives.

Root cause: Windows pipes are unreliable for high-throughput streaming between processes. Additionally, MinGW tar (from Git usr/bin on PATH) gets picked up instead of Windows native tar and can't parse C:\ drive letter paths.

Fix: Replace the single piped command with two-step extraction:

  1. 7za.exe x archive.tar.xz -o"dir" -y -- decompress to .tar on disk
  2. System32\tar.exe -xf archive.tar -C "target" --strip-components 1 -- extract from disk
  3. Clean up the intermediate .tar

Only affects the Windows code path. Linux/macOS extraction is unchanged.

libxml2 2.14+ compatibility (SourcePatcher.php)

Fixes unresolved external symbol errors when linking php8ts.dll with libxml2 >= 2.14.

Root cause: libxml2 2.14 removed many deprecated APIs -- xmlUCSIs* (Unicode block classification), xmlNanoFTP*, xmlNanoHTTP*, xmlShell*, and ~100 other legacy functions. PHP's static ext/libxml/php_libxml2.def still lists all of these as DLL exports. On Windows, the .def file makes every listed symbol a hard linker requirement -- if the symbol doesn't exist in any linked library, the build fails. Linux/macOS are unaffected because they don't use .def files.

This affects all PHP versions (8.2 through 8.5) when built against libxml2 >= 2.14.

Fix: Added patchLibxml2DefForWindows() to SourcePatcher, called from patchBeforeMake() on Windows builds. Rather than maintaining a blocklist of removed symbol prefixes, it scans the installed libxml2 headers (buildroot/include/libxml2/libxml/*.h) for XMLPUBFUN and XMLPUBVAR declarations -- the macros libxml2 uses to mark its entire public API. Any .def entry that doesn't have a matching symbol in the headers is stripped.

This approach is future-proof -- it handles any combination of PHP and libxml2 versions without needing updates as libxml2 continues to deprecate APIs. It also works in plain PHP context without needing Visual Studio tools like dumpbin on PATH.

Checklist before merging

If your PR involves the changes mentioned below and completed the action, please tick the corresponding option.
If a modification is not involved, please skip it directly.

  • If you modified *.php or *.json, run them locally to ensure your changes are valid:
    • composer cs-fix
    • composer analyse
    • composer test
    • bin/spc dev:sort-config
  • If it's an extension or dependency update, please ensure the following:
    • Add your test combination to src/globals/test-extensions.php.
    • If adding new or fixing bugs, add commit message containing extension test or test extensions to trigger full test suite.

@luthermonson
Copy link
Copy Markdown
Author

luthermonson commented Apr 4, 2026

Hi @crazywhalecc this is a bit of a big PR and I'm not even sure if you have hardware to even test this. I can tell you that I have a github workflow that looks like this which I used my personal windows runner with these changes to SPC and it popped out perfectly fine windows binaries that I was able to embed. I haven't tested the output yet thoroughly, so please review for now but hold off on merging until I come back to you after I've tested the binaries a little more thoroughly.

- Fix php-cs-fixer style issues (single-quote escapes, pre-increment)
- Add secur32.lib to LDFLAGS for php8ts.dll (curl SSPI support)
- Strip removed libxml2 symbols from .def by scanning headers
- Respect #ifdef LIBXML_*_ENABLED guards for disabled features
- Two-step archive extraction using Windows native tar
@crazywhalecc
Copy link
Copy Markdown
Owner

Embarrassingly, I have already implemented the Windows embed SAPI in v3 version and fixed several old Windows issues such as tar.exe, sdk wrapper things, single-core build process.

Therefore, I'm not sure how much sense it would make to implement it in v2. However, the release of v3 is still some time away, and I haven't ported all the v2 features and extensions yet.

@luthermonson
Copy link
Copy Markdown
Author

your call, this is working for me today. i dont know this project well only just getting into it this weekend and thought i was helping out. merge it if you want it, i can run my fork if you dont.

@luthermonson
Copy link
Copy Markdown
Author

https://github.com/crazywhalecc/static-php-cli/blob/v3/src/SPC/builder/windows/WindowsBuilder.php#L192-L201 v3 showing this as TODO as well, not that i knew to look for it before putting this up as I didn't know a v3 was coming. you have it in a branch some where? can i compare implementations?

@crazywhalecc
Copy link
Copy Markdown
Owner

v3 version is totally refactored and all of APIs and implementations except shell commands are different from v2. It's now under development branch and in different src directory src/StaticPHP.

Merging sequence: v3-refactor/win-exts -> v3-dev -> v3. Unmerged branch v3-refactor/win-exts is the newest branch of v3 version.

Most of the updates for version 3 are described in the PR with RFCs that are still open; you can check the issue list.

I apologize that now is an awkward time, but I'd prefer you to either keep using your fork or participate adding new features to v3. We now welcome any new feature requests on v3.

@luthermonson
Copy link
Copy Markdown
Author

No worries at all I have what I need for now, I'll keep playing with fork and when you get V3 working better I will migrate

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants