Skip to content

Commit ccadd4a

Browse files
committed
Add support to build from local source and document it
1 parent 28551f2 commit ccadd4a

File tree

9 files changed

+175
-80
lines changed

9 files changed

+175
-80
lines changed

README.md

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -260,12 +260,18 @@ Next, make sure you have the required Visual Studio version installed to build t
260260
If the required Visual Studio version is not installed, for the first time you try to build PHP, the module will try to install the required Visual Studio components automatically.
261261

262262
Then, you can build PHP by using the `Invoke-PhpBuild` command.
263-
- To build a specific version, you can use the `Version` input. It supports values in major.minor.patch format, e.g., 7.4.25, 8.0.12, etc., or `master` for the master branch of `php-src`.
263+
- To build a specific PHP version, you can use the `PhpVersion` input. It supports values in major.minor.patch format, e.g., 7.4.25, 8.0.12, etc., or `master` for the master branch of `php-src`.
264264
- To build a 32-bit or a 64-bit version, you can use the `Arch` input. It supports values `x64` and `x86`.
265265
- To build a thread-safe or non-thread-safe version, you can use the `Ts` input. It supports values `ts` and `nts`.
266266

267267
```powershell
268-
Invoke-PhpBuild -Version '8.4.11' -Arch x64 -Ts nts
268+
Invoke-PhpBuild -PhpVersion '8.4.11' -Arch x64 -Ts nts
269+
```
270+
271+
To build PHP from a local source, run `Invoke-PhpBuild` from the source directory and omit `PhpVersion` input.
272+
273+
```powershell
274+
Invoke-PhpBuild -Arch x64 -Ts nts
269275
```
270276

271277
It should produce the PGO optimized builds for the input PHP version and configuration in a directory named `artifacts` in the current directory.
@@ -292,7 +298,7 @@ Next, make sure you have the required Visual Studio version installed to build t
292298
If the required Visual Studio version is not installed, for the first time you try to build the PHP extension, the module will try to install the required Visual Studio components automatically.
293299

