mirror of
https://github.com/ziglang/zig.git
synced 2025-12-06 06:13:07 +00:00
Support passing null to b.dependency()
Both null literals and optionals are supported.
This commit is contained in:
parent
00bc72b5ff
commit
5380e81924
@ -408,104 +408,127 @@ fn createChildOnly(
|
||||
return child;
|
||||
}
|
||||
|
||||
fn userInputOptionsFromArgs(allocator: Allocator, args: anytype) UserInputOptionsMap {
|
||||
var user_input_options = UserInputOptionsMap.init(allocator);
|
||||
fn userInputOptionsFromArgs(arena: Allocator, args: anytype) UserInputOptionsMap {
|
||||
var map = UserInputOptionsMap.init(arena);
|
||||
inline for (@typeInfo(@TypeOf(args)).@"struct".fields) |field| {
|
||||
const v = @field(args, field.name);
|
||||
const T = @TypeOf(v);
|
||||
switch (T) {
|
||||
Target.Query => {
|
||||
user_input_options.put(field.name, .{
|
||||
.name = field.name,
|
||||
.value = .{ .scalar = v.zigTriple(allocator) catch @panic("OOM") },
|
||||
.used = false,
|
||||
}) catch @panic("OOM");
|
||||
user_input_options.put("cpu", .{
|
||||
.name = "cpu",
|
||||
.value = .{ .scalar = v.serializeCpuAlloc(allocator) catch @panic("OOM") },
|
||||
.used = false,
|
||||
}) catch @panic("OOM");
|
||||
},
|
||||
ResolvedTarget => {
|
||||
user_input_options.put(field.name, .{
|
||||
.name = field.name,
|
||||
.value = .{ .scalar = v.query.zigTriple(allocator) catch @panic("OOM") },
|
||||
.used = false,
|
||||
}) catch @panic("OOM");
|
||||
user_input_options.put("cpu", .{
|
||||
.name = "cpu",
|
||||
.value = .{ .scalar = v.query.serializeCpuAlloc(allocator) catch @panic("OOM") },
|
||||
.used = false,
|
||||
}) catch @panic("OOM");
|
||||
},
|
||||
LazyPath => {
|
||||
user_input_options.put(field.name, .{
|
||||
.name = field.name,
|
||||
.value = .{ .lazy_path = v.dupeInner(allocator) },
|
||||
.used = false,
|
||||
}) catch @panic("OOM");
|
||||
},
|
||||
[]const LazyPath => {
|
||||
var list = ArrayList(LazyPath).initCapacity(allocator, v.len) catch @panic("OOM");
|
||||
for (v) |lp| list.appendAssumeCapacity(lp.dupeInner(allocator));
|
||||
user_input_options.put(field.name, .{
|
||||
.name = field.name,
|
||||
.value = .{ .lazy_path_list = list },
|
||||
.used = false,
|
||||
}) catch @panic("OOM");
|
||||
},
|
||||
[]const u8 => {
|
||||
user_input_options.put(field.name, .{
|
||||
.name = field.name,
|
||||
.value = .{ .scalar = v },
|
||||
.used = false,
|
||||
}) catch @panic("OOM");
|
||||
},
|
||||
[]const []const u8 => {
|
||||
var list = ArrayList([]const u8).initCapacity(allocator, v.len) catch @panic("OOM");
|
||||
list.appendSliceAssumeCapacity(v);
|
||||
|
||||
user_input_options.put(field.name, .{
|
||||
.name = field.name,
|
||||
.value = .{ .list = list },
|
||||
.used = false,
|
||||
}) catch @panic("OOM");
|
||||
},
|
||||
else => switch (@typeInfo(T)) {
|
||||
.bool => {
|
||||
user_input_options.put(field.name, .{
|
||||
.name = field.name,
|
||||
.value = .{ .scalar = if (v) "true" else "false" },
|
||||
.used = false,
|
||||
}) catch @panic("OOM");
|
||||
},
|
||||
.@"enum", .enum_literal => {
|
||||
user_input_options.put(field.name, .{
|
||||
.name = field.name,
|
||||
.value = .{ .scalar = @tagName(v) },
|
||||
.used = false,
|
||||
}) catch @panic("OOM");
|
||||
},
|
||||
.comptime_int, .int => {
|
||||
user_input_options.put(field.name, .{
|
||||
.name = field.name,
|
||||
.value = .{ .scalar = std.fmt.allocPrint(allocator, "{d}", .{v}) catch @panic("OOM") },
|
||||
.used = false,
|
||||
}) catch @panic("OOM");
|
||||
},
|
||||
.comptime_float, .float => {
|
||||
user_input_options.put(field.name, .{
|
||||
.name = field.name,
|
||||
.value = .{ .scalar = std.fmt.allocPrint(allocator, "{e}", .{v}) catch @panic("OOM") },
|
||||
.used = false,
|
||||
}) catch @panic("OOM");
|
||||
},
|
||||
else => @compileError("option '" ++ field.name ++ "' has unsupported type: " ++ @typeName(T)),
|
||||
},
|
||||
}
|
||||
if (field.type == @Type(.null)) continue;
|
||||
addUserInputOptionFromArg(arena, &map, field, field.type, @field(args, field.name));
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
return user_input_options;
|
||||
fn addUserInputOptionFromArg(
|
||||
arena: Allocator,
|
||||
map: *UserInputOptionsMap,
|
||||
field: std.builtin.Type.StructField,
|
||||
comptime T: type,
|
||||
/// If null, the value won't be added, but `T` will still be type-checked.
|
||||
maybe_value: ?T,
|
||||
) void {
|
||||
switch (T) {
|
||||
Target.Query => return if (maybe_value) |v| {
|
||||
map.put(field.name, .{
|
||||
.name = field.name,
|
||||
.value = .{ .scalar = v.zigTriple(arena) catch @panic("OOM") },
|
||||
.used = false,
|
||||
}) catch @panic("OOM");
|
||||
map.put("cpu", .{
|
||||
.name = "cpu",
|
||||
.value = .{ .scalar = v.serializeCpuAlloc(arena) catch @panic("OOM") },
|
||||
.used = false,
|
||||
}) catch @panic("OOM");
|
||||
},
|
||||
ResolvedTarget => return if (maybe_value) |v| {
|
||||
map.put(field.name, .{
|
||||
.name = field.name,
|
||||
.value = .{ .scalar = v.query.zigTriple(arena) catch @panic("OOM") },
|
||||
.used = false,
|
||||
}) catch @panic("OOM");
|
||||
map.put("cpu", .{
|
||||
.name = "cpu",
|
||||
.value = .{ .scalar = v.query.serializeCpuAlloc(arena) catch @panic("OOM") },
|
||||
.used = false,
|
||||
}) catch @panic("OOM");
|
||||
},
|
||||
LazyPath => return if (maybe_value) |v| {
|
||||
map.put(field.name, .{
|
||||
.name = field.name,
|
||||
.value = .{ .lazy_path = v.dupeInner(arena) },
|
||||
.used = false,
|
||||
}) catch @panic("OOM");
|
||||
},
|
||||
[]const LazyPath => return if (maybe_value) |v| {
|
||||
var list = ArrayList(LazyPath).initCapacity(arena, v.len) catch @panic("OOM");
|
||||
for (v) |lp| list.appendAssumeCapacity(lp.dupeInner(arena));
|
||||
map.put(field.name, .{
|
||||
.name = field.name,
|
||||
.value = .{ .lazy_path_list = list },
|
||||
.used = false,
|
||||
}) catch @panic("OOM");
|
||||
},
|
||||
[]const u8 => return if (maybe_value) |v| {
|
||||
map.put(field.name, .{
|
||||
.name = field.name,
|
||||
.value = .{ .scalar = v },
|
||||
.used = false,
|
||||
}) catch @panic("OOM");
|
||||
},
|
||||
[]const []const u8 => return if (maybe_value) |v| {
|
||||
var list = ArrayList([]const u8).initCapacity(arena, v.len) catch @panic("OOM");
|
||||
list.appendSliceAssumeCapacity(v);
|
||||
map.put(field.name, .{
|
||||
.name = field.name,
|
||||
.value = .{ .list = list },
|
||||
.used = false,
|
||||
}) catch @panic("OOM");
|
||||
},
|
||||
else => switch (@typeInfo(T)) {
|
||||
.bool => return if (maybe_value) |v| {
|
||||
map.put(field.name, .{
|
||||
.name = field.name,
|
||||
.value = .{ .scalar = if (v) "true" else "false" },
|
||||
.used = false,
|
||||
}) catch @panic("OOM");
|
||||
},
|
||||
.@"enum", .enum_literal => return if (maybe_value) |v| {
|
||||
map.put(field.name, .{
|
||||
.name = field.name,
|
||||
.value = .{ .scalar = @tagName(v) },
|
||||
.used = false,
|
||||
}) catch @panic("OOM");
|
||||
},
|
||||
.comptime_int, .int => return if (maybe_value) |v| {
|
||||
map.put(field.name, .{
|
||||
.name = field.name,
|
||||
.value = .{ .scalar = std.fmt.allocPrint(arena, "{d}", .{v}) catch @panic("OOM") },
|
||||
.used = false,
|
||||
}) catch @panic("OOM");
|
||||
},
|
||||
.comptime_float, .float => return if (maybe_value) |v| {
|
||||
map.put(field.name, .{
|
||||
.name = field.name,
|
||||
.value = .{ .scalar = std.fmt.allocPrint(arena, "{e}", .{v}) catch @panic("OOM") },
|
||||
.used = false,
|
||||
}) catch @panic("OOM");
|
||||
},
|
||||
.null => unreachable,
|
||||
.optional => |info| switch (@typeInfo(info.child)) {
|
||||
.optional => {},
|
||||
else => {
|
||||
addUserInputOptionFromArg(
|
||||
arena,
|
||||
map,
|
||||
field,
|
||||
info.child,
|
||||
maybe_value orelse null,
|
||||
);
|
||||
return;
|
||||
},
|
||||
},
|
||||
else => {},
|
||||
},
|
||||
}
|
||||
@compileError("option '" ++ field.name ++ "' has unsupported type: " ++ @typeName(field.type));
|
||||
}
|
||||
|
||||
const OrderedUserValue = union(enum) {
|
||||
|
||||
@ -12,6 +12,29 @@ pub fn build(b: *std.Build) !void {
|
||||
if (!none_specified_mod.resolved_target.?.query.eql(b.graph.host.query)) return error.TestFailed;
|
||||
if (none_specified_mod.optimize.? != .Debug) return error.TestFailed;
|
||||
|
||||
// Passing null is the same as not specifying the option,
|
||||
// so this should resolve to the same cached dependency instance.
|
||||
const null_specified = b.dependency("other", .{
|
||||
// Null literals
|
||||
.target = null,
|
||||
.optimize = null,
|
||||
.bool = null,
|
||||
|
||||
// Optionals
|
||||
.int = @as(?i64, null),
|
||||
.float = @as(?f64, null),
|
||||
|
||||
// Optionals of the wrong type
|
||||
.string = @as(?usize, null),
|
||||
.@"enum" = @as(?bool, null),
|
||||
|
||||
// Non-defined option names
|
||||
.this_option_does_not_exist = null,
|
||||
.neither_does_this_one = @as(?[]const u8, null),
|
||||
});
|
||||
|
||||
if (null_specified != none_specified) return error.TestFailed;
|
||||
|
||||
const all_specified = b.dependency("other", .{
|
||||
.target = b.resolveTargetQuery(.{ .cpu_arch = .x86_64, .os_tag = .windows, .abi = .gnu }),
|
||||
.optimize = @as(std.builtin.OptimizeMode, .ReleaseSafe),
|
||||
@ -37,6 +60,27 @@ pub fn build(b: *std.Build) !void {
|
||||
if (all_specified_mod.resolved_target.?.result.abi != .gnu) return error.TestFailed;
|
||||
if (all_specified_mod.optimize.? != .ReleaseSafe) return error.TestFailed;
|
||||
|
||||
const all_specified_optional = b.dependency("other", .{
|
||||
.target = @as(?std.Build.ResolvedTarget, b.resolveTargetQuery(.{ .cpu_arch = .x86_64, .os_tag = .windows, .abi = .gnu })),
|
||||
.optimize = @as(?std.builtin.OptimizeMode, .ReleaseSafe),
|
||||
.bool = @as(?bool, true),
|
||||
.int = @as(?i64, 123),
|
||||
.float = @as(?f64, 0.5),
|
||||
.string = @as(?[]const u8, "abc"),
|
||||
.string_list = @as(?[]const []const u8, &.{ "a", "b", "c" }),
|
||||
.lazy_path = @as(?std.Build.LazyPath, .{ .cwd_relative = "abc.txt" }),
|
||||
.lazy_path_list = @as(?[]const std.Build.LazyPath, &.{
|
||||
.{ .cwd_relative = "a.txt" },
|
||||
.{ .cwd_relative = "b.txt" },
|
||||
.{ .cwd_relative = "c.txt" },
|
||||
}),
|
||||
.@"enum" = @as(?Enum, .alfa),
|
||||
//.enum_list = @as(?[]const Enum, &.{ .alfa, .bravo, .charlie }),
|
||||
//.build_id = @as(?std.zig.BuildId, .uuid),
|
||||
});
|
||||
|
||||
if (all_specified_optional != all_specified) return error.TestFailed;
|
||||
|
||||
// Most supported option types are serialized to a string representation,
|
||||
// so alternative representations of the same option value should resolve
|
||||
// to the same cached dependency instance.
|
||||
@ -59,5 +103,5 @@ pub fn build(b: *std.Build) !void {
|
||||
//.build_id = @as(std.zig.BuildId, .uuid),
|
||||
});
|
||||
|
||||
if (all_specified != all_specified_alt) return error.TestFailed;
|
||||
if (all_specified_alt != all_specified) return error.TestFailed;
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user