| ... | ... | @@ -25,10 +25,14 @@ os_version_min: ?OsVersion = null, |
| 25 | 25 | /// When `os_tag` is native, `null` means equal to the native OS version. |
| 26 | 26 | os_version_max: ?OsVersion = null, |
| 27 | 27 | |
| 28 | | /// `null` means default when cross compiling, or native when os_tag is native. |
| 28 | /// `null` means default when cross compiling, or native when `os_tag` is native. |
| 29 | 29 | /// If `isGnuLibC()` is `false`, this must be `null` and is ignored. |
| 30 | 30 | glibc_version: ?SemanticVersion = null, |
| 31 | 31 | |
| 32 | /// `null` means default when cross compiling, or native when `os_tag` is native. |
| 33 | /// If `isAndroid()` is `false`, this must be `null` and is ignored. |
| 34 | android_api_level: ?u32 = null, |
| 35 | |
| 32 | 36 | /// `null` means the native C ABI, if `os_tag` is native, otherwise it means the default C ABI. |
| 33 | 37 | abi: ?Target.Abi = null, |
| 34 | 38 | |
| ... | ... | @@ -98,10 +102,8 @@ pub fn fromTarget(target: Target) Query { |
| 98 | 102 | .os_version_min = undefined, |
| 99 | 103 | .os_version_max = undefined, |
| 100 | 104 | .abi = target.abi, |
| 101 | | .glibc_version = if (target.isGnuLibC()) |
| 102 | | target.os.version_range.linux.glibc |
| 103 | | else |
| 104 | | null, |
| 105 | .glibc_version = if (target.isGnuLibC()) target.os.version_range.linux.glibc else null, |
| 106 | .android_api_level = if (target.abi.isAndroid()) target.os.version_range.linux.android else null, |
| 105 | 107 | }; |
| 106 | 108 | result.updateOsVersionRange(target.os); |
| 107 | 109 | |
| ... | ... | @@ -147,7 +149,7 @@ pub const ParseOptions = struct { |
| 147 | 149 | /// The fields are, respectively: |
| 148 | 150 | /// * CPU Architecture |
| 149 | 151 | /// * Operating System (and optional version range) |
| 150 | | /// * C ABI (optional, with optional glibc version) |
| 152 | /// * C ABI (optional, with optional glibc version or Android API level) |
| 151 | 153 | /// The string "native" can be used for CPU architecture as well as Operating System. |
| 152 | 154 | /// If the CPU Architecture is specified as "native", then the Operating System and C ABI may be omitted. |
| 153 | 155 | arch_os_abi: []const u8 = "native", |
| ... | ... | @@ -234,6 +236,11 @@ pub fn parse(args: ParseOptions) !Query { |
| 234 | 236 | error.Overflow => return error.InvalidAbiVersion, |
| 235 | 237 | error.InvalidVersion => return error.InvalidAbiVersion, |
| 236 | 238 | }; |
| 239 | } else if (abi.isAndroid()) { |
| 240 | result.android_api_level = std.fmt.parseUnsigned(u32, abi_ver_text, 10) catch |err| switch (err) { |
| 241 | error.InvalidCharacter => return error.InvalidVersion, |
| 242 | error.Overflow => return error.Overflow, |
| 243 | }; |
| 237 | 244 | } else { |
| 238 | 245 | return error.InvalidAbiVersion; |
| 239 | 246 | } |
| ... | ... | @@ -355,7 +362,7 @@ pub fn isNativeCpu(self: Query) bool { |
| 355 | 362 | |
| 356 | 363 | pub fn isNativeOs(self: Query) bool { |
| 357 | 364 | return self.os_tag == null and self.os_version_min == null and self.os_version_max == null and |
| 358 | | self.dynamic_linker.get() == null and self.glibc_version == null; |
| 365 | self.dynamic_linker.get() == null and self.glibc_version == null and self.android_api_level == null; |
| 359 | 366 | } |
| 360 | 367 | |
| 361 | 368 | pub fn isNativeAbi(self: Query) bool { |
| ... | ... | @@ -439,6 +446,13 @@ pub fn zigTriple(self: Query, allocator: Allocator) Allocator.Error![]u8 { |
| 439 | 446 | result.appendSliceAssumeCapacity(name); |
| 440 | 447 | result.appendAssumeCapacity('.'); |
| 441 | 448 | try formatVersion(v, result.writer()); |
| 449 | } else if (self.android_api_level) |lvl| { |
| 450 | const name = if (self.abi) |abi| @tagName(abi) else "android"; |
| 451 | try result.ensureUnusedCapacity(name.len + 2); |
| 452 | result.appendAssumeCapacity('-'); |
| 453 | result.appendSliceAssumeCapacity(name); |
| 454 | result.appendAssumeCapacity('.'); |
| 455 | try result.writer().print("{d}", .{lvl}); |
| 442 | 456 | } else if (self.abi) |abi| { |
| 443 | 457 | const name = @tagName(abi); |
| 444 | 458 | try result.ensureUnusedCapacity(name.len + 1); |
| ... | ... | @@ -561,6 +575,7 @@ pub fn eql(a: Query, b: Query) bool { |
| 561 | 575 | if (!OsVersion.eqlOpt(a.os_version_min, b.os_version_min)) return false; |
| 562 | 576 | if (!OsVersion.eqlOpt(a.os_version_max, b.os_version_max)) return false; |
| 563 | 577 | if (!versionEqualOpt(a.glibc_version, b.glibc_version)) return false; |
| 578 | if (a.android_api_level != b.android_api_level) return false; |
| 564 | 579 | if (a.abi != b.abi) return false; |
| 565 | 580 | if (!a.dynamic_linker.eql(b.dynamic_linker)) return false; |
| 566 | 581 | if (a.ofmt != b.ofmt) return false; |
| ... | ... | @@ -592,6 +607,15 @@ test parse { |
| 592 | 607 | |
| 593 | 608 | try std.testing.expectEqualSlices(u8, "native-native-gnu.2.1.1", text); |
| 594 | 609 | } |
| 610 | if (builtin.target.abi.isAndroid()) { |
| 611 | var query = try Query.parse(.{}); |
| 612 | query.android_api_level = 30; |
| 613 | |
| 614 | const text = try query.zigTriple(std.testing.allocator); |
| 615 | defer std.testing.allocator.free(text); |
| 616 | |
| 617 | try std.testing.expectEqualSlices(u8, "native-native-android.30", text); |
| 618 | } |
| 595 | 619 | { |
| 596 | 620 | const query = try Query.parse(.{ |
| 597 | 621 | .arch_os_abi = "aarch64-linux", |
| ... | ... | @@ -677,4 +701,25 @@ test parse { |
| 677 | 701 | defer std.testing.allocator.free(text); |
| 678 | 702 | try std.testing.expectEqualSlices(u8, "aarch64-linux.3.10...4.4.1-gnu.2.27", text); |
| 679 | 703 | } |
| 704 | { |
| 705 | const query = try Query.parse(.{ |
| 706 | .arch_os_abi = "aarch64-linux.3.10...4.4.1-android.30", |
| 707 | }); |
| 708 | const target = try std.zig.system.resolveTargetQuery(query); |
| 709 | |
| 710 | try std.testing.expect(target.cpu.arch == .aarch64); |
| 711 | try std.testing.expect(target.os.tag == .linux); |
| 712 | try std.testing.expect(target.os.version_range.linux.range.min.major == 3); |
| 713 | try std.testing.expect(target.os.version_range.linux.range.min.minor == 10); |
| 714 | try std.testing.expect(target.os.version_range.linux.range.min.patch == 0); |
| 715 | try std.testing.expect(target.os.version_range.linux.range.max.major == 4); |
| 716 | try std.testing.expect(target.os.version_range.linux.range.max.minor == 4); |
| 717 | try std.testing.expect(target.os.version_range.linux.range.max.patch == 1); |
| 718 | try std.testing.expect(target.os.version_range.linux.android == 30); |
| 719 | try std.testing.expect(target.abi == .android); |
| 720 | |
| 721 | const text = try query.zigTriple(std.testing.allocator); |
| 722 | defer std.testing.allocator.free(text); |
| 723 | try std.testing.expectEqualSlices(u8, "aarch64-linux.3.10...4.4.1-android.30", text); |
| 724 | } |
| 680 | 725 | } |