diff --git a/.github/workflows/docker-image.yml b/.github/workflows/docker-image.yml index 715c42029..740860e90 100644 --- a/.github/workflows/docker-image.yml +++ b/.github/workflows/docker-image.yml @@ -6,14 +6,22 @@ on: php: description: "PHP Version" required: true - zts: - description: "ZTS (Zend Thread Safety)" + default: '8.4' + threading: + type: string + description: "nts or zts" required: true + default: "nts" ubuntu_version: type: string description: 'Ubuntu Version' required: false default: '24.04' + debug: + type: string + description: "PHP Debug -> Options [yes, no]" + default: "no" + required: false workflow_call: inputs: php: @@ -24,13 +32,13 @@ on: type: string description: "PHP Debug -> Options [yes, no]" required: false - zts: + threading: type: string - description: "ZTS (Zend Thread Safety) -> Options [yes, no]" + description: "nts or zts" required: true ubuntu_version: type: string - description: "Ubuntu Version -> Options [20.04, 22.04, 24.04]" + description: "Ubuntu Version -> Options [22.04, 24.04]" required: false default: "24.04" secrets: @@ -41,7 +49,7 @@ on: jobs: build-docker-image: - runs-on: ubuntu-latest + runs-on: ubuntu-24.04 steps: - uses: actions/checkout@v4 with: @@ -56,19 +64,27 @@ jobs: with: username: ${{ secrets.DOCKER_USERNAME }} password: ${{ secrets.DOCKER_PASSWORD }} - - name: Extract PHP Version and ZTS - id: version - run: | - export PHP_VERSION="$(echo ${{ inputs.php }} | grep -oP '^\d+\.\d+')" - PHP_ENDING="php-$PHP_VERSION" - - [[ ${{ inputs.zts }} == "yes" ]] && PHP_ENDING="$PHP_ENDING-zts" - [[ ${{ inputs.debug }} == "yes" ]] && PHP_ENDING="$PHP_ENDING-debug" - - echo "php_ending=$PHP_ENDING" >> $GITHUB_ENV - - name: Build and push API - id: docker_build + if: ${{ inputs.debug != 'yes' }} + uses: docker/build-push-action@v5 + with: + file: ./docker/Dockerfile + context: . + push: true + pull: true + platforms: linux/amd64 + target: final + tags: "malusevd99/scylladb-php-driver:ubuntu-${{ inputs.ubuntu_version }}-${{ inputs.php }}-${{ inputs.threading }}" + cache-from: type=gha + cache-to: type=gha,mode=max + build-args: | + UBUNTU_VERSION=${{ inputs.ubuntu_version }} + PHP_VERSION=${{ inputs.php }} + PHP_THREAD_MODEL=${{ inputs.threading }} + PHP_DEBUG=no + PHP_MEM_SANITIZERS=no + - name: Build and push API + if: ${{ inputs.debug == 'yes' }} uses: docker/build-push-action@v5 with: file: ./docker/Dockerfile @@ -77,12 +93,12 @@ jobs: pull: true platforms: linux/amd64 target: final - tags: malusevd99/scylladb-php-driver:ubuntu-${{ inputs.ubuntu_version }}-${{ steps.version.outputs.php_ending }} + tags: "malusevd99/scylladb-php-driver:ubuntu-${{ inputs.ubuntu_version }}-${{ inputs.php }}-${{ inputs.threading }}-debug" cache-from: type=gha cache-to: type=gha,mode=max build-args: | UBUNTU_VERSION=${{ inputs.ubuntu_version }} PHP_VERSION=${{ inputs.php }} - PHP_ZTS=${{ inputs.zts }} - PHP_DEBUG=${{ inputs.debug }} - PHP_MEM_SANITIZERS=${{ inputs.debug }} + PHP_THREAD_MODEL=${{ inputs.threading }} + PHP_DEBUG=yes + PHP_MEM_SANITIZERS=yes diff --git a/.github/workflows/dockerhub-description.yml b/.github/workflows/dockerhub-description.yml new file mode 100644 index 000000000..a35a5842d --- /dev/null +++ b/.github/workflows/dockerhub-description.yml @@ -0,0 +1,22 @@ +name: Update Docker Hub Description +on: + push: + branches: + - v1.3.x + paths: + - README.md + - .github/workflows/dockerhub-description.yml +jobs: + description: + runs-on: ubuntu-24.04 + steps: + - uses: actions/checkout@v4 + + - name: Docker Hub Description + uses: peter-evans/dockerhub-description@v4 + with: + username: ${{ secrets.DOCKER_USERNAME }} + password: ${{ secrets.DOCKER_PASSWORD }} + repository: malusevd99/scylladb-php-driver + short-description: ${{ github.event.repository.description }} + enable-url-completion: true diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 24a7b0193..e13a2fdb7 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -10,7 +10,7 @@ on: jobs: tag: - runs-on: ubuntu-latest + runs-on: ubuntu-24.04 outputs: version: ${{ steps.tag.outputs.tag }} prerelease: ${{ (!!steps.prerelease.outputs.is_prerelease) || false }} @@ -30,13 +30,13 @@ jobs: id: prerelease build: - runs-on: ubuntu-latest + runs-on: ubuntu-24.04 needs: ['tag'] strategy: matrix: php: ['8.1', '8.1-zts', '8.2', '8.2-zts', '8.3', '8.3-zts'] - os: ['ubuntu-20.04', 'ubuntu-24.04'] - preset: ['CICassandra', 'CIScylla'] + os: ['ubuntu-22.04', 'ubuntu-24.04'] + driver: ['scylladb', 'cassandra'] fail-fast: true container: malusevd99/scylladb-php-driver:${{ matrix.os }}-php-${{ matrix.php }} steps: @@ -44,36 +44,23 @@ jobs: with: fetch-depth: 0 submodules: recursive - - name: Extract PHP Version and ZTS - id: name - run: | - [ "CICassandra" = "${{ matrix.preset }}" ] && echo 'extension="cassandra-${{ matrix.os }}-${{ matrix.php }}"' >> $GITHUB_ENV - - [ "CIScylla" = "${{ matrix.preset }}" ] && echo 'extension="scylla-${{ matrix.os }}-${{ matrix.php }}"' >> $GITHUB_ENV - name: Build Driver + shell: bash run: | - cmake --preset ${{ matrix.preset }} -DPHP_SCYLLADB_VERSION=${{ needs.tag.outputs.version }} || exit 1 - - cd out/${{ matrix.preset }} || exit 1 - ninja build || exit 1 - cd ../../ - - mv out/${{ matrix.preset }}/cassandra.so || exit 1 - sed -i "s/extension = cassandra/extension = ${{ steps.name.outputs.extension }}/g" cassandra.ini || exit 1 - - tar czf ${{ steps.name.outputs.extension }}.tar.gz ${{ steps.name.outputs.extension }}.so cassandra.ini + ./build.sh ${{ matrix.driver }} ${{ needs.tag.outputs.version }} + tar czf ${{ matrix.os }}-php-${{ matrix.php }}-${{ matrix.driver }}.tar.gz cassandra.so cassandra.ini - uses: actions/upload-artifact@v4 with: - name: ${{ steps.name.outputs.extension }} - path: ${{ steps.name.outputs.extension }}.tar.gz + name: ${{ matrix.os }}-php-${{ matrix.php }}-${{ matrix.driver }}.tar.gz + path: ${{ matrix.os }}-php-${{ matrix.php }}-${{ matrix.driver }}.tar.gz if-no-files-found: error retention-days: 5 overwrite: true release: - runs-on: ubuntu-latest + runs-on: ubuntu-24.04 needs: ["build", 'tag'] steps: - uses: actions/download-artifact@v4 @@ -86,7 +73,7 @@ jobs: with: make_latest: ${{ !needs.tag.outputs.prerelease }} name: "v${{ needs.tag.outputs.version }}" - tag_name: "v${{ needs.tag.outputs.version }}" + tag_name: "v${{ needs.tag.outputs.version }}" generate_release_notes: true append_body: true prerelease: ${{ needs.tag.outputs.prerelease }} diff --git a/.github/workflows/test-images.yml b/.github/workflows/test-images.yml index 1ef12f2db..c9d6af3cc 100644 --- a/.github/workflows/test-images.yml +++ b/.github/workflows/test-images.yml @@ -1,8 +1,8 @@ -name: "Build Docker Images" +name: 'Build Docker Images' on: schedule: - - cron: "0 0 1,15 * *" + - cron: '0 0 1,15 * *' workflow_call: workflow_dispatch: @@ -10,14 +10,16 @@ jobs: build: strategy: matrix: - tag: ["8.1.29", "8.2.20", "8.3.8"] - zts: ['yes', 'no'] + tag: ['8.1', '8.2', '8.3', '8.4'] + threading: ['zts', 'nts'] debug: ['yes', 'no'] - ubuntu_version: ["20.04", "22.04", "24.04"] - uses: "./.github/workflows/docker-image.yml" + ubuntu_version: ['22.04', '24.04'] + fail-fast: false + max-parallel: 6 + uses: './.github/workflows/docker-image.yml' with: php: ${{ matrix.tag }} - zts: ${{ matrix.zts }} + threading: ${{ matrix.threading }} ubuntu_version: ${{ matrix.ubuntu_version }} debug: ${{ matrix.debug }} secrets: diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 1cd5b83f6..226b9c64c 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -12,27 +12,45 @@ jobs: test: strategy: matrix: - php: ['8.1', '8.2', '8.3', '8.1-zts', '8.2-zts', '8.3-zts'] - os: ['ubuntu-20.04', 'ubuntu-24.04'] - preset: ['CICassandraDebug', 'CIScyllaDebug'] + php: ['8.1', '8.2', '8.3', '8.4'] + threading: ['zts', 'nts'] + os: ['ubuntu-22.04', 'ubuntu-24.04'] + driver: ['scylladb', 'cassandra'] fail-fast: false - runs-on: ubuntu-latest - container: malusevd99/scylladb-php-driver:${{ matrix.os }}-php-${{ matrix.php }}-debug + runs-on: ubuntu-24.04 + container: malusevd99/scylladb-php-driver:${{ matrix.os }}-${{ matrix.php }}-${{ matrix.threading }}-debug steps: - uses: actions/checkout@v4 with: fetch-depth: 0 submodules: recursive - - name: Run tests - run: | - cmake --preset ${{ matrix.preset }} || exit 1 + - name: Cache Vendor + uses: actions/cache@v3 + with: + path: tests/vendor + key: ${{ runner.os }}-${{ matrix.php }}-vendor-${{ hashFiles('**/composer.lock') }} - cd out/${{ matrix.preset }} || exit 1 - ninja install || exit 1 - cd ../../ + - name: Build + run: ./scripts/build.sh ${{ matrix.driver }} - cat cassandra.ini >> "$(php-config --ini-path | xargs -I {} printf '%s/php.ini' {})" || exit 1 + - name: Install PHP Dependencies + working-directory: tests + shell: bash + run: | + php -d extension=cassandra /php/bin/composer \ + --ignore-platform-reqs \ + --no-ansi \ + --prefer-dist \ + --no-interaction \ + --no-progress \ + install - cd tests - composer install - php ./vendor/bin/pest + - name: Run tests + working-directory: tests + shell: bash + run: | + php -d extension=cassandra ./vendor/bin/pest \ + --colors=always \ + --fail-on-risky \ + --fail-on-warning \ + --fail-on-deprecation diff --git a/.vscode/settings.json b/.vscode/settings.json index 261acbfb3..7b1914bd4 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -2,18 +2,8 @@ "cmake.buildDirectory": "${workspaceFolder}/out/Debug", "cmake.allowCommentsInPresetsFile": true, "cmake.buildTask": true, - "cmake.configureEnvironment": { - "CMAKE_BUILD_TYPE": "Debug", - "CMAKE_INSTALL_PREFIX": "${sourceDir}/out/install/${presetName}", - "PHP_SCYLLADB_LIBUV_STATIC": "ON", - "PHP_SCYLLADB_LIBSCYLLADB_STATIC": "ON", - "CASS_CPP_STANDARD": "17", - "CASS_USE_STATIC_LIBS": "ON", - "PHP_SCYLLADB_ENABLE_SANITIZERS": "ON" - }, "cmake.configureSettings": {}, "cmake.generator": "Ninja", - "cmake.installPrefix": "${workspaceFolder}/out/Debug/install", "cmake.loggingLevel": "debug", "cmake.configureArgs": [], "cmake.sourceDirectory": "${workspaceFolder}/.", diff --git a/CMakeLists.txt b/CMakeLists.txt index 216b1b259..8f672a87c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,96 +1,72 @@ -cmake_minimum_required(VERSION 3.24) +cmake_minimum_required(VERSION 3.30) -if(POLICY CMP0074) +if (POLICY CMP0074) cmake_policy(SET CMP0074 NEW) -endif() +endif () -if(POLICY CMP0054) +if (POLICY CMP0054) cmake_policy(SET CMP0054 NEW) -endif() +endif () -if(POLICY CMP0079) +if (POLICY CMP0079) cmake_policy(SET CMP0079 NEW) -endif() +endif () -if(POLICY CMP0108) +if (POLICY CMP0108) cmake_policy(SET CMP0108 NEW) -endif() +endif () -if(POLICY CMP0109) +if (POLICY CMP0109) cmake_policy(SET CMP0109 NEW) -endif() +endif () -if(POLICY CMP0128) +if (POLICY CMP0128) cmake_policy(SET CMP0128 NEW) -endif() +endif () project(php-ext-scylladb LANGUAGES C CXX) add_library(ext_scylladb SHARED) # if build type is not set, default to debug -if(NOT CMAKE_BUILD_TYPE OR CMAKE_BUILD_TYPE STREQUAL "") +if (NOT CMAKE_BUILD_TYPE OR CMAKE_BUILD_TYPE STREQUAL "") set(CMAKE_BUILD_TYPE "Debug") -endif() +endif () include(CheckSymbolExists) include(CheckIncludeFile) include(CMakePackageConfigHelpers) include(cmake/CPM.cmake) include(cmake/TargetOptimizations.cmake) -include(cmake/ScyllaDBPHPLibrary.cmake) -set(PHP_SCYLLADB_VERSION "1.4.0-dev") - -set(CMAKE_C_STANDARD 17) -set(CMAKE_CXX_STANDARD 20) +set(PHP_SCYLLADB_DRIVER_VERSION "1.4.0-dev") set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${PROJECT_SOURCE_DIR}/cmake" "${PROJECT_SOURCE_DIR}/third-party/sanitizers-cmake/cmake") # Library Options -option(PHP_SCYLLADB_ENABLE_SANITIZERS "Enable sanitizers" OFF) -option(PHP_SCYLLADB_ENABLE_COVERAGE "Enable coverage" OFF) -option(PHP_SCYLLADB_OPTIMISE_FOR_CURRENT_MACHINE "Optimise for current machine" OFF) +option(ENABLE_SANITIZERS "Enable sanitizers" OFF) +option(ENABLE_AVX "Enable AVX" OFF) +option(ENABLE_AVX2 "Enable AVX2" OFF) +option(ENABLE_LTO "Enable LTO" OFF) +set(CPU_TYPE "x86-64-v2" CACHE STRING "For x86_64 = x86-64|x86-64-v2|x86-64-v3|x86-64-v4|native") # PHP Options set(CUSTOM_PHP_CONFIG "" CACHE STRING "Custom PHP config path") -set(PHP_VERSION_FOR_PHP_CONFIG "8.3" CACHE STRING "PHP version") - -option(PHP_DEBUG_FOR_PHP_CONFIG "Debug or Release" ON) -option(PHP_THREAD_SAFE_FOR_PHP_CONFIG "ZTS(zts) or NTS(nts)" OFF) - -if(CMAKE_HOST_APPLE) - option(PHP_SCYLLADB_LIBUV_STATIC "Statically link libuv" ON) -else() - option(PHP_SCYLLADB_LIBUV_STATIC "Statically link libuv" OFF) -endif() - -option(PHP_SCYLLADB_LIBUV_FROM_SRC "Build LibUV from Source" ON) +set(PHP_VERSION_FOR_PHP_CONFIG "8.4" CACHE STRING "PHP version") +option(PHP_DEBUG "Debug or Release" ON) +option(PHP_THREAD_SAFE "ZTS(zts) or NTS(nts)" OFF) -if(CMAKE_HOST_APPLE) - option(PHP_SCYLLADB_LIBSCYLLADB_STATIC "Statically link LibScyllaDB" ON) -else() - option(PHP_SCYLLADB_LIBSCYLLADB_STATIC "Statically link LibScyllaDB" OFF) -endif() +option(LINK_LIBUV_STATIC "Statically link libuv" OFF) +option(BUILD_LIBUV_FROM_SRC "Build LibUV from Source" OFF) -option(PHP_SCYLLADB_USE_LIBCASSANDRA "Use DataStax LibCassandra instead of LibScyllaDB" OFF) - -if(CMAKE_HOST_APPLE) - option(PHP_SCYLLADB_LIBCASSANDRA_STATIC "Statically link LibCassandra" ON) -else() - option(PHP_SCYLLADB_LIBCASSANDRA_STATIC "Statically link LibCassandra" OFF) -endif() +option(PHP_DRIVER_STATIC "Statically link PHP Driver" OFF) +option(USE_LIBCASSANDRA "Use DataStax LibCassandra instead of LibScyllaDB" OFF) find_package(PHPConfig REQUIRED) find_package(PHP REQUIRED) find_package(Sanitizers REQUIRED) find_package(Libuv REQUIRED) find_package(LibGMP REQUIRED) - -if(PHP_SCYLLADB_USE_LIBCASSANDRA) - find_package(CassandraDriver REQUIRED) -else() - find_package(ScyllaDBDriver REQUIRED) -endif() +find_package(CPPDriver REQUIRED) add_subdirectory(ZendCPP) add_subdirectory(util) @@ -107,57 +83,38 @@ add_subdirectory(src/Type) file(GLOB_RECURSE HEADERS_LIST FOLLOW_SYMLINKS include/*.h) -scylladb_php_library(ext_scylladb ${PHP_SCYLLADB_ENABLE_SANITIZERS} ${PHP_SCYLLADB_OPTIMISE_FOR_CURRENT_MACHINE} OFF) - -target_sources(ext_scylladb PUBLIC FILE_SET headers TYPE HEADERS FILES "${HEADERS_LIST}" "${PROJECT_BINARY_DIR}/config.h") -target_sources(ext_scylladb PRIVATE php_driver.cpp) +scylladb_php_library(ext_scylladb "${ENABLE_SANITIZERS}" "${CPU_TYPE}" "${ENABLE_LTO}") -target_link_libraries( - ext_scylladb PRIVATE - Zend - ext_scylladb::src - ext_scylladb::utils - ext_scylladb::type - ext_scylladb::datetime - ext_scylladb::database - ext_scylladb::numbers - ext_scylladb::ssl_options - ext_scylladb::exceptions - ext_scylladb::cluster::builder - ext_scylladb::retry_policy - ext_scylladb::timestamp_generator +target_sources(ext_scylladb PUBLIC FILE_SET headers TYPE HEADERS FILES "${HEADERS_LIST}") +target_sources( + ext_scylladb + PRIVATE + src/php_driver.cpp ) - -check_include_file("dlfcn.h" HAVE_DLFCN_H) -check_include_file("stdio.h" HAVE_STDIO_H) -check_include_file("stdint.h" HAVE_STDINT_H) -check_include_file("stdlib.h" HAVE_STDLIB_H) -check_include_file("inttypes.h" HAVE_INTTYPES_H) -check_include_file("sys/stat.h" HAVE_SYS_STAT_H) -check_include_file("sys/types.h" HAVE_SYS_TYPES_H) -check_include_file("string.h" HAVE_STRING_H) -check_include_file("unistd.h" HAVE_UNISTD_H) - -set(HAVE_STRINGS_H 0) - -configure_file( - config.in - config.h - USE_SOURCE_PERMISSIONS - NEWLINE_STYLE UNIX +target_link_libraries( + ext_scylladb PRIVATE + Zend + ext_scylladb::src + ext_scylladb::utils + ext_scylladb::type + ext_scylladb::datetime + ext_scylladb::database + ext_scylladb::numbers + ext_scylladb::ssl_options + ext_scylladb::exceptions + ext_scylladb::cluster::builder + ext_scylladb::retry_policy + ext_scylladb::timestamp_generator ) configure_file( - version.h.in - version.h - USE_SOURCE_PERMISSIONS - NEWLINE_STYLE UNIX + version.h.in + version.h + USE_SOURCE_PERMISSIONS + NEWLINE_STYLE UNIX ) -target_compile_definitions(ext_scylladb PRIVATE -DCOMPILE_DL_CASSANDRA -DHAVE_CONFIG_H) +target_compile_definitions(ext_scylladb PRIVATE -DCOMPILE_DL_CASSANDRA) set_target_properties(ext_scylladb PROPERTIES POSITION_INDEPENDENT_CODE ON) set_target_properties(ext_scylladb PROPERTIES PREFIX "") set_target_properties(ext_scylladb PROPERTIES OUTPUT_NAME "cassandra") - -install(TARGETS ext_scylladb DESTINATION "${PHP_EXTENSION_DIR}") -install(TARGETS ext_scylladb FILE_SET headers DESTINATION "${PHP_INCLUDES_DIR}/ext/cassandra") diff --git a/CMakePresets.json b/CMakePresets.json index bd39d7ee4..be10076a9 100644 --- a/CMakePresets.json +++ b/CMakePresets.json @@ -1,157 +1,2741 @@ { - "version": 2, - "configurePresets": [ - { - "name": "Debug", - "displayName": "Debug", - "description": "", - "generator": "Ninja", - "environment": {}, - "binaryDir": "${sourceDir}/out/${presetName}", - "cacheVariables": { - "CMAKE_BUILD_TYPE": "Debug", - "CMAKE_INSTALL_PREFIX": "${sourceDir}/out/install/${presetName}", - "PHP_SCYLLADB_ENABLE_SANITIZERS": "ON", - "SANITIZE_UNDEFINED": "ON", - "SANITIZE_ADDRESS": "ON" - } - }, - { - "name": "DebugLibCassandra", - "displayName": "DebugLibCassandra", - "description": "Use LibCassandra instead of LibScyllaDB", - "generator": "Ninja", - "environment": {}, - "binaryDir": "${sourceDir}/out/${presetName}", - "cacheVariables": { - "CMAKE_BUILD_TYPE": "Debug", - "CMAKE_INSTALL_PREFIX": "${sourceDir}/out/install/${presetName}", - "PHP_SCYLLADB_ENABLE_SANITIZERS": "ON", - "PHP_SCYLLADB_USE_LIBCASSANDRA": "ON", - "SANITIZE_UNDEFINED": "ON", - "SANITIZE_ADDRESS": "ON" - } - }, - { - "name": "Release", - "displayName": "Release", - "description": "", - "generator": "Ninja", - "environment": {}, - "binaryDir": "${sourceDir}/out/${presetName}", - "cacheVariables": { - "CMAKE_BUILD_TYPE": "Release", - "CMAKE_INSTALL_PREFIX": "${sourceDir}/out/install/${presetName}", - "PHP_SCYLLADB_USE_LIBCASSANDRA": "OFF", - "SANITIZE_UNDEFINED": "OFF", - "SANITIZE_ADDRESS": "OFF" - } - }, - { - "name": "ReleaseLibCassandra", - "displayName": "ReleaseLibCassandra", - "description": "Use LibCassandra instead of LibScyllaDB", - "generator": "Ninja", - "environment": {}, - "binaryDir": "${sourceDir}/out/${presetName}", - "cacheVariables": { - "CMAKE_BUILD_TYPE": "Release", - "CMAKE_INSTALL_PREFIX": "${sourceDir}/out/install/${presetName}", - "PHP_SCYLLADB_USE_LIBCASSANDRA": "ON", - "SANITIZE_UNDEFINED": "OFF", - "SANITIZE_ADDRESS": "OFF" - } - }, - { - "name": "RelWithInfo", - "displayName": "RelWithInfo", - "description": "", - "generator": "Ninja", - "environment": {}, - "binaryDir": "${sourceDir}/out/${presetName}", - "cacheVariables": { - "CMAKE_BUILD_TYPE": "RelWithInfo", - "CMAKE_INSTALL_PREFIX": "${sourceDir}/out/install/${presetName}", - "PHP_SCYLLADB_ENABLE_SANITIZERS": "OFF", - "SANITIZE_UNDEFINED": "OFF", - "SANITIZE_ADDRESS": "OFF" - } - }, - { - "name": "RelWithInfoCassandra", - "displayName": "RelWithInfoCassandra", - "description": "", - "generator": "Ninja", - "environment": {}, - "binaryDir": "${sourceDir}/out/${presetName}", - "cacheVariables": { - "CMAKE_BUILD_TYPE": "RelWithInfo", - "CMAKE_INSTALL_PREFIX": "${sourceDir}/out/install/${presetName}", - "PHP_SCYLLADB_USE_LIBCASSANDRA": "ON", - "PHP_SCYLLADB_ENABLE_SANITIZERS": "OFF", - "SANITIZE_UNDEFINED": "OFF", - "SANITIZE_ADDRESS": "OFF" - } - }, - { - "name": "CIScylla", - "displayName": "GithubActions CIScylla", - "description": "", - "generator": "Ninja", - "environment": {}, - "binaryDir": "${sourceDir}/out/${presetName}", - "cacheVariables": { - "CMAKE_BUILD_TYPE": "RelWithInfo", - "PHP_SCYLLADB_ENABLE_SANITIZERS": "OFF", - "SANITIZE_UNDEFINED": "OFF", - "SANITIZE_ADDRESS": "OFF", - "CUSTOM_PHP_CONFIG": "/php/bin/php-config" - } - }, - { - "name": "CICassandra", - "displayName": "GithubActions CI", - "description": "", - "generator": "Ninja", - "environment": {}, - "binaryDir": "${sourceDir}/out/${presetName}", - "cacheVariables": { - "CMAKE_BUILD_TYPE": "RelWithInfo", - "PHP_SCYLLADB_ENABLE_SANITIZERS": "OFF", - "SANITIZE_UNDEFINED": "OFF", - "SANITIZE_ADDRESS": "OFF", - "CUSTOM_PHP_CONFIG": "/php/bin/php-config" - } - }, - { - "name": "CIScyllaDebug", - "displayName": "GithubActions CIScylla", - "description": "", - "generator": "Ninja", - "environment": {}, - "binaryDir": "${sourceDir}/out/${presetName}", - "cacheVariables": { - "CMAKE_BUILD_TYPE": "Debug", - "PHP_SCYLLADB_ENABLE_SANITIZERS": "ON", - "SANITIZE_UNDEFINED": "ON", - "SANITIZE_ADDRESS": "ON", - "CUSTOM_PHP_CONFIG": "/php/bin/php-config" - } - }, - { - "name": "CICassandraDebug", - "displayName": "GithubActions CI", - "description": "", - "generator": "Ninja", - "environment": {}, - "binaryDir": "${sourceDir}/out/${presetName}", - "cacheVariables": { - "CMAKE_BUILD_TYPE": "Debug", - "PHP_SCYLLADB_ENABLE_SANITIZERS": "ON", - "SANITIZE_UNDEFINED": "ON", - "SANITIZE_ADDRESS": "ON", - "CUSTOM_PHP_CONFIG": "/php/bin/php-config" - } - } - ] + "version": 2, + "configurePresets": [ + { + "name": "DebugPHP8.1ZTSCassandra", + "displayName": "DebugPHP8.1ZTSCassandra", + "description": "", + "generator": "Ninja", + "binaryDir": "./out/DebugPHP8.1ZTSCassandra", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "CMAKE_INSTALL_PREFIX": "./out/install/DebugPHP8.1ZTSCassandra", + "ENABLE_SANITIZERS": "ON", + "SANITIZE_UNDEFINED": "ON", + "SANITIZE_ADDRESS": "ON", + "USE_LIBCASSANDRA": "ON", + "PHP_VERSION_FOR_PHP_CONFIG": "8.1", + "LINK_LIBUV_STATIC": "ON", + "PHP_DRIVER_STATIC": "ON", + "PHP_THREAD_SAFE": "ON" + } + }, + { + "name": "DebugPHP8.1NTSCassandra", + "displayName": "DebugPHP8.1NTSCassandra", + "description": "", + "generator": "Ninja", + "binaryDir": "./out/DebugPHP8.1NTSCassandra", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "CMAKE_INSTALL_PREFIX": "./out/install/DebugPHP8.1NTSCassandra", + "ENABLE_SANITIZERS": "ON", + "SANITIZE_UNDEFINED": "ON", + "SANITIZE_ADDRESS": "ON", + "USE_LIBCASSANDRA": "ON", + "PHP_VERSION_FOR_PHP_CONFIG": "8.1", + "LINK_LIBUV_STATIC": "ON", + "PHP_DRIVER_STATIC": "ON", + "PHP_THREAD_SAFE": "OFF" + } + }, + { + "name": "DebugPHP8.2ZTSCassandra", + "displayName": "DebugPHP8.2ZTSCassandra", + "description": "", + "generator": "Ninja", + "binaryDir": "./out/DebugPHP8.2ZTSCassandra", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "CMAKE_INSTALL_PREFIX": "./out/install/DebugPHP8.2ZTSCassandra", + "ENABLE_SANITIZERS": "ON", + "SANITIZE_UNDEFINED": "ON", + "SANITIZE_ADDRESS": "ON", + "USE_LIBCASSANDRA": "ON", + "PHP_VERSION_FOR_PHP_CONFIG": "8.2", + "LINK_LIBUV_STATIC": "ON", + "PHP_DRIVER_STATIC": "ON", + "PHP_THREAD_SAFE": "ON" + } + }, + { + "name": "DebugPHP8.2NTSCassandra", + "displayName": "DebugPHP8.2NTSCassandra", + "description": "", + "generator": "Ninja", + "binaryDir": "./out/DebugPHP8.2NTSCassandra", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "CMAKE_INSTALL_PREFIX": "./out/install/DebugPHP8.2NTSCassandra", + "ENABLE_SANITIZERS": "ON", + "SANITIZE_UNDEFINED": "ON", + "SANITIZE_ADDRESS": "ON", + "USE_LIBCASSANDRA": "ON", + "PHP_VERSION_FOR_PHP_CONFIG": "8.2", + "LINK_LIBUV_STATIC": "ON", + "PHP_DRIVER_STATIC": "ON", + "PHP_THREAD_SAFE": "OFF" + } + }, + { + "name": "DebugPHP8.3ZTSCassandra", + "displayName": "DebugPHP8.3ZTSCassandra", + "description": "", + "generator": "Ninja", + "binaryDir": "./out/DebugPHP8.3ZTSCassandra", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "CMAKE_INSTALL_PREFIX": "./out/install/DebugPHP8.3ZTSCassandra", + "ENABLE_SANITIZERS": "ON", + "SANITIZE_UNDEFINED": "ON", + "SANITIZE_ADDRESS": "ON", + "USE_LIBCASSANDRA": "ON", + "PHP_VERSION_FOR_PHP_CONFIG": "8.3", + "LINK_LIBUV_STATIC": "ON", + "PHP_DRIVER_STATIC": "ON", + "PHP_THREAD_SAFE": "ON" + } + }, + { + "name": "DebugPHP8.3NTSCassandra", + "displayName": "DebugPHP8.3NTSCassandra", + "description": "", + "generator": "Ninja", + "binaryDir": "./out/DebugPHP8.3NTSCassandra", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "CMAKE_INSTALL_PREFIX": "./out/install/DebugPHP8.3NTSCassandra", + "ENABLE_SANITIZERS": "ON", + "SANITIZE_UNDEFINED": "ON", + "SANITIZE_ADDRESS": "ON", + "USE_LIBCASSANDRA": "ON", + "PHP_VERSION_FOR_PHP_CONFIG": "8.3", + "LINK_LIBUV_STATIC": "ON", + "PHP_DRIVER_STATIC": "ON", + "PHP_THREAD_SAFE": "OFF" + } + }, + { + "name": "DebugPHP8.4ZTSCassandra", + "displayName": "DebugPHP8.4ZTSCassandra", + "description": "", + "generator": "Ninja", + "binaryDir": "./out/DebugPHP8.4ZTSCassandra", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "CMAKE_INSTALL_PREFIX": "./out/install/DebugPHP8.4ZTSCassandra", + "ENABLE_SANITIZERS": "ON", + "SANITIZE_UNDEFINED": "ON", + "SANITIZE_ADDRESS": "ON", + "USE_LIBCASSANDRA": "ON", + "PHP_VERSION_FOR_PHP_CONFIG": "8.4", + "LINK_LIBUV_STATIC": "ON", + "PHP_DRIVER_STATIC": "ON", + "PHP_THREAD_SAFE": "ON" + } + }, + { + "name": "DebugPHP8.4NTSCassandra", + "displayName": "DebugPHP8.4NTSCassandra", + "description": "", + "generator": "Ninja", + "binaryDir": "./out/DebugPHP8.4NTSCassandra", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "CMAKE_INSTALL_PREFIX": "./out/install/DebugPHP8.4NTSCassandra", + "ENABLE_SANITIZERS": "ON", + "SANITIZE_UNDEFINED": "ON", + "SANITIZE_ADDRESS": "ON", + "USE_LIBCASSANDRA": "ON", + "PHP_VERSION_FOR_PHP_CONFIG": "8.4", + "LINK_LIBUV_STATIC": "ON", + "PHP_DRIVER_STATIC": "ON", + "PHP_THREAD_SAFE": "OFF" + } + }, + { + "name": "DebugPHP8.1ZTSCassandra", + "displayName": "DebugPHP8.1ZTSCassandra", + "description": "", + "generator": "Ninja", + "binaryDir": "./out/DebugPHP8.1ZTSCassandra", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "CMAKE_INSTALL_PREFIX": "./out/install/DebugPHP8.1ZTSCassandra", + "ENABLE_SANITIZERS": "OFF", + "SANITIZE_UNDEFINED": "OFF", + "SANITIZE_ADDRESS": "OFF", + "USE_LIBCASSANDRA": "ON", + "PHP_VERSION_FOR_PHP_CONFIG": "8.1", + "LINK_LIBUV_STATIC": "ON", + "PHP_DRIVER_STATIC": "ON", + "PHP_THREAD_SAFE": "ON" + } + }, + { + "name": "DebugPHP8.1NTSCassandra", + "displayName": "DebugPHP8.1NTSCassandra", + "description": "", + "generator": "Ninja", + "binaryDir": "./out/DebugPHP8.1NTSCassandra", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "CMAKE_INSTALL_PREFIX": "./out/install/DebugPHP8.1NTSCassandra", + "ENABLE_SANITIZERS": "OFF", + "SANITIZE_UNDEFINED": "OFF", + "SANITIZE_ADDRESS": "OFF", + "USE_LIBCASSANDRA": "ON", + "PHP_VERSION_FOR_PHP_CONFIG": "8.1", + "LINK_LIBUV_STATIC": "ON", + "PHP_DRIVER_STATIC": "ON", + "PHP_THREAD_SAFE": "OFF" + } + }, + { + "name": "DebugPHP8.2ZTSCassandra", + "displayName": "DebugPHP8.2ZTSCassandra", + "description": "", + "generator": "Ninja", + "binaryDir": "./out/DebugPHP8.2ZTSCassandra", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "CMAKE_INSTALL_PREFIX": "./out/install/DebugPHP8.2ZTSCassandra", + "ENABLE_SANITIZERS": "OFF", + "SANITIZE_UNDEFINED": "OFF", + "SANITIZE_ADDRESS": "OFF", + "USE_LIBCASSANDRA": "ON", + "PHP_VERSION_FOR_PHP_CONFIG": "8.2", + "LINK_LIBUV_STATIC": "ON", + "PHP_DRIVER_STATIC": "ON", + "PHP_THREAD_SAFE": "ON" + } + }, + { + "name": "DebugPHP8.2NTSCassandra", + "displayName": "DebugPHP8.2NTSCassandra", + "description": "", + "generator": "Ninja", + "binaryDir": "./out/DebugPHP8.2NTSCassandra", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "CMAKE_INSTALL_PREFIX": "./out/install/DebugPHP8.2NTSCassandra", + "ENABLE_SANITIZERS": "OFF", + "SANITIZE_UNDEFINED": "OFF", + "SANITIZE_ADDRESS": "OFF", + "USE_LIBCASSANDRA": "ON", + "PHP_VERSION_FOR_PHP_CONFIG": "8.2", + "LINK_LIBUV_STATIC": "ON", + "PHP_DRIVER_STATIC": "ON", + "PHP_THREAD_SAFE": "OFF" + } + }, + { + "name": "DebugPHP8.3ZTSCassandra", + "displayName": "DebugPHP8.3ZTSCassandra", + "description": "", + "generator": "Ninja", + "binaryDir": "./out/DebugPHP8.3ZTSCassandra", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "CMAKE_INSTALL_PREFIX": "./out/install/DebugPHP8.3ZTSCassandra", + "ENABLE_SANITIZERS": "OFF", + "SANITIZE_UNDEFINED": "OFF", + "SANITIZE_ADDRESS": "OFF", + "USE_LIBCASSANDRA": "ON", + "PHP_VERSION_FOR_PHP_CONFIG": "8.3", + "LINK_LIBUV_STATIC": "ON", + "PHP_DRIVER_STATIC": "ON", + "PHP_THREAD_SAFE": "ON" + } + }, + { + "name": "DebugPHP8.3NTSCassandra", + "displayName": "DebugPHP8.3NTSCassandra", + "description": "", + "generator": "Ninja", + "binaryDir": "./out/DebugPHP8.3NTSCassandra", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "CMAKE_INSTALL_PREFIX": "./out/install/DebugPHP8.3NTSCassandra", + "ENABLE_SANITIZERS": "OFF", + "SANITIZE_UNDEFINED": "OFF", + "SANITIZE_ADDRESS": "OFF", + "USE_LIBCASSANDRA": "ON", + "PHP_VERSION_FOR_PHP_CONFIG": "8.3", + "LINK_LIBUV_STATIC": "ON", + "PHP_DRIVER_STATIC": "ON", + "PHP_THREAD_SAFE": "OFF" + } + }, + { + "name": "DebugPHP8.4ZTSCassandra", + "displayName": "DebugPHP8.4ZTSCassandra", + "description": "", + "generator": "Ninja", + "binaryDir": "./out/DebugPHP8.4ZTSCassandra", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "CMAKE_INSTALL_PREFIX": "./out/install/DebugPHP8.4ZTSCassandra", + "ENABLE_SANITIZERS": "OFF", + "SANITIZE_UNDEFINED": "OFF", + "SANITIZE_ADDRESS": "OFF", + "USE_LIBCASSANDRA": "ON", + "PHP_VERSION_FOR_PHP_CONFIG": "8.4", + "LINK_LIBUV_STATIC": "ON", + "PHP_DRIVER_STATIC": "ON", + "PHP_THREAD_SAFE": "ON" + } + }, + { + "name": "DebugPHP8.4NTSCassandra", + "displayName": "DebugPHP8.4NTSCassandra", + "description": "", + "generator": "Ninja", + "binaryDir": "./out/DebugPHP8.4NTSCassandra", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "CMAKE_INSTALL_PREFIX": "./out/install/DebugPHP8.4NTSCassandra", + "ENABLE_SANITIZERS": "OFF", + "SANITIZE_UNDEFINED": "OFF", + "SANITIZE_ADDRESS": "OFF", + "USE_LIBCASSANDRA": "ON", + "PHP_VERSION_FOR_PHP_CONFIG": "8.4", + "LINK_LIBUV_STATIC": "ON", + "PHP_DRIVER_STATIC": "ON", + "PHP_THREAD_SAFE": "OFF" + } + }, + { + "name": "DebugPHP8.1ZTSCassandra", + "displayName": "DebugPHP8.1ZTSCassandra", + "description": "", + "generator": "Ninja", + "binaryDir": "./out/DebugPHP8.1ZTSCassandra", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "CMAKE_INSTALL_PREFIX": "./out/install/DebugPHP8.1ZTSCassandra", + "ENABLE_SANITIZERS": "OFF", + "SANITIZE_UNDEFINED": "OFF", + "SANITIZE_ADDRESS": "OFF", + "USE_LIBCASSANDRA": "ON", + "PHP_VERSION_FOR_PHP_CONFIG": "8.1", + "LINK_LIBUV_STATIC": "ON", + "PHP_DRIVER_STATIC": "ON", + "PHP_THREAD_SAFE": "ON" + } + }, + { + "name": "DebugPHP8.1NTSCassandra", + "displayName": "DebugPHP8.1NTSCassandra", + "description": "", + "generator": "Ninja", + "binaryDir": "./out/DebugPHP8.1NTSCassandra", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "CMAKE_INSTALL_PREFIX": "./out/install/DebugPHP8.1NTSCassandra", + "ENABLE_SANITIZERS": "OFF", + "SANITIZE_UNDEFINED": "OFF", + "SANITIZE_ADDRESS": "OFF", + "USE_LIBCASSANDRA": "ON", + "PHP_VERSION_FOR_PHP_CONFIG": "8.1", + "LINK_LIBUV_STATIC": "ON", + "PHP_DRIVER_STATIC": "ON", + "PHP_THREAD_SAFE": "OFF" + } + }, + { + "name": "DebugPHP8.2ZTSCassandra", + "displayName": "DebugPHP8.2ZTSCassandra", + "description": "", + "generator": "Ninja", + "binaryDir": "./out/DebugPHP8.2ZTSCassandra", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "CMAKE_INSTALL_PREFIX": "./out/install/DebugPHP8.2ZTSCassandra", + "ENABLE_SANITIZERS": "OFF", + "SANITIZE_UNDEFINED": "OFF", + "SANITIZE_ADDRESS": "OFF", + "USE_LIBCASSANDRA": "ON", + "PHP_VERSION_FOR_PHP_CONFIG": "8.2", + "LINK_LIBUV_STATIC": "ON", + "PHP_DRIVER_STATIC": "ON", + "PHP_THREAD_SAFE": "ON" + } + }, + { + "name": "DebugPHP8.2NTSCassandra", + "displayName": "DebugPHP8.2NTSCassandra", + "description": "", + "generator": "Ninja", + "binaryDir": "./out/DebugPHP8.2NTSCassandra", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "CMAKE_INSTALL_PREFIX": "./out/install/DebugPHP8.2NTSCassandra", + "ENABLE_SANITIZERS": "OFF", + "SANITIZE_UNDEFINED": "OFF", + "SANITIZE_ADDRESS": "OFF", + "USE_LIBCASSANDRA": "ON", + "PHP_VERSION_FOR_PHP_CONFIG": "8.2", + "LINK_LIBUV_STATIC": "ON", + "PHP_DRIVER_STATIC": "ON", + "PHP_THREAD_SAFE": "OFF" + } + }, + { + "name": "DebugPHP8.3ZTSCassandra", + "displayName": "DebugPHP8.3ZTSCassandra", + "description": "", + "generator": "Ninja", + "binaryDir": "./out/DebugPHP8.3ZTSCassandra", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "CMAKE_INSTALL_PREFIX": "./out/install/DebugPHP8.3ZTSCassandra", + "ENABLE_SANITIZERS": "OFF", + "SANITIZE_UNDEFINED": "OFF", + "SANITIZE_ADDRESS": "OFF", + "USE_LIBCASSANDRA": "ON", + "PHP_VERSION_FOR_PHP_CONFIG": "8.3", + "LINK_LIBUV_STATIC": "ON", + "PHP_DRIVER_STATIC": "ON", + "PHP_THREAD_SAFE": "ON" + } + }, + { + "name": "DebugPHP8.3NTSCassandra", + "displayName": "DebugPHP8.3NTSCassandra", + "description": "", + "generator": "Ninja", + "binaryDir": "./out/DebugPHP8.3NTSCassandra", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "CMAKE_INSTALL_PREFIX": "./out/install/DebugPHP8.3NTSCassandra", + "ENABLE_SANITIZERS": "OFF", + "SANITIZE_UNDEFINED": "OFF", + "SANITIZE_ADDRESS": "OFF", + "USE_LIBCASSANDRA": "ON", + "PHP_VERSION_FOR_PHP_CONFIG": "8.3", + "LINK_LIBUV_STATIC": "ON", + "PHP_DRIVER_STATIC": "ON", + "PHP_THREAD_SAFE": "OFF" + } + }, + { + "name": "DebugPHP8.4ZTSCassandra", + "displayName": "DebugPHP8.4ZTSCassandra", + "description": "", + "generator": "Ninja", + "binaryDir": "./out/DebugPHP8.4ZTSCassandra", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "CMAKE_INSTALL_PREFIX": "./out/install/DebugPHP8.4ZTSCassandra", + "ENABLE_SANITIZERS": "OFF", + "SANITIZE_UNDEFINED": "OFF", + "SANITIZE_ADDRESS": "OFF", + "USE_LIBCASSANDRA": "ON", + "PHP_VERSION_FOR_PHP_CONFIG": "8.4", + "LINK_LIBUV_STATIC": "ON", + "PHP_DRIVER_STATIC": "ON", + "PHP_THREAD_SAFE": "ON" + } + }, + { + "name": "DebugPHP8.4NTSCassandra", + "displayName": "DebugPHP8.4NTSCassandra", + "description": "", + "generator": "Ninja", + "binaryDir": "./out/DebugPHP8.4NTSCassandra", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "CMAKE_INSTALL_PREFIX": "./out/install/DebugPHP8.4NTSCassandra", + "ENABLE_SANITIZERS": "OFF", + "SANITIZE_UNDEFINED": "OFF", + "SANITIZE_ADDRESS": "OFF", + "USE_LIBCASSANDRA": "ON", + "PHP_VERSION_FOR_PHP_CONFIG": "8.4", + "LINK_LIBUV_STATIC": "ON", + "PHP_DRIVER_STATIC": "ON", + "PHP_THREAD_SAFE": "OFF" + } + }, + { + "name": "DebugPHP8.1ZTS", + "displayName": "DebugPHP8.1ZTS", + "description": "", + "generator": "Ninja", + "binaryDir": "./out/DebugPHP8.1ZTS", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "CMAKE_INSTALL_PREFIX": "./out/install/DebugPHP8.1ZTS", + "ENABLE_SANITIZERS": "ON", + "SANITIZE_UNDEFINED": "ON", + "SANITIZE_ADDRESS": "ON", + "USE_LIBCASSANDRA": "OFF", + "PHP_VERSION_FOR_PHP_CONFIG": "8.1", + "LINK_LIBUV_STATIC": "ON", + "PHP_DRIVER_STATIC": "ON", + "PHP_THREAD_SAFE": "ON" + } + }, + { + "name": "DebugPHP8.1NTS", + "displayName": "DebugPHP8.1NTS", + "description": "", + "generator": "Ninja", + "binaryDir": "./out/DebugPHP8.1NTS", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "CMAKE_INSTALL_PREFIX": "./out/install/DebugPHP8.1NTS", + "ENABLE_SANITIZERS": "ON", + "SANITIZE_UNDEFINED": "ON", + "SANITIZE_ADDRESS": "ON", + "USE_LIBCASSANDRA": "OFF", + "PHP_VERSION_FOR_PHP_CONFIG": "8.1", + "LINK_LIBUV_STATIC": "ON", + "PHP_DRIVER_STATIC": "ON", + "PHP_THREAD_SAFE": "OFF" + } + }, + { + "name": "DebugPHP8.2ZTS", + "displayName": "DebugPHP8.2ZTS", + "description": "", + "generator": "Ninja", + "binaryDir": "./out/DebugPHP8.2ZTS", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "CMAKE_INSTALL_PREFIX": "./out/install/DebugPHP8.2ZTS", + "ENABLE_SANITIZERS": "ON", + "SANITIZE_UNDEFINED": "ON", + "SANITIZE_ADDRESS": "ON", + "USE_LIBCASSANDRA": "OFF", + "PHP_VERSION_FOR_PHP_CONFIG": "8.2", + "LINK_LIBUV_STATIC": "ON", + "PHP_DRIVER_STATIC": "ON", + "PHP_THREAD_SAFE": "ON" + } + }, + { + "name": "DebugPHP8.2NTS", + "displayName": "DebugPHP8.2NTS", + "description": "", + "generator": "Ninja", + "binaryDir": "./out/DebugPHP8.2NTS", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "CMAKE_INSTALL_PREFIX": "./out/install/DebugPHP8.2NTS", + "ENABLE_SANITIZERS": "ON", + "SANITIZE_UNDEFINED": "ON", + "SANITIZE_ADDRESS": "ON", + "USE_LIBCASSANDRA": "OFF", + "PHP_VERSION_FOR_PHP_CONFIG": "8.2", + "LINK_LIBUV_STATIC": "ON", + "PHP_DRIVER_STATIC": "ON", + "PHP_THREAD_SAFE": "OFF" + } + }, + { + "name": "DebugPHP8.3ZTS", + "displayName": "DebugPHP8.3ZTS", + "description": "", + "generator": "Ninja", + "binaryDir": "./out/DebugPHP8.3ZTS", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "CMAKE_INSTALL_PREFIX": "./out/install/DebugPHP8.3ZTS", + "ENABLE_SANITIZERS": "ON", + "SANITIZE_UNDEFINED": "ON", + "SANITIZE_ADDRESS": "ON", + "USE_LIBCASSANDRA": "OFF", + "PHP_VERSION_FOR_PHP_CONFIG": "8.3", + "LINK_LIBUV_STATIC": "ON", + "PHP_DRIVER_STATIC": "ON", + "PHP_THREAD_SAFE": "ON" + } + }, + { + "name": "DebugPHP8.3NTS", + "displayName": "DebugPHP8.3NTS", + "description": "", + "generator": "Ninja", + "binaryDir": "./out/DebugPHP8.3NTS", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "CMAKE_INSTALL_PREFIX": "./out/install/DebugPHP8.3NTS", + "ENABLE_SANITIZERS": "ON", + "SANITIZE_UNDEFINED": "ON", + "SANITIZE_ADDRESS": "ON", + "USE_LIBCASSANDRA": "OFF", + "PHP_VERSION_FOR_PHP_CONFIG": "8.3", + "LINK_LIBUV_STATIC": "ON", + "PHP_DRIVER_STATIC": "ON", + "PHP_THREAD_SAFE": "OFF" + } + }, + { + "name": "DebugPHP8.4ZTS", + "displayName": "DebugPHP8.4ZTS", + "description": "", + "generator": "Ninja", + "binaryDir": "./out/DebugPHP8.4ZTS", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "CMAKE_INSTALL_PREFIX": "./out/install/DebugPHP8.4ZTS", + "ENABLE_SANITIZERS": "ON", + "SANITIZE_UNDEFINED": "ON", + "SANITIZE_ADDRESS": "ON", + "USE_LIBCASSANDRA": "OFF", + "PHP_VERSION_FOR_PHP_CONFIG": "8.4", + "LINK_LIBUV_STATIC": "ON", + "PHP_DRIVER_STATIC": "ON", + "PHP_THREAD_SAFE": "ON" + } + }, + { + "name": "DebugPHP8.4NTS", + "displayName": "DebugPHP8.4NTS", + "description": "", + "generator": "Ninja", + "binaryDir": "./out/DebugPHP8.4NTS", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "CMAKE_INSTALL_PREFIX": "./out/install/DebugPHP8.4NTS", + "ENABLE_SANITIZERS": "ON", + "SANITIZE_UNDEFINED": "ON", + "SANITIZE_ADDRESS": "ON", + "USE_LIBCASSANDRA": "OFF", + "PHP_VERSION_FOR_PHP_CONFIG": "8.4", + "LINK_LIBUV_STATIC": "ON", + "PHP_DRIVER_STATIC": "ON", + "PHP_THREAD_SAFE": "OFF" + } + }, + { + "name": "DebugPHP8.1ZTS", + "displayName": "DebugPHP8.1ZTS", + "description": "", + "generator": "Ninja", + "binaryDir": "./out/DebugPHP8.1ZTS", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "CMAKE_INSTALL_PREFIX": "./out/install/DebugPHP8.1ZTS", + "ENABLE_SANITIZERS": "OFF", + "SANITIZE_UNDEFINED": "OFF", + "SANITIZE_ADDRESS": "OFF", + "USE_LIBCASSANDRA": "OFF", + "PHP_VERSION_FOR_PHP_CONFIG": "8.1", + "LINK_LIBUV_STATIC": "ON", + "PHP_DRIVER_STATIC": "ON", + "PHP_THREAD_SAFE": "ON" + } + }, + { + "name": "DebugPHP8.1NTS", + "displayName": "DebugPHP8.1NTS", + "description": "", + "generator": "Ninja", + "binaryDir": "./out/DebugPHP8.1NTS", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "CMAKE_INSTALL_PREFIX": "./out/install/DebugPHP8.1NTS", + "ENABLE_SANITIZERS": "OFF", + "SANITIZE_UNDEFINED": "OFF", + "SANITIZE_ADDRESS": "OFF", + "USE_LIBCASSANDRA": "OFF", + "PHP_VERSION_FOR_PHP_CONFIG": "8.1", + "LINK_LIBUV_STATIC": "ON", + "PHP_DRIVER_STATIC": "ON", + "PHP_THREAD_SAFE": "OFF" + } + }, + { + "name": "DebugPHP8.2ZTS", + "displayName": "DebugPHP8.2ZTS", + "description": "", + "generator": "Ninja", + "binaryDir": "./out/DebugPHP8.2ZTS", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "CMAKE_INSTALL_PREFIX": "./out/install/DebugPHP8.2ZTS", + "ENABLE_SANITIZERS": "OFF", + "SANITIZE_UNDEFINED": "OFF", + "SANITIZE_ADDRESS": "OFF", + "USE_LIBCASSANDRA": "OFF", + "PHP_VERSION_FOR_PHP_CONFIG": "8.2", + "LINK_LIBUV_STATIC": "ON", + "PHP_DRIVER_STATIC": "ON", + "PHP_THREAD_SAFE": "ON" + } + }, + { + "name": "DebugPHP8.2NTS", + "displayName": "DebugPHP8.2NTS", + "description": "", + "generator": "Ninja", + "binaryDir": "./out/DebugPHP8.2NTS", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "CMAKE_INSTALL_PREFIX": "./out/install/DebugPHP8.2NTS", + "ENABLE_SANITIZERS": "OFF", + "SANITIZE_UNDEFINED": "OFF", + "SANITIZE_ADDRESS": "OFF", + "USE_LIBCASSANDRA": "OFF", + "PHP_VERSION_FOR_PHP_CONFIG": "8.2", + "LINK_LIBUV_STATIC": "ON", + "PHP_DRIVER_STATIC": "ON", + "PHP_THREAD_SAFE": "OFF" + } + }, + { + "name": "DebugPHP8.3ZTS", + "displayName": "DebugPHP8.3ZTS", + "description": "", + "generator": "Ninja", + "binaryDir": "./out/DebugPHP8.3ZTS", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "CMAKE_INSTALL_PREFIX": "./out/install/DebugPHP8.3ZTS", + "ENABLE_SANITIZERS": "OFF", + "SANITIZE_UNDEFINED": "OFF", + "SANITIZE_ADDRESS": "OFF", + "USE_LIBCASSANDRA": "OFF", + "PHP_VERSION_FOR_PHP_CONFIG": "8.3", + "LINK_LIBUV_STATIC": "ON", + "PHP_DRIVER_STATIC": "ON", + "PHP_THREAD_SAFE": "ON" + } + }, + { + "name": "DebugPHP8.3NTS", + "displayName": "DebugPHP8.3NTS", + "description": "", + "generator": "Ninja", + "binaryDir": "./out/DebugPHP8.3NTS", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "CMAKE_INSTALL_PREFIX": "./out/install/DebugPHP8.3NTS", + "ENABLE_SANITIZERS": "OFF", + "SANITIZE_UNDEFINED": "OFF", + "SANITIZE_ADDRESS": "OFF", + "USE_LIBCASSANDRA": "OFF", + "PHP_VERSION_FOR_PHP_CONFIG": "8.3", + "LINK_LIBUV_STATIC": "ON", + "PHP_DRIVER_STATIC": "ON", + "PHP_THREAD_SAFE": "OFF" + } + }, + { + "name": "DebugPHP8.4ZTS", + "displayName": "DebugPHP8.4ZTS", + "description": "", + "generator": "Ninja", + "binaryDir": "./out/DebugPHP8.4ZTS", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "CMAKE_INSTALL_PREFIX": "./out/install/DebugPHP8.4ZTS", + "ENABLE_SANITIZERS": "OFF", + "SANITIZE_UNDEFINED": "OFF", + "SANITIZE_ADDRESS": "OFF", + "USE_LIBCASSANDRA": "OFF", + "PHP_VERSION_FOR_PHP_CONFIG": "8.4", + "LINK_LIBUV_STATIC": "ON", + "PHP_DRIVER_STATIC": "ON", + "PHP_THREAD_SAFE": "ON" + } + }, + { + "name": "DebugPHP8.4NTS", + "displayName": "DebugPHP8.4NTS", + "description": "", + "generator": "Ninja", + "binaryDir": "./out/DebugPHP8.4NTS", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "CMAKE_INSTALL_PREFIX": "./out/install/DebugPHP8.4NTS", + "ENABLE_SANITIZERS": "OFF", + "SANITIZE_UNDEFINED": "OFF", + "SANITIZE_ADDRESS": "OFF", + "USE_LIBCASSANDRA": "OFF", + "PHP_VERSION_FOR_PHP_CONFIG": "8.4", + "LINK_LIBUV_STATIC": "ON", + "PHP_DRIVER_STATIC": "ON", + "PHP_THREAD_SAFE": "OFF" + } + }, + { + "name": "DebugPHP8.1ZTS", + "displayName": "DebugPHP8.1ZTS", + "description": "", + "generator": "Ninja", + "binaryDir": "./out/DebugPHP8.1ZTS", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "CMAKE_INSTALL_PREFIX": "./out/install/DebugPHP8.1ZTS", + "ENABLE_SANITIZERS": "OFF", + "SANITIZE_UNDEFINED": "OFF", + "SANITIZE_ADDRESS": "OFF", + "USE_LIBCASSANDRA": "OFF", + "PHP_VERSION_FOR_PHP_CONFIG": "8.1", + "LINK_LIBUV_STATIC": "ON", + "PHP_DRIVER_STATIC": "ON", + "PHP_THREAD_SAFE": "ON" + } + }, + { + "name": "DebugPHP8.1NTS", + "displayName": "DebugPHP8.1NTS", + "description": "", + "generator": "Ninja", + "binaryDir": "./out/DebugPHP8.1NTS", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "CMAKE_INSTALL_PREFIX": "./out/install/DebugPHP8.1NTS", + "ENABLE_SANITIZERS": "OFF", + "SANITIZE_UNDEFINED": "OFF", + "SANITIZE_ADDRESS": "OFF", + "USE_LIBCASSANDRA": "OFF", + "PHP_VERSION_FOR_PHP_CONFIG": "8.1", + "LINK_LIBUV_STATIC": "ON", + "PHP_DRIVER_STATIC": "ON", + "PHP_THREAD_SAFE": "OFF" + } + }, + { + "name": "DebugPHP8.2ZTS", + "displayName": "DebugPHP8.2ZTS", + "description": "", + "generator": "Ninja", + "binaryDir": "./out/DebugPHP8.2ZTS", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "CMAKE_INSTALL_PREFIX": "./out/install/DebugPHP8.2ZTS", + "ENABLE_SANITIZERS": "OFF", + "SANITIZE_UNDEFINED": "OFF", + "SANITIZE_ADDRESS": "OFF", + "USE_LIBCASSANDRA": "OFF", + "PHP_VERSION_FOR_PHP_CONFIG": "8.2", + "LINK_LIBUV_STATIC": "ON", + "PHP_DRIVER_STATIC": "ON", + "PHP_THREAD_SAFE": "ON" + } + }, + { + "name": "DebugPHP8.2NTS", + "displayName": "DebugPHP8.2NTS", + "description": "", + "generator": "Ninja", + "binaryDir": "./out/DebugPHP8.2NTS", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "CMAKE_INSTALL_PREFIX": "./out/install/DebugPHP8.2NTS", + "ENABLE_SANITIZERS": "OFF", + "SANITIZE_UNDEFINED": "OFF", + "SANITIZE_ADDRESS": "OFF", + "USE_LIBCASSANDRA": "OFF", + "PHP_VERSION_FOR_PHP_CONFIG": "8.2", + "LINK_LIBUV_STATIC": "ON", + "PHP_DRIVER_STATIC": "ON", + "PHP_THREAD_SAFE": "OFF" + } + }, + { + "name": "DebugPHP8.3ZTS", + "displayName": "DebugPHP8.3ZTS", + "description": "", + "generator": "Ninja", + "binaryDir": "./out/DebugPHP8.3ZTS", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "CMAKE_INSTALL_PREFIX": "./out/install/DebugPHP8.3ZTS", + "ENABLE_SANITIZERS": "OFF", + "SANITIZE_UNDEFINED": "OFF", + "SANITIZE_ADDRESS": "OFF", + "USE_LIBCASSANDRA": "OFF", + "PHP_VERSION_FOR_PHP_CONFIG": "8.3", + "LINK_LIBUV_STATIC": "ON", + "PHP_DRIVER_STATIC": "ON", + "PHP_THREAD_SAFE": "ON" + } + }, + { + "name": "DebugPHP8.3NTS", + "displayName": "DebugPHP8.3NTS", + "description": "", + "generator": "Ninja", + "binaryDir": "./out/DebugPHP8.3NTS", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "CMAKE_INSTALL_PREFIX": "./out/install/DebugPHP8.3NTS", + "ENABLE_SANITIZERS": "OFF", + "SANITIZE_UNDEFINED": "OFF", + "SANITIZE_ADDRESS": "OFF", + "USE_LIBCASSANDRA": "OFF", + "PHP_VERSION_FOR_PHP_CONFIG": "8.3", + "LINK_LIBUV_STATIC": "ON", + "PHP_DRIVER_STATIC": "ON", + "PHP_THREAD_SAFE": "OFF" + } + }, + { + "name": "DebugPHP8.4ZTS", + "displayName": "DebugPHP8.4ZTS", + "description": "", + "generator": "Ninja", + "binaryDir": "./out/DebugPHP8.4ZTS", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "CMAKE_INSTALL_PREFIX": "./out/install/DebugPHP8.4ZTS", + "ENABLE_SANITIZERS": "OFF", + "SANITIZE_UNDEFINED": "OFF", + "SANITIZE_ADDRESS": "OFF", + "USE_LIBCASSANDRA": "OFF", + "PHP_VERSION_FOR_PHP_CONFIG": "8.4", + "LINK_LIBUV_STATIC": "ON", + "PHP_DRIVER_STATIC": "ON", + "PHP_THREAD_SAFE": "ON" + } + }, + { + "name": "DebugPHP8.4NTS", + "displayName": "DebugPHP8.4NTS", + "description": "", + "generator": "Ninja", + "binaryDir": "./out/DebugPHP8.4NTS", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "CMAKE_INSTALL_PREFIX": "./out/install/DebugPHP8.4NTS", + "ENABLE_SANITIZERS": "OFF", + "SANITIZE_UNDEFINED": "OFF", + "SANITIZE_ADDRESS": "OFF", + "USE_LIBCASSANDRA": "OFF", + "PHP_VERSION_FOR_PHP_CONFIG": "8.4", + "LINK_LIBUV_STATIC": "ON", + "PHP_DRIVER_STATIC": "ON", + "PHP_THREAD_SAFE": "OFF" + } + }, + { + "name": "ReleasePHP8.1ZTSCassandra", + "displayName": "ReleasePHP8.1ZTSCassandra", + "description": "", + "generator": "Ninja", + "binaryDir": "./out/ReleasePHP8.1ZTSCassandra", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "CMAKE_INSTALL_PREFIX": "./out/install/ReleasePHP8.1ZTSCassandra", + "ENABLE_SANITIZERS": "ON", + "SANITIZE_UNDEFINED": "ON", + "SANITIZE_ADDRESS": "ON", + "USE_LIBCASSANDRA": "ON", + "PHP_VERSION_FOR_PHP_CONFIG": "8.1", + "LINK_LIBUV_STATIC": "ON", + "PHP_DRIVER_STATIC": "ON", + "PHP_THREAD_SAFE": "ON" + } + }, + { + "name": "ReleasePHP8.1NTSCassandra", + "displayName": "ReleasePHP8.1NTSCassandra", + "description": "", + "generator": "Ninja", + "binaryDir": "./out/ReleasePHP8.1NTSCassandra", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "CMAKE_INSTALL_PREFIX": "./out/install/ReleasePHP8.1NTSCassandra", + "ENABLE_SANITIZERS": "ON", + "SANITIZE_UNDEFINED": "ON", + "SANITIZE_ADDRESS": "ON", + "USE_LIBCASSANDRA": "ON", + "PHP_VERSION_FOR_PHP_CONFIG": "8.1", + "LINK_LIBUV_STATIC": "ON", + "PHP_DRIVER_STATIC": "ON", + "PHP_THREAD_SAFE": "OFF" + } + }, + { + "name": "ReleasePHP8.2ZTSCassandra", + "displayName": "ReleasePHP8.2ZTSCassandra", + "description": "", + "generator": "Ninja", + "binaryDir": "./out/ReleasePHP8.2ZTSCassandra", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "CMAKE_INSTALL_PREFIX": "./out/install/ReleasePHP8.2ZTSCassandra", + "ENABLE_SANITIZERS": "ON", + "SANITIZE_UNDEFINED": "ON", + "SANITIZE_ADDRESS": "ON", + "USE_LIBCASSANDRA": "ON", + "PHP_VERSION_FOR_PHP_CONFIG": "8.2", + "LINK_LIBUV_STATIC": "ON", + "PHP_DRIVER_STATIC": "ON", + "PHP_THREAD_SAFE": "ON" + } + }, + { + "name": "ReleasePHP8.2NTSCassandra", + "displayName": "ReleasePHP8.2NTSCassandra", + "description": "", + "generator": "Ninja", + "binaryDir": "./out/ReleasePHP8.2NTSCassandra", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "CMAKE_INSTALL_PREFIX": "./out/install/ReleasePHP8.2NTSCassandra", + "ENABLE_SANITIZERS": "ON", + "SANITIZE_UNDEFINED": "ON", + "SANITIZE_ADDRESS": "ON", + "USE_LIBCASSANDRA": "ON", + "PHP_VERSION_FOR_PHP_CONFIG": "8.2", + "LINK_LIBUV_STATIC": "ON", + "PHP_DRIVER_STATIC": "ON", + "PHP_THREAD_SAFE": "OFF" + } + }, + { + "name": "ReleasePHP8.3ZTSCassandra", + "displayName": "ReleasePHP8.3ZTSCassandra", + "description": "", + "generator": "Ninja", + "binaryDir": "./out/ReleasePHP8.3ZTSCassandra", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "CMAKE_INSTALL_PREFIX": "./out/install/ReleasePHP8.3ZTSCassandra", + "ENABLE_SANITIZERS": "ON", + "SANITIZE_UNDEFINED": "ON", + "SANITIZE_ADDRESS": "ON", + "USE_LIBCASSANDRA": "ON", + "PHP_VERSION_FOR_PHP_CONFIG": "8.3", + "LINK_LIBUV_STATIC": "ON", + "PHP_DRIVER_STATIC": "ON", + "PHP_THREAD_SAFE": "ON" + } + }, + { + "name": "ReleasePHP8.3NTSCassandra", + "displayName": "ReleasePHP8.3NTSCassandra", + "description": "", + "generator": "Ninja", + "binaryDir": "./out/ReleasePHP8.3NTSCassandra", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "CMAKE_INSTALL_PREFIX": "./out/install/ReleasePHP8.3NTSCassandra", + "ENABLE_SANITIZERS": "ON", + "SANITIZE_UNDEFINED": "ON", + "SANITIZE_ADDRESS": "ON", + "USE_LIBCASSANDRA": "ON", + "PHP_VERSION_FOR_PHP_CONFIG": "8.3", + "LINK_LIBUV_STATIC": "ON", + "PHP_DRIVER_STATIC": "ON", + "PHP_THREAD_SAFE": "OFF" + } + }, + { + "name": "ReleasePHP8.4ZTSCassandra", + "displayName": "ReleasePHP8.4ZTSCassandra", + "description": "", + "generator": "Ninja", + "binaryDir": "./out/ReleasePHP8.4ZTSCassandra", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "CMAKE_INSTALL_PREFIX": "./out/install/ReleasePHP8.4ZTSCassandra", + "ENABLE_SANITIZERS": "ON", + "SANITIZE_UNDEFINED": "ON", + "SANITIZE_ADDRESS": "ON", + "USE_LIBCASSANDRA": "ON", + "PHP_VERSION_FOR_PHP_CONFIG": "8.4", + "LINK_LIBUV_STATIC": "ON", + "PHP_DRIVER_STATIC": "ON", + "PHP_THREAD_SAFE": "ON" + } + }, + { + "name": "ReleasePHP8.4NTSCassandra", + "displayName": "ReleasePHP8.4NTSCassandra", + "description": "", + "generator": "Ninja", + "binaryDir": "./out/ReleasePHP8.4NTSCassandra", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "CMAKE_INSTALL_PREFIX": "./out/install/ReleasePHP8.4NTSCassandra", + "ENABLE_SANITIZERS": "ON", + "SANITIZE_UNDEFINED": "ON", + "SANITIZE_ADDRESS": "ON", + "USE_LIBCASSANDRA": "ON", + "PHP_VERSION_FOR_PHP_CONFIG": "8.4", + "LINK_LIBUV_STATIC": "ON", + "PHP_DRIVER_STATIC": "ON", + "PHP_THREAD_SAFE": "OFF" + } + }, + { + "name": "ReleasePHP8.1ZTSCassandra", + "displayName": "ReleasePHP8.1ZTSCassandra", + "description": "", + "generator": "Ninja", + "binaryDir": "./out/ReleasePHP8.1ZTSCassandra", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "CMAKE_INSTALL_PREFIX": "./out/install/ReleasePHP8.1ZTSCassandra", + "ENABLE_SANITIZERS": "OFF", + "SANITIZE_UNDEFINED": "OFF", + "SANITIZE_ADDRESS": "OFF", + "USE_LIBCASSANDRA": "ON", + "PHP_VERSION_FOR_PHP_CONFIG": "8.1", + "LINK_LIBUV_STATIC": "ON", + "PHP_DRIVER_STATIC": "ON", + "PHP_THREAD_SAFE": "ON" + } + }, + { + "name": "ReleasePHP8.1NTSCassandra", + "displayName": "ReleasePHP8.1NTSCassandra", + "description": "", + "generator": "Ninja", + "binaryDir": "./out/ReleasePHP8.1NTSCassandra", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "CMAKE_INSTALL_PREFIX": "./out/install/ReleasePHP8.1NTSCassandra", + "ENABLE_SANITIZERS": "OFF", + "SANITIZE_UNDEFINED": "OFF", + "SANITIZE_ADDRESS": "OFF", + "USE_LIBCASSANDRA": "ON", + "PHP_VERSION_FOR_PHP_CONFIG": "8.1", + "LINK_LIBUV_STATIC": "ON", + "PHP_DRIVER_STATIC": "ON", + "PHP_THREAD_SAFE": "OFF" + } + }, + { + "name": "ReleasePHP8.2ZTSCassandra", + "displayName": "ReleasePHP8.2ZTSCassandra", + "description": "", + "generator": "Ninja", + "binaryDir": "./out/ReleasePHP8.2ZTSCassandra", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "CMAKE_INSTALL_PREFIX": "./out/install/ReleasePHP8.2ZTSCassandra", + "ENABLE_SANITIZERS": "OFF", + "SANITIZE_UNDEFINED": "OFF", + "SANITIZE_ADDRESS": "OFF", + "USE_LIBCASSANDRA": "ON", + "PHP_VERSION_FOR_PHP_CONFIG": "8.2", + "LINK_LIBUV_STATIC": "ON", + "PHP_DRIVER_STATIC": "ON", + "PHP_THREAD_SAFE": "ON" + } + }, + { + "name": "ReleasePHP8.2NTSCassandra", + "displayName": "ReleasePHP8.2NTSCassandra", + "description": "", + "generator": "Ninja", + "binaryDir": "./out/ReleasePHP8.2NTSCassandra", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "CMAKE_INSTALL_PREFIX": "./out/install/ReleasePHP8.2NTSCassandra", + "ENABLE_SANITIZERS": "OFF", + "SANITIZE_UNDEFINED": "OFF", + "SANITIZE_ADDRESS": "OFF", + "USE_LIBCASSANDRA": "ON", + "PHP_VERSION_FOR_PHP_CONFIG": "8.2", + "LINK_LIBUV_STATIC": "ON", + "PHP_DRIVER_STATIC": "ON", + "PHP_THREAD_SAFE": "OFF" + } + }, + { + "name": "ReleasePHP8.3ZTSCassandra", + "displayName": "ReleasePHP8.3ZTSCassandra", + "description": "", + "generator": "Ninja", + "binaryDir": "./out/ReleasePHP8.3ZTSCassandra", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "CMAKE_INSTALL_PREFIX": "./out/install/ReleasePHP8.3ZTSCassandra", + "ENABLE_SANITIZERS": "OFF", + "SANITIZE_UNDEFINED": "OFF", + "SANITIZE_ADDRESS": "OFF", + "USE_LIBCASSANDRA": "ON", + "PHP_VERSION_FOR_PHP_CONFIG": "8.3", + "LINK_LIBUV_STATIC": "ON", + "PHP_DRIVER_STATIC": "ON", + "PHP_THREAD_SAFE": "ON" + } + }, + { + "name": "ReleasePHP8.3NTSCassandra", + "displayName": "ReleasePHP8.3NTSCassandra", + "description": "", + "generator": "Ninja", + "binaryDir": "./out/ReleasePHP8.3NTSCassandra", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "CMAKE_INSTALL_PREFIX": "./out/install/ReleasePHP8.3NTSCassandra", + "ENABLE_SANITIZERS": "OFF", + "SANITIZE_UNDEFINED": "OFF", + "SANITIZE_ADDRESS": "OFF", + "USE_LIBCASSANDRA": "ON", + "PHP_VERSION_FOR_PHP_CONFIG": "8.3", + "LINK_LIBUV_STATIC": "ON", + "PHP_DRIVER_STATIC": "ON", + "PHP_THREAD_SAFE": "OFF" + } + }, + { + "name": "ReleasePHP8.4ZTSCassandra", + "displayName": "ReleasePHP8.4ZTSCassandra", + "description": "", + "generator": "Ninja", + "binaryDir": "./out/ReleasePHP8.4ZTSCassandra", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "CMAKE_INSTALL_PREFIX": "./out/install/ReleasePHP8.4ZTSCassandra", + "ENABLE_SANITIZERS": "OFF", + "SANITIZE_UNDEFINED": "OFF", + "SANITIZE_ADDRESS": "OFF", + "USE_LIBCASSANDRA": "ON", + "PHP_VERSION_FOR_PHP_CONFIG": "8.4", + "LINK_LIBUV_STATIC": "ON", + "PHP_DRIVER_STATIC": "ON", + "PHP_THREAD_SAFE": "ON" + } + }, + { + "name": "ReleasePHP8.4NTSCassandra", + "displayName": "ReleasePHP8.4NTSCassandra", + "description": "", + "generator": "Ninja", + "binaryDir": "./out/ReleasePHP8.4NTSCassandra", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "CMAKE_INSTALL_PREFIX": "./out/install/ReleasePHP8.4NTSCassandra", + "ENABLE_SANITIZERS": "OFF", + "SANITIZE_UNDEFINED": "OFF", + "SANITIZE_ADDRESS": "OFF", + "USE_LIBCASSANDRA": "ON", + "PHP_VERSION_FOR_PHP_CONFIG": "8.4", + "LINK_LIBUV_STATIC": "ON", + "PHP_DRIVER_STATIC": "ON", + "PHP_THREAD_SAFE": "OFF" + } + }, + { + "name": "ReleasePHP8.1ZTSCassandra", + "displayName": "ReleasePHP8.1ZTSCassandra", + "description": "", + "generator": "Ninja", + "binaryDir": "./out/ReleasePHP8.1ZTSCassandra", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "CMAKE_INSTALL_PREFIX": "./out/install/ReleasePHP8.1ZTSCassandra", + "ENABLE_SANITIZERS": "OFF", + "SANITIZE_UNDEFINED": "OFF", + "SANITIZE_ADDRESS": "OFF", + "USE_LIBCASSANDRA": "ON", + "PHP_VERSION_FOR_PHP_CONFIG": "8.1", + "LINK_LIBUV_STATIC": "ON", + "PHP_DRIVER_STATIC": "ON", + "PHP_THREAD_SAFE": "ON" + } + }, + { + "name": "ReleasePHP8.1NTSCassandra", + "displayName": "ReleasePHP8.1NTSCassandra", + "description": "", + "generator": "Ninja", + "binaryDir": "./out/ReleasePHP8.1NTSCassandra", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "CMAKE_INSTALL_PREFIX": "./out/install/ReleasePHP8.1NTSCassandra", + "ENABLE_SANITIZERS": "OFF", + "SANITIZE_UNDEFINED": "OFF", + "SANITIZE_ADDRESS": "OFF", + "USE_LIBCASSANDRA": "ON", + "PHP_VERSION_FOR_PHP_CONFIG": "8.1", + "LINK_LIBUV_STATIC": "ON", + "PHP_DRIVER_STATIC": "ON", + "PHP_THREAD_SAFE": "OFF" + } + }, + { + "name": "ReleasePHP8.2ZTSCassandra", + "displayName": "ReleasePHP8.2ZTSCassandra", + "description": "", + "generator": "Ninja", + "binaryDir": "./out/ReleasePHP8.2ZTSCassandra", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "CMAKE_INSTALL_PREFIX": "./out/install/ReleasePHP8.2ZTSCassandra", + "ENABLE_SANITIZERS": "OFF", + "SANITIZE_UNDEFINED": "OFF", + "SANITIZE_ADDRESS": "OFF", + "USE_LIBCASSANDRA": "ON", + "PHP_VERSION_FOR_PHP_CONFIG": "8.2", + "LINK_LIBUV_STATIC": "ON", + "PHP_DRIVER_STATIC": "ON", + "PHP_THREAD_SAFE": "ON" + } + }, + { + "name": "ReleasePHP8.2NTSCassandra", + "displayName": "ReleasePHP8.2NTSCassandra", + "description": "", + "generator": "Ninja", + "binaryDir": "./out/ReleasePHP8.2NTSCassandra", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "CMAKE_INSTALL_PREFIX": "./out/install/ReleasePHP8.2NTSCassandra", + "ENABLE_SANITIZERS": "OFF", + "SANITIZE_UNDEFINED": "OFF", + "SANITIZE_ADDRESS": "OFF", + "USE_LIBCASSANDRA": "ON", + "PHP_VERSION_FOR_PHP_CONFIG": "8.2", + "LINK_LIBUV_STATIC": "ON", + "PHP_DRIVER_STATIC": "ON", + "PHP_THREAD_SAFE": "OFF" + } + }, + { + "name": "ReleasePHP8.3ZTSCassandra", + "displayName": "ReleasePHP8.3ZTSCassandra", + "description": "", + "generator": "Ninja", + "binaryDir": "./out/ReleasePHP8.3ZTSCassandra", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "CMAKE_INSTALL_PREFIX": "./out/install/ReleasePHP8.3ZTSCassandra", + "ENABLE_SANITIZERS": "OFF", + "SANITIZE_UNDEFINED": "OFF", + "SANITIZE_ADDRESS": "OFF", + "USE_LIBCASSANDRA": "ON", + "PHP_VERSION_FOR_PHP_CONFIG": "8.3", + "LINK_LIBUV_STATIC": "ON", + "PHP_DRIVER_STATIC": "ON", + "PHP_THREAD_SAFE": "ON" + } + }, + { + "name": "ReleasePHP8.3NTSCassandra", + "displayName": "ReleasePHP8.3NTSCassandra", + "description": "", + "generator": "Ninja", + "binaryDir": "./out/ReleasePHP8.3NTSCassandra", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "CMAKE_INSTALL_PREFIX": "./out/install/ReleasePHP8.3NTSCassandra", + "ENABLE_SANITIZERS": "OFF", + "SANITIZE_UNDEFINED": "OFF", + "SANITIZE_ADDRESS": "OFF", + "USE_LIBCASSANDRA": "ON", + "PHP_VERSION_FOR_PHP_CONFIG": "8.3", + "LINK_LIBUV_STATIC": "ON", + "PHP_DRIVER_STATIC": "ON", + "PHP_THREAD_SAFE": "OFF" + } + }, + { + "name": "ReleasePHP8.4ZTSCassandra", + "displayName": "ReleasePHP8.4ZTSCassandra", + "description": "", + "generator": "Ninja", + "binaryDir": "./out/ReleasePHP8.4ZTSCassandra", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "CMAKE_INSTALL_PREFIX": "./out/install/ReleasePHP8.4ZTSCassandra", + "ENABLE_SANITIZERS": "OFF", + "SANITIZE_UNDEFINED": "OFF", + "SANITIZE_ADDRESS": "OFF", + "USE_LIBCASSANDRA": "ON", + "PHP_VERSION_FOR_PHP_CONFIG": "8.4", + "LINK_LIBUV_STATIC": "ON", + "PHP_DRIVER_STATIC": "ON", + "PHP_THREAD_SAFE": "ON" + } + }, + { + "name": "ReleasePHP8.4NTSCassandra", + "displayName": "ReleasePHP8.4NTSCassandra", + "description": "", + "generator": "Ninja", + "binaryDir": "./out/ReleasePHP8.4NTSCassandra", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "CMAKE_INSTALL_PREFIX": "./out/install/ReleasePHP8.4NTSCassandra", + "ENABLE_SANITIZERS": "OFF", + "SANITIZE_UNDEFINED": "OFF", + "SANITIZE_ADDRESS": "OFF", + "USE_LIBCASSANDRA": "ON", + "PHP_VERSION_FOR_PHP_CONFIG": "8.4", + "LINK_LIBUV_STATIC": "ON", + "PHP_DRIVER_STATIC": "ON", + "PHP_THREAD_SAFE": "OFF" + } + }, + { + "name": "ReleasePHP8.1ZTS", + "displayName": "ReleasePHP8.1ZTS", + "description": "", + "generator": "Ninja", + "binaryDir": "./out/ReleasePHP8.1ZTS", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "CMAKE_INSTALL_PREFIX": "./out/install/ReleasePHP8.1ZTS", + "ENABLE_SANITIZERS": "ON", + "SANITIZE_UNDEFINED": "ON", + "SANITIZE_ADDRESS": "ON", + "USE_LIBCASSANDRA": "OFF", + "PHP_VERSION_FOR_PHP_CONFIG": "8.1", + "LINK_LIBUV_STATIC": "ON", + "PHP_DRIVER_STATIC": "ON", + "PHP_THREAD_SAFE": "ON" + } + }, + { + "name": "ReleasePHP8.1NTS", + "displayName": "ReleasePHP8.1NTS", + "description": "", + "generator": "Ninja", + "binaryDir": "./out/ReleasePHP8.1NTS", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "CMAKE_INSTALL_PREFIX": "./out/install/ReleasePHP8.1NTS", + "ENABLE_SANITIZERS": "ON", + "SANITIZE_UNDEFINED": "ON", + "SANITIZE_ADDRESS": "ON", + "USE_LIBCASSANDRA": "OFF", + "PHP_VERSION_FOR_PHP_CONFIG": "8.1", + "LINK_LIBUV_STATIC": "ON", + "PHP_DRIVER_STATIC": "ON", + "PHP_THREAD_SAFE": "OFF" + } + }, + { + "name": "ReleasePHP8.2ZTS", + "displayName": "ReleasePHP8.2ZTS", + "description": "", + "generator": "Ninja", + "binaryDir": "./out/ReleasePHP8.2ZTS", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "CMAKE_INSTALL_PREFIX": "./out/install/ReleasePHP8.2ZTS", + "ENABLE_SANITIZERS": "ON", + "SANITIZE_UNDEFINED": "ON", + "SANITIZE_ADDRESS": "ON", + "USE_LIBCASSANDRA": "OFF", + "PHP_VERSION_FOR_PHP_CONFIG": "8.2", + "LINK_LIBUV_STATIC": "ON", + "PHP_DRIVER_STATIC": "ON", + "PHP_THREAD_SAFE": "ON" + } + }, + { + "name": "ReleasePHP8.2NTS", + "displayName": "ReleasePHP8.2NTS", + "description": "", + "generator": "Ninja", + "binaryDir": "./out/ReleasePHP8.2NTS", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "CMAKE_INSTALL_PREFIX": "./out/install/ReleasePHP8.2NTS", + "ENABLE_SANITIZERS": "ON", + "SANITIZE_UNDEFINED": "ON", + "SANITIZE_ADDRESS": "ON", + "USE_LIBCASSANDRA": "OFF", + "PHP_VERSION_FOR_PHP_CONFIG": "8.2", + "LINK_LIBUV_STATIC": "ON", + "PHP_DRIVER_STATIC": "ON", + "PHP_THREAD_SAFE": "OFF" + } + }, + { + "name": "ReleasePHP8.3ZTS", + "displayName": "ReleasePHP8.3ZTS", + "description": "", + "generator": "Ninja", + "binaryDir": "./out/ReleasePHP8.3ZTS", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "CMAKE_INSTALL_PREFIX": "./out/install/ReleasePHP8.3ZTS", + "ENABLE_SANITIZERS": "ON", + "SANITIZE_UNDEFINED": "ON", + "SANITIZE_ADDRESS": "ON", + "USE_LIBCASSANDRA": "OFF", + "PHP_VERSION_FOR_PHP_CONFIG": "8.3", + "LINK_LIBUV_STATIC": "ON", + "PHP_DRIVER_STATIC": "ON", + "PHP_THREAD_SAFE": "ON" + } + }, + { + "name": "ReleasePHP8.3NTS", + "displayName": "ReleasePHP8.3NTS", + "description": "", + "generator": "Ninja", + "binaryDir": "./out/ReleasePHP8.3NTS", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "CMAKE_INSTALL_PREFIX": "./out/install/ReleasePHP8.3NTS", + "ENABLE_SANITIZERS": "ON", + "SANITIZE_UNDEFINED": "ON", + "SANITIZE_ADDRESS": "ON", + "USE_LIBCASSANDRA": "OFF", + "PHP_VERSION_FOR_PHP_CONFIG": "8.3", + "LINK_LIBUV_STATIC": "ON", + "PHP_DRIVER_STATIC": "ON", + "PHP_THREAD_SAFE": "OFF" + } + }, + { + "name": "ReleasePHP8.4ZTS", + "displayName": "ReleasePHP8.4ZTS", + "description": "", + "generator": "Ninja", + "binaryDir": "./out/ReleasePHP8.4ZTS", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "CMAKE_INSTALL_PREFIX": "./out/install/ReleasePHP8.4ZTS", + "ENABLE_SANITIZERS": "ON", + "SANITIZE_UNDEFINED": "ON", + "SANITIZE_ADDRESS": "ON", + "USE_LIBCASSANDRA": "OFF", + "PHP_VERSION_FOR_PHP_CONFIG": "8.4", + "LINK_LIBUV_STATIC": "ON", + "PHP_DRIVER_STATIC": "ON", + "PHP_THREAD_SAFE": "ON" + } + }, + { + "name": "ReleasePHP8.4NTS", + "displayName": "ReleasePHP8.4NTS", + "description": "", + "generator": "Ninja", + "binaryDir": "./out/ReleasePHP8.4NTS", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "CMAKE_INSTALL_PREFIX": "./out/install/ReleasePHP8.4NTS", + "ENABLE_SANITIZERS": "ON", + "SANITIZE_UNDEFINED": "ON", + "SANITIZE_ADDRESS": "ON", + "USE_LIBCASSANDRA": "OFF", + "PHP_VERSION_FOR_PHP_CONFIG": "8.4", + "LINK_LIBUV_STATIC": "ON", + "PHP_DRIVER_STATIC": "ON", + "PHP_THREAD_SAFE": "OFF" + } + }, + { + "name": "ReleasePHP8.1ZTS", + "displayName": "ReleasePHP8.1ZTS", + "description": "", + "generator": "Ninja", + "binaryDir": "./out/ReleasePHP8.1ZTS", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "CMAKE_INSTALL_PREFIX": "./out/install/ReleasePHP8.1ZTS", + "ENABLE_SANITIZERS": "OFF", + "SANITIZE_UNDEFINED": "OFF", + "SANITIZE_ADDRESS": "OFF", + "USE_LIBCASSANDRA": "OFF", + "PHP_VERSION_FOR_PHP_CONFIG": "8.1", + "LINK_LIBUV_STATIC": "ON", + "PHP_DRIVER_STATIC": "ON", + "PHP_THREAD_SAFE": "ON" + } + }, + { + "name": "ReleasePHP8.1NTS", + "displayName": "ReleasePHP8.1NTS", + "description": "", + "generator": "Ninja", + "binaryDir": "./out/ReleasePHP8.1NTS", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "CMAKE_INSTALL_PREFIX": "./out/install/ReleasePHP8.1NTS", + "ENABLE_SANITIZERS": "OFF", + "SANITIZE_UNDEFINED": "OFF", + "SANITIZE_ADDRESS": "OFF", + "USE_LIBCASSANDRA": "OFF", + "PHP_VERSION_FOR_PHP_CONFIG": "8.1", + "LINK_LIBUV_STATIC": "ON", + "PHP_DRIVER_STATIC": "ON", + "PHP_THREAD_SAFE": "OFF" + } + }, + { + "name": "ReleasePHP8.2ZTS", + "displayName": "ReleasePHP8.2ZTS", + "description": "", + "generator": "Ninja", + "binaryDir": "./out/ReleasePHP8.2ZTS", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "CMAKE_INSTALL_PREFIX": "./out/install/ReleasePHP8.2ZTS", + "ENABLE_SANITIZERS": "OFF", + "SANITIZE_UNDEFINED": "OFF", + "SANITIZE_ADDRESS": "OFF", + "USE_LIBCASSANDRA": "OFF", + "PHP_VERSION_FOR_PHP_CONFIG": "8.2", + "LINK_LIBUV_STATIC": "ON", + "PHP_DRIVER_STATIC": "ON", + "PHP_THREAD_SAFE": "ON" + } + }, + { + "name": "ReleasePHP8.2NTS", + "displayName": "ReleasePHP8.2NTS", + "description": "", + "generator": "Ninja", + "binaryDir": "./out/ReleasePHP8.2NTS", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "CMAKE_INSTALL_PREFIX": "./out/install/ReleasePHP8.2NTS", + "ENABLE_SANITIZERS": "OFF", + "SANITIZE_UNDEFINED": "OFF", + "SANITIZE_ADDRESS": "OFF", + "USE_LIBCASSANDRA": "OFF", + "PHP_VERSION_FOR_PHP_CONFIG": "8.2", + "LINK_LIBUV_STATIC": "ON", + "PHP_DRIVER_STATIC": "ON", + "PHP_THREAD_SAFE": "OFF" + } + }, + { + "name": "ReleasePHP8.3ZTS", + "displayName": "ReleasePHP8.3ZTS", + "description": "", + "generator": "Ninja", + "binaryDir": "./out/ReleasePHP8.3ZTS", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "CMAKE_INSTALL_PREFIX": "./out/install/ReleasePHP8.3ZTS", + "ENABLE_SANITIZERS": "OFF", + "SANITIZE_UNDEFINED": "OFF", + "SANITIZE_ADDRESS": "OFF", + "USE_LIBCASSANDRA": "OFF", + "PHP_VERSION_FOR_PHP_CONFIG": "8.3", + "LINK_LIBUV_STATIC": "ON", + "PHP_DRIVER_STATIC": "ON", + "PHP_THREAD_SAFE": "ON" + } + }, + { + "name": "ReleasePHP8.3NTS", + "displayName": "ReleasePHP8.3NTS", + "description": "", + "generator": "Ninja", + "binaryDir": "./out/ReleasePHP8.3NTS", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "CMAKE_INSTALL_PREFIX": "./out/install/ReleasePHP8.3NTS", + "ENABLE_SANITIZERS": "OFF", + "SANITIZE_UNDEFINED": "OFF", + "SANITIZE_ADDRESS": "OFF", + "USE_LIBCASSANDRA": "OFF", + "PHP_VERSION_FOR_PHP_CONFIG": "8.3", + "LINK_LIBUV_STATIC": "ON", + "PHP_DRIVER_STATIC": "ON", + "PHP_THREAD_SAFE": "OFF" + } + }, + { + "name": "ReleasePHP8.4ZTS", + "displayName": "ReleasePHP8.4ZTS", + "description": "", + "generator": "Ninja", + "binaryDir": "./out/ReleasePHP8.4ZTS", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "CMAKE_INSTALL_PREFIX": "./out/install/ReleasePHP8.4ZTS", + "ENABLE_SANITIZERS": "OFF", + "SANITIZE_UNDEFINED": "OFF", + "SANITIZE_ADDRESS": "OFF", + "USE_LIBCASSANDRA": "OFF", + "PHP_VERSION_FOR_PHP_CONFIG": "8.4", + "LINK_LIBUV_STATIC": "ON", + "PHP_DRIVER_STATIC": "ON", + "PHP_THREAD_SAFE": "ON" + } + }, + { + "name": "ReleasePHP8.4NTS", + "displayName": "ReleasePHP8.4NTS", + "description": "", + "generator": "Ninja", + "binaryDir": "./out/ReleasePHP8.4NTS", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "CMAKE_INSTALL_PREFIX": "./out/install/ReleasePHP8.4NTS", + "ENABLE_SANITIZERS": "OFF", + "SANITIZE_UNDEFINED": "OFF", + "SANITIZE_ADDRESS": "OFF", + "USE_LIBCASSANDRA": "OFF", + "PHP_VERSION_FOR_PHP_CONFIG": "8.4", + "LINK_LIBUV_STATIC": "ON", + "PHP_DRIVER_STATIC": "ON", + "PHP_THREAD_SAFE": "OFF" + } + }, + { + "name": "ReleasePHP8.1ZTS", + "displayName": "ReleasePHP8.1ZTS", + "description": "", + "generator": "Ninja", + "binaryDir": "./out/ReleasePHP8.1ZTS", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "CMAKE_INSTALL_PREFIX": "./out/install/ReleasePHP8.1ZTS", + "ENABLE_SANITIZERS": "OFF", + "SANITIZE_UNDEFINED": "OFF", + "SANITIZE_ADDRESS": "OFF", + "USE_LIBCASSANDRA": "OFF", + "PHP_VERSION_FOR_PHP_CONFIG": "8.1", + "LINK_LIBUV_STATIC": "ON", + "PHP_DRIVER_STATIC": "ON", + "PHP_THREAD_SAFE": "ON" + } + }, + { + "name": "ReleasePHP8.1NTS", + "displayName": "ReleasePHP8.1NTS", + "description": "", + "generator": "Ninja", + "binaryDir": "./out/ReleasePHP8.1NTS", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "CMAKE_INSTALL_PREFIX": "./out/install/ReleasePHP8.1NTS", + "ENABLE_SANITIZERS": "OFF", + "SANITIZE_UNDEFINED": "OFF", + "SANITIZE_ADDRESS": "OFF", + "USE_LIBCASSANDRA": "OFF", + "PHP_VERSION_FOR_PHP_CONFIG": "8.1", + "LINK_LIBUV_STATIC": "ON", + "PHP_DRIVER_STATIC": "ON", + "PHP_THREAD_SAFE": "OFF" + } + }, + { + "name": "ReleasePHP8.2ZTS", + "displayName": "ReleasePHP8.2ZTS", + "description": "", + "generator": "Ninja", + "binaryDir": "./out/ReleasePHP8.2ZTS", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "CMAKE_INSTALL_PREFIX": "./out/install/ReleasePHP8.2ZTS", + "ENABLE_SANITIZERS": "OFF", + "SANITIZE_UNDEFINED": "OFF", + "SANITIZE_ADDRESS": "OFF", + "USE_LIBCASSANDRA": "OFF", + "PHP_VERSION_FOR_PHP_CONFIG": "8.2", + "LINK_LIBUV_STATIC": "ON", + "PHP_DRIVER_STATIC": "ON", + "PHP_THREAD_SAFE": "ON" + } + }, + { + "name": "ReleasePHP8.2NTS", + "displayName": "ReleasePHP8.2NTS", + "description": "", + "generator": "Ninja", + "binaryDir": "./out/ReleasePHP8.2NTS", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "CMAKE_INSTALL_PREFIX": "./out/install/ReleasePHP8.2NTS", + "ENABLE_SANITIZERS": "OFF", + "SANITIZE_UNDEFINED": "OFF", + "SANITIZE_ADDRESS": "OFF", + "USE_LIBCASSANDRA": "OFF", + "PHP_VERSION_FOR_PHP_CONFIG": "8.2", + "LINK_LIBUV_STATIC": "ON", + "PHP_DRIVER_STATIC": "ON", + "PHP_THREAD_SAFE": "OFF" + } + }, + { + "name": "ReleasePHP8.3ZTS", + "displayName": "ReleasePHP8.3ZTS", + "description": "", + "generator": "Ninja", + "binaryDir": "./out/ReleasePHP8.3ZTS", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "CMAKE_INSTALL_PREFIX": "./out/install/ReleasePHP8.3ZTS", + "ENABLE_SANITIZERS": "OFF", + "SANITIZE_UNDEFINED": "OFF", + "SANITIZE_ADDRESS": "OFF", + "USE_LIBCASSANDRA": "OFF", + "PHP_VERSION_FOR_PHP_CONFIG": "8.3", + "LINK_LIBUV_STATIC": "ON", + "PHP_DRIVER_STATIC": "ON", + "PHP_THREAD_SAFE": "ON" + } + }, + { + "name": "ReleasePHP8.3NTS", + "displayName": "ReleasePHP8.3NTS", + "description": "", + "generator": "Ninja", + "binaryDir": "./out/ReleasePHP8.3NTS", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "CMAKE_INSTALL_PREFIX": "./out/install/ReleasePHP8.3NTS", + "ENABLE_SANITIZERS": "OFF", + "SANITIZE_UNDEFINED": "OFF", + "SANITIZE_ADDRESS": "OFF", + "USE_LIBCASSANDRA": "OFF", + "PHP_VERSION_FOR_PHP_CONFIG": "8.3", + "LINK_LIBUV_STATIC": "ON", + "PHP_DRIVER_STATIC": "ON", + "PHP_THREAD_SAFE": "OFF" + } + }, + { + "name": "ReleasePHP8.4ZTS", + "displayName": "ReleasePHP8.4ZTS", + "description": "", + "generator": "Ninja", + "binaryDir": "./out/ReleasePHP8.4ZTS", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "CMAKE_INSTALL_PREFIX": "./out/install/ReleasePHP8.4ZTS", + "ENABLE_SANITIZERS": "OFF", + "SANITIZE_UNDEFINED": "OFF", + "SANITIZE_ADDRESS": "OFF", + "USE_LIBCASSANDRA": "OFF", + "PHP_VERSION_FOR_PHP_CONFIG": "8.4", + "LINK_LIBUV_STATIC": "ON", + "PHP_DRIVER_STATIC": "ON", + "PHP_THREAD_SAFE": "ON" + } + }, + { + "name": "ReleasePHP8.4NTS", + "displayName": "ReleasePHP8.4NTS", + "description": "", + "generator": "Ninja", + "binaryDir": "./out/ReleasePHP8.4NTS", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "CMAKE_INSTALL_PREFIX": "./out/install/ReleasePHP8.4NTS", + "ENABLE_SANITIZERS": "OFF", + "SANITIZE_UNDEFINED": "OFF", + "SANITIZE_ADDRESS": "OFF", + "USE_LIBCASSANDRA": "OFF", + "PHP_VERSION_FOR_PHP_CONFIG": "8.4", + "LINK_LIBUV_STATIC": "ON", + "PHP_DRIVER_STATIC": "ON", + "PHP_THREAD_SAFE": "OFF" + } + }, + { + "name": "RelWithDebugInfoPHP8.1ZTSCassandra", + "displayName": "RelWithDebugInfoPHP8.1ZTSCassandra", + "description": "", + "generator": "Ninja", + "binaryDir": "./out/RelWithDebugInfoPHP8.1ZTSCassandra", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "CMAKE_INSTALL_PREFIX": "./out/install/RelWithDebugInfoPHP8.1ZTSCassandra", + "ENABLE_SANITIZERS": "ON", + "SANITIZE_UNDEFINED": "ON", + "SANITIZE_ADDRESS": "ON", + "USE_LIBCASSANDRA": "ON", + "PHP_VERSION_FOR_PHP_CONFIG": "8.1", + "LINK_LIBUV_STATIC": "ON", + "PHP_DRIVER_STATIC": "ON", + "PHP_THREAD_SAFE": "ON" + } + }, + { + "name": "RelWithDebugInfoPHP8.1NTSCassandra", + "displayName": "RelWithDebugInfoPHP8.1NTSCassandra", + "description": "", + "generator": "Ninja", + "binaryDir": "./out/RelWithDebugInfoPHP8.1NTSCassandra", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "CMAKE_INSTALL_PREFIX": "./out/install/RelWithDebugInfoPHP8.1NTSCassandra", + "ENABLE_SANITIZERS": "ON", + "SANITIZE_UNDEFINED": "ON", + "SANITIZE_ADDRESS": "ON", + "USE_LIBCASSANDRA": "ON", + "PHP_VERSION_FOR_PHP_CONFIG": "8.1", + "LINK_LIBUV_STATIC": "ON", + "PHP_DRIVER_STATIC": "ON", + "PHP_THREAD_SAFE": "OFF" + } + }, + { + "name": "RelWithDebugInfoPHP8.2ZTSCassandra", + "displayName": "RelWithDebugInfoPHP8.2ZTSCassandra", + "description": "", + "generator": "Ninja", + "binaryDir": "./out/RelWithDebugInfoPHP8.2ZTSCassandra", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "CMAKE_INSTALL_PREFIX": "./out/install/RelWithDebugInfoPHP8.2ZTSCassandra", + "ENABLE_SANITIZERS": "ON", + "SANITIZE_UNDEFINED": "ON", + "SANITIZE_ADDRESS": "ON", + "USE_LIBCASSANDRA": "ON", + "PHP_VERSION_FOR_PHP_CONFIG": "8.2", + "LINK_LIBUV_STATIC": "ON", + "PHP_DRIVER_STATIC": "ON", + "PHP_THREAD_SAFE": "ON" + } + }, + { + "name": "RelWithDebugInfoPHP8.2NTSCassandra", + "displayName": "RelWithDebugInfoPHP8.2NTSCassandra", + "description": "", + "generator": "Ninja", + "binaryDir": "./out/RelWithDebugInfoPHP8.2NTSCassandra", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "CMAKE_INSTALL_PREFIX": "./out/install/RelWithDebugInfoPHP8.2NTSCassandra", + "ENABLE_SANITIZERS": "ON", + "SANITIZE_UNDEFINED": "ON", + "SANITIZE_ADDRESS": "ON", + "USE_LIBCASSANDRA": "ON", + "PHP_VERSION_FOR_PHP_CONFIG": "8.2", + "LINK_LIBUV_STATIC": "ON", + "PHP_DRIVER_STATIC": "ON", + "PHP_THREAD_SAFE": "OFF" + } + }, + { + "name": "RelWithDebugInfoPHP8.3ZTSCassandra", + "displayName": "RelWithDebugInfoPHP8.3ZTSCassandra", + "description": "", + "generator": "Ninja", + "binaryDir": "./out/RelWithDebugInfoPHP8.3ZTSCassandra", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "CMAKE_INSTALL_PREFIX": "./out/install/RelWithDebugInfoPHP8.3ZTSCassandra", + "ENABLE_SANITIZERS": "ON", + "SANITIZE_UNDEFINED": "ON", + "SANITIZE_ADDRESS": "ON", + "USE_LIBCASSANDRA": "ON", + "PHP_VERSION_FOR_PHP_CONFIG": "8.3", + "LINK_LIBUV_STATIC": "ON", + "PHP_DRIVER_STATIC": "ON", + "PHP_THREAD_SAFE": "ON" + } + }, + { + "name": "RelWithDebugInfoPHP8.3NTSCassandra", + "displayName": "RelWithDebugInfoPHP8.3NTSCassandra", + "description": "", + "generator": "Ninja", + "binaryDir": "./out/RelWithDebugInfoPHP8.3NTSCassandra", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "CMAKE_INSTALL_PREFIX": "./out/install/RelWithDebugInfoPHP8.3NTSCassandra", + "ENABLE_SANITIZERS": "ON", + "SANITIZE_UNDEFINED": "ON", + "SANITIZE_ADDRESS": "ON", + "USE_LIBCASSANDRA": "ON", + "PHP_VERSION_FOR_PHP_CONFIG": "8.3", + "LINK_LIBUV_STATIC": "ON", + "PHP_DRIVER_STATIC": "ON", + "PHP_THREAD_SAFE": "OFF" + } + }, + { + "name": "RelWithDebugInfoPHP8.4ZTSCassandra", + "displayName": "RelWithDebugInfoPHP8.4ZTSCassandra", + "description": "", + "generator": "Ninja", + "binaryDir": "./out/RelWithDebugInfoPHP8.4ZTSCassandra", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "CMAKE_INSTALL_PREFIX": "./out/install/RelWithDebugInfoPHP8.4ZTSCassandra", + "ENABLE_SANITIZERS": "ON", + "SANITIZE_UNDEFINED": "ON", + "SANITIZE_ADDRESS": "ON", + "USE_LIBCASSANDRA": "ON", + "PHP_VERSION_FOR_PHP_CONFIG": "8.4", + "LINK_LIBUV_STATIC": "ON", + "PHP_DRIVER_STATIC": "ON", + "PHP_THREAD_SAFE": "ON" + } + }, + { + "name": "RelWithDebugInfoPHP8.4NTSCassandra", + "displayName": "RelWithDebugInfoPHP8.4NTSCassandra", + "description": "", + "generator": "Ninja", + "binaryDir": "./out/RelWithDebugInfoPHP8.4NTSCassandra", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "CMAKE_INSTALL_PREFIX": "./out/install/RelWithDebugInfoPHP8.4NTSCassandra", + "ENABLE_SANITIZERS": "ON", + "SANITIZE_UNDEFINED": "ON", + "SANITIZE_ADDRESS": "ON", + "USE_LIBCASSANDRA": "ON", + "PHP_VERSION_FOR_PHP_CONFIG": "8.4", + "LINK_LIBUV_STATIC": "ON", + "PHP_DRIVER_STATIC": "ON", + "PHP_THREAD_SAFE": "OFF" + } + }, + { + "name": "RelWithDebugInfoPHP8.1ZTSCassandra", + "displayName": "RelWithDebugInfoPHP8.1ZTSCassandra", + "description": "", + "generator": "Ninja", + "binaryDir": "./out/RelWithDebugInfoPHP8.1ZTSCassandra", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "CMAKE_INSTALL_PREFIX": "./out/install/RelWithDebugInfoPHP8.1ZTSCassandra", + "ENABLE_SANITIZERS": "OFF", + "SANITIZE_UNDEFINED": "OFF", + "SANITIZE_ADDRESS": "OFF", + "USE_LIBCASSANDRA": "ON", + "PHP_VERSION_FOR_PHP_CONFIG": "8.1", + "LINK_LIBUV_STATIC": "ON", + "PHP_DRIVER_STATIC": "ON", + "PHP_THREAD_SAFE": "ON" + } + }, + { + "name": "RelWithDebugInfoPHP8.1NTSCassandra", + "displayName": "RelWithDebugInfoPHP8.1NTSCassandra", + "description": "", + "generator": "Ninja", + "binaryDir": "./out/RelWithDebugInfoPHP8.1NTSCassandra", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "CMAKE_INSTALL_PREFIX": "./out/install/RelWithDebugInfoPHP8.1NTSCassandra", + "ENABLE_SANITIZERS": "OFF", + "SANITIZE_UNDEFINED": "OFF", + "SANITIZE_ADDRESS": "OFF", + "USE_LIBCASSANDRA": "ON", + "PHP_VERSION_FOR_PHP_CONFIG": "8.1", + "LINK_LIBUV_STATIC": "ON", + "PHP_DRIVER_STATIC": "ON", + "PHP_THREAD_SAFE": "OFF" + } + }, + { + "name": "RelWithDebugInfoPHP8.2ZTSCassandra", + "displayName": "RelWithDebugInfoPHP8.2ZTSCassandra", + "description": "", + "generator": "Ninja", + "binaryDir": "./out/RelWithDebugInfoPHP8.2ZTSCassandra", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "CMAKE_INSTALL_PREFIX": "./out/install/RelWithDebugInfoPHP8.2ZTSCassandra", + "ENABLE_SANITIZERS": "OFF", + "SANITIZE_UNDEFINED": "OFF", + "SANITIZE_ADDRESS": "OFF", + "USE_LIBCASSANDRA": "ON", + "PHP_VERSION_FOR_PHP_CONFIG": "8.2", + "LINK_LIBUV_STATIC": "ON", + "PHP_DRIVER_STATIC": "ON", + "PHP_THREAD_SAFE": "ON" + } + }, + { + "name": "RelWithDebugInfoPHP8.2NTSCassandra", + "displayName": "RelWithDebugInfoPHP8.2NTSCassandra", + "description": "", + "generator": "Ninja", + "binaryDir": "./out/RelWithDebugInfoPHP8.2NTSCassandra", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "CMAKE_INSTALL_PREFIX": "./out/install/RelWithDebugInfoPHP8.2NTSCassandra", + "ENABLE_SANITIZERS": "OFF", + "SANITIZE_UNDEFINED": "OFF", + "SANITIZE_ADDRESS": "OFF", + "USE_LIBCASSANDRA": "ON", + "PHP_VERSION_FOR_PHP_CONFIG": "8.2", + "LINK_LIBUV_STATIC": "ON", + "PHP_DRIVER_STATIC": "ON", + "PHP_THREAD_SAFE": "OFF" + } + }, + { + "name": "RelWithDebugInfoPHP8.3ZTSCassandra", + "displayName": "RelWithDebugInfoPHP8.3ZTSCassandra", + "description": "", + "generator": "Ninja", + "binaryDir": "./out/RelWithDebugInfoPHP8.3ZTSCassandra", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "CMAKE_INSTALL_PREFIX": "./out/install/RelWithDebugInfoPHP8.3ZTSCassandra", + "ENABLE_SANITIZERS": "OFF", + "SANITIZE_UNDEFINED": "OFF", + "SANITIZE_ADDRESS": "OFF", + "USE_LIBCASSANDRA": "ON", + "PHP_VERSION_FOR_PHP_CONFIG": "8.3", + "LINK_LIBUV_STATIC": "ON", + "PHP_DRIVER_STATIC": "ON", + "PHP_THREAD_SAFE": "ON" + } + }, + { + "name": "RelWithDebugInfoPHP8.3NTSCassandra", + "displayName": "RelWithDebugInfoPHP8.3NTSCassandra", + "description": "", + "generator": "Ninja", + "binaryDir": "./out/RelWithDebugInfoPHP8.3NTSCassandra", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "CMAKE_INSTALL_PREFIX": "./out/install/RelWithDebugInfoPHP8.3NTSCassandra", + "ENABLE_SANITIZERS": "OFF", + "SANITIZE_UNDEFINED": "OFF", + "SANITIZE_ADDRESS": "OFF", + "USE_LIBCASSANDRA": "ON", + "PHP_VERSION_FOR_PHP_CONFIG": "8.3", + "LINK_LIBUV_STATIC": "ON", + "PHP_DRIVER_STATIC": "ON", + "PHP_THREAD_SAFE": "OFF" + } + }, + { + "name": "RelWithDebugInfoPHP8.4ZTSCassandra", + "displayName": "RelWithDebugInfoPHP8.4ZTSCassandra", + "description": "", + "generator": "Ninja", + "binaryDir": "./out/RelWithDebugInfoPHP8.4ZTSCassandra", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "CMAKE_INSTALL_PREFIX": "./out/install/RelWithDebugInfoPHP8.4ZTSCassandra", + "ENABLE_SANITIZERS": "OFF", + "SANITIZE_UNDEFINED": "OFF", + "SANITIZE_ADDRESS": "OFF", + "USE_LIBCASSANDRA": "ON", + "PHP_VERSION_FOR_PHP_CONFIG": "8.4", + "LINK_LIBUV_STATIC": "ON", + "PHP_DRIVER_STATIC": "ON", + "PHP_THREAD_SAFE": "ON" + } + }, + { + "name": "RelWithDebugInfoPHP8.4NTSCassandra", + "displayName": "RelWithDebugInfoPHP8.4NTSCassandra", + "description": "", + "generator": "Ninja", + "binaryDir": "./out/RelWithDebugInfoPHP8.4NTSCassandra", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "CMAKE_INSTALL_PREFIX": "./out/install/RelWithDebugInfoPHP8.4NTSCassandra", + "ENABLE_SANITIZERS": "OFF", + "SANITIZE_UNDEFINED": "OFF", + "SANITIZE_ADDRESS": "OFF", + "USE_LIBCASSANDRA": "ON", + "PHP_VERSION_FOR_PHP_CONFIG": "8.4", + "LINK_LIBUV_STATIC": "ON", + "PHP_DRIVER_STATIC": "ON", + "PHP_THREAD_SAFE": "OFF" + } + }, + { + "name": "RelWithDebugInfoPHP8.1ZTSCassandra", + "displayName": "RelWithDebugInfoPHP8.1ZTSCassandra", + "description": "", + "generator": "Ninja", + "binaryDir": "./out/RelWithDebugInfoPHP8.1ZTSCassandra", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "CMAKE_INSTALL_PREFIX": "./out/install/RelWithDebugInfoPHP8.1ZTSCassandra", + "ENABLE_SANITIZERS": "OFF", + "SANITIZE_UNDEFINED": "OFF", + "SANITIZE_ADDRESS": "OFF", + "USE_LIBCASSANDRA": "ON", + "PHP_VERSION_FOR_PHP_CONFIG": "8.1", + "LINK_LIBUV_STATIC": "ON", + "PHP_DRIVER_STATIC": "ON", + "PHP_THREAD_SAFE": "ON" + } + }, + { + "name": "RelWithDebugInfoPHP8.1NTSCassandra", + "displayName": "RelWithDebugInfoPHP8.1NTSCassandra", + "description": "", + "generator": "Ninja", + "binaryDir": "./out/RelWithDebugInfoPHP8.1NTSCassandra", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "CMAKE_INSTALL_PREFIX": "./out/install/RelWithDebugInfoPHP8.1NTSCassandra", + "ENABLE_SANITIZERS": "OFF", + "SANITIZE_UNDEFINED": "OFF", + "SANITIZE_ADDRESS": "OFF", + "USE_LIBCASSANDRA": "ON", + "PHP_VERSION_FOR_PHP_CONFIG": "8.1", + "LINK_LIBUV_STATIC": "ON", + "PHP_DRIVER_STATIC": "ON", + "PHP_THREAD_SAFE": "OFF" + } + }, + { + "name": "RelWithDebugInfoPHP8.2ZTSCassandra", + "displayName": "RelWithDebugInfoPHP8.2ZTSCassandra", + "description": "", + "generator": "Ninja", + "binaryDir": "./out/RelWithDebugInfoPHP8.2ZTSCassandra", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "CMAKE_INSTALL_PREFIX": "./out/install/RelWithDebugInfoPHP8.2ZTSCassandra", + "ENABLE_SANITIZERS": "OFF", + "SANITIZE_UNDEFINED": "OFF", + "SANITIZE_ADDRESS": "OFF", + "USE_LIBCASSANDRA": "ON", + "PHP_VERSION_FOR_PHP_CONFIG": "8.2", + "LINK_LIBUV_STATIC": "ON", + "PHP_DRIVER_STATIC": "ON", + "PHP_THREAD_SAFE": "ON" + } + }, + { + "name": "RelWithDebugInfoPHP8.2NTSCassandra", + "displayName": "RelWithDebugInfoPHP8.2NTSCassandra", + "description": "", + "generator": "Ninja", + "binaryDir": "./out/RelWithDebugInfoPHP8.2NTSCassandra", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "CMAKE_INSTALL_PREFIX": "./out/install/RelWithDebugInfoPHP8.2NTSCassandra", + "ENABLE_SANITIZERS": "OFF", + "SANITIZE_UNDEFINED": "OFF", + "SANITIZE_ADDRESS": "OFF", + "USE_LIBCASSANDRA": "ON", + "PHP_VERSION_FOR_PHP_CONFIG": "8.2", + "LINK_LIBUV_STATIC": "ON", + "PHP_DRIVER_STATIC": "ON", + "PHP_THREAD_SAFE": "OFF" + } + }, + { + "name": "RelWithDebugInfoPHP8.3ZTSCassandra", + "displayName": "RelWithDebugInfoPHP8.3ZTSCassandra", + "description": "", + "generator": "Ninja", + "binaryDir": "./out/RelWithDebugInfoPHP8.3ZTSCassandra", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "CMAKE_INSTALL_PREFIX": "./out/install/RelWithDebugInfoPHP8.3ZTSCassandra", + "ENABLE_SANITIZERS": "OFF", + "SANITIZE_UNDEFINED": "OFF", + "SANITIZE_ADDRESS": "OFF", + "USE_LIBCASSANDRA": "ON", + "PHP_VERSION_FOR_PHP_CONFIG": "8.3", + "LINK_LIBUV_STATIC": "ON", + "PHP_DRIVER_STATIC": "ON", + "PHP_THREAD_SAFE": "ON" + } + }, + { + "name": "RelWithDebugInfoPHP8.3NTSCassandra", + "displayName": "RelWithDebugInfoPHP8.3NTSCassandra", + "description": "", + "generator": "Ninja", + "binaryDir": "./out/RelWithDebugInfoPHP8.3NTSCassandra", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "CMAKE_INSTALL_PREFIX": "./out/install/RelWithDebugInfoPHP8.3NTSCassandra", + "ENABLE_SANITIZERS": "OFF", + "SANITIZE_UNDEFINED": "OFF", + "SANITIZE_ADDRESS": "OFF", + "USE_LIBCASSANDRA": "ON", + "PHP_VERSION_FOR_PHP_CONFIG": "8.3", + "LINK_LIBUV_STATIC": "ON", + "PHP_DRIVER_STATIC": "ON", + "PHP_THREAD_SAFE": "OFF" + } + }, + { + "name": "RelWithDebugInfoPHP8.4ZTSCassandra", + "displayName": "RelWithDebugInfoPHP8.4ZTSCassandra", + "description": "", + "generator": "Ninja", + "binaryDir": "./out/RelWithDebugInfoPHP8.4ZTSCassandra", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "CMAKE_INSTALL_PREFIX": "./out/install/RelWithDebugInfoPHP8.4ZTSCassandra", + "ENABLE_SANITIZERS": "OFF", + "SANITIZE_UNDEFINED": "OFF", + "SANITIZE_ADDRESS": "OFF", + "USE_LIBCASSANDRA": "ON", + "PHP_VERSION_FOR_PHP_CONFIG": "8.4", + "LINK_LIBUV_STATIC": "ON", + "PHP_DRIVER_STATIC": "ON", + "PHP_THREAD_SAFE": "ON" + } + }, + { + "name": "RelWithDebugInfoPHP8.4NTSCassandra", + "displayName": "RelWithDebugInfoPHP8.4NTSCassandra", + "description": "", + "generator": "Ninja", + "binaryDir": "./out/RelWithDebugInfoPHP8.4NTSCassandra", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "CMAKE_INSTALL_PREFIX": "./out/install/RelWithDebugInfoPHP8.4NTSCassandra", + "ENABLE_SANITIZERS": "OFF", + "SANITIZE_UNDEFINED": "OFF", + "SANITIZE_ADDRESS": "OFF", + "USE_LIBCASSANDRA": "ON", + "PHP_VERSION_FOR_PHP_CONFIG": "8.4", + "LINK_LIBUV_STATIC": "ON", + "PHP_DRIVER_STATIC": "ON", + "PHP_THREAD_SAFE": "OFF" + } + }, + { + "name": "RelWithDebugInfoPHP8.1ZTS", + "displayName": "RelWithDebugInfoPHP8.1ZTS", + "description": "", + "generator": "Ninja", + "binaryDir": "./out/RelWithDebugInfoPHP8.1ZTS", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "CMAKE_INSTALL_PREFIX": "./out/install/RelWithDebugInfoPHP8.1ZTS", + "ENABLE_SANITIZERS": "ON", + "SANITIZE_UNDEFINED": "ON", + "SANITIZE_ADDRESS": "ON", + "USE_LIBCASSANDRA": "OFF", + "PHP_VERSION_FOR_PHP_CONFIG": "8.1", + "LINK_LIBUV_STATIC": "ON", + "PHP_DRIVER_STATIC": "ON", + "PHP_THREAD_SAFE": "ON" + } + }, + { + "name": "RelWithDebugInfoPHP8.1NTS", + "displayName": "RelWithDebugInfoPHP8.1NTS", + "description": "", + "generator": "Ninja", + "binaryDir": "./out/RelWithDebugInfoPHP8.1NTS", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "CMAKE_INSTALL_PREFIX": "./out/install/RelWithDebugInfoPHP8.1NTS", + "ENABLE_SANITIZERS": "ON", + "SANITIZE_UNDEFINED": "ON", + "SANITIZE_ADDRESS": "ON", + "USE_LIBCASSANDRA": "OFF", + "PHP_VERSION_FOR_PHP_CONFIG": "8.1", + "LINK_LIBUV_STATIC": "ON", + "PHP_DRIVER_STATIC": "ON", + "PHP_THREAD_SAFE": "OFF" + } + }, + { + "name": "RelWithDebugInfoPHP8.2ZTS", + "displayName": "RelWithDebugInfoPHP8.2ZTS", + "description": "", + "generator": "Ninja", + "binaryDir": "./out/RelWithDebugInfoPHP8.2ZTS", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "CMAKE_INSTALL_PREFIX": "./out/install/RelWithDebugInfoPHP8.2ZTS", + "ENABLE_SANITIZERS": "ON", + "SANITIZE_UNDEFINED": "ON", + "SANITIZE_ADDRESS": "ON", + "USE_LIBCASSANDRA": "OFF", + "PHP_VERSION_FOR_PHP_CONFIG": "8.2", + "LINK_LIBUV_STATIC": "ON", + "PHP_DRIVER_STATIC": "ON", + "PHP_THREAD_SAFE": "ON" + } + }, + { + "name": "RelWithDebugInfoPHP8.2NTS", + "displayName": "RelWithDebugInfoPHP8.2NTS", + "description": "", + "generator": "Ninja", + "binaryDir": "./out/RelWithDebugInfoPHP8.2NTS", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "CMAKE_INSTALL_PREFIX": "./out/install/RelWithDebugInfoPHP8.2NTS", + "ENABLE_SANITIZERS": "ON", + "SANITIZE_UNDEFINED": "ON", + "SANITIZE_ADDRESS": "ON", + "USE_LIBCASSANDRA": "OFF", + "PHP_VERSION_FOR_PHP_CONFIG": "8.2", + "LINK_LIBUV_STATIC": "ON", + "PHP_DRIVER_STATIC": "ON", + "PHP_THREAD_SAFE": "OFF" + } + }, + { + "name": "RelWithDebugInfoPHP8.3ZTS", + "displayName": "RelWithDebugInfoPHP8.3ZTS", + "description": "", + "generator": "Ninja", + "binaryDir": "./out/RelWithDebugInfoPHP8.3ZTS", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "CMAKE_INSTALL_PREFIX": "./out/install/RelWithDebugInfoPHP8.3ZTS", + "ENABLE_SANITIZERS": "ON", + "SANITIZE_UNDEFINED": "ON", + "SANITIZE_ADDRESS": "ON", + "USE_LIBCASSANDRA": "OFF", + "PHP_VERSION_FOR_PHP_CONFIG": "8.3", + "LINK_LIBUV_STATIC": "ON", + "PHP_DRIVER_STATIC": "ON", + "PHP_THREAD_SAFE": "ON" + } + }, + { + "name": "RelWithDebugInfoPHP8.3NTS", + "displayName": "RelWithDebugInfoPHP8.3NTS", + "description": "", + "generator": "Ninja", + "binaryDir": "./out/RelWithDebugInfoPHP8.3NTS", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "CMAKE_INSTALL_PREFIX": "./out/install/RelWithDebugInfoPHP8.3NTS", + "ENABLE_SANITIZERS": "ON", + "SANITIZE_UNDEFINED": "ON", + "SANITIZE_ADDRESS": "ON", + "USE_LIBCASSANDRA": "OFF", + "PHP_VERSION_FOR_PHP_CONFIG": "8.3", + "LINK_LIBUV_STATIC": "ON", + "PHP_DRIVER_STATIC": "ON", + "PHP_THREAD_SAFE": "OFF" + } + }, + { + "name": "RelWithDebugInfoPHP8.4ZTS", + "displayName": "RelWithDebugInfoPHP8.4ZTS", + "description": "", + "generator": "Ninja", + "binaryDir": "./out/RelWithDebugInfoPHP8.4ZTS", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "CMAKE_INSTALL_PREFIX": "./out/install/RelWithDebugInfoPHP8.4ZTS", + "ENABLE_SANITIZERS": "ON", + "SANITIZE_UNDEFINED": "ON", + "SANITIZE_ADDRESS": "ON", + "USE_LIBCASSANDRA": "OFF", + "PHP_VERSION_FOR_PHP_CONFIG": "8.4", + "LINK_LIBUV_STATIC": "ON", + "PHP_DRIVER_STATIC": "ON", + "PHP_THREAD_SAFE": "ON" + } + }, + { + "name": "RelWithDebugInfoPHP8.4NTS", + "displayName": "RelWithDebugInfoPHP8.4NTS", + "description": "", + "generator": "Ninja", + "binaryDir": "./out/RelWithDebugInfoPHP8.4NTS", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "CMAKE_INSTALL_PREFIX": "./out/install/RelWithDebugInfoPHP8.4NTS", + "ENABLE_SANITIZERS": "ON", + "SANITIZE_UNDEFINED": "ON", + "SANITIZE_ADDRESS": "ON", + "USE_LIBCASSANDRA": "OFF", + "PHP_VERSION_FOR_PHP_CONFIG": "8.4", + "LINK_LIBUV_STATIC": "ON", + "PHP_DRIVER_STATIC": "ON", + "PHP_THREAD_SAFE": "OFF" + } + }, + { + "name": "RelWithDebugInfoPHP8.1ZTS", + "displayName": "RelWithDebugInfoPHP8.1ZTS", + "description": "", + "generator": "Ninja", + "binaryDir": "./out/RelWithDebugInfoPHP8.1ZTS", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "CMAKE_INSTALL_PREFIX": "./out/install/RelWithDebugInfoPHP8.1ZTS", + "ENABLE_SANITIZERS": "OFF", + "SANITIZE_UNDEFINED": "OFF", + "SANITIZE_ADDRESS": "OFF", + "USE_LIBCASSANDRA": "OFF", + "PHP_VERSION_FOR_PHP_CONFIG": "8.1", + "LINK_LIBUV_STATIC": "ON", + "PHP_DRIVER_STATIC": "ON", + "PHP_THREAD_SAFE": "ON" + } + }, + { + "name": "RelWithDebugInfoPHP8.1NTS", + "displayName": "RelWithDebugInfoPHP8.1NTS", + "description": "", + "generator": "Ninja", + "binaryDir": "./out/RelWithDebugInfoPHP8.1NTS", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "CMAKE_INSTALL_PREFIX": "./out/install/RelWithDebugInfoPHP8.1NTS", + "ENABLE_SANITIZERS": "OFF", + "SANITIZE_UNDEFINED": "OFF", + "SANITIZE_ADDRESS": "OFF", + "USE_LIBCASSANDRA": "OFF", + "PHP_VERSION_FOR_PHP_CONFIG": "8.1", + "LINK_LIBUV_STATIC": "ON", + "PHP_DRIVER_STATIC": "ON", + "PHP_THREAD_SAFE": "OFF" + } + }, + { + "name": "RelWithDebugInfoPHP8.2ZTS", + "displayName": "RelWithDebugInfoPHP8.2ZTS", + "description": "", + "generator": "Ninja", + "binaryDir": "./out/RelWithDebugInfoPHP8.2ZTS", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "CMAKE_INSTALL_PREFIX": "./out/install/RelWithDebugInfoPHP8.2ZTS", + "ENABLE_SANITIZERS": "OFF", + "SANITIZE_UNDEFINED": "OFF", + "SANITIZE_ADDRESS": "OFF", + "USE_LIBCASSANDRA": "OFF", + "PHP_VERSION_FOR_PHP_CONFIG": "8.2", + "LINK_LIBUV_STATIC": "ON", + "PHP_DRIVER_STATIC": "ON", + "PHP_THREAD_SAFE": "ON" + } + }, + { + "name": "RelWithDebugInfoPHP8.2NTS", + "displayName": "RelWithDebugInfoPHP8.2NTS", + "description": "", + "generator": "Ninja", + "binaryDir": "./out/RelWithDebugInfoPHP8.2NTS", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "CMAKE_INSTALL_PREFIX": "./out/install/RelWithDebugInfoPHP8.2NTS", + "ENABLE_SANITIZERS": "OFF", + "SANITIZE_UNDEFINED": "OFF", + "SANITIZE_ADDRESS": "OFF", + "USE_LIBCASSANDRA": "OFF", + "PHP_VERSION_FOR_PHP_CONFIG": "8.2", + "LINK_LIBUV_STATIC": "ON", + "PHP_DRIVER_STATIC": "ON", + "PHP_THREAD_SAFE": "OFF" + } + }, + { + "name": "RelWithDebugInfoPHP8.3ZTS", + "displayName": "RelWithDebugInfoPHP8.3ZTS", + "description": "", + "generator": "Ninja", + "binaryDir": "./out/RelWithDebugInfoPHP8.3ZTS", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "CMAKE_INSTALL_PREFIX": "./out/install/RelWithDebugInfoPHP8.3ZTS", + "ENABLE_SANITIZERS": "OFF", + "SANITIZE_UNDEFINED": "OFF", + "SANITIZE_ADDRESS": "OFF", + "USE_LIBCASSANDRA": "OFF", + "PHP_VERSION_FOR_PHP_CONFIG": "8.3", + "LINK_LIBUV_STATIC": "ON", + "PHP_DRIVER_STATIC": "ON", + "PHP_THREAD_SAFE": "ON" + } + }, + { + "name": "RelWithDebugInfoPHP8.3NTS", + "displayName": "RelWithDebugInfoPHP8.3NTS", + "description": "", + "generator": "Ninja", + "binaryDir": "./out/RelWithDebugInfoPHP8.3NTS", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "CMAKE_INSTALL_PREFIX": "./out/install/RelWithDebugInfoPHP8.3NTS", + "ENABLE_SANITIZERS": "OFF", + "SANITIZE_UNDEFINED": "OFF", + "SANITIZE_ADDRESS": "OFF", + "USE_LIBCASSANDRA": "OFF", + "PHP_VERSION_FOR_PHP_CONFIG": "8.3", + "LINK_LIBUV_STATIC": "ON", + "PHP_DRIVER_STATIC": "ON", + "PHP_THREAD_SAFE": "OFF" + } + }, + { + "name": "RelWithDebugInfoPHP8.4ZTS", + "displayName": "RelWithDebugInfoPHP8.4ZTS", + "description": "", + "generator": "Ninja", + "binaryDir": "./out/RelWithDebugInfoPHP8.4ZTS", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "CMAKE_INSTALL_PREFIX": "./out/install/RelWithDebugInfoPHP8.4ZTS", + "ENABLE_SANITIZERS": "OFF", + "SANITIZE_UNDEFINED": "OFF", + "SANITIZE_ADDRESS": "OFF", + "USE_LIBCASSANDRA": "OFF", + "PHP_VERSION_FOR_PHP_CONFIG": "8.4", + "LINK_LIBUV_STATIC": "ON", + "PHP_DRIVER_STATIC": "ON", + "PHP_THREAD_SAFE": "ON" + } + }, + { + "name": "RelWithDebugInfoPHP8.4NTS", + "displayName": "RelWithDebugInfoPHP8.4NTS", + "description": "", + "generator": "Ninja", + "binaryDir": "./out/RelWithDebugInfoPHP8.4NTS", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "CMAKE_INSTALL_PREFIX": "./out/install/RelWithDebugInfoPHP8.4NTS", + "ENABLE_SANITIZERS": "OFF", + "SANITIZE_UNDEFINED": "OFF", + "SANITIZE_ADDRESS": "OFF", + "USE_LIBCASSANDRA": "OFF", + "PHP_VERSION_FOR_PHP_CONFIG": "8.4", + "LINK_LIBUV_STATIC": "ON", + "PHP_DRIVER_STATIC": "ON", + "PHP_THREAD_SAFE": "OFF" + } + }, + { + "name": "RelWithDebugInfoPHP8.1ZTS", + "displayName": "RelWithDebugInfoPHP8.1ZTS", + "description": "", + "generator": "Ninja", + "binaryDir": "./out/RelWithDebugInfoPHP8.1ZTS", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "CMAKE_INSTALL_PREFIX": "./out/install/RelWithDebugInfoPHP8.1ZTS", + "ENABLE_SANITIZERS": "OFF", + "SANITIZE_UNDEFINED": "OFF", + "SANITIZE_ADDRESS": "OFF", + "USE_LIBCASSANDRA": "OFF", + "PHP_VERSION_FOR_PHP_CONFIG": "8.1", + "LINK_LIBUV_STATIC": "ON", + "PHP_DRIVER_STATIC": "ON", + "PHP_THREAD_SAFE": "ON" + } + }, + { + "name": "RelWithDebugInfoPHP8.1NTS", + "displayName": "RelWithDebugInfoPHP8.1NTS", + "description": "", + "generator": "Ninja", + "binaryDir": "./out/RelWithDebugInfoPHP8.1NTS", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "CMAKE_INSTALL_PREFIX": "./out/install/RelWithDebugInfoPHP8.1NTS", + "ENABLE_SANITIZERS": "OFF", + "SANITIZE_UNDEFINED": "OFF", + "SANITIZE_ADDRESS": "OFF", + "USE_LIBCASSANDRA": "OFF", + "PHP_VERSION_FOR_PHP_CONFIG": "8.1", + "LINK_LIBUV_STATIC": "ON", + "PHP_DRIVER_STATIC": "ON", + "PHP_THREAD_SAFE": "OFF" + } + }, + { + "name": "RelWithDebugInfoPHP8.2ZTS", + "displayName": "RelWithDebugInfoPHP8.2ZTS", + "description": "", + "generator": "Ninja", + "binaryDir": "./out/RelWithDebugInfoPHP8.2ZTS", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "CMAKE_INSTALL_PREFIX": "./out/install/RelWithDebugInfoPHP8.2ZTS", + "ENABLE_SANITIZERS": "OFF", + "SANITIZE_UNDEFINED": "OFF", + "SANITIZE_ADDRESS": "OFF", + "USE_LIBCASSANDRA": "OFF", + "PHP_VERSION_FOR_PHP_CONFIG": "8.2", + "LINK_LIBUV_STATIC": "ON", + "PHP_DRIVER_STATIC": "ON", + "PHP_THREAD_SAFE": "ON" + } + }, + { + "name": "RelWithDebugInfoPHP8.2NTS", + "displayName": "RelWithDebugInfoPHP8.2NTS", + "description": "", + "generator": "Ninja", + "binaryDir": "./out/RelWithDebugInfoPHP8.2NTS", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "CMAKE_INSTALL_PREFIX": "./out/install/RelWithDebugInfoPHP8.2NTS", + "ENABLE_SANITIZERS": "OFF", + "SANITIZE_UNDEFINED": "OFF", + "SANITIZE_ADDRESS": "OFF", + "USE_LIBCASSANDRA": "OFF", + "PHP_VERSION_FOR_PHP_CONFIG": "8.2", + "LINK_LIBUV_STATIC": "ON", + "PHP_DRIVER_STATIC": "ON", + "PHP_THREAD_SAFE": "OFF" + } + }, + { + "name": "RelWithDebugInfoPHP8.3ZTS", + "displayName": "RelWithDebugInfoPHP8.3ZTS", + "description": "", + "generator": "Ninja", + "binaryDir": "./out/RelWithDebugInfoPHP8.3ZTS", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "CMAKE_INSTALL_PREFIX": "./out/install/RelWithDebugInfoPHP8.3ZTS", + "ENABLE_SANITIZERS": "OFF", + "SANITIZE_UNDEFINED": "OFF", + "SANITIZE_ADDRESS": "OFF", + "USE_LIBCASSANDRA": "OFF", + "PHP_VERSION_FOR_PHP_CONFIG": "8.3", + "LINK_LIBUV_STATIC": "ON", + "PHP_DRIVER_STATIC": "ON", + "PHP_THREAD_SAFE": "ON" + } + }, + { + "name": "RelWithDebugInfoPHP8.3NTS", + "displayName": "RelWithDebugInfoPHP8.3NTS", + "description": "", + "generator": "Ninja", + "binaryDir": "./out/RelWithDebugInfoPHP8.3NTS", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "CMAKE_INSTALL_PREFIX": "./out/install/RelWithDebugInfoPHP8.3NTS", + "ENABLE_SANITIZERS": "OFF", + "SANITIZE_UNDEFINED": "OFF", + "SANITIZE_ADDRESS": "OFF", + "USE_LIBCASSANDRA": "OFF", + "PHP_VERSION_FOR_PHP_CONFIG": "8.3", + "LINK_LIBUV_STATIC": "ON", + "PHP_DRIVER_STATIC": "ON", + "PHP_THREAD_SAFE": "OFF" + } + }, + { + "name": "RelWithDebugInfoPHP8.4ZTS", + "displayName": "RelWithDebugInfoPHP8.4ZTS", + "description": "", + "generator": "Ninja", + "binaryDir": "./out/RelWithDebugInfoPHP8.4ZTS", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "CMAKE_INSTALL_PREFIX": "./out/install/RelWithDebugInfoPHP8.4ZTS", + "ENABLE_SANITIZERS": "OFF", + "SANITIZE_UNDEFINED": "OFF", + "SANITIZE_ADDRESS": "OFF", + "USE_LIBCASSANDRA": "OFF", + "PHP_VERSION_FOR_PHP_CONFIG": "8.4", + "LINK_LIBUV_STATIC": "ON", + "PHP_DRIVER_STATIC": "ON", + "PHP_THREAD_SAFE": "ON" + } + }, + { + "name": "RelWithDebugInfoPHP8.4NTS", + "displayName": "RelWithDebugInfoPHP8.4NTS", + "description": "", + "generator": "Ninja", + "binaryDir": "./out/RelWithDebugInfoPHP8.4NTS", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "CMAKE_INSTALL_PREFIX": "./out/install/RelWithDebugInfoPHP8.4NTS", + "ENABLE_SANITIZERS": "OFF", + "SANITIZE_UNDEFINED": "OFF", + "SANITIZE_ADDRESS": "OFF", + "USE_LIBCASSANDRA": "OFF", + "PHP_VERSION_FOR_PHP_CONFIG": "8.4", + "LINK_LIBUV_STATIC": "ON", + "PHP_DRIVER_STATIC": "ON", + "PHP_THREAD_SAFE": "OFF" + } + } + ] } \ No newline at end of file diff --git a/README.md b/README.md index 2f7cfb498..e8229d075 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@
- + [![Build Docker Image](https://github.com/he4rt/scylladb-php-driver/actions/workflows/docker-image.yml/badge.svg)](https://github.com/he4rt/scylladb-php-driver/actions/workflows/docker-image.yml) [![ScyllaDB Unnoficial Discord Server](https://img.shields.io/badge/ScyllaDB_Developers-Discord_Server-4C388C)](https://discord.gg/B6rutCXvgp) @@ -83,7 +83,7 @@ $session = $cluster->connect($keyspace); // create session, optionally $statement = new Cassandra\SimpleStatement( // also supports prepared and batch statements 'SELECT keyspace_name, columnfamily_name FROM schema_columnfamilies' ); -$querySent = $session->execute($statement); +$querySent = $session->execute($statement); $result = $querySent->get(); // wait for the result, with an optional timeout foreach ($result as $row) { // results and rows implement Iterator, Countable and ArrayAccess @@ -157,19 +157,23 @@ We provide common setups using CMake Presets. You can use them by passing the pr * ReleaseLibCassandra (Release with LibCassandra) ```` -option(PHP_SCYLLADB_ENABLE_SANITIZERS "Enable sanitizers" OFF) -option(PHP_SCYLLADB_ENABLE_COVERAGE "Enable coverage" OFF) -option(PHP_SCYLLADB_OPTIMISE_FOR_CURRENT_MACHINE "Optimise for current machine" OFF) +option(ENABLE_SANITIZERS "Enable sanitizers" OFF) +option(ENABLE_AVX "Enable AVX" OFF) +option(ENABLE_AVX2 "Enable AVX2" OFF) +option(ENABLE_LTO "Enable LTO" OFF) +set(CPU_TYPE "x86-64-v3" CACHE STRING "For x86_64 = x86-64|x86-64-v2|x86-64-v3|x86-64-v4|native") +# PHP Options +set(CUSTOM_PHP_CONFIG "" CACHE STRING "Custom PHP config path") +set(PHP_VERSION_FOR_PHP_CONFIG "8.3" CACHE STRING "PHP version") +option(PHP_DEBUG "Debug or Release" ON) +option(PHP_THREAD_SAFE "ZTS(zts) or NTS(nts)" OFF) -option(PHP_SCYLLADB_LIBUV_STATIC "Statically link libuv" OFF) -option(PHP_SCYLLADB_LIBUV_FROM_SRC "Build LibUV from Source" OFF) -option(PHP_SCYLLADB_LIBSCYLLADB_STATIC "Statically link LibScyllaDB" OFF) -option(PHP_SCYLLADB_LIBSCYLLADB_FROM_SRC "Build LibScyllaDB from Source" OFF) +option(LINK_LIBUV_STATIC "Statically link libuv" OFF) +option(BUILD_LIBUV_FROM_SRC "Build LibUV from Source" OFF) -option(PHP_SCYLLADB_USE_LIBCASSANDRA "Use DataStax LibCassandra instead of LibScyllaDB" OFF) -option(PHP_SCYLLADB_LIBCASSANDRA_STATIC "Statically link LibCassandra" OFF) -option(PHP_SCYLLADB_LIBCASSANDRA_FROM_SRC "Build LibCassandra from Source" OFF) +option(PHP_DRIVER_STATIC "Statically link PHP Driver" OFF) +option(USE_LIBCASSANDRA "Use DataStax LibCassandra instead of LibScyllaDB" OFF) ```` @@ -182,111 +186,16 @@ To build your Driver, you should first download a few dependencies: #### Debian/Ubuntu ````sh -apt install -y python3 python3-pip unzip mlocate build-essential ninja-build libssl-dev libgmp-dev zlib1g-dev openssl libpcre3-dev php-dev -pip3 install cmake - -# Single Line -apt install -y python3 python3-pip unzip mlocate build-essential ninja-build libssl-dev libgmp-dev zlib1g-dev openssl libpcre3-dev php-dev && pip3 install cmake -```` - -After that, you can run the build command inside the repository root folder: - -````sh -cmake --preset Release && cd out/Release && sudo ninja install -```` - -> `ninja install` needs root privileges. - -After compiled, you will be at directory `scylladb-php-driver/out/Release` and at this folder you will need to move -the `cassandra.so` and `cassandra.ini` to PHP respective folders. - -````shell -# current directory: scylladb-php-driver/out/Release - -# PHP 8.1 -sudo cp ../../cassandra.ini /etc/php/8.1/cli/conf.d/10-cassandra.ini -sudo cp cassandra.so /usr/lib/php/20210902/cassandra.so - -# PHP 8.2 -sudo cp ../../cassandra.ini /etc/php/8.2/cli/conf.d/10-cassandra.ini -sudo cp cassandra.so /usr/lib/php/20220829/cassandra.so +apt install -y pipx build-essential ninja-build libssl-dev libgmp-dev zlib1g-dev openssl libpcre3-dev php-dev && pipx install cmake ```` -### Compiling Development Build - -If you want to contribute to the project, you should follow the steps below. - -#### Debian/Ubuntu - -```shell -apt update -y -apt upgrade -y -apt install -y python3 python3-pip unzip mlocate build-essential ninja-build libssl-dev libgmp-dev zlib1g-dev openssl libpcre3-dev -pip3 install cmake cqlsh # CQL Shell - to connect into your ScyllaDB Cluster -install-php-extensions intl zip pcntl gmp composer -apt-get clean - -# Single Line -apt update -y && apt upgrade -y && apt install -y python3 python3-pip unzip mlocate build-essential ninja-build libssl-dev libgmp-dev zlib1g-dev openssl libpcre3-dev && pip3 install cmake cqlsh && install-php-extensions intl zip pcntl gmp composer && apt-get clean - -``` - After that, you can run the build command inside the repository root folder: ````sh -cmake --preset Debug && cd out/Debug && ninja -```` - -We have a "debug.php" file in the root folder that you can use it for try connection with -the ScyllaDB Cluster (localhost) and check if is everything ok after change the source code. - -Also you can run the PestPHP test suits inside the project and check if the functions are working as expected. - -````shell -## Debug Base Command -php -d "extension=$(pwd)/out/Debug/cassandra.so" debug.php - -## PestPHP Test Suite -./vendor/bin/pest -d "extension=$(pwd)/out/Debug/cassandra.so" -```` - -### Compiling Optimized Build - -The "optimized build" brings a flag that makes the driver runs perfectly with your CPU. So, if you will use it, remember -to build it inside the environment that you will use it. - -#### Debian/Ubuntu - -````sh -apt install -y python3 python3-pip unzip mlocate build-essential ninja-build libssl-dev libgmp-dev zlib1g-dev openssl libpcre3-dev php-dev -pip3 install cmake - -# Single Line -apt install -y python3 python3-pip unzip mlocate build-essential ninja-build libssl-dev libgmp-dev zlib1g-dev openssl libpcre3-dev php-dev && pip3 install cmake -```` - -The only difference between the `Release` and `Optimized` is a flag -called `-DPHP_SCYLLADB_OPTIMISE_FOR_CURRENT_MACHINE=ON`. - -````shell -cmake --preset Release -DPHP_SCYLLADB_OPTIMISE_FOR_CURRENT_MACHINE=ON && cd out/Release && sudo ninja install -```` - -> `ninja install` needs root privileges. - -After compiled, you will be at directory `scylladb-php-driver/out/Release` and at this folder you will need to move -the `cassandra.so` and `cassandra.ini` to PHP respective folders. - -````shell -# current directory: scylladb-php-driver/out/Release - -# PHP 8.1 -sudo cp ../../cassandra.ini /etc/php/8.1/cli/conf.d/10-cassandra.ini -sudo cp cassandra.so /usr/lib/php/20210902/cassandra.so - -# PHP 8.2 -sudo cp ../../cassandra.ini /etc/php/8.2/cli/conf.d/10-cassandra.ini -sudo cp cassandra.so /usr/lib/php/20220829/cassandra.so +phpize +./configure +make -j$(nproc) +sudo make install ```` ## Contributing diff --git a/ZendCPP/CMakeLists.txt b/ZendCPP/CMakeLists.txt index bd0a28c13..7b9766949 100644 --- a/ZendCPP/CMakeLists.txt +++ b/ZendCPP/CMakeLists.txt @@ -1,7 +1,7 @@ add_library(zend STATIC Zend.cpp) add_library(Zend ALIAS zend) +scylladb_php_library(zend OFF "${CPU_TYPE}" "${ENABLE_LTO}") add_subdirectory(String) target_link_libraries(zend PUBLIC zend_strings) -scylladb_php_library(zend OFF ${PHP_SCYLLADB_OPTIMISE_FOR_CURRENT_MACHINE} ON) \ No newline at end of file diff --git a/ZendCPP/String/CMakeLists.txt b/ZendCPP/String/CMakeLists.txt index c035349b3..7992a6b24 100644 --- a/ZendCPP/String/CMakeLists.txt +++ b/ZendCPP/String/CMakeLists.txt @@ -3,4 +3,5 @@ add_library(zend_strings STATIC Builder.h ) add_library(Zend::String ALIAS zend_strings) -scylladb_php_library(zend_strings OFF ${PHP_SCYLLADB_OPTIMISE_FOR_CURRENT_MACHINE} ON) \ No newline at end of file + +scylladb_php_library(zend_strings OFF "${CPU_TYPE}" "${ENABLE_LTO}") \ No newline at end of file diff --git a/cmake/FindCPPDriver.cmake b/cmake/FindCPPDriver.cmake new file mode 100644 index 000000000..8645131ed --- /dev/null +++ b/cmake/FindCPPDriver.cmake @@ -0,0 +1,25 @@ +find_package(PkgConfig REQUIRED) + +if(USE_LIBCASSANDRA) + if (PHP_DRIVER_STATIC) + pkg_check_modules(LIBCASSANDRA REQUIRED IMPORTED_TARGET cassandra_static) + else () + pkg_check_modules(LIBCASSANDRA REQUIRED IMPORTED_TARGET cassandra) + endif () + + target_link_libraries(ext_scylladb PRIVATE ${LIBCASSANDRA_LIBRARIES}) + target_link_directories(ext_scylladb PRIVATE ${LIBCASSANDRA_LIBRARY_DIRS}) + target_include_directories(ext_scylladb PUBLIC ${LIBCASSANDRA_INCLUDE_DIRS}) + set(CASSANDRA_H ${LIBCASSANDRA_INCLUDE_DIRS}) +else() + if (PHP_DRIVER_STATIC) + pkg_check_modules(LIBSCYLLADB REQUIRED IMPORTED_TARGET scylla-cpp-driver_static) + else () + pkg_check_modules(LIBSCYLLADB REQUIRED IMPORTED_TARGET scylla-cpp-driver) + endif () + + target_include_directories(ext_scylladb PUBLIC "${LIBSCYLLADB_INCLUDE_DIRS}") + target_link_libraries(ext_scylladb PRIVATE "${LIBSCYLLADB_LIBRARIES}") + target_link_directories(ext_scylladb PRIVATE "${LIBSCYLLADB_LIBRARY_DIRS}") + set(CASSANDRA_H ${LIBSCYLLADB_INCLUDE_DIRS}) +endif() diff --git a/cmake/FindCassandraDriver.cmake b/cmake/FindCassandraDriver.cmake deleted file mode 100644 index 7fa342076..000000000 --- a/cmake/FindCassandraDriver.cmake +++ /dev/null @@ -1,12 +0,0 @@ -find_package(PkgConfig REQUIRED) - -if (PHP_SCYLLADB_LIBCASSANDRA_STATIC) - pkg_check_modules(LIBCASSANDRA REQUIRED IMPORTED_TARGET cassandra_static) -else () - pkg_check_modules(LIBCASSANDRA REQUIRED IMPORTED_TARGET cassandra) -endif () - -target_link_libraries(ext_scylladb PRIVATE ${LIBCASSANDRA_LIBRARIES}) -target_link_directories(ext_scylladb PRIVATE ${LIBCASSANDRA_LIBRARY_DIRS}) -target_include_directories(ext_scylladb PUBLIC ${LIBCASSANDRA_INCLUDE_DIRS}) -set(CASSANDRA_H ${LIBCASSANDRA_INCLUDE_DIRS}) diff --git a/cmake/FindLibuv.cmake b/cmake/FindLibuv.cmake index a746be5b0..d07045a1d 100644 --- a/cmake/FindLibuv.cmake +++ b/cmake/FindLibuv.cmake @@ -1,5 +1,5 @@ -if (PHP_SCYLLADB_LIBUV_FROM_SRC) - if (PHP_SCYLLADB_LIBUV_STATIC) +if (BUILD_LIBUV_FROM_SRC) + if (LINK_LIBUV_STATIC) set(LIBUV_BUILD_SHARED OFF) else () set(LIBUV_BUILD_SHARED ON) @@ -19,23 +19,24 @@ if (PHP_SCYLLADB_LIBUV_FROM_SRC) set(LIBUV_ROOT_DIR ${libuv_BINARY_DIR}) - if (PHP_SCYLLADB_LIBUV_STATIC) + if (LINK_LIBUV_STATIC) set(LIBUV_LIBRARY "${libuv_BINARY_DIR}/libuv_a.a") else () set(LIBUV_LIBRARY "${libuv_BINARY_DIR}/libuv.so") endif () set(LIBUV_LIBRARY_DIRS "${libuv_BINARY_DIR}") - if (PHP_SCYLLADB_LIBUV_STATIC) + if (LINK_LIBUV_STATIC) target_link_libraries(ext_scylladb PRIVATE uv_a) else () target_link_libraries(ext_scylladb PRIVATE uv) endif () else () find_package(PkgConfig REQUIRED) - if (PHP_SCYLLADB_LIBUV_STATIC) + if (LINK_LIBUV_STATIC) target_compile_definitions(ext_scylladb PRIVATE -DUV_STATIC) pkg_check_modules(LIBUV REQUIRED IMPORTED_TARGET libuv-static) + message(STATUS "Using static libuv ${LIBUV_LIBRARIES}") else () pkg_check_modules(LIBUV REQUIRED IMPORTED_TARGET libuv) endif () diff --git a/cmake/FindPHPConfig.cmake b/cmake/FindPHPConfig.cmake index 230d36915..a6d09a6f8 100644 --- a/cmake/FindPHPConfig.cmake +++ b/cmake/FindPHPConfig.cmake @@ -1,12 +1,7 @@ if (NOT ${CUSTOM_PHP_CONFIG} STREQUAL "") message(STATUS "Using custom php config: ${CUSTOM_PHP_CONFIG}") - if (EXISTS ${CUSTOM_PHP_CONFIG}) - set(PHP_CONFIG_EXECUTABLE ${CUSTOM_PHP_CONFIG}) - set(PHP_CONFIG_FOUND ON) - else () - message(FATAL_ERROR "php-config not found") - set(PHP_CONFIG_FOUND OFF) - endif () + set(PHP_CONFIG_EXECUTABLE ${CUSTOM_PHP_CONFIG}) + set(PHP_CONFIG_FOUND ON) else () message(STATUS "Searching php-config PHP-VERSION: ${PHP_VERSION_FOR_PHP_CONFIG}") @@ -16,13 +11,13 @@ else () set(hint "${PROJECT_SOURCE_DIR}/php/${PHP_VERSION_FOR_PHP_CONFIG}") - if (${PHP_DEBUG_FOR_PHP_CONFIG}) + if (${PHP_DEBUG}) set(hint "${hint}-debug") else () set(hint "${hint}-release") endif () - if (${PHP_THREAD_SAFE_FOR_PHP_CONFIG}) + if (${PHP_THREAD_SAFE}) set(hint "${hint}-zts") else () set(hint "${hint}-nts") diff --git a/cmake/FindScyllaDBDriver.cmake b/cmake/FindScyllaDBDriver.cmake deleted file mode 100644 index 2b52dd295..000000000 --- a/cmake/FindScyllaDBDriver.cmake +++ /dev/null @@ -1,12 +0,0 @@ -find_package(PkgConfig REQUIRED) - -if (PHP_SCYLLADB_LIBSCYLLADB_STATIC) - pkg_check_modules(LIBSCYLLADB REQUIRED IMPORTED_TARGET scylla-cpp-driver_static) -else () - pkg_check_modules(LIBSCYLLADB REQUIRED IMPORTED_TARGET scylla-cpp-driver) -endif () - -target_include_directories(ext_scylladb PUBLIC "${LIBSCYLLADB_INCLUDE_DIRS}") -target_link_libraries(ext_scylladb PRIVATE "${LIBSCYLLADB_LIBRARIES}") -target_link_directories(ext_scylladb PRIVATE "${LIBSCYLLADB_LIBRARY_DIRS}") -set(CASSANDRA_H ${LIBSCYLLADB_INCLUDE_DIRS}) diff --git a/cmake/ScyllaDBPHPLibrary.cmake b/cmake/ScyllaDBPHPLibrary.cmake deleted file mode 100644 index d9afdd3d2..000000000 --- a/cmake/ScyllaDBPHPLibrary.cmake +++ /dev/null @@ -1,61 +0,0 @@ -include(CheckIPOSupported) -include(CheckCXXCompilerFlag) -include(CheckCCompilerFlag) - -function(scylladb_php_library target enable_sanitizers native_arch lto) - target_include_directories( - ${target} - PUBLIC - ${PHP_INCLUDES} - ${PROJECT_SOURCE_DIR}/include - ${PROJECT_BINARY_DIR} - ${PROJECT_SOURCE_DIR} - ${PHP_INCLUDES} - ${libscylladb_SOURCE_DIR}/include - ${LIBGMP_INCLUDE_DIRS} - ${CASSANDRA_H} - ) - - target_compile_features(${target} PUBLIC cxx_std_20 c_std_23) - - set(CMAKE_CXX_STANDARD 20) - set(CMAKE_CXX_STANDARD_REQUIRED ON) - set(CMAKE_CXX_EXTENSIONS OFF) - - set(CMAKE_C_STANDARD 23) - set(CMAKE_C_STANDARD_REQUIRED ON) - set(CMAKE_C_EXTENSIONS OFF) - - target_compile_options( - ${target} - PRIVATE - -fPIC - -Wall - -Wextra - -Wno-long-long - -Wno-deprecated-declarations - -Wno-unused-parameter - -Wno-unused-result - -Wno-variadic-macros - -Wno-format - -pthread - ) - - if (${CMAKE_BUILD_TYPE} STREQUAL "Debug") - target_compile_definitions(${target} PRIVATE -DDEBUG) - elseif (${CMAKE_BUILD_TYPE} STREQUAL "RelWithDebInfo" OR ${CMAKE_BUILD_TYPE} STREQUAL "Release") - target_compile_definitions(${target} PRIVATE -DRELEASE) - endif () - - if (enable_sanitizers) - target_compile_options(${target} PRIVATE -fno-inline -fno-omit-frame-pointer) - add_sanitize_undefined(${target}) - add_sanitize_address(${target}) - endif () - - if (${APPLE}) - target_link_options(${target} PRIVATE -undefined dynamic_lookup) - endif() - - scylladb_php_target_optimize(${target} ${native_arch} ${lto}) -endfunction() \ No newline at end of file diff --git a/cmake/TargetOptimizations.cmake b/cmake/TargetOptimizations.cmake index 29a6282cc..7875fe771 100644 --- a/cmake/TargetOptimizations.cmake +++ b/cmake/TargetOptimizations.cmake @@ -2,44 +2,110 @@ include(CheckIPOSupported) include(CheckCXXCompilerFlag) include(CheckCCompilerFlag) -function(scylladb_php_target_debug_symbols target) - target_compile_options(${target} PRIVATE -g -ggdb -g3 -gdwarf-4 -Wpedantic) -endfunction() +function(scylladb_php_library target enable_sanitizers cpu_type lto) + target_include_directories( + ${target} + PUBLIC + ${PHP_INCLUDES} + ${PROJECT_SOURCE_DIR}/include + ${PROJECT_BINARY_DIR} + ${PROJECT_SOURCE_DIR} + ${PHP_INCLUDES} + ${libscylladb_SOURCE_DIR}/include + ${LIBGMP_INCLUDE_DIRS} + ${CASSANDRA_H} + ) -function(scylladb_php_target_optimization_flags target native_arch lto) - check_ipo_supported(RESULT LTO_SUPPORTED) - if (LTO_SUPPORTED AND lto) - message(STATUS "LTO is supported and enabled") - set_property(TARGET ${target} PROPERTY INTERPROCEDURAL_OPTIMIZATION ON) + target_compile_features(${target} PUBLIC cxx_std_20 c_std_23) + + set(CMAKE_CXX_STANDARD 20) + set(CMAKE_CXX_STANDARD_REQUIRED ON) + set(CMAKE_CXX_EXTENSIONS OFF) + + set(CMAKE_C_STANDARD 23) + set(CMAKE_C_STANDARD_REQUIRED ON) + set(CMAKE_C_EXTENSIONS ON) + + target_compile_options( + ${target} + PRIVATE + -fPIC + -Wall + -Wextra + -Wno-long-long + -Wno-deprecated-declarations + -Wno-unused-parameter + -Wno-unused-result + -Wno-variadic-macros + -Wno-format + -pthread + -D_TIME_BITS=64 + -D_FILE_OFFSET_BITS=64 + ) + + if (enable_sanitizers) + target_compile_options(${target} PRIVATE -fno-inline -fno-omit-frame-pointer) + add_sanitize_undefined(${target}) + add_sanitize_address(${target}) endif () - target_compile_options(${target} PRIVATE -msse2 -msse3 -msse4.1 -msse4.2) + if (${APPLE}) + target_link_options(${target} PRIVATE -undefined dynamic_lookup) + endif () - if (native_arch) - message(WARNING "Be careful when using `-march=native`, it may cause problems when running on different CPUs") - check_cxx_compiler_flag(-march=native SUPPORT_MARCH_NATIVE) - if (SUPPORT_MARCH_NATIVE) - target_compile_options(${target} PRIVATE -march=native) + if ("${CMAKE_BUILD_TYPE}" STREQUAL "Debug") + target_compile_options(${target} PRIVATE -O0 -g -ggdb -g3 -gdwarf-4 -Wpedantic -DDEBUG) + endif () + + if ("${CMAKE_BUILD_TYPE}" STREQUAL "RelWithInfo") + target_compile_options(${target} PRIVATE -O2 -g -ggdb -g3 -gdwarf-4 -Wpedantic -DRELEASE) + endif () + + if ("${CMAKE_BUILD_TYPE}" STREQUAL "Release") + target_compile_options(${target} PRIVATE -O3 -DRELEASE) + endif () + + if (${lto}) + check_ipo_supported(RESULT LTO_SUPPORTED) + if (LTO_SUPPORTED) + message(STATUS "LTO is supported and enabled") + set_property(TARGET ${target} PROPERTY INTERPROCEDURAL_OPTIMIZATION ON) else () - message(WARNING "Compiler does not support `-march=native`") + message(STATUS "LTO is not supported") endif () endif () -endfunction() -function(scylladb_php_target_optimize target native_arch lto) - if (${CMAKE_BUILD_TYPE} MATCHES "Debug") - target_compile_options(${target} PRIVATE -O0) - scylladb_php_target_debug_symbols(${target}) + if (CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64") + target_compile_options(${target} PRIVATE -msse2 -msse3 -msse4.1 -msse4.2) + if (ENABLE_AVX) + check_c_compiler_flag(-mavx SUPPORTS_AVX) + if (SUPPORTS_AVX) + target_compile_options(${target} PRIVATE -mavx) + else () + message(WARNING "Compiler does not support AVX") + endif () + endif () + + if (ENABLE_AVX2) + check_c_compiler_flag(-mavx2 SUPPORTS_AVX2) + if (SUPPORTS_AVX2) + target_compile_options(${target} PRIVATE -mavx2) + else () + message(WARNING "Compiler does not support AVX2") + endif () + endif () + else () + message(STATUS "Architecture is ${CMAKE_SYSTEM_PROCESSOR}") endif () - if (${CMAKE_BUILD_TYPE} MATCHES "RelWithInfo") - target_compile_options(${target} PRIVATE -O2) - scylladb_php_target_debug_symbols(${target}) - scylladb_php_target_optimization_flags(${target} ${native_arch} ${lto}) + if ("${cpu_type}" STREQUAL "native") + message(WARNING "Be careful when using `-march=native`, it may cause problems when running on different CPUs") endif () - if (${CMAKE_BUILD_TYPE} MATCHES "Release") - target_compile_options(${target} PRIVATE -O3) - scylladb_php_target_optimization_flags(${target} ${native_arch} ${lto}) + check_c_compiler_flag(-march=${cpu_type} SUPPORT_MARCH) + if (SUPPORT_MARCH) + target_compile_options(${target} PRIVATE "-march=${cpu_type}") + else () + message(WARNING "Compiler does not support `-march=${cpu_type}`") endif () endfunction() \ No newline at end of file diff --git a/composer.json b/composer.json new file mode 100644 index 000000000..0712f6dab --- /dev/null +++ b/composer.json @@ -0,0 +1,60 @@ +{ + "name": "codelieutenant/scylla-driver", + "version": "1.3.12", + "type": "php-ext", + "authors": [ + { + "name": "Dusan Malusev", + "email": "dusan@dusanmalusev.dev" + } + ], + "minimum-stability": "stable", + "license": "Apache-2.0", + "description": "ScyllaDB/Cassandra PHP driver", + "require": { + "php": ">= 8.1", + "ext-date": "*" + }, + "php-ext": { + "extension-name": "cassandra", + "configure-options": [ + { + "name": "enable-debug", + "description": "Enable debug mode" + }, + { + "name": "with-cpu-type", + "description": "CPU type to optimize for", + "needs-value": true + }, + { + "name": "enable-sanitizers", + "description": "link with address and mem sanitizers" + }, + { + "name": "enable-lto", + "description": "Enable LTO (Link Time Optimization)" + }, + { + "name": "enable-avx", + "description": "Enable AVX" + }, + { + "name": "enable-avx2", + "description": "Enable AVX2" + }, + { + "name": "enable-libuv-static", + "description": "whether to link with libuv statically" + }, + { + "name": "enable-driver-static", + "description": "whether to link with driver statically" + }, + { + "name": "enable-libcassandra", + "description": "whether to link with libcassandra" + } + ] + } +} diff --git a/config.in b/config.in deleted file mode 100644 index 54ac40876..000000000 --- a/config.in +++ /dev/null @@ -1,21 +0,0 @@ -#pragma once - -#cmakedefine HAVE_DLFCN_H @HAVE_DLFCN_H@ -#cmakedefine HAVE_INTTYPES_H @HAVE_INTTYPES_H@ -#cmakedefine HAVE_STDINT_H @HAVE_STDINT_H@ -#cmakedefine HAVE_STDLIB_H @HAVE_STDLIB_H@ -#cmakedefine HAVE_STDIO_H @HAVE_STDIO_H@ -#cmakedefine HAVE_STRING_H @HAVE_STRING_H@ -#cmakedefine HAVE_STRINGS_H @HAVE_STRINGS_H@ -#cmakedefine HAVE_SYS_STAT_H @HAVE_SYS_STAT_H@ -#cmakedefine HAVE_SYS_TYPES_H @HAVE_SYS_TYPES_H@ -#cmakedefine HAVE_UNISTD_H @HAVE_UNISTD_H@ - -#define PACKAGE_NAME "scylladb" -#define PACKAGE_STRING "scylladb-@PHP_SCYLLADB_VERSION@" -#define PACKAGE_TARNAME "scylladb" -#define PACKAGE_VERSION "@PHP_SCYLLADB_VERSION@" -#define PACKAGE_URL "https://github.com/he4rt/scylladb-php-driver" - -/* Define to 1 if you have the ANSI C header files. */ -#cmakedefine STDC_HEADERS 1 \ No newline at end of file diff --git a/config.m4 b/config.m4 index 95e975ee0..b456b2439 100644 --- a/config.m4 +++ b/config.m4 @@ -1,2 +1,150 @@ -PHP_ARG_WITH(cassandra, Enable Cassandra extension, -[ --with-cassandra[=DIR] Enable the Cassandra extension.]) \ No newline at end of file +PHP_ARG_ENABLE([cassandra], + [whether to enable cassandra support], + [AS_HELP_STRING([--enable-cassandra], + [Enable cassandra support])], + [no]) + +PHP_ARG_ENABLE([debug], [whether to enable cassandra debug mode], +[ --enable-debug Enable cassandra debug], no, no) + +PHP_ARG_ENABLE([lto], [whether to enable lto support], +[ --enable-lto Enable lto], no, no) + +PHP_ARG_WITH(cpu-type, + [cpu type For x86_64 = x86-64|x86-64-v2|x86-64-v3|x86-64-v4|native], + [x86-64-v2], + [no], + [no] +) + +PHP_ARG_WITH(driver-version, + [for the driver], + [master], + [no], + [no] +) + +PHP_ARG_ENABLE([avx], [whether to compile with avx instructions], +[ --enable-avx ], no, no) + +PHP_ARG_ENABLE([sanitizers], [whether to link with address and mem sanitizers], +[ --enable-sanitizers ], no, no) + +PHP_ARG_ENABLE([avx2], [whether to compile with avx2 instructions], +[ --enable-avx2 ], no, no) + +PHP_ARG_ENABLE([libuv-static], [whether to link with libuv statically], +[ --enable-libuv-static ], no, no) + +PHP_ARG_ENABLE([driver-static], [whether to link with scylladb/cassandra driver statically], +[ --enable-driver-static ], no, no) + +PHP_ARG_ENABLE([libcassandra], [whether to link with cassandra driver instead of scylladb], +[ --enable-libcassandra ], no, no) + +if test "$PHP_cassandra" != "no"; then + CMAKE_GENERATOR="Unix Makefiles" + CMAKE_BUILD_TYPE="Release" + CMAKE_CPU_TYPE="x86-64-v2" + CMAKE_PHP_DRIVER_VERSION="master" + CMAKE_ENABLE_LTO="OFF" + CMAKE_SANITIZERS="OFF" + CMAKE_AVX="OFF" + CMAKE_AVX2="OFF" + CMAKE_LINK_LIBUV_STATIC="OFF" + CMAKE_DRIVER_STATIC="OFF" + CMAKE_USE_CASSANDRA="OFF" + + AC_PATH_PROG(CMAKE, cmake, no) + if ! test -x "$CMAKE"; then + AC_MSG_ERROR([cmake command missing]) + fi + + AC_PATH_PROG(NINJA, ninja, no) + if ! test -x "$NINJA"; then + CMAKE_GENERATOR="Ninja" + fi + + if test "$PHP_DEBUG" = "yes"; then + CMAKE_BUILD_TYPE="Debug" + fi + + if test "$PHP_CPU_TYPE" != "no"; then + CMAKE_CPU_TYPE="$PHP_CPU_TYPE" + fi + if test "$PHP_DRIVER_VERSION" != "no"; then + CMAKE_PHP_DRIVER_VERSION="$PHP_DRIVER_VERSION" + fi + + if test "$PHP_LTO" = "yes"; then + CMAKE_ENABLE_LTO="ON" + fi + + if test "$PHP_SANITIZERS" = "yes"; then + CMAKE_SANITIZERS="ON" + fi + + if test "$PHP_AVX" = "yes"; then + CMAKE_AVX="ON" + fi + + if test "$PHP_AVX2" = "yes"; then + CMAKE_AVX2="ON" + fi + + if test "$PHP_LINK_LIBUV_STATIC" = "yes"; then + CMAKE_LINK_LIBUV_STATIC="ON" + fi + + if test "$PHP_DRIVER_STATIC" = "yes"; then + CMAKE_DRIVER_STATIC="ON" + fi + + if test "$PHP_LIBCASSANDRA" = "yes"; then + CMAKE_USE_CASSANDRA="ON" + fi + + AC_DEFINE(HAVE_cassandra, 1, [ Have cassandra support ]) + + PHP_NEW_EXTENSION(cassandra, [ ], $ext_shared) + + # PHP_INSTALL_HEADERS([ext/cassandra], [include/php_ext.h]) + + AC_CONFIG_LINKS([ \ + CMakeLists.txt:CMakeLists.txt \ + include:include \ + src:src \ + ]) + + cat >>Makefile.objects<< EOF +all: cmake_build + +clean: cmake_clean + +.PHONY: cmake_build +cmake_build: + $CMAKE -G "$CMAKE_GENERATOR" -B out/ \\ + -DCUSTOM_PHP_CONFIG=$PHP_CONFIG \\ + -DCMAKE_BUILD_TYPE=$CMAKE_BUILD_TYPE \\ + -DCPU_TYPE=$CMAKE_CPU_TYPE \\ + -DENABLE_LTO=$CMAKE_ENABLE_LTO \\ + -DENABLE_AVX=$CMAKE_AVX \\ + -DENABLE_AVX2=$CMAKE_AVX2 \\ + -DENABLE_SANITIZERS=$CMAKE_SANITIZERS \\ + -DLINK_LIBUV_STATIC=$CMAKE_LINK_LIBUV_STATIC \\ + -DPHP_DRIVER_STATIC=$CMAKE_DRIVER_STATIC \\ + -DUSE_LIBCASSANDRA=$CMAKE_USE_CASSANDRA \\ + -DCMAKE_INSTALL_PREFIX=./out/install \\ + -DPHP_SCYLLADB_DRIVER_VERSION=$CMAKE_PHP_DRIVER_VERSION + cmake --build out/ + + if [[ -f ./out/cassandra.dylib ]] ; then \\ + cp ./out/cassandra.dylib ./modules/cassandra.so ; fi + if [[ -f ./out/cassandra.so ]] ; then \\ + cp ./out/cassandra.so ./modules/cassandra.so ; fi + +.PHONY: cmake_clean +cmake_clean: + rm -rf build +EOF +fi diff --git a/docker/Dockerfile b/docker/Dockerfile index 6b05e0b0e..7f166a66f 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -2,7 +2,7 @@ ARG UBUNTU_VERSION="24.04" FROM ubuntu:$UBUNTU_VERSION AS base -ARG LIBUV_VERSION="v1.48.0" +ARG LIBUV_VERSION="v1.50.0" ARG LIBUV_BUILD_TYPE="RelWithInfo" ARG LIBUV_REPO="https://github.com/libuv/libuv.git" @@ -12,7 +12,7 @@ ENV CXX="g++" ENV CFLAGS="-fPIC" ENV CXXFLAGS="-fPIC" ENV CMAKE_CXX_COMPILER_LAUNCHER="ccache" -ENV PATH="$PATH:/usr/local/bin" +ENV PATH="$PATH:/usr/local/bin:/root/.local/bin:/php/bin" ENV LD_LIBRARY_PATH="/lib/x86_64-linux-gnu:/usr/local/lib:/usr/lib:/lib:/lib64:/usr/local/lib/x86_64-linux-gnu" ENV PKG_CONFIG_PATH="/usr/local/lib/pkgconfig" ENV DEBIAN_FRONTEND="noninteractive" @@ -21,7 +21,7 @@ ENV TZ="UTC" RUN ln -snf "/usr/share/zoneinfo/$TZ" /etc/localtime \ && echo "$TZ" > /etc/timezone \ && apt-get update -y \ - && CODENAME=$(grep VERSION_CODENAME /etc/os-release | cut -d= -f2); [ "$CODENAME" = "focal" ] && apt-get install -y libasan6 \ + && CODENAME=$(grep VERSION_CODENAME /etc/os-release | cut -d= -f2); [ "$CODENAME" = "focal" ] && apt-get install -y libasan6 python3.8-venv \ || apt-get install -y libasan8 \ && apt-get install -y \ pkg-config \ @@ -32,57 +32,74 @@ RUN ln -snf "/usr/share/zoneinfo/$TZ" /etc/localtime \ g++ \ clang \ build-essential \ + autoconf \ ninja-build \ libubsan1 \ libssl-dev \ zlib1g-dev \ libubsan1 \ - cmake + pipx \ + gdb \ + python3 \ + python3-pip \ + unzip \ + clang-format \ + lldb \ + libonig5 \ + libgmp-dev \ + vim \ + ca-certificates \ + procps \ + curl \ + jq \ + wget \ + bison \ + re2c \ + libxml2-dev \ + libicu-dev \ + libsqlite3-dev \ + zlib1g-dev \ + libcurl4-openssl-dev \ + libreadline-dev \ + libffi-dev \ + libonig-dev \ + libsodium-dev \ + libgmp-dev \ + libzip-dev \ + && pipx install cqlsh \ + && pipx install cmake RUN git clone --depth 1 $LIBUV_REPO /libuv-src \ && cd libuv-src \ && git fetch --tags \ && git checkout -b $LIBUV_VERSION tags/$LIBUV_VERSION \ - && mkdir build \ - && cd build \ - && LDFLAGS="-flto -g" cmake -G Ninja \ + && LDFLAGS="-flto -g" cmake -G Ninja -B build \ -DBUILD_TESTING=OFF \ -DBUILD_BENCHMARKS=OFF \ -DLIBUV_BUILD_SHARED=ON \ -DCMAKE_CXX_COMPILER_LAUNCHER=ccache \ - -DCMAKE_BUILD_TYPE="$LIBUV_BUILD_TYPE" .. \ - && ninja install \ - && cd .. rm -rf build + -DCMAKE_BUILD_TYPE="$LIBUV_BUILD_TYPE" \ + && cmake --build build \ + && cmake --install build \ + && rm -rf build FROM base AS php_build -ARG PHP_VERSION="8.3.8" -ARG PHP_ZTS="no" +ARG PHP_VERSION="8.4" +ARG PHP_THREAD_MODEL="nts" ARG PHP_DEBUG="no" ARG PHP_MEM_SANITIZERS="no" COPY ./scripts /tmp/scripts -RUN apt-get -y install \ - bison \ - autoconf \ - re2c \ - libxml2-dev \ - libicu-dev \ - libsqlite3-dev \ - zlib1g-dev \ - libcurl4-openssl-dev \ - libffi-dev \ - libonig-dev \ - libzip-dev - ENV PATH="$PATH:/php/bin" -RUN /tmp/scripts/compile-php.sh -v $PHP_VERSION -o /php -s $PHP_MEM_SANITIZERS -d $PHP_DEBUG -z $PHP_ZTS \ - && php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');" \ +RUN /tmp/scripts/compile-php.sh -v $PHP_VERSION -o /php -s $PHP_MEM_SANITIZERS -d $PHP_DEBUG -z $PHP_THREAD_MODEL -a + +RUN wget -c -O composer-setup.php 'https://getcomposer.org/installer' \ && php composer-setup.php --install-dir=/php/bin --filename=composer \ && chmod +x /php/bin/composer \ - && php -r "unlink('composer-setup.php');" \ + && rm -f composer-setup.php \ && rm -rf /tmp/scripts COPY ./docker/php.ini /php/lib/php.ini @@ -97,9 +114,7 @@ ENV LDFLAGS="-flto -g" RUN git clone --depth 1 $SCYLLADB_DRIVER_REPO /scylladb-cpp-src \ && cd /scylladb-cpp-src \ - && mkdir build \ - && cd build \ - && cmake -G Ninja \ + && cmake -G Ninja -B build \ -DCASS_CPP_STANDARD=17 \ -DCASS_BUILD_STATIC=ON \ -DCASS_BUILD_SHARED=ON \ @@ -111,9 +126,10 @@ RUN git clone --depth 1 $SCYLLADB_DRIVER_REPO /scylladb-cpp-src \ -DCMAKE_CXX_COMPILER_LAUNCHER=ccache \ -DCMAKE_EXPORT_COMPILE_COMMANDS="OFF" \ -DCMAKE_INSTALL_PREFIX="/scylladb-cpp" \ - -DCMAKE_BUILD_TYPE="$SCYLLADB_DRIVER_BUILD_TYPE" .. \ - && ninja install \ - && cd ../ && rm -rf build + -DCMAKE_BUILD_TYPE="$SCYLLADB_DRIVER_BUILD_TYPE" \ + && cmake --build build \ + && cmake --install build \ + && rm -rf build FROM base AS cassandra_cpp_driver_build @@ -125,9 +141,7 @@ ENV LDFLAGS="-flto -g" RUN git clone --depth 1 $CASSANDRA_DRIVER_REPO /cassandra-cpp-src \ && cd /cassandra-cpp-src \ - && mkdir build \ - && cd build \ - && cmake -G Ninja \ + && cmake -G Ninja -B build \ -DCASS_CPP_STANDARD=17 \ -DCASS_BUILD_STATIC=ON \ -DCASS_BUILD_SHARED=ON \ @@ -144,9 +158,9 @@ RUN git clone --depth 1 $CASSANDRA_DRIVER_REPO /cassandra-cpp-src \ -DCMAKE_EXPORT_COMPILE_COMMANDS="OFF" \ -DCMAKE_INSTALL_PREFIX="/cassandra-cpp" \ -DCMAKE_BUILD_TYPE="$CASSANDRA_DRIVER_BUILD_TYPE" \ - .. \ - && ninja install \ - && cd ../ && rm -rf build + && cmake --build build \ + && cmake --install build \ + && rm -rf build FROM base AS final @@ -159,26 +173,3 @@ COPY --from=php_build /php /php ENV PKG_CONFIG_PATH="$PKG_CONFIG_PATH:/cassandra-cpp/lib/pkgconfig:/scylladb-cpp/lib/pkgconfig" ENV LD_LIBRARY_PATH="$LD_LIBRARY_PATH:/scylladb-cpp/lib:/cassandra-cpp/lib" -ENV PATH="$PATH:/root/.local/bin:/php/bin" - -RUN apt-get update \ - && apt-get upgrade -y \ - && CODENAME=$(grep VERSION_CODENAME /etc/os-release | cut -d= -f2); [ "$CODENAME" = "focal" ] && apt-get install -y mlocate python3.8-venv \ - || apt-get install -y plocate \ - && apt-get install -y \ - pipx \ - gdb \ - python3 \ - python3-pip \ - unzip \ - clang-format \ - lldb \ - libonig5 \ - libgmp-dev \ - vim \ - ca-certificates \ - procps \ - curl \ - wget \ - && pipx install cqlsh \ - && updatedb \ No newline at end of file diff --git a/generate-presets.php b/generate-presets.php new file mode 100644 index 000000000..bf22f69be --- /dev/null +++ b/generate-presets.php @@ -0,0 +1,97 @@ +value . strtoupper($phpTS->value) . ($useCassandra ? 'Cassandra' : ''); + + return [ + "name" => $fullName, + "displayName" => $fullName, + "description" => "", + "generator" => "Ninja", + "binaryDir" => './out/' . $fullName, + "cacheVariables" => [ + "CMAKE_BUILD_TYPE" => "Debug", + "CMAKE_INSTALL_PREFIX" => './out/' . $fullName . '/install', + "ENABLE_SANITIZERS" => $buildType === BuildType::Debug ? 'ON' : 'OFF', + 'SANITIZE_UNDEFINED' => $buildType === BuildType::Debug ? 'ON' : 'OFF', + 'SANITIZE_ADDRESS' => $buildType === BuildType::Debug ? 'ON' : 'OFF', + 'USE_LIBCASSANDRA' => $useCassandra ? 'ON' : 'OFF', + 'PHP_VERSION_FOR_PHP_CONFIG' => $phpVersion->value, + 'LINK_LIBUV_STATIC' => 'ON', + 'PHP_DRIVER_STATIC' => 'ON', + 'PHP_THREAD_SAFE' => $phpTS === PHPTS::ZTS ? 'ON' : 'OFF', + ], + ]; +} + +function main() +{ + $presetNames = ['Debug', 'Release', 'RelWithDebugInfo']; + $useCassandra = [true, false]; + $buildTypes = BuildType::cases(); + $phpVersions = PHPVersion::cases(); + $phpTS = PHPTS::cases(); + + $presets = []; + + foreach ($presetNames as $presetName) { + foreach ($useCassandra as $useCassandraValue) { + foreach ($buildTypes as $buildType) { + foreach ($phpVersions as $phpVersion) { + foreach ($phpTS as $ts) { + $presets[] = preset($presetName, $useCassandraValue, $buildType, $phpVersion, $ts); + } + } + } + } + } + + + $cmakePresets = [ + 'version' => 2, + "configurePresets" => $presets, + ]; + + $result = @file_put_contents( + __DIR__ . DIRECTORY_SEPARATOR . 'CMakePresets.json', + json_encode($cmakePresets, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES), + LOCK_EX, + ); + + if ($result === false) { + echo 'Failed to write CMakePresets.json'; + exit(1); + } +} + + +main(); diff --git a/include/php_driver.h b/include/php_driver.h index d9bd236cb..6c87dca3d 100644 --- a/include/php_driver.h +++ b/include/php_driver.h @@ -2,42 +2,19 @@ #include #include -#include - -#ifdef HAVE_CONFIG_H -#include -#endif - -#ifdef HAVE_SYS_TYPES_H -#include -#endif - -#ifdef HAVE_UNISTD_H -#include -#endif - -#ifdef HAVE_SYS_STAT_H #include -#endif - -#ifdef HAVE_UNISTD_H +#include #include -#endif +#include #ifdef __cplusplus extern "C" { #endif +#include #include - -#ifdef HAVE_STRING_H #include -#endif - -#ifdef HAVE_INTTYPES_H -#include -#endif #include diff --git a/php-8.4.3.tar.gz b/php-8.4.3.tar.gz new file mode 100644 index 000000000..cba928c40 Binary files /dev/null and b/php-8.4.3.tar.gz differ diff --git a/scripts/build.sh b/scripts/build.sh new file mode 100755 index 000000000..3b0dee859 --- /dev/null +++ b/scripts/build.sh @@ -0,0 +1,30 @@ +#!/bin/bash + +DRIVER=${1:-"scylladb"} +VERSION=${2:-"master"} + +rm -rf out + +phpize --clean +phpize + +if [[ "$DRIVER" == "cassandra" ]]; then + ./configure \ + --enable-lto \ + --enable-avx \ + --enable-libuv-static \ + --enable-driver-static \ + --enable-libcassandra \ + --with-version="$VERSION" +else + ./configure \ + --enable-lto \ + --enable-avx \ + --enable-libuv-static \ + --enable-driver-static \ + --with-version="$VERSION" +fi + +make "-j$(nproc)" || exit 1 +make install +# mv "$(php-config --extension-dir)/cassandra.so" . diff --git a/scripts/compile-cpp-driver.sh b/scripts/compile-cpp-driver.sh index 4d59232a8..76027ba94 100755 --- a/scripts/compile-cpp-driver.sh +++ b/scripts/compile-cpp-driver.sh @@ -1,27 +1,52 @@ -SCYLLA_OR_CASSANDRA=$1 +#!/bin/bash + +SCYLLA_OR_CASSANDRA=${1:-"scylladb"} CURRENT_DIR="$(pwd)" -if [ -z "$SCYLLA_OR_CASSANDRA" ]; then - SCYLLA_OR_CASSANDRA="scylladb" +GIT_REPO="https://github.com/$SCYLLA_OR_CASSANDRA/cpp-driver.git" +GIT_OUTPUT="/opt/$SCYLLA_OR_CASSANDRA-driver" + +is_linux() { + local value + + value="$(uname -s)" + + if [ "$value" = "Linux" ]; then + return 0 + fi + + return 1 +} + +if ! is_linux; then + echo "This script is for Linux only" + exit 1 fi -if [ "$SCYLLA_OR_CASSANDRA" = "scylladb" ]; then - GIT_REPO="https://github.com/scylladb/cpp-driver.git" - GIT_OUTPUT="/opt/scylladb-driver" -else - GIT_REPO="https://github.com/datastax/cpp-driver.git" - GIT_OUTPUT="/opt/cassandra-driver" +. /etc/os-release + +if [[ "$NAME" == "Fedora Linux" ]]; then + dnf install \ + cmake \ + pkg-config \ + gcc \ + ninja-build \ + openssl-devel \ + openssl-devel-engine || exit 1 +fi + +if [[ "$NAME" == "Ubuntu" ]]; then + apt-get install \ + pkg-config \ + build-essential \ + libssl-dev || exit 1 fi git clone --depth 1 "$GIT_REPO" "$GIT_OUTPUT" cd "$GIT_OUTPUT" || exit 1 -mkdir build || exit 1 - -cd build || exit 1 - -CFLAGS="-fPIC" CXXFLAGS="-fPIC -Wno-error=redundant-move" LDFLAGS="-flto" cmake -G Ninja \ +CFLAGS="-fPIC" CXXFLAGS="-fPIC -Wno-error=redundant-move" LDFLAGS="-flto" cmake -G Ninja -B build \ -DCASS_CPP_STANDARD=17 \ -DCASS_BUILD_STATIC=ON \ -DCASS_BUILD_SHARED=ON \ @@ -32,10 +57,9 @@ CFLAGS="-fPIC" CXXFLAGS="-fPIC -Wno-error=redundant-move" LDFLAGS="-flto" cmake -DCASS_USE_ZLIB=ON \ -DCMAKE_CXX_COMPILER_LAUNCHER=ccache \ -DCMAKE_EXPORT_COMPILE_COMMANDS="OFF" \ - -DCMAKE_BUILD_TYPE="RelWithInfo" \ - .. + -DCMAKE_BUILD_TYPE="RelWithInfo" -CFLAGS="-fPIC" CXXFLAGS="-fPIC -Wno-error=redundant-move" LDFLAGS="-flto" ninja install +CFLAGS="-fPIC" CXXFLAGS="-fPIC -Wno-error=redundant-move" LDFLAGS="-flto" cmake --build build cd .. || exit diff --git a/scripts/compile-libuv.sh b/scripts/compile-libuv.sh index 8da850187..3c11a6148 100755 --- a/scripts/compile-libuv.sh +++ b/scripts/compile-libuv.sh @@ -1,4 +1,6 @@ -LIBUV_VERSION="v1.48.0" +#!/bin/bash + +LIBUV_VERSION="v1.50.0" LIBUV_REPO="https://github.com/libuv/libuv.git" CURRENT_DIR="$(pwd)" @@ -10,20 +12,14 @@ git fetch --tags git checkout -b $LIBUV_VERSION tags/$LIBUV_VERSION -mkdir build || exit 1 - -cd build || exit 1 - -LDFLAGS="-flto" CFLAGS="-fPIC" cmake -G Ninja \ +LDFLAGS="-flto" CFLAGS="-fPIC" cmake -G Ninja -B build \ -DBUILD_TESTING=OFF \ -DBUILD_BENCHMARKS=OFF \ - -DLIBUV_BUILD_SHARED=ON \ + -DLIBUV_BUILD_SHARED=OFF \ -DCMAKE_CXX_COMPILER_LAUNCHER=ccache \ - -DCMAKE_BUILD_TYPE="RelWithInfo" .. - -LDFLAGS="-flto" CFLAGS="-fPIC" ninja install + -DCMAKE_BUILD_TYPE="RelWithInfo" -cd .. || exit +LDFLAGS="-flto" CFLAGS="-fPIC" cmake --build build rm -rf build diff --git a/scripts/compile-php.sh b/scripts/compile-php.sh index 3a9a02930..d295bcf81 100755 --- a/scripts/compile-php.sh +++ b/scripts/compile-php.sh @@ -1,6 +1,8 @@ #!/usr/bin/env bash # -*- coding: utf-8 -*- +. /etc/os-release + print_usage() { echo "" echo "Usage: compile-php.sh [OPTION] [ARG]" @@ -12,91 +14,65 @@ print_usage() { echo "-a compile PHP without version suffix" echo "-s Use Memory and Undefined Sanitizers" echo "----------" - echo "Example: compiling PHP 8.2.7 in debug mode with Thread Safety" - echo "./compile-php.sh -v 8.2.7 -s -d -z" + echo "Example: compiling PHP 8.2 in debug mode with Thread Safety" + echo "./compile-php.sh -v 8.2 -s yes -d yes -z yes" echo "" } -which_linux() { - local val=$(grep "NAME=\"$1\"" "/etc/os-release") - - if [ "$val" = "NAME=$1" ]; then - return 0 - fi +PHP_VERSION="8.4" +WITH_VERSION="yes" +PHP_THREAD_MODEL="nts" +ENABLE_DEBUG="no" +OUTPUT="$(pwd)/php" +ENABLE_SANITIZERS="no" - return 1 -} +while getopts "v:o:z:s:d:a" option; do + case "$option" in + "v") PHP_VERSION="$OPTARG" ;; + "z") PHP_THREAD_MODEL="$OPTARG" ;; + "o") OUTPUT="$OPTARG" ;; + "d") ENABLE_DEBUG="$OPTARG" ;; + "s") ENABLE_SANITIZERS="$OPTARG" ;; + "a") WITH_VERSION="no" ;; + *) print_usage ;; + esac +done -is_linux() { - local value +if [[ -z "$PHP_VERSION" ]]; then + print_usage + exit 1 +fi - value=$(uname -s) +fetch_versions() { + local page=$1 - if [ "$value" = "Linux" ]; then - return 0 - fi + curl -s "https://api.github.com/repos/php/php-src/tags?page=$page&per_page=100" | jq -r '.[].name' +} - return 1 +fetch_latest_php_version() { + (fetch_versions "1" && fetch_versions "2" && fetch_versions "3") | + /bin/grep -E "^php-$PHP_VERSION\.[0-9]+$" | + sed 's/^php-//' | + sort -V | + tail -n 1 } -is_macos() { +is_linux() { local value - value=$(uname -s) + value="$(uname -s)" - if [ "$value" = "Darwin" ]; then + if [ "$value" = "Linux" ]; then return 0 fi return 1 } -install_macos_dep() { - local package_path - local path - local PKG_CONFIG="" - local PATH_EXPORT="" - - for package in "$@"; do - output=$(brew install "$package") - - package_path=$(perl -lne 'print $1 if /export PKG_CONFIG_PATH=\"(.*)\"/;' <"$output") - path=$(perl -lne 'print $1 if /export PATH=\"(.*):$PATH\"/;' <"$output") - if [ -n "$package_path" ]; then - PKG_CONFIG="$PKG_CONFIG:$package_path" - fi - if [ -n "$path" ]; then - PATH_EXPORT="$PATH_EXPORT$path:" - fi - done - - if [ -n "$PKG_CONFIG" ]; then - echo "export PKG_CONFIG_PATH=\"\$PKG_CONFIG_PATH$PKG_CONFIG\"" >>~/.profile - fi - - if [ -n "$PATH_EXPORT" ]; then - echo "export PATH=\"$PATH_EXPORT\$PATH\"" >>~/.profile - fi - -} - install_deps() { - if is_macos; then - install_macos_dep \ - pkg-config \ - bison \ - re2c \ - libxml2 \ - sqlite3 \ - zlib-ng \ - readline \ - libiconv \ - libffi - fi - if is_linux; then - if which_linux "Fedora Linux"; then - sudo dnf install \ + if [[ "$NAME" == "Fedora Linux" ]]; then + dnf install \ re2c \ cmake \ gcc \ @@ -115,8 +91,8 @@ install_deps() { gmp-devel -y || exit 1 fi - if which_linux "Ubuntu"; then - sudo apt-get install \ + if [[ "$NAME" == "Ubuntu" ]]; then + apt-get install \ pkg-config \ build-essential \ libssl-dev \ @@ -132,54 +108,42 @@ install_deps() { libonig-dev \ libsodium-dev \ libgmp-dev \ - libasan8 \ libubsan1 \ libzip-dev -y || exit 1 fi - fi - } compile_php() { - local ZTS="$1" - local WITH_DEBUG="$2" - local KEEP_PHP_SOURCE="$3" - - local PHP_BASE_VERSION=$(echo "$PHP_VERSION" | cut -d. -f1,2) - local config=( - --enable-embed=static - --enable-phpdbg --enable-opcache - --disable-short-tags - --enable-phpdbg-debug --enable-rtld-now --with-openssl --with-zlib --with-curl - --with-ffi --enable-pcntl --with-pear --enable-sockets - --with-pic --enable-mbstring - --with-sqlite3 - --enable-calendar + --disable-short-tags + --with-pic ) + local FULL_PHP_VERSION + FULL_PHP_VERSION="$(fetch_latest_php_version)" + local OUTPUT_PATH="$OUTPUT" - if [[ "$WITHOUT_VERSION" == "yes" ]]; then - OUTPUT_PATH="$OUTPUT_PATH/$PHP_BASE_VERSION" - if [[ "$WITH_DEBUG" == "yes" ]]; then + if [[ "$WITH_VERSION" == "yes" ]]; then + OUTPUT_PATH="$OUTPUT_PATH/$PHP_VERSION" + if [[ "$ENABLE_DEBUG" == "yes" ]]; then OUTPUT_PATH="$OUTPUT_PATH-debug" config+=("--enable-debug") else OUTPUT_PATH="$OUTPUT_PATH-release" fi - if [[ "$ZTS" == "yes" || "$ZTS" == "zts" ]]; then + if [[ "$PHP_THREAD_MODEL" == "zts" ]]; then OUTPUT_PATH="$OUTPUT_PATH-zts" config+=("--enable-zts") else @@ -191,93 +155,34 @@ compile_php() { config+=("--enable-address-sanitizer" "--enable-undefined-sanitizer") fi - if is_macos; then - config+=("--with-iconv=/opt/homebrew/opt/libiconv") - fi - rm -rf "$OUTPUT_PATH" || exit 1 mkdir -p "$OUTPUT_PATH" || exit 1 - if [ ! -f "php-$PHP_VERSION.tar.gz" ]; then - wget -O "php-$PHP_VERSION.tar.gz" "https://github.com/php/php-src/archive/refs/tags/php-$PHP_VERSION.tar.gz" || exit 1 + if [ ! -f "php-$FULL_PHP_VERSION.tar.gz" ]; then + wget -O "php-$FULL_PHP_VERSION.tar.gz" "https://github.com/php/php-src/archive/refs/tags/php-$FULL_PHP_VERSION.tar.gz" || exit 1 fi - tar -C "$OUTPUT_PATH" -xzf "php-$PHP_VERSION.tar.gz" || exit 1 - mv "$OUTPUT_PATH/php-src-php-$PHP_VERSION" "$OUTPUT_PATH/src" || exit 1 + tar -C "$OUTPUT_PATH" -xzf "php-$FULL_PHP_VERSION.tar.gz" || exit 1 + mv "$OUTPUT_PATH/php-src-php-$FULL_PHP_VERSION" "$OUTPUT_PATH/src" || exit 1 - if [[ "$KEEP_PHP_SOURCE" == "no" ]]; then - rm -f "php-$PHP_VERSION.tar.gz" || exit 1 - fi + rm -f "php-$FULL_PHP_VERSION.tar.gz" || exit 1 pushd "$OUTPUT_PATH/src" || exit 1 - { - ./buildconf --force - ./configure CFLAGS="$CFLAGS" CXXFLAGS="$CXXFLAGS" --prefix="$OUTPUT_PATH" "${config[@]}" || exit 1 - make "-j$(nproc)" || exit 1 - make install || exit 1 - } + ./buildconf --force + if [ "$ENABLE_DEBUG" = "yes" ]; then + ./configure \ + CFLAGS="-g -ggdb -g3 -gdwarf-4 -fno-omit-frame-pointer" \ + CXXFLAGS="-g -ggdb -g3 -gdwarf-4 -fno-omit-frame-pointer" \ + --prefix="$OUTPUT_PATH" \ + "${config[@]}" || exit 1 + else + ./configure CFLAGS="-O2" CXXFLAGS="-O2" --prefix="$OUTPUT_PATH" "${config[@]}" || exit 1 + fi + make "-j$(nproc)" || exit 1 + make install || exit 1 popd || exit 1 } -check_deps() { - deps="wget make git gcc g++" - - for dep in $deps; do - [ -z "$(command -v "$dep")" ] && echo "Unsatisfied dependency: $dep" && exit 1 - done -} - -check_deps - -while getopts "v:zo:s:d:ka" option; do - case "$option" in - "v") PHP_VERSION="$OPTARG" ;; - "z") PHP_ZTS="$OPTARG" ;; - "o") OUTPUT="$OPTARG" ;; - "d") ENABLE_DEBUG="$OPTARG" ;; - "k") KEEP_PHP_SOURCE="yes" ;; - "s") ENABLE_SANITIZERS="$OPTARG" ;; - "a") WITHOUT_VERSION="yes" ;; - *) print_usage ;; - esac -done - -if [[ -z "$WITHOUT_VERSION" ]]; then - WITHOUT_VERSION="no" -fi - -if [[ -z "$PHP_ZTS" ]]; then - PHP_ZTS="nts" -fi - -if [[ -z "$KEEP_PHP_SOURCE" ]]; then - KEEP_PHP_SOURCE="no" -fi - -if [[ -z "$ENABLE_DEBUG" ]]; then - ENABLE_DEBUG="no" -fi - -if [[ -z "$OUTPUT" ]]; then - OUTPUT="$(pwd)" -fi - -if [[ -z "$ENABLE_SANITIZERS" ]]; then - ENABLE_SANITIZERS="no" -fi - -if [[ -z "$PHP_VERSION" ]]; then - print_usage - exit 1 -fi - -CFLAGS="-g -ggdb -g3 -gdwarf-4 -fno-omit-frame-pointer" -CXXFLAGS="-g -ggdb -g3 -gdwarf-4 -fno-omit-frame-pointer" - -install_deps || exit 1 - -pritnf "\n\nCompiling PHP $PHP_VERSION in $OUTPUT: Debug mode: $ENABLE_DEBUG, Thread Safety: $PHP_ZTS, Sanitizers: $ENABLE_SANITIZERS\n" - -compile_php "$PHP_ZTS" "$ENABLE_DEBUG" "$KEEP_PHP_SOURCE" || exit 1 +compile_php diff --git a/scripts/gen_stub.php b/scripts/gen_stub.php deleted file mode 100755 index 1fff123d8..000000000 --- a/scripts/gen_stub.php +++ /dev/null @@ -1,5011 +0,0 @@ -#!/usr/bin/env php -getPathName(); - if (preg_match('/\.stub\.php$/', $pathName)) { - $pathNames[] = $pathName; - } - } - - // Make sure stub files are processed in a predictable, system-independent order. - sort($pathNames); - - $fileInfos = []; - foreach ($pathNames as $pathName) { - $fileInfo = processStubFile($pathName, $context); - if ($fileInfo) { - $fileInfos[] = $fileInfo; - } - } - return $fileInfos; -} - -function processStubFile(string $stubFile, Context $context, bool $includeOnly = false): ?FileInfo { - try { - if (!file_exists($stubFile)) { - throw new Exception("File $stubFile does not exist"); - } - - if (!$includeOnly) { - $stubFilenameWithoutExtension = str_replace(".stub.php", "", $stubFile); - $arginfoFile = "{$stubFilenameWithoutExtension}_arginfo.h"; - $legacyFile = "{$stubFilenameWithoutExtension}_legacy_arginfo.h"; - - $stubCode = file_get_contents($stubFile); - $stubHash = computeStubHash($stubCode); - $oldStubHash = extractStubHash($arginfoFile); - if ($stubHash === $oldStubHash && !$context->forceParse) { - /* Stub file did not change, do not regenerate. */ - return null; - } - } - - if (!$fileInfo = $context->parsedFiles[$stubFile] ?? null) { - initPhpParser(); - $fileInfo = parseStubFile($stubCode ?? file_get_contents($stubFile)); - $context->parsedFiles[$stubFile] = $fileInfo; - - foreach ($fileInfo->dependencies as $dependency) { - // TODO add header search path for extensions? - $prefixes = [dirname($stubFile) . "/", dirname(__DIR__) . "/"]; - foreach ($prefixes as $prefix) { - $depFile = $prefix . $dependency; - if (file_exists($depFile)) { - break; - } - $depFile = null; - } - if (!$depFile) { - throw new Exception("File $stubFile includes a file $dependency which does not exist"); - } - processStubFile($depFile, $context, true); - } - - $constInfos = $fileInfo->getAllConstInfos(); - $context->allConstInfos = array_merge($context->allConstInfos, $constInfos); - } - - if ($includeOnly) { - return $fileInfo; - } - - $arginfoCode = generateArgInfoCode( - basename($stubFilenameWithoutExtension), - $fileInfo, - $context->allConstInfos, - $stubHash - ); - if (($context->forceRegeneration || $stubHash !== $oldStubHash) && file_put_contents($arginfoFile, $arginfoCode)) { - echo "Saved $arginfoFile\n"; - } - - if ($fileInfo->generateLegacyArginfoForPhpVersionId !== null && $fileInfo->generateLegacyArginfoForPhpVersionId < PHP_80_VERSION_ID) { - $legacyFileInfo = clone $fileInfo; - - foreach ($legacyFileInfo->getAllFuncInfos() as $funcInfo) { - $funcInfo->discardInfoForOldPhpVersions(); - } - foreach ($legacyFileInfo->getAllConstInfos() as $constInfo) { - $constInfo->discardInfoForOldPhpVersions(); - } - foreach ($legacyFileInfo->getAllPropertyInfos() as $propertyInfo) { - $propertyInfo->discardInfoForOldPhpVersions(); - } - - $arginfoCode = generateArgInfoCode( - basename($stubFilenameWithoutExtension), - $legacyFileInfo, - $context->allConstInfos, - $stubHash - ); - if (($context->forceRegeneration || $stubHash !== $oldStubHash) && file_put_contents($legacyFile, $arginfoCode)) { - echo "Saved $legacyFile\n"; - } - } - - return $fileInfo; - } catch (Exception $e) { - echo "In $stubFile:\n{$e->getMessage()}\n"; - exit(1); - } -} - -function computeStubHash(string $stubCode): string { - return sha1(str_replace("\r\n", "\n", $stubCode)); -} - -function extractStubHash(string $arginfoFile): ?string { - if (!file_exists($arginfoFile)) { - return null; - } - - $arginfoCode = file_get_contents($arginfoFile); - if (!preg_match('/\* Stub hash: ([0-9a-f]+) \*/', $arginfoCode, $matches)) { - return null; - } - - return $matches[1]; -} - -class Context { - public bool $forceParse = false; - public bool $forceRegeneration = false; - /** @var iterable */ - public iterable $allConstInfos = []; - /** @var FileInfo[] */ - public array $parsedFiles = []; -} - -class ArrayType extends SimpleType { - public Type $keyType; - public Type $valueType; - - public static function createGenericArray(): self - { - return new ArrayType(Type::fromString("int|string"), Type::fromString("mixed|ref")); - } - - public function __construct(Type $keyType, Type $valueType) - { - parent::__construct("array", true); - - $this->keyType = $keyType; - $this->valueType = $valueType; - } - - public function toOptimizerTypeMask(): string { - $typeMasks = [ - parent::toOptimizerTypeMask(), - $this->keyType->toOptimizerTypeMaskForArrayKey(), - $this->valueType->toOptimizerTypeMaskForArrayValue(), - ]; - - return implode("|", $typeMasks); - } - - public function equals(SimpleType $other): bool { - if (!parent::equals($other)) { - return false; - } - - assert(get_class($other) === self::class); - - return Type::equals($this->keyType, $other->keyType) && - Type::equals($this->valueType, $other->valueType); - } -} - -class SimpleType { - public string $name; - public bool $isBuiltin; - - public static function fromNode(Node $node): SimpleType { - if ($node instanceof Node\Name) { - if ($node->toLowerString() === 'static') { - // PHP internally considers "static" a builtin type. - return new SimpleType($node->toLowerString(), true); - } - - if ($node->toLowerString() === 'self') { - throw new Exception('The exact class name must be used instead of "self"'); - } - - assert($node->isFullyQualified()); - return new SimpleType($node->toString(), false); - } - - if ($node instanceof Node\Identifier) { - if ($node->toLowerString() === 'array') { - return ArrayType::createGenericArray(); - } - - return new SimpleType($node->toLowerString(), true); - } - - throw new Exception("Unexpected node type"); - } - - public static function fromString(string $typeString): SimpleType - { - switch (strtolower($typeString)) { - case "void": - case "null": - case "false": - case "true": - case "bool": - case "int": - case "float": - case "string": - case "callable": - case "object": - case "resource": - case "mixed": - case "static": - case "never": - case "ref": - return new SimpleType(strtolower($typeString), true); - case "array": - return ArrayType::createGenericArray(); - case "self": - throw new Exception('The exact class name must be used instead of "self"'); - case "iterable": - throw new Exception('This should not happen'); - } - - $matches = []; - $isArray = preg_match("/(.*)\s*\[\s*\]/", $typeString, $matches); - if ($isArray) { - return new ArrayType(Type::fromString("int"), Type::fromString($matches[1])); - } - - $matches = []; - $isArray = preg_match("/array\s*<\s*([A-Za-z0-9_-|]+)?(\s*,\s*)?([A-Za-z0-9_-|]+)?\s*>/i", $typeString, $matches); - if ($isArray) { - if (empty($matches[1]) || empty($matches[3])) { - throw new Exception("array<> type hint must have both a key and a value"); - } - - return new ArrayType(Type::fromString($matches[1]), Type::fromString($matches[3])); - } - - return new SimpleType($typeString, false); - } - - /** - * @param mixed $value - */ - public static function fromValue($value): SimpleType - { - switch (gettype($value)) { - case "NULL": - return SimpleType::null(); - case "boolean": - return SimpleType::bool(); - case "integer": - return SimpleType::int(); - case "double": - return SimpleType::float(); - case "string": - return SimpleType::string(); - case "array": - return SimpleType::array(); - case "object": - return SimpleType::object(); - default: - throw new Exception("Type \"" . gettype($value) . "\" cannot be inferred based on value"); - } - } - - public static function null(): SimpleType - { - return new SimpleType("null", true); - } - - public static function bool(): SimpleType - { - return new SimpleType("bool", true); - } - - public static function int(): SimpleType - { - return new SimpleType("int", true); - } - - public static function float(): SimpleType - { - return new SimpleType("float", true); - } - - public static function string(): SimpleType - { - return new SimpleType("string", true); - } - - public static function array(): SimpleType - { - return new SimpleType("array", true); - } - - public static function object(): SimpleType - { - return new SimpleType("object", true); - } - - public static function void(): SimpleType - { - return new SimpleType("void", true); - } - - protected function __construct(string $name, bool $isBuiltin) { - $this->name = $name; - $this->isBuiltin = $isBuiltin; - } - - public function isScalar(): bool { - return $this->isBuiltin && in_array($this->name, ["null", "false", "true", "bool", "int", "float"], true); - } - - public function isNull(): bool { - return $this->isBuiltin && $this->name === 'null'; - } - - public function isBool(): bool { - return $this->isBuiltin && $this->name === 'bool'; - } - - public function isInt(): bool { - return $this->isBuiltin && $this->name === 'int'; - } - - public function isFloat(): bool { - return $this->isBuiltin && $this->name === 'float'; - } - - public function isString(): bool { - return $this->isBuiltin && $this->name === 'string'; - } - - public function isArray(): bool { - return $this->isBuiltin && $this->name === 'array'; - } - - public function toTypeCode(): string { - assert($this->isBuiltin); - switch ($this->name) { - case "bool": - return "_IS_BOOL"; - case "int": - return "IS_LONG"; - case "float": - return "IS_DOUBLE"; - case "string": - return "IS_STRING"; - case "array": - return "IS_ARRAY"; - case "object": - return "IS_OBJECT"; - case "void": - return "IS_VOID"; - case "callable": - return "IS_CALLABLE"; - case "mixed": - return "IS_MIXED"; - case "static": - return "IS_STATIC"; - case "never": - return "IS_NEVER"; - case "null": - return "IS_NULL"; - case "false": - return "IS_FALSE"; - case "true": - return "IS_TRUE"; - default: - throw new Exception("Not implemented: $this->name"); - } - } - - public function toTypeMask(): string { - assert($this->isBuiltin); - - switch ($this->name) { - case "null": - return "MAY_BE_NULL"; - case "false": - return "MAY_BE_FALSE"; - case "true": - return "MAY_BE_TRUE"; - case "bool": - return "MAY_BE_BOOL"; - case "int": - return "MAY_BE_LONG"; - case "float": - return "MAY_BE_DOUBLE"; - case "string": - return "MAY_BE_STRING"; - case "array": - return "MAY_BE_ARRAY"; - case "object": - return "MAY_BE_OBJECT"; - case "callable": - return "MAY_BE_CALLABLE"; - case "mixed": - return "MAY_BE_ANY"; - case "void": - return "MAY_BE_VOID"; - case "static": - return "MAY_BE_STATIC"; - case "never": - return "MAY_BE_NEVER"; - default: - throw new Exception("Not implemented: $this->name"); - } - } - - public function toOptimizerTypeMaskForArrayKey(): string { - assert($this->isBuiltin); - - switch ($this->name) { - case "int": - return "MAY_BE_ARRAY_KEY_LONG"; - case "string": - return "MAY_BE_ARRAY_KEY_STRING"; - default: - throw new Exception("Type $this->name cannot be an array key"); - } - } - - public function toOptimizerTypeMaskForArrayValue(): string { - if (!$this->isBuiltin) { - return "MAY_BE_ARRAY_OF_OBJECT"; - } - - switch ($this->name) { - case "null": - return "MAY_BE_ARRAY_OF_NULL"; - case "false": - return "MAY_BE_ARRAY_OF_FALSE"; - case "true": - return "MAY_BE_ARRAY_OF_TRUE"; - case "bool": - return "MAY_BE_ARRAY_OF_FALSE|MAY_BE_ARRAY_OF_TRUE"; - case "int": - return "MAY_BE_ARRAY_OF_LONG"; - case "float": - return "MAY_BE_ARRAY_OF_DOUBLE"; - case "string": - return "MAY_BE_ARRAY_OF_STRING"; - case "array": - return "MAY_BE_ARRAY_OF_ARRAY"; - case "object": - return "MAY_BE_ARRAY_OF_OBJECT"; - case "resource": - return "MAY_BE_ARRAY_OF_RESOURCE"; - case "mixed": - return "MAY_BE_ARRAY_OF_ANY"; - case "ref": - return "MAY_BE_ARRAY_OF_REF"; - default: - throw new Exception("Type $this->name cannot be an array value"); - } - } - - public function toOptimizerTypeMask(): string { - if (!$this->isBuiltin) { - return "MAY_BE_OBJECT"; - } - - switch ($this->name) { - case "resource": - return "MAY_BE_RESOURCE"; - case "callable": - return "MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_LONG|MAY_BE_ARRAY_OF_STRING|MAY_BE_ARRAY_OF_OBJECT|MAY_BE_OBJECT"; - case "iterable": - return "MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_ANY|MAY_BE_ARRAY_OF_ANY|MAY_BE_OBJECT"; - case "mixed": - return "MAY_BE_ANY|MAY_BE_ARRAY_KEY_ANY|MAY_BE_ARRAY_OF_ANY"; - } - - return $this->toTypeMask(); - } - - public function toEscapedName(): string { - // Escape backslashes, and also encode \u and \U to avoid compilation errors in generated macros - return str_replace( - ['\\', '\\u', '\\U'], - ['\\\\', '\\\\165', '\\\\125'], - $this->name - ); - } - - public function toVarEscapedName(): string { - return str_replace('\\', '_', $this->name); - } - - public function equals(SimpleType $other): bool { - return $this->name === $other->name && $this->isBuiltin === $other->isBuiltin; - } -} - -class Type { - /** @var SimpleType[] */ - public array $types; - public bool $isIntersection; - - public static function fromNode(Node $node): Type { - if ($node instanceof Node\UnionType || $node instanceof Node\IntersectionType) { - $nestedTypeObjects = array_map(['Type', 'fromNode'], $node->types); - $types = []; - foreach ($nestedTypeObjects as $typeObject) { - array_push($types, ...$typeObject->types); - } - return new Type($types, ($node instanceof Node\IntersectionType)); - } - - if ($node instanceof Node\NullableType) { - return new Type( - [ - ...Type::fromNode($node->type)->types, - SimpleType::null(), - ], - false - ); - } - - if ($node instanceof Node\Identifier && $node->toLowerString() === "iterable") { - return new Type( - [ - SimpleType::fromString("Traversable"), - ArrayType::createGenericArray(), - ], - false - ); - } - - return new Type([SimpleType::fromNode($node)], false); - } - - public static function fromString(string $typeString): self { - $typeString .= "|"; - $simpleTypes = []; - $simpleTypeOffset = 0; - $inArray = false; - $isIntersection = false; - - $typeStringLength = strlen($typeString); - for ($i = 0; $i < $typeStringLength; $i++) { - $char = $typeString[$i]; - - if ($char === "<") { - $inArray = true; - continue; - } - - if ($char === ">") { - $inArray = false; - continue; - } - - if ($inArray) { - continue; - } - - if ($char === "|" || $char === "&") { - $isIntersection = ($char === "&"); - $simpleTypeName = trim(substr($typeString, $simpleTypeOffset, $i - $simpleTypeOffset)); - - $simpleTypes[] = SimpleType::fromString($simpleTypeName); - - $simpleTypeOffset = $i + 1; - } - } - - return new Type($simpleTypes, $isIntersection); - } - - /** - * @param SimpleType[] $types - */ - private function __construct(array $types, bool $isIntersection) { - $this->types = $types; - $this->isIntersection = $isIntersection; - } - - public function isScalar(): bool { - foreach ($this->types as $type) { - if (!$type->isScalar()) { - return false; - } - } - - return true; - } - - public function isNullable(): bool { - foreach ($this->types as $type) { - if ($type->isNull()) { - return true; - } - } - - return false; - } - - public function getWithoutNull(): Type { - return new Type( - array_values( - array_filter( - $this->types, - function(SimpleType $type) { - return !$type->isNull(); - } - ) - ), - false - ); - } - - public function tryToSimpleType(): ?SimpleType { - $withoutNull = $this->getWithoutNull(); - /* type has only null */ - if (count($withoutNull->types) === 0) { - return $this->types[0]; - } - if (count($withoutNull->types) === 1) { - return $withoutNull->types[0]; - } - return null; - } - - public function toArginfoType(): ArginfoType { - $classTypes = []; - $builtinTypes = []; - foreach ($this->types as $type) { - if ($type->isBuiltin) { - $builtinTypes[] = $type; - } else { - $classTypes[] = $type; - } - } - return new ArginfoType($classTypes, $builtinTypes); - } - - public function toOptimizerTypeMask(): string { - $optimizerTypes = []; - - foreach ($this->types as $type) { - // TODO Support for toOptimizerMask for intersection - $optimizerTypes[] = $type->toOptimizerTypeMask(); - } - - return implode("|", $optimizerTypes); - } - - public function toOptimizerTypeMaskForArrayKey(): string { - $typeMasks = []; - - foreach ($this->types as $type) { - $typeMasks[] = $type->toOptimizerTypeMaskForArrayKey(); - } - - return implode("|", $typeMasks); - } - - public function toOptimizerTypeMaskForArrayValue(): string { - $typeMasks = []; - - foreach ($this->types as $type) { - $typeMasks[] = $type->toOptimizerTypeMaskForArrayValue(); - } - - return implode("|", $typeMasks); - } - - public function getTypeForDoc(DOMDocument $doc): DOMElement { - if (count($this->types) > 1) { - $typeSort = $this->isIntersection ? "intersection" : "union"; - $typeElement = $doc->createElement('type'); - $typeElement->setAttribute("class", $typeSort); - - foreach ($this->types as $type) { - $unionTypeElement = $doc->createElement('type', $type->name); - $typeElement->appendChild($unionTypeElement); - } - } else { - $type = $this->types[0]; - $name = $type->name; - - $typeElement = $doc->createElement('type', $name); - } - - return $typeElement; - } - - public static function equals(?Type $a, ?Type $b): bool { - if ($a === null || $b === null) { - return $a === $b; - } - - if (count($a->types) !== count($b->types)) { - return false; - } - - for ($i = 0; $i < count($a->types); $i++) { - if (!$a->types[$i]->equals($b->types[$i])) { - return false; - } - } - - return true; - } - - public function __toString() { - if ($this->types === null) { - return 'mixed'; - } - - $char = $this->isIntersection ? '&' : '|'; - return implode($char, array_map( - function ($type) { return $type->name; }, - $this->types) - ); - } -} - -class ArginfoType { - /** @var SimpleType[] $classTypes */ - public array $classTypes; - /** @var SimpleType[] $builtinTypes */ - private array $builtinTypes; - - /** - * @param SimpleType[] $classTypes - * @param SimpleType[] $builtinTypes - */ - public function __construct(array $classTypes, array $builtinTypes) { - $this->classTypes = $classTypes; - $this->builtinTypes = $builtinTypes; - } - - public function hasClassType(): bool { - return !empty($this->classTypes); - } - - public function toClassTypeString(): string { - return implode('|', array_map(function(SimpleType $type) { - return $type->toEscapedName(); - }, $this->classTypes)); - } - - public function toTypeMask(): string { - if (empty($this->builtinTypes)) { - return '0'; - } - return implode('|', array_map(function(SimpleType $type) { - return $type->toTypeMask(); - }, $this->builtinTypes)); - } -} - -class ArgInfo { - const SEND_BY_VAL = 0; - const SEND_BY_REF = 1; - const SEND_PREFER_REF = 2; - - public string $name; - public int $sendBy; - public bool $isVariadic; - public ?Type $type; - public ?Type $phpDocType; - public ?string $defaultValue; - /** @var AttributeInfo[] */ - public array $attributes; - - /** - * @param AttributeInfo[] $attributes - */ - public function __construct( - string $name, - int $sendBy, - bool $isVariadic, - ?Type $type, - ?Type $phpDocType, - ?string $defaultValue, - array $attributes - ) { - $this->name = $name; - $this->sendBy = $sendBy; - $this->isVariadic = $isVariadic; - $this->setTypes($type, $phpDocType); - $this->defaultValue = $defaultValue; - $this->attributes = $attributes; - } - - public function equals(ArgInfo $other): bool { - return $this->name === $other->name - && $this->sendBy === $other->sendBy - && $this->isVariadic === $other->isVariadic - && Type::equals($this->type, $other->type) - && $this->defaultValue === $other->defaultValue; - } - - public function getSendByString(): string { - switch ($this->sendBy) { - case self::SEND_BY_VAL: - return "0"; - case self::SEND_BY_REF: - return "1"; - case self::SEND_PREFER_REF: - return "ZEND_SEND_PREFER_REF"; - } - throw new Exception("Invalid sendBy value"); - } - - public function getMethodSynopsisType(): Type { - if ($this->type) { - return $this->type; - } - - if ($this->phpDocType) { - return $this->phpDocType; - } - - throw new Exception("A parameter must have a type"); - } - - public function hasProperDefaultValue(): bool { - return $this->defaultValue !== null && $this->defaultValue !== "UNKNOWN"; - } - - public function getDefaultValueAsArginfoString(): string { - if ($this->hasProperDefaultValue()) { - return '"' . addslashes($this->defaultValue) . '"'; - } - - return "NULL"; - } - - public function getDefaultValueAsMethodSynopsisString(): ?string { - if ($this->defaultValue === null) { - return null; - } - - switch ($this->defaultValue) { - case 'UNKNOWN': - return null; - case 'false': - case 'true': - case 'null': - return "&{$this->defaultValue};"; - } - - return $this->defaultValue; - } - - private function setTypes(?Type $type, ?Type $phpDocType): void - { - $this->type = $type; - $this->phpDocType = $phpDocType; - } -} - -interface ConstOrClassConstName { - public function __toString(): string; - public function equals(ConstOrClassConstName $const): bool; - public function isClassConst(): bool; - public function isUnknown(): bool; -} - -abstract class AbstractConstName implements ConstOrClassConstName -{ - public function equals(ConstOrClassConstName $const): bool - { - return $this->__toString() === $const->__toString(); - } - - public function isUnknown(): bool - { - return strtolower($this->__toString()) === "unknown"; - } -} - -class ConstName extends AbstractConstName { - public string $const; - - public function __construct(?Name $namespace, string $const) - { - if ($namespace && ($namespace = $namespace->slice(0, -1))) { - $const = $namespace->toString() . '\\' . $const; - } - $this->const = $const; - } - - public function isClassConst(): bool - { - return false; - } - - public function isUnknown(): bool - { - $name = $this->__toString(); - if (($pos = strrpos($name, '\\')) !== false) { - $name = substr($name, $pos + 1); - } - return strtolower($name) === "unknown"; - } - - public function __toString(): string - { - return $this->const; - } -} - -class ClassConstName extends AbstractConstName { - public Name $class; - public string $const; - - public function __construct(Name $class, string $const) - { - $this->class = $class; - $this->const = $const; - } - - public function isClassConst(): bool - { - return true; - } - - public function __toString(): string - { - return $this->class->toString() . "::" . $this->const; - } -} - -class PropertyName { - public Name $class; - public string $property; - - public function __construct(Name $class, string $property) - { - $this->class = $class; - $this->property = $property; - } - - public function __toString() - { - return $this->class->toString() . "::$" . $this->property; - } -} - -interface FunctionOrMethodName { - public function getDeclaration(): string; - public function getArgInfoName(): string; - public function getMethodSynopsisFilename(): string; - public function getNameForAttributes(): string; - public function __toString(): string; - public function isMethod(): bool; - public function isConstructor(): bool; - public function isDestructor(): bool; -} - -class FunctionName implements FunctionOrMethodName { - private Name $name; - - public function __construct(Name $name) { - $this->name = $name; - } - - public function getNamespace(): ?string { - if ($this->name->isQualified()) { - return $this->name->slice(0, -1)->toString(); - } - return null; - } - - public function getNonNamespacedName(): string { - if ($this->name->isQualified()) { - throw new Exception("Namespaced name not supported here"); - } - return $this->name->toString(); - } - - public function getDeclarationName(): string { - return implode('_', $this->name->getParts()); - } - - public function getFunctionName(): string { - return $this->name->getLast(); - } - - public function getDeclaration(): string { - return "ZEND_FUNCTION({$this->getDeclarationName()});\n"; - } - - public function getArgInfoName(): string { - $underscoreName = implode('_', $this->name->getParts()); - return "arginfo_$underscoreName"; - } - - public function getMethodSynopsisFilename(): string { - return implode('_', $this->name->getParts()); - } - - public function getNameForAttributes(): string { - return strtolower($this->name->toString()); - } - - public function __toString(): string { - return $this->name->toString(); - } - - public function isMethod(): bool { - return false; - } - - public function isConstructor(): bool { - return false; - } - - public function isDestructor(): bool { - return false; - } -} - -class MethodName implements FunctionOrMethodName { - public Name $className; - public string $methodName; - - public function __construct(Name $className, string $methodName) { - $this->className = $className; - $this->methodName = $methodName; - } - - public function getDeclarationClassName(): string { - return implode('_', $this->className->getParts()); - } - - public function getDeclaration(): string { - return "ZEND_METHOD({$this->getDeclarationClassName()}, $this->methodName);\n"; - } - - public function getArgInfoName(): string { - return "arginfo_class_{$this->getDeclarationClassName()}_{$this->methodName}"; - } - - public function getMethodSynopsisFilename(): string { - return $this->getDeclarationClassName() . "_{$this->methodName}"; - } - - public function getNameForAttributes(): string { - return strtolower($this->methodName); - } - - public function __toString(): string { - return "$this->className::$this->methodName"; - } - - public function isMethod(): bool { - return true; - } - - public function isConstructor(): bool { - return $this->methodName === "__construct"; - } - - public function isDestructor(): bool { - return $this->methodName === "__destruct"; - } -} - -class ReturnInfo { - const REFCOUNT_0 = "0"; - const REFCOUNT_1 = "1"; - const REFCOUNT_N = "N"; - - const REFCOUNTS = [ - self::REFCOUNT_0, - self::REFCOUNT_1, - self::REFCOUNT_N, - ]; - - public bool $byRef; - public ?Type $type; - public ?Type $phpDocType; - public bool $tentativeReturnType; - public string $refcount; - - public function __construct(bool $byRef, ?Type $type, ?Type $phpDocType, bool $tentativeReturnType, ?string $refcount) { - $this->byRef = $byRef; - $this->setTypes($type, $phpDocType, $tentativeReturnType); - $this->setRefcount($refcount); - } - - public function equalsApartFromPhpDocAndRefcount(ReturnInfo $other): bool { - return $this->byRef === $other->byRef - && Type::equals($this->type, $other->type) - && $this->tentativeReturnType === $other->tentativeReturnType; - } - - public function getMethodSynopsisType(): ?Type { - return $this->type ?? $this->phpDocType; - } - - private function setTypes(?Type $type, ?Type $phpDocType, bool $tentativeReturnType): void - { - $this->type = $type; - $this->phpDocType = $phpDocType; - $this->tentativeReturnType = $tentativeReturnType; - } - - private function setRefcount(?string $refcount): void - { - $type = $this->phpDocType ?? $this->type; - $isScalarType = $type !== null && $type->isScalar(); - - if ($refcount === null) { - $this->refcount = $isScalarType ? self::REFCOUNT_0 : self::REFCOUNT_N; - return; - } - - if (!in_array($refcount, ReturnInfo::REFCOUNTS, true)) { - throw new Exception("@refcount must have one of the following values: \"0\", \"1\", \"N\", $refcount given"); - } - - if ($isScalarType && $refcount !== self::REFCOUNT_0) { - throw new Exception('A scalar return type of "' . $type->__toString() . '" must have a refcount of "' . self::REFCOUNT_0 . '"'); - } - - if (!$isScalarType && $refcount === self::REFCOUNT_0) { - throw new Exception('A non-scalar return type of "' . $type->__toString() . '" cannot have a refcount of "' . self::REFCOUNT_0 . '"'); - } - - $this->refcount = $refcount; - } -} - -class FuncInfo { - public FunctionOrMethodName $name; - public int $classFlags; - public int $flags; - public ?string $aliasType; - public ?FunctionOrMethodName $alias; - public bool $isDeprecated; - public bool $supportsCompileTimeEval; - public bool $verify; - /** @var ArgInfo[] */ - public array $args; - public ReturnInfo $return; - public int $numRequiredArgs; - public ?string $cond; - public bool $isUndocumentable; - - /** - * @param ArgInfo[] $args - */ - public function __construct( - FunctionOrMethodName $name, - int $classFlags, - int $flags, - ?string $aliasType, - ?FunctionOrMethodName $alias, - bool $isDeprecated, - bool $supportsCompileTimeEval, - bool $verify, - array $args, - ReturnInfo $return, - int $numRequiredArgs, - ?string $cond, - bool $isUndocumentable - ) { - $this->name = $name; - $this->classFlags = $classFlags; - $this->flags = $flags; - $this->aliasType = $aliasType; - $this->alias = $alias; - $this->isDeprecated = $isDeprecated; - $this->supportsCompileTimeEval = $supportsCompileTimeEval; - $this->verify = $verify; - $this->args = $args; - $this->return = $return; - $this->numRequiredArgs = $numRequiredArgs; - $this->cond = $cond; - $this->isUndocumentable = $isUndocumentable; - } - - public function isMethod(): bool - { - return $this->name->isMethod(); - } - - public function isFinalMethod(): bool - { - return ($this->flags & Class_::MODIFIER_FINAL) || ($this->classFlags & Class_::MODIFIER_FINAL); - } - - public function isInstanceMethod(): bool - { - return !($this->flags & Class_::MODIFIER_STATIC) && $this->isMethod() && !$this->name->isConstructor(); - } - - /** @return string[] */ - public function getModifierNames(): array - { - if (!$this->isMethod()) { - return []; - } - - $result = []; - - if ($this->flags & Class_::MODIFIER_FINAL) { - $result[] = "final"; - } elseif ($this->flags & Class_::MODIFIER_ABSTRACT && $this->classFlags & ~Class_::MODIFIER_ABSTRACT) { - $result[] = "abstract"; - } - - if ($this->flags & Class_::MODIFIER_PROTECTED) { - $result[] = "protected"; - } elseif ($this->flags & Class_::MODIFIER_PRIVATE) { - $result[] = "private"; - } else { - $result[] = "public"; - } - - if ($this->flags & Class_::MODIFIER_STATIC) { - $result[] = "static"; - } - - return $result; - } - - public function hasParamWithUnknownDefaultValue(): bool - { - foreach ($this->args as $arg) { - if ($arg->defaultValue && !$arg->hasProperDefaultValue()) { - return true; - } - } - - return false; - } - - public function equalsApartFromNameAndRefcount(FuncInfo $other): bool { - if (count($this->args) !== count($other->args)) { - return false; - } - - for ($i = 0; $i < count($this->args); $i++) { - if (!$this->args[$i]->equals($other->args[$i])) { - return false; - } - } - - return $this->return->equalsApartFromPhpDocAndRefcount($other->return) - && $this->numRequiredArgs === $other->numRequiredArgs - && $this->cond === $other->cond; - } - - public function getArgInfoName(): string { - return $this->name->getArgInfoName(); - } - - public function getDeclarationKey(): string - { - $name = $this->alias ?? $this->name; - - return "$name|$this->cond"; - } - - public function getDeclaration(): ?string - { - if ($this->flags & Class_::MODIFIER_ABSTRACT) { - return null; - } - - $name = $this->alias ?? $this->name; - - return $name->getDeclaration(); - } - - public function getFunctionEntry(): string { - if ($this->name instanceof MethodName) { - if ($this->alias) { - if ($this->alias instanceof MethodName) { - return sprintf( - "\tZEND_MALIAS(%s, %s, %s, %s, %s)\n", - $this->alias->getDeclarationClassName(), $this->name->methodName, - $this->alias->methodName, $this->getArgInfoName(), $this->getFlagsAsArginfoString() - ); - } else if ($this->alias instanceof FunctionName) { - return sprintf( - "\tZEND_ME_MAPPING(%s, %s, %s, %s)\n", - $this->name->methodName, $this->alias->getNonNamespacedName(), - $this->getArgInfoName(), $this->getFlagsAsArginfoString() - ); - } else { - throw new Error("Cannot happen"); - } - } else { - $declarationClassName = $this->name->getDeclarationClassName(); - if ($this->flags & Class_::MODIFIER_ABSTRACT) { - return sprintf( - "\tZEND_ABSTRACT_ME_WITH_FLAGS(%s, %s, %s, %s)\n", - $declarationClassName, $this->name->methodName, $this->getArgInfoName(), - $this->getFlagsAsArginfoString() - ); - } - - return sprintf( - "\tZEND_ME(%s, %s, %s, %s)\n", - $declarationClassName, $this->name->methodName, $this->getArgInfoName(), - $this->getFlagsAsArginfoString() - ); - } - } else if ($this->name instanceof FunctionName) { - $namespace = $this->name->getNamespace(); - $functionName = $this->name->getFunctionName(); - $declarationName = $this->alias ? $this->alias->getNonNamespacedName() : $this->name->getDeclarationName(); - - if ($namespace) { - // Namespaced functions are always declared as aliases to avoid name conflicts when two functions with - // the same name exist in separate namespaces - $macro = $this->isDeprecated ? 'ZEND_NS_DEP_FALIAS' : 'ZEND_NS_FALIAS'; - - // Render A\B as "A\\B" in C strings for namespaces - return sprintf( - "\t%s(\"%s\", %s, %s, %s)\n", - $macro, addslashes($namespace), $this->name->getFunctionName(), $declarationName, $this->getArgInfoName() - ); - } - - if ($this->alias) { - $macro = $this->isDeprecated ? 'ZEND_DEP_FALIAS' : 'ZEND_FALIAS'; - - return sprintf( - "\t%s(%s, %s, %s)\n", - $macro, $functionName, $declarationName, $this->getArgInfoName() - ); - } - - switch (true) { - case $this->isDeprecated: - $macro = 'ZEND_DEP_FE'; - break; - case $this->supportsCompileTimeEval: - $macro = 'ZEND_SUPPORTS_COMPILE_TIME_EVAL_FE'; - break; - default: - $macro = 'ZEND_FE'; - } - - return sprintf("\t%s(%s, %s)\n", $macro, $functionName, $this->getArgInfoName()); - } else { - throw new Error("Cannot happen"); - } - } - - public function getOptimizerInfo(): ?string { - if ($this->isMethod()) { - return null; - } - - if ($this->alias !== null) { - return null; - } - - if ($this->return->refcount !== ReturnInfo::REFCOUNT_1 && $this->return->phpDocType === null) { - return null; - } - - $type = $this->return->phpDocType ?? $this->return->type; - if ($type === null) { - return null; - } - - return "\tF" . $this->return->refcount . '("' . $this->name->__toString() . '", ' . $type->toOptimizerTypeMask() . "),\n"; - } - - public function discardInfoForOldPhpVersions(): void { - $this->return->type = null; - foreach ($this->args as $arg) { - $arg->type = null; - $arg->defaultValue = null; - $arg->attributes = []; - } - } - - private function getFlagsAsArginfoString(): string - { - $flags = "ZEND_ACC_PUBLIC"; - if ($this->flags & Class_::MODIFIER_PROTECTED) { - $flags = "ZEND_ACC_PROTECTED"; - } elseif ($this->flags & Class_::MODIFIER_PRIVATE) { - $flags = "ZEND_ACC_PRIVATE"; - } - - if ($this->flags & Class_::MODIFIER_STATIC) { - $flags .= "|ZEND_ACC_STATIC"; - } - - if ($this->flags & Class_::MODIFIER_FINAL) { - $flags .= "|ZEND_ACC_FINAL"; - } - - if ($this->flags & Class_::MODIFIER_ABSTRACT) { - $flags .= "|ZEND_ACC_ABSTRACT"; - } - - if ($this->isDeprecated) { - $flags .= "|ZEND_ACC_DEPRECATED"; - } - - return $flags; - } - - /** - * @param array $funcMap - * @param array $aliasMap - * @throws Exception - */ - public function getMethodSynopsisDocument(array $funcMap, array $aliasMap): ?string { - - $doc = new DOMDocument(); - $doc->formatOutput = true; - $methodSynopsis = $this->getMethodSynopsisElement($funcMap, $aliasMap, $doc); - if (!$methodSynopsis) { - return null; - } - - $doc->appendChild($methodSynopsis); - - return $doc->saveXML(); - } - - /** - * @param array $funcMap - * @param array $aliasMap - * @throws Exception - */ - public function getMethodSynopsisElement(array $funcMap, array $aliasMap, DOMDocument $doc): ?DOMElement { - if ($this->hasParamWithUnknownDefaultValue()) { - return null; - } - - if ($this->name->isConstructor()) { - $synopsisType = "constructorsynopsis"; - } elseif ($this->name->isDestructor()) { - $synopsisType = "destructorsynopsis"; - } else { - $synopsisType = "methodsynopsis"; - } - - $methodSynopsis = $doc->createElement($synopsisType); - - if ($this->isMethod()) { - assert($this->name instanceof MethodName); - $role = $doc->createAttribute("role"); - $role->value = addslashes($this->name->className->__toString()); - $methodSynopsis->appendChild($role); - } - - $methodSynopsis->appendChild(new DOMText("\n ")); - - foreach ($this->getModifierNames() as $modifierString) { - $modifierElement = $doc->createElement('modifier', $modifierString); - $methodSynopsis->appendChild($modifierElement); - $methodSynopsis->appendChild(new DOMText(" ")); - } - - $returnType = $this->return->getMethodSynopsisType(); - if ($returnType) { - $methodSynopsis->appendChild($returnType->getTypeForDoc($doc)); - } - - $methodname = $doc->createElement('methodname', $this->name->__toString()); - $methodSynopsis->appendChild($methodname); - - if (empty($this->args)) { - $methodSynopsis->appendChild(new DOMText("\n ")); - $void = $doc->createElement('void'); - $methodSynopsis->appendChild($void); - } else { - foreach ($this->args as $arg) { - $methodSynopsis->appendChild(new DOMText("\n ")); - $methodparam = $doc->createElement('methodparam'); - if ($arg->defaultValue !== null) { - $methodparam->setAttribute("choice", "opt"); - } - if ($arg->isVariadic) { - $methodparam->setAttribute("rep", "repeat"); - } - - $methodSynopsis->appendChild($methodparam); - $methodparam->appendChild($arg->getMethodSynopsisType()->getTypeForDoc($doc)); - - $parameter = $doc->createElement('parameter', $arg->name); - if ($arg->sendBy !== ArgInfo::SEND_BY_VAL) { - $parameter->setAttribute("role", "reference"); - } - - $methodparam->appendChild($parameter); - $defaultValue = $arg->getDefaultValueAsMethodSynopsisString(); - if ($defaultValue !== null) { - $initializer = $doc->createElement('initializer'); - if (preg_match('/^[a-zA-Z_][a-zA-Z_0-9]*$/', $defaultValue)) { - $constant = $doc->createElement('constant', $defaultValue); - $initializer->appendChild($constant); - } else { - $initializer->nodeValue = $defaultValue; - } - $methodparam->appendChild($initializer); - } - } - } - $methodSynopsis->appendChild(new DOMText("\n ")); - - return $methodSynopsis; - } - - public function __clone() - { - foreach ($this->args as $key => $argInfo) { - $this->args[$key] = clone $argInfo; - } - $this->return = clone $this->return; - } -} - -class EvaluatedValue -{ - /** @var mixed */ - public $value; - public SimpleType $type; - public Expr $expr; - public bool $isUnknownConstValue; - /** @var ConstInfo[] */ - public array $originatingConsts; - - /** - * @param iterable $allConstInfos - */ - public static function createFromExpression(Expr $expr, ?SimpleType $constType, ?string $cConstName, iterable $allConstInfos): EvaluatedValue - { - // This visitor replaces the PHP constants by C constants. It allows direct expansion of the compiled constants, e.g. later in the pretty printer. - $visitor = new class($allConstInfos) extends PhpParser\NodeVisitorAbstract - { - /** @var iterable */ - public array $visitedConstants = []; - /** @var iterable */ - public iterable $allConstInfos; - - /** @param iterable $allConstInfos */ - public function __construct(iterable $allConstInfos) - { - $this->allConstInfos = $allConstInfos; - } - - /** @return Node|null */ - public function enterNode(Node $expr) - { - if (!$expr instanceof Expr\ConstFetch && !$expr instanceof Expr\ClassConstFetch) { - return null; - } - - if ($expr instanceof Expr\ClassConstFetch) { - $originatingConstName = new ClassConstName($expr->class, $expr->name->toString()); - } else { - $originatingConstName = new ConstName($expr->name->getAttribute('namespacedName'), $expr->name->toString()); - } - - if ($originatingConstName->isUnknown()) { - return null; - } - - foreach ($this->allConstInfos as $const) { - if ($originatingConstName->equals($const->name)) { - $this->visitedConstants[] = $const; - return $const->getValue($this->allConstInfos)->expr; - } - } - } - }; - - $nodeTraverser = new PhpParser\NodeTraverser; - $nodeTraverser->addVisitor($visitor); - $expr = $nodeTraverser->traverse([$expr])[0]; - - $isUnknownConstValue = false; - - $evaluator = new ConstExprEvaluator( - static function (Expr $expr) use ($allConstInfos, &$isUnknownConstValue) { - // $expr is a ConstFetch with a name of a C macro here - if (!$expr instanceof Expr\ConstFetch) { - throw new Exception($this->getVariableTypeName() . " " . $this->getVariableLikeName() . " has an unsupported value"); - } - - $constName = $expr->name->__toString(); - if (strtolower($constName) === "unknown") { - $isUnknownConstValue = true; - return null; - } - - foreach ($allConstInfos as $const) { - if ($constName != $const->cValue) { - continue; - } - - $constType = ($const->phpDocType ?? $const->type)->tryToSimpleType(); - if ($constType) { - if ($constType->isBool()) { - return true; - } elseif ($constType->isInt()) { - return 1; - } elseif ($constType->isFloat()) { - return M_PI; - } elseif ($constType->isString()) { - return $const->name; - } elseif ($constType->isArray()) { - return []; - } - } - - return null; - } - - throw new Exception("Constant " . $originatingConstName->__toString() . " cannot be found"); - } - ); - - $result = $evaluator->evaluateDirectly($expr); - - return new EvaluatedValue( - $result, // note: we are generally not interested in the actual value of $result, unless it's a bare value, without constants - $constType ?? SimpleType::fromValue($result), - $cConstName === null ? $expr : new Expr\ConstFetch(new Node\Name($cConstName)), - $visitor->visitedConstants, - $isUnknownConstValue - ); - } - - public static function null(): EvaluatedValue - { - return new self(null, SimpleType::null(), new Expr\ConstFetch(new Node\Name('null')), [], false); - } - - /** - * @param mixed $value - * @param ConstInfo[] $originatingConsts - */ - private function __construct($value, SimpleType $type, Expr $expr, array $originatingConsts, bool $isUnknownConstValue) - { - $this->value = $value; - $this->type = $type; - $this->expr = $expr; - $this->originatingConsts = $originatingConsts; - $this->isUnknownConstValue = $isUnknownConstValue; - } - - public function initializeZval(string $zvalName): string - { - $cExpr = $this->getCExpr(); - - $code = "\tzval $zvalName;\n"; - - if ($this->type->isNull()) { - $code .= "\tZVAL_NULL(&$zvalName);\n"; - } elseif ($this->type->isBool()) { - if ($cExpr == 'true') { - $code .= "\tZVAL_TRUE(&$zvalName);\n"; - } elseif ($cExpr == 'false') { - $code .= "\tZVAL_FALSE(&$zvalName);\n"; - } else { - $code .= "\tZVAL_BOOL(&$zvalName, $cExpr);\n"; - } - } elseif ($this->type->isInt()) { - $code .= "\tZVAL_LONG(&$zvalName, $cExpr);\n"; - } elseif ($this->type->isFloat()) { - $code .= "\tZVAL_DOUBLE(&$zvalName, $cExpr);\n"; - } elseif ($this->type->isString()) { - if ($cExpr === '""') { - $code .= "\tZVAL_EMPTY_STRING(&$zvalName);\n"; - } else { - $code .= "\tzend_string *{$zvalName}_str = zend_string_init($cExpr, strlen($cExpr), 1);\n"; - $code .= "\tZVAL_STR(&$zvalName, {$zvalName}_str);\n"; - } - } elseif ($this->type->isArray()) { - if ($cExpr == '[]') { - $code .= "\tZVAL_EMPTY_ARRAY(&$zvalName);\n"; - } else { - throw new Exception("Unimplemented default value"); - } - } else { - throw new Exception("Invalid default value: " . print_r($this->value, true) . ", type: " . print_r($this->type, true)); - } - - return $code; - } - - public function getCExpr(): ?string - { - // $this->expr has all its PHP constants replaced by C constants - $prettyPrinter = new Standard; - $expr = $prettyPrinter->prettyPrintExpr($this->expr); - return $expr[0] == '"' ? $expr : preg_replace('(\bnull\b)', 'NULL', str_replace('\\', '', $expr)); - } -} - -abstract class VariableLike -{ - public int $flags; - public ?Type $type; - public ?Type $phpDocType; - public ?string $link; - public ?int $phpVersionIdMinimumCompatibility; - - public function __construct( - int $flags, - ?Type $type, - ?Type $phpDocType, - ?string $link, - ?int $phpVersionIdMinimumCompatibility - ) { - $this->flags = $flags; - $this->type = $type; - $this->phpDocType = $phpDocType; - $this->link = $link; - $this->phpVersionIdMinimumCompatibility = $phpVersionIdMinimumCompatibility; - } - - abstract protected function getVariableTypeCode(): string; - - abstract protected function getVariableTypeName(): string; - - abstract protected function getVariableLikeName(): string; - - abstract protected function getFieldSynopsisDefaultLinkend(): string; - - abstract protected function getFieldSynopsisName(): string; - - /** - * @param iterable $allConstInfos - */ - abstract protected function getFieldSynopsisValueString(iterable $allConstInfos): ?string; - - abstract public function discardInfoForOldPhpVersions(): void; - - protected function addTypeToFieldSynopsis(DOMDocument $doc, DOMElement $fieldsynopsisElement): void - { - $type = $this->phpDocType ?? $this->type; - - if ($type) { - $fieldsynopsisElement->appendChild(new DOMText("\n ")); - $fieldsynopsisElement->appendChild($type->getTypeForDoc($doc)); - } - } - - /** - * @return array - */ - protected function getFlagsByPhpVersion(): array - { - $flags = "ZEND_ACC_PUBLIC"; - if ($this->flags & Class_::MODIFIER_PROTECTED) { - $flags = "ZEND_ACC_PROTECTED"; - } elseif ($this->flags & Class_::MODIFIER_PRIVATE) { - $flags = "ZEND_ACC_PRIVATE"; - } - - return [ - PHP_70_VERSION_ID => [$flags], - PHP_80_VERSION_ID => [$flags], - PHP_81_VERSION_ID => [$flags], - PHP_82_VERSION_ID => [$flags], - PHP_83_VERSION_ID => [$flags], - ]; - } - - protected function getTypeCode(string $variableLikeName, string &$code): string - { - $variableLikeType = $this->getVariableTypeName(); - - $typeCode = ""; - - if ($this->type) { - $arginfoType = $this->type->toArginfoType(); - if ($arginfoType->hasClassType()) { - if (count($arginfoType->classTypes) >= 2) { - foreach ($arginfoType->classTypes as $classType) { - $escapedClassName = $classType->toEscapedName(); - $varEscapedClassName = $classType->toVarEscapedName(); - $code .= "\tzend_string *{$variableLikeType}_{$variableLikeName}_class_{$varEscapedClassName} = zend_string_init(\"{$escapedClassName}\", sizeof(\"{$escapedClassName}\") - 1, 1);\n"; - } - - $classTypeCount = count($arginfoType->classTypes); - $code .= "\tzend_type_list *{$variableLikeType}_{$variableLikeName}_type_list = malloc(ZEND_TYPE_LIST_SIZE($classTypeCount));\n"; - $code .= "\t{$variableLikeType}_{$variableLikeName}_type_list->num_types = $classTypeCount;\n"; - - foreach ($arginfoType->classTypes as $k => $classType) { - $escapedClassName = $classType->toEscapedName(); - $code .= "\t{$variableLikeType}_{$variableLikeName}_type_list->types[$k] = (zend_type) ZEND_TYPE_INIT_CLASS({$variableLikeType}_{$variableLikeName}_class_{$escapedClassName}, 0, 0);\n"; - } - - $typeMaskCode = $this->type->toArginfoType()->toTypeMask(); - - if ($this->type->isIntersection) { - $code .= "\tzend_type {$variableLikeType}_{$variableLikeName}_type = ZEND_TYPE_INIT_INTERSECTION({$variableLikeType}_{$variableLikeName}_type_list, $typeMaskCode);\n"; - } else { - $code .= "\tzend_type {$variableLikeType}_{$variableLikeName}_type = ZEND_TYPE_INIT_UNION({$variableLikeType}_{$variableLikeName}_type_list, $typeMaskCode);\n"; - } - $typeCode = "{$variableLikeType}_{$variableLikeName}_type"; - } else { - $escapedClassName = $arginfoType->classTypes[0]->toEscapedName(); - $varEscapedClassName = $arginfoType->classTypes[0]->toVarEscapedName(); - $code .= "\tzend_string *{$variableLikeType}_{$variableLikeName}_class_{$varEscapedClassName} = zend_string_init(\"{$escapedClassName}\", sizeof(\"{$escapedClassName}\")-1, 1);\n"; - - $typeCode = "(zend_type) ZEND_TYPE_INIT_CLASS({$variableLikeType}_{$variableLikeName}_class_{$varEscapedClassName}, 0, " . $arginfoType->toTypeMask() . ")"; - } - } else { - $typeCode = "(zend_type) ZEND_TYPE_INIT_MASK(" . $arginfoType->toTypeMask() . ")"; - } - } - - return $typeCode; - } - - /** - * @param iterable $allConstInfos - */ - public function getFieldSynopsisElement(DOMDocument $doc, iterable $allConstInfos): DOMElement - { - $fieldsynopsisElement = $doc->createElement("fieldsynopsis"); - - $this->addModifiersToFieldSynopsis($doc, $fieldsynopsisElement); - - $this->addTypeToFieldSynopsis($doc, $fieldsynopsisElement); - - $varnameElement = $doc->createElement("varname", $this->getFieldSynopsisName()); - if ($this->link) { - $varnameElement->setAttribute("linkend", $this->link); - } else { - $varnameElement->setAttribute("linkend", $this->getFieldSynopsisDefaultLinkend()); - } - - $fieldsynopsisElement->appendChild(new DOMText("\n ")); - $fieldsynopsisElement->appendChild($varnameElement); - - $valueString = $this->getFieldSynopsisValueString($allConstInfos); - if ($valueString) { - $fieldsynopsisElement->appendChild(new DOMText("\n ")); - $initializerElement = $doc->createElement("initializer", $valueString); - $fieldsynopsisElement->appendChild($initializerElement); - } - - $fieldsynopsisElement->appendChild(new DOMText("\n ")); - - return $fieldsynopsisElement; - } - - protected function addModifiersToFieldSynopsis(DOMDocument $doc, DOMElement $fieldsynopsisElement): void - { - if ($this->flags & Class_::MODIFIER_PUBLIC) { - $fieldsynopsisElement->appendChild(new DOMText("\n ")); - $fieldsynopsisElement->appendChild($doc->createElement("modifier", "public")); - } elseif ($this->flags & Class_::MODIFIER_PROTECTED) { - $fieldsynopsisElement->appendChild(new DOMText("\n ")); - $fieldsynopsisElement->appendChild($doc->createElement("modifier", "protected")); - } elseif ($this->flags & Class_::MODIFIER_PRIVATE) { - $fieldsynopsisElement->appendChild(new DOMText("\n ")); - $fieldsynopsisElement->appendChild($doc->createElement("modifier", "private")); - } - } - - /** - * @param array $flags - * @return array - */ - protected function addFlagForVersionsAbove(array $flags, string $flag, int $minimumVersionId): array - { - $write = false; - - foreach ($flags as $version => $versionFlags) { - if ($version === $minimumVersionId || $write === true) { - $flags[$version][] = $flag; - $write = true; - } - } - - return $flags; - } -} - -class ConstInfo extends VariableLike -{ - public ConstOrClassConstName $name; - public Expr $value; - public bool $isDeprecated; - public ?string $valueString; - public ?string $cond; - public ?string $cValue; - - public function __construct( - ConstOrClassConstName $name, - int $flags, - Expr $value, - ?string $valueString, - ?Type $type, - ?Type $phpDocType, - bool $isDeprecated, - ?string $cond, - ?string $cValue, - ?string $link, - ?int $phpVersionIdMinimumCompatibility - ) { - $this->name = $name; - $this->value = $value; - $this->valueString = $valueString; - $this->isDeprecated = $isDeprecated; - $this->cond = $cond; - $this->cValue = $cValue; - parent::__construct($flags, $type, $phpDocType, $link, $phpVersionIdMinimumCompatibility); - } - - /** - * @param iterable $allConstInfos - */ - public function getValue(iterable $allConstInfos): EvaluatedValue - { - return EvaluatedValue::createFromExpression( - $this->value, - ($this->phpDocType ?? $this->type)->tryToSimpleType(), - $this->cValue, - $allConstInfos - ); - } - - protected function getVariableTypeName(): string - { - return "constant"; - } - - protected function getVariableLikeName(): string - { - return $this->name->const; - } - - protected function getVariableTypeCode(): string - { - return "const"; - } - - protected function getFieldSynopsisDefaultLinkend(): string - { - $className = str_replace(["\\", "_"], ["-", "-"], $this->name->class->toLowerString()); - - return "$className.constants." . strtolower(str_replace("_", "-", $this->getVariableLikeName())); - } - - protected function getFieldSynopsisName(): string - { - return $this->name->__toString(); - } - - /** - * @param iterable $allConstInfos - */ - protected function getFieldSynopsisValueString(iterable $allConstInfos): ?string - { - $value = EvaluatedValue::createFromExpression($this->value, null, $this->cValue, $allConstInfos); - if ($value->isUnknownConstValue) { - return null; - } - - if ($value->originatingConsts) { - return implode("\n", array_map(function (ConstInfo $const) use ($allConstInfos) { - return $const->getFieldSynopsisValueString($allConstInfos); - }, $value->originatingConsts)); - } - - return $this->valueString; - } - - public function discardInfoForOldPhpVersions(): void { - $this->type = null; - $this->flags &= ~Class_::MODIFIER_FINAL; - $this->isDeprecated = false; - } - - /** - * @param iterable $allConstInfos - */ - public function getDeclaration(iterable $allConstInfos): string - { - $simpleType = ($this->phpDocType ?? $this->type)->tryToSimpleType(); - if ($simpleType && $simpleType->name === "mixed") { - $simpleType = null; - } - - $value = EvaluatedValue::createFromExpression($this->value, $simpleType, $this->cValue, $allConstInfos); - if ($value->isUnknownConstValue && ($simpleType === null || !$simpleType->isBuiltin)) { - throw new Exception("Constant " . $this->name->__toString() . " must have a built-in PHPDoc type as the type couldn't be inferred from its value"); - } - - // i.e. const NAME = UNKNOWN;, without the annotation - if ($value->isUnknownConstValue && $this->cValue === null && $value->expr instanceof Expr\ConstFetch && $value->expr->name->__toString() === "UNKNOWN") { - throw new Exception("Constant " . $this->name->__toString() . " must have a @cvalue annotation"); - } - - $code = ""; - - if ($this->cond) { - $code .= "#if {$this->cond}\n"; - } - - if ($this->name->isClassConst()) { - $code .= $this->getClassConstDeclaration($value, $allConstInfos); - } else { - $code .= $this->getGlobalConstDeclaration($value, $allConstInfos); - } - $code .= $this->getValueAssertion($value); - - if ($this->cond) { - $code .= "#endif\n"; - } - - return $code; - } - - /** - * @param iterable $allConstInfos - */ - private function getGlobalConstDeclaration(EvaluatedValue $value, iterable $allConstInfos): string - { - $constName = str_replace('\\', '\\\\', $this->name->__toString()); - $constValue = $value->value; - $cExpr = $value->getCExpr(); - - $flags = "CONST_PERSISTENT"; - if ($this->phpVersionIdMinimumCompatibility !== null && $this->phpVersionIdMinimumCompatibility < 80000) { - $flags .= " | CONST_CS"; - } - - if ($this->isDeprecated) { - $flags .= " | CONST_DEPRECATED"; - } - if ($value->type->isNull()) { - return "\tREGISTER_NULL_CONSTANT(\"$constName\", $flags);\n"; - } - - if ($value->type->isBool()) { - return "\tREGISTER_BOOL_CONSTANT(\"$constName\", " . ($cExpr ?: ($constValue ? "true" : "false")) . ", $flags);\n"; - } - - if ($value->type->isInt()) { - return "\tREGISTER_LONG_CONSTANT(\"$constName\", " . ($cExpr ?: (int) $constValue) . ", $flags);\n"; - } - - if ($value->type->isFloat()) { - return "\tREGISTER_DOUBLE_CONSTANT(\"$constName\", " . ($cExpr ?: (float) $constValue) . ", $flags);\n"; - } - - if ($value->type->isString()) { - return "\tREGISTER_STRING_CONSTANT(\"$constName\", " . ($cExpr ?: '"' . addslashes($constValue) . '"') . ", $flags);\n"; - } - - throw new Exception("Unimplemented constant type");} - - /** - * @param iterable $allConstInfos - */ - private function getClassConstDeclaration(EvaluatedValue $value, iterable $allConstInfos): string - { - $constName = $this->getVariableLikeName(); - - $zvalCode = $value->initializeZval("const_{$constName}_value", $allConstInfos); - - $code = "\n" . $zvalCode; - - $code .= "\tzend_string *const_{$constName}_name = zend_string_init_interned(\"$constName\", sizeof(\"$constName\") - 1, 1);\n"; - $nameCode = "const_{$constName}_name"; - - $php83MinimumCompatibility = $this->phpVersionIdMinimumCompatibility === null || $this->phpVersionIdMinimumCompatibility >= PHP_83_VERSION_ID; - - if ($this->type && !$php83MinimumCompatibility) { - $code .= "#if (PHP_VERSION_ID >= " . PHP_83_VERSION_ID . ")\n"; - } - - if ($this->type) { - $typeCode = $this->getTypeCode($constName, $code); - $template = "\tzend_declare_typed_class_constant(class_entry, $nameCode, &const_{$constName}_value, %s, NULL, $typeCode);\n"; - $flagsCode = generateVersionDependentFlagCode( - $template, - $this->getFlagsByPhpVersion(), - $this->phpVersionIdMinimumCompatibility - ); - $code .= implode("", $flagsCode); - } - - if ($this->type && !$php83MinimumCompatibility) { - $code .= "#else\n"; - } - - if (!$this->type || !$php83MinimumCompatibility) { - $template = "\tzend_declare_class_constant_ex(class_entry, $nameCode, &const_{$constName}_value, %s, NULL);\n"; - $flagsCode = generateVersionDependentFlagCode( - $template, - $this->getFlagsByPhpVersion(), - $this->phpVersionIdMinimumCompatibility - ); - $code .= implode("", $flagsCode); - } - - if ($this->type && !$php83MinimumCompatibility) { - $code .= "#endif\n"; - } - - $code .= "\tzend_string_release(const_{$constName}_name);\n"; - - return $code; - } - - private function getValueAssertion(EvaluatedValue $value): string - { - if ($value->isUnknownConstValue || $value->originatingConsts || $this->cValue === null) { - return ""; - } - - $cExpr = $value->getCExpr(); - $constValue = $value->value; - - if ($value->type->isNull()) { - return "\tZEND_ASSERT($cExpr == NULL);\n"; - } - - if ($value->type->isBool()) { - $cValue = $constValue ? "true" : "false"; - return "\tZEND_ASSERT($cExpr == $cValue);\n"; - } - - if ($value->type->isInt()) { - $cValue = (int) $constValue; - return "\tZEND_ASSERT($cExpr == $cValue);\n"; - } - - if ($value->type->isFloat()) { - $cValue = (float) $constValue; - return "\tZEND_ASSERT($cExpr == $cValue);\n"; - } - - if ($value->type->isString()) { - $cValue = '"' . addslashes($constValue) . '"'; - return "\tZEND_ASSERT(strcmp($cExpr, $cValue) == 0);\n"; - } - - throw new Exception("Unimplemented constant type"); - } - - /** - * @return array - */ - protected function getFlagsByPhpVersion(): array - { - $flags = parent::getFlagsByPhpVersion(); - - if ($this->isDeprecated) { - $flags = $this->addFlagForVersionsAbove($flags, "ZEND_ACC_DEPRECATED", PHP_80_VERSION_ID); - } - - if ($this->flags & Class_::MODIFIER_FINAL) { - $flags = $this->addFlagForVersionsAbove($flags, "ZEND_ACC_FINAL", PHP_81_VERSION_ID); - } - - return $flags; - } - - protected function addModifiersToFieldSynopsis(DOMDocument $doc, DOMElement $fieldsynopsisElement): void - { - parent::addModifiersToFieldSynopsis($doc, $fieldsynopsisElement); - - if ($this->flags & Class_::MODIFIER_FINAL) { - $fieldsynopsisElement->appendChild(new DOMText("\n ")); - $fieldsynopsisElement->appendChild($doc->createElement("modifier", "final")); - } - - $fieldsynopsisElement->appendChild(new DOMText("\n ")); - $fieldsynopsisElement->appendChild($doc->createElement("modifier", "const")); - } -} - -class PropertyInfo extends VariableLike -{ - public PropertyName $name; - public ?Expr $defaultValue; - public ?string $defaultValueString; - public bool $isDocReadonly; - - public function __construct( - PropertyName $name, - int $flags, - ?Type $type, - ?Type $phpDocType, - ?Expr $defaultValue, - ?string $defaultValueString, - bool $isDocReadonly, - ?string $link, - ?int $phpVersionIdMinimumCompatibility - ) { - $this->name = $name; - $this->defaultValue = $defaultValue; - $this->defaultValueString = $defaultValueString; - $this->isDocReadonly = $isDocReadonly; - parent::__construct($flags, $type, $phpDocType, $link, $phpVersionIdMinimumCompatibility); - } - - protected function getVariableTypeCode(): string - { - return "property"; - } - - protected function getVariableTypeName(): string - { - return "property"; - } - - protected function getVariableLikeName(): string - { - return $this->name->property; - } - - protected function getFieldSynopsisDefaultLinkend(): string - { - $className = str_replace(["\\", "_"], ["-", "-"], $this->name->class->toLowerString()); - - return "$className.props." . strtolower(str_replace("_", "-", $this->getVariableLikeName())); - } - - protected function getFieldSynopsisName(): string - { - return $this->getVariableLikeName(); - } - - /** - * @param iterable $allConstInfos - */ - protected function getFieldSynopsisValueString(iterable $allConstInfos): ?string - { - return $this->defaultValueString; - } - - public function discardInfoForOldPhpVersions(): void { - $this->type = null; - $this->flags &= ~Class_::MODIFIER_READONLY; - } - - /** - * @param iterable $allConstInfos - */ - public function getDeclaration(iterable $allConstInfos): string { - $code = "\n"; - - $propertyName = $this->getVariableLikeName(); - - if ($this->defaultValue === null) { - $defaultValue = EvaluatedValue::null(); - } else { - $defaultValue = EvaluatedValue::createFromExpression($this->defaultValue, null, null, $allConstInfos); - if ($defaultValue->isUnknownConstValue || ($defaultValue->originatingConsts && $defaultValue->getCExpr() === null)) { - echo "Skipping code generation for property $this->name, because it has an unknown constant default value\n"; - return ""; - } - } - - $zvalName = "property_{$propertyName}_default_value"; - if ($this->defaultValue === null && $this->type !== null) { - $code .= "\tzval $zvalName;\n\tZVAL_UNDEF(&$zvalName);\n"; - } else { - $code .= $defaultValue->initializeZval($zvalName); - } - - $code .= "\tzend_string *property_{$propertyName}_name = zend_string_init(\"$propertyName\", sizeof(\"$propertyName\") - 1, 1);\n"; - $nameCode = "property_{$propertyName}_name"; - - if ($this->type !== null) { - $typeCode = $this->getTypeCode($propertyName, $code); - $template = "\tzend_declare_typed_property(class_entry, $nameCode, &$zvalName, %s, NULL, $typeCode);\n"; - } else { - $template = "\tzend_declare_property_ex(class_entry, $nameCode, &$zvalName, %s, NULL);\n"; - } - $flagsCode = generateVersionDependentFlagCode( - $template, - $this->getFlagsByPhpVersion(), - $this->phpVersionIdMinimumCompatibility - ); - $code .= implode("", $flagsCode); - - $code .= "\tzend_string_release(property_{$propertyName}_name);\n"; - - return $code; - } - - /** - * @return array - */ - protected function getFlagsByPhpVersion(): array - { - $flags = parent::getFlagsByPhpVersion(); - - if ($this->flags & Class_::MODIFIER_STATIC) { - $flags = $this->addFlagForVersionsAbove($flags, "ZEND_ACC_STATIC", PHP_70_VERSION_ID); - } - - if ($this->flags & Class_::MODIFIER_READONLY) { - $flags = $this->addFlagForVersionsAbove($flags, "ZEND_ACC_READONLY", PHP_81_VERSION_ID); - } - - return $flags; - } - - protected function addModifiersToFieldSynopsis(DOMDocument $doc, DOMElement $fieldsynopsisElement): void - { - parent::addModifiersToFieldSynopsis($doc, $fieldsynopsisElement); - - if ($this->flags & Class_::MODIFIER_STATIC) { - $fieldsynopsisElement->appendChild(new DOMText("\n ")); - $fieldsynopsisElement->appendChild($doc->createElement("modifier", "static")); - } - - if ($this->flags & Class_::MODIFIER_READONLY || $this->isDocReadonly) { - $fieldsynopsisElement->appendChild(new DOMText("\n ")); - $fieldsynopsisElement->appendChild($doc->createElement("modifier", "readonly")); - } - } - - public function __clone() - { - if ($this->type) { - $this->type = clone $this->type; - } - } -} - -class EnumCaseInfo { - public string $name; - public ?Expr $value; - - public function __construct(string $name, ?Expr $value) { - $this->name = $name; - $this->value = $value; - } - - /** - * @param iterable $allConstInfos - */ - public function getDeclaration(iterable $allConstInfos): string { - $escapedName = addslashes($this->name); - if ($this->value === null) { - $code = "\n\tzend_enum_add_case_cstr(class_entry, \"$escapedName\", NULL);\n"; - } else { - $value = EvaluatedValue::createFromExpression($this->value, null, null, $allConstInfos); - - $zvalName = "enum_case_{$escapedName}_value"; - $code = "\n" . $value->initializeZval($zvalName); - $code .= "\tzend_enum_add_case_cstr(class_entry, \"$escapedName\", &$zvalName);\n"; - } - - return $code; - } -} - -class AttributeInfo { - public string $class; - /** @var \PhpParser\Node\Arg[] */ - public array $args; - - /** @param \PhpParser\Node\Arg[] $args */ - public function __construct(string $class, array $args) { - $this->class = $class; - $this->args = $args; - } - - /** @param iterable $allConstInfos */ - public function generateCode(string $invocation, string $nameSuffix, iterable $allConstInfos, ?int $phpVersionIdMinimumCompatibility): string { - $php82MinimumCompatibility = $phpVersionIdMinimumCompatibility === null || $phpVersionIdMinimumCompatibility >= PHP_82_VERSION_ID; - /* see ZEND_KNOWN_STRINGS in Zend/strings.h */ - $knowns = []; - if ($php82MinimumCompatibility) { - $knowns["SensitiveParameter"] = "ZEND_STR_SENSITIVEPARAMETER"; - } - - $code = "\n"; - $escapedAttributeName = strtr($this->class, '\\', '_'); - if (isset($knowns[$escapedAttributeName])) { - $code .= "\t" . ($this->args ? "zend_attribute *attribute_{$escapedAttributeName}_$nameSuffix = " : "") . "$invocation, ZSTR_KNOWN({$knowns[$escapedAttributeName]}), " . count($this->args) . ");\n"; - } else { - $code .= "\tzend_string *attribute_name_{$escapedAttributeName}_$nameSuffix = zend_string_init_interned(\"" . addcslashes($this->class, "\\") . "\", sizeof(\"" . addcslashes($this->class, "\\") . "\") - 1, 1);\n"; - $code .= "\t" . ($this->args ? "zend_attribute *attribute_{$escapedAttributeName}_$nameSuffix = " : "") . "$invocation, attribute_name_{$escapedAttributeName}_$nameSuffix, " . count($this->args) . ");\n"; - $code .= "\tzend_string_release(attribute_name_{$escapedAttributeName}_$nameSuffix);\n"; - } - foreach ($this->args as $i => $arg) { - $value = EvaluatedValue::createFromExpression($arg->value, null, null, $allConstInfos); - $zvalName = "attribute_{$escapedAttributeName}_{$nameSuffix}_arg$i"; - $code .= $value->initializeZval($zvalName); - $code .= "\tZVAL_COPY_VALUE(&attribute_{$escapedAttributeName}_{$nameSuffix}->args[$i].value, &$zvalName);\n"; - if ($arg->name) { - $code .= "\tattribute_{$escapedAttributeName}_{$nameSuffix}->args[$i].name = zend_string_init(\"{$arg->name->name}\", sizeof(\"{$arg->name->name}\") - 1, 1);\n"; - } - } - return $code; - } -} - -class ClassInfo { - public Name $name; - public int $flags; - public string $type; - public ?string $alias; - public ?SimpleType $enumBackingType; - public bool $isDeprecated; - public bool $isStrictProperties; - /** @var AttributeInfo[] */ - public array $attributes; - public bool $isNotSerializable; - /** @var Name[] */ - public array $extends; - /** @var Name[] */ - public array $implements; - /** @var ConstInfo[] */ - public array $constInfos; - /** @var PropertyInfo[] */ - public array $propertyInfos; - /** @var FuncInfo[] */ - public array $funcInfos; - /** @var EnumCaseInfo[] */ - public array $enumCaseInfos; - public ?string $cond; - public ?int $phpVersionIdMinimumCompatibility; - public bool $isUndocumentable; - - /** - * @param AttributeInfo[] $attributes - * @param Name[] $extends - * @param Name[] $implements - * @param ConstInfo[] $constInfos - * @param PropertyInfo[] $propertyInfos - * @param FuncInfo[] $funcInfos - * @param EnumCaseInfo[] $enumCaseInfos - */ - public function __construct( - Name $name, - int $flags, - string $type, - ?string $alias, - ?SimpleType $enumBackingType, - bool $isDeprecated, - bool $isStrictProperties, - array $attributes, - bool $isNotSerializable, - array $extends, - array $implements, - array $constInfos, - array $propertyInfos, - array $funcInfos, - array $enumCaseInfos, - ?string $cond, - ?int $minimumPhpVersionIdCompatibility, - bool $isUndocumentable - ) { - $this->name = $name; - $this->flags = $flags; - $this->type = $type; - $this->alias = $alias; - $this->enumBackingType = $enumBackingType; - $this->isDeprecated = $isDeprecated; - $this->isStrictProperties = $isStrictProperties; - $this->attributes = $attributes; - $this->isNotSerializable = $isNotSerializable; - $this->extends = $extends; - $this->implements = $implements; - $this->constInfos = $constInfos; - $this->propertyInfos = $propertyInfos; - $this->funcInfos = $funcInfos; - $this->enumCaseInfos = $enumCaseInfos; - $this->cond = $cond; - $this->phpVersionIdMinimumCompatibility = $minimumPhpVersionIdCompatibility; - $this->isUndocumentable = $isUndocumentable; - } - - /** - * @param ConstInfo[] $allConstInfos - */ - public function getRegistration(iterable $allConstInfos): string - { - $params = []; - foreach ($this->extends as $extends) { - $params[] = "zend_class_entry *class_entry_" . implode("_", $extends->getParts()); - } - foreach ($this->implements as $implements) { - $params[] = "zend_class_entry *class_entry_" . implode("_", $implements->getParts()); - } - - $escapedName = implode("_", $this->name->getParts()); - - $code = ''; - - $php80MinimumCompatibility = $this->phpVersionIdMinimumCompatibility === null || $this->phpVersionIdMinimumCompatibility >= PHP_80_VERSION_ID; - $php81MinimumCompatibility = $this->phpVersionIdMinimumCompatibility === null || $this->phpVersionIdMinimumCompatibility >= PHP_81_VERSION_ID; - - if ($this->type === "enum" && !$php81MinimumCompatibility) { - $code .= "#if (PHP_VERSION_ID >= " . PHP_81_VERSION_ID . ")\n"; - } - - if ($this->cond) { - $code .= "#if {$this->cond}\n"; - } - - $code .= "static zend_class_entry *register_class_$escapedName(" . (empty($params) ? "void" : implode(", ", $params)) . ")\n"; - - $code .= "{\n"; - if ($this->type === "enum") { - $name = addslashes((string) $this->name); - $backingType = $this->enumBackingType - ? $this->enumBackingType->toTypeCode() : "IS_UNDEF"; - $code .= "\tzend_class_entry *class_entry = zend_register_internal_enum(\"$name\", $backingType, class_{$escapedName}_methods);\n"; - } else { - $code .= "\tzend_class_entry ce, *class_entry;\n\n"; - if (count($this->name->getParts()) > 1) { - $className = $this->name->getLast(); - $namespace = addslashes((string) $this->name->slice(0, -1)); - - $code .= "\tINIT_NS_CLASS_ENTRY(ce, \"$namespace\", \"$className\", class_{$escapedName}_methods);\n"; - } else { - $code .= "\tINIT_CLASS_ENTRY(ce, \"$this->name\", class_{$escapedName}_methods);\n"; - } - - if ($this->type === "class" || $this->type === "trait") { - $code .= "\tclass_entry = zend_register_internal_class_ex(&ce, " . (isset($this->extends[0]) ? "class_entry_" . str_replace("\\", "_", $this->extends[0]->toString()) : "NULL") . ");\n"; - } else { - $code .= "\tclass_entry = zend_register_internal_interface(&ce);\n"; - } - } - - $flagCodes = generateVersionDependentFlagCode("\tclass_entry->ce_flags |= %s;\n", $this->getFlagsByPhpVersion(), $this->phpVersionIdMinimumCompatibility); - $code .= implode("", $flagCodes); - - $implements = array_map( - function (Name $item) { - return "class_entry_" . implode("_", $item->getParts()); - }, - $this->type === "interface" ? $this->extends : $this->implements - ); - - if (!empty($implements)) { - $code .= "\tzend_class_implements(class_entry, " . count($implements) . ", " . implode(", ", $implements) . ");\n"; - } - - if ($this->alias) { - $code .= "\tzend_register_class_alias(\"" . str_replace("\\", "\\\\", $this->alias) . "\", class_entry);\n"; - } - - foreach ($this->constInfos as $const) { - $code .= $const->getDeclaration($allConstInfos); - } - - foreach ($this->enumCaseInfos as $enumCase) { - $code .= $enumCase->getDeclaration($allConstInfos); - } - - foreach ($this->propertyInfos as $property) { - $code .= $property->getDeclaration($allConstInfos); - } - - if (!empty($this->attributes)) { - if (!$php80MinimumCompatibility) { - $code .= "\n#if (PHP_VERSION_ID >= " . PHP_80_VERSION_ID . ")"; - } - - foreach ($this->attributes as $attribute) { - $code .= $attribute->generateCode("zend_add_class_attribute(class_entry", "class_$escapedName", $allConstInfos, $this->phpVersionIdMinimumCompatibility); - } - - if (!$php80MinimumCompatibility) { - $code .= "#endif\n"; - } - } - - if ($attributeInitializationCode = generateAttributeInitialization($this->funcInfos, $allConstInfos, $this->phpVersionIdMinimumCompatibility, $this->cond)) { - if (!$php80MinimumCompatibility) { - $code .= "#if (PHP_VERSION_ID >= " . PHP_80_VERSION_ID . ")\n"; - } - - $code .= "\n" . $attributeInitializationCode; - - if (!$php80MinimumCompatibility) { - $code .= "#endif\n"; - } - } - - $code .= "\n\treturn class_entry;\n"; - - $code .= "}\n"; - - if ($this->cond) { - $code .= "#endif\n"; - } - - if ($this->type === "enum" && !$php81MinimumCompatibility) { - $code .= "#endif\n"; - } - - return $code; - } - - /** - * @return array - */ - private function getFlagsByPhpVersion(): array - { - $php70Flags = []; - - if ($this->type === "trait") { - $php70Flags[] = "ZEND_ACC_TRAIT"; - } - - if ($this->flags & Class_::MODIFIER_FINAL) { - $php70Flags[] = "ZEND_ACC_FINAL"; - } - - if ($this->flags & Class_::MODIFIER_ABSTRACT) { - $php70Flags[] = "ZEND_ACC_ABSTRACT"; - } - - if ($this->isDeprecated) { - $php70Flags[] = "ZEND_ACC_DEPRECATED"; - } - - $php80Flags = $php70Flags; - - if ($this->isStrictProperties) { - $php80Flags[] = "ZEND_ACC_NO_DYNAMIC_PROPERTIES"; - } - - $php81Flags = $php80Flags; - - if ($this->isNotSerializable) { - $php81Flags[] = "ZEND_ACC_NOT_SERIALIZABLE"; - } - - $php82Flags = $php81Flags; - - if ($this->flags & Class_::MODIFIER_READONLY) { - $php82Flags[] = "ZEND_ACC_READONLY_CLASS"; - } - - foreach ($this->attributes as $attr) { - if ($attr->class === "AllowDynamicProperties") { - $php82Flags[] = "ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES"; - break; - } - } - - $php83Flags = $php82Flags; - - return [ - PHP_70_VERSION_ID => $php70Flags, - PHP_80_VERSION_ID => $php80Flags, - PHP_81_VERSION_ID => $php81Flags, - PHP_82_VERSION_ID => $php82Flags, - PHP_83_VERSION_ID => $php83Flags, - ]; - } - - /** - * @param array $classMap - * @param iterable $allConstInfos - * @param iterable $allConstInfo - */ - public function getClassSynopsisDocument(array $classMap, iterable $allConstInfos): ?string { - - $doc = new DOMDocument(); - $doc->formatOutput = true; - $classSynopsis = $this->getClassSynopsisElement($doc, $classMap, $allConstInfos); - if (!$classSynopsis) { - return null; - } - - $doc->appendChild($classSynopsis); - - return $doc->saveXML(); - } - - /** - * @param array $classMap - * @param iterable $allConstInfos - */ - public function getClassSynopsisElement(DOMDocument $doc, array $classMap, iterable $allConstInfos): ?DOMElement { - - $classSynopsis = $doc->createElement("classsynopsis"); - $classSynopsis->setAttribute("class", $this->type === "interface" ? "interface" : "class"); - - $exceptionOverride = $this->isException($classMap) ? "exception" : null; - $ooElement = self::createOoElement($doc, $this, $exceptionOverride, true, null, 4); - if (!$ooElement) { - return null; - } - $classSynopsis->appendChild(new DOMText("\n ")); - $classSynopsis->appendChild($ooElement); - - foreach ($this->extends as $k => $parent) { - $parentInfo = $classMap[$parent->toString()] ?? null; - if ($parentInfo === null) { - throw new Exception("Missing parent class " . $parent->toString()); - } - - $ooElement = self::createOoElement( - $doc, - $parentInfo, - null, - false, - $k === 0 ? "extends" : null, - 4 - ); - if (!$ooElement) { - return null; - } - - $classSynopsis->appendChild(new DOMText("\n\n ")); - $classSynopsis->appendChild($ooElement); - } - - foreach ($this->implements as $k => $interface) { - $interfaceInfo = $classMap[$interface->toString()] ?? null; - if (!$interfaceInfo) { - throw new Exception("Missing implemented interface " . $interface->toString()); - } - - $ooElement = self::createOoElement($doc, $interfaceInfo, null, false, $k === 0 ? "implements" : null, 4); - if (!$ooElement) { - return null; - } - $classSynopsis->appendChild(new DOMText("\n\n ")); - $classSynopsis->appendChild($ooElement); - } - - /** @var array $parentsWithInheritedConstants */ - $parentsWithInheritedConstants = []; - /** @var array $parentsWithInheritedProperties */ - $parentsWithInheritedProperties = []; - /** @var array $parentsWithInheritedMethods */ - $parentsWithInheritedMethods = []; - - $this->collectInheritedMembers( - $parentsWithInheritedConstants, - $parentsWithInheritedProperties, - $parentsWithInheritedMethods, - $this->hasConstructor(), - $classMap - ); - - $this->appendInheritedMemberSectionToClassSynopsis( - $doc, - $classSynopsis, - $parentsWithInheritedConstants, - "&Constants;", - "&InheritedConstants;" - ); - - if (!empty($this->constInfos)) { - $classSynopsis->appendChild(new DOMText("\n\n ")); - $classSynopsisInfo = $doc->createElement("classsynopsisinfo", "&Constants;"); - $classSynopsisInfo->setAttribute("role", "comment"); - $classSynopsis->appendChild($classSynopsisInfo); - - foreach ($this->constInfos as $constInfo) { - $classSynopsis->appendChild(new DOMText("\n ")); - $fieldSynopsisElement = $constInfo->getFieldSynopsisElement($doc, $allConstInfos); - $classSynopsis->appendChild($fieldSynopsisElement); - } - } - - if (!empty($this->propertyInfos)) { - $classSynopsis->appendChild(new DOMText("\n\n ")); - $classSynopsisInfo = $doc->createElement("classsynopsisinfo", "&Properties;"); - $classSynopsisInfo->setAttribute("role", "comment"); - $classSynopsis->appendChild($classSynopsisInfo); - - foreach ($this->propertyInfos as $propertyInfo) { - $classSynopsis->appendChild(new DOMText("\n ")); - $fieldSynopsisElement = $propertyInfo->getFieldSynopsisElement($doc, $allConstInfos); - $classSynopsis->appendChild($fieldSynopsisElement); - } - } - - $this->appendInheritedMemberSectionToClassSynopsis( - $doc, - $classSynopsis, - $parentsWithInheritedProperties, - "&Properties;", - "&InheritedProperties;" - ); - - if (!empty($this->funcInfos)) { - $classSynopsis->appendChild(new DOMText("\n\n ")); - $classSynopsisInfo = $doc->createElement("classsynopsisinfo", "&Methods;"); - $classSynopsisInfo->setAttribute("role", "comment"); - $classSynopsis->appendChild($classSynopsisInfo); - - $classReference = self::getClassSynopsisReference($this->name); - $escapedName = addslashes($this->name->__toString()); - - if ($this->hasConstructor()) { - $classSynopsis->appendChild(new DOMText("\n ")); - $includeElement = $this->createIncludeElement( - $doc, - "xmlns(db=http://docbook.org/ns/docbook) xpointer(id('$classReference')/db:refentry/db:refsect1[@role='description']/descendant::db:constructorsynopsis[@role='$escapedName'])" - ); - $classSynopsis->appendChild($includeElement); - } - - if ($this->hasMethods()) { - $classSynopsis->appendChild(new DOMText("\n ")); - $includeElement = $this->createIncludeElement( - $doc, - "xmlns(db=http://docbook.org/ns/docbook) xpointer(id('$classReference')/db:refentry/db:refsect1[@role='description']/descendant::db:methodsynopsis[@role='$escapedName'])" - ); - $classSynopsis->appendChild($includeElement); - } - - if ($this->hasDestructor()) { - $classSynopsis->appendChild(new DOMText("\n ")); - $includeElement = $this->createIncludeElement( - $doc, - "xmlns(db=http://docbook.org/ns/docbook) xpointer(id('$classReference')/db:refentry/db:refsect1[@role='description']/descendant::db:destructorsynopsis[@role='$escapedName'])" - ); - $classSynopsis->appendChild($includeElement); - } - } - - if (!empty($parentsWithInheritedMethods)) { - $classSynopsis->appendChild(new DOMText("\n\n ")); - $classSynopsisInfo = $doc->createElement("classsynopsisinfo", "&InheritedMethods;"); - $classSynopsisInfo->setAttribute("role", "comment"); - $classSynopsis->appendChild($classSynopsisInfo); - - foreach ($parentsWithInheritedMethods as $parent) { - $parentName = $parent["name"]; - $parentMethodsynopsisTypes = $parent["types"]; - - $parentReference = self::getClassSynopsisReference($parentName); - $escapedParentName = addslashes($parentName->__toString()); - - foreach ($parentMethodsynopsisTypes as $parentMethodsynopsisType) { - $classSynopsis->appendChild(new DOMText("\n ")); - $includeElement = $this->createIncludeElement( - $doc, - "xmlns(db=http://docbook.org/ns/docbook) xpointer(id('$parentReference')/db:refentry/db:refsect1[@role='description']/descendant::db:{$parentMethodsynopsisType}[@role='$escapedParentName'])" - ); - - $classSynopsis->appendChild($includeElement); - } - } - } - - $classSynopsis->appendChild(new DOMText("\n ")); - - return $classSynopsis; - } - - private static function createOoElement( - DOMDocument $doc, - ClassInfo $classInfo, - ?string $typeOverride, - bool $withModifiers, - ?string $modifierOverride, - int $indentationLevel - ): ?DOMElement { - $indentation = str_repeat(" ", $indentationLevel); - - if ($classInfo->type !== "class" && $classInfo->type !== "interface") { - echo "Class synopsis generation is not implemented for " . $classInfo->type . "\n"; - return null; - } - - $type = $typeOverride !== null ? $typeOverride : $classInfo->type; - - $ooElement = $doc->createElement("oo$type"); - $ooElement->appendChild(new DOMText("\n$indentation ")); - if ($modifierOverride !== null) { - $ooElement->appendChild($doc->createElement('modifier', $modifierOverride)); - $ooElement->appendChild(new DOMText("\n$indentation ")); - } elseif ($withModifiers) { - if ($classInfo->flags & Class_::MODIFIER_FINAL) { - $ooElement->appendChild($doc->createElement('modifier', 'final')); - $ooElement->appendChild(new DOMText("\n$indentation ")); - } - if ($classInfo->flags & Class_::MODIFIER_ABSTRACT) { - $ooElement->appendChild($doc->createElement('modifier', 'abstract')); - $ooElement->appendChild(new DOMText("\n$indentation ")); - } - if ($classInfo->flags & Class_::MODIFIER_READONLY) { - $ooElement->appendChild($doc->createElement('modifier', 'readonly')); - $ooElement->appendChild(new DOMText("\n$indentation ")); - } - } - - $nameElement = $doc->createElement("{$type}name", $classInfo->name->toString()); - $ooElement->appendChild($nameElement); - $ooElement->appendChild(new DOMText("\n$indentation")); - - return $ooElement; - } - - public static function getClassSynopsisFilename(Name $name): string { - return strtolower(str_replace("_", "-", implode('-', $name->getParts()))); - } - - public static function getClassSynopsisReference(Name $name): string { - return "class." . self::getClassSynopsisFilename($name); - } - - /** - * @param array $parentsWithInheritedConstants - * @param array $parentsWithInheritedProperties - * @param array $parentsWithInheritedMethods - * @param array $classMap - */ - private function collectInheritedMembers( - array &$parentsWithInheritedConstants, - array &$parentsWithInheritedProperties, - array &$parentsWithInheritedMethods, - bool $hasConstructor, - array $classMap - ): void { - foreach ($this->extends as $parent) { - $parentInfo = $classMap[$parent->toString()] ?? null; - $parentName = $parent->toString(); - - if (!$parentInfo) { - throw new Exception("Missing parent class $parentName"); - } - - if (!empty($parentInfo->constInfos) && !isset($parentsWithInheritedConstants[$parentName])) { - $parentsWithInheritedConstants[] = $parent; - } - - if (!empty($parentInfo->propertyInfos) && !isset($parentsWithInheritedProperties[$parentName])) { - $parentsWithInheritedProperties[$parentName] = $parent; - } - - if (!$hasConstructor && $parentInfo->hasNonPrivateConstructor()) { - $parentsWithInheritedMethods[$parentName]["name"] = $parent; - $parentsWithInheritedMethods[$parentName]["types"][] = "constructorsynopsis"; - } - - if ($parentInfo->hasMethods()) { - $parentsWithInheritedMethods[$parentName]["name"] = $parent; - $parentsWithInheritedMethods[$parentName]["types"][] = "methodsynopsis"; - } - - if ($parentInfo->hasDestructor()) { - $parentsWithInheritedMethods[$parentName]["name"] = $parent; - $parentsWithInheritedMethods[$parentName]["types"][] = "destructorsynopsis"; - } - - $parentInfo->collectInheritedMembers( - $parentsWithInheritedConstants, - $parentsWithInheritedProperties, - $parentsWithInheritedMethods, - $hasConstructor, - $classMap - ); - } - - foreach ($this->implements as $parent) { - $parentInfo = $classMap[$parent->toString()] ?? null; - if (!$parentInfo) { - throw new Exception("Missing parent interface " . $parent->toString()); - } - - if (!empty($parentInfo->constInfos) && !isset($parentsWithInheritedConstants[$parent->toString()])) { - $parentsWithInheritedConstants[$parent->toString()] = $parent; - } - - $unusedParentsWithInheritedProperties = []; - $unusedParentsWithInheritedMethods = []; - - $parentInfo->collectInheritedMembers( - $parentsWithInheritedConstants, - $unusedParentsWithInheritedProperties, - $unusedParentsWithInheritedMethods, - $hasConstructor, - $classMap - ); - } - } - - /** @param array $classMap */ - private function isException(array $classMap): bool - { - if ($this->name->toString() === "Throwable") { - return true; - } - - foreach ($this->extends as $parentName) { - $parent = $classMap[$parentName->toString()] ?? null; - if ($parent === null) { - throw new Exception("Missing parent class " . $parentName->toString()); - } - - if ($parent->isException($classMap)) { - return true; - } - } - - if ($this->type === "class") { - foreach ($this->implements as $interfaceName) { - $interface = $classMap[$interfaceName->toString()] ?? null; - if ($interface === null) { - throw new Exception("Missing implemented interface " . $interfaceName->toString()); - } - - if ($interface->isException($classMap)) { - return true; - } - } - } - - return false; - } - - private function hasConstructor(): bool - { - foreach ($this->funcInfos as $funcInfo) { - if ($funcInfo->name->isConstructor()) { - return true; - } - } - - return false; - } - - private function hasNonPrivateConstructor(): bool - { - foreach ($this->funcInfos as $funcInfo) { - if ($funcInfo->name->isConstructor() && !($funcInfo->flags & Class_::MODIFIER_PRIVATE)) { - return true; - } - } - - return false; - } - - private function hasDestructor(): bool - { - foreach ($this->funcInfos as $funcInfo) { - if ($funcInfo->name->isDestructor()) { - return true; - } - } - - return false; - } - - private function hasMethods(): bool - { - foreach ($this->funcInfos as $funcInfo) { - if (!$funcInfo->name->isConstructor() && !$funcInfo->name->isDestructor()) { - return true; - } - } - - return false; - } - - private function createIncludeElement(DOMDocument $doc, string $query): DOMElement - { - $includeElement = $doc->createElement("xi:include"); - $attr = $doc->createAttribute("xpointer"); - $attr->value = $query; - $includeElement->appendChild($attr); - $fallbackElement = $doc->createElement("xi:fallback"); - $includeElement->appendChild(new DOMText("\n ")); - $includeElement->appendChild($fallbackElement); - $includeElement->appendChild(new DOMText("\n ")); - - return $includeElement; - } - - public function __clone() - { - foreach ($this->propertyInfos as $key => $propertyInfo) { - $this->propertyInfos[$key] = clone $propertyInfo; - } - - foreach ($this->funcInfos as $key => $funcInfo) { - $this->funcInfos[$key] = clone $funcInfo; - } - } - - /** - * @param Name[] $parents - */ - private function appendInheritedMemberSectionToClassSynopsis(DOMDocument $doc, DOMElement $classSynopsis, array $parents, string $label, string $inheritedLabel): void - { - if (empty($parents)) { - return; - } - - $classSynopsis->appendChild(new DOMText("\n\n ")); - $classSynopsisInfo = $doc->createElement("classsynopsisinfo", "$inheritedLabel"); - $classSynopsisInfo->setAttribute("role", "comment"); - $classSynopsis->appendChild($classSynopsisInfo); - - foreach ($parents as $parent) { - $classSynopsis->appendChild(new DOMText("\n ")); - $parentReference = self::getClassSynopsisReference($parent); - - $includeElement = $this->createIncludeElement( - $doc, - "xmlns(db=http://docbook.org/ns/docbook) xpointer(id('$parentReference')/db:partintro/db:section/db:classsynopsis/db:fieldsynopsis[preceding-sibling::db:classsynopsisinfo[1][@role='comment' and text()='$label']]))" - ); - $classSynopsis->appendChild($includeElement); - } - } -} - -class FileInfo { - /** @var string[] */ - public array $dependencies = []; - /** @var ConstInfo[] */ - public array $constInfos = []; - /** @var FuncInfo[] */ - public array $funcInfos = []; - /** @var ClassInfo[] */ - public array $classInfos = []; - public bool $generateFunctionEntries = false; - public string $declarationPrefix = ""; - public ?int $generateLegacyArginfoForPhpVersionId = null; - public bool $generateClassEntries = false; - public bool $isUndocumentable = false; - - /** - * @return iterable - */ - public function getAllFuncInfos(): iterable { - yield from $this->funcInfos; - foreach ($this->classInfos as $classInfo) { - yield from $classInfo->funcInfos; - } - } - - /** - * @return iterable - */ - public function getAllConstInfos(): iterable { - $result = $this->constInfos; - - foreach ($this->classInfos as $classInfo) { - $result = array_merge($result, $classInfo->constInfos); - } - - return $result; - } - - /** - * @return iterable - */ - public function getAllPropertyInfos(): iterable { - foreach ($this->classInfos as $classInfo) { - yield from $classInfo->propertyInfos; - } - } - - public function __clone() - { - foreach ($this->funcInfos as $key => $funcInfo) { - $this->funcInfos[$key] = clone $funcInfo; - } - - foreach ($this->classInfos as $key => $classInfo) { - $this->classInfos[$key] = clone $classInfo; - } - } -} - -class DocCommentTag { - public string $name; - public ?string $value; - - public function __construct(string $name, ?string $value) { - $this->name = $name; - $this->value = $value; - } - - public function getValue(): string { - if ($this->value === null) { - throw new Exception("@$this->name does not have a value"); - } - - return $this->value; - } - - public function getType(): string { - $value = $this->getValue(); - - $matches = []; - - if ($this->name === "param") { - preg_match('/^\s*([\w\|\\\\\[\]<>, ]+)\s*(?:[{(]|\$\w+).*$/', $value, $matches); - } elseif ($this->name === "return" || $this->name === "var") { - preg_match('/^\s*([\w\|\\\\\[\]<>, ]+)/', $value, $matches); - } - - if (!isset($matches[1])) { - throw new Exception("@$this->name doesn't contain a type or has an invalid format \"$value\""); - } - - return trim($matches[1]); - } - - public function getVariableName(): string { - $value = $this->value; - if ($value === null || strlen($value) === 0) { - throw new Exception("@$this->name doesn't have any value"); - } - - $matches = []; - - if ($this->name === "param") { - // Allow for parsing extended types like callable(string):mixed in docblocks - preg_match('/^\s*(?[\w\|\\\\]+(?\((?(?:(?&parens)|[^(){}[\]]*+))++\)|\{(?&inparens)\}|\[(?&inparens)\])*+(?::(?&type))?)\s*\$(?\w+).*$/', $value, $matches); - } elseif ($this->name === "prefer-ref") { - preg_match('/^\s*\$(?\w+).*$/', $value, $matches); - } - - if (!isset($matches["name"])) { - throw new Exception("@$this->name doesn't contain a variable name or has an invalid format \"$value\""); - } - - return $matches["name"]; - } -} - -/** @return DocCommentTag[] */ -function parseDocComment(DocComment $comment): array { - $commentText = substr($comment->getText(), 2, -2); - $tags = []; - foreach (explode("\n", $commentText) as $commentLine) { - $regex = '/^\*\s*@([a-z-]+)(?:\s+(.+))?$/'; - if (preg_match($regex, trim($commentLine), $matches)) { - $tags[] = new DocCommentTag($matches[1], $matches[2] ?? null); - } - } - - return $tags; -} - -function parseFunctionLike( - PrettyPrinterAbstract $prettyPrinter, - FunctionOrMethodName $name, - int $classFlags, - int $flags, - Node\FunctionLike $func, - ?string $cond, - bool $isUndocumentable -): FuncInfo { - try { - $comment = $func->getDocComment(); - $paramMeta = []; - $aliasType = null; - $alias = null; - $isDeprecated = false; - $supportsCompileTimeEval = false; - $verify = true; - $docReturnType = null; - $tentativeReturnType = false; - $docParamTypes = []; - $refcount = null; - - if ($comment) { - $tags = parseDocComment($comment); - foreach ($tags as $tag) { - switch ($tag->name) { - case 'alias': - case 'implementation-alias': - $aliasType = $tag->name; - $aliasParts = explode("::", $tag->getValue()); - if (count($aliasParts) === 1) { - $alias = new FunctionName(new Name($aliasParts[0])); - } else { - $alias = new MethodName(new Name($aliasParts[0]), $aliasParts[1]); - } - break; - - case 'deprecated': - $isDeprecated = true; - break; - - case 'no-verify': - $verify = false; - break; - - case 'tentative-return-type': - $tentativeReturnType = true; - break; - - case 'return': - $docReturnType = $tag->getType(); - break; - - case 'param': - $docParamTypes[$tag->getVariableName()] = $tag->getType(); - break; - - case 'refcount': - $refcount = $tag->getValue(); - break; - - case 'compile-time-eval': - $supportsCompileTimeEval = true; - break; - - case 'prefer-ref': - $varName = $tag->getVariableName(); - if (!isset($paramMeta[$varName])) { - $paramMeta[$varName] = []; - } - $paramMeta[$varName][$tag->name] = true; - break; - - case 'undocumentable': - $isUndocumentable = true; - break; - } - } - } - - $varNameSet = []; - $args = []; - $numRequiredArgs = 0; - $foundVariadic = false; - foreach ($func->getParams() as $i => $param) { - $varName = $param->var->name; - $preferRef = !empty($paramMeta[$varName]['prefer-ref']); - $attributes = []; - foreach ($param->attrGroups as $attrGroup) { - foreach ($attrGroup->attrs as $attr) { - $attributes[] = new AttributeInfo($attr->name->toString(), $attr->args); - } - } - unset($paramMeta[$varName]); - - if (isset($varNameSet[$varName])) { - throw new Exception("Duplicate parameter name $varName"); - } - $varNameSet[$varName] = true; - - if ($preferRef) { - $sendBy = ArgInfo::SEND_PREFER_REF; - } else if ($param->byRef) { - $sendBy = ArgInfo::SEND_BY_REF; - } else { - $sendBy = ArgInfo::SEND_BY_VAL; - } - - if ($foundVariadic) { - throw new Exception("Only the last parameter can be variadic"); - } - - $type = $param->type ? Type::fromNode($param->type) : null; - if ($type === null && !isset($docParamTypes[$varName])) { - throw new Exception("Missing parameter type"); - } - - if ($param->default instanceof Expr\ConstFetch && - $param->default->name->toLowerString() === "null" && - $type && !$type->isNullable() - ) { - $simpleType = $type->tryToSimpleType(); - if ($simpleType === null) { - throw new Exception("Parameter $varName has null default, but is not nullable"); - } - } - - if ($param->default instanceof Expr\ClassConstFetch && $param->default->class->toLowerString() === "self") { - throw new Exception('The exact class name must be used instead of "self"'); - } - - $foundVariadic = $param->variadic; - - $args[] = new ArgInfo( - $varName, - $sendBy, - $param->variadic, - $type, - isset($docParamTypes[$varName]) ? Type::fromString($docParamTypes[$varName]) : null, - $param->default ? $prettyPrinter->prettyPrintExpr($param->default) : null, - $attributes - ); - if (!$param->default && !$param->variadic) { - $numRequiredArgs = $i + 1; - } - } - - foreach (array_keys($paramMeta) as $var) { - throw new Exception("Found metadata for invalid param $var"); - } - - $returnType = $func->getReturnType(); - if ($returnType === null && $docReturnType === null && !$name->isConstructor() && !$name->isDestructor()) { - throw new Exception("Missing return type"); - } - - $return = new ReturnInfo( - $func->returnsByRef(), - $returnType ? Type::fromNode($returnType) : null, - $docReturnType ? Type::fromString($docReturnType) : null, - $tentativeReturnType, - $refcount - ); - - return new FuncInfo( - $name, - $classFlags, - $flags, - $aliasType, - $alias, - $isDeprecated, - $supportsCompileTimeEval, - $verify, - $args, - $return, - $numRequiredArgs, - $cond, - $isUndocumentable - ); - } catch (Exception $e) { - throw new Exception($name . "(): " .$e->getMessage()); - } -} - -function parseConstLike( - PrettyPrinterAbstract $prettyPrinter, - ConstOrClassConstName $name, - Node\Const_ $const, - int $flags, - ?Node $type, - ?DocComment $docComment, - ?string $cond, - ?int $phpVersionIdMinimumCompatibility -): ConstInfo { - $phpDocType = null; - $deprecated = false; - $cValue = null; - $link = null; - if ($docComment) { - $tags = parseDocComment($docComment); - foreach ($tags as $tag) { - if ($tag->name === 'var') { - $phpDocType = $tag->getType(); - } elseif ($tag->name === 'deprecated') { - $deprecated = true; - } elseif ($tag->name === 'cvalue') { - $cValue = $tag->value; - } elseif ($tag->name === 'link') { - $link = $tag->value; - } - } - } - - if ($type === null && $phpDocType === null) { - throw new Exception("Missing type for constant " . $name->__toString()); - } - - return new ConstInfo( - $name, - $flags, - $const->value, - $prettyPrinter->prettyPrintExpr($const->value), - $type ? Type::fromNode($type) : null, - $phpDocType ? Type::fromString($phpDocType) : null, - $deprecated, - $cond, - $cValue, - $link, - $phpVersionIdMinimumCompatibility - ); -} - -function parseProperty( - Name $class, - int $flags, - Stmt\PropertyProperty $property, - ?Node $type, - ?DocComment $comment, - PrettyPrinterAbstract $prettyPrinter, - ?int $phpVersionIdMinimumCompatibility -): PropertyInfo { - $phpDocType = null; - $isDocReadonly = false; - $link = null; - - if ($comment) { - $tags = parseDocComment($comment); - foreach ($tags as $tag) { - if ($tag->name === 'var') { - $phpDocType = $tag->getType(); - } elseif ($tag->name === 'readonly') { - $isDocReadonly = true; - } elseif ($tag->name === 'link') { - $link = $tag->value; - } - } - } - - $propertyType = $type ? Type::fromNode($type) : null; - if ($propertyType === null && !$phpDocType) { - throw new Exception("Missing type for property $class::\$$property->name"); - } - - if ($property->default instanceof Expr\ConstFetch && - $property->default->name->toLowerString() === "null" && - $propertyType && !$propertyType->isNullable() - ) { - $simpleType = $propertyType->tryToSimpleType(); - if ($simpleType === null) { - throw new Exception( - "Property $class::\$$property->name has null default, but is not nullable"); - } - } - - return new PropertyInfo( - new PropertyName($class, $property->name->__toString()), - $flags, - $propertyType, - $phpDocType ? Type::fromString($phpDocType) : null, - $property->default, - $property->default ? $prettyPrinter->prettyPrintExpr($property->default) : null, - $isDocReadonly, - $link, - $phpVersionIdMinimumCompatibility - ); -} - -/** - * @param ConstInfo[] $consts - * @param PropertyInfo[] $properties - * @param FuncInfo[] $methods - * @param EnumCaseInfo[] $enumCases - */ -function parseClass( - Name $name, - Stmt\ClassLike $class, - array $consts, - array $properties, - array $methods, - array $enumCases, - ?string $cond, - ?int $minimumPhpVersionIdCompatibility, - bool $isUndocumentable -): ClassInfo { - $flags = $class instanceof Class_ ? $class->flags : 0; - $comment = $class->getDocComment(); - $alias = null; - $isDeprecated = false; - $isStrictProperties = false; - $isNotSerializable = false; - $allowsDynamicProperties = false; - $attributes = []; - - if ($comment) { - $tags = parseDocComment($comment); - foreach ($tags as $tag) { - if ($tag->name === 'alias') { - $alias = $tag->getValue(); - } else if ($tag->name === 'deprecated') { - $isDeprecated = true; - } else if ($tag->name === 'strict-properties') { - $isStrictProperties = true; - } else if ($tag->name === 'not-serializable') { - $isNotSerializable = true; - } else if ($tag->name === 'undocumentable') { - $isUndocumentable = true; - } - } - } - - foreach ($class->attrGroups as $attrGroup) { - foreach ($attrGroup->attrs as $attr) { - $attributes[] = new AttributeInfo($attr->name->toString(), $attr->args); - switch ($attr->name->toString()) { - case 'AllowDynamicProperties': - $allowsDynamicProperties = true; - break; - } - } - } - - if ($isStrictProperties && $allowsDynamicProperties) { - throw new Exception("A class may not have '@strict-properties' and '#[\\AllowDynamicProperties]' at the same time."); - } - - $extends = []; - $implements = []; - - if ($class instanceof Class_) { - $classKind = "class"; - if ($class->extends) { - $extends[] = $class->extends; - } - $implements = $class->implements; - } elseif ($class instanceof Interface_) { - $classKind = "interface"; - $extends = $class->extends; - } else if ($class instanceof Trait_) { - $classKind = "trait"; - } else if ($class instanceof Enum_) { - $classKind = "enum"; - $implements = $class->implements; - } else { - throw new Exception("Unknown class kind " . get_class($class)); - } - - if ($isUndocumentable) { - foreach ($methods as $method) { - $method->isUndocumentable = true; - } - } - - return new ClassInfo( - $name, - $flags, - $classKind, - $alias, - $class instanceof Enum_ && $class->scalarType !== null - ? SimpleType::fromNode($class->scalarType) : null, - $isDeprecated, - $isStrictProperties, - $attributes, - $isNotSerializable, - $extends, - $implements, - $consts, - $properties, - $methods, - $enumCases, - $cond, - $minimumPhpVersionIdCompatibility, - $isUndocumentable - ); -} - -function handlePreprocessorConditions(array &$conds, Stmt $stmt): ?string { - foreach ($stmt->getComments() as $comment) { - $text = trim($comment->getText()); - if (preg_match('/^#\s*if\s+(.+)$/', $text, $matches)) { - $conds[] = $matches[1]; - } else if (preg_match('/^#\s*ifdef\s+(.+)$/', $text, $matches)) { - $conds[] = "defined($matches[1])"; - } else if (preg_match('/^#\s*ifndef\s+(.+)$/', $text, $matches)) { - $conds[] = "!defined($matches[1])"; - } else if (preg_match('/^#\s*else$/', $text)) { - if (empty($conds)) { - throw new Exception("Encountered else without corresponding #if"); - } - $cond = array_pop($conds); - $conds[] = "!($cond)"; - } else if (preg_match('/^#\s*endif$/', $text)) { - if (empty($conds)) { - throw new Exception("Encountered #endif without corresponding #if"); - } - array_pop($conds); - } else if ($text[0] === '#') { - throw new Exception("Unrecognized preprocessor directive \"$text\""); - } - } - - return empty($conds) ? null : implode(' && ', $conds); -} - -function getFileDocComment(array $stmts): ?DocComment { - if (empty($stmts)) { - return null; - } - - $comments = $stmts[0]->getComments(); - if (empty($comments)) { - return null; - } - - if ($comments[0] instanceof DocComment) { - return $comments[0]; - } - - return null; -} - -function handleStatements(FileInfo $fileInfo, array $stmts, PrettyPrinterAbstract $prettyPrinter) { - $conds = []; - foreach ($stmts as $stmt) { - $cond = handlePreprocessorConditions($conds, $stmt); - - if ($stmt instanceof Stmt\Nop) { - continue; - } - - if ($stmt instanceof Stmt\Namespace_) { - handleStatements($fileInfo, $stmt->stmts, $prettyPrinter); - continue; - } - - if ($stmt instanceof Stmt\Const_) { - foreach ($stmt->consts as $const) { - $fileInfo->constInfos[] = parseConstLike( - $prettyPrinter, - new ConstName($const->namespacedName, $const->name->toString()), - $const, - 0, - null, - $stmt->getDocComment(), - $cond, - $fileInfo->generateLegacyArginfoForPhpVersionId - ); - } - continue; - } - - if ($stmt instanceof Stmt\Function_) { - $fileInfo->funcInfos[] = parseFunctionLike( - $prettyPrinter, - new FunctionName($stmt->namespacedName), - 0, - 0, - $stmt, - $cond, - $fileInfo->isUndocumentable - ); - continue; - } - - if ($stmt instanceof Stmt\ClassLike) { - $className = $stmt->namespacedName; - $constInfos = []; - $propertyInfos = []; - $methodInfos = []; - $enumCaseInfos = []; - foreach ($stmt->stmts as $classStmt) { - $cond = handlePreprocessorConditions($conds, $classStmt); - if ($classStmt instanceof Stmt\Nop) { - continue; - } - - $classFlags = $stmt instanceof Class_ ? $stmt->flags : 0; - $abstractFlag = $stmt instanceof Stmt\Interface_ ? Class_::MODIFIER_ABSTRACT : 0; - - if ($classStmt instanceof Stmt\ClassConst) { - foreach ($classStmt->consts as $const) { - $constInfos[] = parseConstLike( - $prettyPrinter, - new ClassConstName($className, $const->name->toString()), - $const, - $classStmt->flags, - $classStmt->type, - $classStmt->getDocComment(), - $cond, - $fileInfo->generateLegacyArginfoForPhpVersionId - ); - } - } else if ($classStmt instanceof Stmt\Property) { - if (!($classStmt->flags & Class_::VISIBILITY_MODIFIER_MASK)) { - throw new Exception("Visibility modifier is required"); - } - foreach ($classStmt->props as $property) { - $propertyInfos[] = parseProperty( - $className, - $classStmt->flags, - $property, - $classStmt->type, - $classStmt->getDocComment(), - $prettyPrinter, - $fileInfo->generateLegacyArginfoForPhpVersionId - ); - } - } else if ($classStmt instanceof Stmt\ClassMethod) { - if (!($classStmt->flags & Class_::VISIBILITY_MODIFIER_MASK)) { - throw new Exception("Visibility modifier is required"); - } - $methodInfos[] = parseFunctionLike( - $prettyPrinter, - new MethodName($className, $classStmt->name->toString()), - $classFlags, - $classStmt->flags | $abstractFlag, - $classStmt, - $cond, - $fileInfo->isUndocumentable - ); - } else if ($classStmt instanceof Stmt\EnumCase) { - $enumCaseInfos[] = new EnumCaseInfo( - $classStmt->name->toString(), $classStmt->expr); - } else { - throw new Exception("Not implemented {$classStmt->getType()}"); - } - } - - $fileInfo->classInfos[] = parseClass( - $className, $stmt, $constInfos, $propertyInfos, $methodInfos, $enumCaseInfos, $cond, $fileInfo->generateLegacyArginfoForPhpVersionId, $fileInfo->isUndocumentable - ); - continue; - } - - if ($stmt instanceof Stmt\Expression) { - $expr = $stmt->expr; - if ($expr instanceof Expr\Include_) { - $fileInfo->dependencies[] = (string)EvaluatedValue::createFromExpression($expr->expr, null, null, [])->value; - continue; - } - } - - throw new Exception("Unexpected node {$stmt->getType()}"); - } - if (!empty($conds)) { - throw new Exception("Unterminated preprocessor conditions"); - } -} - -function parseStubFile(string $code): FileInfo { - $lexer = new PhpParser\Lexer\Emulative(); - $parser = new PhpParser\Parser\Php7($lexer); - $nodeTraverser = new PhpParser\NodeTraverser; - $nodeTraverser->addVisitor(new PhpParser\NodeVisitor\NameResolver); - $prettyPrinter = new class extends Standard { - protected function pName_FullyQualified(Name\FullyQualified $node): string { - return implode('\\', $node->getParts()); - } - }; - - $stmts = $parser->parse($code); - $nodeTraverser->traverse($stmts); - - $fileInfo = new FileInfo; - $fileDocComment = getFileDocComment($stmts); - if ($fileDocComment) { - $fileTags = parseDocComment($fileDocComment); - foreach ($fileTags as $tag) { - if ($tag->name === 'generate-function-entries') { - $fileInfo->generateFunctionEntries = true; - $fileInfo->declarationPrefix = $tag->value ? $tag->value . " " : ""; - } else if ($tag->name === 'generate-legacy-arginfo') { - if ($tag->value && !in_array((int) $tag->value, ALL_PHP_VERSION_IDS, true)) { - throw new Exception( - "Legacy PHP version must be one of: \"" . PHP_70_VERSION_ID . "\" (PHP 7.0), \"" . PHP_80_VERSION_ID . "\" (PHP 8.0), " . - "\"" . PHP_81_VERSION_ID . "\" (PHP 8.1), \"" . PHP_82_VERSION_ID . "\" (PHP 8.2), \"" . PHP_83_VERSION_ID . "\" (PHP 8.3), " . - "\"" . $tag->value . "\" provided" - ); - } - - $fileInfo->generateLegacyArginfoForPhpVersionId = $tag->value ? (int) $tag->value : PHP_70_VERSION_ID; - } else if ($tag->name === 'generate-class-entries') { - $fileInfo->generateClassEntries = true; - $fileInfo->declarationPrefix = $tag->value ? $tag->value . " " : ""; - } else if ($tag->name === 'undocumentable') { - $fileInfo->isUndocumentable = true; - } - } - } - - // Generating class entries require generating function/method entries - if ($fileInfo->generateClassEntries && !$fileInfo->generateFunctionEntries) { - $fileInfo->generateFunctionEntries = true; - } - - handleStatements($fileInfo, $stmts, $prettyPrinter); - return $fileInfo; -} - -function funcInfoToCode(FileInfo $fileInfo, FuncInfo $funcInfo): string { - $code = ''; - $returnType = $funcInfo->return->type; - $isTentativeReturnType = $funcInfo->return->tentativeReturnType; - $php81MinimumCompatibility = $fileInfo->generateLegacyArginfoForPhpVersionId === null || $fileInfo->generateLegacyArginfoForPhpVersionId >= PHP_81_VERSION_ID; - - if ($returnType !== null) { - if ($isTentativeReturnType && !$php81MinimumCompatibility) { - $code .= "#if (PHP_VERSION_ID >= " . PHP_81_VERSION_ID . ")\n"; - } - if (null !== $simpleReturnType = $returnType->tryToSimpleType()) { - if ($simpleReturnType->isBuiltin) { - $code .= sprintf( - "%s(%s, %d, %d, %s, %d)\n", - $isTentativeReturnType ? "ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX" : "ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX", - $funcInfo->getArgInfoName(), $funcInfo->return->byRef, - $funcInfo->numRequiredArgs, - $simpleReturnType->toTypeCode(), $returnType->isNullable() - ); - } else { - $code .= sprintf( - "%s(%s, %d, %d, %s, %d)\n", - $isTentativeReturnType ? "ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_OBJ_INFO_EX" : "ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX", - $funcInfo->getArgInfoName(), $funcInfo->return->byRef, - $funcInfo->numRequiredArgs, - $simpleReturnType->toEscapedName(), $returnType->isNullable() - ); - } - } else { - $arginfoType = $returnType->toArginfoType(); - if ($arginfoType->hasClassType()) { - $code .= sprintf( - "%s(%s, %d, %d, %s, %s)\n", - $isTentativeReturnType ? "ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_OBJ_TYPE_MASK_EX" : "ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX", - $funcInfo->getArgInfoName(), $funcInfo->return->byRef, - $funcInfo->numRequiredArgs, - $arginfoType->toClassTypeString(), $arginfoType->toTypeMask() - ); - } else { - $code .= sprintf( - "%s(%s, %d, %d, %s)\n", - $isTentativeReturnType ? "ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_MASK_EX" : "ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX", - $funcInfo->getArgInfoName(), $funcInfo->return->byRef, - $funcInfo->numRequiredArgs, - $arginfoType->toTypeMask() - ); - } - } - if ($isTentativeReturnType && !$php81MinimumCompatibility) { - $code .= sprintf( - "#else\nZEND_BEGIN_ARG_INFO_EX(%s, 0, %d, %d)\n#endif\n", - $funcInfo->getArgInfoName(), $funcInfo->return->byRef, $funcInfo->numRequiredArgs - ); - } - } else { - $code .= sprintf( - "ZEND_BEGIN_ARG_INFO_EX(%s, 0, %d, %d)\n", - $funcInfo->getArgInfoName(), $funcInfo->return->byRef, $funcInfo->numRequiredArgs - ); - } - - foreach ($funcInfo->args as $argInfo) { - $argKind = $argInfo->isVariadic ? "ARG_VARIADIC" : "ARG"; - $argDefaultKind = $argInfo->hasProperDefaultValue() ? "_WITH_DEFAULT_VALUE" : ""; - $argType = $argInfo->type; - if ($argType !== null) { - if (null !== $simpleArgType = $argType->tryToSimpleType()) { - if ($simpleArgType->isBuiltin) { - $code .= sprintf( - "\tZEND_%s_TYPE_INFO%s(%s, %s, %s, %d%s)\n", - $argKind, $argDefaultKind, $argInfo->getSendByString(), $argInfo->name, - $simpleArgType->toTypeCode(), $argType->isNullable(), - $argInfo->hasProperDefaultValue() ? ", " . $argInfo->getDefaultValueAsArginfoString() : "" - ); - } else { - $code .= sprintf( - "\tZEND_%s_OBJ_INFO%s(%s, %s, %s, %d%s)\n", - $argKind,$argDefaultKind, $argInfo->getSendByString(), $argInfo->name, - $simpleArgType->toEscapedName(), $argType->isNullable(), - $argInfo->hasProperDefaultValue() ? ", " . $argInfo->getDefaultValueAsArginfoString() : "" - ); - } - } else { - $arginfoType = $argType->toArginfoType(); - if ($arginfoType->hasClassType()) { - $code .= sprintf( - "\tZEND_%s_OBJ_TYPE_MASK(%s, %s, %s, %s%s)\n", - $argKind, $argInfo->getSendByString(), $argInfo->name, - $arginfoType->toClassTypeString(), $arginfoType->toTypeMask(), - !$argInfo->isVariadic ? ", " . $argInfo->getDefaultValueAsArginfoString() : "" - ); - } else { - $code .= sprintf( - "\tZEND_%s_TYPE_MASK(%s, %s, %s, %s)\n", - $argKind, $argInfo->getSendByString(), $argInfo->name, - $arginfoType->toTypeMask(), - $argInfo->getDefaultValueAsArginfoString() - ); - } - } - } else { - $code .= sprintf( - "\tZEND_%s_INFO%s(%s, %s%s)\n", - $argKind, $argDefaultKind, $argInfo->getSendByString(), $argInfo->name, - $argInfo->hasProperDefaultValue() ? ", " . $argInfo->getDefaultValueAsArginfoString() : "" - ); - } - } - - $code .= "ZEND_END_ARG_INFO()"; - return $code . "\n"; -} - -/** @param FuncInfo[] $generatedFuncInfos */ -function findEquivalentFuncInfo(array $generatedFuncInfos, FuncInfo $funcInfo): ?FuncInfo { - foreach ($generatedFuncInfos as $generatedFuncInfo) { - if ($generatedFuncInfo->equalsApartFromNameAndRefcount($funcInfo)) { - return $generatedFuncInfo; - } - } - return null; -} - -/** - * @template T - * @param iterable $infos - * @param Closure(T): string|null $codeGenerator - * @param ?string $parentCond - */ -function generateCodeWithConditions( - iterable $infos, string $separator, Closure $codeGenerator, ?string $parentCond = null): string { - $code = ""; - foreach ($infos as $info) { - $infoCode = $codeGenerator($info); - if ($infoCode === null) { - continue; - } - - $code .= $separator; - if ($info->cond && $info->cond !== $parentCond) { - $code .= "#if {$info->cond}\n"; - $code .= $infoCode; - $code .= "#endif\n"; - } else { - $code .= $infoCode; - } - } - - return $code; -} - -/** - * @param iterable $allConstInfos - */ -function generateArgInfoCode( - string $stubFilenameWithoutExtension, - FileInfo $fileInfo, - iterable $allConstInfos, - string $stubHash -): string { - $code = "/* This is a generated file, edit the .stub.php file instead.\n" - . " * Stub hash: $stubHash */\n"; - - $generatedFuncInfos = []; - $code .= generateCodeWithConditions( - $fileInfo->getAllFuncInfos(), "\n", - static function (FuncInfo $funcInfo) use (&$generatedFuncInfos, $fileInfo) { - /* If there already is an equivalent arginfo structure, only emit a #define */ - if ($generatedFuncInfo = findEquivalentFuncInfo($generatedFuncInfos, $funcInfo)) { - $code = sprintf( - "#define %s %s\n", - $funcInfo->getArgInfoName(), $generatedFuncInfo->getArgInfoName() - ); - } else { - $code = funcInfoToCode($fileInfo, $funcInfo); - } - - $generatedFuncInfos[] = $funcInfo; - return $code; - } - ); - - if ($fileInfo->generateFunctionEntries) { - $code .= "\n\n"; - - $generatedFunctionDeclarations = []; - $code .= generateCodeWithConditions( - $fileInfo->getAllFuncInfos(), "", - static function (FuncInfo $funcInfo) use ($fileInfo, &$generatedFunctionDeclarations) { - $key = $funcInfo->getDeclarationKey(); - if (isset($generatedFunctionDeclarations[$key])) { - return null; - } - - $generatedFunctionDeclarations[$key] = true; - return $fileInfo->declarationPrefix . $funcInfo->getDeclaration(); - } - ); - - if (!empty($fileInfo->funcInfos)) { - $code .= generateFunctionEntries(null, $fileInfo->funcInfos); - } - - foreach ($fileInfo->classInfos as $classInfo) { - $code .= generateFunctionEntries($classInfo->name, $classInfo->funcInfos, $classInfo->cond); - } - } - - $php80MinimumCompatibility = $fileInfo->generateLegacyArginfoForPhpVersionId === null || $fileInfo->generateLegacyArginfoForPhpVersionId >= PHP_80_VERSION_ID; - - if ($fileInfo->generateClassEntries) { - if ($attributeInitializationCode = generateAttributeInitialization($fileInfo->funcInfos, $allConstInfos, $fileInfo->generateLegacyArginfoForPhpVersionId, null)) { - if (!$php80MinimumCompatibility) { - $attributeInitializationCode = "\n#if (PHP_VERSION_ID >= " . PHP_80_VERSION_ID . ")" . $attributeInitializationCode . "#endif\n"; - } - } - - if ($attributeInitializationCode !== "" || !empty($fileInfo->constInfos)) { - $code .= "\nstatic void register_{$stubFilenameWithoutExtension}_symbols(int module_number)\n"; - $code .= "{\n"; - - foreach ($fileInfo->constInfos as $constInfo) { - $code .= $constInfo->getDeclaration($allConstInfos); - } - - if (!empty($attributeInitializationCode !== "" && $fileInfo->constInfos)) { - $code .= "\n"; - } - - $code .= $attributeInitializationCode; - $code .= "}\n"; - } - - $code .= generateClassEntryCode($fileInfo, $allConstInfos); - } - - return $code; -} - -/** - * @param iterable $allConstInfos - */ -function generateClassEntryCode(FileInfo $fileInfo, iterable $allConstInfos): string { - $code = ""; - - foreach ($fileInfo->classInfos as $class) { - $code .= "\n" . $class->getRegistration($allConstInfos); - } - - return $code; -} - -/** @param FuncInfo[] $funcInfos */ -function generateFunctionEntries(?Name $className, array $funcInfos, ?string $cond = null): string { - $code = "\n\n"; - - if ($cond) { - $code .= "#if {$cond}\n"; - } - - $functionEntryName = "ext_functions"; - if ($className) { - $underscoreName = implode("_", $className->getParts()); - $functionEntryName = "class_{$underscoreName}_methods"; - } - - $code .= "static const zend_function_entry {$functionEntryName}[] = {\n"; - $code .= generateCodeWithConditions($funcInfos, "", static function (FuncInfo $funcInfo) { - return $funcInfo->getFunctionEntry(); - }, $cond); - $code .= "\tZEND_FE_END\n"; - $code .= "};\n"; - - if ($cond) { - $code .= "#endif\n"; - } - - return $code; -} -/** - * @param iterable $funcInfos - */ -function generateAttributeInitialization(iterable $funcInfos, iterable $allConstInfos, ?int $phpVersionIdMinimumCompatibility, ?string $parentCond = null): string { - return generateCodeWithConditions( - $funcInfos, - "", - static function (FuncInfo $funcInfo) use ($allConstInfos, $phpVersionIdMinimumCompatibility) { - $code = null; - - foreach ($funcInfo->args as $index => $arg) { - if ($funcInfo->name instanceof MethodName) { - $functionTable = "&class_entry->function_table"; - } else { - $functionTable = "CG(function_table)"; - } - - foreach ($arg->attributes as $attribute) { - $code .= $attribute->generateCode("zend_add_parameter_attribute(zend_hash_str_find_ptr($functionTable, \"" . $funcInfo->name->getNameForAttributes() . "\", sizeof(\"" . $funcInfo->name->getNameForAttributes() . "\") - 1), $index", "{$funcInfo->name->getMethodSynopsisFilename()}_arg{$index}", $allConstInfos, $phpVersionIdMinimumCompatibility); - } - } - - return $code; - }, - $parentCond - ); -} - -/** @param array $funcMap */ -function generateOptimizerInfo(array $funcMap): string { - - $code = "/* This is a generated file, edit the .stub.php files instead. */\n\n"; - - $code .= "static const func_info_t func_infos[] = {\n"; - - $code .= generateCodeWithConditions($funcMap, "", static function (FuncInfo $funcInfo) { - return $funcInfo->getOptimizerInfo(); - }); - - $code .= "};\n"; - - return $code; -} - -/** - * @param array $flagsByPhpVersions - * @return string[] - */ -function generateVersionDependentFlagCode(string $codeTemplate, array $flagsByPhpVersions, ?int $phpVersionIdMinimumCompatibility): array -{ - $phpVersions = ALL_PHP_VERSION_IDS; - sort($phpVersions); - $currentPhpVersion = end($phpVersions); - - // No version compatibility is needed - if ($phpVersionIdMinimumCompatibility === null) { - if (empty($flagsByPhpVersions[$currentPhpVersion])) { - return []; - } - - return [sprintf($codeTemplate, implode("|", $flagsByPhpVersions[$currentPhpVersion]))]; - } - - // Remove flags which depend on a PHP version below the minimally supported one - ksort($flagsByPhpVersions); - $index = array_search($phpVersionIdMinimumCompatibility, array_keys($flagsByPhpVersions)); - if ($index === false) { - throw new Exception("Missing version dependent flags for PHP version ID \"$phpVersionIdMinimumCompatibility\""); - } - $flagsByPhpVersions = array_slice($flagsByPhpVersions, $index, null, true); - - // Remove empty version-specific flags - $flagsByPhpVersions = array_filter( - $flagsByPhpVersions, - static function (array $value): bool { - return !empty($value); - }); - - // There are no version-specific flags - if (empty($flagsByPhpVersions)) { - return []; - } - - // Remove version-specific flags which don't differ from the previous one - $previousVersionId = null; - foreach ($flagsByPhpVersions as $versionId => $versionFlags) { - if ($previousVersionId !== null && $flagsByPhpVersions[$previousVersionId] === $versionFlags) { - unset($flagsByPhpVersions[$versionId]); - } else { - $previousVersionId = $versionId; - } - } - - $flagCount = count($flagsByPhpVersions); - - // Do not add a condition unnecessarily when the only version is the same as the minimally supported one - if ($flagCount === 1) { - reset($flagsByPhpVersions); - $firstVersion = key($flagsByPhpVersions); - if ($firstVersion === $phpVersionIdMinimumCompatibility) { - return [sprintf($codeTemplate, implode("|", reset($flagsByPhpVersions)))]; - } - } - - // Add the necessary conditions around the code using the version-specific flags - $result = []; - $i = 0; - foreach (array_reverse($flagsByPhpVersions, true) as $version => $versionFlags) { - $code = ""; - - $if = $i === 0 ? "#if" : "#elif"; - $endif = $i === $flagCount - 1 ? "#endif\n" : ""; - - $code .= "$if (PHP_VERSION_ID >= $version)\n"; - - $code .= sprintf($codeTemplate, implode("|", $versionFlags)); - $code .= $endif; - - $result[] = $code; - $i++; - } - - return $result; -} - -/** - * @param array $classMap - * @param iterable $allConstInfos - * @return array - */ -function generateClassSynopses(array $classMap, iterable $allConstInfos): array { - $result = []; - - foreach ($classMap as $classInfo) { - $classSynopsis = $classInfo->getClassSynopsisDocument($classMap, $allConstInfos); - if ($classSynopsis !== null) { - $result[ClassInfo::getClassSynopsisFilename($classInfo->name) . ".xml"] = $classSynopsis; - } - } - - return $result; -} - -/** - * @param array $classMap - * $param iterable $allConstInfos - * @return array - */ -function replaceClassSynopses(string $targetDirectory, array $classMap, iterable $allConstInfos, bool $isVerify): array -{ - $existingClassSynopses = []; - - $classSynopses = []; - - $it = new RecursiveIteratorIterator( - new RecursiveDirectoryIterator($targetDirectory), - RecursiveIteratorIterator::LEAVES_ONLY - ); - - foreach ($it as $file) { - $pathName = $file->getPathName(); - if (!preg_match('/\.xml$/i', $pathName)) { - continue; - } - - $xml = file_get_contents($pathName); - if ($xml === false) { - continue; - } - - if (stripos($xml, "formatOutput = false; - $doc->preserveWhiteSpace = true; - $doc->validateOnParse = true; - $success = $doc->loadXML($replacedXml); - if (!$success) { - echo "Failed opening $pathName\n"; - continue; - } - - $classSynopsisElements = []; - foreach ($doc->getElementsByTagName("classsynopsis") as $element) { - $classSynopsisElements[] = $element; - } - - foreach ($classSynopsisElements as $classSynopsis) { - if (!$classSynopsis instanceof DOMElement) { - continue; - } - - $firstChild = $classSynopsis->firstElementChild; - if ($firstChild === null) { - continue; - } - $firstChild = $firstChild->firstElementChild; - if ($firstChild === null) { - continue; - } - $className = $firstChild->textContent; - if (!isset($classMap[$className])) { - continue; - } - - $existingClassSynopses[$className] = $className; - - $classInfo = $classMap[$className]; - - $newClassSynopsis = $classInfo->getClassSynopsisElement($doc, $classMap, $allConstInfos); - if ($newClassSynopsis === null) { - continue; - } - - // Check if there is any change - short circuit if there is not any. - - if (replaceAndCompareXmls($doc, $classSynopsis, $newClassSynopsis)) { - continue; - } - - // Return the updated XML - - $replacedXml = $doc->saveXML(); - - $replacedXml = preg_replace( - [ - "/REPLACED-ENTITY-([A-Za-z0-9._{}%-]+?;)/", - '//i', - '//i', - '//i', - '//i', - '//i', - ], - [ - "&$1", - "", - "", - "", - "", - "", - ], - $replacedXml - ); - - $classSynopses[$pathName] = $replacedXml; - } - } - - if ($isVerify) { - $missingClassSynopses = array_diff_key($classMap, $existingClassSynopses); - foreach ($missingClassSynopses as $className => $info) { - /** @var ClassInfo $info */ - if (!$info->isUndocumentable) { - echo "Warning: Missing class synopsis for $className\n"; - } - } - } - - return $classSynopses; -} - -function getReplacedSynopsisXml(string $xml): string -{ - return preg_replace( - [ - "/&([A-Za-z0-9._{}%-]+?;)/", - "/<(\/)*xi:([A-Za-z]+?)/" - ], - [ - "REPLACED-ENTITY-$1", - "<$1XI$2", - ], - $xml - ); -} - -/** - * @param array $funcMap - * @param array $aliasMap - * @return array - */ -function generateMethodSynopses(array $funcMap, array $aliasMap): array { - $result = []; - - foreach ($funcMap as $funcInfo) { - $methodSynopsis = $funcInfo->getMethodSynopsisDocument($funcMap, $aliasMap); - if ($methodSynopsis !== null) { - $result[$funcInfo->name->getMethodSynopsisFilename() . ".xml"] = $methodSynopsis; - } - } - - return $result; -} - -/** - * @param array $funcMap - * @param array $aliasMap - * @return array - */ -function replaceMethodSynopses(string $targetDirectory, array $funcMap, array $aliasMap, bool $isVerify): array { - $existingMethodSynopses = []; - $methodSynopses = []; - - $it = new RecursiveIteratorIterator( - new RecursiveDirectoryIterator($targetDirectory), - RecursiveIteratorIterator::LEAVES_ONLY - ); - - foreach ($it as $file) { - $pathName = $file->getPathName(); - if (!preg_match('/\.xml$/i', $pathName)) { - continue; - } - - $xml = file_get_contents($pathName); - if ($xml === false) { - continue; - } - - if ($isVerify) { - $matches = []; - preg_match("/\s*([\w:]+)\s*<\/refname>\s*\s*&Alias;\s*<(?:function|methodname)>\s*([\w:]+)\s*<\/(?:function|methodname)>\s*<\/refpurpose>/i", $xml, $matches); - $aliasName = $matches[1] ?? null; - $alias = $funcMap[$aliasName] ?? null; - $funcName = $matches[2] ?? null; - $func = $funcMap[$funcName] ?? null; - - if ($alias && - !$alias->isUndocumentable && - ($func === null || $func->alias === null || $func->alias->__toString() !== $aliasName) && - ($alias->alias === null || $alias->alias->__toString() !== $funcName) - ) { - echo "Warning: $aliasName()" . ($alias->alias ? " is an alias of " . $alias->alias->__toString() . "(), but it" : "") . " is incorrectly documented as an alias for $funcName()\n"; - } - - $matches = []; - preg_match("/<(?:para|simpara)>\s*(?:&info.function.alias;|&info.method.alias;|&Alias;)\s+<(?:function|methodname)>\s*([\w:]+)\s*<\/(?:function|methodname)>/i", $xml, $matches); - $descriptionFuncName = $matches[1] ?? null; - $descriptionFunc = $funcMap[$descriptionFuncName] ?? null; - if ($descriptionFunc && $funcName !== $descriptionFuncName) { - echo "Warning: Alias in the method synopsis description of $pathName doesn't match the alias in the \n"; - } - - if ($aliasName) { - $existingMethodSynopses[$aliasName] = $aliasName; - } - } - - if (stripos($xml, "formatOutput = false; - $doc->preserveWhiteSpace = true; - $doc->validateOnParse = true; - $success = $doc->loadXML($replacedXml); - if (!$success) { - echo "Failed opening $pathName\n"; - continue; - } - - $methodSynopsisElements = []; - foreach ($doc->getElementsByTagName("constructorsynopsis") as $element) { - $methodSynopsisElements[] = $element; - } - foreach ($doc->getElementsByTagName("destructorsynopsis") as $element) { - $methodSynopsisElements[] = $element; - } - foreach ($doc->getElementsByTagName("methodsynopsis") as $element) { - $methodSynopsisElements[] = $element; - } - - foreach ($methodSynopsisElements as $methodSynopsis) { - if (!$methodSynopsis instanceof DOMElement) { - continue; - } - - $list = $methodSynopsis->getElementsByTagName("methodname"); - $item = $list->item(0); - if (!$item instanceof DOMElement) { - continue; - } - $funcName = $item->textContent; - if (!isset($funcMap[$funcName])) { - continue; - } - - $funcInfo = $funcMap[$funcName]; - $existingMethodSynopses[$funcInfo->name->__toString()] = $funcInfo->name->__toString(); - - $newMethodSynopsis = $funcInfo->getMethodSynopsisElement($funcMap, $aliasMap, $doc); - if ($newMethodSynopsis === null) { - continue; - } - - // Retrieve current signature - - $params = []; - $list = $methodSynopsis->getElementsByTagName("methodparam"); - foreach ($list as $i => $item) { - if (!$item instanceof DOMElement) { - continue; - } - - $paramList = $item->getElementsByTagName("parameter"); - if ($paramList->count() !== 1) { - continue; - } - - $paramName = $paramList->item(0)->textContent; - $paramTypes = []; - - $paramList = $item->getElementsByTagName("type"); - foreach ($paramList as $type) { - if (!$type instanceof DOMElement) { - continue; - } - - $paramTypes[] = $type->textContent; - } - - $params[$paramName] = ["index" => $i, "type" => $paramTypes]; - } - - // Check if there is any change - short circuit if there is not any. - - if (replaceAndCompareXmls($doc, $methodSynopsis, $newMethodSynopsis)) { - continue; - } - - // Update parameter references - - $paramList = $doc->getElementsByTagName("parameter"); - /** @var DOMElement $paramElement */ - foreach ($paramList as $paramElement) { - if ($paramElement->parentNode && $paramElement->parentNode->nodeName === "methodparam") { - continue; - } - - $name = $paramElement->textContent; - if (!isset($params[$name])) { - continue; - } - - $index = $params[$name]["index"]; - if (!isset($funcInfo->args[$index])) { - continue; - } - - $paramElement->textContent = $funcInfo->args[$index]->name; - } - - // Return the updated XML - - $replacedXml = $doc->saveXML(); - - $replacedXml = preg_replace( - [ - "/REPLACED-ENTITY-([A-Za-z0-9._{}%-]+?;)/", - '//i', - '//i', - ], - [ - "&$1", - "", - "", - ], - $replacedXml - ); - - $methodSynopses[$pathName] = $replacedXml; - } - } - - if ($isVerify) { - $missingMethodSynopses = array_diff_key($funcMap, $existingMethodSynopses); - foreach ($missingMethodSynopses as $functionName => $info) { - /** @var FuncInfo $info */ - if (!$info->isUndocumentable) { - echo "Warning: Missing method synopsis for $functionName()\n"; - } - } - } - - return $methodSynopses; -} - -function replaceAndCompareXmls(DOMDocument $doc, DOMElement $originalSynopsis, DOMElement $newSynopsis): bool -{ - $docComparator = new DOMDocument(); - $docComparator->preserveWhiteSpace = false; - $docComparator->formatOutput = true; - - $xml1 = $doc->saveXML($originalSynopsis); - $xml1 = getReplacedSynopsisXml($xml1); - $docComparator->loadXML($xml1); - $xml1 = $docComparator->saveXML(); - - $originalSynopsis->parentNode->replaceChild($newSynopsis, $originalSynopsis); - - $xml2 = $doc->saveXML($newSynopsis); - $xml2 = getReplacedSynopsisXml($xml2); - - $docComparator->loadXML($xml2); - $xml2 = $docComparator->saveXML(); - - return $xml1 === $xml2; -} - -function installPhpParser(string $version, string $phpParserDir) { - $lockFile = __DIR__ . "/PHP-Parser-install-lock"; - $lockFd = fopen($lockFile, 'w+'); - if (!flock($lockFd, LOCK_EX)) { - throw new Exception("Failed to acquire installation lock"); - } - - try { - // Check whether a parallel process has already installed PHP-Parser. - if (is_dir($phpParserDir)) { - return; - } - - $cwd = getcwd(); - chdir(__DIR__); - - $tarName = "v$version.tar.gz"; - passthru("wget https://github.com/nikic/PHP-Parser/archive/$tarName", $exit); - if ($exit !== 0) { - passthru("curl -LO https://github.com/nikic/PHP-Parser/archive/$tarName", $exit); - } - if ($exit !== 0) { - throw new Exception("Failed to download PHP-Parser tarball"); - } - if (!mkdir($phpParserDir)) { - throw new Exception("Failed to create directory $phpParserDir"); - } - passthru("tar xvzf $tarName -C PHP-Parser-$version --strip-components 1", $exit); - if ($exit !== 0) { - throw new Exception("Failed to extract PHP-Parser tarball"); - } - unlink(__DIR__ . "/$tarName"); - chdir($cwd); - } finally { - flock($lockFd, LOCK_UN); - @unlink($lockFile); - } -} - -function initPhpParser() { - static $isInitialized = false; - if ($isInitialized) { - return; - } - - if (!extension_loaded("tokenizer")) { - throw new Exception("The \"tokenizer\" extension is not available"); - } - - $isInitialized = true; - $version = "5.0.0alpha3"; - $phpParserDir = __DIR__ . "/PHP-Parser-$version"; - if (!is_dir($phpParserDir)) { - installPhpParser($version, $phpParserDir); - } - - spl_autoload_register(static function(string $class) use ($phpParserDir) { - if (strpos($class, "PhpParser\\") === 0) { - $fileName = $phpParserDir . "/lib/" . str_replace("\\", "/", $class) . ".php"; - require $fileName; - } - }); -} - -$optind = null; -$options = getopt( - "fh", - [ - "force-regeneration", "parameter-stats", "help", "verify", "generate-classsynopses", "replace-classsynopses", - "generate-methodsynopses", "replace-methodsynopses", "generate-optimizer-info" - ], - $optind -); - -$context = new Context; -$printParameterStats = isset($options["parameter-stats"]); -$verify = isset($options["verify"]); -$generateClassSynopses = isset($options["generate-classsynopses"]); -$replaceClassSynopses = isset($options["replace-classsynopses"]); -$generateMethodSynopses = isset($options["generate-methodsynopses"]); -$replaceMethodSynopses = isset($options["replace-methodsynopses"]); -$generateOptimizerInfo = isset($options["generate-optimizer-info"]); -$context->forceRegeneration = isset($options["f"]) || isset($options["force-regeneration"]); -$context->forceParse = $context->forceRegeneration || $printParameterStats || $verify || $generateClassSynopses || $generateOptimizerInfo || $replaceClassSynopses || $generateMethodSynopses || $replaceMethodSynopses; - -$targetSynopses = $argv[$argc - 1] ?? null; -if ($replaceClassSynopses && $targetSynopses === null) { - die("A target class synopsis directory must be provided for.\n"); -} - -if ($replaceMethodSynopses && $targetSynopses === null) { - die("A target method synopsis directory must be provided.\n"); -} - -if (isset($options["h"]) || isset($options["help"])) { - die("\nusage: gen_stub.php [ -f | --force-regeneration ] [ --generate-classsynopses ] [ --replace-classsynopses ] [ --generate-methodsynopses ] [ --replace-methodsynopses ] [ --parameter-stats ] [ --verify ] [ --generate-optimizer-info ] [ -h | --help ] [ name.stub.php | directory ] [ directory ]\n\n"); -} - -$fileInfos = []; -$locations = array_slice($argv, $optind) ?: ['.']; -foreach (array_unique($locations) as $location) { - if (is_file($location)) { - // Generate single file. - $fileInfo = processStubFile($location, $context); - if ($fileInfo) { - $fileInfos[] = $fileInfo; - } - } else if (is_dir($location)) { - array_push($fileInfos, ...processDirectory($location, $context)); - } else { - echo "$location is neither a file nor a directory.\n"; - exit(1); - } -} - -if ($printParameterStats) { - $parameterStats = []; - - foreach ($fileInfos as $fileInfo) { - foreach ($fileInfo->getAllFuncInfos() as $funcInfo) { - foreach ($funcInfo->args as $argInfo) { - if (!isset($parameterStats[$argInfo->name])) { - $parameterStats[$argInfo->name] = 0; - } - $parameterStats[$argInfo->name]++; - } - } - } - - arsort($parameterStats); - echo json_encode($parameterStats, JSON_PRETTY_PRINT), "\n"; -} - -/** @var array $classMap */ -$classMap = []; -/** @var array $funcMap */ -$funcMap = []; -/** @var array $aliasMap */ -$aliasMap = []; - -foreach ($fileInfos as $fileInfo) { - foreach ($fileInfo->getAllFuncInfos() as $funcInfo) { - $funcMap[$funcInfo->name->__toString()] = $funcInfo; - - // TODO: Don't use aliasMap for methodsynopsis? - if ($funcInfo->aliasType === "alias") { - $aliasMap[$funcInfo->alias->__toString()] = $funcInfo; - } - } - - foreach ($fileInfo->classInfos as $classInfo) { - $classMap[$classInfo->name->__toString()] = $classInfo; - } -} - -if ($verify) { - $errors = []; - - foreach ($funcMap as $aliasFunc) { - if (!$aliasFunc->alias) { - continue; - } - - if (!isset($funcMap[$aliasFunc->alias->__toString()])) { - $errors[] = "Aliased function {$aliasFunc->alias}() cannot be found"; - continue; - } - - if (!$aliasFunc->verify) { - continue; - } - - $aliasedFunc = $funcMap[$aliasFunc->alias->__toString()]; - $aliasedArgs = $aliasedFunc->args; - $aliasArgs = $aliasFunc->args; - - if ($aliasFunc->isInstanceMethod() !== $aliasedFunc->isInstanceMethod()) { - if ($aliasFunc->isInstanceMethod()) { - $aliasedArgs = array_slice($aliasedArgs, 1); - } - - if ($aliasedFunc->isInstanceMethod()) { - $aliasArgs = array_slice($aliasArgs, 1); - } - } - - array_map( - function(?ArgInfo $aliasArg, ?ArgInfo $aliasedArg) use ($aliasFunc, $aliasedFunc, &$errors) { - if ($aliasArg === null) { - assert($aliasedArg !== null); - $errors[] = "{$aliasFunc->name}(): Argument \$$aliasedArg->name of aliased function {$aliasedFunc->name}() is missing"; - return null; - } - - if ($aliasedArg === null) { - $errors[] = "{$aliasedFunc->name}(): Argument \$$aliasArg->name of alias function {$aliasFunc->name}() is missing"; - return null; - } - - if ($aliasArg->name !== $aliasedArg->name) { - $errors[] = "{$aliasFunc->name}(): Argument \$$aliasArg->name and argument \$$aliasedArg->name of aliased function {$aliasedFunc->name}() must have the same name"; - return null; - } - - if ($aliasArg->type != $aliasedArg->type) { - $errors[] = "{$aliasFunc->name}(): Argument \$$aliasArg->name and argument \$$aliasedArg->name of aliased function {$aliasedFunc->name}() must have the same type"; - } - - if ($aliasArg->defaultValue !== $aliasedArg->defaultValue) { - $errors[] = "{$aliasFunc->name}(): Argument \$$aliasArg->name and argument \$$aliasedArg->name of aliased function {$aliasedFunc->name}() must have the same default value"; - } - }, - $aliasArgs, $aliasedArgs - ); - - $aliasedReturn = $aliasedFunc->return; - $aliasReturn = $aliasFunc->return; - - if (!$aliasedFunc->name->isConstructor() && !$aliasFunc->name->isConstructor()) { - $aliasedReturnType = $aliasedReturn->type ?? $aliasedReturn->phpDocType; - $aliasReturnType = $aliasReturn->type ?? $aliasReturn->phpDocType; - if ($aliasReturnType != $aliasedReturnType) { - $errors[] = "{$aliasFunc->name}() and {$aliasedFunc->name}() must have the same return type"; - } - } - - $aliasedPhpDocReturnType = $aliasedReturn->phpDocType; - $aliasPhpDocReturnType = $aliasReturn->phpDocType; - if ($aliasedPhpDocReturnType != $aliasPhpDocReturnType && $aliasedPhpDocReturnType != $aliasReturn->type && $aliasPhpDocReturnType != $aliasedReturn->type) { - $errors[] = "{$aliasFunc->name}() and {$aliasedFunc->name}() must have the same PHPDoc return type"; - } - } - - echo implode("\n", $errors); - if (!empty($errors)) { - echo "\n"; - exit(1); - } -} - -if ($generateClassSynopses) { - $classSynopsesDirectory = getcwd() . "/classsynopses"; - - $classSynopses = generateClassSynopses($classMap, $context->allConstInfos); - if (!empty($classSynopses)) { - if (!file_exists($classSynopsesDirectory)) { - mkdir($classSynopsesDirectory); - } - - foreach ($classSynopses as $filename => $content) { - if (file_put_contents("$classSynopsesDirectory/$filename", $content)) { - echo "Saved $filename\n"; - } - } - } -} - -if ($replaceClassSynopses) { - $classSynopses = replaceClassSynopses($targetSynopses, $classMap, $context->allConstInfos, $verify); - - foreach ($classSynopses as $filename => $content) { - if (file_put_contents($filename, $content)) { - echo "Saved $filename\n"; - } - } -} - -if ($generateMethodSynopses) { - $methodSynopsesDirectory = getcwd() . "/methodsynopses"; - - $methodSynopses = generateMethodSynopses($funcMap, $aliasMap); - if (!empty($methodSynopses)) { - if (!file_exists($methodSynopsesDirectory)) { - mkdir($methodSynopsesDirectory); - } - - foreach ($methodSynopses as $filename => $content) { - if (file_put_contents("$methodSynopsesDirectory/$filename", $content)) { - echo "Saved $filename\n"; - } - } - } -} - -if ($replaceMethodSynopses) { - $methodSynopses = replaceMethodSynopses($targetSynopses, $funcMap, $aliasMap, $verify); - - foreach ($methodSynopses as $filename => $content) { - if (file_put_contents($filename, $content)) { - echo "Saved $filename\n"; - } - } -} - -if ($generateOptimizerInfo) { - $filename = dirname(__FILE__, 2) . "/Zend/Optimizer/zend_func_infos.h"; - $optimizerInfo = generateOptimizerInfo($funcMap); - - if (file_put_contents($filename, $optimizerInfo)) { - echo "Saved $filename\n"; - } -} diff --git a/scripts/run-docker-tests.sh b/scripts/run-docker-tests.sh index a0e33d6fa..deaf8362d 100755 --- a/scripts/run-docker-tests.sh +++ b/scripts/run-docker-tests.sh @@ -22,3 +22,5 @@ run_tests "8.2" run_tests "8.2-zts" run_tests "8.3" run_tests "8.3-zts" +run_tests "8.4" +run_tests "8.4-zts" diff --git a/scripts/setup b/scripts/setup new file mode 100755 index 000000000..950ddc5ef --- /dev/null +++ b/scripts/setup @@ -0,0 +1,16 @@ +#!/bin/bash + +set -xe + +declare -a PHP_VERSIONS=("8.4" "8.3" "8.2") + +mkdir -p php + +./scripts/compile-libuv.sh +./scripts/compile-cpp-driver.sh "scylladb" +./scripts/compile-cpp-driver.sh "datastax" + +for version in "${PHP_VERSIONS[@]}" +do + ./scripts/compile-php.sh -o "$(pwd)/php" -v "$version" -s -d +done diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index b6a7fe3c5..afe269a17 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,6 +1,7 @@ add_library(src STATIC) add_library(ext_scylladb::src ALIAS src) -scylladb_php_library(src OFF ${PHP_SCYLLADB_OPTIMISE_FOR_CURRENT_MACHINE} ON) +scylladb_php_library(src OFF "${CPU_TYPE}" "${ENABLE_LTO}") + target_sources( src diff --git a/src/Cluster/CMakeLists.txt b/src/Cluster/CMakeLists.txt index 8334e5e91..0086231d5 100644 --- a/src/Cluster/CMakeLists.txt +++ b/src/Cluster/CMakeLists.txt @@ -1,6 +1,7 @@ add_library(cluster_builder STATIC BuilderHandlers.h) add_library(ext_scylladb::cluster::builder ALIAS cluster_builder) -scylladb_php_library(cluster_builder OFF ${PHP_SCYLLADB_OPTIMISE_FOR_CURRENT_MACHINE} ON) + +scylladb_php_library(cluster_builder OFF "${CPU_TYPE}" "${ENABLE_LTO}") target_sources( cluster_builder diff --git a/src/Cluster/Cluster.cpp b/src/Cluster/Cluster.cpp index dd4d396e9..23bd44c68 100644 --- a/src/Cluster/Cluster.cpp +++ b/src/Cluster/Cluster.cpp @@ -27,4 +27,4 @@ END_EXTERN_C() void php_driver_define_Cluster() { php_driver_cluster_ce = register_class_Cassandra_Cluster(); -} \ No newline at end of file +} diff --git a/src/Database/CMakeLists.txt b/src/Database/CMakeLists.txt index a03ba95ce..a88315be0 100644 --- a/src/Database/CMakeLists.txt +++ b/src/Database/CMakeLists.txt @@ -1,6 +1,8 @@ add_library(database STATIC) add_library(ext_scylladb::database ALIAS database) -scylladb_php_library(database OFF ${PHP_SCYLLADB_OPTIMISE_FOR_CURRENT_MACHINE} ON) + +scylladb_php_library(database OFF "${CPU_TYPE}" "${ENABLE_LTO}") + target_sources( database diff --git a/src/DateTime/CMakeLists.txt b/src/DateTime/CMakeLists.txt index 8615a659c..f556cb373 100644 --- a/src/DateTime/CMakeLists.txt +++ b/src/DateTime/CMakeLists.txt @@ -1,6 +1,7 @@ add_library(datetime STATIC) add_library(ext_scylladb::datetime ALIAS datetime) -scylladb_php_library(datetime OFF ${PHP_SCYLLADB_OPTIMISE_FOR_CURRENT_MACHINE} ON) +scylladb_php_library(datetime OFF "${CPU_TYPE}" "${ENABLE_LTO}") + target_sources( datetime diff --git a/src/Exception/CMakeLists.txt b/src/Exception/CMakeLists.txt index 81724d9b5..6c4739f87 100644 --- a/src/Exception/CMakeLists.txt +++ b/src/Exception/CMakeLists.txt @@ -1,6 +1,7 @@ add_library(exceptions STATIC) add_library(ext_scylladb::exceptions ALIAS exceptions) -scylladb_php_library(exceptions OFF ${PHP_SCYLLADB_OPTIMISE_FOR_CURRENT_MACHINE} ON) +scylladb_php_library(exceptions OFF "${CPU_TYPE}" "${ENABLE_LTO}") + target_sources( exceptions diff --git a/src/Numbers/CMakeLists.txt b/src/Numbers/CMakeLists.txt index 5cad5efeb..3267f9155 100644 --- a/src/Numbers/CMakeLists.txt +++ b/src/Numbers/CMakeLists.txt @@ -1,6 +1,7 @@ add_library(numbers STATIC) add_library(ext_scylladb::numbers ALIAS numbers) -scylladb_php_library(numbers OFF ${PHP_SCYLLADB_OPTIMISE_FOR_CURRENT_MACHINE} ON) +scylladb_php_library(numbers OFF "${CPU_TYPE}" "${ENABLE_LTO}") + target_sources( numbers diff --git a/src/RetryPolicy/CMakeLists.txt b/src/RetryPolicy/CMakeLists.txt index 713b259c9..7186ba14d 100644 --- a/src/RetryPolicy/CMakeLists.txt +++ b/src/RetryPolicy/CMakeLists.txt @@ -1,6 +1,7 @@ add_library(retry_policy STATIC) add_library(ext_scylladb::retry_policy ALIAS retry_policy) -scylladb_php_library(retry_policy OFF ${PHP_SCYLLADB_OPTIMISE_FOR_CURRENT_MACHINE} ON) +scylladb_php_library(retry_policy OFF "${CPU_TYPE}" "${ENABLE_LTO}") + target_sources( retry_policy diff --git a/src/SSLOptions/CMakeLists.txt b/src/SSLOptions/CMakeLists.txt index 24c694e8d..b34bb6e0d 100644 --- a/src/SSLOptions/CMakeLists.txt +++ b/src/SSLOptions/CMakeLists.txt @@ -1,6 +1,6 @@ add_library(ssl_options STATIC) add_library(ext_scylladb::ssl_options ALIAS ssl_options) -scylladb_php_library(ssl_options OFF ${PHP_SCYLLADB_OPTIMISE_FOR_CURRENT_MACHINE} ON) +scylladb_php_library(ssl_options OFF "${CPU_TYPE}" "${ENABLE_LTO}") target_sources( ssl_options diff --git a/src/TimestampGenerator/CMakeLists.txt b/src/TimestampGenerator/CMakeLists.txt index e1806aee4..bd958b5cb 100644 --- a/src/TimestampGenerator/CMakeLists.txt +++ b/src/TimestampGenerator/CMakeLists.txt @@ -1,6 +1,6 @@ add_library(timestamp_generator STATIC) add_library(ext_scylladb::timestamp_generator ALIAS timestamp_generator) -scylladb_php_library(timestamp_generator OFF ${PHP_SCYLLADB_OPTIMISE_FOR_CURRENT_MACHINE} ON) +scylladb_php_library(timestamp_generator OFF "${CPU_TYPE}" "${ENABLE_LTO}") target_sources( timestamp_generator diff --git a/src/Type/CMakeLists.txt b/src/Type/CMakeLists.txt index 7c94ae120..49ed94480 100644 --- a/src/Type/CMakeLists.txt +++ b/src/Type/CMakeLists.txt @@ -1,7 +1,7 @@ add_library(type STATIC) add_library(ext_scylladb::type ALIAS type) +scylladb_php_library(type OFF "${CPU_TYPE}" "${ENABLE_LTO}") -scylladb_php_library(type OFF ${PHP_SCYLLADB_OPTIMISE_FOR_CURRENT_MACHINE} ON) target_sources( type diff --git a/php_driver.cpp b/src/php_driver.cpp similarity index 100% rename from php_driver.cpp rename to src/php_driver.cpp diff --git a/tests/phpunit.xml b/tests/phpunit.xml index 26b008bcf..82a8dfda0 100644 --- a/tests/phpunit.xml +++ b/tests/phpunit.xml @@ -5,9 +5,10 @@ colors="true" > - + + ./Unit diff --git a/util/CMakeLists.txt b/util/CMakeLists.txt index a962a85da..c37ca912a 100644 --- a/util/CMakeLists.txt +++ b/util/CMakeLists.txt @@ -1,7 +1,8 @@ add_library(util STATIC) add_library(ext_scylladb::utils ALIAS util) -scylladb_php_library(util OFF ${PHP_SCYLLADB_OPTIMISE_FOR_CURRENT_MACHINE} ON) +scylladb_php_library(util OFF "${CPU_TYPE}" "${ENABLE_LTO}") + target_sources( util diff --git a/version.h.in b/version.h.in index 8df52f223..4d9018eb8 100644 --- a/version.h.in +++ b/version.h.in @@ -1,4 +1,10 @@ #pragma once #define PHP_DRIVER_NAME "cassandra" -#define PHP_DRIVER_VERSION "@PHP_SCYLLADB_VERSION@" \ No newline at end of file +#define PHP_DRIVER_VERSION "@PHP_SCYLLADB_DRIVER_VERSION@" + +#define PACKAGE_NAME "scylladb" +#define PACKAGE_STRING "scylladb-@PHP_SCYLLADB_DRIVER_VERSION@" +#define PACKAGE_TARNAME "scylladb" +#define PACKAGE_VERSION "@PHP_SCYLLADB_DRIVER_VERSION@" +#define PACKAGE_URL "https://github.com/he4rt/scylladb-php-driver" \ No newline at end of file