From 4eb7b61daae4fe43b218eaaac0614f6bee1915d8 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Fri, 6 Oct 2023 23:59:47 -0700 Subject: [PATCH] package fetching: generate dependencies.zig file Only problem is that it looks like `has_build_zig` is being false when it should be true. After that is fixed then main.zig needs to create the `@dependencies` module from the generated source code. --- src/Package/Fetch.zig | 83 ++++++++++++++++++++++++++++++++++++------- src/main.zig | 19 ++++++---- 2 files changed, 84 insertions(+), 18 deletions(-) diff --git a/src/Package/Fetch.zig b/src/Package/Fetch.zig index 1c4c6ad097..b688b24fe6 100644 --- a/src/Package/Fetch.zig +++ b/src/Package/Fetch.zig @@ -61,6 +61,8 @@ oom_flag: bool, /// Contains shared state among all `Fetch` tasks. pub const JobQueue = struct { mutex: std.Thread.Mutex = .{}, + /// It's an array hash map so that it can be sorted before rendering the + /// dependencies.zig source file. /// Protected by `mutex`. table: Table = .{}, /// `table` may be missing some tasks such as ones that failed, so this @@ -75,7 +77,7 @@ pub const JobQueue = struct { recursive: bool, work_around_btrfs_bug: bool, - pub const Table = std.AutoHashMapUnmanaged(Manifest.MultiHashHexDigest, *Fetch); + pub const Table = std.AutoArrayHashMapUnmanaged(Manifest.MultiHashHexDigest, *Fetch); pub fn deinit(jq: *JobQueue) void { if (jq.all_fetches.items.len == 0) return; @@ -105,17 +107,74 @@ pub const JobQueue = struct { /// Creates the dependencies.zig file and corresponding `Module` for the /// build runner to obtain via `@import("@dependencies")`. - pub fn createDependenciesModule( - jq: *JobQueue, - arena: Allocator, - local_cache_directory: Cache.Directory, - basename: []const u8, - ) !*Package.Module { - _ = jq; - _ = arena; - _ = local_cache_directory; - _ = basename; - @panic("TODO: createDependenciesModule"); + pub fn createDependenciesModule(jq: *JobQueue, buf: *std.ArrayList(u8)) Allocator.Error!void { + try buf.appendSlice("pub const packages = struct {\n"); + + // Ensure the generated .zig file is deterministic. + jq.table.sortUnstable(@as(struct { + keys: []const Manifest.MultiHashHexDigest, + pub fn lessThan(ctx: @This(), a_index: usize, b_index: usize) bool { + return std.mem.lessThan(u8, &ctx.keys[a_index], &ctx.keys[b_index]); + } + }, .{ .keys = jq.table.keys() })); + + for (jq.table.keys()[1..], jq.table.values()[1..]) |hash, fetch| { + try buf.writer().print( + \\ pub const {} = struct {{ + \\ pub const build_root = "{q}"; + \\ + , .{ std.zig.fmtId(&hash), fetch.package_root }); + + if (fetch.has_build_zig) { + try buf.writer().print( + \\ pub const build_zig = @import("{}"); + \\ + , .{std.zig.fmtEscapes(&hash)}); + } + + if (fetch.manifest) |*manifest| { + try buf.appendSlice( + \\ pub const deps: []const struct { []const u8, []const u8 } = &.{ + \\ + ); + for (manifest.dependencies.keys(), manifest.dependencies.values()) |name, dep| { + try buf.writer().print( + " .{{ \"{}\", \"{}\" }},\n", + .{ std.zig.fmtEscapes(name), std.zig.fmtEscapes(dep.hash.?) }, + ); + } + + try buf.appendSlice( + \\ }; + \\ }; + \\ + ); + } else { + try buf.appendSlice( + \\ pub const deps: []const struct { []const u8, []const u8 } = &.{}; + \\ }; + \\ + ); + } + } + + try buf.appendSlice( + \\}; + \\ + \\pub const root_deps: []const struct { []const u8, []const u8 } = &.{ + \\ + ); + + const root_fetch = jq.all_fetches.items[0]; + const root_manifest = &root_fetch.manifest.?; + + for (root_manifest.dependencies.keys(), root_manifest.dependencies.values()) |name, dep| { + try buf.writer().print( + " .{{ \"{}\", \"{}\" }},\n", + .{ std.zig.fmtEscapes(name), std.zig.fmtEscapes(dep.hash.?) }, + ); + } + try buf.appendSlice("};\n"); } }; diff --git a/src/main.zig b/src/main.zig index cd7cd80da4..1cdbd61242 100644 --- a/src/main.zig +++ b/src/main.zig @@ -4887,12 +4887,19 @@ pub fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !voi process.exit(1); } - const deps_mod = try job_queue.createDependenciesModule( - arena, - local_cache_directory, - "dependencies.zig", - ); - try main_mod.deps.put(arena, "@dependencies", deps_mod); + var buf = std.ArrayList(u8).init(gpa); + defer buf.deinit(); + try job_queue.createDependenciesModule(&buf); + if (true) { + std.debug.print("dependencies source:\n\n{s}\n", .{buf.items}); + @panic("TODO"); + } + //const deps_mod = try job_queue.createDependenciesModule( + // arena, + // local_cache_directory, + // "dependencies.zig", + //); + //try main_mod.deps.put(arena, "@dependencies", deps_mod); } try main_mod.deps.put(arena, "@build", &build_mod);