aboutsummaryrefslogtreecommitdiff
path: root/tcc.c
diff options
context:
space:
mode:
Diffstat (limited to 'tcc.c')
-rw-r--r--tcc.c106
1 files changed, 74 insertions, 32 deletions
diff --git a/tcc.c b/tcc.c
index 1babd27..ca7ad15 100644
--- a/tcc.c
+++ b/tcc.c
@@ -7213,16 +7213,18 @@ void help(void)
" -llib link with dynamic or static library 'lib'\n"
" -shared generate a shared library\n"
" -static static linking\n"
+ " -r relocatable output\n"
);
}
int main(int argc, char **argv)
{
char *r, *outfile;
- int optind, output_type, multiple_files, i;
+ int optind, output_type, multiple_files, i, reloc_output;
TCCState *s;
- char **libraries;
- int nb_libraries;
+ char **files;
+ int nb_files, nb_libraries, nb_objfiles;
+ char objfilename[1024];
s = tcc_new();
output_type = TCC_OUTPUT_MEMORY;
@@ -7230,23 +7232,37 @@ int main(int argc, char **argv)
optind = 1;
outfile = NULL;
multiple_files = 0;
- libraries = NULL;
+ files = NULL;
+ nb_files = 0;
nb_libraries = 0;
+ reloc_output = 0;
while (1) {
if (optind >= argc) {
- show_help:
- help();
- return 1;
+ if (nb_files == 0)
+ goto show_help;
+ else
+ break;
}
- r = argv[optind];
- if (r[0] != '-')
- break;
- optind++;
- if (r[1] == '-') {
- /* '--' enables multiple files input */
+ r = argv[optind++];
+ if (r[0] != '-') {
+ /* add a new file */
+ dynarray_add((void ***)&files, &nb_files, r);
+ if (!multiple_files) {
+ optind--;
+ /* argv[0] will be this file */
+ break;
+ }
+ } else if (r[1] == '-') {
+ /* '--' enables multiple files input and also ends several file input */
+ if (multiple_files) {
+ optind--; /* argv[0] will be '--' */
+ break;
+ }
multiple_files = 1;
} else if (r[1] == 'h' || r[1] == '?') {
- goto show_help;
+ show_help:
+ help();
+ return 1;
} else if (r[1] == 'I') {
if (tcc_add_include_path(s, r + 2) < 0)
error("too many include paths");
@@ -7267,7 +7283,8 @@ int main(int argc, char **argv)
/* set tcc utilities path (mainly for tcc development) */
tcc_lib_path = r + 2;
} else if (r[1] == 'l') {
- dynarray_add((void ***)&libraries, &nb_libraries, r + 2);
+ dynarray_add((void ***)&files, &nb_files, r);
+ nb_libraries++;
} else if (!strcmp(r + 1, "bench")) {
do_bench = 1;
} else
@@ -7291,36 +7308,61 @@ int main(int argc, char **argv)
goto show_help;
multiple_files = 1;
outfile = argv[optind++];
+ } else if (r[1] == 'r') {
+ /* generate a .o merging several output files */
+ reloc_output = 1;
+ output_type = TCC_OUTPUT_OBJ;
} else {
error("invalid option -- '%s'", r);
}
}
+ nb_objfiles = nb_files - nb_libraries;
+
/* if outfile provided without other options, we output an
executable */
if (outfile && output_type == TCC_OUTPUT_MEMORY)
output_type = TCC_OUTPUT_EXE;
-
- tcc_set_output_type(s, output_type);
- tcc_add_file(s, argv[optind]);
- if (multiple_files) {
- while ((optind + 1) < argc) {
- optind++;
- r = argv[optind];
- if (r[0] == '-') {
- if (r[1] != '-')
- error("'--' expected");
- break;
- }
- tcc_add_file(s, r);
+ /* check -c consistency : only single file handled. XXX: checks file type */
+ if (output_type == TCC_OUTPUT_OBJ && !reloc_output) {
+ /* accepts only a single input file */
+ if (nb_objfiles != 1)
+ error("cannot specify multiple files with -c");
+ if (nb_libraries != 0)
+ error("cannot specify libraries with -c");
+ }
+
+ /* compute default outfile name */
+ if (output_type != TCC_OUTPUT_MEMORY && !outfile) {
+ if (output_type == TCC_OUTPUT_OBJ && !reloc_output) {
+ char *ext;
+ /* add .o extension */
+ pstrcpy(objfilename, sizeof(objfilename) - 1, files[0]);
+ ext = strrchr(objfilename, '.');
+ if (!ext)
+ goto default_outfile;
+ strcpy(ext + 1, "o");
+ } else {
+ default_outfile:
+ pstrcpy(objfilename, sizeof(objfilename), "a.out");
}
+ outfile = objfilename;
}
- /* add specified libraries */
- for(i = 0; i < nb_libraries;i++) {
- if (tcc_add_library(s, libraries[i]) < 0)
- error("cannot find -l%s", libraries[i]);
+ tcc_set_output_type(s, output_type);
+
+ /* compile or add each files or library */
+ for(i = 0;i < nb_files; i++) {
+ const char *filename;
+
+ filename = files[i];
+ if (filename[0] == '-') {
+ if (tcc_add_library(s, filename + 2) < 0)
+ error("cannot find %s", filename);
+ } else {
+ tcc_add_file(s, filename);
+ }
}
if (do_bench) {