authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-01-05 17:26:32-07:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2023-01-05 17:26:32-07:00
logc28c38d1e5648a45e8b3b2edbd1c732edb8d2642
tree9e151a988b4196a57fe51cd34515cbe1090cc6a2
parent301a89849b1f80afb01bebf1288afd767aea7122
parent25e6187d28813c0f5227095b927374d901c6004b
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

Merge pull request #13514 from kcbanner/windows_build_fixes

Windows: Support building stage3, and bootstrapping via MSVC

7 files changed, 109 insertions(+), 24 deletions(-)

CMakeLists.txt+20-15
...@@ -89,9 +89,9 @@ endif()...@@ -89,9 +89,9 @@ endif()
8989
90set(ZIG_STATIC off CACHE BOOL "Attempt to build a static zig executable (not compatible with glibc)")90set(ZIG_STATIC off CACHE BOOL "Attempt to build a static zig executable (not compatible with glibc)")
91set(ZIG_SHARED_LLVM off CACHE BOOL "Prefer linking against shared LLVM libraries")91set(ZIG_SHARED_LLVM off CACHE BOOL "Prefer linking against shared LLVM libraries")
92set(ZIG_STATIC_LLVM off CACHE BOOL "Prefer linking against static LLVM libraries")92set(ZIG_STATIC_LLVM ${ZIG_STATIC} CACHE BOOL "Prefer linking against static LLVM libraries")
93set(ZIG_STATIC_ZLIB off CACHE BOOL "Prefer linking against static zlib")93set(ZIG_STATIC_ZLIB ${ZIG_STATIC} CACHE BOOL "Prefer linking against static zlib")
94set(ZIG_STATIC_ZSTD off CACHE BOOL "Prefer linking against static zstd")94set(ZIG_STATIC_ZSTD ${ZIG_STATIC} CACHE BOOL "Prefer linking against static zstd")
95set(ZIG_USE_CCACHE off CACHE BOOL "Use ccache")95set(ZIG_USE_CCACHE off CACHE BOOL "Use ccache")
9696
97if(ZIG_USE_CCACHE)97if(ZIG_USE_CCACHE)
...@@ -103,12 +103,6 @@ if(ZIG_USE_CCACHE)...@@ -103,12 +103,6 @@ if(ZIG_USE_CCACHE)
103 endif()103 endif()
104endif()104endif()
105105
106if(ZIG_STATIC)
107 set(ZIG_STATIC_LLVM ON)
108 set(ZIG_STATIC_ZLIB ON)
109 set(ZIG_STATIC_ZSTD ON)
110endif()
111
112if (ZIG_SHARED_LLVM AND ZIG_STATIC_LLVM)106if (ZIG_SHARED_LLVM AND ZIG_STATIC_LLVM)
113 message(SEND_ERROR "-DZIG_SHARED_LLVM and -DZIG_STATIC_LLVM cannot both be enabled simultaneously")107 message(SEND_ERROR "-DZIG_SHARED_LLVM and -DZIG_STATIC_LLVM cannot both be enabled simultaneously")
114endif()108endif()
...@@ -138,13 +132,23 @@ find_package(clang 15)...@@ -138,13 +132,23 @@ find_package(clang 15)
138find_package(lld 15)132find_package(lld 15)
139133
140if(ZIG_STATIC_ZLIB)134if(ZIG_STATIC_ZLIB)
141 list(REMOVE_ITEM LLVM_LIBRARIES "-lz")135 if (MSVC)
136 list(REMOVE_ITEM LLVM_LIBRARIES "z.lib")
137 else()
138 list(REMOVE_ITEM LLVM_LIBRARIES "-lz")
139 endif()
140
142 find_library(ZLIB NAMES libz.a libzlibstatic.a z zlib libz NAMES_PER_DIR)141 find_library(ZLIB NAMES libz.a libzlibstatic.a z zlib libz NAMES_PER_DIR)
143 list(APPEND LLVM_LIBRARIES "${ZLIB}")142 list(APPEND LLVM_LIBRARIES "${ZLIB}")
144endif()143endif()
145144
146if(ZIG_STATIC_ZSTD)145if(ZIG_STATIC_ZSTD)
147 list(REMOVE_ITEM LLVM_LIBRARIES "-lzstd")146 if (MSVC)
147 list(REMOVE_ITEM LLVM_LIBRARIES "zstd.lib")
148 else()
149 list(REMOVE_ITEM LLVM_LIBRARIES "-lzstd")
150 endif()
151
148 find_library(ZSTD NAMES libzstd.a libzstdstatic.a zstd NAMES_PER_DIR)152 find_library(ZSTD NAMES libzstd.a libzstdstatic.a zstd NAMES_PER_DIR)
149 list(APPEND LLVM_LIBRARIES "${ZSTD}")153 list(APPEND LLVM_LIBRARIES "${ZSTD}")
150endif()154endif()
...@@ -168,6 +172,7 @@ foreach(CONFIG_TYPE ${CMAKE_CONFIGURATION_TYPES})...@@ -168,6 +172,7 @@ foreach(CONFIG_TYPE ${CMAKE_CONFIGURATION_TYPES})
168 string(TOUPPER ${CONFIG_TYPE} CONFIG_TYPE)172 string(TOUPPER ${CONFIG_TYPE} CONFIG_TYPE)
169 set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_${CONFIG_TYPE} ${ZIG_CPP_LIB_DIR})173 set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_${CONFIG_TYPE} ${ZIG_CPP_LIB_DIR})
170 set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_${CONFIG_TYPE} ${ZIG_CPP_LIB_DIR})174 set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_${CONFIG_TYPE} ${ZIG_CPP_LIB_DIR})
175 set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_${CONFIG_TYPE} ${CMAKE_BINARY_DIR})
171endforeach(CONFIG_TYPE CMAKE_CONFIGURATION_TYPES)176endforeach(CONFIG_TYPE CMAKE_CONFIGURATION_TYPES)
172177
173include_directories(${LLVM_INCLUDE_DIRS})178include_directories(${LLVM_INCLUDE_DIRS})
...@@ -722,9 +727,9 @@ set(HOST_TARGET_TRIPLE "${HOST_TARGET_ARCH}-${HOST_TARGET_OS}")...@@ -722,9 +727,9 @@ set(HOST_TARGET_TRIPLE "${HOST_TARGET_ARCH}-${HOST_TARGET_OS}")
722727
723if(MSVC)728if(MSVC)
724 set(ZIG_WASM2C_COMPILE_FLAGS "")729 set(ZIG_WASM2C_COMPILE_FLAGS "")
725 set(ZIG1_COMPILE_FLAGS "/std:c99 /Os")730 set(ZIG1_COMPILE_FLAGS "/Os")
726 set(ZIG2_COMPILE_FLAGS "/std:c99 /O0")731 set(ZIG2_COMPILE_FLAGS "/Od")
727 set(ZIG2_LINK_FLAGS "/STACK:16777216")732 set(ZIG2_LINK_FLAGS "/STACK:16777216 /FORCE:MULTIPLE")
728else()733else()
729 set(ZIG_WASM2C_COMPILE_FLAGS "-std=c99 -O2")734 set(ZIG_WASM2C_COMPILE_FLAGS "-std=c99 -O2")
730 set(ZIG1_COMPILE_FLAGS "-std=c99 -Os")735 set(ZIG1_COMPILE_FLAGS "-std=c99 -Os")
...@@ -838,7 +843,7 @@ if(ZIG_SINGLE_THREADED)...@@ -838,7 +843,7 @@ if(ZIG_SINGLE_THREADED)
838else()843else()
839 set(ZIG_SINGLE_THREADED_ARG "")844 set(ZIG_SINGLE_THREADED_ARG "")
840endif()845endif()
841if(ZIG_STATIC)846if(ZIG_STATIC AND NOT MSVC)
842 set(ZIG_STATIC_ARG "-Duse-zig-libcxx")847 set(ZIG_STATIC_ARG "-Duse-zig-libcxx")
843else()848else()
844 set(ZIG_STATIC_ARG "")849 set(ZIG_STATIC_ARG "")
build.zig+12-2
...@@ -628,8 +628,16 @@ fn addStaticLlvmOptionsToExe(exe: *std.build.LibExeObjStep) !void {...@@ -628,8 +628,16 @@ fn addStaticLlvmOptionsToExe(exe: *std.build.LibExeObjStep) !void {
628 exe.linkSystemLibrary("z");628 exe.linkSystemLibrary("z");
629 exe.linkSystemLibrary("zstd");629 exe.linkSystemLibrary("zstd");
630630
631 // This means we rely on clang-or-zig-built LLVM, Clang, LLD libraries.631 if (exe.target.getOs().tag != .windows or exe.target.getAbi() != .msvc) {
632 exe.linkSystemLibrary("c++");632 // This means we rely on clang-or-zig-built LLVM, Clang, LLD libraries.
633 exe.linkSystemLibrary("c++");
634 }
635
636 if (exe.target.getOs().tag == .windows) {
637 exe.linkSystemLibrary("version");
638 exe.linkSystemLibrary("uuid");
639 exe.linkSystemLibrary("ole32");
640 }
633}641}
634642
635fn addCxxKnownPath(643fn addCxxKnownPath(
...@@ -673,6 +681,8 @@ fn addCMakeLibraryList(exe: *std.build.LibExeObjStep, list: []const u8) void {...@@ -673,6 +681,8 @@ fn addCMakeLibraryList(exe: *std.build.LibExeObjStep, list: []const u8) void {
673 while (it.next()) |lib| {681 while (it.next()) |lib| {
674 if (mem.startsWith(u8, lib, "-l")) {682 if (mem.startsWith(u8, lib, "-l")) {
675 exe.linkSystemLibrary(lib["-l".len..]);683 exe.linkSystemLibrary(lib["-l".len..]);
684 } else if (exe.target.isWindows() and mem.endsWith(u8, lib, ".lib") and !fs.path.isAbsolute(lib)) {
685 exe.linkSystemLibrary(lib[0 .. lib.len - ".lib".len]);
676 } else {686 } else {
677 exe.addObjectFile(lib);687 exe.addObjectFile(lib);
678 }688 }
cmake/Findclang.cmake+4
...@@ -68,6 +68,10 @@ else()...@@ -68,6 +68,10 @@ else()
68 FIND_AND_ADD_CLANG_LIB(clangSupport)68 FIND_AND_ADD_CLANG_LIB(clangSupport)
69endif()69endif()
7070
71if (MSVC)
72 set(CLANG_LIBRARIES ${CLANG_LIBRARIES} "version.lib")
73endif()
74
71include(FindPackageHandleStandardArgs)75include(FindPackageHandleStandardArgs)
72find_package_handle_standard_args(clang DEFAULT_MSG CLANG_LIBRARIES CLANG_INCLUDE_DIRS)76find_package_handle_standard_args(clang DEFAULT_MSG CLANG_LIBRARIES CLANG_INCLUDE_DIRS)
7377
src/Compilation.zig+16-3
...@@ -984,6 +984,7 @@ pub const InitOptions = struct {...@@ -984,6 +984,7 @@ pub const InitOptions = struct {
984 linker_dynamicbase: bool = false,984 linker_dynamicbase: bool = false,
985 linker_optimization: ?u8 = null,985 linker_optimization: ?u8 = null,
986 linker_compress_debug_sections: ?link.CompressDebugSections = null,986 linker_compress_debug_sections: ?link.CompressDebugSections = null,
987 linker_module_definition_file: ?[]const u8 = null,
987 major_subsystem_version: ?u32 = null,988 major_subsystem_version: ?u32 = null,
988 minor_subsystem_version: ?u32 = null,989 minor_subsystem_version: ?u32 = null,
989 clang_passthrough_mode: bool = false,990 clang_passthrough_mode: bool = false,
...@@ -1041,6 +1042,11 @@ pub const InitOptions = struct {...@@ -1041,6 +1042,11 @@ pub const InitOptions = struct {
1041 /// (Darwin) remove dylibs that are unreachable by the entry point or exported symbols1042 /// (Darwin) remove dylibs that are unreachable by the entry point or exported symbols
1042 dead_strip_dylibs: bool = false,1043 dead_strip_dylibs: bool = false,
1043 libcxx_abi_version: libcxx.AbiVersion = libcxx.AbiVersion.default,1044 libcxx_abi_version: libcxx.AbiVersion = libcxx.AbiVersion.default,
1045 /// (Windows) PDB source path prefix to instruct the linker how to resolve relative
1046 /// paths when consolidating CodeView streams into a single PDB file.
1047 pdb_source_path: ?[]const u8 = null,
1048 /// (Windows) PDB output path
1049 pdb_out_path: ?[]const u8 = null,
1044};1050};
10451051
1046fn addPackageTableToCacheHash(1052fn addPackageTableToCacheHash(
...@@ -1815,6 +1821,7 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation {...@@ -1815,6 +1821,7 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation {
1815 .allow_shlib_undefined = options.linker_allow_shlib_undefined,1821 .allow_shlib_undefined = options.linker_allow_shlib_undefined,
1816 .bind_global_refs_locally = options.linker_bind_global_refs_locally orelse false,1822 .bind_global_refs_locally = options.linker_bind_global_refs_locally orelse false,
1817 .compress_debug_sections = options.linker_compress_debug_sections orelse .none,1823 .compress_debug_sections = options.linker_compress_debug_sections orelse .none,
1824 .module_definition_file = options.linker_module_definition_file,
1818 .import_memory = options.linker_import_memory orelse false,1825 .import_memory = options.linker_import_memory orelse false,
1819 .import_symbols = options.linker_import_symbols,1826 .import_symbols = options.linker_import_symbols,
1820 .import_table = options.linker_import_table,1827 .import_table = options.linker_import_table,
...@@ -1890,6 +1897,8 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation {...@@ -1890,6 +1897,8 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation {
1890 .headerpad_max_install_names = options.headerpad_max_install_names,1897 .headerpad_max_install_names = options.headerpad_max_install_names,
1891 .dead_strip_dylibs = options.dead_strip_dylibs,1898 .dead_strip_dylibs = options.dead_strip_dylibs,
1892 .force_undefined_symbols = .{},1899 .force_undefined_symbols = .{},
1900 .pdb_source_path = options.pdb_source_path,
1901 .pdb_out_path = options.pdb_out_path,
1893 });1902 });
1894 errdefer bin_file.destroy();1903 errdefer bin_file.destroy();
1895 comp.* = .{1904 comp.* = .{
...@@ -3297,8 +3306,8 @@ fn processOneJob(comp: *Compilation, job: Job) !void {...@@ -3297,8 +3306,8 @@ fn processOneJob(comp: *Compilation, job: Job) !void {
3297 // TODO Surface more error details.3306 // TODO Surface more error details.
3298 comp.lockAndSetMiscFailure(3307 comp.lockAndSetMiscFailure(
3299 .windows_import_lib,3308 .windows_import_lib,
3300 "unable to generate DLL import .lib file: {s}",3309 "unable to generate DLL import .lib file for {s}: {s}",
3301 .{@errorName(err)},3310 .{ link_lib, @errorName(err) },
3302 );3311 );
3303 };3312 };
3304 },3313 },
...@@ -4379,7 +4388,7 @@ pub fn addCCArgs(...@@ -4379,7 +4388,7 @@ pub fn addCCArgs(
4379 try argv.append("-fno-unwind-tables");4388 try argv.append("-fno-unwind-tables");
4380 }4389 }
4381 },4390 },
4382 .shared_library, .ll, .bc, .unknown, .static_library, .object, .zig => {},4391 .shared_library, .ll, .bc, .unknown, .static_library, .object, .def, .zig => {},
4383 .assembly => {4392 .assembly => {
4384 // The Clang assembler does not accept the list of CPU features like the4393 // The Clang assembler does not accept the list of CPU features like the
4385 // compiler frontend does. Therefore we must hard-code the -m flags for4394 // compiler frontend does. Therefore we must hard-code the -m flags for
...@@ -4524,6 +4533,7 @@ pub const FileExt = enum {...@@ -4524,6 +4533,7 @@ pub const FileExt = enum {
4524 object,4533 object,
4525 static_library,4534 static_library,
4526 zig,4535 zig,
4536 def,
4527 unknown,4537 unknown,
45284538
4529 pub fn clangSupportsDepFile(ext: FileExt) bool {4539 pub fn clangSupportsDepFile(ext: FileExt) bool {
...@@ -4537,6 +4547,7 @@ pub const FileExt = enum {...@@ -4537,6 +4547,7 @@ pub const FileExt = enum {
4537 .object,4547 .object,
4538 .static_library,4548 .static_library,
4539 .zig,4549 .zig,
4550 .def,
4540 .unknown,4551 .unknown,
4541 => false,4552 => false,
4542 };4553 };
...@@ -4629,6 +4640,8 @@ pub fn classifyFileExt(filename: []const u8) FileExt {...@@ -4629,6 +4640,8 @@ pub fn classifyFileExt(filename: []const u8) FileExt {
4629 return .object;4640 return .object;
4630 } else if (mem.endsWith(u8, filename, ".cu")) {4641 } else if (mem.endsWith(u8, filename, ".cu")) {
4631 return .cu;4642 return .cu;
4643 } else if (mem.endsWith(u8, filename, ".def")) {
4644 return .def;
4632 } else {4645 } else {
4633 return .unknown;4646 return .unknown;
4634 }4647 }
src/link.zig+10
...@@ -219,6 +219,16 @@ pub const Options = struct {...@@ -219,6 +219,16 @@ pub const Options = struct {
219 /// (Darwin) remove dylibs that are unreachable by the entry point or exported symbols219 /// (Darwin) remove dylibs that are unreachable by the entry point or exported symbols
220 dead_strip_dylibs: bool = false,220 dead_strip_dylibs: bool = false,
221221
222 /// (Windows) PDB source path prefix to instruct the linker how to resolve relative
223 /// paths when consolidating CodeView streams into a single PDB file.
224 pdb_source_path: ?[]const u8 = null,
225
226 /// (Windows) PDB output path
227 pdb_out_path: ?[]const u8 = null,
228
229 /// (Windows) .def file to specify when linking
230 module_definition_file: ?[]const u8 = null,
231
222 pub fn effectiveOutputMode(options: Options) std.builtin.OutputMode {232 pub fn effectiveOutputMode(options: Options) std.builtin.OutputMode {
223 return if (options.use_lld) .Obj else options.output_mode;233 return if (options.use_lld) .Obj else options.output_mode;
224 }234 }
src/link/Coff/lld.zig+17-2
...@@ -98,6 +98,8 @@ pub fn linkWithLLD(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Nod...@@ -98,6 +98,8 @@ pub fn linkWithLLD(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Nod
98 // strip does not need to go into the linker hash because it is part of the hash namespace98 // strip does not need to go into the linker hash because it is part of the hash namespace
99 man.hash.addOptional(self.base.options.major_subsystem_version);99 man.hash.addOptional(self.base.options.major_subsystem_version);
100 man.hash.addOptional(self.base.options.minor_subsystem_version);100 man.hash.addOptional(self.base.options.minor_subsystem_version);
101 man.hash.addOptional(self.base.options.version);
102 try man.addOptionalFile(self.base.options.module_definition_file);
101103
102 // We don't actually care whether it's a cache hit or miss; we just need the digest and the lock.104 // We don't actually care whether it's a cache hit or miss; we just need the digest and the lock.
103 _ = try man.hit();105 _ = try man.hit();
...@@ -166,12 +168,16 @@ pub fn linkWithLLD(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Nod...@@ -166,12 +168,16 @@ pub fn linkWithLLD(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Nod
166 try argv.append("-DEBUG");168 try argv.append("-DEBUG");
167169
168 const out_ext = std.fs.path.extension(full_out_path);170 const out_ext = std.fs.path.extension(full_out_path);
169 const out_pdb = try allocPrint(arena, "{s}.pdb", .{171 const out_pdb = self.base.options.pdb_out_path orelse try allocPrint(arena, "{s}.pdb", .{
170 full_out_path[0 .. full_out_path.len - out_ext.len],172 full_out_path[0 .. full_out_path.len - out_ext.len],
171 });173 });
174
172 try argv.append(try allocPrint(arena, "-PDB:{s}", .{out_pdb}));175 try argv.append(try allocPrint(arena, "-PDB:{s}", .{out_pdb}));
173 try argv.append(try allocPrint(arena, "-PDBALTPATH:{s}", .{out_pdb}));176 try argv.append(try allocPrint(arena, "-PDBALTPATH:{s}", .{out_pdb}));
174 }177 }
178 if (self.base.options.version) |version| {
179 try argv.append(try allocPrint(arena, "-VERSION:{}.{}", .{ version.major, version.minor }));
180 }
175 if (self.base.options.lto) {181 if (self.base.options.lto) {
176 switch (self.base.options.optimize_mode) {182 switch (self.base.options.optimize_mode) {
177 .Debug => {},183 .Debug => {},
...@@ -260,6 +266,10 @@ pub fn linkWithLLD(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Nod...@@ -260,6 +266,10 @@ pub fn linkWithLLD(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Nod
260 try argv.append(p);266 try argv.append(p);
261 }267 }
262268
269 if (self.base.options.module_definition_file) |def| {
270 try argv.append(try allocPrint(arena, "-DEF:{s}", .{def}));
271 }
272
263 const resolved_subsystem: ?std.Target.SubSystem = blk: {273 const resolved_subsystem: ?std.Target.SubSystem = blk: {
264 if (self.base.options.subsystem) |explicit| break :blk explicit;274 if (self.base.options.subsystem) |explicit| break :blk explicit;
265 switch (target.os.tag) {275 switch (target.os.tag) {
...@@ -423,7 +433,7 @@ pub fn linkWithLLD(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Nod...@@ -423,7 +433,7 @@ pub fn linkWithLLD(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Nod
423 }433 }
424 } else {434 } else {
425 try argv.append("-NODEFAULTLIB");435 try argv.append("-NODEFAULTLIB");
426 if (!is_lib) {436 if (!is_lib and self.base.options.entry == null) {
427 if (self.base.options.module) |module| {437 if (self.base.options.module) |module| {
428 if (module.stage1_flags.have_winmain_crt_startup) {438 if (module.stage1_flags.have_winmain_crt_startup) {
429 try argv.append("-ENTRY:WinMainCRTStartup");439 try argv.append("-ENTRY:WinMainCRTStartup");
...@@ -486,6 +496,11 @@ pub fn linkWithLLD(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Nod...@@ -486,6 +496,11 @@ pub fn linkWithLLD(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Nod
486 continue;496 continue;
487 }497 }
488 }498 }
499 if (target.abi == .msvc) {
500 argv.appendAssumeCapacity(lib_basename);
501 continue;
502 }
503
489 log.err("DLL import library for -l{s} not found", .{key});504 log.err("DLL import library for -l{s} not found", .{key});
490 return error.DllImportLibraryNotFound;505 return error.DllImportLibraryNotFound;
491 }506 }
src/main.zig+30-2
...@@ -748,6 +748,7 @@ fn buildOutputType(...@@ -748,6 +748,7 @@ fn buildOutputType(
748 var linker_nxcompat = false;748 var linker_nxcompat = false;
749 var linker_dynamicbase = false;749 var linker_dynamicbase = false;
750 var linker_optimization: ?u8 = null;750 var linker_optimization: ?u8 = null;
751 var linker_module_definition_file: ?[]const u8 = null;
751 var test_evented_io = false;752 var test_evented_io = false;
752 var test_no_exec = false;753 var test_no_exec = false;
753 var entry: ?[]const u8 = null;754 var entry: ?[]const u8 = null;
...@@ -787,6 +788,7 @@ fn buildOutputType(...@@ -787,6 +788,7 @@ fn buildOutputType(
787 var headerpad_max_install_names: bool = false;788 var headerpad_max_install_names: bool = false;
788 var dead_strip_dylibs: bool = false;789 var dead_strip_dylibs: bool = false;
789 var reference_trace: ?u32 = null;790 var reference_trace: ?u32 = null;
791 var pdb_out_path: ?[]const u8 = null;
790792
791 // e.g. -m3dnow or -mno-outline-atomics. They correspond to std.Target llvm cpu feature names.793 // e.g. -m3dnow or -mno-outline-atomics. They correspond to std.Target llvm cpu feature names.
792 // This array is populated by zig cc frontend and then has to be converted to zig-style794 // This array is populated by zig cc frontend and then has to be converted to zig-style
...@@ -1410,7 +1412,7 @@ fn buildOutputType(...@@ -1410,7 +1412,7 @@ fn buildOutputType(
1410 root_src_file = arg;1412 root_src_file = arg;
1411 }1413 }
1412 },1414 },
1413 .unknown => {1415 .def, .unknown => {
1414 fatal("unrecognized file extension of parameter '{s}'", .{arg});1416 fatal("unrecognized file extension of parameter '{s}'", .{arg});
1415 },1417 },
1416 }1418 }
...@@ -1484,6 +1486,9 @@ fn buildOutputType(...@@ -1484,6 +1486,9 @@ fn buildOutputType(
1484 .must_link = must_link,1486 .must_link = must_link,
1485 });1487 });
1486 },1488 },
1489 .def => {
1490 linker_module_definition_file = it.only_arg;
1491 },
1487 .zig => {1492 .zig => {
1488 if (root_src_file) |other| {1493 if (root_src_file) |other| {
1489 fatal("found another zig file '{s}' after root source file '{s}'", .{ it.only_arg, other });1494 fatal("found another zig file '{s}' after root source file '{s}'", .{ it.only_arg, other });
...@@ -1543,7 +1548,10 @@ fn buildOutputType(...@@ -1543,7 +1548,10 @@ fn buildOutputType(
1543 .no_stack_protector => want_stack_protector = 0,1548 .no_stack_protector => want_stack_protector = 0,
1544 .unwind_tables => want_unwind_tables = true,1549 .unwind_tables => want_unwind_tables = true,
1545 .no_unwind_tables => want_unwind_tables = false,1550 .no_unwind_tables => want_unwind_tables = false,
1546 .nostdlib => ensure_libc_on_non_freestanding = false,1551 .nostdlib => {
1552 ensure_libc_on_non_freestanding = false;
1553 ensure_libcpp_on_non_freestanding = false;
1554 },
1547 .nostdlib_cpp => ensure_libcpp_on_non_freestanding = false,1555 .nostdlib_cpp => ensure_libcpp_on_non_freestanding = false,
1548 .shared => {1556 .shared => {
1549 link_mode = .Dynamic;1557 link_mode = .Dynamic;
...@@ -2122,6 +2130,24 @@ fn buildOutputType(...@@ -2122,6 +2130,24 @@ fn buildOutputType(
2122 next_arg,2130 next_arg,
2123 });2131 });
2124 };2132 };
2133 } else if (mem.startsWith(u8, arg, "/subsystem:")) {
2134 var split_it = mem.splitBackwards(u8, arg, ":");
2135 subsystem = try parseSubSystem(split_it.first());
2136 } else if (mem.startsWith(u8, arg, "/implib:")) {
2137 var split_it = mem.splitBackwards(u8, arg, ":");
2138 emit_implib = .{ .yes = split_it.first() };
2139 emit_implib_arg_provided = true;
2140 } else if (mem.startsWith(u8, arg, "/pdb:")) {
2141 var split_it = mem.splitBackwards(u8, arg, ":");
2142 pdb_out_path = split_it.first();
2143 } else if (mem.startsWith(u8, arg, "/version:")) {
2144 var split_it = mem.splitBackwards(u8, arg, ":");
2145 const version_arg = split_it.first();
2146 version = std.builtin.Version.parse(version_arg) catch |err| {
2147 fatal("unable to parse /version '{s}': {s}", .{ arg, @errorName(err) });
2148 };
2149
2150 have_version = true;
2125 } else {2151 } else {
2126 warn("unsupported linker arg: {s}", .{arg});2152 warn("unsupported linker arg: {s}", .{arg});
2127 }2153 }
...@@ -3021,6 +3047,7 @@ fn buildOutputType(...@@ -3021,6 +3047,7 @@ fn buildOutputType(
3021 .linker_dynamicbase = linker_dynamicbase,3047 .linker_dynamicbase = linker_dynamicbase,
3022 .linker_optimization = linker_optimization,3048 .linker_optimization = linker_optimization,
3023 .linker_compress_debug_sections = linker_compress_debug_sections,3049 .linker_compress_debug_sections = linker_compress_debug_sections,
3050 .linker_module_definition_file = linker_module_definition_file,
3024 .major_subsystem_version = major_subsystem_version,3051 .major_subsystem_version = major_subsystem_version,
3025 .minor_subsystem_version = minor_subsystem_version,3052 .minor_subsystem_version = minor_subsystem_version,
3026 .link_eh_frame_hdr = link_eh_frame_hdr,3053 .link_eh_frame_hdr = link_eh_frame_hdr,
...@@ -3070,6 +3097,7 @@ fn buildOutputType(...@@ -3070,6 +3097,7 @@ fn buildOutputType(
3070 .headerpad_max_install_names = headerpad_max_install_names,3097 .headerpad_max_install_names = headerpad_max_install_names,
3071 .dead_strip_dylibs = dead_strip_dylibs,3098 .dead_strip_dylibs = dead_strip_dylibs,
3072 .reference_trace = reference_trace,3099 .reference_trace = reference_trace,
3100 .pdb_out_path = pdb_out_path,
3073 }) catch |err| switch (err) {3101 }) catch |err| switch (err) {
3074 error.LibCUnavailable => {3102 error.LibCUnavailable => {
3075 const target = target_info.target;3103 const target = target_info.target;