Skip to content

Link: Add natvis file support #19873

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 19 additions & 1 deletion src/Compilation.zig
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,7 @@ last_update_was_cache_hit: bool = false,

c_source_files: []const CSourceFile,
rc_source_files: []const RcSourceFile,
natvis_source_files: []const NatvisSourceFile,
global_cc_argv: []const []const u8,
cache_parent: *Cache,
/// Path to own executable for invoking `zig clang`.
Expand Down Expand Up @@ -299,6 +300,12 @@ pub const RcSourceFile = struct {
extra_flags: []const []const u8 = &.{},
};

/// For passing to the linker.
pub const NatvisSourceFile = struct {
owner: *Package.Module,
src_path: []const u8,
};

pub const RcIncludes = enum {
/// Use MSVC if available, fall back to MinGW.
any,
Expand Down Expand Up @@ -1005,6 +1012,7 @@ pub const CreateOptions = struct {
symbol_wrap_set: std.StringArrayHashMapUnmanaged(void) = .{},
c_source_files: []const CSourceFile = &.{},
rc_source_files: []const RcSourceFile = &.{},
natvis_source_files: []const NatvisSourceFile = &.{},
manifest_file: ?[]const u8 = null,
rc_includes: RcIncludes = .any,
link_objects: []LinkObject = &[0]LinkObject{},
Expand Down Expand Up @@ -1424,6 +1432,7 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil
.embed_file_work_queue = std.fifo.LinearFifo(*Module.EmbedFile, .Dynamic).init(gpa),
.c_source_files = options.c_source_files,
.rc_source_files = options.rc_source_files,
.natvis_source_files = options.natvis_source_files,
.cache_parent = cache,
.self_exe_path = options.self_exe_path,
.libc_include_dir_list = libc_dirs.libc_include_dir_list,
Expand Down Expand Up @@ -2414,6 +2423,10 @@ fn addNonIncrementalStuffToCacheManifest(
man.hash.addListOfBytes(key.src.extra_flags);
}

for (comp.natvis_source_files) |nv| {
_ = try man.addFile(nv.src_path, null);
}

if (!build_options.only_core_functionality) {
for (comp.win32_resource_table.keys()) |key| {
switch (key.src) {
Expand Down Expand Up @@ -5381,7 +5394,7 @@ pub fn addCCArgs(
try argv.append("-fno-unwind-tables");
}
},
.shared_library, .ll, .bc, .unknown, .static_library, .object, .def, .zig, .res, .manifest => {},
.shared_library, .ll, .bc, .unknown, .static_library, .object, .def, .zig, .res, .manifest, .natvis => {},
.assembly, .assembly_with_cpp => {
if (ext == .assembly_with_cpp) {
const c_headers_dir = try std.fs.path.join(arena, &[_][]const u8{ comp.zig_lib_directory.path.?, "include" });
Expand Down Expand Up @@ -5613,6 +5626,7 @@ pub const FileExt = enum {
rc,
res,
manifest,
natvis,
unknown,

pub fn clangSupportsDepFile(ext: FileExt) bool {
Expand All @@ -5631,6 +5645,7 @@ pub const FileExt = enum {
.rc,
.res,
.manifest,
.natvis,
.unknown,
=> false,
};
Expand Down Expand Up @@ -5659,6 +5674,7 @@ pub const FileExt = enum {
.rc => ".rc",
.res => ".res",
.manifest => ".manifest",
.natvis => ".natvis",
.unknown => "",
};
}
Expand Down Expand Up @@ -5756,6 +5772,8 @@ pub fn classifyFileExt(filename: []const u8) FileExt {
return .res;
} else if (std.ascii.endsWithIgnoreCase(filename, ".manifest")) {
return .manifest;
} else if (std.ascii.endsWithIgnoreCase(filename, ".natvis")) {
return .natvis;
} else {
return .unknown;
}
Expand Down
3 changes: 3 additions & 0 deletions src/link.zig
Original file line number Diff line number Diff line change
Expand Up @@ -743,6 +743,9 @@ pub const File = struct {
for (comp.c_object_table.keys()) |key| {
_ = try man.addFile(key.status.success.object_path, null);
}
for (comp.natvis_source_files) |nv| {
_ = try man.addFile(nv.src_path, null);
}
if (!build_options.only_core_functionality) {
for (comp.win32_resource_table.keys()) |key| {
_ = try man.addFile(key.status.success.res_path, null);
Expand Down
8 changes: 8 additions & 0 deletions src/link/Coff/lld.zig
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,9 @@ pub fn linkWithLLD(self: *Coff, arena: Allocator, prog_node: *std.Progress.Node)
for (comp.c_object_table.keys()) |key| {
_ = try man.addFile(key.status.success.object_path, null);
}
for (comp.natvis_source_files) |nv| {
_ = try man.addFile(nv.src_path, null);
}
if (!build_options.only_core_functionality) {
for (comp.win32_resource_table.keys()) |key| {
_ = try man.addFile(key.status.success.res_path, null);
Expand Down Expand Up @@ -271,6 +274,11 @@ pub fn linkWithLLD(self: *Coff, arena: Allocator, prog_node: *std.Progress.Node)
}
}

try argv.ensureUnusedCapacity(comp.natvis_source_files.len);
for (comp.natvis_source_files) |nv| {
argv.appendAssumeCapacity(try allocPrint(arena, "-NATVIS:{s}", .{nv.src_path}));
}

for (comp.c_object_table.keys()) |key| {
try argv.append(key.status.success.object_path);
}
Expand Down
40 changes: 40 additions & 0 deletions src/main.zig
Original file line number Diff line number Diff line change
Expand Up @@ -791,6 +791,8 @@ const CliModule = struct {
c_source_files_end: usize,
rc_source_files_start: usize,
rc_source_files_end: usize,
natvis_source_files_start: usize,
natvis_source_files_end: usize,

const Dep = struct {
key: []const u8,
Expand Down Expand Up @@ -923,6 +925,8 @@ fn buildOutputType(
var c_source_files_owner_index: usize = 0;
// Tracks the position in rc_source_files which have already their owner populated.
var rc_source_files_owner_index: usize = 0;
// Tracks the position in natvis_source_files which have already their owner populated.
var natvis_source_files_owner_index: usize = 0;

// null means replace with the test executable binary
var test_exec_args: std.ArrayListUnmanaged(?[]const u8) = .{};
Expand Down Expand Up @@ -971,6 +975,7 @@ fn buildOutputType(

.c_source_files = .{},
.rc_source_files = .{},
.natvis_source_files = .{},

.llvm_m_args = .{},
.sysroot = null,
Expand Down Expand Up @@ -1071,6 +1076,7 @@ fn buildOutputType(
&deps,
&c_source_files_owner_index,
&rc_source_files_owner_index,
&natvis_source_files_owner_index,
&cssan,
);
} else if (mem.startsWith(u8, arg, "-M")) {
Expand All @@ -1089,6 +1095,7 @@ fn buildOutputType(
&deps,
&c_source_files_owner_index,
&rc_source_files_owner_index,
&natvis_source_files_owner_index,
&cssan,
);
} else if (mem.eql(u8, arg, "--error-limit")) {
Expand Down Expand Up @@ -1719,6 +1726,12 @@ fn buildOutputType(
.extra_flags = try arena.dupe([]const u8, extra_rcflags.items),
});
},
.natvis => {
try create_module.natvis_source_files.append(arena, .{
.owner = undefined,
.src_path = arg,
});
},
.zig => {
if (root_src_file) |other| {
fatal("found another zig file '{s}' after root source file '{s}'", .{ arg, other });
Expand Down Expand Up @@ -1839,6 +1852,13 @@ fn buildOutputType(
.src_path = it.only_arg,
});
},
.natvis => {
try create_module.natvis_source_files.append(arena, .{
// Populated after module creation.
.owner = undefined,
.src_path = it.only_arg,
});
},
.zig => {
if (root_src_file) |other| {
fatal("found another zig file '{s}' after root source file '{s}'", .{ it.only_arg, other });
Expand Down Expand Up @@ -2640,13 +2660,16 @@ fn buildOutputType(
.c_source_files_end = create_module.c_source_files.items.len,
.rc_source_files_start = rc_source_files_owner_index,
.rc_source_files_end = create_module.rc_source_files.items.len,
.natvis_source_files_start = natvis_source_files_owner_index,
.natvis_source_files_end = create_module.natvis_source_files.items.len,
});
cssan.reset();
mod_opts = .{};
target_arch_os_abi = null;
target_mcpu = null;
c_source_files_owner_index = create_module.c_source_files.items.len;
rc_source_files_owner_index = create_module.rc_source_files.items.len;
natvis_source_files_owner_index = create_module.natvis_source_files.items.len;
}

if (!create_module.opts.have_zcu and arg_mode == .zig_test) {
Expand All @@ -2665,6 +2688,12 @@ fn buildOutputType(
});
}

if (natvis_source_files_owner_index != create_module.natvis_source_files.items.len) {
fatal("resource file '{s}' has no parent module", .{
create_module.natvis_source_files.items[natvis_source_files_owner_index].src_path,
});
}

const self_exe_path: ?[]const u8 = if (!process.can_spawn)
null
else
Expand Down Expand Up @@ -2812,6 +2841,9 @@ fn buildOutputType(
if (create_module.rc_source_files.items.len != 0) {
fatal("rc files are not allowed unless the target object format is coff (Windows/UEFI)", .{});
}
if (create_module.natvis_source_files.items.len != 0) {
fatal("natvis files are not allowed unless the target object format is coff (Windows/UEFI)", .{});
}
if (contains_res_file) {
fatal("res files are not allowed unless the target object format is coff (Windows/UEFI)", .{});
}
Expand Down Expand Up @@ -3223,6 +3255,7 @@ fn buildOutputType(
.symbol_wrap_set = symbol_wrap_set,
.c_source_files = create_module.c_source_files.items,
.rc_source_files = create_module.rc_source_files.items,
.natvis_source_files = create_module.natvis_source_files.items,
.manifest_file = manifest_file,
.rc_includes = rc_includes,
.mingw_unicode_entry_point = mingw_unicode_entry_point,
Expand Down Expand Up @@ -3495,6 +3528,7 @@ const CreateModule = struct {

c_source_files: std.ArrayListUnmanaged(Compilation.CSourceFile),
rc_source_files: std.ArrayListUnmanaged(Compilation.RcSourceFile),
natvis_source_files: std.ArrayListUnmanaged(Compilation.NatvisSourceFile),

/// e.g. -m3dnow or -mno-outline-atomics. They correspond to std.Target llvm cpu feature names.
/// This array is populated by zig cc frontend and then has to be converted to zig-style
Expand Down Expand Up @@ -3982,6 +4016,8 @@ fn createModule(

for (create_module.rc_source_files.items[cli_mod.rc_source_files_start..cli_mod.rc_source_files_end]) |*item| item.owner = mod;

for (create_module.natvis_source_files.items[cli_mod.natvis_source_files_start..cli_mod.natvis_source_files_end]) |*item| item.owner = mod;

for (cli_mod.deps) |dep| {
const dep_index = create_module.modules.getIndex(dep.value) orelse
fatal("module '{s}' depends on non-existent module '{s}'", .{ name, dep.key });
Expand Down Expand Up @@ -7241,6 +7277,7 @@ fn handleModArg(
deps: *std.ArrayListUnmanaged(CliModule.Dep),
c_source_files_owner_index: *usize,
rc_source_files_owner_index: *usize,
natvis_source_files_owner_index: *usize,
cssan: *ClangSearchSanitizer,
) !void {
const gop = try create_module.modules.getOrPut(arena, mod_name);
Expand Down Expand Up @@ -7291,11 +7328,14 @@ fn handleModArg(
.c_source_files_end = create_module.c_source_files.items.len,
.rc_source_files_start = rc_source_files_owner_index.*,
.rc_source_files_end = create_module.rc_source_files.items.len,
.natvis_source_files_start = natvis_source_files_owner_index.*,
.natvis_source_files_end = create_module.natvis_source_files.items.len,
};
cssan.reset();
mod_opts.* = .{};
target_arch_os_abi.* = null;
target_mcpu.* = null;
c_source_files_owner_index.* = create_module.c_source_files.items.len;
rc_source_files_owner_index.* = create_module.rc_source_files.items.len;
natvis_source_files_owner_index.* = create_module.natvis_source_files.items.len;
}