authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-12-04 12:35:04-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2024-01-01 17:51:18-07:00
log3179f58c414b5e4845b9bf3acdf276fe8e2b88a0
tree23d8f051385f7948aa8c97ece358fdbe35b86803
parent67d48b94d601521e15dd44c8789b1f528d09f10c

rename std.zig.CrossTarget to std.Target.Query


25 files changed, 997 insertions(+), 1004 deletions(-)

CMakeLists.txt+1-1
...@@ -481,6 +481,7 @@ set(ZIG_STAGE2_SOURCES...@@ -481,6 +481,7 @@ set(ZIG_STAGE2_SOURCES
481 "${CMAKE_SOURCE_DIR}/lib/std/start.zig"481 "${CMAKE_SOURCE_DIR}/lib/std/start.zig"
482 "${CMAKE_SOURCE_DIR}/lib/std/std.zig"482 "${CMAKE_SOURCE_DIR}/lib/std/std.zig"
483 "${CMAKE_SOURCE_DIR}/lib/std/Target.zig"483 "${CMAKE_SOURCE_DIR}/lib/std/Target.zig"
484 "${CMAKE_SOURCE_DIR}/lib/std/Target/Query.zig"
484 "${CMAKE_SOURCE_DIR}/lib/std/Target/aarch64.zig"485 "${CMAKE_SOURCE_DIR}/lib/std/Target/aarch64.zig"
485 "${CMAKE_SOURCE_DIR}/lib/std/Target/amdgpu.zig"486 "${CMAKE_SOURCE_DIR}/lib/std/Target/amdgpu.zig"
486 "${CMAKE_SOURCE_DIR}/lib/std/Target/arm.zig"487 "${CMAKE_SOURCE_DIR}/lib/std/Target/arm.zig"
...@@ -508,7 +509,6 @@ set(ZIG_STAGE2_SOURCES...@@ -508,7 +509,6 @@ set(ZIG_STAGE2_SOURCES
508 "${CMAKE_SOURCE_DIR}/lib/std/zig.zig"509 "${CMAKE_SOURCE_DIR}/lib/std/zig.zig"
509 "${CMAKE_SOURCE_DIR}/lib/std/zig/Ast.zig"510 "${CMAKE_SOURCE_DIR}/lib/std/zig/Ast.zig"
510 "${CMAKE_SOURCE_DIR}/lib/std/zig/AstRlAnnotate.zig"511 "${CMAKE_SOURCE_DIR}/lib/std/zig/AstRlAnnotate.zig"
511 "${CMAKE_SOURCE_DIR}/lib/std/zig/CrossTarget.zig"
512 "${CMAKE_SOURCE_DIR}/lib/std/zig/c_builtins.zig"512 "${CMAKE_SOURCE_DIR}/lib/std/zig/c_builtins.zig"
513 "${CMAKE_SOURCE_DIR}/lib/std/zig/Parse.zig"513 "${CMAKE_SOURCE_DIR}/lib/std/zig/Parse.zig"
514 "${CMAKE_SOURCE_DIR}/lib/std/zig/render.zig"514 "${CMAKE_SOURCE_DIR}/lib/std/zig/render.zig"
lib/std/Build.zig+19-19
...@@ -10,11 +10,11 @@ const log = std.log;...@@ -10,11 +10,11 @@ const log = std.log;
10const ArrayList = std.ArrayList;10const ArrayList = std.ArrayList;
11const StringHashMap = std.StringHashMap;11const StringHashMap = std.StringHashMap;
12const Allocator = mem.Allocator;12const Allocator = mem.Allocator;
13const Target = std.Target;
13const process = std.process;14const process = std.process;
14const EnvMap = std.process.EnvMap;15const EnvMap = std.process.EnvMap;
15const fmt_lib = std.fmt;16const fmt_lib = std.fmt;
16const File = std.fs.File;17const File = std.fs.File;
17const TargetQuery = std.zig.CrossTarget;
18const Sha256 = std.crypto.hash.sha2.Sha256;18const Sha256 = std.crypto.hash.sha2.Sha256;
19const Build = @This();19const Build = @This();
2020
...@@ -375,7 +375,7 @@ fn userInputOptionsFromArgs(allocator: Allocator, args: anytype) UserInputOption...@@ -375,7 +375,7 @@ fn userInputOptionsFromArgs(allocator: Allocator, args: anytype) UserInputOption
375 const v = @field(args, field.name);375 const v = @field(args, field.name);
376 const T = @TypeOf(v);376 const T = @TypeOf(v);
377 switch (T) {377 switch (T) {
378 TargetQuery => {378 Target.Query => {
379 user_input_options.put(field.name, .{379 user_input_options.put(field.name, .{
380 .name = field.name,380 .name = field.name,
381 .value = .{ .scalar = v.zigTriple(allocator) catch @panic("OOM") },381 .value = .{ .scalar = v.zigTriple(allocator) catch @panic("OOM") },
...@@ -1195,9 +1195,9 @@ pub fn standardOptimizeOption(self: *Build, options: StandardOptimizeOptionOptio...@@ -1195,9 +1195,9 @@ pub fn standardOptimizeOption(self: *Build, options: StandardOptimizeOptionOptio
1195}1195}
11961196
1197pub const StandardTargetOptionsArgs = struct {1197pub const StandardTargetOptionsArgs = struct {
1198 whitelist: ?[]const TargetQuery = null,1198 whitelist: ?[]const Target.Query = null,
11991199
1200 default_target: TargetQuery = .{},1200 default_target: Target.Query = .{},
1201};1201};
12021202
1203/// Exposes standard `zig build` options for choosing a target and additionally1203/// Exposes standard `zig build` options for choosing a target and additionally
...@@ -1208,7 +1208,7 @@ pub fn standardTargetOptions(b: *Build, args: StandardTargetOptionsArgs) Resolve...@@ -1208,7 +1208,7 @@ pub fn standardTargetOptions(b: *Build, args: StandardTargetOptionsArgs) Resolve
1208}1208}
12091209
1210/// Exposes standard `zig build` options for choosing a target.1210/// Exposes standard `zig build` options for choosing a target.
1211pub fn standardTargetOptionsQueryOnly(self: *Build, args: StandardTargetOptionsArgs) TargetQuery {1211pub fn standardTargetOptionsQueryOnly(self: *Build, args: StandardTargetOptionsArgs) Target.Query {
1212 const maybe_triple = self.option(1212 const maybe_triple = self.option(
1213 []const u8,1213 []const u8,
1214 "target",1214 "target",
...@@ -1222,8 +1222,8 @@ pub fn standardTargetOptionsQueryOnly(self: *Build, args: StandardTargetOptionsA...@@ -1222,8 +1222,8 @@ pub fn standardTargetOptionsQueryOnly(self: *Build, args: StandardTargetOptionsA
12221222
1223 const triple = maybe_triple orelse "native";1223 const triple = maybe_triple orelse "native";
12241224
1225 var diags: TargetQuery.ParseOptions.Diagnostics = .{};1225 var diags: Target.Query.ParseOptions.Diagnostics = .{};
1226 const selected_target = TargetQuery.parse(.{1226 const selected_target = Target.Query.parse(.{
1227 .arch_os_abi = triple,1227 .arch_os_abi = triple,
1228 .cpu_features = mcpu,1228 .cpu_features = mcpu,
1229 .diagnostics = &diags,1229 .diagnostics = &diags,
...@@ -1260,7 +1260,7 @@ pub fn standardTargetOptionsQueryOnly(self: *Build, args: StandardTargetOptionsA...@@ -1260,7 +1260,7 @@ pub fn standardTargetOptionsQueryOnly(self: *Build, args: StandardTargetOptionsA
1260 \\Available operating systems:1260 \\Available operating systems:
1261 \\1261 \\
1262 , .{diags.os_name.?});1262 , .{diags.os_name.?});
1263 inline for (std.meta.fields(std.Target.Os.Tag)) |field| {1263 inline for (std.meta.fields(Target.Os.Tag)) |field| {
1264 log.err(" {s}", .{field.name});1264 log.err(" {s}", .{field.name});
1265 }1265 }
1266 self.markInvalidUserInput();1266 self.markInvalidUserInput();
...@@ -1279,7 +1279,7 @@ pub fn standardTargetOptionsQueryOnly(self: *Build, args: StandardTargetOptionsA...@@ -1279,7 +1279,7 @@ pub fn standardTargetOptionsQueryOnly(self: *Build, args: StandardTargetOptionsA
1279 // Make sure it's a match of one of the list.1279 // Make sure it's a match of one of the list.
1280 var mismatch_triple = true;1280 var mismatch_triple = true;
1281 var mismatch_cpu_features = true;1281 var mismatch_cpu_features = true;
1282 var whitelist_item: TargetQuery = .{};1282 var whitelist_item: Target.Query = .{};
1283 for (list) |t| {1283 for (list) |t| {
1284 mismatch_cpu_features = true;1284 mismatch_cpu_features = true;
1285 mismatch_triple = true;1285 mismatch_triple = true;
...@@ -1316,7 +1316,7 @@ pub fn standardTargetOptionsQueryOnly(self: *Build, args: StandardTargetOptionsA...@@ -1316,7 +1316,7 @@ pub fn standardTargetOptionsQueryOnly(self: *Build, args: StandardTargetOptionsA
1316 var populated_cpu_features = whitelist_cpu.model.features;1316 var populated_cpu_features = whitelist_cpu.model.features;
1317 populated_cpu_features.populateDependencies(all_features);1317 populated_cpu_features.populateDependencies(all_features);
1318 for (all_features, 0..) |feature, i_usize| {1318 for (all_features, 0..) |feature, i_usize| {
1319 const i = @as(std.Target.Cpu.Feature.Set.Index, @intCast(i_usize));1319 const i = @as(Target.Cpu.Feature.Set.Index, @intCast(i_usize));
1320 const in_cpu_set = populated_cpu_features.isEnabled(i);1320 const in_cpu_set = populated_cpu_features.isEnabled(i);
1321 if (in_cpu_set) {1321 if (in_cpu_set) {
1322 log.err("{s} ", .{feature.name});1322 log.err("{s} ", .{feature.name});
...@@ -1324,7 +1324,7 @@ pub fn standardTargetOptionsQueryOnly(self: *Build, args: StandardTargetOptionsA...@@ -1324,7 +1324,7 @@ pub fn standardTargetOptionsQueryOnly(self: *Build, args: StandardTargetOptionsA
1324 }1324 }
1325 log.err(" Remove: ", .{});1325 log.err(" Remove: ", .{});
1326 for (all_features, 0..) |feature, i_usize| {1326 for (all_features, 0..) |feature, i_usize| {
1327 const i = @as(std.Target.Cpu.Feature.Set.Index, @intCast(i_usize));1327 const i = @as(Target.Cpu.Feature.Set.Index, @intCast(i_usize));
1328 const in_cpu_set = populated_cpu_features.isEnabled(i);1328 const in_cpu_set = populated_cpu_features.isEnabled(i);
1329 const in_actual_set = selected_cpu.features.isEnabled(i);1329 const in_actual_set = selected_cpu.features.isEnabled(i);
1330 if (in_actual_set and !in_cpu_set) {1330 if (in_actual_set and !in_cpu_set) {
...@@ -1587,7 +1587,7 @@ pub fn fmt(self: *Build, comptime format: []const u8, args: anytype) []u8 {...@@ -1587,7 +1587,7 @@ pub fn fmt(self: *Build, comptime format: []const u8, args: anytype) []u8 {
15871587
1588pub fn findProgram(self: *Build, names: []const []const u8, paths: []const []const u8) ![]const u8 {1588pub fn findProgram(self: *Build, names: []const []const u8, paths: []const []const u8) ![]const u8 {
1589 // TODO report error for ambiguous situations1589 // TODO report error for ambiguous situations
1590 const exe_extension = @as(TargetQuery, .{}).exeFileExt();1590 const exe_extension = @as(Target.Query, .{}).exeFileExt();
1591 for (self.search_prefixes.items) |search_prefix| {1591 for (self.search_prefixes.items) |search_prefix| {
1592 for (names) |name| {1592 for (names) |name| {
1593 if (fs.path.isAbsolute(name)) {1593 if (fs.path.isAbsolute(name)) {
...@@ -2064,7 +2064,7 @@ pub const InstalledFile = struct {...@@ -2064,7 +2064,7 @@ pub const InstalledFile = struct {
2064 }2064 }
2065};2065};
20662066
2067pub fn serializeCpu(allocator: Allocator, cpu: std.Target.Cpu) ![]const u8 {2067pub fn serializeCpu(allocator: Allocator, cpu: Target.Cpu) ![]const u8 {
2068 // TODO this logic can disappear if cpu model + features becomes part of the target triple2068 // TODO this logic can disappear if cpu model + features becomes part of the target triple
2069 const all_features = cpu.arch.allFeaturesList();2069 const all_features = cpu.arch.allFeaturesList();
2070 var populated_cpu_features = cpu.model.features;2070 var populated_cpu_features = cpu.model.features;
...@@ -2078,7 +2078,7 @@ pub fn serializeCpu(allocator: Allocator, cpu: std.Target.Cpu) ![]const u8 {...@@ -2078,7 +2078,7 @@ pub fn serializeCpu(allocator: Allocator, cpu: std.Target.Cpu) ![]const u8 {
2078 try mcpu_buffer.appendSlice(cpu.model.name);2078 try mcpu_buffer.appendSlice(cpu.model.name);
20792079
2080 for (all_features, 0..) |feature, i_usize| {2080 for (all_features, 0..) |feature, i_usize| {
2081 const i = @as(std.Target.Cpu.Feature.Set.Index, @intCast(i_usize));2081 const i = @as(Target.Cpu.Feature.Set.Index, @intCast(i_usize));
2082 const in_cpu_set = populated_cpu_features.isEnabled(i);2082 const in_cpu_set = populated_cpu_features.isEnabled(i);
2083 const in_actual_set = cpu.features.isEnabled(i);2083 const in_actual_set = cpu.features.isEnabled(i);
2084 if (in_cpu_set and !in_actual_set) {2084 if (in_cpu_set and !in_actual_set) {
...@@ -2127,9 +2127,9 @@ pub fn hex64(x: u64) [16]u8 {...@@ -2127,9 +2127,9 @@ pub fn hex64(x: u64) [16]u8 {
2127/// target. The query is kept because the Zig toolchain needs to know which parts2127/// target. The query is kept because the Zig toolchain needs to know which parts
2128/// of the target are "native". This can apply to the CPU, the OS, or even the ABI.2128/// of the target are "native". This can apply to the CPU, the OS, or even the ABI.
2129pub const ResolvedTarget = struct {2129pub const ResolvedTarget = struct {
2130 query: TargetQuery,2130 query: Target.Query,
2131 target: std.Target,2131 target: Target,
2132 dynamic_linker: std.Target.DynamicLinker,2132 dynamic_linker: Target.DynamicLinker,
21332133
2134 pub fn toNativeTargetInfo(self: ResolvedTarget) std.zig.system.NativeTargetInfo {2134 pub fn toNativeTargetInfo(self: ResolvedTarget) std.zig.system.NativeTargetInfo {
2135 return .{2135 return .{
...@@ -2141,7 +2141,7 @@ pub const ResolvedTarget = struct {...@@ -2141,7 +2141,7 @@ pub const ResolvedTarget = struct {
21412141
2142/// Converts a target query into a fully resolved target that can be passed to2142/// Converts a target query into a fully resolved target that can be passed to
2143/// various parts of the API.2143/// various parts of the API.
2144pub fn resolveTargetQuery(b: *Build, query: TargetQuery) ResolvedTarget {2144pub fn resolveTargetQuery(b: *Build, query: Target.Query) ResolvedTarget {
2145 // This context will likely be required in the future when the target is2145 // This context will likely be required in the future when the target is
2146 // resolved via a WASI API or via the build protocol.2146 // resolved via a WASI API or via the build protocol.
2147 _ = b;2147 _ = b;
...@@ -2156,7 +2156,7 @@ pub fn resolveTargetQuery(b: *Build, query: TargetQuery) ResolvedTarget {...@@ -2156,7 +2156,7 @@ pub fn resolveTargetQuery(b: *Build, query: TargetQuery) ResolvedTarget {
2156 };2156 };
2157}2157}
21582158
2159pub fn wantSharedLibSymLinks(target: std.Target) bool {2159pub fn wantSharedLibSymLinks(target: Target) bool {
2160 return target.os.tag != .windows;2160 return target.os.tag != .windows;
2161}2161}
21622162
lib/std/Build/Step/Compile.zig-1
...@@ -9,7 +9,6 @@ const StringHashMap = std.StringHashMap;...@@ -9,7 +9,6 @@ const StringHashMap = std.StringHashMap;
9const Sha256 = std.crypto.hash.sha2.Sha256;9const Sha256 = std.crypto.hash.sha2.Sha256;
10const Allocator = mem.Allocator;10const Allocator = mem.Allocator;
11const Step = std.Build.Step;11const Step = std.Build.Step;
12const CrossTarget = std.zig.CrossTarget;
13const NativeTargetInfo = std.zig.system.NativeTargetInfo;12const NativeTargetInfo = std.zig.system.NativeTargetInfo;
14const LazyPath = std.Build.LazyPath;13const LazyPath = std.Build.LazyPath;
15const PkgConfigPkg = std.Build.PkgConfigPkg;14const PkgConfigPkg = std.Build.PkgConfigPkg;
lib/std/Target.zig+3-1
...@@ -3,6 +3,8 @@ os: Os,...@@ -3,6 +3,8 @@ os: Os,
3abi: Abi,3abi: Abi,
4ofmt: ObjectFormat,4ofmt: ObjectFormat,
55
6pub const Query = @import("Target/Query.zig");
7
6pub const Os = struct {8pub const Os = struct {
7 tag: Tag,9 tag: Tag,
8 version_range: VersionRange,10 version_range: VersionRange,
...@@ -1387,7 +1389,7 @@ pub const Cpu = struct {...@@ -1387,7 +1389,7 @@ pub const Cpu = struct {
1387};1389};
13881390
1389pub fn zigTriple(self: Target, allocator: Allocator) ![]u8 {1391pub fn zigTriple(self: Target, allocator: Allocator) ![]u8 {
1390 return std.zig.CrossTarget.fromTarget(self).zigTriple(allocator);1392 return Query.fromTarget(self).zigTriple(allocator);
1391}1393}
13921394
1393pub fn linuxTripleSimple(allocator: Allocator, cpu_arch: Cpu.Arch, os_tag: Os.Tag, abi: Abi) ![]u8 {1395pub fn linuxTripleSimple(allocator: Allocator, cpu_arch: Cpu.Arch, os_tag: Os.Tag, abi: Abi) ![]u8 {
lib/std/Target/Query.zig created+855
...@@ -0,0 +1,855 @@
1//! Contains all the same data as `Target`, additionally introducing the
2//! concept of "the native target". The purpose of this abstraction is to
3//! provide meaningful and unsurprising defaults. This struct does reference
4//! any resources and it is copyable.
5
6/// `null` means native.
7cpu_arch: ?Target.Cpu.Arch = null,
8
9cpu_model: CpuModel = CpuModel.determined_by_cpu_arch,
10
11/// Sparse set of CPU features to add to the set from `cpu_model`.
12cpu_features_add: Target.Cpu.Feature.Set = Target.Cpu.Feature.Set.empty,
13
14/// Sparse set of CPU features to remove from the set from `cpu_model`.
15cpu_features_sub: Target.Cpu.Feature.Set = Target.Cpu.Feature.Set.empty,
16
17/// `null` means native.
18os_tag: ?Target.Os.Tag = null,
19
20/// `null` means the default version range for `os_tag`. If `os_tag` is `null` (native)
21/// then `null` for this field means native.
22os_version_min: ?OsVersion = null,
23
24/// When cross compiling, `null` means default (latest known OS version).
25/// When `os_tag` is native, `null` means equal to the native OS version.
26os_version_max: ?OsVersion = null,
27
28/// `null` means default when cross compiling, or native when os_tag is native.
29/// If `isGnuLibC()` is `false`, this must be `null` and is ignored.
30glibc_version: ?SemanticVersion = null,
31
32/// `null` means the native C ABI, if `os_tag` is native, otherwise it means the default C ABI.
33abi: ?Target.Abi = null,
34
35/// When `os_tag` is `null`, then `null` means native. Otherwise it means the standard path
36/// based on the `os_tag`.
37dynamic_linker: DynamicLinker = DynamicLinker{},
38
39/// `null` means default for the cpu/arch/os combo.
40ofmt: ?Target.ObjectFormat = null,
41
42pub const CpuModel = union(enum) {
43 /// Always native
44 native,
45
46 /// Always baseline
47 baseline,
48
49 /// If CPU Architecture is native, then the CPU model will be native. Otherwise,
50 /// it will be baseline.
51 determined_by_cpu_arch,
52
53 explicit: *const Target.Cpu.Model,
54};
55
56pub const OsVersion = union(enum) {
57 none: void,
58 semver: SemanticVersion,
59 windows: Target.Os.WindowsVersion,
60};
61
62pub const SemanticVersion = std.SemanticVersion;
63
64pub const DynamicLinker = Target.DynamicLinker;
65
66pub fn fromTarget(target: Target) Query {
67 var result: Query = .{
68 .cpu_arch = target.cpu.arch,
69 .cpu_model = .{ .explicit = target.cpu.model },
70 .os_tag = target.os.tag,
71 .os_version_min = undefined,
72 .os_version_max = undefined,
73 .abi = target.abi,
74 .glibc_version = if (target.isGnuLibC())
75 target.os.version_range.linux.glibc
76 else
77 null,
78 };
79 result.updateOsVersionRange(target.os);
80
81 const all_features = target.cpu.arch.allFeaturesList();
82 var cpu_model_set = target.cpu.model.features;
83 cpu_model_set.populateDependencies(all_features);
84 {
85 // The "add" set is the full set with the CPU Model set removed.
86 const add_set = &result.cpu_features_add;
87 add_set.* = target.cpu.features;
88 add_set.removeFeatureSet(cpu_model_set);
89 }
90 {
91 // The "sub" set is the features that are on in CPU Model set and off in the full set.
92 const sub_set = &result.cpu_features_sub;
93 sub_set.* = cpu_model_set;
94 sub_set.removeFeatureSet(target.cpu.features);
95 }
96 return result;
97}
98
99fn updateOsVersionRange(self: *Query, os: Target.Os) void {
100 switch (os.tag) {
101 .freestanding,
102 .ananas,
103 .cloudabi,
104 .fuchsia,
105 .kfreebsd,
106 .lv2,
107 .solaris,
108 .illumos,
109 .zos,
110 .haiku,
111 .minix,
112 .rtems,
113 .nacl,
114 .aix,
115 .cuda,
116 .nvcl,
117 .amdhsa,
118 .ps4,
119 .ps5,
120 .elfiamcu,
121 .mesa3d,
122 .contiki,
123 .amdpal,
124 .hermit,
125 .hurd,
126 .wasi,
127 .emscripten,
128 .driverkit,
129 .shadermodel,
130 .liteos,
131 .uefi,
132 .opencl,
133 .glsl450,
134 .vulkan,
135 .plan9,
136 .other,
137 => {
138 self.os_version_min = .{ .none = {} };
139 self.os_version_max = .{ .none = {} };
140 },
141
142 .freebsd,
143 .macos,
144 .ios,
145 .tvos,
146 .watchos,
147 .netbsd,
148 .openbsd,
149 .dragonfly,
150 => {
151 self.os_version_min = .{ .semver = os.version_range.semver.min };
152 self.os_version_max = .{ .semver = os.version_range.semver.max };
153 },
154
155 .linux => {
156 self.os_version_min = .{ .semver = os.version_range.linux.range.min };
157 self.os_version_max = .{ .semver = os.version_range.linux.range.max };
158 },
159
160 .windows => {
161 self.os_version_min = .{ .windows = os.version_range.windows.min };
162 self.os_version_max = .{ .windows = os.version_range.windows.max };
163 },
164 }
165}
166
167/// TODO deprecated, use `std.zig.system.NativeTargetInfo.detect`.
168pub fn toTarget(self: Query) Target {
169 return .{
170 .cpu = self.getCpu(),
171 .os = self.getOs(),
172 .abi = self.getAbi(),
173 .ofmt = self.getObjectFormat(),
174 };
175}
176
177pub const ParseOptions = struct {
178 /// This is sometimes called a "triple". It looks roughly like this:
179 /// riscv64-linux-musl
180 /// The fields are, respectively:
181 /// * CPU Architecture
182 /// * Operating System (and optional version range)
183 /// * C ABI (optional, with optional glibc version)
184 /// The string "native" can be used for CPU architecture as well as Operating System.
185 /// If the CPU Architecture is specified as "native", then the Operating System and C ABI may be omitted.
186 arch_os_abi: []const u8 = "native",
187
188 /// Looks like "name+a+b-c-d+e", where "name" is a CPU Model name, "a", "b", and "e"
189 /// are examples of CPU features to add to the set, and "c" and "d" are examples of CPU features
190 /// to remove from the set.
191 /// The following special strings are recognized for CPU Model name:
192 /// * "baseline" - The "default" set of CPU features for cross-compiling. A conservative set
193 /// of features that is expected to be supported on most available hardware.
194 /// * "native" - The native CPU model is to be detected when compiling.
195 /// If this field is not provided (`null`), then the value will depend on the
196 /// parsed CPU Architecture. If native, then this will be "native". Otherwise, it will be "baseline".
197 cpu_features: ?[]const u8 = null,
198
199 /// Absolute path to dynamic linker, to override the default, which is either a natively
200 /// detected path, or a standard path.
201 dynamic_linker: ?[]const u8 = null,
202
203 object_format: ?[]const u8 = null,
204
205 /// If this is provided, the function will populate some information about parsing failures,
206 /// so that user-friendly error messages can be delivered.
207 diagnostics: ?*Diagnostics = null,
208
209 pub const Diagnostics = struct {
210 /// If the architecture was determined, this will be populated.
211 arch: ?Target.Cpu.Arch = null,
212
213 /// If the OS name was determined, this will be populated.
214 os_name: ?[]const u8 = null,
215
216 /// If the OS tag was determined, this will be populated.
217 os_tag: ?Target.Os.Tag = null,
218
219 /// If the ABI was determined, this will be populated.
220 abi: ?Target.Abi = null,
221
222 /// If the CPU name was determined, this will be populated.
223 cpu_name: ?[]const u8 = null,
224
225 /// If error.UnknownCpuFeature is returned, this will be populated.
226 unknown_feature_name: ?[]const u8 = null,
227 };
228};
229
230pub fn parse(args: ParseOptions) !Query {
231 var dummy_diags: ParseOptions.Diagnostics = undefined;
232 const diags = args.diagnostics orelse &dummy_diags;
233
234 var result: Query = .{
235 .dynamic_linker = DynamicLinker.init(args.dynamic_linker),
236 };
237
238 var it = mem.splitScalar(u8, args.arch_os_abi, '-');
239 const arch_name = it.first();
240 const arch_is_native = mem.eql(u8, arch_name, "native");
241 if (!arch_is_native) {
242 result.cpu_arch = std.meta.stringToEnum(Target.Cpu.Arch, arch_name) orelse
243 return error.UnknownArchitecture;
244 }
245 const arch = result.getCpuArch();
246 diags.arch = arch;
247
248 if (it.next()) |os_text| {
249 try parseOs(&result, diags, os_text);
250 } else if (!arch_is_native) {
251 return error.MissingOperatingSystem;
252 }
253
254 const opt_abi_text = it.next();
255 if (opt_abi_text) |abi_text| {
256 var abi_it = mem.splitScalar(u8, abi_text, '.');
257 const abi = std.meta.stringToEnum(Target.Abi, abi_it.first()) orelse
258 return error.UnknownApplicationBinaryInterface;
259 result.abi = abi;
260 diags.abi = abi;
261
262 const abi_ver_text = abi_it.rest();
263 if (abi_it.next() != null) {
264 if (result.isGnuLibC()) {
265 result.glibc_version = parseVersion(abi_ver_text) catch |err| switch (err) {
266 error.Overflow => return error.InvalidAbiVersion,
267 error.InvalidVersion => return error.InvalidAbiVersion,
268 };
269 } else {
270 return error.InvalidAbiVersion;
271 }
272 }
273 }
274
275 if (it.next() != null) return error.UnexpectedExtraField;
276
277 if (args.cpu_features) |cpu_features| {
278 const all_features = arch.allFeaturesList();
279 var index: usize = 0;
280 while (index < cpu_features.len and
281 cpu_features[index] != '+' and
282 cpu_features[index] != '-')
283 {
284 index += 1;
285 }
286 const cpu_name = cpu_features[0..index];
287 diags.cpu_name = cpu_name;
288
289 const add_set = &result.cpu_features_add;
290 const sub_set = &result.cpu_features_sub;
291 if (mem.eql(u8, cpu_name, "native")) {
292 result.cpu_model = .native;
293 } else if (mem.eql(u8, cpu_name, "baseline")) {
294 result.cpu_model = .baseline;
295 } else {
296 result.cpu_model = .{ .explicit = try arch.parseCpuModel(cpu_name) };
297 }
298
299 while (index < cpu_features.len) {
300 const op = cpu_features[index];
301 const set = switch (op) {
302 '+' => add_set,
303 '-' => sub_set,
304 else => unreachable,
305 };
306 index += 1;
307 const start = index;
308 while (index < cpu_features.len and
309 cpu_features[index] != '+' and
310 cpu_features[index] != '-')
311 {
312 index += 1;
313 }
314 const feature_name = cpu_features[start..index];
315 for (all_features, 0..) |feature, feat_index_usize| {
316 const feat_index = @as(Target.Cpu.Feature.Set.Index, @intCast(feat_index_usize));
317 if (mem.eql(u8, feature_name, feature.name)) {
318 set.addFeature(feat_index);
319 break;
320 }
321 } else {
322 diags.unknown_feature_name = feature_name;
323 return error.UnknownCpuFeature;
324 }
325 }
326 }
327
328 if (args.object_format) |ofmt_name| {
329 result.ofmt = std.meta.stringToEnum(Target.ObjectFormat, ofmt_name) orelse
330 return error.UnknownObjectFormat;
331 }
332
333 return result;
334}
335
336/// Similar to `parse` except instead of fully parsing, it only determines the CPU
337/// architecture and returns it if it can be determined, and returns `null` otherwise.
338/// This is intended to be used if the API user of Query needs to learn the
339/// target CPU architecture in order to fully populate `ParseOptions`.
340pub fn parseCpuArch(args: ParseOptions) ?Target.Cpu.Arch {
341 var it = mem.splitScalar(u8, args.arch_os_abi, '-');
342 const arch_name = it.first();
343 const arch_is_native = mem.eql(u8, arch_name, "native");
344 if (arch_is_native) {
345 return builtin.cpu.arch;
346 } else {
347 return std.meta.stringToEnum(Target.Cpu.Arch, arch_name);
348 }
349}
350
351/// Similar to `SemanticVersion.parse`, but with following changes:
352/// * Leading zeroes are allowed.
353/// * Supports only 2 or 3 version components (major, minor, [patch]). If 3-rd component is omitted, it will be 0.
354pub fn parseVersion(ver: []const u8) error{ InvalidVersion, Overflow }!SemanticVersion {
355 const parseVersionComponentFn = (struct {
356 fn parseVersionComponentInner(component: []const u8) error{ InvalidVersion, Overflow }!usize {
357 return std.fmt.parseUnsigned(usize, component, 10) catch |err| switch (err) {
358 error.InvalidCharacter => return error.InvalidVersion,
359 error.Overflow => return error.Overflow,
360 };
361 }
362 }).parseVersionComponentInner;
363 var version_components = mem.splitScalar(u8, ver, '.');
364 const major = version_components.first();
365 const minor = version_components.next() orelse return error.InvalidVersion;
366 const patch = version_components.next() orelse "0";
367 if (version_components.next() != null) return error.InvalidVersion;
368 return .{
369 .major = try parseVersionComponentFn(major),
370 .minor = try parseVersionComponentFn(minor),
371 .patch = try parseVersionComponentFn(patch),
372 };
373}
374
375test parseVersion {
376 try std.testing.expectError(error.InvalidVersion, parseVersion("1"));
377 try std.testing.expectEqual(SemanticVersion{ .major = 1, .minor = 2, .patch = 0 }, try parseVersion("1.2"));
378 try std.testing.expectEqual(SemanticVersion{ .major = 1, .minor = 2, .patch = 3 }, try parseVersion("1.2.3"));
379 try std.testing.expectError(error.InvalidVersion, parseVersion("1.2.3.4"));
380}
381
382/// TODO deprecated, use `std.zig.system.NativeTargetInfo.detect`.
383pub fn getCpu(self: Query) Target.Cpu {
384 switch (self.cpu_model) {
385 .native => {
386 // This works when doing `zig build` because Zig generates a build executable using
387 // native CPU model & features. However this will not be accurate otherwise, and
388 // will need to be integrated with `std.zig.system.NativeTargetInfo.detect`.
389 return builtin.cpu;
390 },
391 .baseline => {
392 var adjusted_baseline = Target.Cpu.baseline(self.getCpuArch());
393 self.updateCpuFeatures(&adjusted_baseline.features);
394 return adjusted_baseline;
395 },
396 .determined_by_cpu_arch => if (self.cpu_arch == null) {
397 // This works when doing `zig build` because Zig generates a build executable using
398 // native CPU model & features. However this will not be accurate otherwise, and
399 // will need to be integrated with `std.zig.system.NativeTargetInfo.detect`.
400 return builtin.cpu;
401 } else {
402 var adjusted_baseline = Target.Cpu.baseline(self.getCpuArch());
403 self.updateCpuFeatures(&adjusted_baseline.features);
404 return adjusted_baseline;
405 },
406 .explicit => |model| {
407 var adjusted_model = model.toCpu(self.getCpuArch());
408 self.updateCpuFeatures(&adjusted_model.features);
409 return adjusted_model;
410 },
411 }
412}
413
414pub fn getCpuArch(self: Query) Target.Cpu.Arch {
415 return self.cpu_arch orelse builtin.cpu.arch;
416}
417
418pub fn getCpuModel(self: Query) *const Target.Cpu.Model {
419 return switch (self.cpu_model) {
420 .explicit => |cpu_model| cpu_model,
421 else => self.getCpu().model,
422 };
423}
424
425pub fn getCpuFeatures(self: Query) Target.Cpu.Feature.Set {
426 return self.getCpu().features;
427}
428
429/// TODO deprecated, use `std.zig.system.NativeTargetInfo.detect`.
430pub fn getOs(self: Query) Target.Os {
431 // `builtin.os` works when doing `zig build` because Zig generates a build executable using
432 // native OS version range. However this will not be accurate otherwise, and
433 // will need to be integrated with `std.zig.system.NativeTargetInfo.detect`.
434 var adjusted_os = if (self.os_tag) |os_tag| os_tag.defaultVersionRange(self.getCpuArch()) else builtin.os;
435
436 if (self.os_version_min) |min| switch (min) {
437 .none => {},
438 .semver => |semver| switch (self.getOsTag()) {
439 .linux => adjusted_os.version_range.linux.range.min = semver,
440 else => adjusted_os.version_range.semver.min = semver,
441 },
442 .windows => |win_ver| adjusted_os.version_range.windows.min = win_ver,
443 };
444
445 if (self.os_version_max) |max| switch (max) {
446 .none => {},
447 .semver => |semver| switch (self.getOsTag()) {
448 .linux => adjusted_os.version_range.linux.range.max = semver,
449 else => adjusted_os.version_range.semver.max = semver,
450 },
451 .windows => |win_ver| adjusted_os.version_range.windows.max = win_ver,
452 };
453
454 if (self.glibc_version) |glibc| {
455 assert(self.isGnuLibC());
456 adjusted_os.version_range.linux.glibc = glibc;
457 }
458
459 return adjusted_os;
460}
461
462pub fn getOsTag(self: Query) Target.Os.Tag {
463 return self.os_tag orelse builtin.os.tag;
464}
465
466/// TODO deprecated, use `std.zig.system.NativeTargetInfo.detect`.
467pub fn getOsVersionMin(self: Query) OsVersion {
468 if (self.os_version_min) |version_min| return version_min;
469 var tmp: Query = undefined;
470 tmp.updateOsVersionRange(self.getOs());
471 return tmp.os_version_min.?;
472}
473
474/// TODO deprecated, use `std.zig.system.NativeTargetInfo.detect`.
475pub fn getOsVersionMax(self: Query) OsVersion {
476 if (self.os_version_max) |version_max| return version_max;
477 var tmp: Query = undefined;
478 tmp.updateOsVersionRange(self.getOs());
479 return tmp.os_version_max.?;
480}
481
482/// TODO deprecated, use `std.zig.system.NativeTargetInfo.detect`.
483pub fn getAbi(self: Query) Target.Abi {
484 if (self.abi) |abi| return abi;
485
486 if (self.os_tag == null) {
487 // This works when doing `zig build` because Zig generates a build executable using
488 // native CPU model & features. However this will not be accurate otherwise, and
489 // will need to be integrated with `std.zig.system.NativeTargetInfo.detect`.
490 return builtin.abi;
491 }
492
493 return Target.Abi.default(self.getCpuArch(), self.getOs());
494}
495
496pub fn isFreeBSD(self: Query) bool {
497 return self.getOsTag() == .freebsd;
498}
499
500pub fn isDarwin(self: Query) bool {
501 return self.getOsTag().isDarwin();
502}
503
504pub fn isNetBSD(self: Query) bool {
505 return self.getOsTag() == .netbsd;
506}
507
508pub fn isOpenBSD(self: Query) bool {
509 return self.getOsTag() == .openbsd;
510}
511
512pub fn isUefi(self: Query) bool {
513 return self.getOsTag() == .uefi;
514}
515
516pub fn isDragonFlyBSD(self: Query) bool {
517 return self.getOsTag() == .dragonfly;
518}
519
520pub fn isLinux(self: Query) bool {
521 return self.getOsTag() == .linux;
522}
523
524pub fn isWindows(self: Query) bool {
525 return self.getOsTag() == .windows;
526}
527
528pub fn exeFileExt(self: Query) [:0]const u8 {
529 return Target.exeFileExtSimple(self.getCpuArch(), self.getOsTag());
530}
531
532pub fn staticLibSuffix(self: Query) [:0]const u8 {
533 return Target.staticLibSuffix_os_abi(self.getOsTag(), self.getAbi());
534}
535
536pub fn dynamicLibSuffix(self: Query) [:0]const u8 {
537 return self.getOsTag().dynamicLibSuffix();
538}
539
540pub fn libPrefix(self: Query) [:0]const u8 {
541 return Target.libPrefix_os_abi(self.getOsTag(), self.getAbi());
542}
543
544pub fn isNativeCpu(self: Query) bool {
545 return self.cpu_arch == null and
546 (self.cpu_model == .native or self.cpu_model == .determined_by_cpu_arch) and
547 self.cpu_features_sub.isEmpty() and self.cpu_features_add.isEmpty();
548}
549
550pub fn isNativeOs(self: Query) bool {
551 return self.os_tag == null and self.os_version_min == null and self.os_version_max == null and
552 self.dynamic_linker.get() == null and self.glibc_version == null;
553}
554
555pub fn isNativeAbi(self: Query) bool {
556 return self.os_tag == null and self.abi == null;
557}
558
559pub fn isNative(self: Query) bool {
560 return self.isNativeCpu() and self.isNativeOs() and self.isNativeAbi();
561}
562
563/// Formats a version with the patch component omitted if it is zero,
564/// unlike SemanticVersion.format which formats all its version components regardless.
565fn formatVersion(version: SemanticVersion, writer: anytype) !void {
566 if (version.patch == 0) {
567 try writer.print("{d}.{d}", .{ version.major, version.minor });
568 } else {
569 try writer.print("{d}.{d}.{d}", .{ version.major, version.minor, version.patch });
570 }
571}
572
573pub fn zigTriple(self: Query, allocator: mem.Allocator) error{OutOfMemory}![]u8 {
574 if (self.isNative()) {
575 return allocator.dupe(u8, "native");
576 }
577
578 const arch_name = if (self.cpu_arch) |arch| @tagName(arch) else "native";
579 const os_name = if (self.os_tag) |os_tag| @tagName(os_tag) else "native";
580
581 var result = std.ArrayList(u8).init(allocator);
582 defer result.deinit();
583
584 try result.writer().print("{s}-{s}", .{ arch_name, os_name });
585
586 // The zig target syntax does not allow specifying a max os version with no min, so
587 // if either are present, we need the min.
588 if (self.os_version_min != null or self.os_version_max != null) {
589 switch (self.getOsVersionMin()) {
590 .none => {},
591 .semver => |v| {
592 try result.writer().writeAll(".");
593 try formatVersion(v, result.writer());
594 },
595 .windows => |v| try result.writer().print("{s}", .{v}),
596 }
597 }
598 if (self.os_version_max) |max| {
599 switch (max) {
600 .none => {},
601 .semver => |v| {
602 try result.writer().writeAll("...");
603 try formatVersion(v, result.writer());
604 },
605 .windows => |v| try result.writer().print("..{s}", .{v}),
606 }
607 }
608
609 if (self.glibc_version) |v| {
610 try result.writer().print("-{s}.", .{@tagName(self.getAbi())});
611 try formatVersion(v, result.writer());
612 } else if (self.abi) |abi| {
613 try result.writer().print("-{s}", .{@tagName(abi)});
614 }
615
616 return result.toOwnedSlice();
617}
618
619pub fn allocDescription(self: Query, allocator: mem.Allocator) ![]u8 {
620 // TODO is there anything else worthy of the description that is not
621 // already captured in the triple?
622 return self.zigTriple(allocator);
623}
624
625pub fn linuxTriple(self: Query, allocator: mem.Allocator) ![]u8 {
626 return Target.linuxTripleSimple(allocator, self.getCpuArch(), self.getOsTag(), self.getAbi());
627}
628
629pub fn isGnuLibC(self: Query) bool {
630 return Target.isGnuLibC_os_tag_abi(self.getOsTag(), self.getAbi());
631}
632
633pub fn setGnuLibCVersion(self: *Query, major: u32, minor: u32, patch: u32) void {
634 assert(self.isGnuLibC());
635 self.glibc_version = SemanticVersion{ .major = major, .minor = minor, .patch = patch };
636}
637
638pub fn getObjectFormat(self: Query) Target.ObjectFormat {
639 return self.ofmt orelse Target.ObjectFormat.default(self.getOsTag(), self.getCpuArch());
640}
641
642pub fn updateCpuFeatures(self: Query, set: *Target.Cpu.Feature.Set) void {
643 set.removeFeatureSet(self.cpu_features_sub);
644 set.addFeatureSet(self.cpu_features_add);
645 set.populateDependencies(self.getCpuArch().allFeaturesList());
646 set.removeFeatureSet(self.cpu_features_sub);
647}
648
649fn parseOs(result: *Query, diags: *ParseOptions.Diagnostics, text: []const u8) !void {
650 var it = mem.splitScalar(u8, text, '.');
651 const os_name = it.first();
652 diags.os_name = os_name;
653 const os_is_native = mem.eql(u8, os_name, "native");
654 if (!os_is_native) {
655 result.os_tag = std.meta.stringToEnum(Target.Os.Tag, os_name) orelse
656 return error.UnknownOperatingSystem;
657 }
658 const tag = result.getOsTag();
659 diags.os_tag = tag;
660
661 const version_text = it.rest();
662 if (it.next() == null) return;
663
664 switch (tag) {
665 .freestanding,
666 .ananas,
667 .cloudabi,
668 .fuchsia,
669 .kfreebsd,
670 .lv2,
671 .solaris,
672 .illumos,
673 .zos,
674 .haiku,
675 .minix,
676 .rtems,
677 .nacl,
678 .aix,
679 .cuda,
680 .nvcl,
681 .amdhsa,
682 .ps4,
683 .ps5,
684 .elfiamcu,
685 .mesa3d,
686 .contiki,
687 .amdpal,
688 .hermit,
689 .hurd,
690 .wasi,
691 .emscripten,
692 .uefi,
693 .opencl,
694 .glsl450,
695 .vulkan,
696 .plan9,
697 .driverkit,
698 .shadermodel,
699 .liteos,
700 .other,
701 => return error.InvalidOperatingSystemVersion,
702
703 .freebsd,
704 .macos,
705 .ios,
706 .tvos,
707 .watchos,
708 .netbsd,
709 .openbsd,
710 .linux,
711 .dragonfly,
712 => {
713 var range_it = mem.splitSequence(u8, version_text, "...");
714
715 const min_text = range_it.next().?;
716 const min_ver = parseVersion(min_text) catch |err| switch (err) {
717 error.Overflow => return error.InvalidOperatingSystemVersion,
718 error.InvalidVersion => return error.InvalidOperatingSystemVersion,
719 };
720 result.os_version_min = .{ .semver = min_ver };
721
722 const max_text = range_it.next() orelse return;
723 const max_ver = parseVersion(max_text) catch |err| switch (err) {
724 error.Overflow => return error.InvalidOperatingSystemVersion,
725 error.InvalidVersion => return error.InvalidOperatingSystemVersion,
726 };
727 result.os_version_max = .{ .semver = max_ver };
728 },
729
730 .windows => {
731 var range_it = mem.splitSequence(u8, version_text, "...");
732
733 const min_text = range_it.first();
734 const min_ver = std.meta.stringToEnum(Target.Os.WindowsVersion, min_text) orelse
735 return error.InvalidOperatingSystemVersion;
736 result.os_version_min = .{ .windows = min_ver };
737
738 const max_text = range_it.next() orelse return;
739 const max_ver = std.meta.stringToEnum(Target.Os.WindowsVersion, max_text) orelse
740 return error.InvalidOperatingSystemVersion;
741 result.os_version_max = .{ .windows = max_ver };
742 },
743 }
744}
745
746const Query = @This();
747const std = @import("../std.zig");
748const builtin = @import("builtin");
749const assert = std.debug.assert;
750const Target = std.Target;
751const mem = std.mem;
752
753test parse {
754 if (builtin.target.isGnuLibC()) {
755 var query = try Query.parse(.{});
756 query.setGnuLibCVersion(2, 1, 1);
757
758 const text = try query.zigTriple(std.testing.allocator);
759 defer std.testing.allocator.free(text);
760
761 var buf: [256]u8 = undefined;
762 const triple = std.fmt.bufPrint(
763 buf[0..],
764 "native-native-{s}.2.1.1",
765 .{@tagName(builtin.abi)},
766 ) catch unreachable;
767
768 try std.testing.expectEqualSlices(u8, triple, text);
769 }
770 {
771 const query = try Query.parse(.{
772 .arch_os_abi = "aarch64-linux",
773 .cpu_features = "native",
774 });
775
776 try std.testing.expect(query.cpu_arch.? == .aarch64);
777 try std.testing.expect(query.cpu_model == .native);
778 }
779 {
780 const query = try Query.parse(.{ .arch_os_abi = "native" });
781
782 try std.testing.expect(query.cpu_arch == null);
783 try std.testing.expect(query.isNative());
784
785 const text = try query.zigTriple(std.testing.allocator);
786 defer std.testing.allocator.free(text);
787 try std.testing.expectEqualSlices(u8, "native", text);
788 }
789 {
790 const query = try Query.parse(.{
791 .arch_os_abi = "x86_64-linux-gnu",
792 .cpu_features = "x86_64-sse-sse2-avx-cx8",
793 });
794 const target = query.toTarget();
795
796 try std.testing.expect(target.os.tag == .linux);
797 try std.testing.expect(target.abi == .gnu);
798 try std.testing.expect(target.cpu.arch == .x86_64);
799 try std.testing.expect(!Target.x86.featureSetHas(target.cpu.features, .sse));
800 try std.testing.expect(!Target.x86.featureSetHas(target.cpu.features, .avx));
801 try std.testing.expect(!Target.x86.featureSetHas(target.cpu.features, .cx8));
802 try std.testing.expect(Target.x86.featureSetHas(target.cpu.features, .cmov));
803 try std.testing.expect(Target.x86.featureSetHas(target.cpu.features, .fxsr));
804
805 try std.testing.expect(Target.x86.featureSetHasAny(target.cpu.features, .{ .sse, .avx, .cmov }));
806 try std.testing.expect(!Target.x86.featureSetHasAny(target.cpu.features, .{ .sse, .avx }));
807 try std.testing.expect(Target.x86.featureSetHasAll(target.cpu.features, .{ .mmx, .x87 }));
808 try std.testing.expect(!Target.x86.featureSetHasAll(target.cpu.features, .{ .mmx, .x87, .sse }));
809
810 const text = try query.zigTriple(std.testing.allocator);
811 defer std.testing.allocator.free(text);
812 try std.testing.expectEqualSlices(u8, "x86_64-linux-gnu", text);
813 }
814 {
815 const query = try Query.parse(.{
816 .arch_os_abi = "arm-linux-musleabihf",
817 .cpu_features = "generic+v8a",
818 });
819 const target = query.toTarget();
820
821 try std.testing.expect(target.os.tag == .linux);
822 try std.testing.expect(target.abi == .musleabihf);
823 try std.testing.expect(target.cpu.arch == .arm);
824 try std.testing.expect(target.cpu.model == &Target.arm.cpu.generic);
825 try std.testing.expect(Target.arm.featureSetHas(target.cpu.features, .v8a));
826
827 const text = try query.zigTriple(std.testing.allocator);
828 defer std.testing.allocator.free(text);
829 try std.testing.expectEqualSlices(u8, "arm-linux-musleabihf", text);
830 }
831 {
832 const query = try Query.parse(.{
833 .arch_os_abi = "aarch64-linux.3.10...4.4.1-gnu.2.27",
834 .cpu_features = "generic+v8a",
835 });
836 const target = query.toTarget();
837
838 try std.testing.expect(target.cpu.arch == .aarch64);
839 try std.testing.expect(target.os.tag == .linux);
840 try std.testing.expect(target.os.version_range.linux.range.min.major == 3);
841 try std.testing.expect(target.os.version_range.linux.range.min.minor == 10);
842 try std.testing.expect(target.os.version_range.linux.range.min.patch == 0);
843 try std.testing.expect(target.os.version_range.linux.range.max.major == 4);
844 try std.testing.expect(target.os.version_range.linux.range.max.minor == 4);
845 try std.testing.expect(target.os.version_range.linux.range.max.patch == 1);
846 try std.testing.expect(target.os.version_range.linux.glibc.major == 2);
847 try std.testing.expect(target.os.version_range.linux.glibc.minor == 27);
848 try std.testing.expect(target.os.version_range.linux.glibc.patch == 0);
849 try std.testing.expect(target.abi == .gnu);
850
851 const text = try query.zigTriple(std.testing.allocator);
852 defer std.testing.allocator.free(text);
853 try std.testing.expectEqualSlices(u8, "aarch64-linux.3.10...4.4.1-gnu.2.27", text);
854 }
855}
lib/std/zig.zig+2-1
...@@ -16,7 +16,8 @@ pub const number_literal = @import("zig/number_literal.zig");...@@ -16,7 +16,8 @@ pub const number_literal = @import("zig/number_literal.zig");
16pub const primitives = @import("zig/primitives.zig");16pub const primitives = @import("zig/primitives.zig");
17pub const Ast = @import("zig/Ast.zig");17pub const Ast = @import("zig/Ast.zig");
18pub const system = @import("zig/system.zig");18pub const system = @import("zig/system.zig");
19pub const CrossTarget = @import("zig/CrossTarget.zig");19/// Deprecated: use `std.Target.Query`.
20pub const CrossTarget = std.Target.Query;
20pub const BuiltinFn = @import("zig/BuiltinFn.zig");21pub const BuiltinFn = @import("zig/BuiltinFn.zig");
21pub const AstRlAnnotate = @import("zig/AstRlAnnotate.zig");22pub const AstRlAnnotate = @import("zig/AstRlAnnotate.zig");
2223
lib/std/zig/CrossTarget.zig deleted-854
...@@ -1,854 +0,0 @@
1//! Contains all the same data as `Target`, additionally introducing the concept of "the native target".
2//! The purpose of this abstraction is to provide meaningful and unsurprising defaults.
3//! This struct does reference any resources and it is copyable.
4
5const CrossTarget = @This();
6const std = @import("../std.zig");
7const builtin = @import("builtin");
8const assert = std.debug.assert;
9const Target = std.Target;
10const mem = std.mem;
11
12/// `null` means native.
13cpu_arch: ?Target.Cpu.Arch = null,
14
15cpu_model: CpuModel = CpuModel.determined_by_cpu_arch,
16
17/// Sparse set of CPU features to add to the set from `cpu_model`.
18cpu_features_add: Target.Cpu.Feature.Set = Target.Cpu.Feature.Set.empty,
19
20/// Sparse set of CPU features to remove from the set from `cpu_model`.
21cpu_features_sub: Target.Cpu.Feature.Set = Target.Cpu.Feature.Set.empty,
22
23/// `null` means native.
24os_tag: ?Target.Os.Tag = null,
25
26/// `null` means the default version range for `os_tag`. If `os_tag` is `null` (native)
27/// then `null` for this field means native.
28os_version_min: ?OsVersion = null,
29
30/// When cross compiling, `null` means default (latest known OS version).
31/// When `os_tag` is native, `null` means equal to the native OS version.
32os_version_max: ?OsVersion = null,
33
34/// `null` means default when cross compiling, or native when os_tag is native.
35/// If `isGnuLibC()` is `false`, this must be `null` and is ignored.
36glibc_version: ?SemanticVersion = null,
37
38/// `null` means the native C ABI, if `os_tag` is native, otherwise it means the default C ABI.
39abi: ?Target.Abi = null,
40
41/// When `os_tag` is `null`, then `null` means native. Otherwise it means the standard path
42/// based on the `os_tag`.
43dynamic_linker: DynamicLinker = DynamicLinker{},
44
45/// `null` means default for the cpu/arch/os combo.
46ofmt: ?Target.ObjectFormat = null,
47
48pub const CpuModel = union(enum) {
49 /// Always native
50 native,
51
52 /// Always baseline
53 baseline,
54
55 /// If CPU Architecture is native, then the CPU model will be native. Otherwise,
56 /// it will be baseline.
57 determined_by_cpu_arch,
58
59 explicit: *const Target.Cpu.Model,
60};
61
62pub const OsVersion = union(enum) {
63 none: void,
64 semver: SemanticVersion,
65 windows: Target.Os.WindowsVersion,
66};
67
68pub const SemanticVersion = std.SemanticVersion;
69
70pub const DynamicLinker = Target.DynamicLinker;
71
72pub fn fromTarget(target: Target) CrossTarget {
73 var result: CrossTarget = .{
74 .cpu_arch = target.cpu.arch,
75 .cpu_model = .{ .explicit = target.cpu.model },
76 .os_tag = target.os.tag,
77 .os_version_min = undefined,
78 .os_version_max = undefined,
79 .abi = target.abi,
80 .glibc_version = if (target.isGnuLibC())
81 target.os.version_range.linux.glibc
82 else
83 null,
84 };
85 result.updateOsVersionRange(target.os);
86
87 const all_features = target.cpu.arch.allFeaturesList();
88 var cpu_model_set = target.cpu.model.features;
89 cpu_model_set.populateDependencies(all_features);
90 {
91 // The "add" set is the full set with the CPU Model set removed.
92 const add_set = &result.cpu_features_add;
93 add_set.* = target.cpu.features;
94 add_set.removeFeatureSet(cpu_model_set);
95 }
96 {
97 // The "sub" set is the features that are on in CPU Model set and off in the full set.
98 const sub_set = &result.cpu_features_sub;
99 sub_set.* = cpu_model_set;
100 sub_set.removeFeatureSet(target.cpu.features);
101 }
102 return result;
103}
104
105fn updateOsVersionRange(self: *CrossTarget, os: Target.Os) void {
106 switch (os.tag) {
107 .freestanding,
108 .ananas,
109 .cloudabi,
110 .fuchsia,
111 .kfreebsd,
112 .lv2,
113 .solaris,
114 .illumos,
115 .zos,
116 .haiku,
117 .minix,
118 .rtems,
119 .nacl,
120 .aix,
121 .cuda,
122 .nvcl,
123 .amdhsa,
124 .ps4,
125 .ps5,
126 .elfiamcu,
127 .mesa3d,
128 .contiki,
129 .amdpal,
130 .hermit,
131 .hurd,
132 .wasi,
133 .emscripten,
134 .driverkit,
135 .shadermodel,
136 .liteos,
137 .uefi,
138 .opencl,
139 .glsl450,
140 .vulkan,
141 .plan9,
142 .other,
143 => {
144 self.os_version_min = .{ .none = {} };
145 self.os_version_max = .{ .none = {} };
146 },
147
148 .freebsd,
149 .macos,
150 .ios,
151 .tvos,
152 .watchos,
153 .netbsd,
154 .openbsd,
155 .dragonfly,
156 => {
157 self.os_version_min = .{ .semver = os.version_range.semver.min };
158 self.os_version_max = .{ .semver = os.version_range.semver.max };
159 },
160
161 .linux => {
162 self.os_version_min = .{ .semver = os.version_range.linux.range.min };
163 self.os_version_max = .{ .semver = os.version_range.linux.range.max };
164 },
165
166 .windows => {
167 self.os_version_min = .{ .windows = os.version_range.windows.min };
168 self.os_version_max = .{ .windows = os.version_range.windows.max };
169 },
170 }
171}
172
173/// TODO deprecated, use `std.zig.system.NativeTargetInfo.detect`.
174pub fn toTarget(self: CrossTarget) Target {
175 return .{
176 .cpu = self.getCpu(),
177 .os = self.getOs(),
178 .abi = self.getAbi(),
179 .ofmt = self.getObjectFormat(),
180 };
181}
182
183pub const ParseOptions = struct {
184 /// This is sometimes called a "triple". It looks roughly like this:
185 /// riscv64-linux-musl
186 /// The fields are, respectively:
187 /// * CPU Architecture
188 /// * Operating System (and optional version range)
189 /// * C ABI (optional, with optional glibc version)
190 /// The string "native" can be used for CPU architecture as well as Operating System.
191 /// If the CPU Architecture is specified as "native", then the Operating System and C ABI may be omitted.
192 arch_os_abi: []const u8 = "native",
193
194 /// Looks like "name+a+b-c-d+e", where "name" is a CPU Model name, "a", "b", and "e"
195 /// are examples of CPU features to add to the set, and "c" and "d" are examples of CPU features
196 /// to remove from the set.
197 /// The following special strings are recognized for CPU Model name:
198 /// * "baseline" - The "default" set of CPU features for cross-compiling. A conservative set
199 /// of features that is expected to be supported on most available hardware.
200 /// * "native" - The native CPU model is to be detected when compiling.
201 /// If this field is not provided (`null`), then the value will depend on the
202 /// parsed CPU Architecture. If native, then this will be "native". Otherwise, it will be "baseline".
203 cpu_features: ?[]const u8 = null,
204
205 /// Absolute path to dynamic linker, to override the default, which is either a natively
206 /// detected path, or a standard path.
207 dynamic_linker: ?[]const u8 = null,
208
209 object_format: ?[]const u8 = null,
210
211 /// If this is provided, the function will populate some information about parsing failures,
212 /// so that user-friendly error messages can be delivered.
213 diagnostics: ?*Diagnostics = null,
214
215 pub const Diagnostics = struct {
216 /// If the architecture was determined, this will be populated.
217 arch: ?Target.Cpu.Arch = null,
218
219 /// If the OS name was determined, this will be populated.
220 os_name: ?[]const u8 = null,
221
222 /// If the OS tag was determined, this will be populated.
223 os_tag: ?Target.Os.Tag = null,
224
225 /// If the ABI was determined, this will be populated.
226 abi: ?Target.Abi = null,
227
228 /// If the CPU name was determined, this will be populated.
229 cpu_name: ?[]const u8 = null,
230
231 /// If error.UnknownCpuFeature is returned, this will be populated.
232 unknown_feature_name: ?[]const u8 = null,
233 };
234};
235
236pub fn parse(args: ParseOptions) !CrossTarget {
237 var dummy_diags: ParseOptions.Diagnostics = undefined;
238 const diags = args.diagnostics orelse &dummy_diags;
239
240 var result: CrossTarget = .{
241 .dynamic_linker = DynamicLinker.init(args.dynamic_linker),
242 };
243
244 var it = mem.splitScalar(u8, args.arch_os_abi, '-');
245 const arch_name = it.first();
246 const arch_is_native = mem.eql(u8, arch_name, "native");
247 if (!arch_is_native) {
248 result.cpu_arch = std.meta.stringToEnum(Target.Cpu.Arch, arch_name) orelse
249 return error.UnknownArchitecture;
250 }
251 const arch = result.getCpuArch();
252 diags.arch = arch;
253
254 if (it.next()) |os_text| {
255 try parseOs(&result, diags, os_text);
256 } else if (!arch_is_native) {
257 return error.MissingOperatingSystem;
258 }
259
260 const opt_abi_text = it.next();
261 if (opt_abi_text) |abi_text| {
262 var abi_it = mem.splitScalar(u8, abi_text, '.');
263 const abi = std.meta.stringToEnum(Target.Abi, abi_it.first()) orelse
264 return error.UnknownApplicationBinaryInterface;
265 result.abi = abi;
266 diags.abi = abi;
267
268 const abi_ver_text = abi_it.rest();
269 if (abi_it.next() != null) {
270 if (result.isGnuLibC()) {
271 result.glibc_version = parseVersion(abi_ver_text) catch |err| switch (err) {
272 error.Overflow => return error.InvalidAbiVersion,
273 error.InvalidVersion => return error.InvalidAbiVersion,
274 };
275 } else {
276 return error.InvalidAbiVersion;
277 }
278 }
279 }
280
281 if (it.next() != null) return error.UnexpectedExtraField;
282
283 if (args.cpu_features) |cpu_features| {
284 const all_features = arch.allFeaturesList();
285 var index: usize = 0;
286 while (index < cpu_features.len and
287 cpu_features[index] != '+' and
288 cpu_features[index] != '-')
289 {
290 index += 1;
291 }
292 const cpu_name = cpu_features[0..index];
293 diags.cpu_name = cpu_name;
294
295 const add_set = &result.cpu_features_add;
296 const sub_set = &result.cpu_features_sub;
297 if (mem.eql(u8, cpu_name, "native")) {
298 result.cpu_model = .native;
299 } else if (mem.eql(u8, cpu_name, "baseline")) {
300 result.cpu_model = .baseline;
301 } else {
302 result.cpu_model = .{ .explicit = try arch.parseCpuModel(cpu_name) };
303 }
304
305 while (index < cpu_features.len) {
306 const op = cpu_features[index];
307 const set = switch (op) {
308 '+' => add_set,
309 '-' => sub_set,
310 else => unreachable,
311 };
312 index += 1;
313 const start = index;
314 while (index < cpu_features.len and
315 cpu_features[index] != '+' and
316 cpu_features[index] != '-')
317 {
318 index += 1;
319 }
320 const feature_name = cpu_features[start..index];
321 for (all_features, 0..) |feature, feat_index_usize| {
322 const feat_index = @as(Target.Cpu.Feature.Set.Index, @intCast(feat_index_usize));
323 if (mem.eql(u8, feature_name, feature.name)) {
324 set.addFeature(feat_index);
325 break;
326 }
327 } else {
328 diags.unknown_feature_name = feature_name;
329 return error.UnknownCpuFeature;
330 }
331 }
332 }
333
334 if (args.object_format) |ofmt_name| {
335 result.ofmt = std.meta.stringToEnum(Target.ObjectFormat, ofmt_name) orelse
336 return error.UnknownObjectFormat;
337 }
338
339 return result;
340}
341
342/// Similar to `parse` except instead of fully parsing, it only determines the CPU
343/// architecture and returns it if it can be determined, and returns `null` otherwise.
344/// This is intended to be used if the API user of CrossTarget needs to learn the
345/// target CPU architecture in order to fully populate `ParseOptions`.
346pub fn parseCpuArch(args: ParseOptions) ?Target.Cpu.Arch {
347 var it = mem.splitScalar(u8, args.arch_os_abi, '-');
348 const arch_name = it.first();
349 const arch_is_native = mem.eql(u8, arch_name, "native");
350 if (arch_is_native) {
351 return builtin.cpu.arch;
352 } else {
353 return std.meta.stringToEnum(Target.Cpu.Arch, arch_name);
354 }
355}
356
357/// Similar to `SemanticVersion.parse`, but with following changes:
358/// * Leading zeroes are allowed.
359/// * Supports only 2 or 3 version components (major, minor, [patch]). If 3-rd component is omitted, it will be 0.
360pub fn parseVersion(ver: []const u8) error{ InvalidVersion, Overflow }!SemanticVersion {
361 const parseVersionComponentFn = (struct {
362 fn parseVersionComponentInner(component: []const u8) error{ InvalidVersion, Overflow }!usize {
363 return std.fmt.parseUnsigned(usize, component, 10) catch |err| switch (err) {
364 error.InvalidCharacter => return error.InvalidVersion,
365 error.Overflow => return error.Overflow,
366 };
367 }
368 }).parseVersionComponentInner;
369 var version_components = mem.splitScalar(u8, ver, '.');
370 const major = version_components.first();
371 const minor = version_components.next() orelse return error.InvalidVersion;
372 const patch = version_components.next() orelse "0";
373 if (version_components.next() != null) return error.InvalidVersion;
374 return .{
375 .major = try parseVersionComponentFn(major),
376 .minor = try parseVersionComponentFn(minor),
377 .patch = try parseVersionComponentFn(patch),
378 };
379}
380
381test parseVersion {
382 try std.testing.expectError(error.InvalidVersion, parseVersion("1"));
383 try std.testing.expectEqual(SemanticVersion{ .major = 1, .minor = 2, .patch = 0 }, try parseVersion("1.2"));
384 try std.testing.expectEqual(SemanticVersion{ .major = 1, .minor = 2, .patch = 3 }, try parseVersion("1.2.3"));
385 try std.testing.expectError(error.InvalidVersion, parseVersion("1.2.3.4"));
386}
387
388/// TODO deprecated, use `std.zig.system.NativeTargetInfo.detect`.
389pub fn getCpu(self: CrossTarget) Target.Cpu {
390 switch (self.cpu_model) {
391 .native => {
392 // This works when doing `zig build` because Zig generates a build executable using
393 // native CPU model & features. However this will not be accurate otherwise, and
394 // will need to be integrated with `std.zig.system.NativeTargetInfo.detect`.
395 return builtin.cpu;
396 },
397 .baseline => {
398 var adjusted_baseline = Target.Cpu.baseline(self.getCpuArch());
399 self.updateCpuFeatures(&adjusted_baseline.features);
400 return adjusted_baseline;
401 },
402 .determined_by_cpu_arch => if (self.cpu_arch == null) {
403 // This works when doing `zig build` because Zig generates a build executable using
404 // native CPU model & features. However this will not be accurate otherwise, and
405 // will need to be integrated with `std.zig.system.NativeTargetInfo.detect`.
406 return builtin.cpu;
407 } else {
408 var adjusted_baseline = Target.Cpu.baseline(self.getCpuArch());
409 self.updateCpuFeatures(&adjusted_baseline.features);
410 return adjusted_baseline;
411 },
412 .explicit => |model| {
413 var adjusted_model = model.toCpu(self.getCpuArch());
414 self.updateCpuFeatures(&adjusted_model.features);
415 return adjusted_model;
416 },
417 }
418}
419
420pub fn getCpuArch(self: CrossTarget) Target.Cpu.Arch {
421 return self.cpu_arch orelse builtin.cpu.arch;
422}
423
424pub fn getCpuModel(self: CrossTarget) *const Target.Cpu.Model {
425 return switch (self.cpu_model) {
426 .explicit => |cpu_model| cpu_model,
427 else => self.getCpu().model,
428 };
429}
430
431pub fn getCpuFeatures(self: CrossTarget) Target.Cpu.Feature.Set {
432 return self.getCpu().features;
433}
434
435/// TODO deprecated, use `std.zig.system.NativeTargetInfo.detect`.
436pub fn getOs(self: CrossTarget) Target.Os {
437 // `builtin.os` works when doing `zig build` because Zig generates a build executable using
438 // native OS version range. However this will not be accurate otherwise, and
439 // will need to be integrated with `std.zig.system.NativeTargetInfo.detect`.
440 var adjusted_os = if (self.os_tag) |os_tag| os_tag.defaultVersionRange(self.getCpuArch()) else builtin.os;
441
442 if (self.os_version_min) |min| switch (min) {
443 .none => {},
444 .semver => |semver| switch (self.getOsTag()) {
445 .linux => adjusted_os.version_range.linux.range.min = semver,
446 else => adjusted_os.version_range.semver.min = semver,
447 },
448 .windows => |win_ver| adjusted_os.version_range.windows.min = win_ver,
449 };
450
451 if (self.os_version_max) |max| switch (max) {
452 .none => {},
453 .semver => |semver| switch (self.getOsTag()) {
454 .linux => adjusted_os.version_range.linux.range.max = semver,
455 else => adjusted_os.version_range.semver.max = semver,
456 },
457 .windows => |win_ver| adjusted_os.version_range.windows.max = win_ver,
458 };
459
460 if (self.glibc_version) |glibc| {
461 assert(self.isGnuLibC());
462 adjusted_os.version_range.linux.glibc = glibc;
463 }
464
465 return adjusted_os;
466}
467
468pub fn getOsTag(self: CrossTarget) Target.Os.Tag {
469 return self.os_tag orelse builtin.os.tag;
470}
471
472/// TODO deprecated, use `std.zig.system.NativeTargetInfo.detect`.
473pub fn getOsVersionMin(self: CrossTarget) OsVersion {
474 if (self.os_version_min) |version_min| return version_min;
475 var tmp: CrossTarget = undefined;
476 tmp.updateOsVersionRange(self.getOs());
477 return tmp.os_version_min.?;
478}
479
480/// TODO deprecated, use `std.zig.system.NativeTargetInfo.detect`.
481pub fn getOsVersionMax(self: CrossTarget) OsVersion {
482 if (self.os_version_max) |version_max| return version_max;
483 var tmp: CrossTarget = undefined;
484 tmp.updateOsVersionRange(self.getOs());
485 return tmp.os_version_max.?;
486}
487
488/// TODO deprecated, use `std.zig.system.NativeTargetInfo.detect`.
489pub fn getAbi(self: CrossTarget) Target.Abi {
490 if (self.abi) |abi| return abi;
491
492 if (self.os_tag == null) {
493 // This works when doing `zig build` because Zig generates a build executable using
494 // native CPU model & features. However this will not be accurate otherwise, and
495 // will need to be integrated with `std.zig.system.NativeTargetInfo.detect`.
496 return builtin.abi;
497 }
498
499 return Target.Abi.default(self.getCpuArch(), self.getOs());
500}
501
502pub fn isFreeBSD(self: CrossTarget) bool {
503 return self.getOsTag() == .freebsd;
504}
505
506pub fn isDarwin(self: CrossTarget) bool {
507 return self.getOsTag().isDarwin();
508}
509
510pub fn isNetBSD(self: CrossTarget) bool {
511 return self.getOsTag() == .netbsd;
512}
513
514pub fn isOpenBSD(self: CrossTarget) bool {
515 return self.getOsTag() == .openbsd;
516}
517
518pub fn isUefi(self: CrossTarget) bool {
519 return self.getOsTag() == .uefi;
520}
521
522pub fn isDragonFlyBSD(self: CrossTarget) bool {
523 return self.getOsTag() == .dragonfly;
524}
525
526pub fn isLinux(self: CrossTarget) bool {
527 return self.getOsTag() == .linux;
528}
529
530pub fn isWindows(self: CrossTarget) bool {
531 return self.getOsTag() == .windows;
532}
533
534pub fn exeFileExt(self: CrossTarget) [:0]const u8 {
535 return Target.exeFileExtSimple(self.getCpuArch(), self.getOsTag());
536}
537
538pub fn staticLibSuffix(self: CrossTarget) [:0]const u8 {
539 return Target.staticLibSuffix_os_abi(self.getOsTag(), self.getAbi());
540}
541
542pub fn dynamicLibSuffix(self: CrossTarget) [:0]const u8 {
543 return self.getOsTag().dynamicLibSuffix();
544}
545
546pub fn libPrefix(self: CrossTarget) [:0]const u8 {
547 return Target.libPrefix_os_abi(self.getOsTag(), self.getAbi());
548}
549
550pub fn isNativeCpu(self: CrossTarget) bool {
551 return self.cpu_arch == null and
552 (self.cpu_model == .native or self.cpu_model == .determined_by_cpu_arch) and
553 self.cpu_features_sub.isEmpty() and self.cpu_features_add.isEmpty();
554}
555
556pub fn isNativeOs(self: CrossTarget) bool {
557 return self.os_tag == null and self.os_version_min == null and self.os_version_max == null and
558 self.dynamic_linker.get() == null and self.glibc_version == null;
559}
560
561pub fn isNativeAbi(self: CrossTarget) bool {
562 return self.os_tag == null and self.abi == null;
563}
564
565pub fn isNative(self: CrossTarget) bool {
566 return self.isNativeCpu() and self.isNativeOs() and self.isNativeAbi();
567}
568
569/// Formats a version with the patch component omitted if it is zero,
570/// unlike SemanticVersion.format which formats all its version components regardless.
571fn formatVersion(version: SemanticVersion, writer: anytype) !void {
572 if (version.patch == 0) {
573 try writer.print("{d}.{d}", .{ version.major, version.minor });
574 } else {
575 try writer.print("{d}.{d}.{d}", .{ version.major, version.minor, version.patch });
576 }
577}
578
579pub fn zigTriple(self: CrossTarget, allocator: mem.Allocator) error{OutOfMemory}![]u8 {
580 if (self.isNative()) {
581 return allocator.dupe(u8, "native");
582 }
583
584 const arch_name = if (self.cpu_arch) |arch| @tagName(arch) else "native";
585 const os_name = if (self.os_tag) |os_tag| @tagName(os_tag) else "native";
586
587 var result = std.ArrayList(u8).init(allocator);
588 defer result.deinit();
589
590 try result.writer().print("{s}-{s}", .{ arch_name, os_name });
591
592 // The zig target syntax does not allow specifying a max os version with no min, so
593 // if either are present, we need the min.
594 if (self.os_version_min != null or self.os_version_max != null) {
595 switch (self.getOsVersionMin()) {
596 .none => {},
597 .semver => |v| {
598 try result.writer().writeAll(".");
599 try formatVersion(v, result.writer());
600 },
601 .windows => |v| try result.writer().print("{s}", .{v}),
602 }
603 }
604 if (self.os_version_max) |max| {
605 switch (max) {
606 .none => {},
607 .semver => |v| {
608 try result.writer().writeAll("...");
609 try formatVersion(v, result.writer());
610 },
611 .windows => |v| try result.writer().print("..{s}", .{v}),
612 }
613 }
614
615 if (self.glibc_version) |v| {
616 try result.writer().print("-{s}.", .{@tagName(self.getAbi())});
617 try formatVersion(v, result.writer());
618 } else if (self.abi) |abi| {
619 try result.writer().print("-{s}", .{@tagName(abi)});
620 }
621
622 return result.toOwnedSlice();
623}
624
625pub fn allocDescription(self: CrossTarget, allocator: mem.Allocator) ![]u8 {
626 // TODO is there anything else worthy of the description that is not
627 // already captured in the triple?
628 return self.zigTriple(allocator);
629}
630
631pub fn linuxTriple(self: CrossTarget, allocator: mem.Allocator) ![]u8 {
632 return Target.linuxTripleSimple(allocator, self.getCpuArch(), self.getOsTag(), self.getAbi());
633}
634
635pub fn isGnuLibC(self: CrossTarget) bool {
636 return Target.isGnuLibC_os_tag_abi(self.getOsTag(), self.getAbi());
637}
638
639pub fn setGnuLibCVersion(self: *CrossTarget, major: u32, minor: u32, patch: u32) void {
640 assert(self.isGnuLibC());
641 self.glibc_version = SemanticVersion{ .major = major, .minor = minor, .patch = patch };
642}
643
644pub fn getObjectFormat(self: CrossTarget) Target.ObjectFormat {
645 return self.ofmt orelse Target.ObjectFormat.default(self.getOsTag(), self.getCpuArch());
646}
647
648pub fn updateCpuFeatures(self: CrossTarget, set: *Target.Cpu.Feature.Set) void {
649 set.removeFeatureSet(self.cpu_features_sub);
650 set.addFeatureSet(self.cpu_features_add);
651 set.populateDependencies(self.getCpuArch().allFeaturesList());
652 set.removeFeatureSet(self.cpu_features_sub);
653}
654
655fn parseOs(result: *CrossTarget, diags: *ParseOptions.Diagnostics, text: []const u8) !void {
656 var it = mem.splitScalar(u8, text, '.');
657 const os_name = it.first();
658 diags.os_name = os_name;
659 const os_is_native = mem.eql(u8, os_name, "native");
660 if (!os_is_native) {
661 result.os_tag = std.meta.stringToEnum(Target.Os.Tag, os_name) orelse
662 return error.UnknownOperatingSystem;
663 }
664 const tag = result.getOsTag();
665 diags.os_tag = tag;
666
667 const version_text = it.rest();
668 if (it.next() == null) return;
669
670 switch (tag) {
671 .freestanding,
672 .ananas,
673 .cloudabi,
674 .fuchsia,
675 .kfreebsd,
676 .lv2,
677 .solaris,
678 .illumos,
679 .zos,
680 .haiku,
681 .minix,
682 .rtems,
683 .nacl,
684 .aix,
685 .cuda,
686 .nvcl,
687 .amdhsa,
688 .ps4,
689 .ps5,
690 .elfiamcu,
691 .mesa3d,
692 .contiki,
693 .amdpal,
694 .hermit,
695 .hurd,
696 .wasi,
697 .emscripten,
698 .uefi,
699 .opencl,
700 .glsl450,
701 .vulkan,
702 .plan9,
703 .driverkit,
704 .shadermodel,
705 .liteos,
706 .other,
707 => return error.InvalidOperatingSystemVersion,
708
709 .freebsd,
710 .macos,
711 .ios,
712 .tvos,
713 .watchos,
714 .netbsd,
715 .openbsd,
716 .linux,
717 .dragonfly,
718 => {
719 var range_it = mem.splitSequence(u8, version_text, "...");
720
721 const min_text = range_it.next().?;
722 const min_ver = parseVersion(min_text) catch |err| switch (err) {
723 error.Overflow => return error.InvalidOperatingSystemVersion,
724 error.InvalidVersion => return error.InvalidOperatingSystemVersion,
725 };
726 result.os_version_min = .{ .semver = min_ver };
727
728 const max_text = range_it.next() orelse return;
729 const max_ver = parseVersion(max_text) catch |err| switch (err) {
730 error.Overflow => return error.InvalidOperatingSystemVersion,
731 error.InvalidVersion => return error.InvalidOperatingSystemVersion,
732 };
733 result.os_version_max = .{ .semver = max_ver };
734 },
735
736 .windows => {
737 var range_it = mem.splitSequence(u8, version_text, "...");
738
739 const min_text = range_it.first();
740 const min_ver = std.meta.stringToEnum(Target.Os.WindowsVersion, min_text) orelse
741 return error.InvalidOperatingSystemVersion;
742 result.os_version_min = .{ .windows = min_ver };
743
744 const max_text = range_it.next() orelse return;
745 const max_ver = std.meta.stringToEnum(Target.Os.WindowsVersion, max_text) orelse
746 return error.InvalidOperatingSystemVersion;
747 result.os_version_max = .{ .windows = max_ver };
748 },
749 }
750}
751
752test "CrossTarget.parse" {
753 if (builtin.target.isGnuLibC()) {
754 var cross_target = try CrossTarget.parse(.{});
755 cross_target.setGnuLibCVersion(2, 1, 1);
756
757 const text = try cross_target.zigTriple(std.testing.allocator);
758 defer std.testing.allocator.free(text);
759
760 var buf: [256]u8 = undefined;
761 const triple = std.fmt.bufPrint(
762 buf[0..],
763 "native-native-{s}.2.1.1",
764 .{@tagName(builtin.abi)},
765 ) catch unreachable;
766
767 try std.testing.expectEqualSlices(u8, triple, text);
768 }
769 {
770 const cross_target = try CrossTarget.parse(.{
771 .arch_os_abi = "aarch64-linux",
772 .cpu_features = "native",
773 });
774
775 try std.testing.expect(cross_target.cpu_arch.? == .aarch64);
776 try std.testing.expect(cross_target.cpu_model == .native);
777 }
778 {
779 const cross_target = try CrossTarget.parse(.{ .arch_os_abi = "native" });
780
781 try std.testing.expect(cross_target.cpu_arch == null);
782 try std.testing.expect(cross_target.isNative());
783
784 const text = try cross_target.zigTriple(std.testing.allocator);
785 defer std.testing.allocator.free(text);
786 try std.testing.expectEqualSlices(u8, "native", text);
787 }
788 {
789 const cross_target = try CrossTarget.parse(.{
790 .arch_os_abi = "x86_64-linux-gnu",
791 .cpu_features = "x86_64-sse-sse2-avx-cx8",
792 });
793 const target = cross_target.toTarget();
794
795 try std.testing.expect(target.os.tag == .linux);
796 try std.testing.expect(target.abi == .gnu);
797 try std.testing.expect(target.cpu.arch == .x86_64);
798 try std.testing.expect(!Target.x86.featureSetHas(target.cpu.features, .sse));
799 try std.testing.expect(!Target.x86.featureSetHas(target.cpu.features, .avx));
800 try std.testing.expect(!Target.x86.featureSetHas(target.cpu.features, .cx8));
801 try std.testing.expect(Target.x86.featureSetHas(target.cpu.features, .cmov));
802 try std.testing.expect(Target.x86.featureSetHas(target.cpu.features, .fxsr));
803
804 try std.testing.expect(Target.x86.featureSetHasAny(target.cpu.features, .{ .sse, .avx, .cmov }));
805 try std.testing.expect(!Target.x86.featureSetHasAny(target.cpu.features, .{ .sse, .avx }));
806 try std.testing.expect(Target.x86.featureSetHasAll(target.cpu.features, .{ .mmx, .x87 }));
807 try std.testing.expect(!Target.x86.featureSetHasAll(target.cpu.features, .{ .mmx, .x87, .sse }));
808
809 const text = try cross_target.zigTriple(std.testing.allocator);
810 defer std.testing.allocator.free(text);
811 try std.testing.expectEqualSlices(u8, "x86_64-linux-gnu", text);
812 }
813 {
814 const cross_target = try CrossTarget.parse(.{
815 .arch_os_abi = "arm-linux-musleabihf",
816 .cpu_features = "generic+v8a",
817 });
818 const target = cross_target.toTarget();
819
820 try std.testing.expect(target.os.tag == .linux);
821 try std.testing.expect(target.abi == .musleabihf);
822 try std.testing.expect(target.cpu.arch == .arm);
823 try std.testing.expect(target.cpu.model == &Target.arm.cpu.generic);
824 try std.testing.expect(Target.arm.featureSetHas(target.cpu.features, .v8a));
825
826 const text = try cross_target.zigTriple(std.testing.allocator);
827 defer std.testing.allocator.free(text);
828 try std.testing.expectEqualSlices(u8, "arm-linux-musleabihf", text);
829 }
830 {
831 const cross_target = try CrossTarget.parse(.{
832 .arch_os_abi = "aarch64-linux.3.10...4.4.1-gnu.2.27",
833 .cpu_features = "generic+v8a",
834 });
835 const target = cross_target.toTarget();
836
837 try std.testing.expect(target.cpu.arch == .aarch64);
838 try std.testing.expect(target.os.tag == .linux);
839 try std.testing.expect(target.os.version_range.linux.range.min.major == 3);
840 try std.testing.expect(target.os.version_range.linux.range.min.minor == 10);
841 try std.testing.expect(target.os.version_range.linux.range.min.patch == 0);
842 try std.testing.expect(target.os.version_range.linux.range.max.major == 4);
843 try std.testing.expect(target.os.version_range.linux.range.max.minor == 4);
844 try std.testing.expect(target.os.version_range.linux.range.max.patch == 1);
845 try std.testing.expect(target.os.version_range.linux.glibc.major == 2);
846 try std.testing.expect(target.os.version_range.linux.glibc.minor == 27);
847 try std.testing.expect(target.os.version_range.linux.glibc.patch == 0);
848 try std.testing.expect(target.abi == .gnu);
849
850 const text = try cross_target.zigTriple(std.testing.allocator);
851 defer std.testing.allocator.free(text);
852 try std.testing.expectEqualSlices(u8, "aarch64-linux.3.10...4.4.1-gnu.2.27", text);
853 }
854}
lib/std/zig/system/NativeTargetInfo.zig+53-53
...@@ -9,7 +9,6 @@ const native_endian = builtin.cpu.arch.endian();...@@ -9,7 +9,6 @@ const native_endian = builtin.cpu.arch.endian();
9const NativeTargetInfo = @This();9const NativeTargetInfo = @This();
10const Target = std.Target;10const Target = std.Target;
11const Allocator = std.mem.Allocator;11const Allocator = std.mem.Allocator;
12const CrossTarget = std.zig.CrossTarget;
13const windows = std.zig.system.windows;12const windows = std.zig.system.windows;
14const darwin = std.zig.system.darwin;13const darwin = std.zig.system.darwin;
15const linux = std.zig.system.linux;14const linux = std.zig.system.linux;
...@@ -30,13 +29,14 @@ pub const DetectError = error{...@@ -30,13 +29,14 @@ pub const DetectError = error{
30 Unexpected,29 Unexpected,
31};30};
3231
33/// Given a `CrossTarget`, which specifies in detail which parts of the target should be detected32/// Given a `Target.Query`, which specifies in detail which parts of the
34/// natively, which should be standard or default, and which are provided explicitly, this function33/// target should be detected natively, which should be standard or default,
35/// resolves the native components by detecting the native system, and then resolves standard/default parts34/// and which are provided explicitly, this function resolves the native
36/// relative to that.35/// components by detecting the native system, and then resolves
37pub fn detect(cross_target: CrossTarget) DetectError!NativeTargetInfo {36/// standard/default parts relative to that.
38 var os = cross_target.getOsTag().defaultVersionRange(cross_target.getCpuArch());37pub fn detect(query: Target.Query) DetectError!NativeTargetInfo {
39 if (cross_target.os_tag == null) {38 var os = query.getOsTag().defaultVersionRange(query.getCpuArch());
39 if (query.os_tag == null) {
40 switch (builtin.target.os.tag) {40 switch (builtin.target.os.tag) {
41 .linux => {41 .linux => {
42 const uts = std.os.uname();42 const uts = std.os.uname();
...@@ -162,45 +162,45 @@ pub fn detect(cross_target: CrossTarget) DetectError!NativeTargetInfo {...@@ -162,45 +162,45 @@ pub fn detect(cross_target: CrossTarget) DetectError!NativeTargetInfo {
162 }162 }
163 }163 }
164164
165 if (cross_target.os_version_min) |min| switch (min) {165 if (query.os_version_min) |min| switch (min) {
166 .none => {},166 .none => {},
167 .semver => |semver| switch (cross_target.getOsTag()) {167 .semver => |semver| switch (query.getOsTag()) {
168 .linux => os.version_range.linux.range.min = semver,168 .linux => os.version_range.linux.range.min = semver,
169 else => os.version_range.semver.min = semver,169 else => os.version_range.semver.min = semver,
170 },170 },
171 .windows => |win_ver| os.version_range.windows.min = win_ver,171 .windows => |win_ver| os.version_range.windows.min = win_ver,
172 };172 };
173173
174 if (cross_target.os_version_max) |max| switch (max) {174 if (query.os_version_max) |max| switch (max) {
175 .none => {},175 .none => {},
176 .semver => |semver| switch (cross_target.getOsTag()) {176 .semver => |semver| switch (query.getOsTag()) {
177 .linux => os.version_range.linux.range.max = semver,177 .linux => os.version_range.linux.range.max = semver,
178 else => os.version_range.semver.max = semver,178 else => os.version_range.semver.max = semver,
179 },179 },
180 .windows => |win_ver| os.version_range.windows.max = win_ver,180 .windows => |win_ver| os.version_range.windows.max = win_ver,
181 };181 };
182182
183 if (cross_target.glibc_version) |glibc| {183 if (query.glibc_version) |glibc| {
184 assert(cross_target.isGnuLibC());184 assert(query.isGnuLibC());
185 os.version_range.linux.glibc = glibc;185 os.version_range.linux.glibc = glibc;
186 }186 }
187187
188 // Until https://github.com/ziglang/zig/issues/4592 is implemented (support detecting the188 // Until https://github.com/ziglang/zig/issues/4592 is implemented (support detecting the
189 // native CPU architecture as being different than the current target), we use this:189 // native CPU architecture as being different than the current target), we use this:
190 const cpu_arch = cross_target.getCpuArch();190 const cpu_arch = query.getCpuArch();
191191
192 const cpu = switch (cross_target.cpu_model) {192 const cpu = switch (query.cpu_model) {
193 .native => detectNativeCpuAndFeatures(cpu_arch, os, cross_target),193 .native => detectNativeCpuAndFeatures(cpu_arch, os, query),
194 .baseline => Target.Cpu.baseline(cpu_arch),194 .baseline => Target.Cpu.baseline(cpu_arch),
195 .determined_by_cpu_arch => if (cross_target.cpu_arch == null)195 .determined_by_cpu_arch => if (query.cpu_arch == null)
196 detectNativeCpuAndFeatures(cpu_arch, os, cross_target)196 detectNativeCpuAndFeatures(cpu_arch, os, query)
197 else197 else
198 Target.Cpu.baseline(cpu_arch),198 Target.Cpu.baseline(cpu_arch),
199 .explicit => |model| model.toCpu(cpu_arch),199 .explicit => |model| model.toCpu(cpu_arch),
200 } orelse backup_cpu_detection: {200 } orelse backup_cpu_detection: {
201 break :backup_cpu_detection Target.Cpu.baseline(cpu_arch);201 break :backup_cpu_detection Target.Cpu.baseline(cpu_arch);
202 };202 };
203 var result = try detectAbiAndDynamicLinker(cpu, os, cross_target);203 var result = try detectAbiAndDynamicLinker(cpu, os, query);
204 // For x86, we need to populate some CPU feature flags depending on architecture204 // For x86, we need to populate some CPU feature flags depending on architecture
205 // and mode:205 // and mode:
206 // * 16bit_mode => if the abi is code16206 // * 16bit_mode => if the abi is code16
...@@ -209,15 +209,15 @@ pub fn detect(cross_target: CrossTarget) DetectError!NativeTargetInfo {...@@ -209,15 +209,15 @@ pub fn detect(cross_target: CrossTarget) DetectError!NativeTargetInfo {
209 // sets one of them, that takes precedence.209 // sets one of them, that takes precedence.
210 switch (cpu_arch) {210 switch (cpu_arch) {
211 .x86 => {211 .x86 => {
212 if (!std.Target.x86.featureSetHasAny(cross_target.cpu_features_add, .{212 if (!Target.x86.featureSetHasAny(query.cpu_features_add, .{
213 .@"16bit_mode", .@"32bit_mode",213 .@"16bit_mode", .@"32bit_mode",
214 })) {214 })) {
215 switch (result.target.abi) {215 switch (result.target.abi) {
216 .code16 => result.target.cpu.features.addFeature(216 .code16 => result.target.cpu.features.addFeature(
217 @intFromEnum(std.Target.x86.Feature.@"16bit_mode"),217 @intFromEnum(Target.x86.Feature.@"16bit_mode"),
218 ),218 ),
219 else => result.target.cpu.features.addFeature(219 else => result.target.cpu.features.addFeature(
220 @intFromEnum(std.Target.x86.Feature.@"32bit_mode"),220 @intFromEnum(Target.x86.Feature.@"32bit_mode"),
221 ),221 ),
222 }222 }
223 }223 }
...@@ -228,12 +228,12 @@ pub fn detect(cross_target: CrossTarget) DetectError!NativeTargetInfo {...@@ -228,12 +228,12 @@ pub fn detect(cross_target: CrossTarget) DetectError!NativeTargetInfo {
228 },228 },
229 .thumb, .thumbeb => {229 .thumb, .thumbeb => {
230 result.target.cpu.features.addFeature(230 result.target.cpu.features.addFeature(
231 @intFromEnum(std.Target.arm.Feature.thumb_mode),231 @intFromEnum(Target.arm.Feature.thumb_mode),
232 );232 );
233 },233 },
234 else => {},234 else => {},
235 }235 }
236 cross_target.updateCpuFeatures(&result.target.cpu.features);236 query.updateCpuFeatures(&result.target.cpu.features);
237 return result;237 return result;
238}238}
239239
...@@ -253,22 +253,22 @@ pub fn detect(cross_target: CrossTarget) DetectError!NativeTargetInfo {...@@ -253,22 +253,22 @@ pub fn detect(cross_target: CrossTarget) DetectError!NativeTargetInfo {
253fn detectAbiAndDynamicLinker(253fn detectAbiAndDynamicLinker(
254 cpu: Target.Cpu,254 cpu: Target.Cpu,
255 os: Target.Os,255 os: Target.Os,
256 cross_target: CrossTarget,256 query: Target.Query,
257) DetectError!NativeTargetInfo {257) DetectError!NativeTargetInfo {
258 const native_target_has_ld = comptime builtin.target.hasDynamicLinker();258 const native_target_has_ld = comptime builtin.target.hasDynamicLinker();
259 const is_linux = builtin.target.os.tag == .linux;259 const is_linux = builtin.target.os.tag == .linux;
260 const is_solarish = builtin.target.os.tag.isSolarish();260 const is_solarish = builtin.target.os.tag.isSolarish();
261 const have_all_info = cross_target.dynamic_linker.get() != null and261 const have_all_info = query.dynamic_linker.get() != null and
262 cross_target.abi != null and (!is_linux or cross_target.abi.?.isGnu());262 query.abi != null and (!is_linux or query.abi.?.isGnu());
263 const os_is_non_native = cross_target.os_tag != null;263 const os_is_non_native = query.os_tag != null;
264 // The Solaris/illumos environment is always the same.264 // The Solaris/illumos environment is always the same.
265 if (!native_target_has_ld or have_all_info or os_is_non_native or is_solarish) {265 if (!native_target_has_ld or have_all_info or os_is_non_native or is_solarish) {
266 return defaultAbiAndDynamicLinker(cpu, os, cross_target);266 return defaultAbiAndDynamicLinker(cpu, os, query);
267 }267 }
268 if (cross_target.abi) |abi| {268 if (query.abi) |abi| {
269 if (abi.isMusl()) {269 if (abi.isMusl()) {
270 // musl implies static linking.270 // musl implies static linking.
271 return defaultAbiAndDynamicLinker(cpu, os, cross_target);271 return defaultAbiAndDynamicLinker(cpu, os, query);
272 }272 }
273 }273 }
274 // The current target's ABI cannot be relied on for this. For example, we may build the zig274 // The current target's ABI cannot be relied on for this. For example, we may build the zig
...@@ -287,7 +287,7 @@ fn detectAbiAndDynamicLinker(...@@ -287,7 +287,7 @@ fn detectAbiAndDynamicLinker(
287 };287 };
288 var ld_info_list_buffer: [all_abis.len]LdInfo = undefined;288 var ld_info_list_buffer: [all_abis.len]LdInfo = undefined;
289 var ld_info_list_len: usize = 0;289 var ld_info_list_len: usize = 0;
290 const ofmt = cross_target.ofmt orelse Target.ObjectFormat.default(os.tag, cpu.arch);290 const ofmt = query.ofmt orelse Target.ObjectFormat.default(os.tag, cpu.arch);
291291
292 for (all_abis) |abi| {292 for (all_abis) |abi| {
293 // This may be a nonsensical parameter. We detect this with293 // This may be a nonsensical parameter. We detect this with
...@@ -345,7 +345,7 @@ fn detectAbiAndDynamicLinker(...@@ -345,7 +345,7 @@ fn detectAbiAndDynamicLinker(
345 error.Unexpected,345 error.Unexpected,
346 => |e| {346 => |e| {
347 std.log.warn("Encountered error: {s}, falling back to default ABI and dynamic linker.\n", .{@errorName(e)});347 std.log.warn("Encountered error: {s}, falling back to default ABI and dynamic linker.\n", .{@errorName(e)});
348 return defaultAbiAndDynamicLinker(cpu, os, cross_target);348 return defaultAbiAndDynamicLinker(cpu, os, query);
349 },349 },
350350
351 else => |e| return e,351 else => |e| return e,
...@@ -363,7 +363,7 @@ fn detectAbiAndDynamicLinker(...@@ -363,7 +363,7 @@ fn detectAbiAndDynamicLinker(
363 const line = buffer[0..newline];363 const line = buffer[0..newline];
364 if (!mem.startsWith(u8, line, "#!")) break :blk file;364 if (!mem.startsWith(u8, line, "#!")) break :blk file;
365 var it = mem.tokenizeScalar(u8, line[2..], ' ');365 var it = mem.tokenizeScalar(u8, line[2..], ' ');
366 file_name = it.next() orelse return defaultAbiAndDynamicLinker(cpu, os, cross_target);366 file_name = it.next() orelse return defaultAbiAndDynamicLinker(cpu, os, query);
367 file.close();367 file.close();
368 }368 }
369 };369 };
...@@ -373,7 +373,7 @@ fn detectAbiAndDynamicLinker(...@@ -373,7 +373,7 @@ fn detectAbiAndDynamicLinker(
373 // trick (block self_exe) won't work. The next thing we fall back to is the same thing, but for elf_file.373 // trick (block self_exe) won't work. The next thing we fall back to is the same thing, but for elf_file.
374 // TODO: inline this function and combine the buffer we already read above to find374 // TODO: inline this function and combine the buffer we already read above to find
375 // the possible shebang line with the buffer we use for the ELF header.375 // the possible shebang line with the buffer we use for the ELF header.
376 return abiAndDynamicLinkerFromFile(elf_file, cpu, os, ld_info_list, cross_target) catch |err| switch (err) {376 return abiAndDynamicLinkerFromFile(elf_file, cpu, os, ld_info_list, query) catch |err| switch (err) {
377 error.FileSystem,377 error.FileSystem,
378 error.SystemResources,378 error.SystemResources,
379 error.SymLinkLoop,379 error.SymLinkLoop,
...@@ -393,7 +393,7 @@ fn detectAbiAndDynamicLinker(...@@ -393,7 +393,7 @@ fn detectAbiAndDynamicLinker(
393 // Finally, we fall back on the standard path.393 // Finally, we fall back on the standard path.
394 => |e| {394 => |e| {
395 std.log.warn("Encountered error: {s}, falling back to default ABI and dynamic linker.\n", .{@errorName(e)});395 std.log.warn("Encountered error: {s}, falling back to default ABI and dynamic linker.\n", .{@errorName(e)});
396 return defaultAbiAndDynamicLinker(cpu, os, cross_target);396 return defaultAbiAndDynamicLinker(cpu, os, query);
397 },397 },
398 };398 };
399}399}
...@@ -565,7 +565,7 @@ fn glibcVerFromSoFile(file: fs.File) !std.SemanticVersion {...@@ -565,7 +565,7 @@ fn glibcVerFromSoFile(file: fs.File) !std.SemanticVersion {
565 while (it.next()) |s| {565 while (it.next()) |s| {
566 if (mem.startsWith(u8, s, "GLIBC_2.")) {566 if (mem.startsWith(u8, s, "GLIBC_2.")) {
567 const chopped = s["GLIBC_".len..];567 const chopped = s["GLIBC_".len..];
568 const ver = CrossTarget.parseVersion(chopped) catch |err| switch (err) {568 const ver = Target.Query.parseVersion(chopped) catch |err| switch (err) {
569 error.Overflow => return error.InvalidGnuLibCVersion,569 error.Overflow => return error.InvalidGnuLibCVersion,
570 error.InvalidVersion => return error.InvalidGnuLibCVersion,570 error.InvalidVersion => return error.InvalidGnuLibCVersion,
571 };571 };
...@@ -588,7 +588,7 @@ fn glibcVerFromLinkName(link_name: []const u8, prefix: []const u8) error{ Unreco...@@ -588,7 +588,7 @@ fn glibcVerFromLinkName(link_name: []const u8, prefix: []const u8) error{ Unreco
588 }588 }
589 // chop off "libc-" and ".so"589 // chop off "libc-" and ".so"
590 const link_name_chopped = link_name[prefix.len .. link_name.len - suffix.len];590 const link_name_chopped = link_name[prefix.len .. link_name.len - suffix.len];
591 return CrossTarget.parseVersion(link_name_chopped) catch |err| switch (err) {591 return Target.Query.parseVersion(link_name_chopped) catch |err| switch (err) {
592 error.Overflow => return error.InvalidGnuLibCVersion,592 error.Overflow => return error.InvalidGnuLibCVersion,
593 error.InvalidVersion => return error.InvalidGnuLibCVersion,593 error.InvalidVersion => return error.InvalidGnuLibCVersion,
594 };594 };
...@@ -627,7 +627,7 @@ pub fn abiAndDynamicLinkerFromFile(...@@ -627,7 +627,7 @@ pub fn abiAndDynamicLinkerFromFile(
627 cpu: Target.Cpu,627 cpu: Target.Cpu,
628 os: Target.Os,628 os: Target.Os,
629 ld_info_list: []const LdInfo,629 ld_info_list: []const LdInfo,
630 cross_target: CrossTarget,630 query: Target.Query,
631) AbiAndDynamicLinkerFromFileError!NativeTargetInfo {631) AbiAndDynamicLinkerFromFileError!NativeTargetInfo {
632 var hdr_buf: [@sizeOf(elf.Elf64_Ehdr)]u8 align(@alignOf(elf.Elf64_Ehdr)) = undefined;632 var hdr_buf: [@sizeOf(elf.Elf64_Ehdr)]u8 align(@alignOf(elf.Elf64_Ehdr)) = undefined;
633 _ = try preadMin(file, &hdr_buf, 0, hdr_buf.len);633 _ = try preadMin(file, &hdr_buf, 0, hdr_buf.len);
...@@ -655,13 +655,13 @@ pub fn abiAndDynamicLinkerFromFile(...@@ -655,13 +655,13 @@ pub fn abiAndDynamicLinkerFromFile(
655 .target = .{655 .target = .{
656 .cpu = cpu,656 .cpu = cpu,
657 .os = os,657 .os = os,
658 .abi = cross_target.abi orelse Target.Abi.default(cpu.arch, os),658 .abi = query.abi orelse Target.Abi.default(cpu.arch, os),
659 .ofmt = cross_target.ofmt orelse Target.ObjectFormat.default(os.tag, cpu.arch),659 .ofmt = query.ofmt orelse Target.ObjectFormat.default(os.tag, cpu.arch),
660 },660 },
661 .dynamic_linker = cross_target.dynamic_linker,661 .dynamic_linker = query.dynamic_linker,
662 };662 };
663 var rpath_offset: ?u64 = null; // Found inside PT_DYNAMIC663 var rpath_offset: ?u64 = null; // Found inside PT_DYNAMIC
664 const look_for_ld = cross_target.dynamic_linker.get() == null;664 const look_for_ld = query.dynamic_linker.get() == null;
665665
666 var ph_buf: [16 * @sizeOf(elf.Elf64_Phdr)]u8 align(@alignOf(elf.Elf64_Phdr)) = undefined;666 var ph_buf: [16 * @sizeOf(elf.Elf64_Phdr)]u8 align(@alignOf(elf.Elf64_Phdr)) = undefined;
667 if (phentsize > @sizeOf(elf.Elf64_Phdr)) return error.InvalidElfFile;667 if (phentsize > @sizeOf(elf.Elf64_Phdr)) return error.InvalidElfFile;
...@@ -706,7 +706,7 @@ pub fn abiAndDynamicLinkerFromFile(...@@ -706,7 +706,7 @@ pub fn abiAndDynamicLinkerFromFile(
706 },706 },
707 // We only need this for detecting glibc version.707 // We only need this for detecting glibc version.
708 elf.PT_DYNAMIC => if (builtin.target.os.tag == .linux and result.target.isGnuLibC() and708 elf.PT_DYNAMIC => if (builtin.target.os.tag == .linux and result.target.isGnuLibC() and
709 cross_target.glibc_version == null)709 query.glibc_version == null)
710 {710 {
711 var dyn_off = elfInt(is_64, need_bswap, ph32.p_offset, ph64.p_offset);711 var dyn_off = elfInt(is_64, need_bswap, ph32.p_offset, ph64.p_offset);
712 const p_filesz = elfInt(is_64, need_bswap, ph32.p_filesz, ph64.p_filesz);712 const p_filesz = elfInt(is_64, need_bswap, ph32.p_filesz, ph64.p_filesz);
...@@ -747,7 +747,7 @@ pub fn abiAndDynamicLinkerFromFile(...@@ -747,7 +747,7 @@ pub fn abiAndDynamicLinkerFromFile(
747 }747 }
748748
749 if (builtin.target.os.tag == .linux and result.target.isGnuLibC() and749 if (builtin.target.os.tag == .linux and result.target.isGnuLibC() and
750 cross_target.glibc_version == null)750 query.glibc_version == null)
751 {751 {
752 const shstrndx = elfInt(is_64, need_bswap, hdr32.e_shstrndx, hdr64.e_shstrndx);752 const shstrndx = elfInt(is_64, need_bswap, hdr32.e_shstrndx, hdr64.e_shstrndx);
753753
...@@ -927,19 +927,19 @@ fn preadMin(file: fs.File, buf: []u8, offset: u64, min_read_len: usize) !usize {...@@ -927,19 +927,19 @@ fn preadMin(file: fs.File, buf: []u8, offset: u64, min_read_len: usize) !usize {
927 return i;927 return i;
928}928}
929929
930fn defaultAbiAndDynamicLinker(cpu: Target.Cpu, os: Target.Os, cross_target: CrossTarget) !NativeTargetInfo {930fn defaultAbiAndDynamicLinker(cpu: Target.Cpu, os: Target.Os, query: Target.Query) !NativeTargetInfo {
931 const target: Target = .{931 const target: Target = .{
932 .cpu = cpu,932 .cpu = cpu,
933 .os = os,933 .os = os,
934 .abi = cross_target.abi orelse Target.Abi.default(cpu.arch, os),934 .abi = query.abi orelse Target.Abi.default(cpu.arch, os),
935 .ofmt = cross_target.ofmt orelse Target.ObjectFormat.default(os.tag, cpu.arch),935 .ofmt = query.ofmt orelse Target.ObjectFormat.default(os.tag, cpu.arch),
936 };936 };
937 return NativeTargetInfo{937 return NativeTargetInfo{
938 .target = target,938 .target = target,
939 .dynamic_linker = if (cross_target.dynamic_linker.get() == null)939 .dynamic_linker = if (query.dynamic_linker.get() == null)
940 target.standardDynamicLinkerPath()940 target.standardDynamicLinkerPath()
941 else941 else
942 cross_target.dynamic_linker,942 query.dynamic_linker,
943 };943 };
944}944}
945945
...@@ -964,13 +964,13 @@ pub fn elfInt(is_64: bool, need_bswap: bool, int_32: anytype, int_64: anytype) @...@@ -964,13 +964,13 @@ pub fn elfInt(is_64: bool, need_bswap: bool, int_32: anytype, int_64: anytype) @
964 }964 }
965}965}
966966
967fn detectNativeCpuAndFeatures(cpu_arch: Target.Cpu.Arch, os: Target.Os, cross_target: CrossTarget) ?Target.Cpu {967fn detectNativeCpuAndFeatures(cpu_arch: Target.Cpu.Arch, os: Target.Os, query: Target.Query) ?Target.Cpu {
968 // Here we switch on a comptime value rather than `cpu_arch`. This is valid because `cpu_arch`,968 // Here we switch on a comptime value rather than `cpu_arch`. This is valid because `cpu_arch`,
969 // although it is a runtime value, is guaranteed to be one of the architectures in the set969 // although it is a runtime value, is guaranteed to be one of the architectures in the set
970 // of the respective switch prong.970 // of the respective switch prong.
971 switch (builtin.cpu.arch) {971 switch (builtin.cpu.arch) {
972 .x86_64, .x86 => {972 .x86_64, .x86 => {
973 return @import("x86.zig").detectNativeCpuAndFeatures(cpu_arch, os, cross_target);973 return @import("x86.zig").detectNativeCpuAndFeatures(cpu_arch, os, query);
974 },974 },
975 else => {},975 else => {},
976 }976 }
lib/std/zig/system/darwin/macos.zig+1-1
...@@ -87,7 +87,7 @@ fn parseSystemVersion(buf: []const u8) !std.SemanticVersion {...@@ -87,7 +87,7 @@ fn parseSystemVersion(buf: []const u8) !std.SemanticVersion {
87 const ver = try svt.expectContent();87 const ver = try svt.expectContent();
88 try svt.skipUntilTag(.end, "string");88 try svt.skipUntilTag(.end, "string");
8989
90 return try std.zig.CrossTarget.parseVersion(ver);90 return try std.Target.Query.parseVersion(ver);
91}91}
9292
93const SystemVersionTokenizer = struct {93const SystemVersionTokenizer = struct {
lib/std/zig/system/linux.zig-3
...@@ -5,10 +5,7 @@ const io = std.io;...@@ -5,10 +5,7 @@ const io = std.io;
5const fs = std.fs;5const fs = std.fs;
6const fmt = std.fmt;6const fmt = std.fmt;
7const testing = std.testing;7const testing = std.testing;
8
9const Target = std.Target;8const Target = std.Target;
10const CrossTarget = std.zig.CrossTarget;
11
12const assert = std.debug.assert;9const assert = std.debug.assert;
1310
14const SparcCpuinfoImpl = struct {11const SparcCpuinfoImpl = struct {
lib/std/zig/system/x86.zig+2-3
...@@ -1,7 +1,6 @@...@@ -1,7 +1,6 @@
1const std = @import("std");1const std = @import("std");
2const builtin = @import("builtin");2const builtin = @import("builtin");
3const Target = std.Target;3const Target = std.Target;
4const CrossTarget = std.zig.CrossTarget;
54
6const XCR0_XMM = 0x02;5const XCR0_XMM = 0x02;
7const XCR0_YMM = 0x04;6const XCR0_YMM = 0x04;
...@@ -23,8 +22,8 @@ inline fn hasMask(input: u32, mask: u32) bool {...@@ -23,8 +22,8 @@ inline fn hasMask(input: u32, mask: u32) bool {
23 return (input & mask) == mask;22 return (input & mask) == mask;
24}23}
2524
26pub fn detectNativeCpuAndFeatures(arch: Target.Cpu.Arch, os: Target.Os, cross_target: CrossTarget) Target.Cpu {25pub fn detectNativeCpuAndFeatures(arch: Target.Cpu.Arch, os: Target.Os, query: Target.Query) Target.Cpu {
27 _ = cross_target;26 _ = query;
28 var cpu = Target.Cpu{27 var cpu = Target.Cpu{
29 .arch = arch,28 .arch = arch,
30 .model = Target.Cpu.Model.generic(arch),29 .model = Target.Cpu.Model.generic(arch),
src/libc_installation.zig+1-1
...@@ -41,7 +41,7 @@ pub const LibCInstallation = struct {...@@ -41,7 +41,7 @@ pub const LibCInstallation = struct {
41 pub fn parse(41 pub fn parse(
42 allocator: Allocator,42 allocator: Allocator,
43 libc_file: []const u8,43 libc_file: []const u8,
44 target: std.zig.CrossTarget,44 target: std.Target.Query,
45 ) !LibCInstallation {45 ) !LibCInstallation {
46 var self: LibCInstallation = .{};46 var self: LibCInstallation = .{};
4747
src/main.zig+37-37
...@@ -2551,7 +2551,7 @@ fn buildOutputType(...@@ -2551,7 +2551,7 @@ fn buildOutputType(
2551 }2551 }
2552 };2552 };
25532553
2554 var target_parse_options: std.zig.CrossTarget.ParseOptions = .{2554 var target_parse_options: std.Target.Query.ParseOptions = .{
2555 .arch_os_abi = target_arch_os_abi,2555 .arch_os_abi = target_arch_os_abi,
2556 .cpu_features = target_mcpu,2556 .cpu_features = target_mcpu,
2557 .dynamic_linker = target_dynamic_linker,2557 .dynamic_linker = target_dynamic_linker,
...@@ -2563,7 +2563,7 @@ fn buildOutputType(...@@ -2563,7 +2563,7 @@ fn buildOutputType(
2563 if (llvm_m_args.items.len != 0) {2563 if (llvm_m_args.items.len != 0) {
2564 // If this returns null, we let it fall through to the case below which will2564 // If this returns null, we let it fall through to the case below which will
2565 // run the full parse function and do proper error handling.2565 // run the full parse function and do proper error handling.
2566 if (std.zig.CrossTarget.parseCpuArch(target_parse_options)) |cpu_arch| {2566 if (std.Target.Query.parseCpuArch(target_parse_options)) |cpu_arch| {
2567 var llvm_to_zig_name = std.StringHashMap([]const u8).init(gpa);2567 var llvm_to_zig_name = std.StringHashMap([]const u8).init(gpa);
2568 defer llvm_to_zig_name.deinit();2568 defer llvm_to_zig_name.deinit();
25692569
...@@ -2607,8 +2607,8 @@ fn buildOutputType(...@@ -2607,8 +2607,8 @@ fn buildOutputType(
2607 }2607 }
2608 }2608 }
26092609
2610 const cross_target = try parseCrossTargetOrReportFatalError(arena, target_parse_options);2610 const target_query = try parseTargetQueryOrReportFatalError(arena, target_parse_options);
2611 const target_info = try detectNativeTargetInfo(cross_target);2611 const target_info = try detectNativeTargetInfo(target_query);
26122612
2613 if (target_info.target.os.tag != .freestanding) {2613 if (target_info.target.os.tag != .freestanding) {
2614 if (ensure_libc_on_non_freestanding)2614 if (ensure_libc_on_non_freestanding)
...@@ -2695,13 +2695,13 @@ fn buildOutputType(...@@ -2695,13 +2695,13 @@ fn buildOutputType(
2695 }2695 }
26962696
2697 if (use_lld) |opt| {2697 if (use_lld) |opt| {
2698 if (opt and cross_target.isDarwin()) {2698 if (opt and target_query.isDarwin()) {
2699 fatal("LLD requested with Mach-O object format. Only the self-hosted linker is supported for this target.", .{});2699 fatal("LLD requested with Mach-O object format. Only the self-hosted linker is supported for this target.", .{});
2700 }2700 }
2701 }2701 }
27022702
2703 if (want_lto) |opt| {2703 if (want_lto) |opt| {
2704 if (opt and cross_target.isDarwin()) {2704 if (opt and target_query.isDarwin()) {
2705 fatal("LTO is not yet supported with the Mach-O object format. More details: https://github.com/ziglang/zig/issues/8680", .{});2705 fatal("LTO is not yet supported with the Mach-O object format. More details: https://github.com/ziglang/zig/issues/8680", .{});
2706 }2706 }
2707 }2707 }
...@@ -2771,7 +2771,7 @@ fn buildOutputType(...@@ -2771,7 +2771,7 @@ fn buildOutputType(
27712771
2772 var libc_installation: ?LibCInstallation = null;2772 var libc_installation: ?LibCInstallation = null;
2773 if (libc_paths_file) |paths_file| {2773 if (libc_paths_file) |paths_file| {
2774 libc_installation = LibCInstallation.parse(arena, paths_file, cross_target) catch |err| {2774 libc_installation = LibCInstallation.parse(arena, paths_file, target_query) catch |err| {
2775 fatal("unable to parse libc paths file at path {s}: {s}", .{ paths_file, @errorName(err) });2775 fatal("unable to parse libc paths file at path {s}: {s}", .{ paths_file, @errorName(err) });
2776 };2776 };
2777 }2777 }
...@@ -2835,7 +2835,7 @@ fn buildOutputType(...@@ -2835,7 +2835,7 @@ fn buildOutputType(
2835 // After this point, external_system_libs is used instead of system_libs.2835 // After this point, external_system_libs is used instead of system_libs.
28362836
2837 // Trigger native system library path detection if necessary.2837 // Trigger native system library path detection if necessary.
2838 if (sysroot == null and cross_target.isNativeOs() and cross_target.isNativeAbi() and2838 if (sysroot == null and target_query.isNativeOs() and target_query.isNativeAbi() and
2839 (external_system_libs.len != 0 or want_native_include_dirs))2839 (external_system_libs.len != 0 or want_native_include_dirs))
2840 {2840 {
2841 const paths = std.zig.system.NativePaths.detect(arena, target_info) catch |err| {2841 const paths = std.zig.system.NativePaths.detect(arena, target_info) catch |err| {
...@@ -2864,7 +2864,7 @@ fn buildOutputType(...@@ -2864,7 +2864,7 @@ fn buildOutputType(
2864 libc_installation = try LibCInstallation.findNative(.{2864 libc_installation = try LibCInstallation.findNative(.{
2865 .allocator = arena,2865 .allocator = arena,
2866 .verbose = true,2866 .verbose = true,
2867 .target = cross_target.toTarget(),2867 .target = target_query.toTarget(),
2868 });2868 });
28692869
2870 try lib_dirs.appendSlice(&.{ libc_installation.?.msvc_lib_dir.?, libc_installation.?.kernel32_lib_dir.? });2870 try lib_dirs.appendSlice(&.{ libc_installation.?.msvc_lib_dir.?, libc_installation.?.kernel32_lib_dir.? });
...@@ -3455,8 +3455,8 @@ fn buildOutputType(...@@ -3455,8 +3455,8 @@ fn buildOutputType(
3455 .global_cache_directory = global_cache_directory,3455 .global_cache_directory = global_cache_directory,
3456 .root_name = root_name,3456 .root_name = root_name,
3457 .target = target_info.target,3457 .target = target_info.target,
3458 .is_native_os = cross_target.isNativeOs(),3458 .is_native_os = target_query.isNativeOs(),
3459 .is_native_abi = cross_target.isNativeAbi(),3459 .is_native_abi = target_query.isNativeAbi(),
3460 .dynamic_linker = target_info.dynamic_linker.get(),3460 .dynamic_linker = target_info.dynamic_linker.get(),
3461 .sysroot = sysroot,3461 .sysroot = sysroot,
3462 .output_mode = output_mode,3462 .output_mode = output_mode,
...@@ -4013,16 +4013,16 @@ const ModuleDepIterator = struct {...@@ -4013,16 +4013,16 @@ const ModuleDepIterator = struct {
4013 }4013 }
4014};4014};
40154015
4016fn parseCrossTargetOrReportFatalError(4016fn parseTargetQueryOrReportFatalError(
4017 allocator: Allocator,4017 allocator: Allocator,
4018 opts: std.zig.CrossTarget.ParseOptions,4018 opts: std.Target.Query.ParseOptions,
4019) !std.zig.CrossTarget {4019) !std.Target.Query {
4020 var opts_with_diags = opts;4020 var opts_with_diags = opts;
4021 var diags: std.zig.CrossTarget.ParseOptions.Diagnostics = .{};4021 var diags: std.Target.Query.ParseOptions.Diagnostics = .{};
4022 if (opts_with_diags.diagnostics == null) {4022 if (opts_with_diags.diagnostics == null) {
4023 opts_with_diags.diagnostics = &diags;4023 opts_with_diags.diagnostics = &diags;
4024 }4024 }
4025 return std.zig.CrossTarget.parse(opts_with_diags) catch |err| switch (err) {4025 return std.Target.Query.parse(opts_with_diags) catch |err| switch (err) {
4026 error.UnknownCpuModel => {4026 error.UnknownCpuModel => {
4027 help: {4027 help: {
4028 var help_text = std.ArrayList(u8).init(allocator);4028 var help_text = std.ArrayList(u8).init(allocator);
...@@ -4666,9 +4666,9 @@ fn detectRcIncludeDirs(arena: Allocator, zig_lib_dir: []const u8, auto_includes:...@@ -4666,9 +4666,9 @@ fn detectRcIncludeDirs(arena: Allocator, zig_lib_dir: []const u8, auto_includes:
4666 while (true) {4666 while (true) {
4667 switch (cur_includes) {4667 switch (cur_includes) {
4668 .any, .msvc => {4668 .any, .msvc => {
4669 const cross_target = std.zig.CrossTarget.parse(.{ .arch_os_abi = "native-windows-msvc" }) catch unreachable;4669 const target_query = std.Target.Query.parse(.{ .arch_os_abi = "native-windows-msvc" }) catch unreachable;
4670 const target = cross_target.toTarget();4670 const target = target_query.toTarget();
4671 const is_native_abi = cross_target.isNativeAbi();4671 const is_native_abi = target_query.isNativeAbi();
4672 const detected_libc = Compilation.detectLibCIncludeDirs(arena, zig_lib_dir, target, is_native_abi, true, null) catch |err| {4672 const detected_libc = Compilation.detectLibCIncludeDirs(arena, zig_lib_dir, target, is_native_abi, true, null) catch |err| {
4673 if (cur_includes == .any) {4673 if (cur_includes == .any) {
4674 // fall back to mingw4674 // fall back to mingw
...@@ -4691,9 +4691,9 @@ fn detectRcIncludeDirs(arena: Allocator, zig_lib_dir: []const u8, auto_includes:...@@ -4691,9 +4691,9 @@ fn detectRcIncludeDirs(arena: Allocator, zig_lib_dir: []const u8, auto_includes:
4691 };4691 };
4692 },4692 },
4693 .gnu => {4693 .gnu => {
4694 const cross_target = std.zig.CrossTarget.parse(.{ .arch_os_abi = "native-windows-gnu" }) catch unreachable;4694 const target_query = std.Target.Query.parse(.{ .arch_os_abi = "native-windows-gnu" }) catch unreachable;
4695 const target = cross_target.toTarget();4695 const target = target_query.toTarget();
4696 const is_native_abi = cross_target.isNativeAbi();4696 const is_native_abi = target_query.isNativeAbi();
4697 const detected_libc = try Compilation.detectLibCIncludeDirs(arena, zig_lib_dir, target, is_native_abi, true, null);4697 const detected_libc = try Compilation.detectLibCIncludeDirs(arena, zig_lib_dir, target, is_native_abi, true, null);
4698 return .{4698 return .{
4699 .include_paths = detected_libc.libc_include_dir_list,4699 .include_paths = detected_libc.libc_include_dir_list,
...@@ -4754,7 +4754,7 @@ pub fn cmdLibC(gpa: Allocator, args: []const []const u8) !void {...@@ -4754,7 +4754,7 @@ pub fn cmdLibC(gpa: Allocator, args: []const []const u8) !void {
4754 }4754 }
4755 }4755 }
47564756
4757 const cross_target = try parseCrossTargetOrReportFatalError(gpa, .{4757 const target_query = try parseTargetQueryOrReportFatalError(gpa, .{
4758 .arch_os_abi = target_arch_os_abi,4758 .arch_os_abi = target_arch_os_abi,
4759 });4759 });
47604760
...@@ -4766,7 +4766,7 @@ pub fn cmdLibC(gpa: Allocator, args: []const []const u8) !void {...@@ -4766,7 +4766,7 @@ pub fn cmdLibC(gpa: Allocator, args: []const []const u8) !void {
4766 const libc_installation: ?*LibCInstallation = libc: {4766 const libc_installation: ?*LibCInstallation = libc: {
4767 if (input_file) |libc_file| {4767 if (input_file) |libc_file| {
4768 const libc = try arena.create(LibCInstallation);4768 const libc = try arena.create(LibCInstallation);
4769 libc.* = LibCInstallation.parse(arena, libc_file, cross_target) catch |err| {4769 libc.* = LibCInstallation.parse(arena, libc_file, target_query) catch |err| {
4770 fatal("unable to parse libc file at path {s}: {s}", .{ libc_file, @errorName(err) });4770 fatal("unable to parse libc file at path {s}: {s}", .{ libc_file, @errorName(err) });
4771 };4771 };
4772 break :libc libc;4772 break :libc libc;
...@@ -4781,8 +4781,8 @@ pub fn cmdLibC(gpa: Allocator, args: []const []const u8) !void {...@@ -4781,8 +4781,8 @@ pub fn cmdLibC(gpa: Allocator, args: []const []const u8) !void {
4781 };4781 };
4782 defer zig_lib_directory.handle.close();4782 defer zig_lib_directory.handle.close();
47834783
4784 const target = cross_target.toTarget();4784 const target = target_query.toTarget();
4785 const is_native_abi = cross_target.isNativeAbi();4785 const is_native_abi = target_query.isNativeAbi();
47864786
4787 const libc_dirs = Compilation.detectLibCIncludeDirs(4787 const libc_dirs = Compilation.detectLibCIncludeDirs(
4788 arena,4788 arena,
...@@ -4812,15 +4812,15 @@ pub fn cmdLibC(gpa: Allocator, args: []const []const u8) !void {...@@ -4812,15 +4812,15 @@ pub fn cmdLibC(gpa: Allocator, args: []const []const u8) !void {
4812 }4812 }
48134813
4814 if (input_file) |libc_file| {4814 if (input_file) |libc_file| {
4815 var libc = LibCInstallation.parse(gpa, libc_file, cross_target) catch |err| {4815 var libc = LibCInstallation.parse(gpa, libc_file, target_query) catch |err| {
4816 fatal("unable to parse libc file at path {s}: {s}", .{ libc_file, @errorName(err) });4816 fatal("unable to parse libc file at path {s}: {s}", .{ libc_file, @errorName(err) });
4817 };4817 };
4818 defer libc.deinit(gpa);4818 defer libc.deinit(gpa);
4819 } else {4819 } else {
4820 if (!cross_target.isNative()) {4820 if (!target_query.isNative()) {
4821 fatal("unable to detect libc for non-native target", .{});4821 fatal("unable to detect libc for non-native target", .{});
4822 }4822 }
4823 const target_info = try detectNativeTargetInfo(cross_target);4823 const target_info = try detectNativeTargetInfo(target_query);
48244824
4825 var libc = LibCInstallation.findNative(.{4825 var libc = LibCInstallation.findNative(.{
4826 .allocator = gpa,4826 .allocator = gpa,
...@@ -5113,8 +5113,8 @@ pub fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !voi...@@ -5113,8 +5113,8 @@ pub fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !voi
51135113
5114 gimmeMoreOfThoseSweetSweetFileDescriptors();5114 gimmeMoreOfThoseSweetSweetFileDescriptors();
51155115
5116 const cross_target: std.zig.CrossTarget = .{};5116 const target_query: std.Target.Query = .{};
5117 const target_info = try detectNativeTargetInfo(cross_target);5117 const target_info = try detectNativeTargetInfo(target_query);
51185118
5119 const exe_basename = try std.zig.binNameAlloc(arena, .{5119 const exe_basename = try std.zig.binNameAlloc(arena, .{
5120 .root_name = "build",5120 .root_name = "build",
...@@ -5283,8 +5283,8 @@ pub fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !voi...@@ -5283,8 +5283,8 @@ pub fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !voi
5283 .global_cache_directory = global_cache_directory,5283 .global_cache_directory = global_cache_directory,
5284 .root_name = "build",5284 .root_name = "build",
5285 .target = target_info.target,5285 .target = target_info.target,
5286 .is_native_os = cross_target.isNativeOs(),5286 .is_native_os = target_query.isNativeOs(),
5287 .is_native_abi = cross_target.isNativeAbi(),5287 .is_native_abi = target_query.isNativeAbi(),
5288 .dynamic_linker = target_info.dynamic_linker.get(),5288 .dynamic_linker = target_info.dynamic_linker.get(),
5289 .output_mode = .Exe,5289 .output_mode = .Exe,
5290 .main_mod = &main_mod,5290 .main_mod = &main_mod,
...@@ -6269,8 +6269,8 @@ test "fds" {...@@ -6269,8 +6269,8 @@ test "fds" {
6269 gimmeMoreOfThoseSweetSweetFileDescriptors();6269 gimmeMoreOfThoseSweetSweetFileDescriptors();
6270}6270}
62716271
6272fn detectNativeTargetInfo(cross_target: std.zig.CrossTarget) !std.zig.system.NativeTargetInfo {6272fn detectNativeTargetInfo(target_query: std.Target.Query) !std.zig.system.NativeTargetInfo {
6273 return std.zig.system.NativeTargetInfo.detect(cross_target);6273 return std.zig.system.NativeTargetInfo.detect(target_query);
6274}6274}
62756275
6276const usage_ast_check =6276const usage_ast_check =
...@@ -6672,8 +6672,8 @@ fn warnAboutForeignBinaries(...@@ -6672,8 +6672,8 @@ fn warnAboutForeignBinaries(
6672 target_info: *const std.zig.system.NativeTargetInfo,6672 target_info: *const std.zig.system.NativeTargetInfo,
6673 link_libc: bool,6673 link_libc: bool,
6674) !void {6674) !void {
6675 const host_cross_target: std.zig.CrossTarget = .{};6675 const host_query: std.Target.Query = .{};
6676 const host_target_info = try detectNativeTargetInfo(host_cross_target);6676 const host_target_info = try detectNativeTargetInfo(host_query);
66776677
6678 switch (host_target_info.getExternalExecutor(target_info, .{ .link_libc = link_libc })) {6678 switch (host_target_info.getExternalExecutor(target_info, .{ .link_libc = link_libc })) {
6679 .native => return,6679 .native => return,
test/cbe.zig+1-1
...@@ -5,7 +5,7 @@ const nl = if (@import("builtin").os.tag == .windows) "\r\n" else "\n";...@@ -5,7 +5,7 @@ const nl = if (@import("builtin").os.tag == .windows) "\r\n" else "\n";
5pub fn addCases(ctx: *Cases, b: *std.Build) !void {5pub fn addCases(ctx: *Cases, b: *std.Build) !void {
6 // These tests should work with all platforms, but we're using linux_x64 for6 // These tests should work with all platforms, but we're using linux_x64 for
7 // now for consistency. Will be expanded eventually.7 // now for consistency. Will be expanded eventually.
8 const linux_x64: std.zig.CrossTarget = .{8 const linux_x64: std.Target.Query = .{
9 .cpu_arch = .x86_64,9 .cpu_arch = .x86_64,
10 .os_tag = .linux,10 .os_tag = .linux,
11 };11 };
test/link/elf.zig-1
...@@ -3833,7 +3833,6 @@ const link = @import("link.zig");...@@ -3833,7 +3833,6 @@ const link = @import("link.zig");
3833const std = @import("std");3833const std = @import("std");
38343834
3835const Build = std.Build;3835const Build = std.Build;
3836const CrossTarget = std.zig.CrossTarget;
3837const Options = link.Options;3836const Options = link.Options;
3838const Step = Build.Step;3837const Step = Build.Step;
3839const WriteFile = Step.WriteFile;3838const WriteFile = Step.WriteFile;
test/link/glibc_compat/build.zig+1-1
...@@ -8,7 +8,7 @@ pub fn build(b: *std.Build) void {...@@ -8,7 +8,7 @@ pub fn build(b: *std.Build) void {
8 const exe = b.addExecutable(.{8 const exe = b.addExecutable(.{
9 .name = t,9 .name = t,
10 .root_source_file = .{ .path = "main.c" },10 .root_source_file = .{ .path = "main.c" },
11 .target = b.resolveTargetQuery(std.zig.CrossTarget.parse(11 .target = b.resolveTargetQuery(std.Target.Query.parse(
12 .{ .arch_os_abi = t },12 .{ .arch_os_abi = t },
13 ) catch unreachable),13 ) catch unreachable),
14 });14 });
test/link/link.zig-1
...@@ -199,7 +199,6 @@ const std = @import("std");...@@ -199,7 +199,6 @@ const std = @import("std");
199199
200const Build = std.Build;200const Build = std.Build;
201const Compile = Step.Compile;201const Compile = Step.Compile;
202const CrossTarget = std.zig.CrossTarget;
203const Run = Step.Run;202const Run = Step.Run;
204const Step = Build.Step;203const Step = Build.Step;
205const WriteFile = Step.WriteFile;204const WriteFile = Step.WriteFile;
test/link/macho.zig-2
...@@ -95,7 +95,5 @@ const addExecutable = link.addExecutable;...@@ -95,7 +95,5 @@ const addExecutable = link.addExecutable;
95const expectLinkErrors = link.expectLinkErrors;95const expectLinkErrors = link.expectLinkErrors;
96const link = @import("link.zig");96const link = @import("link.zig");
97const std = @import("std");97const std = @import("std");
98
99const CrossTarget = std.zig.CrossTarget;
100const Options = link.Options;98const Options = link.Options;
101const Step = std.Build.Step;99const Step = std.Build.Step;
test/llvm_targets.zig+1-1
...@@ -1,7 +1,7 @@...@@ -1,7 +1,7 @@
1const std = @import("std");1const std = @import("std");
2const Cases = @import("src/Cases.zig");2const Cases = @import("src/Cases.zig");
33
4const targets = [_]std.zig.CrossTarget{4const targets = [_]std.Target.Query{
5 .{ .cpu_arch = .aarch64, .os_tag = .freestanding, .abi = .none },5 .{ .cpu_arch = .aarch64, .os_tag = .freestanding, .abi = .none },
6 .{ .cpu_arch = .aarch64, .os_tag = .ios, .abi = .none },6 .{ .cpu_arch = .aarch64, .os_tag = .ios, .abi = .none },
7 .{ .cpu_arch = .aarch64, .os_tag = .ios, .abi = .simulator },7 .{ .cpu_arch = .aarch64, .os_tag = .ios, .abi = .simulator },
test/src/Cases.zig+6-6
...@@ -188,7 +188,7 @@ pub fn exe(ctx: *Cases, name: []const u8, target: std.Build.ResolvedTarget) *Cas...@@ -188,7 +188,7 @@ pub fn exe(ctx: *Cases, name: []const u8, target: std.Build.ResolvedTarget) *Cas
188 return ctx.addExe(name, target);188 return ctx.addExe(name, target);
189}189}
190190
191pub fn exeFromCompiledC(ctx: *Cases, name: []const u8, target_query: std.zig.CrossTarget, b: *std.Build) *Case {191pub fn exeFromCompiledC(ctx: *Cases, name: []const u8, target_query: std.Target.Query, b: *std.Build) *Case {
192 var adjusted_query = target_query;192 var adjusted_query = target_query;
193 adjusted_query.ofmt = .c;193 adjusted_query.ofmt = .c;
194 ctx.cases.append(Case{194 ctx.cases.append(Case{
...@@ -423,7 +423,7 @@ fn addFromDirInner(...@@ -423,7 +423,7 @@ fn addFromDirInner(
423 var manifest = try TestManifest.parse(ctx.arena, src);423 var manifest = try TestManifest.parse(ctx.arena, src);
424424
425 const backends = try manifest.getConfigForKeyAlloc(ctx.arena, "backend", Backend);425 const backends = try manifest.getConfigForKeyAlloc(ctx.arena, "backend", Backend);
426 const targets = try manifest.getConfigForKeyAlloc(ctx.arena, "target", std.zig.CrossTarget);426 const targets = try manifest.getConfigForKeyAlloc(ctx.arena, "target", std.Target.Query);
427 const c_frontends = try manifest.getConfigForKeyAlloc(ctx.arena, "c_frontend", CFrontend);427 const c_frontends = try manifest.getConfigForKeyAlloc(ctx.arena, "c_frontend", CFrontend);
428 const is_test = try manifest.getConfigForKeyAssertSingle("is_test", bool);428 const is_test = try manifest.getConfigForKeyAssertSingle("is_test", bool);
429 const link_libc = try manifest.getConfigForKeyAssertSingle("link_libc", bool);429 const link_libc = try manifest.getConfigForKeyAssertSingle("link_libc", bool);
...@@ -1160,9 +1160,9 @@ const TestManifest = struct {...@@ -1160,9 +1160,9 @@ const TestManifest = struct {
1160 }1160 }
11611161
1162 fn getDefaultParser(comptime T: type) ParseFn(T) {1162 fn getDefaultParser(comptime T: type) ParseFn(T) {
1163 if (T == std.zig.CrossTarget) return struct {1163 if (T == std.Target.Query) return struct {
1164 fn parse(str: []const u8) anyerror!T {1164 fn parse(str: []const u8) anyerror!T {
1165 return std.zig.CrossTarget.parse(.{ .arch_os_abi = str });1165 return std.Target.Query.parse(.{ .arch_os_abi = str });
1166 }1166 }
1167 }.parse;1167 }.parse;
11681168
...@@ -1287,7 +1287,7 @@ pub fn main() !void {...@@ -1287,7 +1287,7 @@ pub fn main() !void {
12871287
1288 if (cases.items.len == 0) {1288 if (cases.items.len == 0) {
1289 const backends = try manifest.getConfigForKeyAlloc(arena, "backend", Backend);1289 const backends = try manifest.getConfigForKeyAlloc(arena, "backend", Backend);
1290 const targets = try manifest.getConfigForKeyAlloc(arena, "target", std.zig.CrossTarget);1290 const targets = try manifest.getConfigForKeyAlloc(arena, "target", std.Target.Query);
1291 const c_frontends = try manifest.getConfigForKeyAlloc(ctx.arena, "c_frontend", CFrontend);1291 const c_frontends = try manifest.getConfigForKeyAlloc(ctx.arena, "c_frontend", CFrontend);
1292 const is_test = try manifest.getConfigForKeyAssertSingle("is_test", bool);1292 const is_test = try manifest.getConfigForKeyAssertSingle("is_test", bool);
1293 const link_libc = try manifest.getConfigForKeyAssertSingle("link_libc", bool);1293 const link_libc = try manifest.getConfigForKeyAssertSingle("link_libc", bool);
...@@ -1385,7 +1385,7 @@ pub fn main() !void {...@@ -1385,7 +1385,7 @@ pub fn main() !void {
1385 return runCases(&ctx, zig_exe_path);1385 return runCases(&ctx, zig_exe_path);
1386}1386}
13871387
1388fn resolveTargetQuery(query: std.zig.CrossTarget) std.Build.ResolvedTarget {1388fn resolveTargetQuery(query: std.Target.Query) std.Build.ResolvedTarget {
1389 const result = std.zig.system.NativeTargetInfo.detect(query) catch1389 const result = std.zig.system.NativeTargetInfo.detect(query) catch
1390 @panic("unable to resolve target query");1390 @panic("unable to resolve target query");
13911391
test/src/translate_c.zig+2-3
...@@ -5,7 +5,6 @@ const ArrayList = std.ArrayList;...@@ -5,7 +5,6 @@ const ArrayList = std.ArrayList;
5const fmt = std.fmt;5const fmt = std.fmt;
6const mem = std.mem;6const mem = std.mem;
7const fs = std.fs;7const fs = std.fs;
8const CrossTarget = std.zig.CrossTarget;
98
10pub const TranslateCContext = struct {9pub const TranslateCContext = struct {
11 b: *std.Build,10 b: *std.Build,
...@@ -18,7 +17,7 @@ pub const TranslateCContext = struct {...@@ -18,7 +17,7 @@ pub const TranslateCContext = struct {
18 sources: ArrayList(SourceFile),17 sources: ArrayList(SourceFile),
19 expected_lines: ArrayList([]const u8),18 expected_lines: ArrayList([]const u8),
20 allow_warnings: bool,19 allow_warnings: bool,
21 target: CrossTarget = .{},20 target: std.Target.Query = .{},
2221
23 const SourceFile = struct {22 const SourceFile = struct {
24 filename: []const u8,23 filename: []const u8,
...@@ -74,7 +73,7 @@ pub const TranslateCContext = struct {...@@ -74,7 +73,7 @@ pub const TranslateCContext = struct {
74 pub fn addWithTarget(73 pub fn addWithTarget(
75 self: *TranslateCContext,74 self: *TranslateCContext,
76 name: []const u8,75 name: []const u8,
77 target: CrossTarget,76 target: std.Target.Query,
78 source: []const u8,77 source: []const u8,
79 expected_lines: []const []const u8,78 expected_lines: []const []const u8,
80 ) void {79 ) void {
test/standalone.zig+1-1
...@@ -2,7 +2,7 @@ pub const SimpleCase = struct {...@@ -2,7 +2,7 @@ pub const SimpleCase = struct {
2 src_path: []const u8,2 src_path: []const u8,
3 link_libc: bool = false,3 link_libc: bool = false,
4 all_modes: bool = false,4 all_modes: bool = false,
5 target: std.zig.CrossTarget = .{},5 target: std.Target.Query = .{},
6 is_test: bool = false,6 is_test: bool = false,
7 is_exe: bool = true,7 is_exe: bool = true,
8 /// Run only on this OS.8 /// Run only on this OS.
test/standalone/windows_resources/build.zig+3-3
...@@ -4,17 +4,17 @@ pub fn build(b: *std.Build) void {...@@ -4,17 +4,17 @@ pub fn build(b: *std.Build) void {
4 const test_step = b.step("test", "Test it");4 const test_step = b.step("test", "Test it");
5 b.default_step = test_step;5 b.default_step = test_step;
66
7 const cross_target = b.resolveTargetQuery(.{7 const target = b.resolveTargetQuery(.{
8 .cpu_arch = .x86_64,8 .cpu_arch = .x86_64,
9 .os_tag = .windows,9 .os_tag = .windows,
10 .abi = .gnu,10 .abi = .gnu,
11 });11 });
1212
13 add(b, b.host, .any, test_step);13 add(b, b.host, .any, test_step);
14 add(b, cross_target, .any, test_step);14 add(b, target, .any, test_step);
1515
16 add(b, b.host, .gnu, test_step);16 add(b, b.host, .gnu, test_step);
17 add(b, cross_target, .gnu, test_step);17 add(b, target, .gnu, test_step);
18}18}
1919
20fn add(20fn add(
test/tests.zig+6-6
...@@ -21,7 +21,7 @@ pub const CompareOutputContext = @import("src/CompareOutput.zig");...@@ -21,7 +21,7 @@ pub const CompareOutputContext = @import("src/CompareOutput.zig");
21pub const StackTracesContext = @import("src/StackTrace.zig");21pub const StackTracesContext = @import("src/StackTrace.zig");
2222
23const TestTarget = struct {23const TestTarget = struct {
24 target: std.zig.CrossTarget = .{},24 target: std.Target.Query = .{},
25 optimize_mode: std.builtin.OptimizeMode = .Debug,25 optimize_mode: std.builtin.OptimizeMode = .Debug,
26 link_libc: ?bool = null,26 link_libc: ?bool = null,
27 single_threaded: ?bool = null,27 single_threaded: ?bool = null,
...@@ -145,7 +145,7 @@ const test_targets = blk: {...@@ -145,7 +145,7 @@ const test_targets = blk: {
145 //},145 //},
146 // https://github.com/ziglang/zig/issues/13623146 // https://github.com/ziglang/zig/issues/13623
147 //.{147 //.{
148 // .target = std.zig.CrossTarget.parse(.{148 // .target = std.Target.Query.parse(.{
149 // .arch_os_abi = "arm-linux-none",149 // .arch_os_abi = "arm-linux-none",
150 // .cpu_features = "generic+v8a",150 // .cpu_features = "generic+v8a",
151 // }) catch unreachable,151 // }) catch unreachable,
...@@ -286,13 +286,13 @@ const test_targets = blk: {...@@ -286,13 +286,13 @@ const test_targets = blk: {
286 },286 },
287287
288 .{288 .{
289 .target = std.zig.CrossTarget.parse(.{289 .target = std.Target.Query.parse(.{
290 .arch_os_abi = "arm-linux-none",290 .arch_os_abi = "arm-linux-none",
291 .cpu_features = "generic+v8a",291 .cpu_features = "generic+v8a",
292 }) catch unreachable,292 }) catch unreachable,
293 },293 },
294 .{294 .{
295 .target = std.zig.CrossTarget.parse(.{295 .target = std.Target.Query.parse(.{
296 .arch_os_abi = "arm-linux-musleabihf",296 .arch_os_abi = "arm-linux-musleabihf",
297 .cpu_features = "generic+v8a",297 .cpu_features = "generic+v8a",
298 }) catch unreachable,298 }) catch unreachable,
...@@ -300,7 +300,7 @@ const test_targets = blk: {...@@ -300,7 +300,7 @@ const test_targets = blk: {
300 },300 },
301 // https://github.com/ziglang/zig/issues/3287301 // https://github.com/ziglang/zig/issues/3287
302 //.{302 //.{
303 // .target = std.zig.CrossTarget.parse(.{303 // .target = std.Target.Query.parse(.{
304 // .arch_os_abi = "arm-linux-gnueabihf",304 // .arch_os_abi = "arm-linux-gnueabihf",
305 // .cpu_features = "generic+v8a",305 // .cpu_features = "generic+v8a",
306 // }) catch unreachable,306 // }) catch unreachable,
...@@ -494,7 +494,7 @@ const test_targets = blk: {...@@ -494,7 +494,7 @@ const test_targets = blk: {
494};494};
495495
496const CAbiTarget = struct {496const CAbiTarget = struct {
497 target: std.zig.CrossTarget = .{},497 target: std.Target.Query = .{},
498 use_llvm: ?bool = null,498 use_llvm: ?bool = null,
499 use_lld: ?bool = null,499 use_lld: ?bool = null,
500 pic: ?bool = null,500 pic: ?bool = null,
test/translate_c.zig+2-3
...@@ -1,7 +1,6 @@...@@ -1,7 +1,6 @@
1const std = @import("std");1const std = @import("std");
2const builtin = @import("builtin");2const builtin = @import("builtin");
3const tests = @import("tests.zig");3const tests = @import("tests.zig");
4const CrossTarget = std.zig.CrossTarget;
54
6// ********************************************************5// ********************************************************
7// * *6// * *
...@@ -1846,7 +1845,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -1846,7 +1845,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
1846 \\pub extern fn foo5(a: [*c]f32) callconv(.Thiscall) void;1845 \\pub extern fn foo5(a: [*c]f32) callconv(.Thiscall) void;
1847 });1846 });
18481847
1849 cases.addWithTarget("Calling convention", CrossTarget.parse(.{1848 cases.addWithTarget("Calling convention", std.Target.Query.parse(.{
1850 .arch_os_abi = "arm-linux-none",1849 .arch_os_abi = "arm-linux-none",
1851 .cpu_features = "generic+v8_5a",1850 .cpu_features = "generic+v8_5a",
1852 }) catch unreachable,1851 }) catch unreachable,
...@@ -1857,7 +1856,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -1857,7 +1856,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
1857 \\pub extern fn foo2(a: [*c]f32) callconv(.AAPCSVFP) void;1856 \\pub extern fn foo2(a: [*c]f32) callconv(.AAPCSVFP) void;
1858 });1857 });
18591858
1860 cases.addWithTarget("Calling convention", CrossTarget.parse(.{1859 cases.addWithTarget("Calling convention", std.Target.Query.parse(.{
1861 .arch_os_abi = "aarch64-linux-none",1860 .arch_os_abi = "aarch64-linux-none",
1862 .cpu_features = "generic+v8_5a",1861 .cpu_features = "generic+v8_5a",
1863 }) catch unreachable,1862 }) catch unreachable,