authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-05-18 17:18:42-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-05-18 17:18:42-07:00
log667236668f865de4c854a047d65017140317e7e9
tree2f1ab1dc537ba8804ae6d1e0bdd094d646625e53
parent2c12f5f55b67e3201f019ea6d05db1c7ac8a0025

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.

2 files changed, 47 insertions(+), 10 deletions(-)

build.zig+3-1
...@@ -69,13 +69,15 @@ pub fn build(b: *Builder) !void {...@@ -69,13 +69,15 @@ pub fn build(b: *Builder) !void {
69 .install_dir = .Lib,69 .install_dir = .Lib,
70 .install_subdir = "zig",70 .install_subdir = "zig",
71 .exclude_extensions = &[_][]const u8{71 .exclude_extensions = &[_][]const u8{
72 "test.zig",
73 "README.md",72 "README.md",
74 ".z.0",73 ".z.0",
75 ".z.9",74 ".z.9",
76 ".gz",75 ".gz",
77 "rfc1951.txt",76 "rfc1951.txt",
78 },77 },
78 .blank_extensions = &[_][]const u8{
79 "test.zig",
80 },
79 });81 });
80 }82 }
8183
lib/std/build.zig+44-9
...@@ -1019,6 +1019,23 @@ pub const Builder = struct {...@@ -1019,6 +1019,23 @@ pub const Builder = struct {
1019 };1019 };
1020 }1020 }
10211021
1022 pub fn truncateFile(self: *Builder, dest_path: []const u8) !void {
1023 if (self.verbose) {
1024 warn("truncate {s}\n", .{dest_path});
1025 }
1026 const cwd = fs.cwd();
1027 var src_file = cwd.createFile(dest_path, .{}) catch |err| switch (err) {
1028 error.FileNotFound => blk: {
1029 if (fs.path.dirname(dest_path)) |dirname| {
1030 try cwd.makePath(dirname);
1031 }
1032 break :blk try cwd.createFile(dest_path, .{});
1033 },
1034 else => |e| return e,
1035 };
1036 src_file.close();
1037 }
1038
1022 pub fn pathFromRoot(self: *Builder, rel_path: []const u8) []u8 {1039 pub fn pathFromRoot(self: *Builder, rel_path: []const u8) []u8 {
1023 return fs.path.resolve(self.allocator, &[_][]const u8{ self.build_root, rel_path }) catch unreachable;1040 return fs.path.resolve(self.allocator, &[_][]const u8{ self.build_root, rel_path }) catch unreachable;
1024 }1041 }
...@@ -2791,17 +2808,23 @@ pub const InstallDirectoryOptions = struct {...@@ -2791,17 +2808,23 @@ pub const InstallDirectoryOptions = struct {
2791 source_dir: []const u8,2808 source_dir: []const u8,
2792 install_dir: InstallDir,2809 install_dir: InstallDir,
2793 install_subdir: []const u8,2810 install_subdir: []const u8,
2794 exclude_extensions: ?[]const []const u8 = null,2811 /// File paths which end in any of these suffixes will be excluded
2812 /// from being installed.
2813 exclude_extensions: []const []const u8 = &.{},
2814 /// File paths which end in any of these suffixes will result in
2815 /// empty files being installed. This is mainly intended for large
2816 /// test.zig files in order to prevent needless installation bloat.
2817 /// However if the files were not present at all, then
2818 /// `@import("test.zig")` would be a compile error.
2819 blank_extensions: []const []const u8 = &.{},
27952820
2796 fn dupe(self: InstallDirectoryOptions, b: *Builder) InstallDirectoryOptions {2821 fn dupe(self: InstallDirectoryOptions, b: *Builder) InstallDirectoryOptions {
2797 return .{2822 return .{
2798 .source_dir = b.dupe(self.source_dir),2823 .source_dir = b.dupe(self.source_dir),
2799 .install_dir = self.install_dir.dupe(b),2824 .install_dir = self.install_dir.dupe(b),
2800 .install_subdir = b.dupe(self.install_subdir),2825 .install_subdir = b.dupe(self.install_subdir),
2801 .exclude_extensions = if (self.exclude_extensions) |extensions|2826 .exclude_extensions = b.dupeStrings(self.exclude_extensions),
2802 b.dupeStrings(extensions)2827 .blank_extensions = b.dupeStrings(self.blank_extensions),
2803 else
2804 null,
2805 };2828 };
2806 }2829 }
2807};2830};
...@@ -2829,17 +2852,29 @@ pub const InstallDirStep = struct {...@@ -2829,17 +2852,29 @@ pub const InstallDirStep = struct {
2829 const full_src_dir = self.builder.pathFromRoot(self.options.source_dir);2852 const full_src_dir = self.builder.pathFromRoot(self.options.source_dir);
2830 var it = try fs.walkPath(self.builder.allocator, full_src_dir);2853 var it = try fs.walkPath(self.builder.allocator, full_src_dir);
2831 next_entry: while (try it.next()) |entry| {2854 next_entry: while (try it.next()) |entry| {
2832 if (self.options.exclude_extensions) |ext_list| for (ext_list) |ext| {2855 for (self.options.exclude_extensions) |ext| {
2833 if (mem.endsWith(u8, entry.path, ext)) {2856 if (mem.endsWith(u8, entry.path, ext)) {
2834 continue :next_entry;2857 continue :next_entry;
2835 }2858 }
2836 };2859 }
28372860
2838 const rel_path = entry.path[full_src_dir.len + 1 ..];2861 const rel_path = entry.path[full_src_dir.len + 1 ..];
2839 const dest_path = try fs.path.join(self.builder.allocator, &[_][]const u8{ dest_prefix, rel_path });2862 const dest_path = try fs.path.join(self.builder.allocator, &[_][]const u8{
2863 dest_prefix, rel_path,
2864 });
2865
2840 switch (entry.kind) {2866 switch (entry.kind) {
2841 .Directory => try fs.cwd().makePath(dest_path),2867 .Directory => try fs.cwd().makePath(dest_path),
2842 .File => try self.builder.updateFile(entry.path, dest_path),2868 .File => {
2869 for (self.options.blank_extensions) |ext| {
2870 if (mem.endsWith(u8, entry.path, ext)) {
2871 try self.builder.truncateFile(dest_path);
2872 continue :next_entry;
2873 }
2874 }
2875
2876 try self.builder.updateFile(entry.path, dest_path);
2877 },
2843 else => continue,2878 else => continue,
2844 }2879 }
2845 }2880 }