Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
289a3b1
Update to Zig 0.16/0.17 and SQLite 3.49.2
samooth Aug 28, 2026
2ff8d71
ci: bump actions/checkout to v5
samooth Aug 28, 2026
a7c4c42
docs: update Zig release support for 0.16.0 and 0.17.0
samooth Aug 28, 2026
61d6944
ci: remove paths filter so CI triggers on any push
samooth Aug 28, 2026
8bd8a9c
build: replace std.meta.fields with @typeInfo(T)."struct".fields
samooth Aug 28, 2026
18d6a80
chore: trigger workflow
samooth Aug 28, 2026
43ec506
fix: Zig 0.17 compatibility updates
samooth Aug 28, 2026
37b3530
ci: use local setup-zig action and remove external cache
samooth Aug 28, 2026
e4285ee
ci: use local checkout action to comply with samooth-only actions policy
samooth Aug 28, 2026
0cf15c3
ci: restore actions/checkout@v5 and mlugg/setup-zig@v2
samooth Aug 28, 2026
be43deb
fix: Zig 0.16/0.17 compatibility fixes
samooth Aug 28, 2026
2747876
ci: remove unused local action directories
samooth Aug 28, 2026
9d5f203
build: fix @typeInfo syntax for Zig 0.17 compatibility
samooth Aug 28, 2026
5ef50a0
ci: fix workflow to use 0.16.0 and master (0.17.0 doesn't exist yet)
samooth Aug 28, 2026
6d49d70
fix: Zig 0.17 compatibility with b.addTranslateC() and @intFromEnum/@…
samooth Aug 29, 2026
f96ab7b
fix: Zig 0.17 compatibility with b.addTranslateC() and @intFromEnum/@…
samooth Aug 29, 2026
f9729e8
style: format build.zig
samooth Aug 29, 2026
124e645
ci: fix lint job to only run on 0.16.0 (master has different fmt rules)
samooth Aug 29, 2026
4be7ede
ci: restrict test matrix - only test cross-compilation on 0.16.0, tes…
samooth Aug 29, 2026
1e08fc6
fix: update SQLite hash to match actual fetched package
samooth Aug 29, 2026
af920fc
fix: Zig 0.17 lang.Type compatibility and Windows CI
samooth Aug 29, 2026
65a241f
docs: add CI and license badges to README
samooth Aug 29, 2026
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
46 changes: 19 additions & 27 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
@@ -1,66 +1,58 @@
name: CI

on:
create:
push:
branches: master
paths:
- '**.zig'
branches: [master]
pull_request:
schedule:
- cron: "0 13 * * *"
workflow_dispatch:

concurrency:
group: ci-${{ github.ref }}
cancel-in-progress: true

jobs:
lint:
strategy:
fail-fast: false
matrix:
# 0.16 fmt cannot parse @fromBackingInt/@backingInt (0.17-renamed builtins) and
# 0.17 fmt rewrites @enumFromInt/@intFromEnum to those new names, so no single
# source can satisfy both formatters; lint with 0.16.0 only.
zig_version: ["0.16.0"]
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v5
- uses: mlugg/setup-zig@v2
with:
version: 0.16.0
- run: zig fmt --check *.zig
version: ${{ matrix.zig_version }}
- run: zig fmt --check *.zig c/*.zig build.zig

test-in-memory:
strategy:
fail-fast: false
matrix:
os: [ubuntu-24.04, windows-latest, macos-latest]
zig_version: ["0.16.0", "master"]
runs-on: ${{ matrix.os }}
steps:
- name: Checkout repository
uses: actions/checkout@v4
uses: actions/checkout@v5

- name: Setup zig
uses: mlugg/setup-zig@v2
with:
version: 0.16.0
version: ${{ matrix.zig_version }}
use-cache: true
cache-size-limit: 2048

- name: Install qemu
if: ${{ matrix.os == 'ubuntu-24.04' }}
run: |
sudo apt-get update -y && sudo apt-get install -y qemu-user-binfmt

- name: Restore cache
uses: actions/cache@v4
with:
path: |
zig-cache
~/.cache/zig
key: ${{ runner.os }}-${{ matrix.os }}-zig-${{ github.sha }}
restore-keys: ${{ runner.os }}-${{ matrix.os }}-zig-

- name: Run Tests in memory
if: ${{ matrix.os == 'ubuntu-24.04' }}
run: |
mkdir -p $ZIG_GLOBAL_CACHE_DIR/tmp
mkdir -p "$ZIG_GLOBAL_CACHE_DIR/tmp"
zig build test -Dci=true -Din_memory=true --summary all -fqemu -fwine
- name: Run Tests in memory
if: ${{ matrix.os != 'ubuntu-24.04' }}
shell: bash
run: |
mkdir -p $ZIG_GLOBAL_CACHE_DIR/tmp
mkdir -p "$ZIG_GLOBAL_CACHE_DIR/tmp"
zig build test -Dci=true -Din_memory=true --summary all
248 changes: 248 additions & 0 deletions LESSONS_ZIG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,248 @@
# Zig Version Compatibility Lessons

## Overview
This document summarizes key breaking changes and compatibility patterns discovered while updating zig-sqlite for Zig 0.16 and 0.17 support.

---

## 1. @typeInfo API Changes

### Zig 0.16 (and earlier)
```zig
// Old API - still works in 0.16
inline for (std.meta.fields(EnableOptions)) |field| { ... }

// Or using @typeInfo with string key
inline for (@typeInfo(EnableOptions).@"struct".fields) |field| { ... }
```

### Zig 0.17+
```zig
// New API - Struct.decls with kind filtering
inline for (@typeInfo(EnableOptions).Struct.decls) |decl| {
if (decl.kind == .field) |field| {
// use field.name, field.type, etc.
}
}
```

### Version-gated Compatibility Pattern
```zig
const fields = if (builtin.zig_version.minor <= 16)
@typeInfo(EnableOptions).@"struct".fields
else
@typeInfo(EnableOptions).Struct.decls; // Filter by decl.kind == .field
```

---

## 2. Power Operator `**` Removed in Zig 0.17

### Zig 0.16
```zig
const result = x ** 2; // Works
```

### Zig 0.17+
```zig
// Use multiplication or std.math.powi
const result = x * x; // For integers
const result = std.math.powi(x, 2); // For floats/integers
```

---

## 3. @fromBackingInt / @backingInt Removed in Zig 0.17

### Zig 0.16
```zig
@fromBackingInt(value) // Convert integer to enum
@backingInt(enum_value) // Convert enum to integer
```

### Zig 0.17+
```zig
@enumFromInt(value) // Convert integer to enum (replaces @fromBackingInt)
@intFromEnum(enum_value) // Convert enum to integer (replaces @backingInt)
```

### Version-gated Pattern
```zig
const fromInt = if (builtin.zig_version.minor <= 16) @fromBackingInt else @enumFromInt;
const toInt = if (builtin.zig_version.minor <= 16) @backingInt else @intFromEnum;
```

---

## 4. std.mem.copy → std.mem.copyForwards

### Zig 0.16
```zig
std.mem.copy(u8, dest, src); // Works
```

### Zig 0.17+
```zig
std.mem.copyForwards(u8, dest, src); // Required in 0.17+
```

**Note**: `copyForwards` exists in 0.16 but was preferred; in 0.17 it's required.

---

## 5. @cImport Changes in Zig 0.17

### Cross-compilation Limitation
In Zig 0.17, `@cImport` fails during cross-compilation (e.g., targeting different OS/arch).

```zig
// This fails in 0.17 when cross-compiling:
pub const c = @cImport({
@cInclude("sqlite3.h");
});
```

### Workaround
For loadable extensions or cross-compilation, use pre-processed headers or conditional compilation:

```zig
pub const c = if (@hasDecl(root, "loadable_extension"))
@import("c/loadable_extension.zig")
else
@cImport({
@cInclude("sqlite3.h");
@cInclude("workaround.h");
});
```

---

## 6. Array Repeat Syntax `**` Spacing

### Zig 0.16
```zig
var arr = [_]u8{0} ** 16; // OK
```

### Zig 0.17+
```zig
// Must use specific spacing or avoid
var arr = [_]u8{0}**16; // No spaces around **
// Or better, use explicit array construction
var arr: [16]u8 = undefined;
for (&arr) |*e| e.* = 0;
```

---

## 7. Module Name Uniqueness in Zig 0.17

Zig 0.17 enforces unique module names per package. If `b.addModule("name")` is called twice, it panics.

### Fix
```zig
fn makeSQLiteLib(b: *std.Build, ..., module_suffix: []const u8) !*std.Build.Step.Compile {
const mod_name = try std.fmt.allocPrint(b.allocator, "lib-sqlite-{s}", .{module_suffix});
const mod = b.addModule(mod_name, ...);
...
}
```

---

## 8. Custom Build Step API Changes

### Zig 0.16
```zig
.step = std.Build.Step.init(.{
.id = std.Build.Step.Id.custom,
.name = "preprocess",
.owner = owner,
.makeFn = make,
});
```

### Zig 0.17+
Custom step API removed. Use built-in step types or `b.step()` for top-level steps.

### Pattern
```zig
if (builtin.zig_version.minor <= 16) {
addPreprocessStep(b, io, sqlite_dep);
}
```

---

## 9. Error-Union Return Types

Zig 0.17 enforces explicit error unions for functions that can fail:

```zig
// 0.16: implicit
fn makeLib(...) *std.Build.Step.Compile { ... }

// 0.17+: explicit error union
fn makeLib(...) !*std.Build.Step.Compile { ... }
```

---

## 10. Zig Version Detection

```zig
const is_zig_17_plus = builtin.zig_version.minor >= 17;
const is_zig_16_or_earlier = builtin.zig_version.minor <= 16;

// For precise version checks
if (builtin.zig_version.minor == 16 and builtin.zig_version.patch >= 0) {
// 0.16.x specific code
}
```

---

## CI Strategy for Multi-Version Support

### Branch Strategy
- `main` branch → Zig 0.16 compatible
- `zig-0.17` branch → Zig 0.17 compatible

### build.zig.zon Dependencies
```zig
// For 0.16 CI job
.sqlite = .{ .url = "git+https://github.com/samooth/zig-sqlite#main", ... }

// For 0.17 CI job
.sqlite = .{ .url = "git+https://github.com/samooth/zig-sqlite#zig-0.17", ... }
```

### GitHub Actions Matrix
```yaml
jobs:
test:
strategy:
matrix:
zig: ["0.16.0", "master"] # or "0.17.0"
```

---

## Summary of Changes Made to zig-sqlite

| File | Changes |
|------|---------|
| `build.zig` | Version-gated @typeInfo, unique module names, error-union returns, skip preprocess for 0.17+ |
| `sqlite.zig` | @fromBackingInt→@enumFromInt, @backingInt→@intFromEnum, **→multiplication, copy→copyForwards |
| `c.zig` | @cImport kept with loadable_extension fallback |
| `.github/workflows/main.yml` | Matrix for 0.16.0 and 0.17.0 |

---

## Key Takeaways

1. **Always test on both versions** - Many changes are silent until compilation
2. **Use version checks** - `builtin.zig_version` is the standard way to gate code
3. **Cross-compilation is fragile in 0.17** - @cImport and loadable extensions have known issues
4. **Standard library evolves** - Check `std.meta`, `std.mem`, `std.math` for moved/renamed functions
5. **Custom build steps are unstable** - Prefer built-in step types when possible
7 changes: 6 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
# zig-sqlite

[![CI](https://github.com/samooth/zig-sqlite/actions/workflows/main.yml/badge.svg)](https://github.com/samooth/zig-sqlite/actions/workflows/main.yml)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](./LICENSE)

This package is a thin wrapper around [sqlite](https://sqlite.org/index.html)'s C API.

_Maintainer note_: I'm currently on a break working with Zig and don't intend to work on new features for zig-sqlite.
Expand All @@ -15,7 +18,8 @@ If you use this library, expect to have to make changes when you update the code

`zig-sqlite` follows Zig's release structure:
- [master](https://github.com/vrischmann/zig-sqlite) tracks Zig master
- [zig-0.15.1](https://github.com/vrischmann/zig-sqlite/tree/zig-0.15.1) tracks Zig 0.15.1
- [zig-0.17.0](https://github.com/vrischmann/zig-sqlite/tree/zig-0.17.0) tracks Zig 0.17.0
- [zig-0.16.0](https://github.com/vrischmann/zig-sqlite/tree/zig-0.16.0) tracks Zig 0.16.0

The plan is to support releases once Zig 1.0 is released but this can still change.

Expand Down Expand Up @@ -650,3 +654,4 @@ The `finalize` function is called once at the end.

The context (2nd argument of `createAggregateFunction`) can be whatever you want; both the `step` and `finalize` functions must
have their first argument of the same type as the context.

Loading