From 667236668f865de4c854a047d65017140317e7e9 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Tue, 18 May 2021 17:18:42 -0700 Subject: [PATCH] build.zig: blank out "*test.zig" files instead of omit Now that `@import` of a non-existent file name is a compile error, the Zig installation needs to include files that end with test.zig. However we still want to avoid bloat in the installation size, so we blank them out instead of omitting them entirely. Now AstGen of the full standard library can complete successfully on a Zig installation rather than erroring out with file not found. --- build.zig | 4 +++- lib/std/build.zig | 53 +++++++++++++++++++++++++++++++++++++++-------- 2 files changed, 47 insertions(+), 10 deletions(-) diff --git a/build.zig b/build.zig index 14b503a8a2..e8e1dcc0b6 100644 --- a/build.zig +++ b/build.zig @@ -69,13 +69,15 @@ pub fn build(b: *Builder) !void { .install_dir = .Lib, .install_subdir = "zig", .exclude_extensions = &[_][]const u8{ - "test.zig", "README.md", ".z.0", ".z.9", ".gz", "rfc1951.txt", }, + .blank_extensions = &[_][]const u8{ + "test.zig", + }, }); } diff --git a/lib/std/build.zig b/lib/std/build.zig index bd6360d8d6..40f8343843 100644 --- a/lib/std/build.zig +++ b/lib/std/build.zig @@ -1019,6 +1019,23 @@ pub const Builder = struct { }; } + pub fn truncateFile(self: *Builder, dest_path: []const u8) !void { + if (self.verbose) { + warn("truncate {s}\n", .{dest_path}); + } + const cwd = fs.cwd(); + var src_file = cwd.createFile(dest_path, .{}) catch |err| switch (err) { + error.FileNotFound => blk: { + if (fs.path.dirname(dest_path)) |dirname| { + try cwd.makePath(dirname); + } + break :blk try cwd.createFile(dest_path, .{}); + }, + else => |e| return e, + }; + src_file.close(); + } + pub fn pathFromRoot(self: *Builder, rel_path: []const u8) []u8 { return fs.path.resolve(self.allocator, &[_][]const u8{ self.build_root, rel_path }) catch unreachable; } @@ -2791,17 +2808,23 @@ pub const InstallDirectoryOptions = struct { source_dir: []const u8, install_dir: InstallDir, install_subdir: []const u8, - exclude_extensions: ?[]const []const u8 = null, + /// File paths which end in any of these suffixes will be excluded + /// from being installed. + exclude_extensions: []const []const u8 = &.{}, + /// File paths which end in any of these suffixes will result in + /// empty files being installed. This is mainly intended for large + /// test.zig files in order to prevent needless installation bloat. + /// However if the files were not present at all, then + /// `@import("test.zig")` would be a compile error. + blank_extensions: []const []const u8 = &.{}, fn dupe(self: InstallDirectoryOptions, b: *Builder) InstallDirectoryOptions { return .{ .source_dir = b.dupe(self.source_dir), .install_dir = self.install_dir.dupe(b), .install_subdir = b.dupe(self.install_subdir), - .exclude_extensions = if (self.exclude_extensions) |extensions| - b.dupeStrings(extensions) - else - null, + .exclude_extensions = b.dupeStrings(self.exclude_extensions), + .blank_extensions = b.dupeStrings(self.blank_extensions), }; } }; @@ -2829,17 +2852,29 @@ pub const InstallDirStep = struct { const full_src_dir = self.builder.pathFromRoot(self.options.source_dir); var it = try fs.walkPath(self.builder.allocator, full_src_dir); next_entry: while (try it.next()) |entry| { - if (self.options.exclude_extensions) |ext_list| for (ext_list) |ext| { + for (self.options.exclude_extensions) |ext| { if (mem.endsWith(u8, entry.path, ext)) { continue :next_entry; } - }; + } const rel_path = entry.path[full_src_dir.len + 1 ..]; - const dest_path = try fs.path.join(self.builder.allocator, &[_][]const u8{ dest_prefix, rel_path }); + const dest_path = try fs.path.join(self.builder.allocator, &[_][]const u8{ + dest_prefix, rel_path, + }); + switch (entry.kind) { .Directory => try fs.cwd().makePath(dest_path), - .File => try self.builder.updateFile(entry.path, dest_path), + .File => { + for (self.options.blank_extensions) |ext| { + if (mem.endsWith(u8, entry.path, ext)) { + try self.builder.truncateFile(dest_path); + continue :next_entry; + } + } + + try self.builder.updateFile(entry.path, dest_path); + }, else => continue, } }