From 76aba2fadb51021b1103630dfb35596d016fdf08 Mon Sep 17 00:00:00 2001 From: James Titcumb Date: Tue, 10 Sep 2024 21:50:42 +0100 Subject: [PATCH 1/4] Added initial documentation for maintainers --- docs/extension-maintainers.md | 128 ++++++++++++++++++++++++++++++++++ 1 file changed, 128 insertions(+) create mode 100644 docs/extension-maintainers.md diff --git a/docs/extension-maintainers.md b/docs/extension-maintainers.md new file mode 100644 index 0000000..abb8272 --- /dev/null +++ b/docs/extension-maintainers.md @@ -0,0 +1,128 @@ +# PIE for Extension Maintainers + +Adding PIE support for your extension is relatively straightforward, and the +flow is quite similar to adding a regular PHP package into Packagist. + +## Add a `composer.json` to your extension + +The first step to adding PIE support is adding a `composer.json` to your +extension repository. Most of the typical fields are the same, with a few +notable exceptions: + + * The `type` MUST be either `php-ext` for a PHP Module (this will be most + extensions), or `php-ext-zend` for a Zend Extension. + * An additional `php-ext` section MAY exist. + * The Composer package name (i.e. the top level `name` field) for a PIE + extension cannot share the same Composer package name as a regular PHP + package, even if they have different `type` fields. + +### The `php-ext` definition + +#### `extension-name` + +The `extension-name` SHOULD be specified, and must conform to the usual extension +name regular expression, which is defined in +[\Php\Pie\ExtensionName::VALID_PACKAGE_NAME_REGEX](../src/ExtensionName.php). +If the `extension-name` is not specified, the `extension-name` will be derived +from the Composer package name, with the vendor prefix removed. For example, +given a `composer.json` with: + +```json +{ + "name": "myvendor/myextension" +} +``` + +The extension name would be derived as `myextension`. The `myvendor/` vendor +prefix is removed. + +The `extension-name` MAY be prefixed with `ext-` as is a convention in Composer, +but this is optional. + +An example of `extension-name` being used: + +```json +{ + "name": "xdebug/xdebug", + "php-ext": { + "extension-name": "xdebug" + } +} +``` + +#### `priority` + +`priority` is currently not used, but will form part of the `ini` filename to +control ordering of extensions, if the target platform uses it. + +#### `support-zts` + +Indicates whether the extension supports Zend Thread-Safe (ZTS) mode or not. + +#### `configure-options` + +This is a list of parameters that may be passed to the `./configure` command. +Each item of the list is a JSON object with: + + * `name`, the parameter name itself + * `description`, a helpful description of what the parameter does + * optionally, `needs-value`, a boolean to tell PIE whether the parameter is a + simple flag (typically used for `--enable-this-flag` type parameters), or if + the parameter should have a value specified (typically used for + `--with-library-path=...` type parameters, where a value must be given by + the end user) + +When an end user is installing an extension with PIE, they may specify any +defined `configure-options` that are passed to `./configure`. For example, if +an extension defines the following `composer.json`: + +```json +{ + "name": "myvendor/myext", + "php-ext": { + "extension-name": "myext", + "configure-options": [ + { + "name": "enable-my-flag", + "description": "Should my flag be enabled", + "needs-value": false + }, + { + "name": "with-some-lib", + "description": "Specify the path to some-lib", + "needs-value": true + } + ] + } +} +``` + +Then the `pie build` or `pie install` commands may be invoked in the following +ways to achieve the desired configuration: + + * `pie install myvendor/myext` + * This will simply invoke `./configure` without any parameters + * `pie install myvendor/myext --enable-my-flag` + * This will invoke `./configure --enable-my-flag` + * `pie install myvendor/myext --with-some-lib=/path/to/somelib` + * This will invoke `./configure --with-some-lib=/path/to/somelib` + * `pie install myvendor/myext --enable-my-flag --with-some-lib=/path/to/somelib` + * This will invoke `./configure --enable-my-flag --with-some-lib=/path/to/somelib` + +Note that it is not possible for end users of PIE to specify configuration +options that have not been defined in your extension's `configure-options` +definition. Using the same example above `composer.json`, invoking PIE with +an invalid option, such as `pie install myvendor/myext --something-else` will +result in an error `The "--something-else" option does not exist.`. + +If an end user does not specify a flag defined in the `configure-options` +definition, it will simply not be passed to `./configure`. There is no way to +specify a default value in the `configure-options` definition. + +## Submit the extension to Packagist + +Once you have committed your `composer.json` to your repository, you may then +submit it to Packagist in the same way as any other package. + + * Head to [https://packagist.org/packages/submit](https://packagist.org/packages/submit) + * Enter the URL of your repository, and follow the instructions. From efcb310575a62fbd9b852801279900ccef6cd36d Mon Sep 17 00:00:00 2001 From: James Titcumb Date: Tue, 10 Sep 2024 22:04:11 +0100 Subject: [PATCH 2/4] Updated main README to reference ext maintainer doc --- README.md | 61 +++++++++++++++++++++++++------------------------------ 1 file changed, 28 insertions(+), 33 deletions(-) diff --git a/README.md b/README.md index e9c4a00..6fc85da 100644 --- a/README.md +++ b/README.md @@ -1,53 +1,48 @@ # 🥧 PIE (PHP Installer for Extensions) -You will need PHP 8.1 or newer to run PIE, but PIE can install an extension to any installed PHP version. +You will need PHP 8.1 or newer to run PIE, but PIE can install an extension to +any installed PHP version. -## Installing +If you are an extension maintainer wanting to add PIE support to your extension, +please read [extension-maintainers](./docs/extension-maintainers.md). -## Usage +## Installing an extension using PIE -You can download an extension ready to be built or installed using the `download` command. For example, to download the -`example_pie_extension` extension, you would run: +You can install an extension using the `install` command. For example, to +install the `example_pie_extension` extension, you would run: ```shell -$ bin/pie download asgrim/example-pie-extension -You are running PHP 8.3.7 -Target PHP installation: 8.3.7 nts, on Linux/OSX/etc x86_64 (from /usr/bin/php8.3) +$ bin/pie install asgrim/example-pie-extension +This command may need elevated privileges, and may prompt you for your password. +You are running PHP 8.3.10 +Target PHP installation: 8.3.10 nts, on Linux/OSX/etc x86_64 (from /usr/bin/php8.3) Found package: asgrim/example-pie-extension:1.0.1 which provides ext-example_pie_extension -Extracted asgrim/example-pie-extension:1.0.1 source to: /tmp/pie_downloader_6645f07a28bec9.66045489/asgrim-example-pie-extension-769f906 -$ +phpize complete. +Configure complete. +Build complete: /tmp/pie_downloader_66e0b1de73cdb6.04069773/asgrim-example-pie-extension-769f906/modules/example_pie_extension.so +Install complete: /usr/lib/php/20230831/example_pie_extension.so +You must now add "extension=example_pie_extension" to your php.ini +$ ``` -If you are trying to install an extension for a different version of PHP, you may specify this on non-Windows systems -with the `--with-php-config` option like: +### Using PIE to install an extension for a different PHP version -```shell -bin/pie download --with-php-config=/usr/bin/php-config7.2 my/extension -``` - -On all platforms, you may provide a path to the `php` executable itself using the `--with-php-path` option. This is an -example on Windows where PHP 8.1 is used to run PIE, but we want to download the extension for PHP 8.3: +If you are trying to install an extension for a different version of PHP, you +may specify this on non-Windows systems with the `--with-php-config` option: ```shell -> C:\php-8.1.7\php.exe bin/pie download --with-php-path=C:\php-8.3.6\php.exe asgrim/example-pie-extension -You are running PHP 8.1.7 -Target PHP installation: 8.3.6 ts, vs16, on Windows x86_64 (from C:\php-8.3.6\php.exe) -Found package: asgrim/example-pie-extension:1.0.1 which provides ext-example_pie_extension -Extracted asgrim/example-pie-extension:1.0.1 source to: C:\path\to\temp\pie_downloader_66547faa7db3d7.06129230 +bin/pie install --with-php-config=/usr/bin/php-config7.2 my/extension ``` -And this is a very similar example (using PHP 8.1 to run PIE to download a PHP 8.3 extension) on a non-Windows platform: +On Windows, you may provide a path to the `php` executable itself using the +`--with-php-path` option. This is an example on Windows where PHP 8.1 is used +to run PIE, but we want to download the extension for PHP 8.3: ```shell -$ php8.1 bin/pie download --with-php-path=/usr/bin/php8.3 asgrim/example-pie-extension -You are running PHP 8.1.28 -Target PHP installation: 8.3.7 nts, on Linux/OSX/etc x86_64 (from /usr/bin/php8.3) -Found package: asgrim/example-pie-extension:1.0.1 which provides ext-example_pie_extension -Extracted asgrim/example-pie-extension:1.0.1 source to: /tmp/pie_downloader_66547da1e6c685.25242810/asgrim-example-pie-extension-769f906 +> C:\php-8.3.6\php.exe bin/pie install --with-php-path=C:\php-8.1.7\php.exe asgrim/example-pie-extension ``` -## Developing - -### Testing +## Extensions that support PIE -### Building and Deploying +A list of extensions that support PIE can be found on +[https://packagist.org/extensions](https://packagist.org/extensions). From 9754de9602cdc12102fbc7e4e014d1dd2d36bfd1 Mon Sep 17 00:00:00 2001 From: James Titcumb Date: Wed, 11 Sep 2024 20:57:09 +0100 Subject: [PATCH 3/4] Small improvements suggested from PR review --- README.md | 8 ++++---- docs/extension-maintainers.md | 12 +++++++----- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 6fc85da..6e8ed78 100644 --- a/README.md +++ b/README.md @@ -12,14 +12,14 @@ You can install an extension using the `install` command. For example, to install the `example_pie_extension` extension, you would run: ```shell -$ bin/pie install asgrim/example-pie-extension +$ bin/pie install example/example-pie-extension This command may need elevated privileges, and may prompt you for your password. You are running PHP 8.3.10 Target PHP installation: 8.3.10 nts, on Linux/OSX/etc x86_64 (from /usr/bin/php8.3) -Found package: asgrim/example-pie-extension:1.0.1 which provides ext-example_pie_extension +Found package: example/example-pie-extension:1.0.1 which provides ext-example_pie_extension phpize complete. Configure complete. -Build complete: /tmp/pie_downloader_66e0b1de73cdb6.04069773/asgrim-example-pie-extension-769f906/modules/example_pie_extension.so +Build complete: /tmp/pie_downloader_66e0b1de73cdb6.04069773/example-example-pie-extension-769f906/modules/example_pie_extension.so Install complete: /usr/lib/php/20230831/example_pie_extension.so You must now add "extension=example_pie_extension" to your php.ini $ @@ -39,7 +39,7 @@ On Windows, you may provide a path to the `php` executable itself using the to run PIE, but we want to download the extension for PHP 8.3: ```shell -> C:\php-8.3.6\php.exe bin/pie install --with-php-path=C:\php-8.1.7\php.exe asgrim/example-pie-extension +> C:\php-8.3.6\php.exe bin/pie install --with-php-path=C:\php-8.1.7\php.exe example/example-pie-extension ``` ## Extensions that support PIE diff --git a/docs/extension-maintainers.md b/docs/extension-maintainers.md index abb8272..f7febc3 100644 --- a/docs/extension-maintainers.md +++ b/docs/extension-maintainers.md @@ -12,9 +12,11 @@ notable exceptions: * The `type` MUST be either `php-ext` for a PHP Module (this will be most extensions), or `php-ext-zend` for a Zend Extension. * An additional `php-ext` section MAY exist. - * The Composer package name (i.e. the top level `name` field) for a PIE - extension cannot share the same Composer package name as a regular PHP - package, even if they have different `type` fields. + * The Composer package name (i.e. the top level `name` field) should follow + the usual Composer package name format, i.e. `/`. + * However, please note that the Composer package name for a PIE extension + cannot share the same Composer package name as a regular PHP package, even + if they have different `type` fields. ### The `php-ext` definition @@ -36,8 +38,8 @@ given a `composer.json` with: The extension name would be derived as `myextension`. The `myvendor/` vendor prefix is removed. -The `extension-name` MAY be prefixed with `ext-` as is a convention in Composer, -but this is optional. +The `extension-name` SHOULD NOT be prefixed with `ext-` as is a convention in +Composer when using `require`. An example of `extension-name` being used: From 42287d74643bd577068e159a915b55730a36397e Mon Sep 17 00:00:00 2001 From: James Titcumb Date: Mon, 16 Sep 2024 21:44:30 +0100 Subject: [PATCH 4/4] Added docs for Windows extension maintenance --- docs/extension-maintainers.md | 96 +++++++++++++++++++++++++++++++++++ 1 file changed, 96 insertions(+) diff --git a/docs/extension-maintainers.md b/docs/extension-maintainers.md index f7febc3..b4c602e 100644 --- a/docs/extension-maintainers.md +++ b/docs/extension-maintainers.md @@ -128,3 +128,99 @@ submit it to Packagist in the same way as any other package. * Head to [https://packagist.org/packages/submit](https://packagist.org/packages/submit) * Enter the URL of your repository, and follow the instructions. + +## Windows Support + +In order to support Windows users, you must publish pre-built DLLs, as PIE does +not currently support building DLLs on the fly. The expected workflow for +Windows-compatible releases is: + + - The release is made on GitHub (only GitHub is supported at the moment) + - A CI pipeline runs to build the release assets, e.g. in a GitHub Action + - The resulting build assets are published to the GitHub release in a ZIP file + +The name of the ZIP file, and the DLL contained within must be: + +* `php_{extension-name}-{tag}-{php-maj/min}-{ts|nts}-{compiler}-{arch}.zip` +* Example: `php_xdebug-3.3.2-8.3-ts-vs16-x86_64.zip` + +The descriptions of these items: + +* `extension-name` the name of the extension, e.g. `xdebug` +* `tag` for example `3.3.0alpha3` - defined by the tag/release you have made +* `php-maj/min` - for example `8.3` for PHP 8.3.* +* `compiler` - usually something like `vc6`, `vs16` - fetch from + 'PHP Extension Build' flags in `php -i` +* `ts|nts` - Thread-safe or non-thread safe. +* `arch` - for example `x86_64`. + * Windows: `Architecture` from `php -i` + * non-Windows: check `PHP_INT_SIZE` - 4 for 32-bit, 8 for 64-bit. + +### Contents of the Windows ZIP + +The pre-built ZIP should contain at minimum a DLL named in the same way as the +ZIP itself, for example +`php_{extension-name}-{tag}-{php-maj/min}-{ts|nts}-{compiler}-{arch}.dll`. +The `.dll` will be moved into the PHP extensions path, and renamed, e.g. +to `C:\path\to\php\ext\php_{extension-name}.dll`. The ZIP file may include +additional resources, such as: + +* `php_{extension-name}.pdb` - this will be moved alongside + the `C:\path\to\php\ext\php_{extension-name}.dll` +* `*.dll` - any other `.dll` would be moved alongside `C:\path\to\php\php.exe` +* Any other file, which would be moved + into `C:\path\to\php\extras\{extension-name}\.` + +### Automation of the Windows publishing + +PHP provides a [set of GitHub Actions](https://github.com/php/php-windows-builder) +that enable extension maintainers to build and release the Windows compatible +assets. An example workflow that uses these actions: + +```yaml +name: Publish Windows Releases +on: + release: + types: [published] + +permissions: + contents: write + +jobs: + get-extension-matrix: + runs-on: ubuntu-latest + outputs: + matrix: ${{ steps.extension-matrix.outputs.matrix }} + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: Get the extension matrix + id: extension-matrix + uses: php/php-windows-builder/extension-matrix@v1 + build: + needs: get-extension-matrix + runs-on: ${{ matrix.os }} + strategy: + matrix: ${{fromJson(needs.get-extension-matrix.outputs.matrix)}} + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: Build the extension + uses: php/php-windows-builder/extension@v1 + with: + php-version: ${{ matrix.php-version }} + arch: ${{ matrix.arch }} + ts: ${{ matrix.ts }} + release: + runs-on: ubuntu-latest + needs: build + if: ${{ github.event_name == 'release' }} + steps: + - name: Upload artifact to the release + uses: php/php-windows-builder/release@v1 + with: + release: ${{ github.event.release.tag_name }} + token: ${{ secrets.GITHUB_TOKEN }} +``` + +Source: [https://github.com/php/php-windows-builder?tab=readme-ov-file#example-workflow-to-build-and-release-an-extension](https://github.com/php/php-windows-builder?tab=readme-ov-file#example-workflow-to-build-and-release-an-extension)