| ... | ... | @@ -5202,562 +5202,564 @@ fn cmdBuild( |
| 5202 | 5202 | .build_file = build_file, |
| 5203 | 5203 | }); |
| 5204 | 5204 | |
| 5205 | | // This `init` calls `fatal` on error. |
| 5206 | | var dirs: Compilation.Directories = .init( |
| 5207 | | arena, |
| 5208 | | io, |
| 5209 | | override_lib_dir, |
| 5210 | | override_global_cache_dir, |
| 5211 | | .{ .override = path: { |
| 5212 | | if (override_local_cache_dir) |d| break :path d; |
| 5213 | | break :path try build_root.directory.join(arena, &.{introspect.default_local_zig_cache_basename}); |
| 5214 | | } }, |
| 5215 | | .empty, |
| 5216 | | self_exe_path, |
| 5217 | | environ_map, |
| 5218 | | cwd_path, |
| 5219 | | ); |
| 5220 | | defer dirs.deinit(io); |
| 5221 | | |
| 5222 | | const thread_limit = @min( |
| 5223 | | @max(n_jobs orelse std.Thread.getCpuCount() catch 1, 1), |
| 5224 | | std.math.maxInt(Zcu.PerThread.IdBacking), |
| 5225 | | ); |
| 5226 | | try setThreadLimit(arena, thread_limit); |
| 5205 | { |
| 5206 | // This `init` calls `fatal` on error. |
| 5207 | var dirs: Compilation.Directories = .init( |
| 5208 | arena, |
| 5209 | io, |
| 5210 | override_lib_dir, |
| 5211 | override_global_cache_dir, |
| 5212 | .{ .override = path: { |
| 5213 | if (override_local_cache_dir) |d| break :path d; |
| 5214 | break :path try build_root.directory.join(arena, &.{introspect.default_local_zig_cache_basename}); |
| 5215 | } }, |
| 5216 | .empty, |
| 5217 | self_exe_path, |
| 5218 | environ_map, |
| 5219 | cwd_path, |
| 5220 | ); |
| 5221 | defer dirs.deinit(io); |
| 5227 | 5222 | |
| 5228 | | // Cache lookup for configure options. If we get a match, we can skip |
| 5229 | | // execution of the configure script. If not, we get the file path to pass |
| 5230 | | // to the configure process. |
| 5231 | | var local_cache: Cache = .{ |
| 5232 | | .gpa = gpa, |
| 5233 | | .io = io, |
| 5234 | | .manifest_dir = try dirs.local_cache.handle.createDirPathOpen(io, "h", .{}), |
| 5235 | | .cwd = cwd_path, |
| 5236 | | }; |
| 5237 | | local_cache.addPrefix(.{ .path = null, .handle = Io.Dir.cwd() }); |
| 5238 | | local_cache.addPrefix(dirs.zig_lib); |
| 5239 | | local_cache.addPrefix(dirs.local_cache); |
| 5240 | | local_cache.addPrefix(dirs.global_cache); |
| 5241 | | defer local_cache.manifest_dir.close(io); |
| 5242 | | |
| 5243 | | var config_man = local_cache.obtain(); |
| 5244 | | defer config_man.deinit(); |
| 5245 | | config_man.hash.addBytes(build_options.version); |
| 5246 | | |
| 5247 | | for (cached_passthru_configure.items) |i| |
| 5248 | | config_man.hash.addBytes(configure_argv.items[i]); |
| 5249 | | |
| 5250 | | // Prevents a `zig build` from getting a false positive cache hit following |
| 5251 | | // a `zig build --cache-poison=ignored`. |
| 5252 | | config_man.hash.add(cache_poison == .ignored); |
| 5253 | | |
| 5254 | | // Normally the build runner is compiled for the host target but here is |
| 5255 | | // some code to help when debugging edits to the build runner so that you |
| 5256 | | // can make sure it compiles successfully on other targets. |
| 5257 | | const resolved_target: Package.Module.ResolvedTarget = t: { |
| 5258 | | if (build_options.enable_debug_extensions) { |
| 5259 | | if (debug_target) |triple| { |
| 5260 | | const target_query = try std.Target.Query.parse(.{ |
| 5261 | | .arch_os_abi = triple, |
| 5262 | | }); |
| 5263 | | config_man.hash.addBytes(triple); |
| 5264 | | break :t .{ |
| 5265 | | .result = std.zig.resolveTargetQueryOrFatal(io, target_query), |
| 5266 | | .is_native_os = false, |
| 5267 | | .is_native_abi = false, |
| 5268 | | .is_explicit_dynamic_linker = false, |
| 5269 | | }; |
| 5223 | const thread_limit = @min( |
| 5224 | @max(n_jobs orelse std.Thread.getCpuCount() catch 1, 1), |
| 5225 | std.math.maxInt(Zcu.PerThread.IdBacking), |
| 5226 | ); |
| 5227 | try setThreadLimit(arena, thread_limit); |
| 5228 | |
| 5229 | // Cache lookup for configure options. If we get a match, we can skip |
| 5230 | // execution of the configure script. If not, we get the file path to pass |
| 5231 | // to the configure process. |
| 5232 | var local_cache: Cache = .{ |
| 5233 | .gpa = gpa, |
| 5234 | .io = io, |
| 5235 | .manifest_dir = try dirs.local_cache.handle.createDirPathOpen(io, "h", .{}), |
| 5236 | .cwd = cwd_path, |
| 5237 | }; |
| 5238 | local_cache.addPrefix(.{ .path = null, .handle = Io.Dir.cwd() }); |
| 5239 | local_cache.addPrefix(dirs.zig_lib); |
| 5240 | local_cache.addPrefix(dirs.local_cache); |
| 5241 | local_cache.addPrefix(dirs.global_cache); |
| 5242 | defer local_cache.manifest_dir.close(io); |
| 5243 | |
| 5244 | var config_man = local_cache.obtain(); |
| 5245 | defer config_man.deinit(); |
| 5246 | config_man.hash.addBytes(build_options.version); |
| 5247 | |
| 5248 | for (cached_passthru_configure.items) |i| |
| 5249 | config_man.hash.addBytes(configure_argv.items[i]); |
| 5250 | |
| 5251 | // Prevents a `zig build` from getting a false positive cache hit following |
| 5252 | // a `zig build --cache-poison=ignored`. |
| 5253 | config_man.hash.add(cache_poison == .ignored); |
| 5254 | |
| 5255 | // Normally the build runner is compiled for the host target but here is |
| 5256 | // some code to help when debugging edits to the build runner so that you |
| 5257 | // can make sure it compiles successfully on other targets. |
| 5258 | const resolved_target: Package.Module.ResolvedTarget = t: { |
| 5259 | if (build_options.enable_debug_extensions) { |
| 5260 | if (debug_target) |triple| { |
| 5261 | const target_query = try std.Target.Query.parse(.{ |
| 5262 | .arch_os_abi = triple, |
| 5263 | }); |
| 5264 | config_man.hash.addBytes(triple); |
| 5265 | break :t .{ |
| 5266 | .result = std.zig.resolveTargetQueryOrFatal(io, target_query), |
| 5267 | .is_native_os = false, |
| 5268 | .is_native_abi = false, |
| 5269 | .is_explicit_dynamic_linker = false, |
| 5270 | }; |
| 5271 | } |
| 5270 | 5272 | } |
| 5271 | | } |
| 5272 | | break :t .{ |
| 5273 | | .result = std.zig.resolveTargetQueryOrFatal(io, .{}), |
| 5274 | | .is_native_os = true, |
| 5275 | | .is_native_abi = true, |
| 5276 | | .is_explicit_dynamic_linker = false, |
| 5273 | break :t .{ |
| 5274 | .result = std.zig.resolveTargetQueryOrFatal(io, .{}), |
| 5275 | .is_native_os = true, |
| 5276 | .is_native_abi = true, |
| 5277 | .is_explicit_dynamic_linker = false, |
| 5278 | }; |
| 5277 | 5279 | }; |
| 5278 | | }; |
| 5279 | 5280 | |
| 5280 | | // Likewise, `--debug-libc` allows overriding the libc installation. |
| 5281 | | const libc_installation: ?*const LibCInstallation = lci: { |
| 5282 | | const paths_file = debug_libc_paths_file orelse break :lci null; |
| 5283 | | if (!build_options.enable_debug_extensions) unreachable; |
| 5284 | | const lci = try arena.create(LibCInstallation); |
| 5285 | | lci.* = try .parse(arena, io, paths_file, &resolved_target.result); |
| 5286 | | LibCInstallation.addToHash(lci, &config_man.hash, resolved_target.result.abi); |
| 5287 | | break :lci lci; |
| 5288 | | }; |
| 5289 | | |
| 5290 | | // Kick off an optimized compilation of the make runner. |
| 5291 | | var make_runner_task = io.async(compileMakeRunner, .{ gpa, arena, io, .{ |
| 5292 | | .dirs = .{ |
| 5293 | | .cwd = dirs.cwd, |
| 5294 | | .zig_lib = dirs.zig_lib, |
| 5295 | | .global_cache = dirs.global_cache, |
| 5296 | | .local_cache = dirs.global_cache, |
| 5297 | | }, |
| 5298 | | .environ_map = environ_map, |
| 5299 | | .parent_prog_node = root_prog_node, |
| 5300 | | .resolved_target = resolved_target, |
| 5301 | | .libc_installation = libc_installation, |
| 5302 | | .thread_limit = thread_limit, |
| 5303 | | .self_exe_path = self_exe_path, |
| 5304 | | .color = color, |
| 5305 | | .reference_trace = reference_trace, |
| 5306 | | .optimize_mode = maker_optimize_mode, |
| 5307 | | } }); |
| 5308 | | defer _ = make_runner_task.cancel(io) catch {}; |
| 5309 | | |
| 5310 | | const pkg_root: Path = if (override_pkg_dir) |p| |
| 5311 | | .initCwd(p) |
| 5312 | | else if (system_pkg_dir_path) |p| |
| 5313 | | .initCwd(p) |
| 5314 | | else |
| 5315 | | .{ |
| 5316 | | .root_dir = build_root.directory, |
| 5317 | | .sub_path = "zig-pkg", |
| 5281 | // Likewise, `--debug-libc` allows overriding the libc installation. |
| 5282 | const libc_installation: ?*const LibCInstallation = lci: { |
| 5283 | const paths_file = debug_libc_paths_file orelse break :lci null; |
| 5284 | if (!build_options.enable_debug_extensions) unreachable; |
| 5285 | const lci = try arena.create(LibCInstallation); |
| 5286 | lci.* = try .parse(arena, io, paths_file, &resolved_target.result); |
| 5287 | LibCInstallation.addToHash(lci, &config_man.hash, resolved_target.result.abi); |
| 5288 | break :lci lci; |
| 5318 | 5289 | }; |
| 5319 | 5290 | |
| 5320 | | make_argv.items[make_argv_index_zig_lib_dir] = dirs.zig_lib.path orelse cwd_path; |
| 5321 | | make_argv.items[make_argv_index_build_root] = build_root.directory.path orelse cwd_path; |
| 5322 | | make_argv.items[make_argv_index_global_cache_dir] = dirs.global_cache.path orelse cwd_path; |
| 5323 | | make_argv.items[make_argv_index_cache_dir] = dirs.local_cache.path orelse cwd_path; |
| 5291 | // Kick off an optimized compilation of the make runner. |
| 5292 | var make_runner_task = io.async(compileMakeRunner, .{ gpa, arena, io, .{ |
| 5293 | .dirs = .{ |
| 5294 | .cwd = dirs.cwd, |
| 5295 | .zig_lib = dirs.zig_lib, |
| 5296 | .global_cache = dirs.global_cache, |
| 5297 | .local_cache = dirs.global_cache, |
| 5298 | }, |
| 5299 | .environ_map = environ_map, |
| 5300 | .parent_prog_node = root_prog_node, |
| 5301 | .resolved_target = resolved_target, |
| 5302 | .libc_installation = libc_installation, |
| 5303 | .thread_limit = thread_limit, |
| 5304 | .self_exe_path = self_exe_path, |
| 5305 | .color = color, |
| 5306 | .reference_trace = reference_trace, |
| 5307 | .optimize_mode = maker_optimize_mode, |
| 5308 | } }); |
| 5309 | defer _ = make_runner_task.cancel(io) catch {}; |
| 5310 | |
| 5311 | const pkg_root: Path = if (override_pkg_dir) |p| |
| 5312 | .initCwd(p) |
| 5313 | else if (system_pkg_dir_path) |p| |
| 5314 | .initCwd(p) |
| 5315 | else |
| 5316 | .{ |
| 5317 | .root_dir = build_root.directory, |
| 5318 | .sub_path = "zig-pkg", |
| 5319 | }; |
| 5324 | 5320 | |
| 5325 | | configure_argv.items[conf_argv_index_build_root] = build_root.directory.path orelse cwd_path; |
| 5321 | make_argv.items[make_argv_index_zig_lib_dir] = dirs.zig_lib.path orelse cwd_path; |
| 5322 | make_argv.items[make_argv_index_build_root] = build_root.directory.path orelse cwd_path; |
| 5323 | make_argv.items[make_argv_index_global_cache_dir] = dirs.global_cache.path orelse cwd_path; |
| 5324 | make_argv.items[make_argv_index_cache_dir] = dirs.local_cache.path orelse cwd_path; |
| 5326 | 5325 | |
| 5327 | | // Dummy http client that is not actually used when fetch_command is unsupported. |
| 5328 | | // Prevents bootstrap from depending on a bunch of unnecessary stuff. |
| 5329 | | var http_client: if (dev.env.supports(.fetch_command)) std.http.Client else struct { |
| 5330 | | allocator: Allocator, |
| 5331 | | io: Io, |
| 5332 | | fn deinit(_: @This()) void {} |
| 5333 | | } = .{ .allocator = gpa, .io = io }; |
| 5334 | | defer http_client.deinit(); |
| 5326 | configure_argv.items[conf_argv_index_build_root] = build_root.directory.path orelse cwd_path; |
| 5335 | 5327 | |
| 5336 | | var unlazy_set: Package.Fetch.JobQueue.UnlazySet = .{}; |
| 5337 | | var fork_set: Package.Fetch.JobQueue.ForkSet = .{}; |
| 5328 | // Dummy http client that is not actually used when fetch_command is unsupported. |
| 5329 | // Prevents bootstrap from depending on a bunch of unnecessary stuff. |
| 5330 | var http_client: if (dev.env.supports(.fetch_command)) std.http.Client else struct { |
| 5331 | allocator: Allocator, |
| 5332 | io: Io, |
| 5333 | fn deinit(_: @This()) void {} |
| 5334 | } = .{ .allocator = gpa, .io = io }; |
| 5335 | defer http_client.deinit(); |
| 5338 | 5336 | |
| 5339 | | { |
| 5340 | | // Populate fork_set. |
| 5341 | | var group: Io.Group = .init; |
| 5342 | | defer group.cancel(io); |
| 5343 | | |
| 5344 | | for (forks.items) |*fork| |
| 5345 | | group.async(io, Fork.load, .{ io, gpa, fork, color }); |
| 5346 | | |
| 5347 | | try group.await(io); |
| 5348 | | |
| 5349 | | for (forks.items) |*fork| { |
| 5350 | | if (fork.failed) process.exit(1); |
| 5351 | | try fork_set.put(arena, .{ |
| 5352 | | .path = fork.path, |
| 5353 | | .manifest_ast = fork.manifest_ast, |
| 5354 | | .manifest = fork.manifest, |
| 5355 | | .uses = 0, |
| 5356 | | }, {}); |
| 5357 | | } |
| 5358 | | } |
| 5359 | | defer Fork.deinitList(forks.items); |
| 5337 | var unlazy_set: Package.Fetch.JobQueue.UnlazySet = .{}; |
| 5338 | var fork_set: Package.Fetch.JobQueue.ForkSet = .{}; |
| 5360 | 5339 | |
| 5361 | | // This loop is re-evaluated when the build script exits with an indication that it |
| 5362 | | // could not continue due to missing lazy dependencies. |
| 5363 | | const configuration_path: Path, const poisoned: bool = cp: while (true) { |
| 5364 | | // We want to release all the locks before executing the child process, so we make a nice |
| 5365 | | // big block here to ensure the cleanup gets run when we extract out our argv. |
| 5366 | 5340 | { |
| 5367 | | const main_mod_paths: Package.Module.CreateOptions.Paths = if (override_make_runner) |runner| .{ |
| 5368 | | .root = try .fromUnresolved(arena, dirs, &.{fs.path.dirname(runner) orelse "."}), |
| 5369 | | .root_src_path = fs.path.basename(runner), |
| 5370 | | } else .{ |
| 5371 | | .root = try .fromRoot(arena, dirs, .zig_lib, "compiler"), |
| 5372 | | .root_src_path = "configurer.zig", |
| 5373 | | }; |
| 5341 | // Populate fork_set. |
| 5342 | var group: Io.Group = .init; |
| 5343 | defer group.cancel(io); |
| 5344 | |
| 5345 | for (forks.items) |*fork| |
| 5346 | group.async(io, Fork.load, .{ io, gpa, fork, color }); |
| 5347 | |
| 5348 | try group.await(io); |
| 5349 | |
| 5350 | for (forks.items) |*fork| { |
| 5351 | if (fork.failed) process.exit(1); |
| 5352 | try fork_set.put(arena, .{ |
| 5353 | .path = fork.path, |
| 5354 | .manifest_ast = fork.manifest_ast, |
| 5355 | .manifest = fork.manifest, |
| 5356 | .uses = 0, |
| 5357 | }, {}); |
| 5358 | } |
| 5359 | } |
| 5360 | defer Fork.deinitList(forks.items); |
| 5374 | 5361 | |
| 5375 | | const config = try Compilation.Config.resolve(.{ |
| 5376 | | .output_mode = .Exe, |
| 5377 | | .resolved_target = resolved_target, |
| 5378 | | .have_zcu = true, |
| 5379 | | .emit_bin = true, |
| 5380 | | .is_test = false, |
| 5381 | | }); |
| 5362 | // This loop is re-evaluated when the build script exits with an indication that it |
| 5363 | // could not continue due to missing lazy dependencies. |
| 5364 | const configuration_path: Path, const poisoned: bool = cp: while (true) { |
| 5365 | // We want to release all the locks before executing the child process, so we make a nice |
| 5366 | // big block here to ensure the cleanup gets run when we extract out our argv. |
| 5367 | { |
| 5368 | const main_mod_paths: Package.Module.CreateOptions.Paths = if (override_make_runner) |runner| .{ |
| 5369 | .root = try .fromUnresolved(arena, dirs, &.{fs.path.dirname(runner) orelse "."}), |
| 5370 | .root_src_path = fs.path.basename(runner), |
| 5371 | } else .{ |
| 5372 | .root = try .fromRoot(arena, dirs, .zig_lib, "compiler"), |
| 5373 | .root_src_path = "configurer.zig", |
| 5374 | }; |
| 5382 | 5375 | |
| 5383 | | const root_mod = try Package.Module.create(arena, .{ |
| 5384 | | .paths = main_mod_paths, |
| 5385 | | .fully_qualified_name = "root", |
| 5386 | | .cc_argv = &.{}, |
| 5387 | | .inherited = .{ |
| 5376 | const config = try Compilation.Config.resolve(.{ |
| 5377 | .output_mode = .Exe, |
| 5388 | 5378 | .resolved_target = resolved_target, |
| 5389 | | .single_threaded = true, |
| 5390 | | }, |
| 5391 | | .global = config, |
| 5392 | | .parent = null, |
| 5393 | | }); |
| 5379 | .have_zcu = true, |
| 5380 | .emit_bin = true, |
| 5381 | .is_test = false, |
| 5382 | }); |
| 5394 | 5383 | |
| 5395 | | const build_mod = try Package.Module.create(arena, .{ |
| 5396 | | .paths = .{ |
| 5397 | | .root = try .fromUnresolved(arena, dirs, &.{build_root.directory.path orelse "."}), |
| 5398 | | .root_src_path = build_root.build_zig_basename, |
| 5399 | | }, |
| 5400 | | .fully_qualified_name = "root.@build", |
| 5401 | | .cc_argv = &.{}, |
| 5402 | | .inherited = .{}, |
| 5403 | | .global = config, |
| 5404 | | .parent = root_mod, |
| 5405 | | }); |
| 5384 | const root_mod = try Package.Module.create(arena, .{ |
| 5385 | .paths = main_mod_paths, |
| 5386 | .fully_qualified_name = "root", |
| 5387 | .cc_argv = &.{}, |
| 5388 | .inherited = .{ |
| 5389 | .resolved_target = resolved_target, |
| 5390 | .single_threaded = true, |
| 5391 | }, |
| 5392 | .global = config, |
| 5393 | .parent = null, |
| 5394 | }); |
| 5406 | 5395 | |
| 5407 | | if (dev.env.supports(.fetch_command)) { |
| 5408 | | const fetch_prog_node = root_prog_node.start("Fetch Packages", 0); |
| 5409 | | defer fetch_prog_node.end(); |
| 5396 | const build_mod = try Package.Module.create(arena, .{ |
| 5397 | .paths = .{ |
| 5398 | .root = try .fromUnresolved(arena, dirs, &.{build_root.directory.path orelse "."}), |
| 5399 | .root_src_path = build_root.build_zig_basename, |
| 5400 | }, |
| 5401 | .fully_qualified_name = "root.@build", |
| 5402 | .cc_argv = &.{}, |
| 5403 | .inherited = .{}, |
| 5404 | .global = config, |
| 5405 | .parent = root_mod, |
| 5406 | }); |
| 5410 | 5407 | |
| 5411 | | // Reset fork match counts. |
| 5412 | | for (fork_set.keys()) |*fork| fork.uses = 0; |
| 5408 | if (dev.env.supports(.fetch_command)) { |
| 5409 | const fetch_prog_node = root_prog_node.start("Fetch Packages", 0); |
| 5410 | defer fetch_prog_node.end(); |
| 5413 | 5411 | |
| 5414 | | var job_queue: Package.Fetch.JobQueue = .{ |
| 5415 | | .io = io, |
| 5416 | | .http_client = &http_client, |
| 5417 | | .global_cache = dirs.global_cache, |
| 5418 | | .local_storage = &.{ |
| 5419 | | .cache_root = .{ .root_dir = dirs.local_cache, .sub_path = "" }, |
| 5420 | | .pkg_root = pkg_root, |
| 5421 | | }, |
| 5422 | | .recursive = true, |
| 5423 | | .debug_hash = false, |
| 5424 | | .unlazy_set = unlazy_set, |
| 5425 | | .fork_set = fork_set, |
| 5426 | | .mode = fetch_mode, |
| 5427 | | .prog_node = fetch_prog_node, |
| 5428 | | .read_only = system_pkg_dir_path != null, |
| 5429 | | }; |
| 5430 | | defer job_queue.deinit(); |
| 5412 | // Reset fork match counts. |
| 5413 | for (fork_set.keys()) |*fork| fork.uses = 0; |
| 5431 | 5414 | |
| 5432 | | if (system_pkg_dir_path == null) { |
| 5433 | | try http_client.initDefaultProxies(arena, environ_map); |
| 5434 | | } |
| 5415 | var job_queue: Package.Fetch.JobQueue = .{ |
| 5416 | .io = io, |
| 5417 | .http_client = &http_client, |
| 5418 | .global_cache = dirs.global_cache, |
| 5419 | .local_storage = &.{ |
| 5420 | .cache_root = .{ .root_dir = dirs.local_cache, .sub_path = "" }, |
| 5421 | .pkg_root = pkg_root, |
| 5422 | }, |
| 5423 | .recursive = true, |
| 5424 | .debug_hash = false, |
| 5425 | .unlazy_set = unlazy_set, |
| 5426 | .fork_set = fork_set, |
| 5427 | .mode = fetch_mode, |
| 5428 | .prog_node = fetch_prog_node, |
| 5429 | .read_only = system_pkg_dir_path != null, |
| 5430 | }; |
| 5431 | defer job_queue.deinit(); |
| 5435 | 5432 | |
| 5436 | | try job_queue.all_fetches.ensureUnusedCapacity(gpa, 1); |
| 5437 | | try job_queue.table.ensureUnusedCapacity(gpa, 1); |
| 5438 | | |
| 5439 | | const phantom_package_root: Cache.Path = .{ .root_dir = build_root.directory }; |
| 5440 | | |
| 5441 | | var fetch: Package.Fetch = .{ |
| 5442 | | .arena = std.heap.ArenaAllocator.init(gpa), |
| 5443 | | .location = .{ .relative_path = phantom_package_root }, |
| 5444 | | .location_tok = 0, |
| 5445 | | .hash_tok = .none, |
| 5446 | | .name_tok = 0, |
| 5447 | | .lazy_status = .eager, |
| 5448 | | .remote_package_root = phantom_package_root, |
| 5449 | | .parent_package_root = phantom_package_root, |
| 5450 | | .parent_manifest_ast = null, |
| 5451 | | .prog_node = fetch_prog_node, |
| 5452 | | .job_queue = &job_queue, |
| 5453 | | .omit_missing_hash_error = true, |
| 5454 | | .allow_missing_paths_field = false, |
| 5455 | | .use_latest_commit = false, |
| 5456 | | |
| 5457 | | .package_root = undefined, |
| 5458 | | .error_bundle = undefined, |
| 5459 | | .manifest = undefined, |
| 5460 | | .manifest_ast = undefined, |
| 5461 | | .have_manifest = false, |
| 5462 | | .computed_hash = undefined, |
| 5463 | | .has_build_zig = true, |
| 5464 | | .oom_flag = false, |
| 5465 | | .latest_commit = null, |
| 5466 | | |
| 5467 | | .module = build_mod, |
| 5468 | | }; |
| 5433 | if (system_pkg_dir_path == null) { |
| 5434 | try http_client.initDefaultProxies(arena, environ_map); |
| 5435 | } |
| 5469 | 5436 | |
| 5470 | | job_queue.all_fetches.appendAssumeCapacity(&fetch); |
| 5437 | try job_queue.all_fetches.ensureUnusedCapacity(gpa, 1); |
| 5438 | try job_queue.table.ensureUnusedCapacity(gpa, 1); |
| 5439 | |
| 5440 | const phantom_package_root: Cache.Path = .{ .root_dir = build_root.directory }; |
| 5441 | |
| 5442 | var fetch: Package.Fetch = .{ |
| 5443 | .arena = std.heap.ArenaAllocator.init(gpa), |
| 5444 | .location = .{ .relative_path = phantom_package_root }, |
| 5445 | .location_tok = 0, |
| 5446 | .hash_tok = .none, |
| 5447 | .name_tok = 0, |
| 5448 | .lazy_status = .eager, |
| 5449 | .remote_package_root = phantom_package_root, |
| 5450 | .parent_package_root = phantom_package_root, |
| 5451 | .parent_manifest_ast = null, |
| 5452 | .prog_node = fetch_prog_node, |
| 5453 | .job_queue = &job_queue, |
| 5454 | .omit_missing_hash_error = true, |
| 5455 | .allow_missing_paths_field = false, |
| 5456 | .use_latest_commit = false, |
| 5457 | |
| 5458 | .package_root = undefined, |
| 5459 | .error_bundle = undefined, |
| 5460 | .manifest = undefined, |
| 5461 | .manifest_ast = undefined, |
| 5462 | .have_manifest = false, |
| 5463 | .computed_hash = undefined, |
| 5464 | .has_build_zig = true, |
| 5465 | .oom_flag = false, |
| 5466 | .latest_commit = null, |
| 5467 | |
| 5468 | .module = build_mod, |
| 5469 | }; |
| 5471 | 5470 | |
| 5472 | | job_queue.table.putAssumeCapacityNoClobber( |
| 5473 | | Package.Fetch.relativePathDigest(phantom_package_root, dirs.global_cache), |
| 5474 | | &fetch, |
| 5475 | | ); |
| 5471 | job_queue.all_fetches.appendAssumeCapacity(&fetch); |
| 5476 | 5472 | |
| 5477 | | job_queue.group.async(io, Package.Fetch.workerRun, .{ &fetch, "root" }); |
| 5478 | | try job_queue.group.await(io); |
| 5473 | job_queue.table.putAssumeCapacityNoClobber( |
| 5474 | Package.Fetch.relativePathDigest(phantom_package_root, dirs.global_cache), |
| 5475 | &fetch, |
| 5476 | ); |
| 5479 | 5477 | |
| 5480 | | { |
| 5481 | | // Ensure that forks were actually used. This is done |
| 5482 | | // before printing manifest errors because using a fork can |
| 5483 | | // prevent them. |
| 5484 | | var any_unused = false; |
| 5485 | | for (fork_set.keys()) |*fork| { |
| 5486 | | if (fork.uses == 0) { |
| 5487 | | std.log.err("fork {f} matched no {s} packages", .{ |
| 5488 | | fork.path, fork.manifest.name, |
| 5489 | | }); |
| 5490 | | any_unused = true; |
| 5491 | | } else { |
| 5492 | | std.log.info("fork {f} matched {d} {s} packages", .{ |
| 5493 | | fork.path, fork.uses, fork.manifest.name, |
| 5494 | | }); |
| 5478 | job_queue.group.async(io, Package.Fetch.workerRun, .{ &fetch, "root" }); |
| 5479 | try job_queue.group.await(io); |
| 5480 | |
| 5481 | { |
| 5482 | // Ensure that forks were actually used. This is done |
| 5483 | // before printing manifest errors because using a fork can |
| 5484 | // prevent them. |
| 5485 | var any_unused = false; |
| 5486 | for (fork_set.keys()) |*fork| { |
| 5487 | if (fork.uses == 0) { |
| 5488 | std.log.err("fork {f} matched no {s} packages", .{ |
| 5489 | fork.path, fork.manifest.name, |
| 5490 | }); |
| 5491 | any_unused = true; |
| 5492 | } else { |
| 5493 | std.log.info("fork {f} matched {d} {s} packages", .{ |
| 5494 | fork.path, fork.uses, fork.manifest.name, |
| 5495 | }); |
| 5496 | } |
| 5495 | 5497 | } |
| 5498 | if (any_unused) process.exit(1); |
| 5496 | 5499 | } |
| 5497 | | if (any_unused) process.exit(1); |
| 5498 | | } |
| 5499 | 5500 | |
| 5500 | | try job_queue.consolidateErrors(); |
| 5501 | try job_queue.consolidateErrors(); |
| 5501 | 5502 | |
| 5502 | | if (fetch.error_bundle.root_list.items.len > 0) { |
| 5503 | | var errors = try fetch.error_bundle.toOwnedBundle(""); |
| 5504 | | errors.renderToStderr(io, .{}, color) catch {}; |
| 5505 | | process.exit(1); |
| 5506 | | } |
| 5503 | if (fetch.error_bundle.root_list.items.len > 0) { |
| 5504 | var errors = try fetch.error_bundle.toOwnedBundle(""); |
| 5505 | errors.renderToStderr(io, .{}, color) catch {}; |
| 5506 | process.exit(1); |
| 5507 | } |
| 5507 | 5508 | |
| 5508 | | if (fetch_only) return cleanExit(io); |
| 5509 | if (fetch_only) return cleanExit(io); |
| 5510 | |
| 5511 | var source_buf = std.array_list.Managed(u8).init(gpa); |
| 5512 | defer source_buf.deinit(); |
| 5513 | try job_queue.createDependenciesSource(&source_buf); |
| 5514 | const deps_mod = try createDependenciesModule( |
| 5515 | arena, |
| 5516 | io, |
| 5517 | source_buf.items, |
| 5518 | root_mod, |
| 5519 | dirs, |
| 5520 | config, |
| 5521 | ); |
| 5522 | |
| 5523 | { |
| 5524 | // We need a Module for each package's build.zig. |
| 5525 | const hashes = job_queue.table.keys(); |
| 5526 | const fetches = job_queue.table.values(); |
| 5527 | try deps_mod.deps.ensureUnusedCapacity(arena, @intCast(hashes.len)); |
| 5528 | for (hashes, fetches) |*hash, f| { |
| 5529 | if (f == &fetch) { |
| 5530 | // The first one is a dummy package for the current project. |
| 5531 | continue; |
| 5532 | } |
| 5533 | if (!f.has_build_zig) |
| 5534 | continue; |
| 5535 | const hash_slice = hash.toSlice(); |
| 5536 | const mod_root_path = try f.package_root.toString(arena); |
| 5537 | const m = try Package.Module.create(arena, .{ |
| 5538 | .paths = .{ |
| 5539 | .root = try .fromUnresolved(arena, dirs, &.{mod_root_path}), |
| 5540 | .root_src_path = Package.build_zig_basename, |
| 5541 | }, |
| 5542 | .fully_qualified_name = try std.fmt.allocPrint( |
| 5543 | arena, |
| 5544 | "root.@dependencies.{s}", |
| 5545 | .{hash_slice}, |
| 5546 | ), |
| 5547 | .cc_argv = &.{}, |
| 5548 | .inherited = .{}, |
| 5549 | .global = config, |
| 5550 | .parent = root_mod, |
| 5551 | }); |
| 5552 | const hash_cloned = try arena.dupe(u8, hash_slice); |
| 5553 | deps_mod.deps.putAssumeCapacityNoClobber(hash_cloned, m); |
| 5554 | f.module = m; |
| 5555 | } |
| 5509 | 5556 | |
| 5510 | | var source_buf = std.array_list.Managed(u8).init(gpa); |
| 5511 | | defer source_buf.deinit(); |
| 5512 | | try job_queue.createDependenciesSource(&source_buf); |
| 5513 | | const deps_mod = try createDependenciesModule( |
| 5557 | // Each build.zig module needs access to each of its |
| 5558 | // dependencies' build.zig modules by name. |
| 5559 | for (fetches) |f| { |
| 5560 | const mod = f.module orelse continue; |
| 5561 | if (!f.have_manifest) continue; |
| 5562 | const man = &f.manifest; |
| 5563 | const dep_names = man.dependencies.keys(); |
| 5564 | try mod.deps.ensureUnusedCapacity(arena, @intCast(dep_names.len)); |
| 5565 | for (dep_names, man.dependencies.values()) |name, dep| { |
| 5566 | const dep_digest = Package.Fetch.depDigest( |
| 5567 | f.package_root, |
| 5568 | dirs.global_cache, |
| 5569 | dep, |
| 5570 | ) orelse continue; |
| 5571 | const dep_mod = job_queue.table.get(dep_digest).?.module orelse continue; |
| 5572 | const name_cloned = try arena.dupe(u8, name); |
| 5573 | mod.deps.putAssumeCapacityNoClobber(name_cloned, dep_mod); |
| 5574 | } |
| 5575 | } |
| 5576 | } |
| 5577 | } else try createEmptyDependenciesModule( |
| 5514 | 5578 | arena, |
| 5515 | 5579 | io, |
| 5516 | | source_buf.items, |
| 5517 | 5580 | root_mod, |
| 5518 | 5581 | dirs, |
| 5519 | 5582 | config, |
| 5520 | 5583 | ); |
| 5521 | 5584 | |
| 5522 | | { |
| 5523 | | // We need a Module for each package's build.zig. |
| 5524 | | const hashes = job_queue.table.keys(); |
| 5525 | | const fetches = job_queue.table.values(); |
| 5526 | | try deps_mod.deps.ensureUnusedCapacity(arena, @intCast(hashes.len)); |
| 5527 | | for (hashes, fetches) |*hash, f| { |
| 5528 | | if (f == &fetch) { |
| 5529 | | // The first one is a dummy package for the current project. |
| 5530 | | continue; |
| 5531 | | } |
| 5532 | | if (!f.has_build_zig) |
| 5533 | | continue; |
| 5534 | | const hash_slice = hash.toSlice(); |
| 5535 | | const mod_root_path = try f.package_root.toString(arena); |
| 5536 | | const m = try Package.Module.create(arena, .{ |
| 5537 | | .paths = .{ |
| 5538 | | .root = try .fromUnresolved(arena, dirs, &.{mod_root_path}), |
| 5539 | | .root_src_path = Package.build_zig_basename, |
| 5540 | | }, |
| 5541 | | .fully_qualified_name = try std.fmt.allocPrint( |
| 5542 | | arena, |
| 5543 | | "root.@dependencies.{s}", |
| 5544 | | .{hash_slice}, |
| 5545 | | ), |
| 5546 | | .cc_argv = &.{}, |
| 5547 | | .inherited = .{}, |
| 5548 | | .global = config, |
| 5549 | | .parent = root_mod, |
| 5550 | | }); |
| 5551 | | const hash_cloned = try arena.dupe(u8, hash_slice); |
| 5552 | | deps_mod.deps.putAssumeCapacityNoClobber(hash_cloned, m); |
| 5553 | | f.module = m; |
| 5554 | | } |
| 5585 | const compile_prog_node = root_prog_node.start("Compile Configure Script", 0); |
| 5586 | defer compile_prog_node.end(); |
| 5587 | |
| 5588 | try root_mod.deps.put(arena, "@build", build_mod); |
| 5589 | |
| 5590 | var create_diag: Compilation.CreateDiagnostic = undefined; |
| 5591 | const comp = Compilation.create(gpa, arena, io, &create_diag, .{ |
| 5592 | .libc_installation = libc_installation, |
| 5593 | .dirs = dirs, |
| 5594 | .root_name = "configure", |
| 5595 | .config = config, |
| 5596 | .root_mod = root_mod, |
| 5597 | .main_mod = build_mod, |
| 5598 | .emit_bin = .yes_cache, |
| 5599 | .self_exe_path = self_exe_path, |
| 5600 | .thread_limit = thread_limit, |
| 5601 | .verbose_cc = verbose_cc, |
| 5602 | .verbose_link = verbose_link, |
| 5603 | .verbose_air = verbose_air, |
| 5604 | .verbose_intern_pool = verbose_intern_pool, |
| 5605 | .verbose_generic_instances = verbose_generic_instances, |
| 5606 | .verbose_llvm_ir = verbose_llvm_ir, |
| 5607 | .verbose_llvm_bc = verbose_llvm_bc, |
| 5608 | .verbose_llvm_cpu_features = verbose_llvm_cpu_features, |
| 5609 | .cache_mode = .whole, |
| 5610 | .reference_trace = reference_trace, |
| 5611 | .debug_compile_errors = debug_compile_errors, |
| 5612 | .environ_map = environ_map, |
| 5613 | }) catch |err| switch (err) { |
| 5614 | error.CreateFail => fatal("failed to create compilation: {f}", .{create_diag}), |
| 5615 | else => |e| fatal("failed to create compilation: {t}", .{e}), |
| 5616 | }; |
| 5617 | defer comp.destroy(); |
| 5555 | 5618 | |
| 5556 | | // Each build.zig module needs access to each of its |
| 5557 | | // dependencies' build.zig modules by name. |
| 5558 | | for (fetches) |f| { |
| 5559 | | const mod = f.module orelse continue; |
| 5560 | | if (!f.have_manifest) continue; |
| 5561 | | const man = &f.manifest; |
| 5562 | | const dep_names = man.dependencies.keys(); |
| 5563 | | try mod.deps.ensureUnusedCapacity(arena, @intCast(dep_names.len)); |
| 5564 | | for (dep_names, man.dependencies.values()) |name, dep| { |
| 5565 | | const dep_digest = Package.Fetch.depDigest( |
| 5566 | | f.package_root, |
| 5567 | | dirs.global_cache, |
| 5568 | | dep, |
| 5569 | | ) orelse continue; |
| 5570 | | const dep_mod = job_queue.table.get(dep_digest).?.module orelse continue; |
| 5571 | | const name_cloned = try arena.dupe(u8, name); |
| 5572 | | mod.deps.putAssumeCapacityNoClobber(name_cloned, dep_mod); |
| 5573 | | } |
| 5574 | | } |
| 5575 | | } |
| 5576 | | } else try createEmptyDependenciesModule( |
| 5577 | | arena, |
| 5578 | | io, |
| 5579 | | root_mod, |
| 5580 | | dirs, |
| 5581 | | config, |
| 5582 | | ); |
| 5619 | updateModule(comp, color, compile_prog_node) catch |err| switch (err) { |
| 5620 | error.CompileErrorsReported => process.exit(2), |
| 5621 | else => |e| return e, |
| 5622 | }; |
| 5583 | 5623 | |
| 5584 | | const compile_prog_node = root_prog_node.start("Compile Configure Script", 0); |
| 5585 | | defer compile_prog_node.end(); |
| 5586 | | |
| 5587 | | try root_mod.deps.put(arena, "@build", build_mod); |
| 5588 | | |
| 5589 | | var create_diag: Compilation.CreateDiagnostic = undefined; |
| 5590 | | const comp = Compilation.create(gpa, arena, io, &create_diag, .{ |
| 5591 | | .libc_installation = libc_installation, |
| 5592 | | .dirs = dirs, |
| 5593 | | .root_name = "configure", |
| 5594 | | .config = config, |
| 5595 | | .root_mod = root_mod, |
| 5596 | | .main_mod = build_mod, |
| 5597 | | .emit_bin = .yes_cache, |
| 5598 | | .self_exe_path = self_exe_path, |
| 5599 | | .thread_limit = thread_limit, |
| 5600 | | .verbose_cc = verbose_cc, |
| 5601 | | .verbose_link = verbose_link, |
| 5602 | | .verbose_air = verbose_air, |
| 5603 | | .verbose_intern_pool = verbose_intern_pool, |
| 5604 | | .verbose_generic_instances = verbose_generic_instances, |
| 5605 | | .verbose_llvm_ir = verbose_llvm_ir, |
| 5606 | | .verbose_llvm_bc = verbose_llvm_bc, |
| 5607 | | .verbose_llvm_cpu_features = verbose_llvm_cpu_features, |
| 5608 | | .cache_mode = .whole, |
| 5609 | | .reference_trace = reference_trace, |
| 5610 | | .debug_compile_errors = debug_compile_errors, |
| 5611 | | .environ_map = environ_map, |
| 5612 | | }) catch |err| switch (err) { |
| 5613 | | error.CreateFail => fatal("failed to create compilation: {f}", .{create_diag}), |
| 5614 | | else => |e| fatal("failed to create compilation: {t}", .{e}), |
| 5615 | | }; |
| 5616 | | defer comp.destroy(); |
| 5624 | // Since incremental compilation isn't done yet, we use cache_mode = whole |
| 5625 | // above, and thus the output file is already closed. |
| 5626 | //try comp.makeBinFileExecutable(); |
| 5627 | const hex_digest: []const u8 = &Cache.binToHex(comp.digest.?); |
| 5628 | const exe_path: Path = .{ |
| 5629 | .root_dir = dirs.local_cache, |
| 5630 | .sub_path = try std.fmt.allocPrint(arena, "o/{s}/{s}", .{ hex_digest, comp.emit_bin.? }), |
| 5631 | }; |
| 5632 | _ = try config_man.addFilePath(exe_path, null); |
| 5633 | configure_argv.items[0] = try exe_path.toString(arena); |
| 5634 | |
| 5635 | switch (cache_poison) { |
| 5636 | .pure, .disallowed, .ignored => if (try config_man.hit()) { |
| 5637 | const digest = config_man.final(); |
| 5638 | break :cp .{ |
| 5639 | .{ |
| 5640 | .root_dir = dirs.local_cache, |
| 5641 | .sub_path = try std.fmt.allocPrint(arena, "o/{s}", .{&digest}), |
| 5642 | }, |
| 5643 | false, |
| 5644 | }; |
| 5645 | }, |
| 5646 | .poisoned => {}, // Don't bother checking for cache hit. |
| 5647 | } |
| 5648 | } |
| 5617 | 5649 | |
| 5618 | | updateModule(comp, color, compile_prog_node) catch |err| switch (err) { |
| 5619 | | error.CompileErrorsReported => process.exit(2), |
| 5620 | | else => |e| return e, |
| 5621 | | }; |
| 5650 | if (!process.can_spawn) { |
| 5651 | const cmd = try std.mem.join(arena, " ", configure_argv.items); |
| 5652 | fatal("the following command cannot be executed ({t} does not support spawning a child process):\n{s}", .{ native_os, cmd }); |
| 5653 | } |
| 5622 | 5654 | |
| 5623 | | // Since incremental compilation isn't done yet, we use cache_mode = whole |
| 5624 | | // above, and thus the output file is already closed. |
| 5625 | | //try comp.makeBinFileExecutable(); |
| 5626 | | const hex_digest: []const u8 = &Cache.binToHex(comp.digest.?); |
| 5627 | | const exe_path: Path = .{ |
| 5655 | const rand_int = randInt(io, u64); |
| 5656 | const tmp_dir_sub_path = "tmp" ++ fs.path.sep_str ++ std.fmt.hex(rand_int); |
| 5657 | const config_tmp_path: Path = .{ |
| 5628 | 5658 | .root_dir = dirs.local_cache, |
| 5629 | | .sub_path = try std.fmt.allocPrint(arena, "o/{s}/{s}", .{ hex_digest, comp.emit_bin.? }), |
| 5659 | .sub_path = tmp_dir_sub_path, |
| 5630 | 5660 | }; |
| 5631 | | _ = try config_man.addFilePath(exe_path, null); |
| 5632 | | configure_argv.items[0] = try exe_path.toString(arena); |
| 5633 | | |
| 5634 | | switch (cache_poison) { |
| 5635 | | .pure, .disallowed, .ignored => if (try config_man.hit()) { |
| 5636 | | const digest = config_man.final(); |
| 5637 | | break :cp .{ |
| 5638 | | .{ |
| 5639 | | .root_dir = dirs.local_cache, |
| 5640 | | .sub_path = try std.fmt.allocPrint(arena, "o/{s}", .{&digest}), |
| 5641 | | }, |
| 5642 | | false, |
| 5643 | | }; |
| 5644 | | }, |
| 5645 | | .poisoned => {}, // Don't bother checking for cache hit. |
| 5661 | const config_tmp_file: Io.File = try config_tmp_path.root_dir.handle.createFile( |
| 5662 | io, |
| 5663 | config_tmp_path.sub_path, |
| 5664 | .{ .read = true, .exclusive = true }, |
| 5665 | ); |
| 5666 | defer config_tmp_file.close(io); |
| 5667 | |
| 5668 | const term = term: { |
| 5669 | const child_node = root_prog_node.start("Run Configure Script", 0); |
| 5670 | defer child_node.end(); |
| 5671 | var child = std.process.spawn(io, .{ |
| 5672 | .argv = configure_argv.items, |
| 5673 | .stdout = .{ .file = config_tmp_file }, |
| 5674 | .progress_node = child_node, |
| 5675 | }) catch |err| fatal("failed to spawn configure script {s}: {t}", .{ configure_argv.items[0], err }); |
| 5676 | defer child.kill(io); |
| 5677 | break :term child.wait(io) catch |err| |
| 5678 | fatal("failed to wait configure script {s}: {t}", .{ configure_argv.items[0], err }); |
| 5679 | }; |
| 5680 | if (!term.success()) { |
| 5681 | // Failure to produce the configuration file. |
| 5682 | const cmd = try std.mem.join(arena, " ", configure_argv.items); |
| 5683 | fatal("the following configure command {f}:\n{s}", .{ term, cmd }); |
| 5646 | 5684 | } |
| 5647 | | } |
| 5648 | | |
| 5649 | | if (!process.can_spawn) { |
| 5650 | | const cmd = try std.mem.join(arena, " ", configure_argv.items); |
| 5651 | | fatal("the following command cannot be executed ({t} does not support spawning a child process):\n{s}", .{ native_os, cmd }); |
| 5652 | | } |
| 5653 | | |
| 5654 | | const rand_int = randInt(io, u64); |
| 5655 | | const tmp_dir_sub_path = "tmp" ++ fs.path.sep_str ++ std.fmt.hex(rand_int); |
| 5656 | | const config_tmp_path: Path = .{ |
| 5657 | | .root_dir = dirs.local_cache, |
| 5658 | | .sub_path = tmp_dir_sub_path, |
| 5659 | | }; |
| 5660 | | const config_tmp_file: Io.File = try config_tmp_path.root_dir.handle.createFile( |
| 5661 | | io, |
| 5662 | | config_tmp_path.sub_path, |
| 5663 | | .{ .read = true, .exclusive = true }, |
| 5664 | | ); |
| 5665 | | defer config_tmp_file.close(io); |
| 5666 | | |
| 5667 | | const term = term: { |
| 5668 | | const child_node = root_prog_node.start("Run Configure Script", 0); |
| 5669 | | defer child_node.end(); |
| 5670 | | var child = std.process.spawn(io, .{ |
| 5671 | | .argv = configure_argv.items, |
| 5672 | | .stdout = .{ .file = config_tmp_file }, |
| 5673 | | .progress_node = child_node, |
| 5674 | | }) catch |err| fatal("failed to spawn configure script {s}: {t}", .{ configure_argv.items[0], err }); |
| 5675 | | defer child.kill(io); |
| 5676 | | break :term child.wait(io) catch |err| |
| 5677 | | fatal("failed to wait configure script {s}: {t}", .{ configure_argv.items[0], err }); |
| 5678 | | }; |
| 5679 | | if (!term.success()) { |
| 5680 | | // Failure to produce the configuration file. |
| 5681 | | const cmd = try std.mem.join(arena, " ", configure_argv.items); |
| 5682 | | fatal("the following configure command {f}:\n{s}", .{ term, cmd }); |
| 5683 | | } |
| 5684 | | // Even though the file is designed to be sent directly to make |
| 5685 | | // runner, we must load it now because: |
| 5686 | | // * If it contains additional file dependencies, we need to |
| 5687 | | // add them to `config_man` before obtaining the final digest. |
| 5688 | | // * If it contains a set of lazy packages that need to be |
| 5689 | | // fetched, we need to fetch those now and re-run configure. |
| 5690 | | var configuration = std.Build.Configuration.loadFile(arena, io, config_tmp_file) catch |err| |
| 5691 | | fatal("failed to load configuration file {f}: {t}", .{ config_tmp_path, err }); |
| 5692 | | |
| 5693 | | if (configuration.unlazy_deps.len != 0) { |
| 5694 | | if (!dev.env.supports(.fetch_command)) process.exit(1); |
| 5695 | | var any_errors = false; |
| 5696 | | for (configuration.unlazy_deps) |hash_string| { |
| 5697 | | const hash = hash_string.slice(&configuration); |
| 5698 | | assert(hash.len != 0); |
| 5699 | | if (hash.len > Package.Hash.max_len) { |
| 5700 | | std.log.err("invalid digest (length {d} exceeds maximum): '{s}'", .{ hash.len, hash }); |
| 5701 | | any_errors = true; |
| 5702 | | continue; |
| 5685 | // Even though the file is designed to be sent directly to make |
| 5686 | // runner, we must load it now because: |
| 5687 | // * If it contains additional file dependencies, we need to |
| 5688 | // add them to `config_man` before obtaining the final digest. |
| 5689 | // * If it contains a set of lazy packages that need to be |
| 5690 | // fetched, we need to fetch those now and re-run configure. |
| 5691 | var configuration = std.Build.Configuration.loadFile(arena, io, config_tmp_file) catch |err| |
| 5692 | fatal("failed to load configuration file {f}: {t}", .{ config_tmp_path, err }); |
| 5693 | |
| 5694 | if (configuration.unlazy_deps.len != 0) { |
| 5695 | if (!dev.env.supports(.fetch_command)) process.exit(1); |
| 5696 | var any_errors = false; |
| 5697 | for (configuration.unlazy_deps) |hash_string| { |
| 5698 | const hash = hash_string.slice(&configuration); |
| 5699 | assert(hash.len != 0); |
| 5700 | if (hash.len > Package.Hash.max_len) { |
| 5701 | std.log.err("invalid digest (length {d} exceeds maximum): '{s}'", .{ hash.len, hash }); |
| 5702 | any_errors = true; |
| 5703 | continue; |
| 5704 | } |
| 5705 | try unlazy_set.put(arena, .fromSlice(hash), {}); |
| 5703 | 5706 | } |
| 5704 | | try unlazy_set.put(arena, .fromSlice(hash), {}); |
| 5705 | | } |
| 5706 | | if (any_errors) process.exit(1); |
| 5707 | | if (system_pkg_dir_path) |p| { |
| 5708 | | // In this mode, the system needs to provide these packages; they |
| 5709 | | // cannot be fetched by Zig. |
| 5710 | | const s = fs.path.sep_str; |
| 5711 | | for (unlazy_set.keys()) |*hash| { |
| 5712 | | std.log.err("lazy dependency package not found: {s}" ++ s ++ "{s}", .{ p, hash.toSlice() }); |
| 5707 | if (any_errors) process.exit(1); |
| 5708 | if (system_pkg_dir_path) |p| { |
| 5709 | // In this mode, the system needs to provide these packages; they |
| 5710 | // cannot be fetched by Zig. |
| 5711 | const s = fs.path.sep_str; |
| 5712 | for (unlazy_set.keys()) |*hash| { |
| 5713 | std.log.err("lazy dependency package not found: {s}" ++ s ++ "{s}", .{ p, hash.toSlice() }); |
| 5714 | } |
| 5715 | std.log.info("remote package fetching disabled due to --system mode", .{}); |
| 5716 | std.log.info("dependencies might be avoidable depending on build configuration", .{}); |
| 5717 | process.exit(1); |
| 5713 | 5718 | } |
| 5714 | | std.log.info("remote package fetching disabled due to --system mode", .{}); |
| 5715 | | std.log.info("dependencies might be avoidable depending on build configuration", .{}); |
| 5716 | | process.exit(1); |
| 5719 | continue :cp; |
| 5717 | 5720 | } |
| 5718 | | continue :cp; |
| 5719 | | } |
| 5720 | 5721 | |
| 5721 | | for (configuration.path_deps_base, configuration.path_deps_sub) |base, sub| { |
| 5722 | | const conf_path: std.Build.Configuration.Path = .{ .base = base, .sub = sub }; |
| 5723 | | try config_man.addPathPost(conf_path.toCachePath(&configuration, arena)); |
| 5724 | | } |
| 5722 | for (configuration.path_deps_base, configuration.path_deps_sub) |base, sub| { |
| 5723 | const conf_path: std.Build.Configuration.Path = .{ .base = base, .sub = sub }; |
| 5724 | try config_man.addPathPost(conf_path.toCachePath(&configuration, arena)); |
| 5725 | } |
| 5725 | 5726 | |
| 5726 | | // If it is poisoned, there is no point in moving it to cached |
| 5727 | | // location. Just leave it in the tmp directory. |
| 5728 | | if (configuration.poisoned) { |
| 5729 | | break :cp .{ config_tmp_path, true }; |
| 5730 | | } else { |
| 5731 | | const digest = config_man.final(); |
| 5732 | | const final_path: Path = .{ |
| 5733 | | .root_dir = dirs.local_cache, |
| 5734 | | .sub_path = try std.fmt.allocPrint(arena, "o/{s}", .{&digest}), |
| 5735 | | }; |
| 5736 | | Io.Dir.rename( |
| 5737 | | config_tmp_path.root_dir.handle, |
| 5738 | | config_tmp_path.sub_path, |
| 5739 | | final_path.root_dir.handle, |
| 5740 | | final_path.sub_path, |
| 5741 | | io, |
| 5742 | | ) catch |err| { |
| 5743 | | fatal("failed to rename configuration file from {f} into {f}: {t}", .{ |
| 5744 | | config_tmp_path, final_path, err, |
| 5745 | | }); |
| 5746 | | }; |
| 5747 | | config_man.writeManifest() catch |err| warn("failed to write cache manifest: {t}", .{err}); |
| 5748 | | break :cp .{ final_path, false }; |
| 5749 | | } |
| 5750 | | }; |
| 5727 | // If it is poisoned, there is no point in moving it to cached |
| 5728 | // location. Just leave it in the tmp directory. |
| 5729 | if (configuration.poisoned) { |
| 5730 | break :cp .{ config_tmp_path, true }; |
| 5731 | } else { |
| 5732 | const digest = config_man.final(); |
| 5733 | const final_path: Path = .{ |
| 5734 | .root_dir = dirs.local_cache, |
| 5735 | .sub_path = try std.fmt.allocPrint(arena, "o/{s}", .{&digest}), |
| 5736 | }; |
| 5737 | Io.Dir.rename( |
| 5738 | config_tmp_path.root_dir.handle, |
| 5739 | config_tmp_path.sub_path, |
| 5740 | final_path.root_dir.handle, |
| 5741 | final_path.sub_path, |
| 5742 | io, |
| 5743 | ) catch |err| { |
| 5744 | fatal("failed to rename configuration file from {f} into {f}: {t}", .{ |
| 5745 | config_tmp_path, final_path, err, |
| 5746 | }); |
| 5747 | }; |
| 5748 | config_man.writeManifest() catch |err| warn("failed to write cache manifest: {t}", .{err}); |
| 5749 | break :cp .{ final_path, false }; |
| 5750 | } |
| 5751 | }; |
| 5751 | 5752 | |
| 5752 | | { |
| 5753 | | // Release all file system locks just before running the maker process. |
| 5754 | | var configuration_lock = if (!poisoned) config_man.toOwnedLock() else null; |
| 5755 | | defer if (configuration_lock) |*l| l.release(io); |
| 5753 | { |
| 5754 | // Release all file system locks just before running the maker process. |
| 5755 | var configuration_lock = if (!poisoned) config_man.toOwnedLock() else null; |
| 5756 | defer if (configuration_lock) |*l| l.release(io); |
| 5756 | 5757 | |
| 5757 | | const make_runner = make_runner_task.await(io) catch |err| fatal("failed compiling maker: {t}", .{err}); |
| 5758 | const make_runner = make_runner_task.await(io) catch |err| fatal("failed compiling maker: {t}", .{err}); |
| 5758 | 5759 | |
| 5759 | | make_argv.items[0] = try make_runner.exe_path.toString(arena); |
| 5760 | | make_argv.items[argv_index_configuration_file] = try configuration_path.toString(arena); |
| 5760 | make_argv.items[0] = try make_runner.exe_path.toString(arena); |
| 5761 | make_argv.items[argv_index_configuration_file] = try configuration_path.toString(arena); |
| 5762 | } |
| 5761 | 5763 | } |
| 5762 | 5764 | |
| 5763 | 5765 | if (!process.can_spawn) { |