libtcc: -Wl,... incremental parsing

parse -Wl linker options immediately
master
grischka 2016-10-01 20:49:38 +02:00
parent 2d6aa65067
commit 2f1174550e
3 changed files with 31 additions and 38 deletions

View File

@ -1809,14 +1809,13 @@ static int link_option(const char *str, const char *val, const char **ptr)
/* '=' near eos means ',' or '=' is ok */
if (*q == '=') {
if (*p == 0)
*ptr = p;
if (*p != ',' && *p != '=')
return 0;
p++;
q++;
}
if (ptr)
*ptr = p;
*ptr = p;
return 1;
}
@ -1838,9 +1837,9 @@ static char *copy_linker_arg(const char *p)
/* set linker options */
static int tcc_set_linker(TCCState *s, const char *option)
{
while (option && *option) {
while (*option) {
const char *p = option;
const char *p = NULL;
char *end = NULL;
int ignoring = 0;
@ -1916,20 +1915,19 @@ static int tcc_set_linker(TCCState *s, const char *option)
} else
goto err;
#endif
} else
goto err;
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);
} else if (p) {
return 0;
} else {
err:
tcc_error("unsupported linker option '%s'", option);
}
if (ignoring && s->warn_unsupported)
tcc_warning("unsupported linker option '%s'", option);
option = skip_linker_arg(&p);
}
return 0;
return 1;
}
typedef struct TCCOption {
@ -2089,9 +2087,10 @@ PUB_FUNC int tcc_parse_args(TCCState *s, int argc, char **argv)
int optind = 0;
int run = 0;
int x;
CString linker_arg; /* collect -Wl options */
char buf[1024];
++s->args_ref;
cstr_new(&linker_arg);
while (optind < argc) {
@ -2124,6 +2123,7 @@ PUB_FUNC int tcc_parse_args(TCCState *s, int argc, char **argv)
if (popt->flags & TCC_OPTION_HAS_ARG) {
if (*r1 == '\0' && !(popt->flags & TCC_OPTION_NOSEP)) {
if (optind >= argc)
arg_err:
tcc_error("argument to '%s' is missing", r);
optarg = argv[optind++];
}
@ -2157,7 +2157,7 @@ PUB_FUNC int tcc_parse_args(TCCState *s, int argc, char **argv)
break;
case TCC_OPTION_pthread:
parse_option_D(s, "_REENTRANT");
s->args_pthread = 1;
s->option_pthread = 1;
break;
case TCC_OPTION_bench:
s->do_bench = 1;
@ -2273,9 +2273,11 @@ PUB_FUNC int tcc_parse_args(TCCState *s, int argc, char **argv)
s->rdynamic = 1;
break;
case TCC_OPTION_Wl:
if (s->linker_arg.size)
--s->linker_arg.size, cstr_ccat(&s->linker_arg, ',');
cstr_cat(&s->linker_arg, optarg, 0);
if (linker_arg.size)
--linker_arg.size, cstr_ccat(&linker_arg, ',');
cstr_cat(&linker_arg, optarg, 0);
if (tcc_set_linker(s, linker_arg.data))
cstr_free(&linker_arg);
break;
case TCC_OPTION_E:
x = TCC_OUTPUT_PREPROCESS;
@ -2323,19 +2325,10 @@ unsupported_option:
}
}
if (1 == s->args_ref) {
/* top instance */
if (s->output_type != TCC_OUTPUT_OBJ) {
tcc_set_linker(s, (const char *)s->linker_arg.data);
if (s->args_pthread) {
args_parser_add_file(s, optarg, 'l');
s->nb_libraries++;
}
}
cstr_free(&s->linker_arg);
s->args_pthread = 0;
if (linker_arg.size) {
r = linker_arg.data;
goto arg_err;
}
--s->args_ref;
return optind;
}

3
tcc.c
View File

@ -303,6 +303,9 @@ int main(int argc, char **argv)
if (!s->ppfp)
tcc_error("could not write '%s'", s->outfile);
}
} else if (s->output_type != TCC_OUTPUT_OBJ) {
if (s->option_pthread)
tcc_set_options(s, "-lpthread");
}
if (s->do_bench)

5
tcc.h
View File

@ -762,10 +762,7 @@ struct TCCState {
int do_bench; /* option -bench */
int gen_deps; /* option -MD */
char *deps_outfile; /* option -MF */
int args_pthread; /* -pthread option */
CString linker_arg; /* collect -Wl options for input such as "-Wl,-rpath -Wl,<path>" */
int args_ref; /* tcc_parse_args recursive counter */
int option_pthread; /* -pthread option */
};
struct filespec {