| ... | ... | @@ -30,8 +30,7 @@ install_tls: Step.TopLevel, |
| 30 | 30 | uninstall_tls: Step.TopLevel, |
| 31 | 31 | allocator: Allocator, |
| 32 | 32 | user_input_options: UserInputOptionsMap, |
| 33 | | available_options_map: AvailableOptionsMap, |
| 34 | | available_options_list: std.array_list.Managed(AvailableOption), |
| 33 | available_options_map: std.array_hash_map.String(AvailableOption) = .empty, |
| 35 | 34 | invalid_user_input: bool, |
| 36 | 35 | default_step: *Step, |
| 37 | 36 | top_level_steps: std.StringArrayHashMapUnmanaged(*Step.TopLevel), |
| ... | ... | @@ -180,11 +179,10 @@ pub const RunError = error{ |
| 180 | 179 | } || std.process.SpawnError; |
| 181 | 180 | |
| 182 | 181 | const UserInputOptionsMap = StringHashMap(UserInputOption); |
| 183 | | const AvailableOptionsMap = StringHashMap(AvailableOption); |
| 184 | 182 | |
| 185 | 183 | const AvailableOption = struct { |
| 186 | 184 | name: []const u8, |
| 187 | | type_id: TypeId, |
| 185 | type_id: Configuration.AvailableOption.Type, |
| 188 | 186 | description: []const u8, |
| 189 | 187 | /// If the `type_id` is `enum` or `enum_list` this provides the list of enum options |
| 190 | 188 | enum_options: ?[]const []const u8, |
| ... | ... | @@ -205,19 +203,6 @@ const UserValue = union(enum) { |
| 205 | 203 | lazy_path_list: std.array_list.Managed(LazyPath), |
| 206 | 204 | }; |
| 207 | 205 | |
| 208 | | const TypeId = enum { |
| 209 | | bool, |
| 210 | | int, |
| 211 | | float, |
| 212 | | @"enum", |
| 213 | | enum_list, |
| 214 | | string, |
| 215 | | list, |
| 216 | | build_id, |
| 217 | | lazy_path, |
| 218 | | lazy_path_list, |
| 219 | | }; |
| 220 | | |
| 221 | 206 | pub fn create( |
| 222 | 207 | graph: *Graph, |
| 223 | 208 | available_deps: AvailableDeps, |
| ... | ... | @@ -230,8 +215,6 @@ pub fn create( |
| 230 | 215 | .invalid_user_input = false, |
| 231 | 216 | .allocator = arena, |
| 232 | 217 | .user_input_options = UserInputOptionsMap.init(arena), |
| 233 | | .available_options_map = AvailableOptionsMap.init(arena), |
| 234 | | .available_options_list = std.array_list.Managed(AvailableOption).init(arena), |
| 235 | 218 | .top_level_steps = .{}, |
| 236 | 219 | .default_step = undefined, |
| 237 | 220 | .install_prefix = undefined, |
| ... | ... | @@ -292,8 +275,6 @@ fn createChild( |
| 292 | 275 | .description = "Remove build artifacts from prefix path", |
| 293 | 276 | }, |
| 294 | 277 | .user_input_options = user_input_options, |
| 295 | | .available_options_map = AvailableOptionsMap.init(allocator), |
| 296 | | .available_options_list = std.array_list.Managed(AvailableOption).init(allocator), |
| 297 | 278 | .invalid_user_input = false, |
| 298 | 279 | .default_step = undefined, |
| 299 | 280 | .top_level_steps = .{}, |
| ... | ... | @@ -960,13 +941,14 @@ pub fn getUninstallStep(b: *Build) *Step { |
| 960 | 941 | /// these options when calling the dependency's build.zig script as a function. |
| 961 | 942 | /// `null` is returned when an option is left to default. |
| 962 | 943 | pub fn option(b: *Build, comptime T: type, name_raw: []const u8, description_raw: []const u8) ?T { |
| 944 | const arena = b.allocator; |
| 963 | 945 | const name = b.dupe(name_raw); |
| 964 | 946 | const description = b.dupe(description_raw); |
| 965 | 947 | const type_id = comptime typeToEnum(T); |
| 966 | 948 | const enum_options = if (type_id == .@"enum" or type_id == .enum_list) blk: { |
| 967 | 949 | const EnumType = if (type_id == .enum_list) @typeInfo(T).pointer.child else T; |
| 968 | 950 | const fields = comptime std.meta.fields(EnumType); |
| 969 | | var options = std.array_list.Managed([]const u8).initCapacity(b.allocator, fields.len) catch @panic("OOM"); |
| 951 | var options = std.array_list.Managed([]const u8).initCapacity(arena, fields.len) catch @panic("OOM"); |
| 970 | 952 | |
| 971 | 953 | inline for (fields) |field| { |
| 972 | 954 | options.appendAssumeCapacity(field.name); |
| ... | ... | @@ -980,10 +962,9 @@ pub fn option(b: *Build, comptime T: type, name_raw: []const u8, description_raw |
| 980 | 962 | .description = description, |
| 981 | 963 | .enum_options = enum_options, |
| 982 | 964 | }; |
| 983 | | if ((b.available_options_map.fetchPut(name, available_option) catch @panic("OOM")) != null) { |
| 984 | | panic("Option '{s}' declared twice", .{name}); |
| 965 | if ((b.available_options_map.fetchPut(arena, name, available_option) catch @panic("OOM")) != null) { |
| 966 | panic("option '{s}' declared twice", .{name}); |
| 985 | 967 | } |
| 986 | | b.available_options_list.append(available_option) catch @panic("OOM"); |
| 987 | 968 | |
| 988 | 969 | const option_ptr = b.user_input_options.getPtr(name) orelse return null; |
| 989 | 970 | option_ptr.used = true; |
| ... | ... | @@ -996,36 +977,32 @@ pub fn option(b: *Build, comptime T: type, name_raw: []const u8, description_raw |
| 996 | 977 | } else if (mem.eql(u8, s, "false")) { |
| 997 | 978 | return false; |
| 998 | 979 | } else { |
| 999 | | log.err("Expected -D{s} to be a boolean, but received '{s}'", .{ name, s }); |
| 980 | log.err("expected -D{s} to be a boolean; received: {s}", .{ name, s }); |
| 1000 | 981 | b.markInvalidUserInput(); |
| 1001 | 982 | return null; |
| 1002 | 983 | } |
| 1003 | 984 | }, |
| 1004 | 985 | .list, .map, .lazy_path, .lazy_path_list => { |
| 1005 | | log.err("Expected -D{s} to be a boolean, but received a {s}.", .{ |
| 1006 | | name, @tagName(option_ptr.value), |
| 1007 | | }); |
| 986 | log.err("expected -D{s} to be a boolean; received: {t}", .{ name, option_ptr.value }); |
| 1008 | 987 | b.markInvalidUserInput(); |
| 1009 | 988 | return null; |
| 1010 | 989 | }, |
| 1011 | 990 | }, |
| 1012 | 991 | .int => switch (option_ptr.value) { |
| 1013 | 992 | .flag, .list, .map, .lazy_path, .lazy_path_list => { |
| 1014 | | log.err("Expected -D{s} to be an integer, but received a {s}.", .{ |
| 1015 | | name, @tagName(option_ptr.value), |
| 1016 | | }); |
| 993 | log.err("expected -D{s} to be an integer; received: {t}", .{ name, option_ptr.value }); |
| 1017 | 994 | b.markInvalidUserInput(); |
| 1018 | 995 | return null; |
| 1019 | 996 | }, |
| 1020 | 997 | .scalar => |s| { |
| 1021 | 998 | const n = std.fmt.parseInt(T, s, 10) catch |err| switch (err) { |
| 1022 | 999 | error.Overflow => { |
| 1023 | | log.err("-D{s} value {s} cannot fit into type {s}.", .{ name, s, @typeName(T) }); |
| 1000 | log.err("-D{s} value {s} cannot fit into type {s}", .{ name, s, @typeName(T) }); |
| 1024 | 1001 | b.markInvalidUserInput(); |
| 1025 | 1002 | return null; |
| 1026 | 1003 | }, |
| 1027 | 1004 | else => { |
| 1028 | | log.err("Expected -D{s} to be an integer of type {s}.", .{ name, @typeName(T) }); |
| 1005 | log.err("expected -D{s} to be an integer of type {s}", .{ name, @typeName(T) }); |
| 1029 | 1006 | b.markInvalidUserInput(); |
| 1030 | 1007 | return null; |
| 1031 | 1008 | }, |
| ... | ... | @@ -1035,15 +1012,13 @@ pub fn option(b: *Build, comptime T: type, name_raw: []const u8, description_raw |
| 1035 | 1012 | }, |
| 1036 | 1013 | .float => switch (option_ptr.value) { |
| 1037 | 1014 | .flag, .map, .list, .lazy_path, .lazy_path_list => { |
| 1038 | | log.err("Expected -D{s} to be a float, but received a {s}.", .{ |
| 1039 | | name, @tagName(option_ptr.value), |
| 1040 | | }); |
| 1015 | log.err("expected -D{s} to be a float; received: {t}", .{ name, option_ptr.value }); |
| 1041 | 1016 | b.markInvalidUserInput(); |
| 1042 | 1017 | return null; |
| 1043 | 1018 | }, |
| 1044 | 1019 | .scalar => |s| { |
| 1045 | 1020 | const n = std.fmt.parseFloat(T, s) catch { |
| 1046 | | log.err("Expected -D{s} to be a float of type {s}.", .{ name, @typeName(T) }); |
| 1021 | log.err("expected -D{s} to be a float of type {s}", .{ name, @typeName(T) }); |
| 1047 | 1022 | b.markInvalidUserInput(); |
| 1048 | 1023 | return null; |
| 1049 | 1024 | }; |
| ... | ... | @@ -1052,9 +1027,7 @@ pub fn option(b: *Build, comptime T: type, name_raw: []const u8, description_raw |
| 1052 | 1027 | }, |
| 1053 | 1028 | .@"enum" => switch (option_ptr.value) { |
| 1054 | 1029 | .flag, .map, .list, .lazy_path, .lazy_path_list => { |
| 1055 | | log.err("Expected -D{s} to be an enum, but received a {s}.", .{ |
| 1056 | | name, @tagName(option_ptr.value), |
| 1057 | | }); |
| 1030 | log.err("expected -D{s} to be an enum; received: {t}.", .{ name, option_ptr.value }); |
| 1058 | 1031 | b.markInvalidUserInput(); |
| 1059 | 1032 | return null; |
| 1060 | 1033 | }, |
| ... | ... | @@ -1062,7 +1035,7 @@ pub fn option(b: *Build, comptime T: type, name_raw: []const u8, description_raw |
| 1062 | 1035 | if (std.meta.stringToEnum(T, s)) |enum_lit| { |
| 1063 | 1036 | return enum_lit; |
| 1064 | 1037 | } else { |
| 1065 | | log.err("Expected -D{s} to be of type {s}.", .{ name, @typeName(T) }); |
| 1038 | log.err("expected -D{s} to be of type {s}", .{ name, @typeName(T) }); |
| 1066 | 1039 | b.markInvalidUserInput(); |
| 1067 | 1040 | return null; |
| 1068 | 1041 | } |
| ... | ... | @@ -1070,9 +1043,7 @@ pub fn option(b: *Build, comptime T: type, name_raw: []const u8, description_raw |
| 1070 | 1043 | }, |
| 1071 | 1044 | .string => switch (option_ptr.value) { |
| 1072 | 1045 | .flag, .list, .map, .lazy_path, .lazy_path_list => { |
| 1073 | | log.err("Expected -D{s} to be a string, but received a {s}.", .{ |
| 1074 | | name, @tagName(option_ptr.value), |
| 1075 | | }); |
| 1046 | log.err("expected -D{s} to be a string; received: {t}", .{ name, option_ptr.value }); |
| 1076 | 1047 | b.markInvalidUserInput(); |
| 1077 | 1048 | return null; |
| 1078 | 1049 | }, |
| ... | ... | @@ -1080,9 +1051,7 @@ pub fn option(b: *Build, comptime T: type, name_raw: []const u8, description_raw |
| 1080 | 1051 | }, |
| 1081 | 1052 | .build_id => switch (option_ptr.value) { |
| 1082 | 1053 | .flag, .map, .list, .lazy_path, .lazy_path_list => { |
| 1083 | | log.err("Expected -D{s} to be an enum, but received a {s}.", .{ |
| 1084 | | name, @tagName(option_ptr.value), |
| 1085 | | }); |
| 1054 | log.err("expected -D{s} to be an enum; received: {t}.", .{ name, option_ptr.value }); |
| 1086 | 1055 | b.markInvalidUserInput(); |
| 1087 | 1056 | return null; |
| 1088 | 1057 | }, |
| ... | ... | @@ -1090,7 +1059,7 @@ pub fn option(b: *Build, comptime T: type, name_raw: []const u8, description_raw |
| 1090 | 1059 | if (std.zig.BuildId.parse(s)) |build_id| { |
| 1091 | 1060 | return build_id; |
| 1092 | 1061 | } else |err| { |
| 1093 | | log.err("unable to parse option '-D{s}': {t}", .{ name, err }); |
| 1062 | log.err("failed to parse option -D{s}: {t}", .{ name, err }); |
| 1094 | 1063 | b.markInvalidUserInput(); |
| 1095 | 1064 | return null; |
| 1096 | 1065 | } |
| ... | ... | @@ -1098,42 +1067,38 @@ pub fn option(b: *Build, comptime T: type, name_raw: []const u8, description_raw |
| 1098 | 1067 | }, |
| 1099 | 1068 | .list => switch (option_ptr.value) { |
| 1100 | 1069 | .flag, .map, .lazy_path, .lazy_path_list => { |
| 1101 | | log.err("Expected -D{s} to be a list, but received a {s}.", .{ |
| 1102 | | name, @tagName(option_ptr.value), |
| 1103 | | }); |
| 1070 | log.err("expected -D{s} to be a list; received: {t}", .{ name, option_ptr.value }); |
| 1104 | 1071 | b.markInvalidUserInput(); |
| 1105 | 1072 | return null; |
| 1106 | 1073 | }, |
| 1107 | 1074 | .scalar => |s| { |
| 1108 | | return b.allocator.dupe([]const u8, &[_][]const u8{s}) catch @panic("OOM"); |
| 1075 | return arena.dupe([]const u8, &[_][]const u8{s}) catch @panic("OOM"); |
| 1109 | 1076 | }, |
| 1110 | 1077 | .list => |lst| return lst.items, |
| 1111 | 1078 | }, |
| 1112 | 1079 | .enum_list => switch (option_ptr.value) { |
| 1113 | 1080 | .flag, .map, .lazy_path, .lazy_path_list => { |
| 1114 | | log.err("Expected -D{s} to be a list, but received a {s}.", .{ |
| 1115 | | name, @tagName(option_ptr.value), |
| 1116 | | }); |
| 1081 | log.err("expected -D{s} to be a list; received: {t}", .{ name, option_ptr.value }); |
| 1117 | 1082 | b.markInvalidUserInput(); |
| 1118 | 1083 | return null; |
| 1119 | 1084 | }, |
| 1120 | 1085 | .scalar => |s| { |
| 1121 | 1086 | const Child = @typeInfo(T).pointer.child; |
| 1122 | 1087 | const value = std.meta.stringToEnum(Child, s) orelse { |
| 1123 | | log.err("Expected -D{s} to be of type {s}.", .{ name, @typeName(Child) }); |
| 1088 | log.err("expected -D{s} to be of type {s}", .{ name, @typeName(Child) }); |
| 1124 | 1089 | b.markInvalidUserInput(); |
| 1125 | 1090 | return null; |
| 1126 | 1091 | }; |
| 1127 | | return b.allocator.dupe(Child, &[_]Child{value}) catch @panic("OOM"); |
| 1092 | return arena.dupe(Child, &[_]Child{value}) catch @panic("OOM"); |
| 1128 | 1093 | }, |
| 1129 | 1094 | .list => |lst| { |
| 1130 | 1095 | const Child = @typeInfo(T).pointer.child; |
| 1131 | | const new_list = b.allocator.alloc(Child, lst.items.len) catch @panic("OOM"); |
| 1096 | const new_list = arena.alloc(Child, lst.items.len) catch @panic("OOM"); |
| 1132 | 1097 | for (new_list, lst.items) |*new_item, str| { |
| 1133 | 1098 | new_item.* = std.meta.stringToEnum(Child, str) orelse { |
| 1134 | | log.err("Expected -D{s} to be of type {s}.", .{ name, @typeName(Child) }); |
| 1099 | log.err("expected -D{s} to be of type {s}", .{ name, @typeName(Child) }); |
| 1135 | 1100 | b.markInvalidUserInput(); |
| 1136 | | b.allocator.free(new_list); |
| 1101 | arena.free(new_list); |
| 1137 | 1102 | return null; |
| 1138 | 1103 | }; |
| 1139 | 1104 | } |
| ... | ... | @@ -1144,18 +1109,16 @@ pub fn option(b: *Build, comptime T: type, name_raw: []const u8, description_raw |
| 1144 | 1109 | .scalar => |s| return .{ .cwd_relative = s }, |
| 1145 | 1110 | .lazy_path => |lp| return lp, |
| 1146 | 1111 | .flag, .map, .list, .lazy_path_list => { |
| 1147 | | log.err("Expected -D{s} to be a path, but received a {s}.", .{ |
| 1148 | | name, @tagName(option_ptr.value), |
| 1149 | | }); |
| 1112 | log.err("expected -D{s} to be a path; received: {t}", .{ name, option_ptr.value }); |
| 1150 | 1113 | b.markInvalidUserInput(); |
| 1151 | 1114 | return null; |
| 1152 | 1115 | }, |
| 1153 | 1116 | }, |
| 1154 | 1117 | .lazy_path_list => switch (option_ptr.value) { |
| 1155 | | .scalar => |s| return b.allocator.dupe(LazyPath, &[_]LazyPath{.{ .cwd_relative = s }}) catch @panic("OOM"), |
| 1156 | | .lazy_path => |lp| return b.allocator.dupe(LazyPath, &[_]LazyPath{lp}) catch @panic("OOM"), |
| 1118 | .scalar => |s| return arena.dupe(LazyPath, &[_]LazyPath{.{ .cwd_relative = s }}) catch @panic("OOM"), |
| 1119 | .lazy_path => |lp| return arena.dupe(LazyPath, &[_]LazyPath{lp}) catch @panic("OOM"), |
| 1157 | 1120 | .list => |lst| { |
| 1158 | | const new_list = b.allocator.alloc(LazyPath, lst.items.len) catch @panic("OOM"); |
| 1121 | const new_list = arena.alloc(LazyPath, lst.items.len) catch @panic("OOM"); |
| 1159 | 1122 | for (new_list, lst.items) |*new_item, str| { |
| 1160 | 1123 | new_item.* = .{ .cwd_relative = str }; |
| 1161 | 1124 | } |
| ... | ... | @@ -1163,9 +1126,7 @@ pub fn option(b: *Build, comptime T: type, name_raw: []const u8, description_raw |
| 1163 | 1126 | }, |
| 1164 | 1127 | .lazy_path_list => |lp_list| return lp_list.items, |
| 1165 | 1128 | .flag, .map => { |
| 1166 | | log.err("Expected -D{s} to be a path, but received a {s}.", .{ |
| 1167 | | name, @tagName(option_ptr.value), |
| 1168 | | }); |
| 1129 | log.err("expected -D{s} to be a path; received: {t}", .{ name, option_ptr.value }); |
| 1169 | 1130 | b.markInvalidUserInput(); |
| 1170 | 1131 | return null; |
| 1171 | 1132 | }, |
| ... | ... | @@ -1250,8 +1211,8 @@ pub fn parseTargetQuery(options: std.Target.Query.ParseOptions) error{ParseFaile |
| 1250 | 1211 | opts_copy.diagnostics = &diags; |
| 1251 | 1212 | return std.Target.Query.parse(opts_copy) catch |err| switch (err) { |
| 1252 | 1213 | error.UnknownCpuModel => { |
| 1253 | | std.debug.print("unknown CPU: '{s}'\navailable CPUs for architecture '{s}':\n", .{ |
| 1254 | | diags.cpu_name.?, @tagName(diags.arch.?), |
| 1214 | std.debug.print("unknown CPU: '{s}'\navailable CPUs for architecture '{t}':\n", .{ |
| 1215 | diags.cpu_name.?, diags.arch.?, |
| 1255 | 1216 | }); |
| 1256 | 1217 | for (diags.arch.?.allCpuModels()) |cpu| { |
| 1257 | 1218 | std.debug.print(" {s}\n", .{cpu.name}); |
| ... | ... | @@ -1261,11 +1222,10 @@ pub fn parseTargetQuery(options: std.Target.Query.ParseOptions) error{ParseFaile |
| 1261 | 1222 | error.UnknownCpuFeature => { |
| 1262 | 1223 | std.debug.print( |
| 1263 | 1224 | \\unknown CPU feature: '{s}' |
| 1264 | | \\available CPU features for architecture '{s}': |
| 1225 | \\available CPU features for architecture '{t}': |
| 1265 | 1226 | \\ |
| 1266 | 1227 | , .{ |
| 1267 | | diags.unknown_feature_name.?, |
| 1268 | | @tagName(diags.arch.?), |
| 1228 | diags.unknown_feature_name.?, diags.arch.?, |
| 1269 | 1229 | }); |
| 1270 | 1230 | for (diags.arch.?.allFeaturesList()) |feature| { |
| 1271 | 1231 | std.debug.print(" {s}: {s}\n", .{ feature.name, feature.description }); |
| ... | ... | @@ -1398,7 +1358,9 @@ pub fn addUserInputOption(b: *Build, name_raw: []const u8, value_raw: []const u8 |
| 1398 | 1358 | return true; |
| 1399 | 1359 | }, |
| 1400 | 1360 | .lazy_path, .lazy_path_list => { |
| 1401 | | log.warn("the lazy path value type isn't added from the CLI, but somehow '{s}' is a .{f}", .{ name, std.zig.fmtId(@tagName(gop.value_ptr.value)) }); |
| 1361 | log.warn("the lazy path value type isn't added from the CLI, but somehow '{s}' is a .{f}", .{ |
| 1362 | name, std.zig.fmtId(@tagName(gop.value_ptr.value)), |
| 1363 | }); |
| 1402 | 1364 | return true; |
| 1403 | 1365 | }, |
| 1404 | 1366 | } |
| ... | ... | @@ -1437,7 +1399,7 @@ pub fn addUserInputFlag(b: *Build, name_raw: []const u8) error{OutOfMemory}!bool |
| 1437 | 1399 | return false; |
| 1438 | 1400 | } |
| 1439 | 1401 | |
| 1440 | | fn typeToEnum(comptime T: type) TypeId { |
| 1402 | fn typeToEnum(comptime T: type) Configuration.AvailableOption.Type { |
| 1441 | 1403 | return switch (T) { |
| 1442 | 1404 | std.zig.BuildId => .build_id, |
| 1443 | 1405 | LazyPath => .lazy_path, |
| ... | ... | @@ -1588,17 +1550,6 @@ pub fn path(b: *Build, sub_path: []const u8) LazyPath { |
| 1588 | 1550 | } }; |
| 1589 | 1551 | } |
| 1590 | 1552 | |
| 1591 | | /// This is low-level implementation details of the build system, not meant to |
| 1592 | | /// be called by users' build scripts. Even in the build system itself it is a |
| 1593 | | /// code smell to call this function. |
| 1594 | | pub fn pathFromRoot(b: *Build, sub_path: []const u8) []u8 { |
| 1595 | | return b.pathResolve(&.{ b.build_root.path orelse ".", sub_path }); |
| 1596 | | } |
| 1597 | | |
| 1598 | | fn pathFromCwd(b: *Build, sub_path: []const u8) []u8 { |
| 1599 | | return b.pathResolve(&.{ b.graph.cache.cwd, sub_path }); |
| 1600 | | } |
| 1601 | | |
| 1602 | 1553 | pub fn pathJoin(b: *Build, paths: []const []const u8) []u8 { |
| 1603 | 1554 | return fs.path.join(b.allocator, paths) catch @panic("OOM"); |
| 1604 | 1555 | } |
| ... | ... | @@ -1792,7 +1743,9 @@ inline fn findImportPkgHashOrFatal(b: *Build, comptime asking_build_zig: type, c |
| 1792 | 1743 | if (@hasDecl(pkg, "build_zig") and pkg.build_zig == asking_build_zig) break .{ pkg_hash, pkg.deps }; |
| 1793 | 1744 | } else .{ "", deps.root_deps }; |
| 1794 | 1745 | if (!std.mem.eql(u8, b_pkg_hash, b.pkg_hash)) { |
| 1795 | | std.debug.panic("'{}' is not the struct that corresponds to '{s}'", .{ asking_build_zig, b.pathFromRoot("build.zig") }); |
| 1746 | std.debug.panic("'{}' is not the struct that corresponds to '{s}'", .{ |
| 1747 | asking_build_zig, b.pathFromRoot("build.zig"), |
| 1748 | }); |
| 1796 | 1749 | } |
| 1797 | 1750 | comptime for (b_pkg_deps) |dep| { |
| 1798 | 1751 | if (std.mem.eql(u8, dep[0], dep_name)) return dep[1]; |