| ... | @@ -2135,25 +2135,46 @@ pub fn lazyDependency(b: *Build, name: []const u8, args: anytype) ?*Dependency { | ... | @@ -2135,25 +2135,46 @@ pub fn lazyDependency(b: *Build, name: []const u8, args: anytype) ?*Dependency { |
| 2135 | /// | 2135 | /// |
| 2136 | /// For non-lazy dependencies, this always succeeds. | 2136 | /// For non-lazy dependencies, this always succeeds. |
| 2137 | pub fn dependencyLazy(b: *Build, name: []const u8, args: anytype) error{LazyDependencyNeeded}!*Dependency { | 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 | const pkg_hash = findPkgHashOrFatal(b, name); | 2138 | const pkg_hash = findPkgHashOrFatal(b, name); |
| 2141 | | 2139 | const entry = package_map.get(pkg_hash) orelse unreachable; |
| 2142 | inline for (@typeInfo(deps.packages).@"struct".decl_names) |decl_name| { | 2140 | if (!entry.available) { |
| 2143 | if (mem.eql(u8, decl_name, pkg_hash)) { | 2141 | markNeededLazyDep(b, pkg_hash); |
| 2144 | const pkg = @field(deps.packages, decl_name); | 2142 | return error.LazyDependencyNeeded; |
| 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 | } | | |
| 2152 | } | 2143 | } |
| 2153 | | 2144 | return dependencyResolved(b, name, entry, userInputOptionsFromArgs(b.graph.arena, args)); |
| 2154 | unreachable; // bad @dependencies source | | |
| 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 | /// Declares that the current configuration does in fact require a potentially | 2178 | /// Declares that the current configuration does in fact require a potentially |
| 2158 | /// lazy dependency. | 2179 | /// lazy dependency. |
| 2159 | /// | 2180 | /// |
| ... | @@ -2210,6 +2231,14 @@ pub inline fn lazyImport( | ... | @@ -2210,6 +2231,14 @@ pub inline fn lazyImport( |
| 2210 | comptime unreachable; // Bad @dependencies source | 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 | /// Build system implementation detail. | 2242 | /// Build system implementation detail. |
| 2214 | pub fn dependencyFromBuildZig( | 2243 | pub fn dependencyFromBuildZig( |
| 2215 | b: *Build, | 2244 | b: *Build, |
| ... | @@ -2218,20 +2247,15 @@ pub fn dependencyFromBuildZig( | ... | @@ -2218,20 +2247,15 @@ pub fn dependencyFromBuildZig( |
| 2218 | comptime build_zig: type, | 2247 | comptime build_zig: type, |
| 2219 | args: anytype, | 2248 | args: anytype, |
| 2220 | ) *Dependency { | 2249 | ) *Dependency { |
| 2221 | const build_runner = @import("root"); | 2250 | const arena = b.graph.arena; |
| 2222 | const deps = build_runner.dependencies; | | |
| 2223 | const graph = b.graph; | | |
| 2224 | const arena = graph.arena; | | |
| 2225 | | 2251 | |
| 2226 | find_dep: { | 2252 | find_dep: { |
| 2227 | const pkg, const pkg_hash = inline for (@typeInfo(deps.packages).@"struct".decl_names) |pkg_hash| { | 2253 | const pkg_hash = comptime pkgHashFromBuildZig(build_zig) orelse break :find_dep; |
| 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; | | |
| 2231 | const dep_name = for (b.available_deps) |dep| { | 2254 | const dep_name = for (b.available_deps) |dep| { |
| 2232 | if (mem.eql(u8, dep[1], pkg_hash)) break dep[1]; | 2255 | if (mem.eql(u8, dep[1], pkg_hash)) break dep[1]; |
| 2233 | } else break :find_dep; | 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 | const full_path = b.root.join(arena, "build.zig.zon") catch @panic("OOM"); | 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,35 +2345,31 @@ fn userLazyPathsAreTheSame(lhs_lp: LazyPath, rhs_lp: LazyPath) bool { |
| 2321 | return true; | 2345 | return true; |
| 2322 | } | 2346 | } |
| 2323 | | 2347 | |
| 2324 | fn dependencyInner( | 2348 | fn dependencyResolved( |
| 2325 | b: *Build, | 2349 | b: *Build, |
| 2326 | name: []const u8, | 2350 | name: []const u8, |
| 2327 | build_root_string: []const u8, | 2351 | entry: PackageEntry, |
| 2328 | comptime build_zig: ?type, | 2352 | user_input_options: UserInputOptionsMap, |
| 2329 | pkg_hash: []const u8, | | |
| 2330 | pkg_deps: AvailableDeps, | | |
| 2331 | args: anytype, | | |
| 2332 | ) *Dependency { | 2353 | ) *Dependency { |
| 2333 | const graph = b.graph; | 2354 | const graph = b.graph; |
| 2334 | const io = graph.io; | 2355 | const io = graph.io; |
| 2335 | const arena = graph.arena; | 2356 | const arena = graph.arena; |
| 2336 | const user_input_options = userInputOptionsFromArgs(arena, args); | | |
| 2337 | if (graph.dependency_cache.getContext(.{ | 2357 | if (graph.dependency_cache.getContext(.{ |
| 2338 | .build_root_string = build_root_string, | 2358 | .build_root_string = entry.build_root, |
| 2339 | .user_input_options = user_input_options, | 2359 | .user_input_options = user_input_options, |
| 2340 | }, .{ .allocator = arena })) |dep| return dep; | 2360 | }, .{ .allocator = arena })) |dep| return dep; |
| 2341 | | 2361 | |
| 2342 | const dep_root: Cache.Path = .{ | 2362 | const dep_root: Cache.Path = .{ |
| 2343 | .root_dir = .{ | 2363 | .root_dir = .{ |
| 2344 | .path = build_root_string, | 2364 | .path = entry.build_root, |
| 2345 | .handle = Io.Dir.cwd().openDir(io, build_root_string, .{}) catch |err| | 2365 | .handle = Io.Dir.cwd().openDir(io, entry.build_root, .{}) catch |err| |
| 2346 | fatal("failed to open {q}: {t}", .{ build_root_string, 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"); | 2370 | const sub_builder = b.createChild(name, dep_root, entry.hash, entry.deps, user_input_options) catch @panic("OOM"); |
| 2351 | if (build_zig) |bz| { | 2371 | if (entry.run_build) |run_build| { |
| 2352 | sub_builder.runPackageScript(bz); | 2372 | run_build(sub_builder); |
| 2353 | | 2373 | |
| 2354 | if (sub_builder.validateUserInputDidItFail()) { | 2374 | if (sub_builder.validateUserInputDidItFail()) { |
| 2355 | std.debug.dumpCurrentStackTrace(.{ .first_address = @returnAddress() }); | 2375 | std.debug.dumpCurrentStackTrace(.{ .first_address = @returnAddress() }); |
| ... | @@ -2360,7 +2380,7 @@ fn dependencyInner( | ... | @@ -2360,7 +2380,7 @@ fn dependencyInner( |
| 2360 | dep.* = .{ .builder = sub_builder }; | 2380 | dep.* = .{ .builder = sub_builder }; |
| 2361 | | 2381 | |
| 2362 | graph.dependency_cache.putContext(arena, .{ | 2382 | graph.dependency_cache.putContext(arena, .{ |
| 2363 | .build_root_string = build_root_string, | 2383 | .build_root_string = entry.build_root, |
| 2364 | .user_input_options = user_input_options, | 2384 | .user_input_options = user_input_options, |
| 2365 | }, dep, .{ .allocator = arena }) catch @panic("OOM"); | 2385 | }, dep, .{ .allocator = arena }) catch @panic("OOM"); |
| 2366 | return dep; | 2386 | return dep; |