Changeset 331 for EcnlProtoTool/trunk/tcc-0.9.27/tcc.c
- Timestamp:
- Jan 21, 2018, 12:10:09 AM (6 years ago)
- Location:
- EcnlProtoTool/trunk/tcc-0.9.27
- Files:
-
- 1 edited
- 1 moved
Legend:
- Unmodified
- Added
- Removed
-
EcnlProtoTool/trunk/tcc-0.9.27/tcc.c
r321 r331 19 19 */ 20 20 21 #ifdef ONE_SOURCE 22 #include "libtcc.c" 21 #include "tcc.h" 22 #if ONE_SOURCE 23 # include "libtcc.c" 24 #endif 25 #include "tcctools.c" 26 27 static const char help[] = 28 "Tiny C Compiler "TCC_VERSION" - Copyright (C) 2001-2006 Fabrice Bellard\n" 29 "Usage: tcc [options...] [-o outfile] [-c] infile(s)...\n" 30 " tcc [options...] -run infile [arguments...]\n" 31 "General options:\n" 32 " -c compile only - generate an object file\n" 33 " -o outfile set output filename\n" 34 " -run run compiled source\n" 35 " -fflag set or reset (with 'no-' prefix) 'flag' (see tcc -hh)\n" 36 " -Wwarning set or reset (with 'no-' prefix) 'warning' (see tcc -hh)\n" 37 " -w disable all warnings\n" 38 " -v -vv show version, show search paths or loaded files\n" 39 " -h -hh show this, show more help\n" 40 " -bench show compilation statistics\n" 41 " - use stdin pipe as infile\n" 42 " @listfile read arguments from listfile\n" 43 "Preprocessor options:\n" 44 " -Idir add include path 'dir'\n" 45 " -Dsym[=val] define 'sym' with value 'val'\n" 46 " -Usym undefine 'sym'\n" 47 " -E preprocess only\n" 48 "Linker options:\n" 49 " -Ldir add library path 'dir'\n" 50 " -llib link with dynamic or static library 'lib'\n" 51 " -r generate (relocatable) object file\n" 52 " -shared generate a shared library/dll\n" 53 " -rdynamic export all global symbols to dynamic linker\n" 54 " -soname set name for shared library to be used at runtime\n" 55 " -Wl,-opt[=val] set linker option (see tcc -hh)\n" 56 "Debugger options:\n" 57 " -g generate runtime debug info\n" 58 #ifdef CONFIG_TCC_BCHECK 59 " -b compile with built-in memory and bounds checker (implies -g)\n" 60 #endif 61 #ifdef CONFIG_TCC_BACKTRACE 62 " -bt N show N callers in stack traces\n" 63 #endif 64 "Misc. options:\n" 65 " -x[c|a|n] specify type of the next infile\n" 66 " -nostdinc do not use standard system include paths\n" 67 " -nostdlib do not link with standard crt and libraries\n" 68 " -Bdir set tcc's private include/library dir\n" 69 " -MD generate dependency file for make\n" 70 " -MF file specify dependency file name\n" 71 " -m32/64 defer to i386/x86_64 cross compiler\n" 72 "Tools:\n" 73 " create library : tcc -ar [rcsv] lib.a files\n" 74 #ifdef TCC_TARGET_PE 75 " create def file : tcc -impdef lib.dll [-v] [-o lib.def]\n" 76 #endif 77 ; 78 79 static const char help2[] = 80 "Tiny C Compiler "TCC_VERSION" - More Options\n" 81 "Special options:\n" 82 " -P -P1 with -E: no/alternative #line output\n" 83 " -dD -dM with -E: output #define directives\n" 84 " -pthread same as -D_REENTRANT and -lpthread\n" 85 " -On same as -D__OPTIMIZE__ for n > 0\n" 86 " -Wp,-opt same as -opt\n" 87 " -include file include 'file' above each input file\n" 88 " -isystem dir add 'dir' to system include path\n" 89 " -static link to static libraries (not recommended)\n" 90 " -dumpversion print version\n" 91 " -print-search-dirs print search paths\n" 92 " -dt with -run/-E: auto-define 'test_...' macros\n" 93 "Ignored options:\n" 94 " --param -pedantic -pipe -s -std -traditional\n" 95 "-W... warnings:\n" 96 " all turn on some (*) warnings\n" 97 " error stop after first warning\n" 98 " unsupported warn about ignored options, pragmas, etc.\n" 99 " write-strings strings are const\n" 100 " implicit-function-declaration warn for missing prototype (*)\n" 101 "-f[no-]... flags:\n" 102 " unsigned-char default char is unsigned\n" 103 " signed-char default char is signed\n" 104 " common use common section instead of bss\n" 105 " leading-underscore decorate extern symbols\n" 106 " ms-extensions allow anonymous struct in struct\n" 107 " dollars-in-identifiers allow '$' in C symbols\n" 108 "-m... target specific options:\n" 109 " ms-bitfields use MSVC bitfield layout\n" 110 #ifdef TCC_TARGET_ARM 111 " float-abi hard/softfp on arm\n" 112 #endif 113 #ifdef TCC_TARGET_X86_64 114 " no-sse disable floats on x86_64\n" 115 #endif 116 "-Wl,... linker options:\n" 117 " -nostdlib do not link with standard crt/libs\n" 118 " -[no-]whole-archive load lib(s) fully/only as needed\n" 119 " -export-all-symbols same as -rdynamic\n" 120 " -image-base= -Ttext= set base address of executable\n" 121 " -section-alignment= set section alignment in executable\n" 122 #ifdef TCC_TARGET_PE 123 " -file-alignment= set PE file alignment\n" 124 " -stack= set PE stack reserve\n" 125 " -large-address-aware set related PE option\n" 126 " -subsystem=[console/windows] set PE subsystem\n" 127 " -oformat=[pe-* binary] set executable output format\n" 128 "Predefined macros:\n" 129 " tcc -E -dM - < nul\n" 23 130 #else 24 #include "tcc.h" 25 #endif 26 27 static void help(void) 28 { 29 printf("tcc version " TCC_VERSION " - Tiny C Compiler - Copyright (C) 2001-2006 Fabrice Bellard\n" 30 "Usage: tcc [options...] [-o outfile] [-c] infile(s)...\n" 31 " tcc [options...] -run infile [arguments...]\n" 32 "General options:\n" 33 " -c compile only - generate an object file\n" 34 " -o outfile set output filename\n" 35 " -run run compiled source\n" 36 " -fflag set or reset (with 'no-' prefix) 'flag' (see man page)\n" 37 " -Wwarning set or reset (with 'no-' prefix) 'warning' (see man page)\n" 38 " -w disable all warnings\n" 39 " -v show version\n" 40 " -vv show included files (as sole argument: show search paths)\n" 41 " -dumpversion\n" 42 " -bench show compilation statistics\n" 43 "Preprocessor options:\n" 44 " -E preprocess only\n" 45 " -Idir add include path 'dir'\n" 46 " -Dsym[=val] define 'sym' with value 'val'\n" 47 " -Usym undefine 'sym'\n" 48 "Linker options:\n" 49 " -Ldir add library path 'dir'\n" 50 " -llib link with dynamic or static library 'lib'\n" 51 " -pthread link with -lpthread and -D_REENTRANT (POSIX Linux)\n" 52 " -r generate (relocatable) object file\n" 53 " -rdynamic export all global symbols to dynamic linker\n" 54 " -shared generate a shared library\n" 55 " -soname set name for shared library to be used at runtime\n" 56 " -static static linking\n" 57 " -Wl,-opt[=val] set linker option (see manual)\n" 58 "Debugger options:\n" 59 " -g generate runtime debug info\n" 60 #ifdef CONFIG_TCC_BCHECK 61 " -b compile with built-in memory and bounds checker (implies -g)\n" 62 #endif 63 #ifdef CONFIG_TCC_BACKTRACE 64 " -bt N show N callers in stack traces\n" 65 #endif 66 "Misc options:\n" 67 " -nostdinc do not use standard system include paths\n" 68 " -nostdlib do not link with standard crt and libraries\n" 69 " -Bdir use 'dir' as tcc internal library and include path\n" 70 " -MD generate target dependencies for make\n" 71 " -MF depfile put generated dependencies here\n" 72 ); 73 } 74 75 /* re-execute the i386/x86_64 cross-compilers with tcc -m32/-m64: */ 76 #if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64 77 #ifdef _WIN32 78 #include <process.h> 79 static int execvp_win32(const char *prog, char **argv) 80 { 81 int ret = spawnvp(P_NOWAIT, prog, (char const*const*)argv); 82 if (-1 == ret) 83 return ret; 84 cwait(&ret, ret, WAIT_CHILD); 85 exit(ret); 86 } 87 #define execvp execvp_win32 88 #endif 89 static void exec_other_tcc(TCCState *s, char **argv, const char *optarg) 90 { 91 char child_path[4096], *child_name; const char *target; 92 switch (atoi(optarg)) { 131 " -rpath= set dynamic library search path\n" 132 " -enable-new-dtags set DT_RUNPATH instead of DT_RPATH\n" 133 " -soname= set DT_SONAME elf tag\n" 134 " -Bsymbolic set DT_SYMBOLIC elf tag\n" 135 " -oformat=[elf32/64-* binary] set executable output format\n" 136 " -init= -fini= -as-needed -O (ignored)\n" 137 "Predefined macros:\n" 138 " tcc -E -dM - < /dev/null\n" 139 #endif 140 "See also the manual for more details.\n" 141 ; 142 143 static const char version[] = 144 "tcc version "TCC_VERSION" (" 93 145 #ifdef TCC_TARGET_I386 94 case 32: break; 95 case 64: target = "x86_64"; 146 "i386" 147 #elif defined TCC_TARGET_X86_64 148 "x86_64" 149 #elif defined TCC_TARGET_C67 150 "C67" 151 #elif defined TCC_TARGET_ARM 152 "ARM" 153 #elif defined TCC_TARGET_ARM64 154 "AArch64" 155 #endif 156 #ifdef TCC_ARM_HARDFLOAT 157 " Hard Float" 158 #endif 159 #ifdef TCC_TARGET_PE 160 " Windows" 161 #elif defined(TCC_TARGET_MACHO) 162 " Darwin" 163 #elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) 164 " FreeBSD" 96 165 #else 97 case 64: break; 98 case 32: target = "i386"; 99 #endif 100 pstrcpy(child_path, sizeof child_path - 40, argv[0]); 101 child_name = tcc_basename(child_path); 102 strcpy(child_name, target); 103 #ifdef TCC_TARGET_PE 104 strcat(child_name, "-win32"); 105 #endif 106 strcat(child_name, "-tcc"); 107 if (strcmp(argv[0], child_path)) { 108 if (s->verbose > 0) 109 printf("tcc: using '%s'\n", child_name), fflush(stdout); 110 execvp(argv[0] = child_path, argv); 111 } 112 tcc_error("'%s' not found", child_name); 113 case 0: /* ignore -march etc. */ 114 break; 115 default: 116 tcc_warning("unsupported option \"-m%s\"", optarg); 117 } 118 } 119 #else 120 #define exec_other_tcc(s, argv, optarg) 121 #endif 122 123 static void gen_makedeps(TCCState *s, const char *target, const char *filename) 124 { 125 FILE *depout; 126 char buf[1024], *ext; 166 " Linux" 167 #endif 168 ")\n" 169 ; 170 171 static void print_dirs(const char *msg, char **paths, int nb_paths) 172 { 127 173 int i; 128 129 if (!filename) { 130 /* compute filename automatically 131 * dir/file.o -> dir/file.d */ 132 pstrcpy(buf, sizeof(buf), target); 133 ext = tcc_fileextension(buf); 134 pstrcpy(ext, sizeof(buf) - (ext-buf), ".d"); 135 filename = buf; 136 } 137 138 if (s->verbose) 139 printf("<- %s\n", filename); 140 141 /* XXX return err codes instead of error() ? */ 142 depout = fopen(filename, "w"); 143 if (!depout) 144 tcc_error("could not open '%s'", filename); 145 146 fprintf(depout, "%s : \\\n", target); 147 for (i=0; i<s->nb_target_deps; ++i) 148 fprintf(depout, " %s \\\n", s->target_deps[i]); 149 fprintf(depout, "\n"); 150 fclose(depout); 174 printf("%s:\n%s", msg, nb_paths ? "" : " -\n"); 175 for(i = 0; i < nb_paths; i++) 176 printf(" %s\n", paths[i]); 177 } 178 179 static void print_search_dirs(TCCState *s) 180 { 181 printf("install: %s\n", s->tcc_lib_path); 182 /* print_dirs("programs", NULL, 0); */ 183 print_dirs("include", s->sysinclude_paths, s->nb_sysinclude_paths); 184 print_dirs("libraries", s->library_paths, s->nb_library_paths); 185 printf("libtcc1:\n %s/"TCC_LIBTCC1"\n", s->tcc_lib_path); 186 #ifndef TCC_TARGET_PE 187 print_dirs("crt", s->crt_paths, s->nb_crt_paths); 188 printf("elfinterp:\n %s\n", DEFAULT_ELFINTERP(s)); 189 #endif 190 } 191 192 static void set_environment(TCCState *s) 193 { 194 char * path; 195 196 path = getenv("C_INCLUDE_PATH"); 197 if(path != NULL) { 198 tcc_add_sysinclude_path(s, path); 199 } 200 path = getenv("CPATH"); 201 if(path != NULL) { 202 tcc_add_include_path(s, path); 203 } 204 path = getenv("LIBRARY_PATH"); 205 if(path != NULL) { 206 tcc_add_library_path(s, path); 207 } 151 208 } 152 209 … … 159 216 if (first_file && strcmp(first_file, "-")) 160 217 name = tcc_basename(first_file); 161 pstrcpy(buf, sizeof(buf), name);218 snprintf(buf, sizeof(buf), "%s", name); 162 219 ext = tcc_fileextension(buf); 163 220 #ifdef TCC_TARGET_PE … … 169 226 else 170 227 #endif 171 if (( (s->output_type == TCC_OUTPUT_OBJ && !s->option_r) || 172 (s->output_type == TCC_OUTPUT_PREPROCESS) ) 173 && *ext) 228 if (s->output_type == TCC_OUTPUT_OBJ && !s->option_r && *ext) 174 229 strcpy(ext, ".o"); 175 230 else 176 231 strcpy(buf, "a.out"); 177 178 232 return tcc_strdup(buf); 179 233 } 180 234 181 static void print_paths(const char *msg, char **paths, int nb_paths) 182 { 183 int i; 184 printf("%s:\n%s", msg, nb_paths ? "" : " -\n"); 185 for(i = 0; i < nb_paths; i++) 186 printf(" %s\n", paths[i]); 187 } 188 189 static void display_info(TCCState *s, int what) 190 { 191 switch (what) { 192 case 0: 193 printf("tcc version %s (" 194 #ifdef TCC_TARGET_I386 195 "i386" 196 # ifdef TCC_TARGET_PE 197 " Win32" 198 # endif 199 #elif defined TCC_TARGET_X86_64 200 "x86-64" 201 # ifdef TCC_TARGET_PE 202 " Win64" 203 # endif 204 #elif defined TCC_TARGET_ARM 205 "ARM" 206 # ifdef TCC_ARM_HARDFLOAT 207 " Hard Float" 208 # endif 209 # ifdef TCC_TARGET_PE 210 " WinCE" 211 # endif 212 #endif 213 #ifndef TCC_TARGET_PE 214 # ifdef __linux 215 " Linux" 216 # endif 217 #endif 218 ")\n", TCC_VERSION); 219 break; 220 case 1: 221 printf("install: %s/\n", s->tcc_lib_path); 222 /* print_paths("programs", NULL, 0); */ 223 print_paths("crt", s->crt_paths, s->nb_crt_paths); 224 print_paths("libraries", s->library_paths, s->nb_library_paths); 225 print_paths("include", s->sysinclude_paths, s->nb_sysinclude_paths); 226 printf("elfinterp:\n %s\n", CONFIG_TCC_ELFINTERP); 227 break; 228 } 229 } 230 231 static int64_t getclock_us(void) 232 { 233 #if 0//def _WIN32 234 struct _timeb tb; 235 _ftime(&tb); 236 return (tb.time * 1000LL + tb.millitm) * 1000LL; 235 static unsigned getclock_ms(void) 236 { 237 #ifdef _WIN32 238 return GetTickCount(); 237 239 #else 238 240 struct timeval tv; 239 241 gettimeofday(&tv, NULL); 240 return tv.tv_sec * 1000000LL + tv.tv_usec;241 #endif 242 } 243 244 int tcc_main(int argc , char **argv)242 return tv.tv_sec*1000 + (tv.tv_usec+500)/1000; 243 #endif 244 } 245 246 int tcc_main(int argc0, char **argv0) 245 247 { 246 248 TCCState *s; 247 int ret, optind, i, bench; 248 int64_t start_time = 0; 249 const char *first_file = NULL; 250 249 int ret, opt, n = 0, t = 0; 250 unsigned start_time = 0; 251 const char *first_file; 252 int argc; char **argv; 253 FILE *ppfp = stdout; 254 255 redo: 256 argc = argc0, argv = argv0; 251 257 s = tcc_new(); 252 s->output_type = TCC_OUTPUT_EXE; 253 254 optind = tcc_parse_args(s, argc - 1, argv + 1); 255 256 if (optind == 0) { 257 help(); 258 return 1; 259 } 260 261 if (s->option_m) 262 exec_other_tcc(s, argv, s->option_m); 263 264 if (s->verbose) 265 display_info(s, 0); 266 267 if (s->print_search_dirs || (s->verbose == 2 && optind == 1)) { 268 tcc_set_output_type(s, TCC_OUTPUT_MEMORY); 269 display_info(s, 1); 270 return 0; 271 } 272 273 if (s->verbose && optind == 1) 274 return 0; 275 276 if (s->nb_files == 0) 277 tcc_error("no input files\n"); 278 279 /* check -c consistency : only single file handled. XXX: checks file type */ 280 if (s->output_type == TCC_OUTPUT_OBJ && !s->option_r) { 281 if (s->nb_libraries != 0) 282 tcc_error("cannot specify libraries with -c"); 283 /* accepts only a single input file */ 284 if (s->nb_files != 1) 285 tcc_error("cannot specify multiple files with -c"); 286 } 287 288 if (s->output_type == TCC_OUTPUT_PREPROCESS) { 289 if (!s->outfile) { 290 s->ppfp = stdout; 258 opt = tcc_parse_args(s, &argc, &argv, 1); 259 260 if ((n | t) == 0) { 261 if (opt == OPT_HELP) 262 return printf(help), 1; 263 if (opt == OPT_HELP2) 264 return printf(help2), 1; 265 if (opt == OPT_M32 || opt == OPT_M64) 266 tcc_tool_cross(s, argv, opt); /* never returns */ 267 if (s->verbose) 268 printf(version); 269 if (opt == OPT_AR) 270 return tcc_tool_ar(s, argc, argv); 271 #ifdef TCC_TARGET_PE 272 if (opt == OPT_IMPDEF) 273 return tcc_tool_impdef(s, argc, argv); 274 #endif 275 if (opt == OPT_V) 276 return 0; 277 if (opt == OPT_PRINT_DIRS) { 278 /* initialize search dirs */ 279 set_environment(s); 280 tcc_set_output_type(s, TCC_OUTPUT_MEMORY); 281 print_search_dirs(s); 282 return 0; 283 } 284 285 n = s->nb_files; 286 if (n == 0) 287 tcc_error("no input files\n"); 288 289 if (s->output_type == TCC_OUTPUT_PREPROCESS) { 290 if (s->outfile) { 291 ppfp = fopen(s->outfile, "w"); 292 if (!ppfp) 293 tcc_error("could not write '%s'", s->outfile); 294 } 295 } else if (s->output_type == TCC_OUTPUT_OBJ && !s->option_r) { 296 if (s->nb_libraries) 297 tcc_error("cannot specify libraries with -c"); 298 if (n > 1 && s->outfile) 299 tcc_error("cannot specify output file with -c many files"); 291 300 } else { 292 s->ppfp = fopen(s->outfile, "w"); 293 if (!s->ppfp) 294 tcc_error("could not write '%s'", s->outfile); 301 if (s->option_pthread) 302 tcc_set_options(s, "-lpthread"); 295 303 } 296 } 297 298 bench = s->do_bench; 299 if (bench) 300 start_time = getclock_us(); 301 304 305 if (s->do_bench) 306 start_time = getclock_ms(); 307 } 308 309 set_environment(s); 310 if (s->output_type == 0) 311 s->output_type = TCC_OUTPUT_EXE; 302 312 tcc_set_output_type(s, s->output_type); 313 s->ppfp = ppfp; 314 315 if ((s->output_type == TCC_OUTPUT_MEMORY 316 || s->output_type == TCC_OUTPUT_PREPROCESS) && (s->dflag & 16)) 317 s->dflag |= t ? 32 : 0, s->run_test = ++t, n = s->nb_files; 303 318 304 319 /* compile or add each files or library */ 305 for(i = ret = 0; i < s->nb_files && ret == 0; i++) { 306 const char *filename; 307 308 filename = s->files[i]; 309 if (filename[0] == '-' && filename[1] == 'l') { 310 if (tcc_add_library(s, filename + 2) < 0) { 311 tcc_error_noabort("cannot find '%s'", filename); 320 for (first_file = NULL, ret = 0;;) { 321 struct filespec *f = s->files[s->nb_files - n]; 322 s->filetype = f->type; 323 s->alacarte_link = f->alacarte; 324 if (f->type == AFF_TYPE_LIB) { 325 if (tcc_add_library_err(s, f->name) < 0) 312 326 ret = 1; 313 }314 327 } else { 315 328 if (1 == s->verbose) 316 printf("-> %s\n", filename); 317 if (tcc_add_file(s, filename) < 0) 329 printf("-> %s\n", f->name); 330 if (!first_file) 331 first_file = f->name; 332 if (tcc_add_file(s, f->name) < 0) 318 333 ret = 1; 319 if (!first_file)320 first_file = filename;321 334 } 322 } 323 324 if (0 == ret) { 325 if (bench) 326 tcc_print_stats(s, getclock_us() - start_time); 327 335 s->filetype = 0; 336 s->alacarte_link = 1; 337 if (--n == 0 || ret 338 || (s->output_type == TCC_OUTPUT_OBJ && !s->option_r)) 339 break; 340 } 341 342 if (s->run_test) { 343 t = 0; 344 } else if (s->output_type == TCC_OUTPUT_PREPROCESS) { 345 ; 346 } else if (0 == ret) { 328 347 if (s->output_type == TCC_OUTPUT_MEMORY) { 329 348 #ifdef TCC_IS_NATIVE 330 ret = tcc_run(s, argc - 1 - optind, argv + 1 + optind); 331 #else 332 tcc_error_noabort("-run is not available in a cross compiler"); 333 ret = 1; 334 #endif 335 } else if (s->output_type == TCC_OUTPUT_PREPROCESS) { 336 if (s->outfile) 337 fclose(s->ppfp); 349 ret = tcc_run(s, argc, argv); 350 #endif 338 351 } else { 339 352 if (!s->outfile) 340 353 s->outfile = default_outputfile(s, first_file); 341 ret = !!tcc_output_file(s, s->outfile);342 /* dump collected dependencies */343 if (s->gen_deps && !ret)354 if (tcc_output_file(s, s->outfile)) 355 ret = 1; 356 else if (s->gen_deps) 344 357 gen_makedeps(s, s->outfile, s->deps_outfile); 345 358 } 346 359 } 347 360 361 if (s->do_bench && (n | t | ret) == 0) 362 tcc_print_stats(s, getclock_ms() - start_time); 348 363 tcc_delete(s); 349 if (bench) 350 tcc_memstats(); 364 if (ret == 0 && n) 365 goto redo; /* compile more files with -c */ 366 if (t) 367 goto redo; /* run more tests with -dt -run */ 368 if (ppfp && ppfp != stdout) 369 fclose(ppfp); 351 370 return ret; 352 371 }
Note:
See TracChangeset
for help on using the changeset viewer.