authorgravatar for xq@random-projects.netFelix "xq" Queißner <xq@random-projects.net> 2021-02-22 21:23:44+01:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2021-06-11 10:33:26+03:00
log4ed567d12e2670596ebc4bf42c710b4e3210e77e
treeed4986cddfe64caa612748b1deb3fa591053ce89
parent437f81aa9a963af2dce654cd0ac7ac0e19a4922a

Adds more FileSources everywhere.


4 files changed, 111 insertions(+), 160 deletions(-)

lib/std/build.zig+46-118
...@@ -204,55 +204,24 @@ pub const Builder = struct {...@@ -204,55 +204,24 @@ pub const Builder = struct {
204 self.h_dir = fs.path.join(self.allocator, &[_][]const u8{ self.install_path, "include" }) catch unreachable;204 self.h_dir = fs.path.join(self.allocator, &[_][]const u8{ self.install_path, "include" }) catch unreachable;
205 }205 }
206206
207 pub fn addExecutable(self: *Builder, name: []const u8, root_src: ?[]const u8) *LibExeObjStep {207 fn convertOptionalPathToFileSource(path: ?[]const u8) ?FileSource {
208 return LibExeObjStep.createExecutable(208 return if (path) |p|
209 self,209 FileSource.relative(p)
210 name,210 else
211 if (root_src) |p| FileSource{ .path = p } else null,211 null;
212 false,
213 );
214 }212 }
215213
216 pub fn addExecutableFromWriteFileStep(214 pub fn addExecutable(self: *Builder, name: []const u8, root_src: ?[]const u8) *LibExeObjStep {
217 self: *Builder,215 return addExecutableSource(self, name, convertOptionalPathToFileSource(root_src), false);
218 name: []const u8,
219 wfs: *WriteFileStep,
220 basename: []const u8,
221 ) *LibExeObjStep {
222 return LibExeObjStep.createExecutable(self, name, @as(FileSource, .{
223 .write_file = .{
224 .step = wfs,
225 .basename = basename,
226 },
227 }), false);
228 }216 }
229217
230 pub fn addExecutableSource(218 pub const addExecutableSource = LibExeObjStep.createExecutable;
231 self: *Builder,
232 name: []const u8,
233 root_src: ?FileSource,
234 ) *LibExeObjStep {
235 return LibExeObjStep.createExecutable(self, name, root_src, false);
236 }
237219
238 pub fn addObject(self: *Builder, name: []const u8, root_src: ?[]const u8) *LibExeObjStep {220 pub fn addObject(self: *Builder, name: []const u8, root_src: ?[]const u8) *LibExeObjStep {
239 const root_src_param = if (root_src) |p| @as(FileSource, .{ .path = p }) else null;221 return addObjectSource(self, name, convertOptionalPathToFileSource(root_src));
240 return LibExeObjStep.createObject(self, name, root_src_param);
241 }222 }
242223
243 pub fn addObjectFromWriteFileStep(224 pub const addObjectSource = LibExeObjStep.createObject;
244 self: *Builder,
245 name: []const u8,
246 wfs: *WriteFileStep,
247 basename: []const u8,
248 ) *LibExeObjStep {
249 return LibExeObjStep.createObject(self, name, @as(FileSource, .{
250 .write_file = .{
251 .step = wfs,
252 .basename = basename,
253 },
254 }));
255 }
256225
257 pub fn addSharedLibrary(226 pub fn addSharedLibrary(
258 self: *Builder,227 self: *Builder,
...@@ -260,64 +229,33 @@ pub const Builder = struct {...@@ -260,64 +229,33 @@ pub const Builder = struct {
260 root_src: ?[]const u8,229 root_src: ?[]const u8,
261 kind: LibExeObjStep.SharedLibKind,230 kind: LibExeObjStep.SharedLibKind,
262 ) *LibExeObjStep {231 ) *LibExeObjStep {
263 const root_src_param = if (root_src) |p| @as(FileSource, .{ .path = p }) else null;232 return addSharedLibrarySource(self, name, convertOptionalPathToFileSource(root_src), kind);
264 return LibExeObjStep.createSharedLibrary(self, name, root_src_param, kind);
265 }233 }
266234
267 pub fn addSharedLibraryFromWriteFileStep(235 pub const addSharedLibrarySource = LibExeObjStep.createSharedLibrary;
268 self: *Builder,
269 name: []const u8,
270 wfs: *WriteFileStep,
271 basename: []const u8,
272 kind: LibExeObjStep.SharedLibKind,
273 ) *LibExeObjStep {
274 return LibExeObjStep.createSharedLibrary(self, name, @as(FileSource, .{
275 .write_file = .{
276 .step = wfs,
277 .basename = basename,
278 },
279 }), kind);
280 }
281236
282 pub fn addStaticLibrary(self: *Builder, name: []const u8, root_src: ?[]const u8) *LibExeObjStep {237 pub fn addStaticLibrary(self: *Builder, name: []const u8, root_src: ?[]const u8) *LibExeObjStep {
283 const root_src_param = if (root_src) |p| @as(FileSource, .{ .path = p }) else null;238 const root_src_param = if (root_src) |p| @as(FileSource, .{ .path = p }) else null;
284 return LibExeObjStep.createStaticLibrary(self, name, root_src_param);239 return LibExeObjStep.createStaticLibrary(self, name, root_src_param);
285 }240 }
286241
287 pub fn addStaticLibraryFromWriteFileStep(242 pub const addStaticLibrarySource = LibExeObjStep.createStaticLibrary;
288 self: *Builder,
289 name: []const u8,
290 wfs: *WriteFileStep,
291 basename: []const u8,
292 ) *LibExeObjStep {
293 return LibExeObjStep.createStaticLibrary(self, name, @as(FileSource, .{
294 .write_file = .{
295 .step = wfs,
296 .basename = basename,
297 },
298 }));
299 }
300243
301 pub fn addTest(self: *Builder, root_src: []const u8) *LibExeObjStep {244 pub fn addTest(self: *Builder, root_src: []const u8) *LibExeObjStep {
302 return LibExeObjStep.createTest(self, "test", .{ .path = root_src });245 return LibExeObjStep.createTest(self, "test", .{ .path = root_src });
303 }246 }
304247
305 pub fn addTestFromWriteFileStep(248 pub fn addTestSource(self: *Builder, root_src: FileSource) *LibExeObjStep {
306 self: *Builder,249 return LibExeObjStep.createTest(self, "test", root_src);
307 wfs: *WriteFileStep,
308 basename: []const u8,
309 ) *LibExeObjStep {
310 return LibExeObjStep.createTest(self, "test", @as(FileSource, .{
311 .write_file = .{
312 .step = wfs,
313 .basename = basename,
314 },
315 }));
316 }250 }
317251
318 pub fn addAssemble(self: *Builder, name: []const u8, src: []const u8) *LibExeObjStep {252 pub fn addAssemble(self: *Builder, name: []const u8, src: []const u8) *LibExeObjStep {
253 return addAssembleSource(self, name, FileSource.relative(src));
254 }
255
256 pub fn addAssembleSource(self: *Builder, name: []const u8, src: FileSource) *LibExeObjStep {
319 const obj_step = LibExeObjStep.createObject(self, name, null);257 const obj_step = LibExeObjStep.createObject(self, name, null);
320 obj_step.addAssemblyFile(src);258 obj_step.addAssemblyFileSource(src);
321 return obj_step;259 return obj_step;
322 }260 }
323261
...@@ -938,7 +876,7 @@ pub const Builder = struct {...@@ -938,7 +876,7 @@ pub const Builder = struct {
938876
939 ///`dest_rel_path` is relative to prefix path877 ///`dest_rel_path` is relative to prefix path
940 pub fn installFile(self: *Builder, src_path: []const u8, dest_rel_path: []const u8) void {878 pub fn installFile(self: *Builder, src_path: []const u8, dest_rel_path: []const u8) void {
941 self.getInstallStep().dependOn(&self.addInstallFileWithDir(src_path, .Prefix, dest_rel_path).step);879 self.getInstallStep().dependOn(&self.addInstallFileWithDir(FileSource.relative(src_path), .Prefix, dest_rel_path).step);
942 }880 }
943881
944 pub fn installDirectory(self: *Builder, options: InstallDirectoryOptions) void {882 pub fn installDirectory(self: *Builder, options: InstallDirectoryOptions) void {
...@@ -947,12 +885,12 @@ pub const Builder = struct {...@@ -947,12 +885,12 @@ pub const Builder = struct {
947885
948 ///`dest_rel_path` is relative to bin path886 ///`dest_rel_path` is relative to bin path
949 pub fn installBinFile(self: *Builder, src_path: []const u8, dest_rel_path: []const u8) void {887 pub fn installBinFile(self: *Builder, src_path: []const u8, dest_rel_path: []const u8) void {
950 self.getInstallStep().dependOn(&self.addInstallFileWithDir(src_path, .Bin, dest_rel_path).step);888 self.getInstallStep().dependOn(&self.addInstallFileWithDir(FileSource.relative(src_path), .Bin, dest_rel_path).step);
951 }889 }
952890
953 ///`dest_rel_path` is relative to lib path891 ///`dest_rel_path` is relative to lib path
954 pub fn installLibFile(self: *Builder, src_path: []const u8, dest_rel_path: []const u8) void {892 pub fn installLibFile(self: *Builder, src_path: []const u8, dest_rel_path: []const u8) void {
955 self.getInstallStep().dependOn(&self.addInstallFileWithDir(src_path, .Lib, dest_rel_path).step);893 self.getInstallStep().dependOn(&self.addInstallFileWithDir(FileSource.relative(src_path), .Lib, dest_rel_path).step);
956 }894 }
957895
958 pub fn installRaw(self: *Builder, artifact: *LibExeObjStep, dest_filename: []const u8) void {896 pub fn installRaw(self: *Builder, artifact: *LibExeObjStep, dest_filename: []const u8) void {
...@@ -961,17 +899,17 @@ pub const Builder = struct {...@@ -961,17 +899,17 @@ pub const Builder = struct {
961899
962 ///`dest_rel_path` is relative to install prefix path900 ///`dest_rel_path` is relative to install prefix path
963 pub fn addInstallFile(self: *Builder, src_path: []const u8, dest_rel_path: []const u8) *InstallFileStep {901 pub fn addInstallFile(self: *Builder, src_path: []const u8, dest_rel_path: []const u8) *InstallFileStep {
964 return self.addInstallFileWithDir(src_path, .Prefix, dest_rel_path);902 return self.addInstallFileWithDir(FileSource.relative(src_path), .Prefix, dest_rel_path);
965 }903 }
966904
967 ///`dest_rel_path` is relative to bin path905 ///`dest_rel_path` is relative to bin path
968 pub fn addInstallBinFile(self: *Builder, src_path: []const u8, dest_rel_path: []const u8) *InstallFileStep {906 pub fn addInstallBinFile(self: *Builder, src_path: []const u8, dest_rel_path: []const u8) *InstallFileStep {
969 return self.addInstallFileWithDir(src_path, .Bin, dest_rel_path);907 return self.addInstallFileWithDir(FileSource.relative(src_path), .Bin, dest_rel_path);
970 }908 }
971909
972 ///`dest_rel_path` is relative to lib path910 ///`dest_rel_path` is relative to lib path
973 pub fn addInstallLibFile(self: *Builder, src_path: []const u8, dest_rel_path: []const u8) *InstallFileStep {911 pub fn addInstallLibFile(self: *Builder, src_path: []const u8, dest_rel_path: []const u8) *InstallFileStep {
974 return self.addInstallFileWithDir(src_path, .Lib, dest_rel_path);912 return self.addInstallFileWithDir(FileSource.relative(src_path), .Lib, dest_rel_path);
975 }913 }
976914
977 pub fn addInstallRaw(self: *Builder, artifact: *LibExeObjStep, dest_filename: []const u8) *InstallRawStep {915 pub fn addInstallRaw(self: *Builder, artifact: *LibExeObjStep, dest_filename: []const u8) *InstallRawStep {
...@@ -980,7 +918,7 @@ pub const Builder = struct {...@@ -980,7 +918,7 @@ pub const Builder = struct {
980918
981 pub fn addInstallFileWithDir(919 pub fn addInstallFileWithDir(
982 self: *Builder,920 self: *Builder,
983 src_path: []const u8,921 source: FileSource,
984 install_dir: InstallDir,922 install_dir: InstallDir,
985 dest_rel_path: []const u8,923 dest_rel_path: []const u8,
986 ) *InstallFileStep {924 ) *InstallFileStep {
...@@ -988,7 +926,7 @@ pub const Builder = struct {...@@ -988,7 +926,7 @@ pub const Builder = struct {
988 panic("dest_rel_path must be non-empty", .{});926 panic("dest_rel_path must be non-empty", .{});
989 }927 }
990 const install_step = self.allocator.create(InstallFileStep) catch unreachable;928 const install_step = self.allocator.create(InstallFileStep) catch unreachable;
991 install_step.* = InstallFileStep.init(self, src_path, install_dir, dest_rel_path);929 install_step.* = InstallFileStep.init(self, source, install_dir, dest_rel_path);
992 return install_step;930 return install_step;
993 }931 }
994932
...@@ -1301,42 +1239,41 @@ pub const GeneratedFile = struct {...@@ -1301,42 +1239,41 @@ pub const GeneratedFile = struct {
1301pub const FileSource = union(enum) {1239pub const FileSource = union(enum) {
1302 /// Relative to build root1240 /// Relative to build root
1303 path: []const u8,1241 path: []const u8,
1304 write_file: struct {
1305 step: *WriteFileStep,
1306 basename: []const u8,
1307 },
1308 generated: *const GeneratedFile,1242 generated: *const GeneratedFile,
13091243
1310 pub fn relative(path: []const u8) FileSource {1244 pub fn relative(path: []const u8) FileSource {
1311 return FileSource{ .path = path };1245 return FileSource{ .path = path };
1312 }1246 }
13131247
1248 /// Returns a string that can be shown to represent the file source.
1249 /// Either returns the path or `"generated"`.
1250 pub fn getDisplayName(self: FileSource) []const u8 {
1251 return switch (self) {
1252 .path => self.path,
1253 .generated => "generated",
1254 };
1255 }
1256
1314 pub fn addStepDependencies(self: FileSource, step: *Step) void {1257 pub fn addStepDependencies(self: FileSource, step: *Step) void {
1315 switch (self) {1258 switch (self) {
1316 .path => {},1259 .path => {},
1317 .write_file => |wf| step.dependOn(&wf.step.step),
1318 .generated => |gen| step.dependOn(gen.step),1260 .generated => |gen| step.dependOn(gen.step),
1319 }1261 }
1320 }1262 }
13211263
1322 /// Should only be called during make()1264 /// Should only be called during make(), returns an absolute path to the file.
1323 pub fn getPath(self: FileSource, builder: *Builder) []const u8 {1265 pub fn getPath(self: FileSource, builder: *Builder) []const u8 {
1324 return switch (self) {1266 const path = switch (self) {
1325 .path => |p| builder.pathFromRoot(p),1267 .path => |p| builder.pathFromRoot(p),
1326 .write_file => |wf| wf.step.getOutputPath(wf.basename),
1327 .generated => |gen| gen.getPath(),1268 .generated => |gen| gen.getPath(),
1328 };1269 };
1270 std.debug.assert(std.fs.path.isAbsolute(path));
1271 return path;
1329 }1272 }
13301273
1331 pub fn dupe(self: FileSource, b: *Builder) FileSource {1274 pub fn dupe(self: FileSource, b: *Builder) FileSource {
1332 return switch (self) {1275 return switch (self) {
1333 .path => |p| .{ .path = b.dupePath(p) },1276 .path => |p| .{ .path = b.dupePath(p) },
1334 .write_file => |wf| .{
1335 .write_file = .{
1336 .step = wf.step,
1337 .basename = b.dupe(wf.basename),
1338 },
1339 },
1340 .generated => |gen| .{ .generated = gen },1277 .generated => |gen| .{ .generated = gen },
1341 };1278 };
1342 }1279 }
...@@ -1967,15 +1904,6 @@ pub const LibExeObjStep = struct {...@@ -1967,15 +1904,6 @@ pub const LibExeObjStep = struct {
1967 }) catch unreachable;1904 }) catch unreachable;
1968 }1905 }
19691906
1970 pub fn addAssemblyFileFromWriteFileStep(self: *LibExeObjStep, wfs: *WriteFileStep, basename: []const u8) void {
1971 self.addAssemblyFileSource(.{
1972 .write_file = .{
1973 .step = wfs,
1974 .basename = self.builder.dupe(basename),
1975 },
1976 });
1977 }
1978
1979 pub fn addAssemblyFileSource(self: *LibExeObjStep, source: FileSource) void {1907 pub fn addAssemblyFileSource(self: *LibExeObjStep, source: FileSource) void {
1980 const source_duped = source.dupe(self.builder);1908 const source_duped = source.dupe(self.builder);
1981 self.link_objects.append(LinkObject{ .AssemblyFile = source_duped }) catch unreachable;1909 self.link_objects.append(LinkObject{ .AssemblyFile = source_duped }) catch unreachable;
...@@ -2834,21 +2762,21 @@ pub const InstallArtifactStep = struct {...@@ -2834,21 +2762,21 @@ pub const InstallArtifactStep = struct {
2834pub const InstallFileStep = struct {2762pub const InstallFileStep = struct {
2835 step: Step,2763 step: Step,
2836 builder: *Builder,2764 builder: *Builder,
2837 src_path: []const u8,2765 source: FileSource,
2838 dir: InstallDir,2766 dir: InstallDir,
2839 dest_rel_path: []const u8,2767 dest_rel_path: []const u8,
28402768
2841 pub fn init(2769 pub fn init(
2842 builder: *Builder,2770 builder: *Builder,
2843 src_path: []const u8,2771 source: FileSource,
2844 dir: InstallDir,2772 dir: InstallDir,
2845 dest_rel_path: []const u8,2773 dest_rel_path: []const u8,
2846 ) InstallFileStep {2774 ) InstallFileStep {
2847 builder.pushInstalledFile(dir, dest_rel_path);2775 builder.pushInstalledFile(dir, dest_rel_path);
2848 return InstallFileStep{2776 return InstallFileStep{
2849 .builder = builder,2777 .builder = builder,
2850 .step = Step.init(.InstallFile, builder.fmt("install {s}", .{src_path}), builder.allocator, make),2778 .step = Step.init(.InstallFile, builder.fmt("install {s} to {s}", .{ source.getDisplayName(), dest_rel_path }), builder.allocator, make),
2851 .src_path = builder.dupePath(src_path),2779 .source = source.dupe(builder),
2852 .dir = dir.dupe(builder),2780 .dir = dir.dupe(builder),
2853 .dest_rel_path = builder.dupePath(dest_rel_path),2781 .dest_rel_path = builder.dupePath(dest_rel_path),
2854 };2782 };
...@@ -2857,7 +2785,7 @@ pub const InstallFileStep = struct {...@@ -2857,7 +2785,7 @@ pub const InstallFileStep = struct {
2857 fn make(step: *Step) !void {2785 fn make(step: *Step) !void {
2858 const self = @fieldParentPtr(InstallFileStep, "step", step);2786 const self = @fieldParentPtr(InstallFileStep, "step", step);
2859 const full_dest_path = self.builder.getInstallPath(self.dir, self.dest_rel_path);2787 const full_dest_path = self.builder.getInstallPath(self.dir, self.dest_rel_path);
2860 const full_src_path = self.builder.pathFromRoot(self.src_path);2788 const full_src_path = self.source.getPath(self.builder);
2861 try self.builder.updateFile(full_src_path, full_dest_path);2789 try self.builder.updateFile(full_src_path, full_dest_path);
2862 }2790 }
2863};2791};
lib/std/build/run.zig+11-19
...@@ -47,12 +47,9 @@ pub const RunStep = struct {...@@ -47,12 +47,9 @@ pub const RunStep = struct {
47 };47 };
4848
49 pub const Arg = union(enum) {49 pub const Arg = union(enum) {
50 Artifact: *LibExeObjStep,50 artifact: *LibExeObjStep,
51 WriteFile: struct {51 file_source: build.FileSource,
52 step: *WriteFileStep,52 bytes: []u8,
53 file_name: []const u8,
54 },
55 Bytes: []u8,
56 };53 };
5754
58 pub fn create(builder: *Builder, name: []const u8) *RunStep {55 pub fn create(builder: *Builder, name: []const u8) *RunStep {
...@@ -68,22 +65,19 @@ pub const RunStep = struct {...@@ -68,22 +65,19 @@ pub const RunStep = struct {
68 }65 }
6966
70 pub fn addArtifactArg(self: *RunStep, artifact: *LibExeObjStep) void {67 pub fn addArtifactArg(self: *RunStep, artifact: *LibExeObjStep) void {
71 self.argv.append(Arg{ .Artifact = artifact }) catch unreachable;68 self.argv.append(Arg{ .artifact = artifact }) catch unreachable;
72 self.step.dependOn(&artifact.step);69 self.step.dependOn(&artifact.step);
73 }70 }
7471
75 pub fn addWriteFileArg(self: *RunStep, write_file: *WriteFileStep, file_name: []const u8) void {72 pub fn addFileSourceArg(self: *RunStep, file_source: build.FileSource) void {
76 self.argv.append(Arg{73 self.argv.append(Arg{
77 .WriteFile = .{74 .file_source = file_source,
78 .step = write_file,
79 .file_name = self.builder.dupePath(file_name),
80 },
81 }) catch unreachable;75 }) catch unreachable;
82 self.step.dependOn(&write_file.step);76 file_source.addStepDependencies(&self.step);
83 }77 }
8478
85 pub fn addArg(self: *RunStep, arg: []const u8) void {79 pub fn addArg(self: *RunStep, arg: []const u8) void {
86 self.argv.append(Arg{ .Bytes = self.builder.dupe(arg) }) catch unreachable;80 self.argv.append(Arg{ .bytes = self.builder.dupe(arg) }) catch unreachable;
87 }81 }
8882
89 pub fn addArgs(self: *RunStep, args: []const []const u8) void {83 pub fn addArgs(self: *RunStep, args: []const []const u8) void {
...@@ -162,11 +156,9 @@ pub const RunStep = struct {...@@ -162,11 +156,9 @@ pub const RunStep = struct {
162 var argv_list = ArrayList([]const u8).init(self.builder.allocator);156 var argv_list = ArrayList([]const u8).init(self.builder.allocator);
163 for (self.argv.items) |arg| {157 for (self.argv.items) |arg| {
164 switch (arg) {158 switch (arg) {
165 Arg.Bytes => |bytes| try argv_list.append(bytes),159 .bytes => |bytes| try argv_list.append(bytes),
166 Arg.WriteFile => |file| {160 .file_source => |file| try argv_list.append(file.getPath(self.builder)),
167 try argv_list.append(file.step.getOutputPath(file.file_name));161 .artifact => |artifact| {
168 },
169 Arg.Artifact => |artifact| {
170 if (artifact.target.isWindows()) {162 if (artifact.target.isWindows()) {
171 // On Windows we don't have rpaths so we have to add .dll search paths to PATH163 // On Windows we don't have rpaths so we have to add .dll search paths to PATH
172 self.addPathForDynLibs(artifact);164 self.addPathForDynLibs(artifact);
lib/std/build/translate_c.zig+1-1
...@@ -62,7 +62,7 @@ pub const TranslateCStep = struct {...@@ -62,7 +62,7 @@ pub const TranslateCStep = struct {
6262
63 /// Creates a step to build an executable from the translated source.63 /// Creates a step to build an executable from the translated source.
64 pub fn addExecutable(self: *TranslateCStep) *LibExeObjStep {64 pub fn addExecutable(self: *TranslateCStep) *LibExeObjStep {
65 return self.builder.addExecutableSource("translated_c", @as(build.FileSource, .{ .generated = &self.output_file }));65 return self.builder.addExecutableSource("translated_c", build.FileSource{ .generated = &self.output_file }, false);
66 }66 }
6767
68 pub fn addIncludeDir(self: *TranslateCStep, include_dir: []const u8) void {68 pub fn addIncludeDir(self: *TranslateCStep, include_dir: []const u8) void {
lib/std/build/write_file.zig+53-22
...@@ -15,9 +15,10 @@ pub const WriteFileStep = struct {...@@ -15,9 +15,10 @@ pub const WriteFileStep = struct {
15 step: Step,15 step: Step,
16 builder: *Builder,16 builder: *Builder,
17 output_dir: []const u8,17 output_dir: []const u8,
18 files: ArrayList(File),18 files: std.TailQueue(File),
1919
20 pub const File = struct {20 pub const File = struct {
21 source: build.GeneratedFile,
21 basename: []const u8,22 basename: []const u8,
22 bytes: []const u8,23 bytes: []const u8,
23 };24 };
...@@ -26,25 +27,49 @@ pub const WriteFileStep = struct {...@@ -26,25 +27,49 @@ pub const WriteFileStep = struct {
26 return WriteFileStep{27 return WriteFileStep{
27 .builder = builder,28 .builder = builder,
28 .step = Step.init(.WriteFile, "writefile", builder.allocator, make),29 .step = Step.init(.WriteFile, "writefile", builder.allocator, make),
29 .files = ArrayList(File).init(builder.allocator),30 .files = .{},
30 .output_dir = undefined,31 .output_dir = undefined,
31 };32 };
32 }33 }
3334
34 pub fn add(self: *WriteFileStep, basename: []const u8, bytes: []const u8) void {35 pub fn add(self: *WriteFileStep, basename: []const u8, bytes: []const u8) void {
35 self.files.append(.{36 const node = self.builder.allocator.create(std.TailQueue(File).Node) catch unreachable;
36 .basename = self.builder.dupePath(basename),37 node.* = .{
37 .bytes = self.builder.dupe(bytes),38 .data = .{
38 }) catch unreachable;39 .source = build.GeneratedFile{
40 .step = &self.step,
41 .getPathFn = getFilePath,
42 },
43 .basename = self.builder.dupePath(basename),
44 .bytes = self.builder.dupe(bytes),
45 },
46 };
47
48 self.files.append(node);
39 }49 }
4050
41 /// Unless setOutputDir was called, this function must be called only in51 /// Unless setOutputDir was called, this function must be called only in
42 /// the make step, from a step that has declared a dependency on this one.52 /// the make step, from a step that has declared a dependency on this one.
43 /// To run an executable built with zig build, use `run`, or create an install step and invoke it.53 /// To run an executable built with zig build, use `run`, or create an install step and invoke it.
44 pub fn getOutputPath(self: *WriteFileStep, basename: []const u8) []const u8 {54 //pub const getOutputPath = @compileError("WriteFileStep.getOutputPath is deprecated! Use getFileSource to retrieve a ");
55 /// Gets a file source for the given basename. If the file does not exist, returns `null`.
56 pub fn getFileSource(step: *WriteFileStep, basename: []const u8) ?build.FileSource {
57 var it = step.files.first;
58 while (it) |node| : (it = node.next) {
59 if (std.mem.eql(u8, node.data.basename, basename))
60 return build.FileSource{ .generated = &node.data.source };
61 }
62 return null;
63 }
64
65 /// Returns the
66 fn getFilePath(source: *const build.GeneratedFile) []const u8 {
67 const file = @fieldParentPtr(File, "source", source);
68 const step = @fieldParentPtr(WriteFileStep, "step", source.step);
69
45 return fs.path.join(70 return fs.path.join(
46 self.builder.allocator,71 step.builder.allocator,
47 &[_][]const u8{ self.output_dir, basename },72 &[_][]const u8{ step.output_dir, file.basename },
48 ) catch unreachable;73 ) catch unreachable;
49 }74 }
5075
...@@ -67,10 +92,13 @@ pub const WriteFileStep = struct {...@@ -67,10 +92,13 @@ pub const WriteFileStep = struct {
67 // new random bytes when WriteFileStep implementation is modified92 // new random bytes when WriteFileStep implementation is modified
68 // in a non-backwards-compatible way.93 // in a non-backwards-compatible way.
69 hash.update("eagVR1dYXoE7ARDP");94 hash.update("eagVR1dYXoE7ARDP");
70 for (self.files.items) |file| {95 {
71 hash.update(file.basename);96 var it = self.files.first;
72 hash.update(file.bytes);97 while (it) |node| : (it = node.next) {
73 hash.update("|");98 hash.update(node.data.basename);
99 hash.update(node.data.bytes);
100 hash.update("|");
101 }
74 }102 }
75 var digest: [48]u8 = undefined;103 var digest: [48]u8 = undefined;
76 hash.final(&digest);104 hash.final(&digest);
...@@ -88,15 +116,18 @@ pub const WriteFileStep = struct {...@@ -88,15 +116,18 @@ pub const WriteFileStep = struct {
88 };116 };
89 var dir = try fs.cwd().openDir(self.output_dir, .{});117 var dir = try fs.cwd().openDir(self.output_dir, .{});
90 defer dir.close();118 defer dir.close();
91 for (self.files.items) |file| {119 {
92 dir.writeFile(file.basename, file.bytes) catch |err| {120 var it = self.files.first;
93 warn("unable to write {s} into {s}: {s}\n", .{121 while (it) |node| : (it = node.next) {
94 file.basename,122 dir.writeFile(node.data.basename, node.data.bytes) catch |err| {
95 self.output_dir,123 warn("unable to write {s} into {s}: {s}\n", .{
96 @errorName(err),124 node.data.basename,
97 });125 self.output_dir,
98 return err;126 @errorName(err),
99 };127 });
128 return err;
129 };
130 }
100 }131 }
101 }132 }
102};133};