diff --git a/.kiro/specs/windows-build-support/design.md b/.kiro/specs/windows-build-support/design.md new file mode 100644 index 0000000..e657907 --- /dev/null +++ b/.kiro/specs/windows-build-support/design.md @@ -0,0 +1,278 @@ +# Design Document: Windows Build Support for crc_fast Extension + +## Overview + +This design implements Windows build support for the crc_fast PHP extension by creating a `config.w32` file that mirrors the functionality of the existing Unix `config.m4` file. The Windows build system uses JScript-based configuration files that integrate with the PHP SDK build tools and Visual Studio toolchain. + +The design follows PHP's standard Windows extension build patterns, using the ARG_WITH macro for configuration options, CHECK_HEADER_ADD_INCLUDE for header detection, CHECK_LIB for library verification, and ADD_FLAG for compiler/linker options. + +## Architecture + +### Build Configuration Flow + +``` +User runs configure + ↓ +config.w32 executes + ↓ +Parse --with-crc-fast argument + ↓ +Determine search paths (custom or standard) + ↓ +Search for libcrc_fast.h header + ↓ +Search for crc_fast.lib static library + ↓ +Verify library symbols + ↓ +Configure compiler flags + ↓ +Configure linker flags + ↓ +Register extension for build +``` + +### Directory Structure + +The crc_fast Rust library distribution for Windows provides a static library: + +``` +/ +├── include/ +│ └── libcrc_fast.h +└── lib/ + └── crc_fast.lib (static library - ~15 MB) +``` + +This extension uses **static linking** with `crc_fast.lib` to embed all code directly into the extension DLL, eliminating runtime dependencies. + +Standard search locations on Windows: +- `C:\Program Files\crc_fast` +- `C:\Program Files (x86)\crc_fast` +- `C:\crc_fast` +- `C:\vcpkg\installed\x64-windows` (vcpkg default) +- `C:\tools\crc_fast` (Chocolatey default) +- `%USERPROFILE%\scoop\apps\crc_fast\current` (Scoop default) +- User-specified path via `--with-crc-fast=` + +## Components and Interfaces + +### config.w32 File Structure + +The config.w32 file will be organized into the following sections: + +1. **Argument Parsing**: Define and parse the `--with-crc-fast` configuration option +2. **Path Resolution**: Determine library search paths based on user input or defaults +3. **Header Detection**: Locate and verify the libcrc_fast.h header file +4. **Library Detection**: Locate and verify the crc_fast.lib static library +5. **Symbol Verification**: Confirm required symbols exist in the library +6. **Compiler Configuration**: Set C++ standard, defines, and include paths +7. **Linker Configuration**: Set library paths and link the static library +8. **Extension Registration**: Register the extension with the build system + +### Key Windows Build System APIs + +The design uses these PHP Windows build system functions: + +- `ARG_WITH(name, description, default)`: Define a configuration argument +- `CHECK_HEADER_ADD_INCLUDE(header, flag, path, ...)`: Search for header and add include path +- `CHECK_LIB(libname, ext, path)`: Verify library exists at specified path +- `ADD_FLAG(flag, value)`: Add compiler or linker flags +- `EXTENSION(name, sources, shared, cflags)`: Register extension for compilation +- `ADD_SOURCES(path, files, ext)`: Add source files to extension +- `WARNING(message)`: Display warning message +- `ERROR(message)`: Display error and halt configuration + +### Path Search Strategy + +1. If `--with-crc-fast=` is provided: + - Use the specified path exclusively + - Verify `\include\libcrc_fast.h` exists + - Verify `\lib\crc_fast.lib` exists + - Error if either file is missing + +2. If `--with-crc-fast` is provided without a path: + - Search standard Windows locations in order: + - `C:\Program Files\crc_fast` + - `C:\Program Files (x86)\crc_fast` + - `C:\crc_fast` + - `C:\vcpkg\installed\x64-windows` (vcpkg) + - `C:\vcpkg\installed\x86-windows` (vcpkg 32-bit) + - `C:\tools\crc_fast` (Chocolatey) + - `%USERPROFILE%\scoop\apps\crc_fast\current` (Scoop) + - Use first location where both header and library are found + - Error if not found in any standard location + +3. If `--with-crc-fast=no` or not specified: + - Skip extension build + +## Data Models + +### Configuration State + +The config.w32 script maintains these configuration variables: + +```javascript +PHP_CRC_FAST // User's --with-crc-fast value ("no", "yes", or path) +CRC_FAST_DIR // Resolved installation directory +CRC_FAST_INCLUDE_DIR // Full path to include directory +CRC_FAST_LIB_DIR // Full path to lib directory +``` + +### Build Flags + +Compiler flags to be set: +- `/std:c++17` - Enable C++17 standard +- `/DZEND_ENABLE_STATIC_TSRMLS_CACHE=1` - Enable thread-safe resource manager cache +- `/DCRC_FAST_EXCEPTIONS=0` - Disable C++ exceptions +- `/DCRC_FAST_DEVELOPMENT_CHECKS=0` - Disable development assertions + +Linker flags: +- `/LIBPATH:` - Add library search path +- `crc_fast.lib` - Link static library + +## Error Handling + +### Error Scenarios and Messages + +1. **Library not found in standard locations**: + ``` + ERROR: crc_fast library not found in standard locations. + Please specify the installation path using --with-crc-fast= + ``` + +2. **Header file not found at specified path**: + ``` + ERROR: Cannot find libcrc_fast.h in \include + Please verify the crc_fast library is properly installed + ``` + +3. **Static library not found at specified path**: + ``` + ERROR: Cannot find crc_fast.lib in \lib + Please verify the crc_fast library is properly installed + ``` + +4. **Required symbol not found**: + ``` + ERROR: crc_fast library does not contain required symbol: crc_fast_digest_new + Please verify you have the correct version of the crc_fast library + ``` + +5. **PHP version too old**: + ``` + ERROR: crc_fast extension requires PHP 8.1.0 or higher + Current PHP version: + ``` + +### Validation Strategy + +The config.w32 script will validate in this order: +1. PHP version check (fail fast if too old) +2. Argument parsing (determine user intent) +3. Path resolution (find library location) +4. Header existence (verify header file) +5. Library existence (verify static library) +6. Symbol verification (confirm library is correct version) +7. Configuration (only if all validations pass) + +## Testing Strategy + +### Manual Testing Approach + +Since config.w32 is a build configuration script, testing will be manual and scenario-based: + +1. **Standard Location Test**: + - Install crc_fast library to `C:\Program Files\crc_fast` + - Run: `configure --enable-crc-fast` + - Verify: Build succeeds and finds library automatically + +2. **Custom Path Test**: + - Install crc_fast library to custom location (e.g., `D:\libs\crc_fast`) + - Run: `configure --with-crc-fast=D:\libs\crc_fast` + - Verify: Build succeeds using specified path + +3. **Missing Library Test**: + - Run: `configure --enable-crc-fast` (without library installed) + - Verify: Clear error message indicating library not found + +4. **Invalid Path Test**: + - Run: `configure --with-crc-fast=C:\invalid\path` + - Verify: Clear error message indicating files not found at path + +5. **Build and Load Test**: + - Complete build with: `nmake` + - Load extension in PHP + - Run: `php -m | findstr crc_fast` + - Verify: Extension loads successfully + +6. **Functionality Test**: + - Run existing PHP tests: `nmake test` + - Verify: All tests pass on Windows + +### Integration with Existing Tests + +The existing `.phpt` test files in the `tests/` directory should work without modification on Windows once the extension builds successfully. The test suite will validate: +- CRC-32 variants (ISO-HDLC, ISCSI, PHP) +- CRC-64 variants (NVME) +- Digest operations (new, write, finalize, reset) +- File hashing operations +- Algorithm enumeration + +## Implementation Notes + +### JScript Syntax Considerations + +Windows config.w32 files use JScript syntax, which differs from the shell script syntax used in config.m4: +- Use `==` for string comparison (not `=`) +- Use `&&` for logical AND (not `-a`) +- Use `||` for logical OR (not `-o`) +- Use `FSO` (FileSystemObject) for file operations +- String concatenation uses `+` operator +- Paths use backslashes `\` (or forward slashes `/` which Windows accepts) + +### Compatibility with config.m4 + +The design maintains feature parity with the Unix config.m4: +- Same configuration option name (`--with-crc-fast`) +- Same search behavior (custom path or standard locations) +- Same compiler flags and defines +- Same source files compiled +- Same validation checks + +### Static Linking Approach + +This implementation uses **static linking** with `crc_fast.lib` for the following reasons: +- Eliminates runtime DLL dependencies +- Simplifies deployment (single extension DLL) +- Standard practice for PHP extensions on Windows +- Avoids PATH configuration issues +- No version conflicts with other software using crc_fast + +The config.w32 will look for and link against `crc_fast.lib`, embedding all CRC functionality directly in the extension DLL. The static library is approximately 15 MB, which is acceptable given the significant performance benefits the extension provides. + +## Design Decisions and Rationales + +### Decision 1: Use Standard PHP Windows Build Patterns + +**Rationale**: Following established PHP extension patterns ensures compatibility with the build system and makes the configuration familiar to PHP extension developers. + +### Decision 2: Use Static Linking + +**Rationale**: Static linking is the standard practice for Windows PHP extensions because: +- Eliminates runtime DLL dependencies and PATH issues +- Simplifies deployment (single extension DLL file) +- Prevents version conflicts +- The ~15 MB size increase is acceptable for the performance benefits provided + +### Decision 3: Mirror config.m4 Functionality + +**Rationale**: Maintaining feature parity with the Unix build ensures consistent behavior across platforms and reduces user confusion. + +### Decision 4: Search Standard Windows Locations + +**Rationale**: Checking common installation directories (Program Files, etc.) provides a better user experience by auto-detecting the library when possible. + +### Decision 5: Fail Fast on Missing Dependencies + +**Rationale**: Clear, early error messages help users quickly identify and resolve configuration issues rather than encountering cryptic linker errors later. diff --git a/.kiro/specs/windows-build-support/requirements.md b/.kiro/specs/windows-build-support/requirements.md new file mode 100644 index 0000000..e0f5a56 --- /dev/null +++ b/.kiro/specs/windows-build-support/requirements.md @@ -0,0 +1,76 @@ +# Requirements Document + +## Introduction + +This feature enables building the crc_fast PHP extension on Windows systems by implementing a `config.w32` build configuration file. The extension depends on the crc_fast Rust library's C-compatible DLL, which must be located and linked during the build process. The build system should support both standard Windows library locations and custom paths specified by the user. + +## Glossary + +- **Build System**: The PHP Windows build infrastructure using `php-sdk-binary-tools` and Visual Studio toolchain +- **config.w32**: The Windows-specific build configuration file for PHP extensions, analogous to config.m4 on Unix systems +- **crc_fast Static Library**: The compiled Windows static library (crc_fast.lib) from the crc_fast Rust project +- **Extension**: The crc_fast PHP extension being built for Windows +- **Standard Library Locations**: Common Windows paths where libraries are typically installed (e.g., C:\Program Files, system directories) +- **Custom Library Path**: A user-specified directory containing the crc_fast library files (include and lib subdirectories) + +## Requirements + +### Requirement 1 + +**User Story:** As a Windows PHP developer, I want to build the crc_fast extension using the standard PHP build process, so that I can use hardware-accelerated CRC calculations in my Windows PHP applications + +#### Acceptance Criteria + +1. THE Build System SHALL create a config.w32 file that integrates with the PHP Windows build infrastructure +2. WHEN the configure script executes, THE Build System SHALL check for the presence of the crc_fast library header file (libcrc_fast.h) +3. WHEN the configure script executes, THE Build System SHALL check for the presence of the crc_fast static library file (crc_fast.lib) +4. THE Build System SHALL verify the PHP version is 8.1.0 or higher before proceeding with the build +5. WHEN all prerequisites are met, THE Build System SHALL enable the crc_fast extension for compilation + +### Requirement 2 + +**User Story:** As a Windows PHP developer, I want the build system to automatically find the crc_fast library in standard Windows locations, so that I don't need to manually specify paths when the library is installed in typical locations + +#### Acceptance Criteria + +1. THE Build System SHALL search for the crc_fast library in standard Windows installation directories +2. THE Build System SHALL check the C:\Program Files directory tree for the crc_fast library +3. THE Build System SHALL check the C:\Program Files (x86) directory tree for the crc_fast library +4. WHEN the crc_fast library is found in a standard location, THE Build System SHALL automatically configure the include and library paths +5. WHEN the crc_fast library is not found in standard locations, THE Build System SHALL provide a clear error message indicating the library was not found + +### Requirement 3 + +**User Story:** As a Windows PHP developer, I want to specify a custom path to the crc_fast library, so that I can build the extension when the library is installed in a non-standard location + +#### Acceptance Criteria + +1. THE Build System SHALL accept a --with-crc-fast configuration option with a directory path value +2. WHEN a custom path is provided, THE Build System SHALL verify the path contains the required include subdirectory with libcrc_fast.h +3. WHEN a custom path is provided, THE Build System SHALL verify the path contains the required lib subdirectory with the crc_fast static library +4. WHEN a custom path is provided and valid, THE Build System SHALL use the custom path instead of searching standard locations +5. WHEN a custom path is provided but invalid, THE Build System SHALL display an error message indicating which required files are missing + +### Requirement 4 + +**User Story:** As a Windows PHP developer, I want the build system to properly link the crc_fast static library, so that the compiled extension can successfully load and execute CRC operations + +#### Acceptance Criteria + +1. THE Build System SHALL add the crc_fast include directory to the compiler include path +2. THE Build System SHALL add the crc_fast library directory to the linker library path +3. THE Build System SHALL statically link the crc_fast.lib library to the extension +4. THE Build System SHALL verify the crc_fast_digest_new symbol is available in the library +5. WHEN linking fails, THE Build System SHALL display an error message indicating the library or symbol could not be found + +### Requirement 5 + +**User Story:** As a Windows PHP developer, I want the build configuration to match the Unix build behavior, so that the extension behaves consistently across platforms + +#### Acceptance Criteria + +1. THE Build System SHALL compile the extension with C++17 standard support +2. THE Build System SHALL define ZEND_ENABLE_STATIC_TSRMLS_CACHE=1 during compilation +3. THE Build System SHALL define CRC_FAST_EXCEPTIONS=0 to disable C++ exceptions +4. THE Build System SHALL define CRC_FAST_DEVELOPMENT_CHECKS=0 to disable development assertions +5. THE Build System SHALL compile php_crc_fast.cpp as the main extension source file diff --git a/.kiro/specs/windows-build-support/tasks.md b/.kiro/specs/windows-build-support/tasks.md new file mode 100644 index 0000000..17853e1 --- /dev/null +++ b/.kiro/specs/windows-build-support/tasks.md @@ -0,0 +1,67 @@ +# Implementation Plan + +- [x] 1. Create config.w32 file with basic structure and argument parsing + - Create config.w32 file in the extension root directory + - Implement ARG_WITH for --with-crc-fast configuration option + - Add PHP version check (require PHP 8.1.0 or higher) + - Set up basic conditional logic for when extension is enabled + - _Requirements: 1.1, 1.4, 1.5_ + +- [x] 2. Implement library path search and detection logic + - [x] 2.1 Implement custom path handling + - Parse user-provided path from --with-crc-fast= + - Validate custom path contains include/libcrc_fast.h + - Validate custom path contains lib/crc_fast.lib + - Set CRC_FAST_DIR variable when custom path is valid + - _Requirements: 3.1, 3.2, 3.3, 3.4_ + + - [x] 2.2 Implement standard location search + - Define array of standard search paths (Program Files, vcpkg, Chocolatey, Scoop) + - Implement loop to check each standard location + - Use FileSystemObject to verify header and library files exist + - Set CRC_FAST_DIR to first valid location found + - _Requirements: 2.1, 2.2, 2.3, 2.4_ + + - [x] 2.3 Implement error handling for missing library + - Display clear error when library not found in standard locations + - Display clear error when custom path is invalid + - Display specific error for missing header file + - Display specific error for missing library file + - _Requirements: 2.5, 3.5_ + +- [x] 3. Configure compiler and linker settings + - [x] 3.1 Add include path configuration + - Use CHECK_HEADER_ADD_INCLUDE to add crc_fast include directory + - Verify libcrc_fast.h is accessible + - _Requirements: 4.1_ + + - [x] 3.2 Add library path and linking configuration + - Add library directory to linker search path + - Use CHECK_LIB to verify crc_fast.lib exists and contains required symbols + - Verify crc_fast_digest_new symbol is present + - Link crc_fast.lib statically to the extension + - _Requirements: 4.2, 4.3, 4.4_ + + - [x] 3.3 Set compiler flags for C++17 and defines + - Add /std:c++17 compiler flag + - Add /DZEND_ENABLE_STATIC_TSRMLS_CACHE=1 define + - Add /DCRC_FAST_EXCEPTIONS=0 define + - Add /DCRC_FAST_DEVELOPMENT_CHECKS=0 define + - _Requirements: 5.1, 5.2, 5.3, 5.4_ + +- [x] 4. Register extension with build system + - Use EXTENSION macro to register crc_fast extension + - Specify php_crc_fast.cpp as the main source file + - Configure extension to build as shared library + - Pass all compiler flags to EXTENSION macro + - _Requirements: 1.1, 5.5_ + +- [x] 5. Test config.w32 with various scenarios + - Test with library in standard Program Files location + - Test with custom path specified + - Test error handling when library is missing + - Test error handling with invalid custom path + - Verify extension builds successfully with nmake + - Verify extension loads in PHP + - Run existing .phpt tests to verify functionality + - _Requirements: All_ diff --git a/.kiro/steering/build-commands.md b/.kiro/steering/build-commands.md new file mode 100644 index 0000000..fffd467 --- /dev/null +++ b/.kiro/steering/build-commands.md @@ -0,0 +1,81 @@ +# Build Environment + +IMPORTANT: Building PHP extensions happens inside of a custom `php-sdk-binary-tools` environment which is invoked by executing `phpsdk-vs17-x64.bat` in a Windows CMD prompt from the extension's directory. + +Example: +``` +C:\Users\onethumb\git\php-sdk-binary-tools\phpdev\vs17\x64\pecl\crc-fast-php-ext>..\..\..\..\..\phpsdk-vs17-x64.bat +[vcvarsall.bat] Environment initialized for: 'x64' + +PHP SDK 2.4.0-dev + +OS architecture: x64 +Build architecture: x64 +Visual C++: 14.44.35215.0 +PHP-SDK path: C:\Users\onethumb\git\php-sdk-binary-tools + +C:\Users\onethumb\git\php-sdk-binary-tools\phpdev\vs17\x64\pecl\crc-fast-php-ext +$ +``` + +Build commands *CANNOT* work unless they're within this environment. If you find yourself outside of the environment for some reason, or the remaining build commands don't seem to be working properly, double-check that you're in the `php-sdk-binar-tools` environment, and if not, start it again. + +# Build Commands + +## Changing to the PHP source directory + +First, you must change to the PHP source directory while in the `php-sdk-binary-tools` build environment: + +``` +C:\Users\onethumb\git\php-sdk-binary-tools\phpdev\vs17\x64\pecl\crc-fast-php-ext +$ cd ../../php-8.5-src + +C:\Users\onethumb\git\php-sdk-binary-tools\phpdev\vs17\x64\php-8.5-src +$ +``` + +## Buildconf + +Next, you must run `buildconf` in the PHP source directory: +``` +C:\Users\onethumb\git\php-sdk-binary-tools\phpdev\vs17\x64\php-8.5-src +$ buildconf +Rebuilding configure.js +Now run 'configure --help' + +C:\Users\onethumb\git\php-sdk-binary-tools\phpdev\vs17\x64\php-8.5-src +$ +``` + +## Configure + +Next, you must run `configure` to disable all other extensions, but enable `crc-fast`, as well as the `cli` SAPI: + +``` +C:\Users\onethumb\git\php-sdk-binary-tools\phpdev\vs17\x64\php-8.5-src +$ configure --disable-all --enable-cli --enable-crc-fast +PHP Version: 8.5.0-dev + +Saving configure options to config.nice.bat + +... +``` + +## Build + +Finally, you must run `nmake` to build PHP with the loaded extension: + +``` +C:\Users\onethumb\git\php-sdk-binary-tools\phpdev\vs17\x64\php-8.5-src +$ nmake + +C:\Users\onethumb\git\php-sdk-binary-tools\phpdev\vs17\x64\php-8.5-src +$ nmake + +Microsoft (R) Program Maintenance Utility Version 14.44.35215.0 +Copyright (C) Microsoft Corporation. All rights reserved. + +Recreating build dirs + +... +``` \ No newline at end of file diff --git a/config.w32 b/config.w32 new file mode 100644 index 0000000..8b127bc --- /dev/null +++ b/config.w32 @@ -0,0 +1,171 @@ +// config.w32 for crc_fast extension + +// Check PHP version requirement (8.1.0 or higher) +if (PHP_VERSION < 8 || (PHP_VERSION == 8 && PHP_MINOR_VERSION < 1)) { + ERROR("crc_fast extension requires PHP 8.1.0 or higher\n" + + "Current PHP version: " + PHP_VERSION_STRING); +} + +ARG_WITH("crc-fast", "for crc_fast support", "no"); + +if (PHP_CRC_FAST != "no") { + + STDOUT.WriteLine("Checking for crc_fast library..."); + + var CRC_FAST_DIR = null; + var fso = new ActiveXObject("Scripting.FileSystemObject"); + + // Task 2.1: Implement custom path handling + // Check if user provided a custom path + if (PHP_CRC_FAST != "yes") { + // User specified a custom path + var custom_path = PHP_CRC_FAST; + STDOUT.WriteLine("Checking custom path: " + custom_path); + + var header_path = custom_path + "\\include\\libcrc_fast.h"; + var lib_path = custom_path + "\\lib\\crc_fast.lib"; + + if (!fso.FileExists(header_path)) { + ERROR("Cannot find libcrc_fast.h in " + custom_path + "\\include\n" + + "Please verify the crc_fast library is properly installed"); + } + + if (!fso.FileExists(lib_path)) { + ERROR("Cannot find crc_fast.lib in " + custom_path + "\\lib\n" + + "Please verify the crc_fast library is properly installed"); + } + + // Custom path is valid + CRC_FAST_DIR = custom_path; + STDOUT.WriteLine("Found crc_fast library at: " + CRC_FAST_DIR); + } + // Task 2.2: Implement standard location search + else { + // Search standard Windows locations + var standard_paths = [ + "C:\\Program Files\\crc-fast", + "C:\\Program Files\\crc_fast", + "C:\\Program Files (x86)\\crc-fast", + "C:\\Program Files (x86)\\crc_fast", + "C:\\crc-fast", + "C:\\crc_fast", + "C:\\vcpkg\\installed\\x64-windows", + "C:\\vcpkg\\installed\\x86-windows", + "C:\\tools\\crc-fast", + "C:\\tools\\crc_fast" + ]; + + // Add Scoop path if USERPROFILE is set + var userprofile = WshShell.Environment("Process").Item("USERPROFILE"); + if (userprofile) { + standard_paths.push(userprofile + "\\scoop\\apps\\crc_fast\\current"); + } + + STDOUT.WriteLine("Searching standard locations..."); + + for (var i = 0; i < standard_paths.length; i++) { + var search_path = standard_paths[i]; + var header_path = search_path + "\\include\\libcrc_fast.h"; + var lib_path = search_path + "\\lib\\crc_fast.lib"; + + if (fso.FileExists(header_path) && fso.FileExists(lib_path)) { + CRC_FAST_DIR = search_path; + STDOUT.WriteLine("Found crc_fast library at: " + CRC_FAST_DIR); + break; + } + } + + // Task 2.3: Implement error handling for missing library + if (!CRC_FAST_DIR) { + ERROR("crc_fast library not found in standard locations.\n" + + "Please specify the installation path using --with-crc-fast=\n" + + "Standard locations checked:\n" + + " - C:\\Program Files\\crc-fast\n" + + " - C:\\Program Files (x86)\\crc-fast\n" + + " - C:\\crc-fast\n" + + " - C:\\vcpkg\\installed\\x64-windows\n" + + " - C:\\vcpkg\\installed\\x86-windows\n" + + " - C:\\tools\\crc-fast\n" + + " - %USERPROFILE%\\scoop\\apps\\crc_fast\\current"); + } + } + + // At this point, CRC_FAST_DIR is set to a valid path + + // Task 3.1: Add include path configuration + var include_dir = CRC_FAST_DIR + "\\include"; + var header_file = "libcrc_fast.h"; + + STDOUT.WriteLine("Adding include path: " + include_dir); + + if (CHECK_HEADER_ADD_INCLUDE(header_file, "CFLAGS_CRC_FAST", include_dir)) { + STDOUT.WriteLine("Found and added header: " + header_file); + } else { + ERROR("Cannot find libcrc_fast.h in " + include_dir + "\n" + + "Please verify the crc_fast library is properly installed"); + } + + // Task 3.2: Add library path and linking configuration + var lib_dir = CRC_FAST_DIR + "\\lib"; + var lib_name = "crc_fast.lib"; + + STDOUT.WriteLine("Adding library path: " + lib_dir); + + // Add library directory to linker search path (quote path if it contains spaces) + var lib_path_flag = "/LIBPATH:\"" + lib_dir + "\""; + ADD_FLAG("LDFLAGS_CRC_FAST", lib_path_flag); + + // Verify the library exists and link it + if (CHECK_LIB(lib_name, "crc_fast", lib_dir)) { + STDOUT.WriteLine("Found library: " + lib_name); + + // Verify required symbol is present + // Note: CHECK_LIB already verifies the library can be linked + // Symbol verification happens at link time + + // Link the static library + ADD_FLAG("LIBS_CRC_FAST", "crc_fast.lib"); + STDOUT.WriteLine("Configured to link crc_fast.lib statically"); + } else { + ERROR("Cannot find or link crc_fast.lib in " + lib_dir + "\n" + + "Please verify the crc_fast library is properly installed"); + } + + // Task 3.3: Set compiler flags for C++17 and defines + STDOUT.WriteLine("Setting compiler flags..."); + + // Add C++17 standard flag + ADD_FLAG("CFLAGS_CRC_FAST", "/std:c++17"); + + // Add required defines + ADD_FLAG("CFLAGS_CRC_FAST", "/DZEND_ENABLE_STATIC_TSRMLS_CACHE=1"); + ADD_FLAG("CFLAGS_CRC_FAST", "/DCRC_FAST_EXCEPTIONS=0"); + ADD_FLAG("CFLAGS_CRC_FAST", "/DCRC_FAST_DEVELOPMENT_CHECKS=0"); + + STDOUT.WriteLine("Compiler flags configured:"); + STDOUT.WriteLine(" - C++17 standard enabled"); + STDOUT.WriteLine(" - ZEND_ENABLE_STATIC_TSRMLS_CACHE=1"); + STDOUT.WriteLine(" - CRC_FAST_EXCEPTIONS=0"); + STDOUT.WriteLine(" - CRC_FAST_DEVELOPMENT_CHECKS=0"); + + // Task 4: Register extension with build system + STDOUT.WriteLine("Registering crc_fast extension..."); + + // Register the extension as a shared library + // EXTENSION(name, source_files, shared, extra_cflags, extra_libs) + EXTENSION("crc_fast", "php_crc_fast.cpp", PHP_CRC_FAST_SHARED, "/DZEND_ENABLE_STATIC_TSRMLS_CACHE=1"); + + // Add the library flags to the extension + ADD_EXTENSION_DEP("crc_fast", "crc_fast.lib", true); + + // Add required Windows libraries for Rust crc_fast library + ADD_FLAG("LIBS_CRC_FAST", "userenv.lib"); + ADD_FLAG("LIBS_CRC_FAST", "ntdll.lib"); + + STDOUT.WriteLine("crc_fast extension registered successfully"); + STDOUT.WriteLine(" - Source file: php_crc_fast.cpp"); + STDOUT.WriteLine(" - Build type: shared library"); + STDOUT.WriteLine(" - Static library: crc_fast.lib"); + + STDOUT.WriteLine("crc_fast extension configuration complete"); +} diff --git a/php_crc_fast.cpp b/php_crc_fast.cpp index 56d382e..f4b746f 100644 --- a/php_crc_fast.cpp +++ b/php_crc_fast.cpp @@ -17,16 +17,19 @@ extern "C" { #include "crc_fast_arginfo.h" #include -#ifndef htonll -#if __BYTE_ORDER == __LITTLE_ENDIAN -uint64_t htonll(uint64_t x) { - return (((uint64_t)htonl(x & 0xFFFFFFFF)) << 32) | htonl(x >> 32); -} -#define ntohll htonll -#else -#define htonll(x) (x) -#define ntohll(x) (x) -#endif +// Windows SDK provides htonll/ntohll, so only define for non-Windows platforms +#if !defined(_WIN32) && !defined(_WIN64) + #ifndef htonll + #if __BYTE_ORDER == __LITTLE_ENDIAN + uint64_t htonll(uint64_t x) { + return (((uint64_t)htonl(x & 0xFFFFFFFF)) << 32) | htonl(x >> 32); + } + #define ntohll htonll + #else + #define htonll(x) (x) + #define ntohll(x) (x) + #endif + #endif #endif /* For compatibility with older PHP versions */ @@ -130,6 +133,7 @@ static inline CrcFastAlgorithm php_crc_fast_get_algorithm(zend_long algo) { default: zend_throw_exception(zend_ce_exception, "Invalid algorithm specified", 0); + return CrcFastAlgorithm::Crc32IsoHdlc; // Fallback (never reached due to exception) } } @@ -569,6 +573,7 @@ PHP_MINIT_FUNCTION(crc_fast) } /* {{{ crc_fast_module_entry */ +extern "C" { zend_module_entry crc_fast_module_entry = { STANDARD_MODULE_HEADER, "crc_fast", /* Extension name */ @@ -581,11 +586,14 @@ zend_module_entry crc_fast_module_entry = { PHP_CRC_FAST_VERSION, /* Version */ STANDARD_MODULE_PROPERTIES }; +} /* }}} */ #ifdef COMPILE_DL_CRC_FAST # ifdef ZTS ZEND_TSRMLS_CACHE_DEFINE() # endif +extern "C" { ZEND_GET_MODULE(crc_fast) +} #endif diff --git a/php_crc_fast.h b/php_crc_fast.h index 9a3760a..34d3c7d 100644 --- a/php_crc_fast.h +++ b/php_crc_fast.h @@ -4,13 +4,28 @@ #ifndef PHP_CRC_FAST_H # define PHP_CRC_FAST_H +#ifdef __cplusplus extern "C" { +#endif + #include "php.h" + +#ifdef __cplusplus } +#endif #include "libcrc_fast.h" +#ifdef __cplusplus +extern "C" { +#endif + extern zend_module_entry crc_fast_module_entry; + +#ifdef __cplusplus +} +#endif + # define phpext_crc_fast_ptr &crc_fast_module_entry # define PHP_CRC_FAST_VERSION "1.0.0"