diff --git a/.github/workflows/artifact.yml b/.github/workflows/artifact.yml index 2f2aec5..797a042 100644 --- a/.github/workflows/artifact.yml +++ b/.github/workflows/artifact.yml @@ -12,7 +12,7 @@ jobs: - uses: actions/checkout@v2 - uses: goto-bus-stop/setup-zig@v1 with: - version: 0.11.0-dev.1507+6f13a725a + version: 0.11.0-dev.4002+7dd1cf26f - run: | zig build test -Dfetch -Dci_target=${{matrix.os}}-${{matrix.arch}} - run: | diff --git a/GitRepoStep.zig b/GitRepoStep.zig index f7fe895..838405b 100644 --- a/GitRepoStep.zig +++ b/GitRepoStep.zig @@ -1,4 +1,4 @@ -//! Publish Date: 2022_09_09 +//! Publish Date: 2023_03_19 //! This file is hosted at github.com/marler8997/zig-build-repos and is meant to be copied //! to projects that use it. const std = @import("std"); @@ -22,7 +22,6 @@ pub const ShaCheck = enum { }; step: std.build.Step, -builder: *std.build.Builder, url: []const u8, name: []const u8, branch: ?[]const u8 = null, @@ -46,21 +45,24 @@ pub fn create(b: *std.build.Builder, opt: struct { path: ?[]const u8 = null, sha_check: ShaCheck = .warn, fetch_enabled: ?bool = null, + first_ret_addr: ?usize = null, }) *GitRepoStep { var result = b.allocator.create(GitRepoStep) catch @panic("memory"); const name = std.fs.path.basename(opt.url); result.* = GitRepoStep{ - .step = std.build.Step.init(.custom, "clone a git repository", b.allocator, make), - .builder = b, + .step = std.build.Step.init(.{ + .id = .custom, + .name = b.fmt("clone git repository '{s}'", .{name}), + .owner = b, + .makeFn = make, + .first_ret_addr = opt.first_ret_addr orelse @returnAddress(), + .max_rss = 0, + }), .url = opt.url, .name = name, .branch = opt.branch, .sha = opt.sha, - .path = if (opt.path) |p| (b.allocator.dupe(u8, p) catch @panic("memory")) else (std.fs.path.resolve(b.allocator, &[_][]const u8{ - b.build_root, - "dep", - name, - })) catch @panic("memory"), + .path = if (opt.path) |p| b.allocator.dupe(u8, p) catch @panic("OOM") else b.pathFromRoot(b.pathJoin(&.{ "dep", name })), .sha_check = opt.sha_check, .fetch_enabled = if (opt.fetch_enabled) |fe| fe else defaultFetchOption(b), }; @@ -79,7 +81,8 @@ fn hasDependency(step: *const std.build.Step, dep_candidate: *const std.build.St return false; } -fn make(step: *std.build.Step) !void { +fn make(step: *std.Build.Step, prog_node: *std.Progress.Node) !void { + _ = prog_node; const self = @fieldParentPtr(GitRepoStep, "step", step); std.fs.accessAbsolute(self.path, .{}) catch { @@ -98,7 +101,7 @@ fn make(step: *std.build.Step) !void { } { - var args = std.ArrayList([]const u8).init(self.builder.allocator); + var args = std.ArrayList([]const u8).init(self.step.owner.allocator); defer args.deinit(); try args.append("git"); try args.append("clone"); @@ -110,9 +113,9 @@ fn make(step: *std.build.Step) !void { try args.append("-b"); try args.append(branch); } - try run(self.builder, args.items); + try run(self.step.owner, args.items); } - try run(self.builder, &[_][]const u8{ + try run(self.step.owner, &[_][]const u8{ "git", "-C", self.path, @@ -132,7 +135,7 @@ fn checkSha(self: GitRepoStep) !void { const result: union(enum) { failed: anyerror, output: []const u8 } = blk: { const result = std.ChildProcess.exec(.{ - .allocator = self.builder.allocator, + .allocator = self.step.owner.allocator, .argv = &[_][]const u8{ "git", "-C", @@ -140,8 +143,8 @@ fn checkSha(self: GitRepoStep) !void { "rev-parse", "HEAD", }, - .cwd = self.builder.build_root, - .env_map = self.builder.env_map, + .cwd = self.step.owner.build_root.path, + .env_map = self.step.owner.env_map, }) catch |e| break :blk .{ .failed = e }; try std.io.getStdErr().writer().writeAll(result.stderr); switch (result.term) { @@ -183,7 +186,7 @@ fn run(builder: *std.build.Builder, argv: []const []const u8) !void { child.stdin_behavior = .Ignore; child.stdout_behavior = .Inherit; child.stderr_behavior = .Inherit; - child.cwd = builder.build_root; + child.cwd = builder.build_root.path; child.env_map = builder.env_map; try child.spawn(); diff --git a/build.zig b/build.zig index 3952197..960ac9d 100644 --- a/build.zig +++ b/build.zig @@ -23,14 +23,25 @@ fn buildOrFail(b: *Builder) anyerror { .url = "https://github.com/marler8997/ziget", .branch = null, .sha = @embedFile("zigetsha"), + .fetch_enabled = true, }); const build2 = addBuild(b, .{ .path = "build2.zig" }, .{}); build2.addArgs(try getBuildArgs(b)); - ziget_repo.step.make() catch |e| return e; - build2.step.make() catch |err| switch (err) { - error.UnexpectedExitCode => std.os.exit(0xff), // error already printed by subprocess - else => |e| return e, - }; + + var progress = std.Progress{}; + { + var prog_node = progress.start("clone ziget", 1); + ziget_repo.step.make(prog_node) catch |e| return e; + prog_node.end(); + } + { + var prog_node = progress.start("run build2.zig", 1); + build2.step.make(prog_node) catch |err| switch (err) { + error.MakeFailed => std.os.exit(0xff), // error already printed by subprocess, hopefully? + error.MakeSkipped => @panic("impossible?"), + }; + prog_node.end(); + } std.os.exit(0); } @@ -49,6 +60,7 @@ pub fn addBuild(self: *Builder, build_file: std.build.FileSource, _: struct { }) run_step.addArg("--build-file"); run_step.addFileSourceArg(build_file); run_step.addArg("--cache-dir"); - run_step.addArg(self.pathFromRoot(self.cache_root)); + const cache_root_path = self.cache_root.path orelse @panic("todo"); + run_step.addArg(self.pathFromRoot(cache_root_path)); return run_step; } diff --git a/build2.zig b/build2.zig index 613f6f7..a5a965b 100644 --- a/build2.zig +++ b/build2.zig @@ -39,14 +39,17 @@ pub fn build(b: *Builder) !void { else b.standardTargetOptions(.{}); - const mode = b.standardReleaseOptions(); + const optimize = b.standardOptimizeOption(.{}); const zigup_build_options = b.addOptions(); const win32exelink: ?*std.build.LibExeObjStep = blk: { if (target.getOs().tag == .windows) { - const exe = b.addExecutable("win32exelink", "win32exelink.zig"); - exe.setTarget(target); - exe.setBuildMode(mode); + const exe = b.addExecutable(.{ + .name = "win32exelink", + .root_source_file = .{ .path = "win32exelink.zig" }, + .target = target, + .optimize = optimize, + }); // workaround @embedFile not working with absolute paths, see https://github.com/ziglang/zig/issues/14551 //zigup_build_options.addOptionFileSource("win32exelink_filename", .{ .generated = &exe.output_path_source }); const update_step = RelativeOutputPathSourceStep.create(exe); @@ -57,10 +60,10 @@ pub fn build(b: *Builder) !void { }; // TODO: Maybe add more executables with different ssl backends - const exe = try addZigupExe(b, ziget_repo, target, mode, zigup_build_options, win32exelink, .std); - exe.install(); + const exe = try addZigupExe(b, ziget_repo, target, optimize, zigup_build_options, win32exelink, .iguana); + b.installArtifact(exe); - const run_cmd = exe.run(); + const run_cmd = b.addRunArtifact(exe); run_cmd.step.dependOn(b.getInstallStep()); const run_step = b.step("run", "Run the app"); @@ -69,7 +72,7 @@ pub fn build(b: *Builder) !void { run_cmd.addArgs(args); } - addTest(b, exe, target, mode); + addTest(b, exe, target, optimize); } // This whole step is a workaround to @embedFile not working with absolute paths, see https://github.com/ziglang/zig/issues/14551 @@ -78,31 +81,42 @@ const RelativeOutputPathSourceStep = struct { exe: *std.build.LibExeObjStep, output_path_source: std.build.GeneratedFile, pub fn create(exe: *std.build.LibExeObjStep) *RelativeOutputPathSourceStep { - const s = exe.builder.allocator.create(RelativeOutputPathSourceStep) catch unreachable; + const s = exe.step.owner.allocator.create(RelativeOutputPathSourceStep) catch unreachable; s.* = .{ - .step = std.build.Step.init(.custom, "relative output path", exe.builder.allocator, make), + .step = std.build.Step.init(.{ + .id = .custom, + .name = "relative output path", + .owner = exe.step.owner, + .makeFn = make, + }), .exe = exe, .output_path_source = .{ .step = &s.step, }, }; + s.step.dependOn(&exe.step); return s; } - fn make(step: *std.build.Step) !void { + fn make(step: *std.build.Step, prog_node: *std.Progress.Node) !void { + _ = prog_node; const self = @fieldParentPtr(RelativeOutputPathSourceStep, "step", step); - const b = self.exe.builder; + const b = self.exe.step.owner; //std.log.info("output path is '{s}'", .{self.exe.output_path_source.path.?}); const abs_path = self.exe.output_path_source.path.?; - std.debug.assert(std.mem.startsWith(u8, abs_path, b.build_root)); - self.output_path_source.path = std.mem.trimLeft(u8, abs_path[b.build_root.len..], "\\/"); + const build_root_path = b.build_root.path orelse @panic("todo"); + std.debug.assert(std.mem.startsWith(u8, abs_path, build_root_path)); + self.output_path_source.path = std.mem.trimLeft(u8, abs_path[build_root_path.len..], "\\/"); } }; -fn addTest(b: *Builder, exe: *std.build.LibExeObjStep, target: std.zig.CrossTarget, mode: std.builtin.Mode) void { - const test_exe = b.addExecutable("test", "test.zig"); - test_exe.setTarget(target); - test_exe.setBuildMode(mode); - const run_cmd = test_exe.run(); +fn addTest(b: *Builder, exe: *std.build.LibExeObjStep, target: std.zig.CrossTarget, optimize: std.builtin.Mode) void { + const test_exe = b.addExecutable(.{ + .name = "test", + .root_source_file = .{ .path = "test.zig" }, + .target = target, + .optimize = optimize, + }); + const run_cmd = b.addRunArtifact(test_exe); // TODO: make this work, add exe install path as argument to test //run_cmd.addArg(exe.getInstallPath()); @@ -117,7 +131,7 @@ fn addZigupExe( b: *Builder, ziget_repo: *GitRepoStep, target: std.zig.CrossTarget, - mode: std.builtin.Mode, + optimize: std.builtin.Mode, zigup_build_options: *std.build.OptionsStep, optional_win32exelink: ?*std.build.LibExeObjStep, ssl_backend: ?SslBackend @@ -125,9 +139,12 @@ fn addZigupExe( const require_ssl_backend = b.allocator.create(RequireSslBackendStep) catch unreachable; require_ssl_backend.* = RequireSslBackendStep.init(b, "the zigup exe", ssl_backend); - const exe = b.addExecutable("zigup", "zigup.zig"); - exe.setTarget(target); - exe.setBuildMode(mode); + const exe = b.addExecutable(.{ + .name = "zigup", + .root_source_file = .{ .path = "zigup.zig" }, + .target = target, + .optimize = optimize, + }); if (optional_win32exelink) |win32exelink| { exe.step.dependOn(&win32exelink.step); @@ -135,20 +152,20 @@ fn addZigupExe( exe.addOptions("build_options", zigup_build_options); exe.step.dependOn(&ziget_repo.step); - zigetbuild.addZigetPkg(exe, ssl_backend, ziget_repo.getPath(&exe.step)); + zigetbuild.addZigetModule(exe, ssl_backend, ziget_repo.getPath(&exe.step)); if (targetIsWindows(target)) { const zarc_repo = GitRepoStep.create(b, .{ .url = "https://github.com/marler8997/zarc", .branch = "protected", - .sha = "ca9554ffbfceedec6aae5f39fc71a52dbdec2a15", + .sha = "2e5256624d7871180badc9784b96dd66d927d604", }); exe.step.dependOn(&zarc_repo.step); const zarc_repo_path = zarc_repo.getPath(&exe.step); - exe.addPackage(Pkg { - .name = "zarc", - .source = .{ .path = try join(b, &[_][]const u8 { zarc_repo_path, "src", "main.zig" }) }, + const zarc_mod = b.addModule("zarc", .{ + .source_file = .{ .path = b.pathJoin(&.{ zarc_repo_path, "src", "main.zig" }) }, }); + exe.addModule("zarc", zarc_mod); } exe.step.dependOn(&require_ssl_backend.step); @@ -185,12 +202,18 @@ const RequireSslBackendStep = struct { backend: ?SslBackend, pub fn init(b: *Builder, context: []const u8, backend: ?SslBackend) RequireSslBackendStep { return .{ - .step = std.build.Step.init(.custom, "RequireSslBackend", b.allocator, make), + .step = std.build.Step.init(.{ + .id = .custom, + .name = "RequireSslBackend", + .owner = b, + .makeFn = make, + }), .context = context, .backend = backend, }; } - fn make(step: *std.build.Step) !void { + fn make(step: *std.build.Step, prog_node: *std.Progress.Node) !void { + _ = prog_node; const self = @fieldParentPtr(RequireSslBackendStep, "step", step); if (self.backend) |_| { } else { std.debug.print("error: {s} requires an SSL backend:\n", .{self.context}); @@ -216,10 +239,6 @@ fn addGithubReleaseExe(b: *Builder, github_release_step: *std.build.Step, ziget_ github_release_step.dependOn(&exe.step); } -fn join(b: *Builder, parts: []const []const u8) ![]const u8 { - return try std.fs.path.join(b.allocator, parts); -} - const ci_target_map = std.ComptimeStringMap([]const u8, .{ .{ "ubuntu-latest-x86_64", "x86_64-linux" }, .{ "macos-latest-x86_64", "x86_64-macos" }, diff --git a/test.zig b/test.zig index ee28273..1428b18 100644 --- a/test.zig +++ b/test.zig @@ -205,8 +205,12 @@ pub fn main() !u8 { try testing.expect(std.mem.containsAtLeast(u8, result.stderr, 1, " is lower priority in PATH than ")); } } + // verify a dev build - try runNoCapture(zigup_args ++ &[_][]const u8 { "0.10.0-dev.2836+2360f8c49" }); + // NOTE: this test will eventually break when these builds are cleaned up, + // we should support downloading from bazel and use that instead since + // it should be more permanent + try runNoCapture(zigup_args ++ &[_][]const u8 { "0.11.0-dev.4263+f821543e4" }); std.log.info("Success", .{}); return 0; @@ -218,13 +222,13 @@ fn getCompilerCount(install_dir: []const u8) !u32 { var it = dir.iterate(); var count: u32 = 0; while (try it.next()) |entry| { - if (entry.kind == .Directory) { + if (entry.kind == .directory) { count += 1; } else { if (builtin.os.tag == .windows) { - try testing.expect(entry.kind == .File); + try testing.expect(entry.kind == .file); } else { - try testing.expect(entry.kind == .SymLink); + try testing.expect(entry.kind == .sym_link); } } } diff --git a/zigetsha b/zigetsha index e48866b..283f687 100644 --- a/zigetsha +++ b/zigetsha @@ -1 +1 @@ -bcba3e1fe1c3464fa1bb2e8058942e134e2e03a2 \ No newline at end of file +0981200706ebc60495413006992b920a8f9bcae0 \ No newline at end of file diff --git a/zigup.zig b/zigup.zig index 70cb034..047bd4a 100644 --- a/zigup.zig +++ b/zigup.zig @@ -370,10 +370,10 @@ fn fetchCompiler(allocator: Allocator, version_arg: []const u8, set_default: Set if (!is_master) break :blk VersionUrl{ .version = version_arg, .url = try getDefaultUrl(allocator, version_arg) }; optional_download_index = try fetchDownloadIndex(allocator); - const master = optional_download_index.?.json.root.Object.get("master").?; - const compiler_version = master.Object.get("version").?.String; - const master_linux = master.Object.get(json_platform).?; - const master_linux_tarball = master_linux.Object.get("tarball").?.String; + const master = optional_download_index.?.json.value.object.get("master").?; + const compiler_version = master.object.get("version").?.string; + const master_linux = master.object.get(json_platform).?; + const master_linux_tarball = master_linux.object.get("tarball").?.string; break :blk VersionUrl{ .version = compiler_version, .url = master_linux_tarball }; }; const compiler_dir = try std.fs.path.join(allocator, &[_][]const u8{ install_dir, version_url.version }); @@ -399,7 +399,7 @@ const download_index_url = "https://ziglang.org/download/index.json"; const DownloadIndex = struct { text: []u8, - json: std.json.ValueTree, + json: std.json.Parsed(std.json.Value), pub fn deinit(self: *DownloadIndex, allocator: Allocator) void { self.json.deinit(); allocator.free(self.text); @@ -414,11 +414,7 @@ fn fetchDownloadIndex(allocator: Allocator) !DownloadIndex { }, }; errdefer allocator.free(text); - var json = init: { - var parser = std.json.Parser.init(allocator, false); - defer parser.deinit(); - break :init try parser.parse(text); - }; + var json = try std.json.parseFromSlice(std.json.Value, allocator, text, .{}); errdefer json.deinit(); return DownloadIndex{ .text = text, .json = json }; } @@ -504,7 +500,7 @@ fn listCompilers(allocator: Allocator) !void { { var it = install_dir.iterate(); while (try it.next()) |entry| { - if (entry.kind != .Directory) + if (entry.kind != .directory) continue; if (std.mem.endsWith(u8, entry.name, ".installing")) continue; @@ -556,7 +552,7 @@ fn cleanCompilers(allocator: Allocator, compiler_name_opt: ?[]const u8) !void { } else { var it = install_dir.iterate(); while (try it.next()) |entry| { - if (entry.kind != .Directory) + if (entry.kind != .directory) continue; if (getKeepReason(master_points_to_opt, default_comp_opt, entry.name)) |reason| { loginfo("keeping '{s}' ({s})", .{ entry.name, reason }); @@ -804,7 +800,7 @@ const FileId = struct { } return FileId{ .dev = info.dwVolumeSerialNumber, - .ino = (@intCast(u64, info.nFileIndexHigh) << 32) | @intCast(u64, info.nFileIndexLow), + .ino = (@as(u64, @intCast(info.nFileIndexHigh)) << 32) | @as(u64, @intCast(info.nFileIndexLow)), }; } const st = try std.os.fstat(file.handle); @@ -939,7 +935,7 @@ fn installCompiler(allocator: Allocator, compiler_dir: []const u8, url: []const defer archive.deinit(allocator); _ = try archive.extract(reader, installing_dir_opened, .{}); const time = timer.read(); - loginfo("extracted archive in {d:.2} s", .{@intToFloat(f32, time) / @intToFloat(f32, std.time.ns_per_s)}); + loginfo("extracted archive in {d:.2} s", .{@as(f32, @floatFromInt(time)) / @as(f32, @floatFromInt(std.time.ns_per_s))}); } }