diff options
| author | grischka <grischka> | 2017-02-18 09:55:34 +0100 |
|---|---|---|
| committer | grischka <grischka> | 2017-02-18 09:55:34 +0100 |
| commit | 2d3b9559bf569f137cefb7f8386a0dc58e33c81f (patch) | |
| tree | 4da5267d5dd1bf907bdf82d7065c751a05757e6e /libtcc.c | |
| parent | f34b1feaca557cd9da198610b67d4328fb0c7a84 (diff) | |
| download | tinycc-2d3b9559bf569f137cefb7f8386a0dc58e33c81f.tar.gz tinycc-2d3b9559bf569f137cefb7f8386a0dc58e33c81f.tar.bz2 | |
tcctools.c: integrate tiny_libmaker/_impdef
usage:
tcc -ar [rcsv] lib files...
tcc -impdef lib.dll [-v] [-o lib.def]
also:
- support more files with -c: tcc -c f1.c f2.c ...
- fix a bug which caused tcc f1.c f2.S to produce no asm
- allow tcc -ar @listfile too
- change prototype: _void_ tcc_set_options(...)
- apply -Wl,-whole-archive when a librariy is given
as libxxx.a also (not just for -lxxx)
Diffstat (limited to 'libtcc.c')
| -rw-r--r-- | libtcc.c | 210 |
1 files changed, 128 insertions, 82 deletions
@@ -239,7 +239,7 @@ PUB_FUNC char *tcc_strdup(const char *str) return ptr; } -PUB_FUNC void tcc_memstats(int bench) +PUB_FUNC void tcc_memcheck(void) { } @@ -379,7 +379,7 @@ PUB_FUNC char *tcc_strdup_debug(const char *str, const char *file, int line) return ptr; } -PUB_FUNC void tcc_memstats(int bench) +PUB_FUNC void tcc_memcheck(void) { if (mem_cur_size) { mem_debug_header_t *header = mem_debug_chain; @@ -393,8 +393,7 @@ PUB_FUNC void tcc_memstats(int bench) #if MEM_DEBUG-0 == 2 exit(2); #endif - } else if (bench) - fprintf(stderr, "mem_max_size= %d bytes\n", mem_max_size); + } } #endif /* MEM_DEBUG */ @@ -435,7 +434,7 @@ ST_FUNC void dynarray_reset(void *pp, int *n) *(void**)pp = NULL; } -static void tcc_split_path(TCCState *s, void ***p_ary, int *p_nb_ary, const char *in) +static void tcc_split_path(TCCState *s, void *p_ary, int *p_nb_ary, const char *in) { const char *p; do { @@ -878,18 +877,14 @@ LIBTCCAPI TCCState *tcc_new(void) tcc_define_symbol(s, "__REDIRECT_NTH(name, proto, alias)", "name proto __asm__ (#alias) __THROW"); # endif -#endif /* ndef TCC_TARGET_PE */ - /* Some GCC builtins that are simple to express as macros. */ tcc_define_symbol(s, "__builtin_extract_return_addr(x)", "x"); - +#endif /* ndef TCC_TARGET_PE */ return s; } LIBTCCAPI void tcc_delete(TCCState *s1) { - int bench = s1->do_bench; - tcc_cleanup(); /* free sections */ @@ -915,6 +910,7 @@ LIBTCCAPI void tcc_delete(TCCState *s1) dynarray_reset(&s1->files, &s1->nb_files); dynarray_reset(&s1->target_deps, &s1->nb_target_deps); dynarray_reset(&s1->pragma_libs, &s1->nb_pragma_libs); + dynarray_reset(&s1->argv, &s1->argc); #ifdef TCC_IS_NATIVE /* free runtime memory */ @@ -923,7 +919,7 @@ LIBTCCAPI void tcc_delete(TCCState *s1) tcc_free(s1); if (0 == --nb_states) - tcc_memstats(bench); + tcc_memcheck(); } LIBTCCAPI int tcc_set_output_type(TCCState *s, int output_type) @@ -965,7 +961,7 @@ LIBTCCAPI int tcc_set_output_type(TCCState *s, int output_type) # endif #else /* paths for crt objects */ - tcc_split_path(s, (void ***)&s->crt_paths, &s->nb_crt_paths, CONFIG_TCC_CRTPREFIX); + tcc_split_path(s, &s->crt_paths, &s->nb_crt_paths, CONFIG_TCC_CRTPREFIX); /* add libc crt1/crti objects */ if ((output_type == TCC_OUTPUT_EXE || output_type == TCC_OUTPUT_DLL) && !s->nostdlib) { @@ -979,13 +975,13 @@ LIBTCCAPI int tcc_set_output_type(TCCState *s, int output_type) LIBTCCAPI int tcc_add_include_path(TCCState *s, const char *pathname) { - tcc_split_path(s, (void ***)&s->include_paths, &s->nb_include_paths, pathname); + tcc_split_path(s, &s->include_paths, &s->nb_include_paths, pathname); return 0; } LIBTCCAPI int tcc_add_sysinclude_path(TCCState *s, const char *pathname) { - tcc_split_path(s, (void ***)&s->sysinclude_paths, &s->nb_sysinclude_paths, pathname); + tcc_split_path(s, &s->sysinclude_paths, &s->nb_sysinclude_paths, pathname); return 0; } @@ -1106,7 +1102,7 @@ LIBTCCAPI int tcc_add_file(TCCState *s, const char *filename) LIBTCCAPI int tcc_add_library_path(TCCState *s, const char *pathname) { - tcc_split_path(s, (void ***)&s->library_paths, &s->nb_library_paths, pathname); + tcc_split_path(s, &s->library_paths, &s->nb_library_paths, pathname); return 0; } @@ -1440,6 +1436,7 @@ typedef struct TCCOption { enum { TCC_OPTION_HELP, + TCC_OPTION_v, TCC_OPTION_I, TCC_OPTION_D, TCC_OPTION_U, @@ -1480,13 +1477,14 @@ enum { TCC_OPTION_pedantic, TCC_OPTION_pthread, TCC_OPTION_run, - TCC_OPTION_v, TCC_OPTION_w, TCC_OPTION_pipe, TCC_OPTION_E, TCC_OPTION_MD, TCC_OPTION_MF, - TCC_OPTION_x + TCC_OPTION_x, + TCC_OPTION_ar, + TCC_OPTION_impdef }; #define TCC_OPTION_HAS_ARG 0x0001 @@ -1496,6 +1494,7 @@ static const TCCOption tcc_options[] = { { "h", TCC_OPTION_HELP, 0 }, { "-help", TCC_OPTION_HELP, 0 }, { "?", TCC_OPTION_HELP, 0 }, + { "v", TCC_OPTION_v, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP }, { "I", TCC_OPTION_I, TCC_OPTION_HAS_ARG }, { "D", TCC_OPTION_D, TCC_OPTION_HAS_ARG }, { "U", TCC_OPTION_U, TCC_OPTION_HAS_ARG }, @@ -1542,13 +1541,16 @@ static const TCCOption tcc_options[] = { { "nostdinc", TCC_OPTION_nostdinc, 0 }, { "nostdlib", TCC_OPTION_nostdlib, 0 }, { "print-search-dirs", TCC_OPTION_print_search_dirs, 0 }, - { "v", TCC_OPTION_v, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP }, { "w", TCC_OPTION_w, 0 }, { "pipe", TCC_OPTION_pipe, 0}, { "E", TCC_OPTION_E, 0}, { "MD", TCC_OPTION_MD, 0}, { "MF", TCC_OPTION_MF, TCC_OPTION_HAS_ARG }, { "x", TCC_OPTION_x, TCC_OPTION_HAS_ARG }, + { "ar", TCC_OPTION_ar, 0}, +#ifdef TCC_TARGET_PE + { "impdef", TCC_OPTION_impdef, 0}, +#endif { NULL, 0, 0 }, }; @@ -1595,58 +1597,106 @@ static void args_parser_add_file(TCCState *s, const char* filename, int filetype { struct filespec *f = tcc_malloc(sizeof *f + strlen(filename)); f->type = filetype; + f->alacarte = s->alacarte_link; strcpy(f->name, filename); dynarray_add(&s->files, &s->nb_files, f); } +static int args_parser_make_argv(const char *r, int *argc, char ***argv) +{ + int ret = 0, q, c; + CString str; + for(;;) { + while (c = (unsigned char)*r, c && c <= ' ') + ++r; + if (c == 0) + break; + q = 0; + cstr_new(&str); + while (c = (unsigned char)*r, c) { + ++r; + if (c == '\\' && (*r == '"' || *r == '\\')) { + c = *r++; + } else if (c == '"') { + q = !q; + continue; + } else if (q == 0 && c <= ' ') { + break; + } + cstr_ccat(&str, c); + } + cstr_ccat(&str, 0); + //printf("<%s>\n", str.data), fflush(stdout); + dynarray_add(argv, argc, tcc_strdup(str.data)); + cstr_free(&str); + ++ret; + } + return ret; +} + /* read list file */ -static void args_parser_listfile(TCCState *s, const char *filename) +static void args_parser_listfile(TCCState *s, + const char *filename, int optind, int *pargc, char ***pargv) { - int fd; + int fd, i; size_t len; char *p; + int argc = 0; + char **argv = NULL; fd = open(filename, O_RDONLY | O_BINARY); if (fd < 0) - tcc_error("file '%s' not found", filename); + tcc_error("listfile '%s' not found", filename); len = lseek(fd, 0, SEEK_END); p = tcc_malloc(len + 1), p[len] = 0; lseek(fd, 0, SEEK_SET), read(fd, p, len), close(fd); - tcc_set_options(s, p); + + for (i = 0; i < *pargc; ++i) + if (i == optind) + args_parser_make_argv(p, &argc, &argv); + else + dynarray_add(&argv, &argc, tcc_strdup((*pargv)[i])); + tcc_free(p); + dynarray_reset(&s->argv, &s->argc); + *pargc = s->argc = argc, *pargv = s->argv = argv; } -PUB_FUNC int tcc_parse_args(TCCState *s, int argc, char **argv) +PUB_FUNC int tcc_parse_args(TCCState *s, int *pargc, char ***pargv, int optind) { const TCCOption *popt; const char *optarg, *r; const char *run = NULL; - int optind = 0; - int x; int last_o = -1; + int x; CString linker_arg; /* collect -Wl options */ char buf[1024]; + int tool = 0, arg_start = 0, noaction = optind; + char **argv = *pargv; + int argc = *pargc; cstr_new(&linker_arg); while (optind < argc) { - - r = argv[optind++]; - -reparse: + r = argv[optind]; if (r[0] == '@' && r[1] != '\0') { - args_parser_listfile(s, r + 1); + args_parser_listfile(s, r + 1, optind, &argc, &argv); continue; } - + optind++; + if (tool) { + if (r[0] == '-' && r[1] == 'v' && r[2] == 0) + ++s->verbose; + continue; + } +reparse: if (r[0] != '-' || r[1] == '\0') { if (r[0] != '@') /* allow "tcc file(s) -run @ args ..." */ args_parser_add_file(s, r, s->filetype); if (run) { tcc_set_options(s, run); - optind--; - /* argv[0] will be this file */ + arg_start = optind - 1; break; } continue; @@ -1675,7 +1725,7 @@ reparse: switch(popt->index) { case TCC_OPTION_HELP: - return 0; + return OPT_HELP; case TCC_OPTION_I: tcc_add_include_path(s, optarg); break; @@ -1693,7 +1743,7 @@ reparse: tcc_set_lib_path(s, optarg); break; case TCC_OPTION_l: - args_parser_add_file(s, optarg, AFF_TYPE_LIBWH - s->alacarte_link); + args_parser_add_file(s, optarg, AFF_TYPE_LIB); s->nb_libraries++; break; case TCC_OPTION_pthread: @@ -1774,9 +1824,6 @@ reparse: case TCC_OPTION_nostdlib: s->nostdlib = 1; break; - case TCC_OPTION_print_search_dirs: - s->print_search_dirs = 1; - break; case TCC_OPTION_run: #ifndef TCC_IS_NATIVE tcc_error("-run is not available in a cross compiler"); @@ -1786,6 +1833,7 @@ reparse: goto set_output_type; case TCC_OPTION_v: do ++s->verbose; while (*optarg++ == 'v'); + ++noaction; break; case TCC_OPTION_f: if (set_flag(s, options_f, optarg) < 0) @@ -1804,12 +1852,13 @@ reparse: break; #endif case TCC_OPTION_m: - if (set_flag(s, options_m, optarg) == 0) - break; - else if (x = atoi(optarg), x == 32 || x == 64) - s->cross_target = x; - else - goto unsupported_option; + if (set_flag(s, options_m, optarg) < 0) { + if (x = atoi(optarg), x != 32 && x != 64) + goto unsupported_option; + if (PTR_SIZE != x/8) + return x; + ++noaction; + } break; case TCC_OPTION_W: if (set_flag(s, options_W, optarg) < 0) @@ -1860,6 +1909,20 @@ reparse: case TCC_OPTION_O: last_o = atoi(optarg); break; + case TCC_OPTION_print_search_dirs: + x = OPT_PRINT_DIRS; + goto extra_action; + case TCC_OPTION_impdef: + x = OPT_IMPDEF; + goto extra_action; + case TCC_OPTION_ar: + x = OPT_AR; + extra_action: + arg_start = optind - 1; + if (arg_start != noaction) + tcc_error("cannot parse %s here", r); + tool = x; + break; case TCC_OPTION_traditional: case TCC_OPTION_pedantic: case TCC_OPTION_pipe: @@ -1873,53 +1936,32 @@ unsupported_option: break; } } - if (last_o > 0) tcc_define_symbol(s, "__OPTIMIZE__", NULL); - if (linker_arg.size) { r = linker_arg.data; goto arg_err; } - - return optind; + *pargc = argc - arg_start; + *pargv = argv + arg_start; + if (tool) + return tool; + if (optind != noaction) + return 0; + if (s->verbose == 2) + return OPT_PRINT_DIRS; + if (s->verbose) + return OPT_V; + return OPT_HELP; } -LIBTCCAPI int tcc_set_options(TCCState *s, const char *r) +LIBTCCAPI void tcc_set_options(TCCState *s, const char *r) { - char **argv; - int argc; - int ret, q, c; - CString str; - - argc = 0, argv = NULL; - for(;;) { - while (c = (unsigned char)*r, c && c <= ' ') - ++r; - if (c == 0) - break; - q = 0; - cstr_new(&str); - while (c = (unsigned char)*r, c) { - ++r; - if (c == '\\' && (*r == '"' || *r == '\\')) { - c = *r++; - } else if (c == '"') { - q = !q; - continue; - } else if (q == 0 && c <= ' ') { - break; - } - cstr_ccat(&str, c); - } - cstr_ccat(&str, 0); - //printf("<%s>\n", str.data), fflush(stdout); - dynarray_add(&argv, &argc, tcc_strdup(str.data)); - cstr_free(&str); - } - ret = tcc_parse_args(s, argc, argv); + char **argv = NULL; + int argc = 0; + args_parser_make_argv(r, &argc, &argv); + tcc_parse_args(s, &argc, &argv, 0); dynarray_reset(&argv, &argc); - return ret; } PUB_FUNC void tcc_print_stats(TCCState *s, unsigned total_time) @@ -1928,11 +1970,15 @@ PUB_FUNC void tcc_print_stats(TCCState *s, unsigned total_time) total_time = 1; if (total_bytes < 1) total_bytes = 1; - fprintf(stderr, "%d idents, %d lines, %d bytes, %0.3f s, %u lines/s, %0.1f MB/s\n", + fprintf(stderr, "* %d idents, %d lines, %d bytes\n" + "* %0.3f s, %u lines/s, %0.1f MB/s\n", tok_ident - TOK_IDENT, total_lines, total_bytes, (double)total_time/1000, (unsigned)total_lines*1000/total_time, (double)total_bytes/1000/total_time); +#ifdef MEM_DEBUG + fprintf(stderr, "* %d bytes memory used\n", mem_max_size); +#endif } PUB_FUNC void tcc_set_environment(TCCState *s) |
