Commit 471f279cd6

Ryan Liptak <squeek502@hotmail.com>
2023-09-17 22:09:16
Fix rc preprocessing when using the MinGW includes and targeting the GNU abi
Also update the standalone test so that this failure would have been detected on any host system.
1 parent 0168ed7
Changed files (2)
src
test
standalone
windows_resources
src/Compilation.zig
@@ -4513,6 +4513,19 @@ fn updateWin32Resource(comp: *Compilation, win32_resource: *Win32Resource, win32
             "-fms-compatibility", // Allow things like "header.h" to be resolved relative to the 'root' .rc file, among other things
             "-DRC_INVOKED", // https://learn.microsoft.com/en-us/windows/win32/menurc/predefined-macros
         });
+        // Using -fms-compatibility and targeting the gnu abi interact in a strange way:
+        // - Targeting the GNU abi stops _MSC_VER from being defined
+        // - Passing -fms-compatibility stops __GNUC__ from being defined
+        // Neither being defined is a problem for things like things like MinGW's
+        // vadefs.h, which will fail during preprocessing if neither are defined.
+        // So, when targeting the GNU abi, we need to force __GNUC__ to be defined.
+        //
+        // TODO: This is a workaround that should be removed if possible.
+        if (comp.getTarget().isGnu()) {
+            // This is the same default gnuc version that Clang uses:
+            // https://github.com/llvm/llvm-project/blob/4b5366c9512aa273a5272af1d833961e1ed156e7/clang/lib/Driver/ToolChains/Clang.cpp#L6738
+            try argv.append("-fgnuc-version=4.2.1");
+        }
         for (options.extra_include_paths.items) |extra_include_path| {
             try argv.append("--include-directory");
             try argv.append(extra_include_path);
test/standalone/windows_resources/build.zig
@@ -11,11 +11,14 @@ pub fn build(b: *std.Build) void {
         .abi = .gnu,
     };
 
-    add(b, native_target, test_step);
-    add(b, cross_target, test_step);
+    add(b, native_target, .any, test_step);
+    add(b, cross_target, .any, test_step);
+
+    add(b, native_target, .gnu, test_step);
+    add(b, cross_target, .gnu, test_step);
 }
 
-fn add(b: *std.Build, target: std.zig.CrossTarget, test_step: *std.Build.Step) void {
+fn add(b: *std.Build, target: std.zig.CrossTarget, rc_includes: enum { any, gnu }, test_step: *std.Build.Step) void {
     const exe = b.addExecutable(.{
         .name = "zig_resource_test",
         .root_source_file = .{ .path = "main.zig" },
@@ -26,6 +29,10 @@ fn add(b: *std.Build, target: std.zig.CrossTarget, test_step: *std.Build.Step) v
         .file = .{ .path = "res/zig.rc" },
         .flags = &.{"/c65001"}, // UTF-8 code page
     });
+    exe.rc_includes = switch (rc_includes) {
+        .any => .any,
+        .gnu => .gnu,
+    };
 
     _ = exe.getEmittedBin();