authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2024-01-07 18:41:26-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2024-01-08 11:52:38-07:00
log491b460e0a5637d42cc60e9d69a666cac2591ae3
tree52880b688e1955fd3011871d2449097eb391bdc6
parent9346cd38e831f9790df106e26423f711ba60e997

add tool for updating mingw crt files


3 files changed, 164 insertions(+), 1 deletions(-)

build.zig+18
......@@ -537,6 +537,24 @@ pub fn build(b: *std.Build) !void {
537537
538538 b.step("fmt", "Modify source files in place to have conforming formatting")
539539 .dependOn(&do_fmt.step);
540
541 const update_mingw_step = b.step("update-mingw", "Update zig's bundled mingw");
542 const opt_mingw_src_path = b.option([]const u8, "mingw-src", "path to mingw-w64 source directory");
543 const update_mingw_exe = b.addExecutable(.{
544 .name = "update_mingw",
545 .target = b.host,
546 .root_source_file = .{ .path = "tools/update_mingw.zig" },
547 });
548 const update_mingw_run = b.addRunArtifact(update_mingw_exe);
549 update_mingw_run.addDirectoryArg(.{ .path = "lib" });
550 if (opt_mingw_src_path) |mingw_src_path| {
551 update_mingw_run.addDirectoryArg(.{ .cwd_relative = mingw_src_path });
552 } else {
553 // Intentionally cause an error if this build step is requested.
554 update_mingw_run.addArg("--missing-mingw-source-directory");
555 }
556
557 update_mingw_step.dependOn(&update_mingw_run.step);
540558}
541559
542560fn addWasiUpdateStep(b: *std.Build, version: [:0]const u8) !void {
src/mingw.zig-1
......@@ -782,7 +782,6 @@ const mingwex_generic_src = [_][]const u8{
782782 "math" ++ path.sep_str ++ "tgammal.c",
783783 "math" ++ path.sep_str ++ "truncl.c",
784784 "misc" ++ path.sep_str ++ "alarm.c",
785 "misc" ++ path.sep_str ++ "basename.c",
786785 "misc" ++ path.sep_str ++ "btowc.c",
787786 "misc" ++ path.sep_str ++ "delay-f.c",
788787 "misc" ++ path.sep_str ++ "delay-n.c",
tools/update_mingw.zig created+146
......@@ -0,0 +1,146 @@
1const std = @import("std");
2
3pub fn main() !void {
4 var arena_instance = std.heap.ArenaAllocator.init(std.heap.page_allocator);
5 defer arena_instance.deinit();
6 const arena = arena_instance.allocator();
7
8 const args = try std.process.argsAlloc(arena);
9 const zig_src_lib_path = args[1];
10 const mingw_src_path = args[2];
11
12 if (std.mem.eql(u8, mingw_src_path, "--missing-mingw-source-directory")) {
13 std.log.err("this build step requires passing -Dmingw-src=[path]", .{});
14 std.process.exit(1);
15 }
16
17 const dest_mingw_crt_path = try std.fs.path.join(arena, &.{
18 zig_src_lib_path, "libc", "mingw",
19 });
20 const src_mingw_crt_path = try std.fs.path.join(arena, &.{
21 mingw_src_path, "mingw-w64-crt",
22 });
23
24 // Update only the set of existing files we have already chosen to include
25 // in zig's installation.
26
27 var dest_crt_dir = std.fs.cwd().openDir(dest_mingw_crt_path, .{ .iterate = true }) catch |err| {
28 std.log.err("unable to open directory '{s}': {s}", .{ dest_mingw_crt_path, @errorName(err) });
29 std.process.exit(1);
30 };
31 defer dest_crt_dir.close();
32
33 var src_crt_dir = std.fs.cwd().openDir(src_mingw_crt_path, .{ .iterate = true }) catch |err| {
34 std.log.err("unable to open directory '{s}': {s}", .{ src_mingw_crt_path, @errorName(err) });
35 std.process.exit(1);
36 };
37 defer src_crt_dir.close();
38
39 {
40 var walker = try dest_crt_dir.walk(arena);
41 defer walker.deinit();
42
43 var fail = false;
44
45 while (try walker.next()) |entry| {
46 if (entry.kind != .file) continue;
47
48 // Special exception to keep the copyright file.
49 if (std.mem.eql(u8, entry.path, "COPYING")) continue;
50
51 src_crt_dir.copyFile(entry.path, dest_crt_dir, entry.path, .{}) catch |err| switch (err) {
52 error.FileNotFound => {
53 std.log.warn("deleting {s}", .{entry.path});
54 try dest_crt_dir.deleteFile(entry.path);
55 },
56 else => {
57 std.log.err("unable to copy {s}: {s}", .{ entry.path, @errorName(err) });
58 fail = true;
59 },
60 };
61 }
62
63 if (fail) std.process.exit(1);
64 }
65
66 {
67 // Also add all new def and def.in files.
68 var walker = try src_crt_dir.walk(arena);
69 defer walker.deinit();
70
71 var fail = false;
72
73 while (try walker.next()) |entry| {
74 if (entry.kind != .file) continue;
75
76 const ok_ext = for (ok_exts) |ext| {
77 if (std.mem.endsWith(u8, entry.path, ext)) break true;
78 } else false;
79
80 if (!ok_ext) continue;
81
82 const ok_prefix = for (ok_prefixes) |p| {
83 if (std.mem.startsWith(u8, entry.path, p)) break true;
84 } else false;
85
86 if (!ok_prefix) continue;
87
88 const blacklisted = for (blacklist) |item| {
89 if (std.mem.eql(u8, entry.basename, item)) break true;
90 } else false;
91
92 if (blacklisted) continue;
93
94 if (std.mem.startsWith(u8, entry.basename, "api-ms-win-"))
95 continue;
96
97 src_crt_dir.copyFile(entry.path, dest_crt_dir, entry.path, .{}) catch |err| {
98 std.log.err("unable to copy {s}: {s}", .{ entry.path, @errorName(err) });
99 fail = true;
100 };
101 }
102 if (fail) std.process.exit(1);
103 }
104
105 return std.process.cleanExit();
106}
107
108const ok_exts = [_][]const u8{
109 ".def",
110 ".def.in",
111};
112
113const ok_prefixes = [_][]const u8{
114 "lib32" ++ std.fs.path.sep_str,
115 "lib64" ++ std.fs.path.sep_str,
116 "libarm32" ++ std.fs.path.sep_str,
117 "libarm64" ++ std.fs.path.sep_str,
118 "lib-common" ++ std.fs.path.sep_str,
119 "def-include" ++ std.fs.path.sep_str,
120};
121
122const blacklist = [_][]const u8{
123 "msvcp60.def",
124 "msvcp120_app.def.in",
125 "msvcp60.def",
126 "msvcp120_clr0400.def",
127 "msvcp110.def",
128 "msvcp60.def",
129 "msvcp120_app.def.in",
130
131 "msvcr100.def.in",
132 "msvcr110.def",
133 "msvcr110.def.in",
134 "msvcr120.def.in",
135 "msvcr120_app.def.in",
136 "msvcr120_clr0400.def",
137 "msvcr120d.def.in",
138 "msvcr70.def.in",
139 "msvcr71.def.in",
140 "msvcr80.def.in",
141 "msvcr90.def.in",
142 "msvcr90d.def.in",
143 "msvcrt10.def.in",
144 "msvcrt20.def.in",
145 "msvcrt40.def.in",
146};