Commit e5c2a7dbca

Andrew Kelley <andrew@ziglang.org>
2023-10-08 07:34:45
finish hooking up new dependency tree logic
* add Module instances for each package's build.zig and attach it to the dependencies.zig module with the hash digest hex string as the name. * fix incorrectly skipping the wrong packages for creating dependencies.zig * a couple more renaming of "package" to "module"
1 parent 35d81c9
Changed files (6)
lib/std/Build/Cache.zig
@@ -9,6 +9,13 @@ pub const Directory = struct {
     path: ?[]const u8,
     handle: fs.Dir,
 
+    pub fn clone(d: Directory, arena: Allocator) Allocator.Error!Directory {
+        return .{
+            .path = if (d.path) |p| try arena.dupe(u8, p) else null,
+            .handle = d.handle,
+        };
+    }
+
     pub fn cwd() Directory {
         return .{
             .path = null,
src/Package/Fetch.zig
@@ -109,7 +109,6 @@ pub const JobQueue = struct {
     /// build runner to obtain via `@import("@dependencies")`.
     pub fn createDependenciesModule(jq: *JobQueue, buf: *std.ArrayList(u8)) Allocator.Error!void {
         const keys = jq.table.keys();
-        const values = jq.table.values();
 
         if (keys.len == 0)
             return createEmptyDependenciesModule(buf);
@@ -124,7 +123,11 @@ pub const JobQueue = struct {
             }
         }, .{ .keys = keys }));
 
-        for (keys[1..], values[1..]) |hash, fetch| {
+        for (keys, jq.table.values()) |hash, fetch| {
+            if (fetch == jq.all_fetches.items[0]) {
+                // The first one is a dummy package for the current project.
+                continue;
+            }
             try buf.writer().print(
                 \\    pub const {} = struct {{
                 \\        pub const build_root = "{q}";
src/main.zig
@@ -4885,39 +4885,60 @@ pub fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !voi
             }
 
             try job_queue.createDependenciesModule(&dependencies_zig_src);
-        }
-        {
-            // Atomically create the file in a directory named after the hash of its contents.
-            const basename = "dependencies.zig";
-            const rand_int = std.crypto.random.int(u64);
-            const tmp_dir_sub_path = "tmp" ++ fs.path.sep_str ++ Package.Manifest.hex64(rand_int);
-            {
-                var tmp_dir = try local_cache_directory.handle.makeOpenPath(tmp_dir_sub_path, .{});
-                defer tmp_dir.close();
-                try tmp_dir.writeFile(basename, dependencies_zig_src.items);
-            }
-
-            var hh: Cache.HashHelper = .{};
-            hh.addBytes(build_options.version);
-            hh.addBytes(dependencies_zig_src.items);
-            const hex_digest = hh.final();
 
-            const o_dir_sub_path = try arena.dupe(u8, "o" ++ fs.path.sep_str ++ hex_digest);
-            try Package.Fetch.renameTmpIntoCache(
-                local_cache_directory.handle,
-                tmp_dir_sub_path,
-                o_dir_sub_path,
-            );
+            const deps_mod = m: {
+                // Atomically create the file in a directory named after the hash of its contents.
+                const basename = "dependencies.zig";
+                const rand_int = std.crypto.random.int(u64);
+                const tmp_dir_sub_path = "tmp" ++ fs.path.sep_str ++
+                    Package.Manifest.hex64(rand_int);
+                {
+                    var tmp_dir = try local_cache_directory.handle.makeOpenPath(tmp_dir_sub_path, .{});
+                    defer tmp_dir.close();
+                    try tmp_dir.writeFile(basename, dependencies_zig_src.items);
+                }
 
-            const deps_mod = try Package.Module.create(arena, .{
-                .root = .{
-                    .root_dir = local_cache_directory,
-                    .sub_path = o_dir_sub_path,
-                },
-                .root_src_path = basename,
-            });
+                var hh: Cache.HashHelper = .{};
+                hh.addBytes(build_options.version);
+                hh.addBytes(dependencies_zig_src.items);
+                const hex_digest = hh.final();
+
+                const o_dir_sub_path = try arena.dupe(u8, "o" ++ fs.path.sep_str ++ hex_digest);
+                try Package.Fetch.renameTmpIntoCache(
+                    local_cache_directory.handle,
+                    tmp_dir_sub_path,
+                    o_dir_sub_path,
+                );
+
+                break :m try Package.Module.create(arena, .{
+                    .root = .{
+                        .root_dir = local_cache_directory,
+                        .sub_path = o_dir_sub_path,
+                    },
+                    .root_src_path = basename,
+                });
+            };
+            {
+                // We need a Module for each package's build.zig.
+                const hashes = job_queue.table.keys();
+                const fetches = job_queue.table.values();
+                try deps_mod.deps.ensureUnusedCapacity(arena, @intCast(hashes.len));
+                for (hashes, fetches) |hash, f| {
+                    if (f == &fetch) {
+                        // The first one is a dummy package for the current project.
+                        continue;
+                    }
+                    const m = try Package.Module.create(arena, .{
+                        .root = try f.package_root.clone(arena),
+                        .root_src_path = if (f.has_build_zig) Package.build_zig_basename else "",
+                    });
+                    const hash_cloned = try arena.dupe(u8, &hash);
+                    deps_mod.deps.putAssumeCapacityNoClobber(hash_cloned, m);
+                }
+            }
             try main_mod.deps.put(arena, "@dependencies", deps_mod);
         }
+
         try main_mod.deps.put(arena, "@build", &build_mod);
 
         const comp = Compilation.create(gpa, .{
src/Module.zig
@@ -4074,7 +4074,7 @@ pub fn importFile(
         return mod.importPkg(pkg);
     }
     if (!mem.endsWith(u8, import_string, ".zig")) {
-        return error.PackageNotFound;
+        return error.ModuleNotFound;
     }
     const gpa = mod.gpa;
 
@@ -4120,7 +4120,7 @@ pub fn importFile(
         {
             break :p try gpa.dupe(u8, resolved_path);
         }
-        return error.ImportOutsidePkgPath;
+        return error.ImportOutsideModulePath;
     };
     errdefer gpa.free(sub_file_path);
 
@@ -4206,7 +4206,7 @@ pub fn embedFile(mod: *Module, cur_file: *File, import_string: []const u8) !*Emb
         {
             break :p try gpa.dupe(u8, resolved_path);
         }
-        return error.ImportOutsidePkgPath;
+        return error.ImportOutsideModulePath;
     };
     errdefer gpa.free(sub_file_path);
 
src/Package.zig
@@ -9,6 +9,13 @@ pub const Path = struct {
     /// Empty string means the root_dir is the path.
     sub_path: []const u8 = "",
 
+    pub fn clone(p: Path, arena: Allocator) Allocator.Error!Path {
+        return .{
+            .root_dir = try p.root_dir.clone(arena),
+            .sub_path = try arena.dupe(u8, p.sub_path),
+        };
+    }
+
     pub fn cwd() Path {
         return .{ .root_dir = Cache.Directory.cwd() };
     }
src/Sema.zig
@@ -13075,13 +13075,13 @@ fn zirImport(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
     const operand = inst_data.get(sema.code);
 
     const result = mod.importFile(block.getFileScope(mod), operand) catch |err| switch (err) {
-        error.ImportOutsidePkgPath => {
-            return sema.fail(block, operand_src, "import of file outside package path: '{s}'", .{operand});
+        error.ImportOutsideModulePath => {
+            return sema.fail(block, operand_src, "import of file outside module path: '{s}'", .{operand});
         },
-        error.PackageNotFound => {
+        error.ModuleNotFound => {
             //const name = try block.getFileScope(mod).mod.getName(sema.gpa, mod.*);
             //defer sema.gpa.free(name);
-            return sema.fail(block, operand_src, "no package named '{s}' available within package '{}'", .{
+            return sema.fail(block, operand_src, "no module named '{s}' available within module '{}'", .{
                 operand, block.getFileScope(mod).mod.root,
             });
         },
@@ -13112,7 +13112,7 @@ fn zirEmbedFile(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
     }
 
     const embed_file = mod.embedFile(block.getFileScope(mod), name) catch |err| switch (err) {
-        error.ImportOutsidePkgPath => {
+        error.ImportOutsideModulePath => {
             return sema.fail(block, operand_src, "embed of file outside package path: '{s}'", .{name});
         },
         else => {