| ... | ... | @@ -2135,25 +2135,46 @@ pub fn lazyDependency(b: *Build, name: []const u8, args: anytype) ?*Dependency { |
| 2135 | 2135 | /// |
| 2136 | 2136 | /// For non-lazy dependencies, this always succeeds. |
| 2137 | 2137 | pub fn dependencyLazy(b: *Build, name: []const u8, args: anytype) error{LazyDependencyNeeded}!*Dependency { |
| 2138 | | const build_runner = @import("root"); |
| 2139 | | const deps = build_runner.dependencies; |
| 2140 | 2138 | const pkg_hash = findPkgHashOrFatal(b, name); |
| 2141 | | |
| 2142 | | inline for (@typeInfo(deps.packages).@"struct".decl_names) |decl_name| { |
| 2143 | | if (mem.eql(u8, decl_name, pkg_hash)) { |
| 2144 | | const pkg = @field(deps.packages, decl_name); |
| 2145 | | const available = !@hasDecl(pkg, "available") or pkg.available; |
| 2146 | | if (!available) { |
| 2147 | | markNeededLazyDep(b, pkg_hash); |
| 2148 | | return error.LazyDependencyNeeded; |
| 2149 | | } |
| 2150 | | return dependencyInner(b, name, pkg.build_root, if (@hasDecl(pkg, "build_zig")) pkg.build_zig else null, pkg_hash, pkg.deps, args); |
| 2151 | | } |
| 2139 | const entry = package_map.get(pkg_hash) orelse unreachable; |
| 2140 | if (!entry.available) { |
| 2141 | markNeededLazyDep(b, pkg_hash); |
| 2142 | return error.LazyDependencyNeeded; |
| 2152 | 2143 | } |
| 2153 | | |
| 2154 | | unreachable; // bad @dependencies source |
| 2144 | return dependencyResolved(b, name, entry, userInputOptionsFromArgs(b.graph.arena, args)); |
| 2155 | 2145 | } |
| 2156 | 2146 | |
| 2147 | const PackageEntry = struct { |
| 2148 | hash: []const u8, |
| 2149 | available: bool, |
| 2150 | build_root: []const u8, |
| 2151 | deps: AvailableDeps, |
| 2152 | run_build: ?*const fn (*Build) void, |
| 2153 | }; |
| 2154 | |
| 2155 | const package_map: std.StaticStringMap(PackageEntry) = blk: { |
| 2156 | const deps = @import("root").dependencies; |
| 2157 | const decl_names = @typeInfo(deps.packages).@"struct".decl_names; |
| 2158 | var kvs: [decl_names.len]struct { []const u8, PackageEntry } = undefined; |
| 2159 | for (decl_names, 0..) |decl_name, i| { |
| 2160 | const pkg = @field(deps.packages, decl_name); |
| 2161 | const available = !@hasDecl(pkg, "available") or pkg.available; |
| 2162 | kvs[i] = .{ decl_name, .{ |
| 2163 | .hash = decl_name, |
| 2164 | .available = available, |
| 2165 | .build_root = if (available) pkg.build_root else "", |
| 2166 | .deps = if (available) pkg.deps else &.{}, |
| 2167 | .run_build = if (available and @hasDecl(pkg, "build_zig")) &struct { |
| 2168 | fn run(sb: *Build) void { |
| 2169 | sb.runPackageScript(pkg.build_zig); |
| 2170 | } |
| 2171 | }.run else null, |
| 2172 | } }; |
| 2173 | } |
| 2174 | const frozen = kvs; |
| 2175 | break :blk .initComptime(&frozen); |
| 2176 | }; |
| 2177 | |
| 2157 | 2178 | /// Declares that the current configuration does in fact require a potentially |
| 2158 | 2179 | /// lazy dependency. |
| 2159 | 2180 | /// |
| ... | ... | @@ -2210,6 +2231,14 @@ pub inline fn lazyImport( |
| 2210 | 2231 | comptime unreachable; // Bad @dependencies source |
| 2211 | 2232 | } |
| 2212 | 2233 | |
| 2234 | fn pkgHashFromBuildZig(comptime build_zig: type) ?[]const u8 { |
| 2235 | const deps = @import("root").dependencies; |
| 2236 | return comptime for (@typeInfo(deps.packages).@"struct".decl_names) |pkg_hash| { |
| 2237 | const pkg = @field(deps.packages, pkg_hash); |
| 2238 | if (@hasDecl(pkg, "build_zig") and pkg.build_zig == build_zig) break pkg_hash; |
| 2239 | } else null; |
| 2240 | } |
| 2241 | |
| 2213 | 2242 | /// Build system implementation detail. |
| 2214 | 2243 | pub fn dependencyFromBuildZig( |
| 2215 | 2244 | b: *Build, |
| ... | ... | @@ -2218,20 +2247,15 @@ pub fn dependencyFromBuildZig( |
| 2218 | 2247 | comptime build_zig: type, |
| 2219 | 2248 | args: anytype, |
| 2220 | 2249 | ) *Dependency { |
| 2221 | | const build_runner = @import("root"); |
| 2222 | | const deps = build_runner.dependencies; |
| 2223 | | const graph = b.graph; |
| 2224 | | const arena = graph.arena; |
| 2250 | const arena = b.graph.arena; |
| 2225 | 2251 | |
| 2226 | 2252 | find_dep: { |
| 2227 | | const pkg, const pkg_hash = inline for (@typeInfo(deps.packages).@"struct".decl_names) |pkg_hash| { |
| 2228 | | const pkg = @field(deps.packages, pkg_hash); |
| 2229 | | if (@hasDecl(pkg, "build_zig") and pkg.build_zig == build_zig) break .{ pkg, pkg_hash }; |
| 2230 | | } else break :find_dep; |
| 2253 | const pkg_hash = comptime pkgHashFromBuildZig(build_zig) orelse break :find_dep; |
| 2231 | 2254 | const dep_name = for (b.available_deps) |dep| { |
| 2232 | 2255 | if (mem.eql(u8, dep[1], pkg_hash)) break dep[1]; |
| 2233 | 2256 | } else break :find_dep; |
| 2234 | | return dependencyInner(b, dep_name, pkg.build_root, pkg.build_zig, pkg_hash, pkg.deps, args); |
| 2257 | const entry = package_map.get(pkg_hash) orelse break :find_dep; |
| 2258 | return dependencyResolved(b, dep_name, entry, userInputOptionsFromArgs(arena, args)); |
| 2235 | 2259 | } |
| 2236 | 2260 | |
| 2237 | 2261 | const full_path = b.root.join(arena, "build.zig.zon") catch @panic("OOM"); |
| ... | ... | @@ -2321,35 +2345,31 @@ fn userLazyPathsAreTheSame(lhs_lp: LazyPath, rhs_lp: LazyPath) bool { |
| 2321 | 2345 | return true; |
| 2322 | 2346 | } |
| 2323 | 2347 | |
| 2324 | | fn dependencyInner( |
| 2348 | fn dependencyResolved( |
| 2325 | 2349 | b: *Build, |
| 2326 | 2350 | name: []const u8, |
| 2327 | | build_root_string: []const u8, |
| 2328 | | comptime build_zig: ?type, |
| 2329 | | pkg_hash: []const u8, |
| 2330 | | pkg_deps: AvailableDeps, |
| 2331 | | args: anytype, |
| 2351 | entry: PackageEntry, |
| 2352 | user_input_options: UserInputOptionsMap, |
| 2332 | 2353 | ) *Dependency { |
| 2333 | 2354 | const graph = b.graph; |
| 2334 | 2355 | const io = graph.io; |
| 2335 | 2356 | const arena = graph.arena; |
| 2336 | | const user_input_options = userInputOptionsFromArgs(arena, args); |
| 2337 | 2357 | if (graph.dependency_cache.getContext(.{ |
| 2338 | | .build_root_string = build_root_string, |
| 2358 | .build_root_string = entry.build_root, |
| 2339 | 2359 | .user_input_options = user_input_options, |
| 2340 | 2360 | }, .{ .allocator = arena })) |dep| return dep; |
| 2341 | 2361 | |
| 2342 | 2362 | const dep_root: Cache.Path = .{ |
| 2343 | 2363 | .root_dir = .{ |
| 2344 | | .path = build_root_string, |
| 2345 | | .handle = Io.Dir.cwd().openDir(io, build_root_string, .{}) catch |err| |
| 2346 | | fatal("failed to open {q}: {t}", .{ build_root_string, err }), |
| 2364 | .path = entry.build_root, |
| 2365 | .handle = Io.Dir.cwd().openDir(io, entry.build_root, .{}) catch |err| |
| 2366 | fatal("failed to open {q}: {t}", .{ entry.build_root, err }), |
| 2347 | 2367 | }, |
| 2348 | 2368 | }; |
| 2349 | 2369 | |
| 2350 | | const sub_builder = b.createChild(name, dep_root, pkg_hash, pkg_deps, user_input_options) catch @panic("OOM"); |
| 2351 | | if (build_zig) |bz| { |
| 2352 | | sub_builder.runPackageScript(bz); |
| 2370 | const sub_builder = b.createChild(name, dep_root, entry.hash, entry.deps, user_input_options) catch @panic("OOM"); |
| 2371 | if (entry.run_build) |run_build| { |
| 2372 | run_build(sub_builder); |
| 2353 | 2373 | |
| 2354 | 2374 | if (sub_builder.validateUserInputDidItFail()) { |
| 2355 | 2375 | std.debug.dumpCurrentStackTrace(.{ .first_address = @returnAddress() }); |
| ... | ... | @@ -2360,7 +2380,7 @@ fn dependencyInner( |
| 2360 | 2380 | dep.* = .{ .builder = sub_builder }; |
| 2361 | 2381 | |
| 2362 | 2382 | graph.dependency_cache.putContext(arena, .{ |
| 2363 | | .build_root_string = build_root_string, |
| 2383 | .build_root_string = entry.build_root, |
| 2364 | 2384 | .user_input_options = user_input_options, |
| 2365 | 2385 | }, dep, .{ .allocator = arena }) catch @panic("OOM"); |
| 2366 | 2386 | return dep; |