diff --git a/lib/std/Build.zig b/lib/std/Build.zig index e65a71e12b..d6b0e68f5d 100644 --- a/lib/std/Build.zig +++ b/lib/std/Build.zig @@ -408,104 +408,179 @@ 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"); + }, + std.zig.BuildId => return if (maybe_value) |v| { + map.put(field.name, .{ + .name = field.name, + .value = .{ .scalar = std.fmt.allocPrint(arena, "{f}", .{v}) 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 = arena.dupe(u8, v) catch @panic("OOM") }, + .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"); + for (v) |s| list.appendAssumeCapacity(arena.dupe(u8, s) catch @panic("OOM")); + 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, "{x}", .{v}) catch @panic("OOM") }, + .used = false, + }) catch @panic("OOM"); + }, + .pointer => |ptr_info| switch (ptr_info.size) { + .one => switch (@typeInfo(ptr_info.child)) { + .array => |array_info| { + comptime var slice_info = ptr_info; + slice_info.size = .slice; + slice_info.is_const = true; + slice_info.child = array_info.child; + slice_info.sentinel_ptr = null; + addUserInputOptionFromArg( + arena, + map, + field, + @Type(.{ .pointer = slice_info }), + maybe_value orelse null, + ); + return; + }, + else => {}, + }, + .slice => switch (@typeInfo(ptr_info.child)) { + .@"enum" => return if (maybe_value) |v| { + var list = ArrayList([]const u8).initCapacity(arena, v.len) catch @panic("OOM"); + for (v) |tag| list.appendAssumeCapacity(@tagName(tag)); + map.put(field.name, .{ + .name = field.name, + .value = .{ .list = list }, + .used = false, + }) catch @panic("OOM"); + }, + else => { + comptime var slice_info = ptr_info; + slice_info.is_const = true; + slice_info.sentinel_ptr = null; + addUserInputOptionFromArg( + arena, + map, + field, + @Type(.{ .pointer = slice_info }), + maybe_value orelse null, + ); + return; + }, + }, + else => {}, + }, + .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) { diff --git a/lib/std/Io/Writer.zig b/lib/std/Io/Writer.zig index 55672c557c..a9595a1dc7 100644 --- a/lib/std/Io/Writer.zig +++ b/lib/std/Io/Writer.zig @@ -1564,17 +1564,23 @@ pub fn printFloatHexOptions(w: *Writer, value: anytype, options: std.fmt.Number) } pub fn printFloatHex(w: *Writer, value: anytype, case: std.fmt.Case, opt_precision: ?usize) Error!void { - if (std.math.signbit(value)) try w.writeByte('-'); - if (std.math.isNan(value)) return w.writeAll(switch (case) { + const v = switch (@TypeOf(value)) { + // comptime_float internally is a f128; this preserves precision. + comptime_float => @as(f128, value), + else => value, + }; + + if (std.math.signbit(v)) try w.writeByte('-'); + if (std.math.isNan(v)) return w.writeAll(switch (case) { .lower => "nan", .upper => "NAN", }); - if (std.math.isInf(value)) return w.writeAll(switch (case) { + if (std.math.isInf(v)) return w.writeAll(switch (case) { .lower => "inf", .upper => "INF", }); - const T = @TypeOf(value); + const T = @TypeOf(v); const TU = std.meta.Int(.unsigned, @bitSizeOf(T)); const mantissa_bits = std.math.floatMantissaBits(T); @@ -1584,7 +1590,7 @@ pub fn printFloatHex(w: *Writer, value: anytype, case: std.fmt.Case, opt_precisi const exponent_mask = (1 << exponent_bits) - 1; const exponent_bias = (1 << (exponent_bits - 1)) - 1; - const as_bits: TU = @bitCast(value); + const as_bits: TU = @bitCast(v); var mantissa = as_bits & mantissa_mask; var exponent: i32 = @as(u16, @truncate((as_bits >> mantissa_bits) & exponent_mask)); diff --git a/lib/std/zig.zig b/lib/std/zig.zig index 486947768d..2039a4d8c0 100644 --- a/lib/std/zig.zig +++ b/lib/std/zig.zig @@ -321,6 +321,27 @@ pub const BuildId = union(enum) { try std.testing.expectError(error.InvalidCharacter, parse("0xfoobbb")); try std.testing.expectError(error.InvalidBuildIdStyle, parse("yaddaxxx")); } + + pub fn format(id: BuildId, writer: *std.io.Writer) std.io.Writer.Error!void { + switch (id) { + .none, .fast, .uuid, .sha1, .md5 => { + try writer.writeAll(@tagName(id)); + }, + .hexstring => |hs| { + try writer.print("0x{x}", .{hs.toSlice()}); + }, + } + } + + test format { + try std.testing.expectFmt("none", "{f}", .{@as(BuildId, .none)}); + try std.testing.expectFmt("fast", "{f}", .{@as(BuildId, .fast)}); + try std.testing.expectFmt("uuid", "{f}", .{@as(BuildId, .uuid)}); + try std.testing.expectFmt("sha1", "{f}", .{@as(BuildId, .sha1)}); + try std.testing.expectFmt("md5", "{f}", .{@as(BuildId, .md5)}); + try std.testing.expectFmt("0x", "{f}", .{BuildId.initHexString("")}); + try std.testing.expectFmt("0x1234cdef", "{f}", .{BuildId.initHexString("\x12\x34\xcd\xef")}); + } }; pub const LtoMode = enum { none, full, thin }; diff --git a/test/link/build.zig.zon b/test/link/build.zig.zon index 16bba08c4e..ab44726091 100644 --- a/test/link/build.zig.zon +++ b/test/link/build.zig.zon @@ -1,5 +1,6 @@ .{ - .name = "link_test_cases", + .name = .link_test_cases, + .fingerprint = 0x404f657576fec9f2, .version = "0.0.0", .dependencies = .{ .bss = .{ diff --git a/test/standalone/build.zig.zon b/test/standalone/build.zig.zon index 8cf899477f..bdd059ab37 100644 --- a/test/standalone/build.zig.zon +++ b/test/standalone/build.zig.zon @@ -1,6 +1,6 @@ .{ .name = .standalone_test_cases, - .fingerprint = 0xc0dbdf9c818957be, + .fingerprint = 0xc0dbdf9c3b92810b, .version = "0.0.0", .dependencies = .{ .simple = .{ @@ -181,6 +181,9 @@ .install_headers = .{ .path = "install_headers", }, + .dependency_options = .{ + .path = "dependency_options", + }, .dependencyFromBuildZig = .{ .path = "dependencyFromBuildZig", }, diff --git a/test/standalone/dependencyFromBuildZig/build.zig.zon b/test/standalone/dependencyFromBuildZig/build.zig.zon index 085ae2c80b..fda6a098d8 100644 --- a/test/standalone/dependencyFromBuildZig/build.zig.zon +++ b/test/standalone/dependencyFromBuildZig/build.zig.zon @@ -1,5 +1,6 @@ .{ - .name = "dependencyFromBuildZig", + .name = .dependencyFromBuildZig, + .fingerprint = 0xfd939a1eb8169080, .version = "0.0.0", .dependencies = .{ .other = .{ diff --git a/test/standalone/dependencyFromBuildZig/other/build.zig.zon b/test/standalone/dependencyFromBuildZig/other/build.zig.zon index 204abdbbba..bb8fcb6fb4 100644 --- a/test/standalone/dependencyFromBuildZig/other/build.zig.zon +++ b/test/standalone/dependencyFromBuildZig/other/build.zig.zon @@ -1,5 +1,6 @@ .{ - .name = "other", + .name = .other, + .fingerprint = 0xd9583520a2405f6c, .version = "0.0.0", .dependencies = .{}, .paths = .{""}, diff --git a/test/standalone/dependency_options/build.zig b/test/standalone/dependency_options/build.zig new file mode 100644 index 0000000000..20e2db1fa2 --- /dev/null +++ b/test/standalone/dependency_options/build.zig @@ -0,0 +1,141 @@ +const std = @import("std"); + +pub const Enum = enum { alfa, bravo, charlie }; + +pub fn build(b: *std.Build) !void { + const test_step = b.step("test", "Test passing options to a dependency"); + b.default_step = test_step; + + const none_specified = b.dependency("other", .{}); + + const none_specified_mod = none_specified.module("dummy"); + 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), + .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), + .hex_build_id = std.zig.BuildId.initHexString("\x12\x34\xcd\xef"), + }); + + const all_specified_mod = all_specified.module("dummy"); + if (all_specified_mod.resolved_target.?.result.cpu.arch != .x86_64) return error.TestFailed; + if (all_specified_mod.resolved_target.?.result.os.tag != .windows) return error.TestFailed; + 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), + .hex_build_id = @as(?std.zig.BuildId, .initHexString("\x12\x34\xcd\xef")), + }); + + if (all_specified_optional != all_specified) return error.TestFailed; + + const all_specified_literal = b.dependency("other", .{ + .target = b.resolveTargetQuery(.{ .cpu_arch = .x86_64, .os_tag = .windows, .abi = .gnu }), + .optimize = .ReleaseSafe, + .bool = true, + .int = 123, + .float = 0.5, + .string = "abc", + .string_list = &[_][]const u8{ "a", "b", "c" }, + .lazy_path = @as(std.Build.LazyPath, .{ .cwd_relative = "abc.txt" }), + .lazy_path_list = &[_]std.Build.LazyPath{ + .{ .cwd_relative = "a.txt" }, + .{ .cwd_relative = "b.txt" }, + .{ .cwd_relative = "c.txt" }, + }, + .@"enum" = .alfa, + .enum_list = &[_]Enum{ .alfa, .bravo, .charlie }, + .build_id = .uuid, + .hex_build_id = std.zig.BuildId.initHexString("\x12\x34\xcd\xef"), + }); + + if (all_specified_literal != all_specified) return error.TestFailed; + + var mut_string_buf = "abc".*; + const mut_string: []u8 = &mut_string_buf; + var mut_string_list_buf = [_][]const u8{ "a", "b", "c" }; + const mut_string_list: [][]const u8 = &mut_string_list_buf; + var mut_lazy_path_list_buf = [_]std.Build.LazyPath{ + .{ .cwd_relative = "a.txt" }, + .{ .cwd_relative = "b.txt" }, + .{ .cwd_relative = "c.txt" }, + }; + const mut_lazy_path_list: []std.Build.LazyPath = &mut_lazy_path_list_buf; + var mut_enum_list_buf = [_]Enum{ .alfa, .bravo, .charlie }; + const mut_enum_list: []Enum = &mut_enum_list_buf; + + // 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. + const all_specified_alt = b.dependency("other", .{ + .target = @as(std.Target.Query, .{ .cpu_arch = .x86_64, .os_tag = .windows, .abi = .gnu }), + .optimize = "ReleaseSafe", + .bool = .true, + .int = "123", + .float = @as(f16, 0.5), + .string = mut_string, + .string_list = mut_string_list, + .lazy_path = @as(std.Build.LazyPath, .{ .cwd_relative = "abc.txt" }), + .lazy_path_list = mut_lazy_path_list, + .@"enum" = "alfa", + .enum_list = mut_enum_list, + .build_id = "uuid", + .hex_build_id = "0x1234cdef", + }); + + if (all_specified_alt != all_specified) return error.TestFailed; +} diff --git a/test/standalone/dependency_options/build.zig.zon b/test/standalone/dependency_options/build.zig.zon new file mode 100644 index 0000000000..6788640a80 --- /dev/null +++ b/test/standalone/dependency_options/build.zig.zon @@ -0,0 +1,11 @@ +.{ + .name = .dependency_options, + .fingerprint = 0x3e3ce1c1f92ba47e, + .version = "0.0.0", + .dependencies = .{ + .other = .{ + .path = "other", + }, + }, + .paths = .{""}, +} diff --git a/test/standalone/dependency_options/other/build.zig b/test/standalone/dependency_options/other/build.zig new file mode 100644 index 0000000000..c18f92f14d --- /dev/null +++ b/test/standalone/dependency_options/other/build.zig @@ -0,0 +1,59 @@ +const std = @import("std"); + +pub const Enum = enum { alfa, bravo, charlie }; + +pub fn build(b: *std.Build) !void { + const target = b.standardTargetOptions(.{}); + const optimize = b.standardOptimizeOption(.{}); + + const expected_bool: bool = true; + const expected_int: i64 = 123; + const expected_float: f64 = 0.5; + const expected_string: []const u8 = "abc"; + const expected_string_list: []const []const u8 = &.{ "a", "b", "c" }; + const expected_lazy_path: std.Build.LazyPath = .{ .cwd_relative = "abc.txt" }; + const expected_lazy_path_list: []const std.Build.LazyPath = &.{ + .{ .cwd_relative = "a.txt" }, + .{ .cwd_relative = "b.txt" }, + .{ .cwd_relative = "c.txt" }, + }; + const expected_enum: Enum = .alfa; + const expected_enum_list: []const Enum = &.{ .alfa, .bravo, .charlie }; + const expected_build_id: std.zig.BuildId = .uuid; + const expected_hex_build_id: std.zig.BuildId = .initHexString("\x12\x34\xcd\xef"); + + const @"bool" = b.option(bool, "bool", "bool") orelse expected_bool; + const int = b.option(i64, "int", "int") orelse expected_int; + const float = b.option(f64, "float", "float") orelse expected_float; + const string = b.option([]const u8, "string", "string") orelse expected_string; + const string_list = b.option([]const []const u8, "string_list", "string_list") orelse expected_string_list; + const lazy_path = b.option(std.Build.LazyPath, "lazy_path", "lazy_path") orelse expected_lazy_path; + const lazy_path_list = b.option([]const std.Build.LazyPath, "lazy_path_list", "lazy_path_list") orelse expected_lazy_path_list; + const @"enum" = b.option(Enum, "enum", "enum") orelse expected_enum; + const enum_list = b.option([]const Enum, "enum_list", "enum_list") orelse expected_enum_list; + const build_id = b.option(std.zig.BuildId, "build_id", "build_id") orelse expected_build_id; + const hex_build_id = b.option(std.zig.BuildId, "hex_build_id", "hex_build_id") orelse expected_hex_build_id; + + if (@"bool" != expected_bool) return error.TestFailed; + if (int != expected_int) return error.TestFailed; + if (float != expected_float) return error.TestFailed; + if (!std.mem.eql(u8, string, expected_string)) return error.TestFailed; + if (string_list.len != expected_string_list.len) return error.TestFailed; + for (string_list, expected_string_list) |x, y| { + if (!std.mem.eql(u8, x, y)) return error.TestFailed; + } + if (!std.mem.eql(u8, lazy_path.cwd_relative, expected_lazy_path.cwd_relative)) return error.TestFailed; + for (lazy_path_list, expected_lazy_path_list) |x, y| { + if (!std.mem.eql(u8, x.cwd_relative, y.cwd_relative)) return error.TestFailed; + } + if (@"enum" != expected_enum) return error.TestFailed; + if (!std.mem.eql(Enum, enum_list, expected_enum_list)) return error.TestFailed; + if (!std.meta.eql(build_id, expected_build_id)) return error.TestFailed; + if (!hex_build_id.eql(expected_hex_build_id)) return error.TestFailed; + + _ = b.addModule("dummy", .{ + .root_source_file = b.path("build.zig"), + .target = target, + .optimize = optimize, + }); +} diff --git a/test/standalone/dependency_options/other/build.zig.zon b/test/standalone/dependency_options/other/build.zig.zon new file mode 100644 index 0000000000..d49a2cdcf8 --- /dev/null +++ b/test/standalone/dependency_options/other/build.zig.zon @@ -0,0 +1,7 @@ +.{ + .name = .other, + .fingerprint = 0xd95835207bc8b630, + .version = "0.0.0", + .dependencies = .{}, + .paths = .{""}, +}