authorgravatar for hemisputnik@proton.mehemisputnik <hemisputnik@proton.me> 2026-08-05 06:50:26+03:00
committergravatar for hemisputnik@proton.mehemisputnik <hemisputnik@proton.me> 2026-08-08 09:02:31+03:00
log0f332fd536aee4fcff4d0875d1d7136ba5b6f01b
treeca6c0c7fb119087c1604477a3a35e033636f7b01
parent800fc5d25a5ed386910dc36c81ae200a19a1d01b
signaturebadge-check Signed by SSH key SHA256:iUK/EffQPyeXTXChJNV0UrxsscinNLxnk+0pu4OGU7Q

std.Build.Configuration: serialize packages and their dependencies

The serializer now traverses the builder's available_deps and their dependencies recursively, and serializes them into Configuration.packages.

5 files changed, 136 insertions(+), 33 deletions(-)

lib/compiler/Maker.zig+5-3
...@@ -3312,17 +3312,19 @@ pub fn packagePath(...@@ -3312,17 +3312,19 @@ pub fn packagePath(
3312) Allocator.Error!Path {3312) Allocator.Error!Path {
3313 const c = &maker.scanned_config.configuration;3313 const c = &maker.scanned_config.configuration;
3314 const graph = maker.graph;3314 const graph = maker.graph;
3315 const package = package_index.get(c) orelse return .{3315
3316 if (package_index == .root) return .{
3316 .root_dir = graph.build_root_directory,3317 .root_dir = graph.build_root_directory,
3317 .sub_path = sub_path,3318 .sub_path = sub_path,
3318 };3319 };
3320
3319 // Currently, neither configurer nor Maker is aware of the standard zig3321 // Currently, neither configurer nor Maker is aware of the standard zig
3320 // package path, and the root path is stored as a bare string rather than3322 // package path, and the root path is stored as a bare string rather than
3321 // relative to a known base directory. Without changing that, we must3323 // relative to a known base directory. Without changing that, we must
3322 // construct a cwd relative path here.3324 // construct a cwd relative path here.
3323 return .{3325 return .{
3324 .root_dir = .cwd(),3326 .root_dir = .cwd(),
3325 .sub_path = try Dir.path.join(arena, &.{ package.root_path.slice(c), sub_path }),3327 .sub_path = try Dir.path.join(arena, &.{ package_index.ptr(c).root_path.slice(c), sub_path }),
3326 };3328 };
3327}3329}
33283330
...@@ -3952,7 +3954,7 @@ fn confPathDepToCachePath(...@@ -3952,7 +3954,7 @@ fn confPathDepToCachePath(
3952 .root_dir = graph.build_root_directory,3954 .root_dir = graph.build_root_directory,
3953 .sub_path = switch (path_dep.pkg.unwrap().?) {3955 .sub_path = switch (path_dep.pkg.unwrap().?) {
3954 .root => sub_path,3956 .root => sub_path,
3955 else => |index| try Dir.path.join(arena, &.{ index.get(c).?.root_path.slice(c), sub_path }),3957 else => |index| try Dir.path.join(arena, &.{ index.ptr(c).root_path.slice(c), sub_path }),
3956 },3958 },
3957 },3959 },
3958 .zig_lib => .{3960 .zig_lib => .{
lib/compiler/Maker/ScannedConfig.zig+21
...@@ -83,6 +83,27 @@ pub fn print(sc: *const ScannedConfig, w: *Writer) Writer.Error!void {...@@ -83,6 +83,27 @@ pub fn print(sc: *const ScannedConfig, w: *Writer) Writer.Error!void {
83 try tf.end();83 try tf.end();
84 }84 }
8585
86 {
87 var tf = try s.beginTupleField("packages", .{});
88 for (c.packages) |package| {
89 var sf = try tf.beginStructField(.{});
90 try sf.field("dep_prefix", package.dep_prefix.slice(c), .{});
91 try sf.field("hash", package.hash.slice(c), .{});
92 try sf.field("root_path", package.root_path.slice(c), .{});
93
94 var dtf = try sf.beginTupleField("deps", .{});
95 for (package.deps.slice(c)) |dep| {
96 var dsf = try dtf.beginStructField(.{});
97 try sc.printStruct(&dsf, Configuration.Package.Dep, dep);
98 try dsf.end();
99 }
100 try dtf.end();
101
102 try sf.end();
103 }
104 try tf.end();
105 }
106
86 try s.end();107 try s.end();
87}108}
88109
lib/std/Build.zig+3-2
...@@ -2160,7 +2160,7 @@ pub fn dependencyLazy(b: *Build, name: []const u8, args: anytype) error{LazyDepe...@@ -2160,7 +2160,7 @@ pub fn dependencyLazy(b: *Build, name: []const u8, args: anytype) error{LazyDepe
2160 return dependencyResolved(b, name, entry, userInputOptionsFromArgs(b.graph.arena, args));2160 return dependencyResolved(b, name, entry, userInputOptionsFromArgs(b.graph.arena, args));
2161}2161}
21622162
2163const PackageEntry = struct {2163pub const PackageEntry = struct {
2164 hash: []const u8,2164 hash: []const u8,
2165 available: bool,2165 available: bool,
2166 build_root: []const u8,2166 build_root: []const u8,
...@@ -2168,7 +2168,8 @@ const PackageEntry = struct {...@@ -2168,7 +2168,8 @@ const PackageEntry = struct {
2168 run_build: ?*const fn (*Build) void,2168 run_build: ?*const fn (*Build) void,
2169};2169};
21702170
2171const package_map: std.StaticStringMap(PackageEntry) = blk: {2171/// Build system implementation detail.
2172pub const package_map: std.StaticStringMap(PackageEntry) = blk: {
2172 const deps = @import("root").dependencies;2173 const deps = @import("root").dependencies;
2173 const decl_names = @typeInfo(deps.packages).@"struct".decl_names;2174 const decl_names = @typeInfo(deps.packages).@"struct".decl_names;
2174 var kvs: [decl_names.len]struct { []const u8, PackageEntry } = undefined;2175 var kvs: [decl_names.len]struct { []const u8, PackageEntry } = undefined;
lib/std/Build/Configuration.zig+39-10
...@@ -15,6 +15,8 @@ unlazy_deps: []String,...@@ -15,6 +15,8 @@ unlazy_deps: []String,
15system_integrations: []SystemIntegration,15system_integrations: []SystemIntegration,
16available_options: []AvailableOption,16available_options: []AvailableOption,
17search_prefixes: []String,17search_prefixes: []String,
18/// Index 0 always exists and is the root package.
19packages: []Package,
18extra: []u32,20extra: []u32,
19default_step: Step.Index,21default_step: Step.Index,
20generated_files_len: u32,22generated_files_len: u32,
...@@ -30,6 +32,7 @@ pub const Header = extern struct {...@@ -30,6 +32,7 @@ pub const Header = extern struct {
30 system_integrations_len: u32,32 system_integrations_len: u32,
31 available_options_len: u32,33 available_options_len: u32,
32 search_prefixes_len: u32,34 search_prefixes_len: u32,
35 packages_len: u32,
33 extra_len: u32,36 extra_len: u32,
3437
35 default_step: Step.Index,38 default_step: Step.Index,
...@@ -58,6 +61,7 @@ pub const Wip = struct {...@@ -58,6 +61,7 @@ pub const Wip = struct {
58 steps: std.ArrayList(Step) = .empty,61 steps: std.ArrayList(Step) = .empty,
59 path_deps: std.ArrayList(PathDep) = .empty,62 path_deps: std.ArrayList(PathDep) = .empty,
60 search_prefixes: std.ArrayList(String) = .empty,63 search_prefixes: std.ArrayList(String) = .empty,
64 packages: std.ArrayList(Package) = .empty,
61 extra: std.ArrayList(u32) = .empty,65 extra: std.ArrayList(u32) = .empty,
62 next_generated_file_index: u32 = 0,66 next_generated_file_index: u32 = 0,
63 cache_poison: bool = false,67 cache_poison: bool = false,
...@@ -139,6 +143,7 @@ pub const Wip = struct {...@@ -139,6 +143,7 @@ pub const Wip = struct {
139 wip.steps.deinit(gpa);143 wip.steps.deinit(gpa);
140 wip.path_deps.deinit(gpa);144 wip.path_deps.deinit(gpa);
141 wip.search_prefixes.deinit(gpa);145 wip.search_prefixes.deinit(gpa);
146 wip.packages.deinit(gpa);
142 wip.extra.deinit(gpa);147 wip.extra.deinit(gpa);
143 wip.* = undefined;148 wip.* = undefined;
144 }149 }
...@@ -158,6 +163,7 @@ pub const Wip = struct {...@@ -158,6 +163,7 @@ pub const Wip = struct {
158 .system_integrations_len = @intCast(wip.system_integrations.items.len),163 .system_integrations_len = @intCast(wip.system_integrations.items.len),
159 .available_options_len = @intCast(wip.available_options.items.len),164 .available_options_len = @intCast(wip.available_options.items.len),
160 .search_prefixes_len = @intCast(wip.search_prefixes.items.len),165 .search_prefixes_len = @intCast(wip.search_prefixes.items.len),
166 .packages_len = @intCast(wip.packages.items.len),
161 .extra_len = @intCast(wip.extra.items.len),167 .extra_len = @intCast(wip.extra.items.len),
162168
163 .default_step = static.default_step,169 .default_step = static.default_step,
...@@ -175,6 +181,7 @@ pub const Wip = struct {...@@ -175,6 +181,7 @@ pub const Wip = struct {
175 @ptrCast(wip.system_integrations.items),181 @ptrCast(wip.system_integrations.items),
176 @ptrCast(wip.available_options.items),182 @ptrCast(wip.available_options.items),
177 @ptrCast(wip.search_prefixes.items),183 @ptrCast(wip.search_prefixes.items),
184 @ptrCast(wip.packages.items),
178 @ptrCast(wip.extra.items),185 @ptrCast(wip.extra.items),
179 };186 };
180 try w.writeVecAll(&buffers);187 try w.writeVecAll(&buffers);
...@@ -1596,30 +1603,28 @@ pub const OptionalGeneratedFileIndex = enum(u32) {...@@ -1596,30 +1603,28 @@ pub const OptionalGeneratedFileIndex = enum(u32) {
1596 }1603 }
1597};1604};
15981605
1599pub const Package = struct {1606pub const Package = extern struct {
1600 dep_prefix: String,1607 dep_prefix: String,
1601 hash: String,1608 hash: String,
1602 root_path: String,1609 root_path: String,
1610 deps: Dep.List.Index,
16031611
1604 pub const Index = enum(u32) {1612 pub const Index = enum(u32) {
1605 root = max_u32,1613 root,
1606 _,1614 _,
16071615
1608 /// Returns `null` for root package.1616 pub fn ptr(i: @This(), c: *const Configuration) *const Package {
1609 pub fn get(i: @This(), c: *const Configuration) ?Package {1617 return &c.packages[@backingInt(i)];
1610 if (i == .root) return null;
1611 return extraData(c, Package, @backingInt(i));
1612 }1618 }
16131619
1614 pub fn depPrefixSlice(i: @This(), c: *const Configuration) [:0]const u8 {1620 pub fn depPrefixSlice(i: @This(), c: *const Configuration) [:0]const u8 {
1615 const package = get(i, c) orelse return "";1621 return ptr(i, c).dep_prefix.slice(c);
1616 return package.dep_prefix.slice(c);
1617 }1622 }
1618 };1623 };
16191624
1620 pub const OptionalIndex = enum(u32) {1625 pub const OptionalIndex = enum(u32) {
1621 none = max_u32 - 1,1626 root,
1622 root = max_u32,1627 none = max_u32,
1623 _,1628 _,
16241629
1625 pub fn init(i: Index) OptionalIndex {1630 pub fn init(i: Index) OptionalIndex {
...@@ -1636,6 +1641,28 @@ pub const Package = struct {...@@ -1636,6 +1641,28 @@ pub const Package = struct {
1636 };1641 };
1637 }1642 }
1638 };1643 };
1644
1645 pub const Dep = extern struct {
1646 name: String,
1647 /// Must not be `.root`.
1648 package: Package.Index,
1649
1650 pub const List = struct {
1651 deps: Storage.LengthPrefixedList(Dep),
1652
1653 pub const Index = enum(u32) {
1654 _,
1655
1656 pub fn get(this: @This(), c: *const Configuration) List {
1657 return extraData(c, List, @backingInt(this));
1658 }
1659
1660 pub fn slice(this: @This(), c: *const Configuration) []const Dep {
1661 return get(this, c).deps.slice;
1662 }
1663 };
1664 };
1665 };
1639};1666};
16401667
1641pub const Module = struct {1668pub const Module = struct {
...@@ -3170,6 +3197,7 @@ pub fn load(arena: Allocator, reader: *Io.Reader) LoadError!Configuration {...@@ -3170,6 +3197,7 @@ pub fn load(arena: Allocator, reader: *Io.Reader) LoadError!Configuration {
3170 .system_integrations = try arena.alloc(SystemIntegration, header.system_integrations_len),3197 .system_integrations = try arena.alloc(SystemIntegration, header.system_integrations_len),
3171 .available_options = try arena.alloc(AvailableOption, header.available_options_len),3198 .available_options = try arena.alloc(AvailableOption, header.available_options_len),
3172 .search_prefixes = try arena.alloc(String, header.search_prefixes_len),3199 .search_prefixes = try arena.alloc(String, header.search_prefixes_len),
3200 .packages = try arena.alloc(Package, header.packages_len),
3173 .extra = try arena.alloc(u32, header.extra_len),3201 .extra = try arena.alloc(u32, header.extra_len),
3174 .default_step = header.default_step,3202 .default_step = header.default_step,
3175 .generated_files_len = header.generated_files_len,3203 .generated_files_len = header.generated_files_len,
...@@ -3183,6 +3211,7 @@ pub fn load(arena: Allocator, reader: *Io.Reader) LoadError!Configuration {...@@ -3183,6 +3211,7 @@ pub fn load(arena: Allocator, reader: *Io.Reader) LoadError!Configuration {
3183 @ptrCast(result.system_integrations),3211 @ptrCast(result.system_integrations),
3184 @ptrCast(result.available_options),3212 @ptrCast(result.available_options),
3185 @ptrCast(result.search_prefixes),3213 @ptrCast(result.search_prefixes),
3214 @ptrCast(result.packages),
3186 @ptrCast(result.extra),3215 @ptrCast(result.extra),
3187 };3216 };
3188 try reader.readVecAll(&vecs);3217 try reader.readVecAll(&vecs);
lib/std/Build/Serialize.zig+68-18
...@@ -10,7 +10,8 @@ const log = std.log;...@@ -10,7 +10,8 @@ const log = std.log;
10arena: Allocator,10arena: Allocator,
11wc: *Configuration.Wip,11wc: *Configuration.Wip,
12module_map: std.array_hash_map.Auto(*std.Build.Module, Configuration.Module.Index) = .empty,12module_map: std.array_hash_map.Auto(*std.Build.Module, Configuration.Module.Index) = .empty,
13package_map: std.array_hash_map.Auto(*std.Build, Configuration.Package.Index) = .empty,13/// Keyed by package hash.
14package_map: std.array_hash_map.String(Configuration.Package.Index) = .empty,
14/// Index corresponds to `Configuration.steps` index.15/// Index corresponds to `Configuration.steps` index.
15step_map: std.array_hash_map.Auto(*Step, void) = .empty,16step_map: std.array_hash_map.Auto(*Step, void) = .empty,
1617
...@@ -21,6 +22,10 @@ pub fn write(b: *std.Build, wc: *Configuration.Wip, writer: *std.Io.Writer) !voi...@@ -21,6 +22,10 @@ pub fn write(b: *std.Build, wc: *Configuration.Wip, writer: *std.Io.Writer) !voi
2122
22 var s: Serialize = .{ .wc = wc, .arena = arena };23 var s: Serialize = .{ .wc = wc, .arena = arena };
2324
25 // Serialize all of the packages first to seed the package_map, which is
26 // later used in calls to packageFromHash.
27 try s.addRootPackage(b);
28
24 try wc.path_deps.ensureTotalCapacityPrecise(gpa, graph.configure_dependencies.items.len);29 try wc.path_deps.ensureTotalCapacityPrecise(gpa, graph.configure_dependencies.items.len);
25 for (30 for (
26 graph.configure_dependencies.items,31 graph.configure_dependencies.items,
...@@ -44,10 +49,10 @@ pub fn write(b: *std.Build, wc: *Configuration.Wip, writer: *std.Io.Writer) !voi...@@ -44,10 +49,10 @@ pub fn write(b: *std.Build, wc: *Configuration.Wip, writer: *std.Io.Writer) !voi
44 .relative => |r| try wc.addString(r.sub_path),49 .relative => |r| try wc.addString(r.sub_path),
45 },50 },
46 .pkg = switch (src.lazy_path) {51 .pkg = switch (src.lazy_path) {
47 .src_path => |sp| .init(try s.builderToPackage(sp.owner)),52 .src_path => |sp| .init(s.packageFromHash(sp.owner.pkg_hash)),
48 .generated => unreachable,53 .generated => unreachable,
49 .cwd_relative, .relative => .none,54 .cwd_relative, .relative => .none,
50 .dependency => |d| .init(try s.builderToPackage(d.dependency.builder)),55 .dependency => |d| .init(s.packageFromHash(d.dependency.builder.pkg_hash)),
51 },56 },
52 };57 };
53 }58 }
...@@ -84,7 +89,7 @@ pub fn write(b: *std.Build, wc: *Configuration.Wip, writer: *std.Io.Writer) !voi...@@ -84,7 +89,7 @@ pub fn write(b: *std.Build, wc: *Configuration.Wip, writer: *std.Io.Writer) !voi
84 try wc.steps.ensureTotalCapacity(gpa, s.step_map.entries.capacity);89 try wc.steps.ensureTotalCapacity(gpa, s.step_map.entries.capacity);
85 wc.steps.appendAssumeCapacity(.{90 wc.steps.appendAssumeCapacity(.{
86 .name = try wc.addString(step.name),91 .name = try wc.addString(step.name),
87 .owner = try s.builderToPackage(step.owner),92 .owner = s.packageFromHash(step.owner.pkg_hash),
88 .deps = deps,93 .deps = deps,
89 .max_rss = .fromBytes(step.max_rss),94 .max_rss = .fromBytes(step.max_rss),
90 .extended = @fromBackingInt(@intCast(switch (step.tag) {95 .extended = @fromBackingInt(@intCast(switch (step.tag) {
...@@ -724,19 +729,64 @@ pub fn packageOptions(b: *std.Build, wc: *Configuration.Wip) Allocator.Error!voi...@@ -724,19 +729,64 @@ pub fn packageOptions(b: *std.Build, wc: *Configuration.Wip) Allocator.Error!voi
724 }729 }
725}730}
726731
727fn builderToPackage(s: *Serialize, b: *std.Build) !Configuration.Package.Index {732fn addRootPackage(s: *Serialize, b: *std.Build) Allocator.Error!void {
728 if (b.pkg_hash.len == 0) return .root;
729 const arena = s.arena;733 const arena = s.arena;
730 const wc = s.wc;734 const wc = s.wc;
731 const gop = try s.package_map.getOrPut(arena, b);735
732 if (!gop.found_existing) {736 try wc.packages.append(wc.gpa, .{
733 gop.value_ptr.* = try wc.addExtra(Configuration.Package, .{737 .dep_prefix = .empty,
734 .hash = try wc.addString(b.pkg_hash),738 .hash = .empty,
735 .dep_prefix = try wc.addString(b.dep_prefix),739 .root_path = try wc.addString(try b.root.toString(arena)),
736 .root_path = try wc.addString(try b.root.toString(arena)),740 .deps = undefined,
737 });741 });
738 }742
739 return gop.value_ptr.*;743 const deps = try arena.alloc(Configuration.Package.Dep, b.available_deps.len);
744 for (deps, b.available_deps) |*dest, src| dest.* = try s.makePackageDep("", src[0], src[1]);
745
746 wc.packages.items[0].deps = try wc.addExtra(Configuration.Package.Dep.List, .{
747 .deps = .{ .slice = deps },
748 });
749}
750
751fn makePackageDep(s: *Serialize, parent_dep_prefix: []const u8, name: []const u8, hash: []const u8) Allocator.Error!Configuration.Package.Dep {
752 const arena = s.arena;
753 const wc = s.wc;
754
755 if (s.package_map.get(hash)) |index| return .{
756 .name = try wc.addString(name),
757 .package = index,
758 };
759
760 const entry = std.Build.package_map.get(hash) orelse unreachable;
761
762 const dep_prefix = try arena.print("{s}{s}.", .{ parent_dep_prefix, name });
763
764 const index: Configuration.Package.Index = @fromBackingInt(@intCast(wc.packages.items.len));
765 try s.package_map.put(arena, hash, index);
766
767 try wc.packages.append(wc.gpa, .{
768 .dep_prefix = try wc.addString(dep_prefix),
769 .hash = try wc.addString(hash),
770 .root_path = try wc.addString(entry.build_root),
771 .deps = undefined,
772 });
773
774 const deps = try arena.alloc(Configuration.Package.Dep, entry.deps.len);
775 for (deps, entry.deps) |*dest, src| dest.* = try s.makePackageDep(dep_prefix, src[0], src[1]);
776
777 wc.packages.items[@backingInt(index)].deps = try wc.addExtra(Configuration.Package.Dep.List, .{
778 .deps = .{ .slice = deps },
779 });
780
781 return .{
782 .name = try wc.addString(name),
783 .package = index,
784 };
785}
786
787fn packageFromHash(s: *Serialize, pkg_hash: []const u8) Configuration.Package.Index {
788 if (pkg_hash.len == 0) return .root;
789 return s.package_map.get(pkg_hash) orelse std.debug.panic("unrecognized package hash: {q}", .{pkg_hash});
740}790}
741791
742fn addOptionalLazyPathEnum(s: *Serialize, lp: ?std.Build.LazyPath) !Configuration.LazyPath.OptionalIndex {792fn addOptionalLazyPathEnum(s: *Serialize, lp: ?std.Build.LazyPath) !Configuration.LazyPath.OptionalIndex {
...@@ -745,7 +795,7 @@ fn addOptionalLazyPathEnum(s: *Serialize, lp: ?std.Build.LazyPath) !Configuratio...@@ -745,7 +795,7 @@ fn addOptionalLazyPathEnum(s: *Serialize, lp: ?std.Build.LazyPath) !Configuratio
745 .src_path => |src_path| i: {795 .src_path => |src_path| i: {
746 const sub_path = try wc.addString(src_path.sub_path);796 const sub_path = try wc.addString(src_path.sub_path);
747 break :i try wc.addExtraErased(Configuration.LazyPath.SourcePath, .{797 break :i try wc.addExtraErased(Configuration.LazyPath.SourcePath, .{
748 .owner = try s.builderToPackage(src_path.owner),798 .owner = s.packageFromHash(src_path.owner.pkg_hash),
749 .sub_path = sub_path,799 .sub_path = sub_path,
750 });800 });
751 },801 },
...@@ -773,7 +823,7 @@ fn addOptionalLazyPathEnum(s: *Serialize, lp: ?std.Build.LazyPath) !Configuratio...@@ -773,7 +823,7 @@ fn addOptionalLazyPathEnum(s: *Serialize, lp: ?std.Build.LazyPath) !Configuratio
773 .dependency => |dependency| i: {823 .dependency => |dependency| i: {
774 const sub_path = try wc.addString(dependency.sub_path);824 const sub_path = try wc.addString(dependency.sub_path);
775 break :i try wc.addExtraErased(Configuration.LazyPath.SourcePath, .{825 break :i try wc.addExtraErased(Configuration.LazyPath.SourcePath, .{
776 .owner = try s.builderToPackage(dependency.dependency.builder),826 .owner = s.packageFromHash(dependency.dependency.builder.pkg_hash),
777 .sub_path = sub_path,827 .sub_path = sub_path,
778 });828 });
779 },829 },
...@@ -1138,7 +1188,7 @@ fn addModule(s: *Serialize, m: *std.Build.Module) !Configuration.Module.Index {...@@ -1138,7 +1188,7 @@ fn addModule(s: *Serialize, m: *std.Build.Module) !Configuration.Module.Index {
1138 .link_libcpp = .init(m.link_libcpp),1188 .link_libcpp = .init(m.link_libcpp),
1139 .no_builtin = .init(m.no_builtin),1189 .no_builtin = .init(m.no_builtin),
1140 },1190 },
1141 .owner = try s.builderToPackage(m.owner),1191 .owner = s.packageFromHash(m.owner.pkg_hash),
1142 .root_source_file = try s.addOptionalLazyPathEnum(m.root_source_file),1192 .root_source_file = try s.addOptionalLazyPathEnum(m.root_source_file),
1143 .import_table = .invalid,1193 .import_table = .invalid,
1144 .resolved_target = try addOptionalResolvedTarget(wc, m.resolved_target),1194 .resolved_target = try addOptionalResolvedTarget(wc, m.resolved_target),