diff --git a/build.zig b/build.zig index a5e430fb01..51089664ad 100644 --- a/build.zig +++ b/build.zig @@ -77,6 +77,9 @@ pub fn build(b: *Builder) !void { const link_libc = b.option(bool, "force-link-libc", "Force self-hosted compiler to link libc") orelse false; if (link_libc) exe.linkLibC(); + const log_scopes = b.option([]const []const u8, "log", "Which log scopes to enable") orelse &[0][]const u8{}; + + exe.addBuildOption([]const []const u8, "log_scopes", log_scopes); exe.addBuildOption(bool, "enable_tracy", tracy != null); if (tracy) |tracy_path| { const client_cpp = fs.path.join( diff --git a/lib/std/build.zig b/lib/std/build.zig index 103d3a3193..c85534ba7d 100644 --- a/lib/std/build.zig +++ b/lib/std/build.zig @@ -430,9 +430,9 @@ pub const Builder = struct { const entry = self.user_input_options.getEntry(name) orelse return null; entry.value.used = true; switch (type_id) { - TypeId.Bool => switch (entry.value.value) { - UserValue.Flag => return true, - UserValue.Scalar => |s| { + .Bool => switch (entry.value.value) { + .Flag => return true, + .Scalar => |s| { if (mem.eql(u8, s, "true")) { return true; } else if (mem.eql(u8, s, "false")) { @@ -443,21 +443,21 @@ pub const Builder = struct { return null; } }, - UserValue.List => { + .List => { warn("Expected -D{} to be a boolean, but received a list.\n", .{name}); self.markInvalidUserInput(); return null; }, }, - TypeId.Int => panic("TODO integer options to build script", .{}), - TypeId.Float => panic("TODO float options to build script", .{}), - TypeId.Enum => switch (entry.value.value) { - UserValue.Flag => { + .Int => panic("TODO integer options to build script", .{}), + .Float => panic("TODO float options to build script", .{}), + .Enum => switch (entry.value.value) { + .Flag => { warn("Expected -D{} to be a string, but received a boolean.\n", .{name}); self.markInvalidUserInput(); return null; }, - UserValue.Scalar => |s| { + .Scalar => |s| { if (std.meta.stringToEnum(T, s)) |enum_lit| { return enum_lit; } else { @@ -466,33 +466,35 @@ pub const Builder = struct { return null; } }, - UserValue.List => { + .List => { warn("Expected -D{} to be a string, but received a list.\n", .{name}); self.markInvalidUserInput(); return null; }, }, - TypeId.String => switch (entry.value.value) { - UserValue.Flag => { + .String => switch (entry.value.value) { + .Flag => { warn("Expected -D{} to be a string, but received a boolean.\n", .{name}); self.markInvalidUserInput(); return null; }, - UserValue.List => { + .List => { warn("Expected -D{} to be a string, but received a list.\n", .{name}); self.markInvalidUserInput(); return null; }, - UserValue.Scalar => |s| return s, + .Scalar => |s| return s, }, - TypeId.List => switch (entry.value.value) { - UserValue.Flag => { + .List => switch (entry.value.value) { + .Flag => { warn("Expected -D{} to be a list, but received a boolean.\n", .{name}); self.markInvalidUserInput(); return null; }, - UserValue.Scalar => |s| return &[_][]const u8{s}, - UserValue.List => |lst| return lst.span(), + .Scalar => |s| { + return self.allocator.dupe([]const u8, &[_][]const u8{s}) catch unreachable; + }, + .List => |lst| return lst.span(), }, } } @@ -1706,9 +1708,19 @@ pub const LibExeObjStep = struct { pub fn addBuildOption(self: *LibExeObjStep, comptime T: type, name: []const u8, value: T) void { const out = self.build_options_contents.outStream(); + if (T == []const []const u8) { + out.print("pub const {}: []const []const u8 = &[_][]const u8{{\n", .{name}) catch unreachable; + for (value) |slice| { + out.writeAll(" ") catch unreachable; + std.zig.renderStringLiteral(slice, out) catch unreachable; + out.writeAll(",\n") catch unreachable; + } + out.writeAll("};\n") catch unreachable; + return; + } switch (@typeInfo(T)) { .Enum => |enum_info| { - out.print("const {} = enum {{\n", .{@typeName(T)}) catch unreachable; + out.print("pub const {} = enum {{\n", .{@typeName(T)}) catch unreachable; inline for (enum_info.fields) |field| { out.print(" {},\n", .{field.name}) catch unreachable; } diff --git a/src-self-hosted/Module.zig b/src-self-hosted/Module.zig index d6cc35b2b6..0eb79e92ed 100644 --- a/src-self-hosted/Module.zig +++ b/src-self-hosted/Module.zig @@ -6,6 +6,7 @@ const Value = @import("value.zig").Value; const Type = @import("type.zig").Type; const TypedValue = @import("TypedValue.zig"); const assert = std.debug.assert; +const log = std.log; const BigIntConst = std.math.big.int.Const; const BigIntMutable = std.math.big.int.Mutable; const Target = std.Target; @@ -235,7 +236,7 @@ pub const Decl = struct { pub fn dump(self: *Decl) void { const loc = std.zig.findLineColumn(self.scope.source.bytes, self.src); - std.debug.warn("{}:{}:{} name={} status={}", .{ + std.debug.print("{}:{}:{} name={} status={}", .{ self.scope.sub_file_path, loc.line + 1, loc.column + 1, @@ -243,9 +244,9 @@ pub const Decl = struct { @tagName(self.analysis), }); if (self.typedValueManaged()) |tvm| { - std.debug.warn(" ty={} val={}", .{ tvm.typed_value.ty, tvm.typed_value.val }); + std.debug.print(" ty={} val={}", .{ tvm.typed_value.ty, tvm.typed_value.val }); } - std.debug.warn("\n", .{}); + std.debug.print("\n", .{}); } pub fn typedValueManaged(self: *Decl) ?*TypedValue.Managed { @@ -544,7 +545,7 @@ pub const Scope = struct { pub fn dumpSrc(self: *File, src: usize) void { const loc = std.zig.findLineColumn(self.source.bytes, src); - std.debug.warn("{}:{}:{}\n", .{ self.sub_file_path, loc.line + 1, loc.column + 1 }); + std.debug.print("{}:{}:{}\n", .{ self.sub_file_path, loc.line + 1, loc.column + 1 }); } pub fn getSource(self: *File, module: *Module) ![:0]const u8 { @@ -646,7 +647,7 @@ pub const Scope = struct { pub fn dumpSrc(self: *ZIRModule, src: usize) void { const loc = std.zig.findLineColumn(self.source.bytes, src); - std.debug.warn("{}:{}:{}\n", .{ self.sub_file_path, loc.line + 1, loc.column + 1 }); + std.debug.print("{}:{}:{}\n", .{ self.sub_file_path, loc.line + 1, loc.column + 1 }); } pub fn getSource(self: *ZIRModule, module: *Module) ![:0]const u8 { @@ -946,7 +947,6 @@ pub fn update(self: *Module) !void { } self.link_error_flags = self.bin_file.errorFlags(); - std.log.debug(.module, "link_error_flags: {}\n", .{self.link_error_flags}); // If there are any errors, we anticipate the source files being loaded // to report error messages. Otherwise we unload all source files to save memory. @@ -1109,7 +1109,7 @@ pub fn ensureDeclAnalyzed(self: *Module, decl: *Decl) InnerError!void { assert(decl.analysis == .complete); return; } - //std.debug.warn("re-analyzing {}\n", .{decl.name}); + log.debug(.module, "re-analyzing {}\n", .{decl.name}); // The exports this Decl performs will be re-discovered, so we remove them here // prior to re-analysis. @@ -1546,7 +1546,7 @@ fn analyzeRootSrcFile(self: *Module, root_scope: *Scope.File) !void { // Handle explicitly deleted decls from the source code. Not to be confused // with when we delete decls because they are no longer referenced. for (deleted_decls.items()) |entry| { - //std.debug.warn("noticed '{}' deleted from source\n", .{entry.key.name}); + log.debug(.module, "noticed '{}' deleted from source\n", .{entry.key.name}); try self.deleteDecl(entry.key); } } @@ -1575,7 +1575,6 @@ fn analyzeRootZIRModule(self: *Module, root_scope: *Scope.ZIRModule) !void { const name_hash = root_scope.fullyQualifiedNameHash(src_decl.name); if (self.decl_table.get(name_hash)) |decl| { deleted_decls.removeAssertDiscard(decl); - //std.debug.warn("'{}' contents: '{}'\n", .{ src_decl.name, src_decl.contents }); if (!srcHashEql(src_decl.contents_hash, decl.contents_hash)) { try self.markOutdatedDecl(decl); decl.contents_hash = src_decl.contents_hash; @@ -1600,7 +1599,7 @@ fn analyzeRootZIRModule(self: *Module, root_scope: *Scope.ZIRModule) !void { // Handle explicitly deleted decls from the source code. Not to be confused // with when we delete decls because they are no longer referenced. for (deleted_decls.items()) |entry| { - //std.debug.warn("noticed '{}' deleted from source\n", .{entry.key.name}); + log.debug(.module, "noticed '{}' deleted from source\n", .{entry.key.name}); try self.deleteDecl(entry.key); } } @@ -1612,7 +1611,7 @@ fn deleteDecl(self: *Module, decl: *Decl) !void { // not be present in the set, and this does nothing. decl.scope.removeDecl(decl); - //std.debug.warn("deleting decl '{}'\n", .{decl.name}); + log.debug(.module, "deleting decl '{}'\n", .{decl.name}); const name_hash = decl.fullyQualifiedNameHash(); self.decl_table.removeAssertDiscard(name_hash); // Remove itself from its dependencies, because we are about to destroy the decl pointer. @@ -1698,17 +1697,17 @@ fn analyzeFnBody(self: *Module, decl: *Decl, func: *Fn) !void { const fn_zir = func.analysis.queued; defer fn_zir.arena.promote(self.gpa).deinit(); func.analysis = .{ .in_progress = {} }; - //std.debug.warn("set {} to in_progress\n", .{decl.name}); + log.debug(.module, "set {} to in_progress\n", .{decl.name}); try zir_sema.analyzeBody(self, &inner_block.base, fn_zir.body); const instructions = try arena.allocator.dupe(*Inst, inner_block.instructions.items); func.analysis = .{ .success = .{ .instructions = instructions } }; - //std.debug.warn("set {} to success\n", .{decl.name}); + log.debug(.module, "set {} to success\n", .{decl.name}); } fn markOutdatedDecl(self: *Module, decl: *Decl) !void { - //std.debug.warn("mark {} outdated\n", .{decl.name}); + log.debug(.module, "mark {} outdated\n", .{decl.name}); try self.work_queue.writeItem(.{ .analyze_decl = decl }); if (self.failed_decls.remove(decl)) |entry| { entry.value.destroy(self.gpa); @@ -2817,7 +2816,7 @@ pub fn dumpInst(self: *Module, scope: *Scope, inst: *Inst) void { const source = zir_module.getSource(self) catch @panic("dumpInst failed to get source"); const loc = std.zig.findLineColumn(source, inst.src); if (inst.tag == .constant) { - std.debug.warn("constant ty={} val={} src={}:{}:{}\n", .{ + std.debug.print("constant ty={} val={} src={}:{}:{}\n", .{ inst.ty, inst.castTag(.constant).?.val, zir_module.subFilePath(), @@ -2825,7 +2824,7 @@ pub fn dumpInst(self: *Module, scope: *Scope, inst: *Inst) void { loc.column + 1, }); } else if (inst.deaths == 0) { - std.debug.warn("{} ty={} src={}:{}:{}\n", .{ + std.debug.print("{} ty={} src={}:{}:{}\n", .{ @tagName(inst.tag), inst.ty, zir_module.subFilePath(), @@ -2833,7 +2832,7 @@ pub fn dumpInst(self: *Module, scope: *Scope, inst: *Inst) void { loc.column + 1, }); } else { - std.debug.warn("{} ty={} deaths={b} src={}:{}:{}\n", .{ + std.debug.print("{} ty={} deaths={b} src={}:{}:{}\n", .{ @tagName(inst.tag), inst.ty, inst.deaths, diff --git a/src-self-hosted/main.zig b/src-self-hosted/main.zig index 4c5d433f05..8b545ab546 100644 --- a/src-self-hosted/main.zig +++ b/src-self-hosted/main.zig @@ -10,9 +10,7 @@ const Module = @import("Module.zig"); const link = @import("link.zig"); const Package = @import("Package.zig"); const zir = @import("zir.zig"); - -// TODO Improve async I/O enough that we feel comfortable doing this. -//pub const io_mode = .evented; +const build_options = @import("build_options"); pub const max_src_size = 2 * 1024 * 1024 * 1024; // 2 GiB @@ -47,18 +45,16 @@ pub fn log( if (@enumToInt(level) > @enumToInt(std.log.level)) return; - const scope_prefix = "(" ++ switch (scope) { - // Uncomment to hide logs - //.compiler, - .module, - .liveness, - .link, - => return, + const scope_name = @tagName(scope); + const ok = comptime for (build_options.log_scopes) |log_scope| { + if (mem.eql(u8, log_scope, scope_name)) + break true; + } else false; - else => @tagName(scope), - } ++ "): "; + if (!ok) + return; - const prefix = "[" ++ @tagName(level) ++ "] " ++ scope_prefix; + const prefix = "[" ++ @tagName(level) ++ "] " ++ "(" ++ @tagName(scope) ++ "): "; // Print the message to stderr, silently ignoring any errors std.debug.print(prefix ++ format, args);