authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-08-18 18:58:28-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-08-18 18:58:28-07:00
logb975f7a56fec9e0e7aca9832282bc772c743d731
treeb19f37881f1fe8918dc9aa156b3210c4b7b343fc
parent517eb73b23ee77672abe6b20b79b6648cd3ff879

std.Target gains ObjectFormat field


18 files changed, 93 insertions(+), 85 deletions(-)

lib/std/target.zig+15-18
...@@ -9,6 +9,7 @@ pub const Target = struct {...@@ -9,6 +9,7 @@ pub const Target = struct {
9 cpu: Cpu,9 cpu: Cpu,
10 os: Os,10 os: Os,
11 abi: Abi,11 abi: Abi,
12 ofmt: ObjectFormat,
1213
13 pub const Os = struct {14 pub const Os = struct {
14 tag: Tag,15 tag: Tag,
...@@ -594,6 +595,20 @@ pub const Target = struct {...@@ -594,6 +595,20 @@ pub const Target = struct {
594 .nvptx => ".ptx",595 .nvptx => ".ptx",
595 };596 };
596 }597 }
598
599 pub fn default(os_tag: Os.Tag, cpu_arch: Cpu.Arch) ObjectFormat {
600 return switch (os_tag) {
601 .windows, .uefi => .coff,
602 .ios, .macos, .watchos, .tvos => .macho,
603 .plan9 => .plan9,
604 else => return switch (cpu_arch) {
605 .wasm32, .wasm64 => .wasm,
606 .spirv32, .spirv64 => .spirv,
607 .nvptx, .nvptx64 => .nvptx,
608 else => .elf,
609 },
610 };
611 }
597 };612 };
598613
599 pub const SubSystem = enum {614 pub const SubSystem = enum {
...@@ -1381,24 +1396,6 @@ pub const Target = struct {...@@ -1381,24 +1396,6 @@ pub const Target = struct {
1381 return libPrefix_os_abi(self.os.tag, self.abi);1396 return libPrefix_os_abi(self.os.tag, self.abi);
1382 }1397 }
13831398
1384 pub fn getObjectFormatSimple(os_tag: Os.Tag, cpu_arch: Cpu.Arch) ObjectFormat {
1385 return switch (os_tag) {
1386 .windows, .uefi => .coff,
1387 .ios, .macos, .watchos, .tvos => .macho,
1388 .plan9 => .plan9,
1389 else => return switch (cpu_arch) {
1390 .wasm32, .wasm64 => .wasm,
1391 .spirv32, .spirv64 => .spirv,
1392 .nvptx, .nvptx64 => .nvptx,
1393 else => .elf,
1394 },
1395 };
1396 }
1397
1398 pub fn getObjectFormat(self: Target) ObjectFormat {
1399 return getObjectFormatSimple(self.os.tag, self.cpu.arch);
1400 }
1401
1402 pub fn isMinGW(self: Target) bool {1399 pub fn isMinGW(self: Target) bool {
1403 return self.os.tag == .windows and self.isGnu();1400 return self.os.tag == .windows and self.isGnu();
1404 }1401 }
lib/std/zig.zig+7-5
...@@ -103,7 +103,6 @@ pub const BinNameOptions = struct {...@@ -103,7 +103,6 @@ pub const BinNameOptions = struct {
103 target: std.Target,103 target: std.Target,
104 output_mode: std.builtin.OutputMode,104 output_mode: std.builtin.OutputMode,
105 link_mode: ?std.builtin.LinkMode = null,105 link_mode: ?std.builtin.LinkMode = null,
106 object_format: ?std.Target.ObjectFormat = null,
107 version: ?std.builtin.Version = null,106 version: ?std.builtin.Version = null,
108};107};
109108
...@@ -111,8 +110,7 @@ pub const BinNameOptions = struct {...@@ -111,8 +110,7 @@ pub const BinNameOptions = struct {
111pub fn binNameAlloc(allocator: std.mem.Allocator, options: BinNameOptions) error{OutOfMemory}![]u8 {110pub fn binNameAlloc(allocator: std.mem.Allocator, options: BinNameOptions) error{OutOfMemory}![]u8 {
112 const root_name = options.root_name;111 const root_name = options.root_name;
113 const target = options.target;112 const target = options.target;
114 const ofmt = options.object_format orelse target.getObjectFormat();113 switch (target.ofmt) {
115 switch (ofmt) {
116 .coff => switch (options.output_mode) {114 .coff => switch (options.output_mode) {
117 .Exe => return std.fmt.allocPrint(allocator, "{s}{s}", .{ root_name, target.exeFileExt() }),115 .Exe => return std.fmt.allocPrint(allocator, "{s}{s}", .{ root_name, target.exeFileExt() }),
118 .Lib => {116 .Lib => {
...@@ -186,8 +184,12 @@ pub fn binNameAlloc(allocator: std.mem.Allocator, options: BinNameOptions) error...@@ -186,8 +184,12 @@ pub fn binNameAlloc(allocator: std.mem.Allocator, options: BinNameOptions) error
186 .raw => return std.fmt.allocPrint(allocator, "{s}.bin", .{root_name}),184 .raw => return std.fmt.allocPrint(allocator, "{s}.bin", .{root_name}),
187 .plan9 => switch (options.output_mode) {185 .plan9 => switch (options.output_mode) {
188 .Exe => return allocator.dupe(u8, root_name),186 .Exe => return allocator.dupe(u8, root_name),
189 .Obj => return std.fmt.allocPrint(allocator, "{s}{s}", .{ root_name, ofmt.fileExt(target.cpu.arch) }),187 .Obj => return std.fmt.allocPrint(allocator, "{s}{s}", .{
190 .Lib => return std.fmt.allocPrint(allocator, "{s}{s}.a", .{ target.libPrefix(), root_name }),188 root_name, target.ofmt.fileExt(target.cpu.arch),
189 }),
190 .Lib => return std.fmt.allocPrint(allocator, "{s}{s}.a", .{
191 target.libPrefix(), root_name,
192 }),
191 },193 },
192 .nvptx => return std.fmt.allocPrint(allocator, "{s}", .{root_name}),194 .nvptx => return std.fmt.allocPrint(allocator, "{s}", .{root_name}),
193 }195 }
lib/std/zig/CrossTarget.zig+12-1
...@@ -42,6 +42,9 @@ abi: ?Target.Abi = null,...@@ -42,6 +42,9 @@ abi: ?Target.Abi = null,
42/// based on the `os_tag`.42/// based on the `os_tag`.
43dynamic_linker: DynamicLinker = DynamicLinker{},43dynamic_linker: DynamicLinker = DynamicLinker{},
4444
45/// `null` means default for the cpu/arch/os combo.
46ofmt: ?Target.ObjectFormat = null,
47
45pub const CpuModel = union(enum) {48pub const CpuModel = union(enum) {
46 /// Always native49 /// Always native
47 native,50 native,
...@@ -168,6 +171,7 @@ pub fn toTarget(self: CrossTarget) Target {...@@ -168,6 +171,7 @@ pub fn toTarget(self: CrossTarget) Target {
168 .cpu = self.getCpu(),171 .cpu = self.getCpu(),
169 .os = self.getOs(),172 .os = self.getOs(),
170 .abi = self.getAbi(),173 .abi = self.getAbi(),
174 .ofmt = self.getObjectFormat(),
171 };175 };
172}176}
173177
...@@ -197,6 +201,8 @@ pub const ParseOptions = struct {...@@ -197,6 +201,8 @@ pub const ParseOptions = struct {
197 /// detected path, or a standard path.201 /// detected path, or a standard path.
198 dynamic_linker: ?[]const u8 = null,202 dynamic_linker: ?[]const u8 = null,
199203
204 object_format: ?[]const u8 = null,
205
200 /// If this is provided, the function will populate some information about parsing failures,206 /// If this is provided, the function will populate some information about parsing failures,
201 /// so that user-friendly error messages can be delivered.207 /// so that user-friendly error messages can be delivered.
202 diagnostics: ?*Diagnostics = null,208 diagnostics: ?*Diagnostics = null,
...@@ -321,6 +327,11 @@ pub fn parse(args: ParseOptions) !CrossTarget {...@@ -321,6 +327,11 @@ pub fn parse(args: ParseOptions) !CrossTarget {
321 }327 }
322 }328 }
323329
330 if (args.object_format) |ofmt_name| {
331 result.ofmt = std.meta.stringToEnum(Target.ObjectFormat, ofmt_name) orelse
332 return error.UnknownObjectFormat;
333 }
334
324 return result;335 return result;
325}336}
326337
...@@ -620,7 +631,7 @@ pub fn setGnuLibCVersion(self: *CrossTarget, major: u32, minor: u32, patch: u32)...@@ -620,7 +631,7 @@ pub fn setGnuLibCVersion(self: *CrossTarget, major: u32, minor: u32, patch: u32)
620}631}
621632
622pub fn getObjectFormat(self: CrossTarget) Target.ObjectFormat {633pub fn getObjectFormat(self: CrossTarget) Target.ObjectFormat {
623 return Target.getObjectFormatSimple(self.getOsTag(), self.getCpuArch());634 return self.ofmt orelse Target.ObjectFormat.default(self.getOsTag(), self.getCpuArch());
624}635}
625636
626pub fn updateCpuFeatures(self: CrossTarget, set: *Target.Cpu.Feature.Set) void {637pub fn updateCpuFeatures(self: CrossTarget, set: *Target.Cpu.Feature.Set) void {
lib/std/zig/system/NativeTargetInfo.zig+5
...@@ -276,6 +276,7 @@ fn detectAbiAndDynamicLinker(...@@ -276,6 +276,7 @@ fn detectAbiAndDynamicLinker(
276 };276 };
277 var ld_info_list_buffer: [all_abis.len]LdInfo = undefined;277 var ld_info_list_buffer: [all_abis.len]LdInfo = undefined;
278 var ld_info_list_len: usize = 0;278 var ld_info_list_len: usize = 0;
279 const ofmt = cross_target.ofmt orelse Target.ObjectFormat.default(os.tag, cpu.arch);
279280
280 for (all_abis) |abi| {281 for (all_abis) |abi| {
281 // This may be a nonsensical parameter. We detect this with error.UnknownDynamicLinkerPath and282 // This may be a nonsensical parameter. We detect this with error.UnknownDynamicLinkerPath and
...@@ -284,6 +285,7 @@ fn detectAbiAndDynamicLinker(...@@ -284,6 +285,7 @@ fn detectAbiAndDynamicLinker(
284 .cpu = cpu,285 .cpu = cpu,
285 .os = os,286 .os = os,
286 .abi = abi,287 .abi = abi,
288 .ofmt = ofmt,
287 };289 };
288 const ld = target.standardDynamicLinkerPath();290 const ld = target.standardDynamicLinkerPath();
289 if (ld.get() == null) continue;291 if (ld.get() == null) continue;
...@@ -346,6 +348,7 @@ fn detectAbiAndDynamicLinker(...@@ -346,6 +348,7 @@ fn detectAbiAndDynamicLinker(
346 .cpu = cpu,348 .cpu = cpu,
347 .os = os_adjusted,349 .os = os_adjusted,
348 .abi = cross_target.abi orelse found_ld_info.abi,350 .abi = cross_target.abi orelse found_ld_info.abi,
351 .ofmt = cross_target.ofmt orelse Target.ObjectFormat.default(os_adjusted.tag, cpu.arch),
349 },352 },
350 .dynamic_linker = if (cross_target.dynamic_linker.get() == null)353 .dynamic_linker = if (cross_target.dynamic_linker.get() == null)
351 DynamicLinker.init(found_ld_path)354 DynamicLinker.init(found_ld_path)
...@@ -539,6 +542,7 @@ pub fn abiAndDynamicLinkerFromFile(...@@ -539,6 +542,7 @@ pub fn abiAndDynamicLinkerFromFile(
539 .cpu = cpu,542 .cpu = cpu,
540 .os = os,543 .os = os,
541 .abi = cross_target.abi orelse Target.Abi.default(cpu.arch, os),544 .abi = cross_target.abi orelse Target.Abi.default(cpu.arch, os),
545 .ofmt = cross_target.ofmt orelse Target.ObjectFormat.default(os.tag, cpu.arch),
542 },546 },
543 .dynamic_linker = cross_target.dynamic_linker,547 .dynamic_linker = cross_target.dynamic_linker,
544 };548 };
...@@ -829,6 +833,7 @@ fn defaultAbiAndDynamicLinker(cpu: Target.Cpu, os: Target.Os, cross_target: Cros...@@ -829,6 +833,7 @@ fn defaultAbiAndDynamicLinker(cpu: Target.Cpu, os: Target.Os, cross_target: Cros
829 .cpu = cpu,833 .cpu = cpu,
830 .os = os,834 .os = os,
831 .abi = cross_target.abi orelse Target.Abi.default(cpu.arch, os),835 .abi = cross_target.abi orelse Target.Abi.default(cpu.arch, os),
836 .ofmt = cross_target.ofmt orelse Target.ObjectFormat.default(os.tag, cpu.arch),
832 };837 };
833 return NativeTargetInfo{838 return NativeTargetInfo{
834 .target = target,839 .target = target,
src/Compilation.zig+15-15
...@@ -810,7 +810,6 @@ pub const InitOptions = struct {...@@ -810,7 +810,6 @@ pub const InitOptions = struct {
810 /// this flag would be set to disable this machinery to avoid false positives.810 /// this flag would be set to disable this machinery to avoid false positives.
811 disable_lld_caching: bool = false,811 disable_lld_caching: bool = false,
812 cache_mode: CacheMode = .incremental,812 cache_mode: CacheMode = .incremental,
813 object_format: ?std.Target.ObjectFormat = null,
814 optimize_mode: std.builtin.Mode = .Debug,813 optimize_mode: std.builtin.Mode = .Debug,
815 keep_source_files_loaded: bool = false,814 keep_source_files_loaded: bool = false,
816 clang_argv: []const []const u8 = &[0][]const u8{},815 clang_argv: []const []const u8 = &[0][]const u8{},
...@@ -1027,8 +1026,6 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation {...@@ -1027,8 +1026,6 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation {
1027 const comp = try arena.create(Compilation);1026 const comp = try arena.create(Compilation);
1028 const root_name = try arena.dupeZ(u8, options.root_name);1027 const root_name = try arena.dupeZ(u8, options.root_name);
10291028
1030 const ofmt = options.object_format orelse options.target.getObjectFormat();
1031
1032 const use_stage1 = options.use_stage1 orelse blk: {1029 const use_stage1 = options.use_stage1 orelse blk: {
1033 // Even though we may have no Zig code to compile (depending on `options.main_pkg`),1030 // Even though we may have no Zig code to compile (depending on `options.main_pkg`),
1034 // we may need to use stage1 for building compiler-rt and other dependencies.1031 // 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 {...@@ -1042,7 +1039,7 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation {
1042 }1039 }
10431040
1044 // If LLVM does not support the target, then we can't use it.1041 // If LLVM does not support the target, then we can't use it.
1045 if (!target_util.hasLlvmSupport(options.target, ofmt))1042 if (!target_util.hasLlvmSupport(options.target, options.target.ofmt))
1046 break :blk false;1043 break :blk false;
10471044
1048 break :blk build_options.is_stage1;1045 break :blk build_options.is_stage1;
...@@ -1072,7 +1069,7 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation {...@@ -1072,7 +1069,7 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation {
1072 break :blk true;1069 break :blk true;
10731070
1074 // If LLVM does not support the target, then we can't use it.1071 // If LLVM does not support the target, then we can't use it.
1075 if (!target_util.hasLlvmSupport(options.target, ofmt))1072 if (!target_util.hasLlvmSupport(options.target, options.target.ofmt))
1076 break :blk false;1073 break :blk false;
10771074
1078 // Prefer LLVM for release builds.1075 // Prefer LLVM for release builds.
...@@ -1115,7 +1112,7 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation {...@@ -1115,7 +1112,7 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation {
1115 if (!build_options.have_llvm)1112 if (!build_options.have_llvm)
1116 break :blk false;1113 break :blk false;
11171114
1118 if (ofmt == .c)1115 if (options.target.ofmt == .c)
1119 break :blk false;1116 break :blk false;
11201117
1121 if (options.want_lto) |lto| {1118 if (options.want_lto) |lto| {
...@@ -1374,7 +1371,7 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation {...@@ -1374,7 +1371,7 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation {
1374 cache.hash.add(options.target.os.getVersionRange());1371 cache.hash.add(options.target.os.getVersionRange());
1375 cache.hash.add(options.is_native_os);1372 cache.hash.add(options.is_native_os);
1376 cache.hash.add(options.target.abi);1373 cache.hash.add(options.target.abi);
1377 cache.hash.add(ofmt);1374 cache.hash.add(options.target.ofmt);
1378 cache.hash.add(pic);1375 cache.hash.add(pic);
1379 cache.hash.add(pie);1376 cache.hash.add(pie);
1380 cache.hash.add(lto);1377 cache.hash.add(lto);
...@@ -1682,7 +1679,6 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation {...@@ -1682,7 +1679,6 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation {
1682 .sysroot = sysroot,1679 .sysroot = sysroot,
1683 .output_mode = options.output_mode,1680 .output_mode = options.output_mode,
1684 .link_mode = link_mode,1681 .link_mode = link_mode,
1685 .object_format = ofmt,
1686 .optimize_mode = options.optimize_mode,1682 .optimize_mode = options.optimize_mode,
1687 .use_lld = use_lld,1683 .use_lld = use_lld,
1688 .use_llvm = use_llvm,1684 .use_llvm = use_llvm,
...@@ -1841,7 +1837,9 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation {...@@ -1841,7 +1837,9 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation {
18411837
1842 const have_bin_emit = comp.bin_file.options.emit != null or comp.whole_bin_sub_path != null;1838 const have_bin_emit = comp.bin_file.options.emit != null or comp.whole_bin_sub_path != null;
18431839
1844 if (have_bin_emit and !comp.bin_file.options.skip_linker_dependencies) {1840 if (have_bin_emit and !comp.bin_file.options.skip_linker_dependencies and
1841 options.target.ofmt != .c)
1842 {
1845 if (comp.getTarget().isDarwin()) {1843 if (comp.getTarget().isDarwin()) {
1846 switch (comp.getTarget().abi) {1844 switch (comp.getTarget().abi) {
1847 .none,1845 .none,
...@@ -3739,7 +3737,8 @@ fn updateCObject(comp: *Compilation, c_object: *CObject, c_obj_prog_node: *std.P...@@ -3739,7 +3737,8 @@ fn updateCObject(comp: *Compilation, c_object: *CObject, c_obj_prog_node: *std.P
3739 else3737 else
3740 c_source_basename[0 .. c_source_basename.len - std.fs.path.extension(c_source_basename).len];3738 c_source_basename[0 .. c_source_basename.len - std.fs.path.extension(c_source_basename).len];
37413739
3742 const o_ext = comp.bin_file.options.object_format.fileExt(comp.bin_file.options.target.cpu.arch);3740 const target = comp.getTarget();
3741 const o_ext = target.ofmt.fileExt(target.cpu.arch);
3743 const digest = if (!comp.disable_c_depfile and try man.hit()) man.final() else blk: {3742 const digest = if (!comp.disable_c_depfile and try man.hit()) man.final() else blk: {
3744 var argv = std.ArrayList([]const u8).init(comp.gpa);3743 var argv = std.ArrayList([]const u8).init(comp.gpa);
3745 defer argv.deinit();3744 defer argv.deinit();
...@@ -4092,7 +4091,7 @@ pub fn addCCArgs(...@@ -4092,7 +4091,7 @@ pub fn addCCArgs(
40924091
4093 if (!comp.bin_file.options.strip) {4092 if (!comp.bin_file.options.strip) {
4094 try argv.append("-g");4093 try argv.append("-g");
4095 switch (comp.bin_file.options.object_format) {4094 switch (target.ofmt) {
4096 .coff => try argv.append("-gcodeview"),4095 .coff => try argv.append("-gcodeview"),
4097 else => {},4096 else => {},
4098 }4097 }
...@@ -4660,7 +4659,7 @@ fn wantBuildLibCFromSource(comp: Compilation) bool {...@@ -4660,7 +4659,7 @@ fn wantBuildLibCFromSource(comp: Compilation) bool {
4660 };4659 };
4661 return comp.bin_file.options.link_libc and is_exe_or_dyn_lib and4660 return comp.bin_file.options.link_libc and is_exe_or_dyn_lib and
4662 comp.bin_file.options.libc_installation == null and4661 comp.bin_file.options.libc_installation == null and
4663 comp.bin_file.options.object_format != .c;4662 comp.bin_file.options.target.ofmt != .c;
4664}4663}
46654664
4666fn wantBuildGLibCFromSource(comp: Compilation) bool {4665fn wantBuildGLibCFromSource(comp: Compilation) bool {
...@@ -4688,7 +4687,7 @@ fn wantBuildLibUnwindFromSource(comp: *Compilation) bool {...@@ -4688,7 +4687,7 @@ fn wantBuildLibUnwindFromSource(comp: *Compilation) bool {
4688 .Exe => true,4687 .Exe => true,
4689 };4688 };
4690 return is_exe_or_dyn_lib and comp.bin_file.options.link_libunwind and4689 return is_exe_or_dyn_lib and comp.bin_file.options.link_libunwind and
4691 comp.bin_file.options.object_format != .c;4690 comp.bin_file.options.target.ofmt != .c;
4692}4691}
46934692
4694fn setAllocFailure(comp: *Compilation) void {4693fn setAllocFailure(comp: *Compilation) void {
...@@ -4747,7 +4746,7 @@ pub fn generateBuiltinZigSource(comp: *Compilation, allocator: Allocator) Alloca...@@ -4747,7 +4746,7 @@ pub fn generateBuiltinZigSource(comp: *Compilation, allocator: Allocator) Alloca
4747 const zig_backend: std.builtin.CompilerBackend = blk: {4746 const zig_backend: std.builtin.CompilerBackend = blk: {
4748 if (use_stage1) break :blk .stage1;4747 if (use_stage1) break :blk .stage1;
4749 if (build_options.have_llvm and comp.bin_file.options.use_llvm) break :blk .stage2_llvm;4748 if (build_options.have_llvm and comp.bin_file.options.use_llvm) break :blk .stage2_llvm;
4750 if (comp.bin_file.options.object_format == .c) break :blk .stage2_c;4749 if (target.ofmt == .c) break :blk .stage2_c;
4751 break :blk switch (target.cpu.arch) {4750 break :blk switch (target.cpu.arch) {
4752 .wasm32, .wasm64 => std.builtin.CompilerBackend.stage2_wasm,4751 .wasm32, .wasm64 => std.builtin.CompilerBackend.stage2_wasm,
4753 .arm, .armeb, .thumb, .thumbeb => .stage2_arm,4752 .arm, .armeb, .thumb, .thumbeb => .stage2_arm,
...@@ -4895,6 +4894,7 @@ pub fn generateBuiltinZigSource(comp: *Compilation, allocator: Allocator) Alloca...@@ -4895,6 +4894,7 @@ pub fn generateBuiltinZigSource(comp: *Compilation, allocator: Allocator) Alloca
4895 \\ .cpu = cpu,4894 \\ .cpu = cpu,
4896 \\ .os = os,4895 \\ .os = os,
4897 \\ .abi = abi,4896 \\ .abi = abi,
4897 \\ .ofmt = object_format,
4898 \\}};4898 \\}};
4899 \\pub const object_format = std.Target.ObjectFormat.{};4899 \\pub const object_format = std.Target.ObjectFormat.{};
4900 \\pub const mode = std.builtin.Mode.{};4900 \\pub const mode = std.builtin.Mode.{};
...@@ -4909,7 +4909,7 @@ pub fn generateBuiltinZigSource(comp: *Compilation, allocator: Allocator) Alloca...@@ -4909,7 +4909,7 @@ pub fn generateBuiltinZigSource(comp: *Compilation, allocator: Allocator) Alloca
4909 \\pub const code_model = std.builtin.CodeModel.{};4909 \\pub const code_model = std.builtin.CodeModel.{};
4910 \\4910 \\
4911 , .{4911 , .{
4912 std.zig.fmtId(@tagName(comp.bin_file.options.object_format)),4912 std.zig.fmtId(@tagName(target.ofmt)),
4913 std.zig.fmtId(@tagName(comp.bin_file.options.optimize_mode)),4913 std.zig.fmtId(@tagName(comp.bin_file.options.optimize_mode)),
4914 link_libc,4914 link_libc,
4915 comp.bin_file.options.link_libcpp,4915 comp.bin_file.options.link_libcpp,
src/Sema.zig+1-1
...@@ -20654,7 +20654,7 @@ fn panicWithMsg(...@@ -20654,7 +20654,7 @@ fn panicWithMsg(
20654 const arena = sema.arena;20654 const arena = sema.arena;
2065520655
20656 const this_feature_is_implemented_in_the_backend =20656 const this_feature_is_implemented_in_the_backend =
20657 mod.comp.bin_file.options.object_format == .c or20657 mod.comp.bin_file.options.target.ofmt == .c or
20658 mod.comp.bin_file.options.use_llvm;20658 mod.comp.bin_file.options.use_llvm;
20659 if (!this_feature_is_implemented_in_the_backend) {20659 if (!this_feature_is_implemented_in_the_backend) {
20660 // TODO implement this feature in all the backends and then delete this branch20660 // TODO implement this feature in all the backends and then delete this branch
src/codegen/llvm.zig+1-1
...@@ -273,7 +273,7 @@ pub const Object = struct {...@@ -273,7 +273,7 @@ pub const Object = struct {
273 var di_compile_unit: ?*llvm.DICompileUnit = null;273 var di_compile_unit: ?*llvm.DICompileUnit = null;
274274
275 if (!options.strip) {275 if (!options.strip) {
276 switch (options.object_format) {276 switch (options.target.ofmt) {
277 .coff => llvm_module.addModuleCodeViewFlag(),277 .coff => llvm_module.addModuleCodeViewFlag(),
278 else => llvm_module.addModuleDebugInfoFlag(),278 else => llvm_module.addModuleDebugInfoFlag(),
279 }279 }
src/link.zig+5-6
...@@ -72,7 +72,6 @@ pub const Options = struct {...@@ -72,7 +72,6 @@ pub const Options = struct {
72 target: std.Target,72 target: std.Target,
73 output_mode: std.builtin.OutputMode,73 output_mode: std.builtin.OutputMode,
74 link_mode: std.builtin.LinkMode,74 link_mode: std.builtin.LinkMode,
75 object_format: std.Target.ObjectFormat,
76 optimize_mode: std.builtin.Mode,75 optimize_mode: std.builtin.Mode,
77 machine_code_model: std.builtin.CodeModel,76 machine_code_model: std.builtin.CodeModel,
78 root_name: [:0]const u8,77 root_name: [:0]const u8,
...@@ -273,13 +272,13 @@ pub const File = struct {...@@ -273,13 +272,13 @@ pub const File = struct {
273 /// rewriting it. A malicious file is detected as incremental link failure272 /// rewriting it. A malicious file is detected as incremental link failure
274 /// and does not cause Illegal Behavior. This operation is not atomic.273 /// and does not cause Illegal Behavior. This operation is not atomic.
275 pub fn openPath(allocator: Allocator, options: Options) !*File {274 pub fn openPath(allocator: Allocator, options: Options) !*File {
276 if (options.object_format == .macho) {275 if (options.target.ofmt == .macho) {
277 return &(try MachO.openPath(allocator, options)).base;276 return &(try MachO.openPath(allocator, options)).base;
278 }277 }
279278
280 const use_stage1 = build_options.is_stage1 and options.use_stage1;279 const use_stage1 = build_options.is_stage1 and options.use_stage1;
281 if (use_stage1 or options.emit == null) {280 if (use_stage1 or options.emit == null) {
282 return switch (options.object_format) {281 return switch (options.target.ofmt) {
283 .coff => &(try Coff.createEmpty(allocator, options)).base,282 .coff => &(try Coff.createEmpty(allocator, options)).base,
284 .elf => &(try Elf.createEmpty(allocator, options)).base,283 .elf => &(try Elf.createEmpty(allocator, options)).base,
285 .macho => unreachable,284 .macho => unreachable,
...@@ -298,7 +297,7 @@ pub const File = struct {...@@ -298,7 +297,7 @@ pub const File = struct {
298 if (options.module == null) {297 if (options.module == null) {
299 // No point in opening a file, we would not write anything to it.298 // No point in opening a file, we would not write anything to it.
300 // Initialize with empty.299 // Initialize with empty.
301 return switch (options.object_format) {300 return switch (options.target.ofmt) {
302 .coff => &(try Coff.createEmpty(allocator, options)).base,301 .coff => &(try Coff.createEmpty(allocator, options)).base,
303 .elf => &(try Elf.createEmpty(allocator, options)).base,302 .elf => &(try Elf.createEmpty(allocator, options)).base,
304 .macho => unreachable,303 .macho => unreachable,
...@@ -314,12 +313,12 @@ pub const File = struct {...@@ -314,12 +313,12 @@ pub const File = struct {
314 // Open a temporary object file, not the final output file because we313 // Open a temporary object file, not the final output file because we
315 // want to link with LLD.314 // want to link with LLD.
316 break :blk try std.fmt.allocPrint(allocator, "{s}{s}", .{315 break :blk try std.fmt.allocPrint(allocator, "{s}{s}", .{
317 emit.sub_path, options.object_format.fileExt(options.target.cpu.arch),316 emit.sub_path, options.target.ofmt.fileExt(options.target.cpu.arch),
318 });317 });
319 } else emit.sub_path;318 } else emit.sub_path;
320 errdefer if (use_lld) allocator.free(sub_path);319 errdefer if (use_lld) allocator.free(sub_path);
321320
322 const file: *File = switch (options.object_format) {321 const file: *File = switch (options.target.ofmt) {
323 .coff => &(try Coff.openPath(allocator, sub_path, options)).base,322 .coff => &(try Coff.openPath(allocator, sub_path, options)).base,
324 .elf => &(try Elf.openPath(allocator, sub_path, options)).base,323 .elf => &(try Elf.openPath(allocator, sub_path, options)).base,
325 .macho => unreachable,324 .macho => unreachable,
src/link/C.zig+1-1
...@@ -48,7 +48,7 @@ const DeclBlock = struct {...@@ -48,7 +48,7 @@ const DeclBlock = struct {
48};48};
4949
50pub fn openPath(gpa: Allocator, sub_path: []const u8, options: link.Options) !*C {50pub fn openPath(gpa: Allocator, sub_path: []const u8, options: link.Options) !*C {
51 assert(options.object_format == .c);51 assert(options.target.ofmt == .c);
5252
53 if (options.use_llvm) return error.LLVMHasNoCBackend;53 if (options.use_llvm) return error.LLVMHasNoCBackend;
54 if (options.use_lld) return error.LLDHasNoCBackend;54 if (options.use_lld) return error.LLDHasNoCBackend;
src/link/Coff.zig+1-1
...@@ -128,7 +128,7 @@ pub const TextBlock = struct {...@@ -128,7 +128,7 @@ pub const TextBlock = struct {
128pub const SrcFn = void;128pub const SrcFn = void;
129129
130pub fn openPath(allocator: Allocator, sub_path: []const u8, options: link.Options) !*Coff {130pub fn openPath(allocator: Allocator, sub_path: []const u8, options: link.Options) !*Coff {
131 assert(options.object_format == .coff);131 assert(options.target.ofmt == .coff);
132132
133 if (build_options.have_llvm and options.use_llvm) {133 if (build_options.have_llvm and options.use_llvm) {
134 return createEmpty(allocator, options);134 return createEmpty(allocator, options);
src/link/Elf.zig+1-1
...@@ -249,7 +249,7 @@ pub const Export = struct {...@@ -249,7 +249,7 @@ pub const Export = struct {
249};249};
250250
251pub fn openPath(allocator: Allocator, sub_path: []const u8, options: link.Options) !*Elf {251pub fn openPath(allocator: Allocator, sub_path: []const u8, options: link.Options) !*Elf {
252 assert(options.object_format == .elf);252 assert(options.target.ofmt == .elf);
253253
254 if (build_options.have_llvm and options.use_llvm) {254 if (build_options.have_llvm and options.use_llvm) {
255 return createEmpty(allocator, options);255 return createEmpty(allocator, options);
src/link/MachO.zig+2-2
...@@ -270,7 +270,7 @@ pub const Export = struct {...@@ -270,7 +270,7 @@ pub const Export = struct {
270};270};
271271
272pub fn openPath(allocator: Allocator, options: link.Options) !*MachO {272pub fn openPath(allocator: Allocator, options: link.Options) !*MachO {
273 assert(options.object_format == .macho);273 assert(options.target.ofmt == .macho);
274274
275 const use_stage1 = build_options.is_stage1 and options.use_stage1;275 const use_stage1 = build_options.is_stage1 and options.use_stage1;
276 if (use_stage1 or options.emit == null) {276 if (use_stage1 or options.emit == null) {
...@@ -289,7 +289,7 @@ pub fn openPath(allocator: Allocator, options: link.Options) !*MachO {...@@ -289,7 +289,7 @@ pub fn openPath(allocator: Allocator, options: link.Options) !*MachO {
289 // we also want to put the intermediary object file in the cache while the289 // we also want to put the intermediary object file in the cache while the
290 // main emit directory is the cwd.290 // main emit directory is the cwd.
291 self.base.intermediary_basename = try std.fmt.allocPrint(allocator, "{s}{s}", .{291 self.base.intermediary_basename = try std.fmt.allocPrint(allocator, "{s}{s}", .{
292 emit.sub_path, options.object_format.fileExt(options.target.cpu.arch),292 emit.sub_path, options.target.ofmt.fileExt(options.target.cpu.arch),
293 });293 });
294 }294 }
295295
src/link/NvPtx.zig+1-1
...@@ -57,7 +57,7 @@ pub fn createEmpty(gpa: Allocator, options: link.Options) !*NvPtx {...@@ -57,7 +57,7 @@ pub fn createEmpty(gpa: Allocator, options: link.Options) !*NvPtx {
57pub fn openPath(allocator: Allocator, sub_path: []const u8, options: link.Options) !*NvPtx {57pub fn openPath(allocator: Allocator, sub_path: []const u8, options: link.Options) !*NvPtx {
58 if (!build_options.have_llvm) @panic("nvptx target requires a zig compiler with llvm enabled.");58 if (!build_options.have_llvm) @panic("nvptx target requires a zig compiler with llvm enabled.");
59 if (!options.use_llvm) return error.PtxArchNotSupported;59 if (!options.use_llvm) return error.PtxArchNotSupported;
60 assert(options.object_format == .nvptx);60 assert(options.target.ofmt == .nvptx);
6161
62 const nvptx = try createEmpty(allocator, options);62 const nvptx = try createEmpty(allocator, options);
63 log.info("Opening .ptx target file {s}", .{sub_path});63 log.info("Opening .ptx target file {s}", .{sub_path});
src/link/Plan9.zig+1-1
...@@ -657,7 +657,7 @@ pub const base_tag = .plan9;...@@ -657,7 +657,7 @@ pub const base_tag = .plan9;
657pub fn openPath(allocator: Allocator, sub_path: []const u8, options: link.Options) !*Plan9 {657pub fn openPath(allocator: Allocator, sub_path: []const u8, options: link.Options) !*Plan9 {
658 if (options.use_llvm)658 if (options.use_llvm)
659 return error.LLVMBackendDoesNotSupportPlan9;659 return error.LLVMBackendDoesNotSupportPlan9;
660 assert(options.object_format == .plan9);660 assert(options.target.ofmt == .plan9);
661661
662 const self = try createEmpty(allocator, options);662 const self = try createEmpty(allocator, options);
663 errdefer self.base.destroy();663 errdefer self.base.destroy();
src/link/SpirV.zig+1-1
...@@ -99,7 +99,7 @@ pub fn createEmpty(gpa: Allocator, options: link.Options) !*SpirV {...@@ -99,7 +99,7 @@ pub fn createEmpty(gpa: Allocator, options: link.Options) !*SpirV {
99}99}
100100
101pub fn openPath(allocator: Allocator, sub_path: []const u8, options: link.Options) !*SpirV {101pub fn openPath(allocator: Allocator, sub_path: []const u8, options: link.Options) !*SpirV {
102 assert(options.object_format == .spirv);102 assert(options.target.ofmt == .spirv);
103103
104 if (options.use_llvm) return error.LLVM_BackendIsTODO_ForSpirV; // TODO: LLVM Doesn't support SpirV at all.104 if (options.use_llvm) return error.LLVM_BackendIsTODO_ForSpirV; // TODO: LLVM Doesn't support SpirV at all.
105 if (options.use_lld) return error.LLD_LinkingIsTODO_ForSpirV; // TODO: LLD Doesn't support SpirV at all.105 if (options.use_lld) return error.LLD_LinkingIsTODO_ForSpirV; // TODO: LLD Doesn't support SpirV at all.
src/link/Wasm.zig+1-1
...@@ -282,7 +282,7 @@ pub const StringTable = struct {...@@ -282,7 +282,7 @@ pub const StringTable = struct {
282};282};
283283
284pub fn openPath(allocator: Allocator, sub_path: []const u8, options: link.Options) !*Wasm {284pub fn openPath(allocator: Allocator, sub_path: []const u8, options: link.Options) !*Wasm {
285 assert(options.object_format == .wasm);285 assert(options.target.ofmt == .wasm);
286286
287 if (build_options.have_llvm and options.use_llvm) {287 if (build_options.have_llvm and options.use_llvm) {
288 return createEmpty(allocator, options);288 return createEmpty(allocator, options);
src/main.zig+22-29
...@@ -2192,6 +2192,7 @@ fn buildOutputType(...@@ -2192,6 +2192,7 @@ fn buildOutputType(
2192 .arch_os_abi = target_arch_os_abi,2192 .arch_os_abi = target_arch_os_abi,
2193 .cpu_features = target_mcpu,2193 .cpu_features = target_mcpu,
2194 .dynamic_linker = target_dynamic_linker,2194 .dynamic_linker = target_dynamic_linker,
2195 .object_format = target_ofmt,
2195 };2196 };
21962197
2197 // Before passing the mcpu string in for parsing, we convert any -m flags that were2198 // Before passing the mcpu string in for parsing, we convert any -m flags that were
...@@ -2494,28 +2495,7 @@ fn buildOutputType(...@@ -2494,28 +2495,7 @@ fn buildOutputType(
2494 }2495 }
2495 }2496 }
24962497
2497 const object_format: std.Target.ObjectFormat = blk: {2498 const object_format = target_info.target.ofmt;
2498 const ofmt = target_ofmt orelse break :blk target_info.target.getObjectFormat();
2499 if (mem.eql(u8, ofmt, "elf")) {
2500 break :blk .elf;
2501 } else if (mem.eql(u8, ofmt, "c")) {
2502 break :blk .c;
2503 } else if (mem.eql(u8, ofmt, "coff")) {
2504 break :blk .coff;
2505 } else if (mem.eql(u8, ofmt, "macho")) {
2506 break :blk .macho;
2507 } else if (mem.eql(u8, ofmt, "wasm")) {
2508 break :blk .wasm;
2509 } else if (mem.eql(u8, ofmt, "hex")) {
2510 break :blk .hex;
2511 } else if (mem.eql(u8, ofmt, "raw")) {
2512 break :blk .raw;
2513 } else if (mem.eql(u8, ofmt, "spirv")) {
2514 break :blk .spirv;
2515 } else {
2516 fatal("unsupported object format: {s}", .{ofmt});
2517 }
2518 };
25192499
2520 if (output_mode == .Obj and (object_format == .coff or object_format == .macho)) {2500 if (output_mode == .Obj and (object_format == .coff or object_format == .macho)) {
2521 const total_obj_count = c_source_files.items.len +2501 const total_obj_count = c_source_files.items.len +
...@@ -2569,7 +2549,6 @@ fn buildOutputType(...@@ -2569,7 +2549,6 @@ fn buildOutputType(
2569 .target = target_info.target,2549 .target = target_info.target,
2570 .output_mode = output_mode,2550 .output_mode = output_mode,
2571 .link_mode = link_mode,2551 .link_mode = link_mode,
2572 .object_format = object_format,
2573 .version = optional_version,2552 .version = optional_version,
2574 }),2553 }),
2575 },2554 },
...@@ -2859,7 +2838,6 @@ fn buildOutputType(...@@ -2859,7 +2838,6 @@ fn buildOutputType(
2859 .emit_implib = emit_implib_resolved.data,2838 .emit_implib = emit_implib_resolved.data,
2860 .link_mode = link_mode,2839 .link_mode = link_mode,
2861 .dll_export_fns = dll_export_fns,2840 .dll_export_fns = dll_export_fns,
2862 .object_format = object_format,
2863 .optimize_mode = optimize_mode,2841 .optimize_mode = optimize_mode,
2864 .keep_source_files_loaded = false,2842 .keep_source_files_loaded = false,
2865 .clang_argv = clang_argv.items,2843 .clang_argv = clang_argv.items,
...@@ -3173,11 +3151,11 @@ fn parseCrossTargetOrReportFatalError(...@@ -3173,11 +3151,11 @@ fn parseCrossTargetOrReportFatalError(
3173 for (diags.arch.?.allCpuModels()) |cpu| {3151 for (diags.arch.?.allCpuModels()) |cpu| {
3174 help_text.writer().print(" {s}\n", .{cpu.name}) catch break :help;3152 help_text.writer().print(" {s}\n", .{cpu.name}) catch break :help;
3175 }3153 }
3176 std.log.info("Available CPUs for architecture '{s}':\n{s}", .{3154 std.log.info("available CPUs for architecture '{s}':\n{s}", .{
3177 @tagName(diags.arch.?), help_text.items,3155 @tagName(diags.arch.?), help_text.items,
3178 });3156 });
3179 }3157 }
3180 fatal("Unknown CPU: '{s}'", .{diags.cpu_name.?});3158 fatal("unknown CPU: '{s}'", .{diags.cpu_name.?});
3181 },3159 },
3182 error.UnknownCpuFeature => {3160 error.UnknownCpuFeature => {
3183 help: {3161 help: {
...@@ -3186,11 +3164,26 @@ fn parseCrossTargetOrReportFatalError(...@@ -3186,11 +3164,26 @@ fn parseCrossTargetOrReportFatalError(
3186 for (diags.arch.?.allFeaturesList()) |feature| {3164 for (diags.arch.?.allFeaturesList()) |feature| {
3187 help_text.writer().print(" {s}: {s}\n", .{ feature.name, feature.description }) catch break :help;3165 help_text.writer().print(" {s}: {s}\n", .{ feature.name, feature.description }) catch break :help;
3188 }3166 }
3189 std.log.info("Available CPU features for architecture '{s}':\n{s}", .{3167 std.log.info("available CPU features for architecture '{s}':\n{s}", .{
3190 @tagName(diags.arch.?), help_text.items,3168 @tagName(diags.arch.?), help_text.items,
3191 });3169 });
3192 }3170 }
3193 fatal("Unknown CPU feature: '{s}'", .{diags.unknown_feature_name.?});3171 fatal("unknown CPU feature: '{s}'", .{diags.unknown_feature_name.?});
3172 },
3173 error.UnknownObjectFormat => {
3174 {
3175 var help_text = std.ArrayList(u8).init(allocator);
3176 defer help_text.deinit();
3177 inline for (@typeInfo(std.Target.ObjectFormat).Enum.fields) |field| {
3178 help_text.writer().print(" {s}\n", .{field.name}) catch
3179 // TODO change this back to `break :help`
3180 // this working around a stage1 bug.
3181 //break :help;
3182 @panic("out of memory");
3183 }
3184 std.log.info("available object formats:\n{s}", .{help_text.items});
3185 }
3186 fatal("unknown object format: '{s}'", .{opts.object_format.?});
3194 },3187 },
3195 else => |e| return e,3188 else => |e| return e,
3196 };3189 };
...@@ -3360,7 +3353,7 @@ fn updateModule(gpa: Allocator, comp: *Compilation, hook: AfterUpdateHook) !void...@@ -3360,7 +3353,7 @@ fn updateModule(gpa: Allocator, comp: *Compilation, hook: AfterUpdateHook) !void
33603353
3361 // If a .pdb file is part of the expected output, we must also copy3354 // If a .pdb file is part of the expected output, we must also copy
3362 // it into place here.3355 // it into place here.
3363 const is_coff = comp.bin_file.options.object_format == .coff;3356 const is_coff = comp.bin_file.options.target.ofmt == .coff;
3364 const have_pdb = is_coff and !comp.bin_file.options.strip;3357 const have_pdb = is_coff and !comp.bin_file.options.strip;
3365 if (have_pdb) {3358 if (have_pdb) {
3366 // Replace `.out` or `.exe` with `.pdb` on both the source and destination3359 // Replace `.out` or `.exe` with `.pdb` on both the source and destination
src/stage1/codegen.cpp+1
...@@ -10082,6 +10082,7 @@ Buf *codegen_generate_builtin_source(CodeGen *g) {...@@ -10082,6 +10082,7 @@ Buf *codegen_generate_builtin_source(CodeGen *g) {
10082 " .cpu = cpu,\n"10082 " .cpu = cpu,\n"
10083 " .os = os,\n"10083 " .os = os,\n"
10084 " .abi = abi,\n"10084 " .abi = abi,\n"
10085 " .ofmt = object_format,\n"
10085 "};\n"10086 "};\n"
10086 );10087 );
1008710088