diff options
Diffstat (limited to 'vppversion/lt.c')
-rw-r--r-- | vppversion/lt.c | 577 |
1 files changed, 0 insertions, 577 deletions
diff --git a/vppversion/lt.c b/vppversion/lt.c deleted file mode 100644 index 0de2b06114e..00000000000 --- a/vppversion/lt.c +++ /dev/null @@ -1,577 +0,0 @@ -/* - * Copyright (c) 2015 Cisco and/or its affiliates. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#include <string.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <sys/wait.h> -#include <vppinfra/bitmap.h> -#include <vppinfra/format.h> -#include <vppinfra/hash.h> - -#define foreach_libtool_mode _ (compile) _ (link) _ (install) - -typedef enum { -#define _(m) MODE_##m, - foreach_libtool_mode -#undef _ -} lt_mode_t; - -typedef enum { - LITERAL, - OUTPUT_EXE, - OUTPUT_LO, - OUTPUT_LA, - LT_LIB, - NON_LT_LIB, - IGNORE, -} lt_edit_type_t; - -typedef struct { - lt_edit_type_t type; - u8 * data; -} lt_edit_t; - -typedef struct { - u8 * path; -} lt_lib_path_t; - -typedef struct { - lt_mode_t mode; - int link_static; - int silent; - lt_edit_type_t output_edit_type; - u8 * output_file; - lt_edit_t * edits; - lt_lib_path_t * lib_path; - uword * rpath_hash; - u8 * tag; -} lt_main_t; - -static lt_lib_path_t * -search_lib_path (lt_main_t * lm, char * fmt, ...) -{ - va_list va; - static u8 * file_name, * path_name; - lt_lib_path_t * p = 0; - - if (file_name) - _vec_len (file_name) = 0; - - va_start (va, fmt); - file_name = va_format (file_name, fmt, &va); - va_end (va); - - path_name = 0; - vec_foreach (p, lm->lib_path) - { - struct stat st; - - if (path_name) - _vec_len (path_name) = 0; - - path_name = format (path_name, "%s/%v%c", p->path, file_name, 0); - if (stat ((char *) path_name, &st) >= 0) - return p; - } - return 0; -} - -static u8 * format_libtool_mode (u8 * s, va_list * args) -{ - int m = va_arg (*args, int); - char * t; - switch (m) - { -#define _(f) case MODE_##f: t = #f; break; - foreach_libtool_mode; -#undef _ - default: - t = 0; - } - if (t) - vec_add (s, t, strlen (t)); - else - s = format (s, "unknown 0x%x", m); - return s; -} - -static uword unformat_libtool_mode (unformat_input_t * input, va_list * args) -{ - int * result = va_arg (*args, int *); -#define _(m) if (unformat (input, #m)) { *result = MODE_##m; return 1; } - foreach_libtool_mode; -#undef _ - return 0; -} - -static uword unformat_basename (unformat_input_t * input, va_list * args) -{ - u8 ** result = va_arg (*args, u8 **); - u8 * suffix = va_arg (*args, u8 *); - u8 * current_suffix = suffix; - uword c; - - while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT) - { - switch (c) - { - case 0: - case ' ': - case '\t': - case '\n': - case '\r': - goto fail; - } - - vec_add1 (*result, c); - if (c == *current_suffix) - current_suffix++; - else - current_suffix = suffix; - - if (*current_suffix == 0) - { - _vec_len (*result) -= current_suffix - suffix; - return 1; - } - } - fail: - vec_free (*result); - return 0; -} - -static void edit (lt_main_t * lm, lt_edit_type_t type, char * fmt, ...) -{ - va_list va; - lt_edit_t * e; - u8 * s; - - va_start (va, fmt); - s = va_format (0, fmt, &va); - va_end (va); - - vec_add2 (lm->edits, e, 1); - e->type = type; - e->data = s; -} - -static u8 * format_argv (u8 * s, va_list * args) -{ - u8 ** a = va_arg (*args, u8 **); - uword i; - for (i = 0; i < vec_len (a) - 1; i++) - { - if (i > 0) - vec_add1 (s, ' '); - vec_add (s, a[i], vec_len (a[i]) - 1); - } - return s; -} - -static u8 * format_dirname (u8 * s, va_list * args) -{ - u8 * f = va_arg (*args, u8 *); - u8 * t; - - for (t = vec_end (f) - 1; t >= f; t--) - { - if (t[0] == '/') - break; - } - if (t[0] == '/') - vec_add (s, f, t - f); - else - vec_add1 (s, '.'); - return s; -} - -static u8 * format_basename (u8 * s, va_list * args) -{ - u8 * f = va_arg (*args, u8 *); - u8 * t; - - for (t = vec_end (f) - 1; t >= f; t--) - { - if (t[0] == '/') - break; - } - if (t[0] == '/') - vec_add (s, t + 1, vec_end (f) - (t + 1)); - else - vec_add (s, f, vec_len (f)); - return s; -} - -static void my_system (char * fmt, ...) -{ - va_list va; - u8 * s; - - va_start (va, fmt); - s = va_format (0, fmt, &va); - va_end (va); - - vec_add1 (s, 0); /* null terminate */ - if (system ((char *) s) != 0) - clib_error ("%s", s); - vec_free (s); -} - -static u8 * my_cmd (char * fmt, ...) -{ - va_list va; - u8 * s; - FILE * result; - int c; - - va_start (va, fmt); - s = va_format (0, fmt, &va); - va_end (va); - - vec_add1 (s, 0); /* null terminate */ - result = popen ((char *) s, "r"); - if (! result) - clib_error ("%s", s); - _vec_len (s) = 0; - while ((c = fgetc (result)) != EOF) - vec_add1 (s, c); - pclose (result); - return s; -} - -static void make_file_with_contents (lt_main_t * lm, u8 * contents, char * fmt, ...) -{ - va_list va; - u8 * s; - FILE * f; - - va_start (va, fmt); - s = va_format (0, fmt, &va); - va_end (va); - - vec_add1 (s, 0); /* null terminate */ - f = fopen ((char *) s, "w"); - - if (! f) - clib_error ("fopen %s", s); - - if (1 != fwrite (contents, vec_len (contents), 1, f)) - clib_error ("fwrite"); - - fclose (f); -} - -static u8 ** add_argv (u8 ** argv, char * fmt, ...) -{ - va_list va; - u8 * s; - - va_start (va, fmt); - s = va_format (0, fmt, &va); - va_end (va); - vec_add1 (s, 0); /* null terminate */ - vec_add1 (argv, s); - return argv; -} - -#define GEN_ARGV_PIC (1 << 0) -#define GEN_ARGV_PUNT (1 << 1) - -static u8 ** gen_argv (lt_main_t * lm, uword flags) -{ - u8 ** r = 0; - uword * path_used_bitmap = 0; - lt_edit_t * e; - int is_punt; - - is_punt = (flags & GEN_ARGV_PUNT) != 0; - if (is_punt) - { - /* No supported so punt back to shell based libtool. */ - r = add_argv (r, "/bin/sh"); - r = add_argv (r, "./libtool"); - r = add_argv (r, "--mode=%U", format_libtool_mode, lm->mode); - } - - if (lm->mode == MODE_compile) - ASSERT (lm->output_edit_type != OUTPUT_LA); - - vec_foreach (e, lm->edits) - { - switch (e->type) - { - case LITERAL: - r = add_argv (r, "%v", e->data); - break; - - case OUTPUT_EXE: - if (! is_punt) - my_system ("mkdir -p %U/.libs", format_dirname, e->data); - r = add_argv (r, "-o"); - r = add_argv (r, "%s%v", is_punt ? "" : ".libs/", e->data); - break; - - case OUTPUT_LO: - if (flags & GEN_ARGV_PIC) - { - r = add_argv (r, "-fPIC"); - r = add_argv (r, "-DPIC"); - } - r = add_argv (r, "-o"); - - if (is_punt) - r = add_argv (r, "-o %v.lo", e->data); - - else if (flags & GEN_ARGV_PIC) - { - my_system ("mkdir -p %U/.libs", format_dirname, e->data); - r = add_argv (r, "%U/.libs/%U.o", - format_dirname, e->data, - format_basename, e->data); - } - else - { - my_system ("mkdir -p %U", format_dirname, e->data); - r = add_argv (r, "%v.o", e->data); - } - break; - - case OUTPUT_LA: - if (is_punt) - r = add_argv (r, "-o %v.la", e->data); - else - abort (); - break; - - case LT_LIB: - if (is_punt) - r = add_argv (r, "%v.la", e->data); - - else if (lm->mode == MODE_link) - { - u8 * pwd = get_current_dir_name (); - u8 * libdir = my_cmd (". %s/%v.la && echo -n ${libdir}", pwd, e->data); - - if (! hash_get_mem (lm->rpath_hash, libdir)) - { - r = add_argv (r, "-Wl,-rpath"); - r = add_argv (r, "-Wl,%v", libdir); - hash_set_mem (lm->rpath_hash, libdir, 0); - } - - r = add_argv (r, "%U/.libs/%U.so", - format_dirname, e->data, - format_basename, e->data); - } - else - r = add_argv (r, "%v.la", e->data); - break; - - case NON_LT_LIB: - if (lm->mode == MODE_link && ! is_punt) - { - lt_lib_path_t * p = search_lib_path (lm, "lib%v.so", e->data); - if (p) - { - path_used_bitmap = clib_bitmap_ori (path_used_bitmap, p - lm->lib_path); - r = add_argv (r, "%s/lib%v.so", p->path, e->data); - } - else - r = add_argv (r, "-l%v", e->data); - } - - else - r = add_argv (r, "-l%v", e->data); - break; - - default: - ASSERT (0); - } - } - - { - uword i; - clib_bitmap_foreach (i, path_used_bitmap, ({ - lt_lib_path_t * p = vec_elt_at_index (lm->lib_path, i); - r = add_argv (r, "-Wl,-rpath"); - r = add_argv (r, "-Wl,%s", p->path); - })); - clib_bitmap_free (path_used_bitmap); - } - - vec_add1 (r, 0); - - return r; -} - -static void do_command (lt_main_t * lm, u8 ** argv) -{ - u8 * cmd = format (0, "%U%c", format_argv, argv, 0); - - if (! lm->silent) - fformat (stderr, "lt: %s\n", cmd); - - if (system ((char *) cmd)) - exit (1); - - vec_free (cmd); -} - -static int lt_main (unformat_input_t * input) -{ - lt_main_t _lm = {0}, * lm = &_lm; - clib_error_t * error = 0; - u8 * s; - - lm->rpath_hash = hash_create_vec (0, sizeof (u8), sizeof (uword)); - while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) - { - s = 0; - - if (s) - _vec_len (s) = 0; - - if (unformat (input, "-o %s", &s)) - { - u8 * dot = vec_end (s) - 4; - int is_la = 0, is_lo = 0; - - is_lo = vec_len (s) >= 4 && ! strcmp ((char *) dot, ".lo"); - is_la = vec_len (s) >= 4 && ! strcmp ((char *) dot, ".la"); - if (is_lo || is_la) - { - dot[0] = 0; - lm->output_edit_type = is_lo ? OUTPUT_LO : OUTPUT_LA; - } - else - lm->output_edit_type = OUTPUT_EXE; - edit (lm, lm->output_edit_type, "%s", s); - lm->output_file = format (0, "%s", s); - } - - else if (unformat (input, "-L%s", &s)) - { - lt_lib_path_t * p; - vec_add2 (lm->lib_path, p, 1); - p->path = s; - edit (lm, LITERAL, "-L%s", s); - } - - else if (unformat (input, "%U", unformat_basename, &s, ".la")) - edit (lm, LT_LIB, "%v", s); - - else if (unformat (input, "-l%s", &s)) - edit (lm, NON_LT_LIB, "%s", s); - - else if (unformat (input, "--mode=%U", unformat_libtool_mode, &lm->mode)) - ; - - else if (unformat (input, "--tag=%s", &lm->tag)) - ; - - else if (unformat (input, "-static")) - { - lm->link_static = 1; - edit (lm, LITERAL, "%s", "-static"); - } - - else if (unformat (input, "%s", &s)) - edit (lm, LITERAL, "%s", s); - - else - { - error = clib_error_create ("parse error `%U'", - format_unformat_error, input); - goto done; - } - } - - { - u8 ** argv; - - if (! (lm->mode == MODE_compile - || (lm->mode == MODE_link && lm->output_edit_type == OUTPUT_EXE && ! lm->link_static))) - { - argv = gen_argv (lm, GEN_ARGV_PUNT); - do_command (lm, argv); - } - else if (lm->mode == MODE_compile) - { - argv = gen_argv (lm, GEN_ARGV_PIC); - do_command (lm, argv); - argv = gen_argv (lm, 0); - do_command (lm, argv); - } - else - { - argv = gen_argv (lm, 0); - do_command (lm, argv); - } - - if (lm->mode == MODE_compile) - { - u8 * s = 0; - u8 * f = lm->output_file; - - /* Need this or .lo files are rejected. */ - s = format (s, "# Generated by libtool (Eliot lt 0.0)\n"); - - s = format (s, "pic_object='.libs/%U.o'\n", format_basename, f); - s = format (s, "non_pic_object='%U.o'\n", format_basename, f); - make_file_with_contents (lm, s, "%v.lo", f); - vec_free (s); - } - else if (lm->mode == MODE_link) - { - u8 * s = 0; - u8 * f = lm->output_file; - s = format (s, "%s", - "# Generated by libtool (Eliot lt) 2.4\n" - "# %%%MAGIC variable%%%\n" - "generated_by_libtool_version=2.4\n"); - make_file_with_contents (lm, s, "%v", f); - vec_free (s); - } - - { - int status; - while (1) - { - if (waitpid (-1, &status, 0) < 0 && errno == ECHILD) - break; - } - exit (0); - } - } - - done: - if (s) - vec_free (s); - if (error) - { - clib_error_report (error); - return 1; - } - return 0; -} - -int main (int argc, char * argv[]) -{ - unformat_input_t i; - - unformat_init_command_line (&i, argv); - exit (lt_main (&i)); - return 0; -} |