| author | |
| committer | |
| log | 642d017fea531d1347b8ade16c33065389a20192 |
| tree | 0787d894331e74f60c0352c02ce7f629aa6a3dd4 |
| parent | 9b6dd7ee5c4137942f7fbbdd27d8e06f6ce7c7b1 |
4 files changed, 35 insertions(+), 32 deletions(-)
lib/compiler/Maker.zig+4-2| ... | @@ -1708,12 +1708,14 @@ pub fn resolveLazyPath( | ... | @@ -1708,12 +1708,14 @@ pub fn resolveLazyPath( |
| 1708 | .source_path => |sp| try packagePath(maker, arena, sp.owner, sp.sub_path.slice(c)), | 1708 | .source_path => |sp| try packagePath(maker, arena, sp.owner, sp.sub_path.slice(c)), |
| 1709 | .relative => |relative| relativePath(maker, relative), | 1709 | .relative => |relative| relativePath(maker, relative), |
| 1710 | .generated => |gen| { | 1710 | .generated => |gen| { |
| 1711 | const base = generatedPath(maker, gen.index); | 1711 | const base = generatedPath(maker, gen.index).*; |
| 1712 | var file_path = base; | 1712 | var file_path = base; |
| 1713 | for (0..gen.flags.up) |_| { | 1713 | for (0..gen.flags.up) |_| { |
| 1714 | file_path.sub_path = Dir.path.dirname(file_path.sub_path) orelse { | 1714 | file_path.sub_path = Dir.path.dirname(file_path.sub_path) orelse { |
| 1715 | const s = stepByIndex(maker, asking_step_index); | 1715 | const s = stepByIndex(maker, asking_step_index); |
| 1716 | return s.fail(maker, "invalid LazyPath traversal: up {d} times from {f}", .{ gen.flags.up, base }); | 1716 | return s.fail(maker, "invalid LazyPath traversal: up {d} times from {f}", .{ |
| 1717 | gen.flags.up, base, | ||
| 1718 | }); | ||
| 1717 | }; | 1719 | }; |
| 1718 | } | 1720 | } |
| 1719 | return file_path.join(arena, gen.sub_path.slice(c)); | 1721 | return file_path.join(arena, gen.sub_path.slice(c)); |
lib/std/Build/Step/Run.zig+16-10| ... | @@ -242,21 +242,23 @@ pub fn addPrefixedArtifactArg(run: *Run, prefix: []const u8, artifact: *Step.Com | ... | @@ -242,21 +242,23 @@ pub fn addPrefixedArtifactArg(run: *Run, prefix: []const u8, artifact: *Step.Com |
| 242 | /// Returns a `std.Build.LazyPath` which can be used as inputs to other APIs | 242 | /// Returns a `std.Build.LazyPath` which can be used as inputs to other APIs |
| 243 | /// throughout the build system. | 243 | /// throughout the build system. |
| 244 | /// | 244 | /// |
| 245 | /// `sub_path` is the name of the generated output file which may have zero or | ||
| 246 | /// more path components. | ||
| 247 | /// | ||
| 245 | /// Related: | 248 | /// Related: |
| 246 | /// * `addPrefixedOutputFileArg` - same thing but prepends a string to the argument | 249 | /// * `addPrefixedOutputFileArg` - same thing but prepends a string to the argument |
| 247 | /// * `addFileArg` - for input files given to the child process | 250 | /// * `addFileArg` - for input files given to the child process |
| 248 | pub fn addOutputFileArg(run: *Run, basename: []const u8) std.Build.LazyPath { | 251 | pub fn addOutputFileArg(run: *Run, sub_path: []const u8) std.Build.LazyPath { |
| 249 | return run.addPrefixedOutputFileArg("", basename); | 252 | return run.addPrefixedOutputFileArg("", sub_path); |
| 250 | } | 253 | } |
| 251 | 254 | ||
| 252 | /// Provides a file path as a command line argument to the command being run. | 255 | /// Provides a file path as a command line argument to the command being run. |
| 253 | /// Asserts `basename` is not empty. | ||
| 254 | /// | 256 | /// |
| 255 | /// For example, a prefix of "-o" and basename of "output.txt" will result in | 257 | /// For example, a prefix of "-o" and `sub_path` of "output.txt" will result in |
| 256 | /// the child process seeing something like this: "-ozig-cache/.../output.txt" | 258 | /// the child process seeing something like this: "-ozig-cache/.../output.txt" |
| 257 | /// | 259 | /// |
| 258 | /// The child process will see a single argument, regardless of whether the | 260 | /// The child process will see a single argument, regardless of whether the |
| 259 | /// prefix or basename have spaces. | 261 | /// prefix or `sub_path` have spaces. |
| 260 | /// | 262 | /// |
| 261 | /// The returned `std.Build.LazyPath` can be used as inputs to other APIs | 263 | /// The returned `std.Build.LazyPath` can be used as inputs to other APIs |
| 262 | /// throughout the build system. | 264 | /// throughout the build system. |
| ... | @@ -267,23 +269,27 @@ pub fn addOutputFileArg(run: *Run, basename: []const u8) std.Build.LazyPath { | ... | @@ -267,23 +269,27 @@ pub fn addOutputFileArg(run: *Run, basename: []const u8) std.Build.LazyPath { |
| 267 | pub fn addPrefixedOutputFileArg( | 269 | pub fn addPrefixedOutputFileArg( |
| 268 | run: *Run, | 270 | run: *Run, |
| 269 | prefix: []const u8, | 271 | prefix: []const u8, |
| 270 | basename: []const u8, | 272 | /// The name of the generated output file which may have zero or more path |
| 273 | /// components. | ||
| 274 | /// | ||
| 275 | /// Asserted to be non-empty. | ||
| 276 | sub_path: []const u8, | ||
| 271 | ) std.Build.LazyPath { | 277 | ) std.Build.LazyPath { |
| 272 | const b = run.step.owner; | 278 | const b = run.step.owner; |
| 273 | const graph = b.graph; | 279 | const graph = b.graph; |
| 274 | const arena = graph.arena; | 280 | const arena = graph.arena; |
| 275 | if (basename.len == 0) @panic("basename must not be empty"); | 281 | assert(sub_path.len != 0); |
| 276 | 282 | ||
| 277 | const output = arena.create(Output) catch @panic("OOM"); | 283 | const output = graph.create(Output); |
| 278 | output.* = .{ | 284 | output.* = .{ |
| 279 | .prefix = graph.dupeString(prefix), | 285 | .prefix = graph.dupeString(prefix), |
| 280 | .basename = graph.dupeString(basename), | 286 | .basename = graph.dupeString(sub_path), |
| 281 | .generated_file = graph.addGeneratedFile(&run.step), | 287 | .generated_file = graph.addGeneratedFile(&run.step), |
| 282 | }; | 288 | }; |
| 283 | run.argv.append(arena, .{ .output_file = output }) catch @panic("OOM"); | 289 | run.argv.append(arena, .{ .output_file = output }) catch @panic("OOM"); |
| 284 | 290 | ||
| 285 | if (run.rename_step_with_output_arg) { | 291 | if (run.rename_step_with_output_arg) { |
| 286 | run.setName(b.fmt("{s} ({s})", .{ run.step.name, basename })); | 292 | run.setName(b.fmt("{s} ({s})", .{ run.step.name, sub_path })); |
| 287 | } | 293 | } |
| 288 | 294 | ||
| 289 | return .{ .generated = .{ .index = output.generated_file } }; | 295 | return .{ .generated = .{ .index = output.generated_file } }; |
test/standalone/dirname/build.zig+6-10| ... | @@ -27,22 +27,16 @@ pub fn build(b: *std.Build) void { | ... | @@ -27,22 +27,16 @@ pub fn build(b: *std.Build) void { |
| 27 | }), | 27 | }), |
| 28 | }); | 28 | }); |
| 29 | 29 | ||
| 30 | // Known path: | 30 | addTestRun(test_step, exists_in, "run exists_in (known path)", touch_src.dirname(), &.{"touch.zig"}); |
| 31 | addTestRun(test_step, exists_in, touch_src.dirname(), &.{"touch.zig"}); | 31 | addTestRun(test_step, exists_in, "run exists_in (generated file)", generated.dirname(), &.{"generated.txt"}); |
| 32 | 32 | addTestRun(test_step, exists_in, "run exists_in (generated file multi level)", generated.dirname().dirname(), &.{ | |
| 33 | // Generated file: | ||
| 34 | addTestRun(test_step, exists_in, generated.dirname(), &.{"generated.txt"}); | ||
| 35 | |||
| 36 | // Generated file multiple levels: | ||
| 37 | addTestRun(test_step, exists_in, generated.dirname().dirname(), &.{ | ||
| 38 | "subdir" ++ std.fs.path.sep_str ++ "generated.txt", | 33 | "subdir" ++ std.fs.path.sep_str ++ "generated.txt", |
| 39 | }); | 34 | }); |
| 40 | 35 | ||
| 41 | // Absolute path: | ||
| 42 | const write_files = b.addWriteFiles(); | 36 | const write_files = b.addWriteFiles(); |
| 43 | _ = write_files.add("foo.txt", ""); | 37 | _ = write_files.add("foo.txt", ""); |
| 44 | const abs_path = write_files.getDirectory(); | 38 | const abs_path = write_files.getDirectory(); |
| 45 | addTestRun(test_step, exists_in, abs_path, &.{"foo.txt"}); | 39 | addTestRun(test_step, exists_in, "run exists_in (absolute path)", abs_path, &.{"foo.txt"}); |
| 46 | } | 40 | } |
| 47 | 41 | ||
| 48 | // Runs exe with the parameters [dirname, args...]. | 42 | // Runs exe with the parameters [dirname, args...]. |
| ... | @@ -50,10 +44,12 @@ pub fn build(b: *std.Build) void { | ... | @@ -50,10 +44,12 @@ pub fn build(b: *std.Build) void { |
| 50 | fn addTestRun( | 44 | fn addTestRun( |
| 51 | test_step: *std.Build.Step, | 45 | test_step: *std.Build.Step, |
| 52 | exe: *std.Build.Step.Compile, | 46 | exe: *std.Build.Step.Compile, |
| 47 | step_name: []const u8, | ||
| 53 | dirname: std.Build.LazyPath, | 48 | dirname: std.Build.LazyPath, |
| 54 | args: []const []const u8, | 49 | args: []const []const u8, |
| 55 | ) void { | 50 | ) void { |
| 56 | const run = test_step.owner.addRunArtifact(exe); | 51 | const run = test_step.owner.addRunArtifact(exe); |
| 52 | run.setName(step_name); | ||
| 57 | run.addDirectoryArg(dirname); | 53 | run.addDirectoryArg(dirname); |
| 58 | run.addArgs(args); | 54 | run.addArgs(args); |
| 59 | run.expectExitCode(0); | 55 | run.expectExitCode(0); |
test/standalone/dirname/touch.zig+9-10| ... | @@ -7,27 +7,26 @@ | ... | @@ -7,27 +7,26 @@ |
| 7 | //! Path must be absolute. | 7 | //! Path must be absolute. |
| 8 | 8 | ||
| 9 | const std = @import("std"); | 9 | const std = @import("std"); |
| 10 | const Io = std.Io; | ||
| 10 | 11 | ||
| 11 | pub fn main(init: std.process.Init) !void { | 12 | pub fn main(init: std.process.Init) !void { |
| 13 | const io = init.io; | ||
| 14 | |||
| 12 | var args = try init.minimal.args.iterateAllocator(init.gpa); | 15 | var args = try init.minimal.args.iterateAllocator(init.gpa); |
| 13 | defer args.deinit(); | 16 | defer args.deinit(); |
| 14 | _ = args.next() orelse unreachable; // skip binary name | 17 | _ = args.next().?; // skip binary name |
| 15 | 18 | ||
| 16 | const path = args.next() orelse { | 19 | const path = args.next() orelse { |
| 17 | std.log.err("missing <path> argument", .{}); | 20 | std.log.err("missing <path> argument", .{}); |
| 18 | return error.BadUsage; | 21 | return error.BadUsage; |
| 19 | }; | 22 | }; |
| 20 | 23 | ||
| 21 | const dir_path = std.Io.Dir.path.dirname(path) orelse unreachable; | 24 | const dir_path = Io.Dir.path.dirname(path).?; |
| 22 | const basename = std.Io.Dir.path.basename(path); | 25 | const basename = Io.Dir.path.basename(path); |
| 23 | |||
| 24 | const io = std.Io.Threaded.global_single_threaded.io(); | ||
| 25 | 26 | ||
| 26 | var dir = try std.Io.Dir.cwd().openDir(io, dir_path, .{}); | 27 | var dir = try Io.Dir.cwd().openDir(io, dir_path, .{}); |
| 27 | defer dir.close(io); | 28 | defer dir.close(io); |
| 28 | 29 | ||
| 29 | _ = dir.statFile(io, basename, .{}) catch { | 30 | var file = try dir.createFile(io, basename, .{ .truncate = false }); |
| 30 | var file = try dir.createFile(io, basename, .{}); | 31 | file.close(io); |
| 31 | file.close(io); | ||
| 32 | }; | ||
| 33 | } | 32 | } |