| author | |
| committer | |
| log | 3179f58c414b5e4845b9bf3acdf276fe8e2b88a0 |
| tree | 23d8f051385f7948aa8c97ece358fdbe35b86803 |
| parent | 67d48b94d601521e15dd44c8789b1f528d09f10c |
25 files changed, 997 insertions(+), 1004 deletions(-)
CMakeLists.txt+1-1| ... | ... | @@ -481,6 +481,7 @@ set(ZIG_STAGE2_SOURCES |
| 481 | 481 | "${CMAKE_SOURCE_DIR}/lib/std/start.zig" |
| 482 | 482 | "${CMAKE_SOURCE_DIR}/lib/std/std.zig" |
| 483 | 483 | "${CMAKE_SOURCE_DIR}/lib/std/Target.zig" |
| 484 | "${CMAKE_SOURCE_DIR}/lib/std/Target/Query.zig" | |
| 484 | 485 | "${CMAKE_SOURCE_DIR}/lib/std/Target/aarch64.zig" |
| 485 | 486 | "${CMAKE_SOURCE_DIR}/lib/std/Target/amdgpu.zig" |
| 486 | 487 | "${CMAKE_SOURCE_DIR}/lib/std/Target/arm.zig" |
| ... | ... | @@ -508,7 +509,6 @@ set(ZIG_STAGE2_SOURCES |
| 508 | 509 | "${CMAKE_SOURCE_DIR}/lib/std/zig.zig" |
| 509 | 510 | "${CMAKE_SOURCE_DIR}/lib/std/zig/Ast.zig" |
| 510 | 511 | "${CMAKE_SOURCE_DIR}/lib/std/zig/AstRlAnnotate.zig" |
| 511 | "${CMAKE_SOURCE_DIR}/lib/std/zig/CrossTarget.zig" | |
| 512 | 512 | "${CMAKE_SOURCE_DIR}/lib/std/zig/c_builtins.zig" |
| 513 | 513 | "${CMAKE_SOURCE_DIR}/lib/std/zig/Parse.zig" |
| 514 | 514 | "${CMAKE_SOURCE_DIR}/lib/std/zig/render.zig" |
lib/std/Build.zig+19-19| ... | ... | @@ -10,11 +10,11 @@ const log = std.log; |
| 10 | 10 | const ArrayList = std.ArrayList; |
| 11 | 11 | const StringHashMap = std.StringHashMap; |
| 12 | 12 | const Allocator = mem.Allocator; |
| 13 | const Target = std.Target; | |
| 13 | 14 | const process = std.process; |
| 14 | 15 | const EnvMap = std.process.EnvMap; |
| 15 | 16 | const fmt_lib = std.fmt; |
| 16 | 17 | const File = std.fs.File; |
| 17 | const TargetQuery = std.zig.CrossTarget; | |
| 18 | 18 | const Sha256 = std.crypto.hash.sha2.Sha256; |
| 19 | 19 | const Build = @This(); |
| 20 | 20 | |
| ... | ... | @@ -375,7 +375,7 @@ fn userInputOptionsFromArgs(allocator: Allocator, args: anytype) UserInputOption |
| 375 | 375 | const v = @field(args, field.name); |
| 376 | 376 | const T = @TypeOf(v); |
| 377 | 377 | switch (T) { |
| 378 | TargetQuery => { | |
| 378 | Target.Query => { | |
| 379 | 379 | user_input_options.put(field.name, .{ |
| 380 | 380 | .name = field.name, |
| 381 | 381 | .value = .{ .scalar = v.zigTriple(allocator) catch @panic("OOM") }, |
| ... | ... | @@ -1195,9 +1195,9 @@ pub fn standardOptimizeOption(self: *Build, options: StandardOptimizeOptionOptio |
| 1195 | 1195 | } |
| 1196 | 1196 | |
| 1197 | 1197 | pub const StandardTargetOptionsArgs = struct { |
| 1198 | whitelist: ?[]const TargetQuery = null, | |
| 1198 | whitelist: ?[]const Target.Query = null, | |
| 1199 | 1199 | |
| 1200 | default_target: TargetQuery = .{}, | |
| 1200 | default_target: Target.Query = .{}, | |
| 1201 | 1201 | }; |
| 1202 | 1202 | |
| 1203 | 1203 | /// Exposes standard `zig build` options for choosing a target and additionally |
| ... | ... | @@ -1208,7 +1208,7 @@ pub fn standardTargetOptions(b: *Build, args: StandardTargetOptionsArgs) Resolve |
| 1208 | 1208 | } |
| 1209 | 1209 | |
| 1210 | 1210 | /// Exposes standard `zig build` options for choosing a target. |
| 1211 | pub fn standardTargetOptionsQueryOnly(self: *Build, args: StandardTargetOptionsArgs) TargetQuery { | |
| 1211 | pub fn standardTargetOptionsQueryOnly(self: *Build, args: StandardTargetOptionsArgs) Target.Query { | |
| 1212 | 1212 | const maybe_triple = self.option( |
| 1213 | 1213 | []const u8, |
| 1214 | 1214 | "target", |
| ... | ... | @@ -1222,8 +1222,8 @@ pub fn standardTargetOptionsQueryOnly(self: *Build, args: StandardTargetOptionsA |
| 1222 | 1222 | |
| 1223 | 1223 | const triple = maybe_triple orelse "native"; |
| 1224 | 1224 | |
| 1225 | var diags: TargetQuery.ParseOptions.Diagnostics = .{}; | |
| 1226 | const selected_target = TargetQuery.parse(.{ | |
| 1225 | var diags: Target.Query.ParseOptions.Diagnostics = .{}; | |
| 1226 | const selected_target = Target.Query.parse(.{ | |
| 1227 | 1227 | .arch_os_abi = triple, |
| 1228 | 1228 | .cpu_features = mcpu, |
| 1229 | 1229 | .diagnostics = &diags, |
| ... | ... | @@ -1260,7 +1260,7 @@ pub fn standardTargetOptionsQueryOnly(self: *Build, args: StandardTargetOptionsA |
| 1260 | 1260 | \\Available operating systems: |
| 1261 | 1261 | \\ |
| 1262 | 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 | 1264 | log.err(" {s}", .{field.name}); |
| 1265 | 1265 | } |
| 1266 | 1266 | self.markInvalidUserInput(); |
| ... | ... | @@ -1279,7 +1279,7 @@ pub fn standardTargetOptionsQueryOnly(self: *Build, args: StandardTargetOptionsA |
| 1279 | 1279 | // Make sure it's a match of one of the list. |
| 1280 | 1280 | var mismatch_triple = true; |
| 1281 | 1281 | var mismatch_cpu_features = true; |
| 1282 | var whitelist_item: TargetQuery = .{}; | |
| 1282 | var whitelist_item: Target.Query = .{}; | |
| 1283 | 1283 | for (list) |t| { |
| 1284 | 1284 | mismatch_cpu_features = true; |
| 1285 | 1285 | mismatch_triple = true; |
| ... | ... | @@ -1316,7 +1316,7 @@ pub fn standardTargetOptionsQueryOnly(self: *Build, args: StandardTargetOptionsA |
| 1316 | 1316 | var populated_cpu_features = whitelist_cpu.model.features; |
| 1317 | 1317 | populated_cpu_features.populateDependencies(all_features); |
| 1318 | 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 | 1320 | const in_cpu_set = populated_cpu_features.isEnabled(i); |
| 1321 | 1321 | if (in_cpu_set) { |
| 1322 | 1322 | log.err("{s} ", .{feature.name}); |
| ... | ... | @@ -1324,7 +1324,7 @@ pub fn standardTargetOptionsQueryOnly(self: *Build, args: StandardTargetOptionsA |
| 1324 | 1324 | } |
| 1325 | 1325 | log.err(" Remove: ", .{}); |
| 1326 | 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 | 1328 | const in_cpu_set = populated_cpu_features.isEnabled(i); |
| 1329 | 1329 | const in_actual_set = selected_cpu.features.isEnabled(i); |
| 1330 | 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 | 1587 | |
| 1588 | 1588 | pub fn findProgram(self: *Build, names: []const []const u8, paths: []const []const u8) ![]const u8 { |
| 1589 | 1589 | // TODO report error for ambiguous situations |
| 1590 | const exe_extension = @as(TargetQuery, .{}).exeFileExt(); | |
| 1590 | const exe_extension = @as(Target.Query, .{}).exeFileExt(); | |
| 1591 | 1591 | for (self.search_prefixes.items) |search_prefix| { |
| 1592 | 1592 | for (names) |name| { |
| 1593 | 1593 | if (fs.path.isAbsolute(name)) { |
| ... | ... | @@ -2064,7 +2064,7 @@ pub const InstalledFile = struct { |
| 2064 | 2064 | } |
| 2065 | 2065 | }; |
| 2066 | 2066 | |
| 2067 | pub fn serializeCpu(allocator: Allocator, cpu: std.Target.Cpu) ![]const u8 { | |
| 2067 | pub fn serializeCpu(allocator: Allocator, cpu: Target.Cpu) ![]const u8 { | |
| 2068 | 2068 | // TODO this logic can disappear if cpu model + features becomes part of the target triple |
| 2069 | 2069 | const all_features = cpu.arch.allFeaturesList(); |
| 2070 | 2070 | var populated_cpu_features = cpu.model.features; |
| ... | ... | @@ -2078,7 +2078,7 @@ pub fn serializeCpu(allocator: Allocator, cpu: std.Target.Cpu) ![]const u8 { |
| 2078 | 2078 | try mcpu_buffer.appendSlice(cpu.model.name); |
| 2079 | 2079 | |
| 2080 | 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 | 2082 | const in_cpu_set = populated_cpu_features.isEnabled(i); |
| 2083 | 2083 | const in_actual_set = cpu.features.isEnabled(i); |
| 2084 | 2084 | if (in_cpu_set and !in_actual_set) { |
| ... | ... | @@ -2127,9 +2127,9 @@ pub fn hex64(x: u64) [16]u8 { |
| 2127 | 2127 | /// target. The query is kept because the Zig toolchain needs to know which parts |
| 2128 | 2128 | /// of the target are "native". This can apply to the CPU, the OS, or even the ABI. |
| 2129 | 2129 | pub const ResolvedTarget = struct { |
| 2130 | query: TargetQuery, | |
| 2131 | target: std.Target, | |
| 2132 | dynamic_linker: std.Target.DynamicLinker, | |
| 2130 | query: Target.Query, | |
| 2131 | target: Target, | |
| 2132 | dynamic_linker: Target.DynamicLinker, | |
| 2133 | 2133 | |
| 2134 | 2134 | pub fn toNativeTargetInfo(self: ResolvedTarget) std.zig.system.NativeTargetInfo { |
| 2135 | 2135 | return .{ |
| ... | ... | @@ -2141,7 +2141,7 @@ pub const ResolvedTarget = struct { |
| 2141 | 2141 | |
| 2142 | 2142 | /// Converts a target query into a fully resolved target that can be passed to |
| 2143 | 2143 | /// various parts of the API. |
| 2144 | pub fn resolveTargetQuery(b: *Build, query: TargetQuery) ResolvedTarget { | |
| 2144 | pub fn resolveTargetQuery(b: *Build, query: Target.Query) ResolvedTarget { | |
| 2145 | 2145 | // This context will likely be required in the future when the target is |
| 2146 | 2146 | // resolved via a WASI API or via the build protocol. |
| 2147 | 2147 | _ = b; |
| ... | ... | @@ -2156,7 +2156,7 @@ pub fn resolveTargetQuery(b: *Build, query: TargetQuery) ResolvedTarget { |
| 2156 | 2156 | }; |
| 2157 | 2157 | } |
| 2158 | 2158 | |
| 2159 | pub fn wantSharedLibSymLinks(target: std.Target) bool { | |
| 2159 | pub fn wantSharedLibSymLinks(target: Target) bool { | |
| 2160 | 2160 | return target.os.tag != .windows; |
| 2161 | 2161 | } |
| 2162 | 2162 |
lib/std/Build/Step/Compile.zig-1| ... | ... | @@ -9,7 +9,6 @@ const StringHashMap = std.StringHashMap; |
| 9 | 9 | const Sha256 = std.crypto.hash.sha2.Sha256; |
| 10 | 10 | const Allocator = mem.Allocator; |
| 11 | 11 | const Step = std.Build.Step; |
| 12 | const CrossTarget = std.zig.CrossTarget; | |
| 13 | 12 | const NativeTargetInfo = std.zig.system.NativeTargetInfo; |
| 14 | 13 | const LazyPath = std.Build.LazyPath; |
| 15 | 14 | const PkgConfigPkg = std.Build.PkgConfigPkg; |
lib/std/Target.zig+3-1| ... | ... | @@ -3,6 +3,8 @@ os: Os, |
| 3 | 3 | abi: Abi, |
| 4 | 4 | ofmt: ObjectFormat, |
| 5 | 5 | |
| 6 | pub const Query = @import("Target/Query.zig"); | |
| 7 | ||
| 6 | 8 | pub const Os = struct { |
| 7 | 9 | tag: Tag, |
| 8 | 10 | version_range: VersionRange, |
| ... | ... | @@ -1387,7 +1389,7 @@ pub const Cpu = struct { |
| 1387 | 1389 | }; |
| 1388 | 1390 | |
| 1389 | 1391 | pub 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 | } |
| 1392 | 1394 | |
| 1393 | 1395 | pub 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. | |
| 7 | cpu_arch: ?Target.Cpu.Arch = null, | |
| 8 | ||
| 9 | cpu_model: CpuModel = CpuModel.determined_by_cpu_arch, | |
| 10 | ||
| 11 | /// Sparse set of CPU features to add to the set from `cpu_model`. | |
| 12 | cpu_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`. | |
| 15 | cpu_features_sub: Target.Cpu.Feature.Set = Target.Cpu.Feature.Set.empty, | |
| 16 | ||
| 17 | /// `null` means native. | |
| 18 | os_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. | |
| 22 | os_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. | |
| 26 | os_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. | |
| 30 | glibc_version: ?SemanticVersion = null, | |
| 31 | ||
| 32 | /// `null` means the native C ABI, if `os_tag` is native, otherwise it means the default C ABI. | |
| 33 | abi: ?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`. | |
| 37 | dynamic_linker: DynamicLinker = DynamicLinker{}, | |
| 38 | ||
| 39 | /// `null` means default for the cpu/arch/os combo. | |
| 40 | ofmt: ?Target.ObjectFormat = null, | |
| 41 | ||
| 42 | pub 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 | ||
| 56 | pub const OsVersion = union(enum) { | |
| 57 | none: void, | |
| 58 | semver: SemanticVersion, | |
| 59 | windows: Target.Os.WindowsVersion, | |
| 60 | }; | |
| 61 | ||
| 62 | pub const SemanticVersion = std.SemanticVersion; | |
| 63 | ||
| 64 | pub const DynamicLinker = Target.DynamicLinker; | |
| 65 | ||
| 66 | pub 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 | ||
| 99 | fn 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`. | |
| 168 | pub 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 | ||
| 177 | pub 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 | ||
| 230 | pub 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`. | |
| 340 | pub 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. | |
| 354 | pub 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 | ||
| 375 | test 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`. | |
| 383 | pub 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 | ||
| 414 | pub fn getCpuArch(self: Query) Target.Cpu.Arch { | |
| 415 | return self.cpu_arch orelse builtin.cpu.arch; | |
| 416 | } | |
| 417 | ||
| 418 | pub 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 | ||
| 425 | pub fn getCpuFeatures(self: Query) Target.Cpu.Feature.Set { | |
| 426 | return self.getCpu().features; | |
| 427 | } | |
| 428 | ||
| 429 | /// TODO deprecated, use `std.zig.system.NativeTargetInfo.detect`. | |
| 430 | pub 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 | ||
| 462 | pub 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`. | |
| 467 | pub 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`. | |
| 475 | pub 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`. | |
| 483 | pub 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 | ||
| 496 | pub fn isFreeBSD(self: Query) bool { | |
| 497 | return self.getOsTag() == .freebsd; | |
| 498 | } | |
| 499 | ||
| 500 | pub fn isDarwin(self: Query) bool { | |
| 501 | return self.getOsTag().isDarwin(); | |
| 502 | } | |
| 503 | ||
| 504 | pub fn isNetBSD(self: Query) bool { | |
| 505 | return self.getOsTag() == .netbsd; | |
| 506 | } | |
| 507 | ||
| 508 | pub fn isOpenBSD(self: Query) bool { | |
| 509 | return self.getOsTag() == .openbsd; | |
| 510 | } | |
| 511 | ||
| 512 | pub fn isUefi(self: Query) bool { | |
| 513 | return self.getOsTag() == .uefi; | |
| 514 | } | |
| 515 | ||
| 516 | pub fn isDragonFlyBSD(self: Query) bool { | |
| 517 | return self.getOsTag() == .dragonfly; | |
| 518 | } | |
| 519 | ||
| 520 | pub fn isLinux(self: Query) bool { | |
| 521 | return self.getOsTag() == .linux; | |
| 522 | } | |
| 523 | ||
| 524 | pub fn isWindows(self: Query) bool { | |
| 525 | return self.getOsTag() == .windows; | |
| 526 | } | |
| 527 | ||
| 528 | pub fn exeFileExt(self: Query) [:0]const u8 { | |
| 529 | return Target.exeFileExtSimple(self.getCpuArch(), self.getOsTag()); | |
| 530 | } | |
| 531 | ||
| 532 | pub fn staticLibSuffix(self: Query) [:0]const u8 { | |
| 533 | return Target.staticLibSuffix_os_abi(self.getOsTag(), self.getAbi()); | |
| 534 | } | |
| 535 | ||
| 536 | pub fn dynamicLibSuffix(self: Query) [:0]const u8 { | |
| 537 | return self.getOsTag().dynamicLibSuffix(); | |
| 538 | } | |
| 539 | ||
| 540 | pub fn libPrefix(self: Query) [:0]const u8 { | |
| 541 | return Target.libPrefix_os_abi(self.getOsTag(), self.getAbi()); | |
| 542 | } | |
| 543 | ||
| 544 | pub 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 | ||
| 550 | pub 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 | ||
| 555 | pub fn isNativeAbi(self: Query) bool { | |
| 556 | return self.os_tag == null and self.abi == null; | |
| 557 | } | |
| 558 | ||
| 559 | pub 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. | |
| 565 | fn 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 | ||
| 573 | pub 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 | ||
| 619 | pub 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 | ||
| 625 | pub fn linuxTriple(self: Query, allocator: mem.Allocator) ![]u8 { | |
| 626 | return Target.linuxTripleSimple(allocator, self.getCpuArch(), self.getOsTag(), self.getAbi()); | |
| 627 | } | |
| 628 | ||
| 629 | pub fn isGnuLibC(self: Query) bool { | |
| 630 | return Target.isGnuLibC_os_tag_abi(self.getOsTag(), self.getAbi()); | |
| 631 | } | |
| 632 | ||
| 633 | pub 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 | ||
| 638 | pub fn getObjectFormat(self: Query) Target.ObjectFormat { | |
| 639 | return self.ofmt orelse Target.ObjectFormat.default(self.getOsTag(), self.getCpuArch()); | |
| 640 | } | |
| 641 | ||
| 642 | pub 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 | ||
| 649 | fn 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 | ||
| 746 | const Query = @This(); | |
| 747 | const std = @import("../std.zig"); | |
| 748 | const builtin = @import("builtin"); | |
| 749 | const assert = std.debug.assert; | |
| 750 | const Target = std.Target; | |
| 751 | const mem = std.mem; | |
| 752 | ||
| 753 | test 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 | 16 | pub const primitives = @import("zig/primitives.zig"); |
| 17 | 17 | pub const Ast = @import("zig/Ast.zig"); |
| 18 | 18 | pub const system = @import("zig/system.zig"); |
| 19 | pub const CrossTarget = @import("zig/CrossTarget.zig"); | |
| 19 | /// Deprecated: use `std.Target.Query`. | |
| 20 | pub const CrossTarget = std.Target.Query; | |
| 20 | 21 | pub const BuiltinFn = @import("zig/BuiltinFn.zig"); |
| 21 | 22 | pub const AstRlAnnotate = @import("zig/AstRlAnnotate.zig"); |
| 22 | 23 |
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 | ||
| 5 | const CrossTarget = @This(); | |
| 6 | const std = @import("../std.zig"); | |
| 7 | const builtin = @import("builtin"); | |
| 8 | const assert = std.debug.assert; | |
| 9 | const Target = std.Target; | |
| 10 | const mem = std.mem; | |
| 11 | ||
| 12 | /// `null` means native. | |
| 13 | cpu_arch: ?Target.Cpu.Arch = null, | |
| 14 | ||
| 15 | cpu_model: CpuModel = CpuModel.determined_by_cpu_arch, | |
| 16 | ||
| 17 | /// Sparse set of CPU features to add to the set from `cpu_model`. | |
| 18 | cpu_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`. | |
| 21 | cpu_features_sub: Target.Cpu.Feature.Set = Target.Cpu.Feature.Set.empty, | |
| 22 | ||
| 23 | /// `null` means native. | |
| 24 | os_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. | |
| 28 | os_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. | |
| 32 | os_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. | |
| 36 | glibc_version: ?SemanticVersion = null, | |
| 37 | ||
| 38 | /// `null` means the native C ABI, if `os_tag` is native, otherwise it means the default C ABI. | |
| 39 | abi: ?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`. | |
| 43 | dynamic_linker: DynamicLinker = DynamicLinker{}, | |
| 44 | ||
| 45 | /// `null` means default for the cpu/arch/os combo. | |
| 46 | ofmt: ?Target.ObjectFormat = null, | |
| 47 | ||
| 48 | pub 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 | ||
| 62 | pub const OsVersion = union(enum) { | |
| 63 | none: void, | |
| 64 | semver: SemanticVersion, | |
| 65 | windows: Target.Os.WindowsVersion, | |
| 66 | }; | |
| 67 | ||
| 68 | pub const SemanticVersion = std.SemanticVersion; | |
| 69 | ||
| 70 | pub const DynamicLinker = Target.DynamicLinker; | |
| 71 | ||
| 72 | pub 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 | ||
| 105 | fn 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`. | |
| 174 | pub 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 | ||
| 183 | pub 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 | ||
| 236 | pub 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`. | |
| 346 | pub 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. | |
| 360 | pub 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 | ||
| 381 | test 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`. | |
| 389 | pub 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 | ||
| 420 | pub fn getCpuArch(self: CrossTarget) Target.Cpu.Arch { | |
| 421 | return self.cpu_arch orelse builtin.cpu.arch; | |
| 422 | } | |
| 423 | ||
| 424 | pub 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 | ||
| 431 | pub fn getCpuFeatures(self: CrossTarget) Target.Cpu.Feature.Set { | |
| 432 | return self.getCpu().features; | |
| 433 | } | |
| 434 | ||
| 435 | /// TODO deprecated, use `std.zig.system.NativeTargetInfo.detect`. | |
| 436 | pub 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 | ||
| 468 | pub 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`. | |
| 473 | pub 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`. | |
| 481 | pub 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`. | |
| 489 | pub 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 | ||
| 502 | pub fn isFreeBSD(self: CrossTarget) bool { | |
| 503 | return self.getOsTag() == .freebsd; | |
| 504 | } | |
| 505 | ||
| 506 | pub fn isDarwin(self: CrossTarget) bool { | |
| 507 | return self.getOsTag().isDarwin(); | |
| 508 | } | |
| 509 | ||
| 510 | pub fn isNetBSD(self: CrossTarget) bool { | |
| 511 | return self.getOsTag() == .netbsd; | |
| 512 | } | |
| 513 | ||
| 514 | pub fn isOpenBSD(self: CrossTarget) bool { | |
| 515 | return self.getOsTag() == .openbsd; | |
| 516 | } | |
| 517 | ||
| 518 | pub fn isUefi(self: CrossTarget) bool { | |
| 519 | return self.getOsTag() == .uefi; | |
| 520 | } | |
| 521 | ||
| 522 | pub fn isDragonFlyBSD(self: CrossTarget) bool { | |
| 523 | return self.getOsTag() == .dragonfly; | |
| 524 | } | |
| 525 | ||
| 526 | pub fn isLinux(self: CrossTarget) bool { | |
| 527 | return self.getOsTag() == .linux; | |
| 528 | } | |
| 529 | ||
| 530 | pub fn isWindows(self: CrossTarget) bool { | |
| 531 | return self.getOsTag() == .windows; | |
| 532 | } | |
| 533 | ||
| 534 | pub fn exeFileExt(self: CrossTarget) [:0]const u8 { | |
| 535 | return Target.exeFileExtSimple(self.getCpuArch(), self.getOsTag()); | |
| 536 | } | |
| 537 | ||
| 538 | pub fn staticLibSuffix(self: CrossTarget) [:0]const u8 { | |
| 539 | return Target.staticLibSuffix_os_abi(self.getOsTag(), self.getAbi()); | |
| 540 | } | |
| 541 | ||
| 542 | pub fn dynamicLibSuffix(self: CrossTarget) [:0]const u8 { | |
| 543 | return self.getOsTag().dynamicLibSuffix(); | |
| 544 | } | |
| 545 | ||
| 546 | pub fn libPrefix(self: CrossTarget) [:0]const u8 { | |
| 547 | return Target.libPrefix_os_abi(self.getOsTag(), self.getAbi()); | |
| 548 | } | |
| 549 | ||
| 550 | pub 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 | ||
| 556 | pub 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 | ||
| 561 | pub fn isNativeAbi(self: CrossTarget) bool { | |
| 562 | return self.os_tag == null and self.abi == null; | |
| 563 | } | |
| 564 | ||
| 565 | pub 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. | |
| 571 | fn 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 | ||
| 579 | pub 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 | ||
| 625 | pub 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 | ||
| 631 | pub fn linuxTriple(self: CrossTarget, allocator: mem.Allocator) ![]u8 { | |
| 632 | return Target.linuxTripleSimple(allocator, self.getCpuArch(), self.getOsTag(), self.getAbi()); | |
| 633 | } | |
| 634 | ||
| 635 | pub fn isGnuLibC(self: CrossTarget) bool { | |
| 636 | return Target.isGnuLibC_os_tag_abi(self.getOsTag(), self.getAbi()); | |
| 637 | } | |
| 638 | ||
| 639 | pub 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 | ||
| 644 | pub fn getObjectFormat(self: CrossTarget) Target.ObjectFormat { | |
| 645 | return self.ofmt orelse Target.ObjectFormat.default(self.getOsTag(), self.getCpuArch()); | |
| 646 | } | |
| 647 | ||
| 648 | pub 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 | ||
| 655 | fn 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 | ||
| 752 | test "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 | 9 | const NativeTargetInfo = @This(); |
| 10 | 10 | const Target = std.Target; |
| 11 | 11 | const Allocator = std.mem.Allocator; |
| 12 | const CrossTarget = std.zig.CrossTarget; | |
| 13 | 12 | const windows = std.zig.system.windows; |
| 14 | 13 | const darwin = std.zig.system.darwin; |
| 15 | 14 | const linux = std.zig.system.linux; |
| ... | ... | @@ -30,13 +29,14 @@ pub const DetectError = error{ |
| 30 | 29 | Unexpected, |
| 31 | 30 | }; |
| 32 | 31 | |
| 33 | /// Given a `CrossTarget`, which specifies in detail which parts of the target should be detected | |
| 34 | /// natively, which should be standard or default, and which are provided explicitly, this function | |
| 35 | /// resolves the native components by detecting the native system, and then resolves standard/default parts | |
| 36 | /// relative to that. | |
| 37 | pub fn detect(cross_target: CrossTarget) DetectError!NativeTargetInfo { | |
| 38 | var os = cross_target.getOsTag().defaultVersionRange(cross_target.getCpuArch()); | |
| 39 | if (cross_target.os_tag == null) { | |
| 32 | /// Given a `Target.Query`, which specifies in detail which parts of the | |
| 33 | /// target should be detected natively, which should be standard or default, | |
| 34 | /// and which are provided explicitly, this function resolves the native | |
| 35 | /// components by detecting the native system, and then resolves | |
| 36 | /// standard/default parts relative to that. | |
| 37 | pub fn detect(query: Target.Query) DetectError!NativeTargetInfo { | |
| 38 | var os = query.getOsTag().defaultVersionRange(query.getCpuArch()); | |
| 39 | if (query.os_tag == null) { | |
| 40 | 40 | switch (builtin.target.os.tag) { |
| 41 | 41 | .linux => { |
| 42 | 42 | const uts = std.os.uname(); |
| ... | ... | @@ -162,45 +162,45 @@ pub fn detect(cross_target: CrossTarget) DetectError!NativeTargetInfo { |
| 162 | 162 | } |
| 163 | 163 | } |
| 164 | 164 | |
| 165 | if (cross_target.os_version_min) |min| switch (min) { | |
| 165 | if (query.os_version_min) |min| switch (min) { | |
| 166 | 166 | .none => {}, |
| 167 | .semver => |semver| switch (cross_target.getOsTag()) { | |
| 167 | .semver => |semver| switch (query.getOsTag()) { | |
| 168 | 168 | .linux => os.version_range.linux.range.min = semver, |
| 169 | 169 | else => os.version_range.semver.min = semver, |
| 170 | 170 | }, |
| 171 | 171 | .windows => |win_ver| os.version_range.windows.min = win_ver, |
| 172 | 172 | }; |
| 173 | 173 | |
| 174 | if (cross_target.os_version_max) |max| switch (max) { | |
| 174 | if (query.os_version_max) |max| switch (max) { | |
| 175 | 175 | .none => {}, |
| 176 | .semver => |semver| switch (cross_target.getOsTag()) { | |
| 176 | .semver => |semver| switch (query.getOsTag()) { | |
| 177 | 177 | .linux => os.version_range.linux.range.max = semver, |
| 178 | 178 | else => os.version_range.semver.max = semver, |
| 179 | 179 | }, |
| 180 | 180 | .windows => |win_ver| os.version_range.windows.max = win_ver, |
| 181 | 181 | }; |
| 182 | 182 | |
| 183 | if (cross_target.glibc_version) |glibc| { | |
| 184 | assert(cross_target.isGnuLibC()); | |
| 183 | if (query.glibc_version) |glibc| { | |
| 184 | assert(query.isGnuLibC()); | |
| 185 | 185 | os.version_range.linux.glibc = glibc; |
| 186 | 186 | } |
| 187 | 187 | |
| 188 | 188 | // Until https://github.com/ziglang/zig/issues/4592 is implemented (support detecting the |
| 189 | 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(); | |
| 191 | 191 | |
| 192 | const cpu = switch (cross_target.cpu_model) { | |
| 193 | .native => detectNativeCpuAndFeatures(cpu_arch, os, cross_target), | |
| 192 | const cpu = switch (query.cpu_model) { | |
| 193 | .native => detectNativeCpuAndFeatures(cpu_arch, os, query), | |
| 194 | 194 | .baseline => Target.Cpu.baseline(cpu_arch), |
| 195 | .determined_by_cpu_arch => if (cross_target.cpu_arch == null) | |
| 196 | detectNativeCpuAndFeatures(cpu_arch, os, cross_target) | |
| 195 | .determined_by_cpu_arch => if (query.cpu_arch == null) | |
| 196 | detectNativeCpuAndFeatures(cpu_arch, os, query) | |
| 197 | 197 | else |
| 198 | 198 | Target.Cpu.baseline(cpu_arch), |
| 199 | 199 | .explicit => |model| model.toCpu(cpu_arch), |
| 200 | 200 | } orelse backup_cpu_detection: { |
| 201 | 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 | 204 | // For x86, we need to populate some CPU feature flags depending on architecture |
| 205 | 205 | // and mode: |
| 206 | 206 | // * 16bit_mode => if the abi is code16 |
| ... | ... | @@ -209,15 +209,15 @@ pub fn detect(cross_target: CrossTarget) DetectError!NativeTargetInfo { |
| 209 | 209 | // sets one of them, that takes precedence. |
| 210 | 210 | switch (cpu_arch) { |
| 211 | 211 | .x86 => { |
| 212 | if (!std.Target.x86.featureSetHasAny(cross_target.cpu_features_add, .{ | |
| 212 | if (!Target.x86.featureSetHasAny(query.cpu_features_add, .{ | |
| 213 | 213 | .@"16bit_mode", .@"32bit_mode", |
| 214 | 214 | })) { |
| 215 | 215 | switch (result.target.abi) { |
| 216 | 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 | 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 | 228 | }, |
| 229 | 229 | .thumb, .thumbeb => { |
| 230 | 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 | 234 | else => {}, |
| 235 | 235 | } |
| 236 | cross_target.updateCpuFeatures(&result.target.cpu.features); | |
| 236 | query.updateCpuFeatures(&result.target.cpu.features); | |
| 237 | 237 | return result; |
| 238 | 238 | } |
| 239 | 239 | |
| ... | ... | @@ -253,22 +253,22 @@ pub fn detect(cross_target: CrossTarget) DetectError!NativeTargetInfo { |
| 253 | 253 | fn detectAbiAndDynamicLinker( |
| 254 | 254 | cpu: Target.Cpu, |
| 255 | 255 | os: Target.Os, |
| 256 | cross_target: CrossTarget, | |
| 256 | query: Target.Query, | |
| 257 | 257 | ) DetectError!NativeTargetInfo { |
| 258 | 258 | const native_target_has_ld = comptime builtin.target.hasDynamicLinker(); |
| 259 | 259 | const is_linux = builtin.target.os.tag == .linux; |
| 260 | 260 | const is_solarish = builtin.target.os.tag.isSolarish(); |
| 261 | const have_all_info = cross_target.dynamic_linker.get() != null and | |
| 262 | cross_target.abi != null and (!is_linux or cross_target.abi.?.isGnu()); | |
| 263 | const os_is_non_native = cross_target.os_tag != null; | |
| 261 | const have_all_info = query.dynamic_linker.get() != null and | |
| 262 | query.abi != null and (!is_linux or query.abi.?.isGnu()); | |
| 263 | const os_is_non_native = query.os_tag != null; | |
| 264 | 264 | // The Solaris/illumos environment is always the same. |
| 265 | 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 | 269 | if (abi.isMusl()) { |
| 270 | 270 | // musl implies static linking. |
| 271 | return defaultAbiAndDynamicLinker(cpu, os, cross_target); | |
| 271 | return defaultAbiAndDynamicLinker(cpu, os, query); | |
| 272 | 272 | } |
| 273 | 273 | } |
| 274 | 274 | // 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 | 287 | }; |
| 288 | 288 | var ld_info_list_buffer: [all_abis.len]LdInfo = undefined; |
| 289 | 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); | |
| 291 | 291 | |
| 292 | 292 | for (all_abis) |abi| { |
| 293 | 293 | // This may be a nonsensical parameter. We detect this with |
| ... | ... | @@ -345,7 +345,7 @@ fn detectAbiAndDynamicLinker( |
| 345 | 345 | error.Unexpected, |
| 346 | 346 | => |e| { |
| 347 | 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 | }, |
| 350 | 350 | |
| 351 | 351 | else => |e| return e, |
| ... | ... | @@ -363,7 +363,7 @@ fn detectAbiAndDynamicLinker( |
| 363 | 363 | const line = buffer[0..newline]; |
| 364 | 364 | if (!mem.startsWith(u8, line, "#!")) break :blk file; |
| 365 | 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 | 367 | file.close(); |
| 368 | 368 | } |
| 369 | 369 | }; |
| ... | ... | @@ -373,7 +373,7 @@ fn detectAbiAndDynamicLinker( |
| 373 | 373 | // trick (block self_exe) won't work. The next thing we fall back to is the same thing, but for elf_file. |
| 374 | 374 | // TODO: inline this function and combine the buffer we already read above to find |
| 375 | 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 | 377 | error.FileSystem, |
| 378 | 378 | error.SystemResources, |
| 379 | 379 | error.SymLinkLoop, |
| ... | ... | @@ -393,7 +393,7 @@ fn detectAbiAndDynamicLinker( |
| 393 | 393 | // Finally, we fall back on the standard path. |
| 394 | 394 | => |e| { |
| 395 | 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 | 565 | while (it.next()) |s| { |
| 566 | 566 | if (mem.startsWith(u8, s, "GLIBC_2.")) { |
| 567 | 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 | 569 | error.Overflow => return error.InvalidGnuLibCVersion, |
| 570 | 570 | error.InvalidVersion => return error.InvalidGnuLibCVersion, |
| 571 | 571 | }; |
| ... | ... | @@ -588,7 +588,7 @@ fn glibcVerFromLinkName(link_name: []const u8, prefix: []const u8) error{ Unreco |
| 588 | 588 | } |
| 589 | 589 | // chop off "libc-" and ".so" |
| 590 | 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 | 592 | error.Overflow => return error.InvalidGnuLibCVersion, |
| 593 | 593 | error.InvalidVersion => return error.InvalidGnuLibCVersion, |
| 594 | 594 | }; |
| ... | ... | @@ -627,7 +627,7 @@ pub fn abiAndDynamicLinkerFromFile( |
| 627 | 627 | cpu: Target.Cpu, |
| 628 | 628 | os: Target.Os, |
| 629 | 629 | ld_info_list: []const LdInfo, |
| 630 | cross_target: CrossTarget, | |
| 630 | query: Target.Query, | |
| 631 | 631 | ) AbiAndDynamicLinkerFromFileError!NativeTargetInfo { |
| 632 | 632 | var hdr_buf: [@sizeOf(elf.Elf64_Ehdr)]u8 align(@alignOf(elf.Elf64_Ehdr)) = undefined; |
| 633 | 633 | _ = try preadMin(file, &hdr_buf, 0, hdr_buf.len); |
| ... | ... | @@ -655,13 +655,13 @@ pub fn abiAndDynamicLinkerFromFile( |
| 655 | 655 | .target = .{ |
| 656 | 656 | .cpu = cpu, |
| 657 | 657 | .os = os, |
| 658 | .abi = cross_target.abi orelse Target.Abi.default(cpu.arch, os), | |
| 659 | .ofmt = cross_target.ofmt orelse Target.ObjectFormat.default(os.tag, cpu.arch), | |
| 658 | .abi = query.abi orelse Target.Abi.default(cpu.arch, os), | |
| 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 | 663 | 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; | |
| 665 | 665 | |
| 666 | 666 | var ph_buf: [16 * @sizeOf(elf.Elf64_Phdr)]u8 align(@alignOf(elf.Elf64_Phdr)) = undefined; |
| 667 | 667 | if (phentsize > @sizeOf(elf.Elf64_Phdr)) return error.InvalidElfFile; |
| ... | ... | @@ -706,7 +706,7 @@ pub fn abiAndDynamicLinkerFromFile( |
| 706 | 706 | }, |
| 707 | 707 | // We only need this for detecting glibc version. |
| 708 | 708 | 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 | 711 | var dyn_off = elfInt(is_64, need_bswap, ph32.p_offset, ph64.p_offset); |
| 712 | 712 | const p_filesz = elfInt(is_64, need_bswap, ph32.p_filesz, ph64.p_filesz); |
| ... | ... | @@ -747,7 +747,7 @@ pub fn abiAndDynamicLinkerFromFile( |
| 747 | 747 | } |
| 748 | 748 | |
| 749 | 749 | 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 | 752 | const shstrndx = elfInt(is_64, need_bswap, hdr32.e_shstrndx, hdr64.e_shstrndx); |
| 753 | 753 | |
| ... | ... | @@ -927,19 +927,19 @@ fn preadMin(file: fs.File, buf: []u8, offset: u64, min_read_len: usize) !usize { |
| 927 | 927 | return i; |
| 928 | 928 | } |
| 929 | 929 | |
| 930 | fn defaultAbiAndDynamicLinker(cpu: Target.Cpu, os: Target.Os, cross_target: CrossTarget) !NativeTargetInfo { | |
| 930 | fn defaultAbiAndDynamicLinker(cpu: Target.Cpu, os: Target.Os, query: Target.Query) !NativeTargetInfo { | |
| 931 | 931 | const target: Target = .{ |
| 932 | 932 | .cpu = cpu, |
| 933 | 933 | .os = os, |
| 934 | .abi = cross_target.abi orelse Target.Abi.default(cpu.arch, os), | |
| 935 | .ofmt = cross_target.ofmt orelse Target.ObjectFormat.default(os.tag, cpu.arch), | |
| 934 | .abi = query.abi orelse Target.Abi.default(cpu.arch, os), | |
| 935 | .ofmt = query.ofmt orelse Target.ObjectFormat.default(os.tag, cpu.arch), | |
| 936 | 936 | }; |
| 937 | 937 | return NativeTargetInfo{ |
| 938 | 938 | .target = target, |
| 939 | .dynamic_linker = if (cross_target.dynamic_linker.get() == null) | |
| 939 | .dynamic_linker = if (query.dynamic_linker.get() == null) | |
| 940 | 940 | target.standardDynamicLinkerPath() |
| 941 | 941 | else |
| 942 | cross_target.dynamic_linker, | |
| 942 | query.dynamic_linker, | |
| 943 | 943 | }; |
| 944 | 944 | } |
| 945 | 945 | |
| ... | ... | @@ -964,13 +964,13 @@ pub fn elfInt(is_64: bool, need_bswap: bool, int_32: anytype, int_64: anytype) @ |
| 964 | 964 | } |
| 965 | 965 | } |
| 966 | 966 | |
| 967 | fn detectNativeCpuAndFeatures(cpu_arch: Target.Cpu.Arch, os: Target.Os, cross_target: CrossTarget) ?Target.Cpu { | |
| 967 | fn detectNativeCpuAndFeatures(cpu_arch: Target.Cpu.Arch, os: Target.Os, query: Target.Query) ?Target.Cpu { | |
| 968 | 968 | // Here we switch on a comptime value rather than `cpu_arch`. This is valid because `cpu_arch`, |
| 969 | 969 | // although it is a runtime value, is guaranteed to be one of the architectures in the set |
| 970 | 970 | // of the respective switch prong. |
| 971 | 971 | switch (builtin.cpu.arch) { |
| 972 | 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 | 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 | 87 | const ver = try svt.expectContent(); |
| 88 | 88 | try svt.skipUntilTag(.end, "string"); |
| 89 | 89 | |
| 90 | return try std.zig.CrossTarget.parseVersion(ver); | |
| 90 | return try std.Target.Query.parseVersion(ver); | |
| 91 | 91 | } |
| 92 | 92 | |
| 93 | 93 | const SystemVersionTokenizer = struct { |
lib/std/zig/system/linux.zig-3| ... | ... | @@ -5,10 +5,7 @@ const io = std.io; |
| 5 | 5 | const fs = std.fs; |
| 6 | 6 | const fmt = std.fmt; |
| 7 | 7 | const testing = std.testing; |
| 8 | ||
| 9 | 8 | const Target = std.Target; |
| 10 | const CrossTarget = std.zig.CrossTarget; | |
| 11 | ||
| 12 | 9 | const assert = std.debug.assert; |
| 13 | 10 | |
| 14 | 11 | const SparcCpuinfoImpl = struct { |
lib/std/zig/system/x86.zig+2-3| ... | ... | @@ -1,7 +1,6 @@ |
| 1 | 1 | const std = @import("std"); |
| 2 | 2 | const builtin = @import("builtin"); |
| 3 | 3 | const Target = std.Target; |
| 4 | const CrossTarget = std.zig.CrossTarget; | |
| 5 | 4 | |
| 6 | 5 | const XCR0_XMM = 0x02; |
| 7 | 6 | const XCR0_YMM = 0x04; |
| ... | ... | @@ -23,8 +22,8 @@ inline fn hasMask(input: u32, mask: u32) bool { |
| 23 | 22 | return (input & mask) == mask; |
| 24 | 23 | } |
| 25 | 24 | |
| 26 | pub fn detectNativeCpuAndFeatures(arch: Target.Cpu.Arch, os: Target.Os, cross_target: CrossTarget) Target.Cpu { | |
| 27 | _ = cross_target; | |
| 25 | pub fn detectNativeCpuAndFeatures(arch: Target.Cpu.Arch, os: Target.Os, query: Target.Query) Target.Cpu { | |
| 26 | _ = query; | |
| 28 | 27 | var cpu = Target.Cpu{ |
| 29 | 28 | .arch = arch, |
| 30 | 29 | .model = Target.Cpu.Model.generic(arch), |
src/libc_installation.zig+1-1| ... | ... | @@ -41,7 +41,7 @@ pub const LibCInstallation = struct { |
| 41 | 41 | pub fn parse( |
| 42 | 42 | allocator: Allocator, |
| 43 | 43 | libc_file: []const u8, |
| 44 | target: std.zig.CrossTarget, | |
| 44 | target: std.Target.Query, | |
| 45 | 45 | ) !LibCInstallation { |
| 46 | 46 | var self: LibCInstallation = .{}; |
| 47 | 47 |
src/main.zig+37-37| ... | ... | @@ -2551,7 +2551,7 @@ fn buildOutputType( |
| 2551 | 2551 | } |
| 2552 | 2552 | }; |
| 2553 | 2553 | |
| 2554 | var target_parse_options: std.zig.CrossTarget.ParseOptions = .{ | |
| 2554 | var target_parse_options: std.Target.Query.ParseOptions = .{ | |
| 2555 | 2555 | .arch_os_abi = target_arch_os_abi, |
| 2556 | 2556 | .cpu_features = target_mcpu, |
| 2557 | 2557 | .dynamic_linker = target_dynamic_linker, |
| ... | ... | @@ -2563,7 +2563,7 @@ fn buildOutputType( |
| 2563 | 2563 | if (llvm_m_args.items.len != 0) { |
| 2564 | 2564 | // If this returns null, we let it fall through to the case below which will |
| 2565 | 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 | 2567 | var llvm_to_zig_name = std.StringHashMap([]const u8).init(gpa); |
| 2568 | 2568 | defer llvm_to_zig_name.deinit(); |
| 2569 | 2569 | |
| ... | ... | @@ -2607,8 +2607,8 @@ fn buildOutputType( |
| 2607 | 2607 | } |
| 2608 | 2608 | } |
| 2609 | 2609 | |
| 2610 | const cross_target = try parseCrossTargetOrReportFatalError(arena, target_parse_options); | |
| 2611 | const target_info = try detectNativeTargetInfo(cross_target); | |
| 2610 | const target_query = try parseTargetQueryOrReportFatalError(arena, target_parse_options); | |
| 2611 | const target_info = try detectNativeTargetInfo(target_query); | |
| 2612 | 2612 | |
| 2613 | 2613 | if (target_info.target.os.tag != .freestanding) { |
| 2614 | 2614 | if (ensure_libc_on_non_freestanding) |
| ... | ... | @@ -2695,13 +2695,13 @@ fn buildOutputType( |
| 2695 | 2695 | } |
| 2696 | 2696 | |
| 2697 | 2697 | if (use_lld) |opt| { |
| 2698 | if (opt and cross_target.isDarwin()) { | |
| 2698 | if (opt and target_query.isDarwin()) { | |
| 2699 | 2699 | fatal("LLD requested with Mach-O object format. Only the self-hosted linker is supported for this target.", .{}); |
| 2700 | 2700 | } |
| 2701 | 2701 | } |
| 2702 | 2702 | |
| 2703 | 2703 | if (want_lto) |opt| { |
| 2704 | if (opt and cross_target.isDarwin()) { | |
| 2704 | if (opt and target_query.isDarwin()) { | |
| 2705 | 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 | 2771 | |
| 2772 | 2772 | var libc_installation: ?LibCInstallation = null; |
| 2773 | 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 | 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 | 2835 | // After this point, external_system_libs is used instead of system_libs. |
| 2836 | 2836 | |
| 2837 | 2837 | // Trigger native system library path detection if necessary. |
| 2838 | if (sysroot == null and cross_target.isNativeOs() and cross_target.isNativeAbi() and | |
| 2838 | if (sysroot == null and target_query.isNativeOs() and target_query.isNativeAbi() and | |
| 2839 | 2839 | (external_system_libs.len != 0 or want_native_include_dirs)) |
| 2840 | 2840 | { |
| 2841 | 2841 | const paths = std.zig.system.NativePaths.detect(arena, target_info) catch |err| { |
| ... | ... | @@ -2864,7 +2864,7 @@ fn buildOutputType( |
| 2864 | 2864 | libc_installation = try LibCInstallation.findNative(.{ |
| 2865 | 2865 | .allocator = arena, |
| 2866 | 2866 | .verbose = true, |
| 2867 | .target = cross_target.toTarget(), | |
| 2867 | .target = target_query.toTarget(), | |
| 2868 | 2868 | }); |
| 2869 | 2869 | |
| 2870 | 2870 | try lib_dirs.appendSlice(&.{ libc_installation.?.msvc_lib_dir.?, libc_installation.?.kernel32_lib_dir.? }); |
| ... | ... | @@ -3455,8 +3455,8 @@ fn buildOutputType( |
| 3455 | 3455 | .global_cache_directory = global_cache_directory, |
| 3456 | 3456 | .root_name = root_name, |
| 3457 | 3457 | .target = target_info.target, |
| 3458 | .is_native_os = cross_target.isNativeOs(), | |
| 3459 | .is_native_abi = cross_target.isNativeAbi(), | |
| 3458 | .is_native_os = target_query.isNativeOs(), | |
| 3459 | .is_native_abi = target_query.isNativeAbi(), | |
| 3460 | 3460 | .dynamic_linker = target_info.dynamic_linker.get(), |
| 3461 | 3461 | .sysroot = sysroot, |
| 3462 | 3462 | .output_mode = output_mode, |
| ... | ... | @@ -4013,16 +4013,16 @@ const ModuleDepIterator = struct { |
| 4013 | 4013 | } |
| 4014 | 4014 | }; |
| 4015 | 4015 | |
| 4016 | fn parseCrossTargetOrReportFatalError( | |
| 4016 | fn parseTargetQueryOrReportFatalError( | |
| 4017 | 4017 | allocator: Allocator, |
| 4018 | opts: std.zig.CrossTarget.ParseOptions, | |
| 4019 | ) !std.zig.CrossTarget { | |
| 4018 | opts: std.Target.Query.ParseOptions, | |
| 4019 | ) !std.Target.Query { | |
| 4020 | 4020 | var opts_with_diags = opts; |
| 4021 | var diags: std.zig.CrossTarget.ParseOptions.Diagnostics = .{}; | |
| 4021 | var diags: std.Target.Query.ParseOptions.Diagnostics = .{}; | |
| 4022 | 4022 | if (opts_with_diags.diagnostics == null) { |
| 4023 | 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 | 4026 | error.UnknownCpuModel => { |
| 4027 | 4027 | help: { |
| 4028 | 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 | 4666 | while (true) { |
| 4667 | 4667 | switch (cur_includes) { |
| 4668 | 4668 | .any, .msvc => { |
| 4669 | const cross_target = std.zig.CrossTarget.parse(.{ .arch_os_abi = "native-windows-msvc" }) catch unreachable; | |
| 4670 | const target = cross_target.toTarget(); | |
| 4671 | const is_native_abi = cross_target.isNativeAbi(); | |
| 4669 | const target_query = std.Target.Query.parse(.{ .arch_os_abi = "native-windows-msvc" }) catch unreachable; | |
| 4670 | const target = target_query.toTarget(); | |
| 4671 | const is_native_abi = target_query.isNativeAbi(); | |
| 4672 | 4672 | const detected_libc = Compilation.detectLibCIncludeDirs(arena, zig_lib_dir, target, is_native_abi, true, null) catch |err| { |
| 4673 | 4673 | if (cur_includes == .any) { |
| 4674 | 4674 | // fall back to mingw |
| ... | ... | @@ -4691,9 +4691,9 @@ fn detectRcIncludeDirs(arena: Allocator, zig_lib_dir: []const u8, auto_includes: |
| 4691 | 4691 | }; |
| 4692 | 4692 | }, |
| 4693 | 4693 | .gnu => { |
| 4694 | const cross_target = std.zig.CrossTarget.parse(.{ .arch_os_abi = "native-windows-gnu" }) catch unreachable; | |
| 4695 | const target = cross_target.toTarget(); | |
| 4696 | const is_native_abi = cross_target.isNativeAbi(); | |
| 4694 | const target_query = std.Target.Query.parse(.{ .arch_os_abi = "native-windows-gnu" }) catch unreachable; | |
| 4695 | const target = target_query.toTarget(); | |
| 4696 | const is_native_abi = target_query.isNativeAbi(); | |
| 4697 | 4697 | const detected_libc = try Compilation.detectLibCIncludeDirs(arena, zig_lib_dir, target, is_native_abi, true, null); |
| 4698 | 4698 | return .{ |
| 4699 | 4699 | .include_paths = detected_libc.libc_include_dir_list, |
| ... | ... | @@ -4754,7 +4754,7 @@ pub fn cmdLibC(gpa: Allocator, args: []const []const u8) !void { |
| 4754 | 4754 | } |
| 4755 | 4755 | } |
| 4756 | 4756 | |
| 4757 | const cross_target = try parseCrossTargetOrReportFatalError(gpa, .{ | |
| 4757 | const target_query = try parseTargetQueryOrReportFatalError(gpa, .{ | |
| 4758 | 4758 | .arch_os_abi = target_arch_os_abi, |
| 4759 | 4759 | }); |
| 4760 | 4760 | |
| ... | ... | @@ -4766,7 +4766,7 @@ pub fn cmdLibC(gpa: Allocator, args: []const []const u8) !void { |
| 4766 | 4766 | const libc_installation: ?*LibCInstallation = libc: { |
| 4767 | 4767 | if (input_file) |libc_file| { |
| 4768 | 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 | 4770 | fatal("unable to parse libc file at path {s}: {s}", .{ libc_file, @errorName(err) }); |
| 4771 | 4771 | }; |
| 4772 | 4772 | break :libc libc; |
| ... | ... | @@ -4781,8 +4781,8 @@ pub fn cmdLibC(gpa: Allocator, args: []const []const u8) !void { |
| 4781 | 4781 | }; |
| 4782 | 4782 | defer zig_lib_directory.handle.close(); |
| 4783 | 4783 | |
| 4784 | const target = cross_target.toTarget(); | |
| 4785 | const is_native_abi = cross_target.isNativeAbi(); | |
| 4784 | const target = target_query.toTarget(); | |
| 4785 | const is_native_abi = target_query.isNativeAbi(); | |
| 4786 | 4786 | |
| 4787 | 4787 | const libc_dirs = Compilation.detectLibCIncludeDirs( |
| 4788 | 4788 | arena, |
| ... | ... | @@ -4812,15 +4812,15 @@ pub fn cmdLibC(gpa: Allocator, args: []const []const u8) !void { |
| 4812 | 4812 | } |
| 4813 | 4813 | |
| 4814 | 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 | 4816 | fatal("unable to parse libc file at path {s}: {s}", .{ libc_file, @errorName(err) }); |
| 4817 | 4817 | }; |
| 4818 | 4818 | defer libc.deinit(gpa); |
| 4819 | 4819 | } else { |
| 4820 | if (!cross_target.isNative()) { | |
| 4820 | if (!target_query.isNative()) { | |
| 4821 | 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); | |
| 4824 | 4824 | |
| 4825 | 4825 | var libc = LibCInstallation.findNative(.{ |
| 4826 | 4826 | .allocator = gpa, |
| ... | ... | @@ -5113,8 +5113,8 @@ pub fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !voi |
| 5113 | 5113 | |
| 5114 | 5114 | gimmeMoreOfThoseSweetSweetFileDescriptors(); |
| 5115 | 5115 | |
| 5116 | const cross_target: std.zig.CrossTarget = .{}; | |
| 5117 | const target_info = try detectNativeTargetInfo(cross_target); | |
| 5116 | const target_query: std.Target.Query = .{}; | |
| 5117 | const target_info = try detectNativeTargetInfo(target_query); | |
| 5118 | 5118 | |
| 5119 | 5119 | const exe_basename = try std.zig.binNameAlloc(arena, .{ |
| 5120 | 5120 | .root_name = "build", |
| ... | ... | @@ -5283,8 +5283,8 @@ pub fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !voi |
| 5283 | 5283 | .global_cache_directory = global_cache_directory, |
| 5284 | 5284 | .root_name = "build", |
| 5285 | 5285 | .target = target_info.target, |
| 5286 | .is_native_os = cross_target.isNativeOs(), | |
| 5287 | .is_native_abi = cross_target.isNativeAbi(), | |
| 5286 | .is_native_os = target_query.isNativeOs(), | |
| 5287 | .is_native_abi = target_query.isNativeAbi(), | |
| 5288 | 5288 | .dynamic_linker = target_info.dynamic_linker.get(), |
| 5289 | 5289 | .output_mode = .Exe, |
| 5290 | 5290 | .main_mod = &main_mod, |
| ... | ... | @@ -6269,8 +6269,8 @@ test "fds" { |
| 6269 | 6269 | gimmeMoreOfThoseSweetSweetFileDescriptors(); |
| 6270 | 6270 | } |
| 6271 | 6271 | |
| 6272 | fn detectNativeTargetInfo(cross_target: std.zig.CrossTarget) !std.zig.system.NativeTargetInfo { | |
| 6273 | return std.zig.system.NativeTargetInfo.detect(cross_target); | |
| 6272 | fn detectNativeTargetInfo(target_query: std.Target.Query) !std.zig.system.NativeTargetInfo { | |
| 6273 | return std.zig.system.NativeTargetInfo.detect(target_query); | |
| 6274 | 6274 | } |
| 6275 | 6275 | |
| 6276 | 6276 | const usage_ast_check = |
| ... | ... | @@ -6672,8 +6672,8 @@ fn warnAboutForeignBinaries( |
| 6672 | 6672 | target_info: *const std.zig.system.NativeTargetInfo, |
| 6673 | 6673 | link_libc: bool, |
| 6674 | 6674 | ) !void { |
| 6675 | const host_cross_target: std.zig.CrossTarget = .{}; | |
| 6676 | const host_target_info = try detectNativeTargetInfo(host_cross_target); | |
| 6675 | const host_query: std.Target.Query = .{}; | |
| 6676 | const host_target_info = try detectNativeTargetInfo(host_query); | |
| 6677 | 6677 | |
| 6678 | 6678 | switch (host_target_info.getExternalExecutor(target_info, .{ .link_libc = link_libc })) { |
| 6679 | 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 | 5 | pub fn addCases(ctx: *Cases, b: *std.Build) !void { |
| 6 | 6 | // These tests should work with all platforms, but we're using linux_x64 for |
| 7 | 7 | // now for consistency. Will be expanded eventually. |
| 8 | const linux_x64: std.zig.CrossTarget = .{ | |
| 8 | const linux_x64: std.Target.Query = .{ | |
| 9 | 9 | .cpu_arch = .x86_64, |
| 10 | 10 | .os_tag = .linux, |
| 11 | 11 | }; |
test/link/elf.zig-1| ... | ... | @@ -3833,7 +3833,6 @@ const link = @import("link.zig"); |
| 3833 | 3833 | const std = @import("std"); |
| 3834 | 3834 | |
| 3835 | 3835 | const Build = std.Build; |
| 3836 | const CrossTarget = std.zig.CrossTarget; | |
| 3837 | 3836 | const Options = link.Options; |
| 3838 | 3837 | const Step = Build.Step; |
| 3839 | 3838 | const WriteFile = Step.WriteFile; |
test/link/glibc_compat/build.zig+1-1| ... | ... | @@ -8,7 +8,7 @@ pub fn build(b: *std.Build) void { |
| 8 | 8 | const exe = b.addExecutable(.{ |
| 9 | 9 | .name = t, |
| 10 | 10 | .root_source_file = .{ .path = "main.c" }, |
| 11 | .target = b.resolveTargetQuery(std.zig.CrossTarget.parse( | |
| 11 | .target = b.resolveTargetQuery(std.Target.Query.parse( | |
| 12 | 12 | .{ .arch_os_abi = t }, |
| 13 | 13 | ) catch unreachable), |
| 14 | 14 | }); |
test/link/link.zig-1| ... | ... | @@ -199,7 +199,6 @@ const std = @import("std"); |
| 199 | 199 | |
| 200 | 200 | const Build = std.Build; |
| 201 | 201 | const Compile = Step.Compile; |
| 202 | const CrossTarget = std.zig.CrossTarget; | |
| 203 | 202 | const Run = Step.Run; |
| 204 | 203 | const Step = Build.Step; |
| 205 | 204 | const WriteFile = Step.WriteFile; |
test/link/macho.zig-2| ... | ... | @@ -95,7 +95,5 @@ const addExecutable = link.addExecutable; |
| 95 | 95 | const expectLinkErrors = link.expectLinkErrors; |
| 96 | 96 | const link = @import("link.zig"); |
| 97 | 97 | const std = @import("std"); |
| 98 | ||
| 99 | const CrossTarget = std.zig.CrossTarget; | |
| 100 | 98 | const Options = link.Options; |
| 101 | 99 | const Step = std.Build.Step; |
test/llvm_targets.zig+1-1| ... | ... | @@ -1,7 +1,7 @@ |
| 1 | 1 | const std = @import("std"); |
| 2 | 2 | const Cases = @import("src/Cases.zig"); |
| 3 | 3 | |
| 4 | const targets = [_]std.zig.CrossTarget{ | |
| 4 | const targets = [_]std.Target.Query{ | |
| 5 | 5 | .{ .cpu_arch = .aarch64, .os_tag = .freestanding, .abi = .none }, |
| 6 | 6 | .{ .cpu_arch = .aarch64, .os_tag = .ios, .abi = .none }, |
| 7 | 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 | 188 | return ctx.addExe(name, target); |
| 189 | 189 | } |
| 190 | 190 | |
| 191 | pub fn exeFromCompiledC(ctx: *Cases, name: []const u8, target_query: std.zig.CrossTarget, b: *std.Build) *Case { | |
| 191 | pub fn exeFromCompiledC(ctx: *Cases, name: []const u8, target_query: std.Target.Query, b: *std.Build) *Case { | |
| 192 | 192 | var adjusted_query = target_query; |
| 193 | 193 | adjusted_query.ofmt = .c; |
| 194 | 194 | ctx.cases.append(Case{ |
| ... | ... | @@ -423,7 +423,7 @@ fn addFromDirInner( |
| 423 | 423 | var manifest = try TestManifest.parse(ctx.arena, src); |
| 424 | 424 | |
| 425 | 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 | 427 | const c_frontends = try manifest.getConfigForKeyAlloc(ctx.arena, "c_frontend", CFrontend); |
| 428 | 428 | const is_test = try manifest.getConfigForKeyAssertSingle("is_test", bool); |
| 429 | 429 | const link_libc = try manifest.getConfigForKeyAssertSingle("link_libc", bool); |
| ... | ... | @@ -1160,9 +1160,9 @@ const TestManifest = struct { |
| 1160 | 1160 | } |
| 1161 | 1161 | |
| 1162 | 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 | 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 | 1167 | }.parse; |
| 1168 | 1168 | |
| ... | ... | @@ -1287,7 +1287,7 @@ pub fn main() !void { |
| 1287 | 1287 | |
| 1288 | 1288 | if (cases.items.len == 0) { |
| 1289 | 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 | 1291 | const c_frontends = try manifest.getConfigForKeyAlloc(ctx.arena, "c_frontend", CFrontend); |
| 1292 | 1292 | const is_test = try manifest.getConfigForKeyAssertSingle("is_test", bool); |
| 1293 | 1293 | const link_libc = try manifest.getConfigForKeyAssertSingle("link_libc", bool); |
| ... | ... | @@ -1385,7 +1385,7 @@ pub fn main() !void { |
| 1385 | 1385 | return runCases(&ctx, zig_exe_path); |
| 1386 | 1386 | } |
| 1387 | 1387 | |
| 1388 | fn resolveTargetQuery(query: std.zig.CrossTarget) std.Build.ResolvedTarget { | |
| 1388 | fn resolveTargetQuery(query: std.Target.Query) std.Build.ResolvedTarget { | |
| 1389 | 1389 | const result = std.zig.system.NativeTargetInfo.detect(query) catch |
| 1390 | 1390 | @panic("unable to resolve target query"); |
| 1391 | 1391 |
test/src/translate_c.zig+2-3| ... | ... | @@ -5,7 +5,6 @@ const ArrayList = std.ArrayList; |
| 5 | 5 | const fmt = std.fmt; |
| 6 | 6 | const mem = std.mem; |
| 7 | 7 | const fs = std.fs; |
| 8 | const CrossTarget = std.zig.CrossTarget; | |
| 9 | 8 | |
| 10 | 9 | pub const TranslateCContext = struct { |
| 11 | 10 | b: *std.Build, |
| ... | ... | @@ -18,7 +17,7 @@ pub const TranslateCContext = struct { |
| 18 | 17 | sources: ArrayList(SourceFile), |
| 19 | 18 | expected_lines: ArrayList([]const u8), |
| 20 | 19 | allow_warnings: bool, |
| 21 | target: CrossTarget = .{}, | |
| 20 | target: std.Target.Query = .{}, | |
| 22 | 21 | |
| 23 | 22 | const SourceFile = struct { |
| 24 | 23 | filename: []const u8, |
| ... | ... | @@ -74,7 +73,7 @@ pub const TranslateCContext = struct { |
| 74 | 73 | pub fn addWithTarget( |
| 75 | 74 | self: *TranslateCContext, |
| 76 | 75 | name: []const u8, |
| 77 | target: CrossTarget, | |
| 76 | target: std.Target.Query, | |
| 78 | 77 | source: []const u8, |
| 79 | 78 | expected_lines: []const []const u8, |
| 80 | 79 | ) void { |
test/standalone.zig+1-1| ... | ... | @@ -2,7 +2,7 @@ pub const SimpleCase = struct { |
| 2 | 2 | src_path: []const u8, |
| 3 | 3 | link_libc: bool = false, |
| 4 | 4 | all_modes: bool = false, |
| 5 | target: std.zig.CrossTarget = .{}, | |
| 5 | target: std.Target.Query = .{}, | |
| 6 | 6 | is_test: bool = false, |
| 7 | 7 | is_exe: bool = true, |
| 8 | 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 | 4 | const test_step = b.step("test", "Test it"); |
| 5 | 5 | b.default_step = test_step; |
| 6 | 6 | |
| 7 | const cross_target = b.resolveTargetQuery(.{ | |
| 7 | const target = b.resolveTargetQuery(.{ | |
| 8 | 8 | .cpu_arch = .x86_64, |
| 9 | 9 | .os_tag = .windows, |
| 10 | 10 | .abi = .gnu, |
| 11 | 11 | }); |
| 12 | 12 | |
| 13 | 13 | add(b, b.host, .any, test_step); |
| 14 | add(b, cross_target, .any, test_step); | |
| 14 | add(b, target, .any, test_step); | |
| 15 | 15 | |
| 16 | 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 | } |
| 19 | 19 | |
| 20 | 20 | fn add( |
test/tests.zig+6-6| ... | ... | @@ -21,7 +21,7 @@ pub const CompareOutputContext = @import("src/CompareOutput.zig"); |
| 21 | 21 | pub const StackTracesContext = @import("src/StackTrace.zig"); |
| 22 | 22 | |
| 23 | 23 | const TestTarget = struct { |
| 24 | target: std.zig.CrossTarget = .{}, | |
| 24 | target: std.Target.Query = .{}, | |
| 25 | 25 | optimize_mode: std.builtin.OptimizeMode = .Debug, |
| 26 | 26 | link_libc: ?bool = null, |
| 27 | 27 | single_threaded: ?bool = null, |
| ... | ... | @@ -145,7 +145,7 @@ const test_targets = blk: { |
| 145 | 145 | //}, |
| 146 | 146 | // https://github.com/ziglang/zig/issues/13623 |
| 147 | 147 | //.{ |
| 148 | // .target = std.zig.CrossTarget.parse(.{ | |
| 148 | // .target = std.Target.Query.parse(.{ | |
| 149 | 149 | // .arch_os_abi = "arm-linux-none", |
| 150 | 150 | // .cpu_features = "generic+v8a", |
| 151 | 151 | // }) catch unreachable, |
| ... | ... | @@ -286,13 +286,13 @@ const test_targets = blk: { |
| 286 | 286 | }, |
| 287 | 287 | |
| 288 | 288 | .{ |
| 289 | .target = std.zig.CrossTarget.parse(.{ | |
| 289 | .target = std.Target.Query.parse(.{ | |
| 290 | 290 | .arch_os_abi = "arm-linux-none", |
| 291 | 291 | .cpu_features = "generic+v8a", |
| 292 | 292 | }) catch unreachable, |
| 293 | 293 | }, |
| 294 | 294 | .{ |
| 295 | .target = std.zig.CrossTarget.parse(.{ | |
| 295 | .target = std.Target.Query.parse(.{ | |
| 296 | 296 | .arch_os_abi = "arm-linux-musleabihf", |
| 297 | 297 | .cpu_features = "generic+v8a", |
| 298 | 298 | }) catch unreachable, |
| ... | ... | @@ -300,7 +300,7 @@ const test_targets = blk: { |
| 300 | 300 | }, |
| 301 | 301 | // https://github.com/ziglang/zig/issues/3287 |
| 302 | 302 | //.{ |
| 303 | // .target = std.zig.CrossTarget.parse(.{ | |
| 303 | // .target = std.Target.Query.parse(.{ | |
| 304 | 304 | // .arch_os_abi = "arm-linux-gnueabihf", |
| 305 | 305 | // .cpu_features = "generic+v8a", |
| 306 | 306 | // }) catch unreachable, |
| ... | ... | @@ -494,7 +494,7 @@ const test_targets = blk: { |
| 494 | 494 | }; |
| 495 | 495 | |
| 496 | 496 | const CAbiTarget = struct { |
| 497 | target: std.zig.CrossTarget = .{}, | |
| 497 | target: std.Target.Query = .{}, | |
| 498 | 498 | use_llvm: ?bool = null, |
| 499 | 499 | use_lld: ?bool = null, |
| 500 | 500 | pic: ?bool = null, |
test/translate_c.zig+2-3| ... | ... | @@ -1,7 +1,6 @@ |
| 1 | 1 | const std = @import("std"); |
| 2 | 2 | const builtin = @import("builtin"); |
| 3 | 3 | const tests = @import("tests.zig"); |
| 4 | const CrossTarget = std.zig.CrossTarget; | |
| 5 | 4 | |
| 6 | 5 | // ******************************************************** |
| 7 | 6 | // * * |
| ... | ... | @@ -1846,7 +1845,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void { |
| 1846 | 1845 | \\pub extern fn foo5(a: [*c]f32) callconv(.Thiscall) void; |
| 1847 | 1846 | }); |
| 1848 | 1847 | |
| 1849 | cases.addWithTarget("Calling convention", CrossTarget.parse(.{ | |
| 1848 | cases.addWithTarget("Calling convention", std.Target.Query.parse(.{ | |
| 1850 | 1849 | .arch_os_abi = "arm-linux-none", |
| 1851 | 1850 | .cpu_features = "generic+v8_5a", |
| 1852 | 1851 | }) catch unreachable, |
| ... | ... | @@ -1857,7 +1856,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void { |
| 1857 | 1856 | \\pub extern fn foo2(a: [*c]f32) callconv(.AAPCSVFP) void; |
| 1858 | 1857 | }); |
| 1859 | 1858 | |
| 1860 | cases.addWithTarget("Calling convention", CrossTarget.parse(.{ | |
| 1859 | cases.addWithTarget("Calling convention", std.Target.Query.parse(.{ | |
| 1861 | 1860 | .arch_os_abi = "aarch64-linux-none", |
| 1862 | 1861 | .cpu_features = "generic+v8_5a", |
| 1863 | 1862 | }) catch unreachable, |