Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
278 changes: 278 additions & 0 deletions .kiro/specs/windows-build-support/design.md
Original file line number Diff line number Diff line change
@@ -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:

```
<install_prefix>/
├── 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=<path>`

## 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=<path>` is provided:
- Use the specified path exclusively
- Verify `<path>\include\libcrc_fast.h` exists
- Verify `<path>\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:<CRC_FAST_LIB_DIR>` - 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=<path>
```

2. **Header file not found at specified path**:
```
ERROR: Cannot find libcrc_fast.h in <path>\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 <path>\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: <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.
76 changes: 76 additions & 0 deletions .kiro/specs/windows-build-support/requirements.md
Original file line number Diff line number Diff line change
@@ -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
Loading