diff options
| author | grischka <grischka> | 2013-02-12 19:13:28 +0100 |
|---|---|---|
| committer | grischka <grischka> | 2013-02-12 19:13:28 +0100 |
| commit | 05108a3b0a8eff70739b253b8995999b1861f9f2 (patch) | |
| tree | 690c17ebe3cd0479e278bc3b65e00eba7ec674fd /libtcc.c | |
| parent | 829655949b7964c66e1f7da9d44c19655dba88aa (diff) | |
| download | tinycc-05108a3b0a8eff70739b253b8995999b1861f9f2.tar.gz tinycc-05108a3b0a8eff70739b253b8995999b1861f9f2.tar.bz2 | |
libtcc: new LIBTCCAPI tcc_set_options(TCCState*, const char*str)
This replaces -> use instead:
-----------------------------------
- tcc_set_linker -> tcc_set_options(s, "-Wl,...");
- tcc_set_warning -> tcc_set_options(s, "-W...");
- tcc_enable_debug -> tcc_set_options(s, "-g");
parse_args is moved to libtcc.c (now tcc_parse_args).
Also some cleanups:
- reorder TCCState members
- add some comments here and there
- do not use argv's directly, make string copies
- use const char* in tcc_set_linker
- tccpe: use fd instead of fp
tested with -D MEM_DEBUG: 0 bytes left
Diffstat (limited to 'libtcc.c')
| -rw-r--r-- | libtcc.c | 631 |
1 files changed, 423 insertions, 208 deletions
@@ -197,8 +197,8 @@ PUB_FUNC char *tcc_fileextension (const char *name) #undef realloc #ifdef MEM_DEBUG -int mem_cur_size; -int mem_max_size; +ST_DATA int mem_cur_size; +ST_DATA int mem_max_size; unsigned malloc_usable_size(void*); #endif @@ -261,7 +261,7 @@ PUB_FUNC char *tcc_strdup(const char *str) PUB_FUNC void tcc_memstats(void) { #ifdef MEM_DEBUG - printf("memory in use: %d\n", mem_cur_size); + printf("memory: %d bytes, max = %d bytes\n", mem_cur_size, mem_max_size); #endif } @@ -272,7 +272,7 @@ PUB_FUNC void tcc_memstats(void) /********************************************************/ /* dynarrays */ -PUB_FUNC void dynarray_add(void ***ptab, int *nb_ptr, void *data) +ST_FUNC void dynarray_add(void ***ptab, int *nb_ptr, void *data) { int nb, nb_alloc; void **pp; @@ -292,7 +292,7 @@ PUB_FUNC void dynarray_add(void ***ptab, int *nb_ptr, void *data) *nb_ptr = nb; } -PUB_FUNC void dynarray_reset(void *pp, int *n) +ST_FUNC void dynarray_reset(void *pp, int *n) { void **p; for (p = *(void***)pp; *n; ++p, --*n) @@ -860,10 +860,10 @@ LIBTCCAPI void tcc_undefine_symbol(TCCState *s1, const char *sym) define_undef(s); } +/* cleanup all static data used during compilation */ static void tcc_cleanup(void) { int i, n; - if (NULL == tcc_state) return; tcc_state = NULL; @@ -915,18 +915,23 @@ LIBTCCAPI TCCState *tcc_new(void) define_push(TOK___DATE__, MACRO_OBJ, NULL, NULL); define_push(TOK___TIME__, MACRO_OBJ, NULL, NULL); + /* define __TINYC__ 92X */ + sscanf(TCC_VERSION, "%d.%d.%d", &a, &b, &c); + sprintf(buffer, "%d", a*10000 + b*100 + c); + tcc_define_symbol(s, "__TINYC__", buffer); + /* standard defines */ tcc_define_symbol(s, "__STDC__", NULL); tcc_define_symbol(s, "__STDC_VERSION__", "199901L"); + + /* target defines */ #if defined(TCC_TARGET_I386) tcc_define_symbol(s, "__i386__", NULL); tcc_define_symbol(s, "__i386", NULL); tcc_define_symbol(s, "i386", NULL); -#endif -#if defined(TCC_TARGET_X86_64) +#elif defined(TCC_TARGET_X86_64) tcc_define_symbol(s, "__x86_64__", NULL); -#endif -#if defined(TCC_TARGET_ARM) +#elif defined(TCC_TARGET_ARM) tcc_define_symbol(s, "__ARM_ARCH_4__", NULL); tcc_define_symbol(s, "__arm_elf__", NULL); tcc_define_symbol(s, "__arm_elf", NULL); @@ -936,34 +941,31 @@ LIBTCCAPI TCCState *tcc_new(void) tcc_define_symbol(s, "arm", NULL); tcc_define_symbol(s, "__APCS_32__", NULL); #endif + #ifdef TCC_TARGET_PE tcc_define_symbol(s, "_WIN32", NULL); -#ifdef TCC_TARGET_X86_64 +# ifdef TCC_TARGET_X86_64 tcc_define_symbol(s, "_WIN64", NULL); -#endif +# endif #else tcc_define_symbol(s, "__unix__", NULL); tcc_define_symbol(s, "__unix", NULL); tcc_define_symbol(s, "unix", NULL); -#if defined(__FreeBSD__) -#define str(s) #s - tcc_define_symbol(s, "__FreeBSD__", str( __FreeBSD__)); -#undef str -#endif -#if defined(__FreeBSD_kernel__) - tcc_define_symbol(s, "__FreeBSD_kernel__", NULL); -#endif -#if defined(__linux) +# if defined(__linux) tcc_define_symbol(s, "__linux__", NULL); tcc_define_symbol(s, "__linux", NULL); +# endif +# if defined(__FreeBSD__) +# define str(s) #s + tcc_define_symbol(s, "__FreeBSD__", str( __FreeBSD__)); +# undef str +# endif +# if defined(__FreeBSD_kernel__) + tcc_define_symbol(s, "__FreeBSD_kernel__", NULL); +# endif #endif -#endif - /* tiny C specific defines */ - sscanf(TCC_VERSION, "%d.%d.%d", &a, &b, &c); - sprintf(buffer, "%d", a*10000 + b*100 + c); - tcc_define_symbol(s, "__TINYC__", buffer); - /* tiny C & gcc defines */ + /* TinyCC & gcc defines */ #if defined TCC_TARGET_PE && defined TCC_TARGET_X86_64 tcc_define_symbol(s, "__SIZE_TYPE__", "unsigned long long"); tcc_define_symbol(s, "__PTRDIFF_TYPE__", "long long"); @@ -978,11 +980,10 @@ LIBTCCAPI TCCState *tcc_new(void) tcc_define_symbol(s, "__WCHAR_TYPE__", "int"); #endif +#ifndef TCC_TARGET_PE /* glibc defines */ tcc_define_symbol(s, "__REDIRECT(name, proto, alias)", "name proto __asm__ (#alias)"); tcc_define_symbol(s, "__REDIRECT_NTH(name, proto, alias)", "name proto __asm__ (#alias) __THROW"); - -#ifndef TCC_TARGET_PE /* default library paths */ tcc_add_library_path(s, CONFIG_TCC_LIBPATHS); /* paths for crt objects */ @@ -1010,16 +1011,15 @@ LIBTCCAPI TCCState *tcc_new(void) ".dynhashtab", SHF_PRIVATE); s->alacarte_link = 1; s->nocommon = 1; + s->section_align = ELF_PAGE_SIZE; #ifdef CHAR_IS_UNSIGNED s->char_is_unsigned = 1; #endif /* enable this if you want symbols with leading underscore on windows: */ -#if defined(TCC_TARGET_PE) && 0 +#if 0 //def TCC_TARGET_PE s->leading_underscore = 1; #endif - if (s->section_align == 0) - s->section_align = ELF_PAGE_SIZE; #ifdef TCC_TARGET_I386 s->seg_size = 32; #endif @@ -1060,16 +1060,25 @@ LIBTCCAPI void tcc_delete(TCCState *s1) dynarray_reset(&s1->include_paths, &s1->nb_include_paths); dynarray_reset(&s1->sysinclude_paths, &s1->nb_sysinclude_paths); - dynarray_reset(&s1->target_deps, &s1->nb_target_deps); - tcc_free(s1->tcc_lib_path); + tcc_free(s1->soname); + tcc_free(s1->rpath); + tcc_free(s1->init_symbol); + tcc_free(s1->fini_symbol); + tcc_free(s1->outfile); + tcc_free(s1->deps_outfile); + dynarray_reset(&s1->files, &s1->nb_files); + dynarray_reset(&s1->target_deps, &s1->nb_target_deps); -#ifdef HAVE_SELINUX +#ifdef TCC_IS_NATIVE +# ifdef HAVE_SELINUX munmap (s1->write_mem, s1->mem_size); munmap (s1->runtime_mem, s1->mem_size); -#else +# else tcc_free(s1->runtime_mem); +# endif #endif + tcc_free(s1); } @@ -1236,7 +1245,6 @@ static int tcc_add_library_internal(TCCState *s, const char *fmt, return -1; } -#ifndef TCC_TARGET_PE /* find and load a dll. Return non zero if not found */ /* XXX: add '-rpath' option support ? */ ST_FUNC int tcc_add_dll(TCCState *s, const char *filename, int flags) @@ -1244,7 +1252,6 @@ ST_FUNC int tcc_add_dll(TCCState *s, const char *filename, int flags) return tcc_add_library_internal(s, "%s/%s", filename, flags, s->library_paths, s->nb_library_paths); } -#endif ST_FUNC int tcc_add_crt(TCCState *s, const char *filename) { @@ -1276,11 +1283,15 @@ LIBTCCAPI int tcc_add_library(TCCState *s, const char *libraryname) LIBTCCAPI int tcc_add_symbol(TCCState *s, const char *name, const void *val) { #ifdef TCC_TARGET_PE -pe_putimport(s, 0, name, (uintptr_t)val); + /* On x86_64 'val' might not be reachable with a 32bit offset. + So it is handled here as if it were in a DLL. */ + pe_putimport(s, 0, name, (uintptr_t)val); #else -add_elf_sym(symtab_section, (uintptr_t)val, 0, - ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0, - SHN_ABS, name); + /* XXX: Same problem on linux but currently "solved" elsewhere + via the rather dirty 'runtime_plt_and_got' hack. */ + add_elf_sym(symtab_section, (uintptr_t)val, 0, + ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0, + SHN_ABS, name); #endif return 0; } @@ -1341,6 +1352,12 @@ LIBTCCAPI int tcc_set_output_type(TCCState *s, int output_type) return 0; } +LIBTCCAPI void tcc_set_lib_path(TCCState *s, const char *path) +{ + tcc_free(s->tcc_lib_path); + s->tcc_lib_path = tcc_strdup(path); +} + #define WD_ALL 0x0001 /* warning is activated when using -Wall */ #define FD_INVERT 0x0002 /* invert value before storing */ @@ -1382,14 +1399,8 @@ ST_FUNC int set_flag(TCCState *s, const FlagDef *flags, int nb_flags, return 0; } -/* enable debug */ -LIBTCCAPI void tcc_enable_debug(TCCState *s) -{ - s->do_debug = 1; -} - /* set/reset a warning */ -LIBTCCAPI int tcc_set_warning(TCCState *s, const char *warning_name, int value) +static int tcc_set_warning(TCCState *s, const char *warning_name, int value) { int i; const FlagDef *p; @@ -1414,30 +1425,28 @@ static const FlagDef flag_defs[] = { }; /* set/reset a flag */ -PUB_FUNC int tcc_set_flag(TCCState *s, const char *flag_name, int value) +static int tcc_set_flag(TCCState *s, const char *flag_name, int value) { return set_flag(s, flag_defs, countof(flag_defs), flag_name, value); } -static int strstart(const char *str, const char *val, char **ptr) +static int strstart(const char *val, const char **str) { const char *p, *q; - p = str; + p = *str; q = val; - while (*q != '\0') { + while (*q) { if (*p != *q) return 0; p++; q++; } - if (ptr) - *ptr = (char *) p; + *str = p; return 1; } - /* Like strstart, but automatically takes into account that ld options can * * - start with double or single dash (e.g. '--soname' or '-soname') @@ -1446,7 +1455,7 @@ static int strstart(const char *str, const char *val, char **ptr) * * you provide `val` always in 'option[=]' form (no leading -) */ -static int link_option(const char *str, const char *val, char **ptr) +static int link_option(const char *str, const char *val, const char **ptr) { const char *p, *q; @@ -1476,64 +1485,72 @@ static int link_option(const char *str, const char *val, char **ptr) } if (ptr) - *ptr = (char *) p; + *ptr = p; return 1; } +static const char *skip_linker_arg(const char **str) +{ + const char *s1 = *str; + const char *s2 = strchr(s1, ','); + *str = s2 ? s2++ : (s2 = s1 + strlen(s1)); + return s2; +} + +static char *copy_linker_arg(const char *p) +{ + const char *q = p; + skip_linker_arg(&q); + return pstrncpy(tcc_malloc(q - p + 1), p, q - p); +} /* set linker options */ -PUB_FUNC const char * tcc_set_linker(TCCState *s, char *option, int multi) +static int tcc_set_linker(TCCState *s, const char *option) { - char *p = option; - char *end; - while (option && *option) { - end = NULL; + + const char *p = option; + char *end = NULL; + int ignoring = 0; + if (link_option(option, "Bsymbolic", &p)) { s->symbolic = 1; } else if (link_option(option, "nostdlib", &p)) { s->nostdlib = 1; } else if (link_option(option, "fini=", &p)) { - s->fini_symbol = p; - if (s->warn_unsupported) - tcc_warning("ignoring -fini %s", p); - } else if (link_option(option, "image-base=", &p)) { + s->fini_symbol = copy_linker_arg(p); + ignoring = 1; + } else if (link_option(option, "image-base=", &p) + || link_option(option, "Ttext=", &p)) { s->text_addr = strtoull(p, &end, 16); s->has_text_addr = 1; } else if (link_option(option, "init=", &p)) { - s->init_symbol = p; - if (s->warn_unsupported) - tcc_warning("ignoring -init %s", p); + s->init_symbol = copy_linker_arg(p); + ignoring = 1; } else if (link_option(option, "oformat=", &p)) { #if defined(TCC_TARGET_PE) - if (strstart(p, "pe-", NULL)) { + if (strstart("pe-", &p)) { +#elif defined(TCC_TARGET_X86_64) + if (strstart("elf64-", &p)) { #else -#if defined(TCC_TARGET_X86_64) - if (strstart(p, "elf64-", NULL)) { -#else - if (strstart(p, "elf32-", NULL)) { -#endif + if (strstart("elf32-", &p)) { #endif s->output_format = TCC_OUTPUT_FORMAT_ELF; } else if (!strcmp(p, "binary")) { s->output_format = TCC_OUTPUT_FORMAT_BINARY; - } else #ifdef TCC_TARGET_COFF - if (!strcmp(p, "coff")) { + } else if (!strcmp(p, "coff")) { s->output_format = TCC_OUTPUT_FORMAT_COFF; - } else #endif - { - return p; - } + } else + goto err; } else if (link_option(option, "rpath=", &p)) { - s->rpath = p; + s->rpath = copy_linker_arg(p); } else if (link_option(option, "section-alignment=", &p)) { s->section_align = strtoul(p, &end, 16); } else if (link_option(option, "soname=", &p)) { - s->soname = p; - multi = 0; + s->soname = copy_linker_arg(p); #ifdef TCC_TARGET_PE } else if (link_option(option, "file-alignment=", &p)) { s->pe_file_align = strtoul(p, &end, 16); @@ -1561,98 +1578,346 @@ PUB_FUNC const char * tcc_set_linker(TCCState *s, char *option, int multi) if (!strcmp(p, "wince")) { s->pe_subsystem = 9; #endif - } else { - return p; - } + } else + goto err; #endif + } else + goto err; - } else if (link_option(option, "Ttext=", &p)) { - s->text_addr = strtoull(p, &end, 16); - s->has_text_addr = 1; - } else { - char *comma_ptr = strchr(option, ','); - if (comma_ptr) - *comma_ptr = '\0'; - return option; + if (ignoring && s->warn_unsupported) err: { + char buf[100], *e; + pstrcpy(buf, sizeof buf, e = copy_linker_arg(option)), tcc_free(e); + if (ignoring) + tcc_warning("unsupported linker option '%s'", buf); + else + tcc_error("unsupported linker option '%s'", buf); } - - if (multi) { - option = NULL; - p = strchr( (end) ? end : p, ','); - if (p) { - *p = 0; /* terminate last option */ - option = ++p; - } - } else - option = NULL; + option = skip_linker_arg(&p); } - return NULL; + return 0; } -/* set CONFIG_TCCDIR at runtime */ -LIBTCCAPI void tcc_set_lib_path(TCCState *s, const char *path) +typedef struct TCCOption { + const char *name; + uint16_t index; + uint16_t flags; +} TCCOption; + +enum { + TCC_OPTION_HELP, + TCC_OPTION_I, + TCC_OPTION_D, + TCC_OPTION_U, + TCC_OPTION_L, + TCC_OPTION_B, + TCC_OPTION_l, + TCC_OPTION_bench, + TCC_OPTION_bt, + TCC_OPTION_b, + TCC_OPTION_g, + TCC_OPTION_c, + TCC_OPTION_static, + TCC_OPTION_shared, + TCC_OPTION_soname, + TCC_OPTION_o, + TCC_OPTION_r, + TCC_OPTION_s, + TCC_OPTION_Wl, + TCC_OPTION_W, + TCC_OPTION_O, + TCC_OPTION_m, + TCC_OPTION_f, + TCC_OPTION_isystem, + TCC_OPTION_nostdinc, + TCC_OPTION_nostdlib, + TCC_OPTION_print_search_dirs, + TCC_OPTION_rdynamic, + 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, +}; + +#define TCC_OPTION_HAS_ARG 0x0001 +#define TCC_OPTION_NOSEP 0x0002 /* cannot have space before option and arg */ + +static const TCCOption tcc_options[] = { + { "h", TCC_OPTION_HELP, 0 }, + { "-help", TCC_OPTION_HELP, 0 }, + { "?", TCC_OPTION_HELP, 0 }, + { "I", TCC_OPTION_I, TCC_OPTION_HAS_ARG }, + { "D", TCC_OPTION_D, TCC_OPTION_HAS_ARG }, + { "U", TCC_OPTION_U, TCC_OPTION_HAS_ARG }, + { "L", TCC_OPTION_L, TCC_OPTION_HAS_ARG }, + { "B", TCC_OPTION_B, TCC_OPTION_HAS_ARG }, + { "l", TCC_OPTION_l, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP }, + { "bench", TCC_OPTION_bench, 0 }, +#ifdef CONFIG_TCC_BACKTRACE + { "bt", TCC_OPTION_bt, TCC_OPTION_HAS_ARG }, +#endif +#ifdef CONFIG_TCC_BCHECK + { "b", TCC_OPTION_b, 0 }, +#endif + { "g", TCC_OPTION_g, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP }, + { "c", TCC_OPTION_c, 0 }, + { "static", TCC_OPTION_static, 0 }, + { "shared", TCC_OPTION_shared, 0 }, + { "soname", TCC_OPTION_soname, TCC_OPTION_HAS_ARG }, + { "o", TCC_OPTION_o, TCC_OPTION_HAS_ARG }, + { "pedantic", TCC_OPTION_pedantic, 0}, + { "pthread", TCC_OPTION_pthread, 0}, + { "run", TCC_OPTION_run, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP }, + { "rdynamic", TCC_OPTION_rdynamic, 0 }, + { "r", TCC_OPTION_r, 0 }, + { "s", TCC_OPTION_s, 0 }, + { "Wl,", TCC_OPTION_Wl, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP }, + { "W", TCC_OPTION_W, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP }, + { "O", TCC_OPTION_O, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP }, + { "m", TCC_OPTION_m, TCC_OPTION_HAS_ARG }, + { "f", TCC_OPTION_f, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP }, + { "isystem", TCC_OPTION_isystem, TCC_OPTION_HAS_ARG }, + { "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 }, + { NULL, 0, 0 }, +}; + +static void parse_option_D(TCCState *s1, const char *optarg) { - tcc_free(s->tcc_lib_path); - s->tcc_lib_path = tcc_strdup(path); + char *sym = tcc_strdup(optarg); + char *value = strchr(sym, '='); + if (value) + *value++ = '\0'; + tcc_define_symbol(s1, sym, value); + tcc_free(sym); } -PUB_FUNC char *tcc_default_target(TCCState *s, const char *default_file) +PUB_FUNC int tcc_parse_args(TCCState *s, int argc, char **argv) { - char buf[1024]; - char *ext; - const char *name = "a"; + const TCCOption *popt; + const char *optarg, *r; + int run = 0; + int pthread = 0; + int optind = 0; - if (default_file && strcmp(default_file, "-")) - name = tcc_basename(default_file); - pstrcpy(buf, sizeof(buf), name); - ext = tcc_fileextension(buf); -#ifdef TCC_TARGET_PE - if (s->output_type == TCC_OUTPUT_DLL) - strcpy(ext, ".dll"); - else - if (s->output_type == TCC_OUTPUT_EXE) - strcpy(ext, ".exe"); - else -#endif - if (( (s->output_type == TCC_OUTPUT_OBJ && !s->reloc_output) || - (s->output_type == TCC_OUTPUT_PREPROCESS) ) - && *ext) - strcpy(ext, ".o"); - else - strcpy(buf, "a.out"); + /* collect -Wl options for input such as "-Wl,-rpath -Wl,<path>" */ + CString linker_arg; + cstr_new(&linker_arg); - return tcc_strdup(buf); -} + while (optind < argc) { + r = argv[optind++]; + if (r[0] != '-' || r[1] == '\0') { + /* add a new file */ + dynarray_add((void ***)&s->files, &s->nb_files, tcc_strdup(r)); + if (run) { + optind--; + /* argv[0] will be this file */ + break; + } + continue; + } -PUB_FUNC void tcc_gen_makedeps(TCCState *s, const char *target, const char *filename) -{ - FILE *depout; - char buf[1024], *ext; - int i; + /* find option in table */ + for(popt = tcc_options; ; ++popt) { + const char *p1 = popt->name; + const char *r1 = r + 1; + if (p1 == NULL) + tcc_error("invalid option -- '%s'", r); + if (!strstart(p1, &r1)) + continue; + optarg = r1; + if (popt->flags & TCC_OPTION_HAS_ARG) { + if (*r1 == '\0' && !(popt->flags & TCC_OPTION_NOSEP)) { + if (optind >= argc) + tcc_error("argument to '%s' is missing", r); + optarg = argv[optind++]; + } + } else if (*r1 != '\0') + continue; + break; + } - if (!filename) { - /* compute filename automatically - * dir/file.o -> dir/file.d */ - pstrcpy(buf, sizeof(buf), target); - ext = tcc_fileextension(buf); - pstrcpy(ext, sizeof(buf) - (ext-buf), ".d"); - filename = buf; + switch(popt->index) { + case TCC_OPTION_HELP: + return 0; + case TCC_OPTION_I: + if (tcc_add_include_path(s, optarg) < 0) + tcc_error("too many include paths"); + break; + case TCC_OPTION_D: + parse_option_D(s, optarg); + break; + case TCC_OPTION_U: + tcc_undefine_symbol(s, optarg); + break; + case TCC_OPTION_L: + tcc_add_library_path(s, optarg); + break; + case TCC_OPTION_B: + /* set tcc utilities path (mainly for tcc development) */ + tcc_set_lib_path(s, optarg); + break; + case TCC_OPTION_l: + dynarray_add((void ***)&s->files, &s->nb_files, tcc_strdup(r)); + s->nb_libraries++; + break; + case TCC_OPTION_pthread: + parse_option_D(s, "_REENTRANT"); + pthread = 1; + break; + case TCC_OPTION_bench: + s->do_bench = 1; + break; +#ifdef CONFIG_TCC_BACKTRACE + case TCC_OPTION_bt: + tcc_set_num_callers(atoi(optarg)); + break; +#endif +#ifdef CONFIG_TCC_BCHECK + case TCC_OPTION_b: + s->do_bounds_check = 1; + s->do_debug = 1; + break; +#endif + case TCC_OPTION_g: + s->do_debug = 1; + break; + case TCC_OPTION_c: + s->output_type = TCC_OUTPUT_OBJ; + break; + case TCC_OPTION_static: + s->static_link = 1; + break; + case TCC_OPTION_shared: + s->output_type = TCC_OUTPUT_DLL; + break; + case TCC_OPTION_soname: + s->soname = tcc_strdup(optarg); + break; + case TCC_OPTION_m: + s->option_m = tcc_strdup(optarg); + break; + case TCC_OPTION_o: + s->outfile = tcc_strdup(optarg); + break; + case TCC_OPTION_r: + /* generate a .o merging several output files */ + s->option_r = 1; + s->output_type = TCC_OUTPUT_OBJ; + break; + case TCC_OPTION_isystem: + tcc_add_sysinclude_path(s, optarg); + break; + case TCC_OPTION_nostdinc: + s->nostdinc = 1; + break; + case TCC_OPTION_nostdlib: + s->nostdlib = 1; + break; + case TCC_OPTION_print_search_dirs: + s->print_search_dirs = 1; + break; + case TCC_OPTION_run: + s->output_type = TCC_OUTPUT_MEMORY; + tcc_set_options(s, optarg); + run = 1; + break; + case TCC_OPTION_v: + do ++s->verbose; while (*optarg++ == 'v'); + break; + case TCC_OPTION_f: + if (tcc_set_flag(s, optarg, 1) < 0 && s->warn_unsupported) + goto unsupported_option; + break; + case TCC_OPTION_W: + if (tcc_set_warning(s, optarg, 1) < 0 && + s->warn_unsupported) + goto unsupported_option; + break; + case TCC_OPTION_w: + s->warn_none = 1; + break; + case TCC_OPTION_rdynamic: + s->rdynamic = 1; + break; + case TCC_OPTION_Wl: + if (linker_arg.size) + --linker_arg.size, cstr_ccat(&linker_arg, ','); + cstr_cat(&linker_arg, optarg); + cstr_ccat(&linker_arg, '\0'); + break; + case TCC_OPTION_E: + s->output_type = TCC_OUTPUT_PREPROCESS; + break; + case TCC_OPTION_MD: + s->gen_deps = 1; + break; + case TCC_OPTION_MF: + s->deps_outfile = tcc_strdup(optarg); + break; + case TCC_OPTION_O: + case TCC_OPTION_pedantic: + case TCC_OPTION_pipe: + case TCC_OPTION_s: + case TCC_OPTION_x: + /* ignored */ + break; + default: + if (s->warn_unsupported) { + unsupported_option: + tcc_warning("unsupported option '%s'", r); + } + break; + } } - if (s->verbose) - printf("<- %s\n", filename); + if (pthread && s->output_type != TCC_OUTPUT_OBJ) + tcc_set_options(s, "-lpthread"); - /* XXX return err codes instead of error() ? */ - depout = fopen(filename, "w"); - if (!depout) - tcc_error("could not open '%s'", filename); + tcc_set_linker(s, (const char *)linker_arg.data); + cstr_free(&linker_arg); - fprintf(depout, "%s : \\\n", target); - for (i=0; i<s->nb_target_deps; ++i) - fprintf(depout, " %s \\\n", s->target_deps[i]); - fprintf(depout, "\n"); - fclose(depout); + return optind; +} + +LIBTCCAPI int tcc_set_options(TCCState *s, const char *str) +{ + const char *s1; + char **argv, *arg; + int argc, len; + int ret; + + argc = 0, argv = NULL; + for(;;) { + while (is_space(*str)) + str++; + if (*str == '\0') + break; + s1 = str; + while (*str != '\0' && !is_space(*str)) + str++; + len = str - s1; + arg = tcc_malloc(len + 1); + pstrncpy(arg, s1, len); + dynarray_add((void ***)&argv, &argc, arg); + } + ret = tcc_parse_args(s, argc, argv); + dynarray_reset(&argv, &argc); + return ret; } PUB_FUNC void tcc_print_stats(TCCState *s, int64_t total_time) @@ -1668,53 +1933,3 @@ PUB_FUNC void tcc_print_stats(TCCState *s, int64_t total_time) tt, (int)(total_lines / tt), total_bytes / tt / 1000000.0); } - -static void print_paths(const char *msg, char **paths, int nb_paths) -{ - int i; - printf("%s:\n%s", msg, nb_paths ? "" : " -\n"); - for(i = 0; i < nb_paths; i++) - printf(" %s\n", paths[i]); -} - -PUB_FUNC void tcc_display_info(TCCState *s, int what) -{ - switch (what) { - case 0: - printf("tcc version %s (" -#ifdef TCC_TARGET_I386 - "i386" -# ifdef TCC_TARGET_PE - " Win32" -# endif -#elif defined TCC_TARGET_X86_64 - "x86-64" -# ifdef TCC_TARGET_PE - " Win64" -# endif -#elif defined TCC_TARGET_ARM - "ARM" -# ifdef TCC_ARM_HARDFLOAT - " Hard Float" -# endif -# ifdef TCC_TARGET_PE - " WinCE" -# endif -#endif -#ifndef TCC_TARGET_PE -# ifdef __linux - " Linux" -# endif -#endif - ")\n", TCC_VERSION); - break; - case 1: - printf("install: %s/\n", s->tcc_lib_path); - /* print_paths("programs", NULL, 0); */ - print_paths("crt", s->crt_paths, s->nb_crt_paths); - print_paths("libraries", s->library_paths, s->nb_library_paths); - print_paths("include", s->sysinclude_paths, s->nb_sysinclude_paths); - break; - } -} - |
