Unified · Split
| @@ -7213,16 +7213,18 @@ void help(void) · 7212 unmodified lines | ||
| 7213 | 7213 | " -llib link with dynamic or static library 'lib'\n" |
| 7214 | 7214 | " -shared generate a shared library\n" |
| 7215 | 7215 | " -static static linking\n" |
| 7216 | + " -r relocatable output\n" | |
| 7216 | 7217 | ); |
| 7217 | 7218 | } |
| 7218 | 7219 | |
| 7219 | 7220 | int main(int argc, char **argv) |
| 7220 | 7221 | { |
| 7221 | 7222 | char *r, *outfile; |
| 7222 | − int optind, output_type, multiple_files, i; | |
| 7223 | + int optind, output_type, multiple_files, i, reloc_output; | |
| 7223 | 7224 | TCCState *s; |
| 7224 | − char **libraries; | |
| 7225 | − int nb_libraries; | |
| 7225 | + char **files; | |
| 7226 | + int nb_files, nb_libraries, nb_objfiles; | |
| 7227 | + char objfilename[1024]; | |
| 7226 | 7228 | |
| 7227 | 7229 | s = tcc_new(); |
| 7228 | 7230 | output_type = TCC_OUTPUT_MEMORY; |
| @@ -7230,23 +7232,37 @@ int main(int argc, char **argv) · 1 unmodified line | ||
| 7230 | 7232 | optind = 1; |
| 7231 | 7233 | outfile = NULL; |
| 7232 | 7234 | multiple_files = 0; |
| 7233 | − libraries = NULL; | |
| 7235 | + files = NULL; | |
| 7236 | + nb_files = 0; | |
| 7234 | 7237 | nb_libraries = 0; |
| 7238 | + reloc_output = 0; | |
| 7235 | 7239 | while (1) { |
| 7236 | 7240 | if (optind >= argc) { |
| 7237 | − show_help: | |
| 7238 | − help(); | |
| 7239 | − return 1; | |
| 7241 | + if (nb_files == 0) | |
| 7242 | + goto show_help; | |
| 7243 | + else | |
| 7244 | + break; | |
| 7240 | 7245 | } |
| 7241 | − r = argv[optind]; | |
| 7242 | − if (r[0] != '-') | |
| 7243 | − break; | |
| 7244 | − optind++; | |
| 7245 | − if (r[1] == '-') { | |
| 7246 | − /* '--' enables multiple files input */ | |
| 7246 | + r = argv[optind++]; | |
| 7247 | + if (r[0] != '-') { | |
| 7248 | + /* add a new file */ | |
| 7249 | + dynarray_add((void ***)&files, &nb_files, r); | |
| 7250 | + if (!multiple_files) { | |
| 7251 | + optind--; | |
| 7252 | + /* argv[0] will be this file */ | |
| 7253 | + break; | |
| 7254 | + } | |
| 7255 | + } else if (r[1] == '-') { | |
| 7256 | + /* '--' enables multiple files input and also ends several file input */ | |
| 7257 | + if (multiple_files) { | |
| 7258 | + optind--; /* argv[0] will be '--' */ | |
| 7259 | + break; | |
| 7260 | + } | |
| 7247 | 7261 | multiple_files = 1; |
| 7248 | 7262 | } else if (r[1] == 'h' || r[1] == '?') { |
| 7249 | − goto show_help; | |
| 7263 | + show_help: | |
| 7264 | + help(); | |
| 7265 | + return 1; | |
| 7250 | 7266 | } else if (r[1] == 'I') { |
| 7251 | 7267 | if (tcc_add_include_path(s, r + 2) < 0) |
| 7252 | 7268 | error("too many include paths"); |
| @@ -7267,7 +7283,8 @@ int main(int argc, char **argv) · 14 unmodified lines | ||
| 7267 | 7283 | /* set tcc utilities path (mainly for tcc development) */ |
| 7268 | 7284 | tcc_lib_path = r + 2; |
| 7269 | 7285 | } else if (r[1] == 'l') { |
| 7270 | − dynarray_add((void ***)&libraries, &nb_libraries, r + 2); | |
| 7286 | + dynarray_add((void ***)&files, &nb_files, r); | |
| 7287 | + nb_libraries++; | |
| 7271 | 7288 | } else if (!strcmp(r + 1, "bench")) { |
| 7272 | 7289 | do_bench = 1; |
| 7273 | 7290 | } else |
| @@ -7291,36 +7308,61 @@ int main(int argc, char **argv) · 17 unmodified lines | ||
| 7291 | 7308 | goto show_help; |
| 7292 | 7309 | multiple_files = 1; |
| 7293 | 7310 | outfile = argv[optind++]; |
| 7311 | + } else if (r[1] == 'r') { | |
| 7312 | + /* generate a .o merging several output files */ | |
| 7313 | + reloc_output = 1; | |
| 7314 | + output_type = TCC_OUTPUT_OBJ; | |
| 7294 | 7315 | } else { |
| 7295 | 7316 | error("invalid option -- '%s'", r); |
| 7296 | 7317 | } |
| 7297 | 7318 | } |
| 7298 | 7319 | |
| 7320 | + nb_objfiles = nb_files - nb_libraries; | |
| 7321 | + | |
| 7299 | 7322 | /* if outfile provided without other options, we output an |
| 7300 | 7323 | executable */ |
| 7301 | 7324 | if (outfile && output_type == TCC_OUTPUT_MEMORY) |
| 7302 | 7325 | output_type = TCC_OUTPUT_EXE; |
| 7303 | − | |
| 7304 | − tcc_set_output_type(s, output_type); | |
| 7305 | 7326 | |
| 7306 | − tcc_add_file(s, argv[optind]); | |
| 7307 | − if (multiple_files) { | |
| 7308 | − while ((optind + 1) < argc) { | |
| 7309 | − optind++; | |
| 7310 | − r = argv[optind]; | |
| 7311 | − if (r[0] == '-') { | |
| 7312 | − if (r[1] != '-') | |
| 7313 | − error("'--' expected"); | |
| 7314 | − break; | |
| 7315 | − } | |
| 7316 | − tcc_add_file(s, r); | |
| 7327 | + /* check -c consistency : only single file handled. XXX: checks file type */ | |
| 7328 | + if (output_type == TCC_OUTPUT_OBJ && !reloc_output) { | |
| 7329 | + /* accepts only a single input file */ | |
| 7330 | + if (nb_objfiles != 1) | |
| 7331 | + error("cannot specify multiple files with -c"); | |
| 7332 | + if (nb_libraries != 0) | |
| 7333 | + error("cannot specify libraries with -c"); | |
| 7334 | + } | |
| 7335 | + | |
| 7336 | + /* compute default outfile name */ | |
| 7337 | + if (output_type != TCC_OUTPUT_MEMORY && !outfile) { | |
| 7338 | + if (output_type == TCC_OUTPUT_OBJ && !reloc_output) { | |
| 7339 | + char *ext; | |
| 7340 | + /* add .o extension */ | |
| 7341 | + pstrcpy(objfilename, sizeof(objfilename) - 1, files[0]); | |
| 7342 | + ext = strrchr(objfilename, '.'); | |
| 7343 | + if (!ext) | |
| 7344 | + goto default_outfile; | |
| 7345 | + strcpy(ext + 1, "o"); | |
| 7346 | + } else { | |
| 7347 | + default_outfile: | |
| 7348 | + pstrcpy(objfilename, sizeof(objfilename), "a.out"); | |
| 7317 | 7349 | } |
| 7350 | + outfile = objfilename; | |
| 7318 | 7351 | } |
| 7319 | 7352 | |
| 7320 | − /* add specified libraries */ | |
| 7321 | − for(i = 0; i < nb_libraries;i++) { | |
| 7322 | − if (tcc_add_library(s, libraries[i]) < 0) | |
| 7323 | − error("cannot find -l%s", libraries[i]); | |
| 7353 | + tcc_set_output_type(s, output_type); | |
| 7354 | + | |
| 7355 | + /* compile or add each files or library */ | |
| 7356 | + for(i = 0;i < nb_files; i++) { | |
| 7357 | + const char *filename; | |
| 7358 | + | |
| 7359 | + filename = files[i]; | |
| 7360 | + if (filename[0] == '-') { | |
| 7361 | + if (tcc_add_library(s, filename + 2) < 0) | |
| 7362 | + error("cannot find %s", filename); | |
| 7363 | + } else { | |
| 7364 | + tcc_add_file(s, filename); | |
| 7365 | + } | |
| 7324 | 7366 | } |
| 7325 | 7367 | |
| 7326 | 7368 | if (do_bench) { |