mirror of
https://github.com/ziglang/zig.git
synced 2025-12-06 06:13:07 +00:00
packages: avoid creating multiple modules with same build.zig
When there is a diamond dependency, reuse a *Module instead of creating a redundant one using the same build.zig file. Otherwise, the compile error "file exists in multiple modules" would occur.
This commit is contained in:
parent
874d3a17ae
commit
db8217f9a0
@ -225,6 +225,7 @@ pub fn fetchAndAddDependencies(
|
|||||||
build_roots_source: *std.ArrayList(u8),
|
build_roots_source: *std.ArrayList(u8),
|
||||||
name_prefix: []const u8,
|
name_prefix: []const u8,
|
||||||
color: main.Color,
|
color: main.Color,
|
||||||
|
all_modules: *AllModules,
|
||||||
) !void {
|
) !void {
|
||||||
const max_bytes = 10 * 1024 * 1024;
|
const max_bytes = 10 * 1024 * 1024;
|
||||||
const gpa = thread_pool.allocator;
|
const gpa = thread_pool.allocator;
|
||||||
@ -291,6 +292,7 @@ pub fn fetchAndAddDependencies(
|
|||||||
report,
|
report,
|
||||||
build_roots_source,
|
build_roots_source,
|
||||||
fqn,
|
fqn,
|
||||||
|
all_modules,
|
||||||
);
|
);
|
||||||
|
|
||||||
try pkg.fetchAndAddDependencies(
|
try pkg.fetchAndAddDependencies(
|
||||||
@ -304,6 +306,7 @@ pub fn fetchAndAddDependencies(
|
|||||||
build_roots_source,
|
build_roots_source,
|
||||||
sub_prefix,
|
sub_prefix,
|
||||||
color,
|
color,
|
||||||
|
all_modules,
|
||||||
);
|
);
|
||||||
|
|
||||||
try add(pkg, gpa, fqn, sub_pkg);
|
try add(pkg, gpa, fqn, sub_pkg);
|
||||||
@ -402,6 +405,11 @@ const Report = struct {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const hex_multihash_len = 2 * Manifest.multihash_len;
|
||||||
|
const MultiHashHexDigest = [hex_multihash_len]u8;
|
||||||
|
/// This is to avoid creating multiple modules for the same build.zig file.
|
||||||
|
pub const AllModules = std.AutoHashMapUnmanaged(MultiHashHexDigest, *Package);
|
||||||
|
|
||||||
fn fetchAndUnpack(
|
fn fetchAndUnpack(
|
||||||
thread_pool: *ThreadPool,
|
thread_pool: *ThreadPool,
|
||||||
http_client: *std.http.Client,
|
http_client: *std.http.Client,
|
||||||
@ -410,6 +418,7 @@ fn fetchAndUnpack(
|
|||||||
report: Report,
|
report: Report,
|
||||||
build_roots_source: *std.ArrayList(u8),
|
build_roots_source: *std.ArrayList(u8),
|
||||||
fqn: []const u8,
|
fqn: []const u8,
|
||||||
|
all_modules: *AllModules,
|
||||||
) !*Package {
|
) !*Package {
|
||||||
const gpa = http_client.allocator;
|
const gpa = http_client.allocator;
|
||||||
const s = fs.path.sep_str;
|
const s = fs.path.sep_str;
|
||||||
@ -417,9 +426,24 @@ fn fetchAndUnpack(
|
|||||||
// Check if the expected_hash is already present in the global package
|
// Check if the expected_hash is already present in the global package
|
||||||
// cache, and thereby avoid both fetching and unpacking.
|
// cache, and thereby avoid both fetching and unpacking.
|
||||||
if (dep.hash) |h| cached: {
|
if (dep.hash) |h| cached: {
|
||||||
const hex_multihash_len = 2 * Manifest.multihash_len;
|
|
||||||
const hex_digest = h[0..hex_multihash_len];
|
const hex_digest = h[0..hex_multihash_len];
|
||||||
const pkg_dir_sub_path = "p" ++ s ++ hex_digest;
|
const pkg_dir_sub_path = "p" ++ s ++ hex_digest;
|
||||||
|
|
||||||
|
const build_root = try global_cache_directory.join(gpa, &.{pkg_dir_sub_path});
|
||||||
|
errdefer gpa.free(build_root);
|
||||||
|
|
||||||
|
try build_roots_source.writer().print(" pub const {s} = \"{}\";\n", .{
|
||||||
|
std.zig.fmtId(fqn), std.zig.fmtEscapes(build_root),
|
||||||
|
});
|
||||||
|
|
||||||
|
// The compiler has a rule that a file must not be included in multiple modules,
|
||||||
|
// so we must detect if a module has been created for this package and reuse it.
|
||||||
|
const gop = try all_modules.getOrPut(gpa, hex_digest.*);
|
||||||
|
if (gop.found_existing) {
|
||||||
|
gpa.free(build_root);
|
||||||
|
return gop.value_ptr.*;
|
||||||
|
}
|
||||||
|
|
||||||
var pkg_dir = global_cache_directory.handle.openDir(pkg_dir_sub_path, .{}) catch |err| switch (err) {
|
var pkg_dir = global_cache_directory.handle.openDir(pkg_dir_sub_path, .{}) catch |err| switch (err) {
|
||||||
error.FileNotFound => break :cached,
|
error.FileNotFound => break :cached,
|
||||||
else => |e| return e,
|
else => |e| return e,
|
||||||
@ -432,13 +456,6 @@ fn fetchAndUnpack(
|
|||||||
const owned_src_path = try gpa.dupe(u8, build_zig_basename);
|
const owned_src_path = try gpa.dupe(u8, build_zig_basename);
|
||||||
errdefer gpa.free(owned_src_path);
|
errdefer gpa.free(owned_src_path);
|
||||||
|
|
||||||
const build_root = try global_cache_directory.join(gpa, &.{pkg_dir_sub_path});
|
|
||||||
errdefer gpa.free(build_root);
|
|
||||||
|
|
||||||
try build_roots_source.writer().print(" pub const {s} = \"{}\";\n", .{
|
|
||||||
std.zig.fmtId(fqn), std.zig.fmtEscapes(build_root),
|
|
||||||
});
|
|
||||||
|
|
||||||
ptr.* = .{
|
ptr.* = .{
|
||||||
.root_src_directory = .{
|
.root_src_directory = .{
|
||||||
.path = build_root,
|
.path = build_root,
|
||||||
@ -448,6 +465,7 @@ fn fetchAndUnpack(
|
|||||||
.root_src_path = owned_src_path,
|
.root_src_path = owned_src_path,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
gop.value_ptr.* = ptr;
|
||||||
return ptr;
|
return ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -4244,6 +4244,9 @@ pub fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !voi
|
|||||||
var build_roots_source = std.ArrayList(u8).init(gpa);
|
var build_roots_source = std.ArrayList(u8).init(gpa);
|
||||||
defer build_roots_source.deinit();
|
defer build_roots_source.deinit();
|
||||||
|
|
||||||
|
var all_modules: Package.AllModules = .{};
|
||||||
|
defer all_modules.deinit(gpa);
|
||||||
|
|
||||||
// Here we borrow main package's table and will replace it with a fresh
|
// Here we borrow main package's table and will replace it with a fresh
|
||||||
// one after this process completes.
|
// one after this process completes.
|
||||||
main_pkg.fetchAndAddDependencies(
|
main_pkg.fetchAndAddDependencies(
|
||||||
@ -4257,6 +4260,7 @@ pub fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !voi
|
|||||||
&build_roots_source,
|
&build_roots_source,
|
||||||
"",
|
"",
|
||||||
color,
|
color,
|
||||||
|
&all_modules,
|
||||||
) catch |err| switch (err) {
|
) catch |err| switch (err) {
|
||||||
error.PackageFetchFailed => process.exit(1),
|
error.PackageFetchFailed => process.exit(1),
|
||||||
else => |e| return e,
|
else => |e| return e,
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user