master
1//! This script updates the .c, .h, .s, and .S files that make up the start
2//! files such as crt1.o.
3//!
4//! Example usage:
5//! `zig run tools/update_freebsd_libc.zig -- ~/Downloads/freebsd-src .`
6
7const std = @import("std");
8
9const exempt_files = [_][]const u8{
10 // This file is maintained by a separate project and does not come from FreeBSD.
11 "abilists",
12};
13
14pub fn main() !void {
15 var arena_instance = std.heap.ArenaAllocator.init(std.heap.page_allocator);
16 defer arena_instance.deinit();
17 const arena = arena_instance.allocator();
18
19 const args = try std.process.argsAlloc(arena);
20 const freebsd_src_path = args[1];
21 const zig_src_path = args[2];
22
23 const dest_dir_path = try std.fmt.allocPrint(arena, "{s}/lib/libc/freebsd", .{zig_src_path});
24
25 var dest_dir = std.fs.cwd().openDir(dest_dir_path, .{ .iterate = true }) catch |err| {
26 std.log.err("unable to open destination directory '{s}': {s}", .{
27 dest_dir_path, @errorName(err),
28 });
29 std.process.exit(1);
30 };
31 defer dest_dir.close();
32
33 var freebsd_src_dir = try std.fs.cwd().openDir(freebsd_src_path, .{});
34 defer freebsd_src_dir.close();
35
36 // Copy updated files from upstream.
37 {
38 var walker = try dest_dir.walk(arena);
39 defer walker.deinit();
40
41 walk: while (try walker.next()) |entry| {
42 if (entry.kind != .file) continue;
43 if (std.mem.startsWith(u8, entry.basename, ".")) continue;
44 for (exempt_files) |p| {
45 if (std.mem.eql(u8, entry.path, p)) continue :walk;
46 }
47
48 std.log.info("updating '{s}/{s}' from '{s}/{s}'", .{
49 dest_dir_path, entry.path,
50 freebsd_src_path, entry.path,
51 });
52
53 freebsd_src_dir.copyFile(entry.path, dest_dir, entry.path, .{}) catch |err| {
54 std.log.warn("unable to copy '{s}/{s}' to '{s}/{s}': {s}", .{
55 freebsd_src_path, entry.path,
56 dest_dir_path, entry.path,
57 @errorName(err),
58 });
59 if (err == error.FileNotFound) {
60 try dest_dir.deleteFile(entry.path);
61 }
62 };
63 }
64 }
65}