From bb88f7bc4e2d23ccd141c3edfbd77aa44ba68b78 Mon Sep 17 00:00:00 2001 From: Kendall Condon Date: Sun, 23 Nov 2025 13:54:13 -0500 Subject: [PATCH] allow specifying mode in --debug-rt The motivation is that libfuzzer is slow in Debug mode and bugs usually manifest late into fuzzing, which makes testing it in ReleaseSafe useful. --- lib/compiler/build_runner.zig | 6 +++++- lib/std/Build.zig | 2 +- lib/std/Build/Step/Compile.zig | 3 ++- src/Compilation.zig | 11 ++++++----- src/main.zig | 9 ++++++--- 5 files changed, 20 insertions(+), 11 deletions(-) diff --git a/lib/compiler/build_runner.zig b/lib/compiler/build_runner.zig index e5eb5eec67..c3219e1278 100644 --- a/lib/compiler/build_runner.zig +++ b/lib/compiler/build_runner.zig @@ -304,7 +304,11 @@ pub fn main() !void { } else if (mem.eql(u8, arg, "--debug-pkg-config")) { builder.debug_pkg_config = true; } else if (mem.eql(u8, arg, "--debug-rt")) { - graph.debug_compiler_runtime_libs = true; + graph.debug_compiler_runtime_libs = .Debug; + } else if (mem.cutPrefix(u8, arg, "--debug-rt=")) |rest| { + graph.debug_compiler_runtime_libs = + std.meta.stringToEnum(std.builtin.OptimizeMode, rest) orelse + fatal("unrecognized optimization mode: '{s}'", .{rest}); } else if (mem.eql(u8, arg, "--debug-compile-errors")) { builder.debug_compile_errors = true; } else if (mem.eql(u8, arg, "--debug-incremental")) { diff --git a/lib/std/Build.zig b/lib/std/Build.zig index 25d1ff6d95..b843626120 100644 --- a/lib/std/Build.zig +++ b/lib/std/Build.zig @@ -116,7 +116,7 @@ pub const Graph = struct { arena: Allocator, system_library_options: std.StringArrayHashMapUnmanaged(SystemLibraryMode) = .empty, system_package_mode: bool = false, - debug_compiler_runtime_libs: bool = false, + debug_compiler_runtime_libs: ?std.builtin.OptimizeMode = null, cache: Cache, zig_exe: [:0]const u8, env_map: EnvMap, diff --git a/lib/std/Build/Step/Compile.zig b/lib/std/Build/Step/Compile.zig index 4f9900ab59..3e5bc23cb9 100644 --- a/lib/std/Build/Step/Compile.zig +++ b/lib/std/Build/Step/Compile.zig @@ -1572,7 +1572,8 @@ fn getZigArgs(compile: *Compile, fuzz: bool) ![][]const u8 { try zig_args.append("--global-cache-dir"); try zig_args.append(b.graph.global_cache_root.path orelse "."); - if (b.graph.debug_compiler_runtime_libs) try zig_args.append("--debug-rt"); + if (b.graph.debug_compiler_runtime_libs) |mode| + try zig_args.append(b.fmt("--debug-rt={t}", .{mode})); try zig_args.append("--name"); try zig_args.append(compile.name); diff --git a/src/Compilation.zig b/src/Compilation.zig index c76bcc37ea..25521e054a 100644 --- a/src/Compilation.zig +++ b/src/Compilation.zig @@ -175,7 +175,7 @@ verbose_llvm_cpu_features: bool, verbose_link: bool, disable_c_depfile: bool, stack_report: bool, -debug_compiler_runtime_libs: bool, +debug_compiler_runtime_libs: ?std.builtin.OptimizeMode, debug_compile_errors: bool, /// Do not check this field directly. Instead, use the `debugIncremental` wrapper function. debug_incremental: bool, @@ -1734,7 +1734,7 @@ pub const CreateOptions = struct { verbose_llvm_bc: ?[]const u8 = null, verbose_cimport: bool = false, verbose_llvm_cpu_features: bool = false, - debug_compiler_runtime_libs: bool = false, + debug_compiler_runtime_libs: ?std.builtin.OptimizeMode = null, debug_compile_errors: bool = false, debug_incremental: bool = false, /// Normally when you create a `Compilation`, Zig will automatically build @@ -2134,7 +2134,8 @@ pub fn create(gpa: Allocator, arena: Allocator, io: Io, diag: *CreateDiagnostic, cache.hash.addBytes(options.root_name); cache.hash.add(options.config.wasi_exec_model); cache.hash.add(options.config.san_cov_trace_pc_guard); - cache.hash.add(options.debug_compiler_runtime_libs); + cache.hash.add(options.debug_compiler_runtime_libs != null); + if (options.debug_compiler_runtime_libs) |mode| cache.hash.add(mode); // The actual emit paths don't matter. They're only user-specified if we aren't using the // cache! However, it does matter whether the files are emitted at all. cache.hash.add(options.emit_bin != .no); @@ -8152,8 +8153,8 @@ pub fn addLinkLib(comp: *Compilation, lib_name: []const u8) !void { /// This decides the optimization mode for all zig-provided libraries, including /// compiler-rt, libcxx, libc, libunwind, etc. pub fn compilerRtOptMode(comp: Compilation) std.builtin.OptimizeMode { - if (comp.debug_compiler_runtime_libs) { - return .Debug; + if (comp.debug_compiler_runtime_libs) |mode| { + return mode; } const target = &comp.root_mod.resolved_target.result; switch (comp.root_mod.optimize_mode) { diff --git a/src/main.zig b/src/main.zig index 8199f2d405..d7e1441225 100644 --- a/src/main.zig +++ b/src/main.zig @@ -678,7 +678,8 @@ const usage_build_generic = \\ --debug-log [scope] Enable printing debug/info log messages for scope \\ --debug-compile-errors Crash with helpful diagnostics at the first compile error \\ --debug-link-snapshot Enable dumping of the linker's state in JSON format - \\ --debug-rt Debug compiler runtime libraries + \\ --debug-rt[=mode] Build compiler runtime libraries with [mode] optimization + \\ (Debug if [=mode] is omitted) \\ --debug-incremental Enable incremental compilation debug features \\ ; @@ -895,7 +896,7 @@ fn buildOutputType( var minor_subsystem_version: ?u16 = null; var mingw_unicode_entry_point: bool = false; var enable_link_snapshots: bool = false; - var debug_compiler_runtime_libs = false; + var debug_compiler_runtime_libs: ?std.builtin.OptimizeMode = null; var install_name: ?[]const u8 = null; var hash_style: link.File.Lld.Elf.HashStyle = .both; var entitlements: ?[]const u8 = null; @@ -1350,7 +1351,9 @@ fn buildOutputType( enable_link_snapshots = true; } } else if (mem.eql(u8, arg, "--debug-rt")) { - debug_compiler_runtime_libs = true; + debug_compiler_runtime_libs = .Debug; + } else if (mem.cutPrefix(u8, arg, "--debug-rt=")) |rest| { + debug_compiler_runtime_libs = parseOptimizeMode(rest); } else if (mem.eql(u8, arg, "--debug-incremental")) { if (build_options.enable_debug_extensions) { debug_incremental = true;