-
-
Notifications
You must be signed in to change notification settings - Fork 287
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[feat] Code change for compile on windows. Needs to modify php-src. #1286
base: main
Are you sure you want to change the base?
Changes from all commits
fc35566
51e6c3a
f81db83
d059f87
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,130 @@ | ||||||||||||
# Compile From Source on windows | ||||||||||||
|
||||||||||||
Frankenphp could only dynamic compiled on Windows system. It is still in dev. This steps to compile blew. | ||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||
|
||||||||||||
## Prepare MSYS2 and FrankenPHP source | ||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||
|
||||||||||||
Click [msys2-x86_64-20240507.exe](https://github.com/msys2/msys2-installer/releases/download/2024-05-07/msys2-x86_64-20240507.exe) dowload and install it in `C:\`, then its `C:\msys64`. We use environment 'MSYS2 MINGW64'. | ||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||
|
||||||||||||
### Install basic tools | ||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||
|
||||||||||||
```bash | ||||||||||||
# mingw64/msys2 bash | ||||||||||||
pacman -S git | ||||||||||||
pacman -S vim | ||||||||||||
pacman -S make | ||||||||||||
pacman -S wget | ||||||||||||
``` | ||||||||||||
|
||||||||||||
### Install gcc | ||||||||||||
|
||||||||||||
```bash | ||||||||||||
# mingw64/msys2 bash | ||||||||||||
# TODO: Check out that why other gcc versions are not able to compile frankenphp | ||||||||||||
pacman -U https://repo.msys2.org/mingw/mingw64/mingw-w64-x86_64-gcc-13.2.0-6-any.pkg.tar.zst | ||||||||||||
``` | ||||||||||||
|
||||||||||||
### Setup go | ||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||
|
||||||||||||
```bash | ||||||||||||
# mingw64/msys2 bash | ||||||||||||
# TODO: Better install this version | ||||||||||||
pacman -U https://mirror.msys2.org/mingw/mingw64/mingw-w64-x86_64-go-1.22.2-1-any.pkg.tar.zst | ||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You should use version 1.23 if possible |
||||||||||||
|
||||||||||||
# set go env | ||||||||||||
export GO111MODULE='on' | ||||||||||||
export GOBIN='/home/you-user-name/go/bin' | ||||||||||||
export GOCACHE='/home/you-user-name/.cache/go-build' | ||||||||||||
export GOENV='/home/you-user-name/.config/go/env' | ||||||||||||
export GOROOT="/mingw64/lib/go" | ||||||||||||
export GOPATH="/home/you-user-name/go" | ||||||||||||
mkdir ~/go/bin ~/go/pkg ~/go/src | ||||||||||||
``` | ||||||||||||
|
||||||||||||
### Install brotli | ||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||
```bash | ||||||||||||
# mingw64/msys2 bash | ||||||||||||
pacman -S mingw-w64-x86_64-brotli | ||||||||||||
``` | ||||||||||||
|
||||||||||||
### Get Frankenphp source | ||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||
|
||||||||||||
```bash | ||||||||||||
# mingw64/msys2 bash | ||||||||||||
cd ~/go/src | ||||||||||||
git clone https://github.com/dunglas/frankenphp.git | ||||||||||||
cd frankenphp | ||||||||||||
git checkout win | ||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||
``` | ||||||||||||
|
||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||
|
||||||||||||
## Compile PHP | ||||||||||||
|
||||||||||||
FrankenPHP is compatible with PHP 8.2 and superior. In dev stage, php-8.3.0 recommanded. | ||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||
|
||||||||||||
### Install PHP-SDK | ||||||||||||
|
||||||||||||
Recommend reference [build php on windows](https://wiki.php.net/internals/windows/stepbystepbuild_sdk_2). | ||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||
|
||||||||||||
The first step, you should install visual studio. For php-8.3.0, its visual_studio_2019(vs16). Here are some older [visual studio](https://github.com/user-attachments/files/18225924/visual_studio.zip) releases. | ||||||||||||
After visual C++ installed(may need reboot), windows terminal will provide a 'Developer PowerShell for VS 2019'. If not have windows terminal, click [windows terminal](https://aka.ms/terminal). | ||||||||||||
|
||||||||||||
Then download [php-sdk-binary-tools](https://github.com/php/php-sdk-binary-tools/releases). Unzip it, remove and rename the folder under `C:\`, then its `C:\php-sdk`. | ||||||||||||
|
||||||||||||
### Patch, compile, and copy to target path | ||||||||||||
|
||||||||||||
Enter 'Developer PowerShell for VS 2019', then: | ||||||||||||
``` | ||||||||||||
cd C:\php-sdk | ||||||||||||
.\phpsdk-vs16-x64.bat | ||||||||||||
phpsdk_buildtree phpdev | ||||||||||||
# now in C:\php-sdk\phpdev\vs16\x64 | ||||||||||||
git clone -b php-8.3.0 https://github.com/php/php-src.git php-8.3.0 | ||||||||||||
cd php-8.3.0 | ||||||||||||
phpsdk_deps -u -b 8.3 | ||||||||||||
buildconf | ||||||||||||
# basic configure | ||||||||||||
configure --with-prefix="C:\php-sdk\phpdev\vs16\x64\php-8.3.0\php" --enable-zts --enable-embed --enable-cli --disable-opcache-jit | ||||||||||||
COPY C:\msys64\home\TenHian\go\src\frankenphp\patch.php .\ | ||||||||||||
COPY C:\msys64\home\TenHian\go\src\frankenphp\make_dep.bat .\ | ||||||||||||
# modify php-src and Makefile generated by configure | ||||||||||||
..\..\..\..\bin\php\php.exe patch.php | ||||||||||||
make | ||||||||||||
make devel | ||||||||||||
# modifiy a header file, mv includes and dll in target paths | ||||||||||||
make_dep.bat | ||||||||||||
``` | ||||||||||||
|
||||||||||||
## Compile Frankenphp | ||||||||||||
|
||||||||||||
Back to 'MSYS2 MINGW64'. | ||||||||||||
|
||||||||||||
```bash | ||||||||||||
cp /mingw64/lib/libbrotlicommon.a /mingw64/lib/libbrotlidec.a /mingw64/lib/libbrotlienc.a /usr/local/lib | ||||||||||||
# now you should in ~/go/src/frankenphp | ||||||||||||
cd caddy/frankenphp | ||||||||||||
# TODO: compile with watcher | ||||||||||||
go build -tags nowatcher | ||||||||||||
# for clean | ||||||||||||
# go clean && go clean -cache | ||||||||||||
# for build details | ||||||||||||
# go build -tags nowatcher -x | ||||||||||||
``` | ||||||||||||
|
||||||||||||
Now you get frankenphp.exe in `~/go/src/frankenphp/caddy/frankenphp` | ||||||||||||
|
||||||||||||
## After compile | ||||||||||||
|
||||||||||||
The frankenphp.exe needs some shared libraries in the same directory to run. Like `libcrypto-3-x64.dll` `libpq.dll` `libssh2.dll` `libssl-3-x64.dll` `libwinpthread-1.dll` `nghttp2.dll` `php_openssl.dll` `php8embed.dll` `php8ts.dll`. | ||||||||||||
`libwinpthread-1.dll` in `C:\msys64\mingw64\bin`. | ||||||||||||
`libcrypto-3-x64.dll` `libpq.dll` `libssh2.dll` `libssl-3-x64.dll` `nghttp2.dll` in `C:\php-sdk\phpdev\vs16\x64\deps\bin`. | ||||||||||||
`php_openssl.dll` `php8embed.dll` `php8ts.dll` in `C:\php-sdk\phpdev\vs16\x64\php-8.3.0\x64\Release_TS`. | ||||||||||||
You could use `ldd frankenphp.exe` `ldd php8ts.dll` in 'MSYS2 MINGW64', or `dumpbin /dependents frankenphp.exe` `dumpbin /dependents php8ts.dll` in php-sdk console to see libriaries that need by frankenphp.exe. | ||||||||||||
The .dll files start with 'php_' are php extensions, you can find them in `C:\php-sdk\phpdev\vs16\x64\php-8.3.0\x64\Release_TS`. In order to use the extensions, you need to move them to the same path as frankenphp and edit php.ini in this path. | ||||||||||||
|
||||||||||||
# Principle | ||||||||||||
|
||||||||||||
First, the windows cgo support MinGW-w64 compiler suite is more complete. In fact all GNU C compilers are relatively ok, but almost all cgo compilation is based on MinGW-w64. | ||||||||||||
Second, PHP offical only recommand compile with Visual C++(MSVC). | ||||||||||||
|
||||||||||||
So the core problem is to make Mingw-w64 compiler set could link with .dll that PHP on Windows. The `patch.php` does those work, see its comments for more details. |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
@echo off | ||
|
||
REM process php.h | ||
set "php_h_path=.\x64\Release_TS\php-8.3.0-devel-vs16-x64\include\main\php.h" | ||
if exist "%php_h_path%" ( | ||
echo Updating pid_t definition in %php_h_path%... | ||
powershell -Command "(Get-Content '%php_h_path%' | ForEach-Object { $_ -replace '^typedef int pid_t;', 'typedef long long pid_t;' }) | Set-Content '%php_h_path%'" | ||
) else ( | ||
echo File %php_h_path% does not exist. | ||
) | ||
|
||
REM copy include | ||
set "src_include_dir=.\x64\Release_TS\php-8.3.0-devel-vs16-x64\include" | ||
set "dest_include_dir=C:\msys64\usr\local\include\php" | ||
|
||
if not exist "%dest_include_dir%" ( | ||
echo Creating directory %dest_include_dir%... | ||
mkdir "%dest_include_dir%" | ||
) | ||
|
||
echo Copying folders from %src_include_dir% to %dest_include_dir%... | ||
xcopy "%src_include_dir%\*" "%dest_include_dir%\" /E /I /Y | ||
|
||
REM copy php8ts.dll php8embed.dll | ||
set "src_php_dll_dir=.\x64\Release_TS" | ||
set "dest_lib_dir=C:\msys64\usr\local\lib" | ||
|
||
if not exist "%dest_lib_dir%" ( | ||
echo Creating directory %dest_lib_dir%... | ||
mkdir "%dest_lib_dir%" | ||
) | ||
|
||
echo Copying php8ts.dll and php8embed.dll to %dest_lib_dir%... | ||
copy "%src_php_dll_dir%\php8ts.dll" "%dest_lib_dir%\" /Y | ||
copy "%src_php_dll_dir%\php8embed.dll" "%dest_lib_dir%\" /Y | ||
|
||
echo Done! |
Original file line number | Diff line number | Diff line change | ||||||
---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,59 @@ | ||||||||
<?php | ||||||||
/* -------------------------------- | ||||||||
This script aim to modify the php-8.3.0 source code to achieve two things: | ||||||||
1. Remove specifics that are supported by msvc but not by mingw-w64-gcc; | ||||||||
2. Modify the Makefile so that could get php8embeded.dll. | ||||||||
--------------------------------*/ | ||||||||
|
||||||||
$file_path = 'Zend/zend_portability.h'; | ||||||||
$content = file_get_contents($file_path); | ||||||||
$content = str_replace('__assume(c)', 'assert(c)', $content); | ||||||||
$content = str_replace('__vectorcall', '__fastcall', $content); | ||||||||
$content = str_replace('__forceinline', 'inline', $content); | ||||||||
file_put_contents($file_path, $content); | ||||||||
echo "process Zend/zend_portability.h done;\n"; | ||||||||
|
||||||||
$directories = ['ext/hash/murmur', 'ext/hash/xxhash', 'ext/opcache/jit/vtune', 'win32']; | ||||||||
foreach ($directories as $dir) { | ||||||||
$files = scandir($dir); | ||||||||
foreach ($files as $file) { | ||||||||
if (is_file($dir . '/' . $file)) { | ||||||||
$file_path = $dir . '/' . $file; | ||||||||
|
||||||||
$content = file_get_contents($file_path); | ||||||||
$new_content = str_replace('__forceinline', 'inline', $content); | ||||||||
|
||||||||
if ($content !== $new_content) { | ||||||||
file_put_contents($file_path, $new_content); | ||||||||
echo "\"__forceinline\" in $file_path has been replace by \"inline\"\n"; | ||||||||
} | ||||||||
} | ||||||||
} | ||||||||
} | ||||||||
echo "Replace __forceinline in assigned directory done;\n"; | ||||||||
|
||||||||
$file_path = 'sapi/embed/php_embed.h'; | ||||||||
$content = file_get_contents($file_path); | ||||||||
$old_code = '#ifndef PHP_WIN32 | ||||||||
#define EMBED_SAPI_API SAPI_API | ||||||||
#else | ||||||||
#define EMBED_SAPI_API | ||||||||
#endif'; | ||||||||
$new_code = '#ifndef __MINGW64__ | ||||||||
#define EMBED_SAPI_API __declspec(dllexport) | ||||||||
#else | ||||||||
#define EMBED_SAPI_API __declspec(dllimport) | ||||||||
#endif'; | ||||||||
$content = str_replace($old_code, $new_code, $content); | ||||||||
file_put_contents($file_path, $content); | ||||||||
echo "Process sapi/embed/php_embed.h done;\n"; | ||||||||
|
||||||||
$file_path = 'Makefile'; | ||||||||
$content = file_get_contents($file_path); | ||||||||
$content = str_replace('php.exe php8embed.lib', 'php.exe php8embed.dll', $content); | ||||||||
$content = str_replace('php8embed.lib: $(BUILD_DIR)\php8embed.lib', 'php8embed.dll: $(BUILD_DIR)\php8embed.dll', $content); | ||||||||
$content = str_replace('$(BUILD_DIR)\php8embed.lib:', '$(BUILD_DIR)\php8embed.dll:', $content); | ||||||||
$content = str_replace('$(MAKE_LIB)', '@"$(LINK)"', $content); | ||||||||
$content = str_replace('/nologo /out:$(BUILD_DIR)\php8embed.lib', '/nologo /DLL /out:$(BUILD_DIR)\php8embed.dll', $content); | ||||||||
file_put_contents($file_path, $content); | ||||||||
echo "Process Makefile done;\n"; | ||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.