| ... | @@ -25,10 +25,14 @@ os_version_min: ?OsVersion = null, | ... | @@ -25,10 +25,14 @@ os_version_min: ?OsVersion = null, |
| 25 | /// When `os_tag` is native, `null` means equal to the native OS version. | 25 | /// When `os_tag` is native, `null` means equal to the native OS version. |
| 26 | os_version_max: ?OsVersion = null, | 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 | /// If `isGnuLibC()` is `false`, this must be `null` and is ignored. | 29 | /// If `isGnuLibC()` is `false`, this must be `null` and is ignored. |
| 30 | glibc_version: ?SemanticVersion = null, | 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 | /// `null` means the native C ABI, if `os_tag` is native, otherwise it means the default C ABI. | 36 | /// `null` means the native C ABI, if `os_tag` is native, otherwise it means the default C ABI. |
| 33 | abi: ?Target.Abi = null, | 37 | abi: ?Target.Abi = null, |
| 34 | | 38 | |
| ... | @@ -98,10 +102,8 @@ pub fn fromTarget(target: Target) Query { | ... | @@ -98,10 +102,8 @@ pub fn fromTarget(target: Target) Query { |
| 98 | .os_version_min = undefined, | 102 | .os_version_min = undefined, |
| 99 | .os_version_max = undefined, | 103 | .os_version_max = undefined, |
| 100 | .abi = target.abi, | 104 | .abi = target.abi, |
| 101 | .glibc_version = if (target.isGnuLibC()) | 105 | .glibc_version = if (target.isGnuLibC()) target.os.version_range.linux.glibc else null, |
| 102 | target.os.version_range.linux.glibc | 106 | .android_api_level = if (target.abi.isAndroid()) target.os.version_range.linux.android else null, |
| 103 | else | | |
| 104 | null, | | |
| 105 | }; | 107 | }; |
| 106 | result.updateOsVersionRange(target.os); | 108 | result.updateOsVersionRange(target.os); |
| 107 | | 109 | |
| ... | @@ -147,7 +149,7 @@ pub const ParseOptions = struct { | ... | @@ -147,7 +149,7 @@ pub const ParseOptions = struct { |
| 147 | /// The fields are, respectively: | 149 | /// The fields are, respectively: |
| 148 | /// * CPU Architecture | 150 | /// * CPU Architecture |
| 149 | /// * Operating System (and optional version range) | 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 | /// The string "native" can be used for CPU architecture as well as Operating System. | 153 | /// The string "native" can be used for CPU architecture as well as Operating System. |
| 152 | /// If the CPU Architecture is specified as "native", then the Operating System and C ABI may be omitted. | 154 | /// If the CPU Architecture is specified as "native", then the Operating System and C ABI may be omitted. |
| 153 | arch_os_abi: []const u8 = "native", | 155 | arch_os_abi: []const u8 = "native", |
| ... | @@ -234,6 +236,11 @@ pub fn parse(args: ParseOptions) !Query { | ... | @@ -234,6 +236,11 @@ pub fn parse(args: ParseOptions) !Query { |
| 234 | error.Overflow => return error.InvalidAbiVersion, | 236 | error.Overflow => return error.InvalidAbiVersion, |
| 235 | error.InvalidVersion => return error.InvalidAbiVersion, | 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 | } else { | 244 | } else { |
| 238 | return error.InvalidAbiVersion; | 245 | return error.InvalidAbiVersion; |
| 239 | } | 246 | } |
| ... | @@ -355,7 +362,7 @@ pub fn isNativeCpu(self: Query) bool { | ... | @@ -355,7 +362,7 @@ pub fn isNativeCpu(self: Query) bool { |
| 355 | | 362 | |
| 356 | pub fn isNativeOs(self: Query) bool { | 363 | pub fn isNativeOs(self: Query) bool { |
| 357 | return self.os_tag == null and self.os_version_min == null and self.os_version_max == null and | 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 | pub fn isNativeAbi(self: Query) bool { | 368 | pub fn isNativeAbi(self: Query) bool { |
| ... | @@ -439,6 +446,13 @@ pub fn zigTriple(self: Query, allocator: Allocator) Allocator.Error![]u8 { | ... | @@ -439,6 +446,13 @@ pub fn zigTriple(self: Query, allocator: Allocator) Allocator.Error![]u8 { |
| 439 | result.appendSliceAssumeCapacity(name); | 446 | result.appendSliceAssumeCapacity(name); |
| 440 | result.appendAssumeCapacity('.'); | 447 | result.appendAssumeCapacity('.'); |
| 441 | try formatVersion(v, result.writer()); | 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 | } else if (self.abi) |abi| { | 456 | } else if (self.abi) |abi| { |
| 443 | const name = @tagName(abi); | 457 | const name = @tagName(abi); |
| 444 | try result.ensureUnusedCapacity(name.len + 1); | 458 | try result.ensureUnusedCapacity(name.len + 1); |
| ... | @@ -561,6 +575,7 @@ pub fn eql(a: Query, b: Query) bool { | ... | @@ -561,6 +575,7 @@ pub fn eql(a: Query, b: Query) bool { |
| 561 | if (!OsVersion.eqlOpt(a.os_version_min, b.os_version_min)) return false; | 575 | if (!OsVersion.eqlOpt(a.os_version_min, b.os_version_min)) return false; |
| 562 | if (!OsVersion.eqlOpt(a.os_version_max, b.os_version_max)) return false; | 576 | if (!OsVersion.eqlOpt(a.os_version_max, b.os_version_max)) return false; |
| 563 | if (!versionEqualOpt(a.glibc_version, b.glibc_version)) return false; | 577 | if (!versionEqualOpt(a.glibc_version, b.glibc_version)) return false; |
| | 578 | if (a.android_api_level != b.android_api_level) return false; |
| 564 | if (a.abi != b.abi) return false; | 579 | if (a.abi != b.abi) return false; |
| 565 | if (!a.dynamic_linker.eql(b.dynamic_linker)) return false; | 580 | if (!a.dynamic_linker.eql(b.dynamic_linker)) return false; |
| 566 | if (a.ofmt != b.ofmt) return false; | 581 | if (a.ofmt != b.ofmt) return false; |
| ... | @@ -592,6 +607,15 @@ test parse { | ... | @@ -592,6 +607,15 @@ test parse { |
| 592 | | 607 | |
| 593 | try std.testing.expectEqualSlices(u8, "native-native-gnu.2.1.1", text); | 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 | const query = try Query.parse(.{ | 620 | const query = try Query.parse(.{ |
| 597 | .arch_os_abi = "aarch64-linux", | 621 | .arch_os_abi = "aarch64-linux", |
| ... | @@ -677,4 +701,25 @@ test parse { | ... | @@ -677,4 +701,25 @@ test parse { |
| 677 | defer std.testing.allocator.free(text); | 701 | defer std.testing.allocator.free(text); |
| 678 | try std.testing.expectEqualSlices(u8, "aarch64-linux.3.10...4.4.1-gnu.2.27", text); | 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 | } |