112 lines
3.6 KiB
Zig
112 lines
3.6 KiB
Zig
const root = @import("@build@");
|
|
const std = @import("std");
|
|
const fmt = std.fmt;
|
|
const io = std.io;
|
|
const log = std.log;
|
|
const process = std.process;
|
|
const Builder = std.build.Builder;
|
|
const Pkg = std.build.Pkg;
|
|
const InstallArtifactStep = std.build.InstallArtifactStep;
|
|
const LibExeObjStep = std.build.LibExeObjStep;
|
|
const ArrayList = std.ArrayList;
|
|
|
|
|
|
///! This is a modified build runner to extract information out of build.zig
|
|
///! Modified from the std.special.build_runner
|
|
pub fn main() !void {
|
|
var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
|
|
defer arena.deinit();
|
|
|
|
const allocator = arena.allocator();
|
|
|
|
var args = try process.argsAlloc(allocator);
|
|
defer process.argsFree(allocator, args);
|
|
|
|
// skip my own exe name
|
|
var arg_idx: usize = 1;
|
|
|
|
const zig_exe = nextArg(args, &arg_idx) orelse {
|
|
log.warn("Expected first argument to be path to zig compiler\n", .{});
|
|
return error.InvalidArgs;
|
|
};
|
|
const build_root = nextArg(args, &arg_idx) orelse {
|
|
log.warn("Expected second argument to be build root directory path\n", .{});
|
|
return error.InvalidArgs;
|
|
};
|
|
const cache_root = nextArg(args, &arg_idx) orelse {
|
|
log.warn("Expected third argument to be cache root directory path\n", .{});
|
|
return error.InvalidArgs;
|
|
};
|
|
const global_cache_root = nextArg(args, &arg_idx) orelse {
|
|
log.warn("Expected third argument to be global cache root directory path\n", .{});
|
|
return error.InvalidArgs;
|
|
};
|
|
|
|
const builder = try Builder.create(
|
|
allocator,
|
|
zig_exe,
|
|
build_root,
|
|
cache_root,
|
|
global_cache_root,
|
|
);
|
|
|
|
defer builder.destroy();
|
|
|
|
builder.resolveInstallPrefix(null, Builder.DirList{});
|
|
try runBuild(builder);
|
|
|
|
const stdout_stream = io.getStdOut().writer();
|
|
|
|
// TODO: We currently add packages from every LibExeObj step that the install step depends on.
|
|
// Should we error out or keep one step or something similar?
|
|
// We also flatten them, we should probably keep the nested structure.
|
|
for (builder.top_level_steps.items) |tls| {
|
|
for (tls.step.dependencies.items) |step| {
|
|
try processStep(stdout_stream, step);
|
|
}
|
|
}
|
|
}
|
|
|
|
fn processStep(stdout_stream: anytype, step: *std.build.Step) anyerror!void {
|
|
if (step.cast(InstallArtifactStep)) |install_exe| {
|
|
for (install_exe.artifact.packages.items) |pkg| {
|
|
try processPackage(stdout_stream, pkg);
|
|
}
|
|
} else if (step.cast(LibExeObjStep)) |exe| {
|
|
for (exe.packages.items) |pkg| {
|
|
try processPackage(stdout_stream, pkg);
|
|
}
|
|
} else {
|
|
for (step.dependencies.items) |unknown_step| {
|
|
try processStep(stdout_stream, unknown_step);
|
|
}
|
|
}
|
|
}
|
|
|
|
fn processPackage(out_stream: anytype, pkg: Pkg) anyerror!void {
|
|
switch (pkg.source) {
|
|
.path => |path| try out_stream.print("{s}\x00{s}\n", .{ pkg.name, path }),
|
|
.generated => |generated| if (generated.path != null) try out_stream.print("{s}\x00{s}\n", .{ pkg.name, generated.path.? }),
|
|
}
|
|
|
|
if (pkg.dependencies) |dependencies| {
|
|
for (dependencies) |dep| {
|
|
try processPackage(out_stream, dep);
|
|
}
|
|
}
|
|
}
|
|
|
|
fn runBuild(builder: *Builder) anyerror!void {
|
|
switch (@typeInfo(@typeInfo(@TypeOf(root.build)).Fn.return_type.?)) {
|
|
.Void => root.build(builder),
|
|
.ErrorUnion => try root.build(builder),
|
|
else => @compileError("expected return type of build to be 'void' or '!void'"),
|
|
}
|
|
}
|
|
|
|
fn nextArg(args: [][]const u8, idx: *usize) ?[]const u8 {
|
|
if (idx.* >= args.len) return null;
|
|
defer idx.* += 1;
|
|
return args[idx.*];
|
|
}
|