| ... | @@ -21,41 +21,42 @@ const Blake3 = std.crypto.hash.Blake3; | ... | @@ -21,41 +21,42 @@ const Blake3 = std.crypto.hash.Blake3; |
| 21 | const LibCTarget = struct { | 21 | const LibCTarget = struct { |
| 22 | arch: Arch, | 22 | arch: Arch, |
| 23 | abi: Abi, | 23 | abi: Abi, |
| | 24 | dest: ?[]const u8 = null, |
| 24 | }; | 25 | }; |
| 25 | | 26 | |
| 26 | const glibc_targets = [_]LibCTarget{ | 27 | const glibc_targets = [_]LibCTarget{ |
| 27 | .{ .arch = .arc, .abi = .gnu }, | 28 | .{ .arch = .arc, .abi = .gnu }, |
| 28 | .{ .arch = .arm, .abi = .gnueabi }, | 29 | .{ .arch = .arm, .abi = .gnueabi, .dest = "arm-linux-gnu" }, |
| 29 | .{ .arch = .arm, .abi = .gnueabihf }, | 30 | .{ .arch = .arm, .abi = .gnueabihf, .dest = "arm-linux-gnu" }, |
| 30 | .{ .arch = .armeb, .abi = .gnueabi }, | 31 | .{ .arch = .armeb, .abi = .gnueabi, .dest = "arm-linux-gnu" }, |
| 31 | .{ .arch = .armeb, .abi = .gnueabihf }, | 32 | .{ .arch = .armeb, .abi = .gnueabihf, .dest = "arm-linux-gnu" }, |
| 32 | .{ .arch = .aarch64, .abi = .gnu }, | 33 | .{ .arch = .aarch64, .abi = .gnu, .dest = "aarch64-linux-gnu" }, |
| 33 | .{ .arch = .aarch64_be, .abi = .gnu }, | 34 | .{ .arch = .aarch64_be, .abi = .gnu, .dest = "aarch64-linux-gnu" }, |
| 34 | .{ .arch = .csky, .abi = .gnueabi }, | 35 | .{ .arch = .csky, .abi = .gnueabi, .dest = "csky-linux-gnu" }, |
| 35 | .{ .arch = .csky, .abi = .gnueabihf }, | 36 | .{ .arch = .csky, .abi = .gnueabihf, .dest = "csky-linux-gnu" }, |
| 36 | .{ .arch = .loongarch64, .abi = .gnu }, | 37 | .{ .arch = .loongarch64, .abi = .gnu, .dest = "loongarch-linux-gnu" }, |
| 37 | .{ .arch = .loongarch64, .abi = .gnusf }, | 38 | .{ .arch = .loongarch64, .abi = .gnusf, .dest = "loongarch-linux-gnu" }, |
| 38 | .{ .arch = .m68k, .abi = .gnu }, | 39 | .{ .arch = .m68k, .abi = .gnu }, |
| 39 | .{ .arch = .mips, .abi = .gnueabi }, | 40 | .{ .arch = .mips, .abi = .gnueabi, .dest = "mips-linux-gnu" }, |
| 40 | .{ .arch = .mips, .abi = .gnueabihf }, | 41 | .{ .arch = .mips, .abi = .gnueabihf, .dest = "mips-linux-gnu" }, |
| 41 | .{ .arch = .mipsel, .abi = .gnueabi }, | 42 | .{ .arch = .mipsel, .abi = .gnueabi, .dest = "mips-linux-gnu" }, |
| 42 | .{ .arch = .mipsel, .abi = .gnueabihf }, | 43 | .{ .arch = .mipsel, .abi = .gnueabihf, .dest = "mips-linux-gnu" }, |
| 43 | .{ .arch = .mips64, .abi = .gnuabi64 }, | 44 | .{ .arch = .mips64, .abi = .gnuabi64, .dest = "mips-linux-gnu" }, |
| 44 | .{ .arch = .mips64, .abi = .gnuabin32 }, | 45 | .{ .arch = .mips64, .abi = .gnuabin32, .dest = "mips-linux-gnu" }, |
| 45 | .{ .arch = .mips64el, .abi = .gnuabi64 }, | 46 | .{ .arch = .mips64el, .abi = .gnuabi64, .dest = "mips-linux-gnu" }, |
| 46 | .{ .arch = .mips64el, .abi = .gnuabin32 }, | 47 | .{ .arch = .mips64el, .abi = .gnuabin32, .dest = "mips-linux-gnu" }, |
| 47 | .{ .arch = .powerpc, .abi = .gnueabi }, | 48 | .{ .arch = .powerpc, .abi = .gnueabi, .dest = "powerpc-linux-gnu" }, |
| 48 | .{ .arch = .powerpc, .abi = .gnueabihf }, | 49 | .{ .arch = .powerpc, .abi = .gnueabihf, .dest = "powerpc-linux-gnu" }, |
| 49 | .{ .arch = .powerpc64, .abi = .gnu }, | 50 | .{ .arch = .powerpc64, .abi = .gnu, .dest = "powerpc-linux-gnu" }, |
| 50 | .{ .arch = .powerpc64le, .abi = .gnu }, | 51 | .{ .arch = .powerpc64le, .abi = .gnu, .dest = "powerpc-linux-gnu" }, |
| 51 | .{ .arch = .riscv32, .abi = .gnu }, | 52 | .{ .arch = .riscv32, .abi = .gnu, .dest = "riscv-linux-gnu" }, |
| 52 | .{ .arch = .riscv64, .abi = .gnu }, | 53 | .{ .arch = .riscv64, .abi = .gnu, .dest = "riscv-linux-gnu" }, |
| 53 | .{ .arch = .s390x, .abi = .gnu }, | 54 | .{ .arch = .s390x, .abi = .gnu }, |
| 54 | .{ .arch = .sparc, .abi = .gnu }, | 55 | .{ .arch = .sparc, .abi = .gnu, .dest = "sparc-linux-gnu" }, |
| 55 | .{ .arch = .sparc64, .abi = .gnu }, | 56 | .{ .arch = .sparc64, .abi = .gnu, .dest = "sparc-linux-gnu" }, |
| 56 | .{ .arch = .x86, .abi = .gnu }, | 57 | .{ .arch = .x86, .abi = .gnu, .dest = "x86-linux-gnu" }, |
| 57 | .{ .arch = .x86_64, .abi = .gnu }, | 58 | .{ .arch = .x86_64, .abi = .gnu, .dest = "x86-linux-gnu" }, |
| 58 | .{ .arch = .x86_64, .abi = .gnux32 }, | 59 | .{ .arch = .x86_64, .abi = .gnux32, .dest = "x86-linux-gnu" }, |
| 59 | }; | 60 | }; |
| 60 | | 61 | |
| 61 | const musl_targets = [_]LibCTarget{ | 62 | const musl_targets = [_]LibCTarget{ |
| ... | @@ -88,43 +89,20 @@ const freebsd_targets = [_]LibCTarget{ | ... | @@ -88,43 +89,20 @@ const freebsd_targets = [_]LibCTarget{ |
| 88 | }; | 89 | }; |
| 89 | | 90 | |
| 90 | const netbsd_targets = [_]LibCTarget{ | 91 | const netbsd_targets = [_]LibCTarget{ |
| 91 | .{ .arch = .arm, .abi = .eabi }, | 92 | .{ .arch = .arm, .abi = .eabi, .dest = "arm-netbsd-eabi" }, |
| 92 | .{ .arch = .arm, .abi = .eabihf }, | 93 | .{ .arch = .arm, .abi = .eabihf, .dest = "arm-netbsd-eabi" }, |
| 93 | .{ .arch = .aarch64, .abi = .none }, | 94 | .{ .arch = .aarch64, .abi = .none }, |
| 94 | .{ .arch = .m68k, .abi = .none }, | 95 | .{ .arch = .m68k, .abi = .none }, |
| 95 | .{ .arch = .mips, .abi = .eabi }, | 96 | .{ .arch = .mips, .abi = .eabi, .dest = "mips-netbsd-eabi" }, |
| 96 | .{ .arch = .mips, .abi = .eabihf }, | 97 | .{ .arch = .mips, .abi = .eabihf, .dest = "mips-netbsd-eabi" }, |
| 97 | .{ .arch = .powerpc, .abi = .eabi }, | 98 | .{ .arch = .powerpc, .abi = .eabi, .dest = "powerpc-netbsd-eabi" }, |
| 98 | .{ .arch = .powerpc, .abi = .eabihf }, | 99 | .{ .arch = .powerpc, .abi = .eabihf, .dest = "powerpc-netbsd-eabi" }, |
| 99 | .{ .arch = .sparc, .abi = .none }, | 100 | .{ .arch = .sparc, .abi = .none }, |
| 100 | .{ .arch = .sparc64, .abi = .none }, | 101 | .{ .arch = .sparc64, .abi = .none }, |
| 101 | .{ .arch = .x86, .abi = .none }, | 102 | .{ .arch = .x86, .abi = .none }, |
| 102 | .{ .arch = .x86_64, .abi = .none }, | 103 | .{ .arch = .x86_64, .abi = .none }, |
| 103 | }; | 104 | }; |
| 104 | | 105 | |
| 105 | const DestTarget = struct { | | |
| 106 | arch: Arch, | | |
| 107 | os: OsTag, | | |
| 108 | abi: Abi, | | |
| 109 | | | |
| 110 | const HashContext = struct { | | |
| 111 | pub fn hash(self: @This(), a: DestTarget) u32 { | | |
| 112 | _ = self; | | |
| 113 | return @intFromEnum(a.arch) +% | | |
| 114 | (@intFromEnum(a.os) *% @as(u32, 4202347608)) +% | | |
| 115 | (@intFromEnum(a.abi) *% @as(u32, 4082223418)); | | |
| 116 | } | | |
| 117 | | | |
| 118 | pub fn eql(self: @This(), a: DestTarget, b: DestTarget, b_index: usize) bool { | | |
| 119 | _ = self; | | |
| 120 | _ = b_index; | | |
| 121 | return a.arch == b.arch and | | |
| 122 | a.os == b.os and | | |
| 123 | a.abi == b.abi; | | |
| 124 | } | | |
| 125 | }; | | |
| 126 | }; | | |
| 127 | | | |
| 128 | const Contents = struct { | 106 | const Contents = struct { |
| 129 | bytes: []const u8, | 107 | bytes: []const u8, |
| 130 | hit_count: usize, | 108 | hit_count: usize, |
| ... | @@ -138,7 +116,7 @@ const Contents = struct { | ... | @@ -138,7 +116,7 @@ const Contents = struct { |
| 138 | }; | 116 | }; |
| 139 | | 117 | |
| 140 | const HashToContents = std.StringHashMap(Contents); | 118 | const HashToContents = std.StringHashMap(Contents); |
| 141 | const TargetToHash = std.ArrayHashMap(DestTarget, []const u8, DestTarget.HashContext, true); | 119 | const TargetToHash = std.StringArrayHashMap([]const u8); |
| 142 | const PathTable = std.StringHashMap(*TargetToHash); | 120 | const PathTable = std.StringHashMap(*TargetToHash); |
| 143 | | 121 | |
| 144 | const LibCVendor = enum { | 122 | const LibCVendor = enum { |
| ... | @@ -236,15 +214,16 @@ pub fn main() !void { | ... | @@ -236,15 +214,16 @@ pub fn main() !void { |
| 236 | else => unreachable, | 214 | else => unreachable, |
| 237 | }, | 215 | }, |
| 238 | }; | 216 | }; |
| 239 | const dest_target = DestTarget{ | 217 | |
| 240 | .arch = libc_target.arch, | 218 | const dest_target = if (libc_target.dest) |dest| dest else try std.fmt.allocPrint(allocator, "{s}-{s}-{s}", .{ |
| 241 | .os = switch (vendor) { | 219 | @tagName(libc_target.arch), |
| 242 | .musl, .glibc => .linux, | 220 | switch (vendor) { |
| 243 | .freebsd => .freebsd, | 221 | .musl, .glibc => "linux", |
| 244 | .netbsd => .netbsd, | 222 | .freebsd => "freebsd", |
| | 223 | .netbsd => "netbsd", |
| 245 | }, | 224 | }, |
| 246 | .abi = libc_target.abi, | 225 | @tagName(libc_target.abi), |
| 247 | }; | 226 | }); |
| 248 | | 227 | |
| 249 | search: for (search_paths.items) |search_path| { | 228 | search: for (search_paths.items) |search_path| { |
| 250 | const sub_path = switch (vendor) { | 229 | const sub_path = switch (vendor) { |
| ... | @@ -307,7 +286,21 @@ pub fn main() !void { | ... | @@ -307,7 +286,21 @@ pub fn main() !void { |
| 307 | path_gop.value_ptr.* = ptr; | 286 | path_gop.value_ptr.* = ptr; |
| 308 | break :blk ptr; | 287 | break :blk ptr; |
| 309 | }; | 288 | }; |
| 310 | try target_to_hash.putNoClobber(dest_target, hash); | 289 | // When `dest` is set, there are a few rare cases where we expect to overwrite a header. For |
| | 290 | // example, `bits/long-double.h` differs very slightly between `powerpc64le-linux-gnu` and |
| | 291 | // other `powerpc*-linux-gnu` targets, and we unify those targets as `powerpc-linux-gnu`. In |
| | 292 | // such cases, we manually patch the affected header after processing, so it's fine that |
| | 293 | // only one header wins here. |
| | 294 | if (libc_target.dest != null) { |
| | 295 | const hash_gop = try target_to_hash.getOrPut(dest_target); |
| | 296 | if (hash_gop.found_existing) std.debug.print("overwrote: {s} {s} {s}\n", .{ |
| | 297 | libc_dir, |
| | 298 | rel_path, |
| | 299 | dest_target, |
| | 300 | }) else hash_gop.value_ptr.* = hash; |
| | 301 | } else { |
| | 302 | try target_to_hash.putNoClobber(dest_target, hash); |
| | 303 | } |
| 311 | }, | 304 | }, |
| 312 | else => std.debug.print("warning: weird file: {s}\n", .{full_path}), | 305 | else => std.debug.print("warning: weird file: {s}\n", .{full_path}), |
| 313 | } | 306 | } |
| ... | @@ -363,12 +356,7 @@ pub fn main() !void { | ... | @@ -363,12 +356,7 @@ pub fn main() !void { |
| 363 | if (contents.is_generic) continue; | 356 | if (contents.is_generic) continue; |
| 364 | | 357 | |
| 365 | const dest_target = hash_kv.key_ptr.*; | 358 | const dest_target = hash_kv.key_ptr.*; |
| 366 | const out_subpath = try std.fmt.allocPrint(allocator, "{s}-{s}-{s}", .{ | 359 | const full_path = try std.fs.path.join(allocator, &[_][]const u8{ out_dir, dest_target, path_kv.key_ptr.* }); |
| 367 | @tagName(dest_target.arch), | | |
| 368 | @tagName(dest_target.os), | | |
| 369 | @tagName(dest_target.abi), | | |
| 370 | }); | | |
| 371 | const full_path = try std.fs.path.join(allocator, &[_][]const u8{ out_dir, out_subpath, path_kv.key_ptr.* }); | | |
| 372 | try std.fs.cwd().makePath(std.fs.path.dirname(full_path).?); | 360 | try std.fs.cwd().makePath(std.fs.path.dirname(full_path).?); |
| 373 | try std.fs.cwd().writeFile(.{ .sub_path = full_path, .data = contents.bytes }); | 361 | try std.fs.cwd().writeFile(.{ .sub_path = full_path, .data = contents.bytes }); |
| 374 | } | 362 | } |