4.9 KiB
4.9 KiB
SDL3 Header Parser: Dependency Resolution Plan
Problem Statement
The generated gpu.zig references types from other SDL headers:
FColor(SDL_pixels.h)Rect(SDL_rect.h)PropertiesID(SDL_properties.h)Window(SDL_video.h - opaque type)FlipMode(SDL_surface.h)GPUShaderFormat(special case: #define flags)
Without these types, the generated code won't compile.
Analysis of SDL Header Structure
SDL_gpu.h includes:
#include <SDL3/SDL_stdinc.h> // Basic types (Uint32, etc.)
#include <SDL3/SDL_pixels.h> // SDL_FColor
#include <SDL3/SDL_properties.h> // SDL_PropertiesID
#include <SDL3/SDL_rect.h> // SDL_Rect
#include <SDL3/SDL_surface.h> // SDL_FlipMode
#include <SDL3/SDL_video.h> // SDL_Window (opaque)
Solution Options
Option 1: Parse Dependencies Recursively (REJECTED - Too Complex)
- Parse all included headers
- Build dependency graph
- Generate all files in correct order
- Issues:
- SDL has circular dependencies
- Would need to parse entire SDL API
- Overkill for our use case
Option 2: Manual Type Imports (REJECTED - Not Maintainable)
- Manually copy type definitions
- Issues:
- Not automated
- Breaks on SDL updates
- Defeats purpose of parser
Option 3: Hybrid Approach - Parse Referenced Types Only (RECOMMENDED)
Phase 1: Dependency Detection
- Parse target header (e.g., SDL_gpu.h)
- Collect all non-GPU SDL types referenced in signatures
- Map types to their source headers (from #include directives)
Phase 2: Selective Type Extraction
For each dependency header, extract ONLY referenced types:
- Parse dependency header in "extract mode"
- Only output declarations that match our needed types
- Generate minimal
<module>.zigfiles (e.g.,pixels.zig,rect.zig)
Phase 3: Code Generation
Generate main file with imports:
pub const c = @import("c.zig").c;
// Import minimal dependencies
const pixels = @import("pixels.zig");
const rect = @import("rect.zig");
const properties = @import("properties.zig");
const video = @import("video.zig");
const surface = @import("surface.zig");
// Re-export needed types
pub const FColor = pixels.FColor;
pub const Rect = rect.Rect;
pub const PropertiesID = properties.PropertiesID;
pub const Window = video.Window;
pub const FlipMode = surface.FlipMode;
// Manual override for #define-based types
pub const GPUShaderFormat = packed struct(u32) {
// ... handwritten
};
// Generated GPU declarations follow...
Implementation Plan
Step 1: Add Dependency Analysis
const DependencyInfo = struct {
types_needed: []const []const u8,
source_headers: std.StringHashMap([]const u8), // type -> header
};
fn analyzeDependencies(decls: []Declaration) !DependencyInfo {
// Scan all function signatures for SDL_ types
// Map types to headers based on SDL conventions
}
Step 2: Extract Types from Dependencies
fn extractTypesFromHeader(
header_path: []const u8,
types_to_extract: []const []const u8,
) ![]Declaration {
// Parse dependency header
// Filter to only needed types
// Return minimal declaration set
}
Step 3: Generate Import Structure
fn generateWithDependencies(
main_decls: []Declaration,
deps: DependencyInfo,
output_dir: []const u8,
) !void {
// Generate dependency .zig files
// Generate main file with imports
}
Step 4: Handle Special Cases
Opaque Types (e.g., Window):
- SDL_Window is
typedef struct SDL_Window SDL_Window;(forward decl) - Generate as:
pub const Window = opaque {};orpub const Window = c.SDL_Window; - Decision: Use
c.SDL_Windowfor true opaque types
#define Flags (e.g., GPUShaderFormat):
- Cannot be auto-parsed
- Maintain "overrides" file:
overrides.zig - User can provide manual definitions for unparseable types
File Structure
v2/
├── gpu.zig # Main generated file with imports
├── pixels.zig # Minimal: FColor only
├── rect.zig # Minimal: Rect only
├── properties.zig # Minimal: PropertiesID only
├── video.zig # Minimal: Window only
├── surface.zig # Minimal: FlipMode only
└── overrides.zig # Manual definitions (GPUShaderFormat)
Advantages
- ✅ Automated - no manual copying
- ✅ Minimal - only extracts needed types
- ✅ Maintainable - regenerate on SDL updates
- ✅ Avoids circular dependencies - only extracts leaf types
- ✅ Flexible - handles special cases via overrides
Testing Strategy
- Parse SDL_gpu.h → detect dependencies
- Parse dependency headers → extract types
- Generate all files
- Run
zig buildto verify compilation - Compare API compatibility with handwritten version
Future Enhancements
- Cache parsed headers to avoid re-parsing
- Support transitive dependencies (if type A needs type B)
- Auto-generate overrides file with placeholders
- Support multiple target headers in one run