Unified · Split
| @@ -212,35 +212,69 @@ static int expand_args(char ***pargv, const char *str) · 211 unmodified lines | |||
| 212 | return argc; | 212 | return argc; |
| 213 | } | 213 | } |
| 214 | 214 | ||
| 215 | void exec_other_tcc(TCCState *s, int argc,char **argv,int optarg) | 215 | #if defined(TCC_TARGET_X86_64) || defined (TCC_TARGET_I386) |
| 216 | { | 216 | |
| 217 | #ifdef TCC_TARGET_X86_64 | ||
| 218 | #define WIN32_CAST | ||
| 219 | char arg[20]="i386-tcc"; | ||
| 220 | char sep='/',*tcc; | ||
| 221 | if (32 == optarg) {/* -m32 launches 32 bit tcc */ | ||
| 222 | #ifdef TCC_TARGET_PE | ||
| 223 | #ifdef _WIN32 | 217 | #ifdef _WIN32 |
| 224 | #define WIN32_CAST (const char**)(const char *) | 218 | #define CAST (const char * const *) |
| 225 | strcpy(arg,"tcc.exe"); | ||
| 226 | sep='\\'; | ||
| 227 | #else | 219 | #else |
| 228 | strcpy(arg,"i386-win32-tcc"); | 220 | #define CAST (char * const *) |
| 229 | #endif | 221 | #endif |
| 222 | |||
| 223 | #if defined(TCC_TARGET_X86_64) | ||
| 224 | #define ARG 32 | ||
| 225 | #define CHILD "i386" | ||
| 226 | #elif defined (TCC_TARGET_I386) | ||
| 227 | #define ARG 64 | ||
| 228 | #define CHILD "x86_64" | ||
| 230 | #endif | 229 | #endif |
| 231 | if (!(tcc=strrchr(argv[0],sep))) | 230 | |
| 232 | tcc=argv[0]; | 231 | static const char *ssuffix(const char *name, const char sep) |
| 233 | else tcc++; | 232 | { |
| 234 | if (0<s->verbose) printf("%s->%s\n",tcc,arg); | 233 | char *p = strchr(name, sep); |
| 235 | if (strcmp(tcc,arg)) { | 234 | return p?p+1:name; |
| 236 | execvp(arg, WIN32_CAST (argv)); | 235 | } |
| 237 | error("cross compiler not found!"); | 236 | |
| 238 | exit(1); | 237 | static void exec_other_tcc(TCCState *s, int argc, |
| 239 | } else warning("-m32 infinite loop prevented"); | 238 | char **argv,const char *optarg, int optind) |
| 240 | } else warning("usupported option \"-m%s\"",optarg); | 239 | { |
| 241 | #undef WIN32_CAST | 240 | char child_path[4096],child_name[4096]; |
| 242 | #endif | 241 | char *parent,*child_tcc; |
| 242 | int opt = atoi(optarg); | ||
| 243 | if (strlen(argv[0]) > 4000) | ||
| 244 | error("-m%s unsafe path length", ARG); | ||
| 245 | switch (opt) { | ||
| 246 | case ARG + 1: /* oops we called ourselves */ | ||
| 247 | error("-m%s cross compiler not installed", ARG); | ||
| 248 | break; | ||
| 249 | case ARG: | ||
| 250 | { | ||
| 251 | parent = tcc_basename(argv[0]); | ||
| 252 | sprintf(child_name, CHILD "-%s", ssuffix(parent,'-')); | ||
| 253 | if (strcmp(parent, child_name)) { | ||
| 254 | /* child_path = dirname */ | ||
| 255 | pstrcpy(child_path, parent - argv[0] + 1, argv[0]); | ||
| 256 | child_tcc = strchr(child_path, 0); | ||
| 257 | strcpy(child_tcc, child_name); | ||
| 258 | if (0 < s->verbose) | ||
| 259 | printf("%s -m%i -> %s\n", | ||
| 260 | parent, ARG, child_path); | ||
| 261 | sprintf(argv[optind],"-m%i", ARG + 1); /* no loop */ | ||
| 262 | execvp(child_path, CAST argv); | ||
| 263 | sprintf(child_tcc,"tcc%s",tcc_fileextension(parent)); | ||
| 264 | execvp(child_path, CAST argv); | ||
| 265 | error("-m%s cross compiler not found", ARG); | ||
| 266 | } else error("-m%s unsupported configuration", ARG); | ||
| 267 | } | ||
| 268 | case 96 ^ ARG : break; | ||
| 269 | case 96 ^ (ARG + 1): break; | ||
| 270 | default: | ||
| 271 | warning("usupported option \"-m%s\"",optarg); | ||
| 272 | } | ||
| 243 | } | 273 | } |
| 274 | #undef CAST | ||
| 275 | #undef ARG | ||
| 276 | #undef CHILD | ||
| 277 | #endif | ||
| 244 | 278 | ||
| 245 | static int parse_args(TCCState *s, int argc, char **argv) | 279 | static int parse_args(TCCState *s, int argc, char **argv) |
| 246 | { | 280 | { |
| @@ -366,9 +400,11 @@ static int parse_args(TCCState *s, int argc, char **argv) · 119 unmodified lines | |||
| 366 | case TCC_OPTION_soname: | 400 | case TCC_OPTION_soname: |
| 367 | s->soname = optarg; | 401 | s->soname = optarg; |
| 368 | break; | 402 | break; |
| 403 | #if defined(TCC_TARGET_X86_64) || defined (TCC_TARGET_I386) | ||
| 369 | case TCC_OPTION_m: | 404 | case TCC_OPTION_m: |
| 370 | exec_other_tcc(s,argc+1,argv-1,atoi(optarg)); | 405 | exec_other_tcc(s, argc+1, argv-1, optarg, optind); |
| 371 | break; | 406 | break; |
| 407 | #endif | ||
| 372 | case TCC_OPTION_o: | 408 | case TCC_OPTION_o: |
| 373 | multiple_files = 1; | 409 | multiple_files = 1; |
| 374 | outfile = optarg; | 410 | outfile = optarg; |