Commit 1ad33f53fe

Andrew Kelley <andrew@ziglang.org>
2023-10-09 01:08:08
give build.zig modules access to their dependencies' build.zig modules
1 parent ce052d8
Changed files (2)
src
src/Package/Fetch.zig
@@ -58,6 +58,12 @@ has_build_zig: bool,
 /// Indicates whether the task aborted due to an out-of-memory condition.
 oom_flag: bool,
 
+// This field is used by the CLI only, untouched by this file.
+
+/// The module for this `Fetch` tasks's package, which exposes `build.zig` as
+/// the root source file.
+module: ?*Package.Module,
+
 /// Contains shared state among all `Fetch` tasks.
 pub const JobQueue = struct {
     mutex: std.Thread.Mutex = .{},
@@ -147,10 +153,10 @@ pub const JobQueue = struct {
                     \\
                 );
                 for (manifest.dependencies.keys(), manifest.dependencies.values()) |name, dep| {
-                    const h = dep.hash orelse continue;
+                    const h = depDigest(fetch.package_root, jq.global_cache, dep) orelse continue;
                     try buf.writer().print(
                         "            .{{ \"{}\", \"{}\" }},\n",
-                        .{ std.zig.fmtEscapes(name), std.zig.fmtEscapes(h) },
+                        .{ std.zig.fmtEscapes(name), std.zig.fmtEscapes(&h) },
                     );
                 }
 
@@ -179,10 +185,10 @@ pub const JobQueue = struct {
         const root_manifest = &root_fetch.manifest.?;
 
         for (root_manifest.dependencies.keys(), root_manifest.dependencies.values()) |name, dep| {
-            const h = dep.hash orelse continue;
+            const h = depDigest(root_fetch.package_root, jq.global_cache, dep) orelse continue;
             try buf.writer().print(
                 "    .{{ \"{}\", \"{}\" }},\n",
-                .{ std.zig.fmtEscapes(name), std.zig.fmtEscapes(h) },
+                .{ std.zig.fmtEscapes(name), std.zig.fmtEscapes(&h) },
             );
         }
         try buf.appendSlice("};\n");
@@ -258,7 +264,7 @@ pub fn run(f: *Fetch) RunError!void {
             }
             f.package_root = pkg_root;
             try loadManifest(f, pkg_root);
-            try checkBuildFileExistence(f);
+            if (!f.has_build_zig) try checkBuildFileExistence(f);
             if (!f.job_queue.recursive) return;
             return queueJobsForDeps(f);
         },
@@ -604,6 +610,8 @@ fn queueJobsForDeps(f: *Fetch) RunError!void {
                 .actual_hash = undefined,
                 .has_build_zig = false,
                 .oom_flag = false,
+
+                .module = null,
             };
         }
 
@@ -1400,6 +1408,25 @@ const Filter = struct {
     }
 };
 
+pub fn depDigest(
+    pkg_root: Package.Path,
+    cache_root: Cache.Directory,
+    dep: Manifest.Dependency,
+) ?Manifest.MultiHashHexDigest {
+    if (dep.hash) |h| return h[0..Manifest.multihash_hex_digest_len].*;
+
+    switch (dep.location) {
+        .url => return null,
+        .path => |rel_path| {
+            var buf: [fs.MAX_PATH_BYTES]u8 = undefined;
+            var fba = std.heap.FixedBufferAllocator.init(&buf);
+            const new_root = pkg_root.resolvePosix(fba.allocator(), rel_path) catch
+                return null;
+            return relativePathDigest(new_root, cache_root);
+        },
+    }
+}
+
 // These are random bytes.
 const package_hash_prefix_cached = [8]u8{ 0x53, 0x7e, 0xfa, 0x94, 0x65, 0xe9, 0xf8, 0x73 };
 const package_hash_prefix_project = [8]u8{ 0xe1, 0x25, 0xee, 0xfa, 0xa6, 0x17, 0x38, 0xcc };
src/main.zig
@@ -4870,8 +4870,10 @@ pub fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !voi
                 .manifest = null,
                 .manifest_ast = undefined,
                 .actual_hash = undefined,
-                .has_build_zig = false,
+                .has_build_zig = true,
                 .oom_flag = false,
+
+                .module = &build_mod,
             };
             job_queue.all_fetches.appendAssumeCapacity(&fetch);
 
@@ -4922,6 +4924,26 @@ pub fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !voi
                     });
                     const hash_cloned = try arena.dupe(u8, &hash);
                     deps_mod.deps.putAssumeCapacityNoClobber(hash_cloned, m);
+                    f.module = m;
+                }
+
+                // Each build.zig module needs access to each of its
+                // dependencies' build.zig modules by name.
+                for (fetches) |f| {
+                    const mod = f.module orelse continue;
+                    const man = f.manifest orelse continue;
+                    const dep_names = man.dependencies.keys();
+                    try mod.deps.ensureUnusedCapacity(arena, @intCast(dep_names.len));
+                    for (dep_names, man.dependencies.values()) |name, dep| {
+                        const dep_digest = Package.Fetch.depDigest(
+                            f.package_root,
+                            global_cache_directory,
+                            dep,
+                        ) orelse continue;
+                        const dep_mod = job_queue.table.get(dep_digest).?.module orelse continue;
+                        const name_cloned = try arena.dupe(u8, name);
+                        mod.deps.putAssumeCapacityNoClobber(name_cloned, dep_mod);
+                    }
                 }
             }
         }
@@ -6751,6 +6773,8 @@ fn cmdFetch(
         .actual_hash = undefined,
         .has_build_zig = false,
         .oom_flag = false,
+
+        .module = null,
     };
     defer fetch.deinit();