From 4346a74570201fa965a0afca73be8439b873c6a5 Mon Sep 17 00:00:00 2001 From: Go Kudo Date: Tue, 21 Apr 2026 01:00:13 +0000 Subject: [PATCH 1/2] overhawl --- .dockerignore | 2 - .github/workflows/ci_native_linux.yaml | 4 +- .github/workflows/pie_release.yaml | 119 ---------- .github/workflows/release.yaml | 209 +++++++++++++++++ .gitignore | 2 + .idea/.gitignore | 8 - .idea/inspectionProfiles/Project_Default.xml | 7 - .idea/modules.xml | 8 - .idea/php-colopl_bc.iml | 71 ------ .idea/php.xml | 103 --------- .idea/phpunit.xml | 10 - .idea/vcs.xml | 6 - CHANGELOG.md | 12 +- LICENSE | 93 +++----- README.md | 35 ++- build/library/test.sh | 9 +- build/ubuntu2204/Dockerfile | 15 +- build/ubuntu2204/build.sh | 33 +-- build/ubuntu2204/debian/changelog.in | 5 + build/ubuntu2204/debian/control | 32 +++ build/ubuntu2204/debian/copyright | 31 +++ .../debian/php8.1-colopl-bc.postinst | 14 ++ .../ubuntu2204/debian/php8.1-colopl-bc.prerm | 14 ++ build/ubuntu2204/debian/rules | 32 +++ build/ubuntu2204/debian/source/format | 1 + build/ubuntu2204_sury84/Dockerfile | 14 +- build/ubuntu2204_sury84/build.sh | 34 +-- build/ubuntu2204_sury84/debian/changelog.in | 5 + build/ubuntu2204_sury84/debian/control | 22 ++ build/ubuntu2204_sury84/debian/copyright | 31 +++ .../debian/php8.4-colopl-bc.postinst | 14 ++ .../debian/php8.4-colopl-bc.prerm | 14 ++ build/ubuntu2204_sury84/debian/rules | 32 +++ build/ubuntu2204_sury84/debian/source/format | 1 + composer.json | 2 +- ext/colopl_bc.c | 10 +- ext/colopl_bc_php70.c | 168 ++++++++++---- ext/colopl_bc_php74.c | 29 ++- ext/description-pak | 1 - ext/php_colopl_bc.h | 17 +- ext/php_colopl_bc_php70.h | 51 +---- ext/php_colopl_bc_php74.h | 10 +- library.php | 6 +- library_test.sh | 6 +- phpunit.xml | 19 +- pskel.sh | 211 +++++++++++++++--- tests/Extension/PHP70Test.php | 2 +- 47 files changed, 952 insertions(+), 622 deletions(-) delete mode 100644 .github/workflows/pie_release.yaml create mode 100644 .github/workflows/release.yaml delete mode 100644 .idea/.gitignore delete mode 100644 .idea/inspectionProfiles/Project_Default.xml delete mode 100644 .idea/modules.xml delete mode 100644 .idea/php-colopl_bc.iml delete mode 100644 .idea/php.xml delete mode 100644 .idea/phpunit.xml delete mode 100644 .idea/vcs.xml create mode 100644 build/ubuntu2204/debian/changelog.in create mode 100644 build/ubuntu2204/debian/control create mode 100644 build/ubuntu2204/debian/copyright create mode 100755 build/ubuntu2204/debian/php8.1-colopl-bc.postinst create mode 100755 build/ubuntu2204/debian/php8.1-colopl-bc.prerm create mode 100755 build/ubuntu2204/debian/rules create mode 100644 build/ubuntu2204/debian/source/format create mode 100644 build/ubuntu2204_sury84/debian/changelog.in create mode 100644 build/ubuntu2204_sury84/debian/control create mode 100644 build/ubuntu2204_sury84/debian/copyright create mode 100755 build/ubuntu2204_sury84/debian/php8.4-colopl-bc.postinst create mode 100755 build/ubuntu2204_sury84/debian/php8.4-colopl-bc.prerm create mode 100755 build/ubuntu2204_sury84/debian/rules create mode 100644 build/ubuntu2204_sury84/debian/source/format delete mode 100644 ext/description-pak diff --git a/.dockerignore b/.dockerignore index 723dc5c..0ca9a5a 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1,4 +1,2 @@ **/.git -**/README.md -**/LICENSE **/.editorconfig diff --git a/.github/workflows/ci_native_linux.yaml b/.github/workflows/ci_native_linux.yaml index 3b4a454..d4bcb62 100644 --- a/.github/workflows/ci_native_linux.yaml +++ b/.github/workflows/ci_native_linux.yaml @@ -62,9 +62,9 @@ jobs: docker compose build --no-cache --build-arg IMAGE="php" --build-arg TAG="${{ matrix.version }}-${{ matrix.type }}-${{ matrix.distro }}" - name: Test extension with Bundled PHP run: docker compose run --rm -v "$(pwd)/php-cache:/opt/php-cache" -e PHP_CACHE_DIR="/opt/php-cache" -e GITHUB_ACTIONS="true" -e CONTAINER_IMAGE_HASH="${{ steps.pull-image.outputs.image_hash }}" shell pskel test - - name: Test extension with PHP Debug Build + - name: Test extension with PHP Debug Build (in-tree static) if: matrix.version != '8.1' - run: docker compose run --rm -v "$(pwd)/php-cache:/opt/php-cache" -e PHP_CACHE_DIR="/opt/php-cache" -e GITHUB_ACTIONS="true" -e CONTAINER_IMAGE_HASH="${{ steps.pull-image.outputs.image_hash }}" shell pskel test debug + run: docker compose run --rm -v "$(pwd)/php-cache:/opt/php-cache" -e PHP_CACHE_DIR="/opt/php-cache" -e GITHUB_ACTIONS="true" -e CONTAINER_IMAGE_HASH="${{ steps.pull-image.outputs.image_hash }}" shell pskel test debug-static - name: Test extension with Valgrind if: matrix.distro != 'alpine' && matrix.version != '8.1' run: docker compose run --rm -v "$(pwd)/php-cache:/opt/php-cache" -e PHP_CACHE_DIR="/opt/php-cache" -e GITHUB_ACTIONS="true" -e CONTAINER_IMAGE_HASH="${{ steps.pull-image.outputs.image_hash }}" shell pskel test valgrind diff --git a/.github/workflows/pie_release.yaml b/.github/workflows/pie_release.yaml deleted file mode 100644 index e64bdb6..0000000 --- a/.github/workflows/pie_release.yaml +++ /dev/null @@ -1,119 +0,0 @@ -name: Build and release binaries for PIE - -on: - push: - tags: - - '*' - -permissions: - contents: read - -jobs: - CreateDraftRelease: - runs-on: ubuntu-latest - permissions: - contents: write - steps: - - uses: actions/checkout@v6 - with: - fetch-tags: 'true' - ref: ${{ github.ref }} - - name: Create draft release from tag - env: - GH_TOKEN: ${{ github.token }} - run: gh release create "${{ github.ref_name }}" --title "${{ github.ref_name }}" --draft --notes-from-tag - AddPieBinaries: - needs: [ CreateDraftRelease ] - runs-on: ${{ matrix.operating-system }} - strategy: - fail-fast: false - matrix: - operating-system: - - ubuntu-latest - - macos-latest - php-versions: - - '8.1' - - '8.2' - - '8.3' - - '8.4' - - '8.5' - zts-mode: - - ts - - nts - permissions: - contents: write - steps: - - name: Checkout - uses: actions/checkout@v6 - - name: Setup PHP - uses: shivammathur/setup-php@accd6127cb78bee3e8082180cb391013d204ef9f # v2.37.0 - with: - php-version: ${{ matrix.php-versions }} - env: - phpts: ${{ matrix.zts-mode }} - - name: Build and release - uses: php/pie-ext-binary-builder@5298761950f63c7e9565ed7004e922b346e4386c # 0.0.3 - with: - release-tag: ${{ github.ref_name }} - github-token: ${{ secrets.GITHUB_TOKEN }} - configure-flags: '--enable-colopl_bc' - build-path: 'ext' - GetWindowsExtensionMatrix: - needs: [ CreateDraftRelease ] - runs-on: ubuntu-latest - outputs: - matrix: ${{ steps.extension-matrix.outputs.matrix }} - steps: - - name: Checkout - uses: actions/checkout@v6 - with: - fetch-depth: 1 - - name: Get the extension matrix - id: extension-matrix - uses: php/php-windows-builder/extension-matrix@e03e5d39879adaeb61ed2225f0f4eae7db8c1df8 # 1.8.1 - with: - php-version-list: '8.1,8.2,8.3,8.4,8.5' - BuildWindows: - needs: GetWindowsExtensionMatrix - runs-on: ${{ matrix.os }} - strategy: - fail-fast: false - matrix: ${{ fromJson(needs.GetWindowsExtensionMatrix.outputs.matrix) }} - steps: - - name: Checkout - uses: actions/checkout@v6 - with: - fetch-depth: 1 - # Workaround: php-windows-builder reads config.w32 from repo root, - # but our extension source is in ext/. Copy ext/* to root so the - # action can find config.w32 and the source files. - - name: Copy extension source to root - shell: pwsh - run: Copy-Item -Path ext\* -Destination . -Recurse -Force - - name: Build the extension - uses: php/php-windows-builder/extension@e03e5d39879adaeb61ed2225f0f4eae7db8c1df8 # 1.8.1 - with: - php-version: ${{ matrix.php-version }} - arch: ${{ matrix.arch }} - ts: ${{ matrix.ts }} - ReleaseWindows: - runs-on: ubuntu-latest - needs: BuildWindows - permissions: - contents: write - steps: - - name: Upload artifact to the release - uses: php/php-windows-builder/release@e03e5d39879adaeb61ed2225f0f4eae7db8c1df8 # 1.8.1 - with: - release: ${{ github.ref_name }} - token: ${{ secrets.GITHUB_TOKEN }} - publish-release: - needs: [ AddPieBinaries, ReleaseWindows ] - runs-on: ubuntu-latest - permissions: - contents: write - steps: - - name: Publish release - env: - GH_TOKEN: ${{ github.token }} - run: gh release edit "${{ github.ref_name }}" --draft=false --repo "${{ github.repository }}" diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml new file mode 100644 index 0000000..3e31eaa --- /dev/null +++ b/.github/workflows/release.yaml @@ -0,0 +1,209 @@ +name: Build and release extension artifacts + +on: + push: + tags: + - '*' + +permissions: + contents: read + +jobs: + CreateDraftRelease: + runs-on: ubuntu-latest + outputs: + package_version: ${{ steps.package-version.outputs.version }} + permissions: + contents: write + steps: + - uses: actions/checkout@v6 + with: + fetch-tags: 'true' + ref: ${{ github.ref }} + - name: Normalize package version + id: package-version + run: echo "version=${GITHUB_REF_NAME#v}" >> "${GITHUB_OUTPUT}" + - name: Create draft release from tag + env: + GH_TOKEN: ${{ github.token }} + run: | + if gh release view "${{ github.ref_name }}" >/dev/null 2>&1; then + echo "Release already exists: ${{ github.ref_name }}" + else + gh release create "${{ github.ref_name }}" --title "${{ github.ref_name }}" --draft --notes-from-tag + fi + BuildDebPackages: + needs: [ CreateDraftRelease ] + runs-on: ${{ matrix.runs-on }} + strategy: + fail-fast: false + matrix: + include: + - runs-on: ubuntu-24.04 + platform: linux/amd64 + arch: amd64 + dockerfile: build/ubuntu2204/Dockerfile + image_name: colopl-bc-u2204-php81 + artifact_name: ubuntu2204-php81-amd64-debs + prune_meta_package: false + - runs-on: ubuntu-24.04-arm + platform: linux/arm64 + arch: arm64 + dockerfile: build/ubuntu2204/Dockerfile + image_name: colopl-bc-u2204-php81 + artifact_name: ubuntu2204-php81-arm64-debs + prune_meta_package: true + - runs-on: ubuntu-24.04 + platform: linux/amd64 + arch: amd64 + dockerfile: build/ubuntu2204_sury84/Dockerfile + image_name: colopl-bc-u2204-sury84-php84 + artifact_name: ubuntu2204-sury84-php84-amd64-debs + prune_meta_package: false + - runs-on: ubuntu-24.04-arm + platform: linux/arm64 + arch: arm64 + dockerfile: build/ubuntu2204_sury84/Dockerfile + image_name: colopl-bc-u2204-sury84-php84 + artifact_name: ubuntu2204-sury84-php84-arm64-debs + prune_meta_package: false + steps: + - name: Checkout + uses: actions/checkout@v6 + - name: Build package image + run: | + docker build \ + --pull \ + --build-arg PLATFORM="${{ matrix.platform }}" \ + -f "${{ matrix.dockerfile }}" \ + -t "${{ matrix.image_name }}:${{ matrix.arch }}" \ + . + - name: Build deb packages + run: | + mkdir -p "artifacts" + docker run --rm \ + --platform "${{ matrix.platform }}" \ + -e VERSION="${{ needs.CreateDraftRelease.outputs.package_version }}" \ + -v "${PWD}/artifacts:/tmp/artifacts" \ + "${{ matrix.image_name }}:${{ matrix.arch }}" + - name: Remove duplicated meta package + if: matrix.prune_meta_package + run: rm -f artifacts/php-colopl-bc_*_all.deb + - name: Upload deb package artifacts + uses: actions/upload-artifact@v7 + with: + name: ${{ matrix.artifact_name }} + path: artifacts/* + if-no-files-found: error + retention-days: 1 + AddPieBinaries: + needs: [ CreateDraftRelease ] + runs-on: ${{ matrix.operating-system }} + strategy: + fail-fast: false + matrix: + operating-system: + - ubuntu-latest + - macos-latest + php-versions: + - '8.1' + - '8.2' + - '8.3' + - '8.4' + - '8.5' + zts-mode: + - ts + - nts + permissions: + contents: write + steps: + - name: Checkout + uses: actions/checkout@v6 + - name: Setup PHP + uses: shivammathur/setup-php@accd6127cb78bee3e8082180cb391013d204ef9f # v2.37.0 + with: + php-version: ${{ matrix.php-versions }} + env: + phpts: ${{ matrix.zts-mode }} + - name: Build and release + uses: php/pie-ext-binary-builder@5298761950f63c7e9565ed7004e922b346e4386c # 0.0.3 + with: + release-tag: ${{ github.ref_name }} + github-token: ${{ secrets.GITHUB_TOKEN }} + configure-flags: '--enable-colopl_bc' + build-path: 'ext' + GetWindowsExtensionMatrix: + needs: [ CreateDraftRelease ] + runs-on: ubuntu-latest + outputs: + matrix: ${{ steps.extension-matrix.outputs.matrix }} + steps: + - name: Checkout + uses: actions/checkout@v6 + with: + fetch-depth: 1 + - name: Get the extension matrix + id: extension-matrix + uses: php/php-windows-builder/extension-matrix@e03e5d39879adaeb61ed2225f0f4eae7db8c1df8 # 1.8.1 + with: + php-version-list: '8.1,8.2,8.3,8.4,8.5' + BuildWindows: + needs: GetWindowsExtensionMatrix + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: ${{ fromJson(needs.GetWindowsExtensionMatrix.outputs.matrix) }} + steps: + - name: Checkout + uses: actions/checkout@v6 + with: + fetch-depth: 1 + # Workaround: php-windows-builder reads config.w32 from repo root, + # but our extension source is in ext/. Copy ext/* to root so the + # action can find config.w32 and the source files. + - name: Copy extension source to root + shell: pwsh + run: Copy-Item -Path ext\* -Destination . -Recurse -Force + - name: Build the extension + uses: php/php-windows-builder/extension@e03e5d39879adaeb61ed2225f0f4eae7db8c1df8 # 1.8.1 + with: + php-version: ${{ matrix.php-version }} + arch: ${{ matrix.arch }} + ts: ${{ matrix.ts }} + ReleaseWindows: + runs-on: ubuntu-latest + needs: BuildWindows + permissions: + contents: write + steps: + - name: Upload artifact to the release + uses: php/php-windows-builder/release@e03e5d39879adaeb61ed2225f0f4eae7db8c1df8 # 1.8.1 + with: + release: ${{ github.ref_name }} + token: ${{ secrets.GITHUB_TOKEN }} + ReleaseDebPackages: + runs-on: ubuntu-latest + needs: BuildDebPackages + permissions: + contents: write + steps: + - name: Download deb package artifacts + uses: actions/download-artifact@v8 + with: + pattern: '*-debs' + path: deb-artifacts + merge-multiple: true + - name: Upload deb packages to the release + env: + GH_TOKEN: ${{ github.token }} + run: gh release upload "${{ github.ref_name }}" deb-artifacts/* --clobber + PublishRelease: + needs: [ AddPieBinaries, ReleaseWindows, ReleaseDebPackages ] + runs-on: ubuntu-latest + permissions: + contents: write + steps: + - name: Publish release + env: + GH_TOKEN: ${{ github.token }} + run: gh release edit "${{ github.ref_name }}" --draft=false --repo "${{ github.repository }}" diff --git a/.gitignore b/.gitignore index 6b74b10..dde4b98 100644 --- a/.gitignore +++ b/.gitignore @@ -2,7 +2,9 @@ /ext/*~ /vendor /artifacts +/.idea *.DS_Store lcov.info +.phpunit.cache .phpunit.result.cache composer.lock diff --git a/.idea/.gitignore b/.idea/.gitignore deleted file mode 100644 index 13566b8..0000000 --- a/.idea/.gitignore +++ /dev/null @@ -1,8 +0,0 @@ -# Default ignored files -/shelf/ -/workspace.xml -# Editor-based HTTP Client requests -/httpRequests/ -# Datasource local storage ignored files -/dataSources/ -/dataSources.local.xml diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml deleted file mode 100644 index 8bcca30..0000000 --- a/.idea/inspectionProfiles/Project_Default.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml deleted file mode 100644 index 7d33487..0000000 --- a/.idea/modules.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/.idea/php-colopl_bc.iml b/.idea/php-colopl_bc.iml deleted file mode 100644 index 43c9694..0000000 --- a/.idea/php-colopl_bc.iml +++ /dev/null @@ -1,71 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/php.xml b/.idea/php.xml deleted file mode 100644 index 817548c..0000000 --- a/.idea/php.xml +++ /dev/null @@ -1,103 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/phpunit.xml b/.idea/phpunit.xml deleted file mode 100644 index 4f8104c..0000000 --- a/.idea/phpunit.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml deleted file mode 100644 index 35eb1dd..0000000 --- a/.idea/vcs.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 04abb0f..24a2a5a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,14 @@ -# 11.1.0 +# 12.0.0 +- Change the project license from PHP-3.01 to BSD-3-Clause +- Tighten package support to PHP 7.4 or PHP 8.1+ +- Refactor internals toward PHP 8.1+ APIs +- Replace checkinstall-based Ubuntu 22.04 packaging with standard Debian package builds +- Restore tag-triggered GitHub Actions builds for Ubuntu 22.04 deb packages +- Fix in-source build on PHP 8.5 and later (#70) +- Improve `.deb` build from upstream method (#18) +- Official support for PIE + +# 11.1.0 - Add Windows and macOS support - Bump Pskel 2.0.0 - Fix SEGV on date_create, date_create_immutable (#30, https://github.com/colopl/php-colopl_bc/issues/30) diff --git a/LICENSE b/LICENSE index 4076fe9..74b9886 100644 --- a/LICENSE +++ b/LICENSE @@ -1,68 +1,29 @@ --------------------------------------------------------------------- - The PHP License, version 3.01 -Copyright (c) 1999 - 2019 The PHP Group. All rights reserved. --------------------------------------------------------------------- +BSD 3-Clause License -Redistribution and use in source and binary forms, with or without -modification, is permitted provided that the following conditions -are met: - - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - - 3. The name "PHP" must not be used to endorse or promote products - derived from this software without prior written permission. For - written permission, please contact group@php.net. - - 4. Products derived from this software may not be called "PHP", nor - may "PHP" appear in their name, without prior written permission - from group@php.net. You may indicate that your software works in - conjunction with PHP by saying "Foo for PHP" instead of calling - it "PHP Foo" or "phpfoo" - - 5. The PHP Group may publish revised and/or new versions of the - license from time to time. Each version will be given a - distinguishing version number. - Once covered code has been published under a particular version - of the license, you may always continue to use it under the terms - of that version. You may also choose to use such covered code - under the terms of any subsequent version of the license - published by the PHP Group. No one other than the PHP Group has - the right to modify the terms applicable to covered code created - under this License. - - 6. Redistributions of any form whatsoever must retain the following - acknowledgment: - "This product includes PHP software, freely available from - ". +Copyright (c) COLOPL, Inc. +All rights reserved. -THIS SOFTWARE IS PROVIDED BY THE PHP DEVELOPMENT TEAM ``AS IS'' AND -ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A -PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE PHP -DEVELOPMENT TEAM OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, -INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, -STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED -OF THE POSSIBILITY OF SUCH DAMAGE. - --------------------------------------------------------------------- - -This software consists of voluntary contributions made by many -individuals on behalf of the PHP Group. - -The PHP Group can be contacted via Email at group@php.net. - -For more information on the PHP Group and the PHP project, -please see . - -PHP includes the Zend Engine, freely available at -. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +3. Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/README.md b/README.md index 46add65..3d81557 100644 --- a/README.md +++ b/README.md @@ -7,10 +7,10 @@ Provides various compatibility functions required for PHP (temporary) migration. ## Supported Versions -- Extension: PHP >= 8.0, 8.5 >= PHP -- Library: PHP >= 7.4, 8.5 >= PHP +- Extension: PHP >= 8.1, 8.5 >= PHP +- Library: PHP == 7.4 or PHP >= 8.1, 8.5 >= PHP -Library is introduced for migration to PHP 8.x with the same code base. If you do not need to work with the same code base, you can use only the Extension. +Library is introduced for migration from PHP 7.4 to PHP 8.1+ with the same code base. PHP 8.0 is not supported. If you do not need to work with the same code base, you can use only the Extension. ## Usage @@ -37,6 +37,31 @@ $ php -m | grep "colopl_bc" colopl_bc ``` +### Build Ubuntu 22.04 packages + +Ubuntu 22.04 packages are built with standard Debian packaging via `dpkg-buildpackage`, not `checkinstall`. +The packaging definitions live alongside each build target under `build/ubuntu2204/debian` and `build/ubuntu2204_sury84/debian`. + +Build packages for the official Ubuntu 22.04 PHP 8.1 stack: + +```bash +$ docker build -f "build/ubuntu2204/Dockerfile" -t "colopl-bc-u2204-php81" . +$ mkdir -p "artifacts" +$ docker run --rm -e VERSION="12.0.0" -v "$(pwd)/artifacts:/tmp/artifacts" "colopl-bc-u2204-php81" +``` + +This target produces `php-colopl-bc` and `php8.1-colopl-bc` binary packages together with the corresponding `.changes` and `.buildinfo` files. + +Build packages for Ubuntu 22.04 with the Ondrej Sury PHP 8.4 repository: + +```bash +$ docker build -f "build/ubuntu2204_sury84/Dockerfile" -t "colopl-bc-u2204-php84" . +$ mkdir -p "artifacts" +$ docker run --rm -e VERSION="12.0.0" -v "$(pwd)/artifacts:/tmp/artifacts" "colopl-bc-u2204-php84" +``` + +This target produces the `php8.4-colopl-bc` binary package together with the corresponding `.changes` and `.buildinfo` files. + The library is installed in the following steps. ```bash @@ -212,3 +237,7 @@ Generate random numbers. - `Colopl\ColoplBc\Php70\date_create_immutable()` Always instantiate DateTime without milliseconds. + +## License + +This project is licensed under the BSD-3-Clause license. See [LICENSE](LICENSE). diff --git a/build/library/test.sh b/build/library/test.sh index cad9edd..e2c7193 100755 --- a/build/library/test.sh +++ b/build/library/test.sh @@ -1,6 +1,11 @@ #!/bin/sh -if php -r 'exit((\PHP_VERSION_ID >= 80000) ? 0 : 1);'; then +if php -r 'exit((\PHP_VERSION_ID >= 80000 && \PHP_VERSION_ID < 80100) ? 0 : 1);'; then + echo 'colopl_bc does not support PHP 8.0' >&2 + exit 1 +fi + +if php -r 'exit((\PHP_VERSION_ID >= 80100) ? 0 : 1);'; then cd "ext" phpize ./configure --with-php-config="$(which php-config)" @@ -14,7 +19,7 @@ fi composer install composer exec -- phpunit --config="phpunit.xml" -if php -r 'exit((\PHP_VERSION_ID >= 80000) ? 0 : 1);'; then +if php -r 'exit((\PHP_VERSION_ID >= 80100) ? 0 : 1);'; then composer exec -- phpstan analyse --memory-limit=-1 --configuration="phpstan.neon" composer exec -- psalm --memory-limit=-1 --config="psalm.xml" fi diff --git a/build/ubuntu2204/Dockerfile b/build/ubuntu2204/Dockerfile index df5a932..a34d4b5 100644 --- a/build/ubuntu2204/Dockerfile +++ b/build/ubuntu2204/Dockerfile @@ -2,10 +2,21 @@ ARG PLATFORM=${BUILDPLATFORM:-linux/amd64} FROM --platform=${PLATFORM} ubuntu:22.04 +ENV DEBIAN_FRONTEND="noninteractive" + RUN apt-get update && \ - DEBIAN_FRONTEND="noninteractive" apt-get install -y "php" "php-dev" "checkinstall" + apt-get install -y --no-install-recommends \ + "build-essential" \ + "debhelper" \ + "dpkg-dev" \ + "php8.1-cli" \ + "php8.1-dev" && \ + rm -rf /var/lib/apt/lists/* -COPY ./ext /tmp/ext +COPY ./ext /tmp/src/ext +COPY ./LICENSE /tmp/src/LICENSE +COPY ./README.md /tmp/src/README.md +COPY ./build/ubuntu2204/debian /tmp/build/ubuntu2204/debian COPY ./build/ubuntu2204/build.sh /usr/bin/build diff --git a/build/ubuntu2204/build.sh b/build/ubuntu2204/build.sh index 6970709..c7153f1 100755 --- a/build/ubuntu2204/build.sh +++ b/build/ubuntu2204/build.sh @@ -1,18 +1,19 @@ #!/bin/sh -eux -cd "/tmp/ext" - echo "COLOPL PHP backwards compatibility extension" > "description-pak" - phpize - ./configure --with-php-config="$(which "php-config")" - make -j$(nproc) - checkinstall \ - --pkgname="php-colopl-bc" \ - --pkglicense="PHP-3.01" \ - --pkgversion="${VERSION}" \ - --pkggroup="php" \ - --maintainer="g-kudo@colopl.co.jp" \ - --requires="php" \ - --stripso="yes" \ - --pakdir="/tmp/artifacts" \ - --nodoc -cd - +: "${VERSION:?VERSION is required}" + +SOURCE_DIR="/tmp/src" +PACKAGING_DIR="/tmp/build/ubuntu2204/debian" +ARTIFACTS_DIR="/tmp/artifacts" + +rm -rf "${SOURCE_DIR}/debian" +install -d "${SOURCE_DIR}/debian" "${ARTIFACTS_DIR}" +find "${ARTIFACTS_DIR}" -mindepth 1 -maxdepth 1 -delete + +cp -a "${PACKAGING_DIR}/." "${SOURCE_DIR}/debian/" +sed "s/@VERSION@/${VERSION}/g" "${PACKAGING_DIR}/changelog.in" > "${SOURCE_DIR}/debian/changelog" +rm -f "${SOURCE_DIR}/debian/changelog.in" + +cd "${SOURCE_DIR}" +dpkg-buildpackage -us -uc -b +find /tmp -maxdepth 1 -type f \( -name '*.deb' -o -name '*.buildinfo' -o -name '*.changes' \) -exec cp {} "${ARTIFACTS_DIR}/" \; diff --git a/build/ubuntu2204/debian/changelog.in b/build/ubuntu2204/debian/changelog.in new file mode 100644 index 0000000..4ca3c51 --- /dev/null +++ b/build/ubuntu2204/debian/changelog.in @@ -0,0 +1,5 @@ +php-colopl-bc (@VERSION@) jammy; urgency=medium + + * Build php8.1-colopl-bc for Ubuntu 22.04. + + -- Go Kudo Sun, 20 Apr 2026 00:00:00 +0000 diff --git a/build/ubuntu2204/debian/control b/build/ubuntu2204/debian/control new file mode 100644 index 0000000..012d90d --- /dev/null +++ b/build/ubuntu2204/debian/control @@ -0,0 +1,32 @@ +Source: php-colopl-bc +Section: php +Priority: optional +Maintainer: Go Kudo +Homepage: https://github.com/colopl/php-colopl_bc +Standards-Version: 4.6.2 +Rules-Requires-Root: no +Build-Depends: + debhelper-compat (= 13), + php8.1-cli, + php8.1-dev + +Package: php-colopl-bc +Section: php +Architecture: all +Depends: + ${misc:Depends}, + php8.1-colopl-bc +Description: Meta package for the COLOPL backwards compatibility extension + This package depends on the Ubuntu 22.04 build of the colopl_bc extension + for PHP 8.1. + +Package: php8.1-colopl-bc +Section: php +Architecture: any +Depends: + ${misc:Depends}, + ${shlibs:Depends}, + php8.1-common +Description: COLOPL backwards compatibility extension for PHP 8.1 + The colopl_bc extension provides compatibility helpers that support staged + migrations from older PHP behavior to PHP 8.1 and later. diff --git a/build/ubuntu2204/debian/copyright b/build/ubuntu2204/debian/copyright new file mode 100644 index 0000000..1a55bf3 --- /dev/null +++ b/build/ubuntu2204/debian/copyright @@ -0,0 +1,31 @@ +Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ +Upstream-Name: php-colopl-bc +Source: https://github.com/colopl/php-colopl_bc + +Files: * +Copyright: 2020-2026 COLOPL, Inc. +License: BSD-3-Clause + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + . + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + . + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + . + 3. Neither the name of COLOPL, Inc. nor the names of its contributors may be + used to endorse or promote products derived from this software without + specific prior written permission. + . + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/build/ubuntu2204/debian/php8.1-colopl-bc.postinst b/build/ubuntu2204/debian/php8.1-colopl-bc.postinst new file mode 100755 index 0000000..889f0aa --- /dev/null +++ b/build/ubuntu2204/debian/php8.1-colopl-bc.postinst @@ -0,0 +1,14 @@ +#!/bin/sh +set -e + +case "$1" in + configure|abort-upgrade|abort-deconfigure|abort-remove) + if command -v phpenmod >/dev/null 2>&1; then + phpenmod -v 8.1 -s ALL colopl_bc || true + fi + ;; +esac + +#DEBHELPER# + +exit 0 diff --git a/build/ubuntu2204/debian/php8.1-colopl-bc.prerm b/build/ubuntu2204/debian/php8.1-colopl-bc.prerm new file mode 100755 index 0000000..df9cc04 --- /dev/null +++ b/build/ubuntu2204/debian/php8.1-colopl-bc.prerm @@ -0,0 +1,14 @@ +#!/bin/sh +set -e + +case "$1" in + remove|deconfigure) + if command -v phpdismod >/dev/null 2>&1; then + phpdismod -v 8.1 -s ALL colopl_bc || true + fi + ;; +esac + +#DEBHELPER# + +exit 0 diff --git a/build/ubuntu2204/debian/rules b/build/ubuntu2204/debian/rules new file mode 100755 index 0000000..ff5d175 --- /dev/null +++ b/build/ubuntu2204/debian/rules @@ -0,0 +1,32 @@ +#!/usr/bin/make -f + +PHPIZE = phpize +PHP_CONFIG = php-config +PHP_VERSION = 8.1 +BINARY_PACKAGE = php8.1-colopl-bc + +export DEB_BUILD_MAINT_OPTIONS = hardening=+all + +%: + dh $@ + +override_dh_auto_configure: + cd ext && $(PHPIZE) + cd ext && ./configure --with-php-config="$$(command -v $(PHP_CONFIG))" + +override_dh_auto_build: + $(MAKE) -C ext -j$(shell nproc) + +override_dh_auto_test: + cd ext && TEST_PHP_ARGS="--show-diff -q" $(MAKE) test + +override_dh_auto_install: + extdir="$$( $(PHP_CONFIG) --extension-dir )"; \ + pkgdir="$(CURDIR)/debian/$(BINARY_PACKAGE)"; \ + install -d "$$pkgdir$$extdir" "$$pkgdir/etc/php/$(PHP_VERSION)/mods-available"; \ + install -m 0644 ext/modules/colopl_bc.so "$$pkgdir$$extdir/colopl_bc.so"; \ + printf '%s\n' '; priority=20' 'extension=colopl_bc' > "$$pkgdir/etc/php/$(PHP_VERSION)/mods-available/colopl_bc.ini" + +override_dh_auto_clean: + if [ -f ext/Makefile ]; then $(MAKE) -C ext clean || true; fi + rm -rf ext/modules ext/autom4te.cache diff --git a/build/ubuntu2204/debian/source/format b/build/ubuntu2204/debian/source/format new file mode 100644 index 0000000..89ae9db --- /dev/null +++ b/build/ubuntu2204/debian/source/format @@ -0,0 +1 @@ +3.0 (native) diff --git a/build/ubuntu2204_sury84/Dockerfile b/build/ubuntu2204_sury84/Dockerfile index 4743d10..0d1a42c 100644 --- a/build/ubuntu2204_sury84/Dockerfile +++ b/build/ubuntu2204_sury84/Dockerfile @@ -9,10 +9,18 @@ RUN apt-get update && \ "software-properties-common" && \ add-apt-repository ppa:ondrej/php -y && \ apt-get update && \ - apt-get install -y \ - "php8.4" "php8.4-dev" "checkinstall" + apt-get install -y --no-install-recommends \ + "build-essential" \ + "debhelper" \ + "dpkg-dev" \ + "php8.4-cli" \ + "php8.4-dev" && \ + rm -rf /var/lib/apt/lists/* -COPY ./ext /tmp/ext +COPY ./ext /tmp/src/ext +COPY ./LICENSE /tmp/src/LICENSE +COPY ./README.md /tmp/src/README.md +COPY ./build/ubuntu2204_sury84/debian /tmp/build/ubuntu2204_sury84/debian COPY ./build/ubuntu2204_sury84/build.sh /usr/bin/build diff --git a/build/ubuntu2204_sury84/build.sh b/build/ubuntu2204_sury84/build.sh index 8c516c2..267963a 100755 --- a/build/ubuntu2204_sury84/build.sh +++ b/build/ubuntu2204_sury84/build.sh @@ -1,19 +1,19 @@ #!/bin/sh -eux -cd "/tmp/ext" - echo "COLOPL PHP backwards compatibility extension for sury PHP 8.4" > "description-pak" - phpize8.4 - ./configure --with-php-config="$(which "php-config8.4")" - make -j"$(nproc)" - TEST_PHP_ARGS="--show-diff -q" make test - checkinstall \ - --pkgname="php8.4-colopl-bc" \ - --pkglicense="PHP-3.01" \ - --pkgversion="${VERSION}" \ - --pkggroup="php8.4" \ - --maintainer="g-kudo@colopl.co.jp" \ - --requires="php8.4-common" \ - --stripso="yes" \ - --pakdir="/tmp/artifacts" \ - --nodoc -cd - +: "${VERSION:?VERSION is required}" + +SOURCE_DIR="/tmp/src" +PACKAGING_DIR="/tmp/build/ubuntu2204_sury84/debian" +ARTIFACTS_DIR="/tmp/artifacts" + +rm -rf "${SOURCE_DIR}/debian" +install -d "${SOURCE_DIR}/debian" "${ARTIFACTS_DIR}" +find "${ARTIFACTS_DIR}" -mindepth 1 -maxdepth 1 -delete + +cp -a "${PACKAGING_DIR}/." "${SOURCE_DIR}/debian/" +sed "s/@VERSION@/${VERSION}/g" "${PACKAGING_DIR}/changelog.in" > "${SOURCE_DIR}/debian/changelog" +rm -f "${SOURCE_DIR}/debian/changelog.in" + +cd "${SOURCE_DIR}" +dpkg-buildpackage -us -uc -b +find /tmp -maxdepth 1 -type f \( -name '*.deb' -o -name '*.buildinfo' -o -name '*.changes' \) -exec cp {} "${ARTIFACTS_DIR}/" \; diff --git a/build/ubuntu2204_sury84/debian/changelog.in b/build/ubuntu2204_sury84/debian/changelog.in new file mode 100644 index 0000000..79b1a3c --- /dev/null +++ b/build/ubuntu2204_sury84/debian/changelog.in @@ -0,0 +1,5 @@ +php-colopl-bc (@VERSION@) jammy; urgency=medium + + * Build php8.4-colopl-bc for Ubuntu 22.04 with the Ondrej Sury PHP 8.4 repository. + + -- Go Kudo Sun, 20 Apr 2026 00:00:00 +0000 \ No newline at end of file diff --git a/build/ubuntu2204_sury84/debian/control b/build/ubuntu2204_sury84/debian/control new file mode 100644 index 0000000..1a5950c --- /dev/null +++ b/build/ubuntu2204_sury84/debian/control @@ -0,0 +1,22 @@ +Source: php-colopl-bc +Section: php +Priority: optional +Maintainer: Go Kudo +Homepage: https://github.com/colopl/php-colopl_bc +Standards-Version: 4.6.2 +Rules-Requires-Root: no +Build-Depends: + debhelper-compat (= 13), + php8.4-cli, + php8.4-dev + +Package: php8.4-colopl-bc +Section: php +Architecture: any +Depends: + ${misc:Depends}, + ${shlibs:Depends}, + php8.4-common +Description: COLOPL backwards compatibility extension for Sury PHP 8.4 + The colopl_bc extension provides compatibility helpers that support staged + migrations from older PHP behavior to PHP 8.1 and later. diff --git a/build/ubuntu2204_sury84/debian/copyright b/build/ubuntu2204_sury84/debian/copyright new file mode 100644 index 0000000..f0bcbb6 --- /dev/null +++ b/build/ubuntu2204_sury84/debian/copyright @@ -0,0 +1,31 @@ +Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ +Upstream-Name: php-colopl-bc +Source: https://github.com/colopl/php-colopl_bc + +Files: * +Copyright: 2020-2026 COLOPL, Inc. +License: BSD-3-Clause + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + . + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + . + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + . + 3. Neither the name of COLOPL, Inc. nor the names of its contributors may be + used to endorse or promote products derived from this software without + specific prior written permission. + . + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \ No newline at end of file diff --git a/build/ubuntu2204_sury84/debian/php8.4-colopl-bc.postinst b/build/ubuntu2204_sury84/debian/php8.4-colopl-bc.postinst new file mode 100755 index 0000000..b346166 --- /dev/null +++ b/build/ubuntu2204_sury84/debian/php8.4-colopl-bc.postinst @@ -0,0 +1,14 @@ +#!/bin/sh +set -e + +case "$1" in + configure|abort-upgrade|abort-deconfigure|abort-remove) + if command -v phpenmod >/dev/null 2>&1; then + phpenmod -v 8.4 -s ALL colopl_bc || true + fi + ;; +esac + +#DEBHELPER# + +exit 0 \ No newline at end of file diff --git a/build/ubuntu2204_sury84/debian/php8.4-colopl-bc.prerm b/build/ubuntu2204_sury84/debian/php8.4-colopl-bc.prerm new file mode 100755 index 0000000..4b4dbd9 --- /dev/null +++ b/build/ubuntu2204_sury84/debian/php8.4-colopl-bc.prerm @@ -0,0 +1,14 @@ +#!/bin/sh +set -e + +case "$1" in + remove|deconfigure) + if command -v phpdismod >/dev/null 2>&1; then + phpdismod -v 8.4 -s ALL colopl_bc || true + fi + ;; +esac + +#DEBHELPER# + +exit 0 \ No newline at end of file diff --git a/build/ubuntu2204_sury84/debian/rules b/build/ubuntu2204_sury84/debian/rules new file mode 100755 index 0000000..45c990d --- /dev/null +++ b/build/ubuntu2204_sury84/debian/rules @@ -0,0 +1,32 @@ +#!/usr/bin/make -f + +PHPIZE = phpize8.4 +PHP_CONFIG = php-config8.4 +PHP_VERSION = 8.4 +BINARY_PACKAGE = php8.4-colopl-bc + +export DEB_BUILD_MAINT_OPTIONS = hardening=+all + +%: + dh $@ + +override_dh_auto_configure: + cd ext && $(PHPIZE) + cd ext && ./configure --with-php-config="$$(command -v $(PHP_CONFIG))" + +override_dh_auto_build: + $(MAKE) -C ext -j$(shell nproc) + +override_dh_auto_test: + cd ext && TEST_PHP_ARGS="--show-diff -q" $(MAKE) test + +override_dh_auto_install: + extdir="$$( $(PHP_CONFIG) --extension-dir )"; \ + pkgdir="$(CURDIR)/debian/$(BINARY_PACKAGE)"; \ + install -d "$$pkgdir$$extdir" "$$pkgdir/etc/php/$(PHP_VERSION)/mods-available"; \ + install -m 0644 ext/modules/colopl_bc.so "$$pkgdir$$extdir/colopl_bc.so"; \ + printf '%s\n' '; priority=20' 'extension=colopl_bc' > "$$pkgdir/etc/php/$(PHP_VERSION)/mods-available/colopl_bc.ini" + +override_dh_auto_clean: + if [ -f ext/Makefile ]; then $(MAKE) -C ext clean || true; fi + rm -rf ext/modules ext/autom4te.cache \ No newline at end of file diff --git a/build/ubuntu2204_sury84/debian/source/format b/build/ubuntu2204_sury84/debian/source/format new file mode 100644 index 0000000..9f67427 --- /dev/null +++ b/build/ubuntu2204_sury84/debian/source/format @@ -0,0 +1 @@ +3.0 (native) \ No newline at end of file diff --git a/composer.json b/composer.json index 4e34c95..667e878 100644 --- a/composer.json +++ b/composer.json @@ -36,7 +36,7 @@ } ] }, - "license": "PHP-3.01", + "license": "BSD-3-Clause", "authors": [ { "name": "Go Kudo", diff --git a/ext/colopl_bc.c b/ext/colopl_bc.c index ebf9c16..7ce1456 100644 --- a/ext/colopl_bc.c +++ b/ext/colopl_bc.c @@ -3,15 +3,9 @@ | COLOPL PHP Backwards Compatibility Extension. | +----------------------------------------------------------------------+ | Copyright (c) COLOPL, Inc. | - | Copyright (c) The PHP Group | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | http://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the BSD-3-Clause license that is | + | bundled with this package in the file LICENSE. | +----------------------------------------------------------------------+ | Author: Go Kudo | +----------------------------------------------------------------------+ diff --git a/ext/colopl_bc_php70.c b/ext/colopl_bc_php70.c index 928722d..45bff24 100644 --- a/ext/colopl_bc_php70.c +++ b/ext/colopl_bc_php70.c @@ -3,15 +3,9 @@ | COLOPL PHP Backwards Compatibility Extension. | +----------------------------------------------------------------------+ | Copyright (c) COLOPL, Inc. | - | Copyright (c) The PHP Group | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | http://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the BSD-3-Clause license that is | + | bundled with this package in the file LICENSE. | +----------------------------------------------------------------------+ | Author: Go Kudo | +----------------------------------------------------------------------+ @@ -26,6 +20,76 @@ #include "ext/date/php_date.h" #include "zend_bitset.h" +#ifndef RAND_MAX +# define RAND_MAX (1 << 15) +#endif + +#if !defined(ZTS) && (defined(HAVE_LRAND48) || defined(HAVE_RANDOM)) +enum { + COLOPL_BC_RAND_MAX_VALUE = 2147483647, + COLOPL_BC_MT_M = 397, + COLOPL_BC_MT_RAND_MAX_VALUE = 0x7FFFFFFF +}; +#else +enum { + COLOPL_BC_RAND_MAX_VALUE = RAND_MAX, + COLOPL_BC_MT_M = 397, + COLOPL_BC_MT_RAND_MAX_VALUE = 0x7FFFFFFF +}; +#endif + +/* Emulate gcc + amd64 undefined behavior results. */ +static inline zend_long php_colopl_bc_float_to_long_amd64(zend_long min, double value) +{ + if (value > ((double) ZEND_LONG_MAX) || value < ((double) ZEND_LONG_MIN)) { + return 0; + } + + return min + (zend_long) value; +} + +static inline zend_long php_colopl_bc_rand_range(zend_long number, zend_long min, zend_long max, zend_long rand_max) +{ + return php_colopl_bc_float_to_long_amd64( + min, + ((double) max - (double) min + 1.0) * ((double) number / ((double) rand_max + 1.0)) + ); +} + +static inline zend_long php_colopl_bc_generate_seed(void) +{ +#ifdef PHP_WIN32 + return (((zend_long) (time(0) * GetCurrentProcessId())) ^ ((zend_long) (1000000.0 * php_combined_lcg()))); +#else + return (((zend_long) (time(0) * getpid())) ^ ((zend_long) (1000000.0 * php_combined_lcg()))); +#endif +} + +static inline uint32_t php_colopl_bc_mt_hi_bit(uint32_t value) +{ + return value & 0x80000000U; +} + +static inline uint32_t php_colopl_bc_mt_lo_bit(uint32_t value) +{ + return value & 0x00000001U; +} + +static inline uint32_t php_colopl_bc_mt_lo_bits(uint32_t value) +{ + return value & 0x7FFFFFFFU; +} + +static inline uint32_t php_colopl_bc_mt_mix_bits(uint32_t left, uint32_t right) +{ + return php_colopl_bc_mt_hi_bit(left) | php_colopl_bc_mt_lo_bits(right); +} + +static inline uint32_t php_colopl_bc_mt_twist(uint32_t m, uint32_t u, uint32_t v) +{ + return m ^ (php_colopl_bc_mt_mix_bits(u, v) >> 1) ^ ((uint32_t) (-(uint32_t) php_colopl_bc_mt_lo_bit(u)) & 0x9908b0dfU); +} + /* rand.c */ #if defined(__clang__) @@ -70,7 +134,7 @@ zend_long php_colopl_bc_rand(void) zend_long ret; if (!COLOPL_BC_G(rand_is_seeded)) { - php_colopl_bc_srand(COLOPL_BC_GENERATE_SEED()); + php_colopl_bc_srand(php_colopl_bc_generate_seed()); } #ifdef ZTS @@ -106,7 +170,7 @@ PHP_FUNCTION(Colopl_ColoplBc_Php70_srand) ZEND_PARSE_PARAMETERS_END(); if (ZEND_NUM_ARGS() == 0) { - seed = COLOPL_BC_GENERATE_SEED(); + seed = php_colopl_bc_generate_seed(); } php_colopl_bc_srand(seed); @@ -129,7 +193,7 @@ PHP_FUNCTION(Colopl_ColoplBc_Php70_rand) Z_PARAM_LONG(max) ZEND_PARSE_PARAMETERS_END(); - PHP_COLOPL_BC_RAND_RANGE(number, min, max, PHP_COLOPL_BC_RAND_MAX); + number = php_colopl_bc_rand_range(number, min, max, COLOPL_BC_RAND_MAX_VALUE); RETURN_LONG(number); } @@ -137,7 +201,7 @@ PHP_FUNCTION(Colopl_ColoplBc_Php70_getrandmax) { ZEND_PARSE_PARAMETERS_NONE(); - RETURN_LONG(PHP_COLOPL_BC_RAND_MAX); + RETURN_LONG(COLOPL_BC_RAND_MAX_VALUE); } /* mt_rand.c */ @@ -149,7 +213,7 @@ static inline void mt_initialize(uint32_t seed, uint32_t *state) register int i = 1; *s++ = seed & 0xffffffffU; - for (; i < N; ++i) { + for (; i < COLOPL_BC_MT_N; ++i) { *s++ = ( 1812433253U * ( *r ^ (*r >> 30) ) + i ) & 0xffffffffU; r++; } @@ -161,14 +225,14 @@ static inline void mt_reload(void) register uint32_t *p = state; register int i; - for (i = N - M; i--; ++p) { - *p = twist(p[M], p[0], p[1]); + for (i = COLOPL_BC_MT_N - COLOPL_BC_MT_M; i--; ++p) { + *p = php_colopl_bc_mt_twist(p[COLOPL_BC_MT_M], p[0], p[1]); } - for (i = M; --i; ++p) { - *p = twist(p[M-N], p[0], p[1]); + for (i = COLOPL_BC_MT_M; --i; ++p) { + *p = php_colopl_bc_mt_twist(p[COLOPL_BC_MT_M - COLOPL_BC_MT_N], p[0], p[1]); } - *p = twist(p[M-N], p[0], state[0]); - COLOPL_BC_G(mt_left) = N; + *p = php_colopl_bc_mt_twist(p[COLOPL_BC_MT_M - COLOPL_BC_MT_N], p[0], state[0]); + COLOPL_BC_G(mt_left) = COLOPL_BC_MT_N; COLOPL_BC_G(mt_next) = state; } @@ -206,7 +270,7 @@ PHP_FUNCTION(Colopl_ColoplBc_Php70_mt_srand) ZEND_PARSE_PARAMETERS_END(); if (ZEND_NUM_ARGS() == 0) { - seed = COLOPL_BC_GENERATE_SEED(); + seed = php_colopl_bc_generate_seed(); } php_colopl_bc_mt_srand((uint32_t) seed); @@ -219,7 +283,7 @@ PHP_FUNCTION(Colopl_ColoplBc_Php70_mt_rand) if (argc == 0) { if (!COLOPL_BC_G(mt_rand_is_seeded)) { - php_colopl_bc_mt_srand(COLOPL_BC_GENERATE_SEED()); + php_colopl_bc_mt_srand(php_colopl_bc_generate_seed()); } RETURN_LONG(php_colopl_bc_mt_rand() >> 1); } @@ -235,11 +299,11 @@ PHP_FUNCTION(Colopl_ColoplBc_Php70_mt_rand) } if (!COLOPL_BC_G(mt_rand_is_seeded)) { - php_colopl_bc_mt_srand(COLOPL_BC_GENERATE_SEED()); + php_colopl_bc_mt_srand(php_colopl_bc_generate_seed()); } number = (zend_long) (php_colopl_bc_mt_rand() >> 1); - PHP_COLOPL_BC_RAND_RANGE(number, min, max, PHP_COLOPL_BC_MT_RAND_MAX); + number = php_colopl_bc_rand_range(number, min, max, COLOPL_BC_MT_RAND_MAX_VALUE); RETURN_LONG(number); } @@ -247,7 +311,7 @@ PHP_FUNCTION(Colopl_ColoplBc_Php70_mt_getrandmax) { ZEND_PARSE_PARAMETERS_NONE(); - RETURN_LONG(PHP_COLOPL_BC_MT_RAND_MAX); + RETURN_LONG(COLOPL_BC_MT_RAND_MAX_VALUE); } /* array.c */ @@ -283,7 +347,7 @@ void php_colopl_bc_array_data_shuffle(zval *array) } while (--n_left) { rnd_idx = php_colopl_bc_rand(); - PHP_COLOPL_BC_RAND_RANGE(rnd_idx, 0, n_left, PHP_COLOPL_BC_RAND_MAX); + rnd_idx = php_colopl_bc_rand_range(rnd_idx, 0, n_left, COLOPL_BC_RAND_MAX_VALUE); if (rnd_idx != n_left) { temp = hash->arData[n_left]; hash->arData[n_left] = hash->arData[rnd_idx]; @@ -309,7 +373,7 @@ void php_colopl_bc_array_data_shuffle(zval *array) } while (--n_left) { rnd_idx = php_colopl_bc_rand(); - PHP_COLOPL_BC_RAND_RANGE(rnd_idx, 0, n_left, PHP_COLOPL_BC_RAND_MAX); + rnd_idx = php_colopl_bc_rand_range(rnd_idx, 0, n_left, COLOPL_BC_RAND_MAX_VALUE); if (rnd_idx != n_left) { temp = hash->arData[n_left]; hash->arData[n_left] = hash->arData[rnd_idx]; @@ -380,7 +444,7 @@ void php_colopl_bc_array_data_shuffle(zval *array) } while (--n_left) { rnd_idx = php_colopl_bc_rand(); - PHP_COLOPL_BC_RAND_RANGE(rnd_idx, 0, n_left, PHP_COLOPL_BC_RAND_MAX); + rnd_idx = php_colopl_bc_rand_range(rnd_idx, 0, n_left, COLOPL_BC_RAND_MAX_VALUE); if (rnd_idx != n_left) { ZVAL_COPY_VALUE(&temp, &hash->arPacked[n_left]); ZVAL_COPY_VALUE(&hash->arPacked[n_left], &hash->arPacked[rnd_idx]); @@ -406,7 +470,7 @@ void php_colopl_bc_array_data_shuffle(zval *array) } while (--n_left) { rnd_idx = php_colopl_bc_rand(); - PHP_COLOPL_BC_RAND_RANGE(rnd_idx, 0, n_left, PHP_COLOPL_BC_RAND_MAX); + rnd_idx = php_colopl_bc_rand_range(rnd_idx, 0, n_left, COLOPL_BC_RAND_MAX_VALUE); if (rnd_idx != n_left) { ZVAL_COPY_VALUE(&temp, &hash->arPacked[n_left]); ZVAL_COPY_VALUE(&hash->arPacked[n_left], &hash->arPacked[rnd_idx]); @@ -470,7 +534,7 @@ PHP_FUNCTION(Colopl_ColoplBc_Php70_array_rand) randval = php_colopl_bc_rand(); - if ((double) (randval / (PHP_COLOPL_BC_RAND_MAX + 1.0)) < (double) num_req / (double) num_avail) { + if ((double) randval / ((double) COLOPL_BC_RAND_MAX_VALUE + 1.0) < (double) num_req / (double) num_avail) { /* If we are returning a single result, just do it. */ if (Z_TYPE_P(return_value) != IS_ARRAY) { if (string_key) { @@ -509,7 +573,7 @@ void php_colopl_bc_string_shuffle(char *str, zend_long len) while (--n_left) { rnd_idx = php_colopl_bc_rand(); - PHP_COLOPL_BC_RAND_RANGE(rnd_idx, 0, n_left, PHP_COLOPL_BC_RAND_MAX); + rnd_idx = php_colopl_bc_rand_range(rnd_idx, 0, n_left, COLOPL_BC_RAND_MAX_VALUE); if (rnd_idx != n_left) { temp = str[n_left]; str[n_left] = str[rnd_idx]; @@ -534,30 +598,46 @@ PHP_FUNCTION(Colopl_ColoplBc_Php70_str_shuffle) PHP_FUNCTION(Colopl_ColoplBc_Php70_date_create) { - zend_function *fn; + zval *timezone_object = NULL; + char *time_str = NULL; + size_t time_str_len = 0; php_date_obj *date; - fn = zend_hash_str_find_ptr(CG(function_table), "date_create", strlen("date_create")); - ZEND_ASSERT(fn); - fn->internal_function.handler(INTERNAL_FUNCTION_PARAM_PASSTHRU); + ZEND_PARSE_PARAMETERS_START(0, 2) + Z_PARAM_OPTIONAL + Z_PARAM_STRING(time_str, time_str_len) + Z_PARAM_OBJECT_OF_CLASS_OR_NULL(timezone_object, php_date_get_timezone_ce()) + ZEND_PARSE_PARAMETERS_END(); - if (Z_TYPE_P(return_value) != IS_FALSE) { - date = Z_PHPDATE_P(return_value); - date->time->us = 0; + php_date_instantiate(php_date_get_date_ce(), return_value); + if (!php_date_initialize(Z_PHPDATE_P(return_value), time_str, time_str_len, NULL, timezone_object, 0)) { + zval_ptr_dtor(return_value); + RETURN_FALSE; } + + date = Z_PHPDATE_P(return_value); + date->time->us = 0; } PHP_FUNCTION(Colopl_ColoplBc_Php70_date_create_immutable) { - zend_function *fn; + zval *timezone_object = NULL; + char *time_str = NULL; + size_t time_str_len = 0; php_date_obj *date; - fn = zend_hash_str_find_ptr(CG(function_table), "date_create_immutable", strlen("date_create_immutable")); - ZEND_ASSERT(fn); - fn->internal_function.handler(INTERNAL_FUNCTION_PARAM_PASSTHRU); + ZEND_PARSE_PARAMETERS_START(0, 2) + Z_PARAM_OPTIONAL + Z_PARAM_STRING(time_str, time_str_len) + Z_PARAM_OBJECT_OF_CLASS_OR_NULL(timezone_object, php_date_get_timezone_ce()) + ZEND_PARSE_PARAMETERS_END(); - if (Z_TYPE_P(return_value) != IS_FALSE) { - date = Z_PHPDATE_P(return_value); - date->time->us = 0; + php_date_instantiate(php_date_get_immutable_ce(), return_value); + if (!php_date_initialize(Z_PHPDATE_P(return_value), time_str, time_str_len, NULL, timezone_object, 0)) { + zval_ptr_dtor(return_value); + RETURN_FALSE; } + + date = Z_PHPDATE_P(return_value); + date->time->us = 0; } diff --git a/ext/colopl_bc_php74.c b/ext/colopl_bc_php74.c index a1e52e1..4c4cc35 100644 --- a/ext/colopl_bc_php74.c +++ b/ext/colopl_bc_php74.c @@ -3,15 +3,9 @@ | COLOPL PHP Backwards Compatibility Extension. | +----------------------------------------------------------------------+ | Copyright (c) COLOPL, Inc. | - | Copyright (c) The PHP Group | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | http://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the BSD-3-Clause license that is | + | bundled with this package in the file LICENSE. | +----------------------------------------------------------------------+ | Author: Go Kudo | +----------------------------------------------------------------------+ @@ -31,13 +25,18 @@ #define COLOPL_BC_TYPE_PAIR(t1,t2) (((t1) << 4) | (t2)) -#define php_colopl_bc_convert_object_to_type(op, dst, ctype) \ - ZVAL_UNDEF(dst); \ - if (Z_OBJ_HT_P(op)->cast_object(Z_OBJ_P(op), dst, ctype) == FAILURE) { \ - zend_error(E_WARNING, \ - "Object of class %s could not be converted to %s", ZSTR_VAL(Z_OBJCE_P(op)->name), \ - zend_get_type_by_const(ctype)); \ - } \ +static inline void php_colopl_bc_convert_object_to_type(zval *op, zval *dst, uint32_t ctype) +{ + ZVAL_UNDEF(dst); + if (Z_OBJ_HT_P(op)->cast_object(Z_OBJ_P(op), dst, ctype) == FAILURE) { + zend_error( + E_WARNING, + "Object of class %s could not be converted to %s", + ZSTR_VAL(Z_OBJCE_P(op)->name), + zend_get_type_by_const(ctype) + ); + } +} static zend_never_inline zval* ZEND_FASTCALL _php_colopl_bc_zendi_convert_scalar_to_number_silent(zval *op, zval *holder) { diff --git a/ext/description-pak b/ext/description-pak deleted file mode 100644 index 1c8e423..0000000 --- a/ext/description-pak +++ /dev/null @@ -1 +0,0 @@ -Package created with checkinstall 1.6.3 diff --git a/ext/php_colopl_bc.h b/ext/php_colopl_bc.h index 927d406..6e56de4 100644 --- a/ext/php_colopl_bc.h +++ b/ext/php_colopl_bc.h @@ -3,15 +3,9 @@ | COLOPL PHP Backwards Compatibility Extension. | +----------------------------------------------------------------------+ | Copyright (c) COLOPL, Inc. | - | Copyright (c) The PHP Group | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | http://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the BSD-3-Clause license that is | + | bundled with this package in the file LICENSE. | +----------------------------------------------------------------------+ | Author: Go Kudo | +----------------------------------------------------------------------+ @@ -44,11 +38,16 @@ extern zend_module_entry colopl_bc_module_entry; #define PHP_COLOPL_BC_VERSION "12.0.1" +enum { + COLOPL_BC_MT_N = 624, + COLOPL_BC_MT_STATE_SIZE = COLOPL_BC_MT_N + 1 +}; + ZEND_BEGIN_MODULE_GLOBALS(colopl_bc) bool rand_is_seeded; bool mt_rand_is_seeded; uint32_t rand_seed; - uint32_t mt_state[N+1]; + uint32_t mt_state[COLOPL_BC_MT_STATE_SIZE]; uint32_t *mt_next; int mt_left; int gnurandom_r[344]; diff --git a/ext/php_colopl_bc_php70.h b/ext/php_colopl_bc_php70.h index 08c493e..dc9db81 100644 --- a/ext/php_colopl_bc_php70.h +++ b/ext/php_colopl_bc_php70.h @@ -3,15 +3,9 @@ | COLOPL PHP Backwards Compatibility Extension. | +----------------------------------------------------------------------+ | Copyright (c) COLOPL, Inc. | - | Copyright (c) The PHP Group | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | http://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the BSD-3-Clause license that is | + | bundled with this package in the file LICENSE. | +----------------------------------------------------------------------+ | Author: Go Kudo | +----------------------------------------------------------------------+ @@ -22,35 +16,6 @@ #include "php_colopl_bc.h" -#ifndef RAND_MAX -# define RAND_MAX (1<<15) -#endif - -#if !defined(ZTS) && (defined(HAVE_LRAND48) || defined(HAVE_RANDOM)) -# define PHP_COLOPL_BC_RAND_MAX 2147483647 -#else -# define PHP_COLOPL_BC_RAND_MAX RAND_MAX -#endif - -/* Emulate gcc + amd64 undefined behavior results. */ -static inline zend_long float_to_long_amd64(zend_long min, double f) -{ - if (f > ((double) ZEND_LONG_MAX) || f < ((double) ZEND_LONG_MIN)) { - return 0; - } - - return min + (zend_long) f; -} - -# define PHP_COLOPL_BC_RAND_RANGE(__n, __min, __max, __tmax) \ - (__n) = float_to_long_amd64(__min, ((double) (__max) - (__min) + 1.0) * ((__n) / ((__tmax) + 1.0))) - -#ifdef PHP_WIN32 -# define COLOPL_BC_GENERATE_SEED() (((zend_long) (time(0) * GetCurrentProcessId())) ^ ((zend_long) (1000000.0 * php_combined_lcg()))) -#else -# define COLOPL_BC_GENERATE_SEED() (((zend_long) (time(0) * getpid())) ^ ((zend_long) (1000000.0 * php_combined_lcg()))) -#endif - /* rand.c */ PHPAPI void php_colopl_bc_srand(zend_long seed); @@ -110,18 +75,6 @@ PHPAPI zend_long php_colopl_bc_rand(void); NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ - -#define PHP_COLOPL_BC_MT_RAND_MAX ((zend_long) (0x7FFFFFFF)) /* (1<<31) - 1 */ - -#define N (624) /* length of state vector */ -#define M (397) /* a period parameter */ -#define hiBit(u) ((u) & 0x80000000U) /* mask all but highest bit of u */ -#define loBit(u) ((u) & 0x00000001U) /* mask all but lowest bit of u */ -#define loBits(u) ((u) & 0x7FFFFFFFU) /* mask the highest bit of u */ -#define mixBits(u, v) (hiBit(u)|loBits(v)) /* move hi bit of u to hi bit of v */ - -#define twist(m,u,v) (m ^ (mixBits(u,v)>>1) ^ ((uint32_t)(-(uint32_t)(loBit(u))) & 0x9908b0dfU)) - PHPAPI void php_colopl_bc_mt_srand(uint32_t seed); PHPAPI uint32_t php_colopl_bc_mt_rand(void); diff --git a/ext/php_colopl_bc_php74.h b/ext/php_colopl_bc_php74.h index d3a48ab..19f50d2 100644 --- a/ext/php_colopl_bc_php74.h +++ b/ext/php_colopl_bc_php74.h @@ -3,15 +3,9 @@ | COLOPL PHP Backwards Compatibility Extension. | +----------------------------------------------------------------------+ | Copyright (c) COLOPL, Inc. | - | Copyright (c) The PHP Group | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | http://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the BSD-3-Clause license that is | + | bundled with this package in the file LICENSE. | +----------------------------------------------------------------------+ | Author: Go Kudo | +----------------------------------------------------------------------+ diff --git a/library.php b/library.php index 58e9db2..84c8475 100644 --- a/library.php +++ b/library.php @@ -1,7 +1,11 @@ = 80000 && !\extension_loaded('colopl_bc')) { + if (\PHP_VERSION_ID >= 80000 && \PHP_VERSION_ID < 80100) { + \user_error('colopl_bc supports PHP 7.4 or PHP 8.1 and later; PHP 8.0 is not supported', \E_USER_ERROR); + } + + if (\PHP_VERSION_ID >= 80100 && !\extension_loaded('colopl_bc')) { \user_error('colopl_bc extension is not loaded', \E_USER_ERROR); } } diff --git a/library_test.sh b/library_test.sh index e95cce5..66e03ca 100755 --- a/library_test.sh +++ b/library_test.sh @@ -4,7 +4,11 @@ export USE_ZEND_ALLOC=1 export USE_TRACKED_ALLOC=0 export ZEND_DONT_UNLOAD_MODULES=1 cd "/project" - if php -r 'exit((\PHP_VERSION_ID >= 80000) ? 0 : 1);'; then + if php -r 'exit((\PHP_VERSION_ID >= 80000 && \PHP_VERSION_ID < 80100) ? 0 : 1);'; then + echo 'colopl_bc does not support PHP 8.0' >&2 + exit 1 + fi + if php -r 'exit((\PHP_VERSION_ID >= 80100) ? 0 : 1);'; then cd "ext" phpize ./configure diff --git a/phpunit.xml b/phpunit.xml index 56284b9..4f66f6c 100644 --- a/phpunit.xml +++ b/phpunit.xml @@ -1,25 +1,24 @@ + colors="true" + cacheDirectory=".phpunit.cache" + beStrictAboutCoverageMetadata="true"> tests - + + + + library.php src - - - - + diff --git a/pskel.sh b/pskel.sh index 411098f..308e25e 100755 --- a/pskel.sh +++ b/pskel.sh @@ -19,6 +19,140 @@ get_ext_dir() { echo "${PSKEL_EXT_DIR}" } +get_in_tree_ext_dir() { + echo "/usr/src/php/ext/colopl_bc" +} + +sync_ext_into_php_source() { + SOURCE_DIR="${1}" + TARGET_DIR="$(get_in_tree_ext_dir)" + + rm -rf "${TARGET_DIR}" + mkdir -p "${TARGET_DIR}" + + rsync -a \ + --exclude ".git/" \ + --exclude "autom4te.cache/" \ + --exclude "build/" \ + --exclude "modules/" \ + --exclude "*.dep" \ + --exclude "*.la" \ + --exclude "*.lo" \ + --exclude "*.o" \ + --exclude "Makefile" \ + --exclude "Makefile.fragments" \ + --exclude "Makefile.global" \ + --exclude "Makefile.objects" \ + --exclude "config.h" \ + --exclude "config.h.in" \ + --exclude "config.nice" \ + --exclude "config.status" \ + --exclude "configure" \ + --exclude "configure.ac" \ + --exclude "libtool" \ + --exclude "run-tests.php" \ + --exclude "*~" \ + "${SOURCE_DIR}/" "${TARGET_DIR}/" + + echo "${TARGET_DIR}" +} + +generate_ext_source_hash() { + SOURCE_DIR="${1}" + + ( + cd "${SOURCE_DIR}" + find . \ + \( -path "./autom4te.cache" -o -path "./autom4te.cache/*" -o -path "./build" -o -path "./build/*" -o -path "./modules" -o -path "./modules/*" \) -prune -o \ + -type f \ + ! -name "*.dep" \ + ! -name "*.la" \ + ! -name "*.lo" \ + ! -name "*.o" \ + ! -name "Makefile" \ + ! -name "Makefile.fragments" \ + ! -name "Makefile.global" \ + ! -name "Makefile.objects" \ + ! -name "config.h" \ + ! -name "config.h.in" \ + ! -name "config.nice" \ + ! -name "config.status" \ + ! -name "configure" \ + ! -name "configure.ac" \ + ! -name "libtool" \ + ! -name "run-tests.php" \ + ! -name "*~" \ + -print \ + | LC_ALL=C sort \ + | while IFS= read -r FILE; do + sha256sum "${FILE}" + done \ + | sha256sum \ + | cut -d' ' -f1 \ + | cut -c1-16 + ) +} + +get_php_build_key_file() { + echo "/usr/local/include/${1}-php/.pskel-build-key" +} + +php_build_is_current() { + PREFIX="${1}" + BUILD_KEY="${2}" + BUILD_KEY_FILE="$(get_php_build_key_file "${PREFIX}")" + + if ! test -x "/usr/local/bin/${PREFIX}-php"; then + return 1 + fi + + if ! test -f "${BUILD_KEY_FILE}"; then + return 1 + fi + + test "$(cat "${BUILD_KEY_FILE}")" = "${BUILD_KEY}" +} + +mark_php_build() { + PREFIX="${1}" + BUILD_KEY="${2}" + INCLUDE_DIR="/usr/local/include/${PREFIX}-php" + + if ! test -d "${INCLUDE_DIR}"; then + mkdir -p "${INCLUDE_DIR}" + fi + + printf '%s\n' "${BUILD_KEY}" > "${INCLUDE_DIR}/.pskel-build-key" +} + +clear_php_build() { + PREFIX="${1}" + + rm -f "/usr/local/bin/${PREFIX}-php" "/usr/local/bin/${PREFIX}-phpize" "/usr/local/bin/${PREFIX}-php-config" + rm -rf "/usr/local/include/${PREFIX}-php" +} + +run_in_tree_static_tests() { + PHP_BIN="${1}" + TESTS_DIR="${2}" + + if ! "${PHP_BIN}" -m | grep -qx "colopl_bc"; then + echo "Error: colopl_bc is not built into ${PHP_BIN}" >&2 + return 1 + fi + + ( + if test -n "${TEST_PHP_ARGS}"; then + eval "set -- ${TEST_PHP_ARGS}" + else + set -- + fi + + set -- "$@" --show-diff -q -p "${PHP_BIN}" "${TESTS_DIR}" + "${PHP_BIN}" "/usr/src/php/run-tests.php" "$@" + ) +} + cmd_usage() { cat << EOF Usage: ${0} [task] ... @@ -66,13 +200,25 @@ cmd_test() { case "${1}" in -h|--help) cat << EOF -Usage: ${0} test [test_type|php_binary_name] +Usage: ${0} test [debug|debug-static|gcov|valgrind|msan|asan|ubsan|php_binary_name] Environment variables: CFLAGS, CPPFLAGS: Compilation flags TEST_PHP_ARGS: Test flags EOF return 0 ;; + debug-static) + CC="$(command -v "gcc")" + CXX="$(command -v "g++")" + PSKEL_EXT_DIR="$(get_ext_dir)" + sync_ext_into_php_source "${PSKEL_EXT_DIR}" >/dev/null + CACHE_KEY_SUFFIX="$(generate_ext_source_hash "${PSKEL_EXT_DIR}")" + CONFIGURE_OPTS="${CONFIGURE_OPTS} --enable-colopl_bc" + build_php_if_not_exists "debug-static" + CMD="$(basename "${CC}")-debug-static-php" + run_in_tree_static_tests "$(command -v "${CMD}")" "$(get_in_tree_ext_dir)/tests" + return 0 + ;; debug|gcov|valgrind) CC="$(command -v "gcc")" CXX="$(command -v "g++")" @@ -148,36 +294,41 @@ EOF build_php_if_not_exists() { PREFIX="$(basename "${CC}")-${1}" + BUILD_KEY="$(generate_cache_key "${1}" "${CC}")" + + if php_build_is_current "${PREFIX}" "${BUILD_KEY}"; then + return 0 + fi + + clear_php_build "${PREFIX}" if test -n "${GITHUB_ACTIONS}" && test -d "${PHP_CACHE_DIR}"; then - if check_and_restore_cached_php "${PREFIX}" "${1}" "${CC}" "${CONFIGURE_OPTS}"; then + if check_and_restore_cached_php "${PREFIX}" "${BUILD_KEY}"; then return 0 fi + + clear_php_build "${PREFIX}" fi - if ! command -v "${PREFIX}-php" >/dev/null 2>&1; then - CC="${CC}" \ - CXX="${CXX}" \ - CFLAGS="-DZEND_TRACK_ARENA_ALLOC" \ - CPPFLAGS="${CFLAGS}" \ - LDFLAGS="${LDFLAGS}" \ - CONFIGURE_OPTS="${CONFIGURE_OPTS} --enable-debug $(php -r "echo (bool)PHP_ZTS ? '--enable-zts' : '';") --enable-option-checking=fatal --disable-phpdbg --disable-cgi --disable-fpm --enable-cli --without-pcre-jit --disable-opcache-jit --disable-zend-max-execution-timers" \ - cmd_build "${PREFIX}" - - if test -n "${GITHUB_ACTIONS}" && test -d "${PHP_CACHE_DIR}"; then - cache_php_build "${PREFIX}" "${1}" "${CC}" - fi + CC="${CC}" \ + CXX="${CXX}" \ + CFLAGS="-DZEND_TRACK_ARENA_ALLOC" \ + CPPFLAGS="${CFLAGS}" \ + LDFLAGS="${LDFLAGS}" \ + CONFIGURE_OPTS="${CONFIGURE_OPTS} --enable-debug $(php -r "echo (bool)PHP_ZTS ? '--enable-zts' : '';") --enable-option-checking=fatal --disable-phpdbg --disable-cgi --disable-fpm --enable-cli --without-pcre-jit --disable-opcache-jit --disable-zend-max-execution-timers" \ + cmd_build "${PREFIX}" + + mark_php_build "${PREFIX}" "${BUILD_KEY}" + + if test -n "${GITHUB_ACTIONS}" && test -d "${PHP_CACHE_DIR}"; then + cache_php_build "${PREFIX}" "${BUILD_KEY}" fi } check_and_restore_cached_php() { PREFIX="${1}" - BUILD_TYPE="${2}" - COMPILER="${3}" - CONFIGURE_OPTS_LOCAL="${4}" - - CACHE_KEY="$(generate_cache_key "${BUILD_TYPE}" "${COMPILER}")" - CACHE_DIR="${PHP_CACHE_DIR}/${CACHE_KEY}" + BUILD_KEY="${2}" + CACHE_DIR="${PHP_CACHE_DIR}/${BUILD_KEY}" if test -f "${CACHE_DIR}/.build_complete"; then for BIN in php phpize php-config; do @@ -190,9 +341,11 @@ check_and_restore_cached_php() { ln -sf "${CACHE_DIR}/usr/local/include/${PREFIX}-php" "/usr/local/include/${PREFIX}-php" fi - echo "[Pskel > Cache] Restored PHP header and binary: ${PREFIX}-php" >&2 + if php_build_is_current "${PREFIX}" "${BUILD_KEY}"; then + echo "[Pskel > Cache] Restored PHP header and binary: ${PREFIX}-php" >&2 - return 0 + return 0 + fi fi return 1 @@ -214,16 +367,18 @@ generate_cache_key() { fi fi - echo "php-${PHP_VERSION}-${PHP_ZTS}-${BUILD_TYPE}-${COMPILER}-${IMAGE_HASH}" + EXTRA_KEY="" + if test -n "${CACHE_KEY_SUFFIX}"; then + EXTRA_KEY="-${CACHE_KEY_SUFFIX}" + fi + + echo "php-${PHP_VERSION}-${PHP_ZTS}-${BUILD_TYPE}-${COMPILER}-${IMAGE_HASH}${EXTRA_KEY}" } cache_php_build() { PREFIX="${1}" - BUILD_TYPE="${2}" - COMPILER="${3}" - - CACHE_KEY="$(generate_cache_key "${BUILD_TYPE}" "${COMPILER}")" - CACHE_DIR="${PHP_CACHE_DIR}/${CACHE_KEY}" + BUILD_KEY="${2}" + CACHE_DIR="${PHP_CACHE_DIR}/${BUILD_KEY}" mkdir -p "${CACHE_DIR}/usr/local/bin" diff --git a/tests/Extension/PHP70Test.php b/tests/Extension/PHP70Test.php index 5dd9d02..25b4ba4 100644 --- a/tests/Extension/PHP70Test.php +++ b/tests/Extension/PHP70Test.php @@ -111,7 +111,7 @@ public function testMtSRand(): void public function testMtSRandNull(): void { - /* PHP 8.1 does not support null -> 0 auto casting. */ + /* Keep the legacy null-to-zero cast explicit across supported runtimes. */ $seed = (int) \null; \Colopl\ColoplBc\Php70\mt_srand($seed); From b1b89c829ad53670e71e9b77bbda849aad6e0697 Mon Sep 17 00:00:00 2001 From: Go Kudo Date: Tue, 21 Apr 2026 02:13:33 +0000 Subject: [PATCH 2/2] backport pskel 4.x --- .devcontainer/devcontainer.json | 13 +- .devcontainer/local/devcontainer.json | 20 -- .dockerignore | 2 + .gitattributes | 32 +-- .github/workflows/ci_coverage.yaml | 37 +++ .github/workflows/ci_emulated_linux.yaml | 2 +- .gitmodules | 2 + .pskel/LICENSE.template | 26 +++ CHANGELOG.md | 2 +- Dockerfile | 51 +++-- README.md | 4 +- compose.yaml | 2 +- composer.json | 2 +- ext/.gitignore | 21 +- ext/php_colopl_bc.h | 2 +- pskel.sh | 280 +++++++++++++++++++++-- third_party/valgrind | 2 +- 17 files changed, 407 insertions(+), 93 deletions(-) delete mode 100644 .devcontainer/local/devcontainer.json create mode 100644 .pskel/LICENSE.template diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 654171b..00e26ae 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -1,5 +1,5 @@ { - "name": "colopl_bc: Pskel (for Codespaces)", + "name": "colopl_bc: Pskel", "customizations": { "vscode": { "extensions": [ @@ -7,10 +7,17 @@ "ms-vscode.cpptools-extension-pack", "maelvalais.autoconf", "ms-azuretools.vscode-docker", - "editorconfig.editorconfig" + "editorconfig.editorconfig", + "markis.code-coverage" ] } }, "dockerComposeFile": "./../compose.yaml", - "service": "shell" + "service": "shell", + "mounts": [ + "source=${localWorkspaceFolder},target=/workspace,type=bind,consistency=cached" + ], + "workspaceFolder": "/workspace", + "initializeCommand": "git submodule update --init --recursive", + "postCreateCommand": "ln -sf \"$(pwd)/pskel.sh\" /usr/local/bin/pskel" } diff --git a/.devcontainer/local/devcontainer.json b/.devcontainer/local/devcontainer.json deleted file mode 100644 index 0e35acf..0000000 --- a/.devcontainer/local/devcontainer.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "name": "colopl_bc: Pskel (for Local)", - "customizations": { - "vscode": { - "extensions": [ - "ms-vscode.cpptools", - "ms-vscode.cpptools-extension-pack", - "maelvalais.autoconf", - "ms-azuretools.vscode-docker", - "editorconfig.editorconfig" - ] - } - }, - "dockerComposeFile": "./../../compose.yaml", - "service": "shell", - "mounts": [ - "source=${localWorkspaceFolder},target=/workspaces/pskel,type=bind,consistency=cached" - ], - "workspaceFolder": "/workspaces/pskel" -} diff --git a/.dockerignore b/.dockerignore index 0ca9a5a..723dc5c 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1,2 +1,4 @@ **/.git +**/README.md +**/LICENSE **/.editorconfig diff --git a/.gitattributes b/.gitattributes index 43bc10e..e12ef0c 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,15 +1,21 @@ # Exclude non-essential files from git archive (used by PIE/Composer downloads) -/.github/ export-ignore -/build/ export-ignore -/patches/ export-ignore -/tests/ export-ignore -/third_party/ export-ignore -/ext/tests/ export-ignore +# Exclude devcontainer and editor metadata from git archive +/.devcontainer/ export-ignore +/.dockerignore export-ignore +/.editorconfig export-ignore +/.github/ export-ignore +/.gitmodules export-ignore +/.vscode/ export-ignore +/build/ export-ignore +/patches/ export-ignore +/tests/ export-ignore +/third_party/ export-ignore +/ext/tests/ export-ignore /ext/description-pak export-ignore -Dockerfile export-ignore -compose.yaml export-ignore -library_test.sh export-ignore -phpstan.neon export-ignore -phpunit.xml export-ignore -pskel.sh export-ignore -CHANGELOG.md export-ignore +Dockerfile export-ignore +compose.yaml export-ignore +library_test.sh export-ignore +phpstan.neon export-ignore +phpunit.xml export-ignore +pskel.sh export-ignore +CHANGELOG.md export-ignore diff --git a/.github/workflows/ci_coverage.yaml b/.github/workflows/ci_coverage.yaml index 466259a..1817e7d 100644 --- a/.github/workflows/ci_coverage.yaml +++ b/.github/workflows/ci_coverage.yaml @@ -93,6 +93,16 @@ jobs: touch "lcov.info" docker compose run -v "$(pwd)/lcov.info:/ext/lcov.info" --rm shell pskel coverage mv "lcov.info" "${{ matrix.platform }}_${{ matrix.versions }}_${{ matrix.ts }}_lcov.info" + - name: Verify shard function coverage records + run: | + COVERAGE_FILE="${{ matrix.platform }}_${{ matrix.versions }}_${{ matrix.ts }}_lcov.info" + for RECORD in "FN:" "FNDA:" "FNF:" "FNH:"; do + if ! grep -q "^${RECORD}" "${COVERAGE_FILE}"; then + echo "Missing ${RECORD} records in ${COVERAGE_FILE}" + exit 1 + fi + done + lcov --summary "${COVERAGE_FILE}" - name: Upload coverage artifact uses: actions/upload-artifact@v7 with: @@ -137,6 +147,24 @@ jobs: with: name: initialized-ext-coverage path: ext/ + - name: Verify downloaded function coverage records + run: | + cd "coverage-files" || exit 1 + set -- ./*.info + if test "${1}" = "./*.info"; then + echo "No coverage .info files found" + exit 1 + fi + for INFO_FILE in "$@"; do + for RECORD in "FN:" "FNDA:" "FNF:" "FNH:"; do + if ! grep -q "^${RECORD}" "${INFO_FILE}"; then + echo "Missing ${RECORD} records in ${INFO_FILE} before merge" + exit 1 + fi + done + lcov --summary "${INFO_FILE}" + done + cd - || exit 1 - name: Generate integrated HTML coverage reports run: | if ! test -d "/ext"; then @@ -165,6 +193,15 @@ jobs: genhtml "total.info" \ --output-directory "coverage-html" \ --title "Extension code coverage" + - name: Verify merged function coverage records + run: | + for RECORD in "FN:" "FNDA:" "FNF:" "FNH:"; do + if ! grep -q "^${RECORD}" "total.info"; then + echo "Missing ${RECORD} records in total.info after merge" + exit 1 + fi + done + lcov --summary "total.info" - name: Setup Pages uses: actions/configure-pages@v6 - name: Upload Pages artifact diff --git a/.github/workflows/ci_emulated_linux.yaml b/.github/workflows/ci_emulated_linux.yaml index 979b21d..a0fe59d 100644 --- a/.github/workflows/ci_emulated_linux.yaml +++ b/.github/workflows/ci_emulated_linux.yaml @@ -60,7 +60,7 @@ jobs: - name: Generate image tag id: image-tag run: | - TAG="ghcr.io/${{ github.repository }}/ci-emulated-cache:${{ steps.cut-arch.outputs.arch }}-${{ matrix.version }}-${{ matrix.type }}-${{ matrix.distro }}-${{ hashFiles('**/Dockerfile', '**/compose.yaml', '**/pskel.sh') }}" + TAG="ghcr.io/${{ github.repository }}/ci-emulated-cache:${{ steps.cut-arch.outputs.arch }}-${{ matrix.version }}-${{ matrix.type }}-${{ matrix.distro }}-${{ hashFiles('**/Dockerfile', '**/compose.yaml', '**/pskel.sh', '.pskel/**') }}" echo "tag=${TAG}" >> $GITHUB_OUTPUT - name: Check if image exists id: check-image diff --git a/.gitmodules b/.gitmodules index 1c917d9..e34b3b3 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,5 @@ [submodule "third_party/valgrind"] path = third_party/valgrind url = https://sourceware.org/git/valgrind.git + branch = VALGRIND_3_27_0 + diff --git a/.pskel/LICENSE.template b/.pskel/LICENSE.template new file mode 100644 index 0000000..b043d7a --- /dev/null +++ b/.pskel/LICENSE.template @@ -0,0 +1,26 @@ +Copyright (c) %YEAR% %VENDOR% + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +3. Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/CHANGELOG.md b/CHANGELOG.md index 24a2a5a..ca5d1af 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,4 @@ -# 12.0.0 +# 12.1.0 - Change the project license from PHP-3.01 to BSD-3-Clause - Tighten package support to PHP 7.4 or PHP 8.1+ - Refactor internals toward PHP 8.1+ APIs diff --git a/Dockerfile b/Dockerfile index 9fe1358..160cec3 100644 --- a/Dockerfile +++ b/Dockerfile @@ -15,34 +15,33 @@ ENV LC_ALL="C" RUN docker-php-source extract \ && if test -f "/etc/debian_version"; then \ - apt-get update \ - && DEBIAN_FRONTEND="noninteractive" apt-get install -y "bison" "re2c" "zlib1g-dev" "libsqlite3-dev" "libxml2-dev" \ + apt-get update && \ + DEBIAN_FRONTEND="noninteractive" apt-get install -y "bison" "re2c" "zlib1g-dev" "libsqlite3-dev" "libxml2-dev" \ "autoconf" "pkg-config" "make" "gcc" "rsync" "git" "ssh" "libc6-dbg" \ - "ca-certificates" "tzdata" "lsb-release" "curl" \ + "ca-certificates" "tzdata" "curl" "gnupg" \ "lcov" "gzip" \ "vim" \ "unzip" && \ if test "${ENABLE_CLANG}" = "1"; then \ - # fixme: re-enable keyring usage when SHA256 key is available - # apt-get --no-install-recommends -y "gnupg" && \ - # curl -sSL "https://apt.llvm.org/llvm-snapshot.gpg.key" | gpg --dearmor > "/usr/share/keyrings/llvm-archive-keyring.gpg" && \ - echo "deb [trusted=yes] http://apt.llvm.org/$(lsb_release -cs)/ llvm-toolchain-$(lsb_release -cs) main" > "/etc/apt/sources.list.d/llvm.list" && \ - echo "deb [trusted=yes] http://apt.llvm.org/$(lsb_release -cs)/ llvm-toolchain-$(lsb_release -cs)-21 main" >> "/etc/apt/sources.list.d/llvm.list" && \ + LLVM_APT_CODENAME="$(. "/etc/os-release" && printf '%s' "${VERSION_CODENAME}")" && \ + test -n "${LLVM_APT_CODENAME}" && \ + mkdir -p "/usr/share/keyrings" && \ + curl -fsSL "https://apt.llvm.org/llvm-snapshot.gpg.key" | gpg --dearmor --yes -o "/usr/share/keyrings/llvm-snapshot.gpg" && \ + echo "deb [signed-by=/usr/share/keyrings/llvm-snapshot.gpg] https://apt.llvm.org/${LLVM_APT_CODENAME}/ llvm-toolchain-${LLVM_APT_CODENAME}-22 main" > "/etc/apt/sources.list.d/llvm.list" && \ apt-get update && \ DEBIAN_FRONTEND="noninteractive" apt-get install --no-install-recommends -y \ - "clang-21" "clang-tools-21" "clang-format-21" "clang-tidy-21" \ - "libclang-rt-21-dev" "lld-21" "lldb-21" \ - "libc++-21-dev" "libc++abi-21-dev" \ - "llvm-21" "llvm-21-dev" "llvm-21-runtime" \ - "clang-format-21" && \ - update-alternatives --install "/usr/bin/clang" clang "/usr/bin/clang-21" 100 && \ - update-alternatives --install "/usr/bin/clang++" clang++ "/usr/bin/clang++-21" 100 && \ - update-alternatives --install "/usr/bin/clang-format" clang-format "/usr/bin/clang-format-21" 100 && \ - update-alternatives --install "/usr/bin/clang-tidy" clang-tidy "/usr/bin/clang-tidy-21" 100 && \ - update-alternatives --install "/usr/bin/lldb" lldb "/usr/bin/lldb-21" 100 && \ - update-alternatives --install "/usr/bin/ld.lld" ld.lld "/usr/bin/ld.lld-21" 100 && \ - update-alternatives --install "/usr/bin/llvm-symbolizer" llvm-symbolizer "/usr/bin/llvm-symbolizer-21" 100 && \ - update-alternatives --install "/usr/bin/llvm-config" llvm-config "/usr/bin/llvm-config-21" 100; \ + "clang-22" "clang-tools-22" "clang-format-22" "clang-tidy-22" \ + "libclang-rt-22-dev" "lld-22" "lldb-22" \ + "libc++-22-dev" "libc++abi-22-dev" \ + "llvm-22" "llvm-22-dev" "llvm-22-runtime" && \ + update-alternatives --install "/usr/bin/clang" clang "/usr/bin/clang-22" 100 && \ + update-alternatives --install "/usr/bin/clang++" clang++ "/usr/bin/clang++-22" 100 && \ + update-alternatives --install "/usr/bin/clang-format" clang-format "/usr/bin/clang-format-22" 100 && \ + update-alternatives --install "/usr/bin/clang-tidy" clang-tidy "/usr/bin/clang-tidy-22" 100 && \ + update-alternatives --install "/usr/bin/lldb" lldb "/usr/bin/lldb-22" 100 && \ + update-alternatives --install "/usr/bin/ld.lld" ld.lld "/usr/bin/ld.lld-22" 100 && \ + update-alternatives --install "/usr/bin/llvm-symbolizer" llvm-symbolizer "/usr/bin/llvm-symbolizer-22" 100 && \ + update-alternatives --install "/usr/bin/llvm-config" llvm-config "/usr/bin/llvm-config-22" 100; \ fi; \ else \ apk add --no-cache "bison" "zlib-dev" "sqlite-dev" "libxml2-dev" "linux-headers" \ @@ -57,6 +56,10 @@ COPY ./third_party/valgrind "/third_party/valgrind" ARG SKIP_VALGRIND RUN if test "${SKIP_VALGRIND}" != "1" && test -f "/etc/debian_version"; then \ cd "/third_party/valgrind" && \ + test -x "./autogen.sh" || { \ + echo "Valgrind submodule is missing. Run 'git submodule update --init --recursive' before building the container." >&2; \ + exit 1; \ + } && \ if test -f "/etc/debian_version"; then \ apt-get update && \ DEBIAN_FRONTEND="noninteractive" apt-get install -y \ @@ -73,11 +76,13 @@ RUN if test "${SKIP_VALGRIND}" != "1" && test -f "/etc/debian_version"; then \ cd -; \ fi -COPY ./pskel.sh "/usr/local/bin/pskel" +COPY ./.pskel "/opt/pskel/.pskel" +COPY ./pskel.sh "/opt/pskel/pskel.sh" COPY ./patches "/patches" COPY ./ext "/ext" -RUN chmod +x "/usr/local/bin/pskel" +RUN chmod +x "/opt/pskel/pskel.sh" \ + && ln -sf "/opt/pskel/pskel.sh" "/usr/local/bin/pskel" RUN cat <<'EOF' > "/usr/local/bin/docker-entrypoint.sh" #!/bin/sh diff --git a/README.md b/README.md index 3d81557..2369435 100644 --- a/README.md +++ b/README.md @@ -47,7 +47,7 @@ Build packages for the official Ubuntu 22.04 PHP 8.1 stack: ```bash $ docker build -f "build/ubuntu2204/Dockerfile" -t "colopl-bc-u2204-php81" . $ mkdir -p "artifacts" -$ docker run --rm -e VERSION="12.0.0" -v "$(pwd)/artifacts:/tmp/artifacts" "colopl-bc-u2204-php81" +$ docker run --rm -e VERSION="x.y.z" -v "$(pwd)/artifacts:/tmp/artifacts" "colopl-bc-u2204-php81" ``` This target produces `php-colopl-bc` and `php8.1-colopl-bc` binary packages together with the corresponding `.changes` and `.buildinfo` files. @@ -57,7 +57,7 @@ Build packages for Ubuntu 22.04 with the Ondrej Sury PHP 8.4 repository: ```bash $ docker build -f "build/ubuntu2204_sury84/Dockerfile" -t "colopl-bc-u2204-php84" . $ mkdir -p "artifacts" -$ docker run --rm -e VERSION="12.0.0" -v "$(pwd)/artifacts:/tmp/artifacts" "colopl-bc-u2204-php84" +$ docker run --rm -e VERSION="x.y.z" -v "$(pwd)/artifacts:/tmp/artifacts" "colopl-bc-u2204-php84" ``` This target produces the `php8.4-colopl-bc` binary package together with the corresponding `.changes` and `.buildinfo` files. diff --git a/compose.yaml b/compose.yaml index d1569f4..4cf6c89 100644 --- a/compose.yaml +++ b/compose.yaml @@ -3,7 +3,7 @@ services: image: ${SHELL_IMAGE:-shell} # environment: # - CONFIGURE_OPTS=--enable-pdo --enable-mysqlnd --with-pdo-mysql - # - LCOV_OPTS=--ignore-errors unused --exclude=/ext/third_party/* --ignore-errors unused --exclude=/workspaces/pskel/ext/third_party/* + # - LCOV_OPTS=--ignore-errors unused --exclude=/ext/third_party/* build: context: ./ dockerfile: ./Dockerfile diff --git a/composer.json b/composer.json index 667e878..b7dcde9 100644 --- a/composer.json +++ b/composer.json @@ -28,7 +28,7 @@ "php-ext": { "extension-name": "colopl_bc", "build-path": "ext", - "download-url-method": ["pre-packaged-binary", "composer-default"], + "download-url-method": ["pre-packaged-binary", "pre-packaged-source", "composer-default"], "configure-options": [ { "name": "enable-colopl_bc", diff --git a/ext/.gitignore b/ext/.gitignore index 6f644f8..dc89e86 100644 --- a/ext/.gitignore +++ b/ext/.gitignore @@ -6,15 +6,19 @@ acinclude.m4 aclocal.m4 autom4te.cache build +config.cache config.guess config.h config.h.in config.h.in~ config.log config.nice +config.nice.bat config.status config.sub configure +configure.bat +configure.js configure~ configure.ac configure.in @@ -29,11 +33,16 @@ Makefile.objects missing mkinstalldirs modules +php_test_results_*.txt +phpt.* +run-test-info.php run-tests.php -tests/*/*.diff -tests/*/*.out -tests/*/*.php -tests/*/*.exp -tests/*/*.log -tests/*/*.sh +tests/**/*.diff +tests/**/*.out +tests/**/*.php +tests/**/*.exp +tests/**/*.log +tests/**/*.sh +tests/**/*.db +tests/**/*.mem tmp-php.ini diff --git a/ext/php_colopl_bc.h b/ext/php_colopl_bc.h index 6e56de4..dd3733f 100644 --- a/ext/php_colopl_bc.h +++ b/ext/php_colopl_bc.h @@ -36,7 +36,7 @@ extern zend_module_entry colopl_bc_module_entry; #define COLOPL_BC_PHP74_SORT_MODE_DEPRECATED 1 #define COLOPL_BC_PHP74_SORT_MODE_LOG 2 -#define PHP_COLOPL_BC_VERSION "12.0.1" +#define PHP_COLOPL_BC_VERSION "12.1.0" enum { COLOPL_BC_MT_N = 624, diff --git a/pskel.sh b/pskel.sh index 308e25e..bf5fbe0 100755 --- a/pskel.sh +++ b/pskel.sh @@ -2,18 +2,171 @@ set -e +get_pskel_root_dir() { + PSKEL_PATH="${0}" + + case "${PSKEL_PATH}" in + */*) + ;; + *) + PSKEL_PATH="$(command -v "${PSKEL_PATH}")" + ;; + esac + + if command -v readlink >/dev/null 2>&1; then + PSKEL_PATH="$(readlink -f "${PSKEL_PATH}" 2>/dev/null || printf '%s' "${PSKEL_PATH}")" + fi + + CDPATH='' cd -- "$(dirname -- "${PSKEL_PATH}")" && pwd +} + +find_workspace_dir_from_pwd() { + SEARCH_DIR="${PWD}" + + while test -n "${SEARCH_DIR}"; do + if test -f "${SEARCH_DIR}/pskel.sh" && test -f "${SEARCH_DIR}/.pskel/LICENSE.template"; then + echo "${SEARCH_DIR}" + return 0 + fi + + if test "${SEARCH_DIR}" = "/"; then + break + fi + + SEARCH_DIR="$(dirname -- "${SEARCH_DIR}")" + done + + return 1 +} + +get_workspace_dir() { + if test -n "${PSKEL_WORKSPACE_DIR}" && test -d "${PSKEL_WORKSPACE_DIR}"; then + echo "${PSKEL_WORKSPACE_DIR}" + elif PWD_WORKSPACE_DIR="$(find_workspace_dir_from_pwd 2>/dev/null)" && test -n "${PWD_WORKSPACE_DIR}"; then + echo "${PWD_WORKSPACE_DIR}" + elif test -d "${CODESPACE_VSCODE_FOLDER}"; then + echo "${CODESPACE_VSCODE_FOLDER}" + elif test -d "/workspace"; then + echo "/workspace" + elif test -d "/workspaces/pskel"; then + echo "/workspaces/pskel" + else + PSKEL_ROOT_DIR="$(get_pskel_root_dir)" || return 1 + if test -f "${PSKEL_ROOT_DIR}/pskel.sh"; then + echo "${PSKEL_ROOT_DIR}" + else + echo "Error: Workspace root not found." >&2 + return 1 + fi + fi +} + + +get_project_license_template_path() { + PSKEL_ROOT_DIR="$(get_pskel_root_dir)" || return 1 + LICENSE_TEMPLATE_PATH="${PSKEL_ROOT_DIR}/.pskel/LICENSE.template" + + if test -f "${LICENSE_TEMPLATE_PATH}"; then + echo "${LICENSE_TEMPLATE_PATH}" + else + echo "Error: LICENSE template not found." >&2 + return 1 + fi +} + +escape_sed_replacement() { + printf '%s' "${1}" | sed -e 's/[\\/&]/\\&/g' +} + +slugify_vendor_name() { + printf '%s' "${1}" \ + | tr '[:upper:]' '[:lower:]' \ + | sed \ + -e 's/[^a-z0-9._-]/-/g' \ + -e 's/-\{2,\}/-/g' \ + -e 's/^[._-]*//' \ + -e 's/[._-]*$//' +} + +create_project_license() { + LICENSE_TEMPLATE_PATH="$(get_project_license_template_path)" || return 1 + WORKSPACE_DIR="$(get_workspace_dir)" || return 1 + LICENSE_YEAR="$(date -u "+%Y")" + LICENSE_YEAR_ESCAPED="$(escape_sed_replacement "${LICENSE_YEAR}")" + EXT_VENDOR_DISPLAY_ESCAPED="$(escape_sed_replacement "${EXT_VENDOR_DISPLAY}")" + + sed \ + -e "s/%YEAR%/${LICENSE_YEAR_ESCAPED}/g" \ + -e "s/%VENDOR%/${EXT_VENDOR_DISPLAY_ESCAPED}/g" \ + "${LICENSE_TEMPLATE_PATH}" > "${WORKSPACE_DIR}/LICENSE" +} + +create_project_composer_manifest() { + WORKSPACE_DIR="$(get_workspace_dir)" || return 1 + EXT_COMPOSER_PATH="${PSKEL_TMP_DIR}/${EXT_NAME}/composer.json" + + if ! test -f "${EXT_COMPOSER_PATH}"; then + echo "Error: composer.json template not found." >&2 + return 1 + fi + + EXT_COMPOSER_PATH="${EXT_COMPOSER_PATH}" \ + PROJECT_COMPOSER_PATH="${WORKSPACE_DIR}/composer.json" \ + EXT_NAME="${EXT_NAME}" \ + /usr/local/bin/php -r ' + $sourcePath = getenv("EXT_COMPOSER_PATH"); + $targetPath = getenv("PROJECT_COMPOSER_PATH"); + $extensionName = getenv("EXT_NAME"); + + $manifest = json_decode((string) file_get_contents($sourcePath), true); + if (!is_array($manifest)) { + fwrite(STDERR, "Error: Failed to parse composer.json template.\n"); + exit(1); + } + + if (!isset($manifest["php-ext"]) || !is_array($manifest["php-ext"])) { + $manifest["php-ext"] = []; + } + + $manifest["php-ext"]["extension-name"] = $extensionName; + $manifest["php-ext"]["build-path"] = "ext"; + $manifest["php-ext"]["download-url-method"] = [ + "pre-packaged-binary", + "pre-packaged-source", + "composer-default", + ]; + + $encoded = json_encode($manifest, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES); + if (!is_string($encoded)) { + fwrite(STDERR, "Error: Failed to encode project composer.json.\n"); + exit(1); + } + + file_put_contents($targetPath, $encoded . PHP_EOL); + ' || return 1 + + rm -f "${EXT_COMPOSER_PATH}" +} + get_ext_dir() { - PSKEL_EXT_DIR="/ext" - - if test -d "${CODESPACE_VSCODE_FOLDER}"; then - echo "[Pskel] GitHub Codespace workspace detected, using \"${CODESPACE_VSCODE_FOLDER}/ext\"." >&2 - PSKEL_EXT_DIR="${CODESPACE_VSCODE_FOLDER}/ext" - elif test -d "/workspaces/pskel/ext"; then - echo "[Pskel] Development Containers workspace detected, using \"/workspaces/pskel/ext\"." >&2 - PSKEL_EXT_DIR="/workspaces/pskel/ext" + WORKSPACE_DIR="$(get_workspace_dir 2>/dev/null || true)" + + if test -n "${WORKSPACE_DIR}" && test -d "${WORKSPACE_DIR}/ext"; then + if test -f "${WORKSPACE_DIR}/ext/.gitkeep" && test "$(cat "${WORKSPACE_DIR}/ext/.gitkeep")" = "pskel_uninitialized" && test "${1}" != "--no-init"; then + echo "[Pskel] Uninitialized project detected, initializing default skeleton." >&2 + cmd_init "skeleton" >&2 + fi + echo "[Pskel] Workspace extension directory detected, using \"${WORKSPACE_DIR}/ext\"." >&2 + PSKEL_EXT_DIR="${WORKSPACE_DIR}/ext" elif test -f "/ext/.gitkeep" && test "$(cat "/ext/.gitkeep")" = "pskel_uninitialized" && test "${1}" != "--no-init"; then echo "[Pskel] Uninitialized project detected, initializing default skeleton." >&2 cmd_init "skeleton" >&2 + PSKEL_EXT_DIR="/ext" + elif test -d "/ext"; then + PSKEL_EXT_DIR="/ext" + else + echo "Error: Extension directory not found." >&2 + return 1 fi echo "${PSKEL_EXT_DIR}" @@ -169,7 +322,7 @@ cmd_init() { case "${1}" in -h|--help) cat << EOF -Usage: ${0} init [extension_name] [ext_skel.php options...] +Usage: ${0} init [vendor_name] [ext_skel.php options...] EOF return 0 ;; @@ -179,20 +332,72 @@ EOF ;; esac - mkdir -p "/tmp/pskel_extension_tmp" - if test "$(/usr/local/bin/php -r 'echo PHP_VERSION_ID;')" -lt "80500"; then - /usr/local/bin/php "/usr/src/php/ext/ext_skel.php" --ext "${1}" --dir "/tmp/pskel_extension_tmp" "${@}" + EXT_NAME="${1}" + shift + + if test -n "${1}" && test "${1}" = "${1#-}"; then + EXT_VENDOR_DISPLAY="${1}" + shift else - if test -z "${2}"; then - EXT_VENDOR="pskel" - else - EXT_VENDOR="${2}" + EXT_VENDOR_DISPLAY="pskel" + fi + + PSKEL_TMP_DIR="$(mktemp -d "${TMPDIR:-/tmp}/pskel_extension_tmp.XXXXXX")" + cleanup_pskel_tmp_dir() { + if test -n "${PSKEL_TMP_DIR}" && test -d "${PSKEL_TMP_DIR}"; then + rm -rf "${PSKEL_TMP_DIR}" fi - /usr/local/bin/php "/usr/src/php/ext/ext_skel.php" --vendor "${EXT_VENDOR}" --ext "${1}" --dir "/tmp/pskel_extension_tmp" "${@}" + } + trap cleanup_pskel_tmp_dir EXIT HUP INT TERM + + EXT_VENDOR="$(slugify_vendor_name "${EXT_VENDOR_DISPLAY}")" + + case "${EXT_NAME}" in + *[!-a-z0-9_.]*) + echo "Error: Extension name must only contain lowercase letters, numbers, hyphens, underscores, and dots." >&2 + return 1 + ;; + esac + + if test -z "${EXT_VENDOR}"; then + echo "Error: Vendor name must contain at least one ASCII letter or number." >&2 + return 1 fi + + if test "$(/usr/local/bin/php -r 'echo PHP_VERSION_ID;')" -lt "80500"; then + /usr/local/bin/php "/usr/src/php/ext/ext_skel.php" --ext "${EXT_NAME}" --dir "${PSKEL_TMP_DIR}" "${@}" + cat > "${PSKEL_TMP_DIR}/${EXT_NAME}/composer.json" << COMPOSER_EOF +{ + "name": "${EXT_VENDOR}/${EXT_NAME}", + "type": "php-ext", + "license": "BSD-3-Clause", + "description": "Describe your extension here", + "require": { + "php": "~8.1.0" + }, + "php-ext": { + "extension-name": "${EXT_NAME}", + "configure-options": [ + { + "name": "enable-${EXT_NAME}", + "needs-value": false, + "description": "whether to enable ${EXT_NAME} support" + } + ] + } +} +COMPOSER_EOF + else + /usr/local/bin/php "/usr/src/php/ext/ext_skel.php" --vendor "${EXT_VENDOR}" --ext "${EXT_NAME}" --dir "${PSKEL_TMP_DIR}" "${@}" + fi + + create_project_composer_manifest + create_project_license + PSKEL_EXT_DIR="$(get_ext_dir --no-init)" - rm -rf "/tmp/pskel_extension_tmp/${1}/.gitkeep" - rsync -av "/tmp/pskel_extension_tmp/${1}/" "${PSKEL_EXT_DIR}/" + rm -f "${PSKEL_EXT_DIR}/composer.json" + rm -rf "${PSKEL_TMP_DIR}/${EXT_NAME}/.gitkeep" + cp -a "${PSKEL_TMP_DIR}/${EXT_NAME}/." "${PSKEL_EXT_DIR}/" rm -rf "${PSKEL_EXT_DIR}/.gitkeep" } @@ -357,6 +562,7 @@ generate_cache_key() { PHP_VERSION="$(php -r 'echo PHP_VERSION;')" PHP_ZTS="$(php -r 'echo (bool)PHP_ZTS ? "zts" : "nts";')" + ARCH="$(uname -m)" if test -n "${CONTAINER_IMAGE_HASH}"; then IMAGE_HASH="${CONTAINER_IMAGE_HASH}" @@ -372,7 +578,7 @@ generate_cache_key() { EXTRA_KEY="-${CACHE_KEY_SUFFIX}" fi - echo "php-${PHP_VERSION}-${PHP_ZTS}-${BUILD_TYPE}-${COMPILER}-${IMAGE_HASH}${EXTRA_KEY}" + echo "php-${PHP_VERSION}-${PHP_ZTS}-${BUILD_TYPE}-${COMPILER}-${ARCH}-${IMAGE_HASH}${EXTRA_KEY}" } cache_php_build() { @@ -443,6 +649,40 @@ EOF ${LCOV_OPTS} \ --exclude "/usr/local/include/*" \ --output-file "${PSKEL_EXT_DIR}/lcov.info" + + # Convert lcov 2.0 FNL/FNA records to legacy FN/FNDA for CI compatibility. + awk 'BEGIN { _n = 0 } + /^FNL:/ { + split($0, a, /[,:]/) + _start[a[2]] = a[3] + next + } + /^FNA:/ { + idx = "" + cnt = "" + rest = $0 + sub(/^FNA:/, "", rest) + split(rest, b, /,/) + idx = b[1] + cnt = b[2] + sub(/^[^,]*,[^,]*,/, "", rest) + _fn[_n] = "FN:" _start[idx] "," rest + _fnda[_n] = "FNDA:" cnt "," rest + _n++ + next + } + /^FNF:/ { + for (i = 0; i < _n; i++) print _fn[i] + for (i = 0; i < _n; i++) print _fnda[i] + _n = 0 + print + next + } + { print } + ' "${PSKEL_EXT_DIR}/lcov.info" > "${PSKEL_EXT_DIR}/lcov.info.tmp" \ + && cat "${PSKEL_EXT_DIR}/lcov.info.tmp" > "${PSKEL_EXT_DIR}/lcov.info" \ + && rm -f "${PSKEL_EXT_DIR}/lcov.info.tmp" + lcov --list "${PSKEL_EXT_DIR}/lcov.info" } diff --git a/third_party/valgrind b/third_party/valgrind index c15bcfe..b80fd12 160000 --- a/third_party/valgrind +++ b/third_party/valgrind @@ -1 +1 @@ -Subproject commit c15bcfe15bd785a528725eebb7d985fcb8a86bed +Subproject commit b80fd124192df64c168b4bbd8ef68a3c0abbba28