Skip to content

Commit c4f53d1

Browse files
committed
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: ziglang#5825
1 parent 5b56f4e commit c4f53d1

File tree

4 files changed

+35
-0
lines changed

4 files changed

+35
-0
lines changed

src/Compilation.zig

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3174,6 +3174,11 @@ pub fn build_crt_file(
31743174
}
31753175

31763176
pub fn stage1AddLinkLib(comp: *Compilation, lib_name: []const u8) !void {
3177+
// Avoid deadlocking on building import libs such as kernel32.lib
3178+
// This can happen when the user uses `build-exe foo.obj -lkernel32` and then
3179+
// when we create a sub-Compilation for zig libc, it also tries to build kernel32.lib.
3180+
if (comp.bin_file.options.is_compiler_rt_or_libc) return;
3181+
31773182
// This happens when an `extern "foo"` function is referenced by the stage1 backend.
31783183
// If we haven't seen this library yet and we're targeting Windows, we need to queue up
31793184
// a work item to produce the DLL import library for this.

test/standalone.zig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ pub fn addCases(cases: *tests.StandaloneContext) void {
1515
cases.addBuildFile("test/standalone/static_c_lib/build.zig");
1616
cases.addBuildFile("test/standalone/issue_339/build.zig");
1717
cases.addBuildFile("test/standalone/issue_794/build.zig");
18+
cases.addBuildFile("test/standalone/issue_5825/build.zig");
1819
cases.addBuildFile("test/standalone/pkg_import/build.zig");
1920
cases.addBuildFile("test/standalone/use_alias/build.zig");
2021
cases.addBuildFile("test/standalone/brace_expansion/build.zig");

test/standalone/issue_5825/build.zig

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
const Builder = @import("std").build.Builder;
2+
3+
pub 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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
const std = @import("std");
2+
3+
pub fn main() anyerror!void {
4+
std.log.info("All your codebase are belong to us.", .{});
5+
}

0 commit comments

Comments
 (0)