| ... | @@ -622,6 +622,18 @@ fn checksContainStderr(checks: []const StdIo.Check) bool { | ... | @@ -622,6 +622,18 @@ fn checksContainStderr(checks: []const StdIo.Check) bool { |
| 622 | return false; | 622 | return false; |
| 623 | } | 623 | } |
| 624 | | 624 | |
| | 625 | /// If `path` is cwd-relative, make it relative to the cwd of the child instead. |
| | 626 | /// |
| | 627 | /// Whenever a path is included in the argv of a child, it should be put through this function first |
| | 628 | /// to make sure the child doesn't see paths relative to a cwd other than its own. |
| | 629 | fn convertPathArg(run: *Run, path: Build.Cache.Path) []const u8 { |
| | 630 | const b = run.step.owner; |
| | 631 | const path_str = path.toString(b.graph.arena) catch @panic("OOM"); |
| | 632 | const child_lazy_cwd = run.cwd orelse return path_str; |
| | 633 | const child_cwd = child_lazy_cwd.getPath3(b, &run.step).toString(b.graph.arena) catch @panic("OOM"); |
| | 634 | return std.fs.path.relative(b.graph.arena, child_cwd, path_str) catch @panic("OOM"); |
| | 635 | } |
| | 636 | |
| 625 | const IndexedOutput = struct { | 637 | const IndexedOutput = struct { |
| 626 | index: usize, | 638 | index: usize, |
| 627 | tag: @typeInfo(Arg).@"union".tag_type.?, | 639 | tag: @typeInfo(Arg).@"union".tag_type.?, |
| ... | @@ -676,14 +688,14 @@ fn make(step: *Step, options: Step.MakeOptions) !void { | ... | @@ -676,14 +688,14 @@ fn make(step: *Step, options: Step.MakeOptions) !void { |
| 676 | man.hash.addBytes(bytes); | 688 | man.hash.addBytes(bytes); |
| 677 | }, | 689 | }, |
| 678 | .lazy_path => |file| { | 690 | .lazy_path => |file| { |
| 679 | const file_path = file.lazy_path.getPath2(b, step); | 691 | const file_path = file.lazy_path.getPath3(b, step); |
| 680 | try argv_list.append(b.fmt("{s}{s}", .{ file.prefix, file_path })); | 692 | try argv_list.append(b.fmt("{s}{s}", .{ file.prefix, run.convertPathArg(file_path) })); |
| 681 | man.hash.addBytes(file.prefix); | 693 | man.hash.addBytes(file.prefix); |
| 682 | _ = try man.addFile(file_path, null); | 694 | _ = try man.addFilePath(file_path, null); |
| 683 | }, | 695 | }, |
| 684 | .decorated_directory => |dd| { | 696 | .decorated_directory => |dd| { |
| 685 | const file_path = dd.lazy_path.getPath3(b, step); | 697 | const file_path = dd.lazy_path.getPath3(b, step); |
| 686 | const resolved_arg = b.fmt("{s}{}{s}", .{ dd.prefix, file_path, dd.suffix }); | 698 | const resolved_arg = b.fmt("{s}{s}{s}", .{ dd.prefix, run.convertPathArg(file_path), dd.suffix }); |
| 687 | try argv_list.append(resolved_arg); | 699 | try argv_list.append(resolved_arg); |
| 688 | man.hash.addBytes(resolved_arg); | 700 | man.hash.addBytes(resolved_arg); |
| 689 | }, | 701 | }, |
| ... | @@ -696,7 +708,10 @@ fn make(step: *Step, options: Step.MakeOptions) !void { | ... | @@ -696,7 +708,10 @@ fn make(step: *Step, options: Step.MakeOptions) !void { |
| 696 | } | 708 | } |
| 697 | const file_path = artifact.installed_path orelse artifact.generated_bin.?.path.?; | 709 | const file_path = artifact.installed_path orelse artifact.generated_bin.?.path.?; |
| 698 | | 710 | |
| 699 | try argv_list.append(b.fmt("{s}{s}", .{ pa.prefix, file_path })); | 711 | try argv_list.append(b.fmt("{s}{s}", .{ |
| | 712 | pa.prefix, |
| | 713 | run.convertPathArg(.{ .root_dir = .cwd(), .sub_path = file_path }), |
| | 714 | })); |
| 700 | | 715 | |
| 701 | _ = try man.addFile(file_path, null); | 716 | _ = try man.addFile(file_path, null); |
| 702 | }, | 717 | }, |
| ... | @@ -787,11 +802,14 @@ fn make(step: *Step, options: Step.MakeOptions) !void { | ... | @@ -787,11 +802,14 @@ fn make(step: *Step, options: Step.MakeOptions) !void { |
| 787 | b.cache_root, output_sub_dir_path, @errorName(err), | 802 | b.cache_root, output_sub_dir_path, @errorName(err), |
| 788 | }); | 803 | }); |
| 789 | }; | 804 | }; |
| 790 | const output_path = placeholder.output.generated_file.path.?; | 805 | const arg_output_path = run.convertPathArg(.{ |
| | 806 | .root_dir = .cwd(), |
| | 807 | .sub_path = placeholder.output.generated_file.getPath(), |
| | 808 | }); |
| 791 | argv_list.items[placeholder.index] = if (placeholder.output.prefix.len == 0) | 809 | argv_list.items[placeholder.index] = if (placeholder.output.prefix.len == 0) |
| 792 | output_path | 810 | arg_output_path |
| 793 | else | 811 | else |
| 794 | b.fmt("{s}{s}", .{ placeholder.output.prefix, output_path }); | 812 | b.fmt("{s}{s}", .{ placeholder.output.prefix, arg_output_path }); |
| 795 | } | 813 | } |
| 796 | | 814 | |
| 797 | try runCommand(run, argv_list.items, has_side_effects, output_dir_path, prog_node, null); | 815 | try runCommand(run, argv_list.items, has_side_effects, output_dir_path, prog_node, null); |
| ... | @@ -816,12 +834,15 @@ fn make(step: *Step, options: Step.MakeOptions) !void { | ... | @@ -816,12 +834,15 @@ fn make(step: *Step, options: Step.MakeOptions) !void { |
| 816 | b.cache_root, output_sub_dir_path, @errorName(err), | 834 | b.cache_root, output_sub_dir_path, @errorName(err), |
| 817 | }); | 835 | }); |
| 818 | }; | 836 | }; |
| 819 | const output_path = try b.cache_root.join(arena, &output_components); | 837 | const raw_output_path: Build.Cache.Path = .{ |
| 820 | placeholder.output.generated_file.path = output_path; | 838 | .root_dir = b.cache_root, |
| 821 | argv_list.items[placeholder.index] = if (placeholder.output.prefix.len == 0) | 839 | .sub_path = b.pathJoin(&output_components), |
| 822 | output_path | 840 | }; |
| 823 | else | 841 | placeholder.output.generated_file.path = raw_output_path.toString(b.graph.arena) catch @panic("OOM"); |
| 824 | b.fmt("{s}{s}", .{ placeholder.output.prefix, output_path }); | 842 | argv_list.items[placeholder.index] = b.fmt("{s}{s}", .{ |
| | 843 | placeholder.output.prefix, |
| | 844 | run.convertPathArg(raw_output_path), |
| | 845 | }); |
| 825 | } | 846 | } |
| 826 | | 847 | |
| 827 | try runCommand(run, argv_list.items, has_side_effects, tmp_dir_path, prog_node, null); | 848 | try runCommand(run, argv_list.items, has_side_effects, tmp_dir_path, prog_node, null); |
| ... | @@ -899,20 +920,23 @@ pub fn rerunInFuzzMode( | ... | @@ -899,20 +920,23 @@ pub fn rerunInFuzzMode( |
| 899 | try argv_list.append(arena, bytes); | 920 | try argv_list.append(arena, bytes); |
| 900 | }, | 921 | }, |
| 901 | .lazy_path => |file| { | 922 | .lazy_path => |file| { |
| 902 | const file_path = file.lazy_path.getPath2(b, step); | 923 | const file_path = file.lazy_path.getPath3(b, step); |
| 903 | try argv_list.append(arena, b.fmt("{s}{s}", .{ file.prefix, file_path })); | 924 | try argv_list.append(arena, b.fmt("{s}{s}", .{ file.prefix, run.convertPathArg(file_path) })); |
| 904 | }, | 925 | }, |
| 905 | .decorated_directory => |dd| { | 926 | .decorated_directory => |dd| { |
| 906 | const file_path = dd.lazy_path.getPath3(b, step); | 927 | const file_path = dd.lazy_path.getPath3(b, step); |
| 907 | try argv_list.append(arena, b.fmt("{s}{}{s}", .{ dd.prefix, file_path, dd.suffix })); | 928 | try argv_list.append(arena, b.fmt("{s}{s}{s}", .{ dd.prefix, run.convertPathArg(file_path), dd.suffix })); |
| 908 | }, | 929 | }, |
| 909 | .artifact => |pa| { | 930 | .artifact => |pa| { |
| 910 | const artifact = pa.artifact; | 931 | const artifact = pa.artifact; |
| 911 | const file_path = if (artifact == run.producer.?) | 932 | const file_path: []const u8 = p: { |
| 912 | b.fmt("{}", .{run.rebuilt_executable.?}) | 933 | if (artifact == run.producer.?) break :p b.fmt("{}", .{run.rebuilt_executable.?}); |
| 913 | else | 934 | break :p artifact.installed_path orelse artifact.generated_bin.?.path.?; |
| 914 | (artifact.installed_path orelse artifact.generated_bin.?.path.?); | 935 | }; |
| 915 | try argv_list.append(arena, b.fmt("{s}{s}", .{ pa.prefix, file_path })); | 936 | try argv_list.append(arena, b.fmt("{s}{s}", .{ |
| | 937 | pa.prefix, |
| | 938 | run.convertPathArg(.{ .root_dir = .cwd(), .sub_path = file_path }), |
| | 939 | })); |
| 916 | }, | 940 | }, |
| 917 | .output_file, .output_directory => unreachable, | 941 | .output_file, .output_directory => unreachable, |
| 918 | } | 942 | } |