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 }