| author | |
| committer | |
| log | 16d78bc0c024da307c7ab5f6b94622e6b4b37397 |
| tree | 9eb0e671a4ac1cfaf3795384d4b4e7d050d017d2 |
| parent | df4068cabd9af96d0aca1f435b985d1c103976da |
11 files changed, 160 insertions(+), 97 deletions(-)
build.zig+4-4| ... | ... | @@ -203,6 +203,10 @@ pub fn build(b: *std.Build) !void { |
| 203 | 203 | exe.pie = pie; |
| 204 | 204 | exe.entitlements = entitlements; |
| 205 | 205 | |
| 206 | const use_llvm = b.option(bool, "use-llvm", "Use the llvm backend"); | |
| 207 | exe.use_llvm = use_llvm; | |
| 208 | exe.use_lld = use_llvm; | |
| 209 | ||
| 206 | 210 | if (no_bin) { |
| 207 | 211 | b.getInstallStep().dependOn(&exe.step); |
| 208 | 212 | } else { |
| ... | ... | @@ -214,10 +218,6 @@ pub fn build(b: *std.Build) !void { |
| 214 | 218 | |
| 215 | 219 | test_step.dependOn(&exe.step); |
| 216 | 220 | |
| 217 | const use_llvm = b.option(bool, "use-llvm", "Use the llvm backend"); | |
| 218 | exe.use_llvm = use_llvm; | |
| 219 | exe.use_lld = use_llvm; | |
| 220 | ||
| 221 | 221 | const exe_options = b.addOptions(); |
| 222 | 222 | exe.root_module.addOptions("build_options", exe_options); |
| 223 | 223 |
lib/std/Build.zig+23| ... | ... | @@ -2456,12 +2456,23 @@ pub const GeneratedFile = struct { |
| 2456 | 2456 | /// This value must be set in the `fn make()` of the `step` and must not be `null` afterwards. |
| 2457 | 2457 | path: ?[]const u8 = null, |
| 2458 | 2458 | |
| 2459 | /// Deprecated, see `getPath2`. | |
| 2459 | 2460 | pub fn getPath(gen: GeneratedFile) []const u8 { |
| 2460 | 2461 | return gen.step.owner.pathFromCwd(gen.path orelse std.debug.panic( |
| 2461 | 2462 | "getPath() was called on a GeneratedFile that wasn't built yet. Is there a missing Step dependency on step '{s}'?", |
| 2462 | 2463 | .{gen.step.name}, |
| 2463 | 2464 | )); |
| 2464 | 2465 | } |
| 2466 | ||
| 2467 | pub fn getPath2(gen: GeneratedFile, src_builder: *Build, asking_step: ?*Step) []const u8 { | |
| 2468 | return gen.path orelse { | |
| 2469 | std.debug.lockStdErr(); | |
| 2470 | const stderr = std.io.getStdErr(); | |
| 2471 | dumpBadGetPathHelp(gen.step, stderr, src_builder, asking_step) catch {}; | |
| 2472 | std.debug.unlockStdErr(); | |
| 2473 | @panic("misconfigured build script"); | |
| 2474 | }; | |
| 2475 | } | |
| 2465 | 2476 | }; |
| 2466 | 2477 | |
| 2467 | 2478 | // dirnameAllowEmpty is a variant of fs.path.dirname |
| ... | ... | @@ -2712,6 +2723,18 @@ pub const LazyPath = union(enum) { |
| 2712 | 2723 | } |
| 2713 | 2724 | } |
| 2714 | 2725 | |
| 2726 | pub fn basename(lazy_path: LazyPath, src_builder: *Build, asking_step: ?*Step) []const u8 { | |
| 2727 | return fs.path.basename(switch (lazy_path) { | |
| 2728 | .src_path => |sp| sp.sub_path, | |
| 2729 | .cwd_relative => |sub_path| sub_path, | |
| 2730 | .generated => |gen| if (gen.sub_path.len > 0) | |
| 2731 | gen.sub_path | |
| 2732 | else | |
| 2733 | gen.file.getPath2(src_builder, asking_step), | |
| 2734 | .dependency => |dep| dep.sub_path, | |
| 2735 | }); | |
| 2736 | } | |
| 2737 | ||
| 2715 | 2738 | /// Copies the internal strings. |
| 2716 | 2739 | /// |
| 2717 | 2740 | /// The `b` parameter is only used for its allocator. All *Build instances |
lib/std/Build/Step.zig+67-4| ... | ... | @@ -478,6 +478,29 @@ pub fn evalZigProcess( |
| 478 | 478 | return result; |
| 479 | 479 | } |
| 480 | 480 | |
| 481 | /// Wrapper around `std.fs.Dir.updateFile` that handles verbose and error output. | |
| 482 | pub fn installFile(s: *Step, src_lazy_path: Build.LazyPath, dest_path: []const u8) !std.fs.Dir.PrevStatus { | |
| 483 | const b = s.owner; | |
| 484 | const src_path = src_lazy_path.getPath3(b, s); | |
| 485 | try handleVerbose(b, null, &.{ "install", "-C", b.fmt("{}", .{src_path}), dest_path }); | |
| 486 | return src_path.root_dir.handle.updateFile(src_path.sub_path, std.fs.cwd(), dest_path, .{}) catch |err| { | |
| 487 | return s.fail("unable to update file from '{}' to '{s}': {s}", .{ | |
| 488 | src_path, dest_path, @errorName(err), | |
| 489 | }); | |
| 490 | }; | |
| 491 | } | |
| 492 | ||
| 493 | /// Wrapper around `std.fs.Dir.makePathStatus` that handles verbose and error output. | |
| 494 | pub fn installDir(s: *Step, dest_path: []const u8) !std.fs.Dir.MakePathStatus { | |
| 495 | const b = s.owner; | |
| 496 | try handleVerbose(b, null, &.{ "install", "-d", dest_path }); | |
| 497 | return std.fs.cwd().makePathStatus(dest_path) catch |err| { | |
| 498 | return s.fail("unable to create dir '{s}': {s}", .{ | |
| 499 | dest_path, @errorName(err), | |
| 500 | }); | |
| 501 | }; | |
| 502 | } | |
| 503 | ||
| 481 | 504 | fn zigProcessUpdate(s: *Step, zp: *ZigProcess, watch: bool) !?Path { |
| 482 | 505 | const b = s.owner; |
| 483 | 506 | const arena = b.allocator; |
| ... | ... | @@ -714,8 +737,44 @@ pub fn allocPrintCmd2( |
| 714 | 737 | opt_env: ?*const std.process.EnvMap, |
| 715 | 738 | argv: []const []const u8, |
| 716 | 739 | ) Allocator.Error![]u8 { |
| 740 | const shell = struct { | |
| 741 | fn escape(writer: anytype, string: []const u8, is_argv0: bool) !void { | |
| 742 | for (string) |c| { | |
| 743 | if (switch (c) { | |
| 744 | else => true, | |
| 745 | '%', '+'...':', '@'...'Z', '_', 'a'...'z' => false, | |
| 746 | '=' => is_argv0, | |
| 747 | }) break; | |
| 748 | } else return writer.writeAll(string); | |
| 749 | ||
| 750 | try writer.writeByte('"'); | |
| 751 | for (string) |c| { | |
| 752 | if (switch (c) { | |
| 753 | std.ascii.control_code.nul => break, | |
| 754 | '!', '"', '$', '\\', '`' => true, | |
| 755 | else => !std.ascii.isPrint(c), | |
| 756 | }) try writer.writeByte('\\'); | |
| 757 | switch (c) { | |
| 758 | std.ascii.control_code.nul => unreachable, | |
| 759 | std.ascii.control_code.bel => try writer.writeByte('a'), | |
| 760 | std.ascii.control_code.bs => try writer.writeByte('b'), | |
| 761 | std.ascii.control_code.ht => try writer.writeByte('t'), | |
| 762 | std.ascii.control_code.lf => try writer.writeByte('n'), | |
| 763 | std.ascii.control_code.vt => try writer.writeByte('v'), | |
| 764 | std.ascii.control_code.ff => try writer.writeByte('f'), | |
| 765 | std.ascii.control_code.cr => try writer.writeByte('r'), | |
| 766 | std.ascii.control_code.esc => try writer.writeByte('E'), | |
| 767 | ' '...'~' => try writer.writeByte(c), | |
| 768 | else => try writer.print("{o:0>3}", .{c}), | |
| 769 | } | |
| 770 | } | |
| 771 | try writer.writeByte('"'); | |
| 772 | } | |
| 773 | }; | |
| 774 | ||
| 717 | 775 | var buf: std.ArrayListUnmanaged(u8) = .empty; |
| 718 | if (opt_cwd) |cwd| try buf.writer(arena).print("cd {s} && ", .{cwd}); | |
| 776 | const writer = buf.writer(arena); | |
| 777 | if (opt_cwd) |cwd| try writer.print("cd {s} && ", .{cwd}); | |
| 719 | 778 | if (opt_env) |env| { |
| 720 | 779 | const process_env_map = std.process.getEnvMap(arena) catch std.process.EnvMap.init(arena); |
| 721 | 780 | var it = env.iterator(); |
| ... | ... | @@ -725,11 +784,15 @@ pub fn allocPrintCmd2( |
| 725 | 784 | if (process_env_map.get(key)) |process_value| { |
| 726 | 785 | if (std.mem.eql(u8, value, process_value)) continue; |
| 727 | 786 | } |
| 728 | try buf.writer(arena).print("{s}={s} ", .{ key, value }); | |
| 787 | try writer.print("{s}=", .{key}); | |
| 788 | try shell.escape(writer, value, false); | |
| 789 | try writer.writeByte(' '); | |
| 729 | 790 | } |
| 730 | 791 | } |
| 731 | for (argv) |arg| { | |
| 732 | try buf.writer(arena).print("{s} ", .{arg}); | |
| 792 | try shell.escape(writer, argv[0], true); | |
| 793 | for (argv[1..]) |arg| { | |
| 794 | try writer.writeByte(' '); | |
| 795 | try shell.escape(writer, arg, false); | |
| 733 | 796 | } |
| 734 | 797 | return buf.toOwnedSlice(arena); |
| 735 | 798 | } |
lib/std/Build/Step/Compile.zig+1| ... | ... | @@ -668,6 +668,7 @@ pub fn producesPdbFile(compile: *Compile) bool { |
| 668 | 668 | else => return false, |
| 669 | 669 | } |
| 670 | 670 | if (target.ofmt == .c) return false; |
| 671 | if (compile.use_llvm == false) return false; | |
| 671 | 672 | if (compile.root_module.strip == true or |
| 672 | 673 | (compile.root_module.strip == null and compile.root_module.optimize == .ReleaseSmall)) |
| 673 | 674 | { |
lib/std/Build/Step/InstallArtifact.zig+14-41| ... | ... | @@ -119,18 +119,12 @@ fn make(step: *Step, options: Step.MakeOptions) !void { |
| 119 | 119 | _ = options; |
| 120 | 120 | const install_artifact: *InstallArtifact = @fieldParentPtr("step", step); |
| 121 | 121 | const b = step.owner; |
| 122 | const cwd = fs.cwd(); | |
| 123 | 122 | |
| 124 | 123 | var all_cached = true; |
| 125 | 124 | |
| 126 | 125 | if (install_artifact.dest_dir) |dest_dir| { |
| 127 | 126 | const full_dest_path = b.getInstallPath(dest_dir, install_artifact.dest_sub_path); |
| 128 | const src_path = install_artifact.emitted_bin.?.getPath3(b, step); | |
| 129 | const p = fs.Dir.updateFile(src_path.root_dir.handle, src_path.sub_path, cwd, full_dest_path, .{}) catch |err| { | |
| 130 | return step.fail("unable to update file from '{s}' to '{s}': {s}", .{ | |
| 131 | src_path.sub_path, full_dest_path, @errorName(err), | |
| 132 | }); | |
| 133 | }; | |
| 127 | const p = try step.installFile(install_artifact.emitted_bin.?, full_dest_path); | |
| 134 | 128 | all_cached = all_cached and p == .fresh; |
| 135 | 129 | |
| 136 | 130 | if (install_artifact.dylib_symlinks) |dls| { |
| ... | ... | @@ -141,48 +135,28 @@ fn make(step: *Step, options: Step.MakeOptions) !void { |
| 141 | 135 | } |
| 142 | 136 | |
| 143 | 137 | if (install_artifact.implib_dir) |implib_dir| { |
| 144 | const src_path = install_artifact.emitted_implib.?.getPath3(b, step); | |
| 145 | const full_implib_path = b.getInstallPath(implib_dir, fs.path.basename(src_path.sub_path)); | |
| 146 | const p = fs.Dir.updateFile(src_path.root_dir.handle, src_path.sub_path, cwd, full_implib_path, .{}) catch |err| { | |
| 147 | return step.fail("unable to update file from '{s}' to '{s}': {s}", .{ | |
| 148 | src_path.sub_path, full_implib_path, @errorName(err), | |
| 149 | }); | |
| 150 | }; | |
| 138 | const full_implib_path = b.getInstallPath(implib_dir, install_artifact.emitted_implib.?.basename(b, step)); | |
| 139 | const p = try step.installFile(install_artifact.emitted_implib.?, full_implib_path); | |
| 151 | 140 | all_cached = all_cached and p == .fresh; |
| 152 | 141 | } |
| 153 | 142 | |
| 154 | 143 | if (install_artifact.pdb_dir) |pdb_dir| { |
| 155 | const src_path = install_artifact.emitted_pdb.?.getPath3(b, step); | |
| 156 | const full_pdb_path = b.getInstallPath(pdb_dir, fs.path.basename(src_path.sub_path)); | |
| 157 | const p = fs.Dir.updateFile(src_path.root_dir.handle, src_path.sub_path, cwd, full_pdb_path, .{}) catch |err| { | |
| 158 | return step.fail("unable to update file from '{s}' to '{s}': {s}", .{ | |
| 159 | src_path.sub_path, full_pdb_path, @errorName(err), | |
| 160 | }); | |
| 161 | }; | |
| 144 | const full_pdb_path = b.getInstallPath(pdb_dir, install_artifact.emitted_pdb.?.basename(b, step)); | |
| 145 | const p = try step.installFile(install_artifact.emitted_pdb.?, full_pdb_path); | |
| 162 | 146 | all_cached = all_cached and p == .fresh; |
| 163 | 147 | } |
| 164 | 148 | |
| 165 | 149 | if (install_artifact.h_dir) |h_dir| { |
| 166 | 150 | if (install_artifact.emitted_h) |emitted_h| { |
| 167 | const src_path = emitted_h.getPath3(b, step); | |
| 168 | const full_h_path = b.getInstallPath(h_dir, fs.path.basename(src_path.sub_path)); | |
| 169 | const p = fs.Dir.updateFile(src_path.root_dir.handle, src_path.sub_path, cwd, full_h_path, .{}) catch |err| { | |
| 170 | return step.fail("unable to update file from '{s}' to '{s}': {s}", .{ | |
| 171 | src_path.sub_path, full_h_path, @errorName(err), | |
| 172 | }); | |
| 173 | }; | |
| 151 | const full_h_path = b.getInstallPath(h_dir, emitted_h.basename(b, step)); | |
| 152 | const p = try step.installFile(emitted_h, full_h_path); | |
| 174 | 153 | all_cached = all_cached and p == .fresh; |
| 175 | 154 | } |
| 176 | 155 | |
| 177 | 156 | for (install_artifact.artifact.installed_headers.items) |installation| switch (installation) { |
| 178 | 157 | .file => |file| { |
| 179 | const src_path = file.source.getPath3(b, step); | |
| 180 | 158 | const full_h_path = b.getInstallPath(h_dir, file.dest_rel_path); |
| 181 | const p = fs.Dir.updateFile(src_path.root_dir.handle, src_path.sub_path, cwd, full_h_path, .{}) catch |err| { | |
| 182 | return step.fail("unable to update file from '{s}' to '{s}': {s}", .{ | |
| 183 | src_path.sub_path, full_h_path, @errorName(err), | |
| 184 | }); | |
| 185 | }; | |
| 159 | const p = try step.installFile(file.source, full_h_path); | |
| 186 | 160 | all_cached = all_cached and p == .fresh; |
| 187 | 161 | }, |
| 188 | 162 | .directory => |dir| { |
| ... | ... | @@ -209,16 +183,15 @@ fn make(step: *Step, options: Step.MakeOptions) !void { |
| 209 | 183 | } |
| 210 | 184 | } |
| 211 | 185 | |
| 212 | const src_entry_path = src_dir_path.join(b.allocator, entry.path) catch @panic("OOM"); | |
| 213 | 186 | const full_dest_path = b.pathJoin(&.{ full_h_prefix, entry.path }); |
| 214 | 187 | switch (entry.kind) { |
| 215 | .directory => try cwd.makePath(full_dest_path), | |
| 188 | .directory => { | |
| 189 | try Step.handleVerbose(b, null, &.{ "install", "-d", full_dest_path }); | |
| 190 | const p = try step.installDir(full_dest_path); | |
| 191 | all_cached = all_cached and p == .existed; | |
| 192 | }, | |
| 216 | 193 | .file => { |
| 217 | const p = fs.Dir.updateFile(src_entry_path.root_dir.handle, src_entry_path.sub_path, cwd, full_dest_path, .{}) catch |err| { | |
| 218 | return step.fail("unable to update file from '{s}' to '{s}': {s}", .{ | |
| 219 | src_entry_path.sub_path, full_dest_path, @errorName(err), | |
| 220 | }); | |
| 221 | }; | |
| 194 | const p = try step.installFile(try dir.source.join(b.allocator, entry.path), full_dest_path); | |
| 222 | 195 | all_cached = all_cached and p == .fresh; |
| 223 | 196 | }, |
| 224 | 197 | else => continue, |
lib/std/Build/Step/InstallDir.zig+10-28| ... | ... | @@ -74,31 +74,23 @@ fn make(step: *Step, options: Step.MakeOptions) !void { |
| 74 | 74 | var all_cached = true; |
| 75 | 75 | next_entry: while (try it.next()) |entry| { |
| 76 | 76 | for (install_dir.options.exclude_extensions) |ext| { |
| 77 | if (mem.endsWith(u8, entry.path, ext)) { | |
| 78 | continue :next_entry; | |
| 79 | } | |
| 77 | if (mem.endsWith(u8, entry.path, ext)) continue :next_entry; | |
| 80 | 78 | } |
| 81 | 79 | if (install_dir.options.include_extensions) |incs| { |
| 82 | var found = false; | |
| 83 | 80 | for (incs) |inc| { |
| 84 | if (mem.endsWith(u8, entry.path, inc)) { | |
| 85 | found = true; | |
| 86 | break; | |
| 87 | } | |
| 81 | if (mem.endsWith(u8, entry.path, inc)) break; | |
| 82 | } else { | |
| 83 | continue :next_entry; | |
| 88 | 84 | } |
| 89 | if (!found) continue :next_entry; | |
| 90 | 85 | } |
| 91 | 86 | |
| 92 | // relative to src build root | |
| 93 | const src_sub_path = try src_dir_path.join(arena, entry.path); | |
| 87 | const src_path = try install_dir.options.source_dir.join(b.allocator, entry.path); | |
| 94 | 88 | const dest_path = b.pathJoin(&.{ dest_prefix, entry.path }); |
| 95 | const cwd = fs.cwd(); | |
| 96 | ||
| 97 | 89 | switch (entry.kind) { |
| 98 | 90 | .directory => { |
| 99 | if (need_derived_inputs) try step.addDirectoryWatchInputFromPath(src_sub_path); | |
| 100 | try cwd.makePath(dest_path); | |
| 101 | // TODO: set result_cached=false if the directory did not already exist. | |
| 91 | if (need_derived_inputs) _ = try step.addDirectoryWatchInput(src_path); | |
| 92 | const p = try step.installDir(dest_path); | |
| 93 | all_cached = all_cached and p == .existed; | |
| 102 | 94 | }, |
| 103 | 95 | .file => { |
| 104 | 96 | for (install_dir.options.blank_extensions) |ext| { |
| ... | ... | @@ -108,18 +100,8 @@ fn make(step: *Step, options: Step.MakeOptions) !void { |
| 108 | 100 | } |
| 109 | 101 | } |
| 110 | 102 | |
| 111 | const prev_status = fs.Dir.updateFile( | |
| 112 | src_sub_path.root_dir.handle, | |
| 113 | src_sub_path.sub_path, | |
| 114 | cwd, | |
| 115 | dest_path, | |
| 116 | .{}, | |
| 117 | ) catch |err| { | |
| 118 | return step.fail("unable to update file from '{}' to '{s}': {s}", .{ | |
| 119 | src_sub_path, dest_path, @errorName(err), | |
| 120 | }); | |
| 121 | }; | |
| 122 | all_cached = all_cached and prev_status == .fresh; | |
| 103 | const p = try step.installFile(src_path, dest_path); | |
| 104 | all_cached = all_cached and p == .fresh; | |
| 123 | 105 | }, |
| 124 | 106 | else => continue, |
| 125 | 107 | } |
lib/std/Build/Step/InstallFile.zig+2-8| ... | ... | @@ -41,13 +41,7 @@ fn make(step: *Step, options: Step.MakeOptions) !void { |
| 41 | 41 | const install_file: *InstallFile = @fieldParentPtr("step", step); |
| 42 | 42 | try step.singleUnchangingWatchInput(install_file.source); |
| 43 | 43 | |
| 44 | const full_src_path = install_file.source.getPath2(b, step); | |
| 45 | 44 | const full_dest_path = b.getInstallPath(install_file.dir, install_file.dest_rel_path); |
| 46 | const cwd = std.fs.cwd(); | |
| 47 | const prev = std.fs.Dir.updateFile(cwd, full_src_path, cwd, full_dest_path, .{}) catch |err| { | |
| 48 | return step.fail("unable to update file from '{s}' to '{s}': {s}", .{ | |
| 49 | full_src_path, full_dest_path, @errorName(err), | |
| 50 | }); | |
| 51 | }; | |
| 52 | step.result_cached = prev == .fresh; | |
| 45 | const p = try step.installFile(install_file.source, full_dest_path); | |
| 46 | step.result_cached = p == .fresh; | |
| 53 | 47 | } |
lib/std/Build/Step/ObjCopy.zig+1-1| ... | ... | @@ -209,7 +209,7 @@ fn make(step: *Step, options: Step.MakeOptions) !void { |
| 209 | 209 | } |
| 210 | 210 | if (objcopy.add_section) |section| { |
| 211 | 211 | try argv.append("--add-section"); |
| 212 | try argv.appendSlice(&.{b.fmt("{s}={s}", .{ section.section_name, section.file_path.getPath(b) })}); | |
| 212 | try argv.appendSlice(&.{b.fmt("{s}={s}", .{ section.section_name, section.file_path.getPath2(b, step) })}); | |
| 213 | 213 | } |
| 214 | 214 | if (objcopy.set_section_alignment) |set_align| { |
| 215 | 215 | try argv.append("--set-section-alignment"); |
lib/std/Build/Step/Run.zig+20-3| ... | ... | @@ -456,11 +456,28 @@ pub fn addPathDir(run: *Run, search_path: []const u8) void { |
| 456 | 456 | const b = run.step.owner; |
| 457 | 457 | const env_map = getEnvMapInternal(run); |
| 458 | 458 | |
| 459 | const key = "PATH"; | |
| 459 | const use_wine = b.enable_wine and b.graph.host.result.os.tag != .windows and use_wine: switch (run.argv.items[0]) { | |
| 460 | .artifact => |p| p.artifact.rootModuleTarget().os.tag == .windows, | |
| 461 | .lazy_path => |p| { | |
| 462 | switch (p.lazy_path) { | |
| 463 | .generated => |g| if (g.file.step.cast(Step.Compile)) |cs| break :use_wine cs.rootModuleTarget().os.tag == .windows, | |
| 464 | else => {}, | |
| 465 | } | |
| 466 | break :use_wine std.mem.endsWith(u8, p.lazy_path.basename(b, &run.step), ".exe"); | |
| 467 | }, | |
| 468 | .decorated_directory => false, | |
| 469 | .bytes => |bytes| std.mem.endsWith(u8, bytes, ".exe"), | |
| 470 | .output_file, .output_directory => false, | |
| 471 | }; | |
| 472 | const key = if (use_wine) "WINEPATH" else "PATH"; | |
| 460 | 473 | const prev_path = env_map.get(key); |
| 461 | 474 | |
| 462 | 475 | if (prev_path) |pp| { |
| 463 | const new_path = b.fmt("{s}" ++ [1]u8{fs.path.delimiter} ++ "{s}", .{ pp, search_path }); | |
| 476 | const new_path = b.fmt("{s}{c}{s}", .{ | |
| 477 | pp, | |
| 478 | if (use_wine) fs.path.delimiter_windows else fs.path.delimiter, | |
| 479 | search_path, | |
| 480 | }); | |
| 464 | 481 | env_map.put(key, new_path) catch @panic("OOM"); |
| 465 | 482 | } else { |
| 466 | 483 | env_map.put(key, b.dupePath(search_path)) catch @panic("OOM"); |
| ... | ... | @@ -866,7 +883,7 @@ fn make(step: *Step, options: Step.MakeOptions) !void { |
| 866 | 883 | try runCommand(run, argv_list.items, has_side_effects, tmp_dir_path, prog_node, null); |
| 867 | 884 | |
| 868 | 885 | const dep_file_dir = std.fs.cwd(); |
| 869 | const dep_file_basename = dep_output_file.generated_file.getPath(); | |
| 886 | const dep_file_basename = dep_output_file.generated_file.getPath2(b, step); | |
| 870 | 887 | if (has_side_effects) |
| 871 | 888 | try man.addDepFile(dep_file_dir, dep_file_basename) |
| 872 | 889 | else |
lib/std/fs/Dir.zig+14-4| ... | ... | @@ -1146,6 +1146,7 @@ pub fn makeDirW(self: Dir, sub_path: [*:0]const u16) MakeError!void { |
| 1146 | 1146 | /// On Windows, `sub_path` should be encoded as [WTF-8](https://simonsapin.github.io/wtf-8/). |
| 1147 | 1147 | /// On WASI, `sub_path` should be encoded as valid UTF-8. |
| 1148 | 1148 | /// On other platforms, `sub_path` is an opaque sequence of bytes with no particular encoding. |
| 1149 | /// Fails on an empty path with `error.BadPathName` as that is not a path that can be created. | |
| 1149 | 1150 | /// |
| 1150 | 1151 | /// Paths containing `..` components are handled differently depending on the platform: |
| 1151 | 1152 | /// - On Windows, `..` are resolved before the path is passed to NtCreateFile, meaning |
| ... | ... | @@ -1155,10 +1156,19 @@ pub fn makeDirW(self: Dir, sub_path: [*:0]const u16) MakeError!void { |
| 1155 | 1156 | /// meaning a `sub_path` like "first/../second" will create both a `./first` |
| 1156 | 1157 | /// and a `./second` directory. |
| 1157 | 1158 | pub fn makePath(self: Dir, sub_path: []const u8) (MakeError || StatFileError)!void { |
| 1159 | _ = try self.makePathStatus(sub_path); | |
| 1160 | } | |
| 1161 | ||
| 1162 | pub const MakePathStatus = enum { existed, created }; | |
| 1163 | /// Same as `makePath` except returns whether the path already existed or was successfully created. | |
| 1164 | pub fn makePathStatus(self: Dir, sub_path: []const u8) (MakeError || StatFileError)!MakePathStatus { | |
| 1158 | 1165 | var it = try fs.path.componentIterator(sub_path); |
| 1159 | var component = it.last() orelse return; | |
| 1166 | var status: MakePathStatus = .existed; | |
| 1167 | var component = it.last() orelse return error.BadPathName; | |
| 1160 | 1168 | while (true) { |
| 1161 | self.makeDir(component.path) catch |err| switch (err) { | |
| 1169 | if (self.makeDir(component.path)) |_| { | |
| 1170 | status = .created; | |
| 1171 | } else |err| switch (err) { | |
| 1162 | 1172 | error.PathAlreadyExists => { |
| 1163 | 1173 | // stat the file and return an error if it's not a directory |
| 1164 | 1174 | // this is important because otherwise a dangling symlink |
| ... | ... | @@ -1177,8 +1187,8 @@ pub fn makePath(self: Dir, sub_path: []const u8) (MakeError || StatFileError)!vo |
| 1177 | 1187 | continue; |
| 1178 | 1188 | }, |
| 1179 | 1189 | else => |e| return e, |
| 1180 | }; | |
| 1181 | component = it.next() orelse return; | |
| 1190 | } | |
| 1191 | component = it.next() orelse return status; | |
| 1182 | 1192 | } |
| 1183 | 1193 | } |
| 1184 | 1194 |
lib/std/fs/path.zig+4-4| ... | ... | @@ -27,8 +27,8 @@ const fs = std.fs; |
| 27 | 27 | const process = std.process; |
| 28 | 28 | const native_os = builtin.target.os.tag; |
| 29 | 29 | |
| 30 | pub const sep_windows = '\\'; | |
| 31 | pub const sep_posix = '/'; | |
| 30 | pub const sep_windows: u8 = '\\'; | |
| 31 | pub const sep_posix: u8 = '/'; | |
| 32 | 32 | pub const sep = switch (native_os) { |
| 33 | 33 | .windows, .uefi => sep_windows, |
| 34 | 34 | else => sep_posix, |
| ... | ... | @@ -41,8 +41,8 @@ pub const sep_str = switch (native_os) { |
| 41 | 41 | else => sep_str_posix, |
| 42 | 42 | }; |
| 43 | 43 | |
| 44 | pub const delimiter_windows = ';'; | |
| 45 | pub const delimiter_posix = ':'; | |
| 44 | pub const delimiter_windows: u8 = ';'; | |
| 45 | pub const delimiter_posix: u8 = ':'; | |
| 46 | 46 | pub const delimiter = if (native_os == .windows) delimiter_windows else delimiter_posix; |
| 47 | 47 | |
| 48 | 48 | /// Returns if the given byte is a valid path separator |