From b975f7a56fec9e0e7aca9832282bc772c743d731 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Thu, 18 Aug 2022 18:58:28 -0700 Subject: [PATCH] std.Target gains ObjectFormat field --- lib/std/target.zig | 33 ++++++++-------- lib/std/zig.zig | 12 +++--- lib/std/zig/CrossTarget.zig | 13 ++++++- lib/std/zig/system/NativeTargetInfo.zig | 5 +++ src/Compilation.zig | 30 +++++++-------- src/Sema.zig | 2 +- src/codegen/llvm.zig | 2 +- src/link.zig | 11 +++--- src/link/C.zig | 2 +- src/link/Coff.zig | 2 +- src/link/Elf.zig | 2 +- src/link/MachO.zig | 4 +- src/link/NvPtx.zig | 2 +- src/link/Plan9.zig | 2 +- src/link/SpirV.zig | 2 +- src/link/Wasm.zig | 2 +- src/main.zig | 51 +++++++++++-------------- src/stage1/codegen.cpp | 1 + 18 files changed, 93 insertions(+), 85 deletions(-) diff --git a/lib/std/target.zig b/lib/std/target.zig index 155c59bdfc..00553bb520 100644 --- a/lib/std/target.zig +++ b/lib/std/target.zig @@ -9,6 +9,7 @@ pub const Target = struct { cpu: Cpu, os: Os, abi: Abi, + ofmt: ObjectFormat, pub const Os = struct { tag: Tag, @@ -594,6 +595,20 @@ pub const Target = struct { .nvptx => ".ptx", }; } + + pub fn default(os_tag: Os.Tag, cpu_arch: Cpu.Arch) ObjectFormat { + return switch (os_tag) { + .windows, .uefi => .coff, + .ios, .macos, .watchos, .tvos => .macho, + .plan9 => .plan9, + else => return switch (cpu_arch) { + .wasm32, .wasm64 => .wasm, + .spirv32, .spirv64 => .spirv, + .nvptx, .nvptx64 => .nvptx, + else => .elf, + }, + }; + } }; pub const SubSystem = enum { @@ -1381,24 +1396,6 @@ pub const Target = struct { return libPrefix_os_abi(self.os.tag, self.abi); } - pub fn getObjectFormatSimple(os_tag: Os.Tag, cpu_arch: Cpu.Arch) ObjectFormat { - return switch (os_tag) { - .windows, .uefi => .coff, - .ios, .macos, .watchos, .tvos => .macho, - .plan9 => .plan9, - else => return switch (cpu_arch) { - .wasm32, .wasm64 => .wasm, - .spirv32, .spirv64 => .spirv, - .nvptx, .nvptx64 => .nvptx, - else => .elf, - }, - }; - } - - pub fn getObjectFormat(self: Target) ObjectFormat { - return getObjectFormatSimple(self.os.tag, self.cpu.arch); - } - pub fn isMinGW(self: Target) bool { return self.os.tag == .windows and self.isGnu(); } diff --git a/lib/std/zig.zig b/lib/std/zig.zig index b8f75f649e..85835ebf18 100644 --- a/lib/std/zig.zig +++ b/lib/std/zig.zig @@ -103,7 +103,6 @@ pub const BinNameOptions = struct { target: std.Target, output_mode: std.builtin.OutputMode, link_mode: ?std.builtin.LinkMode = null, - object_format: ?std.Target.ObjectFormat = null, version: ?std.builtin.Version = null, }; @@ -111,8 +110,7 @@ pub const BinNameOptions = struct { pub fn binNameAlloc(allocator: std.mem.Allocator, options: BinNameOptions) error{OutOfMemory}![]u8 { const root_name = options.root_name; const target = options.target; - const ofmt = options.object_format orelse target.getObjectFormat(); - switch (ofmt) { + switch (target.ofmt) { .coff => switch (options.output_mode) { .Exe => return std.fmt.allocPrint(allocator, "{s}{s}", .{ root_name, target.exeFileExt() }), .Lib => { @@ -186,8 +184,12 @@ pub fn binNameAlloc(allocator: std.mem.Allocator, options: BinNameOptions) error .raw => return std.fmt.allocPrint(allocator, "{s}.bin", .{root_name}), .plan9 => switch (options.output_mode) { .Exe => return allocator.dupe(u8, root_name), - .Obj => return std.fmt.allocPrint(allocator, "{s}{s}", .{ root_name, ofmt.fileExt(target.cpu.arch) }), - .Lib => return std.fmt.allocPrint(allocator, "{s}{s}.a", .{ target.libPrefix(), root_name }), + .Obj => return std.fmt.allocPrint(allocator, "{s}{s}", .{ + root_name, target.ofmt.fileExt(target.cpu.arch), + }), + .Lib => return std.fmt.allocPrint(allocator, "{s}{s}.a", .{ + target.libPrefix(), root_name, + }), }, .nvptx => return std.fmt.allocPrint(allocator, "{s}", .{root_name}), } diff --git a/lib/std/zig/CrossTarget.zig b/lib/std/zig/CrossTarget.zig index 196afbc835..a4e9b2576d 100644 --- a/lib/std/zig/CrossTarget.zig +++ b/lib/std/zig/CrossTarget.zig @@ -42,6 +42,9 @@ abi: ?Target.Abi = null, /// based on the `os_tag`. dynamic_linker: DynamicLinker = DynamicLinker{}, +/// `null` means default for the cpu/arch/os combo. +ofmt: ?Target.ObjectFormat = null, + pub const CpuModel = union(enum) { /// Always native native, @@ -168,6 +171,7 @@ pub fn toTarget(self: CrossTarget) Target { .cpu = self.getCpu(), .os = self.getOs(), .abi = self.getAbi(), + .ofmt = self.getObjectFormat(), }; } @@ -197,6 +201,8 @@ pub const ParseOptions = struct { /// detected path, or a standard path. dynamic_linker: ?[]const u8 = null, + object_format: ?[]const u8 = null, + /// If this is provided, the function will populate some information about parsing failures, /// so that user-friendly error messages can be delivered. diagnostics: ?*Diagnostics = null, @@ -321,6 +327,11 @@ pub fn parse(args: ParseOptions) !CrossTarget { } } + if (args.object_format) |ofmt_name| { + result.ofmt = std.meta.stringToEnum(Target.ObjectFormat, ofmt_name) orelse + return error.UnknownObjectFormat; + } + return result; } @@ -620,7 +631,7 @@ pub fn setGnuLibCVersion(self: *CrossTarget, major: u32, minor: u32, patch: u32) } pub fn getObjectFormat(self: CrossTarget) Target.ObjectFormat { - return Target.getObjectFormatSimple(self.getOsTag(), self.getCpuArch()); + return self.ofmt orelse Target.ObjectFormat.default(self.getOsTag(), self.getCpuArch()); } pub fn updateCpuFeatures(self: CrossTarget, set: *Target.Cpu.Feature.Set) void { diff --git a/lib/std/zig/system/NativeTargetInfo.zig b/lib/std/zig/system/NativeTargetInfo.zig index 6dcedd93b8..4f8c0025c5 100644 --- a/lib/std/zig/system/NativeTargetInfo.zig +++ b/lib/std/zig/system/NativeTargetInfo.zig @@ -276,6 +276,7 @@ fn detectAbiAndDynamicLinker( }; var ld_info_list_buffer: [all_abis.len]LdInfo = undefined; var ld_info_list_len: usize = 0; + const ofmt = cross_target.ofmt orelse Target.ObjectFormat.default(os.tag, cpu.arch); for (all_abis) |abi| { // This may be a nonsensical parameter. We detect this with error.UnknownDynamicLinkerPath and @@ -284,6 +285,7 @@ fn detectAbiAndDynamicLinker( .cpu = cpu, .os = os, .abi = abi, + .ofmt = ofmt, }; const ld = target.standardDynamicLinkerPath(); if (ld.get() == null) continue; @@ -346,6 +348,7 @@ fn detectAbiAndDynamicLinker( .cpu = cpu, .os = os_adjusted, .abi = cross_target.abi orelse found_ld_info.abi, + .ofmt = cross_target.ofmt orelse Target.ObjectFormat.default(os_adjusted.tag, cpu.arch), }, .dynamic_linker = if (cross_target.dynamic_linker.get() == null) DynamicLinker.init(found_ld_path) @@ -539,6 +542,7 @@ pub fn abiAndDynamicLinkerFromFile( .cpu = cpu, .os = os, .abi = cross_target.abi orelse Target.Abi.default(cpu.arch, os), + .ofmt = cross_target.ofmt orelse Target.ObjectFormat.default(os.tag, cpu.arch), }, .dynamic_linker = cross_target.dynamic_linker, }; @@ -829,6 +833,7 @@ fn defaultAbiAndDynamicLinker(cpu: Target.Cpu, os: Target.Os, cross_target: Cros .cpu = cpu, .os = os, .abi = cross_target.abi orelse Target.Abi.default(cpu.arch, os), + .ofmt = cross_target.ofmt orelse Target.ObjectFormat.default(os.tag, cpu.arch), }; return NativeTargetInfo{ .target = target, diff --git a/src/Compilation.zig b/src/Compilation.zig index af39154a3f..5e0d815c96 100644 --- a/src/Compilation.zig +++ b/src/Compilation.zig @@ -810,7 +810,6 @@ pub const InitOptions = struct { /// this flag would be set to disable this machinery to avoid false positives. disable_lld_caching: bool = false, cache_mode: CacheMode = .incremental, - object_format: ?std.Target.ObjectFormat = null, optimize_mode: std.builtin.Mode = .Debug, keep_source_files_loaded: bool = false, clang_argv: []const []const u8 = &[0][]const u8{}, @@ -1027,8 +1026,6 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation { const comp = try arena.create(Compilation); const root_name = try arena.dupeZ(u8, options.root_name); - const ofmt = options.object_format orelse options.target.getObjectFormat(); - const use_stage1 = options.use_stage1 orelse blk: { // Even though we may have no Zig code to compile (depending on `options.main_pkg`), // we may need to use stage1 for building compiler-rt and other dependencies. @@ -1042,7 +1039,7 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation { } // If LLVM does not support the target, then we can't use it. - if (!target_util.hasLlvmSupport(options.target, ofmt)) + if (!target_util.hasLlvmSupport(options.target, options.target.ofmt)) break :blk false; break :blk build_options.is_stage1; @@ -1072,7 +1069,7 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation { break :blk true; // If LLVM does not support the target, then we can't use it. - if (!target_util.hasLlvmSupport(options.target, ofmt)) + if (!target_util.hasLlvmSupport(options.target, options.target.ofmt)) break :blk false; // Prefer LLVM for release builds. @@ -1115,7 +1112,7 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation { if (!build_options.have_llvm) break :blk false; - if (ofmt == .c) + if (options.target.ofmt == .c) break :blk false; if (options.want_lto) |lto| { @@ -1374,7 +1371,7 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation { cache.hash.add(options.target.os.getVersionRange()); cache.hash.add(options.is_native_os); cache.hash.add(options.target.abi); - cache.hash.add(ofmt); + cache.hash.add(options.target.ofmt); cache.hash.add(pic); cache.hash.add(pie); cache.hash.add(lto); @@ -1682,7 +1679,6 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation { .sysroot = sysroot, .output_mode = options.output_mode, .link_mode = link_mode, - .object_format = ofmt, .optimize_mode = options.optimize_mode, .use_lld = use_lld, .use_llvm = use_llvm, @@ -1841,7 +1837,9 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation { const have_bin_emit = comp.bin_file.options.emit != null or comp.whole_bin_sub_path != null; - if (have_bin_emit and !comp.bin_file.options.skip_linker_dependencies) { + if (have_bin_emit and !comp.bin_file.options.skip_linker_dependencies and + options.target.ofmt != .c) + { if (comp.getTarget().isDarwin()) { switch (comp.getTarget().abi) { .none, @@ -3739,7 +3737,8 @@ fn updateCObject(comp: *Compilation, c_object: *CObject, c_obj_prog_node: *std.P else c_source_basename[0 .. c_source_basename.len - std.fs.path.extension(c_source_basename).len]; - const o_ext = comp.bin_file.options.object_format.fileExt(comp.bin_file.options.target.cpu.arch); + const target = comp.getTarget(); + const o_ext = target.ofmt.fileExt(target.cpu.arch); const digest = if (!comp.disable_c_depfile and try man.hit()) man.final() else blk: { var argv = std.ArrayList([]const u8).init(comp.gpa); defer argv.deinit(); @@ -4092,7 +4091,7 @@ pub fn addCCArgs( if (!comp.bin_file.options.strip) { try argv.append("-g"); - switch (comp.bin_file.options.object_format) { + switch (target.ofmt) { .coff => try argv.append("-gcodeview"), else => {}, } @@ -4660,7 +4659,7 @@ fn wantBuildLibCFromSource(comp: Compilation) bool { }; return comp.bin_file.options.link_libc and is_exe_or_dyn_lib and comp.bin_file.options.libc_installation == null and - comp.bin_file.options.object_format != .c; + comp.bin_file.options.target.ofmt != .c; } fn wantBuildGLibCFromSource(comp: Compilation) bool { @@ -4688,7 +4687,7 @@ fn wantBuildLibUnwindFromSource(comp: *Compilation) bool { .Exe => true, }; return is_exe_or_dyn_lib and comp.bin_file.options.link_libunwind and - comp.bin_file.options.object_format != .c; + comp.bin_file.options.target.ofmt != .c; } fn setAllocFailure(comp: *Compilation) void { @@ -4747,7 +4746,7 @@ pub fn generateBuiltinZigSource(comp: *Compilation, allocator: Allocator) Alloca const zig_backend: std.builtin.CompilerBackend = blk: { if (use_stage1) break :blk .stage1; if (build_options.have_llvm and comp.bin_file.options.use_llvm) break :blk .stage2_llvm; - if (comp.bin_file.options.object_format == .c) break :blk .stage2_c; + if (target.ofmt == .c) break :blk .stage2_c; break :blk switch (target.cpu.arch) { .wasm32, .wasm64 => std.builtin.CompilerBackend.stage2_wasm, .arm, .armeb, .thumb, .thumbeb => .stage2_arm, @@ -4895,6 +4894,7 @@ pub fn generateBuiltinZigSource(comp: *Compilation, allocator: Allocator) Alloca \\ .cpu = cpu, \\ .os = os, \\ .abi = abi, + \\ .ofmt = object_format, \\}}; \\pub const object_format = std.Target.ObjectFormat.{}; \\pub const mode = std.builtin.Mode.{}; @@ -4909,7 +4909,7 @@ pub fn generateBuiltinZigSource(comp: *Compilation, allocator: Allocator) Alloca \\pub const code_model = std.builtin.CodeModel.{}; \\ , .{ - std.zig.fmtId(@tagName(comp.bin_file.options.object_format)), + std.zig.fmtId(@tagName(target.ofmt)), std.zig.fmtId(@tagName(comp.bin_file.options.optimize_mode)), link_libc, comp.bin_file.options.link_libcpp, diff --git a/src/Sema.zig b/src/Sema.zig index 32b95a4c21..d059ee09a3 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -20654,7 +20654,7 @@ fn panicWithMsg( const arena = sema.arena; const this_feature_is_implemented_in_the_backend = - mod.comp.bin_file.options.object_format == .c or + mod.comp.bin_file.options.target.ofmt == .c or mod.comp.bin_file.options.use_llvm; if (!this_feature_is_implemented_in_the_backend) { // TODO implement this feature in all the backends and then delete this branch diff --git a/src/codegen/llvm.zig b/src/codegen/llvm.zig index 983813d780..8c84f61a81 100644 --- a/src/codegen/llvm.zig +++ b/src/codegen/llvm.zig @@ -273,7 +273,7 @@ pub const Object = struct { var di_compile_unit: ?*llvm.DICompileUnit = null; if (!options.strip) { - switch (options.object_format) { + switch (options.target.ofmt) { .coff => llvm_module.addModuleCodeViewFlag(), else => llvm_module.addModuleDebugInfoFlag(), } diff --git a/src/link.zig b/src/link.zig index a6dafce20e..31b54f705a 100644 --- a/src/link.zig +++ b/src/link.zig @@ -72,7 +72,6 @@ pub const Options = struct { target: std.Target, output_mode: std.builtin.OutputMode, link_mode: std.builtin.LinkMode, - object_format: std.Target.ObjectFormat, optimize_mode: std.builtin.Mode, machine_code_model: std.builtin.CodeModel, root_name: [:0]const u8, @@ -273,13 +272,13 @@ pub const File = struct { /// rewriting it. A malicious file is detected as incremental link failure /// and does not cause Illegal Behavior. This operation is not atomic. pub fn openPath(allocator: Allocator, options: Options) !*File { - if (options.object_format == .macho) { + if (options.target.ofmt == .macho) { return &(try MachO.openPath(allocator, options)).base; } const use_stage1 = build_options.is_stage1 and options.use_stage1; if (use_stage1 or options.emit == null) { - return switch (options.object_format) { + return switch (options.target.ofmt) { .coff => &(try Coff.createEmpty(allocator, options)).base, .elf => &(try Elf.createEmpty(allocator, options)).base, .macho => unreachable, @@ -298,7 +297,7 @@ pub const File = struct { if (options.module == null) { // No point in opening a file, we would not write anything to it. // Initialize with empty. - return switch (options.object_format) { + return switch (options.target.ofmt) { .coff => &(try Coff.createEmpty(allocator, options)).base, .elf => &(try Elf.createEmpty(allocator, options)).base, .macho => unreachable, @@ -314,12 +313,12 @@ pub const File = struct { // Open a temporary object file, not the final output file because we // want to link with LLD. break :blk try std.fmt.allocPrint(allocator, "{s}{s}", .{ - emit.sub_path, options.object_format.fileExt(options.target.cpu.arch), + emit.sub_path, options.target.ofmt.fileExt(options.target.cpu.arch), }); } else emit.sub_path; errdefer if (use_lld) allocator.free(sub_path); - const file: *File = switch (options.object_format) { + const file: *File = switch (options.target.ofmt) { .coff => &(try Coff.openPath(allocator, sub_path, options)).base, .elf => &(try Elf.openPath(allocator, sub_path, options)).base, .macho => unreachable, diff --git a/src/link/C.zig b/src/link/C.zig index 6449be9c56..955044f90d 100644 --- a/src/link/C.zig +++ b/src/link/C.zig @@ -48,7 +48,7 @@ const DeclBlock = struct { }; pub fn openPath(gpa: Allocator, sub_path: []const u8, options: link.Options) !*C { - assert(options.object_format == .c); + assert(options.target.ofmt == .c); if (options.use_llvm) return error.LLVMHasNoCBackend; if (options.use_lld) return error.LLDHasNoCBackend; diff --git a/src/link/Coff.zig b/src/link/Coff.zig index 1b5ddbbf8b..92e9dce3ad 100644 --- a/src/link/Coff.zig +++ b/src/link/Coff.zig @@ -128,7 +128,7 @@ pub const TextBlock = struct { pub const SrcFn = void; pub fn openPath(allocator: Allocator, sub_path: []const u8, options: link.Options) !*Coff { - assert(options.object_format == .coff); + assert(options.target.ofmt == .coff); if (build_options.have_llvm and options.use_llvm) { return createEmpty(allocator, options); diff --git a/src/link/Elf.zig b/src/link/Elf.zig index 917e4c18d1..2f67c35205 100644 --- a/src/link/Elf.zig +++ b/src/link/Elf.zig @@ -249,7 +249,7 @@ pub const Export = struct { }; pub fn openPath(allocator: Allocator, sub_path: []const u8, options: link.Options) !*Elf { - assert(options.object_format == .elf); + assert(options.target.ofmt == .elf); if (build_options.have_llvm and options.use_llvm) { return createEmpty(allocator, options); diff --git a/src/link/MachO.zig b/src/link/MachO.zig index e4370c703e..7a50843023 100644 --- a/src/link/MachO.zig +++ b/src/link/MachO.zig @@ -270,7 +270,7 @@ pub const Export = struct { }; pub fn openPath(allocator: Allocator, options: link.Options) !*MachO { - assert(options.object_format == .macho); + assert(options.target.ofmt == .macho); const use_stage1 = build_options.is_stage1 and options.use_stage1; if (use_stage1 or options.emit == null) { @@ -289,7 +289,7 @@ pub fn openPath(allocator: Allocator, options: link.Options) !*MachO { // we also want to put the intermediary object file in the cache while the // main emit directory is the cwd. self.base.intermediary_basename = try std.fmt.allocPrint(allocator, "{s}{s}", .{ - emit.sub_path, options.object_format.fileExt(options.target.cpu.arch), + emit.sub_path, options.target.ofmt.fileExt(options.target.cpu.arch), }); } diff --git a/src/link/NvPtx.zig b/src/link/NvPtx.zig index bd86d87201..7bf51c7ad3 100644 --- a/src/link/NvPtx.zig +++ b/src/link/NvPtx.zig @@ -57,7 +57,7 @@ pub fn createEmpty(gpa: Allocator, options: link.Options) !*NvPtx { pub fn openPath(allocator: Allocator, sub_path: []const u8, options: link.Options) !*NvPtx { if (!build_options.have_llvm) @panic("nvptx target requires a zig compiler with llvm enabled."); if (!options.use_llvm) return error.PtxArchNotSupported; - assert(options.object_format == .nvptx); + assert(options.target.ofmt == .nvptx); const nvptx = try createEmpty(allocator, options); log.info("Opening .ptx target file {s}", .{sub_path}); diff --git a/src/link/Plan9.zig b/src/link/Plan9.zig index 16f7841c2d..9a8927dcb4 100644 --- a/src/link/Plan9.zig +++ b/src/link/Plan9.zig @@ -657,7 +657,7 @@ pub const base_tag = .plan9; pub fn openPath(allocator: Allocator, sub_path: []const u8, options: link.Options) !*Plan9 { if (options.use_llvm) return error.LLVMBackendDoesNotSupportPlan9; - assert(options.object_format == .plan9); + assert(options.target.ofmt == .plan9); const self = try createEmpty(allocator, options); errdefer self.base.destroy(); diff --git a/src/link/SpirV.zig b/src/link/SpirV.zig index e295dceb55..b2f6edddfb 100644 --- a/src/link/SpirV.zig +++ b/src/link/SpirV.zig @@ -99,7 +99,7 @@ pub fn createEmpty(gpa: Allocator, options: link.Options) !*SpirV { } pub fn openPath(allocator: Allocator, sub_path: []const u8, options: link.Options) !*SpirV { - assert(options.object_format == .spirv); + assert(options.target.ofmt == .spirv); if (options.use_llvm) return error.LLVM_BackendIsTODO_ForSpirV; // TODO: LLVM Doesn't support SpirV at all. if (options.use_lld) return error.LLD_LinkingIsTODO_ForSpirV; // TODO: LLD Doesn't support SpirV at all. diff --git a/src/link/Wasm.zig b/src/link/Wasm.zig index 1bdd9426a5..6267865888 100644 --- a/src/link/Wasm.zig +++ b/src/link/Wasm.zig @@ -282,7 +282,7 @@ pub const StringTable = struct { }; pub fn openPath(allocator: Allocator, sub_path: []const u8, options: link.Options) !*Wasm { - assert(options.object_format == .wasm); + assert(options.target.ofmt == .wasm); if (build_options.have_llvm and options.use_llvm) { return createEmpty(allocator, options); diff --git a/src/main.zig b/src/main.zig index 971fe19e36..dfce4d83b8 100644 --- a/src/main.zig +++ b/src/main.zig @@ -2192,6 +2192,7 @@ fn buildOutputType( .arch_os_abi = target_arch_os_abi, .cpu_features = target_mcpu, .dynamic_linker = target_dynamic_linker, + .object_format = target_ofmt, }; // Before passing the mcpu string in for parsing, we convert any -m flags that were @@ -2494,28 +2495,7 @@ fn buildOutputType( } } - const object_format: std.Target.ObjectFormat = blk: { - const ofmt = target_ofmt orelse break :blk target_info.target.getObjectFormat(); - if (mem.eql(u8, ofmt, "elf")) { - break :blk .elf; - } else if (mem.eql(u8, ofmt, "c")) { - break :blk .c; - } else if (mem.eql(u8, ofmt, "coff")) { - break :blk .coff; - } else if (mem.eql(u8, ofmt, "macho")) { - break :blk .macho; - } else if (mem.eql(u8, ofmt, "wasm")) { - break :blk .wasm; - } else if (mem.eql(u8, ofmt, "hex")) { - break :blk .hex; - } else if (mem.eql(u8, ofmt, "raw")) { - break :blk .raw; - } else if (mem.eql(u8, ofmt, "spirv")) { - break :blk .spirv; - } else { - fatal("unsupported object format: {s}", .{ofmt}); - } - }; + const object_format = target_info.target.ofmt; if (output_mode == .Obj and (object_format == .coff or object_format == .macho)) { const total_obj_count = c_source_files.items.len + @@ -2569,7 +2549,6 @@ fn buildOutputType( .target = target_info.target, .output_mode = output_mode, .link_mode = link_mode, - .object_format = object_format, .version = optional_version, }), }, @@ -2859,7 +2838,6 @@ fn buildOutputType( .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, @@ -3173,11 +3151,11 @@ fn parseCrossTargetOrReportFatalError( for (diags.arch.?.allCpuModels()) |cpu| { help_text.writer().print(" {s}\n", .{cpu.name}) catch break :help; } - std.log.info("Available CPUs for architecture '{s}':\n{s}", .{ + std.log.info("available CPUs for architecture '{s}':\n{s}", .{ @tagName(diags.arch.?), help_text.items, }); } - fatal("Unknown CPU: '{s}'", .{diags.cpu_name.?}); + fatal("unknown CPU: '{s}'", .{diags.cpu_name.?}); }, error.UnknownCpuFeature => { help: { @@ -3186,11 +3164,26 @@ fn parseCrossTargetOrReportFatalError( for (diags.arch.?.allFeaturesList()) |feature| { help_text.writer().print(" {s}: {s}\n", .{ feature.name, feature.description }) catch break :help; } - std.log.info("Available CPU features for architecture '{s}':\n{s}", .{ + std.log.info("available CPU features for architecture '{s}':\n{s}", .{ @tagName(diags.arch.?), help_text.items, }); } - fatal("Unknown CPU feature: '{s}'", .{diags.unknown_feature_name.?}); + fatal("unknown CPU feature: '{s}'", .{diags.unknown_feature_name.?}); + }, + error.UnknownObjectFormat => { + { + var help_text = std.ArrayList(u8).init(allocator); + defer help_text.deinit(); + inline for (@typeInfo(std.Target.ObjectFormat).Enum.fields) |field| { + help_text.writer().print(" {s}\n", .{field.name}) catch + // TODO change this back to `break :help` + // this working around a stage1 bug. + //break :help; + @panic("out of memory"); + } + std.log.info("available object formats:\n{s}", .{help_text.items}); + } + fatal("unknown object format: '{s}'", .{opts.object_format.?}); }, else => |e| return e, }; @@ -3360,7 +3353,7 @@ fn updateModule(gpa: Allocator, comp: *Compilation, hook: AfterUpdateHook) !void // If a .pdb file is part of the expected output, we must also copy // it into place here. - const is_coff = comp.bin_file.options.object_format == .coff; + const is_coff = comp.bin_file.options.target.ofmt == .coff; const have_pdb = is_coff and !comp.bin_file.options.strip; if (have_pdb) { // Replace `.out` or `.exe` with `.pdb` on both the source and destination diff --git a/src/stage1/codegen.cpp b/src/stage1/codegen.cpp index 7010e736dc..d4a09f7968 100644 --- a/src/stage1/codegen.cpp +++ b/src/stage1/codegen.cpp @@ -10082,6 +10082,7 @@ Buf *codegen_generate_builtin_source(CodeGen *g) { " .cpu = cpu,\n" " .os = os,\n" " .abi = abi,\n" + " .ofmt = object_format,\n" "};\n" );