| ... | @@ -225,6 +225,7 @@ pub fn fetchAndAddDependencies( | ... | @@ -225,6 +225,7 @@ pub fn fetchAndAddDependencies( |
| 225 | build_roots_source: *std.ArrayList(u8), | 225 | build_roots_source: *std.ArrayList(u8), |
| 226 | name_prefix: []const u8, | 226 | name_prefix: []const u8, |
| 227 | color: main.Color, | 227 | color: main.Color, |
| | 228 | all_modules: *AllModules, |
| 228 | ) !void { | 229 | ) !void { |
| 229 | const max_bytes = 10 * 1024 * 1024; | 230 | const max_bytes = 10 * 1024 * 1024; |
| 230 | const gpa = thread_pool.allocator; | 231 | const gpa = thread_pool.allocator; |
| ... | @@ -291,6 +292,7 @@ pub fn fetchAndAddDependencies( | ... | @@ -291,6 +292,7 @@ pub fn fetchAndAddDependencies( |
| 291 | report, | 292 | report, |
| 292 | build_roots_source, | 293 | build_roots_source, |
| 293 | fqn, | 294 | fqn, |
| | 295 | all_modules, |
| 294 | ); | 296 | ); |
| 295 | | 297 | |
| 296 | try pkg.fetchAndAddDependencies( | 298 | try pkg.fetchAndAddDependencies( |
| ... | @@ -304,6 +306,7 @@ pub fn fetchAndAddDependencies( | ... | @@ -304,6 +306,7 @@ pub fn fetchAndAddDependencies( |
| 304 | build_roots_source, | 306 | build_roots_source, |
| 305 | sub_prefix, | 307 | sub_prefix, |
| 306 | color, | 308 | color, |
| | 309 | all_modules, |
| 307 | ); | 310 | ); |
| 308 | | 311 | |
| 309 | try add(pkg, gpa, fqn, sub_pkg); | 312 | try add(pkg, gpa, fqn, sub_pkg); |
| ... | @@ -402,6 +405,11 @@ const Report = struct { | ... | @@ -402,6 +405,11 @@ const Report = struct { |
| 402 | } | 405 | } |
| 403 | }; | 406 | }; |
| 404 | | 407 | |
| | 408 | const hex_multihash_len = 2 * Manifest.multihash_len; |
| | 409 | const MultiHashHexDigest = [hex_multihash_len]u8; |
| | 410 | /// This is to avoid creating multiple modules for the same build.zig file. |
| | 411 | pub const AllModules = std.AutoHashMapUnmanaged(MultiHashHexDigest, *Package); |
| | 412 | |
| 405 | fn fetchAndUnpack( | 413 | fn fetchAndUnpack( |
| 406 | thread_pool: *ThreadPool, | 414 | thread_pool: *ThreadPool, |
| 407 | http_client: *std.http.Client, | 415 | http_client: *std.http.Client, |
| ... | @@ -410,6 +418,7 @@ fn fetchAndUnpack( | ... | @@ -410,6 +418,7 @@ fn fetchAndUnpack( |
| 410 | report: Report, | 418 | report: Report, |
| 411 | build_roots_source: *std.ArrayList(u8), | 419 | build_roots_source: *std.ArrayList(u8), |
| 412 | fqn: []const u8, | 420 | fqn: []const u8, |
| | 421 | all_modules: *AllModules, |
| 413 | ) !*Package { | 422 | ) !*Package { |
| 414 | const gpa = http_client.allocator; | 423 | const gpa = http_client.allocator; |
| 415 | const s = fs.path.sep_str; | 424 | const s = fs.path.sep_str; |
| ... | @@ -417,9 +426,24 @@ fn fetchAndUnpack( | ... | @@ -417,9 +426,24 @@ fn fetchAndUnpack( |
| 417 | // Check if the expected_hash is already present in the global package | 426 | // Check if the expected_hash is already present in the global package |
| 418 | // cache, and thereby avoid both fetching and unpacking. | 427 | // cache, and thereby avoid both fetching and unpacking. |
| 419 | if (dep.hash) |h| cached: { | 428 | if (dep.hash) |h| cached: { |
| 420 | const hex_multihash_len = 2 * Manifest.multihash_len; | | |
| 421 | const hex_digest = h[0..hex_multihash_len]; | 429 | const hex_digest = h[0..hex_multihash_len]; |
| 422 | const pkg_dir_sub_path = "p" ++ s ++ hex_digest; | 430 | const pkg_dir_sub_path = "p" ++ s ++ hex_digest; |
| | 431 | |
| | 432 | const build_root = try global_cache_directory.join(gpa, &.{pkg_dir_sub_path}); |
| | 433 | errdefer gpa.free(build_root); |
| | 434 | |
| | 435 | try build_roots_source.writer().print(" pub const {s} = \"{}\";\n", .{ |
| | 436 | std.zig.fmtId(fqn), std.zig.fmtEscapes(build_root), |
| | 437 | }); |
| | 438 | |
| | 439 | // The compiler has a rule that a file must not be included in multiple modules, |
| | 440 | // so we must detect if a module has been created for this package and reuse it. |
| | 441 | const gop = try all_modules.getOrPut(gpa, hex_digest.*); |
| | 442 | if (gop.found_existing) { |
| | 443 | gpa.free(build_root); |
| | 444 | return gop.value_ptr.*; |
| | 445 | } |
| | 446 | |
| 423 | var pkg_dir = global_cache_directory.handle.openDir(pkg_dir_sub_path, .{}) catch |err| switch (err) { | 447 | var pkg_dir = global_cache_directory.handle.openDir(pkg_dir_sub_path, .{}) catch |err| switch (err) { |
| 424 | error.FileNotFound => break :cached, | 448 | error.FileNotFound => break :cached, |
| 425 | else => |e| return e, | 449 | else => |e| return e, |
| ... | @@ -432,13 +456,6 @@ fn fetchAndUnpack( | ... | @@ -432,13 +456,6 @@ fn fetchAndUnpack( |
| 432 | const owned_src_path = try gpa.dupe(u8, build_zig_basename); | 456 | const owned_src_path = try gpa.dupe(u8, build_zig_basename); |
| 433 | errdefer gpa.free(owned_src_path); | 457 | errdefer gpa.free(owned_src_path); |
| 434 | | 458 | |
| 435 | const build_root = try global_cache_directory.join(gpa, &.{pkg_dir_sub_path}); | | |
| 436 | errdefer gpa.free(build_root); | | |
| 437 | | | |
| 438 | try build_roots_source.writer().print(" pub const {s} = \"{}\";\n", .{ | | |
| 439 | std.zig.fmtId(fqn), std.zig.fmtEscapes(build_root), | | |
| 440 | }); | | |
| 441 | | | |
| 442 | ptr.* = .{ | 459 | ptr.* = .{ |
| 443 | .root_src_directory = .{ | 460 | .root_src_directory = .{ |
| 444 | .path = build_root, | 461 | .path = build_root, |
| ... | @@ -448,6 +465,7 @@ fn fetchAndUnpack( | ... | @@ -448,6 +465,7 @@ fn fetchAndUnpack( |
| 448 | .root_src_path = owned_src_path, | 465 | .root_src_path = owned_src_path, |
| 449 | }; | 466 | }; |
| 450 | | 467 | |
| | 468 | gop.value_ptr.* = ptr; |
| 451 | return ptr; | 469 | return ptr; |
| 452 | } | 470 | } |
| 453 | | 471 | |