Windows build #22
This file contains 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
name: Windows build | |
on: | |
workflow_dispatch: | |
inputs: | |
flavors: | |
description: "flavors, comma splited, empty for 'min,lite,max-swow', available: min, lite, max[-eventengine, like swow/swoole/libev], custom" | |
required: false | |
default: "" | |
archs: | |
description: "archs, comma splited, empty for all, available: x64, arm64" | |
required: false | |
default: "" | |
sapis: | |
description: "SAPIs, comma splited, empty for all, available: micro, micro-cli, cli" | |
required: false | |
default: "" | |
phpVers: | |
description: "PHP versions, empty for all, available: 8.0, 8.1, 8.2" | |
required: false | |
default: "" | |
customExtensions: | |
description: "custom extensions, used for custom flavor build" | |
required: false | |
default: "" | |
customLibraries: | |
description: "custom libraries, used for custom flavor build" | |
required: false | |
default: "" | |
# schedule: | |
# - cron: "33 4 * * *" | |
jobs: | |
gen-jobs: | |
name: Generate jobs | |
runs-on: windows-latest | |
outputs: | |
jobs: ${{ steps.gen-jobs.outputs.jobs }} | |
steps: | |
- name: Generate jobs | |
id: gen-jobs | |
shell: php {0} | |
run: | | |
<?php | |
function arg2arr(string $arg): array | |
{ | |
return array_filter(array_map("trim", explode(',', $arg))); | |
} | |
$flavors = arg2arr(<<<'ARG' | |
${{ github.event.inputs.flavors }} | |
ARG); | |
$archs = arg2arr(<<<'ARG' | |
${{ github.event.inputs.archs }} | |
ARG); | |
$sapis = arg2arr(<<<'ARG' | |
${{ github.event.inputs.sapis }} | |
ARG); | |
$phpVers = arg2arr(<<<'ARG' | |
${{ github.event.inputs.phpVers }} | |
ARG); | |
if (!$flavors) { | |
$flavors = ['min', 'lite', 'max-swow']; | |
} | |
if (!$archs) { | |
$archs = ['x64', 'arm64']; | |
} | |
if (!$sapis) { | |
$sapis = ['micro', 'micro-cli', 'cli']; | |
} | |
if (!$phpVers) { | |
$phpVers = ['8.0', '8.1', '8.2']; | |
} | |
$customLibraries = <<<'ARG' | |
${{ github.event.inputs.customLibraries }} | |
ARG; | |
$customExtensions = <<<'ARG' | |
${{ github.event.inputs.customExtensions }} | |
ARG; | |
$customLibraries = trim($customLibraries); | |
$customExtensions = trim($customExtensions); | |
foreach ($archs as $arch) { | |
foreach ($phpVers as $phpVer) { | |
if ($arch === 'arm64' && version_compare($phpVer, '8.2', '<')) { | |
// arm64 only supported on PHP 8.2+ | |
echo "skip arm64 $phpVer\n"; | |
continue; | |
} | |
$job = [ | |
'flavors' => $flavors, | |
'customLibraries' => $customLibraries, | |
'customExtensions' => $customExtensions, | |
'arch' => $arch, | |
'sapis' => $sapis, | |
'phpVer' => $phpVer, | |
]; | |
$jobs[] = $job; | |
} | |
} | |
if (!$jobs) { | |
echo "no jobs generated\n"; | |
exit(1); | |
} | |
$json = json_encode($jobs); | |
# file_put_contents(getenv('GITHUB_OUTPUT'), "jobs=$json"); | |
$jsonDebug = <<<'JSON' | |
[{ | |
"flavors": [ | |
"min" | |
], | |
"customLibraries": "", | |
"customExtensions": "", | |
"arch": "arm64", | |
"sapis": [ | |
"micro" | |
], | |
"phpVer": "8.2" | |
}] | |
JSON; | |
$json = json_encode(json_decode($jsonDebug, true)); | |
file_put_contents(getenv('GITHUB_OUTPUT'), "jobs=$json"); | |
build: | |
name: ${{ matrix.phpVer }} ${{ matrix.arch }} ${{ toJson(matrix.flavors) }} | |
runs-on: windows-latest | |
# TODO: use docker | |
# container: "ghcr.io/dixyes/prepared-lwmbs:windows-${{ matrix.arch }}-src" | |
needs: | |
- gen-jobs | |
strategy: | |
max-parallel: 3 | |
fail-fast: false | |
matrix: | |
include: ${{ fromJson(needs.gen-jobs.outputs.jobs) }} | |
steps: | |
- name: Restore tools and sources | |
uses: actions/cache/restore@v3 | |
id: cache-restore | |
with: | |
path: | | |
C:\tools\php-sdk-binary-tools | |
C:\build\bin | |
C:\build\downloads | |
C:\build\src | |
C:\build\versionFile | |
key: ${{ runner.os }}-build-v1-${{ matrix.arch }}-${{ hashFiles('C:\build\versionFile') }} | |
restore-keys: | | |
${{ runner.os }}-build-v1-${{ matrix.arch }}- | |
- name: Prepare tools and sources | |
id: prepare | |
shell: pwsh | |
run: | | |
${env:GITHUB_TOKEN} = "${{ secrets.GITHUB_TOKEN }}" | |
# prepare lwmbs | |
New-Item -ItemType Container -Force C:\lwmbs | |
Set-Location C:\lwmbs | |
git init | |
if (0 -Ne $lastexitcode) { | |
exit 1 | |
} | |
git remote add origin https://github.com/${{ github.repository }} | |
if (0 -Ne $lastexitcode) { | |
exit 1 | |
} | |
git fetch --depth 1 origin ${{ github.sha }} | |
if (0 -Ne $lastexitcode) { | |
exit 1 | |
} | |
git checkout ${{ github.sha }} | |
if (0 -Ne $lastexitcode) { | |
exit 1 | |
} | |
if ( '${{steps.cache-restore.outputs.cache-hit}}' -ne 'true' ) { | |
Write-Output "cache miss, prepare tools" | |
# install php-sdk-binary-tools | |
git clone --depth 1 --single-branch --branch master https://github.com/php/php-sdk-binary-tools C:\tools\php-sdk-binary-tools | |
if (0 -Ne $lastexitcode) { | |
exit 1 | |
} | |
# prepare nasm | |
Invoke-WebRequest -Uri "https://www.nasm.us/pub/nasm/releasebuilds/2.15.05/win64/nasm-2.15.05-win64.zip" ` | |
-OutFile "nasm-2.15.05-win64.zip" | |
unzip nasm-2.15.05-win64.zip | |
if (0 -Ne $lastexitcode) { | |
exit 1 | |
} | |
New-Item -ItemType Container -Force C:\build\bin | |
Move-Item nasm-2.15.05/*.exe C:\build\bin\ | |
Move-Item nasm-2.15.05/rdoff/*.exe C:\build\bin\ | |
# download source | |
Set-Location C:\build | |
php C:\lwmbs\fetch_source.php ` | |
"" ` | |
"" ` | |
"--phpVer=${{ matrix.phpVer }}" ` | |
"--versionFile=C:\build\versionFile" | |
if (0 -Ne $lastexitcode) { | |
exit 1 | |
} | |
} | |
Write-Output "PATH=${env:PATH};C:\build\bin" | Out-File -FilePath "${env:GITHUB_ENV}" -Append | |
- name: Save tools and sources | |
uses: actions/cache/save@v3 | |
with: | |
path: | | |
C:\tools\php-sdk-binary-tools | |
C:\build\bin | |
C:\build\downloads | |
C:\build\src | |
C:\build\versionFile | |
key: ${{ runner.os }}-build-v1-${{ matrix.arch }}-${{ hashFiles('C:\build\versionFile') }} | |
- name: Make build commands | |
shell: php {0} | |
run: | | |
<?php | |
$matrix = <<<'EOF' | |
${{ toJson(matrix) }} | |
EOF; | |
$matrix = json_decode($matrix, true); | |
$customLibraries = $matrix['customLibraries']; | |
$customExtensions = $matrix['customExtensions']; | |
$commands = []; | |
@mkdir('C:\build'); | |
$output = fopen('C:\build\build.ps1', 'w'); | |
$writeps = function (...$args) use ($output) { | |
fwrite($output, sprintf(...$args)); | |
fwrite(STDOUT, sprintf(...$args)); | |
}; | |
$writeps(<<<PWSH | |
# NOTE: to build these binaries on your machine, you may require php8.1+, vs, git, cmake, 7z(-zstd/nanazip better), perl | |
\$buildDir = "C:\\build" | |
\$phpSdkDir = "C:\\tools\\php-sdk-binary-tools" | |
\$lwmbsDir = "C:\\lwmbs" | |
\$vsVer = "17" | |
\$outDir = "C:\\out" | |
Set-Location -Path \$buildDir | |
New-Item -Path \$buildDir -ItemType Directory -Force | |
# # prepare source for specified php version | |
# # you may select only libraries and extensions you will use | |
# # we donot do this because in actions it was cached | |
# & php \${lwmbsDir}\\fetch_source.php ` | |
# "" ` | |
# "" ` | |
# "--phpVer={$matrix['phpVer']}" ` | |
# "--versionFile=\${buildDir}\\versionFile" | |
# \$ret=\$LASTEXITCODE | |
# if (\$ret -ne 0) { | |
# Write-Host "::error::fetch source failed" | |
# exit 1 | |
# } | |
Write-Host "::group::Show versions" | |
Get-Content \${buildDir}\\versionFile | |
Get-FileHash -Path \${buildDir}\\versionFile -Algorithm SHA256 | |
Write-Host "::endgroup::" | |
PWSH); | |
$maxLibraries = 'zstd,libssh2,curl,zlib,brotli,libffi,openssl,libzip,bzip2,nghttp2,onig,libyaml,xz,libxml2,libpng'; | |
$maxExtensions = 'dom,xml,simplexml,xmlwriter,xmlreader,opcache,bcmath,pdo,phar,mysqlnd,mysqli,pdo,pdo_mysql,mbstring,mbregex,session,ctype,fileinfo,filter,tokenizer,curl,ffi,redis,sockets,openssl,zip,zlib,bz2,yaml,zstd,gd'; | |
foreach ($matrix['flavors'] as $flavor) { | |
$libraries = match ($flavor) { | |
'min' => 'libffi', | |
'lite' => 'zstd,zlib,libffi,libzip,bzip2,xz,onig', | |
'max', 'max-swow' => $maxLibraries, | |
'max-libev' => "{$maxLibraries},libev", | |
'max-swoole' => "{$maxLibraries},libstdc++", | |
'custom' => $customLibraries, | |
}; | |
$extensions = match ($flavor) { | |
'min' => 'posix,pcntl,ffi,filter,tokenizer,ctype', | |
'lite' => 'opcache,posix,pcntl,ffi,filter,tokenizer,ctype,iconv,mbstring,mbregex,sockets,zip,zstd,zlib,bz2,phar,fileinfo', | |
'max' => $maxExtensions, | |
'max-swow' => "{$maxExtensions},swow", | |
'max-swoole' => "{$maxExtensions},swoole", | |
'max-libev' => "{$maxExtensions},libev", | |
'custom' => $customExtensions, | |
}; | |
$writeps("\n\n"); | |
$writeps(<<<PWSH | |
# ----- "$flavor" flavor ----- | |
Write-Host "::group::Build $flavor libs" | |
# rebuild libs for this flavor to avoid cache | |
& php \${lwmbsDir}\build_libs.php ` | |
"$libraries" ` | |
"--phpBinarySDKDir=\$phpSdkDir" ` | |
"--vsVer=\$vsVer" ` | |
"--arch={$matrix['arch']}" ` | |
"--fresh" | |
\$ret=\$LASTEXITCODE | |
Write-Host "::endgroup::" | |
if (\$ret -ne 0) { | |
Write-Host "::error::failed build lib for $flavor" | |
} else { | |
PWSH); | |
foreach ($matrix['sapis'] as $sapi) { | |
$command = match ($sapi) { | |
'micro' => 'build_micro.php', | |
'micro-cli' => 'build_micro.php --fakeCli', | |
'cli' => 'build_cli.php', | |
}; | |
$targetBin = match ($sapi) { | |
'micro', 'micro-cli' => "\\src\\php-src\\{$matrix['arch']}\\Release_TS\\micro.sfx", | |
'cli' => "\\src\\php-src\\{$matrix['arch']}\\Release_TS\\php.exe", | |
}; | |
$binName = match ($sapi) { | |
'micro' => "micro.sfx", | |
'micro-cli' => "micro_cli.sfx", | |
'cli' => "php.exe", | |
}; | |
$targetBinPDB = match ($sapi) { | |
'micro', 'micro-cli' => "\\src\\php-src\\{$matrix['arch']}\\Release_TS\\micro.pdb", | |
'cli' => "\\src\\php-src\\{$matrix['arch']}\\Release_TS\\php.pdb", | |
}; | |
$binNamePDB = match ($sapi) { | |
'micro' => "micro.pdb", | |
'micro-cli' => "micro_cli.pdb", | |
'cli' => "php.pdb", | |
}; | |
// $writeps("\n"); | |
// $writeps("# cleam php build dir\n"); | |
$writeps("\n\n"); | |
$writeps(<<<PWSH | |
Write-Host "::group::Build $flavor $sapi" | |
# $sapi | |
& php \${lwmbsDir}\\$command ` | |
"$libraries" ` | |
"$extensions" ` | |
"--phpBinarySDKDir=\$phpSdkDir" ` | |
"--vsVer=\$vsVer" ` | |
"--arch={$matrix['arch']}" | |
\$ret=\$LASTEXITCODE | |
Write-Host "::endgroup::" | |
if (\$ret -ne 0) { | |
Write-Host "::error::failed build $flavor $sapi" | |
} else { | |
# copy the built bin out | |
New-Item -Path "\$outDir\\{$flavor}" -ItemType Directory -Force | |
Copy-Item -Path \${buildDir}$targetBin -Destination "\$outDir\\{$flavor}\\$binName" -Force | |
Copy-Item -Path \${buildDir}$targetBinPDB -Destination "\$outDir\\{$flavor}\\$binNamePDB" -Force | |
} | |
PWSH); | |
} | |
$writeps("\n\n"); | |
$writeps(<<<PWSH | |
Write-Host "::group::Dump $flavor licenses" | |
# dump licenses | |
& php \${lwmbsDir}\\dump_licenses.php ` | |
"\$outDir\\{$flavor}/\\licenses" ` | |
"$libraries" ` | |
"$extensions" | |
# copy versionFile | |
Copy-Item -Path \${buildDir}\\versionFile -Destination "\$outDir\\{$flavor}\\versionFile" -Force | |
Write-Host "::endgroup::" | |
} | |
PWSH); | |
} | |
$writeps("\n"); | |
- name: Build | |
shell: pwsh | |
run: | | |
Get-Item C:\build\src\php-src\ext\swow | |
C:\build\build.ps1 |