aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2023-01-05 17:26:32 -0700
committerGitHub <noreply@github.com>2023-01-05 17:26:32 -0700
commitc28c38d1e5648a45e8b3b2edbd1c732edb8d2642 (patch)
tree9e151a988b4196a57fe51cd34515cbe1090cc6a2 /src
parent301a89849b1f80afb01bebf1288afd767aea7122 (diff)
parent25e6187d28813c0f5227095b927374d901c6004b (diff)
downloadzig-c28c38d1e5648a45e8b3b2edbd1c732edb8d2642.tar.gz
zig-c28c38d1e5648a45e8b3b2edbd1c732edb8d2642.zip
Merge pull request #13514 from kcbanner/windows_build_fixes
Windows: Support building stage3, and bootstrapping via MSVC
Diffstat (limited to 'src')
-rw-r--r--src/Compilation.zig19
-rw-r--r--src/link.zig10
-rw-r--r--src/link/Coff/lld.zig19
-rw-r--r--src/main.zig32
4 files changed, 73 insertions, 7 deletions
diff --git a/src/Compilation.zig b/src/Compilation.zig
index e365d1dab2..f90b8f28d1 100644
--- a/src/Compilation.zig
+++ b/src/Compilation.zig
@@ -984,6 +984,7 @@ pub const InitOptions = struct {
linker_dynamicbase: bool = false,
linker_optimization: ?u8 = null,
linker_compress_debug_sections: ?link.CompressDebugSections = null,
+ linker_module_definition_file: ?[]const u8 = null,
major_subsystem_version: ?u32 = null,
minor_subsystem_version: ?u32 = null,
clang_passthrough_mode: bool = false,
@@ -1041,6 +1042,11 @@ 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,
+ /// (Windows) PDB output path
+ pdb_out_path: ?[]const u8 = null,
};
fn addPackageTableToCacheHash(
@@ -1815,6 +1821,7 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation {
.allow_shlib_undefined = options.linker_allow_shlib_undefined,
.bind_global_refs_locally = options.linker_bind_global_refs_locally orelse false,
.compress_debug_sections = options.linker_compress_debug_sections orelse .none,
+ .module_definition_file = options.linker_module_definition_file,
.import_memory = options.linker_import_memory orelse false,
.import_symbols = options.linker_import_symbols,
.import_table = options.linker_import_table,
@@ -1890,6 +1897,8 @@ 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 = options.pdb_source_path,
+ .pdb_out_path = options.pdb_out_path,
});
errdefer bin_file.destroy();
comp.* = .{
@@ -3297,8 +3306,8 @@ fn processOneJob(comp: *Compilation, job: Job) !void {
// TODO Surface more error details.
comp.lockAndSetMiscFailure(
.windows_import_lib,
- "unable to generate DLL import .lib file: {s}",
- .{@errorName(err)},
+ "unable to generate DLL import .lib file for {s}: {s}",
+ .{ link_lib, @errorName(err) },
);
};
},
@@ -4379,7 +4388,7 @@ pub fn addCCArgs(
try argv.append("-fno-unwind-tables");
}
},
- .shared_library, .ll, .bc, .unknown, .static_library, .object, .zig => {},
+ .shared_library, .ll, .bc, .unknown, .static_library, .object, .def, .zig => {},
.assembly => {
// The Clang assembler does not accept the list of CPU features like the
// compiler frontend does. Therefore we must hard-code the -m flags for
@@ -4524,6 +4533,7 @@ pub const FileExt = enum {
object,
static_library,
zig,
+ def,
unknown,
pub fn clangSupportsDepFile(ext: FileExt) bool {
@@ -4537,6 +4547,7 @@ pub const FileExt = enum {
.object,
.static_library,
.zig,
+ .def,
.unknown,
=> false,
};
@@ -4629,6 +4640,8 @@ pub fn classifyFileExt(filename: []const u8) FileExt {
return .object;
} else if (mem.endsWith(u8, filename, ".cu")) {
return .cu;
+ } else if (mem.endsWith(u8, filename, ".def")) {
+ return .def;
} else {
return .unknown;
}
diff --git a/src/link.zig b/src/link.zig
index 0a526db0de..222c0e4918 100644
--- a/src/link.zig
+++ b/src/link.zig
@@ -219,6 +219,16 @@ 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,
+
+ /// (Windows) PDB output path
+ pdb_out_path: ?[]const u8 = null,
+
+ /// (Windows) .def file to specify when linking
+ module_definition_file: ?[]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 46b0130542..d705f62f5c 100644
--- a/src/link/Coff/lld.zig
+++ b/src/link/Coff/lld.zig
@@ -98,6 +98,8 @@ pub fn linkWithLLD(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Nod
// strip does not need to go into the linker hash because it is part of the hash namespace
man.hash.addOptional(self.base.options.major_subsystem_version);
man.hash.addOptional(self.base.options.minor_subsystem_version);
+ man.hash.addOptional(self.base.options.version);
+ try man.addOptionalFile(self.base.options.module_definition_file);
// We don't actually care whether it's a cache hit or miss; we just need the digest and the lock.
_ = try man.hit();
@@ -166,12 +168,16 @@ pub fn linkWithLLD(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Nod
try argv.append("-DEBUG");
const out_ext = std.fs.path.extension(full_out_path);
- const out_pdb = try allocPrint(arena, "{s}.pdb", .{
+ const out_pdb = self.base.options.pdb_out_path orelse 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.version) |version| {
+ try argv.append(try allocPrint(arena, "-VERSION:{}.{}", .{ version.major, version.minor }));
+ }
if (self.base.options.lto) {
switch (self.base.options.optimize_mode) {
.Debug => {},
@@ -260,6 +266,10 @@ pub fn linkWithLLD(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Nod
try argv.append(p);
}
+ if (self.base.options.module_definition_file) |def| {
+ try argv.append(try allocPrint(arena, "-DEF:{s}", .{def}));
+ }
+
const resolved_subsystem: ?std.Target.SubSystem = blk: {
if (self.base.options.subsystem) |explicit| break :blk explicit;
switch (target.os.tag) {
@@ -423,7 +433,7 @@ pub fn linkWithLLD(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Nod
}
} else {
try argv.append("-NODEFAULTLIB");
- if (!is_lib) {
+ if (!is_lib and self.base.options.entry == null) {
if (self.base.options.module) |module| {
if (module.stage1_flags.have_winmain_crt_startup) {
try argv.append("-ENTRY:WinMainCRTStartup");
@@ -486,6 +496,11 @@ pub fn linkWithLLD(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Nod
continue;
}
}
+ if (target.abi == .msvc) {
+ argv.appendAssumeCapacity(lib_basename);
+ continue;
+ }
+
log.err("DLL import library for -l{s} not found", .{key});
return error.DllImportLibraryNotFound;
}
diff --git a/src/main.zig b/src/main.zig
index 814e60f97a..04d1b45d2a 100644
--- a/src/main.zig
+++ b/src/main.zig
@@ -748,6 +748,7 @@ fn buildOutputType(
var linker_nxcompat = false;
var linker_dynamicbase = false;
var linker_optimization: ?u8 = null;
+ var linker_module_definition_file: ?[]const u8 = null;
var test_evented_io = false;
var test_no_exec = false;
var entry: ?[]const u8 = null;
@@ -787,6 +788,7 @@ fn buildOutputType(
var headerpad_max_install_names: bool = false;
var dead_strip_dylibs: bool = false;
var reference_trace: ?u32 = null;
+ var pdb_out_path: ?[]const u8 = null;
// 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
@@ -1410,7 +1412,7 @@ fn buildOutputType(
root_src_file = arg;
}
},
- .unknown => {
+ .def, .unknown => {
fatal("unrecognized file extension of parameter '{s}'", .{arg});
},
}
@@ -1484,6 +1486,9 @@ fn buildOutputType(
.must_link = must_link,
});
},
+ .def => {
+ linker_module_definition_file = it.only_arg;
+ },
.zig => {
if (root_src_file) |other| {
fatal("found another zig file '{s}' after root source file '{s}'", .{ it.only_arg, other });
@@ -1543,7 +1548,10 @@ fn buildOutputType(
.no_stack_protector => want_stack_protector = 0,
.unwind_tables => want_unwind_tables = true,
.no_unwind_tables => want_unwind_tables = false,
- .nostdlib => ensure_libc_on_non_freestanding = false,
+ .nostdlib => {
+ ensure_libc_on_non_freestanding = false;
+ ensure_libcpp_on_non_freestanding = false;
+ },
.nostdlib_cpp => ensure_libcpp_on_non_freestanding = false,
.shared => {
link_mode = .Dynamic;
@@ -2122,6 +2130,24 @@ fn buildOutputType(
next_arg,
});
};
+ } else if (mem.startsWith(u8, arg, "/subsystem:")) {
+ var split_it = mem.splitBackwards(u8, arg, ":");
+ subsystem = try parseSubSystem(split_it.first());
+ } else if (mem.startsWith(u8, arg, "/implib:")) {
+ var split_it = mem.splitBackwards(u8, arg, ":");
+ emit_implib = .{ .yes = split_it.first() };
+ emit_implib_arg_provided = true;
+ } else if (mem.startsWith(u8, arg, "/pdb:")) {
+ var split_it = mem.splitBackwards(u8, arg, ":");
+ pdb_out_path = split_it.first();
+ } else if (mem.startsWith(u8, arg, "/version:")) {
+ var split_it = mem.splitBackwards(u8, arg, ":");
+ const version_arg = split_it.first();
+ version = std.builtin.Version.parse(version_arg) catch |err| {
+ fatal("unable to parse /version '{s}': {s}", .{ arg, @errorName(err) });
+ };
+
+ have_version = true;
} else {
warn("unsupported linker arg: {s}", .{arg});
}
@@ -3021,6 +3047,7 @@ fn buildOutputType(
.linker_dynamicbase = linker_dynamicbase,
.linker_optimization = linker_optimization,
.linker_compress_debug_sections = linker_compress_debug_sections,
+ .linker_module_definition_file = linker_module_definition_file,
.major_subsystem_version = major_subsystem_version,
.minor_subsystem_version = minor_subsystem_version,
.link_eh_frame_hdr = link_eh_frame_hdr,
@@ -3070,6 +3097,7 @@ fn buildOutputType(
.headerpad_max_install_names = headerpad_max_install_names,
.dead_strip_dylibs = dead_strip_dylibs,
.reference_trace = reference_trace,
+ .pdb_out_path = pdb_out_path,
}) catch |err| switch (err) {
error.LibCUnavailable => {
const target = target_info.target;