Example
test parse {
if (builtin.target.isGnuLibC()) {
var query = try Query.parse(.{});
query.setGnuLibCVersion(2, 1, 1);
const text = try query.zigTriple(std.testing.allocator);
defer std.testing.allocator.free(text);
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",
.cpu_features = "native",
});
try std.testing.expect(query.cpu_arch.? == .aarch64);
try std.testing.expect(query.cpu_model == .native);
}
{
const query = try Query.parse(.{ .arch_os_abi = "native" });
try std.testing.expect(query.cpu_arch == null);
try std.testing.expect(query.isNative());
const text = try query.zigTriple(std.testing.allocator);
defer std.testing.allocator.free(text);
try std.testing.expectEqualSlices(u8, "native", text);
}
{
const query = try Query.parse(.{
.arch_os_abi = "x86_64-linux-gnu",
.cpu_features = "x86_64-sse-sse2-avx-cx8",
});
const target = try std.zig.system.resolveTargetQuery(query);
try std.testing.expect(target.os.tag == .linux);
try std.testing.expect(target.abi == .gnu);
try std.testing.expect(target.cpu.arch == .x86_64);
try std.testing.expect(!Target.x86.featureSetHas(target.cpu.features, .sse));
try std.testing.expect(!Target.x86.featureSetHas(target.cpu.features, .avx));
try std.testing.expect(!Target.x86.featureSetHas(target.cpu.features, .cx8));
try std.testing.expect(Target.x86.featureSetHas(target.cpu.features, .cmov));
try std.testing.expect(Target.x86.featureSetHas(target.cpu.features, .fxsr));
try std.testing.expect(Target.x86.featureSetHasAny(target.cpu.features, .{ .sse, .avx, .cmov }));
try std.testing.expect(!Target.x86.featureSetHasAny(target.cpu.features, .{ .sse, .avx }));
try std.testing.expect(Target.x86.featureSetHasAll(target.cpu.features, .{ .mmx, .x87 }));
try std.testing.expect(!Target.x86.featureSetHasAll(target.cpu.features, .{ .mmx, .x87, .sse }));
const text = try query.zigTriple(std.testing.allocator);
defer std.testing.allocator.free(text);
try std.testing.expectEqualSlices(u8, "x86_64-linux-gnu", text);
}
{
const query = try Query.parse(.{
.arch_os_abi = "arm-linux-musleabihf",
.cpu_features = "generic+v8a",
});
const target = try std.zig.system.resolveTargetQuery(query);
try std.testing.expect(target.os.tag == .linux);
try std.testing.expect(target.abi == .musleabihf);
try std.testing.expect(target.cpu.arch == .arm);
try std.testing.expect(target.cpu.model == &Target.arm.cpu.generic);
try std.testing.expect(Target.arm.featureSetHas(target.cpu.features, .v8a));
const text = try query.zigTriple(std.testing.allocator);
defer std.testing.allocator.free(text);
try std.testing.expectEqualSlices(u8, "arm-linux-musleabihf", text);
}
{
const query = try Query.parse(.{
.arch_os_abi = "aarch64-linux.3.10...4.4.1-gnu.2.27",
.cpu_features = "generic+v8a",
});
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.glibc.major == 2);
try std.testing.expect(target.os.version_range.linux.glibc.minor == 27);
try std.testing.expect(target.os.version_range.linux.glibc.patch == 0);
try std.testing.expect(target.abi == .gnu);
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-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);
}
}
Source
pub fn parse(args: ParseOptions) !Query {
var dummy_diags: ParseOptions.Diagnostics = undefined;
const diags = args.diagnostics orelse &dummy_diags;
var result: Query = .{
.dynamic_linker = Target.DynamicLinker.init(args.dynamic_linker),
};
var it = mem.splitScalar(u8, args.arch_os_abi, '-');
const arch_name = it.first();
const arch_is_native = mem.eql(u8, arch_name, "native");
if (!arch_is_native) {
result.cpu_arch = std.meta.stringToEnum(Target.Cpu.Arch, arch_name) orelse {
diags.unknown_architecture_name = arch_name;
return error.UnknownArchitecture;
};
}
const arch = result.cpu_arch orelse builtin.cpu.arch;
diags.arch = arch;
if (it.next()) |os_text| {
try parseOs(&result, diags, os_text);
} else if (!arch_is_native) {
return error.MissingOperatingSystem;
}
const opt_abi_text = it.next();
if (opt_abi_text) |abi_text| {
var abi_it = mem.splitScalar(u8, abi_text, '.');
const abi = std.meta.stringToEnum(Target.Abi, abi_it.first()) orelse
return error.UnknownApplicationBinaryInterface;
result.abi = abi;
diags.abi = abi;
const abi_ver_text = abi_it.rest();
if (abi_it.next() != null) {
if (abi.isGnu()) {
result.glibc_version = parseVersion(abi_ver_text) catch |err| switch (err) {
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;
}
}
}
if (it.next() != null) return error.UnexpectedExtraField;
if (args.cpu_features) |cpu_features| {
const all_features = arch.allFeaturesList();
var index: usize = 0;
while (index < cpu_features.len and
cpu_features[index] != '+' and
cpu_features[index] != '-')
{
index += 1;
}
const cpu_name = cpu_features[0..index];
diags.cpu_name = cpu_name;
const add_set = &result.cpu_features_add;
const sub_set = &result.cpu_features_sub;
if (mem.eql(u8, cpu_name, "native")) {
result.cpu_model = .native;
} else if (mem.eql(u8, cpu_name, "baseline")) {
result.cpu_model = .baseline;
} else {
result.cpu_model = .{ .explicit = try arch.parseCpuModel(cpu_name) };
}
while (index < cpu_features.len) {
const op = cpu_features[index];
const set = switch (op) {
'+' => add_set,
'-' => sub_set,
else => unreachable,
};
index += 1;
const start = index;
while (index < cpu_features.len and
cpu_features[index] != '+' and
cpu_features[index] != '-')
{
index += 1;
}
const feature_name = cpu_features[start..index];
for (all_features, 0..) |feature, feat_index_usize| {
const feat_index = @as(Target.Cpu.Feature.Set.Index, @intCast(feat_index_usize));
if (mem.eql(u8, feature_name, feature.name)) {
set.addFeature(feat_index);
break;
}
} else {
diags.unknown_feature_name = feature_name;
return error.UnknownCpuFeature;
}
}
}
if (args.object_format) |ofmt_name| {
result.ofmt = std.meta.stringToEnum(Target.ObjectFormat, ofmt_name) orelse
return error.UnknownObjectFormat;
}
return result;
}