1
1
const std = @import ("std" );
2
- const builtin = @import ("builtin" );
3
- const Step = std .Build .Step ;
2
+ const debug = std .debug ;
3
+ const heap = std .heap ;
4
+ const mem = std .mem ;
4
5
const ResolvedTarget = std .Build .ResolvedTarget ;
5
6
const Query = std .Target .Query ;
7
+ const builtin = @import ("builtin" );
8
+
9
+ const Preprocessor = @import ("build/Preprocessor.zig" );
6
10
7
11
fn getTarget (original_target : ResolvedTarget ) ResolvedTarget {
8
12
var tmp = original_target ;
@@ -104,6 +108,31 @@ fn computeTestTargets(isNative: bool, ci: ?bool) ?[]const TestTarget {
104
108
return null ;
105
109
}
106
110
111
+ // This creates a SQLite static library from the SQLite dependency code.
112
+ 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 {
113
+ const lib = b .addStaticLibrary (.{
114
+ .name = "sqlite" ,
115
+ .target = target ,
116
+ .optimize = optimize ,
117
+ });
118
+
119
+ lib .addIncludePath (dep .path ("." ));
120
+ lib .addIncludePath (b .path ("c" ));
121
+ if (sqlite_c == .with ) {
122
+ lib .addCSourceFile (.{
123
+ .file = dep .path ("sqlite3.c" ),
124
+ .flags = c_flags ,
125
+ });
126
+ }
127
+ lib .addCSourceFile (.{
128
+ .file = b .path ("c/workaround.c" ),
129
+ .flags = c_flags ,
130
+ });
131
+ lib .linkLibC ();
132
+
133
+ return lib ;
134
+ }
135
+
107
136
pub fn build (b : * std.Build ) ! void {
108
137
const in_memory = b .option (bool , "in_memory" , "Should the tests run with sqlite in memory (default true)" ) orelse true ;
109
138
const dbfile = b .option ([]const u8 , "dbfile" , "Always use this database file instead of a temporary one" );
@@ -113,6 +142,14 @@ pub fn build(b: *std.Build) !void {
113
142
const target = b .resolveTargetQuery (query );
114
143
const optimize = b .standardOptimizeOption (.{});
115
144
145
+ // Upstream dependency
146
+ const sqlite_dep = b .dependency ("sqlite" , .{
147
+ .target = target ,
148
+ .optimize = optimize ,
149
+ });
150
+
151
+ // Define C flags to use
152
+
116
153
var flags = std .ArrayList ([]const u8 ).init (b .allocator );
117
154
defer flags .deinit ();
118
155
try flags .append ("-std=c99" );
@@ -131,50 +168,41 @@ pub fn build(b: *std.Build) !void {
131
168
132
169
const c_flags = flags .items ;
133
170
134
- const sqlite_lib = b .addStaticLibrary (.{
135
- .name = "sqlite" ,
136
- .target = target ,
137
- .optimize = optimize ,
138
- });
171
+ //
172
+ // Main library and module
173
+ //
139
174
140
- sqlite_lib .addIncludePath (b .path ("c/" ));
141
- sqlite_lib .addCSourceFiles (.{
142
- .files = &[_ ][]const u8 {
143
- "c/sqlite3.c" ,
144
- "c/workaround.c" ,
145
- },
146
- .flags = c_flags ,
147
- });
148
- sqlite_lib .linkLibC ();
149
- sqlite_lib .installHeader (b .path ("c/sqlite3.h" ), "sqlite3.h" );
175
+ const sqlite_lib , const sqlite_mod = blk : {
176
+ const lib = makeSQLiteLib (b , sqlite_dep , c_flags , target , optimize , .with );
150
177
151
- b .installArtifact (sqlite_lib );
178
+ const mod = b .addModule ("sqlite" , .{
179
+ .root_source_file = b .path ("sqlite.zig" ),
180
+ .link_libc = true ,
181
+ });
182
+ mod .addIncludePath (b .path ("c" ));
183
+ mod .addIncludePath (sqlite_dep .path ("." ));
184
+ mod .linkLibrary (lib );
152
185
153
- // Create the public 'sqlite' module to be exported
154
- const sqlite_mod = b .addModule ("sqlite" , .{
155
- .root_source_file = b .path ("sqlite.zig" ),
156
- .link_libc = true ,
157
- });
158
- sqlite_mod .addIncludePath (b .path ("c/" ));
159
- sqlite_mod .linkLibrary (sqlite_lib );
186
+ break :blk .{ lib , mod };
187
+ };
188
+ b .installArtifact (sqlite_lib );
160
189
161
- // Tool to preprocess the sqlite header files.
162
- //
163
- // Due to limitations of translate-c the standard header files can't be used for building loadable extensions
164
- // so we have this tool which creates usable header files.
190
+ const sqliteext_mod = blk : {
191
+ const lib = makeSQLiteLib (b , sqlite_dep , c_flags , target , optimize , .without );
165
192
166
- const preprocess_files_tool = b .addExecutable ( .{
167
- . name = "preprocess-files" ,
168
- . root_source_file = b . path ( "tools/preprocess_files.zig" ) ,
169
- . target = getTarget ( target ),
170
- . optimize = optimize ,
171
- } );
193
+ const mod = b .addModule ( "sqliteext" , .{
194
+ . root_source_file = b . path ( "sqlite.zig" ) ,
195
+ . link_libc = true ,
196
+ });
197
+ mod . addIncludePath ( b . path ( "c" ));
198
+ mod . linkLibrary ( lib );
172
199
173
- // Add a top-level step to run the preprocess-files tool
174
- const preprocess_files_run = b . step ( "preprocess-files" , "Run the preprocess-files tool" ) ;
200
+ break : blk mod ;
201
+ } ;
175
202
176
- const preprocess_files_tool_run = b .addRunArtifact (preprocess_files_tool );
177
- preprocess_files_run .dependOn (& preprocess_files_tool_run .step );
203
+ //
204
+ // Tests
205
+ //
178
206
179
207
const test_targets = computeTestTargets (query .isNative (), ci ) orelse &[_ ]TestTarget {.{
180
208
.query = query ,
@@ -195,19 +223,7 @@ pub fn build(b: *std.Build) !void {
195
223
single_threaded_txt ,
196
224
});
197
225
198
- const test_sqlite_lib = b .addStaticLibrary (.{
199
- .name = "sqlite" ,
200
- .target = cross_target ,
201
- .optimize = optimize ,
202
- });
203
- test_sqlite_lib .addCSourceFiles (.{
204
- .files = &[_ ][]const u8 {
205
- "c/sqlite3.c" ,
206
- "c/workaround.c" ,
207
- },
208
- .flags = c_flags ,
209
- });
210
- test_sqlite_lib .linkLibC ();
226
+ const test_sqlite_lib = makeSQLiteLib (b , sqlite_dep , c_flags , cross_target , optimize , .with );
211
227
212
228
const tests = b .addTest (.{
213
229
.name = test_name ,
@@ -217,6 +233,7 @@ pub fn build(b: *std.Build) !void {
217
233
.single_threaded = test_target .single_threaded ,
218
234
});
219
235
tests .addIncludePath (b .path ("c" ));
236
+ tests .addIncludePath (sqlite_dep .path ("." ));
220
237
tests .linkLibrary (test_sqlite_lib );
221
238
222
239
const tests_options = b .addOptions ();
@@ -229,55 +246,119 @@ pub fn build(b: *std.Build) !void {
229
246
test_step .dependOn (& run_tests .step );
230
247
}
231
248
232
- const lib = b . addStaticLibrary (.{
233
- . name = "sqlite" ,
234
- . target = getTarget ( target ),
235
- . optimize = optimize ,
236
- });
237
- lib . addCSourceFile (.{ . file = b . path ( "c/sqlite3.c" ), . flags = c_flags } );
238
- lib . addIncludePath ( b . path ( "c" ) );
239
- lib . linkLibC ( );
249
+ // This builds an example shared library with the extension and a binary that tests it.
250
+
251
+ const zigcrypto_install_artifact = addZigcrypto ( b , sqliteext_mod , target , optimize );
252
+ test_step . dependOn ( & zigcrypto_install_artifact . step );
253
+
254
+ const zigcrypto_test_run = addZigcryptoTestRun ( b , sqlite_mod , target , optimize );
255
+ zigcrypto_test_run . step . dependOn ( & zigcrypto_install_artifact . step );
256
+ test_step . dependOn ( & zigcrypto_test_run . step );
240
257
241
258
//
242
- // Examples
259
+ // Tools
243
260
//
244
261
245
- // Loadable extension
246
- //
247
- // This builds an example shared library with the extension and a binary that tests it.
262
+ addPreprocessStep (b , sqlite_dep );
263
+ }
264
+
265
+ fn addPreprocessStep (b : * std.Build , sqlite_dep : * std.Build.Dependency ) void {
266
+ var wf = b .addWriteFiles ();
267
+
268
+ // Preprocessing step
269
+ const preprocess = PreprocessStep .create (b , .{
270
+ .source = sqlite_dep .path ("." ),
271
+ .target = wf .getDirectory (),
272
+ });
273
+ preprocess .step .dependOn (& wf .step );
274
+
275
+ const w = b .addUpdateSourceFiles ();
276
+ w .addCopyFileToSource (preprocess .target .join (b .allocator , "loadable-ext-sqlite3.h" ) catch @panic ("OOM" ), "c/loadable-ext-sqlite3.h" );
277
+ w .addCopyFileToSource (preprocess .target .join (b .allocator , "loadable-ext-sqlite3ext.h" ) catch @panic ("OOM" ), "c/loadable-ext-sqlite3ext.h" );
278
+ w .step .dependOn (& preprocess .step );
248
279
249
- const zigcrypto_loadable_ext = b .addSharedLibrary (.{
280
+ const preprocess_headers = b .step ("preprocess-headers" , "Preprocess the headers for the loadable extensions" );
281
+ preprocess_headers .dependOn (& w .step );
282
+ }
283
+
284
+ fn addZigcrypto (b : * std.Build , sqlite_mod : * std.Build.Module , target : std.Build.ResolvedTarget , optimize : std.builtin.OptimizeMode ) * std.Build.Step.InstallArtifact {
285
+ const exe = b .addSharedLibrary (.{
250
286
.name = "zigcrypto" ,
251
287
.root_source_file = b .path ("examples/zigcrypto.zig" ),
252
288
.version = null ,
253
289
.target = getTarget (target ),
254
290
.optimize = optimize ,
255
291
});
256
- zigcrypto_loadable_ext .addIncludePath (b .path ("c" ));
257
- zigcrypto_loadable_ext .root_module .addImport ("sqlite" , sqlite_mod );
258
- zigcrypto_loadable_ext .linkLibrary (lib );
292
+ exe .root_module .addImport ("sqlite" , sqlite_mod );
259
293
260
- const install_zigcrypto_loadable_ext = b .addInstallArtifact (zigcrypto_loadable_ext , .{});
294
+ const install_artifact = b .addInstallArtifact (exe , .{});
295
+ install_artifact .step .dependOn (& exe .step );
261
296
297
+ return install_artifact ;
298
+ }
299
+
300
+ fn addZigcryptoTestRun (b : * std.Build , sqlite_mod : * std.Build.Module , target : std.Build.ResolvedTarget , optimize : std.builtin.OptimizeMode ) * std.Build.Step.Run {
262
301
const zigcrypto_test = b .addExecutable (.{
263
302
.name = "zigcrypto-test" ,
264
303
.root_source_file = b .path ("examples/zigcrypto_test.zig" ),
265
304
.target = getTarget (target ),
266
305
.optimize = optimize ,
267
306
});
268
- zigcrypto_test .addIncludePath (b .path ("c" ));
269
307
zigcrypto_test .root_module .addImport ("sqlite" , sqlite_mod );
270
- zigcrypto_test .linkLibrary (lib );
271
308
272
- const install_zigcrypto_test = b .addInstallArtifact (zigcrypto_test , .{});
309
+ const install = b .addInstallArtifact (zigcrypto_test , .{});
310
+ install .step .dependOn (& zigcrypto_test .step );
311
+
312
+ const run = b .addRunArtifact (zigcrypto_test );
313
+ run .step .dependOn (& zigcrypto_test .step );
273
314
274
- const zigcrypto_compile_run = b .step ("zigcrypto" , "Build the 'zigcrypto' SQLite loadable extension" );
275
- zigcrypto_compile_run .dependOn (& install_zigcrypto_loadable_ext .step );
276
- zigcrypto_compile_run .dependOn (& install_zigcrypto_test .step );
315
+ return run ;
277
316
}
278
317
279
318
// See https://www.sqlite.org/compile.html for flags
280
319
const EnableOptions = struct {
281
320
// https://www.sqlite.org/fts5.html
282
321
fts5 : bool = false ,
283
322
};
323
+
324
+ const PreprocessStep = struct {
325
+ const Config = struct {
326
+ source : std.Build.LazyPath ,
327
+ target : std.Build.LazyPath ,
328
+ };
329
+
330
+ step : std.Build.Step ,
331
+
332
+ source : std.Build.LazyPath ,
333
+ target : std.Build.LazyPath ,
334
+
335
+ fn create (owner : * std.Build , config : Config ) * PreprocessStep {
336
+ const step = owner .allocator .create (PreprocessStep ) catch @panic ("OOM" );
337
+ step .* = .{
338
+ .step = std .Build .Step .init (.{
339
+ .id = std .Build .Step .Id .custom ,
340
+ .name = "preprocess" ,
341
+ .owner = owner ,
342
+ .makeFn = make ,
343
+ }),
344
+ .source = config .source ,
345
+ .target = config .target ,
346
+ };
347
+
348
+ return step ;
349
+ }
350
+
351
+ fn make (step : * std.Build.Step , _ : std.Build.Step.MakeOptions ) ! void {
352
+ const ps : * PreprocessStep = @fieldParentPtr ("step" , step );
353
+ const owner = step .owner ;
354
+
355
+ const sqlite3_h = try ps .source .path (owner , "sqlite3.h" ).getPath3 (owner , step ).toString (owner .allocator );
356
+ const sqlite3ext_h = try ps .source .path (owner , "sqlite3ext.h" ).getPath3 (owner , step ).toString (owner .allocator );
357
+
358
+ const loadable_sqlite3_h = try ps .target .path (owner , "loadable-ext-sqlite3.h" ).getPath3 (owner , step ).toString (owner .allocator );
359
+ const loadable_sqlite3ext_h = try ps .target .path (owner , "loadable-ext-sqlite3ext.h" ).getPath3 (owner , step ).toString (owner .allocator );
360
+
361
+ try Preprocessor .sqlite3 (owner .allocator , sqlite3_h , loadable_sqlite3_h );
362
+ try Preprocessor .sqlite3ext (owner .allocator , sqlite3ext_h , loadable_sqlite3ext_h );
363
+ }
364
+ };
0 commit comments