kit

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

ranlib.c (3479B)


      1 #include <kit/archive.h>
      2 #include <kit/core.h>
      3 #include <kit/object.h>
      4 
      5 #include "driver.h"
      6 
      7 /* `kit ranlib` — refresh / add a System-V `/` symbol-index member at the
      8  * head of an existing POSIX `ar` archive. Equivalent to `kit ar s ARCHIVE`,
      9  * which is reserved by the POSIX ar grammar but not yet implemented in the
     10  * ar tool. ranlib is the conventional name and the one Makefiles invoke.
     11  *
     12  * Operation: read all members, rebuild the archive at the same path with
     13  * symbol_index=1 and per-member globally-defined symbols filled in. Long
     14  * member names are preserved via the `//` extended-name table. Reproducible
     15  * output via SOURCE_DATE_EPOCH (same epoch handling as `kit ar`).
     16  *
     17  * The read-members / recompute-index / rewrite pipeline is kit_ar_reindex in
     18  * libkit (shared with ar / strip via the same symbol-index automation). */
     19 
     20 #define RANLIB_TOOL "ranlib"
     21 
     22 void driver_help_ranlib(void) {
     23   driver_printf(
     24       "%.*s",
     25       KIT_SLICE_ARG(KIT_SLICE_LIT(
     26           "kit ranlib — refresh the symbol index of an `ar` archive\n"
     27           "\n"
     28           "USAGE\n"
     29           "  kit ranlib ARCHIVE.a\n"
     30           "\n"
     31           "DESCRIPTION\n"
     32           "  Reads every member of ARCHIVE.a, rebuilds the archive in place\n"
     33           "  with a System-V `/` symbol-index member at the head. Member "
     34           "names,\n"
     35           "  contents, and order are preserved. Reproducible: when\n"
     36           "  SOURCE_DATE_EPOCH is set to a positive integer, that value is\n"
     37           "  written to ar_date for every member.\n"
     38           "OPTIONS\n"
     39           "  -h, --help        Show this help and exit\n"
     40           "\n"
     41           "EXAMPLES\n"
     42           "  kit ar rc libfoo.a a.o b.o\n"
     43           "  kit ranlib libfoo.a\n"
     44           "  kit nm -g libfoo.a\n"
     45           "\n"
     46           "EXIT CODES\n"
     47           "  0   success           1   archive I/O error           2   bad "
     48           "usage\n")));
     49 }
     50 
     51 int driver_ranlib(int argc, char** argv) {
     52   DriverEnv env;
     53   KitContext ctx;
     54   KitFileData old_fd = {0};
     55   KitSlice input;
     56   KitWriter* out = NULL;
     57   const char* archive_path;
     58   int have_old = 0;
     59   int rc = 1;
     60 
     61   if (argc < 2 || driver_argv_wants_help(argc, argv, 1)) {
     62     driver_help_ranlib();
     63     return 0;
     64   }
     65   if (argc != 2) {
     66     driver_errf(RANLIB_TOOL, "usage: kit ranlib ARCHIVE.a");
     67     return 2;
     68   }
     69   archive_path = argv[1];
     70 
     71   driver_env_init(&env);
     72   ctx = driver_env_to_context(&env);
     73 
     74   if (ctx.file_io->read_all(ctx.file_io->user, archive_path, &old_fd) !=
     75       KIT_OK) {
     76     driver_errf(RANLIB_TOOL, "failed to read: %.*s",
     77                 KIT_SLICE_ARG(kit_slice_cstr(archive_path)));
     78     goto out;
     79   }
     80   have_old = 1;
     81   input.data = old_fd.data;
     82   input.len = old_fd.size;
     83 
     84   /* Read every member and rewrite the archive with a freshly-computed symbol
     85    * index — the whole of ranlib is now kit_ar_reindex. */
     86   if (ctx.file_io->open_writer(ctx.file_io->user, archive_path, &out) !=
     87       KIT_OK) {
     88     driver_errf(RANLIB_TOOL, "failed to open: %.*s",
     89                 KIT_SLICE_ARG(kit_slice_cstr(archive_path)));
     90     goto out;
     91   }
     92   if (kit_ar_reindex(&ctx, &input, driver_epoch_from_env(), out) != KIT_OK) {
     93     driver_errf(RANLIB_TOOL, "not an archive: %.*s",
     94                 KIT_SLICE_ARG(kit_slice_cstr(archive_path)));
     95     goto out;
     96   }
     97   rc = kit_writer_status(out) == KIT_OK ? 0 : 1;
     98 
     99 out:
    100   if (out) kit_writer_close(out);
    101   if (have_old) ctx.file_io->release(ctx.file_io->user, &old_fd);
    102   driver_env_fini(&env);
    103   return rc;
    104 }