mirror of
https://codeberg.org/ziglang/zig.git
synced 2025-12-06 05:44:20 +00:00
Sema: Stop adding Windows implib link inputs for extern "..." syntax.
Closes #23971.
This commit is contained in:
parent
044ccf4138
commit
b461d07a54
10 changed files with 75 additions and 46 deletions
20
build.zig
20
build.zig
|
|
@ -450,6 +450,7 @@ pub fn build(b: *std.Build) !void {
|
|||
.desc = "Run the behavior tests",
|
||||
.optimize_modes = optimization_modes,
|
||||
.include_paths = &.{},
|
||||
.windows_libs = &.{},
|
||||
.skip_single_threaded = skip_single_threaded,
|
||||
.skip_non_native = skip_non_native,
|
||||
.skip_freebsd = skip_freebsd,
|
||||
|
|
@ -472,6 +473,7 @@ pub fn build(b: *std.Build) !void {
|
|||
.desc = "Run the @cImport tests",
|
||||
.optimize_modes = optimization_modes,
|
||||
.include_paths = &.{"test/c_import"},
|
||||
.windows_libs = &.{},
|
||||
.skip_single_threaded = true,
|
||||
.skip_non_native = skip_non_native,
|
||||
.skip_freebsd = skip_freebsd,
|
||||
|
|
@ -492,6 +494,7 @@ pub fn build(b: *std.Build) !void {
|
|||
.desc = "Run the compiler_rt tests",
|
||||
.optimize_modes = optimization_modes,
|
||||
.include_paths = &.{},
|
||||
.windows_libs = &.{},
|
||||
.skip_single_threaded = true,
|
||||
.skip_non_native = skip_non_native,
|
||||
.skip_freebsd = skip_freebsd,
|
||||
|
|
@ -513,6 +516,7 @@ pub fn build(b: *std.Build) !void {
|
|||
.desc = "Run the zigc tests",
|
||||
.optimize_modes = optimization_modes,
|
||||
.include_paths = &.{},
|
||||
.windows_libs = &.{},
|
||||
.skip_single_threaded = true,
|
||||
.skip_non_native = skip_non_native,
|
||||
.skip_freebsd = skip_freebsd,
|
||||
|
|
@ -534,6 +538,12 @@ pub fn build(b: *std.Build) !void {
|
|||
.desc = "Run the standard library tests",
|
||||
.optimize_modes = optimization_modes,
|
||||
.include_paths = &.{},
|
||||
.windows_libs = &.{
|
||||
"advapi32",
|
||||
"crypt32",
|
||||
"iphlpapi",
|
||||
"ws2_32",
|
||||
},
|
||||
.skip_single_threaded = skip_single_threaded,
|
||||
.skip_non_native = skip_non_native,
|
||||
.skip_freebsd = skip_freebsd,
|
||||
|
|
@ -731,6 +741,12 @@ fn addCompilerMod(b: *std.Build, options: AddCompilerModOptions) *std.Build.Modu
|
|||
compiler_mod.addImport("aro", aro_mod);
|
||||
compiler_mod.addImport("aro_translate_c", aro_translate_c_mod);
|
||||
|
||||
if (options.target.result.os.tag == .windows) {
|
||||
compiler_mod.linkSystemLibrary("advapi32", .{});
|
||||
compiler_mod.linkSystemLibrary("crypt32", .{});
|
||||
compiler_mod.linkSystemLibrary("ws2_32", .{});
|
||||
}
|
||||
|
||||
return compiler_mod;
|
||||
}
|
||||
|
||||
|
|
@ -1428,6 +1444,10 @@ fn generateLangRef(b: *std.Build) std.Build.LazyPath {
|
|||
}),
|
||||
});
|
||||
|
||||
if (b.graph.host.result.os.tag == .windows) {
|
||||
doctest_exe.root_module.linkSystemLibrary("advapi32", .{});
|
||||
}
|
||||
|
||||
var dir = b.build_root.handle.openDir("doc/langref", .{ .iterate = true }) catch |err| {
|
||||
std.debug.panic("unable to open '{}doc/langref' directory: {s}", .{
|
||||
b.build_root, @errorName(err),
|
||||
|
|
|
|||
|
|
@ -2070,12 +2070,8 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil
|
|||
.emit_docs = try options.emit_docs.resolve(arena, &options, .docs),
|
||||
};
|
||||
|
||||
errdefer {
|
||||
for (comp.windows_libs.keys()) |windows_lib| gpa.free(windows_lib);
|
||||
comp.windows_libs.deinit(gpa);
|
||||
}
|
||||
try comp.windows_libs.ensureUnusedCapacity(gpa, options.windows_lib_names.len);
|
||||
for (options.windows_lib_names) |windows_lib| comp.windows_libs.putAssumeCapacity(try gpa.dupe(u8, windows_lib), {});
|
||||
comp.windows_libs = try std.StringArrayHashMapUnmanaged(void).init(gpa, options.windows_lib_names, &.{});
|
||||
errdefer comp.windows_libs.deinit(gpa);
|
||||
|
||||
// Prevent some footguns by making the "any" fields of config reflect
|
||||
// the default Module settings.
|
||||
|
|
@ -2306,6 +2302,13 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil
|
|||
|
||||
if (comp.emit_bin != null and target.ofmt != .c) {
|
||||
if (!comp.skip_linker_dependencies) {
|
||||
// These DLLs are always loaded into every Windows process.
|
||||
if (target.os.tag == .windows and is_exe_or_dyn_lib) {
|
||||
try comp.windows_libs.ensureUnusedCapacity(gpa, 2);
|
||||
comp.windows_libs.putAssumeCapacity("kernel32", {});
|
||||
comp.windows_libs.putAssumeCapacity("ntdll", {});
|
||||
}
|
||||
|
||||
// If we need to build libc for the target, add work items for it.
|
||||
// We go through the work queue so that building can be done in parallel.
|
||||
// If linking against host libc installation, instead queue up jobs
|
||||
|
|
@ -2399,7 +2402,7 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil
|
|||
|
||||
// When linking mingw-w64 there are some import libs we always need.
|
||||
try comp.windows_libs.ensureUnusedCapacity(gpa, mingw.always_link_libs.len);
|
||||
for (mingw.always_link_libs) |name| comp.windows_libs.putAssumeCapacity(try gpa.dupe(u8, name), {});
|
||||
for (mingw.always_link_libs) |name| comp.windows_libs.putAssumeCapacity(name, {});
|
||||
} else {
|
||||
return error.LibCUnavailable;
|
||||
}
|
||||
|
|
@ -2497,7 +2500,6 @@ pub fn destroy(comp: *Compilation) void {
|
|||
comp.c_object_work_queue.deinit();
|
||||
comp.win32_resource_work_queue.deinit();
|
||||
|
||||
for (comp.windows_libs.keys()) |windows_lib| gpa.free(windows_lib);
|
||||
comp.windows_libs.deinit(gpa);
|
||||
|
||||
{
|
||||
|
|
@ -7599,27 +7601,6 @@ fn getCrtPathsInner(
|
|||
};
|
||||
}
|
||||
|
||||
pub fn addLinkLib(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.skip_linker_dependencies) return;
|
||||
const target = &comp.root_mod.resolved_target.result;
|
||||
if (target.os.tag != .windows or target.ofmt == .c) return;
|
||||
|
||||
// This happens when an `extern "foo"` function is referenced.
|
||||
// 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.
|
||||
const gop = try comp.windows_libs.getOrPut(comp.gpa, lib_name);
|
||||
if (gop.found_existing) return;
|
||||
{
|
||||
errdefer _ = comp.windows_libs.pop();
|
||||
gop.key_ptr.* = try comp.gpa.dupe(u8, lib_name);
|
||||
}
|
||||
try comp.queueJob(.{ .windows_import_lib = gop.index });
|
||||
}
|
||||
|
||||
/// This decides the optimization mode for all zig-provided libraries, including
|
||||
/// compiler-rt, libcxx, libc, libunwind, etc.
|
||||
pub fn compilerRtOptMode(comp: Compilation) std.builtin.OptimizeMode {
|
||||
|
|
|
|||
13
src/Sema.zig
13
src/Sema.zig
|
|
@ -9418,14 +9418,6 @@ fn resolveGenericBody(
|
|||
return sema.resolveConstDefinedValue(block, src, result, reason);
|
||||
}
|
||||
|
||||
/// Given a library name, examines if the library name should end up in
|
||||
/// `link.File.Options.windows_libs` table (for example, libc is always
|
||||
/// specified via dedicated flag `link_libc` instead),
|
||||
/// and puts it there if it doesn't exist.
|
||||
/// It also dupes the library name which can then be saved as part of the
|
||||
/// respective `Decl` (either `ExternFn` or `Var`).
|
||||
/// The liveness of the duped library name is tied to liveness of `Zcu`.
|
||||
/// To deallocate, call `deinit` on the respective `Decl` (`ExternFn` or `Var`).
|
||||
pub fn handleExternLibName(
|
||||
sema: *Sema,
|
||||
block: *Block,
|
||||
|
|
@ -9475,11 +9467,6 @@ pub fn handleExternLibName(
|
|||
.{ lib_name, lib_name },
|
||||
);
|
||||
}
|
||||
comp.addLinkLib(lib_name) catch |err| {
|
||||
return sema.fail(block, src_loc, "unable to add link lib '{s}': {s}", .{
|
||||
lib_name, @errorName(err),
|
||||
});
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1012,6 +1012,7 @@ const mingw32_winpthreads_src = [_][]const u8{
|
|||
"winpthreads" ++ path.sep_str ++ "thread.c",
|
||||
};
|
||||
|
||||
// Note: kernel32 and ntdll are always linked even without targeting MinGW-w64.
|
||||
pub const always_link_libs = [_][]const u8{
|
||||
"api-ms-win-crt-conio-l1-1-0",
|
||||
"api-ms-win-crt-convert-l1-1-0",
|
||||
|
|
@ -1029,8 +1030,6 @@ pub const always_link_libs = [_][]const u8{
|
|||
"api-ms-win-crt-time-l1-1-0",
|
||||
"api-ms-win-crt-utility-l1-1-0",
|
||||
"advapi32",
|
||||
"kernel32",
|
||||
"ntdll",
|
||||
"shell32",
|
||||
"user32",
|
||||
};
|
||||
|
|
|
|||
21
src/main.zig
21
src/main.zig
|
|
@ -306,6 +306,7 @@ fn mainArgs(gpa: Allocator, arena: Allocator, args: []const []const u8) !void {
|
|||
return jitCmd(gpa, arena, cmd_args, .{
|
||||
.cmd_name = "resinator",
|
||||
.root_src_path = "resinator/main.zig",
|
||||
.windows_libs = &.{"advapi32"},
|
||||
.depend_on_aro = true,
|
||||
.prepend_zig_lib_dir_path = true,
|
||||
.server = use_server,
|
||||
|
|
@ -3631,7 +3632,6 @@ fn buildOutputType(
|
|||
} else if (target.os.tag == .windows) {
|
||||
try test_exec_args.appendSlice(arena, &.{
|
||||
"--subsystem", "console",
|
||||
"-lkernel32", "-lntdll",
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -3845,7 +3845,8 @@ fn createModule(
|
|||
.only_compiler_rt => continue,
|
||||
}
|
||||
|
||||
if (target.isMinGW()) {
|
||||
// We currently prefer import libraries provided by MinGW-w64 even for MSVC.
|
||||
if (target.os.tag == .windows) {
|
||||
const exists = mingw.libExists(arena, target, create_module.dirs.zig_lib, lib_name) catch |err| {
|
||||
fatal("failed to check zig installation for DLL import libs: {s}", .{
|
||||
@errorName(err),
|
||||
|
|
@ -5221,6 +5222,12 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !void {
|
|||
|
||||
try root_mod.deps.put(arena, "@build", build_mod);
|
||||
|
||||
var windows_libs: std.StringArrayHashMapUnmanaged(void) = .empty;
|
||||
|
||||
if (resolved_target.result.os.tag == .windows) {
|
||||
try windows_libs.put(arena, "advapi32", {});
|
||||
}
|
||||
|
||||
const comp = Compilation.create(gpa, arena, .{
|
||||
.dirs = dirs,
|
||||
.root_name = "build",
|
||||
|
|
@ -5242,6 +5249,7 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !void {
|
|||
.cache_mode = .whole,
|
||||
.reference_trace = reference_trace,
|
||||
.debug_compile_errors = debug_compile_errors,
|
||||
.windows_lib_names = windows_libs.keys(),
|
||||
}) catch |err| {
|
||||
fatal("unable to create compilation: {s}", .{@errorName(err)});
|
||||
};
|
||||
|
|
@ -5345,6 +5353,7 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !void {
|
|||
const JitCmdOptions = struct {
|
||||
cmd_name: []const u8,
|
||||
root_src_path: []const u8,
|
||||
windows_libs: []const []const u8 = &.{},
|
||||
prepend_zig_lib_dir_path: bool = false,
|
||||
prepend_global_cache_path: bool = false,
|
||||
prepend_zig_exe_path: bool = false,
|
||||
|
|
@ -5461,6 +5470,13 @@ fn jitCmd(
|
|||
try root_mod.deps.put(arena, "aro", aro_mod);
|
||||
}
|
||||
|
||||
var windows_libs: std.StringArrayHashMapUnmanaged(void) = .empty;
|
||||
|
||||
if (resolved_target.result.os.tag == .windows) {
|
||||
try windows_libs.ensureUnusedCapacity(arena, options.windows_libs.len);
|
||||
for (options.windows_libs) |lib| windows_libs.putAssumeCapacity(lib, {});
|
||||
}
|
||||
|
||||
const comp = Compilation.create(gpa, arena, .{
|
||||
.dirs = dirs,
|
||||
.root_name = options.cmd_name,
|
||||
|
|
@ -5471,6 +5487,7 @@ fn jitCmd(
|
|||
.self_exe_path = self_exe_path,
|
||||
.thread_pool = &thread_pool,
|
||||
.cache_mode = .whole,
|
||||
.windows_lib_names = windows_libs.keys(),
|
||||
}) catch |err| {
|
||||
fatal("unable to create compilation: {s}", .{@errorName(err)});
|
||||
};
|
||||
|
|
|
|||
|
|
@ -50,6 +50,10 @@ pub fn build(b: *std.Build) void {
|
|||
});
|
||||
if (case.link_libc) exe.root_module.link_libc = true;
|
||||
|
||||
if (resolved_target.result.os.tag == .windows) {
|
||||
exe.root_module.linkSystemLibrary("advapi32", .{});
|
||||
}
|
||||
|
||||
_ = exe.getEmittedBin();
|
||||
|
||||
step.dependOn(&exe.step);
|
||||
|
|
@ -66,6 +70,10 @@ pub fn build(b: *std.Build) void {
|
|||
});
|
||||
if (case.link_libc) exe.root_module.link_libc = true;
|
||||
|
||||
if (resolved_target.result.os.tag == .windows) {
|
||||
exe.root_module.linkSystemLibrary("advapi32", .{});
|
||||
}
|
||||
|
||||
const run = b.addRunArtifact(exe);
|
||||
step.dependOn(&run.step);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -47,6 +47,8 @@ pub fn build(b: *std.Build) !void {
|
|||
}),
|
||||
});
|
||||
|
||||
fuzz.root_module.linkSystemLibrary("advapi32", .{});
|
||||
|
||||
const fuzz_max_iterations = b.option(u64, "iterations", "The max fuzz iterations (default: 100)") orelse 100;
|
||||
const fuzz_iterations_arg = std.fmt.allocPrint(b.allocator, "{}", .{fuzz_max_iterations}) catch @panic("oom");
|
||||
|
||||
|
|
|
|||
|
|
@ -28,6 +28,8 @@ pub fn build(b: *std.Build) !void {
|
|||
}),
|
||||
});
|
||||
|
||||
test_exe.root_module.linkSystemLibrary("advapi32", .{});
|
||||
|
||||
const run = b.addRunArtifact(test_exe);
|
||||
run.addArtifactArg(echo_args);
|
||||
run.expectExitCode(0);
|
||||
|
|
@ -44,6 +46,8 @@ pub fn build(b: *std.Build) !void {
|
|||
}),
|
||||
});
|
||||
|
||||
fuzz.root_module.linkSystemLibrary("advapi32", .{});
|
||||
|
||||
const fuzz_max_iterations = b.option(u64, "iterations", "The max fuzz iterations (default: 100)") orelse 100;
|
||||
const fuzz_iterations_arg = std.fmt.allocPrint(b.allocator, "{}", .{fuzz_max_iterations}) catch @panic("oom");
|
||||
|
||||
|
|
|
|||
|
|
@ -28,6 +28,8 @@ pub fn build(b: *std.Build) void {
|
|||
}),
|
||||
});
|
||||
|
||||
main.root_module.linkSystemLibrary("advapi32", .{});
|
||||
|
||||
const run = b.addRunArtifact(main);
|
||||
run.addArtifactArg(hello);
|
||||
run.expectExitCode(0);
|
||||
|
|
|
|||
|
|
@ -2308,6 +2308,7 @@ const ModuleTestOptions = struct {
|
|||
desc: []const u8,
|
||||
optimize_modes: []const OptimizeMode,
|
||||
include_paths: []const []const u8,
|
||||
windows_libs: []const []const u8,
|
||||
skip_single_threaded: bool,
|
||||
skip_non_native: bool,
|
||||
skip_freebsd: bool,
|
||||
|
|
@ -2437,6 +2438,10 @@ pub fn addModuleTests(b: *std.Build, options: ModuleTestOptions) *Step {
|
|||
|
||||
for (options.include_paths) |include_path| these_tests.addIncludePath(b.path(include_path));
|
||||
|
||||
if (target.os.tag == .windows) {
|
||||
for (options.windows_libs) |lib| these_tests.linkSystemLibrary(lib);
|
||||
}
|
||||
|
||||
const qualified_name = b.fmt("{s}-{s}-{s}-{s}{s}{s}{s}{s}{s}{s}", .{
|
||||
options.name,
|
||||
triple_txt,
|
||||
|
|
@ -2732,6 +2737,10 @@ pub fn addIncrementalTests(b: *std.Build, test_step: *Step) !void {
|
|||
}),
|
||||
});
|
||||
|
||||
if (b.graph.host.result.os.tag == .windows) {
|
||||
incr_check.root_module.linkSystemLibrary("advapi32", .{});
|
||||
}
|
||||
|
||||
var dir = try b.build_root.handle.openDir("test/incremental", .{ .iterate = true });
|
||||
defer dir.close();
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue