2 * TCC - Tiny C Compiler
4 * Copyright (c) 2001-2004 Fabrice Bellard
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
28 static void help(void)
30 printf("Tiny C Compiler "TCC_VERSION
" - Copyright (C) 2001-2006 Fabrice Bellard\n"
31 "Usage: tcc [options...] [-o outfile] [-c] infile(s)...\n"
32 " tcc [options...] -run infile [arguments...]\n"
34 " -c compile only - generate an object file\n"
35 " -o outfile set output filename\n"
36 " -run run compiled source\n"
37 " -fflag set or reset (with 'no-' prefix) 'flag' (see man page)\n"
38 " -Wwarning set or reset (with 'no-' prefix) 'warning' (see man page)\n"
39 " -w disable all warnings\n"
41 " -vv show included files (as sole argument show search paths)\n"
42 " -h show this help\n"
43 " -bench show compilation statistics\n"
44 "Preprocessor options:\n"
45 " -Idir add include path 'dir'\n"
46 " -Dsym[=val] define 'sym' with value 'val'\n"
47 " -Usym undefine 'sym'\n"
48 " -E preprocess only\n"
49 " -P[1] no / alternative #line output with -E\n"
50 " -dD -dM output #define directives with -E\n"
51 " -include file include file above each input file\n"
53 " -Ldir add library path 'dir'\n"
54 " -llib link with dynamic or static library 'lib'\n"
55 " -r generate (relocatable) object file\n"
56 " -shared generate a shared library\n"
57 " -rdynamic export all global symbols to dynamic linker\n"
58 " -soname set name for shared library to be used at runtime\n"
59 " -static static linking\n"
60 " -pthread link with -lpthread and -D_REENTRANT (POSIX Linux)\n"
61 " -Wl,-opt[=val] set linker option (see manual)\n"
63 " -g generate runtime debug info\n"
64 #ifdef CONFIG_TCC_BCHECK
65 " -b compile with built-in memory and bounds checker (implies -g)\n"
67 #ifdef CONFIG_TCC_BACKTRACE
68 " -bt N show N callers in stack traces\n"
71 " -x[c|a|n] specify type of the next infile\n"
72 " -nostdinc do not use standard system include paths\n"
73 " -nostdlib do not link with standard crt and libraries\n"
74 " -Bdir use 'dir' as tcc's private library/include path\n"
75 " -MD generate target dependencies for make\n"
76 " -MF depfile put generated dependencies here\n"
77 " -dumpversion print version\n"
78 " - use stdin pipe as infile\n"
79 " @listfile read arguments from listfile\n"
80 "Target specific options:\n"
81 " -m32/64 execute i386/x86-64 cross compiler\n"
82 " -mms-bitfields use MSVC bitfield layout\n"
84 " -mfloat-abi hard/softfp on arm\n"
86 #ifdef TCC_TARGET_X86_64
87 " -mno-sse disable floats on x86-64\n"
90 " create library : tcc -ar [rcsv] lib.a files\n"
92 " create .def file : tcc -impdef lib.dll [-v] [-o lib.def]\n"
98 static void version(void)
100 printf("tcc version %s ("
101 #ifdef TCC_TARGET_I386
103 #elif defined TCC_TARGET_X86_64
105 #elif defined TCC_TARGET_C67
107 #elif defined TCC_TARGET_ARM
109 # ifdef TCC_ARM_HARDFLOAT
112 #elif defined TCC_TARGET_ARM64
114 # ifdef TCC_ARM_HARDFLOAT
120 #elif defined(__APPLE__)
121 /* Current Apple OS name as of 2016 */
123 #elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
125 #elif defined(__DragonFly__)
127 #elif defined(__NetBSD__)
129 #elif defined(__OpenBSD__)
131 #elif defined(__linux__)
134 " Unidentified system"
139 static void print_dirs(const char *msg
, char **paths
, int nb_paths
)
142 printf("%s:\n%s", msg
, nb_paths
? "" : " -\n");
143 for(i
= 0; i
< nb_paths
; i
++)
144 printf(" %s\n", paths
[i
]);
147 static void print_search_dirs(TCCState
*s
)
149 printf("install: %s\n", s
->tcc_lib_path
);
150 /* print_dirs("programs", NULL, 0); */
151 print_dirs("include", s
->sysinclude_paths
, s
->nb_sysinclude_paths
);
152 print_dirs("libraries", s
->library_paths
, s
->nb_library_paths
);
153 #ifndef TCC_TARGET_PE
154 print_dirs("crt", s
->crt_paths
, s
->nb_crt_paths
);
155 printf("elfinterp:\n %s\n", DEFAULT_ELFINTERP(s
));
159 static char *default_outputfile(TCCState
*s
, const char *first_file
)
163 const char *name
= "a";
165 if (first_file
&& strcmp(first_file
, "-"))
166 name
= tcc_basename(first_file
);
167 snprintf(buf
, sizeof(buf
), "%s", name
);
168 ext
= tcc_fileextension(buf
);
170 if (s
->output_type
== TCC_OUTPUT_DLL
)
173 if (s
->output_type
== TCC_OUTPUT_EXE
)
177 if (s
->output_type
== TCC_OUTPUT_OBJ
&& !s
->option_r
&& *ext
)
180 strcpy(buf
, "a.out");
181 return tcc_strdup(buf
);
184 static unsigned getclock_ms(void)
187 return GetTickCount();
190 gettimeofday(&tv
, NULL
);
191 return tv
.tv_sec
*1000 + (tv
.tv_usec
+500)/1000;
195 int main(int argc
, char **argv
)
199 unsigned start_time
= 0;
200 const char *first_file
;
204 opt
= tcc_parse_args(s
, &argc
, &argv
, 1);
209 if (opt
== OPT_M32
|| opt
== OPT_M64
)
210 tcc_tool_cross(s
, argv
, opt
); /* never returns */
214 return tcc_tool_ar(s
, argc
, argv
);
216 if (opt
== OPT_IMPDEF
)
217 return tcc_tool_impdef(s
, argc
, argv
);
222 tcc_set_environment(s
);
224 if (opt
== OPT_PRINT_DIRS
) {
225 /* initialize search dirs */
226 tcc_set_output_type(s
, TCC_OUTPUT_MEMORY
);
227 print_search_dirs(s
);
233 tcc_error("no input files\n");
235 if (s
->output_type
== TCC_OUTPUT_PREPROCESS
) {
239 s
->ppfp
= fopen(s
->outfile
, "w");
241 tcc_error("could not write '%s'", s
->outfile
);
243 } else if (s
->output_type
== TCC_OUTPUT_OBJ
) {
244 if (s
->nb_libraries
!= 0 && !s
->option_r
)
245 tcc_error("cannot specify libraries with -c");
246 if (n
> 1 && s
->outfile
)
247 tcc_error("cannot specify output file with -c many files");
249 if (s
->option_pthread
)
250 tcc_set_options(s
, "-lpthread");
254 start_time
= getclock_ms();
257 if (s
->output_type
== 0)
258 s
->output_type
= TCC_OUTPUT_EXE
;
259 tcc_set_output_type(s
, s
->output_type
);
261 /* compile or add each files or library */
262 for (first_file
= NULL
, ret
= 0;;) {
263 struct filespec
*f
= s
->files
[s
->nb_files
- n
];
264 s
->filetype
= f
->type
;
265 s
->alacarte_link
= f
->alacarte
;
266 if (f
->type
== AFF_TYPE_LIB
) {
267 if (tcc_add_library_err(s
, f
->name
) < 0)
271 printf("-> %s\n", f
->name
);
273 first_file
= f
->name
;
274 if (tcc_add_file(s
, f
->name
) < 0)
278 s
->alacarte_link
= 1;
279 if (ret
|| --n
== 0 || s
->output_type
== TCC_OUTPUT_OBJ
)
283 if (s
->output_type
== TCC_OUTPUT_PREPROCESS
) {
286 } else if (0 == ret
) {
287 if (s
->output_type
== TCC_OUTPUT_MEMORY
) {
289 ret
= tcc_run(s
, argc
, argv
);
293 s
->outfile
= default_outputfile(s
, first_file
);
294 if (tcc_output_file(s
, s
->outfile
))
296 else if (s
->gen_deps
)
297 gen_makedeps(s
, s
->outfile
, s
->deps_outfile
);
301 if (s
->do_bench
&& ret
== 0 && n
== 0)
302 tcc_print_stats(s
, getclock_ms() - start_time
);
305 goto redo
; /* compile more files with -c */