aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2020-12-11 13:15:58 -0700
committerAndrew Kelley <andrew@ziglang.org>2020-12-11 18:34:34 -0500
commitc4f53d1ef65b7942383471876e02a1bd03d37dd9 (patch)
tree93652ba8abf6a20f8529354ec165b8f878254b48
parent5b56f4e48ae01b8b108d063cbc2e45c83d76413d (diff)
downloadzig-c4f53d1ef65b7942383471876e02a1bd03d37dd9.tar.gz
zig-c4f53d1ef65b7942383471876e02a1bd03d37dd9.zip
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
-rw-r--r--src/Compilation.zig5
-rw-r--r--test/standalone.zig1
-rw-r--r--test/standalone/issue_5825/build.zig24
-rw-r--r--test/standalone/issue_5825/main.zig5
4 files changed, 35 insertions, 0 deletions
diff --git a/src/Compilation.zig b/src/Compilation.zig
index 3eeaa9ca2a..13ee04765c 100644
--- a/src/Compilation.zig
+++ b/src/Compilation.zig
@@ -3174,6 +3174,11 @@ pub fn build_crt_file(
}
pub fn stage1AddLinkLib(comp: *Compilation, lib_name: []const u8) !void {
+ // Avoid deadlocking on building import libs such as kernel32.lib
+ // This can happen when the user uses `build-exe foo.obj -lkernel32` and then
+ // when we create a sub-Compilation for zig libc, it also tries to build kernel32.lib.
+ if (comp.bin_file.options.is_compiler_rt_or_libc) return;
+
// This happens when an `extern "foo"` function is referenced by the stage1 backend.
// If we haven't seen this library yet and we're targeting Windows, we need to queue up
// a work item to produce the DLL import library for this.
diff --git a/test/standalone.zig b/test/standalone.zig
index 1295ac329b..3ad0659f09 100644
--- a/test/standalone.zig
+++ b/test/standalone.zig
@@ -15,6 +15,7 @@ pub fn addCases(cases: *tests.StandaloneContext) void {
cases.addBuildFile("test/standalone/static_c_lib/build.zig");
cases.addBuildFile("test/standalone/issue_339/build.zig");
cases.addBuildFile("test/standalone/issue_794/build.zig");
+ cases.addBuildFile("test/standalone/issue_5825/build.zig");
cases.addBuildFile("test/standalone/pkg_import/build.zig");
cases.addBuildFile("test/standalone/use_alias/build.zig");
cases.addBuildFile("test/standalone/brace_expansion/build.zig");
diff --git a/test/standalone/issue_5825/build.zig b/test/standalone/issue_5825/build.zig
new file mode 100644
index 0000000000..8f43ae1358
--- /dev/null
+++ b/test/standalone/issue_5825/build.zig
@@ -0,0 +1,24 @@
+const Builder = @import("std").build.Builder;
+
+pub fn build(b: *Builder) void {
+ const target = .{
+ .cpu_arch = .x86_64,
+ .os_tag = .windows,
+ .abi = .msvc,
+ };
+ const mode = b.standardReleaseOptions();
+ const obj = b.addObject("issue_5825", "main.zig");
+ obj.setTarget(target);
+ obj.setBuildMode(mode);
+
+ const exe = b.addExecutable("issue_5825", null);
+ exe.subsystem = .Console;
+ exe.linkSystemLibrary("kernel32");
+ exe.linkSystemLibrary("ntdll");
+ exe.setTarget(target);
+ exe.setBuildMode(mode);
+ exe.addObject(obj);
+
+ const test_step = b.step("test", "Test the program");
+ test_step.dependOn(&exe.step);
+}
diff --git a/test/standalone/issue_5825/main.zig b/test/standalone/issue_5825/main.zig
new file mode 100644
index 0000000000..d29869ff88
--- /dev/null
+++ b/test/standalone/issue_5825/main.zig
@@ -0,0 +1,5 @@
+const std = @import("std");
+
+pub fn main() anyerror!void {
+ std.log.info("All your codebase are belong to us.", .{});
+}