Windows build #14
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: Checkout | |
uses: actions/checkout@v3 | |
with: | |
path: 'C:\lwmbs' | |
- 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 | |
Write-Host "::group::Prepare source" | |
# prepare source for specified php version | |
# you may select only libraries and extensions you will use | |
& php \${lwmbsDir}\\fetch_source.php ` | |
"" ` | |
"" ` | |
"--phpVer={$matrix['phpVer']}" ` | |
"--versionFile=\${buildDir}\\versionFile" | |
\$ret=\$LASTEXITCODE | |
Write-Host "::endgroup::" | |
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" ` | |
"--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: Cache | |
uses: actions/cache@v3 | |
id: cache | |
with: | |
path: | | |
C:\tools\php-sdk-binary-tools | |
C:\build\src | |
C:\build\bin | |
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 | |
if : steps.cache.outputs.cache-hit != 'true' | |
run: | | |
${env:GITHUB_TOKEN} = "${{ secrets.GITHUB_TOKEN }}" | |
# install php-sdk-binary-tools | |
New-Item -ItemType Container -Force C:\tools\php-sdk-binary-tools | |
# 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\ | |
# prepare binary sdk | |
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 | |
} | |
Write-Output "PATH=${env:PATH};C:\build\bin" | Out-File -FilePath "${env:GITHUB_ENV}" -Append | |
- name: Build | |
shell: pwsh | |
run: | | |
${env:GITHUB_TOKEN} = "${{ secrets.GITHUB_TOKEN }}" | |
C:\build\build.ps1 |