mirror of
https://github.com/ziglang/zig.git
synced 2026-01-20 14:25:16 +00:00
extract some logic from std.Build to build_runner.zig
This commit is contained in:
parent
a2c6ecd6dc
commit
c6a895f667
@ -92,23 +92,23 @@ pub fn main() !void {
|
||||
// before arg parsing, check for the NO_COLOR environment variable
|
||||
// if it exists, default the color setting to .off
|
||||
// explicit --color arguments will still override this setting.
|
||||
builder.color = if (std.process.hasEnvVarConstant("NO_COLOR")) .off else .auto;
|
||||
builder.color = if (process.hasEnvVarConstant("NO_COLOR")) .off else .auto;
|
||||
|
||||
while (nextArg(args, &arg_idx)) |arg| {
|
||||
if (mem.startsWith(u8, arg, "-D")) {
|
||||
const option_contents = arg[2..];
|
||||
if (option_contents.len == 0) {
|
||||
std.debug.print("Expected option name after '-D'\n\n", .{});
|
||||
return usageAndErr(builder, false, stderr_stream);
|
||||
usageAndErr(builder, false, stderr_stream);
|
||||
}
|
||||
if (mem.indexOfScalar(u8, option_contents, '=')) |name_end| {
|
||||
const option_name = option_contents[0..name_end];
|
||||
const option_value = option_contents[name_end + 1 ..];
|
||||
if (try builder.addUserInputOption(option_name, option_value))
|
||||
return usageAndErr(builder, false, stderr_stream);
|
||||
usageAndErr(builder, false, stderr_stream);
|
||||
} else {
|
||||
if (try builder.addUserInputFlag(option_contents))
|
||||
return usageAndErr(builder, false, stderr_stream);
|
||||
usageAndErr(builder, false, stderr_stream);
|
||||
}
|
||||
} else if (mem.startsWith(u8, arg, "-")) {
|
||||
if (mem.eql(u8, arg, "--verbose")) {
|
||||
@ -118,61 +118,61 @@ pub fn main() !void {
|
||||
} else if (mem.eql(u8, arg, "-p") or mem.eql(u8, arg, "--prefix")) {
|
||||
install_prefix = nextArg(args, &arg_idx) orelse {
|
||||
std.debug.print("Expected argument after {s}\n\n", .{arg});
|
||||
return usageAndErr(builder, false, stderr_stream);
|
||||
usageAndErr(builder, false, stderr_stream);
|
||||
};
|
||||
} else if (mem.eql(u8, arg, "-l") or mem.eql(u8, arg, "--list-steps")) {
|
||||
return steps(builder, false, stdout_stream);
|
||||
} else if (mem.eql(u8, arg, "--prefix-lib-dir")) {
|
||||
dir_list.lib_dir = nextArg(args, &arg_idx) orelse {
|
||||
std.debug.print("Expected argument after {s}\n\n", .{arg});
|
||||
return usageAndErr(builder, false, stderr_stream);
|
||||
usageAndErr(builder, false, stderr_stream);
|
||||
};
|
||||
} else if (mem.eql(u8, arg, "--prefix-exe-dir")) {
|
||||
dir_list.exe_dir = nextArg(args, &arg_idx) orelse {
|
||||
std.debug.print("Expected argument after {s}\n\n", .{arg});
|
||||
return usageAndErr(builder, false, stderr_stream);
|
||||
usageAndErr(builder, false, stderr_stream);
|
||||
};
|
||||
} else if (mem.eql(u8, arg, "--prefix-include-dir")) {
|
||||
dir_list.include_dir = nextArg(args, &arg_idx) orelse {
|
||||
std.debug.print("Expected argument after {s}\n\n", .{arg});
|
||||
return usageAndErr(builder, false, stderr_stream);
|
||||
usageAndErr(builder, false, stderr_stream);
|
||||
};
|
||||
} else if (mem.eql(u8, arg, "--sysroot")) {
|
||||
const sysroot = nextArg(args, &arg_idx) orelse {
|
||||
std.debug.print("Expected argument after --sysroot\n\n", .{});
|
||||
return usageAndErr(builder, false, stderr_stream);
|
||||
usageAndErr(builder, false, stderr_stream);
|
||||
};
|
||||
builder.sysroot = sysroot;
|
||||
} else if (mem.eql(u8, arg, "--search-prefix")) {
|
||||
const search_prefix = nextArg(args, &arg_idx) orelse {
|
||||
std.debug.print("Expected argument after --search-prefix\n\n", .{});
|
||||
return usageAndErr(builder, false, stderr_stream);
|
||||
usageAndErr(builder, false, stderr_stream);
|
||||
};
|
||||
builder.addSearchPrefix(search_prefix);
|
||||
} else if (mem.eql(u8, arg, "--libc")) {
|
||||
const libc_file = nextArg(args, &arg_idx) orelse {
|
||||
std.debug.print("Expected argument after --libc\n\n", .{});
|
||||
return usageAndErr(builder, false, stderr_stream);
|
||||
usageAndErr(builder, false, stderr_stream);
|
||||
};
|
||||
builder.libc_file = libc_file;
|
||||
} else if (mem.eql(u8, arg, "--color")) {
|
||||
const next_arg = nextArg(args, &arg_idx) orelse {
|
||||
std.debug.print("expected [auto|on|off] after --color", .{});
|
||||
return usageAndErr(builder, false, stderr_stream);
|
||||
usageAndErr(builder, false, stderr_stream);
|
||||
};
|
||||
builder.color = std.meta.stringToEnum(@TypeOf(builder.color), next_arg) orelse {
|
||||
std.debug.print("expected [auto|on|off] after --color, found '{s}'", .{next_arg});
|
||||
return usageAndErr(builder, false, stderr_stream);
|
||||
usageAndErr(builder, false, stderr_stream);
|
||||
};
|
||||
} else if (mem.eql(u8, arg, "--zig-lib-dir")) {
|
||||
builder.zig_lib_dir = nextArg(args, &arg_idx) orelse {
|
||||
std.debug.print("Expected argument after --zig-lib-dir\n\n", .{});
|
||||
return usageAndErr(builder, false, stderr_stream);
|
||||
usageAndErr(builder, false, stderr_stream);
|
||||
};
|
||||
} else if (mem.eql(u8, arg, "--debug-log")) {
|
||||
const next_arg = nextArg(args, &arg_idx) orelse {
|
||||
std.debug.print("Expected argument after {s}\n\n", .{arg});
|
||||
return usageAndErr(builder, false, stderr_stream);
|
||||
usageAndErr(builder, false, stderr_stream);
|
||||
};
|
||||
try debug_log_scopes.append(next_arg);
|
||||
} else if (mem.eql(u8, arg, "--debug-compile-errors")) {
|
||||
@ -180,7 +180,7 @@ pub fn main() !void {
|
||||
} else if (mem.eql(u8, arg, "--glibc-runtimes")) {
|
||||
builder.glibc_runtimes_dir = nextArg(args, &arg_idx) orelse {
|
||||
std.debug.print("Expected argument after --glibc-runtimes\n\n", .{});
|
||||
return usageAndErr(builder, false, stderr_stream);
|
||||
usageAndErr(builder, false, stderr_stream);
|
||||
};
|
||||
} else if (mem.eql(u8, arg, "--verbose-link")) {
|
||||
builder.verbose_link = true;
|
||||
@ -231,7 +231,7 @@ pub fn main() !void {
|
||||
break;
|
||||
} else {
|
||||
std.debug.print("Unrecognized argument: {s}\n\n", .{arg});
|
||||
return usageAndErr(builder, false, stderr_stream);
|
||||
usageAndErr(builder, false, stderr_stream);
|
||||
}
|
||||
} else {
|
||||
try targets.append(arg);
|
||||
@ -243,13 +243,10 @@ pub fn main() !void {
|
||||
try builder.runBuild(root);
|
||||
|
||||
if (builder.validateUserInputDidItFail())
|
||||
return usageAndErr(builder, true, stderr_stream);
|
||||
usageAndErr(builder, true, stderr_stream);
|
||||
|
||||
builder.make(targets.items) catch |err| {
|
||||
make(builder, targets.items) catch |err| {
|
||||
switch (err) {
|
||||
error.InvalidStepName => {
|
||||
return usageAndErr(builder, true, stderr_stream);
|
||||
},
|
||||
error.UncleanExit => process.exit(1),
|
||||
// This error is intended to indicate that the step has already
|
||||
// logged an error message and so printing the error return trace
|
||||
@ -261,6 +258,48 @@ pub fn main() !void {
|
||||
};
|
||||
}
|
||||
|
||||
fn make(b: *std.Build, step_names: []const []const u8) !void {
|
||||
var wanted_steps = ArrayList(*std.Build.Step).init(b.allocator);
|
||||
defer wanted_steps.deinit();
|
||||
|
||||
if (step_names.len == 0) {
|
||||
try wanted_steps.append(b.default_step);
|
||||
} else {
|
||||
for (step_names) |step_name| {
|
||||
const s = b.top_level_steps.get(step_name) orelse {
|
||||
std.debug.print("no step named '{s}'. Access the help menu with 'zig build -h'\n", .{step_name});
|
||||
process.exit(1);
|
||||
};
|
||||
try wanted_steps.append(&s.step);
|
||||
}
|
||||
}
|
||||
|
||||
for (wanted_steps.items) |s| {
|
||||
try makeOneStep(b, s);
|
||||
}
|
||||
}
|
||||
|
||||
fn makeOneStep(b: *std.Build, s: *std.Build.Step) anyerror!void {
|
||||
if (s.loop_flag) {
|
||||
std.debug.print("dependency loop detected:\n {s}\n", .{s.name});
|
||||
return error.DependencyLoopDetected;
|
||||
}
|
||||
s.loop_flag = true;
|
||||
|
||||
for (s.dependencies.items) |dep| {
|
||||
makeOneStep(b, dep) catch |err| {
|
||||
if (err == error.DependencyLoopDetected) {
|
||||
std.debug.print(" {s}\n", .{s.name});
|
||||
}
|
||||
return err;
|
||||
};
|
||||
}
|
||||
|
||||
s.loop_flag = false;
|
||||
|
||||
try s.make();
|
||||
}
|
||||
|
||||
fn steps(builder: *std.Build, already_ran_build: bool, out_stream: anytype) !void {
|
||||
// run the build script to collect the options
|
||||
if (!already_ran_build) {
|
||||
@ -269,7 +308,7 @@ fn steps(builder: *std.Build, already_ran_build: bool, out_stream: anytype) !voi
|
||||
}
|
||||
|
||||
const allocator = builder.allocator;
|
||||
for (builder.top_level_steps.items) |top_level_step| {
|
||||
for (builder.top_level_steps.values()) |top_level_step| {
|
||||
const name = if (&top_level_step.step == builder.default_step)
|
||||
try fmt.allocPrint(allocator, "{s} (default)", .{top_level_step.step.name})
|
||||
else
|
||||
@ -374,7 +413,7 @@ fn usage(builder: *std.Build, already_ran_build: bool, out_stream: anytype) !voi
|
||||
);
|
||||
}
|
||||
|
||||
fn usageAndErr(builder: *std.Build, already_ran_build: bool, out_stream: anytype) void {
|
||||
fn usageAndErr(builder: *std.Build, already_ran_build: bool, out_stream: anytype) noreturn {
|
||||
usage(builder, already_ran_build, out_stream) catch {};
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
@ -67,7 +67,7 @@ invalid_user_input: bool,
|
||||
zig_exe: []const u8,
|
||||
default_step: *Step,
|
||||
env_map: *EnvMap,
|
||||
top_level_steps: ArrayList(*TopLevelStep),
|
||||
top_level_steps: std.StringArrayHashMapUnmanaged(*TopLevelStep),
|
||||
install_prefix: []const u8,
|
||||
dest_dir: ?[]const u8,
|
||||
lib_dir: []const u8,
|
||||
@ -217,7 +217,7 @@ pub fn create(
|
||||
.user_input_options = UserInputOptionsMap.init(allocator),
|
||||
.available_options_map = AvailableOptionsMap.init(allocator),
|
||||
.available_options_list = ArrayList(AvailableOption).init(allocator),
|
||||
.top_level_steps = ArrayList(*TopLevelStep).init(allocator),
|
||||
.top_level_steps = .{},
|
||||
.default_step = undefined,
|
||||
.env_map = env_map,
|
||||
.search_prefixes = ArrayList([]const u8).init(allocator),
|
||||
@ -241,8 +241,8 @@ pub fn create(
|
||||
.host = host,
|
||||
.modules = std.StringArrayHashMap(*Module).init(allocator),
|
||||
};
|
||||
try self.top_level_steps.append(&self.install_tls);
|
||||
try self.top_level_steps.append(&self.uninstall_tls);
|
||||
try self.top_level_steps.put(allocator, self.install_tls.step.name, &self.install_tls);
|
||||
try self.top_level_steps.put(allocator, self.uninstall_tls.step.name, &self.uninstall_tls);
|
||||
self.default_step = &self.install_tls.step;
|
||||
return self;
|
||||
}
|
||||
@ -288,7 +288,7 @@ fn createChildOnly(parent: *Build, dep_name: []const u8, build_root: Cache.Direc
|
||||
.zig_exe = parent.zig_exe,
|
||||
.default_step = undefined,
|
||||
.env_map = parent.env_map,
|
||||
.top_level_steps = ArrayList(*TopLevelStep).init(allocator),
|
||||
.top_level_steps = .{},
|
||||
.install_prefix = undefined,
|
||||
.dest_dir = parent.dest_dir,
|
||||
.lib_dir = parent.lib_dir,
|
||||
@ -316,8 +316,8 @@ fn createChildOnly(parent: *Build, dep_name: []const u8, build_root: Cache.Direc
|
||||
.dep_prefix = parent.fmt("{s}{s}.", .{ parent.dep_prefix, dep_name }),
|
||||
.modules = std.StringArrayHashMap(*Module).init(allocator),
|
||||
};
|
||||
try child.top_level_steps.append(&child.install_tls);
|
||||
try child.top_level_steps.append(&child.uninstall_tls);
|
||||
try child.top_level_steps.put(allocator, child.install_tls.step.name, &child.install_tls);
|
||||
try child.top_level_steps.put(allocator, child.uninstall_tls.step.name, &child.uninstall_tls);
|
||||
child.default_step = &child.install_tls.step;
|
||||
return child;
|
||||
}
|
||||
@ -389,10 +389,10 @@ fn applyArgs(b: *Build, args: anytype) !void {
|
||||
b.resolveInstallPrefix(install_prefix, .{});
|
||||
}
|
||||
|
||||
pub fn destroy(self: *Build) void {
|
||||
self.env_map.deinit();
|
||||
self.top_level_steps.deinit();
|
||||
self.allocator.destroy(self);
|
||||
pub fn destroy(b: *Build) void {
|
||||
b.env_map.deinit();
|
||||
b.top_level_steps.deinit(b.allocator);
|
||||
b.allocator.destroy(b);
|
||||
}
|
||||
|
||||
/// This function is intended to be called by lib/build_runner.zig, not a build.zig file.
|
||||
@ -698,24 +698,6 @@ pub fn addTranslateC(self: *Build, options: TranslateCStep.Options) *TranslateCS
|
||||
return TranslateCStep.create(self, options);
|
||||
}
|
||||
|
||||
pub fn make(self: *Build, step_names: []const []const u8) !void {
|
||||
var wanted_steps = ArrayList(*Step).init(self.allocator);
|
||||
defer wanted_steps.deinit();
|
||||
|
||||
if (step_names.len == 0) {
|
||||
try wanted_steps.append(self.default_step);
|
||||
} else {
|
||||
for (step_names) |step_name| {
|
||||
const s = try self.getTopLevelStepByName(step_name);
|
||||
try wanted_steps.append(s);
|
||||
}
|
||||
}
|
||||
|
||||
for (wanted_steps.items) |s| {
|
||||
try self.makeOneStep(s);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn getInstallStep(self: *Build) *Step {
|
||||
return &self.install_tls.step;
|
||||
}
|
||||
@ -739,37 +721,6 @@ fn makeUninstall(uninstall_step: *Step) anyerror!void {
|
||||
// TODO remove empty directories
|
||||
}
|
||||
|
||||
fn makeOneStep(self: *Build, s: *Step) anyerror!void {
|
||||
if (s.loop_flag) {
|
||||
log.err("Dependency loop detected:\n {s}", .{s.name});
|
||||
return error.DependencyLoopDetected;
|
||||
}
|
||||
s.loop_flag = true;
|
||||
|
||||
for (s.dependencies.items) |dep| {
|
||||
self.makeOneStep(dep) catch |err| {
|
||||
if (err == error.DependencyLoopDetected) {
|
||||
log.err(" {s}", .{s.name});
|
||||
}
|
||||
return err;
|
||||
};
|
||||
}
|
||||
|
||||
s.loop_flag = false;
|
||||
|
||||
try s.make();
|
||||
}
|
||||
|
||||
fn getTopLevelStepByName(self: *Build, name: []const u8) !*Step {
|
||||
for (self.top_level_steps.items) |top_level_step| {
|
||||
if (mem.eql(u8, top_level_step.step.name, name)) {
|
||||
return &top_level_step.step;
|
||||
}
|
||||
}
|
||||
log.err("Cannot run step '{s}' because it does not exist", .{name});
|
||||
return error.InvalidStepName;
|
||||
}
|
||||
|
||||
pub fn option(self: *Build, comptime T: type, name_raw: []const u8, description_raw: []const u8) ?T {
|
||||
const name = self.dupe(name_raw);
|
||||
const description = self.dupe(description_raw);
|
||||
@ -910,7 +861,7 @@ pub fn step(self: *Build, name: []const u8, description: []const u8) *Step {
|
||||
.step = Step.initNoOp(.top_level, name, self.allocator),
|
||||
.description = self.dupe(description),
|
||||
};
|
||||
self.top_level_steps.append(step_info) catch @panic("OOM");
|
||||
self.top_level_steps.put(self.allocator, step_info.step.name, step_info) catch @panic("OOM");
|
||||
return &step_info.step;
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user