mirror of
https://github.com/ziglang/zig.git
synced 2026-01-10 01:15:14 +00:00
link.Coff: notice special windows symbols
in order to have a better default for subsystem. This brings stage2 behavior on par with stage1.
This commit is contained in:
parent
afe6e69e4c
commit
6fc9f6c5f6
@ -809,6 +809,36 @@ pub fn updateDeclExports(
|
||||
if (build_options.skip_non_native and builtin.object_format != .coff) {
|
||||
@panic("Attempted to compile for object format that was disabled by build configuration");
|
||||
}
|
||||
|
||||
// Even in the case of LLVM, we need to notice certain exported symbols in order to
|
||||
// detect the default subsystem.
|
||||
for (exports) |exp| {
|
||||
const exported_decl = module.declPtr(exp.exported_decl);
|
||||
if (exported_decl.getFunction() == null) continue;
|
||||
const winapi_cc = switch (self.base.options.target.cpu.arch) {
|
||||
.i386 => std.builtin.CallingConvention.Stdcall,
|
||||
else => std.builtin.CallingConvention.C,
|
||||
};
|
||||
const decl_cc = exported_decl.ty.fnCallingConvention();
|
||||
if (decl_cc == .C and mem.eql(u8, exp.options.name, "main") and
|
||||
self.base.options.link_libc)
|
||||
{
|
||||
module.stage1_flags.have_c_main = true;
|
||||
} else if (decl_cc == winapi_cc and self.base.options.target.os.tag == .windows) {
|
||||
if (mem.eql(u8, exp.options.name, "WinMain")) {
|
||||
module.stage1_flags.have_winmain = true;
|
||||
} else if (mem.eql(u8, exp.options.name, "wWinMain")) {
|
||||
module.stage1_flags.have_wwinmain = true;
|
||||
} else if (mem.eql(u8, exp.options.name, "WinMainCRTStartup")) {
|
||||
module.stage1_flags.have_winmain_crt_startup = true;
|
||||
} else if (mem.eql(u8, exp.options.name, "wWinMainCRTStartup")) {
|
||||
module.stage1_flags.have_wwinmain_crt_startup = true;
|
||||
} else if (mem.eql(u8, exp.options.name, "DllMainCRTStartup")) {
|
||||
module.stage1_flags.have_dllmain_crt_startup = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (build_options.have_llvm) {
|
||||
if (self.llvm_object) |llvm_object| return llvm_object.updateDeclExports(module, decl_index, exports);
|
||||
}
|
||||
@ -1114,17 +1144,6 @@ fn linkWithLLD(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Node) !
|
||||
try argv.append("-dynamicbase");
|
||||
}
|
||||
|
||||
const subsystem_suffix = ss: {
|
||||
if (self.base.options.major_subsystem_version) |major| {
|
||||
if (self.base.options.minor_subsystem_version) |minor| {
|
||||
break :ss try allocPrint(arena, ",{d}.{d}", .{ major, minor });
|
||||
} else {
|
||||
break :ss try allocPrint(arena, ",{d}", .{major});
|
||||
}
|
||||
}
|
||||
break :ss "";
|
||||
};
|
||||
|
||||
try argv.append(try allocPrint(arena, "-OUT:{s}", .{full_out_path}));
|
||||
|
||||
if (self.base.options.implib_emit) |emit| {
|
||||
@ -1186,57 +1205,71 @@ fn linkWithLLD(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Node) !
|
||||
}
|
||||
break :blk null;
|
||||
};
|
||||
|
||||
const Mode = enum { uefi, win32 };
|
||||
const mode: Mode = mode: {
|
||||
if (resolved_subsystem) |subsystem| switch (subsystem) {
|
||||
.Console => {
|
||||
try argv.append(try allocPrint(arena, "-SUBSYSTEM:console{s}", .{
|
||||
subsystem_suffix,
|
||||
}));
|
||||
break :mode .win32;
|
||||
},
|
||||
.EfiApplication => {
|
||||
try argv.append(try allocPrint(arena, "-SUBSYSTEM:efi_application{s}", .{
|
||||
subsystem_suffix,
|
||||
}));
|
||||
break :mode .uefi;
|
||||
},
|
||||
.EfiBootServiceDriver => {
|
||||
try argv.append(try allocPrint(arena, "-SUBSYSTEM:efi_boot_service_driver{s}", .{
|
||||
subsystem_suffix,
|
||||
}));
|
||||
break :mode .uefi;
|
||||
},
|
||||
.EfiRom => {
|
||||
try argv.append(try allocPrint(arena, "-SUBSYSTEM:efi_rom{s}", .{
|
||||
subsystem_suffix,
|
||||
}));
|
||||
break :mode .uefi;
|
||||
},
|
||||
.EfiRuntimeDriver => {
|
||||
try argv.append(try allocPrint(arena, "-SUBSYSTEM:efi_runtime_driver{s}", .{
|
||||
subsystem_suffix,
|
||||
}));
|
||||
break :mode .uefi;
|
||||
},
|
||||
.Native => {
|
||||
try argv.append(try allocPrint(arena, "-SUBSYSTEM:native{s}", .{
|
||||
subsystem_suffix,
|
||||
}));
|
||||
break :mode .win32;
|
||||
},
|
||||
.Posix => {
|
||||
try argv.append(try allocPrint(arena, "-SUBSYSTEM:posix{s}", .{
|
||||
subsystem_suffix,
|
||||
}));
|
||||
break :mode .win32;
|
||||
},
|
||||
.Windows => {
|
||||
try argv.append(try allocPrint(arena, "-SUBSYSTEM:windows{s}", .{
|
||||
subsystem_suffix,
|
||||
}));
|
||||
break :mode .win32;
|
||||
},
|
||||
if (resolved_subsystem) |subsystem| {
|
||||
const subsystem_suffix = ss: {
|
||||
if (self.base.options.major_subsystem_version) |major| {
|
||||
if (self.base.options.minor_subsystem_version) |minor| {
|
||||
break :ss try allocPrint(arena, ",{d}.{d}", .{ major, minor });
|
||||
} else {
|
||||
break :ss try allocPrint(arena, ",{d}", .{major});
|
||||
}
|
||||
}
|
||||
break :ss "";
|
||||
};
|
||||
|
||||
switch (subsystem) {
|
||||
.Console => {
|
||||
try argv.append(try allocPrint(arena, "-SUBSYSTEM:console{s}", .{
|
||||
subsystem_suffix,
|
||||
}));
|
||||
break :mode .win32;
|
||||
},
|
||||
.EfiApplication => {
|
||||
try argv.append(try allocPrint(arena, "-SUBSYSTEM:efi_application{s}", .{
|
||||
subsystem_suffix,
|
||||
}));
|
||||
break :mode .uefi;
|
||||
},
|
||||
.EfiBootServiceDriver => {
|
||||
try argv.append(try allocPrint(arena, "-SUBSYSTEM:efi_boot_service_driver{s}", .{
|
||||
subsystem_suffix,
|
||||
}));
|
||||
break :mode .uefi;
|
||||
},
|
||||
.EfiRom => {
|
||||
try argv.append(try allocPrint(arena, "-SUBSYSTEM:efi_rom{s}", .{
|
||||
subsystem_suffix,
|
||||
}));
|
||||
break :mode .uefi;
|
||||
},
|
||||
.EfiRuntimeDriver => {
|
||||
try argv.append(try allocPrint(arena, "-SUBSYSTEM:efi_runtime_driver{s}", .{
|
||||
subsystem_suffix,
|
||||
}));
|
||||
break :mode .uefi;
|
||||
},
|
||||
.Native => {
|
||||
try argv.append(try allocPrint(arena, "-SUBSYSTEM:native{s}", .{
|
||||
subsystem_suffix,
|
||||
}));
|
||||
break :mode .win32;
|
||||
},
|
||||
.Posix => {
|
||||
try argv.append(try allocPrint(arena, "-SUBSYSTEM:posix{s}", .{
|
||||
subsystem_suffix,
|
||||
}));
|
||||
break :mode .win32;
|
||||
},
|
||||
.Windows => {
|
||||
try argv.append(try allocPrint(arena, "-SUBSYSTEM:windows{s}", .{
|
||||
subsystem_suffix,
|
||||
}));
|
||||
break :mode .win32;
|
||||
},
|
||||
}
|
||||
} else if (target.os.tag == .uefi) {
|
||||
break :mode .uefi;
|
||||
} else {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user