| ... | ... | @@ -582,11 +582,26 @@ pub fn allocPrintCmd2( |
| 582 | 582 | return buf.toOwnedSlice(arena); |
| 583 | 583 | } |
| 584 | 584 | |
| 585 | /// Prefer `cacheHitAndWatch` unless you already added watch inputs |
| 586 | /// separately from using the cache system. |
| 585 | 587 | pub fn cacheHit(s: *Step, man: *Build.Cache.Manifest) !bool { |
| 586 | 588 | s.result_cached = man.hit() catch |err| return failWithCacheError(s, man, err); |
| 587 | 589 | return s.result_cached; |
| 588 | 590 | } |
| 589 | 591 | |
| 592 | /// Clears previous watch inputs, if any, and then populates watch inputs from |
| 593 | /// the full set of files picked up by the cache manifest. |
| 594 | /// |
| 595 | /// Must be accompanied with `writeManifestAndWatch`. |
| 596 | pub fn cacheHitAndWatch(s: *Step, man: *Build.Cache.Manifest) !bool { |
| 597 | const is_hit = man.hit() catch |err| return failWithCacheError(s, man, err); |
| 598 | s.result_cached = is_hit; |
| 599 | // The above call to hit() populates the manifest with files, so in case of |
| 600 | // a hit, we need to populate watch inputs. |
| 601 | if (is_hit) try setWatchInputsFromManifest(s, man); |
| 602 | return is_hit; |
| 603 | } |
| 604 | |
| 590 | 605 | fn failWithCacheError(s: *Step, man: *const Build.Cache.Manifest, err: anyerror) anyerror { |
| 591 | 606 | const i = man.failed_file_index orelse return err; |
| 592 | 607 | const pp = man.files.keys()[i].prefixed_path; |
| ... | ... | @@ -594,6 +609,8 @@ fn failWithCacheError(s: *Step, man: *const Build.Cache.Manifest, err: anyerror) |
| 594 | 609 | return s.fail("{s}: {s}/{s}", .{ @errorName(err), prefix, pp.sub_path }); |
| 595 | 610 | } |
| 596 | 611 | |
| 612 | /// Prefer `writeManifestAndWatch` unless you already added watch inputs |
| 613 | /// separately from using the cache system. |
| 597 | 614 | pub fn writeManifest(s: *Step, man: *Build.Cache.Manifest) !void { |
| 598 | 615 | if (s.test_results.isSuccess()) { |
| 599 | 616 | man.writeManifest() catch |err| { |
| ... | ... | @@ -602,6 +619,29 @@ pub fn writeManifest(s: *Step, man: *Build.Cache.Manifest) !void { |
| 602 | 619 | } |
| 603 | 620 | } |
| 604 | 621 | |
| 622 | /// Clears previous watch inputs, if any, and then populates watch inputs from |
| 623 | /// the full set of files picked up by the cache manifest. |
| 624 | /// |
| 625 | /// Must be accompanied with `cacheHitAndWatch`. |
| 626 | pub fn writeManifestAndWatch(s: *Step, man: *Build.Cache.Manifest) !void { |
| 627 | try writeManifest(s, man); |
| 628 | try setWatchInputsFromManifest(s, man); |
| 629 | } |
| 630 | |
| 631 | fn setWatchInputsFromManifest(s: *Step, man: *Build.Cache.Manifest) !void { |
| 632 | const arena = s.owner.allocator; |
| 633 | const prefixes = man.cache.prefixes(); |
| 634 | clearWatchInputs(s); |
| 635 | for (man.files.keys()) |file| { |
| 636 | // The file path data is freed when the cache manifest is cleaned up at the end of `make`. |
| 637 | const sub_path = try arena.dupe(u8, file.prefixed_path.sub_path); |
| 638 | try addWatchInputFromPath(s, .{ |
| 639 | .root_dir = prefixes[file.prefixed_path.prefix], |
| 640 | .sub_path = std.fs.path.dirname(sub_path) orelse "", |
| 641 | }, std.fs.path.basename(sub_path)); |
| 642 | } |
| 643 | } |
| 644 | |
| 605 | 645 | /// For steps that have a single input that never changes when re-running `make`. |
| 606 | 646 | pub fn singleUnchangingWatchInput(step: *Step, lazy_path: Build.LazyPath) Allocator.Error!void { |
| 607 | 647 | if (!step.inputs.populated()) try step.addWatchInput(lazy_path); |