1const std = @import("std");
  2
  3pub const Enum = enum { alfa, bravo, charlie };
  4
  5pub fn build(b: *std.Build) !void {
  6    const test_step = b.step("test", "Test passing options to a dependency");
  7    b.default_step = test_step;
  8
  9    const none_specified = b.dependency("other", .{});
 10
 11    const none_specified_mod = none_specified.module("dummy");
 12    if (!none_specified_mod.resolved_target.?.query.eql(b.graph.host.query)) return error.TestFailed;
 13    const expected_optimize: std.builtin.OptimizeMode = switch (b.release_mode) {
 14        .off => .Debug,
 15        .any => unreachable,
 16        .fast => .ReleaseFast,
 17        .safe => .ReleaseSafe,
 18        .small => .ReleaseSmall,
 19    };
 20    if (none_specified_mod.optimize.? != expected_optimize) return error.TestFailed;
 21
 22    // Passing null is the same as not specifying the option,
 23    // so this should resolve to the same cached dependency instance.
 24    const null_specified = b.dependency("other", .{
 25        // Null literals
 26        .target = null,
 27        .optimize = null,
 28        .bool = null,
 29
 30        // Optionals
 31        .int = @as(?i64, null),
 32        .float = @as(?f64, null),
 33
 34        // Optionals of the wrong type
 35        .string = @as(?usize, null),
 36        .@"enum" = @as(?bool, null),
 37
 38        // Non-defined option names
 39        .this_option_does_not_exist = null,
 40        .neither_does_this_one = @as(?[]const u8, null),
 41    });
 42
 43    if (null_specified != none_specified) return error.TestFailed;
 44
 45    const all_specified = b.dependency("other", .{
 46        .target = b.resolveTargetQuery(.{ .cpu_arch = .x86_64, .os_tag = .windows, .abi = .gnu }),
 47        .optimize = @as(std.builtin.OptimizeMode, .ReleaseSafe),
 48        .bool = @as(bool, true),
 49        .int = @as(i64, 123),
 50        .float = @as(f64, 0.5),
 51        .string = @as([]const u8, "abc"),
 52        .string_list = @as([]const []const u8, &.{ "a", "b", "c" }),
 53        .lazy_path = @as(std.Build.LazyPath, .{ .cwd_relative = "abc.txt" }),
 54        .lazy_path_list = @as([]const std.Build.LazyPath, &.{
 55            .{ .cwd_relative = "a.txt" },
 56            .{ .cwd_relative = "b.txt" },
 57            .{ .cwd_relative = "c.txt" },
 58        }),
 59        .@"enum" = @as(Enum, .alfa),
 60        .enum_list = @as([]const Enum, &.{ .alfa, .bravo, .charlie }),
 61        .build_id = @as(std.zig.BuildId, .uuid),
 62        .hex_build_id = std.zig.BuildId.initHexString("\x12\x34\xcd\xef"),
 63    });
 64
 65    const all_specified_mod = all_specified.module("dummy");
 66    if (all_specified_mod.resolved_target.?.result.cpu.arch != .x86_64) return error.TestFailed;
 67    if (all_specified_mod.resolved_target.?.result.os.tag != .windows) return error.TestFailed;
 68    if (all_specified_mod.resolved_target.?.result.abi != .gnu) return error.TestFailed;
 69    if (all_specified_mod.optimize.? != .ReleaseSafe) return error.TestFailed;
 70
 71    const all_specified_optional = b.dependency("other", .{
 72        .target = @as(?std.Build.ResolvedTarget, b.resolveTargetQuery(.{ .cpu_arch = .x86_64, .os_tag = .windows, .abi = .gnu })),
 73        .optimize = @as(?std.builtin.OptimizeMode, .ReleaseSafe),
 74        .bool = @as(?bool, true),
 75        .int = @as(?i64, 123),
 76        .float = @as(?f64, 0.5),
 77        .string = @as(?[]const u8, "abc"),
 78        .string_list = @as(?[]const []const u8, &.{ "a", "b", "c" }),
 79        .lazy_path = @as(?std.Build.LazyPath, .{ .cwd_relative = "abc.txt" }),
 80        .lazy_path_list = @as(?[]const std.Build.LazyPath, &.{
 81            .{ .cwd_relative = "a.txt" },
 82            .{ .cwd_relative = "b.txt" },
 83            .{ .cwd_relative = "c.txt" },
 84        }),
 85        .@"enum" = @as(?Enum, .alfa),
 86        .enum_list = @as(?[]const Enum, &.{ .alfa, .bravo, .charlie }),
 87        .build_id = @as(?std.zig.BuildId, .uuid),
 88        .hex_build_id = @as(?std.zig.BuildId, .initHexString("\x12\x34\xcd\xef")),
 89    });
 90
 91    if (all_specified_optional != all_specified) return error.TestFailed;
 92
 93    const all_specified_literal = b.dependency("other", .{
 94        .target = b.resolveTargetQuery(.{ .cpu_arch = .x86_64, .os_tag = .windows, .abi = .gnu }),
 95        .optimize = .ReleaseSafe,
 96        .bool = true,
 97        .int = 123,
 98        .float = 0.5,
 99        .string = "abc",
100        .string_list = &[_][]const u8{ "a", "b", "c" },
101        .lazy_path = @as(std.Build.LazyPath, .{ .cwd_relative = "abc.txt" }),
102        .lazy_path_list = &[_]std.Build.LazyPath{
103            .{ .cwd_relative = "a.txt" },
104            .{ .cwd_relative = "b.txt" },
105            .{ .cwd_relative = "c.txt" },
106        },
107        .@"enum" = .alfa,
108        .enum_list = &[_]Enum{ .alfa, .bravo, .charlie },
109        .build_id = .uuid,
110        .hex_build_id = std.zig.BuildId.initHexString("\x12\x34\xcd\xef"),
111    });
112
113    if (all_specified_literal != all_specified) return error.TestFailed;
114
115    var mut_string_buf = "abc".*;
116    const mut_string: []u8 = &mut_string_buf;
117    var mut_string_list_buf = [_][]const u8{ "a", "b", "c" };
118    const mut_string_list: [][]const u8 = &mut_string_list_buf;
119    var mut_lazy_path_list_buf = [_]std.Build.LazyPath{
120        .{ .cwd_relative = "a.txt" },
121        .{ .cwd_relative = "b.txt" },
122        .{ .cwd_relative = "c.txt" },
123    };
124    const mut_lazy_path_list: []std.Build.LazyPath = &mut_lazy_path_list_buf;
125    var mut_enum_list_buf = [_]Enum{ .alfa, .bravo, .charlie };
126    const mut_enum_list: []Enum = &mut_enum_list_buf;
127
128    // Most supported option types are serialized to a string representation,
129    // so alternative representations of the same option value should resolve
130    // to the same cached dependency instance.
131    const all_specified_alt = b.dependency("other", .{
132        .target = @as(std.Target.Query, .{ .cpu_arch = .x86_64, .os_tag = .windows, .abi = .gnu }),
133        .optimize = "ReleaseSafe",
134        .bool = .true,
135        .int = "123",
136        .float = @as(f16, 0.5),
137        .string = mut_string,
138        .string_list = mut_string_list,
139        .lazy_path = @as(std.Build.LazyPath, .{ .cwd_relative = "abc.txt" }),
140        .lazy_path_list = mut_lazy_path_list,
141        .@"enum" = "alfa",
142        .enum_list = mut_enum_list,
143        .build_id = "uuid",
144        .hex_build_id = "0x1234cdef",
145    });
146
147    if (all_specified_alt != all_specified) return error.TestFailed;
148}