Skip to content

Commit b975f7a

Browse files
committed
std.Target gains ObjectFormat field
1 parent 517eb73 commit b975f7a

18 files changed

+93
-85
lines changed

lib/std/target.zig

+15-18
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ pub const Target = struct {
99
cpu: Cpu,
1010
os: Os,
1111
abi: Abi,
12+
ofmt: ObjectFormat,
1213

1314
pub const Os = struct {
1415
tag: Tag,
@@ -594,6 +595,20 @@ pub const Target = struct {
594595
.nvptx => ".ptx",
595596
};
596597
}
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+
}
597612
};
598613

599614
pub const SubSystem = enum {
@@ -1381,24 +1396,6 @@ pub const Target = struct {
13811396
return libPrefix_os_abi(self.os.tag, self.abi);
13821397
}
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-
14021399
pub fn isMinGW(self: Target) bool {
14031400
return self.os.tag == .windows and self.isGnu();
14041401
}

lib/std/zig.zig

+7-5
Original file line numberDiff line numberDiff line change
@@ -103,16 +103,14 @@ pub const BinNameOptions = struct {
103103
target: std.Target,
104104
output_mode: std.builtin.OutputMode,
105105
link_mode: ?std.builtin.LinkMode = null,
106-
object_format: ?std.Target.ObjectFormat = null,
107106
version: ?std.builtin.Version = null,
108107
};
109108

110109
/// Returns the standard file system basename of a binary generated by the Zig compiler.
111110
pub fn binNameAlloc(allocator: std.mem.Allocator, options: BinNameOptions) error{OutOfMemory}![]u8 {
112111
const root_name = options.root_name;
113112
const target = options.target;
114-
const ofmt = options.object_format orelse target.getObjectFormat();
115-
switch (ofmt) {
113+
switch (target.ofmt) {
116114
.coff => switch (options.output_mode) {
117115
.Exe => return std.fmt.allocPrint(allocator, "{s}{s}", .{ root_name, target.exeFileExt() }),
118116
.Lib => {
@@ -186,8 +184,12 @@ pub fn binNameAlloc(allocator: std.mem.Allocator, options: BinNameOptions) error
186184
.raw => return std.fmt.allocPrint(allocator, "{s}.bin", .{root_name}),
187185
.plan9 => switch (options.output_mode) {
188186
.Exe => return allocator.dupe(u8, root_name),
189-
.Obj => return std.fmt.allocPrint(allocator, "{s}{s}", .{ root_name, ofmt.fileExt(target.cpu.arch) }),
190-
.Lib => return std.fmt.allocPrint(allocator, "{s}{s}.a", .{ target.libPrefix(), root_name }),
187+
.Obj => return std.fmt.allocPrint(allocator, "{s}{s}", .{
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+
}),
191193
},
192194
.nvptx => return std.fmt.allocPrint(allocator, "{s}", .{root_name}),
193195
}

lib/std/zig/CrossTarget.zig

+12-1
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,9 @@ abi: ?Target.Abi = null,
4242
/// based on the `os_tag`.
4343
dynamic_linker: DynamicLinker = DynamicLinker{},
4444

45+
/// `null` means default for the cpu/arch/os combo.
46+
ofmt: ?Target.ObjectFormat = null,
47+
4548
pub const CpuModel = union(enum) {
4649
/// Always native
4750
native,
@@ -168,6 +171,7 @@ pub fn toTarget(self: CrossTarget) Target {
168171
.cpu = self.getCpu(),
169172
.os = self.getOs(),
170173
.abi = self.getAbi(),
174+
.ofmt = self.getObjectFormat(),
171175
};
172176
}
173177

@@ -197,6 +201,8 @@ pub const ParseOptions = struct {
197201
/// detected path, or a standard path.
198202
dynamic_linker: ?[]const u8 = null,
199203

204+
object_format: ?[]const u8 = null,
205+
200206
/// If this is provided, the function will populate some information about parsing failures,
201207
/// so that user-friendly error messages can be delivered.
202208
diagnostics: ?*Diagnostics = null,
@@ -321,6 +327,11 @@ pub fn parse(args: ParseOptions) !CrossTarget {
321327
}
322328
}
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+
324335
return result;
325336
}
326337

@@ -620,7 +631,7 @@ pub fn setGnuLibCVersion(self: *CrossTarget, major: u32, minor: u32, patch: u32)
620631
}
621632

622633
pub 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());
624635
}
625636

626637
pub fn updateCpuFeatures(self: CrossTarget, set: *Target.Cpu.Feature.Set) void {

lib/std/zig/system/NativeTargetInfo.zig

+5
Original file line numberDiff line numberDiff line change
@@ -276,6 +276,7 @@ fn detectAbiAndDynamicLinker(
276276
};
277277
var ld_info_list_buffer: [all_abis.len]LdInfo = undefined;
278278
var ld_info_list_len: usize = 0;
279+
const ofmt = cross_target.ofmt orelse Target.ObjectFormat.default(os.tag, cpu.arch);
279280

280281
for (all_abis) |abi| {
281282
// This may be a nonsensical parameter. We detect this with error.UnknownDynamicLinkerPath and
@@ -284,6 +285,7 @@ fn detectAbiAndDynamicLinker(
284285
.cpu = cpu,
285286
.os = os,
286287
.abi = abi,
288+
.ofmt = ofmt,
287289
};
288290
const ld = target.standardDynamicLinkerPath();
289291
if (ld.get() == null) continue;
@@ -346,6 +348,7 @@ fn detectAbiAndDynamicLinker(
346348
.cpu = cpu,
347349
.os = os_adjusted,
348350
.abi = cross_target.abi orelse found_ld_info.abi,
351+
.ofmt = cross_target.ofmt orelse Target.ObjectFormat.default(os_adjusted.tag, cpu.arch),
349352
},
350353
.dynamic_linker = if (cross_target.dynamic_linker.get() == null)
351354
DynamicLinker.init(found_ld_path)
@@ -539,6 +542,7 @@ pub fn abiAndDynamicLinkerFromFile(
539542
.cpu = cpu,
540543
.os = os,
541544
.abi = cross_target.abi orelse Target.Abi.default(cpu.arch, os),
545+
.ofmt = cross_target.ofmt orelse Target.ObjectFormat.default(os.tag, cpu.arch),
542546
},
543547
.dynamic_linker = cross_target.dynamic_linker,
544548
};
@@ -829,6 +833,7 @@ fn defaultAbiAndDynamicLinker(cpu: Target.Cpu, os: Target.Os, cross_target: Cros
829833
.cpu = cpu,
830834
.os = os,
831835
.abi = cross_target.abi orelse Target.Abi.default(cpu.arch, os),
836+
.ofmt = cross_target.ofmt orelse Target.ObjectFormat.default(os.tag, cpu.arch),
832837
};
833838
return NativeTargetInfo{
834839
.target = target,

src/Compilation.zig

+15-15
Original file line numberDiff line numberDiff line change
@@ -810,7 +810,6 @@ pub const InitOptions = struct {
810810
/// this flag would be set to disable this machinery to avoid false positives.
811811
disable_lld_caching: bool = false,
812812
cache_mode: CacheMode = .incremental,
813-
object_format: ?std.Target.ObjectFormat = null,
814813
optimize_mode: std.builtin.Mode = .Debug,
815814
keep_source_files_loaded: bool = false,
816815
clang_argv: []const []const u8 = &[0][]const u8{},
@@ -1027,8 +1026,6 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation {
10271026
const comp = try arena.create(Compilation);
10281027
const root_name = try arena.dupeZ(u8, options.root_name);
10291028

1030-
const ofmt = options.object_format orelse options.target.getObjectFormat();
1031-
10321029
const use_stage1 = options.use_stage1 orelse blk: {
10331030
// Even though we may have no Zig code to compile (depending on `options.main_pkg`),
10341031
// 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 {
10421039
}
10431040

10441041
// 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))
10461043
break :blk false;
10471044

10481045
break :blk build_options.is_stage1;
@@ -1072,7 +1069,7 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation {
10721069
break :blk true;
10731070

10741071
// 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))
10761073
break :blk false;
10771074

10781075
// Prefer LLVM for release builds.
@@ -1115,7 +1112,7 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation {
11151112
if (!build_options.have_llvm)
11161113
break :blk false;
11171114

1118-
if (ofmt == .c)
1115+
if (options.target.ofmt == .c)
11191116
break :blk false;
11201117

11211118
if (options.want_lto) |lto| {
@@ -1374,7 +1371,7 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation {
13741371
cache.hash.add(options.target.os.getVersionRange());
13751372
cache.hash.add(options.is_native_os);
13761373
cache.hash.add(options.target.abi);
1377-
cache.hash.add(ofmt);
1374+
cache.hash.add(options.target.ofmt);
13781375
cache.hash.add(pic);
13791376
cache.hash.add(pie);
13801377
cache.hash.add(lto);
@@ -1682,7 +1679,6 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation {
16821679
.sysroot = sysroot,
16831680
.output_mode = options.output_mode,
16841681
.link_mode = link_mode,
1685-
.object_format = ofmt,
16861682
.optimize_mode = options.optimize_mode,
16871683
.use_lld = use_lld,
16881684
.use_llvm = use_llvm,
@@ -1841,7 +1837,9 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation {
18411837

18421838
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+
{
18451843
if (comp.getTarget().isDarwin()) {
18461844
switch (comp.getTarget().abi) {
18471845
.none,
@@ -3739,7 +3737,8 @@ fn updateCObject(comp: *Compilation, c_object: *CObject, c_obj_prog_node: *std.P
37393737
else
37403738
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);
37433742
const digest = if (!comp.disable_c_depfile and try man.hit()) man.final() else blk: {
37443743
var argv = std.ArrayList([]const u8).init(comp.gpa);
37453744
defer argv.deinit();
@@ -4092,7 +4091,7 @@ pub fn addCCArgs(
40924091

40934092
if (!comp.bin_file.options.strip) {
40944093
try argv.append("-g");
4095-
switch (comp.bin_file.options.object_format) {
4094+
switch (target.ofmt) {
40964095
.coff => try argv.append("-gcodeview"),
40974096
else => {},
40984097
}
@@ -4660,7 +4659,7 @@ fn wantBuildLibCFromSource(comp: Compilation) bool {
46604659
};
46614660
return comp.bin_file.options.link_libc and is_exe_or_dyn_lib and
46624661
comp.bin_file.options.libc_installation == null and
4663-
comp.bin_file.options.object_format != .c;
4662+
comp.bin_file.options.target.ofmt != .c;
46644663
}
46654664

46664665
fn wantBuildGLibCFromSource(comp: Compilation) bool {
@@ -4688,7 +4687,7 @@ fn wantBuildLibUnwindFromSource(comp: *Compilation) bool {
46884687
.Exe => true,
46894688
};
46904689
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;
46924691
}
46934692

46944693
fn setAllocFailure(comp: *Compilation) void {
@@ -4747,7 +4746,7 @@ pub fn generateBuiltinZigSource(comp: *Compilation, allocator: Allocator) Alloca
47474746
const zig_backend: std.builtin.CompilerBackend = blk: {
47484747
if (use_stage1) break :blk .stage1;
47494748
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;
47514750
break :blk switch (target.cpu.arch) {
47524751
.wasm32, .wasm64 => std.builtin.CompilerBackend.stage2_wasm,
47534752
.arm, .armeb, .thumb, .thumbeb => .stage2_arm,
@@ -4895,6 +4894,7 @@ pub fn generateBuiltinZigSource(comp: *Compilation, allocator: Allocator) Alloca
48954894
\\ .cpu = cpu,
48964895
\\ .os = os,
48974896
\\ .abi = abi,
4897+
\\ .ofmt = object_format,
48984898
\\}};
48994899
\\pub const object_format = std.Target.ObjectFormat.{};
49004900
\\pub const mode = std.builtin.Mode.{};
@@ -4909,7 +4909,7 @@ pub fn generateBuiltinZigSource(comp: *Compilation, allocator: Allocator) Alloca
49094909
\\pub const code_model = std.builtin.CodeModel.{};
49104910
\\
49114911
, .{
4912-
std.zig.fmtId(@tagName(comp.bin_file.options.object_format)),
4912+
std.zig.fmtId(@tagName(target.ofmt)),
49134913
std.zig.fmtId(@tagName(comp.bin_file.options.optimize_mode)),
49144914
link_libc,
49154915
comp.bin_file.options.link_libcpp,

src/Sema.zig

+1-1
Original file line numberDiff line numberDiff line change
@@ -20654,7 +20654,7 @@ fn panicWithMsg(
2065420654
const arena = sema.arena;
2065520655

2065620656
const this_feature_is_implemented_in_the_backend =
20657-
mod.comp.bin_file.options.object_format == .c or
20657+
mod.comp.bin_file.options.target.ofmt == .c or
2065820658
mod.comp.bin_file.options.use_llvm;
2065920659
if (!this_feature_is_implemented_in_the_backend) {
2066020660
// TODO implement this feature in all the backends and then delete this branch

src/codegen/llvm.zig

+1-1
Original file line numberDiff line numberDiff line change
@@ -273,7 +273,7 @@ pub const Object = struct {
273273
var di_compile_unit: ?*llvm.DICompileUnit = null;
274274

275275
if (!options.strip) {
276-
switch (options.object_format) {
276+
switch (options.target.ofmt) {
277277
.coff => llvm_module.addModuleCodeViewFlag(),
278278
else => llvm_module.addModuleDebugInfoFlag(),
279279
}

src/link.zig

+5-6
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,6 @@ pub const Options = struct {
7272
target: std.Target,
7373
output_mode: std.builtin.OutputMode,
7474
link_mode: std.builtin.LinkMode,
75-
object_format: std.Target.ObjectFormat,
7675
optimize_mode: std.builtin.Mode,
7776
machine_code_model: std.builtin.CodeModel,
7877
root_name: [:0]const u8,
@@ -273,13 +272,13 @@ pub const File = struct {
273272
/// rewriting it. A malicious file is detected as incremental link failure
274273
/// and does not cause Illegal Behavior. This operation is not atomic.
275274
pub fn openPath(allocator: Allocator, options: Options) !*File {
276-
if (options.object_format == .macho) {
275+
if (options.target.ofmt == .macho) {
277276
return &(try MachO.openPath(allocator, options)).base;
278277
}
279278

280279
const use_stage1 = build_options.is_stage1 and options.use_stage1;
281280
if (use_stage1 or options.emit == null) {
282-
return switch (options.object_format) {
281+
return switch (options.target.ofmt) {
283282
.coff => &(try Coff.createEmpty(allocator, options)).base,
284283
.elf => &(try Elf.createEmpty(allocator, options)).base,
285284
.macho => unreachable,
@@ -298,7 +297,7 @@ pub const File = struct {
298297
if (options.module == null) {
299298
// No point in opening a file, we would not write anything to it.
300299
// Initialize with empty.
301-
return switch (options.object_format) {
300+
return switch (options.target.ofmt) {
302301
.coff => &(try Coff.createEmpty(allocator, options)).base,
303302
.elf => &(try Elf.createEmpty(allocator, options)).base,
304303
.macho => unreachable,
@@ -314,12 +313,12 @@ pub const File = struct {
314313
// Open a temporary object file, not the final output file because we
315314
// want to link with LLD.
316315
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),
318317
});
319318
} else emit.sub_path;
320319
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) {
323322
.coff => &(try Coff.openPath(allocator, sub_path, options)).base,
324323
.elf => &(try Elf.openPath(allocator, sub_path, options)).base,
325324
.macho => unreachable,

src/link/C.zig

+1-1
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ const DeclBlock = struct {
4848
};
4949

5050
pub 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

5353
if (options.use_llvm) return error.LLVMHasNoCBackend;
5454
if (options.use_lld) return error.LLDHasNoCBackend;

src/link/Coff.zig

+1-1
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ pub const TextBlock = struct {
128128
pub const SrcFn = void;
129129

130130
pub 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

133133
if (build_options.have_llvm and options.use_llvm) {
134134
return createEmpty(allocator, options);

0 commit comments

Comments
 (0)