authorgravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2023-04-22 18:15:19+01:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-05-18 00:27:21-07:00
logf65e8c78621c90c9b9932903a9ed99c973dbcf63
tree027dc7bdf661ae06bc3f75fb14fd71d5c394a511
parent378264d404e71da878f9e6934c045ad64193877f

Deduplicate uses of the same package across dependencies


2 files changed, 26 insertions(+), 7 deletions(-)

lib/std/Build.zig+16
......@@ -124,6 +124,9 @@ host: NativeTargetInfo,
124124dep_prefix: []const u8 = "",
125125
126126modules: std.StringArrayHashMap(*Module),
127/// A map from build root dirs to the corresponding `*Dependency`. This is shared with all child
128/// `Build`s.
129initialized_deps: *std.StringHashMap(*Dependency),
127130
128131pub const ExecError = error{
129132 ReadFailure,
......@@ -209,6 +212,9 @@ pub fn create(
209212 const env_map = try allocator.create(EnvMap);
210213 env_map.* = try process.getEnvMap(allocator);
211214
215 const initialized_deps = try allocator.create(std.StringHashMap(*Dependency));
216 initialized_deps.* = std.StringHashMap(*Dependency).init(allocator);
217
212218 const self = try allocator.create(Build);
213219 self.* = .{
214220 .zig_exe = zig_exe,
......@@ -261,6 +267,7 @@ pub fn create(
261267 .args = null,
262268 .host = host,
263269 .modules = std.StringArrayHashMap(*Module).init(allocator),
270 .initialized_deps = initialized_deps,
264271 };
265272 try self.top_level_steps.put(allocator, self.install_tls.step.name, &self.install_tls);
266273 try self.top_level_steps.put(allocator, self.uninstall_tls.step.name, &self.uninstall_tls);
......@@ -345,6 +352,7 @@ fn createChildOnly(parent: *Build, dep_name: []const u8, build_root: Cache.Direc
345352 .host = parent.host,
346353 .dep_prefix = parent.fmt("{s}{s}.", .{ parent.dep_prefix, dep_name }),
347354 .modules = std.StringArrayHashMap(*Module).init(allocator),
355 .initialized_deps = parent.initialized_deps,
348356 };
349357 try child.top_level_steps.put(allocator, child.install_tls.step.name, &child.install_tls);
350358 try child.top_level_steps.put(allocator, child.uninstall_tls.step.name, &child.uninstall_tls);
......@@ -1560,6 +1568,11 @@ pub fn dependencyInner(
15601568 comptime build_zig: type,
15611569 args: anytype,
15621570) *Dependency {
1571 if (b.initialized_deps.get(build_root_string)) |dep| {
1572 // TODO: check args are the same
1573 return dep;
1574 }
1575
15631576 const build_root: std.Build.Cache.Directory = .{
15641577 .path = build_root_string,
15651578 .handle = std.fs.cwd().openDir(build_root_string, .{}) catch |err| {
......@@ -1578,6 +1591,9 @@ pub fn dependencyInner(
15781591
15791592 const dep = b.allocator.create(Dependency) catch @panic("OOM");
15801593 dep.* = .{ .builder = sub_builder };
1594
1595 b.initialized_deps.put(build_root_string, dep) catch @panic("OOM");
1596
15811597 return dep;
15821598}
15831599
src/Package.zig+10-7
......@@ -216,7 +216,7 @@ pub const build_zig_basename = "build.zig";
216216
217217pub fn fetchAndAddDependencies(
218218 pkg: *Package,
219 root_pkg: *Package,
219 deps_pkg: *Package,
220220 arena: Allocator,
221221 thread_pool: *ThreadPool,
222222 http_client: *std.http.Client,
......@@ -272,7 +272,6 @@ pub fn fetchAndAddDependencies(
272272 .error_bundle = error_bundle,
273273 };
274274
275 var any_error = false;
276275 const deps_list = manifest.dependencies.values();
277276 for (manifest.dependencies.keys(), 0..) |name, i| {
278277 const dep = deps_list[i];
......@@ -292,7 +291,7 @@ pub fn fetchAndAddDependencies(
292291 );
293292
294293 try sub_pkg.fetchAndAddDependencies(
295 root_pkg,
294 deps_pkg,
296295 arena,
297296 thread_pool,
298297 http_client,
......@@ -307,14 +306,18 @@ pub fn fetchAndAddDependencies(
307306 );
308307
309308 try pkg.add(gpa, name, sub_pkg);
310 try root_pkg.add(gpa, fqn, sub_pkg);
309 if (deps_pkg.table.get(dep.hash.?)) |other_sub| {
310 // This should be the same package (and hence module) since it's the same hash
311 // TODO: dedup multiple versions of the same package
312 assert(other_sub == sub_pkg);
313 } else {
314 try deps_pkg.add(gpa, dep.hash.?, sub_pkg);
315 }
311316
312317 try dependencies_source.writer().print(" pub const {s} = @import(\"{}\");\n", .{
313 std.zig.fmtId(fqn), std.zig.fmtEscapes(fqn),
318 std.zig.fmtId(fqn), std.zig.fmtEscapes(dep.hash.?),
314319 });
315320 }
316
317 if (any_error) return error.InvalidBuildManifestFile;
318321}
319322
320323pub fn createFilePkg(