| author | |
| committer | |
| log | a950cb42bdf7b3f339071868c6675e7dcc892bae |
| tree | ddf75e85213e2b1ea0d8accb78471b6d25d01b60 |
| parent | fdcac5ecbd324170f7281f6704ead18b7d904e72 |
Allow --out-implib and -implib as passed by cmake and meson to be
correctly passed through to the linker to generate import libraries.4 files changed, 40 insertions(+), 1 deletions(-)
src/Compilation.zig+5-1| ... | ... | @@ -767,6 +767,8 @@ pub const InitOptions = struct { |
| 767 | 767 | test_filter: ?[]const u8 = null, |
| 768 | 768 | test_name_prefix: ?[]const u8 = null, |
| 769 | 769 | subsystem: ?std.Target.SubSystem = null, |
| 770 | /// Windows/PE only. Where to output the import library, can contain directories. | |
| 771 | out_implib: ?[]const u8 = null, | |
| 770 | 772 | /// WASI-only. Type of WASI execution model ("command" or "reactor"). |
| 771 | 773 | wasi_exec_model: ?std.builtin.WasiExecModel = null, |
| 772 | 774 | /// (Zig compiler development) Enable dumping linker's state as JSON. |
| ... | ... | @@ -946,7 +948,8 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation { |
| 946 | 948 | options.output_mode == .Lib or |
| 947 | 949 | options.lld_argv.len != 0 or |
| 948 | 950 | options.image_base_override != null or |
| 949 | options.linker_script != null or options.version_script != null) | |
| 951 | options.linker_script != null or options.version_script != null or | |
| 952 | options.out_implib != null) | |
| 950 | 953 | { |
| 951 | 954 | break :blk true; |
| 952 | 955 | } |
| ... | ... | @@ -1461,6 +1464,7 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation { |
| 1461 | 1464 | .each_lib_rpath = options.each_lib_rpath orelse options.is_native_os, |
| 1462 | 1465 | .disable_lld_caching = options.disable_lld_caching, |
| 1463 | 1466 | .subsystem = options.subsystem, |
| 1467 | .out_implib = options.out_implib, | |
| 1464 | 1468 | .is_test = options.is_test, |
| 1465 | 1469 | .wasi_exec_model = wasi_exec_model, |
| 1466 | 1470 | .use_stage1 = use_stage1, |
src/link.zig+1| ... | ... | @@ -127,6 +127,7 @@ pub const Options = struct { |
| 127 | 127 | gc_sections: ?bool = null, |
| 128 | 128 | allow_shlib_undefined: ?bool, |
| 129 | 129 | subsystem: ?std.Target.SubSystem, |
| 130 | out_implib: ?[]const u8, | |
| 130 | 131 | linker_script: ?[]const u8, |
| 131 | 132 | version_script: ?[]const u8, |
| 132 | 133 | soname: ?[]const u8, |
src/link/Coff.zig+5| ... | ... | @@ -948,6 +948,7 @@ fn linkWithLLD(self: *Coff, comp: *Compilation) !void { |
| 948 | 948 | man.hash.add(self.base.options.dynamicbase); |
| 949 | 949 | man.hash.addOptional(self.base.options.major_subsystem_version); |
| 950 | 950 | man.hash.addOptional(self.base.options.minor_subsystem_version); |
| 951 | man.hash.addOptionalBytes(self.base.options.out_implib); | |
| 951 | 952 | |
| 952 | 953 | // We don't actually care whether it's a cache hit or miss; we just need the digest and the lock. |
| 953 | 954 | _ = try man.hit(); |
| ... | ... | @@ -1094,6 +1095,10 @@ fn linkWithLLD(self: *Coff, comp: *Compilation) !void { |
| 1094 | 1095 | try argv.append(p); |
| 1095 | 1096 | } |
| 1096 | 1097 | |
| 1098 | if (self.base.options.out_implib != null) { | |
| 1099 | try argv.append(try allocPrint(arena, "-IMPLIB:{s}.lib", .{full_out_path})); | |
| 1100 | } | |
| 1101 | ||
| 1097 | 1102 | const resolved_subsystem: ?std.Target.SubSystem = blk: { |
| 1098 | 1103 | if (self.base.options.subsystem) |explicit| break :blk explicit; |
| 1099 | 1104 | switch (target.os.tag) { |
src/main.zig+29| ... | ... | @@ -654,6 +654,7 @@ fn buildOutputType( |
| 654 | 654 | var main_pkg_path: ?[]const u8 = null; |
| 655 | 655 | var clang_preprocessor_mode: Compilation.ClangPreprocessorMode = .no; |
| 656 | 656 | var subsystem: ?std.Target.SubSystem = null; |
| 657 | var out_implib: ?[]const u8 = null; | |
| 657 | 658 | var major_subsystem_version: ?u32 = null; |
| 658 | 659 | var minor_subsystem_version: ?u32 = null; |
| 659 | 660 | var wasi_exec_model: ?std.builtin.WasiExecModel = null; |
| ... | ... | @@ -1637,6 +1638,14 @@ fn buildOutputType( |
| 1637 | 1638 | fatal("unable to parse -current_version '{s}': {s}", .{ linker_args.items[i], @errorName(err) }); |
| 1638 | 1639 | }; |
| 1639 | 1640 | have_version = true; |
| 1641 | } else if (mem.eql(u8, arg, "--out-implib") or | |
| 1642 | mem.eql(u8, arg, "-implib")) | |
| 1643 | { | |
| 1644 | i += 1; | |
| 1645 | if (i >= linker_args.items.len) { | |
| 1646 | fatal("expected linker arg after '{s}'", .{arg}); | |
| 1647 | } | |
| 1648 | out_implib = linker_args.items[i]; | |
| 1640 | 1649 | } else { |
| 1641 | 1650 | warn("unsupported linker arg: {s}", .{arg}); |
| 1642 | 1651 | } |
| ... | ... | @@ -2154,6 +2163,16 @@ fn buildOutputType( |
| 2154 | 2163 | else => false, |
| 2155 | 2164 | }; |
| 2156 | 2165 | |
| 2166 | // Always output import libraries (.lib) when building for msvc to replicate | |
| 2167 | // `link` behavior. lld does not always output import libraries so on the | |
| 2168 | // gnu abi users must set out_implib. | |
| 2169 | if (output_mode == .Lib and emit_bin == .yes and target_info.target.abi == .msvc and out_implib == null) { | |
| 2170 | const emit_bin_ext = fs.path.extension(emit_bin.yes); | |
| 2171 | out_implib = try std.fmt.allocPrint(gpa, "{s}.lib", .{ | |
| 2172 | emit_bin.yes[0 .. emit_bin.yes.len - emit_bin_ext.len], | |
| 2173 | }); | |
| 2174 | } | |
| 2175 | ||
| 2157 | 2176 | gimmeMoreOfThoseSweetSweetFileDescriptors(); |
| 2158 | 2177 | |
| 2159 | 2178 | const comp = Compilation.create(gpa, .{ |
| ... | ... | @@ -2263,6 +2282,7 @@ fn buildOutputType( |
| 2263 | 2282 | .test_name_prefix = test_name_prefix, |
| 2264 | 2283 | .disable_lld_caching = !have_enable_cache, |
| 2265 | 2284 | .subsystem = subsystem, |
| 2285 | .out_implib = out_implib, | |
| 2266 | 2286 | .wasi_exec_model = wasi_exec_model, |
| 2267 | 2287 | .debug_compile_errors = debug_compile_errors, |
| 2268 | 2288 | .enable_link_snapshots = enable_link_snapshots, |
| ... | ... | @@ -2661,6 +2681,15 @@ fn updateModule(gpa: *Allocator, comp: *Compilation, hook: AfterUpdateHook) !voi |
| 2661 | 2681 | |
| 2662 | 2682 | _ = try cache_dir.updateFile(src_pdb_path, cwd, dst_pdb_path, .{}); |
| 2663 | 2683 | } |
| 2684 | ||
| 2685 | if (comp.bin_file.options.out_implib) |out_implib| { | |
| 2686 | const src_implib_path = try std.fmt.allocPrint(gpa, "{s}.lib", .{bin_sub_path}); | |
| 2687 | defer gpa.free(src_implib_path); | |
| 2688 | if (std.fs.path.dirname(out_implib)) |implib_dir| { | |
| 2689 | try cwd.makePath(implib_dir); | |
| 2690 | } | |
| 2691 | _ = try cache_dir.updateFile(src_implib_path, cwd, out_implib, .{}); | |
| 2692 | } | |
| 2664 | 2693 | }, |
| 2665 | 2694 | } |
| 2666 | 2695 | } |