| ... | @@ -29,6 +29,7 @@ pub const Wip = struct { | ... | @@ -29,6 +29,7 @@ pub const Wip = struct { |
| 29 | gpa: Allocator, | 29 | gpa: Allocator, |
| 30 | string_table: StringTable = .empty, | 30 | string_table: StringTable = .empty, |
| 31 | deps_table: DepsTable = .empty, | 31 | deps_table: DepsTable = .empty, |
| | 32 | targets_table: TargetsTable = .empty, |
| 32 | | 33 | |
| 33 | string_bytes: std.ArrayList(u8) = .empty, | 34 | string_bytes: std.ArrayList(u8) = .empty, |
| 34 | unlazy_deps: std.ArrayList(String) = .empty, | 35 | unlazy_deps: std.ArrayList(String) = .empty, |
| ... | @@ -37,6 +38,7 @@ pub const Wip = struct { | ... | @@ -37,6 +38,7 @@ pub const Wip = struct { |
| 37 | extra: std.ArrayList(u32) = .empty, | 38 | extra: std.ArrayList(u32) = .empty, |
| 38 | | 39 | |
| 39 | const DepsTable = std.HashMapUnmanaged(Deps, void, DepsTableContext, std.hash_map.default_max_load_percentage); | 40 | const DepsTable = std.HashMapUnmanaged(Deps, void, DepsTableContext, std.hash_map.default_max_load_percentage); |
| | 41 | const TargetsTable = std.HashMapUnmanaged(TargetQuery.Index, void, TargetsTableContext, std.hash_map.default_max_load_percentage); |
| 40 | | 42 | |
| 41 | const DepsTableContext = struct { | 43 | const DepsTableContext = struct { |
| 42 | extra: []const u32, | 44 | extra: []const u32, |
| ... | @@ -56,6 +58,21 @@ pub const Wip = struct { | ... | @@ -56,6 +58,21 @@ pub const Wip = struct { |
| 56 | } | 58 | } |
| 57 | }; | 59 | }; |
| 58 | | 60 | |
| | 61 | const TargetsTableContext = struct { |
| | 62 | extra: []const u32, |
| | 63 | |
| | 64 | pub fn eql(ctx: @This(), a: TargetQuery.Index, b: TargetQuery.Index) bool { |
| | 65 | const slice_a = a.extraSlice(ctx.extra); |
| | 66 | const slice_b = b.extraSlice(ctx.extra); |
| | 67 | return std.mem.eql(u32, slice_a, slice_b); |
| | 68 | } |
| | 69 | |
| | 70 | pub fn hash(ctx: @This(), key: TargetQuery.Index) u64 { |
| | 71 | const slice = key.extraSlice(ctx.extra); |
| | 72 | return std.hash_map.hashString(@ptrCast(slice)); |
| | 73 | } |
| | 74 | }; |
| | 75 | |
| 59 | const StringTable = std.HashMapUnmanaged(String, void, StringTableContext, std.hash_map.default_max_load_percentage); | 76 | const StringTable = std.HashMapUnmanaged(String, void, StringTableContext, std.hash_map.default_max_load_percentage); |
| 60 | const StringTableContext = struct { | 77 | const StringTableContext = struct { |
| 61 | bytes: []const u8, | 78 | bytes: []const u8, |
| ... | @@ -144,6 +161,157 @@ pub const Wip = struct { | ... | @@ -144,6 +161,157 @@ pub const Wip = struct { |
| 144 | return new_off; | 161 | return new_off; |
| 145 | } | 162 | } |
| 146 | | 163 | |
| | 164 | pub fn addSemVer(wip: *Wip, sv: std.SemanticVersion) Allocator.Error!String { |
| | 165 | var buffer: [256]u8 = undefined; |
| | 166 | var writer: std.Io.Writer = .fixed(&buffer); |
| | 167 | sv.format(&writer) catch return error.OutOfMemory; |
| | 168 | return addString(wip, writer.buffered()); |
| | 169 | } |
| | 170 | |
| | 171 | pub fn addTargetQuery(wip: *Wip, q: std.Target.Query) !TargetQuery.OptionalIndex { |
| | 172 | if (q.isNative()) return .none; |
| | 173 | const gpa = wip.gpa; |
| | 174 | const cpu_name: ?String = switch (q.cpu_model) { |
| | 175 | .native, .baseline, .determined_by_arch_os => null, |
| | 176 | .explicit => |model| try wip.addString(model.name), |
| | 177 | }; |
| | 178 | const os_version_min: ?u32 = if (q.os_version_min) |ver| switch (ver) { |
| | 179 | .none => null, |
| | 180 | .semver => |sem_ver| @intFromEnum(try wip.addSemVer(sem_ver)), |
| | 181 | .windows => |win_ver| @intFromEnum(win_ver), |
| | 182 | } else null; |
| | 183 | const os_version_max: ?u32 = if (q.os_version_max) |ver| switch (ver) { |
| | 184 | .none => null, |
| | 185 | .semver => |sem_ver| @intFromEnum(try wip.addSemVer(sem_ver)), |
| | 186 | .windows => |win_ver| @intFromEnum(win_ver), |
| | 187 | } else null; |
| | 188 | const glibc_version: ?String = if (q.glibc_version) |sem_ver| try wip.addSemVer(sem_ver) else null; |
| | 189 | const dynamic_linker: ?String = if (q.dynamic_linker) |*dl| |
| | 190 | if (dl.get()) |s| try wip.addString(s) else .empty |
| | 191 | else |
| | 192 | null; |
| | 193 | const cpu_features_add_empty = q.cpu_features_add.isEmpty(); |
| | 194 | const cpu_features_sub_empty = q.cpu_features_sub.isEmpty(); |
| | 195 | try wip.extra.ensureUnusedCapacity(gpa, @typeInfo(TargetQuery).@"struct".fields.len + 6 + |
| | 196 | 2 * ((@sizeOf(std.Target.Cpu.Feature.Set) + 3) / 4)); |
| | 197 | const result_index: TargetQuery.Index = @enumFromInt(wip.addExtraAssumeCapacity(@as(TargetQuery, .{ |
| | 198 | .flags = .{ |
| | 199 | .cpu_arch = .init(q.cpu_arch), |
| | 200 | .cpu_model = .init(q.cpu_model), |
| | 201 | .cpu_features_add = !cpu_features_add_empty, |
| | 202 | .cpu_features_sub = !cpu_features_sub_empty, |
| | 203 | .os_tag = .init(q.os_tag), |
| | 204 | .abi = .init(q.abi), |
| | 205 | .object_format = .init(q.ofmt), |
| | 206 | .os_version_min = .init(q.os_version_min), |
| | 207 | .os_version_max = .init(q.os_version_max), |
| | 208 | .glibc_version = q.glibc_version != null, |
| | 209 | .android_api_level = q.android_api_level != null, |
| | 210 | .dynamic_linker = q.dynamic_linker != null, |
| | 211 | }, |
| | 212 | }))); |
| | 213 | if (!cpu_features_add_empty) wip.extra.appendSliceAssumeCapacity(@ptrCast(&q.cpu_features_add.ints)); |
| | 214 | if (!cpu_features_sub_empty) wip.extra.appendSliceAssumeCapacity(@ptrCast(&q.cpu_features_sub.ints)); |
| | 215 | wip.addExtraOptionalStringAssumeCapacity(cpu_name); |
| | 216 | if (os_version_min) |v| wip.extra.appendAssumeCapacity(v); |
| | 217 | if (os_version_max) |v| wip.extra.appendAssumeCapacity(v); |
| | 218 | wip.addExtraOptionalStringAssumeCapacity(glibc_version); |
| | 219 | if (q.android_api_level) |x| wip.extra.appendAssumeCapacity(x); |
| | 220 | wip.addExtraOptionalStringAssumeCapacity(dynamic_linker); |
| | 221 | |
| | 222 | // Deduplicate. |
| | 223 | const gop = try wip.targets_table.getOrPutContext(gpa, result_index, @as(TargetsTableContext, .{ |
| | 224 | .extra = wip.extra.items, |
| | 225 | })); |
| | 226 | if (gop.found_existing) { |
| | 227 | wip.extra.items.len = @intFromEnum(result_index); |
| | 228 | return .init(gop.key_ptr.*); |
| | 229 | } else { |
| | 230 | return .init(result_index); |
| | 231 | } |
| | 232 | } |
| | 233 | |
| | 234 | pub fn addTarget(wip: *Wip, t: std.Target) !TargetQuery.Index { |
| | 235 | const gpa = wip.gpa; |
| | 236 | const cpu_name: String = try wip.addString(t.cpu.model.name); |
| | 237 | |
| | 238 | const os_version_min: ?u32, const os_version_max: ?u32, const glibc_version: ?String, const android_api_level: ?u32 = switch (t.os.versionRange()) { |
| | 239 | .none => .{ |
| | 240 | null, |
| | 241 | null, |
| | 242 | null, |
| | 243 | null, |
| | 244 | }, |
| | 245 | .semver => |range| .{ |
| | 246 | @intFromEnum(try wip.addSemVer(range.min)), |
| | 247 | @intFromEnum(try wip.addSemVer(range.max)), |
| | 248 | null, |
| | 249 | null, |
| | 250 | }, |
| | 251 | .hurd => |hurd| .{ |
| | 252 | @intFromEnum(try wip.addSemVer(hurd.range.min)), |
| | 253 | @intFromEnum(try wip.addSemVer(hurd.range.max)), |
| | 254 | try wip.addSemVer(hurd.glibc), |
| | 255 | null, |
| | 256 | }, |
| | 257 | .linux => |linux| .{ |
| | 258 | @intFromEnum(try wip.addSemVer(linux.range.min)), |
| | 259 | @intFromEnum(try wip.addSemVer(linux.range.max)), |
| | 260 | try wip.addSemVer(linux.glibc), |
| | 261 | linux.android, |
| | 262 | }, |
| | 263 | .windows => |range| .{ |
| | 264 | @intFromEnum(range.min), |
| | 265 | @intFromEnum(range.max), |
| | 266 | null, |
| | 267 | null, |
| | 268 | }, |
| | 269 | }; |
| | 270 | const dynamic_linker: ?String = if (t.dynamic_linker.get()) |dl| try wip.addString(dl) else null; |
| | 271 | const cpu_features_add_empty = t.cpu.features.isEmpty(); |
| | 272 | const os_version: TargetQuery.OsVersion = switch (t.os.versionRange()) { |
| | 273 | .none => .none, |
| | 274 | .semver, .linux, .hurd => .semver, |
| | 275 | .windows => .windows, |
| | 276 | }; |
| | 277 | try wip.extra.ensureUnusedCapacity(gpa, @typeInfo(TargetQuery).@"struct".fields.len + 6 + |
| | 278 | 2 * ((@sizeOf(std.Target.Cpu.Feature.Set) + 3) / 4)); |
| | 279 | const result_index: TargetQuery.Index = @enumFromInt(wip.addExtraAssumeCapacity(@as(TargetQuery, .{ |
| | 280 | .flags = .{ |
| | 281 | .cpu_arch = .init(t.cpu.arch), |
| | 282 | .cpu_model = .explicit, |
| | 283 | .cpu_features_add = !cpu_features_add_empty, |
| | 284 | .cpu_features_sub = false, |
| | 285 | .os_tag = .init(t.os.tag), |
| | 286 | .abi = .init(t.abi), |
| | 287 | .object_format = .init(t.ofmt), |
| | 288 | .os_version_min = os_version, |
| | 289 | .os_version_max = os_version, |
| | 290 | .glibc_version = glibc_version != null, |
| | 291 | .android_api_level = android_api_level != null, |
| | 292 | .dynamic_linker = dynamic_linker != null, |
| | 293 | }, |
| | 294 | }))); |
| | 295 | if (!cpu_features_add_empty) wip.extra.appendSliceAssumeCapacity(@ptrCast(&t.cpu.features.ints)); |
| | 296 | wip.addExtraOptionalStringAssumeCapacity(cpu_name); |
| | 297 | if (os_version_min) |v| wip.extra.appendAssumeCapacity(v); |
| | 298 | if (os_version_max) |v| wip.extra.appendAssumeCapacity(v); |
| | 299 | wip.addExtraOptionalStringAssumeCapacity(glibc_version); |
| | 300 | if (android_api_level) |x| wip.extra.appendAssumeCapacity(x); |
| | 301 | wip.addExtraOptionalStringAssumeCapacity(dynamic_linker); |
| | 302 | |
| | 303 | // Deduplicate. |
| | 304 | const gop = try wip.targets_table.getOrPutContext(gpa, result_index, @as(TargetsTableContext, .{ |
| | 305 | .extra = wip.extra.items, |
| | 306 | })); |
| | 307 | if (gop.found_existing) { |
| | 308 | wip.extra.items.len = @intFromEnum(result_index); |
| | 309 | return gop.key_ptr.*; |
| | 310 | } else { |
| | 311 | return result_index; |
| | 312 | } |
| | 313 | } |
| | 314 | |
| 147 | pub fn prepareDeps(wip: *Wip, n: usize) Allocator.Error![]u32 { | 315 | pub fn prepareDeps(wip: *Wip, n: usize) Allocator.Error![]u32 { |
| 148 | const slice = try wip.extra.addManyAsSlice(wip.gpa, n + 1); | 316 | const slice = try wip.extra.addManyAsSlice(wip.gpa, n + 1); |
| 149 | slice[0] = @intCast(n); | 317 | slice[0] = @intCast(n); |
| ... | @@ -178,6 +346,11 @@ pub const Wip = struct { | ... | @@ -178,6 +346,11 @@ pub const Wip = struct { |
| 178 | return result; | 346 | return result; |
| 179 | } | 347 | } |
| 180 | | 348 | |
| | 349 | fn addExtraOptionalStringAssumeCapacity(wip: *Wip, optional_string: ?String) void { |
| | 350 | const string = optional_string orelse return; |
| | 351 | wip.extra.appendAssumeCapacity(@intFromEnum(string)); |
| | 352 | } |
| | 353 | |
| 181 | fn setExtra(wip: *Wip, index: usize, extra: anytype) void { | 354 | fn setExtra(wip: *Wip, index: usize, extra: anytype) void { |
| 182 | const fields = @typeInfo(@TypeOf(extra)).@"struct".fields; | 355 | const fields = @typeInfo(@TypeOf(extra)).@"struct".fields; |
| 183 | var i = index; | 356 | var i = index; |
| ... | @@ -386,7 +559,7 @@ pub const Step = extern struct { | ... | @@ -386,7 +559,7 @@ pub const Step = extern struct { |
| 386 | flags3: Flags3, | 559 | flags3: Flags3, |
| 387 | flags4: Flags4, | 560 | flags4: Flags4, |
| 388 | | 561 | |
| 389 | root_module: Module, | 562 | root_module: Module.Index, |
| 390 | root_name: String, | 563 | root_name: String, |
| 391 | | 564 | |
| 392 | pub const ExpectedCompileErrors = enum(u3) { contains, exact, starts_with, stderr_contains, none }; | 565 | pub const ExpectedCompileErrors = enum(u3) { contains, exact, starts_with, stderr_contains, none }; |
| ... | @@ -466,19 +639,6 @@ pub const Step = extern struct { | ... | @@ -466,19 +639,6 @@ pub const Step = extern struct { |
| 466 | }; | 639 | }; |
| 467 | } | 640 | } |
| 468 | }; | 641 | }; |
| 469 | pub const DefaultingBool = enum(u2) { | | |
| 470 | false, | | |
| 471 | true, | | |
| 472 | default, | | |
| 473 | | | |
| 474 | pub fn init(b: ?bool) DefaultingBool { | | |
| 475 | return switch (b orelse return .default) { | | |
| 476 | false => .false, | | |
| 477 | true => .true, | | |
| 478 | }; | | |
| 479 | } | | |
| 480 | }; | | |
| 481 | | | |
| 482 | pub const Subsystem = enum(u4) { | 642 | pub const Subsystem = enum(u4) { |
| 483 | console, | 643 | console, |
| 484 | windows, | 644 | windows, |
| ... | @@ -626,7 +786,7 @@ pub const LazyPath = enum(u32) { | ... | @@ -626,7 +786,7 @@ pub const LazyPath = enum(u32) { |
| 626 | | 786 | |
| 627 | pub const SourcePath = struct { | 787 | pub const SourcePath = struct { |
| 628 | flags: Flags, | 788 | flags: Flags, |
| 629 | owner: Package, | 789 | owner: Package.Index, |
| 630 | sub_path: String, | 790 | sub_path: String, |
| 631 | | 791 | |
| 632 | pub const Flags = packed struct(u32) { | 792 | pub const Flags = packed struct(u32) { |
| ... | @@ -662,11 +822,168 @@ pub const LazyPath = enum(u32) { | ... | @@ -662,11 +822,168 @@ pub const LazyPath = enum(u32) { |
| 662 | }; | 822 | }; |
| 663 | }; | 823 | }; |
| 664 | | 824 | |
| 665 | pub const Package = enum(u32) { | 825 | pub const Package = extern struct { |
| 666 | _, | 826 | hash: String, |
| | 827 | build_root: OptionalString, |
| | 828 | |
| | 829 | pub const Index = enum(u32) { |
| | 830 | root = maxInt(u32), |
| | 831 | _, |
| | 832 | }; |
| | 833 | }; |
| | 834 | |
| | 835 | /// Trailing: |
| | 836 | /// * c_macros: LengthPrefixedList(String), // if flag is set |
| | 837 | /// * lib_paths: LengthPrefixedList(LazyPath), // if flag is set |
| | 838 | /// * export_symbol_names: LengthPrefixedList(String), // if flag is set |
| | 839 | /// * frameworks: FlagsPrefixedList(FrameworkFlags), // if flag is set |
| | 840 | /// * include_dirs: UnionList(IncludeDir), // if flag is set |
| | 841 | /// * rpaths: UnionList(RPath), // if flag is set |
| | 842 | /// * link_objects: UnionList(LinkObject), // if flag is set |
| | 843 | pub const Module = struct { |
| | 844 | flags: Flags, |
| | 845 | flags2: Flags2, |
| | 846 | owner: Package.Index, |
| | 847 | root_source_file: OptionalLazyPath, |
| | 848 | import_table: ImportTable, |
| | 849 | resolved_target: ResolvedTarget.OptionalIndex, |
| | 850 | |
| | 851 | pub const Optimize = enum(u3) { |
| | 852 | debug, |
| | 853 | safe, |
| | 854 | fast, |
| | 855 | small, |
| | 856 | default, |
| | 857 | |
| | 858 | pub fn init(o: ?std.builtin.OptimizeMode) Optimize { |
| | 859 | return switch (o orelse return .default) { |
| | 860 | .Debug => .debug, |
| | 861 | .ReleaseSafe => .safe, |
| | 862 | .ReleaseFast => .fast, |
| | 863 | .ReleaseSmall => .small, |
| | 864 | }; |
| | 865 | } |
| | 866 | }; |
| | 867 | |
| | 868 | pub const UnwindTables = enum(u2) { |
| | 869 | none, |
| | 870 | sync, |
| | 871 | async, |
| | 872 | default, |
| | 873 | |
| | 874 | pub fn init(ut: ?std.builtin.UnwindTables) UnwindTables { |
| | 875 | return switch (ut orelse return .default) { |
| | 876 | .none => .none, |
| | 877 | .sync => .sync, |
| | 878 | .async => .async, |
| | 879 | }; |
| | 880 | } |
| | 881 | }; |
| | 882 | |
| | 883 | pub const SanitizeC = enum(u2) { |
| | 884 | off, |
| | 885 | trap, |
| | 886 | full, |
| | 887 | default, |
| | 888 | |
| | 889 | pub fn init(sc: ?std.zig.SanitizeC) SanitizeC { |
| | 890 | return switch (sc orelse return .default) { |
| | 891 | .off => .off, |
| | 892 | .trap => .trap, |
| | 893 | .full => .full, |
| | 894 | }; |
| | 895 | } |
| | 896 | }; |
| | 897 | |
| | 898 | pub const DwarfFormat = enum(u2) { |
| | 899 | @"32", |
| | 900 | @"64", |
| | 901 | default, |
| | 902 | |
| | 903 | pub fn init(df: ?std.dwarf.Format) DwarfFormat { |
| | 904 | return switch (df orelse return .default) { |
| | 905 | .@"32" => .@"32", |
| | 906 | .@"64" => .@"64", |
| | 907 | }; |
| | 908 | } |
| | 909 | }; |
| | 910 | |
| | 911 | pub const Index = enum(u32) { |
| | 912 | _, |
| | 913 | }; |
| | 914 | |
| | 915 | pub const Flags = packed struct(u32) { |
| | 916 | optimize: Optimize, |
| | 917 | strip: DefaultingBool, |
| | 918 | unwind_tables: UnwindTables, |
| | 919 | dwarf_format: DwarfFormat, |
| | 920 | single_threaded: DefaultingBool, |
| | 921 | stack_protector: DefaultingBool, |
| | 922 | stack_check: DefaultingBool, |
| | 923 | sanitize_c: SanitizeC, |
| | 924 | sanitize_thread: DefaultingBool, |
| | 925 | fuzz: DefaultingBool, |
| | 926 | code_model: std.builtin.CodeModel, |
| | 927 | c_macros: bool, |
| | 928 | include_dirs: bool, |
| | 929 | lib_paths: bool, |
| | 930 | rpaths: bool, |
| | 931 | frameworks: bool, |
| | 932 | link_objects: bool, |
| | 933 | export_symbol_names: bool, |
| | 934 | }; |
| | 935 | |
| | 936 | pub const Flags2 = packed struct(u32) { |
| | 937 | valgrind: DefaultingBool, |
| | 938 | pic: DefaultingBool, |
| | 939 | red_zone: DefaultingBool, |
| | 940 | omit_frame_pointer: DefaultingBool, |
| | 941 | error_tracing: DefaultingBool, |
| | 942 | link_libc: DefaultingBool, |
| | 943 | link_libcpp: DefaultingBool, |
| | 944 | no_builtin: DefaultingBool, |
| | 945 | _: u16 = 0, |
| | 946 | }; |
| | 947 | |
| | 948 | pub const IncludeDir = union(enum(u3)) { |
| | 949 | path: LazyPath, |
| | 950 | path_system: LazyPath, |
| | 951 | path_after: LazyPath, |
| | 952 | framework_path: LazyPath, |
| | 953 | framework_path_system: LazyPath, |
| | 954 | /// Always `Step.Tag.compile`. |
| | 955 | other_step: Step.Index, |
| | 956 | /// Always `Step.Tag.config_header`. |
| | 957 | config_header_step: Step.Index, |
| | 958 | embed_path: LazyPath, |
| | 959 | }; |
| | 960 | |
| | 961 | pub const RPath = union(enum(u1)) { |
| | 962 | lazy_path: LazyPath, |
| | 963 | special: String, |
| | 964 | }; |
| | 965 | |
| | 966 | pub const LinkObject = union(enum(u3)) { |
| | 967 | static_path: LazyPath, |
| | 968 | /// Always `Step.Tag.compile`. |
| | 969 | other_step: Step.Index, |
| | 970 | system_lib: SystemLib, |
| | 971 | assembly_file: LazyPath, |
| | 972 | c_source_file: CSourceFile.Index, |
| | 973 | c_source_files: CSourceFiles.Index, |
| | 974 | win32_resource_file: RcSourceFile.Index, |
| | 975 | }; |
| | 976 | |
| | 977 | pub const FrameworkFlags = packed struct(u2) { |
| | 978 | needed: bool, |
| | 979 | weak: bool, |
| | 980 | }; |
| 667 | }; | 981 | }; |
| 668 | | 982 | |
| 669 | pub const Module = enum(u32) { | 983 | /// Points into `extra`, first element is len, then: |
| | 984 | /// * import_name: String, // for each len |
| | 985 | /// * Module.Index, // for each len |
| | 986 | pub const ImportTable = enum(u32) { |
| 670 | _, | 987 | _, |
| 671 | }; | 988 | }; |
| 672 | | 989 | |
| ... | @@ -734,6 +1051,397 @@ pub const String = enum(u32) { | ... | @@ -734,6 +1051,397 @@ pub const String = enum(u32) { |
| 734 | } | 1051 | } |
| 735 | }; | 1052 | }; |
| 736 | | 1053 | |
| | 1054 | pub const DefaultingBool = enum(u2) { |
| | 1055 | false, |
| | 1056 | true, |
| | 1057 | default, |
| | 1058 | |
| | 1059 | pub fn init(b: ?bool) DefaultingBool { |
| | 1060 | return switch (b orelse return .default) { |
| | 1061 | false => .false, |
| | 1062 | true => .true, |
| | 1063 | }; |
| | 1064 | } |
| | 1065 | }; |
| | 1066 | |
| | 1067 | pub const SystemLib = struct { |
| | 1068 | name: String, |
| | 1069 | flags: Flags, |
| | 1070 | |
| | 1071 | pub const Index = enum(u32) { |
| | 1072 | _, |
| | 1073 | }; |
| | 1074 | |
| | 1075 | pub const UsePkgConfig = enum(u2) { no, yes, force }; |
| | 1076 | pub const LinkMode = enum { static, dynamic }; |
| | 1077 | |
| | 1078 | pub const Flags = packed struct(u32) { |
| | 1079 | needed: bool, |
| | 1080 | weak: bool, |
| | 1081 | use_pkg_config: UsePkgConfig, |
| | 1082 | preferred_link_mode: LinkMode, |
| | 1083 | search_strategy: SearchStrategy, |
| | 1084 | }; |
| | 1085 | |
| | 1086 | pub const SearchStrategy = enum(u2) { paths_first, mode_first, no_fallback }; |
| | 1087 | }; |
| | 1088 | |
| | 1089 | /// Trailing: |
| | 1090 | /// * flag: String, // for each flags_len |
| | 1091 | /// * sub_path: String, // for each files_len |
| | 1092 | pub const CSourceFiles = struct { |
| | 1093 | root: LazyPath, |
| | 1094 | files_len: u32, |
| | 1095 | flags: Flags, |
| | 1096 | |
| | 1097 | pub const Index = enum(u32) { |
| | 1098 | _, |
| | 1099 | }; |
| | 1100 | |
| | 1101 | pub const Flags = packed struct(u32) { |
| | 1102 | /// C compiler CLI flags. |
| | 1103 | flags_len: u29, |
| | 1104 | lang: OptionalCSourceLanguage, |
| | 1105 | }; |
| | 1106 | }; |
| | 1107 | |
| | 1108 | /// Trailing: |
| | 1109 | /// * flag: String, // for each flags_len |
| | 1110 | pub const CSourceFile = struct { |
| | 1111 | file: LazyPath, |
| | 1112 | flags: Flags, |
| | 1113 | |
| | 1114 | pub const Index = enum(u32) { |
| | 1115 | _, |
| | 1116 | }; |
| | 1117 | |
| | 1118 | pub const Flags = packed struct(u32) { |
| | 1119 | /// C compiler CLI flags. |
| | 1120 | flags_len: u29, |
| | 1121 | lang: OptionalCSourceLanguage, |
| | 1122 | }; |
| | 1123 | }; |
| | 1124 | |
| | 1125 | pub const OptionalCSourceLanguage = enum(u3) { |
| | 1126 | c, |
| | 1127 | cpp, |
| | 1128 | objective_c, |
| | 1129 | objective_cpp, |
| | 1130 | assembly, |
| | 1131 | assembly_with_preprocessor, |
| | 1132 | default, |
| | 1133 | }; |
| | 1134 | |
| | 1135 | pub const RcSourceFile = struct { |
| | 1136 | file: LazyPath, |
| | 1137 | /// Any option that rc.exe accepts will work here, with the exception of: |
| | 1138 | /// - `/fo`: The output filename is set by the build system |
| | 1139 | /// - `/p`: Only running the preprocessor is not supported in this context |
| | 1140 | /// - `/:no-preprocess` (non-standard option): Not supported in this context |
| | 1141 | /// - Any MUI-related option |
| | 1142 | /// https://learn.microsoft.com/en-us/windows/win32/menurc/using-rc-the-rc-command-line- |
| | 1143 | /// |
| | 1144 | /// Implicitly defined options: |
| | 1145 | /// /x (ignore the INCLUDE environment variable) |
| | 1146 | /// /D_DEBUG or /DNDEBUG depending on the optimization mode |
| | 1147 | flags: []const []const u8 = &.{}, |
| | 1148 | /// Include paths that may or may not exist yet and therefore need to be |
| | 1149 | /// specified as a LazyPath. Each path will be appended to the flags |
| | 1150 | /// as `/I <resolved path>`. |
| | 1151 | include_paths: []const LazyPath = &.{}, |
| | 1152 | |
| | 1153 | pub const Index = enum(u32) { |
| | 1154 | _, |
| | 1155 | }; |
| | 1156 | }; |
| | 1157 | |
| | 1158 | pub const ResolvedTarget = struct { |
| | 1159 | /// none indicates host. |
| | 1160 | query: TargetQuery.OptionalIndex, |
| | 1161 | /// defaults will be resolved. |
| | 1162 | result: TargetQuery.Index, |
| | 1163 | |
| | 1164 | pub const Index = enum(u32) { |
| | 1165 | _, |
| | 1166 | }; |
| | 1167 | |
| | 1168 | pub const OptionalIndex = enum(u32) { |
| | 1169 | none = maxInt(u32), |
| | 1170 | _, |
| | 1171 | }; |
| | 1172 | }; |
| | 1173 | |
| | 1174 | /// Trailing: |
| | 1175 | /// * cpu_features_add: std.Target.Feature.Set, // if flag set |
| | 1176 | /// * cpu_features_sub: std.Target.Feature.Set, // if flag set |
| | 1177 | /// * cpu_name: String, // if cpu_model is explicit |
| | 1178 | /// * os_version_min: WindowsVersion // if os_version_min is windows |
| | 1179 | /// * os_version_min: String // if os_version_min is semver |
| | 1180 | /// * os_version_max: WindowsVersion // if os_version_max is windows |
| | 1181 | /// * os_version_max: String // if os_version_max is semver |
| | 1182 | /// * glibc_version: String, // if flag is set |
| | 1183 | /// * android_api_level: u32, // if flag is set |
| | 1184 | /// * dynamic_linker: String, // if flag is set |
| | 1185 | pub const TargetQuery = struct { |
| | 1186 | flags: Flags, |
| | 1187 | |
| | 1188 | pub const Index = enum(u32) { |
| | 1189 | _, |
| | 1190 | |
| | 1191 | pub fn extraSlice(i: Index, extra: []const u32) []const u32 { |
| | 1192 | return extra[@intFromEnum(i)..][0..length(i, extra)]; |
| | 1193 | } |
| | 1194 | |
| | 1195 | pub fn length(i: Index, extra: []const u32) usize { |
| | 1196 | //const flags = getExtra(extra, @intFromEnum(i), TargetQuery).flags; |
| | 1197 | const flags: Flags = @bitCast(extra[@intFromEnum(i)]); |
| | 1198 | const feature_set_size: usize = (@sizeOf(std.Target.Cpu.Feature.Set) + 3) / 4; |
| | 1199 | return @typeInfo(TargetQuery).@"struct".fields.len + |
| | 1200 | (if (flags.cpu_features_add) feature_set_size else 0) + |
| | 1201 | (if (flags.cpu_features_sub) feature_set_size else 0) + |
| | 1202 | @intFromBool(flags.cpu_model == .explicit) + |
| | 1203 | @as(usize, switch (flags.os_version_min) { |
| | 1204 | .semver, .windows => 1, |
| | 1205 | else => 0, |
| | 1206 | }) + |
| | 1207 | @as(usize, switch (flags.os_version_max) { |
| | 1208 | .semver, .windows => 1, |
| | 1209 | else => 0, |
| | 1210 | }) + |
| | 1211 | @intFromBool(flags.glibc_version) + |
| | 1212 | @intFromBool(flags.android_api_level) + |
| | 1213 | @intFromBool(flags.dynamic_linker); |
| | 1214 | } |
| | 1215 | }; |
| | 1216 | |
| | 1217 | pub const OptionalIndex = enum(u32) { |
| | 1218 | none = maxInt(u32), |
| | 1219 | _, |
| | 1220 | |
| | 1221 | pub fn init(i: Index) OptionalIndex { |
| | 1222 | const result: OptionalIndex = @enumFromInt(@intFromEnum(i)); |
| | 1223 | assert(result != .none); |
| | 1224 | return result; |
| | 1225 | } |
| | 1226 | }; |
| | 1227 | |
| | 1228 | pub const CpuModel = enum(u2) { |
| | 1229 | native, |
| | 1230 | baseline, |
| | 1231 | determined_by_arch_os, |
| | 1232 | explicit, |
| | 1233 | |
| | 1234 | pub fn init(x: std.Target.Query.CpuModel) @This() { |
| | 1235 | return switch (x) { |
| | 1236 | .native => .native, |
| | 1237 | .baseline => .baseline, |
| | 1238 | .determined_by_arch_os => .determined_by_arch_os, |
| | 1239 | .explicit => .explicit, |
| | 1240 | }; |
| | 1241 | } |
| | 1242 | }; |
| | 1243 | pub const OsVersion = enum(u2) { |
| | 1244 | none, |
| | 1245 | semver, |
| | 1246 | windows, |
| | 1247 | default, |
| | 1248 | |
| | 1249 | pub fn init(x: ?std.Target.Query.OsVersion) @This() { |
| | 1250 | return switch (x orelse return .default) { |
| | 1251 | .none => .none, |
| | 1252 | .semver => .semver, |
| | 1253 | .windows => .windows, |
| | 1254 | }; |
| | 1255 | } |
| | 1256 | }; |
| | 1257 | pub const Abi = enum(u5) { |
| | 1258 | none, |
| | 1259 | gnu, |
| | 1260 | gnuabin32, |
| | 1261 | gnuabi64, |
| | 1262 | gnueabi, |
| | 1263 | gnueabihf, |
| | 1264 | gnuf32, |
| | 1265 | gnusf, |
| | 1266 | gnux32, |
| | 1267 | eabi, |
| | 1268 | eabihf, |
| | 1269 | ilp32, |
| | 1270 | android, |
| | 1271 | androideabi, |
| | 1272 | musl, |
| | 1273 | muslabin32, |
| | 1274 | muslabi64, |
| | 1275 | musleabi, |
| | 1276 | musleabihf, |
| | 1277 | muslf32, |
| | 1278 | muslsf, |
| | 1279 | muslx32, |
| | 1280 | msvc, |
| | 1281 | itanium, |
| | 1282 | simulator, |
| | 1283 | ohos, |
| | 1284 | ohoseabi, |
| | 1285 | |
| | 1286 | default, |
| | 1287 | |
| | 1288 | pub fn init(x: ?std.Target.Abi) @This() { |
| | 1289 | // TODO comptime assert the enums match |
| | 1290 | return @enumFromInt(@intFromEnum(x orelse return .default)); |
| | 1291 | } |
| | 1292 | }; |
| | 1293 | pub const CpuArch = enum(u6) { |
| | 1294 | aarch64, |
| | 1295 | aarch64_be, |
| | 1296 | alpha, |
| | 1297 | amdgcn, |
| | 1298 | arc, |
| | 1299 | arceb, |
| | 1300 | arm, |
| | 1301 | armeb, |
| | 1302 | avr, |
| | 1303 | bpfeb, |
| | 1304 | bpfel, |
| | 1305 | csky, |
| | 1306 | hexagon, |
| | 1307 | hppa, |
| | 1308 | hppa64, |
| | 1309 | kalimba, |
| | 1310 | kvx, |
| | 1311 | lanai, |
| | 1312 | loongarch32, |
| | 1313 | loongarch64, |
| | 1314 | m68k, |
| | 1315 | microblaze, |
| | 1316 | microblazeel, |
| | 1317 | mips, |
| | 1318 | mipsel, |
| | 1319 | mips64, |
| | 1320 | mips64el, |
| | 1321 | msp430, |
| | 1322 | nvptx, |
| | 1323 | nvptx64, |
| | 1324 | or1k, |
| | 1325 | powerpc, |
| | 1326 | powerpcle, |
| | 1327 | powerpc64, |
| | 1328 | powerpc64le, |
| | 1329 | propeller, |
| | 1330 | riscv32, |
| | 1331 | riscv32be, |
| | 1332 | riscv64, |
| | 1333 | riscv64be, |
| | 1334 | s390x, |
| | 1335 | sh, |
| | 1336 | sheb, |
| | 1337 | sparc, |
| | 1338 | sparc64, |
| | 1339 | spirv32, |
| | 1340 | spirv64, |
| | 1341 | thumb, |
| | 1342 | thumbeb, |
| | 1343 | ve, |
| | 1344 | wasm32, |
| | 1345 | wasm64, |
| | 1346 | x86_16, |
| | 1347 | x86, |
| | 1348 | x86_64, |
| | 1349 | xcore, |
| | 1350 | xtensa, |
| | 1351 | xtensaeb, |
| | 1352 | |
| | 1353 | default, |
| | 1354 | |
| | 1355 | pub fn init(x: ?std.Target.Cpu.Arch) @This() { |
| | 1356 | // TODO comptime assert the enums match |
| | 1357 | return @enumFromInt(@intFromEnum(x orelse return .default)); |
| | 1358 | } |
| | 1359 | }; |
| | 1360 | pub const OsTag = enum(u6) { |
| | 1361 | freestanding, |
| | 1362 | other, |
| | 1363 | contiki, |
| | 1364 | fuchsia, |
| | 1365 | hermit, |
| | 1366 | managarm, |
| | 1367 | haiku, |
| | 1368 | hurd, |
| | 1369 | illumos, |
| | 1370 | linux, |
| | 1371 | plan9, |
| | 1372 | rtems, |
| | 1373 | serenity, |
| | 1374 | dragonfly, |
| | 1375 | freebsd, |
| | 1376 | netbsd, |
| | 1377 | openbsd, |
| | 1378 | driverkit, |
| | 1379 | ios, |
| | 1380 | maccatalyst, |
| | 1381 | macos, |
| | 1382 | tvos, |
| | 1383 | visionos, |
| | 1384 | watchos, |
| | 1385 | windows, |
| | 1386 | uefi, |
| | 1387 | @"3ds", |
| | 1388 | ps3, |
| | 1389 | ps4, |
| | 1390 | ps5, |
| | 1391 | vita, |
| | 1392 | emscripten, |
| | 1393 | wasi, |
| | 1394 | amdhsa, |
| | 1395 | amdpal, |
| | 1396 | cuda, |
| | 1397 | mesa3d, |
| | 1398 | nvcl, |
| | 1399 | opencl, |
| | 1400 | opengl, |
| | 1401 | vulkan, |
| | 1402 | |
| | 1403 | default, |
| | 1404 | |
| | 1405 | pub fn init(x: ?std.Target.Os.Tag) @This() { |
| | 1406 | // TODO comptime assert the enums match |
| | 1407 | return @enumFromInt(@intFromEnum(x orelse return .default)); |
| | 1408 | } |
| | 1409 | }; |
| | 1410 | pub const ObjectFormat = enum(u4) { |
| | 1411 | c, |
| | 1412 | coff, |
| | 1413 | elf, |
| | 1414 | hex, |
| | 1415 | macho, |
| | 1416 | plan9, |
| | 1417 | raw, |
| | 1418 | spirv, |
| | 1419 | wasm, |
| | 1420 | |
| | 1421 | default, |
| | 1422 | |
| | 1423 | pub fn init(x: ?std.Target.ObjectFormat) @This() { |
| | 1424 | // TODO comptime assert the enums match |
| | 1425 | return @enumFromInt(@intFromEnum(x orelse return .default)); |
| | 1426 | } |
| | 1427 | }; |
| | 1428 | |
| | 1429 | pub const Flags = packed struct(u32) { |
| | 1430 | cpu_arch: CpuArch, |
| | 1431 | cpu_model: CpuModel, |
| | 1432 | cpu_features_add: bool, |
| | 1433 | cpu_features_sub: bool, |
| | 1434 | os_tag: OsTag, |
| | 1435 | abi: Abi, |
| | 1436 | object_format: ObjectFormat, |
| | 1437 | os_version_min: OsVersion, |
| | 1438 | os_version_max: OsVersion, |
| | 1439 | glibc_version: bool, |
| | 1440 | android_api_level: bool, |
| | 1441 | dynamic_linker: bool, |
| | 1442 | }; |
| | 1443 | }; |
| | 1444 | |
| 737 | pub const LoadFileError = Io.File.Reader.Error || Allocator.Error || error{EndOfStream}; | 1445 | pub const LoadFileError = Io.File.Reader.Error || Allocator.Error || error{EndOfStream}; |
| 738 | | 1446 | |
| 739 | pub fn loadFile(arena: Allocator, io: Io, file: Io.File) LoadFileError!Configuration { | 1447 | pub fn loadFile(arena: Allocator, io: Io, file: Io.File) LoadFileError!Configuration { |