@@ -69,13 +69,15 @@ pub const Builder = struct {
69
69
search_prefixes : ArrayList ([]const u8 ),
70
70
libc_file : ? []const u8 = null ,
71
71
installed_files : ArrayList (InstalledFile ),
72
+ /// Path to the directory containing build.zig.
72
73
build_root : []const u8 ,
73
74
cache_root : []const u8 ,
74
75
global_cache_root : []const u8 ,
75
76
release_mode : ? std.builtin.Mode ,
76
77
is_release : bool ,
78
+ /// zig lib dir
77
79
override_lib_dir : ? []const u8 ,
78
- vcpkg_root : VcpkgRoot ,
80
+ vcpkg_root : VcpkgRoot = .unattempted ,
79
81
pkg_config_pkg_list : ? (PkgConfigError ! []const PkgConfigPkg ) = null ,
80
82
args : ? [][]const u8 = null ,
81
83
debug_log_scopes : []const []const u8 = &.{},
@@ -100,6 +102,8 @@ pub const Builder = struct {
100
102
/// Information about the native target. Computed before build() is invoked.
101
103
host : NativeTargetInfo ,
102
104
105
+ dep_prefix : []const u8 = "" ,
106
+
103
107
pub const ExecError = error {
104
108
ReadFailure ,
105
109
ExitCodeFailure ,
@@ -223,7 +227,6 @@ pub const Builder = struct {
223
227
.is_release = false ,
224
228
.override_lib_dir = null ,
225
229
.install_path = undefined ,
226
- .vcpkg_root = VcpkgRoot { .unattempted = {} },
227
230
.args = null ,
228
231
.host = host ,
229
232
};
@@ -233,6 +236,92 @@ pub const Builder = struct {
233
236
return self ;
234
237
}
235
238
239
+ fn createChild (
240
+ parent : * Builder ,
241
+ dep_name : []const u8 ,
242
+ build_root : []const u8 ,
243
+ args : anytype ,
244
+ ) ! * Builder {
245
+ const child = try createChildOnly (parent , dep_name , build_root );
246
+ try applyArgs (child , args );
247
+ return child ;
248
+ }
249
+
250
+ fn createChildOnly (parent : * Builder , dep_name : []const u8 , build_root : []const u8 ) ! * Builder {
251
+ const allocator = parent .allocator ;
252
+ const child = try allocator .create (Builder );
253
+ child .* = .{
254
+ .allocator = allocator ,
255
+ .install_tls = .{
256
+ .step = Step .initNoOp (.top_level , "install" , allocator ),
257
+ .description = "Copy build artifacts to prefix path" ,
258
+ },
259
+ .uninstall_tls = .{
260
+ .step = Step .init (.top_level , "uninstall" , allocator , makeUninstall ),
261
+ .description = "Remove build artifacts from prefix path" ,
262
+ },
263
+ .user_input_options = UserInputOptionsMap .init (allocator ),
264
+ .available_options_map = AvailableOptionsMap .init (allocator ),
265
+ .available_options_list = ArrayList (AvailableOption ).init (allocator ),
266
+ .verbose = parent .verbose ,
267
+ .verbose_link = parent .verbose_link ,
268
+ .verbose_cc = parent .verbose_cc ,
269
+ .verbose_air = parent .verbose_air ,
270
+ .verbose_llvm_ir = parent .verbose_llvm_ir ,
271
+ .verbose_cimport = parent .verbose_cimport ,
272
+ .verbose_llvm_cpu_features = parent .verbose_llvm_cpu_features ,
273
+ .prominent_compile_errors = parent .prominent_compile_errors ,
274
+ .color = parent .color ,
275
+ .reference_trace = parent .reference_trace ,
276
+ .invalid_user_input = false ,
277
+ .zig_exe = parent .zig_exe ,
278
+ .default_step = undefined ,
279
+ .env_map = parent .env_map ,
280
+ .top_level_steps = ArrayList (* TopLevelStep ).init (allocator ),
281
+ .install_prefix = undefined ,
282
+ .dest_dir = parent .dest_dir ,
283
+ .lib_dir = parent .lib_dir ,
284
+ .exe_dir = parent .exe_dir ,
285
+ .h_dir = parent .h_dir ,
286
+ .install_path = parent .install_path ,
287
+ .sysroot = parent .sysroot ,
288
+ .search_prefixes = ArrayList ([]const u8 ).init (allocator ),
289
+ .libc_file = parent .libc_file ,
290
+ .installed_files = ArrayList (InstalledFile ).init (allocator ),
291
+ .build_root = build_root ,
292
+ .cache_root = parent .cache_root ,
293
+ .global_cache_root = parent .global_cache_root ,
294
+ .release_mode = parent .release_mode ,
295
+ .is_release = parent .is_release ,
296
+ .override_lib_dir = parent .override_lib_dir ,
297
+ .debug_log_scopes = parent .debug_log_scopes ,
298
+ .debug_compile_errors = parent .debug_compile_errors ,
299
+ .enable_darling = parent .enable_darling ,
300
+ .enable_qemu = parent .enable_qemu ,
301
+ .enable_rosetta = parent .enable_rosetta ,
302
+ .enable_wasmtime = parent .enable_wasmtime ,
303
+ .enable_wine = parent .enable_wine ,
304
+ .glibc_runtimes_dir = parent .glibc_runtimes_dir ,
305
+ .host = parent .host ,
306
+ .dep_prefix = parent .fmt ("{s}{s}." , .{ parent .dep_prefix , dep_name }),
307
+ };
308
+ try child .top_level_steps .append (& child .install_tls );
309
+ try child .top_level_steps .append (& child .uninstall_tls );
310
+ child .default_step = & child .install_tls .step ;
311
+ return child ;
312
+ }
313
+
314
+ fn applyArgs (b : * Builder , args : anytype ) ! void {
315
+ // TODO this function is the way that a build.zig file communicates
316
+ // options to its dependencies. It is the programmatic way to give
317
+ // command line arguments to a build.zig script.
318
+ _ = args ;
319
+ // TODO create a hash based on the args and the package hash, use this
320
+ // to compute the install prefix.
321
+ const install_prefix = b .pathJoin (&.{ b .cache_root , "pkg" });
322
+ b .resolveInstallPrefix (install_prefix , .{});
323
+ }
324
+
236
325
pub fn destroy (self : * Builder ) void {
237
326
self .env_map .deinit ();
238
327
self .top_level_steps .deinit ();
@@ -1068,6 +1157,10 @@ pub const Builder = struct {
1068
1157
return self .addInstallFileWithDir (source .dupe (self ), .lib , dest_rel_path );
1069
1158
}
1070
1159
1160
+ pub fn addInstallHeaderFile (b : * Builder , src_path : []const u8 , dest_rel_path : []const u8 ) * InstallFileStep {
1161
+ return b .addInstallFileWithDir (.{ .path = src_path }, .header , dest_rel_path );
1162
+ }
1163
+
1071
1164
pub fn addInstallRaw (self : * Builder , artifact : * LibExeObjStep , dest_filename : []const u8 , options : InstallRawStep.CreateOptions ) * InstallRawStep {
1072
1165
return InstallRawStep .create (self , artifact , dest_filename , options );
1073
1166
}
@@ -1300,6 +1393,70 @@ pub const Builder = struct {
1300
1393
&[_ ][]const u8 { base_dir , dest_rel_path },
1301
1394
) catch unreachable ;
1302
1395
}
1396
+
1397
+ pub const Dependency = struct {
1398
+ builder : * Builder ,
1399
+
1400
+ pub fn artifact (d : * Dependency , name : []const u8 ) * LibExeObjStep {
1401
+ var found : ? * LibExeObjStep = null ;
1402
+ for (d .builder .install_tls .step .dependencies .items ) | dep_step | {
1403
+ const inst = dep_step .cast (InstallArtifactStep ) orelse continue ;
1404
+ if (mem .eql (u8 , inst .artifact .name , name )) {
1405
+ if (found != null ) panic ("artifact name '{s}' is ambiguous" , .{name });
1406
+ found = inst .artifact ;
1407
+ }
1408
+ }
1409
+ return found orelse {
1410
+ for (d .builder .install_tls .step .dependencies .items ) | dep_step | {
1411
+ const inst = dep_step .cast (InstallArtifactStep ) orelse continue ;
1412
+ log .info ("available artifact: '{s}'" , .{inst .artifact .name });
1413
+ }
1414
+ panic ("unable to find artifact '{s}'" , .{name });
1415
+ };
1416
+ }
1417
+ };
1418
+
1419
+ pub fn dependency (b : * Builder , name : []const u8 , args : anytype ) * Dependency {
1420
+ const build_runner = @import ("root" );
1421
+ const deps = build_runner .dependencies ;
1422
+
1423
+ inline for (@typeInfo (deps .imports ).Struct .decls ) | decl | {
1424
+ if (mem .startsWith (u8 , decl .name , b .dep_prefix ) and
1425
+ mem .endsWith (u8 , decl .name , name ) and
1426
+ decl .name .len == b .dep_prefix .len + name .len )
1427
+ {
1428
+ const build_zig = @field (deps .imports , decl .name );
1429
+ const build_root = @field (deps .build_root , decl .name );
1430
+ return dependencyInner (b , name , build_root , build_zig , args );
1431
+ }
1432
+ }
1433
+
1434
+ const full_path = b .pathFromRoot ("build.zig.ini" );
1435
+ std .debug .print ("no dependency named '{s}' in '{s}'\n " , .{ name , full_path });
1436
+ std .process .exit (1 );
1437
+ }
1438
+
1439
+ fn dependencyInner (
1440
+ b : * Builder ,
1441
+ name : []const u8 ,
1442
+ build_root : []const u8 ,
1443
+ comptime build_zig : type ,
1444
+ args : anytype ,
1445
+ ) * Dependency {
1446
+ const sub_builder = b .createChild (name , build_root , args ) catch unreachable ;
1447
+ sub_builder .runBuild (build_zig ) catch unreachable ;
1448
+ const dep = b .allocator .create (Dependency ) catch unreachable ;
1449
+ dep .* = .{ .builder = sub_builder };
1450
+ return dep ;
1451
+ }
1452
+
1453
+ pub fn runBuild (b : * Builder , build_zig : anytype ) anyerror ! void {
1454
+ switch (@typeInfo (@typeInfo (@TypeOf (build_zig .build )).Fn .return_type .? )) {
1455
+ .Void = > build_zig .build (b ),
1456
+ .ErrorUnion = > try build_zig .build (b ),
1457
+ else = > @compileError ("expected return type of build to be 'void' or '!void'" ),
1458
+ }
1459
+ }
1303
1460
};
1304
1461
1305
1462
test "builder.findProgram compiles" {
0 commit comments