294300
Then, you can build the PHP extension by using the `Invoke-PhpBuildExtension` command.
295-
- To build a php extension, you can use the `ExtensionUrl` input. It supports a git repository URL as value.
301+
- To build a php extension from a git repository, you can use the `ExtensionUrl` input. It supports a git repository URL as value.
296302
- To build a specific version of the extension, you can use the `ExtensionRef` input. It supports a git reference, e.g., a tag or a branch as value.
297303
- To build the extension for a specific PHP version, you can use the `PhpVersion` input. It supports values in major.minor format, e.g., 7.4, 8.0, etc.
298304
- To build the extension for a 32-bit or a 64-bit PHP version, you can use the `Arch` input. It supports values `x64` and `x86`.
@@ -310,6 +316,13 @@ Invoke-PhpBuildExtension -ExtensionUrl https://github.com/xdebug/xdebug `
310316
-Args "--with-xdebug"
311317
```
312318

319+
To build an extension from a local source, run `Invoke-PhpBuildExtension` from the extension’s source directory and omit `ExtensionUrl` and `ExtensionRef` inputs.
320+
321+
```powershell
322+
# cd to xdebug source directory, and then run
323+
Invoke-PhpBuildExtension -PhpVersion 8.4 -Arch x64 -Ts nts -Libraries "zlib" -Args "--with-xdebug"
324+
```
325+
313326
It should produce the extension builds in a directory named `artifacts` in the current directory.
314327

315328
## License

extension/BuildPhpExtension/private/Get-Extension.ps1

Lines changed: 79 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -6,91 +6,109 @@ function Get-Extension {
66
Extension URL
77
.PARAMETER ExtensionRef
88
Extension Reference
9+
.PARAMETER BuildDirectory
10+
Build directory
11+
.PARAMETER LocalSrc
12+
Is source local
913
#>
1014
[OutputType()]
1115
param (
12-
[Parameter(Mandatory = $true, Position=0, HelpMessage='Extension URL')]
13-
[string] $ExtensionUrl,
14-
[Parameter(Mandatory = $true, Position=1, HelpMessage='Extension Reference')]
15-
[string] $ExtensionRef
16+
[Parameter(Mandatory = $false, Position=0, HelpMessage='Extension URL')]
17+
[string] $ExtensionUrl = '',
18+
[Parameter(Mandatory = $false, Position=1, HelpMessage='Extension Reference')]
19+
[string] $ExtensionRef = '',
20+
[Parameter(Mandatory = $true, Position=2, HelpMessage='Build directory')]
21+
[ValidateNotNull()]
22+
[ValidateLength(1, [int]::MaxValue)]
23+
[string] $BuildDirectory,
24+
[Parameter(Mandatory = $true, Position=3, HelpMessage='Is source local')]
25+
[ValidateNotNull()]
26+
[bool] $LocalSrc = $false
1627
)
1728
begin {
1829
}
1930
process {
20-
Add-StepLog "Fetching extension from $ExtensionUrl"
21-
try {
22-
if(
23-
($null -eq $ExtensionUrl -or $null -eq $ExtensionRef) -or
24-
($ExtensionUrl -eq '' -or $ExtensionRef -eq '')
25-
) {
26-
throw "Both Extension URL and Extension Reference are required."
27-
}
31+
if($LocalSrc) {
2832
$currentDirectory = (Get-Location).Path
29-
if($null -ne $ExtensionUrl -and $null -ne $ExtensionRef) {
30-
if ($ExtensionUrl -like "*pecl.php.net*") {
31-
$extension = Split-Path -Path $ExtensionUrl -Leaf
32-
try {
33-
Get-File -Url "https://pecl.php.net/get/$extension-$ExtensionRef.tgz" -OutFile "$extension-$ExtensionRef.tgz"
34-
} catch {}
35-
if(-not(Test-Path "$extension-$ExtensionRef.tgz")) {
33+
Copy-Item -Path "$currentDirectory\*" -Destination $BuildDirectory -Recurse -Force
34+
} else {
35+
Add-StepLog "Fetching extension from $ExtensionUrl"
36+
try {
37+
if (($null -ne $ExtensionUrl -and $null -ne $ExtensionRef) -and ($ExtensionUrl -ne '' -and $ExtensionRef -ne '')) {
38+
Set-Location $BuildDirectory
39+
if ($ExtensionUrl -like "*pecl.php.net*") {
40+
$extension = Split-Path -Path $ExtensionUrl -Leaf
3641
try {
37-
Get-File -Url "https://pecl.php.net/get/$($extension.ToUpper())-$ExtensionRef.tgz" -OutFile "$extension-$ExtensionRef.tgz"
42+
Get-File -Url "https://pecl.php.net/get/$extension-$ExtensionRef.tgz" -OutFile "$extension-$ExtensionRef.tgz"
3843
} catch {}
44+
if(-not(Test-Path "$extension-$ExtensionRef.tgz")) {
45+
try {
46+
Get-File -Url "https://pecl.php.net/get/$($extension.ToUpper())-$ExtensionRef.tgz" -OutFile "$extension-$ExtensionRef.tgz"
47+
} catch {}
48+
}
49+
& tar -xzf "$extension-$ExtensionRef.tgz" -C $BuildDirectory
50+
Copy-Item -Path "$extension-$ExtensionRef\*" -Destination $BuildDirectory -Recurse -Force
51+
Remove-Item -Path "$extension-$ExtensionRef" -Recurse -Force
52+
} else {
53+
if($null -ne $env:AUTH_TOKEN) {
54+
$ExtensionUrl = $ExtensionUrl -replace '^https://', "https://${Env:AUTH_TOKEN}@"
55+
}
56+
git init > $null 2>&1
57+
git remote add origin $ExtensionUrl > $null 2>&1
58+
git fetch --depth=1 origin $ExtensionRef > $null 2>&1
59+
git checkout FETCH_HEAD > $null 2>&1
3960
}
40-
& tar -xzf "$extension-$ExtensionRef.tgz" -C $currentDirectory
41-
Copy-Item -Path "$extension-$ExtensionRef\*" -Destination $currentDirectory -Recurse -Force
42-
Remove-Item -Path "$extension-$ExtensionRef" -Recurse -Force
43-
} else {
44-
if($null -ne $env:AUTH_TOKEN) {
45-
$ExtensionUrl = $ExtensionUrl -replace '^https://', "https://${Env:AUTH_TOKEN}@"
46-
}
47-
git init > $null 2>&1
48-
git remote add origin $ExtensionUrl > $null 2>&1
49-
git fetch --depth=1 origin $ExtensionRef > $null 2>&1
50-
git checkout FETCH_HEAD > $null 2>&1
5161
}
62+
} catch {
63+
Add-BuildLog cross extension "Failed to fetch extension from $ExtensionUrl"
64+
throw
5265
}
66+
}
5367

54-
$patches = $False
68+
$patches = $False
69+
if($null -ne $extension) {
5570
if(Test-Path -PATH $PSScriptRoot\..\patches\$extension.ps1) {
5671
if((Get-Content $PSScriptRoot\..\patches\$extension.ps1).Contains('config.w32')) {
57-
Add-Patches $extension
58-
$patches = $True
72+
Add-Patches $extension
73+
$patches = $True
5974
}
6075
}
76+
}
6177

62-
$configW32 = Get-ChildItem (Get-Location).Path -Recurse -Filter "config.w32" -ErrorAction SilentlyContinue
63-
if($null -eq $configW32) {
64-
throw "No config.w32 found"
78+
$configW32 = Get-ChildItem (Get-Location).Path -Recurse -Filter "config.w32" -ErrorAction SilentlyContinue
79+
if($null -eq $configW32) {
80+
if($LocalSrc) {
81+
throw "No config.w32 found, please make sure you are in the extension source directory and it supports Windows."
82+
} else {
83+
throw "No config.w32 found, please check if the extension supports Windows."
6584
}
66-
$subDirectory = $configW32.DirectoryName
67-
if((Get-Location).Path -ne $subDirectory) {
68-
Copy-Item -Path "${subDirectory}\*" -Destination $currentDirectory -Recurse -Force
69-
Remove-Item -Path $subDirectory -Recurse -Force
70-
}
71-
$configW32Content = Get-Content -Path "config.w32"
72-
$extensionLine = $configW32Content | Select-String -Pattern '\s+(ZEND_)?EXTENSION\(' | Select-Object -Last 1
73-
if($null -eq $extensionLine) {
74-
throw "No extension found in config.w32"
75-
}
76-
$name = ($extensionLine -replace '.*EXTENSION\(([^,]+),.*', '$1') -replace '["'']', ''
77-
if($name.Contains('oci8')) {
78-
$name = 'oci8_19'
79-
} elseif ([string]$configW32Content -match ($([regex]::Escape($name)) + '\s*=\s*["''](.+?)["'']')) {
80-
if($matches[1] -ne 'no') {
81-
$name = $matches[1]
82-
}
85+
}
86+
$subDirectory = $configW32.DirectoryName
87+
if((Get-Location).Path -ne $subDirectory) {
88+
Copy-Item -Path "${subDirectory}\*" -Destination $currentDirectory -Recurse -Force
89+
Remove-Item -Path $subDirectory -Recurse -Force
90+
}
91+
$configW32Content = Get-Content -Path "config.w32"
92+
$extensionLine = $configW32Content | Select-String -Pattern '\s+(ZEND_)?EXTENSION\(' | Select-Object -Last 1
93+
if($null -eq $extensionLine) {
94+
throw "No extension found in config.w32"
95+
}
96+
$name = ($extensionLine -replace '.*EXTENSION\(([^,]+),.*', '$1') -replace '["'']', ''
97+
if($name.Contains('oci8')) {
98+
$name = 'oci8_19'
99+
} elseif ([string]$configW32Content -match ($([regex]::Escape($name)) + '\s*=\s*["''](.+?)["'']')) {
100+
if($matches[1] -ne 'no') {
101+
$name = $matches[1]
83102
}
103+
}
84104

85-
if(!$patches) {
86-
Add-Patches $name
87-
}
105+
if(!$patches) {
106+
Add-Patches $name
107+
}
108+
if(-not($LocalSrc)) {
88109
Add-BuildLog tick $name "Fetched $name extension"
89-
return $name
90-
} catch {
91-
Add-BuildLog cross extension "Failed to fetch extension from $ExtensionUrl"
92-
throw
93110
}
111+
return $name
94112
}
95113
end {
96114
}

extension/BuildPhpExtension/private/Get-ExtensionSource.ps1

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,31 @@ function Get-ExtensionSource {
3030
$ExtensionRef = $env:GITHUB_SHA
3131
}
3232
}
33+
} else {
34+
if($null -eq $ExtensionRef -or $ExtensionRef -eq '') {
35+
try {
36+
if(Test-Path package.xml) {
37+
$xml = [xml](Get-Content package.xml)
38+
$ExtensionRef = $xml.package.version.release
39+
} elseif(Test-Path .git) {
40+
$tag = git tag --points-at HEAD | Where-Object { $_ -match '^v?(\d+(\.\d+){0,2})$' } | Select-Object -First 1
41+
if($tag) {
42+
$ExtensionRef = $tag
43+
} else {
44+
$ExtensionRef = (git rev-parse --abbrev-ref HEAD) -replace 'origin/', ''
45+
}
46+
} else {
47+
$ExtensionRef = 'local'
48+
}
49+
} catch {
50+
$ExtensionRef = 'local'
51+
}
52+
}
3353
}
3454
return [PSCustomObject]@{
3555
url = $ExtensionUrl;
3656
ref = $ExtensionRef
57+
local = ($null -eq $ExtensionUrl -or $ExtensionUrl -eq '')
3758
}
3859
}
3960
end {

extension/BuildPhpExtension/public/Invoke-PhpBuildExtension.ps1

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -62,11 +62,11 @@ function Invoke-PhpBuildExtension {
6262

6363
$buildDirectory = Get-BuildDirectory
6464

65-
Set-Location "$buildDirectory"
66-
6765
$source = Get-ExtensionSource -ExtensionUrl $ExtensionUrl -ExtensionRef $ExtensionRef
6866

69-
$extension = Get-Extension -ExtensionUrl $source.url -ExtensionRef $source.ref
67+
$extension = Get-Extension -ExtensionUrl $source.url -ExtensionRef $source.ref -BuildDirectory $buildDirectory -LocalSrc $source.local
68+
69+
Set-Location "$buildDirectory"
7070

7171
$config = Add-BuildRequirements -Extension $extension `
7272
-ExtensionRef $source.ref `

php/BuildPhp/BuildPhp.psd1

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@
7272
'Get-PhpSdk',
7373
'Get-PhpSrc',
7474
'Get-PhpTestPack',
75+
'Get-SourcePhpVersion',
7576
'Get-TestSettings',
7677
'Get-TestsList'
7778
'Get-VsVersionHelper',

php/BuildPhp/private/Add-BuildRequirements.ps1

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ function Add-BuildRequirements {
66
PHP Version
77
.PARAMETER Arch
88
PHP Architecture
9+
.PARAMETER FetchSrc
10+
Fetch PHP source code
911
#>
1012
[OutputType()]
1113
param (
@@ -16,14 +18,19 @@ function Add-BuildRequirements {
1618
[Parameter(Mandatory = $true, Position=1, HelpMessage='PHP Architecture')]
1719
[ValidateNotNull()]
1820
[ValidateSet('x86', 'x64')]
19-
[string] $Arch
21+
[string] $Arch,
22+
[Parameter(Mandatory = $false, Position=2, HelpMessage='Fetch PHP source code')]
23+
[ValidateNotNull()]
24+
[bool] $FetchSrc = $True
2025
)
2126
begin {
2227
}
2328
process {
2429
Get-OciSdk -Arch $Arch
2530
Get-PhpSdk
26-
Get-PhpSrc -PhpVersion $PhpVersion
31+
if($FetchSrc) {
32+
Get-PhpSrc -PhpVersion $PhpVersion
33+
}
2734
}
2835
end {
2936
}

php/BuildPhp/private/Get-PhpSrc.ps1

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,6 @@ function Get-PhpSrc {
88
[OutputType()]
99
param (
1010
[Parameter(Mandatory = $true, Position=0, HelpMessage='PHP Version')]
11-
[ValidateNotNull()]
12-
[ValidateLength(1, [int]::MaxValue)]
1311
[string] $PhpVersion
1412
)
1513
begin {
@@ -21,10 +19,13 @@ function Get-PhpSrc {
2119
$zipFile = "php-$PhpVersion.zip"
2220
$directory = "php-$PhpVersion-src"
2321

24-
if ($PhpVersion.Contains(".")) {
22+
if ( $PhpVersion.Contains("."))
23+
{
2524
$ref = "php-$PhpVersion"
2625
$url = "$baseUrl/refs/tags/php-$PhpVersion.zip"
27-
} else {
26+
}
27+
else
28+
{
2829
$ref = $PhpVersion
2930
$url = "$baseUrl/$PhpVersion.zip"
3031
}
@@ -37,7 +38,7 @@ function Get-PhpSrc {
3738
Get-File -Url $url -Outfile $zipFile
3839
[System.IO.Compression.ZipFile]::ExtractToDirectory($zipFilePath, $currentDirectory)
3940
Rename-Item -Path "php-src-$ref" -NewName $directory
40-
[System.IO.Compression.ZipFile]::CreateFromDirectory($directoryPath, $srcZipFilePath)
41+
[System.IO.Compression.ZipFile]::CreateFromDirectory($directoryPath, $srcZipFilePath)
4142
}
4243
end {
4344
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
function Get-SourcePhpVersion {
2+
<#
3+
.SYNOPSIS
4+
Get the PHP version from the source code.
5+
#>
6+
[OutputType([string])]
7+
param (
8+
)
9+
begin {
10+
}
11+
process {
12+
$versionFile = "main/php_version.h"
13+
if (-not (Test-Path -Path $versionFile)) {
14+
throw "PHP source not found. Please either specify PhpVersion or ensure you are in the PHP source directory."
15+
}
16+
17+
$content = Get-Content -Path $versionFile -Raw
18+
19+
$major = [regex]::Match($content, 'PHP_MAJOR_VERSION\s+(\d+)').Groups[1].Value
20+
$minor = [regex]::Match($content, 'PHP_MINOR_VERSION\s+(\d+)').Groups[1].Value
21+
$patch = [regex]::Match($content, 'PHP_RELEASE_VERSION\s+(\d+)').Groups[1].Value
22+
23+
"$major.$minor.$patch"
24+
}
25+
end {
26+
}
27+
}

0 commit comments

Comments
 (0)