Skip to content
Closed
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
116 changes: 39 additions & 77 deletions build.zig
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ fn computeTestTargets(isNative: bool, ci: ?bool) ?[]const TestTarget {

// This creates a SQLite static library from the SQLite dependency code.
fn makeSQLiteLib(b: *std.Build, dep: *std.Build.Dependency, c_flags: []const []const u8, target: std.Build.ResolvedTarget, optimize: std.builtin.OptimizeMode, sqlite_c: enum { with, without }) *std.Build.Step.Compile {
const mod = b.addModule("lib-sqlite", .{
const mod = b.createModule(.{
.target = target,
.optimize = optimize,
.link_libc = true,
Expand Down Expand Up @@ -146,8 +146,6 @@ pub fn build(b: *std.Build) !void {
const query = b.standardTargetOptionsQueryOnly(.{});
const target = b.resolveTargetQuery(query);
const optimize = b.standardOptimizeOption(.{});
var threaded = Io.Threaded.init_single_threaded;
const io = threaded.io();

// Upstream dependency
const sqlite_dep = b.dependency("sqlite", .{
Expand All @@ -161,22 +159,25 @@ pub fn build(b: *std.Build) !void {
defer flags.deinit(b.allocator);
try flags.append(b.allocator, "-std=c99");

inline for (std.meta.fields(EnableOptions)) |field| {
const opt = b.option(bool, field.name, "Enable " ++ field.name) orelse field.defaultValue().?;
const info = @typeInfo(EnableOptions).@"struct";
inline for (info.field_names, info.field_types, info.field_attrs) |field_name, field_type, field_attrs| {
const default_val = field_attrs.defaultValue(field_type) orelse false;
const opt = b.option(bool, field_name, "Enable " ++ field_name) orelse default_val;

if (opt) {
var buf: [field.name.len]u8 = undefined;
const name = std.ascii.upperString(&buf, field.name);
var buf: [field_name.len]u8 = undefined;
const name = std.ascii.upperString(&buf, field_name);
const flag = try std.fmt.allocPrint(b.allocator, "-DSQLITE_ENABLE_{s}", .{name});

try flags.append(b.allocator, flag);
}
}

inline for (std.meta.fields(BoolFeatureOptions)) |field| {
comptime var buf: [field.name.len]u8 = undefined;
const name = comptime std.ascii.upperString(&buf, field.name);
const opt = b.option(bool, field.name, "Set SQLITE_" ++ name);
const bool_info = @typeInfo(BoolFeatureOptions).@"enum";
inline for (bool_info.field_names) |field_name| {
comptime var buf: [field_name.len]u8 = undefined;
const name = comptime std.ascii.upperString(&buf, field_name);
const opt = b.option(bool, field_name, "Set SQLITE_" ++ name);

if (opt) |v| {
const flag_value = if (v) "1" else "0";
Expand All @@ -186,10 +187,11 @@ pub fn build(b: *std.Build) !void {
}
}

inline for (std.meta.fields(DefineFeatureOptions)) |field| {
comptime var buf: [field.name.len]u8 = undefined;
const name = comptime std.ascii.upperString(&buf, field.name);
const opt = b.option(bool, field.name, "Set SQLITE_" ++ name) orelse false;
const define_info = @typeInfo(DefineFeatureOptions).@"enum";
inline for (define_info.field_names) |field_name| {
comptime var buf: [field_name.len]u8 = undefined;
const name = comptime std.ascii.upperString(&buf, field_name);
const opt = b.option(bool, field_name, "Set SQLITE_" ++ name) orelse false;

if (opt) {
const flag = try std.fmt.allocPrint(b.allocator, "-DSQLITE_" ++ name, .{});
Expand All @@ -198,10 +200,11 @@ pub fn build(b: *std.Build) !void {
}
}

inline for (std.meta.fields(IntFeatureOptions)) |field| {
comptime var buf: [field.name.len]u8 = undefined;
const name = comptime std.ascii.upperString(&buf, field.name);
const opt = b.option(field.type, field.name, "Set SQLITE_" ++ name);
const int_info = @typeInfo(IntFeatureOptions).@"struct";
inline for (int_info.field_names, int_info.field_types) |field_name, field_type| {
comptime var buf: [field_name.len]u8 = undefined;
const name = comptime std.ascii.upperString(&buf, field_name);
const opt = b.option(field_type, field_name, "Set SQLITE_" ++ name);

if (opt) |v| {
const flag = try std.fmt.allocPrint(b.allocator, "-DSQLITE_" ++ name ++ "={}", .{v});
Expand Down Expand Up @@ -308,24 +311,28 @@ pub fn build(b: *std.Build) !void {
// Tools
//

addPreprocessStep(b, io, sqlite_dep);
addPreprocessStep(b, sqlite_dep);
}

fn addPreprocessStep(b: *std.Build, io: Io, sqlite_dep: *std.Build.Dependency) void {
var wf = b.addWriteFiles();

// Preprocessing step
const preprocess = PreprocessStep.create(b, .{
.source = sqlite_dep.path("."),
.target = wf.getDirectory(),
.io = io,
fn addPreprocessStep(b: *std.Build, sqlite_dep: *std.Build.Dependency) void {
const tool = b.addExecutable(.{
.name = "preprocess-headers",
.root_module = b.createModule(.{
.root_source_file = b.path("build/preprocess_main.zig"),
.target = b.graph.host,
.optimize = .Debug,
}),
});
preprocess.step.dependOn(&wf.step);

const run = b.addRunArtifact(tool);
run.addFileArg(sqlite_dep.path("sqlite3.h"));
const loadable_h = run.addOutputFileArg("loadable-ext-sqlite3.h");
run.addFileArg(sqlite_dep.path("sqlite3ext.h"));
const loadable_ext_h = run.addOutputFileArg("loadable-ext-sqlite3ext.h");

const w = b.addUpdateSourceFiles();
w.addCopyFileToSource(preprocess.target.join(b.allocator, "loadable-ext-sqlite3.h") catch @panic("OOM"), "c/loadable-ext-sqlite3.h");
w.addCopyFileToSource(preprocess.target.join(b.allocator, "loadable-ext-sqlite3ext.h") catch @panic("OOM"), "c/loadable-ext-sqlite3ext.h");
w.step.dependOn(&preprocess.step);
w.addCopyFileToSource(loadable_h, "c/loadable-ext-sqlite3.h");
w.addCopyFileToSource(loadable_ext_h, "c/loadable-ext-sqlite3ext.h");

const preprocess_headers = b.step("preprocess-headers", "Preprocess the headers for the loadable extensions");
preprocess_headers.dependOn(&w.step);
Expand Down Expand Up @@ -436,48 +443,3 @@ const IntFeatureOptions = struct {
default_wal_synchronous: std.math.IntFittingRange(0, 3),
max_expr_depth: c_int,
};

const PreprocessStep = struct {
const Config = struct {
source: std.Build.LazyPath,
target: std.Build.LazyPath,
io: Io,
};

step: std.Build.Step,

source: std.Build.LazyPath,
target: std.Build.LazyPath,
io: Io,

fn create(owner: *std.Build, config: Config) *PreprocessStep {
const step = owner.allocator.create(PreprocessStep) catch @panic("OOM");
step.* = .{
.step = std.Build.Step.init(.{
.id = std.Build.Step.Id.custom,
.name = "preprocess",
.owner = owner,
.makeFn = make,
}),
.source = config.source,
.target = config.target,
.io = config.io,
};

return step;
}

fn make(step: *std.Build.Step, _: std.Build.Step.MakeOptions) !void {
const ps: *PreprocessStep = @fieldParentPtr("step", step);
const owner = step.owner;

const sqlite3_h = try ps.source.path(owner, "sqlite3.h").getPath3(owner, step).toString(owner.allocator);
const sqlite3ext_h = try ps.source.path(owner, "sqlite3ext.h").getPath3(owner, step).toString(owner.allocator);

const loadable_sqlite3_h = try ps.target.path(owner, "loadable-ext-sqlite3.h").getPath3(owner, step).toString(owner.allocator);
const loadable_sqlite3ext_h = try ps.target.path(owner, "loadable-ext-sqlite3ext.h").getPath3(owner, step).toString(owner.allocator);

try Preprocessor.sqlite3(owner.allocator, ps.io, sqlite3_h, loadable_sqlite3_h);
try Preprocessor.sqlite3ext(owner.allocator, ps.io, sqlite3ext_h, loadable_sqlite3ext_h);
}
};
7 changes: 5 additions & 2 deletions build/Preprocessor.zig
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,7 @@ fn readOriginalData(allocator: mem.Allocator, io: Io, path: []const u8) ![]const
var buf: [1024]u8 = undefined;
var reader = file.reader(io, &buf);

const data = reader.interface.readAlloc(allocator, 1024 * 1024);
return data;
return try reader.interface.allocRemaining(allocator, .limited(1024 * 1024));
}

const Processor = struct {
Expand Down Expand Up @@ -201,6 +200,8 @@ pub fn sqlite3(allocator: mem.Allocator, io: Io, input_path: []const u8, output_
var w = output_file.writer(io, &write_buff);

try w.interface.writeAll("/* sqlite3.h edited by the zig-sqlite build script */\n");
try processor.dump(&w);
try w.interface.flush();
}

pub fn sqlite3ext(allocator: mem.Allocator, io: Io, input_path: []const u8, output_path: []const u8) !void {
Expand Down Expand Up @@ -238,4 +239,6 @@ pub fn sqlite3ext(allocator: mem.Allocator, io: Io, input_path: []const u8, outp
var write_buff: [1028]u8 = undefined;
var w = output_file.writer(io, &write_buff);
try w.interface.writeAll("/* sqlite3ext.h edited by the zig-sqlite build script */\n");
try processor.dump(&w);
try w.interface.flush();
}
16 changes: 16 additions & 0 deletions build/preprocess_main.zig
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
const std = @import("std");
const Preprocessor = @import("Preprocessor.zig");

pub fn main(init: std.process.Init) !void {
// Preprocessor never frees, so an arena is the right allocator.
const arena = init.arena.allocator();

const args = try init.minimal.args.toSlice(arena); // GUESS: check std.process.Args
if (args.len != 5) {
std.debug.print("usage: {s} <sqlite3.h> <out-sqlite3.h> <sqlite3ext.h> <out-sqlite3ext.h>\n", .{args[0]});
std.process.exit(1);
}

try Preprocessor.sqlite3(arena, init.io, args[1], args[2]);
try Preprocessor.sqlite3ext(arena, init.io, args[3], args[4]);
}