This cleans up the mess from commit 8f985736580926ac53dc367fc293524bf2810cbb and preceeding. - make tcc -m64 work on windows - execvp on windows returns 0 always, replace by spawnvp - remove bizarre support for i386-win32-tcc -m64
Unified · Split
| @@ -34,6 +34,7 @@ static const char *outfile; · 33 unmodified lines | |||
| 34 | static int do_bench = 0; | 34 | static int do_bench = 0; |
| 35 | static int gen_deps; | 35 | static int gen_deps; |
| 36 | static const char *deps_outfile; | 36 | static const char *deps_outfile; |
| 37 | static const char *m_option; | ||
| 37 | 38 | ||
| 38 | #define TCC_OPTION_HAS_ARG 0x0001 | 39 | #define TCC_OPTION_HAS_ARG 0x0001 |
| 39 | #define TCC_OPTION_NOSEP 0x0002 /* cannot have space before option and arg */ | 40 | #define TCC_OPTION_NOSEP 0x0002 /* cannot have space before option and arg */ |
| @@ -216,78 +217,50 @@ static int expand_args(char ***pargv, const char *str) · 176 unmodified lines | |||
| 216 | return argc; | 217 | return argc; |
| 217 | } | 218 | } |
| 218 | 219 | ||
| 219 | #if defined(TCC_TARGET_X86_64) || defined (TCC_TARGET_I386) | 220 | /* re-execute the i386/x86_64 cross-compilers with tcc -m32/-m64: */ |
| 220 | 221 | #if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64 | |
| 221 | #ifdef _WIN32 | 222 | #ifdef _WIN32 |
| 222 | #define CAST (const char * const *) | 223 | #include <process.h> |
| 223 | #else | 224 | static int execvp_win32(const char *prog, char **argv) |
| 224 | #define CAST (char * const *) | ||
| 225 | #endif | ||
| 226 | |||
| 227 | #if defined(TCC_TARGET_X86_64) | ||
| 228 | #define ARG 32 | ||
| 229 | #define CHILD "i386" | ||
| 230 | #elif defined (TCC_TARGET_I386) | ||
| 231 | #define ARG 64 | ||
| 232 | #define CHILD "x86_64" | ||
| 233 | #endif | ||
| 234 | |||
| 235 | static char *ssuffix(const char *oldname, const char sep) | ||
| 236 | { | 225 | { |
| 237 | char *p, *name = tcc_strdup(oldname); | 226 | int ret = spawnvp(P_NOWAIT, prog, (char const*const*)argv); |
| 238 | p = strchr(name, sep); | 227 | if (-1 == ret) |
| 239 | if (p) | 228 | return ret; |
| 240 | return p + 1; | 229 | cwait(&ret, ret, WAIT_CHILD); |
| 241 | /* prefix "win32-" when file extension is present */ | 230 | exit(ret); |
| 242 | if (*tcc_fileextension(name)){ | ||
| 243 | name = tcc_realloc(name, strlen(oldname + 7)); | ||
| 244 | sprintf(name, "win32-%s", oldname); | ||
| 245 | } | ||
| 246 | return name; | ||
| 247 | } | 231 | } |
| 248 | 232 | #define execvp execvp_win32 | |
| 249 | static void exec_other_tcc(TCCState *s, int argc, | 233 | #endif |
| 250 | char **argv,const char *optarg, int optind) | 234 | static void exec_other_tcc(TCCState *s, char **argv, const char *optarg) |
| 251 | { | 235 | { |
| 252 | char child_path[4096],child_name[4096]; | 236 | char child_path[4096], *child_name; const char *target; |
| 253 | char *parent,*child_tcc; | 237 | switch (atoi(optarg)) { |
| 254 | int opt = atoi(optarg); | 238 | #ifdef TCC_TARGET_I386 |
| 255 | if (strlen(argv[0]) > 4000) | 239 | case 32: break; |
| 256 | error("-m%i unsafe path length", ARG); | 240 | case 64: target = "x86_64"; |
| 257 | switch (opt) { | 241 | #else |
| 258 | case ARG + 1: /* oops we called ourselves */ | 242 | case 64: break; |
| 259 | error("-m%i cross compiler not installed", ARG); | 243 | case 32: target = "i386"; |
| 244 | #endif | ||
| 245 | pstrcpy(child_path, sizeof child_path - 40, argv[0]); | ||
| 246 | child_name = tcc_basename(child_path); | ||
| 247 | strcpy(child_name, target); | ||
| 248 | #ifdef TCC_TARGET_PE | ||
| 249 | strcat(child_name, "-win32"); | ||
| 250 | #endif | ||
| 251 | strcat(child_name, "-tcc"); | ||
| 252 | if (strcmp(argv[0], child_path)) { | ||
| 253 | if (s->verbose > 0) | ||
| 254 | printf("tcc: using '%s'\n", child_name), fflush(stdout); | ||
| 255 | execvp(argv[0] = child_path, argv); | ||
| 256 | } | ||
| 257 | error("'%s' not found", child_name); | ||
| 258 | case 0: /* ignore -march etc. */ | ||
| 260 | break; | 259 | break; |
| 261 | case ARG: | ||
| 262 | { | ||
| 263 | parent = tcc_basename(argv[0]); | ||
| 264 | child_tcc = ssuffix(parent,'-'); | ||
| 265 | sprintf(child_name, CHILD "-%s", child_tcc); | ||
| 266 | tcc_free(child_tcc); | ||
| 267 | if (strcmp(parent, child_name)) { | ||
| 268 | /* child_path = dirname */ | ||
| 269 | pstrcpy(child_path, parent - argv[0] + 1, argv[0]); | ||
| 270 | child_tcc = strchr(child_path, 0); | ||
| 271 | strcpy(child_tcc, child_name); | ||
| 272 | if (0 < s->verbose) | ||
| 273 | printf("%s -m%i -> %s\n", | ||
| 274 | parent, ARG, child_path); | ||
| 275 | sprintf(argv[optind],"-m%i", ARG + 1); /* no loop */ | ||
| 276 | execvp(child_path, CAST argv); | ||
| 277 | sprintf(child_tcc,"tcc%s",tcc_fileextension(parent)); | ||
| 278 | execvp(child_path, CAST argv); | ||
| 279 | error("-m%i cross compiler not found", ARG); | ||
| 280 | } else error("-m%i unsupported configuration", ARG); | ||
| 281 | } | ||
| 282 | case 96 ^ ARG : break; | ||
| 283 | case 96 ^ (ARG + 1): break; | ||
| 284 | default: | 260 | default: |
| 285 | warning("usupported option \"-m%s\"",optarg); | 261 | warning("unsupported option \"-m%s\"", optarg); |
| 286 | } | 262 | } |
| 287 | } | 263 | } |
| 288 | #undef CAST | ||
| 289 | #undef ARG | ||
| 290 | #undef CHILD | ||
| 291 | #endif | 264 | #endif |
| 292 | 265 | ||
| 293 | static int parse_args(TCCState *s, int argc, char **argv) | 266 | static int parse_args(TCCState *s, int argc, char **argv) |
| @@ -300,7 +273,7 @@ static int parse_args(TCCState *s, int argc, char **argv) · 6 unmodified lines | |||
| 300 | 273 | ||
| 301 | was_pthread = 0; /* is set if commandline contains -pthread key */ | 274 | was_pthread = 0; /* is set if commandline contains -pthread key */ |
| 302 | 275 | ||
| 303 | optind = 0; | 276 | optind = 1; |
| 304 | while (optind < argc) { | 277 | while (optind < argc) { |
| 305 | 278 | ||
| 306 | r = argv[optind++]; | 279 | r = argv[optind++]; |
| @@ -419,11 +392,9 @@ static int parse_args(TCCState *s, int argc, char **argv) · 112 unmodified lines | |||
| 419 | case TCC_OPTION_soname: | 392 | case TCC_OPTION_soname: |
| 420 | s->soname = optarg; | 393 | s->soname = optarg; |
| 421 | break; | 394 | break; |
| 422 | #if defined(TCC_TARGET_X86_64) || defined (TCC_TARGET_I386) | ||
| 423 | case TCC_OPTION_m: | 395 | case TCC_OPTION_m: |
| 424 | exec_other_tcc(s, argc+1, argv-1, optarg, optind); | 396 | m_option = optarg; |
| 425 | break; | 397 | break; |
| 426 | #endif | ||
| 427 | case TCC_OPTION_o: | 398 | case TCC_OPTION_o: |
| 428 | multiple_files = 1; | 399 | multiple_files = 1; |
| 429 | outfile = optarg; | 400 | outfile = optarg; |
| @@ -458,10 +429,7 @@ static int parse_args(TCCState *s, int argc, char **argv) · 28 unmodified lines | |||
| 458 | } | 429 | } |
| 459 | break; | 430 | break; |
| 460 | case TCC_OPTION_v: | 431 | case TCC_OPTION_v: |
| 461 | do { | 432 | do ++s->verbose; while (*optarg++ == 'v'); |
| 462 | if (0 == s->verbose++) | ||
| 463 | printf("tcc version %s\n", TCC_VERSION); | ||
| 464 | } while (*optarg++ == 'v'); | ||
| 465 | break; | 433 | break; |
| 466 | case TCC_OPTION_f: | 434 | case TCC_OPTION_f: |
| 467 | if (tcc_set_flag(s, optarg, 1) < 0 && s->warn_unsupported) | 435 | if (tcc_set_flag(s, optarg, 1) < 0 && s->warn_unsupported) |
| @@ -511,7 +479,7 @@ static int parse_args(TCCState *s, int argc, char **argv) · 43 unmodified lines | |||
| 511 | dynarray_add((void ***)&files, &nb_files, "-lpthread"); | 479 | dynarray_add((void ***)&files, &nb_files, "-lpthread"); |
| 512 | nb_libraries++; | 480 | nb_libraries++; |
| 513 | } | 481 | } |
| 514 | return optind + 1; | 482 | return optind; |
| 515 | } | 483 | } |
| 516 | 484 | ||
| 517 | int main(int argc, char **argv) | 485 | int main(int argc, char **argv) |
| @@ -531,14 +499,25 @@ int main(int argc, char **argv) · 13 unmodified lines | |||
| 531 | nb_libraries = 0; | 499 | nb_libraries = 0; |
| 532 | reloc_output = 0; | 500 | reloc_output = 0; |
| 533 | print_search_dirs = 0; | 501 | print_search_dirs = 0; |
| 502 | m_option = NULL; | ||
| 534 | ret = 0; | 503 | ret = 0; |
| 535 | 504 | ||
| 536 | optind = parse_args(s, argc - 1, argv + 1); | 505 | optind = parse_args(s, argc, argv); |
| 506 | |||
| 507 | #if defined TCC_TARGET_X86_64 || defined TCC_TARGET_I386 | ||
| 508 | if (m_option) | ||
| 509 | exec_other_tcc(s, argv, m_option); | ||
| 510 | #endif | ||
| 511 | |||
| 537 | if (print_search_dirs) { | 512 | if (print_search_dirs) { |
| 538 | /* enough for Linux kernel */ | 513 | /* enough for Linux kernel */ |
| 539 | printf("install: %s/\n", s->tcc_lib_path); | 514 | printf("install: %s/\n", s->tcc_lib_path); |
| 540 | return 0; | 515 | return 0; |
| 541 | } | 516 | } |
| 517 | |||
| 518 | if (s->verbose) | ||
| 519 | printf("tcc version %s\n", TCC_VERSION); | ||
| 520 | |||
| 542 | if (optind == 0 || nb_files == 0) { | 521 | if (optind == 0 || nb_files == 0) { |
| 543 | if (optind && s->verbose) | 522 | if (optind && s->verbose) |
| 544 | return 0; | 523 | return 0; |
| @@ -44,7 +44,6 @@ · 43 unmodified lines | |||
| 44 | 44 | ||
| 45 | #ifdef _WIN32 | 45 | #ifdef _WIN32 |
| 46 | #include <windows.h> | 46 | #include <windows.h> |
| 47 | #include <process.h> | ||
| 48 | #include <sys/timeb.h> | 47 | #include <sys/timeb.h> |
| 49 | #include <io.h> /* open, close etc. */ | 48 | #include <io.h> /* open, close etc. */ |
| 50 | #include <direct.h> /* getcwd */ | 49 | #include <direct.h> /* getcwd */ |