Modern, modular C# bindings for SDL2 and SDL3, bundled with cross-platform native libraries built from source via vcpkg.
This project provides comprehensive C# bindings for SDL2 (and upcoming SDL3) along with their satellite libraries (SDL_image, SDL_mixer, SDL_ttf, SDL_gfx, SDL_net), distributed as NuGet packages with pre-compiled native binaries for Windows, Linux, and macOS.
The .NET SDL ecosystem has a gap. Existing binding projects provide C# P/Invoke declarations but expect you to source native libraries yourself. This project is different:
- C# Bindings — Currently based on SDL2-CS, with auto-generated bindings planned
- Native libraries built from source — Reproducible builds via vcpkg with explicit feature flags
- Cross-platform NuGet packages — Proper
runtimes/{rid}/native/layout for 7+ platforms - Symlink preservation — tar.gz archives for Linux/macOS with MSBuild extraction targets
No other project in the ecosystem does all four.
| Package | Description | Status |
|---|---|---|
Janset.SDL2.Core |
Core SDL2 bindings (windowing, input, events, rendering) | Functional |
Janset.SDL2.Image |
SDL2_image bindings (JPEG, PNG, WebP, AVIF, TIFF) | Functional |
Janset.SDL2.Mixer |
SDL2_mixer bindings (MP3, FLAC, OGG, Opus, MOD, MIDI) | In Progress |
Janset.SDL2.Ttf |
SDL2_ttf bindings (TrueType + Harfbuzz text shaping) | In Progress |
Janset.SDL2.Gfx |
SDL2_gfx bindings (primitives, rotozoom) | Functional |
Janset.SDL2.Net |
SDL2_net bindings (TCP/UDP networking) | Planned |
Janset.SDL2 |
Meta-package (pulls everything) | Planned |
| Package | Description | Status |
|---|---|---|
Janset.SDL3.Core |
SDL3 bindings (GPU API, new audio, camera, dialogs) | Planned |
Janset.SDL3.Image |
SDL3_image bindings | Planned |
Janset.SDL3.Mixer |
SDL3_mixer bindings | Planned |
Janset.SDL3.Ttf |
SDL3_ttf bindings (+ SVG/emoji support) | Planned |
Janset.SDL3 |
Meta-package | Planned |
Native binaries are built for all major desktop platforms:
| Platform | Architectures | Status |
|---|---|---|
| Windows | x64, x86, ARM64 | Functional (7-RID green via release.yml) |
| Linux | x64, ARM64 | Functional (GHCR-hosted linux-builder:focal-latest image) |
| macOS | x64 (Intel), ARM64 (Apple Silicon) | Functional |
All native libraries are compiled from source using vcpkg via custom *-hybrid overlay triplets — transitive deps are statically baked into satellite shared libs while the SDL2 core stays dynamic (single source-of-truth instance across the package set). Active feature set:
- SDL2: Vulkan, X11, Wayland, ALSA, D-Bus, IBus, libsamplerate
- SDL2_image: AVIF, JPEG (libjpeg-turbo), WebP, TIFF, PNG
- SDL2_mixer: MP3 (minimp3 — LGPL-free), FLAC (drflac), Opus, WavPack, OGG Vorbis, MOD (libmodplug), MIDI (bundled Timidity + freepats on Linux/CI)
- SDL2_ttf: FreeType, Harfbuzz (advanced text shaping)
- SDL2_gfx: primitives, rotozoom
LGPL-licensed codecs (mpg123, libxmp, FluidSynth) are deliberately not in the active feature set per the project's LGPL-free codec policy — see AGENTS.md Settled Strategic Decisions.
Once packages are published:
# Everything at once
dotnet add package Janset.SDL2
# Or pick what you need
dotnet add package Janset.SDL2.Core
dotnet add package Janset.SDL2.ImageThe native packages are pulled in transitively — you never need to reference .Native packages directly.
Target Frameworks: net10.0, net9.0, net8.0, netstandard2.0, net462
Actively under development. Resuming after a hiatus — core infrastructure is solid, now completing the packaging pipeline.
| Area | Status |
|---|---|
| C# bindings (5 SDL2 libraries) | Done |
| Cake Frosting build host (feature-oriented vertical slices) | Done |
| Native binary harvesting pipeline (7-RID hybrid-static) | Done |
Cross-platform CI workflow (release.yml, 10 jobs) |
Done |
| NuGet package creation (5 family × 3 nupkg) | Done |
| Build-host test suite (TUnit) | Done |
| Cross-platform smoke validation | Done — tools ci-sim on host RID, 7-RID matrix in CI |
| Release pipeline publish | PublishStaging live (GitHub Packages internal feed); PublishPublic pending Phase 2b PD-7 (nuget.org promotion via Trusted Publishing OIDC) |
| SDL2_net support | Phase 3 — manifest entry retired pending binding skeleton (#58) |
| Binding auto-generation (CppAst) | Phase 4 |
| SDL3 support | Phase 5 |
| Samples | Phase 3 (#60) |
See docs/plan.md for detailed status and roadmap.
# Clone with submodules (vcpkg + SDL2-CS)
git clone --recursive https://github.com/janset2d/sdl2-cs-bindings.git
cd sdl2-cs-bindings
# Canonical local setup: prepare local feed + smoke override in one step
dotnet run --file tools.cs -- setup --source=local
# Build managed bindings directly (fast managed-only path)
dotnet build src/SDL2.Core/SDL2.Core.csproj
dotnet build src/SDL2.Image/SDL2.Image.csproj
# Optional: build-host regression suite
dotnet test --project build/_build.Tests/Build.Tests.csproj -c Release --framework net10.0
# Note: the root solution intentionally keeps smoke projects.
# If build/msbuild/Janset.Local.props is missing or stale,
# solution-level build can fail on smoke package restore:
# dotnet build Janset.SDL2.sln
# To build native libraries locally:
# 1. Bootstrap vcpkg
./external/vcpkg/bootstrap-vcpkg.sh # or .bat on Windows
# 2. Install native dependencies for your platform
./external/vcpkg/vcpkg install --triplet x64-linux-hybrid --overlay-triplets=vcpkg-overlay-triplets
# 3. Run the harvest pipeline
cd build/_build
dotnet run -- --target Harvest --library SDL2 --library SDL2_image --rid linux-x64For detailed build instructions, see docs/playbook/local-development.md.
| Document | Purpose |
|---|---|
| docs/onboarding.md | Project overview, glossary, where-to-go pointers |
| docs/plan.md | Current status and roadmap |
| docs/playbook/ | How-to recipes (local dev, validation, adding libraries, vcpkg updates, overlays) |
| docs/knowledge-base/release-guardrails.md | G-numbered guardrail registry + failure-mode catalog |
| docs/decisions/ | Architecture decision records |
| docs/research/ | Design rationale (packaging patterns, autogen approaches, SDL3 analysis, future-research starting points) |
| docs/phases/ | Phase-by-phase execution details |
User's .csproj
└── references Janset.SDL2.Core (managed bindings)
└── depends on Janset.SDL2.Core.Native (native binaries)
└── runtimes/win-x64/native/SDL2.dll
└── runtimes/linux-x64/native/libSDL2-2.0.so.0
└── runtimes/osx-arm64/native/libSDL2.dylib
Native libraries are built via a Cake Frosting pipeline that:
- Compiles SDL2 from source using vcpkg
- Walks the binary dependency closure (dumpbin/ldd/otool)
- Filters out OS-provided libraries
- Packages binaries into NuGet-compatible
runtimes/{rid}/native/layout - Preserves Linux/macOS symlinks via tar.gz archives
This project is the foundation for Janset2D, a cross-platform 2D game framework (named after my daughter, Janset). While these bindings are integral to Janset2D (which will be open-sourced separately), they are designed as a standalone, community-facing contribution.
- C# bindings based on SDL2-CS by Ethan Lee
- Native libraries built using vcpkg by Microsoft
- Build automation powered by Cake Frosting
- Inspired by the packaging patterns of SkiaSharp and LibGit2Sharp
Contributions will be welcome once the initial release and CI/CD pipeline are stabilized. A CONTRIBUTING.md will be added at that time.
This project is licensed under the MIT License. See the LICENSE file for details.
| Family | Version | Upstream | vcpkg Port |
|---|---|---|---|
| Janset.SDL2.Core | 2.32.0 | SDL 2.32.10 | 0 |
| Janset.SDL2.Image | 2.8.0 | SDL2_image 2.8.8 | 2 |
| Janset.SDL2.Mixer | 2.8.0 | SDL2_mixer 2.8.1 | 2 |
| Janset.SDL2.Ttf | 2.24.0 | SDL2_ttf 2.24.0 | 0 |
| Janset.SDL2.Gfx | 1.0.0 | SDL2_gfx 1.0.4 | 11 |