| ... | ... | @@ -1,5 +1,6 @@ |
| 1 | 1 | const Maker = @This(); |
| 2 | 2 | const builtin = @import("builtin"); |
| 3 | const native_os = builtin.os.tag; |
| 3 | 4 | |
| 4 | 5 | const std = @import("std"); |
| 5 | 6 | const Allocator = std.mem.Allocator; |
| ... | ... | @@ -106,7 +107,7 @@ const MultilineErrors = enum { indent, newline, none }; |
| 106 | 107 | const Summary = enum { all, new, failures, line, none }; |
| 107 | 108 | |
| 108 | 109 | /// Used to build the -M flags to pass to build-exe. |
| 109 | | const CliModule = struct { |
| 110 | pub const CliModule = struct { |
| 110 | 111 | name: []const u8, |
| 111 | 112 | root_path: []const u8, |
| 112 | 113 | deps: Deps = .empty, |
| ... | ... | @@ -171,17 +172,17 @@ pub fn main(init: process.Init.Minimal) !void { |
| 171 | 172 | }; |
| 172 | 173 | |
| 173 | 174 | const cmd = stringToEnum(enum { init, fetch, build }, cmd_name) orelse |
| 174 | | fatal("bad command name: {q}", .{ cmd_name }); |
| 175 | fatal("bad command name: {q}", .{cmd_name}); |
| 175 | 176 | switch (cmd) { |
| 176 | | .init => return cmdInit( gpa, &graph, args[arg_i..]), |
| 177 | | .fetch => return cmdFetch( gpa, &graph, args[arg_i..]), |
| 177 | .init => return cmdInit(gpa, &graph, args[arg_i..]), |
| 178 | .fetch => return cmdFetch(gpa, &graph, args[arg_i..]), |
| 178 | 179 | .build => {}, |
| 179 | 180 | } |
| 180 | 181 | |
| 181 | 182 | var step_names: std.ArrayList([]const u8) = .empty; |
| 182 | 183 | var help_menu = false; |
| 183 | 184 | var steps_menu = false; |
| 184 | | var print_configuration: enum {none, zon, path} = .none; |
| 185 | var print_configuration: enum { none, zon, path } = .none; |
| 185 | 186 | var override_install_prefix: ?[]const u8 = null; |
| 186 | 187 | var override_lib_dir: ?[]const u8 = null; |
| 187 | 188 | var override_bin_dir: ?[]const u8 = null; |
| ... | ... | @@ -409,6 +410,8 @@ pub fn main(init: process.Init.Minimal) !void { |
| 409 | 410 | webui_listen = Io.net.IpAddress.parseLiteral(addr_str) catch |err| { |
| 410 | 411 | fatal("invalid web UI address {q}: {t}", .{ addr_str, err }); |
| 411 | 412 | }; |
| 413 | } else if (mem.eql(u8, arg, "--debug-target")) { |
| 414 | debug_target = nextArgOrFatal(args, &arg_i); |
| 412 | 415 | } else if (mem.eql(u8, arg, "--debug-log")) { |
| 413 | 416 | try graph.debug_log_scopes.append(arena, nextArgOrFatal(args, &arg_i)); |
| 414 | 417 | } else if (mem.eql(u8, arg, "--debug-compile-errors")) { |
| ... | ... | @@ -551,9 +554,9 @@ pub fn main(init: process.Init.Minimal) !void { |
| 551 | 554 | io, |
| 552 | 555 | cwd_path, |
| 553 | 556 | unresolved_path, |
| 554 | | .@"local_cache", |
| 557 | .@"local cache", |
| 555 | 558 | ) else .{ |
| 556 | | .path = try Dir.path.join(arena, &.{build_root.directory.path orelse ".", default_local_zig_cache_basename}), |
| 559 | .path = try Dir.path.join(arena, &.{ build_root.directory.path orelse ".", default_local_zig_cache_basename }), |
| 557 | 560 | .handle = try build_root.directory.handle.createDirPathOpen(io, default_local_zig_cache_basename, .{}), |
| 558 | 561 | }; |
| 559 | 562 | graph.cache = .{ |
| ... | ... | @@ -583,10 +586,13 @@ pub fn main(init: process.Init.Minimal) !void { |
| 583 | 586 | }); |
| 584 | 587 | defer main_progress_node.end(); |
| 585 | 588 | |
| 586 | | { |
| 589 | const scanned_config: ScannedConfig = sc: { |
| 587 | 590 | // Cache lookup for configure options. If we get a match, we can skip |
| 588 | 591 | // execution of the configure script. If not, we get the file path to pass |
| 589 | 592 | // to the configure process. |
| 593 | // |
| 594 | // In the hot path, we only check this cache, which means that also |
| 595 | // configure source files need to go in here. |
| 590 | 596 | var config_man = graph.cache.obtain(); |
| 591 | 597 | defer config_man.deinit(); |
| 592 | 598 | |
| ... | ... | @@ -597,28 +603,6 @@ pub fn main(init: process.Init.Minimal) !void { |
| 597 | 603 | // a `zig build --cache-poison=ignored`. |
| 598 | 604 | config_man.hash.add(cache_poison == .ignored); |
| 599 | 605 | |
| 600 | | // Normally the build runner is compiled for the host target but here is |
| 601 | | // some code to help when debugging edits to the build runner so that you |
| 602 | | // can make sure it compiles successfully on other targets. |
| 603 | | const resolved_target: Package.Module.ResolvedTarget = t: { |
| 604 | | if (debug_target) |triple| { |
| 605 | | const target_query = try std.Target.Query.parse(.{ .arch_os_abi = triple }); |
| 606 | | config_man.hash.addBytes(triple); |
| 607 | | break :t .{ |
| 608 | | .result = std.zig.resolveTargetQueryOrFatal(io, target_query), |
| 609 | | .is_native_os = false, |
| 610 | | .is_native_abi = false, |
| 611 | | .is_explicit_dynamic_linker = false, |
| 612 | | }; |
| 613 | | } |
| 614 | | break :t .{ |
| 615 | | .result = std.zig.resolveTargetQueryOrFatal(io, .{}), |
| 616 | | .is_native_os = true, |
| 617 | | .is_native_abi = true, |
| 618 | | .is_explicit_dynamic_linker = false, |
| 619 | | }; |
| 620 | | }; |
| 621 | | |
| 622 | 606 | const pkg_root: Path = if (override_pkg_dir) |p| |
| 623 | 607 | .initCwd(p) |
| 624 | 608 | else if (system_pkg_dir_path) |p| |
| ... | ... | @@ -659,10 +643,7 @@ pub fn main(init: process.Init.Minimal) !void { |
| 659 | 643 | } |
| 660 | 644 | defer Fork.deinitList(forks.items); |
| 661 | 645 | |
| 662 | | var file_system_inputs: std.ArrayList(u8) = .empty; |
| 663 | | defer file_system_inputs.deinit(gpa); |
| 664 | | |
| 665 | | var build_configurer_argv: std.ArrayList(u8) = .empty; |
| 646 | var build_configurer_argv: std.ArrayList([]const u8) = .empty; |
| 666 | 647 | defer build_configurer_argv.deinit(gpa); |
| 667 | 648 | |
| 668 | 649 | var dependencies_source: std.ArrayList(u8) = .empty; |
| ... | ... | @@ -678,16 +659,28 @@ pub fn main(init: process.Init.Minimal) !void { |
| 678 | 659 | .sub_path = build_root.build_zig_basename, |
| 679 | 660 | }; |
| 680 | 661 | |
| 662 | const configurer_exe_name = "configurer"; |
| 663 | |
| 681 | 664 | try build_configurer_argv.appendSlice(gpa, &.{ |
| 682 | 665 | graph.zig_exe, "build-exe", // |
| 683 | 666 | "--cache-dir", graph.local_cache_root.path orelse ".", // |
| 684 | 667 | "--global-cache-dir", graph.global_cache_root.path orelse ".", // |
| 685 | 668 | "--zig-lib-dir", graph.zig_lib_directory.path orelse ".", // |
| 686 | | "--name", "configurer", // |
| 669 | "--name", configurer_exe_name, // |
| 687 | 670 | "-fsingle-threaded", // |
| 688 | 671 | }); |
| 672 | |
| 673 | // Normally the build runner is compiled for the host target but here is |
| 674 | // some code to help when debugging edits to the build runner so that you |
| 675 | // can make sure it compiles successfully on other targets. |
| 676 | const target_arch_os_abi: ?[]const u8 = if (debug_target) |triple| t: { |
| 677 | config_man.hash.addBytes(triple); |
| 678 | try build_configurer_argv.appendSlice(gpa, &.{ "-target", triple }); |
| 679 | break :t triple; |
| 680 | } else null; |
| 681 | |
| 689 | 682 | if (graph.libc_file) |libc_file| { |
| 690 | | try build_configurer_argv.appendSlice(gpa, &.{ "--libc", libc_file}); |
| 683 | try build_configurer_argv.appendSlice(gpa, &.{ "--libc", libc_file }); |
| 691 | 684 | } |
| 692 | 685 | if (graph.reference_trace) |n| { |
| 693 | 686 | try build_configurer_argv.append(gpa, try allocPrint(arena, "-freference-trace={d}", .{n})); |
| ... | ... | @@ -737,9 +730,6 @@ pub fn main(init: process.Init.Minimal) !void { |
| 737 | 730 | // We want to release all the locks before executing the child process, so we make a nice |
| 738 | 731 | // big block here to ensure the cleanup gets run when we extract out our argv. |
| 739 | 732 | { |
| 740 | | |
| 741 | | |
| 742 | | |
| 743 | 733 | { |
| 744 | 734 | const fetch_prog_node = main_progress_node.start("Fetch Packages", 0); |
| 745 | 735 | defer fetch_prog_node.end(); |
| ... | ... | @@ -820,12 +810,12 @@ pub fn main(init: process.Init.Minimal) !void { |
| 820 | 810 | var any_unused = false; |
| 821 | 811 | for (fork_set.keys()) |*fork| { |
| 822 | 812 | if (fork.uses == 0) { |
| 823 | | std.log.err("fork {f} matched no {s} packages", .{ |
| 813 | log.err("fork {f} matched no {s} packages", .{ |
| 824 | 814 | fork.path, fork.manifest.name, |
| 825 | 815 | }); |
| 826 | 816 | any_unused = true; |
| 827 | 817 | } else { |
| 828 | | std.log.info("fork {f} matched {d} {s} packages", .{ |
| 818 | log.info("fork {f} matched {d} {s} packages", .{ |
| 829 | 819 | fork.path, fork.uses, fork.manifest.name, |
| 830 | 820 | }); |
| 831 | 821 | } |
| ... | ... | @@ -842,16 +832,16 @@ pub fn main(init: process.Init.Minimal) !void { |
| 842 | 832 | process.exit(1); |
| 843 | 833 | } |
| 844 | 834 | |
| 845 | | if (fetch_only) return cleanExit(io); |
| 835 | if (fetch_only) return process.cleanExit(io); |
| 846 | 836 | |
| 847 | 837 | // Create the dependencies.zig file for configurer to |
| 848 | 838 | // obtain via `@import("@dependencies")`. |
| 849 | 839 | { |
| 850 | 840 | { |
| 851 | 841 | dependencies_source.clearRetainingCapacity(); |
| 852 | | var source_writer: Io.Writer.Allocating = .fromArrayList(&dependencies_source); |
| 842 | var source_writer: Io.Writer.Allocating = .fromArrayList(gpa, &dependencies_source); |
| 853 | 843 | defer dependencies_source = source_writer.toArrayList(); |
| 854 | | job_queue.createDependenciesSource(&dependencies_source) catch |err| switch (err) { |
| 844 | job_queue.createDependenciesSource(&source_writer.writer) catch |err| switch (err) { |
| 855 | 845 | error.WriteFailed => return error.OutOfMemory, |
| 856 | 846 | }; |
| 857 | 847 | } |
| ... | ... | @@ -862,17 +852,18 @@ pub fn main(init: process.Init.Minimal) !void { |
| 862 | 852 | const hex_digest = hh.final(); |
| 863 | 853 | const dependencies_zig_path: Path = .{ |
| 864 | 854 | .root_dir = graph.local_cache_root, |
| 865 | | .sub_path = try allocPrint(arena, "o/{s}/dependencies.zig", .{ &hex_digest }), |
| 855 | .sub_path = try allocPrint(arena, "o/{s}/dependencies.zig", .{&hex_digest}), |
| 866 | 856 | }; |
| 867 | 857 | var atomic_file = try dependencies_zig_path.root_dir.handle.createFileAtomic( |
| 868 | 858 | io, |
| 869 | | dependencies_zig_path.sub_path, .{ .make_path = true, .replace = true }, |
| 859 | dependencies_zig_path.sub_path, |
| 860 | .{ .make_path = true, .replace = true }, |
| 870 | 861 | ); |
| 871 | 862 | defer atomic_file.deinit(io); |
| 872 | 863 | atomic_file.file.writeStreamingAll(io, dependencies_source.items) catch |err| |
| 873 | 864 | fatal("writing dependencies.zig contents: {t}", .{err}); |
| 874 | 865 | atomic_file.replace(io) catch |err| |
| 875 | | fatal("replacing {f}: {t}", .{dependencies_zig_path, err}); |
| 866 | fatal("replacing {f}: {t}", .{ dependencies_zig_path, err }); |
| 876 | 867 | |
| 877 | 868 | deps_mod.root_path = try dependencies_zig_path.toString(arena); |
| 878 | 869 | } |
| ... | ... | @@ -914,7 +905,7 @@ pub fn main(init: process.Init.Minimal) !void { |
| 914 | 905 | global_cache_directory, |
| 915 | 906 | dep, |
| 916 | 907 | ) orelse continue; |
| 917 | | const dep_mod = job_queue.table.get(dep_digest).?.module orelse continue; |
| 908 | const dep_mod = job_queue.table.get(dep_digest).?.cli_module orelse continue; |
| 918 | 909 | const name_cloned = try arena.dupe(u8, name); |
| 919 | 910 | mod.deps.putAssumeCapacityNoClobber(name_cloned, dep_mod); |
| 920 | 911 | } |
| ... | ... | @@ -948,23 +939,30 @@ pub fn main(init: process.Init.Minimal) !void { |
| 948 | 939 | |
| 949 | 940 | try build_configurer_argv.append(gpa, "--listen=-"); |
| 950 | 941 | |
| 951 | | file_system_inputs.clearRetainingCapacity(); |
| 952 | | execute_child(build_configurer_argv, &file_system_inputs); |
| 953 | | |
| 954 | | const hex_digest: []const u8 = &Cache.binToHex(comp.digest.?); |
| 955 | | const exe_path: Path = .{ |
| 956 | | .root_dir = dirs.local_cache, |
| 957 | | .sub_path = try allocPrint(arena, "o/{s}/{s}", .{ hex_digest, comp.emit_bin.? }), |
| 942 | const configure_exe_path: Path = if (std.zig.buildExeSubprocess(gpa, io, .{ |
| 943 | .argv = build_configurer_argv.items, |
| 944 | .cache_root = graph.local_cache_root, |
| 945 | .root_name = configurer_exe_name, |
| 946 | .environ_map = &graph.environ_map, |
| 947 | .cache_manifest = &config_man, |
| 948 | .arch_os_abi = target_arch_os_abi, |
| 949 | })) |p| p else |err| switch (err) { |
| 950 | error.AlreadyReported => process.exit(1), |
| 951 | // If the file system inputs are populated, we can |
| 952 | // still watch for changes and try again. |
| 953 | error.FailedButCacheIntact => @panic("TODO"), |
| 954 | error.Canceled, error.OutOfMemory => |e| return e, |
| 958 | 955 | }; |
| 959 | | _ = try config_man.addFilePath(exe_path, null); |
| 960 | | configure_argv.items[0] = try exe_path.toString(arena); |
| 956 | defer gpa.free(configure_exe_path.sub_path); |
| 957 | |
| 958 | configure_argv.items[0] = try configure_exe_path.toString(arena); |
| 961 | 959 | |
| 962 | 960 | switch (cache_poison) { |
| 963 | 961 | .pure, .disallowed, .ignored => if (try config_man.hit()) { |
| 964 | 962 | const digest = config_man.final(); |
| 965 | 963 | break :cp .{ |
| 966 | 964 | .{ |
| 967 | | .root_dir = dirs.local_cache, |
| 965 | .root_dir = graph.local_cache_root, |
| 968 | 966 | .sub_path = try allocPrint(arena, "c/{s}", .{&digest}), |
| 969 | 967 | }, |
| 970 | 968 | false, |
| ... | ... | @@ -975,14 +973,15 @@ pub fn main(init: process.Init.Minimal) !void { |
| 975 | 973 | } |
| 976 | 974 | |
| 977 | 975 | if (!process.can_spawn) { |
| 978 | | const cmd = try std.mem.join(arena, " ", configure_argv.items); |
| 979 | | fatal("the following command cannot be executed ({t} does not support spawning a child process):\n{s}", .{ native_os, cmd }); |
| 976 | fatal("cannot spawn command on {t}: {f}", .{ native_os, @as(std.zig.SubprocessCommand, .{ |
| 977 | .argv = configure_argv.items, |
| 978 | }) }); |
| 980 | 979 | } |
| 981 | 980 | |
| 982 | 981 | const rand_int = randInt(io, u64); |
| 983 | 982 | const tmp_dir_sub_path = "tmp" ++ Dir.path.sep_str ++ std.fmt.hex(rand_int); |
| 984 | 983 | const config_tmp_path: Path = .{ |
| 985 | | .root_dir = dirs.local_cache, |
| 984 | .root_dir = graph.local_cache_root, |
| 986 | 985 | .sub_path = tmp_dir_sub_path, |
| 987 | 986 | }; |
| 988 | 987 | const config_tmp_file: Io.File = try config_tmp_path.root_dir.handle.createFile( |
| ... | ... | @@ -995,7 +994,7 @@ pub fn main(init: process.Init.Minimal) !void { |
| 995 | 994 | const term = term: { |
| 996 | 995 | const child_node = main_progress_node.start("Run Configure Script", 0); |
| 997 | 996 | defer child_node.end(); |
| 998 | | var child = std.process.spawn(io, .{ |
| 997 | var child = process.spawn(io, .{ |
| 999 | 998 | .argv = configure_argv.items, |
| 1000 | 999 | .stdout = .{ .file = config_tmp_file }, |
| 1001 | 1000 | .progress_node = child_node, |
| ... | ... | @@ -1006,8 +1005,9 @@ pub fn main(init: process.Init.Minimal) !void { |
| 1006 | 1005 | }; |
| 1007 | 1006 | if (!term.success()) { |
| 1008 | 1007 | // Failure to produce the configuration file. |
| 1009 | | const cmd = try std.mem.join(arena, " ", configure_argv.items); |
| 1010 | | fatal("the following configure command {f}:\n{s}", .{ term, cmd }); |
| 1008 | fatal("configure command {f}: {f}", .{ term, @as(std.zig.SubprocessCommand, .{ |
| 1009 | .argv = configure_argv.items, |
| 1010 | }) }); |
| 1011 | 1011 | } |
| 1012 | 1012 | // Even though the file is designed to be sent directly to make |
| 1013 | 1013 | // runner, we must load it now because: |
| ... | ... | @@ -1015,17 +1015,16 @@ pub fn main(init: process.Init.Minimal) !void { |
| 1015 | 1015 | // add them to `config_man` before obtaining the final digest. |
| 1016 | 1016 | // * If it contains a set of lazy packages that need to be |
| 1017 | 1017 | // fetched, we need to fetch those now and re-run configure. |
| 1018 | | var configuration = std.Build.Configuration.loadFile(arena, io, config_tmp_file) catch |err| |
| 1018 | var configuration = Configuration.loadFile(arena, io, config_tmp_file) catch |err| |
| 1019 | 1019 | fatal("failed to load configuration file {f}: {t}", .{ config_tmp_path, err }); |
| 1020 | 1020 | |
| 1021 | 1021 | if (configuration.unlazy_deps.len != 0) { |
| 1022 | | if (!dev.env.supports(.fetch_command)) process.exit(1); |
| 1023 | 1022 | var any_errors = false; |
| 1024 | 1023 | for (configuration.unlazy_deps) |hash_string| { |
| 1025 | 1024 | const hash = hash_string.slice(&configuration); |
| 1026 | 1025 | assert(hash.len != 0); |
| 1027 | 1026 | if (hash.len > Package.Hash.max_len) { |
| 1028 | | std.log.err("invalid digest (length {d} exceeds maximum): {q}", .{ hash.len, hash }); |
| 1027 | log.err("invalid digest (length {d} exceeds maximum): {q}", .{ hash.len, hash }); |
| 1029 | 1028 | any_errors = true; |
| 1030 | 1029 | continue; |
| 1031 | 1030 | } |
| ... | ... | @@ -1037,33 +1036,17 @@ pub fn main(init: process.Init.Minimal) !void { |
| 1037 | 1036 | // cannot be fetched by Zig. |
| 1038 | 1037 | const s = Dir.path.sep_str; |
| 1039 | 1038 | for (unlazy_set.keys()) |*hash| { |
| 1040 | | std.log.err("lazy dependency package not found: {s}" ++ s ++ "{s}", .{ p, hash.toSlice() }); |
| 1039 | log.err("lazy dependency package not found: {s}" ++ s ++ "{s}", .{ p, hash.toSlice() }); |
| 1041 | 1040 | } |
| 1042 | | std.log.info("remote package fetching disabled due to --system mode", .{}); |
| 1043 | | std.log.info("dependencies might be avoidable depending on build configuration", .{}); |
| 1041 | log.info("remote package fetching disabled due to --system mode", .{}); |
| 1042 | log.info("dependencies might be avoidable depending on build configuration", .{}); |
| 1044 | 1043 | process.exit(1); |
| 1045 | 1044 | } |
| 1046 | 1045 | continue :cp; |
| 1047 | 1046 | } |
| 1048 | 1047 | |
| 1049 | | for (configuration.path_deps_base, configuration.path_deps_sub) |base, sub| { |
| 1050 | | const conf_path: std.Build.Configuration.Path = .{ .base = base, .sub = sub }; |
| 1051 | | try config_man.addPathPost(conf_path.toCachePath(&configuration, arena)); |
| 1052 | | } |
| 1053 | | |
| 1054 | | // We need to add to the configuration cache the source files of |
| 1055 | | // configurer itself, so that the maker process can watch the file system |
| 1056 | | // for those changes and restart itself. By doing this, we make it |
| 1057 | | // possible to bypass creating a Compilation for configurer on |
| 1058 | | // Configuration cache hit. |
| 1059 | | { |
| 1060 | | var it = mem.splitScalar(u8, file_system_inputs.items, 0); |
| 1061 | | while (it.next()) |input| { |
| 1062 | | _ = try config_man.addPrefixedPathPost(.{ |
| 1063 | | .prefix = input[0], |
| 1064 | | .sub_path = input[1..], |
| 1065 | | }); |
| 1066 | | } |
| 1048 | for (configuration.path_deps) |path_dep| { |
| 1049 | try config_man.addPathPost(path_dep.toCachePath(&configuration, arena)); |
| 1067 | 1050 | } |
| 1068 | 1051 | |
| 1069 | 1052 | // If it is poisoned, there is no point in moving it to cached |
| ... | ... | @@ -1073,7 +1056,7 @@ pub fn main(init: process.Init.Minimal) !void { |
| 1073 | 1056 | } else { |
| 1074 | 1057 | const digest = config_man.final(); |
| 1075 | 1058 | const final_path: Path = .{ |
| 1076 | | .root_dir = dirs.local_cache, |
| 1059 | .root_dir = graph.local_cache_root, |
| 1077 | 1060 | .sub_path = try allocPrint(arena, "c/{s}", .{&digest}), |
| 1078 | 1061 | }; |
| 1079 | 1062 | Io.Dir.rename( |
| ... | ... | @@ -1107,33 +1090,27 @@ pub fn main(init: process.Init.Minimal) !void { |
| 1107 | 1090 | } |
| 1108 | 1091 | }; |
| 1109 | 1092 | |
| 1110 | | { |
| 1111 | | // Release all file system locks just before running the maker process. |
| 1112 | | var configuration_lock = if (!poisoned) config_man.toOwnedLock() else null; |
| 1113 | | defer if (configuration_lock) |*l| l.release(io); |
| 1114 | | |
| 1115 | | if (print_configuration_path) { |
| 1116 | | var stdout_writer = Io.File.stdout().writerStreaming(io, &stdout_buffer); |
| 1117 | | stdout_writer.interface.print("{f}\n", .{configuration_path}) catch |
| 1118 | | fatal("failed printing cache file path: {t}", .{stdout_writer.err.?}); |
| 1119 | | stdout_writer.flush() catch |err| |
| 1120 | | fatal("failed printing cache file path: {t}", .{err}); |
| 1121 | | return cleanExit(io); |
| 1122 | | } |
| 1123 | | const make_runner = make_runner_task.await(io) catch |err| fatal("failed compiling maker: {t}", .{err}); |
| 1093 | // Hang on to the configuration file lock until we finish loading the configuration file. |
| 1094 | var configuration_lock = if (!poisoned) config_man.toOwnedLock() else null; |
| 1095 | defer if (configuration_lock) |*l| l.release(io); |
| 1124 | 1096 | |
| 1125 | | make_argv.items[0] = try make_runner.exe_path.toString(arena); |
| 1126 | | make_argv.items[argv_index_configuration_file] = try configuration_path.toString(arena); |
| 1097 | switch (print_configuration) { |
| 1098 | .path => { |
| 1099 | initStdoutWriter(io).print("{f}\n", .{configuration_path}) catch |
| 1100 | fatal("failed printing cache file path: {t}", .{stdout_writer_allocation.err.?}); |
| 1101 | stdout_writer_allocation.flush() catch |err| |
| 1102 | fatal("failed printing cache file path: {t}", .{err}); |
| 1103 | return process.cleanExit(io); |
| 1104 | }, |
| 1105 | .none, .zon => {}, |
| 1127 | 1106 | } |
| 1128 | | } |
| 1129 | 1107 | |
| 1130 | | const scanned_config: ScannedConfig = sc: { |
| 1131 | 1108 | const configuration = c: { |
| 1132 | | var file = cwd.openFile(io, configure_path, .{}) catch |err| |
| 1133 | | fatal("failed to open configuration file {s}: {t}", .{ configure_path, err }); |
| 1109 | var file = configuration_path.root_dir.handle.openFile(io, configuration_path.sub_path, .{}) catch |err| |
| 1110 | fatal("failed to open configuration file {f}: {t}", .{ configuration_path, err }); |
| 1134 | 1111 | defer file.close(io); |
| 1135 | 1112 | break :c Configuration.loadFile(arena, io, file) catch |err| |
| 1136 | | fatal("failed to load configuration file {s}: {t}", .{ configure_path, err }); |
| 1113 | fatal("failed to load configuration file {f}: {t}", .{ configuration_path, err }); |
| 1137 | 1114 | }; |
| 1138 | 1115 | // Technically if the configuration is marked as poisoned, we could |
| 1139 | 1116 | // already delete the file now, but we leave it around in case the |
| ... | ... | @@ -1159,37 +1136,32 @@ pub fn main(init: process.Init.Minimal) !void { |
| 1159 | 1136 | break :sc .{ |
| 1160 | 1137 | .configuration = configuration, |
| 1161 | 1138 | .top_level_steps = top_level_steps, |
| 1162 | | .path = configure_path, |
| 1139 | .path = configuration_path, |
| 1163 | 1140 | }; |
| 1164 | 1141 | }; |
| 1165 | 1142 | |
| 1166 | 1143 | if (help_menu) { |
| 1167 | | const w = initStdoutWriter(io); |
| 1168 | | scanned_config.printUsage(&graph, w) catch |err| switch (err) { |
| 1144 | scanned_config.printUsage(&graph, initStdoutWriter(io)) catch |err| switch (err) { |
| 1169 | 1145 | error.WriteFailed => return stdout_writer_allocation.err.?, |
| 1170 | 1146 | else => |e| return e, |
| 1171 | 1147 | }; |
| 1172 | | w.flush() catch return stdout_writer_allocation.err.?; |
| 1148 | try stdout_writer_allocation.flush(); |
| 1173 | 1149 | return cleanExit(io, &scanned_config); |
| 1174 | 1150 | } else if (steps_menu) { |
| 1175 | | const w = initStdoutWriter(io); |
| 1176 | | scanned_config.printSteps(&graph, w) catch |err| switch (err) { |
| 1151 | scanned_config.printSteps(&graph, initStdoutWriter(io)) catch |err| switch (err) { |
| 1177 | 1152 | error.WriteFailed => return stdout_writer_allocation.err.?, |
| 1178 | 1153 | else => |e| return e, |
| 1179 | 1154 | }; |
| 1180 | | w.flush() catch return stdout_writer_allocation.err.?; |
| 1155 | try stdout_writer_allocation.flush(); |
| 1181 | 1156 | return cleanExit(io, &scanned_config); |
| 1182 | 1157 | } else switch (print_configuration) { |
| 1183 | 1158 | .none => {}, |
| 1184 | 1159 | .zon => { |
| 1185 | | const w = initStdoutWriter(io); |
| 1186 | | scanned_config.print(w) catch return stdout_writer_allocation.err.?; |
| 1187 | | w.flush() catch return stdout_writer_allocation.err.?; |
| 1160 | scanned_config.print(initStdoutWriter(io)) catch return stdout_writer_allocation.err.?; |
| 1161 | try stdout_writer_allocation.flush(); |
| 1188 | 1162 | return cleanExit(io, &scanned_config); |
| 1189 | 1163 | }, |
| 1190 | | .path => { |
| 1191 | | @panic("TODO"); |
| 1192 | | }, |
| 1164 | .path => unreachable, |
| 1193 | 1165 | } |
| 1194 | 1166 | |
| 1195 | 1167 | if (webui_listen != null) { |
| ... | ... | @@ -1204,7 +1176,7 @@ pub fn main(init: process.Init.Minimal) !void { |
| 1204 | 1176 | .root_dir = .cwd(), |
| 1205 | 1177 | .sub_path = cwd_relative, |
| 1206 | 1178 | } else .{ |
| 1207 | | .root_dir = build_root_directory, |
| 1179 | .root_dir = graph.build_root_directory, |
| 1208 | 1180 | .sub_path = "zig-out", |
| 1209 | 1181 | }; |
| 1210 | 1182 | |
| ... | ... | @@ -1274,7 +1246,7 @@ pub fn main(init: process.Init.Minimal) !void { |
| 1274 | 1246 | |
| 1275 | 1247 | var w: Watch = w: { |
| 1276 | 1248 | if (!watch) break :w undefined; |
| 1277 | | if (!Watch.have_impl) fatal("--watch not yet implemented for {t}", .{builtin.os.tag}); |
| 1249 | if (!Watch.have_impl) fatal("--watch not yet implemented for {t}", .{native_os}); |
| 1278 | 1250 | break :w try .init(&maker); |
| 1279 | 1251 | }; |
| 1280 | 1252 | |
| ... | ... | @@ -1366,11 +1338,7 @@ pub fn main(init: process.Init.Minimal) !void { |
| 1366 | 1338 | } |
| 1367 | 1339 | } |
| 1368 | 1340 | |
| 1369 | | fn cmdFetch( |
| 1370 | | gpa: Allocator, |
| 1371 | | graph: *Graph, |
| 1372 | | args: []const []const u8 |
| 1373 | | ) !void { |
| 1341 | fn cmdFetch(gpa: Allocator, graph: *Graph, args: []const []const u8) !void { |
| 1374 | 1342 | const environ_map = &graph.environ_map; |
| 1375 | 1343 | const io = graph.io; |
| 1376 | 1344 | const arena = graph.arena; |
| ... | ... | @@ -1392,7 +1360,7 @@ fn cmdFetch( |
| 1392 | 1360 | if (mem.startsWith(u8, arg, "-")) { |
| 1393 | 1361 | if (mem.eql(u8, arg, "-h") or mem.eql(u8, arg, "--help")) { |
| 1394 | 1362 | try Io.File.stdout().writeStreamingAll(io, usage_fetch); |
| 1395 | | return cleanExit(io); |
| 1363 | return process.cleanExit(io); |
| 1396 | 1364 | } else if (mem.eql(u8, arg, "--global-cache-dir")) { |
| 1397 | 1365 | override_global_cache_dir = nextArgOrFatal(args, &arg_i); |
| 1398 | 1366 | } else if (mem.eql(u8, arg, "--cache-dir")) { |
| ... | ... | @@ -1500,7 +1468,7 @@ fn cmdFetch( |
| 1500 | 1468 | .oom_flag = false, |
| 1501 | 1469 | .latest_commit = null, |
| 1502 | 1470 | |
| 1503 | | .module = null, |
| 1471 | .cli_module = null, |
| 1504 | 1472 | }; |
| 1505 | 1473 | defer fetch.deinit(); |
| 1506 | 1474 | |
| ... | ... | @@ -1526,10 +1494,10 @@ fn cmdFetch( |
| 1526 | 1494 | const name = switch (save) { |
| 1527 | 1495 | .no => { |
| 1528 | 1496 | var data: [2][]const u8 = .{ package_hash_slice, "\n" }; |
| 1529 | | const w = initStdoutWriter(); |
| 1530 | | try w.writeVecAll(&data); |
| 1531 | | try w.flush(); |
| 1532 | | return cleanExit(io); |
| 1497 | const w = initStdoutWriter(io); |
| 1498 | w.writeVecAll(&data) catch return stdout_writer_allocation.err.?; |
| 1499 | try stdout_writer_allocation.flush(); |
| 1500 | return process.cleanExit(io); |
| 1533 | 1501 | }, |
| 1534 | 1502 | .yes, .exact => |name| name: { |
| 1535 | 1503 | if (name) |n| break :name n; |
| ... | ... | @@ -1567,14 +1535,14 @@ fn cmdFetch( |
| 1567 | 1535 | // the refspec may already be fully resolved |
| 1568 | 1536 | if (std.mem.eql(u8, target_ref, latest_commit_hex)) break :resolved; |
| 1569 | 1537 | |
| 1570 | | std.log.info("resolved ref {q} to commit {s}", .{ target_ref, latest_commit_hex }); |
| 1538 | log.info("resolved ref {q} to commit {s}", .{ target_ref, latest_commit_hex }); |
| 1571 | 1539 | |
| 1572 | 1540 | // include the original refspec in a query parameter, could be used to check for updates |
| 1573 | 1541 | uri.query = .{ .percent_encoded = try allocPrint(arena, "ref={f}", .{ |
| 1574 | 1542 | std.fmt.alt(fragment, .formatEscaped), |
| 1575 | 1543 | }) }; |
| 1576 | 1544 | } else { |
| 1577 | | std.log.info("resolved to commit {s}", .{latest_commit_hex}); |
| 1545 | log.info("resolved to commit {s}", .{latest_commit_hex}); |
| 1578 | 1546 | } |
| 1579 | 1547 | |
| 1580 | 1548 | // replace the refspec with the resolved commit SHA |
| ... | ... | @@ -1613,7 +1581,7 @@ fn cmdFetch( |
| 1613 | 1581 | switch (dep.location) { |
| 1614 | 1582 | .url => |u| { |
| 1615 | 1583 | if (mem.eql(u8, h, package_hash_slice) and mem.eql(u8, u, saved_path_or_url)) { |
| 1616 | | std.log.info("existing dependency named {q} is up-to-date", .{name}); |
| 1584 | log.info("existing dependency named {q} is up-to-date", .{name}); |
| 1617 | 1585 | process.exit(0); |
| 1618 | 1586 | } |
| 1619 | 1587 | }, |
| ... | ... | @@ -1661,7 +1629,7 @@ fn cmdFetch( |
| 1661 | 1629 | fatal("unable to write {s} file: {t}", .{ Package.Manifest.basename, err }); |
| 1662 | 1630 | }; |
| 1663 | 1631 | |
| 1664 | | return cleanExit(io); |
| 1632 | return process.cleanExit(io); |
| 1665 | 1633 | } |
| 1666 | 1634 | |
| 1667 | 1635 | const usage_fetch = |
| ... | ... | @@ -1707,13 +1675,10 @@ const usage_init = |
| 1707 | 1675 | \\ |
| 1708 | 1676 | ; |
| 1709 | 1677 | |
| 1710 | | fn cmdInit( |
| 1711 | | gpa: Allocator, |
| 1712 | | graph: *Graph, |
| 1713 | | args: []const []const u8 |
| 1714 | | ) !void { |
| 1678 | fn cmdInit(gpa: Allocator, graph: *Graph, args: []const []const u8) !void { |
| 1715 | 1679 | const arena = graph.arena; |
| 1716 | 1680 | const io = graph.io; |
| 1681 | const default_build_zig_basename = std.zig.build_zig_basename; |
| 1717 | 1682 | |
| 1718 | 1683 | var template: enum { example, minimal } = .example; |
| 1719 | 1684 | { |
| ... | ... | @@ -1725,7 +1690,7 @@ fn cmdInit( |
| 1725 | 1690 | template = .minimal; |
| 1726 | 1691 | } else if (mem.eql(u8, arg, "-h") or mem.eql(u8, arg, "--help")) { |
| 1727 | 1692 | try Io.File.stdout().writeStreamingAll(io, usage_init); |
| 1728 | | return cleanExit(io); |
| 1693 | return process.cleanExit(io); |
| 1729 | 1694 | } else { |
| 1730 | 1695 | fatal("unrecognized parameter: {q}", .{arg}); |
| 1731 | 1696 | } |
| ... | ... | @@ -1749,7 +1714,7 @@ fn cmdInit( |
| 1749 | 1714 | |
| 1750 | 1715 | const s = Dir.path.sep_str; |
| 1751 | 1716 | const template_paths = [_][]const u8{ |
| 1752 | | Package.build_zig_basename, |
| 1717 | default_build_zig_basename, |
| 1753 | 1718 | Package.Manifest.basename, |
| 1754 | 1719 | "src" ++ s ++ "main.zig", |
| 1755 | 1720 | "src" ++ s ++ "root.zig", |
| ... | ... | @@ -1758,20 +1723,20 @@ fn cmdInit( |
| 1758 | 1723 | |
| 1759 | 1724 | for (template_paths) |template_path| { |
| 1760 | 1725 | if (templates.write(arena, io, Io.Dir.cwd(), sanitized_root_name, template_path, fingerprint)) |_| { |
| 1761 | | std.log.info("created {s}", .{template_path}); |
| 1726 | log.info("created {s}", .{template_path}); |
| 1762 | 1727 | ok_count += 1; |
| 1763 | 1728 | } else |err| switch (err) { |
| 1764 | | error.PathAlreadyExists => std.log.info("preserving already existing file: {s}", .{ |
| 1729 | error.PathAlreadyExists => log.info("preserving already existing file: {s}", .{ |
| 1765 | 1730 | template_path, |
| 1766 | 1731 | }), |
| 1767 | | else => std.log.err("unable to write {s}: {s}\n", .{ template_path, @errorName(err) }), |
| 1732 | else => log.err("unable to write {s}: {t}", .{ template_path, err }), |
| 1768 | 1733 | } |
| 1769 | 1734 | } |
| 1770 | 1735 | |
| 1771 | 1736 | if (ok_count == template_paths.len) { |
| 1772 | | std.log.info("see `zig build --help` for a menu of options", .{}); |
| 1737 | log.info("see `zig build --help` for a menu of options", .{}); |
| 1773 | 1738 | } |
| 1774 | | return cleanExit(io); |
| 1739 | return process.cleanExit(io); |
| 1775 | 1740 | }, |
| 1776 | 1741 | .minimal => { |
| 1777 | 1742 | writeSimpleTemplateFile(io, Package.Manifest.basename, |
| ... | ... | @@ -1791,7 +1756,7 @@ fn cmdInit( |
| 1791 | 1756 | else => fatal("failed to create {q}: {t}", .{ Package.Manifest.basename, err }), |
| 1792 | 1757 | error.PathAlreadyExists => fatal("refusing to overwrite {q}", .{Package.Manifest.basename}), |
| 1793 | 1758 | }; |
| 1794 | | writeSimpleTemplateFile(io, Package.build_zig_basename, |
| 1759 | writeSimpleTemplateFile(io, default_build_zig_basename, |
| 1795 | 1760 | \\const std = @import("std"); |
| 1796 | 1761 | \\ |
| 1797 | 1762 | \\pub fn build(b: *std.Build) void {{ |
| ... | ... | @@ -1799,24 +1764,22 @@ fn cmdInit( |
| 1799 | 1764 | \\}} |
| 1800 | 1765 | \\ |
| 1801 | 1766 | , .{}) catch |err| switch (err) { |
| 1802 | | else => fatal("failed to create {q}: {t}", .{ Package.build_zig_basename, err }), |
| 1767 | else => fatal("failed to create {q}: {t}", .{ default_build_zig_basename, err }), |
| 1803 | 1768 | // `build.zig` already existing is okay: the user has just used `zig init` to set up |
| 1804 | 1769 | // their `build.zig.zon` *after* writing their `build.zig`. So this one isn't fatal. |
| 1805 | 1770 | error.PathAlreadyExists => { |
| 1806 | | std.log.info("successfully populated {q}, preserving existing {q}", .{ |
| 1807 | | Package.Manifest.basename, Package.build_zig_basename, |
| 1771 | log.info("successfully populated {q}, preserving existing {q}", .{ |
| 1772 | Package.Manifest.basename, default_build_zig_basename, |
| 1808 | 1773 | }); |
| 1809 | | return cleanExit(io); |
| 1774 | return process.cleanExit(io); |
| 1810 | 1775 | }, |
| 1811 | 1776 | }; |
| 1812 | | std.log.info("successfully populated {q} and {q}", .{ Package.Manifest.basename, Package.build_zig_basename }); |
| 1813 | | return cleanExit(io); |
| 1777 | log.info("successfully populated {q} and {q}", .{ Package.Manifest.basename, default_build_zig_basename }); |
| 1778 | return process.cleanExit(io); |
| 1814 | 1779 | }, |
| 1815 | 1780 | } |
| 1816 | 1781 | } |
| 1817 | 1782 | |
| 1818 | | |
| 1819 | | |
| 1820 | 1783 | fn markFailedStepsDirty(maker: *Maker) void { |
| 1821 | 1784 | const all_steps = maker.step_stack.keys(); |
| 1822 | 1785 | |
| ... | ... | @@ -1918,9 +1881,7 @@ fn prepare(maker: *Maker, step_names: []const []const u8) !void { |
| 1918 | 1881 | } |
| 1919 | 1882 | if (any_problems) { |
| 1920 | 1883 | if (maker.max_rss_is_default) { |
| 1921 | | std.log.info("use --maxrss {d} to proceed, risking system memory exhaustion", .{ |
| 1922 | | max_needed, |
| 1923 | | }); |
| 1884 | log.info("use --maxrss {d} to proceed, risking system memory exhaustion", .{max_needed}); |
| 1924 | 1885 | } |
| 1925 | 1886 | return error.InsufficientMemory; |
| 1926 | 1887 | } |
| ... | ... | @@ -2012,12 +1973,12 @@ fn makeStepNames( |
| 2012 | 1973 | } |
| 2013 | 1974 | |
| 2014 | 1975 | if (fuzz) |mode| blk: { |
| 2015 | | switch (builtin.os.tag) { |
| 1976 | switch (native_os) { |
| 2016 | 1977 | // Current implementation depends on two things that need to be ported to Windows: |
| 2017 | 1978 | // * Memory-mapping to share data between the fuzzer and build runner. |
| 2018 | 1979 | // * COFF/PE support added to `std.debug.Info` (it needs a batching API for resolving |
| 2019 | 1980 | // many addresses to source locations). |
| 2020 | | .windows => fatal("--fuzz not yet implemented for {t}", .{builtin.os.tag}), |
| 1981 | .windows => fatal("--fuzz not yet implemented for {t}", .{native_os}), |
| 2021 | 1982 | else => {}, |
| 2022 | 1983 | } |
| 2023 | 1984 | if (@bitSizeOf(usize) != 64) { |
| ... | ... | @@ -2781,23 +2742,23 @@ pub fn printErrorMessages( |
| 2781 | 2742 | try writer.writeByte('\n'); |
| 2782 | 2743 | } |
| 2783 | 2744 | |
| 2784 | | fn nextArg(args: []const [:0]const u8, idx: *usize) ?[:0]const u8 { |
| 2745 | fn nextArg(args: []const []const u8, idx: *usize) ?[]const u8 { |
| 2785 | 2746 | if (idx.* >= args.len) return null; |
| 2786 | 2747 | defer idx.* += 1; |
| 2787 | 2748 | return args[idx.*]; |
| 2788 | 2749 | } |
| 2789 | 2750 | |
| 2790 | | fn nextArgOrFatal(args: []const [:0]const u8, idx: *usize) [:0]const u8 { |
| 2751 | fn nextArgOrFatal(args: []const []const u8, idx: *usize) []const u8 { |
| 2791 | 2752 | return nextArg(args, idx) orelse fatalWithHint("expected argument after {q}", .{args[idx.* - 1]}); |
| 2792 | 2753 | } |
| 2793 | 2754 | |
| 2794 | | fn prefixedArgOrFatal(args: []const [:0]const u8, index_ptr: *usize, prefix: []const u8) []const u8 { |
| 2755 | fn prefixedArgOrFatal(args: []const []const u8, index_ptr: *usize, prefix: []const u8) []const u8 { |
| 2795 | 2756 | const arg = args[index_ptr.*]; |
| 2796 | 2757 | if (mem.cutPrefix(u8, arg, prefix)) |rest| return rest; |
| 2797 | | fatal("expected {q} to begin with {q}", .{arg, prefix}); |
| 2758 | fatal("expected {q} to begin with {q}", .{ arg, prefix }); |
| 2798 | 2759 | } |
| 2799 | 2760 | |
| 2800 | | fn argsRest(args: []const [:0]const u8, idx: usize) ?[]const [:0]const u8 { |
| 2761 | fn argsRest(args: []const []const u8, idx: usize) ?[]const []const u8 { |
| 2801 | 2762 | if (idx >= args.len) return null; |
| 2802 | 2763 | return args[idx..]; |
| 2803 | 2764 | } |
| ... | ... | @@ -3158,8 +3119,8 @@ fn removePoisonedConfiguration(io: Io, scanned_config: *const ScannedConfig) voi |
| 3158 | 3119 | if (scanned_config.configuration.poisoned) { |
| 3159 | 3120 | // This configuration file was good for only 1 invocation of the maker |
| 3160 | 3121 | // process. Delete it to save space on disk. |
| 3161 | | Io.Dir.cwd().deleteFile(io, scanned_config.path) catch |err| |
| 3162 | | log.warn("failed deleting poisoned configuration file {s}: {t}", .{ scanned_config.path, err }); |
| 3122 | scanned_config.path.root_dir.handle.deleteFile(io, scanned_config.path.sub_path) catch |err| |
| 3123 | log.warn("failed deleting poisoned configuration file {f}: {t}", .{ scanned_config.path, err }); |
| 3163 | 3124 | } |
| 3164 | 3125 | } |
| 3165 | 3126 | |
| ... | ... | @@ -3228,8 +3189,8 @@ fn findBuildRoot(arena: Allocator, io: Io, options: FindBuildRootOptions) !Build |
| 3228 | 3189 | } else |err| switch (err) { |
| 3229 | 3190 | error.FileNotFound => { |
| 3230 | 3191 | dirname = Dir.path.dirname(dirname) orelse { |
| 3231 | | std.log.info("initialize {s} template file with \"zig init\"", .{ std.zig.build_zig_basename }); |
| 3232 | | std.log.info("see \"zig --help\" for more options", .{}); |
| 3192 | log.info("initialize {s} template file with \"zig init\"", .{std.zig.build_zig_basename}); |
| 3193 | log.info("see \"zig --help\" for more options", .{}); |
| 3233 | 3194 | fatal("no build.zig file found, in the current directory or any parent directories", .{}); |
| 3234 | 3195 | }; |
| 3235 | 3196 | continue; |
| ... | ... | @@ -3266,7 +3227,7 @@ const Fork = struct { |
| 3266 | 3227 | error.Canceled => |e| return e, |
| 3267 | 3228 | error.AlreadyReported => fork.failed = true, |
| 3268 | 3229 | else => |e| { |
| 3269 | | std.log.err("failed to load fork at {f}: {t}", .{ fork.path, e }); |
| 3230 | log.err("failed to load fork at {f}: {t}", .{ fork.path, e }); |
| 3270 | 3231 | fork.failed = true; |
| 3271 | 3232 | }, |
| 3272 | 3233 | }; |
| ... | ... | @@ -3299,7 +3260,7 @@ const Fork = struct { |
| 3299 | 3260 | return error.AlreadyReported; |
| 3300 | 3261 | }, |
| 3301 | 3262 | else => |e| { |
| 3302 | | std.log.err("failed to load package manifest {f}: {t}", .{ manifest_path, e }); |
| 3263 | log.err("failed to load package manifest {f}: {t}", .{ manifest_path, e }); |
| 3303 | 3264 | return error.AlreadyReported; |
| 3304 | 3265 | }, |
| 3305 | 3266 | }; |
| ... | ... | @@ -3527,4 +3488,3 @@ fn findTemplates(gpa: Allocator, arena: Allocator, io: Io) Templates { |
| 3527 | 3488 | .buffer = std.array_list.Managed(u8).init(gpa), |
| 3528 | 3489 | }; |
| 3529 | 3490 | } |
| 3530 | | |