| author | |
| committer | |
| log | 8c44954bc6a91ae66f5aea92ea8380c28b50b3f0 |
| tree | 561158f17f27378a0bbd7d572a347082cacc464c |
| parent | dbdb87502d6936597424fe86842c15978ba86918 |
These functions have been doomed for a long time. Finally I figured out
what the proper relationship between this API and std.Target is.10 files changed, 275 insertions(+), 373 deletions(-)
deps/aro/aro/Driver.zig+6-3| ... | ... | @@ -366,12 +366,15 @@ pub fn parseArgs( |
| 366 | 366 | } else if (mem.eql(u8, arg, "-S") or mem.eql(u8, arg, "--assemble")) { |
| 367 | 367 | d.only_preprocess_and_compile = true; |
| 368 | 368 | } else if (option(arg, "--target=")) |triple| { |
| 369 | const cross = std.zig.CrossTarget.parse(.{ .arch_os_abi = triple }) catch { | |
| 369 | const query = std.Target.Query.parse(.{ .arch_os_abi = triple }) catch { | |
| 370 | 370 | try d.comp.addDiagnostic(.{ .tag = .cli_invalid_target, .extra = .{ .str = arg } }, &.{}); |
| 371 | 371 | continue; |
| 372 | 372 | }; |
| 373 | d.comp.target = cross.toTarget(); // TODO deprecated | |
| 374 | d.comp.langopts.setEmulatedCompiler(target_util.systemCompiler(d.comp.target)); | |
| 373 | const target = std.zig.system.resolveTargetQuery(query) catch |e| { | |
| 374 | return d.fatal("unable to resolve target: {s}", .{errorDescription(e)}); | |
| 375 | }; | |
| 376 | d.comp.target = target; | |
| 377 | d.comp.langopts.setEmulatedCompiler(target_util.systemCompiler(target)); | |
| 375 | 378 | d.raw_target_triple = triple; |
| 376 | 379 | } else if (mem.eql(u8, arg, "--verbose-ast")) { |
| 377 | 380 | d.verbose_ast = true; |
lib/std/Build.zig+26-110| ... | ... | @@ -383,12 +383,7 @@ fn userInputOptionsFromArgs(allocator: Allocator, args: anytype) UserInputOption |
| 383 | 383 | }) catch @panic("OOM"); |
| 384 | 384 | user_input_options.put("cpu", .{ |
| 385 | 385 | .name = "cpu", |
| 386 | .value = .{ | |
| 387 | .scalar = if (v.isNativeCpu()) | |
| 388 | "native" | |
| 389 | else | |
| 390 | serializeCpu(allocator, v.getCpu()) catch unreachable, | |
| 391 | }, | |
| 386 | .value = .{ .scalar = v.serializeCpuAlloc(allocator) catch @panic("OOM") }, | |
| 392 | 387 | .used = false, |
| 393 | 388 | }) catch @panic("OOM"); |
| 394 | 389 | }, |
| ... | ... | @@ -400,12 +395,7 @@ fn userInputOptionsFromArgs(allocator: Allocator, args: anytype) UserInputOption |
| 400 | 395 | }) catch @panic("OOM"); |
| 401 | 396 | user_input_options.put("cpu", .{ |
| 402 | 397 | .name = "cpu", |
| 403 | .value = .{ | |
| 404 | .scalar = if (v.query.isNativeCpu()) | |
| 405 | "native" | |
| 406 | else | |
| 407 | serializeCpu(allocator, v.target.cpu) catch unreachable, | |
| 408 | }, | |
| 398 | .value = .{ .scalar = v.query.serializeCpuAlloc(allocator) catch @panic("OOM") }, | |
| 409 | 399 | .used = false, |
| 410 | 400 | }) catch @panic("OOM"); |
| 411 | 401 | }, |
| ... | ... | @@ -1196,7 +1186,6 @@ pub fn standardOptimizeOption(self: *Build, options: StandardOptimizeOptionOptio |
| 1196 | 1186 | |
| 1197 | 1187 | pub const StandardTargetOptionsArgs = struct { |
| 1198 | 1188 | whitelist: ?[]const Target.Query = null, |
| 1199 | ||
| 1200 | 1189 | default_target: Target.Query = .{}, |
| 1201 | 1190 | }; |
| 1202 | 1191 | |
| ... | ... | @@ -1208,13 +1197,13 @@ pub fn standardTargetOptions(b: *Build, args: StandardTargetOptionsArgs) Resolve |
| 1208 | 1197 | } |
| 1209 | 1198 | |
| 1210 | 1199 | /// Exposes standard `zig build` options for choosing a target. |
| 1211 | pub fn standardTargetOptionsQueryOnly(self: *Build, args: StandardTargetOptionsArgs) Target.Query { | |
| 1212 | const maybe_triple = self.option( | |
| 1200 | pub fn standardTargetOptionsQueryOnly(b: *Build, args: StandardTargetOptionsArgs) Target.Query { | |
| 1201 | const maybe_triple = b.option( | |
| 1213 | 1202 | []const u8, |
| 1214 | 1203 | "target", |
| 1215 | 1204 | "The CPU architecture, OS, and ABI to build for", |
| 1216 | 1205 | ); |
| 1217 | const mcpu = self.option([]const u8, "cpu", "Target CPU features to add or subtract"); | |
| 1206 | const mcpu = b.option([]const u8, "cpu", "Target CPU features to add or subtract"); | |
| 1218 | 1207 | |
| 1219 | 1208 | if (maybe_triple == null and mcpu == null) { |
| 1220 | 1209 | return args.default_target; |
| ... | ... | @@ -1236,7 +1225,7 @@ pub fn standardTargetOptionsQueryOnly(self: *Build, args: StandardTargetOptionsA |
| 1236 | 1225 | for (diags.arch.?.allCpuModels()) |cpu| { |
| 1237 | 1226 | log.err(" {s}", .{cpu.name}); |
| 1238 | 1227 | } |
| 1239 | self.markInvalidUserInput(); | |
| 1228 | b.markInvalidUserInput(); | |
| 1240 | 1229 | return args.default_target; |
| 1241 | 1230 | }, |
| 1242 | 1231 | error.UnknownCpuFeature => { |
| ... | ... | @@ -1251,7 +1240,7 @@ pub fn standardTargetOptionsQueryOnly(self: *Build, args: StandardTargetOptionsA |
| 1251 | 1240 | for (diags.arch.?.allFeaturesList()) |feature| { |
| 1252 | 1241 | log.err(" {s}: {s}", .{ feature.name, feature.description }); |
| 1253 | 1242 | } |
| 1254 | self.markInvalidUserInput(); | |
| 1243 | b.markInvalidUserInput(); | |
| 1255 | 1244 | return args.default_target; |
| 1256 | 1245 | }, |
| 1257 | 1246 | error.UnknownOperatingSystem => { |
| ... | ... | @@ -1263,80 +1252,35 @@ pub fn standardTargetOptionsQueryOnly(self: *Build, args: StandardTargetOptionsA |
| 1263 | 1252 | inline for (std.meta.fields(Target.Os.Tag)) |field| { |
| 1264 | 1253 | log.err(" {s}", .{field.name}); |
| 1265 | 1254 | } |
| 1266 | self.markInvalidUserInput(); | |
| 1255 | b.markInvalidUserInput(); | |
| 1267 | 1256 | return args.default_target; |
| 1268 | 1257 | }, |
| 1269 | 1258 | else => |e| { |
| 1270 | 1259 | log.err("Unable to parse target '{s}': {s}\n", .{ triple, @errorName(e) }); |
| 1271 | self.markInvalidUserInput(); | |
| 1260 | b.markInvalidUserInput(); | |
| 1272 | 1261 | return args.default_target; |
| 1273 | 1262 | }, |
| 1274 | 1263 | }; |
| 1275 | 1264 | |
| 1276 | const selected_canonicalized_triple = selected_target.zigTriple(self.allocator) catch @panic("OOM"); | |
| 1277 | ||
| 1278 | if (args.whitelist) |list| whitelist_check: { | |
| 1279 | // Make sure it's a match of one of the list. | |
| 1280 | var mismatch_triple = true; | |
| 1281 | var mismatch_cpu_features = true; | |
| 1282 | var whitelist_item: Target.Query = .{}; | |
| 1283 | for (list) |t| { | |
| 1284 | mismatch_cpu_features = true; | |
| 1285 | mismatch_triple = true; | |
| 1286 | ||
| 1287 | const t_triple = t.zigTriple(self.allocator) catch @panic("OOM"); | |
| 1288 | if (mem.eql(u8, t_triple, selected_canonicalized_triple)) { | |
| 1289 | mismatch_triple = false; | |
| 1290 | whitelist_item = t; | |
| 1291 | if (t.getCpuFeatures().isSuperSetOf(selected_target.getCpuFeatures())) { | |
| 1292 | mismatch_cpu_features = false; | |
| 1293 | break :whitelist_check; | |
| 1294 | } else { | |
| 1295 | break; | |
| 1296 | } | |
| 1297 | } | |
| 1298 | } | |
| 1299 | if (mismatch_triple) { | |
| 1300 | log.err("Chosen target '{s}' does not match one of the supported targets:", .{ | |
| 1301 | selected_canonicalized_triple, | |
| 1302 | }); | |
| 1303 | for (list) |t| { | |
| 1304 | const t_triple = t.zigTriple(self.allocator) catch @panic("OOM"); | |
| 1305 | log.err(" {s}", .{t_triple}); | |
| 1306 | } | |
| 1307 | } else { | |
| 1308 | assert(mismatch_cpu_features); | |
| 1309 | const whitelist_cpu = whitelist_item.getCpu(); | |
| 1310 | const selected_cpu = selected_target.getCpu(); | |
| 1311 | log.err("Chosen CPU model '{s}' does not match one of the supported targets:", .{ | |
| 1312 | selected_cpu.model.name, | |
| 1313 | }); | |
| 1314 | log.err(" Supported feature Set: ", .{}); | |
| 1315 | const all_features = whitelist_cpu.arch.allFeaturesList(); | |
| 1316 | var populated_cpu_features = whitelist_cpu.model.features; | |
| 1317 | populated_cpu_features.populateDependencies(all_features); | |
| 1318 | for (all_features, 0..) |feature, i_usize| { | |
| 1319 | const i = @as(Target.Cpu.Feature.Set.Index, @intCast(i_usize)); | |
| 1320 | const in_cpu_set = populated_cpu_features.isEnabled(i); | |
| 1321 | if (in_cpu_set) { | |
| 1322 | log.err("{s} ", .{feature.name}); | |
| 1323 | } | |
| 1324 | } | |
| 1325 | log.err(" Remove: ", .{}); | |
| 1326 | for (all_features, 0..) |feature, i_usize| { | |
| 1327 | const i = @as(Target.Cpu.Feature.Set.Index, @intCast(i_usize)); | |
| 1328 | const in_cpu_set = populated_cpu_features.isEnabled(i); | |
| 1329 | const in_actual_set = selected_cpu.features.isEnabled(i); | |
| 1330 | if (in_actual_set and !in_cpu_set) { | |
| 1331 | log.err("{s} ", .{feature.name}); | |
| 1332 | } | |
| 1333 | } | |
| 1334 | } | |
| 1335 | self.markInvalidUserInput(); | |
| 1336 | return args.default_target; | |
| 1265 | const whitelist = args.whitelist orelse return selected_target; | |
| 1266 | ||
| 1267 | // Make sure it's a match of one of the list. | |
| 1268 | for (whitelist) |q| { | |
| 1269 | if (q.eql(selected_target)) | |
| 1270 | return selected_target; | |
| 1337 | 1271 | } |
| 1338 | 1272 | |
| 1339 | return selected_target; | |
| 1273 | for (whitelist) |q| { | |
| 1274 | log.info("allowed target: -Dtarget={s} -Dcpu={s}", .{ | |
| 1275 | q.zigTriple(b.allocator) catch @panic("OOM"), | |
| 1276 | q.serializeCpuAlloc(b.allocator) catch @panic("OOM"), | |
| 1277 | }); | |
| 1278 | } | |
| 1279 | log.err("chosen target '{s}' does not match one of the allowed targets", .{ | |
| 1280 | selected_target.zigTriple(b.allocator) catch @panic("OOM"), | |
| 1281 | }); | |
| 1282 | b.markInvalidUserInput(); | |
| 1283 | return args.default_target; | |
| 1340 | 1284 | } |
| 1341 | 1285 | |
| 1342 | 1286 | pub fn addUserInputOption(self: *Build, name_raw: []const u8, value_raw: []const u8) !bool { |
| ... | ... | @@ -2064,34 +2008,6 @@ pub const InstalledFile = struct { |
| 2064 | 2008 | } |
| 2065 | 2009 | }; |
| 2066 | 2010 | |
| 2067 | pub fn serializeCpu(allocator: Allocator, cpu: Target.Cpu) ![]const u8 { | |
| 2068 | // TODO this logic can disappear if cpu model + features becomes part of the target triple | |
| 2069 | const all_features = cpu.arch.allFeaturesList(); | |
| 2070 | var populated_cpu_features = cpu.model.features; | |
| 2071 | populated_cpu_features.populateDependencies(all_features); | |
| 2072 | ||
| 2073 | if (populated_cpu_features.eql(cpu.features)) { | |
| 2074 | // The CPU name alone is sufficient. | |
| 2075 | return cpu.model.name; | |
| 2076 | } else { | |
| 2077 | var mcpu_buffer = ArrayList(u8).init(allocator); | |
| 2078 | try mcpu_buffer.appendSlice(cpu.model.name); | |
| 2079 | ||
| 2080 | for (all_features, 0..) |feature, i_usize| { | |
| 2081 | const i = @as(Target.Cpu.Feature.Set.Index, @intCast(i_usize)); | |
| 2082 | const in_cpu_set = populated_cpu_features.isEnabled(i); | |
| 2083 | const in_actual_set = cpu.features.isEnabled(i); | |
| 2084 | if (in_cpu_set and !in_actual_set) { | |
| 2085 | try mcpu_buffer.writer().print("-{s}", .{feature.name}); | |
| 2086 | } else if (!in_cpu_set and in_actual_set) { | |
| 2087 | try mcpu_buffer.writer().print("+{s}", .{feature.name}); | |
| 2088 | } | |
| 2089 | } | |
| 2090 | ||
| 2091 | return try mcpu_buffer.toOwnedSlice(); | |
| 2092 | } | |
| 2093 | } | |
| 2094 | ||
| 2095 | 2011 | /// This function is intended to be called in the `configure` phase only. |
| 2096 | 2012 | /// It returns an absolute directory path, which is potentially going to be a |
| 2097 | 2013 | /// source of API breakage in the future, so keep that in mind when using this |
lib/std/Build/Module.zig+2-2| ... | ... | @@ -627,12 +627,12 @@ pub fn appendZigProcessFlags( |
| 627 | 627 | try zig_args.append(@tagName(m.code_model)); |
| 628 | 628 | } |
| 629 | 629 | |
| 630 | if (m.target) |target| { | |
| 630 | if (m.target) |*target| { | |
| 631 | 631 | // Communicate the query via CLI since it's more compact. |
| 632 | 632 | if (!target.query.isNative()) { |
| 633 | 633 | try zig_args.appendSlice(&.{ |
| 634 | 634 | "-target", try target.query.zigTriple(b.allocator), |
| 635 | "-mcpu", try std.Build.serializeCpu(b.allocator, target.query.getCpu()), | |
| 635 | "-mcpu", try target.query.serializeCpuAlloc(b.allocator), | |
| 636 | 636 | }); |
| 637 | 637 | |
| 638 | 638 | if (target.query.dynamic_linker.get()) |dynamic_linker| { |
lib/std/Target.zig+11-2| ... | ... | @@ -1394,7 +1394,7 @@ pub const Cpu = struct { |
| 1394 | 1394 | } |
| 1395 | 1395 | }; |
| 1396 | 1396 | |
| 1397 | pub fn zigTriple(self: Target, allocator: Allocator) ![]u8 { | |
| 1397 | pub fn zigTriple(self: Target, allocator: Allocator) Allocator.Error![]u8 { | |
| 1398 | 1398 | return Query.fromTarget(self).zigTriple(allocator); |
| 1399 | 1399 | } |
| 1400 | 1400 | |
| ... | ... | @@ -1566,11 +1566,20 @@ pub const DynamicLinker = struct { |
| 1566 | 1566 | pub fn set(self: *DynamicLinker, dl_or_null: ?[]const u8) void { |
| 1567 | 1567 | if (dl_or_null) |dl| { |
| 1568 | 1568 | @memcpy(self.buffer[0..dl.len], dl); |
| 1569 | self.max_byte = @as(u8, @intCast(dl.len - 1)); | |
| 1569 | self.max_byte = @intCast(dl.len - 1); | |
| 1570 | 1570 | } else { |
| 1571 | 1571 | self.max_byte = null; |
| 1572 | 1572 | } |
| 1573 | 1573 | } |
| 1574 | ||
| 1575 | pub fn eql(a: DynamicLinker, b: DynamicLinker) bool { | |
| 1576 | const a_m = a.max_byte orelse return b.max_byte == null; | |
| 1577 | const b_m = b.max_byte orelse return false; | |
| 1578 | if (a_m != b_m) return false; | |
| 1579 | const a_s = a.buffer[0 .. a_m + 1]; | |
| 1580 | const b_s = b.buffer[0 .. a_m + 1]; | |
| 1581 | return std.mem.eql(u8, a_s, b_s); | |
| 1582 | } | |
| 1574 | 1583 | }; |
| 1575 | 1584 | |
| 1576 | 1585 | pub fn standardDynamicLinkerPath(target: Target) DynamicLinker { |
lib/std/Target/Query.zig+128-206| ... | ... | @@ -51,12 +51,41 @@ pub const CpuModel = union(enum) { |
| 51 | 51 | determined_by_cpu_arch, |
| 52 | 52 | |
| 53 | 53 | explicit: *const Target.Cpu.Model, |
| 54 | ||
| 55 | pub fn eql(a: CpuModel, b: CpuModel) bool { | |
| 56 | const Tag = @typeInfo(CpuModel).Union.tag_type.?; | |
| 57 | const a_tag: Tag = a; | |
| 58 | const b_tag: Tag = b; | |
| 59 | if (a_tag != b_tag) return false; | |
| 60 | return switch (a) { | |
| 61 | .native, .baseline, .determined_by_cpu_arch => true, | |
| 62 | .explicit => |a_model| a_model == b.explicit, | |
| 63 | }; | |
| 64 | } | |
| 54 | 65 | }; |
| 55 | 66 | |
| 56 | 67 | pub const OsVersion = union(enum) { |
| 57 | 68 | none: void, |
| 58 | 69 | semver: SemanticVersion, |
| 59 | 70 | windows: Target.Os.WindowsVersion, |
| 71 | ||
| 72 | pub fn eql(a: OsVersion, b: OsVersion) bool { | |
| 73 | const Tag = @typeInfo(OsVersion).Union.tag_type.?; | |
| 74 | const a_tag: Tag = a; | |
| 75 | const b_tag: Tag = b; | |
| 76 | if (a_tag != b_tag) return false; | |
| 77 | return switch (a) { | |
| 78 | .none => true, | |
| 79 | .semver => |a_semver| a_semver.order(b.semver) == .eq, | |
| 80 | .windows => |a_windows| a_windows == b.windows, | |
| 81 | }; | |
| 82 | } | |
| 83 | ||
| 84 | pub fn eqlOpt(a: ?OsVersion, b: ?OsVersion) bool { | |
| 85 | if (a == null and b == null) return true; | |
| 86 | if (a == null or b == null) return false; | |
| 87 | return OsVersion.eql(a.?, b.?); | |
| 88 | } | |
| 60 | 89 | }; |
| 61 | 90 | |
| 62 | 91 | pub const SemanticVersion = std.SemanticVersion; |
| ... | ... | @@ -162,16 +191,6 @@ fn updateOsVersionRange(self: *Query, os: Target.Os) void { |
| 162 | 191 | } |
| 163 | 192 | } |
| 164 | 193 | |
| 165 | /// TODO deprecated, use `std.zig.system.resolveTargetQuery`. | |
| 166 | pub fn toTarget(self: Query) Target { | |
| 167 | return .{ | |
| 168 | .cpu = self.getCpu(), | |
| 169 | .os = self.getOs(), | |
| 170 | .abi = self.getAbi(), | |
| 171 | .ofmt = self.getObjectFormat(), | |
| 172 | }; | |
| 173 | } | |
| 174 | ||
| 175 | 194 | pub const ParseOptions = struct { |
| 176 | 195 | /// This is sometimes called a "triple". It looks roughly like this: |
| 177 | 196 | /// riscv64-linux-musl |
| ... | ... | @@ -240,7 +259,7 @@ pub fn parse(args: ParseOptions) !Query { |
| 240 | 259 | result.cpu_arch = std.meta.stringToEnum(Target.Cpu.Arch, arch_name) orelse |
| 241 | 260 | return error.UnknownArchitecture; |
| 242 | 261 | } |
| 243 | const arch = result.getCpuArch(); | |
| 262 | const arch = result.cpu_arch orelse builtin.cpu.arch; | |
| 244 | 263 | diags.arch = arch; |
| 245 | 264 | |
| 246 | 265 | if (it.next()) |os_text| { |
| ... | ... | @@ -259,7 +278,7 @@ pub fn parse(args: ParseOptions) !Query { |
| 259 | 278 | |
| 260 | 279 | const abi_ver_text = abi_it.rest(); |
| 261 | 280 | if (abi_it.next() != null) { |
| 262 | if (result.isGnuLibC()) { | |
| 281 | if (Target.isGnuLibC_os_tag_abi(result.os_tag orelse builtin.os.tag, abi)) { | |
| 263 | 282 | result.glibc_version = parseVersion(abi_ver_text) catch |err| switch (err) { |
| 264 | 283 | error.Overflow => return error.InvalidAbiVersion, |
| 265 | 284 | error.InvalidVersion => return error.InvalidAbiVersion, |
| ... | ... | @@ -377,168 +396,6 @@ test parseVersion { |
| 377 | 396 | try std.testing.expectError(error.InvalidVersion, parseVersion("1.2.3.4")); |
| 378 | 397 | } |
| 379 | 398 | |
| 380 | /// TODO deprecated, use `std.zig.system.resolveTargetQuery`. | |
| 381 | pub fn getCpu(self: Query) Target.Cpu { | |
| 382 | switch (self.cpu_model) { | |
| 383 | .native => { | |
| 384 | // This works when doing `zig build` because Zig generates a build executable using | |
| 385 | // native CPU model & features. However this will not be accurate otherwise, and | |
| 386 | // will need to be integrated with `std.zig.system.resolveTargetQuery`. | |
| 387 | return builtin.cpu; | |
| 388 | }, | |
| 389 | .baseline => { | |
| 390 | var adjusted_baseline = Target.Cpu.baseline(self.getCpuArch()); | |
| 391 | self.updateCpuFeatures(&adjusted_baseline.features); | |
| 392 | return adjusted_baseline; | |
| 393 | }, | |
| 394 | .determined_by_cpu_arch => if (self.cpu_arch == null) { | |
| 395 | // This works when doing `zig build` because Zig generates a build executable using | |
| 396 | // native CPU model & features. However this will not be accurate otherwise, and | |
| 397 | // will need to be integrated with `std.zig.system.resolveTargetQuery`. | |
| 398 | return builtin.cpu; | |
| 399 | } else { | |
| 400 | var adjusted_baseline = Target.Cpu.baseline(self.getCpuArch()); | |
| 401 | self.updateCpuFeatures(&adjusted_baseline.features); | |
| 402 | return adjusted_baseline; | |
| 403 | }, | |
| 404 | .explicit => |model| { | |
| 405 | var adjusted_model = model.toCpu(self.getCpuArch()); | |
| 406 | self.updateCpuFeatures(&adjusted_model.features); | |
| 407 | return adjusted_model; | |
| 408 | }, | |
| 409 | } | |
| 410 | } | |
| 411 | ||
| 412 | pub fn getCpuArch(self: Query) Target.Cpu.Arch { | |
| 413 | return self.cpu_arch orelse builtin.cpu.arch; | |
| 414 | } | |
| 415 | ||
| 416 | pub fn getCpuModel(self: Query) *const Target.Cpu.Model { | |
| 417 | return switch (self.cpu_model) { | |
| 418 | .explicit => |cpu_model| cpu_model, | |
| 419 | else => self.getCpu().model, | |
| 420 | }; | |
| 421 | } | |
| 422 | ||
| 423 | pub fn getCpuFeatures(self: Query) Target.Cpu.Feature.Set { | |
| 424 | return self.getCpu().features; | |
| 425 | } | |
| 426 | ||
| 427 | /// TODO deprecated, use `std.zig.system.resolveTargetQuery`. | |
| 428 | pub fn getOs(self: Query) Target.Os { | |
| 429 | // `builtin.os` works when doing `zig build` because Zig generates a build executable using | |
| 430 | // native OS version range. However this will not be accurate otherwise, and | |
| 431 | // will need to be integrated with `std.zig.system.resolveTargetQuery`. | |
| 432 | var adjusted_os = if (self.os_tag) |os_tag| os_tag.defaultVersionRange(self.getCpuArch()) else builtin.os; | |
| 433 | ||
| 434 | if (self.os_version_min) |min| switch (min) { | |
| 435 | .none => {}, | |
| 436 | .semver => |semver| switch (self.getOsTag()) { | |
| 437 | .linux => adjusted_os.version_range.linux.range.min = semver, | |
| 438 | else => adjusted_os.version_range.semver.min = semver, | |
| 439 | }, | |
| 440 | .windows => |win_ver| adjusted_os.version_range.windows.min = win_ver, | |
| 441 | }; | |
| 442 | ||
| 443 | if (self.os_version_max) |max| switch (max) { | |
| 444 | .none => {}, | |
| 445 | .semver => |semver| switch (self.getOsTag()) { | |
| 446 | .linux => adjusted_os.version_range.linux.range.max = semver, | |
| 447 | else => adjusted_os.version_range.semver.max = semver, | |
| 448 | }, | |
| 449 | .windows => |win_ver| adjusted_os.version_range.windows.max = win_ver, | |
| 450 | }; | |
| 451 | ||
| 452 | if (self.glibc_version) |glibc| { | |
| 453 | assert(self.isGnuLibC()); | |
| 454 | adjusted_os.version_range.linux.glibc = glibc; | |
| 455 | } | |
| 456 | ||
| 457 | return adjusted_os; | |
| 458 | } | |
| 459 | ||
| 460 | pub fn getOsTag(self: Query) Target.Os.Tag { | |
| 461 | return self.os_tag orelse builtin.os.tag; | |
| 462 | } | |
| 463 | ||
| 464 | /// TODO deprecated, use `std.zig.system.resolveTargetQuery`. | |
| 465 | pub fn getOsVersionMin(self: Query) OsVersion { | |
| 466 | if (self.os_version_min) |version_min| return version_min; | |
| 467 | var tmp: Query = undefined; | |
| 468 | tmp.updateOsVersionRange(self.getOs()); | |
| 469 | return tmp.os_version_min.?; | |
| 470 | } | |
| 471 | ||
| 472 | /// TODO deprecated, use `std.zig.system.resolveTargetQuery`. | |
| 473 | pub fn getOsVersionMax(self: Query) OsVersion { | |
| 474 | if (self.os_version_max) |version_max| return version_max; | |
| 475 | var tmp: Query = undefined; | |
| 476 | tmp.updateOsVersionRange(self.getOs()); | |
| 477 | return tmp.os_version_max.?; | |
| 478 | } | |
| 479 | ||
| 480 | /// TODO deprecated, use `std.zig.system.resolveTargetQuery`. | |
| 481 | pub fn getAbi(self: Query) Target.Abi { | |
| 482 | if (self.abi) |abi| return abi; | |
| 483 | ||
| 484 | if (self.os_tag == null) { | |
| 485 | // This works when doing `zig build` because Zig generates a build executable using | |
| 486 | // native CPU model & features. However this will not be accurate otherwise, and | |
| 487 | // will need to be integrated with `std.zig.system.resolveTargetQuery`. | |
| 488 | return builtin.abi; | |
| 489 | } | |
| 490 | ||
| 491 | return Target.Abi.default(self.getCpuArch(), self.getOs()); | |
| 492 | } | |
| 493 | ||
| 494 | pub fn isFreeBSD(self: Query) bool { | |
| 495 | return self.getOsTag() == .freebsd; | |
| 496 | } | |
| 497 | ||
| 498 | pub fn isDarwin(self: Query) bool { | |
| 499 | return self.getOsTag().isDarwin(); | |
| 500 | } | |
| 501 | ||
| 502 | pub fn isNetBSD(self: Query) bool { | |
| 503 | return self.getOsTag() == .netbsd; | |
| 504 | } | |
| 505 | ||
| 506 | pub fn isOpenBSD(self: Query) bool { | |
| 507 | return self.getOsTag() == .openbsd; | |
| 508 | } | |
| 509 | ||
| 510 | pub fn isUefi(self: Query) bool { | |
| 511 | return self.getOsTag() == .uefi; | |
| 512 | } | |
| 513 | ||
| 514 | pub fn isDragonFlyBSD(self: Query) bool { | |
| 515 | return self.getOsTag() == .dragonfly; | |
| 516 | } | |
| 517 | ||
| 518 | pub fn isLinux(self: Query) bool { | |
| 519 | return self.getOsTag() == .linux; | |
| 520 | } | |
| 521 | ||
| 522 | pub fn isWindows(self: Query) bool { | |
| 523 | return self.getOsTag() == .windows; | |
| 524 | } | |
| 525 | ||
| 526 | pub fn exeFileExt(self: Query) [:0]const u8 { | |
| 527 | return Target.exeFileExtSimple(self.getCpuArch(), self.getOsTag()); | |
| 528 | } | |
| 529 | ||
| 530 | pub fn staticLibSuffix(self: Query) [:0]const u8 { | |
| 531 | return Target.staticLibSuffix_os_abi(self.getOsTag(), self.getAbi()); | |
| 532 | } | |
| 533 | ||
| 534 | pub fn dynamicLibSuffix(self: Query) [:0]const u8 { | |
| 535 | return self.getOsTag().dynamicLibSuffix(); | |
| 536 | } | |
| 537 | ||
| 538 | pub fn libPrefix(self: Query) [:0]const u8 { | |
| 539 | return Target.libPrefix_os_abi(self.getOsTag(), self.getAbi()); | |
| 540 | } | |
| 541 | ||
| 542 | 399 | pub fn isNativeCpu(self: Query) bool { |
| 543 | 400 | return self.cpu_arch == null and |
| 544 | 401 | (self.cpu_model == .native or self.cpu_model == .determined_by_cpu_arch) and |
| ... | ... | @@ -568,7 +425,7 @@ fn formatVersion(version: SemanticVersion, writer: anytype) !void { |
| 568 | 425 | } |
| 569 | 426 | } |
| 570 | 427 | |
| 571 | pub fn zigTriple(self: Query, allocator: mem.Allocator) error{OutOfMemory}![]u8 { | |
| 428 | pub fn zigTriple(self: Query, allocator: Allocator) Allocator.Error![]u8 { | |
| 572 | 429 | if (self.isNative()) { |
| 573 | 430 | return allocator.dupe(u8, "native"); |
| 574 | 431 | } |
| ... | ... | @@ -583,14 +440,16 @@ pub fn zigTriple(self: Query, allocator: mem.Allocator) error{OutOfMemory}![]u8 |
| 583 | 440 | |
| 584 | 441 | // The zig target syntax does not allow specifying a max os version with no min, so |
| 585 | 442 | // if either are present, we need the min. |
| 586 | if (self.os_version_min != null or self.os_version_max != null) { | |
| 587 | switch (self.getOsVersionMin()) { | |
| 443 | if (self.os_version_min) |min| { | |
| 444 | switch (min) { | |
| 588 | 445 | .none => {}, |
| 589 | 446 | .semver => |v| { |
| 590 | 447 | try result.writer().writeAll("."); |
| 591 | 448 | try formatVersion(v, result.writer()); |
| 592 | 449 | }, |
| 593 | .windows => |v| try result.writer().print("{s}", .{v}), | |
| 450 | .windows => |v| { | |
| 451 | try result.writer().print("{s}", .{v}); | |
| 452 | }, | |
| 594 | 453 | } |
| 595 | 454 | } |
| 596 | 455 | if (self.os_version_max) |max| { |
| ... | ... | @@ -600,48 +459,88 @@ pub fn zigTriple(self: Query, allocator: mem.Allocator) error{OutOfMemory}![]u8 |
| 600 | 459 | try result.writer().writeAll("..."); |
| 601 | 460 | try formatVersion(v, result.writer()); |
| 602 | 461 | }, |
| 603 | .windows => |v| try result.writer().print("..{s}", .{v}), | |
| 462 | .windows => |v| { | |
| 463 | try result.writer().print("...{s}", .{v}); | |
| 464 | }, | |
| 604 | 465 | } |
| 605 | 466 | } |
| 606 | 467 | |
| 607 | 468 | if (self.glibc_version) |v| { |
| 608 | try result.writer().print("-{s}.", .{@tagName(self.getAbi())}); | |
| 469 | const name = @tagName(self.abi orelse builtin.target.abi); | |
| 470 | try result.ensureUnusedCapacity(name.len + 2); | |
| 471 | result.appendAssumeCapacity('-'); | |
| 472 | result.appendSliceAssumeCapacity(name); | |
| 473 | result.appendAssumeCapacity('.'); | |
| 609 | 474 | try formatVersion(v, result.writer()); |
| 610 | 475 | } else if (self.abi) |abi| { |
| 611 | try result.writer().print("-{s}", .{@tagName(abi)}); | |
| 476 | const name = @tagName(abi); | |
| 477 | try result.ensureUnusedCapacity(name.len + 1); | |
| 478 | result.appendAssumeCapacity('-'); | |
| 479 | result.appendSliceAssumeCapacity(name); | |
| 612 | 480 | } |
| 613 | 481 | |
| 614 | 482 | return result.toOwnedSlice(); |
| 615 | 483 | } |
| 616 | 484 | |
| 617 | pub fn allocDescription(self: Query, allocator: mem.Allocator) ![]u8 { | |
| 618 | // TODO is there anything else worthy of the description that is not | |
| 619 | // already captured in the triple? | |
| 620 | return self.zigTriple(allocator); | |
| 621 | } | |
| 485 | /// Renders the query into a textual representation that can be parsed via the | |
| 486 | /// `-mcpu` flag passed to the Zig compiler. | |
| 487 | /// Appends the result to `buffer`. | |
| 488 | pub fn serializeCpu(q: Query, buffer: *std.ArrayList(u8)) Allocator.Error!void { | |
| 489 | try buffer.ensureUnusedCapacity(8); | |
| 490 | switch (q.cpu_model) { | |
| 491 | .native => { | |
| 492 | buffer.appendSliceAssumeCapacity("native"); | |
| 493 | }, | |
| 494 | .baseline => { | |
| 495 | buffer.appendSliceAssumeCapacity("baseline"); | |
| 496 | }, | |
| 497 | .determined_by_cpu_arch => { | |
| 498 | if (q.cpu_arch == null) { | |
| 499 | buffer.appendSliceAssumeCapacity("native"); | |
| 500 | } else { | |
| 501 | buffer.appendSliceAssumeCapacity("baseline"); | |
| 502 | } | |
| 503 | }, | |
| 504 | .explicit => |model| { | |
| 505 | try buffer.appendSlice(model.name); | |
| 506 | }, | |
| 507 | } | |
| 622 | 508 | |
| 623 | pub fn linuxTriple(self: Query, allocator: mem.Allocator) ![]u8 { | |
| 624 | return Target.linuxTripleSimple(allocator, self.getCpuArch(), self.getOsTag(), self.getAbi()); | |
| 625 | } | |
| 509 | if (q.cpu_features_add.isEmpty() and q.cpu_features_sub.isEmpty()) { | |
| 510 | // The CPU name alone is sufficient. | |
| 511 | return; | |
| 512 | } | |
| 626 | 513 | |
| 627 | pub fn isGnuLibC(self: Query) bool { | |
| 628 | return Target.isGnuLibC_os_tag_abi(self.getOsTag(), self.getAbi()); | |
| 514 | const cpu_arch = q.cpu_arch orelse builtin.cpu.arch; | |
| 515 | const all_features = cpu_arch.allFeaturesList(); | |
| 516 | ||
| 517 | for (all_features, 0..) |feature, i_usize| { | |
| 518 | const i: Target.Cpu.Feature.Set.Index = @intCast(i_usize); | |
| 519 | try buffer.ensureUnusedCapacity(feature.name.len + 1); | |
| 520 | if (q.cpu_features_sub.isEnabled(i)) { | |
| 521 | buffer.appendAssumeCapacity('-'); | |
| 522 | buffer.appendSliceAssumeCapacity(feature.name); | |
| 523 | } else if (q.cpu_features_add.isEnabled(i)) { | |
| 524 | buffer.appendAssumeCapacity('+'); | |
| 525 | buffer.appendSliceAssumeCapacity(feature.name); | |
| 526 | } | |
| 527 | } | |
| 629 | 528 | } |
| 630 | 529 | |
| 631 | pub fn setGnuLibCVersion(self: *Query, major: u32, minor: u32, patch: u32) void { | |
| 632 | assert(self.isGnuLibC()); | |
| 633 | self.glibc_version = SemanticVersion{ .major = major, .minor = minor, .patch = patch }; | |
| 530 | pub fn serializeCpuAlloc(q: Query, ally: Allocator) Allocator.Error![]u8 { | |
| 531 | var buffer = std.ArrayList(u8).init(ally); | |
| 532 | try serializeCpu(q, &buffer); | |
| 533 | return buffer.toOwnedSlice(); | |
| 634 | 534 | } |
| 635 | 535 | |
| 636 | pub fn getObjectFormat(self: Query) Target.ObjectFormat { | |
| 637 | return self.ofmt orelse Target.ObjectFormat.default(self.getOsTag(), self.getCpuArch()); | |
| 536 | pub fn allocDescription(self: Query, allocator: Allocator) ![]u8 { | |
| 537 | // TODO is there anything else worthy of the description that is not | |
| 538 | // already captured in the triple? | |
| 539 | return self.zigTriple(allocator); | |
| 638 | 540 | } |
| 639 | 541 | |
| 640 | pub fn updateCpuFeatures(self: Query, set: *Target.Cpu.Feature.Set) void { | |
| 641 | set.removeFeatureSet(self.cpu_features_sub); | |
| 642 | set.addFeatureSet(self.cpu_features_add); | |
| 643 | set.populateDependencies(self.getCpuArch().allFeaturesList()); | |
| 644 | set.removeFeatureSet(self.cpu_features_sub); | |
| 542 | pub fn setGnuLibCVersion(self: *Query, major: u32, minor: u32, patch: u32) void { | |
| 543 | self.glibc_version = SemanticVersion{ .major = major, .minor = minor, .patch = patch }; | |
| 645 | 544 | } |
| 646 | 545 | |
| 647 | 546 | fn parseOs(result: *Query, diags: *ParseOptions.Diagnostics, text: []const u8) !void { |
| ... | ... | @@ -653,7 +552,7 @@ fn parseOs(result: *Query, diags: *ParseOptions.Diagnostics, text: []const u8) ! |
| 653 | 552 | result.os_tag = std.meta.stringToEnum(Target.Os.Tag, os_name) orelse |
| 654 | 553 | return error.UnknownOperatingSystem; |
| 655 | 554 | } |
| 656 | const tag = result.getOsTag(); | |
| 555 | const tag = result.os_tag orelse builtin.os.tag; | |
| 657 | 556 | diags.os_tag = tag; |
| 658 | 557 | |
| 659 | 558 | const version_text = it.rest(); |
| ... | ... | @@ -741,12 +640,35 @@ fn parseOs(result: *Query, diags: *ParseOptions.Diagnostics, text: []const u8) ! |
| 741 | 640 | } |
| 742 | 641 | } |
| 743 | 642 | |
| 643 | pub fn eql(a: Query, b: Query) bool { | |
| 644 | if (a.cpu_arch != b.cpu_arch) return false; | |
| 645 | if (!a.cpu_model.eql(b.cpu_model)) return false; | |
| 646 | if (!a.cpu_features_add.eql(b.cpu_features_add)) return false; | |
| 647 | if (!a.cpu_features_sub.eql(b.cpu_features_sub)) return false; | |
| 648 | if (a.os_tag != b.os_tag) return false; | |
| 649 | if (!OsVersion.eqlOpt(a.os_version_min, b.os_version_min)) return false; | |
| 650 | if (!OsVersion.eqlOpt(a.os_version_max, b.os_version_max)) return false; | |
| 651 | if (!versionEqualOpt(a.glibc_version, b.glibc_version)) return false; | |
| 652 | if (a.abi != b.abi) return false; | |
| 653 | if (!a.dynamic_linker.eql(b.dynamic_linker)) return false; | |
| 654 | if (a.ofmt != b.ofmt) return false; | |
| 655 | ||
| 656 | return true; | |
| 657 | } | |
| 658 | ||
| 659 | fn versionEqualOpt(a: ?SemanticVersion, b: ?SemanticVersion) bool { | |
| 660 | if (a == null and b == null) return true; | |
| 661 | if (a == null or b == null) return false; | |
| 662 | return SemanticVersion.order(a.?, b.?) == .eq; | |
| 663 | } | |
| 664 | ||
| 744 | 665 | const Query = @This(); |
| 745 | 666 | const std = @import("../std.zig"); |
| 746 | 667 | const builtin = @import("builtin"); |
| 747 | 668 | const assert = std.debug.assert; |
| 748 | 669 | const Target = std.Target; |
| 749 | 670 | const mem = std.mem; |
| 671 | const Allocator = std.mem.Allocator; | |
| 750 | 672 | |
| 751 | 673 | test parse { |
| 752 | 674 | if (builtin.target.isGnuLibC()) { |
| ... | ... | @@ -760,7 +682,7 @@ test parse { |
| 760 | 682 | const triple = std.fmt.bufPrint( |
| 761 | 683 | buf[0..], |
| 762 | 684 | "native-native-{s}.2.1.1", |
| 763 | .{@tagName(builtin.abi)}, | |
| 685 | .{@tagName(builtin.target.abi)}, | |
| 764 | 686 | ) catch unreachable; |
| 765 | 687 | |
| 766 | 688 | try std.testing.expectEqualSlices(u8, triple, text); |
| ... | ... | @@ -789,7 +711,7 @@ test parse { |
| 789 | 711 | .arch_os_abi = "x86_64-linux-gnu", |
| 790 | 712 | .cpu_features = "x86_64-sse-sse2-avx-cx8", |
| 791 | 713 | }); |
| 792 | const target = query.toTarget(); | |
| 714 | const target = try std.zig.system.resolveTargetQuery(query); | |
| 793 | 715 | |
| 794 | 716 | try std.testing.expect(target.os.tag == .linux); |
| 795 | 717 | try std.testing.expect(target.abi == .gnu); |
| ... | ... | @@ -814,7 +736,7 @@ test parse { |
| 814 | 736 | .arch_os_abi = "arm-linux-musleabihf", |
| 815 | 737 | .cpu_features = "generic+v8a", |
| 816 | 738 | }); |
| 817 | const target = query.toTarget(); | |
| 739 | const target = try std.zig.system.resolveTargetQuery(query); | |
| 818 | 740 | |
| 819 | 741 | try std.testing.expect(target.os.tag == .linux); |
| 820 | 742 | try std.testing.expect(target.abi == .musleabihf); |
| ... | ... | @@ -831,7 +753,7 @@ test parse { |
| 831 | 753 | .arch_os_abi = "aarch64-linux.3.10...4.4.1-gnu.2.27", |
| 832 | 754 | .cpu_features = "generic+v8a", |
| 833 | 755 | }); |
| 834 | const target = query.toTarget(); | |
| 756 | const target = try std.zig.system.resolveTargetQuery(query); | |
| 835 | 757 | |
| 836 | 758 | try std.testing.expect(target.cpu.arch == .aarch64); |
| 837 | 759 | try std.testing.expect(target.os.tag == .linux); |
lib/std/zig.zig+42-4| ... | ... | @@ -1,7 +1,4 @@ |
| 1 | const std = @import("std.zig"); | |
| 2 | const tokenizer = @import("zig/tokenizer.zig"); | |
| 3 | 1 | pub const fmt = @import("zig/fmt.zig"); |
| 4 | const assert = std.debug.assert; | |
| 5 | 2 | |
| 6 | 3 | pub const ErrorBundle = @import("zig/ErrorBundle.zig"); |
| 7 | 4 | pub const Server = @import("zig/Server.zig"); |
| ... | ... | @@ -115,7 +112,7 @@ pub const BinNameOptions = struct { |
| 115 | 112 | }; |
| 116 | 113 | |
| 117 | 114 | /// Returns the standard file system basename of a binary generated by the Zig compiler. |
| 118 | pub fn binNameAlloc(allocator: std.mem.Allocator, options: BinNameOptions) error{OutOfMemory}![]u8 { | |
| 115 | pub fn binNameAlloc(allocator: Allocator, options: BinNameOptions) error{OutOfMemory}![]u8 { | |
| 119 | 116 | const root_name = options.root_name; |
| 120 | 117 | const target = options.target; |
| 121 | 118 | switch (target.ofmt) { |
| ... | ... | @@ -281,6 +278,47 @@ pub const BuildId = union(enum) { |
| 281 | 278 | } |
| 282 | 279 | }; |
| 283 | 280 | |
| 281 | /// Renders a `std.Target.Cpu` value into a textual representation that can be parsed | |
| 282 | /// via the `-mcpu` flag passed to the Zig compiler. | |
| 283 | /// Appends the result to `buffer`. | |
| 284 | pub fn serializeCpu(buffer: *std.ArrayList(u8), cpu: std.Target.Cpu) Allocator.Error!void { | |
| 285 | const all_features = cpu.arch.allFeaturesList(); | |
| 286 | var populated_cpu_features = cpu.model.features; | |
| 287 | populated_cpu_features.populateDependencies(all_features); | |
| 288 | ||
| 289 | try buffer.appendSlice(cpu.model.name); | |
| 290 | ||
| 291 | if (populated_cpu_features.eql(cpu.features)) { | |
| 292 | // The CPU name alone is sufficient. | |
| 293 | return; | |
| 294 | } | |
| 295 | ||
| 296 | for (all_features, 0..) |feature, i_usize| { | |
| 297 | const i: std.Target.Cpu.Feature.Set.Index = @intCast(i_usize); | |
| 298 | const in_cpu_set = populated_cpu_features.isEnabled(i); | |
| 299 | const in_actual_set = cpu.features.isEnabled(i); | |
| 300 | try buffer.ensureUnusedCapacity(feature.name.len + 1); | |
| 301 | if (in_cpu_set and !in_actual_set) { | |
| 302 | buffer.appendAssumeCapacity('-'); | |
| 303 | buffer.appendSliceAssumeCapacity(feature.name); | |
| 304 | } else if (!in_cpu_set and in_actual_set) { | |
| 305 | buffer.appendAssumeCapacity('+'); | |
| 306 | buffer.appendSliceAssumeCapacity(feature.name); | |
| 307 | } | |
| 308 | } | |
| 309 | } | |
| 310 | ||
| 311 | pub fn serializeCpuAlloc(ally: Allocator, cpu: std.Target.Cpu) Allocator.Error![]u8 { | |
| 312 | var buffer = std.ArrayList(u8).init(ally); | |
| 313 | try serializeCpu(&buffer, cpu); | |
| 314 | return buffer.toOwnedSlice(); | |
| 315 | } | |
| 316 | ||
| 317 | const std = @import("std.zig"); | |
| 318 | const tokenizer = @import("zig/tokenizer.zig"); | |
| 319 | const assert = std.debug.assert; | |
| 320 | const Allocator = std.mem.Allocator; | |
| 321 | ||
| 284 | 322 | test { |
| 285 | 323 | @import("std").testing.refAllDecls(@This()); |
| 286 | 324 | } |
lib/std/zig/system.zig+23-6| ... | ... | @@ -163,7 +163,8 @@ pub const DetectError = error{ |
| 163 | 163 | /// components by detecting the native system, and then resolves |
| 164 | 164 | /// standard/default parts relative to that. |
| 165 | 165 | pub fn resolveTargetQuery(query: Target.Query) DetectError!Target { |
| 166 | var os = query.getOsTag().defaultVersionRange(query.getCpuArch()); | |
| 166 | const query_os_tag = query.os_tag orelse builtin.os.tag; | |
| 167 | var os = query_os_tag.defaultVersionRange(query.cpu_arch orelse builtin.cpu.arch); | |
| 167 | 168 | if (query.os_tag == null) { |
| 168 | 169 | switch (builtin.target.os.tag) { |
| 169 | 170 | .linux => { |
| ... | ... | @@ -292,7 +293,7 @@ pub fn resolveTargetQuery(query: Target.Query) DetectError!Target { |
| 292 | 293 | |
| 293 | 294 | if (query.os_version_min) |min| switch (min) { |
| 294 | 295 | .none => {}, |
| 295 | .semver => |semver| switch (query.getOsTag()) { | |
| 296 | .semver => |semver| switch (os.tag) { | |
| 296 | 297 | .linux => os.version_range.linux.range.min = semver, |
| 297 | 298 | else => os.version_range.semver.min = semver, |
| 298 | 299 | }, |
| ... | ... | @@ -301,7 +302,7 @@ pub fn resolveTargetQuery(query: Target.Query) DetectError!Target { |
| 301 | 302 | |
| 302 | 303 | if (query.os_version_max) |max| switch (max) { |
| 303 | 304 | .none => {}, |
| 304 | .semver => |semver| switch (query.getOsTag()) { | |
| 305 | .semver => |semver| switch (os.tag) { | |
| 305 | 306 | .linux => os.version_range.linux.range.max = semver, |
| 306 | 307 | else => os.version_range.semver.max = semver, |
| 307 | 308 | }, |
| ... | ... | @@ -309,13 +310,12 @@ pub fn resolveTargetQuery(query: Target.Query) DetectError!Target { |
| 309 | 310 | }; |
| 310 | 311 | |
| 311 | 312 | if (query.glibc_version) |glibc| { |
| 312 | assert(query.isGnuLibC()); | |
| 313 | 313 | os.version_range.linux.glibc = glibc; |
| 314 | 314 | } |
| 315 | 315 | |
| 316 | 316 | // Until https://github.com/ziglang/zig/issues/4592 is implemented (support detecting the |
| 317 | 317 | // native CPU architecture as being different than the current target), we use this: |
| 318 | const cpu_arch = query.getCpuArch(); | |
| 318 | const cpu_arch = query.cpu_arch orelse builtin.cpu.arch; | |
| 319 | 319 | |
| 320 | 320 | const cpu = switch (query.cpu_model) { |
| 321 | 321 | .native => detectNativeCpuAndFeatures(cpu_arch, os, query), |
| ... | ... | @@ -361,10 +361,27 @@ pub fn resolveTargetQuery(query: Target.Query) DetectError!Target { |
| 361 | 361 | }, |
| 362 | 362 | else => {}, |
| 363 | 363 | } |
| 364 | query.updateCpuFeatures(&result.cpu.features); | |
| 364 | updateCpuFeatures( | |
| 365 | &result.cpu.features, | |
| 366 | cpu_arch.allFeaturesList(), | |
| 367 | query.cpu_features_add, | |
| 368 | query.cpu_features_sub, | |
| 369 | ); | |
| 365 | 370 | return result; |
| 366 | 371 | } |
| 367 | 372 | |
| 373 | fn updateCpuFeatures( | |
| 374 | set: *Target.Cpu.Feature.Set, | |
| 375 | all_features_list: []const Target.Cpu.Feature, | |
| 376 | add_set: Target.Cpu.Feature.Set, | |
| 377 | sub_set: Target.Cpu.Feature.Set, | |
| 378 | ) void { | |
| 379 | set.removeFeatureSet(sub_set); | |
| 380 | set.addFeatureSet(add_set); | |
| 381 | set.populateDependencies(all_features_list); | |
| 382 | set.removeFeatureSet(sub_set); | |
| 383 | } | |
| 384 | ||
| 368 | 385 | fn detectNativeCpuAndFeatures(cpu_arch: Target.Cpu.Arch, os: Target.Os, query: Target.Query) ?Target.Cpu { |
| 369 | 386 | // Here we switch on a comptime value rather than `cpu_arch`. This is valid because `cpu_arch`, |
| 370 | 387 | // although it is a runtime value, is guaranteed to be one of the architectures in the set |
src/libc_installation.zig+6-7| ... | ... | @@ -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.Target.Query, | |
| 44 | target: std.Target, | |
| 45 | 45 | ) !LibCInstallation { |
| 46 | 46 | var self: LibCInstallation = .{}; |
| 47 | 47 | |
| ... | ... | @@ -95,24 +95,23 @@ pub const LibCInstallation = struct { |
| 95 | 95 | return error.ParseError; |
| 96 | 96 | } |
| 97 | 97 | |
| 98 | const os_tag = target.getOsTag(); | |
| 98 | const os_tag = target.os.tag; | |
| 99 | 99 | if (self.crt_dir == null and !target.isDarwin()) { |
| 100 | 100 | log.err("crt_dir may not be empty for {s}\n", .{@tagName(os_tag)}); |
| 101 | 101 | return error.ParseError; |
| 102 | 102 | } |
| 103 | 103 | |
| 104 | const abi = target.getAbi(); | |
| 105 | if (self.msvc_lib_dir == null and target.isWindows() and abi == .msvc) { | |
| 104 | if (self.msvc_lib_dir == null and os_tag == .windows and target.abi == .msvc) { | |
| 106 | 105 | log.err("msvc_lib_dir may not be empty for {s}-{s}\n", .{ |
| 107 | 106 | @tagName(os_tag), |
| 108 | @tagName(abi), | |
| 107 | @tagName(target.abi), | |
| 109 | 108 | }); |
| 110 | 109 | return error.ParseError; |
| 111 | 110 | } |
| 112 | if (self.kernel32_lib_dir == null and target.isWindows() and abi == .msvc) { | |
| 111 | if (self.kernel32_lib_dir == null and os_tag == .windows and target.abi == .msvc) { | |
| 113 | 112 | log.err("kernel32_lib_dir may not be empty for {s}-{s}\n", .{ |
| 114 | 113 | @tagName(os_tag), |
| 115 | @tagName(abi), | |
| 114 | @tagName(target.abi), | |
| 116 | 115 | }); |
| 117 | 116 | return error.ParseError; |
| 118 | 117 | } |
src/main.zig+8-8| ... | ... | @@ -2696,13 +2696,13 @@ fn buildOutputType( |
| 2696 | 2696 | } |
| 2697 | 2697 | |
| 2698 | 2698 | if (use_lld) |opt| { |
| 2699 | if (opt and target_query.isDarwin()) { | |
| 2699 | if (opt and target.isDarwin()) { | |
| 2700 | 2700 | fatal("LLD requested with Mach-O object format. Only the self-hosted linker is supported for this target.", .{}); |
| 2701 | 2701 | } |
| 2702 | 2702 | } |
| 2703 | 2703 | |
| 2704 | 2704 | if (want_lto) |opt| { |
| 2705 | if (opt and target_query.isDarwin()) { | |
| 2705 | if (opt and target.isDarwin()) { | |
| 2706 | 2706 | fatal("LTO is not yet supported with the Mach-O object format. More details: https://github.com/ziglang/zig/issues/8680", .{}); |
| 2707 | 2707 | } |
| 2708 | 2708 | } |
| ... | ... | @@ -2772,7 +2772,7 @@ fn buildOutputType( |
| 2772 | 2772 | |
| 2773 | 2773 | var libc_installation: ?LibCInstallation = null; |
| 2774 | 2774 | if (libc_paths_file) |paths_file| { |
| 2775 | libc_installation = LibCInstallation.parse(arena, paths_file, target_query) catch |err| { | |
| 2775 | libc_installation = LibCInstallation.parse(arena, paths_file, target) catch |err| { | |
| 2776 | 2776 | fatal("unable to parse libc paths file at path {s}: {s}", .{ paths_file, @errorName(err) }); |
| 2777 | 2777 | }; |
| 2778 | 2778 | } |
| ... | ... | @@ -2865,7 +2865,7 @@ fn buildOutputType( |
| 2865 | 2865 | libc_installation = try LibCInstallation.findNative(.{ |
| 2866 | 2866 | .allocator = arena, |
| 2867 | 2867 | .verbose = true, |
| 2868 | .target = target_query.toTarget(), | |
| 2868 | .target = target, | |
| 2869 | 2869 | }); |
| 2870 | 2870 | |
| 2871 | 2871 | try lib_dirs.appendSlice(&.{ libc_installation.?.msvc_lib_dir.?, libc_installation.?.kernel32_lib_dir.? }); |
| ... | ... | @@ -4755,6 +4755,7 @@ pub fn cmdLibC(gpa: Allocator, args: []const []const u8) !void { |
| 4755 | 4755 | const target_query = try parseTargetQueryOrReportFatalError(gpa, .{ |
| 4756 | 4756 | .arch_os_abi = target_arch_os_abi, |
| 4757 | 4757 | }); |
| 4758 | const target = try std.zig.system.resolveTargetQuery(target_query); | |
| 4758 | 4759 | |
| 4759 | 4760 | if (print_includes) { |
| 4760 | 4761 | var arena_state = std.heap.ArenaAllocator.init(gpa); |
| ... | ... | @@ -4764,7 +4765,7 @@ pub fn cmdLibC(gpa: Allocator, args: []const []const u8) !void { |
| 4764 | 4765 | const libc_installation: ?*LibCInstallation = libc: { |
| 4765 | 4766 | if (input_file) |libc_file| { |
| 4766 | 4767 | const libc = try arena.create(LibCInstallation); |
| 4767 | libc.* = LibCInstallation.parse(arena, libc_file, target_query) catch |err| { | |
| 4768 | libc.* = LibCInstallation.parse(arena, libc_file, target) catch |err| { | |
| 4768 | 4769 | fatal("unable to parse libc file at path {s}: {s}", .{ libc_file, @errorName(err) }); |
| 4769 | 4770 | }; |
| 4770 | 4771 | break :libc libc; |
| ... | ... | @@ -4779,7 +4780,6 @@ pub fn cmdLibC(gpa: Allocator, args: []const []const u8) !void { |
| 4779 | 4780 | }; |
| 4780 | 4781 | defer zig_lib_directory.handle.close(); |
| 4781 | 4782 | |
| 4782 | const target = target_query.toTarget(); | |
| 4783 | 4783 | const is_native_abi = target_query.isNativeAbi(); |
| 4784 | 4784 | |
| 4785 | 4785 | const libc_dirs = Compilation.detectLibCIncludeDirs( |
| ... | ... | @@ -4810,7 +4810,7 @@ pub fn cmdLibC(gpa: Allocator, args: []const []const u8) !void { |
| 4810 | 4810 | } |
| 4811 | 4811 | |
| 4812 | 4812 | if (input_file) |libc_file| { |
| 4813 | var libc = LibCInstallation.parse(gpa, libc_file, target_query) catch |err| { | |
| 4813 | var libc = LibCInstallation.parse(gpa, libc_file, target) catch |err| { | |
| 4814 | 4814 | fatal("unable to parse libc file at path {s}: {s}", .{ libc_file, @errorName(err) }); |
| 4815 | 4815 | }; |
| 4816 | 4816 | defer libc.deinit(gpa); |
| ... | ... | @@ -4821,7 +4821,7 @@ pub fn cmdLibC(gpa: Allocator, args: []const []const u8) !void { |
| 4821 | 4821 | var libc = LibCInstallation.findNative(.{ |
| 4822 | 4822 | .allocator = gpa, |
| 4823 | 4823 | .verbose = true, |
| 4824 | .target = try std.zig.system.resolveTargetQuery(target_query), | |
| 4824 | .target = target, | |
| 4825 | 4825 | }) catch |err| { |
| 4826 | 4826 | fatal("unable to detect native libc: {s}", .{@errorName(err)}); |
| 4827 | 4827 | }; |
test/tests.zig+23-25| ... | ... | @@ -1036,14 +1036,17 @@ pub fn addModuleTests(b: *std.Build, options: ModuleTestOptions) *Step { |
| 1036 | 1036 | |
| 1037 | 1037 | for (test_targets) |test_target| { |
| 1038 | 1038 | const is_native = test_target.target.isNative() or |
| 1039 | (test_target.target.getOsTag() == builtin.os.tag and | |
| 1040 | test_target.target.getCpuArch() == builtin.cpu.arch); | |
| 1039 | (test_target.target.os_tag == builtin.os.tag and | |
| 1040 | test_target.target.cpu_arch == builtin.cpu.arch); | |
| 1041 | 1041 | |
| 1042 | 1042 | if (options.skip_non_native and !is_native) |
| 1043 | 1043 | continue; |
| 1044 | 1044 | |
| 1045 | const resolved_target = b.resolveTargetQuery(test_target.target); | |
| 1046 | const target = resolved_target.target; | |
| 1047 | ||
| 1045 | 1048 | if (options.skip_cross_glibc and !test_target.target.isNative() and |
| 1046 | test_target.target.isGnuLibC() and test_target.link_libc == true) | |
| 1049 | target.isGnuLibC() and test_target.link_libc == true) | |
| 1047 | 1050 | continue; |
| 1048 | 1051 | |
| 1049 | 1052 | if (options.skip_libc and test_target.link_libc == true) |
| ... | ... | @@ -1053,35 +1056,30 @@ pub fn addModuleTests(b: *std.Build, options: ModuleTestOptions) *Step { |
| 1053 | 1056 | continue; |
| 1054 | 1057 | |
| 1055 | 1058 | // TODO get compiler-rt tests passing for self-hosted backends. |
| 1056 | if ((test_target.target.getCpuArch() != .x86_64 or | |
| 1057 | test_target.target.getObjectFormat() != .elf) and | |
| 1059 | if ((target.cpu.arch != .x86_64 or target.ofmt != .elf) and | |
| 1058 | 1060 | test_target.use_llvm == false and mem.eql(u8, options.name, "compiler-rt")) |
| 1059 | 1061 | continue; |
| 1060 | 1062 | |
| 1061 | 1063 | // TODO get compiler-rt tests passing for wasm32-wasi |
| 1062 | 1064 | // currently causes "LLVM ERROR: Unable to expand fixed point multiplication." |
| 1063 | if (test_target.target.getCpuArch() == .wasm32 and | |
| 1064 | test_target.target.getOsTag() == .wasi and | |
| 1065 | if (target.cpu.arch == .wasm32 and target.os.tag == .wasi and | |
| 1065 | 1066 | mem.eql(u8, options.name, "compiler-rt")) |
| 1066 | 1067 | { |
| 1067 | 1068 | continue; |
| 1068 | 1069 | } |
| 1069 | 1070 | |
| 1070 | 1071 | // TODO get universal-libc tests passing for other self-hosted backends. |
| 1071 | if (test_target.target.getCpuArch() != .x86_64 and | |
| 1072 | if (target.cpu.arch != .x86_64 and | |
| 1072 | 1073 | test_target.use_llvm == false and mem.eql(u8, options.name, "universal-libc")) |
| 1073 | 1074 | continue; |
| 1074 | 1075 | |
| 1075 | 1076 | // TODO get std lib tests passing for other self-hosted backends. |
| 1076 | if ((test_target.target.getCpuArch() != .x86_64 or | |
| 1077 | test_target.target.getOsTag() != .linux) and | |
| 1077 | if ((target.cpu.arch != .x86_64 or target.os.tag != .linux) and | |
| 1078 | 1078 | test_target.use_llvm == false and mem.eql(u8, options.name, "std")) |
| 1079 | 1079 | continue; |
| 1080 | 1080 | |
| 1081 | if (test_target.target.getCpuArch() == .x86_64 and | |
| 1082 | test_target.target.getOsTag() == .windows and | |
| 1083 | test_target.target.cpu_arch == null and | |
| 1084 | test_target.optimize_mode != .Debug and | |
| 1081 | if (target.cpu.arch == .x86_64 and target.os.tag == .windows and | |
| 1082 | test_target.target.cpu_arch == null and test_target.optimize_mode != .Debug and | |
| 1085 | 1083 | mem.eql(u8, options.name, "std")) |
| 1086 | 1084 | { |
| 1087 | 1085 | // https://github.com/ziglang/zig/issues/17902 |
| ... | ... | @@ -1094,11 +1092,11 @@ pub fn addModuleTests(b: *std.Build, options: ModuleTestOptions) *Step { |
| 1094 | 1092 | if (!want_this_mode) continue; |
| 1095 | 1093 | |
| 1096 | 1094 | const libc_suffix = if (test_target.link_libc == true) "-libc" else ""; |
| 1097 | const triple_txt = test_target.target.zigTriple(b.allocator) catch @panic("OOM"); | |
| 1098 | const model_txt = test_target.target.getCpuModel().name; | |
| 1095 | const triple_txt = target.zigTriple(b.allocator) catch @panic("OOM"); | |
| 1096 | const model_txt = target.cpu.model.name; | |
| 1099 | 1097 | |
| 1100 | 1098 | // wasm32-wasi builds need more RAM, idk why |
| 1101 | const max_rss = if (test_target.target.getOs().tag == .wasi) | |
| 1099 | const max_rss = if (target.os.tag == .wasi) | |
| 1102 | 1100 | options.max_rss * 2 |
| 1103 | 1101 | else |
| 1104 | 1102 | options.max_rss; |
| ... | ... | @@ -1106,7 +1104,7 @@ pub fn addModuleTests(b: *std.Build, options: ModuleTestOptions) *Step { |
| 1106 | 1104 | const these_tests = b.addTest(.{ |
| 1107 | 1105 | .root_source_file = .{ .path = options.root_src }, |
| 1108 | 1106 | .optimize = test_target.optimize_mode, |
| 1109 | .target = b.resolveTargetQuery(test_target.target), | |
| 1107 | .target = resolved_target, | |
| 1110 | 1108 | .max_rss = max_rss, |
| 1111 | 1109 | .filter = options.test_filter, |
| 1112 | 1110 | .link_libc = test_target.link_libc, |
| ... | ... | @@ -1120,7 +1118,7 @@ pub fn addModuleTests(b: *std.Build, options: ModuleTestOptions) *Step { |
| 1120 | 1118 | const single_threaded_suffix = if (test_target.single_threaded == true) "-single" else ""; |
| 1121 | 1119 | const backend_suffix = if (test_target.use_llvm == true) |
| 1122 | 1120 | "-llvm" |
| 1123 | else if (test_target.target.ofmt == std.Target.ObjectFormat.c) | |
| 1121 | else if (target.ofmt == std.Target.ObjectFormat.c) | |
| 1124 | 1122 | "-cbe" |
| 1125 | 1123 | else if (test_target.use_llvm == false) |
| 1126 | 1124 | "-selfhosted" |
| ... | ... | @@ -1131,7 +1129,7 @@ pub fn addModuleTests(b: *std.Build, options: ModuleTestOptions) *Step { |
| 1131 | 1129 | |
| 1132 | 1130 | these_tests.addIncludePath(.{ .path = "test" }); |
| 1133 | 1131 | |
| 1134 | if (test_target.target.getOs().tag == .wasi) { | |
| 1132 | if (target.os.tag == .wasi) { | |
| 1135 | 1133 | // WASI's default stack size can be too small for some big tests. |
| 1136 | 1134 | these_tests.stack_size = 2 * 1024 * 1024; |
| 1137 | 1135 | } |
| ... | ... | @@ -1148,14 +1146,14 @@ pub fn addModuleTests(b: *std.Build, options: ModuleTestOptions) *Step { |
| 1148 | 1146 | use_pic, |
| 1149 | 1147 | }); |
| 1150 | 1148 | |
| 1151 | if (test_target.target.ofmt == std.Target.ObjectFormat.c) { | |
| 1152 | var altered_target = test_target.target; | |
| 1153 | altered_target.ofmt = null; | |
| 1149 | if (target.ofmt == std.Target.ObjectFormat.c) { | |
| 1150 | var altered_query = test_target.target; | |
| 1151 | altered_query.ofmt = null; | |
| 1154 | 1152 | |
| 1155 | 1153 | const compile_c = b.addExecutable(.{ |
| 1156 | 1154 | .name = qualified_name, |
| 1157 | 1155 | .link_libc = test_target.link_libc, |
| 1158 | .target = b.resolveTargetQuery(altered_target), | |
| 1156 | .target = b.resolveTargetQuery(altered_query), | |
| 1159 | 1157 | .zig_lib_dir = .{ .path = "lib" }, |
| 1160 | 1158 | }); |
| 1161 | 1159 | compile_c.addCSourceFile(.{ |
| ... | ... | @@ -1179,7 +1177,7 @@ pub fn addModuleTests(b: *std.Build, options: ModuleTestOptions) *Step { |
| 1179 | 1177 | }, |
| 1180 | 1178 | }); |
| 1181 | 1179 | compile_c.addIncludePath(.{ .path = "lib" }); // for zig.h |
| 1182 | if (test_target.target.getOsTag() == .windows) { | |
| 1180 | if (target.os.tag == .windows) { | |
| 1183 | 1181 | if (true) { |
| 1184 | 1182 | // Unfortunately this requires about 8G of RAM for clang to compile |
| 1185 | 1183 | // and our Windows CI runners do not have this much. |