authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-12-11 13:15:58-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-12-11 17:23:55-07:00
log4797fdb3db6570ae65ff5f80cb1071307c42a244
treec1f05ac1432f2f47a960f2a86fabd862d2db1913
parent74c17aa8c5bfff9ba13aaed7b978055d85709ede

fix deadlock with build-exe on an object for windows

The steps to repro this issue are: zig build-obj hello.zig -target x86_64-windows-msvc zig build-exe hello.obj -target x86_64-windows-msvc --subsystem console -lkernel32 -lntdll What was happening is that the main Compilation added a work item to produce kernel32.lib. Then it added a sub-Compilation to build zig's libc, which ended up calling a function with extern "kernel32", which caused the sub-Compilation to also try to produce kernel32.lib. The main Compilation and sub-Compilation do not coordinate about the set of import libraries that they will be trying to build, so this caused a deadlock. This commit solves the problem by disabling the extern "foo" feature from working when building compiler_rt or libc. Zig's linker code is now responsible for putting the appropriate import libs on the linker line, if any for compiler_rt and libc. Related: #5825

4 files changed, 35 insertions(+), 0 deletions(-)

src/Compilation.zig+5
...@@ -3116,6 +3116,11 @@ pub fn build_crt_file(...@@ -3116,6 +3116,11 @@ pub fn build_crt_file(
3116}3116}
31173117
3118pub fn stage1AddLinkLib(comp: *Compilation, lib_name: []const u8) !void {3118pub fn stage1AddLinkLib(comp: *Compilation, lib_name: []const u8) !void {
3119 // Avoid deadlocking on building import libs such as kernel32.lib
3120 // This can happen when the user uses `build-exe foo.obj -lkernel32` and then
3121 // when we create a sub-Compilation for zig libc, it also tries to build kernel32.lib.
3122 if (comp.bin_file.options.is_compiler_rt_or_libc) return;
3123
3119 // This happens when an `extern "foo"` function is referenced by the stage1 backend.3124 // This happens when an `extern "foo"` function is referenced by the stage1 backend.
3120 // If we haven't seen this library yet and we're targeting Windows, we need to queue up3125 // If we haven't seen this library yet and we're targeting Windows, we need to queue up
3121 // a work item to produce the DLL import library for this.3126 // a work item to produce the DLL import library for this.
test/standalone.zig+1
...@@ -15,6 +15,7 @@ pub fn addCases(cases: *tests.StandaloneContext) void {...@@ -15,6 +15,7 @@ pub fn addCases(cases: *tests.StandaloneContext) void {
15 cases.addBuildFile("test/standalone/static_c_lib/build.zig");15 cases.addBuildFile("test/standalone/static_c_lib/build.zig");
16 cases.addBuildFile("test/standalone/issue_339/build.zig");16 cases.addBuildFile("test/standalone/issue_339/build.zig");
17 cases.addBuildFile("test/standalone/issue_794/build.zig");17 cases.addBuildFile("test/standalone/issue_794/build.zig");
18 cases.addBuildFile("test/standalone/issue_5825/build.zig");
18 cases.addBuildFile("test/standalone/pkg_import/build.zig");19 cases.addBuildFile("test/standalone/pkg_import/build.zig");
19 cases.addBuildFile("test/standalone/use_alias/build.zig");20 cases.addBuildFile("test/standalone/use_alias/build.zig");
20 cases.addBuildFile("test/standalone/brace_expansion/build.zig");21 cases.addBuildFile("test/standalone/brace_expansion/build.zig");
test/standalone/issue_5825/build.zig created+24
...@@ -0,0 +1,24 @@
1const Builder = @import("std").build.Builder;
2
3pub fn build(b: *Builder) void {
4 const target = .{
5 .cpu_arch = .x86_64,
6 .os_tag = .windows,
7 .abi = .msvc,
8 };
9 const mode = b.standardReleaseOptions();
10 const obj = b.addObject("issue_5825", "main.zig");
11 obj.setTarget(target);
12 obj.setBuildMode(mode);
13
14 const exe = b.addExecutable("issue_5825", null);
15 exe.subsystem = .Console;
16 exe.linkSystemLibrary("kernel32");
17 exe.linkSystemLibrary("ntdll");
18 exe.setTarget(target);
19 exe.setBuildMode(mode);
20 exe.addObject(obj);
21
22 const test_step = b.step("test", "Test the program");
23 test_step.dependOn(&exe.step);
24}
test/standalone/issue_5825/main.zig created+5
...@@ -0,0 +1,5 @@
1const std = @import("std");
2
3pub fn main() anyerror!void {
4 std.log.info("All your codebase are belong to us.", .{});
5}