diff options
| author | Alex Rønne Petersen <alex@alexrp.com> | 2024-10-30 21:57:44 +0100 |
|---|---|---|
| committer | Alex Rønne Petersen <alex@alexrp.com> | 2024-11-01 06:23:59 +0100 |
| commit | 3c1ccbdf3990b6d802cdc8a0db7c11eaac0960e8 (patch) | |
| tree | 4c68b538c30b3df1362fd03fa3947958cce6d744 /lib/std | |
| parent | c5395f7cd948f02ada095515b9d6824cbbac4f22 (diff) | |
| download | zig-3c1ccbdf3990b6d802cdc8a0db7c11eaac0960e8.tar.gz zig-3c1ccbdf3990b6d802cdc8a0db7c11eaac0960e8.zip | |
std.Target: Add support for specifying Android API level.
Diffstat (limited to 'lib/std')
| -rw-r--r-- | lib/std/Build/Cache.zig | 1 | ||||
| -rw-r--r-- | lib/std/Target.zig | 3 | ||||
| -rw-r--r-- | lib/std/Target/Query.zig | 59 | ||||
| -rw-r--r-- | lib/std/c.zig | 18 | ||||
| -rw-r--r-- | lib/std/zig/system.zig | 4 |
5 files changed, 71 insertions, 14 deletions
diff --git a/lib/std/Build/Cache.zig b/lib/std/Build/Cache.zig index 7f8a6d3159..16ecf3c0b0 100644 --- a/lib/std/Build/Cache.zig +++ b/lib/std/Build/Cache.zig @@ -221,6 +221,7 @@ pub const HashHelper = struct { hh.add(linux.range.min); hh.add(linux.range.max); hh.add(linux.glibc); + hh.add(linux.android); }, .windows => |windows| { hh.add(windows.min); diff --git a/lib/std/Target.zig b/lib/std/Target.zig index 5840f55c9e..470009592e 100644 --- a/lib/std/Target.zig +++ b/lib/std/Target.zig @@ -359,6 +359,8 @@ pub const Os = struct { pub const LinuxVersionRange = struct { range: std.SemanticVersion.Range, glibc: std.SemanticVersion, + /// Android API level. + android: u32 = 14, // This default value is to be deleted after zig1.wasm is updated. pub inline fn includesVersion(range: LinuxVersionRange, ver: std.SemanticVersion) bool { return range.range.includesVersion(ver); @@ -480,6 +482,7 @@ pub const Os = struct { break :blk default_min; }, + .android = 14, }, }, .rtems => .{ diff --git a/lib/std/Target/Query.zig b/lib/std/Target/Query.zig index 26001f1408..e50759a347 100644 --- a/lib/std/Target/Query.zig +++ b/lib/std/Target/Query.zig @@ -25,10 +25,14 @@ os_version_min: ?OsVersion = null, /// When `os_tag` is native, `null` means equal to the native OS version. os_version_max: ?OsVersion = null, -/// `null` means default when cross compiling, or native when os_tag is native. +/// `null` means default when cross compiling, or native when `os_tag` is native. /// If `isGnuLibC()` is `false`, this must be `null` and is ignored. glibc_version: ?SemanticVersion = null, +/// `null` means default when cross compiling, or native when `os_tag` is native. +/// If `isAndroid()` is `false`, this must be `null` and is ignored. +android_api_level: ?u32 = null, + /// `null` means the native C ABI, if `os_tag` is native, otherwise it means the default C ABI. abi: ?Target.Abi = null, @@ -98,10 +102,8 @@ pub fn fromTarget(target: Target) Query { .os_version_min = undefined, .os_version_max = undefined, .abi = target.abi, - .glibc_version = if (target.isGnuLibC()) - target.os.version_range.linux.glibc - else - null, + .glibc_version = if (target.isGnuLibC()) target.os.version_range.linux.glibc else null, + .android_api_level = if (target.abi.isAndroid()) target.os.version_range.linux.android else null, }; result.updateOsVersionRange(target.os); @@ -147,7 +149,7 @@ pub const ParseOptions = struct { /// The fields are, respectively: /// * CPU Architecture /// * Operating System (and optional version range) - /// * C ABI (optional, with optional glibc version) + /// * C ABI (optional, with optional glibc version or Android API level) /// The string "native" can be used for CPU architecture as well as Operating System. /// If the CPU Architecture is specified as "native", then the Operating System and C ABI may be omitted. arch_os_abi: []const u8 = "native", @@ -234,6 +236,11 @@ pub fn parse(args: ParseOptions) !Query { error.Overflow => return error.InvalidAbiVersion, error.InvalidVersion => return error.InvalidAbiVersion, }; + } else if (abi.isAndroid()) { + result.android_api_level = std.fmt.parseUnsigned(u32, abi_ver_text, 10) catch |err| switch (err) { + error.InvalidCharacter => return error.InvalidVersion, + error.Overflow => return error.Overflow, + }; } else { return error.InvalidAbiVersion; } @@ -355,7 +362,7 @@ pub fn isNativeCpu(self: Query) bool { pub fn isNativeOs(self: Query) bool { return self.os_tag == null and self.os_version_min == null and self.os_version_max == null and - self.dynamic_linker.get() == null and self.glibc_version == null; + self.dynamic_linker.get() == null and self.glibc_version == null and self.android_api_level == null; } pub fn isNativeAbi(self: Query) bool { @@ -439,6 +446,13 @@ pub fn zigTriple(self: Query, allocator: Allocator) Allocator.Error![]u8 { result.appendSliceAssumeCapacity(name); result.appendAssumeCapacity('.'); try formatVersion(v, result.writer()); + } else if (self.android_api_level) |lvl| { + const name = if (self.abi) |abi| @tagName(abi) else "android"; + try result.ensureUnusedCapacity(name.len + 2); + result.appendAssumeCapacity('-'); + result.appendSliceAssumeCapacity(name); + result.appendAssumeCapacity('.'); + try result.writer().print("{d}", .{lvl}); } else if (self.abi) |abi| { const name = @tagName(abi); try result.ensureUnusedCapacity(name.len + 1); @@ -561,6 +575,7 @@ pub fn eql(a: Query, b: Query) bool { if (!OsVersion.eqlOpt(a.os_version_min, b.os_version_min)) return false; if (!OsVersion.eqlOpt(a.os_version_max, b.os_version_max)) return false; if (!versionEqualOpt(a.glibc_version, b.glibc_version)) return false; + if (a.android_api_level != b.android_api_level) return false; if (a.abi != b.abi) return false; if (!a.dynamic_linker.eql(b.dynamic_linker)) return false; if (a.ofmt != b.ofmt) return false; @@ -592,6 +607,15 @@ test parse { try std.testing.expectEqualSlices(u8, "native-native-gnu.2.1.1", text); } + if (builtin.target.abi.isAndroid()) { + var query = try Query.parse(.{}); + query.android_api_level = 30; + + const text = try query.zigTriple(std.testing.allocator); + defer std.testing.allocator.free(text); + + try std.testing.expectEqualSlices(u8, "native-native-android.30", text); + } { const query = try Query.parse(.{ .arch_os_abi = "aarch64-linux", @@ -677,4 +701,25 @@ test parse { defer std.testing.allocator.free(text); try std.testing.expectEqualSlices(u8, "aarch64-linux.3.10...4.4.1-gnu.2.27", text); } + { + const query = try Query.parse(.{ + .arch_os_abi = "aarch64-linux.3.10...4.4.1-android.30", + }); + const target = try std.zig.system.resolveTargetQuery(query); + + try std.testing.expect(target.cpu.arch == .aarch64); + try std.testing.expect(target.os.tag == .linux); + try std.testing.expect(target.os.version_range.linux.range.min.major == 3); + try std.testing.expect(target.os.version_range.linux.range.min.minor == 10); + try std.testing.expect(target.os.version_range.linux.range.min.patch == 0); + try std.testing.expect(target.os.version_range.linux.range.max.major == 4); + try std.testing.expect(target.os.version_range.linux.range.max.minor == 4); + try std.testing.expect(target.os.version_range.linux.range.max.patch == 1); + try std.testing.expect(target.os.version_range.linux.android == 30); + try std.testing.expect(target.abi == .android); + + const text = try query.zigTriple(std.testing.allocator); + defer std.testing.allocator.free(text); + try std.testing.expectEqualSlices(u8, "aarch64-linux.3.10...4.4.1-android.30", text); + } } diff --git a/lib/std/c.zig b/lib/std/c.zig index d28f5b0ac4..3d638487cb 100644 --- a/lib/std/c.zig +++ b/lib/std/c.zig @@ -44,22 +44,26 @@ comptime { } } -/// If not linking libc, returns false. -/// If linking musl libc, returns true. -/// If linking gnu libc (glibc), returns true if the target version is greater -/// than or equal to `glibc_version`. -/// If linking a libc other than these, returns `false`. -pub inline fn versionCheck(comptime glibc_version: std.SemanticVersion) bool { +/// * If not linking libc, returns `false`. +/// * If linking musl libc, returns `true`. +/// * If linking GNU libc (glibc), returns `true` if the target version is greater than or equal to +/// `version`. +/// * If linking Android libc (bionic), returns `true` if the target API level is greater than or +/// equal to `version.major`, ignoring other components. +/// * If linking a libc other than these, returns `false`. +pub inline fn versionCheck(comptime version: std.SemanticVersion) bool { return comptime blk: { if (!builtin.link_libc) break :blk false; if (native_abi.isMusl()) break :blk true; if (builtin.target.isGnuLibC()) { const ver = builtin.os.version_range.linux.glibc; - const order = ver.order(glibc_version); + const order = ver.order(version); break :blk switch (order) { .gt, .eq => true, .lt => false, }; + } else if (builtin.abi.isAndroid()) { + break :blk builtin.os.version_range.linux.android >= version.major; } else { break :blk false; } diff --git a/lib/std/zig/system.zig b/lib/std/zig/system.zig index d1967877b3..448699a76f 100644 --- a/lib/std/zig/system.zig +++ b/lib/std/zig/system.zig @@ -331,6 +331,10 @@ pub fn resolveTargetQuery(query: Target.Query) DetectError!Target { os.version_range.linux.glibc = glibc; } + if (query.android_api_level) |android| { + os.version_range.linux.android = android; + } + // Until https://github.com/ziglang/zig/issues/4592 is implemented (support detecting the // native CPU architecture as being different than the current target), we use this: const cpu_arch = query.cpu_arch orelse builtin.cpu.arch; |
