diff options
| author | Jakub Konka <kubkon@jakubkonka.com> | 2022-11-10 16:52:43 +0100 |
|---|---|---|
| committer | Jakub Konka <kubkon@jakubkonka.com> | 2022-11-10 16:52:43 +0100 |
| commit | 04b8ce5fd32776cb5c8d34c424efd40cee86412a (patch) | |
| tree | f74dd9c60e879caf8552459acd2b66b700171bd2 /src | |
| parent | 4b3637820d0f43bc5b0e2c938b51ea1545b1c84e (diff) | |
| parent | 1357790ec969bb6ee19ade6e8a348bd9d7cbbc4d (diff) | |
| download | zig-04b8ce5fd32776cb5c8d34c424efd40cee86412a.tar.gz zig-04b8ce5fd32776cb5c8d34c424efd40cee86412a.zip | |
Merge branch 'jcmoyer-lld-explicit-pdb'
Diffstat (limited to 'src')
| -rw-r--r-- | src/Compilation.zig | 25 | ||||
| -rw-r--r-- | src/link.zig | 4 | ||||
| -rw-r--r-- | src/link/Coff/lld.zig | 11 |
3 files changed, 40 insertions, 0 deletions
diff --git a/src/Compilation.zig b/src/Compilation.zig index 7903586450..35be4e86cf 100644 --- a/src/Compilation.zig +++ b/src/Compilation.zig @@ -1016,6 +1016,9 @@ pub const InitOptions = struct { /// (Darwin) remove dylibs that are unreachable by the entry point or exported symbols dead_strip_dylibs: bool = false, libcxx_abi_version: libcxx.AbiVersion = libcxx.AbiVersion.default, + /// (Windows) PDB source path prefix to instruct the linker how to resolve relative + /// paths when consolidating CodeView streams into a single PDB file. + pdb_source_path: ?[]const u8 = null, }; fn addPackageTableToCacheHash( @@ -1719,6 +1722,27 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation { }; }; + const pdb_source_path: ?[]const u8 = options.pdb_source_path orelse blk: { + if (builtin.target.os.tag == .windows) { + // PDB requires all file paths to be fully resolved, and it is really the + // linker's responsibility to canonicalize any path extracted from the CodeView + // in the object file. However, LLD-link has some very questionable defaults, and + // in particular, it purposely bakes in path separator of the host system it was + // built on rather than the targets, or just throw an error. Thankfully, they have + // left a backdoor we can use via -PDBSOURCEPATH. + const mod = module orelse break :blk null; + var buffer: [std.fs.MAX_PATH_BYTES]u8 = undefined; + const resolved_path = if (mod.main_pkg.root_src_directory.path) |base_path| p: { + if (std.fs.path.isAbsolute(base_path)) break :blk base_path; + const resolved_path = std.os.realpath(base_path, &buffer) catch break :blk null; + const pos = std.mem.lastIndexOfLinear(u8, resolved_path, base_path) orelse resolved_path.len; + break :p resolved_path[0..pos]; + } else std.os.realpath(".", &buffer) catch break :blk null; + break :blk try arena.dupe(u8, resolved_path); + } + break :blk null; + }; + const implib_emit: ?link.Emit = blk: { const emit_implib = options.emit_implib orelse break :blk null; @@ -1865,6 +1889,7 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation { .headerpad_max_install_names = options.headerpad_max_install_names, .dead_strip_dylibs = options.dead_strip_dylibs, .force_undefined_symbols = .{}, + .pdb_source_path = pdb_source_path, }); errdefer bin_file.destroy(); comp.* = .{ diff --git a/src/link.zig b/src/link.zig index 3097e5cf1f..4dfcf171af 100644 --- a/src/link.zig +++ b/src/link.zig @@ -218,6 +218,10 @@ pub const Options = struct { /// (Darwin) remove dylibs that are unreachable by the entry point or exported symbols dead_strip_dylibs: bool = false, + /// (Windows) PDB source path prefix to instruct the linker how to resolve relative + /// paths when consolidating CodeView streams into a single PDB file. + pdb_source_path: ?[]const u8 = null, + pub fn effectiveOutputMode(options: Options) std.builtin.OutputMode { return if (options.use_lld) .Obj else options.output_mode; } diff --git a/src/link/Coff/lld.zig b/src/link/Coff/lld.zig index 7047d4fdba..00e6c4d8d1 100644 --- a/src/link/Coff/lld.zig +++ b/src/link/Coff/lld.zig @@ -181,6 +181,17 @@ pub fn linkWithLLD(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Nod try argv.append("-NOLOGO"); if (!self.base.options.strip) { try argv.append("-DEBUG"); + + const out_ext = std.fs.path.extension(full_out_path); + const out_pdb = try allocPrint(arena, "{s}.pdb", .{ + full_out_path[0 .. full_out_path.len - out_ext.len], + }); + try argv.append(try allocPrint(arena, "-PDB:{s}", .{out_pdb})); + try argv.append(try allocPrint(arena, "-PDBALTPATH:{s}", .{out_pdb})); + + if (self.base.options.pdb_source_path) |path| { + try argv.append(try std.fmt.allocPrint(arena, "-PDBSOURCEPATH:{s}", .{path})); + } } if (self.base.options.lto) { switch (self.base.options.optimize_mode) { |
