diff --git a/lib/build_runner.zig b/lib/build_runner.zig index bcefa350d3..2fd8ecd034 100644 --- a/lib/build_runner.zig +++ b/lib/build_runner.zig @@ -131,6 +131,15 @@ pub fn main() !void { } else if (mem.startsWith(u8, arg, "-fno-sys=")) { const name = arg["-fno-sys=".len..]; graph.system_library_options.put(arena, name, .user_disabled) catch @panic("OOM"); + } else if (mem.eql(u8, arg, "--release")) { + builder.release_mode = .any; + } else if (mem.startsWith(u8, arg, "--release=")) { + const text = arg["--release=".len..]; + builder.release_mode = std.meta.stringToEnum(std.Build.ReleaseMode, text) orelse { + fatalWithHint("expected [off|any|fast|safe|small] in '{s}', found '{s}'", .{ + arg, text, + }); + }; } else if (mem.eql(u8, arg, "--host-target")) { graph.host_query_options.arch_os_abi = nextArgOrFatal(args, &arg_idx); } else if (mem.eql(u8, arg, "--host-cpu")) { @@ -1049,6 +1058,9 @@ fn usage(b: *std.Build, out_stream: anytype) !void { \\ --prefix-exe-dir [path] Where to put installed executables \\ --prefix-include-dir [path] Where to put installed C header files \\ + \\ --release[=mode] Request release mode, optionally specifying a + \\ preferred optimization mode: fast, safe, small + \\ \\ --sysroot [path] Set the system root directory (usually /) \\ --search-prefix [path] Add a path to look for binaries, libraries, headers \\ --libc [file] Provide a file which specifies libc paths diff --git a/lib/std/Build.zig b/lib/std/Build.zig index 8105b7330d..6bdd391430 100644 --- a/lib/std/Build.zig +++ b/lib/std/Build.zig @@ -96,6 +96,16 @@ initialized_deps: *InitializedDepMap, /// A mapping from dependency names to package hashes. available_deps: AvailableDeps, +release_mode: ReleaseMode, + +pub const ReleaseMode = enum { + off, + any, + fast, + safe, + small, +}; + /// Shared state among all Build instances. /// Settings that are here rather than in Build are not configurable per-package. pub const Graph = struct { @@ -295,6 +305,7 @@ pub fn create( .named_writefiles = std.StringArrayHashMap(*Step.WriteFile).init(arena), .initialized_deps = initialized_deps, .available_deps = available_deps, + .release_mode = .off, }; try self.top_level_steps.put(arena, self.install_tls.step.name, &self.install_tls); try self.top_level_steps.put(arena, self.uninstall_tls.step.name, &self.uninstall_tls); @@ -386,6 +397,7 @@ fn createChildOnly( .named_writefiles = std.StringArrayHashMap(*Step.WriteFile).init(allocator), .initialized_deps = parent.initialized_deps, .available_deps = pkg_deps, + .release_mode = parent.release_mode, }; 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); @@ -1230,20 +1242,33 @@ pub const StandardOptimizeOptionOptions = struct { preferred_optimize_mode: ?std.builtin.OptimizeMode = null, }; -pub fn standardOptimizeOption(self: *Build, options: StandardOptimizeOptionOptions) std.builtin.OptimizeMode { +pub fn standardOptimizeOption(b: *Build, options: StandardOptimizeOptionOptions) std.builtin.OptimizeMode { if (options.preferred_optimize_mode) |mode| { - if (self.option(bool, "release", "optimize for end users") orelse false) { + if (b.option(bool, "release", "optimize for end users") orelse (b.release_mode != .off)) { return mode; } else { return .Debug; } - } else { - return self.option( - std.builtin.OptimizeMode, - "optimize", - "Prioritize performance, safety, or binary size (-O flag)", - ) orelse .Debug; } + + if (b.option( + std.builtin.OptimizeMode, + "optimize", + "Prioritize performance, safety, or binary size (-O flag)", + )) |mode| { + return mode; + } + + return switch (b.release_mode) { + .off => .Debug, + .any => { + std.debug.print("the project does not declare a preferred optimization mode. choose: --release=fast, --release=safe, or --release=small\n", .{}); + process.exit(1); + }, + .fast => .ReleaseFast, + .safe => .ReleaseSafe, + .small => .ReleaseSmall, + }; } pub const StandardTargetOptionsArgs = struct {