master
  1const std = @import("std");
  2const fs = std.fs;
  3const mem = std.mem;
  4const meta = std.meta;
  5const fatal = std.process.fatal;
  6const Allocator = std.mem.Allocator;
  7const Target = std.Target;
  8const target = @import("target.zig");
  9const assert = std.debug.assert;
 10const glibc = @import("libs/glibc.zig");
 11const introspect = @import("introspect.zig");
 12
 13pub fn cmdTargets(
 14    allocator: Allocator,
 15    args: []const []const u8,
 16    out: *std.Io.Writer,
 17    native_target: *const Target,
 18) !void {
 19    _ = args;
 20    var zig_lib_directory = introspect.findZigLibDir(allocator) catch |err| {
 21        fatal("unable to find zig installation directory: {s}\n", .{@errorName(err)});
 22    };
 23    defer zig_lib_directory.handle.close();
 24    defer allocator.free(zig_lib_directory.path.?);
 25
 26    const abilists_contents = zig_lib_directory.handle.readFileAlloc(
 27        glibc.abilists_path,
 28        allocator,
 29        .limited(glibc.abilists_max_size),
 30    ) catch |err| switch (err) {
 31        error.OutOfMemory => return error.OutOfMemory,
 32        else => fatal("unable to read " ++ glibc.abilists_path ++ ": {s}", .{@errorName(err)}),
 33    };
 34    defer allocator.free(abilists_contents);
 35
 36    const glibc_abi = try glibc.loadMetaData(allocator, abilists_contents);
 37    defer glibc_abi.destroy(allocator);
 38
 39    var serializer: std.zon.Serializer = .{ .writer = out };
 40
 41    {
 42        var root_obj = try serializer.beginStruct(.{});
 43
 44        try root_obj.field("arch", meta.fieldNames(Target.Cpu.Arch), .{});
 45        try root_obj.field("os", meta.fieldNames(Target.Os.Tag), .{});
 46        try root_obj.field("abi", meta.fieldNames(Target.Abi), .{});
 47
 48        {
 49            var libc_obj = try root_obj.beginTupleField("libc", .{});
 50            for (std.zig.target.available_libcs) |libc| {
 51                const tmp = try std.fmt.allocPrint(allocator, "{s}-{s}-{s}", .{
 52                    @tagName(libc.arch), @tagName(libc.os), @tagName(libc.abi),
 53                });
 54                defer allocator.free(tmp);
 55                try libc_obj.field(tmp, .{});
 56            }
 57            try libc_obj.end();
 58        }
 59
 60        {
 61            var glibc_obj = try root_obj.beginTupleField("glibc", .{});
 62            for (glibc_abi.all_versions) |ver| {
 63                const tmp = try std.fmt.allocPrint(allocator, "{f}", .{ver});
 64                defer allocator.free(tmp);
 65                try glibc_obj.field(tmp, .{});
 66            }
 67            try glibc_obj.end();
 68        }
 69
 70        {
 71            var cpus_obj = try root_obj.beginStructField("cpus", .{});
 72            for (meta.tags(Target.Cpu.Arch)) |arch| {
 73                var arch_obj = try cpus_obj.beginStructField(@tagName(arch), .{});
 74                for (arch.allCpuModels()) |model| {
 75                    var features = try arch_obj.beginTupleField(model.name, .{});
 76                    for (arch.allFeaturesList(), 0..) |feature, i_usize| {
 77                        const index = @as(Target.Cpu.Feature.Set.Index, @intCast(i_usize));
 78                        if (model.features.isEnabled(index)) {
 79                            try features.field(feature.name, .{});
 80                        }
 81                    }
 82                    try features.end();
 83                }
 84                try arch_obj.end();
 85            }
 86            try cpus_obj.end();
 87        }
 88
 89        {
 90            var cpu_features_obj = try root_obj.beginStructField("cpu_features", .{});
 91            for (meta.tags(Target.Cpu.Arch)) |arch| {
 92                var arch_features = try cpu_features_obj.beginTupleField(@tagName(arch), .{});
 93                for (arch.allFeaturesList()) |feature| {
 94                    try arch_features.field(feature.name, .{});
 95                }
 96                try arch_features.end();
 97            }
 98            try cpu_features_obj.end();
 99        }
100
101        {
102            var native_obj = try root_obj.beginStructField("native", .{});
103            {
104                const triple = try native_target.zigTriple(allocator);
105                defer allocator.free(triple);
106                try native_obj.field("triple", triple, .{});
107            }
108            {
109                var cpu_obj = try native_obj.beginStructField("cpu", .{});
110                try cpu_obj.field("arch", @tagName(native_target.cpu.arch), .{});
111
112                try cpu_obj.field("name", native_target.cpu.model.name, .{});
113
114                {
115                    var features = try native_obj.beginTupleField("features", .{});
116                    for (native_target.cpu.arch.allFeaturesList(), 0..) |feature, i_usize| {
117                        const index = @as(Target.Cpu.Feature.Set.Index, @intCast(i_usize));
118                        if (native_target.cpu.features.isEnabled(index)) {
119                            try features.field(feature.name, .{});
120                        }
121                    }
122                    try features.end();
123                }
124                try cpu_obj.end();
125            }
126
127            try native_obj.field("os", @tagName(native_target.os.tag), .{});
128            try native_obj.field("abi", @tagName(native_target.abi), .{});
129            try native_obj.end();
130        }
131
132        try root_obj.end();
133    }
134
135    try out.writeByte('\n');
136}