mirror of
https://github.com/ziglang/zig.git
synced 2026-02-02 12:43:40 +00:00
Coff linker: Add IMPLIB support
Allow --out-implib and -implib as passed by cmake and meson to be correctly passed through to the linker to generate import libraries.
This commit is contained in:
parent
fdcac5ecbd
commit
a950cb42bd
@ -767,6 +767,8 @@ pub const InitOptions = struct {
|
||||
test_filter: ?[]const u8 = null,
|
||||
test_name_prefix: ?[]const u8 = null,
|
||||
subsystem: ?std.Target.SubSystem = null,
|
||||
/// Windows/PE only. Where to output the import library, can contain directories.
|
||||
out_implib: ?[]const u8 = null,
|
||||
/// WASI-only. Type of WASI execution model ("command" or "reactor").
|
||||
wasi_exec_model: ?std.builtin.WasiExecModel = null,
|
||||
/// (Zig compiler development) Enable dumping linker's state as JSON.
|
||||
@ -946,7 +948,8 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {
|
||||
options.output_mode == .Lib or
|
||||
options.lld_argv.len != 0 or
|
||||
options.image_base_override != null or
|
||||
options.linker_script != null or options.version_script != null)
|
||||
options.linker_script != null or options.version_script != null or
|
||||
options.out_implib != null)
|
||||
{
|
||||
break :blk true;
|
||||
}
|
||||
@ -1461,6 +1464,7 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {
|
||||
.each_lib_rpath = options.each_lib_rpath orelse options.is_native_os,
|
||||
.disable_lld_caching = options.disable_lld_caching,
|
||||
.subsystem = options.subsystem,
|
||||
.out_implib = options.out_implib,
|
||||
.is_test = options.is_test,
|
||||
.wasi_exec_model = wasi_exec_model,
|
||||
.use_stage1 = use_stage1,
|
||||
|
||||
@ -127,6 +127,7 @@ pub const Options = struct {
|
||||
gc_sections: ?bool = null,
|
||||
allow_shlib_undefined: ?bool,
|
||||
subsystem: ?std.Target.SubSystem,
|
||||
out_implib: ?[]const u8,
|
||||
linker_script: ?[]const u8,
|
||||
version_script: ?[]const u8,
|
||||
soname: ?[]const u8,
|
||||
|
||||
@ -948,6 +948,7 @@ fn linkWithLLD(self: *Coff, comp: *Compilation) !void {
|
||||
man.hash.add(self.base.options.dynamicbase);
|
||||
man.hash.addOptional(self.base.options.major_subsystem_version);
|
||||
man.hash.addOptional(self.base.options.minor_subsystem_version);
|
||||
man.hash.addOptionalBytes(self.base.options.out_implib);
|
||||
|
||||
// We don't actually care whether it's a cache hit or miss; we just need the digest and the lock.
|
||||
_ = try man.hit();
|
||||
@ -1094,6 +1095,10 @@ fn linkWithLLD(self: *Coff, comp: *Compilation) !void {
|
||||
try argv.append(p);
|
||||
}
|
||||
|
||||
if (self.base.options.out_implib != null) {
|
||||
try argv.append(try allocPrint(arena, "-IMPLIB:{s}.lib", .{full_out_path}));
|
||||
}
|
||||
|
||||
const resolved_subsystem: ?std.Target.SubSystem = blk: {
|
||||
if (self.base.options.subsystem) |explicit| break :blk explicit;
|
||||
switch (target.os.tag) {
|
||||
|
||||
29
src/main.zig
29
src/main.zig
@ -654,6 +654,7 @@ fn buildOutputType(
|
||||
var main_pkg_path: ?[]const u8 = null;
|
||||
var clang_preprocessor_mode: Compilation.ClangPreprocessorMode = .no;
|
||||
var subsystem: ?std.Target.SubSystem = null;
|
||||
var out_implib: ?[]const u8 = null;
|
||||
var major_subsystem_version: ?u32 = null;
|
||||
var minor_subsystem_version: ?u32 = null;
|
||||
var wasi_exec_model: ?std.builtin.WasiExecModel = null;
|
||||
@ -1637,6 +1638,14 @@ fn buildOutputType(
|
||||
fatal("unable to parse -current_version '{s}': {s}", .{ linker_args.items[i], @errorName(err) });
|
||||
};
|
||||
have_version = true;
|
||||
} else if (mem.eql(u8, arg, "--out-implib") or
|
||||
mem.eql(u8, arg, "-implib"))
|
||||
{
|
||||
i += 1;
|
||||
if (i >= linker_args.items.len) {
|
||||
fatal("expected linker arg after '{s}'", .{arg});
|
||||
}
|
||||
out_implib = linker_args.items[i];
|
||||
} else {
|
||||
warn("unsupported linker arg: {s}", .{arg});
|
||||
}
|
||||
@ -2154,6 +2163,16 @@ fn buildOutputType(
|
||||
else => false,
|
||||
};
|
||||
|
||||
// Always output import libraries (.lib) when building for msvc to replicate
|
||||
// `link` behavior. lld does not always output import libraries so on the
|
||||
// gnu abi users must set out_implib.
|
||||
if (output_mode == .Lib and emit_bin == .yes and target_info.target.abi == .msvc and out_implib == null) {
|
||||
const emit_bin_ext = fs.path.extension(emit_bin.yes);
|
||||
out_implib = try std.fmt.allocPrint(gpa, "{s}.lib", .{
|
||||
emit_bin.yes[0 .. emit_bin.yes.len - emit_bin_ext.len],
|
||||
});
|
||||
}
|
||||
|
||||
gimmeMoreOfThoseSweetSweetFileDescriptors();
|
||||
|
||||
const comp = Compilation.create(gpa, .{
|
||||
@ -2263,6 +2282,7 @@ fn buildOutputType(
|
||||
.test_name_prefix = test_name_prefix,
|
||||
.disable_lld_caching = !have_enable_cache,
|
||||
.subsystem = subsystem,
|
||||
.out_implib = out_implib,
|
||||
.wasi_exec_model = wasi_exec_model,
|
||||
.debug_compile_errors = debug_compile_errors,
|
||||
.enable_link_snapshots = enable_link_snapshots,
|
||||
@ -2661,6 +2681,15 @@ fn updateModule(gpa: *Allocator, comp: *Compilation, hook: AfterUpdateHook) !voi
|
||||
|
||||
_ = try cache_dir.updateFile(src_pdb_path, cwd, dst_pdb_path, .{});
|
||||
}
|
||||
|
||||
if (comp.bin_file.options.out_implib) |out_implib| {
|
||||
const src_implib_path = try std.fmt.allocPrint(gpa, "{s}.lib", .{bin_sub_path});
|
||||
defer gpa.free(src_implib_path);
|
||||
if (std.fs.path.dirname(out_implib)) |implib_dir| {
|
||||
try cwd.makePath(implib_dir);
|
||||
}
|
||||
_ = try cache_dir.updateFile(src_implib_path, cwd, out_implib, .{});
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user