mirror of
https://github.com/ziglang/zig.git
synced 2026-02-12 20:37:54 +00:00
Merge pull request #9347 from kkartaltepe/implib-support
Coff linker: Add IMPLIB support
This commit is contained in:
commit
0581756453
@ -654,6 +654,8 @@ pub const InitOptions = struct {
|
||||
emit_analysis: ?EmitLoc = null,
|
||||
/// `null` means to not emit docs.
|
||||
emit_docs: ?EmitLoc = null,
|
||||
/// `null` means to not emit an import lib.
|
||||
emit_implib: ?EmitLoc = null,
|
||||
link_mode: ?std.builtin.LinkMode = null,
|
||||
dll_export_fns: ?bool = false,
|
||||
/// Normally when using LLD to link, Zig uses a file named "lld.id" in the
|
||||
@ -667,7 +669,6 @@ pub const InitOptions = struct {
|
||||
optimize_mode: std.builtin.Mode = .Debug,
|
||||
keep_source_files_loaded: bool = false,
|
||||
clang_argv: []const []const u8 = &[0][]const u8{},
|
||||
lld_argv: []const []const u8 = &[0][]const u8{},
|
||||
lib_dirs: []const []const u8 = &[0][]const u8{},
|
||||
rpath_list: []const []const u8 = &[0][]const u8{},
|
||||
c_source_files: []const CSourceFile = &[0]CSourceFile{},
|
||||
@ -735,6 +736,7 @@ pub const InitOptions = struct {
|
||||
linker_tsaware: bool = false,
|
||||
linker_nxcompat: bool = false,
|
||||
linker_dynamicbase: bool = false,
|
||||
linker_optimization: ?u8 = null,
|
||||
major_subsystem_version: ?u32 = null,
|
||||
minor_subsystem_version: ?u32 = null,
|
||||
clang_passthrough_mode: bool = false,
|
||||
@ -944,9 +946,9 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {
|
||||
link_eh_frame_hdr or
|
||||
options.link_emit_relocs or
|
||||
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.emit_implib != null)
|
||||
{
|
||||
break :blk true;
|
||||
}
|
||||
@ -1139,6 +1141,10 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {
|
||||
const strip = options.strip or !target_util.hasDebugInfo(options.target);
|
||||
const red_zone = options.want_red_zone orelse target_util.hasRedZone(options.target);
|
||||
const omit_frame_pointer = options.omit_frame_pointer orelse (options.optimize_mode != .Debug);
|
||||
const linker_optimization: u8 = options.linker_optimization orelse switch (options.optimize_mode) {
|
||||
.Debug => @as(u8, 0),
|
||||
else => @as(u8, 3),
|
||||
};
|
||||
|
||||
// We put everything into the cache hash that *cannot be modified during an incremental update*.
|
||||
// For example, one cannot change the target between updates, but one can change source files,
|
||||
@ -1182,6 +1188,7 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {
|
||||
cache.hash.add(options.output_mode);
|
||||
cache.hash.add(options.machine_code_model);
|
||||
cache.hash.addOptionalEmitLoc(options.emit_bin);
|
||||
cache.hash.addOptionalEmitLoc(options.emit_implib);
|
||||
cache.hash.addBytes(options.root_name);
|
||||
if (options.target.os.tag == .wasi) cache.hash.add(wasi_exec_model);
|
||||
// TODO audit this and make sure everything is in it
|
||||
@ -1338,18 +1345,21 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {
|
||||
|
||||
const bin_file_emit: ?link.Emit = blk: {
|
||||
const emit_bin = options.emit_bin orelse break :blk null;
|
||||
|
||||
if (emit_bin.directory) |directory| {
|
||||
break :blk link.Emit{
|
||||
.directory = directory,
|
||||
.sub_path = emit_bin.basename,
|
||||
};
|
||||
}
|
||||
|
||||
if (module) |zm| {
|
||||
break :blk link.Emit{
|
||||
.directory = zm.zig_cache_artifact_directory,
|
||||
.sub_path = emit_bin.basename,
|
||||
};
|
||||
}
|
||||
|
||||
// We could use the cache hash as is no problem, however, we increase
|
||||
// the likelihood of cache hits by adding the first C source file
|
||||
// path name (not contents) to the hash. This way if the user is compiling
|
||||
@ -1376,6 +1386,24 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {
|
||||
};
|
||||
};
|
||||
|
||||
const implib_emit: ?link.Emit = blk: {
|
||||
const emit_implib = options.emit_implib orelse break :blk null;
|
||||
|
||||
if (emit_implib.directory) |directory| {
|
||||
break :blk link.Emit{
|
||||
.directory = directory,
|
||||
.sub_path = emit_implib.basename,
|
||||
};
|
||||
}
|
||||
|
||||
// Use the same directory as the bin. The CLI already emits an
|
||||
// error if -fno-emit-bin is combined with -femit-implib.
|
||||
break :blk link.Emit{
|
||||
.directory = bin_file_emit.?.directory,
|
||||
.sub_path = emit_implib.basename,
|
||||
};
|
||||
};
|
||||
|
||||
var system_libs: std.StringArrayHashMapUnmanaged(SystemLib) = .{};
|
||||
errdefer system_libs.deinit(gpa);
|
||||
try system_libs.ensureTotalCapacity(gpa, options.system_lib_names.len);
|
||||
@ -1385,6 +1413,7 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {
|
||||
|
||||
const bin_file = try link.File.openPath(gpa, .{
|
||||
.emit = bin_file_emit,
|
||||
.implib_emit = implib_emit,
|
||||
.root_name = root_name,
|
||||
.module = module,
|
||||
.target = options.target,
|
||||
@ -1426,6 +1455,7 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {
|
||||
.tsaware = options.linker_tsaware,
|
||||
.nxcompat = options.linker_nxcompat,
|
||||
.dynamicbase = options.linker_dynamicbase,
|
||||
.linker_optimization = linker_optimization,
|
||||
.major_subsystem_version = options.major_subsystem_version,
|
||||
.minor_subsystem_version = options.minor_subsystem_version,
|
||||
.stack_size_override = options.stack_size_override,
|
||||
@ -1437,7 +1467,6 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {
|
||||
.eh_frame_hdr = link_eh_frame_hdr,
|
||||
.emit_relocs = options.link_emit_relocs,
|
||||
.rdynamic = options.rdynamic,
|
||||
.extra_lld_args = options.lld_argv,
|
||||
.soname = options.soname,
|
||||
.version = options.version,
|
||||
.compatibility_version = options.compatibility_version,
|
||||
|
||||
@ -47,6 +47,8 @@ pub const Options = struct {
|
||||
/// This is `null` when -fno-emit-bin is used. When `openPath` or `flush` is called,
|
||||
/// it will have already been null-checked.
|
||||
emit: ?Emit,
|
||||
/// This is `null` not building a Windows DLL, or when -fno-emit-implib is used.
|
||||
implib_emit: ?Emit,
|
||||
target: std.Target,
|
||||
output_mode: std.builtin.OutputMode,
|
||||
link_mode: std.builtin.LinkMode,
|
||||
@ -97,6 +99,7 @@ pub const Options = struct {
|
||||
tsaware: bool,
|
||||
nxcompat: bool,
|
||||
dynamicbase: bool,
|
||||
linker_optimization: u8,
|
||||
bind_global_refs_locally: bool,
|
||||
import_memory: bool,
|
||||
initial_memory: ?u64,
|
||||
@ -131,8 +134,6 @@ pub const Options = struct {
|
||||
version_script: ?[]const u8,
|
||||
soname: ?[]const u8,
|
||||
llvm_cpu_features: ?[*:0]const u8,
|
||||
/// Extra args passed directly to LLD. Ignored when not linking with LLD.
|
||||
extra_lld_args: []const []const u8,
|
||||
|
||||
objects: []const []const u8,
|
||||
framework_dirs: []const []const u8,
|
||||
|
||||
@ -927,7 +927,6 @@ fn linkWithLLD(self: *Coff, comp: *Compilation) !void {
|
||||
try man.addOptionalFile(module_obj_path);
|
||||
man.hash.addOptional(self.base.options.stack_size_override);
|
||||
man.hash.addOptional(self.base.options.image_base_override);
|
||||
man.hash.addListOfBytes(self.base.options.extra_lld_args);
|
||||
man.hash.addListOfBytes(self.base.options.lib_dirs);
|
||||
man.hash.add(self.base.options.skip_linker_dependencies);
|
||||
if (self.base.options.link_libc) {
|
||||
@ -978,7 +977,6 @@ fn linkWithLLD(self: *Coff, comp: *Compilation) !void {
|
||||
}
|
||||
|
||||
const full_out_path = try directory.join(arena, &[_][]const u8{self.base.options.emit.?.sub_path});
|
||||
|
||||
if (self.base.options.output_mode == .Obj) {
|
||||
// LLD's COFF driver does not support the equivalent of `-r` so we do a simple file copy
|
||||
// here. TODO: think carefully about how we can avoid this redundant operation when doing
|
||||
@ -1056,6 +1054,7 @@ fn linkWithLLD(self: *Coff, comp: *Compilation) !void {
|
||||
if (self.base.options.dynamicbase) {
|
||||
try argv.append("-dynamicbase");
|
||||
}
|
||||
|
||||
const subsystem_suffix = ss: {
|
||||
if (self.base.options.major_subsystem_version) |major| {
|
||||
if (self.base.options.minor_subsystem_version) |minor| {
|
||||
@ -1069,6 +1068,11 @@ fn linkWithLLD(self: *Coff, comp: *Compilation) !void {
|
||||
|
||||
try argv.append(try allocPrint(arena, "-OUT:{s}", .{full_out_path}));
|
||||
|
||||
if (self.base.options.implib_emit) |emit| {
|
||||
const implib_out_path = try emit.directory.join(arena, &[_][]const u8{emit.sub_path});
|
||||
try argv.append(try allocPrint(arena, "-IMPLIB:{s}", .{implib_out_path}));
|
||||
}
|
||||
|
||||
if (self.base.options.link_libc) {
|
||||
if (self.base.options.libc_installation) |libc_installation| {
|
||||
try argv.append(try allocPrint(arena, "-LIBPATH:{s}", .{libc_installation.crt_dir.?}));
|
||||
|
||||
@ -1322,7 +1322,6 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void {
|
||||
man.hash.add(self.base.options.eh_frame_hdr);
|
||||
man.hash.add(self.base.options.emit_relocs);
|
||||
man.hash.add(self.base.options.rdynamic);
|
||||
man.hash.addListOfBytes(self.base.options.extra_lld_args);
|
||||
man.hash.addListOfBytes(self.base.options.lib_dirs);
|
||||
man.hash.addListOfBytes(self.base.options.rpath_list);
|
||||
man.hash.add(self.base.options.each_lib_rpath);
|
||||
@ -1350,6 +1349,7 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void {
|
||||
man.hash.add(self.base.options.bind_global_refs_locally);
|
||||
man.hash.add(self.base.options.tsan);
|
||||
man.hash.addOptionalBytes(self.base.options.sysroot);
|
||||
man.hash.add(self.base.options.linker_optimization);
|
||||
|
||||
// We don't actually care whether it's a cache hit or miss; we just need the digest and the lock.
|
||||
_ = try man.hit();
|
||||
@ -1426,10 +1426,13 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void {
|
||||
if (self.base.options.lto) {
|
||||
switch (self.base.options.optimize_mode) {
|
||||
.Debug => {},
|
||||
.ReleaseSmall => try argv.append("-O2"),
|
||||
.ReleaseFast, .ReleaseSafe => try argv.append("-O3"),
|
||||
.ReleaseSmall => try argv.append("--lto-O2"),
|
||||
.ReleaseFast, .ReleaseSafe => try argv.append("--lto-O3"),
|
||||
}
|
||||
}
|
||||
try argv.append(try std.fmt.allocPrint(arena, "-O{d}", .{
|
||||
self.base.options.linker_optimization,
|
||||
}));
|
||||
|
||||
if (self.base.options.output_mode == .Exe) {
|
||||
try argv.append("-z");
|
||||
@ -1461,8 +1464,6 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void {
|
||||
try argv.append("--export-dynamic");
|
||||
}
|
||||
|
||||
try argv.appendSlice(self.base.options.extra_lld_args);
|
||||
|
||||
if (self.base.options.z_nodelete) {
|
||||
try argv.append("-z");
|
||||
try argv.append("nodelete");
|
||||
|
||||
@ -714,7 +714,6 @@ fn linkWithLLD(self: *Wasm, comp: *Compilation) !void {
|
||||
try man.addOptionalFile(module_obj_path);
|
||||
try man.addOptionalFile(compiler_rt_path);
|
||||
man.hash.addOptional(self.base.options.stack_size_override);
|
||||
man.hash.addListOfBytes(self.base.options.extra_lld_args);
|
||||
man.hash.add(self.base.options.import_memory);
|
||||
man.hash.addOptional(self.base.options.initial_memory);
|
||||
man.hash.addOptional(self.base.options.max_memory);
|
||||
|
||||
126
src/main.zig
126
src/main.zig
@ -317,6 +317,8 @@ const usage_build_generic =
|
||||
\\ -fno-emit-docs (default) Do not produce docs/ dir with html documentation
|
||||
\\ -femit-analysis[=path] Write analysis JSON file with type information
|
||||
\\ -fno-emit-analysis (default) Do not write analysis JSON file with type information
|
||||
\\ -femit-implib[=path] (default) Produce an import .lib when building a Windows DLL
|
||||
\\ -fno-emit-implib Do not produce an import .lib when building a Windows DLL
|
||||
\\ --show-builtin Output the source of @import("builtin") then exit
|
||||
\\ --cache-dir [path] Override the local cache directory
|
||||
\\ --global-cache-dir [path] Override the global cache directory
|
||||
@ -585,6 +587,8 @@ fn buildOutputType(
|
||||
var emit_llvm_bc: Emit = .no;
|
||||
var emit_docs: Emit = .no;
|
||||
var emit_analysis: Emit = .no;
|
||||
var emit_implib: Emit = .yes_default_path;
|
||||
var emit_implib_arg_provided = false;
|
||||
var target_arch_os_abi: []const u8 = "native";
|
||||
var target_mcpu: ?[]const u8 = null;
|
||||
var target_dynamic_linker: ?[]const u8 = null;
|
||||
@ -631,6 +635,7 @@ fn buildOutputType(
|
||||
var linker_tsaware = false;
|
||||
var linker_nxcompat = false;
|
||||
var linker_dynamicbase = false;
|
||||
var linker_optimization: ?u8 = null;
|
||||
var test_evented_io = false;
|
||||
var test_no_exec = false;
|
||||
var stack_size_override: ?u64 = null;
|
||||
@ -671,9 +676,6 @@ fn buildOutputType(
|
||||
var extra_cflags = std.ArrayList([]const u8).init(gpa);
|
||||
defer extra_cflags.deinit();
|
||||
|
||||
var lld_argv = std.ArrayList([]const u8).init(gpa);
|
||||
defer lld_argv.deinit();
|
||||
|
||||
var lib_dirs = std.ArrayList([]const u8).init(gpa);
|
||||
defer lib_dirs.deinit();
|
||||
|
||||
@ -1093,6 +1095,15 @@ fn buildOutputType(
|
||||
emit_analysis = .{ .yes = arg["-femit-analysis=".len..] };
|
||||
} else if (mem.eql(u8, arg, "-fno-emit-analysis")) {
|
||||
emit_analysis = .no;
|
||||
} else if (mem.eql(u8, arg, "-femit-implib")) {
|
||||
emit_implib = .yes_default_path;
|
||||
emit_implib_arg_provided = true;
|
||||
} else if (mem.startsWith(u8, arg, "-femit-implib=")) {
|
||||
emit_implib = .{ .yes = arg["-femit-implib=".len..] };
|
||||
emit_implib_arg_provided = true;
|
||||
} else if (mem.eql(u8, arg, "-fno-emit-implib")) {
|
||||
emit_implib = .no;
|
||||
emit_implib_arg_provided = true;
|
||||
} else if (mem.eql(u8, arg, "-dynamic")) {
|
||||
link_mode = .Dynamic;
|
||||
} else if (mem.eql(u8, arg, "-static")) {
|
||||
@ -1473,8 +1484,18 @@ fn buildOutputType(
|
||||
fatal("expected linker arg after '{s}'", .{arg});
|
||||
}
|
||||
version_script = linker_args.items[i];
|
||||
} else if (mem.eql(u8, arg, "-O")) {
|
||||
i += 1;
|
||||
if (i >= linker_args.items.len) {
|
||||
fatal("expected linker arg after '{s}'", .{arg});
|
||||
}
|
||||
linker_optimization = std.fmt.parseUnsigned(u8, linker_args.items[i], 10) catch |err| {
|
||||
fatal("unable to parse '{s}': {s}", .{ arg, @errorName(err) });
|
||||
};
|
||||
} else if (mem.startsWith(u8, arg, "-O")) {
|
||||
try lld_argv.append(arg);
|
||||
linker_optimization = std.fmt.parseUnsigned(u8, arg["-O".len..], 10) catch |err| {
|
||||
fatal("unable to parse '{s}': {s}", .{ arg, @errorName(err) });
|
||||
};
|
||||
} else if (mem.eql(u8, arg, "--gc-sections")) {
|
||||
linker_gc_sections = true;
|
||||
} else if (mem.eql(u8, arg, "--no-gc-sections")) {
|
||||
@ -1637,6 +1658,15 @@ 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});
|
||||
}
|
||||
emit_implib = .{ .yes = linker_args.items[i] };
|
||||
emit_implib_arg_provided = true;
|
||||
} else {
|
||||
warn("unsupported linker arg: {s}", .{arg});
|
||||
}
|
||||
@ -1984,11 +2014,15 @@ fn buildOutputType(
|
||||
const default_h_basename = try std.fmt.allocPrint(arena, "{s}.h", .{root_name});
|
||||
var emit_h_resolved = emit_h.resolve(default_h_basename) catch |err| {
|
||||
switch (emit_h) {
|
||||
.yes => {
|
||||
fatal("unable to open directory from argument '-femit-h', '{s}': {s}", .{ emit_h.yes, @errorName(err) });
|
||||
.yes => |p| {
|
||||
fatal("unable to open directory from argument '-femit-h', '{s}': {s}", .{
|
||||
p, @errorName(err),
|
||||
});
|
||||
},
|
||||
.yes_default_path => {
|
||||
fatal("unable to open directory from arguments '--name' or '-fsoname', '{s}': {s}", .{ default_h_basename, @errorName(err) });
|
||||
fatal("unable to open directory from arguments '--name' or '-fsoname', '{s}': {s}", .{
|
||||
default_h_basename, @errorName(err),
|
||||
});
|
||||
},
|
||||
.no => unreachable,
|
||||
}
|
||||
@ -1998,11 +2032,15 @@ fn buildOutputType(
|
||||
const default_asm_basename = try std.fmt.allocPrint(arena, "{s}.s", .{root_name});
|
||||
var emit_asm_resolved = emit_asm.resolve(default_asm_basename) catch |err| {
|
||||
switch (emit_asm) {
|
||||
.yes => {
|
||||
fatal("unable to open directory from argument '-femit-asm', '{s}': {s}", .{ emit_asm.yes, @errorName(err) });
|
||||
.yes => |p| {
|
||||
fatal("unable to open directory from argument '-femit-asm', '{s}': {s}", .{
|
||||
p, @errorName(err),
|
||||
});
|
||||
},
|
||||
.yes_default_path => {
|
||||
fatal("unable to open directory from arguments '--name' or '-fsoname', '{s}': {s}", .{ default_asm_basename, @errorName(err) });
|
||||
fatal("unable to open directory from arguments '--name' or '-fsoname', '{s}': {s}", .{
|
||||
default_asm_basename, @errorName(err),
|
||||
});
|
||||
},
|
||||
.no => unreachable,
|
||||
}
|
||||
@ -2012,11 +2050,15 @@ fn buildOutputType(
|
||||
const default_llvm_ir_basename = try std.fmt.allocPrint(arena, "{s}.ll", .{root_name});
|
||||
var emit_llvm_ir_resolved = emit_llvm_ir.resolve(default_llvm_ir_basename) catch |err| {
|
||||
switch (emit_llvm_ir) {
|
||||
.yes => {
|
||||
fatal("unable to open directory from argument '-femit-llvm-ir', '{s}': {s}", .{ emit_llvm_ir.yes, @errorName(err) });
|
||||
.yes => |p| {
|
||||
fatal("unable to open directory from argument '-femit-llvm-ir', '{s}': {s}", .{
|
||||
p, @errorName(err),
|
||||
});
|
||||
},
|
||||
.yes_default_path => {
|
||||
fatal("unable to open directory from arguments '--name' or '-fsoname', '{s}': {s}", .{ default_llvm_ir_basename, @errorName(err) });
|
||||
fatal("unable to open directory from arguments '--name' or '-fsoname', '{s}': {s}", .{
|
||||
default_llvm_ir_basename, @errorName(err),
|
||||
});
|
||||
},
|
||||
.no => unreachable,
|
||||
}
|
||||
@ -2026,11 +2068,15 @@ fn buildOutputType(
|
||||
const default_llvm_bc_basename = try std.fmt.allocPrint(arena, "{s}.bc", .{root_name});
|
||||
var emit_llvm_bc_resolved = emit_llvm_bc.resolve(default_llvm_bc_basename) catch |err| {
|
||||
switch (emit_llvm_bc) {
|
||||
.yes => {
|
||||
fatal("unable to open directory from argument '-femit-llvm-bc', '{s}': {s}", .{ emit_llvm_bc.yes, @errorName(err) });
|
||||
.yes => |p| {
|
||||
fatal("unable to open directory from argument '-femit-llvm-bc', '{s}': {s}", .{
|
||||
p, @errorName(err),
|
||||
});
|
||||
},
|
||||
.yes_default_path => {
|
||||
fatal("unable to open directory from arguments '--name' or '-fsoname', '{s}': {s}", .{ default_llvm_bc_basename, @errorName(err) });
|
||||
fatal("unable to open directory from arguments '--name' or '-fsoname', '{s}': {s}", .{
|
||||
default_llvm_bc_basename, @errorName(err),
|
||||
});
|
||||
},
|
||||
.no => unreachable,
|
||||
}
|
||||
@ -2040,11 +2086,15 @@ fn buildOutputType(
|
||||
const default_analysis_basename = try std.fmt.allocPrint(arena, "{s}-analysis.json", .{root_name});
|
||||
var emit_analysis_resolved = emit_analysis.resolve(default_analysis_basename) catch |err| {
|
||||
switch (emit_analysis) {
|
||||
.yes => {
|
||||
fatal("unable to open directory from argument 'femit-analysis', '{s}': {s}", .{ emit_analysis.yes, @errorName(err) });
|
||||
.yes => |p| {
|
||||
fatal("unable to open directory from argument '-femit-analysis', '{s}': {s}", .{
|
||||
p, @errorName(err),
|
||||
});
|
||||
},
|
||||
.yes_default_path => {
|
||||
fatal("unable to open directory from arguments 'name' or 'soname', '{s}': {s}", .{ default_analysis_basename, @errorName(err) });
|
||||
fatal("unable to open directory from arguments 'name' or 'soname', '{s}': {s}", .{
|
||||
default_analysis_basename, @errorName(err),
|
||||
});
|
||||
},
|
||||
.no => unreachable,
|
||||
}
|
||||
@ -2053,8 +2103,10 @@ fn buildOutputType(
|
||||
|
||||
var emit_docs_resolved = emit_docs.resolve("docs") catch |err| {
|
||||
switch (emit_docs) {
|
||||
.yes => {
|
||||
fatal("unable to open directory from argument 'femit-docs', '{s}': {s}", .{ emit_h.yes, @errorName(err) });
|
||||
.yes => |p| {
|
||||
fatal("unable to open directory from argument '-femit-docs', '{s}': {s}", .{
|
||||
p, @errorName(err),
|
||||
});
|
||||
},
|
||||
.yes_default_path => {
|
||||
fatal("unable to open directory 'docs': {s}", .{@errorName(err)});
|
||||
@ -2064,6 +2116,35 @@ fn buildOutputType(
|
||||
};
|
||||
defer emit_docs_resolved.deinit();
|
||||
|
||||
const is_dyn_lib = switch (output_mode) {
|
||||
.Obj, .Exe => false,
|
||||
.Lib => (link_mode orelse .Static) == .Dynamic,
|
||||
};
|
||||
const implib_eligible = is_dyn_lib and
|
||||
emit_bin_loc != null and target_info.target.os.tag == .windows;
|
||||
if (!implib_eligible) {
|
||||
if (!emit_implib_arg_provided) {
|
||||
emit_implib = .no;
|
||||
} else if (emit_implib != .no) {
|
||||
fatal("the argument -femit-implib is allowed only when building a Windows DLL", .{});
|
||||
}
|
||||
}
|
||||
const default_implib_basename = try std.fmt.allocPrint(arena, "{s}.lib", .{root_name});
|
||||
var emit_implib_resolved = emit_implib.resolve(default_implib_basename) catch |err| {
|
||||
switch (emit_implib) {
|
||||
.yes => |p| {
|
||||
fatal("unable to open directory from argument '-femit-implib', '{s}': {s}", .{
|
||||
p, @errorName(err),
|
||||
});
|
||||
},
|
||||
.yes_default_path => {
|
||||
fatal("unable to open directory 'docs': {s}", .{@errorName(err)});
|
||||
},
|
||||
.no => unreachable,
|
||||
}
|
||||
};
|
||||
defer emit_implib_resolved.deinit();
|
||||
|
||||
const main_pkg: ?*Package = if (root_src_file) |src_path| blk: {
|
||||
if (main_pkg_path) |p| {
|
||||
const rel_src_path = try fs.path.relative(gpa, p, src_path);
|
||||
@ -2175,13 +2256,13 @@ fn buildOutputType(
|
||||
.emit_llvm_bc = emit_llvm_bc_resolved.data,
|
||||
.emit_docs = emit_docs_resolved.data,
|
||||
.emit_analysis = emit_analysis_resolved.data,
|
||||
.emit_implib = emit_implib_resolved.data,
|
||||
.link_mode = link_mode,
|
||||
.dll_export_fns = dll_export_fns,
|
||||
.object_format = object_format,
|
||||
.optimize_mode = optimize_mode,
|
||||
.keep_source_files_loaded = false,
|
||||
.clang_argv = clang_argv.items,
|
||||
.lld_argv = lld_argv.items,
|
||||
.lib_dirs = lib_dirs.items,
|
||||
.rpath_list = rpath_list.items,
|
||||
.c_source_files = c_source_files.items,
|
||||
@ -2231,6 +2312,7 @@ fn buildOutputType(
|
||||
.linker_tsaware = linker_tsaware,
|
||||
.linker_nxcompat = linker_nxcompat,
|
||||
.linker_dynamicbase = linker_dynamicbase,
|
||||
.linker_optimization = linker_optimization,
|
||||
.major_subsystem_version = major_subsystem_version,
|
||||
.minor_subsystem_version = minor_subsystem_version,
|
||||
.link_eh_frame_hdr = link_eh_frame_hdr,
|
||||
|
||||
@ -35,7 +35,7 @@ pub fn build(b: *Builder) void {
|
||||
":1001140000000000000000000000000000000000DB",
|
||||
":1001240000000000000000000000000000000000CB",
|
||||
":1001340000000000000000000000000000000000BB",
|
||||
":10014400830202006C020100090000002102010088",
|
||||
":1001440083020200F401010009000000FE01010025",
|
||||
":100154000900000001000000000000000000000091",
|
||||
":1001640000080002008001010004000010000000EB",
|
||||
":100174000000000000000000000000001F0000005C",
|
||||
@ -44,17 +44,17 @@ pub fn build(b: *Builder) void {
|
||||
":1001A40000000000000000001F000000000000002C",
|
||||
":1001B400000000000000000000000000000000003B",
|
||||
":1001C400000000000000000000000000000000002B",
|
||||
":1001D4005B02010010000000F40101002C0000008B",
|
||||
":1001E4003F0201001B0000002B020100130000006D",
|
||||
":1001F40072656D61696E646572206469766973699C",
|
||||
":100204006F6E206279207A65726F206F72206E653E",
|
||||
":100214006761746976652076616C756500636F72D9",
|
||||
":100224007465782D6D3400696E646578206F75741B",
|
||||
":10023400206F6620626F756E647300696E74656703",
|
||||
":1002440065722063617374207472756E6361746582",
|
||||
":10025400642062697473006469766973696F6E20DF",
|
||||
":100264006279207A65726F00636F727465785F6D6E",
|
||||
":100274003400000081B00091FFE700BEFDE7D0B577",
|
||||
":1001D4000802010010000000190201002C000000B8",
|
||||
":1001E400460201001B00000062020100130000002F",
|
||||
":1001F400636F727465785F6D3400636F72746578D1",
|
||||
":100204002D6D34006469766973696F6E206279209C",
|
||||
":100214007A65726F0072656D61696E6465722064DF",
|
||||
":1002240069766973696F6E206279207A65726F20CE",
|
||||
":100234006F72206E656761746976652076616C758E",
|
||||
":100244006500696E746567657220636173742074F8",
|
||||
":1002540072756E6361746564206269747300696E9B",
|
||||
":10026400646578206F7574206F6620626F756E64A4",
|
||||
":100274007300000081B00091FFE700BEFDE7D0B538",
|
||||
":1002840002AF90B00391029007A800F029F80399F7",
|
||||
":100294000020069048680490FFE7049906980190AE",
|
||||
":1002A40088420FD2FFE7019903980068405C07F881",
|
||||
@ -89,7 +89,7 @@ pub fn build(b: *Builder) void {
|
||||
":1001140000000000000000000000000000000000DB",
|
||||
":1001240000000000000000000000000000000000CB",
|
||||
":1001340000000000000000000000000000000000BB",
|
||||
":10014400830202006C020100090000002102010088",
|
||||
":1001440083020200F401010009000000FE01010025",
|
||||
":100154000900000001000000000000000000000091",
|
||||
":1001640000080002008001010004000010000000EB",
|
||||
":100174000000000000000000000000001F0000005C",
|
||||
@ -98,17 +98,17 @@ pub fn build(b: *Builder) void {
|
||||
":1001A40000000000000000001F000000000000002C",
|
||||
":1001B400000000000000000000000000000000003B",
|
||||
":1001C400000000000000000000000000000000002B",
|
||||
":1001D4005B02010010000000F40101002C0000008B",
|
||||
":1001E4003F0201001B0000002B020100130000006D",
|
||||
":1001F40072656D61696E646572206469766973699C",
|
||||
":100204006F6E206279207A65726F206F72206E653E",
|
||||
":100214006761746976652076616C756500636F72D9",
|
||||
":100224007465782D6D3400696E646578206F75741B",
|
||||
":10023400206F6620626F756E647300696E74656703",
|
||||
":1002440065722063617374207472756E6361746582",
|
||||
":10025400642062697473006469766973696F6E20DF",
|
||||
":100264006279207A65726F00636F727465785F6D6E",
|
||||
":100274003400000081B00091FFE700BEFDE7D0B577",
|
||||
":1001D4000802010010000000190201002C000000B8",
|
||||
":1001E400460201001B00000062020100130000002F",
|
||||
":1001F400636F727465785F6D3400636F72746578D1",
|
||||
":100204002D6D34006469766973696F6E206279209C",
|
||||
":100214007A65726F0072656D61696E6465722064DF",
|
||||
":1002240069766973696F6E206279207A65726F20CE",
|
||||
":100234006F72206E656761746976652076616C758E",
|
||||
":100244006500696E746567657220636173742074F8",
|
||||
":1002540072756E6361746564206269747300696E9B",
|
||||
":10026400646578206F7574206F6620626F756E64A4",
|
||||
":100274007300000081B00091FFE700BEFDE7D0B538",
|
||||
":1002840002AF90B00391029007A800F029F80399F7",
|
||||
":100294000020069048680490FFE7049906980190AE",
|
||||
":1002A40088420FD2FFE7019903980068405C07F881",
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user