Have you ever dreamed of writing C++ code once and deploying it seamlessly across iOS, Android, Windows, and macOS? I recently embarked on this journey while developing a mobile hardware ray tracing renderer. The goal was ambitious: create a framework that rivals the convenience of modern web development tools, but for C++ applications targeting all major platforms.
The good news? In 2025, this is not only possible but surprisingly achievable. I've open-sourced the result as Sparkle: A Cross-Platform Hardware Ray Tracing Renderer.
Why Now?
The C++ ecosystem has evolved significantly:
- Modern C++ - The standard library is richer than ever, and tools like vcpkg have revolutionized package management
- Universal Clang Support - All platforms now support Clang, with Android and macOS using it as their default compiler
- Mature CMake - While still quirky, CMake has become the de facto standard for cross-platform C++ builds
- Platform Evolution - Each platform has developed mature toolchains that still embrace C++
- Graphics API Convergence - Vulkan's cross-platform design and the convergence of graphics APIs make unified rendering possible
- Python Everywhere - Python's ubiquity provides a "free" cross-platform scripting solution for complex build automation
- AI Assistance - Modern AI tools can help navigate documentation, automate tedious tasks, and debug complex build issues
The Magic: One Command, Any Platform
Here's what the final build system looks like:
# Build for Windows (on Windows)
python3 build.py --framework glfw --config Release
# Build and run on macOS
python3 build.py --framework glfw --run
# Generate Visual Studio project (Windows)
python3 build.py --framework glfw --generate_only
# Build Android APK and deploy to connected device
python3 build.py --framework android --run
# Build for iOS with hardware ray tracing
python3 build.py --framework ios --config Release --run --pipeline gpu
The result? Identical rendering output across all platforms:

Design Philosophy
Core Principles
- Platform-Agnostic by Default - Use standard library and cross-platform libraries wherever possible
- Isolate Platform-Specific Code - Keep platform dependencies contained and minimal
- Minimize Macros - Reserve them only for compiler/platform-specific needs
- Source Dependencies Over Binaries - Increases build time but dramatically reduces maintenance overhead
- Python Over CMake/C++ - Use Python for complex build logic instead of CMake scripting
- Modern Language Features - Embrace the latest C++ standards and compiler features
- Compiler as Guardian - Enable all warnings, treat warnings as errors, enforce code style
- Unified Toolchain - Standardize on Clang across platforms while maintaining native toolchain compatibility
- Configuration Over Convention - Make features toggleable for easier debugging and experimentation
Strategic Trade-offs
- Latest Everything - Support only the newest toolchains, SDKs, and hardware to leverage cutting-edge features
- Focused Feature Set - Implement representative, cross-platform solutions rather than comprehensive feature coverage
- Delayed Optimization - Prioritize stability and maintainability over premature optimization
Architecture Overview
Module Structure
sparkle/
├── libraries/ # Platform-independent modules
│ ├── core/ # Logging, math, threading, profiling
│ ├── io/ # Resource loading and file systems
│ ├── scene/ # Scene graph and nodes
│ ├── renderer/ # Rendering pipeline
│ ├── rhi/ # Graphics API abstraction
│ └── application/ # Main loop and initialization
├── frameworks/ # Platform-specific implementations
│ ├── glfw/ # Desktop (Windows/macOS)
│ ├── android/ # Android-specific code
│ ├── apple/ # Shared Apple platform code
│ ├── macos/ # macOS native support
│ └── ios/ # iOS native support
├── shaders/ # Cross-platform shaders
├── resources/ # Assets and configurations
├── build_system/ # Build scripts and platform resources
└── thirdparty/ # Dependencies
CMake Architecture
The build system uses three strategically designed CMake files:
- Main CMake - Manages global parameters, creates core libraries, handles platform-specific configurations
- Dependencies CMake - Consolidates all third-party dependencies into a single static library
- Shader CMake - Manages shader compilation (likely to be replaced with Python/C++ in the future)
Key Dependencies
- GLFW - Mature cross-platform windowing for desktop platforms
- Eigen - Powerful math library (overkill for graphics, but incredibly robust)
- Dear ImGui - Lightweight, flexible immediate-mode GUI
- spdlog - Fast, feature-rich logging
- cpptrace - Cross-platform stack traces for debugging
Platform Implementation Details
Windows: The Reference Implementation
Windows development is straightforward thanks to GLFW and Microsoft's legendary backward compatibility. The interesting part is Clang on Windows support:
- Install LLVM toolchain via Visual Studio Installer (clang-cl)
- Develop without touching Visual Studio IDE
- Unified compiler behavior across all platforms
- Note: VS ships Clang 16 while official Clang is at 18+
macOS: Native Metal Support
Sparkle provides two macOS implementations:
- GLFW - Works out of the box with MoltenVK for Vulkan translation
- Native - Required for Metal ray tracing support
The native implementation bridges C++ and Apple's frameworks:
// Key components connected via Storyboard
- AppDelegate → Application lifecycle
- MetalView → Rendering context and swapchain
- ViewController → Window management and events
- Storyboard → Wires everything together
iOS: Mobile Challenges
iOS support required several adaptations:
- Build System - Using ios-cmake for proper toolchain configuration
- Code Signing - Automatic signing for local development (no paid developer account required)
- Touch Events - Custom UIKit integration for touch handling
- ImGui Backend - Custom implementation for iOS touch and rendering
- File System - Sandbox-aware file handling using NSBundle and app directories
Android: GameActivity Integration
Android's approach uses GameActivity for C++ integration:
- Create a Kotlin/Java class extending GameActivity
- Load the C++ library from this class
- Implement GameActivity hooks in C++
- Configure AndroidManifest.xml to use your GameActivity
- Link everything through gradle's externalNativeBuild
The Build System Magic
The Python-based build system provides consistent commands across all platforms:
Features
- Platform Selection - Target any supported platform
- Build Configurations - Debug/Release modes
- Instant Run - Build and deploy in one command
- Mobile Deployment - Direct USB deployment to devices
- IDE Integration - Generate native project files
- LSP Support - Export compile_commands.json for clangd
- Advanced Options - Shader debugging, ASAN, profiling
Automatic Dependency Management
The build system handles most dependencies automatically:
- Git Submodules - Checked and updated on each build
- CMake FetchContent - Downloaded during configuration
- Vulkan SDK - Silent installation to project directory
- Binary Dependencies - Via system package manager or vcpkg fallback
- macOS Tools - LLVM and CMake via Homebrew
Manual installation is still required for:
- Visual Studio
- Xcode
- Android Studio
- Platform-specific SDKs
Tested Platforms
Platform | OS | CPU | GPU |
---|---|---|---|
Windows | Windows 11 | Ryzen 5975WX | GeForce RTX 4080 |
Android | Android 13 | Snapdragon 8 Gen2 | Adreno 740 |
macOS | macOS 15.5 | Apple M3 Pro | Apple M3 Pro |
iOS | iOS 18.5 | Apple A18 | Apple A18 |
Conclusion
Building a truly cross-platform C++ application framework is challenging but achievable. The key is embracing modern tools, making strategic trade-offs, and maintaining a clear separation between platform-agnostic and platform-specific code.
Sparkle demonstrates that with careful design, you can achieve the "write once, run everywhere" dream for C++ applications, even with advanced features like hardware ray tracing.
The project is actively developed and welcomes contributions. Whether you're building a game engine, a rendering system, or any cross-platform C++ application, I hope Sparkle's approach provides valuable insights for your journey.
Check out the full source code and documentation at github.com/tqjxlm/Sparkle.