kit

kit
git clone https://git.ryansepassi.com/git/kit.git
Log | Files | Refs | README

targets.c (7552B)


      1 #include "driver.h"
      2 
      3 #include <kit/target.h>
      4 #include <stdint.h>
      5 
      6 enum TargetsFormat {
      7   TARGETS_FORMAT_HUMAN,
      8   TARGETS_FORMAT_TRIPLE,
      9   TARGETS_FORMAT_TSV_V1,
     10 };
     11 
     12 static void targets_print_capabilities(uint32_t caps, const char* separator) {
     13   struct CapabilityName {
     14     uint32_t bit;
     15     const char* name;
     16   };
     17   static const struct CapabilityName names[] = {
     18       {KIT_TARGET_CAP_COMPILE, "compile"},
     19       {KIT_TARGET_CAP_ASSEMBLE, "assemble"},
     20       {KIT_TARGET_CAP_LINK, "link"},
     21       {KIT_TARGET_CAP_SHARED, "shared"},
     22       {KIT_TARGET_CAP_EXECUTE, "execute"},
     23       {KIT_TARGET_CAP_SELFHOST, "selfhost"},
     24   };
     25   unsigned i;
     26   int first = 1;
     27   for (i = 0; i < (unsigned)(sizeof names / sizeof names[0]); ++i) {
     28     if (!(caps & names[i].bit)) continue;
     29     if (!first) driver_printf("%s", separator);
     30     driver_printf("%s", names[i].name);
     31     first = 0;
     32   }
     33   if (first) driver_printf("none");
     34 }
     35 
     36 void driver_help_targets(void) {
     37   driver_printf(
     38       "kit targets — inspect the compiled target-profile registry\n"
     39       "\n"
     40       "USAGE\n"
     41       "  kit targets [--format=human|triple|tsv|tsv-v1] [SELECTOR|TRIPLE]\n"
     42       "\n"
     43       "DESCRIPTION\n"
     44       "  With no target argument, list every profile compiled into libkit.\n"
     45       "  A detail argument accepts either the stable orchestration selector or\n"
     46       "  its canonical -target triple. Capability and provisioning are separate:\n"
     47       "  provisioning describes the required local sysroot/SDK/VM/QEMU lane,\n"
     48       "  not a claim that it is installed on this machine.\n"
     49       "\n"
     50       "FORMATS\n"
     51       "  human    Readable table or key/value detail (default)\n"
     52       "  triple   Canonical triples, one per line\n"
     53       "  tsv      Versioned kit-targets-v1 TSV records\n"
     54       "  tsv-v1   Explicit spelling for the same stable TSV schema\n"
     55       "\n"
     56       "EXAMPLES\n"
     57       "  kit targets\n"
     58       "  kit targets --format=triple\n"
     59       "  kit targets --format=tsv linux-musl-aa64\n"
     60       "  kit targets aarch64-linux-android21\n"
     61       "\n"
     62       "EXIT CODES\n"
     63       "  0  Registry/list/detail emitted\n"
     64       "  1  No profile matches the requested selector or triple\n"
     65       "  2  Invalid command-line usage\n");
     66 }
     67 
     68 static int targets_parse_format(const char* value, enum TargetsFormat* out) {
     69   if (driver_streq(value, "human")) {
     70     *out = TARGETS_FORMAT_HUMAN;
     71   } else if (driver_streq(value, "triple")) {
     72     *out = TARGETS_FORMAT_TRIPLE;
     73   } else if (driver_streq(value, "tsv") || driver_streq(value, "tsv-v1")) {
     74     *out = TARGETS_FORMAT_TSV_V1;
     75   } else {
     76     return 1;
     77   }
     78   return 0;
     79 }
     80 
     81 static void targets_unknown_format(const char* value) {
     82   const char* const formats[] = {"human", "triple", "tsv", "tsv-v1"};
     83   DriverSuggestion suggestions[3];
     84   size_t n = driver_suggest_values(value, formats,
     85                                    sizeof formats / sizeof formats[0],
     86                                    suggestions, 3);
     87   if (n)
     88     driver_errf("targets", "unknown format: %s; did you mean '%s'?", value,
     89                 suggestions[0].value);
     90   else
     91     driver_errf("targets", "unknown format: %s", value);
     92 }
     93 
     94 static void targets_print_tsv_header(void) {
     95   driver_printf("# kit-targets-v1\n");
     96   driver_printf("selector\ttriple\tarch\tos\tobject\thosted\tlibc\t"
     97                 "sysroot\tcapabilities\tprovisioning\n");
     98 }
     99 
    100 static void targets_print_tsv(const KitTargetProfile* p) {
    101   driver_printf("%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t", p->selector,
    102                 p->triple, kit_target_arch_name(p->spec.arch),
    103                 kit_target_os_name(p->spec.os),
    104                 kit_target_obj_name(p->spec.obj),
    105                 p->hosted ? "hosted" : "freestanding",
    106                 kit_target_libc_name(p->libc),
    107                 kit_target_sysroot_name(p->sysroot));
    108   targets_print_capabilities(p->capabilities, ",");
    109   driver_printf("\t%s\n",
    110                 kit_target_provisioning_name(p->provisioning));
    111 }
    112 
    113 static void targets_print_human_row(const KitTargetProfile* p) {
    114   driver_printf("%-22s %-29s %-8s %-13s %-6s %-15s ", p->selector,
    115                 p->triple, kit_target_arch_name(p->spec.arch),
    116                 kit_target_os_name(p->spec.os),
    117                 kit_target_obj_name(p->spec.obj),
    118                 kit_target_libc_name(p->libc));
    119   targets_print_capabilities(p->capabilities, ",");
    120   driver_printf("  [%s]\n",
    121                 kit_target_provisioning_name(p->provisioning));
    122 }
    123 
    124 static void targets_print_detail(const KitTargetProfile* p) {
    125   driver_printf("selector:      %s\n", p->selector);
    126   driver_printf("triple:        %s\n", p->triple);
    127   driver_printf("architecture:  %s\n", kit_target_arch_name(p->spec.arch));
    128   driver_printf("os:            %s\n", kit_target_os_name(p->spec.os));
    129   driver_printf("object-format: %s\n", kit_target_obj_name(p->spec.obj));
    130   driver_printf("pointer:       %u-bit %s-endian\n",
    131                 (unsigned)p->spec.ptr_size * 8u,
    132                 p->spec.big_endian ? "big" : "little");
    133   driver_printf("hosted-model:  %s\n",
    134                 p->hosted ? "hosted" : "freestanding");
    135   driver_printf("libc-model:    %s\n", kit_target_libc_name(p->libc));
    136   driver_printf("sysroot-model: %s\n", kit_target_sysroot_name(p->sysroot));
    137   driver_printf("capabilities:  ");
    138   targets_print_capabilities(p->capabilities, ", ");
    139   driver_printf("\nprovisioning:  %s (requirement, local state not inferred)\n",
    140                 kit_target_provisioning_name(p->provisioning));
    141 }
    142 
    143 int driver_targets(int argc, char** argv) {
    144   enum TargetsFormat format = TARGETS_FORMAT_HUMAN;
    145   const char* detail = NULL;
    146   const KitTargetProfile* profiles;
    147   size_t count = 0;
    148   size_t i;
    149 
    150   if (driver_argv_wants_help(argc, argv, 1)) {
    151     driver_help_targets();
    152     return 0;
    153   }
    154   for (i = 1; i < (size_t)argc; ++i) {
    155     const char* arg = argv[i];
    156     if (driver_strneq(arg, "--format=", 9)) {
    157       if (targets_parse_format(arg + 9, &format) != 0) {
    158         targets_unknown_format(arg + 9);
    159         return 2;
    160       }
    161     } else if (driver_streq(arg, "--format")) {
    162       if (++i >= (size_t)argc) {
    163         driver_errf("targets", "--format requires an argument");
    164         return 2;
    165       }
    166       if (targets_parse_format(argv[i], &format) != 0) {
    167         targets_unknown_format(argv[i]);
    168         return 2;
    169       }
    170     } else if (arg[0] == '-') {
    171       driver_errf("targets", "unknown option: %s", arg);
    172       return 2;
    173     } else if (detail) {
    174       driver_errf("targets", "expected at most one selector or triple");
    175       return 2;
    176     } else {
    177       detail = arg;
    178     }
    179   }
    180 
    181   profiles = kit_target_profiles(&count);
    182   if (detail) {
    183     const KitTargetProfile* p = kit_target_profile_lookup(detail);
    184     if (!p) {
    185       driver_err_unknown_target("targets", detail);
    186       return 1;
    187     }
    188     if (format == TARGETS_FORMAT_TRIPLE) {
    189       driver_printf("%s\n", p->triple);
    190     } else if (format == TARGETS_FORMAT_TSV_V1) {
    191       targets_print_tsv_header();
    192       targets_print_tsv(p);
    193     } else {
    194       targets_print_detail(p);
    195     }
    196     return 0;
    197   }
    198 
    199   if (format == TARGETS_FORMAT_TSV_V1) {
    200     targets_print_tsv_header();
    201     for (i = 0; i < count; ++i) targets_print_tsv(&profiles[i]);
    202   } else if (format == TARGETS_FORMAT_TRIPLE) {
    203     for (i = 0; i < count; ++i) driver_printf("%s\n", profiles[i].triple);
    204   } else {
    205     driver_printf("SELECTOR               TRIPLE                        ARCH     "
    206                   "OS            OBJECT LIBC            CAPABILITIES "
    207                   "[PROVISION]\n");
    208     for (i = 0; i < count; ++i) targets_print_human_row(&profiles[i]);
    209   }
    210   return 0;
    211 }