1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
|
const std = @import("std");
pub fn main() !void {
var arena_instance = std.heap.ArenaAllocator.init(std.heap.page_allocator);
defer arena_instance.deinit();
const arena = arena_instance.allocator();
const args = try std.process.argsAlloc(arena);
const zig_src_lib_path = args[1];
const mingw_src_path = args[2];
const dest_mingw_crt_path = try std.fs.path.join(arena, &.{
zig_src_lib_path, "libc", "mingw",
});
const src_mingw_crt_path = try std.fs.path.join(arena, &.{
mingw_src_path, "mingw-w64-crt",
});
// Update only the set of existing files we have already chosen to include
// in zig's installation.
var dest_crt_dir = std.fs.cwd().openDir(dest_mingw_crt_path, .{ .iterate = true }) catch |err| {
std.log.err("unable to open directory '{s}': {s}", .{ dest_mingw_crt_path, @errorName(err) });
std.process.exit(1);
};
defer dest_crt_dir.close();
var src_crt_dir = std.fs.cwd().openDir(src_mingw_crt_path, .{ .iterate = true }) catch |err| {
std.log.err("unable to open directory '{s}': {s}", .{ src_mingw_crt_path, @errorName(err) });
std.process.exit(1);
};
defer src_crt_dir.close();
{
var walker = try dest_crt_dir.walk(arena);
defer walker.deinit();
var fail = false;
while (try walker.next()) |entry| {
if (entry.kind != .file) continue;
src_crt_dir.copyFile(entry.path, dest_crt_dir, entry.path, .{}) catch |err| switch (err) {
error.FileNotFound => {
const keep = for (kept_crt_files) |item| {
if (std.mem.eql(u8, entry.path, item)) break true;
if (std.mem.startsWith(u8, entry.path, "winpthreads/")) break true;
} else false;
if (!keep) {
std.log.warn("deleting {s}", .{entry.path});
try dest_crt_dir.deleteFile(entry.path);
}
},
else => {
std.log.err("unable to copy {s}: {s}", .{ entry.path, @errorName(err) });
fail = true;
},
};
}
if (fail) std.process.exit(1);
}
{
const dest_mingw_winpthreads_path = try std.fs.path.join(arena, &.{
zig_src_lib_path, "libc", "mingw", "winpthreads",
});
const src_mingw_libraries_winpthreads_src_path = try std.fs.path.join(arena, &.{
mingw_src_path, "mingw-w64-libraries", "winpthreads", "src",
});
var dest_winpthreads_dir = std.fs.cwd().openDir(dest_mingw_winpthreads_path, .{ .iterate = true }) catch |err| {
std.log.err("unable to open directory '{s}': {s}", .{ dest_mingw_winpthreads_path, @errorName(err) });
std.process.exit(1);
};
defer dest_winpthreads_dir.close();
var src_winpthreads_dir = std.fs.cwd().openDir(src_mingw_libraries_winpthreads_src_path, .{ .iterate = true }) catch |err| {
std.log.err("unable to open directory '{s}': {s}", .{ src_mingw_libraries_winpthreads_src_path, @errorName(err) });
std.process.exit(1);
};
defer src_winpthreads_dir.close();
{
var walker = try dest_winpthreads_dir.walk(arena);
defer walker.deinit();
var fail = false;
while (try walker.next()) |entry| {
if (entry.kind != .file) continue;
src_winpthreads_dir.copyFile(entry.path, dest_winpthreads_dir, entry.path, .{}) catch |err| switch (err) {
error.FileNotFound => {
std.log.warn("deleting {s}", .{entry.path});
try dest_winpthreads_dir.deleteFile(entry.path);
},
else => {
std.log.err("unable to copy {s}: {s}", .{ entry.path, @errorName(err) });
fail = true;
},
};
}
if (fail) std.process.exit(1);
}
}
{
// Also add all new def and def.in files.
var walker = try src_crt_dir.walk(arena);
defer walker.deinit();
var fail = false;
while (try walker.next()) |entry| {
if (entry.kind != .file) continue;
const ok_ext = for (def_exts) |ext| {
if (std.mem.endsWith(u8, entry.path, ext)) break true;
} else false;
if (!ok_ext) continue;
const ok_prefix = for (def_dirs) |p| {
if (std.mem.startsWith(u8, entry.path, p)) break true;
} else false;
if (!ok_prefix) continue;
const blacklisted = for (blacklisted_defs) |item| {
if (std.mem.eql(u8, entry.basename, item)) break true;
} else false;
if (blacklisted) continue;
if (std.mem.endsWith(u8, entry.basename, "_windowsapp.def"))
continue;
if (std.mem.endsWith(u8, entry.basename, "_onecore.def"))
continue;
src_crt_dir.copyFile(entry.path, dest_crt_dir, entry.path, .{}) catch |err| {
std.log.err("unable to copy {s}: {s}", .{ entry.path, @errorName(err) });
fail = true;
};
}
if (fail) std.process.exit(1);
}
return std.process.cleanExit();
}
const kept_crt_files = [_][]const u8{
"COPYING",
"include" ++ std.fs.path.sep_str ++ "config.h",
};
const def_exts = [_][]const u8{
".def",
".def.in",
};
const def_dirs = [_][]const u8{
"lib32" ++ std.fs.path.sep_str,
"lib64" ++ std.fs.path.sep_str,
"libarm32" ++ std.fs.path.sep_str,
"libarm64" ++ std.fs.path.sep_str,
"lib-common" ++ std.fs.path.sep_str,
"def-include" ++ std.fs.path.sep_str,
};
const blacklisted_defs = [_][]const u8{
"crtdll.def.in",
"msvcp60.def",
"msvcp110.def",
"msvcp120_app.def.in",
"msvcp120_clr0400.def",
"msvcr40d.def.in",
"msvcr70.def.in",
"msvcr70d.def.in",
"msvcr71.def.in",
"msvcr71d.def.in",
"msvcr80.def.in",
"msvcr80d.def.in",
"msvcr90.def.in",
"msvcr90d.def.in",
"msvcr100.def.in",
"msvcr100d.def.in",
"msvcr110.def.in",
"msvcr110d.def.in",
"msvcr120.def.in",
"msvcr120d.def.in",
"msvcr120_app.def.in",
"msvcrt.def.in",
"msvcrtd.def.in",
"msvcrt10.def.in",
"msvcrt20.def.in",
"msvcrt40.def.in",
};
|