authorgravatar for alex@alexrp.comAlex Rønne Petersen <alex@alexrp.com> 2025-06-02 19:02:08+02:00
committergravatar for alex@alexrp.comAlex Rønne Petersen <alex@alexrp.com> 2025-06-04 05:04:29+02:00
logcd03a0a153aae3e0450b7878b67906fb41521d13
tree81aabde76e990bc4e26f9aa3df0db6a8a983f424
parent826e1c30ba81884e1a8fad8664b3da17953d89d1

compiler: Don't link ucrtbased.dll when targeting *-windows-msvc in Debug mode.

Linking it by default means that we produce binaries that, effectively, only run on systems which have the Windows SDK installed because ucrtbased.dll is not redistributable, and the Windows SDK is what actually installs ucrtbased.dll into %SYSTEM32%. The resulting binaries also can't run under Wine because Wine does not provide ucrtbased.dll. It is also inconsistent with our behavior for *-windows-gnu where we always link ucrtbase.dll. See #23983, #24019, and #24053 for more details. So just use ucrtbase.dll regardless of mode. With this change, we can also drop the implicit definition of the _DEBUG macro in zig cc, which has in some cases been problematic for users. Users who want to opt into the old behavior can do so, both for *-windows-msvc and *-windows-gnu, by explicitly passing -lucrtbased and -D_DEBUG. We might consider adding a more ergonomic flag like -fdebug-crt to the zig build-* family of commands in the future. Closes #24052.

2 files changed, 10 insertions(+), 18 deletions(-)

src/Compilation.zig+2-6
...@@ -5904,8 +5904,7 @@ fn updateWin32Resource(comp: *Compilation, win32_resource: *Win32Resource, win32...@@ -5904,8 +5904,7 @@ fn updateWin32Resource(comp: *Compilation, win32_resource: *Win32Resource, win32
5904 // them being defined matches the behavior of how MSVC calls rc.exe which is the more5904 // them being defined matches the behavior of how MSVC calls rc.exe which is the more
5905 // relevant behavior in this case.5905 // relevant behavior in this case.
5906 switch (rc_src.owner.optimize_mode) {5906 switch (rc_src.owner.optimize_mode) {
5907 .Debug => try argv.append("-D_DEBUG"),5907 .Debug, .ReleaseSafe => {},
5908 .ReleaseSafe => {},
5909 .ReleaseFast, .ReleaseSmall => try argv.append("-DNDEBUG"),5908 .ReleaseFast, .ReleaseSmall => try argv.append("-DNDEBUG"),
5910 }5909 }
5911 try argv.appendSlice(rc_src.extra_flags);5910 try argv.appendSlice(rc_src.extra_flags);
...@@ -6260,10 +6259,7 @@ pub fn addCCArgs(...@@ -6260,10 +6259,7 @@ pub fn addCCArgs(
6260 // LLVM IR files don't support these flags.6259 // LLVM IR files don't support these flags.
6261 if (ext != .ll and ext != .bc) {6260 if (ext != .ll and ext != .bc) {
6262 switch (mod.optimize_mode) {6261 switch (mod.optimize_mode) {
6263 .Debug => {6262 .Debug => {},
6264 // windows c runtime requires -D_DEBUG if using debug libraries
6265 try argv.append("-D_DEBUG");
6266 },
6267 .ReleaseSafe => {6263 .ReleaseSafe => {
6268 try argv.append("-D_FORTIFY_SOURCE=2");6264 try argv.append("-D_FORTIFY_SOURCE=2");
6269 },6265 },
src/link/Coff.zig+8-12
...@@ -2113,21 +2113,17 @@ fn linkWithLLD(coff: *Coff, arena: Allocator, tid: Zcu.PerThread.Id, prog_node:...@@ -2113,21 +2113,17 @@ fn linkWithLLD(coff: *Coff, arena: Allocator, tid: Zcu.PerThread.Id, prog_node:
21132113
2114 try argv.append(try comp.crtFileAsString(arena, "libmingw32.lib"));2114 try argv.append(try comp.crtFileAsString(arena, "libmingw32.lib"));
2115 } else {2115 } else {
2116 try argv.append(switch (comp.config.link_mode) {
2117 .static => "libcmt.lib",
2118 .dynamic => "msvcrt.lib",
2119 });
2120
2116 const lib_str = switch (comp.config.link_mode) {2121 const lib_str = switch (comp.config.link_mode) {
2117 .dynamic => "",
2118 .static => "lib",2122 .static => "lib",
2123 .dynamic => "",
2119 };2124 };
2120 const d_str = switch (optimize_mode) {2125 try argv.append(try allocPrint(arena, "{s}vcruntime.lib", .{lib_str}));
2121 .Debug => "d",2126 try argv.append(try allocPrint(arena, "{s}ucrt.lib", .{lib_str}));
2122 else => "",
2123 };
2124 switch (comp.config.link_mode) {
2125 .static => try argv.append(try allocPrint(arena, "libcmt{s}.lib", .{d_str})),
2126 .dynamic => try argv.append(try allocPrint(arena, "msvcrt{s}.lib", .{d_str})),
2127 }
2128
2129 try argv.append(try allocPrint(arena, "{s}vcruntime{s}.lib", .{ lib_str, d_str }));
2130 try argv.append(try allocPrint(arena, "{s}ucrt{s}.lib", .{ lib_str, d_str }));
21312127
2132 //Visual C++ 2015 Conformance Changes2128 //Visual C++ 2015 Conformance Changes
2133 //https://msdn.microsoft.com/en-us/library/bb531344.aspx2129 //https://msdn.microsoft.com/en-us/library/bb531344.aspx