From de7a214c173c75eba273e6cfaefa2ec8a3bc9c57 Mon Sep 17 00:00:00 2001 From: Kirill Smelkov Date: Sat, 12 Jun 2010 18:18:19 +0400 Subject: [PATCH 01/11] .cvsignore -> .gitignore We no longer use CVS, so let's teach Git about what files to ignore... ... though doing `git status` after make + `make test` still gives untracked content: # Untracked files: # (use "git add ..." to include in what will be committed) # # alloca86-bt.o # alloca86.o # bcheck.o # libtcc.a # libtcc.o # libtcc1.a # libtcc1.o # tcc.o See next patch about this stuff. --- .cvsignore => .gitignore | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename .cvsignore => .gitignore (100%) diff --git a/.cvsignore b/.gitignore similarity index 100% rename from .cvsignore rename to .gitignore From 5344b2e73bd2bdb6f5b72cf909a6ddb59232645e Mon Sep 17 00:00:00 2001 From: Kirill Smelkov Date: Sat, 12 Jun 2010 18:26:37 +0400 Subject: [PATCH 02/11] .gitignore += *.o *.a Ignores libtcc.o, libtcc.a and a bunch of other files (see previous patch for details) --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index 95daa1f3..df16ed9d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,5 @@ +*.o +*.a tcc_g tcc tc2.c From 87db8b637e3f8a3088f0af1e82fffb0a467afbb4 Mon Sep 17 00:00:00 2001 From: Kirill Smelkov Date: Wed, 16 Jun 2010 14:37:08 +0400 Subject: [PATCH 03/11] chmod a-x i386-gen.c No need to keep executable bit on plain C source. --- i386-gen.c | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100755 => 100644 i386-gen.c diff --git a/i386-gen.c b/i386-gen.c old mode 100755 new mode 100644 From 66b54af8ea8a2277e5d6b8a0c1661d42fea4a639 Mon Sep 17 00:00:00 2001 From: Kirill Smelkov Date: Wed, 16 Jun 2010 16:51:55 +0400 Subject: [PATCH 04/11] tcc: Fix typo in error (it's '%s', not '%s) --- tcc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tcc.c b/tcc.c index d0ed8f60..759151a5 100644 --- a/tcc.c +++ b/tcc.c @@ -444,7 +444,7 @@ int main(int argc, char **argv) } else { s->outfile = fopen(outfile, "w"); if (!s->outfile) - error("could not open '%s", outfile); + error("could not open '%s'", outfile); } } else if (output_type != TCC_OUTPUT_MEMORY) { if (!outfile) { From a919a373da07305e763d1cb4ecb3a5a44bdebb2a Mon Sep 17 00:00:00 2001 From: Kirill Smelkov Date: Sun, 20 Jun 2010 19:49:58 +0400 Subject: [PATCH 05/11] Add input files/libs and reloc_output switch to TCCState files[0], and reloc_outpu will be needed for (upcoming in the next patch) "compute default outfile name" refactored into libtcc function. Also, since for symmetry and from libification point of view, it makes some sense to also put all information about what was given as input to compilation into TCCState, let's not only put files[0], but all files and all libraries given explicitely by user. One point: I've used bitfield for reloc_output & trimmed down output_type to 8 bits so that TCCState stays the same in size, and also access to output_type is (hopefully) is not slower. By the way -- as of today, sizeof(TCCState) on i686-pc-linux-gnu is 2884 bytes... --- libtcc.c | 8 ++++++++ libtcc.h | 7 +++++++ tcc.c | 1 + tcc.h | 9 ++++++++- 4 files changed, 24 insertions(+), 1 deletion(-) diff --git a/libtcc.c b/libtcc.c index f0da4deb..9cc1b6f9 100644 --- a/libtcc.c +++ b/libtcc.c @@ -1038,6 +1038,10 @@ LIBTCCAPI void tcc_delete(TCCState *s1) dynarray_reset(&s1->sysinclude_paths, &s1->nb_sysinclude_paths); tcc_free(s1->tcc_lib_path); + + dynarray_reset(&s1->input_files, &s1->nb_input_files); + dynarray_reset(&s1->input_libs, &s1->nb_input_libs); + #ifdef HAVE_SELINUX munmap (s1->write_mem, s1->mem_size); munmap (s1->runtime_mem, s1->mem_size); @@ -1184,6 +1188,8 @@ the_end: LIBTCCAPI int tcc_add_file(TCCState *s, const char *filename) { + dynarray_add((void ***)&s->input_files, &s->nb_input_files, tcc_strdup(filename)); + if (s->output_type == TCC_OUTPUT_PREPROCESS) return tcc_add_file_internal(s, filename, AFF_PRINT_ERROR | AFF_PREPROCESS); else @@ -1220,6 +1226,8 @@ LIBTCCAPI int tcc_add_library(TCCState *s, const char *libraryname) { char buf[1024]; int i; + + dynarray_add((void ***)&s->input_libs, &s->nb_input_libs, tcc_strdup(libraryname)); /* first we look for the dynamic library if not static linking */ if (!s->static_link) { diff --git a/libtcc.h b/libtcc.h index 339dec17..13efcd2f 100644 --- a/libtcc.h +++ b/libtcc.h @@ -103,6 +103,13 @@ LIBTCCAPI void *tcc_get_symbol(TCCState *s, const char *name); /* set CONFIG_TCCDIR at runtime */ LIBTCCAPI void tcc_set_lib_path(TCCState *s, const char *path); + +/*****************************/ +/* Miscellaneous */ + +/* Get default target filename for this compilation */ +LIBTCCAPI const char *tcc_default_target(TCCState *s); + #ifdef __cplusplus } #endif diff --git a/tcc.c b/tcc.c index 759151a5..f973972f 100644 --- a/tcc.c +++ b/tcc.c @@ -475,6 +475,7 @@ int main(int argc, char **argv) } tcc_set_output_type(s, output_type); + s->reloc_output = reloc_output; /* compile or add each files or library */ for(i = 0; i < nb_files && ret == 0; i++) { diff --git a/tcc.h b/tcc.h index 29953a6f..8fd44084 100644 --- a/tcc.h +++ b/tcc.h @@ -397,7 +397,8 @@ typedef struct ASMOperand { #endif struct TCCState { - int output_type; + unsigned output_type : 8; + unsigned reloc_output : 1; BufferedFile **include_stack_ptr; int *ifdef_stack_ptr; @@ -518,6 +519,12 @@ struct TCCState { /* output file for preprocessing */ FILE *outfile; + /* input files and libraries for this compilation */ + char **input_files; + int nb_input_files; + char **input_libs; + int nb_input_libs; + /* for tcc_relocate */ int runtime_added; void *runtime_mem; From bdae4a59c3a74b2ff464c02029c625251719a7d7 Mon Sep 17 00:00:00 2001 From: Kirill Smelkov Date: Wed, 16 Jun 2010 16:54:24 +0400 Subject: [PATCH 06/11] tcc: Refactor "compute default outfile name" into libtcc function Since for upcoming -MD support default _compile_ output file be needed even when preprocesssing (tcc -E), let's move this code out of one particular condition block into a common function, so that we could use it in deps generation code too. v2: - As suggested by grischka, moved into libtcc function instead of always computing near start of main() - There is a FIXME about how to return result - I don't want to bother callers with allocating temp buffers, not I think it will be a good idea to hook default_target to TCCState. Clearly, I'm to used to things like std::string and python's str... --- libtcc.c | 28 ++++++++++++++++++++++++++++ tcc.c | 29 ++++------------------------- 2 files changed, 32 insertions(+), 25 deletions(-) diff --git a/libtcc.c b/libtcc.c index 9cc1b6f9..1c963b52 100644 --- a/libtcc.c +++ b/libtcc.c @@ -1557,3 +1557,31 @@ PUB_FUNC void set_num_callers(int n) num_callers = n; #endif } + + +LIBTCCAPI const char *tcc_default_target(TCCState *s) +{ + /* FIXME will break in multithreaded case */ + static char outfile_default[1024]; + + char *ext; + const char *name = + strcmp(s->input_files[0], "-") == 0 ? "a" + : tcc_basename(s->input_files[0]); + pstrcpy(outfile_default, sizeof(outfile_default), name); + ext = tcc_fileextension(outfile_default); +#ifdef TCC_TARGET_PE + if (s->output_type == TCC_OUTPUT_DLL) + strcpy(ext, ".dll"); + else + if (s->output_type == TCC_OUTPUT_EXE) + strcpy(ext, ".exe"); + else +#endif + if (s->output_type == TCC_OUTPUT_OBJ && !s->reloc_output && *ext) + strcpy(ext, ".o"); + else + pstrcpy(outfile_default, sizeof(outfile_default), "a.out"); + + return outfile_default; +} diff --git a/tcc.c b/tcc.c index f973972f..705f5e21 100644 --- a/tcc.c +++ b/tcc.c @@ -393,7 +393,6 @@ int main(int argc, char **argv) int i; TCCState *s; int nb_objfiles, ret, optind; - char objfilename[1024]; int64_t start_time = 0; s = tcc_new(); @@ -446,28 +445,6 @@ int main(int argc, char **argv) if (!s->outfile) error("could not open '%s'", outfile); } - } else if (output_type != TCC_OUTPUT_MEMORY) { - if (!outfile) { - /* compute default outfile name */ - char *ext; - const char *name = - strcmp(files[0], "-") == 0 ? "a" : tcc_basename(files[0]); - pstrcpy(objfilename, sizeof(objfilename), name); - ext = tcc_fileextension(objfilename); -#ifdef TCC_TARGET_PE - if (output_type == TCC_OUTPUT_DLL) - strcpy(ext, ".dll"); - else - if (output_type == TCC_OUTPUT_EXE) - strcpy(ext, ".exe"); - else -#endif - if (output_type == TCC_OUTPUT_OBJ && !reloc_output && *ext) - strcpy(ext, ".o"); - else - pstrcpy(objfilename, sizeof(objfilename), "a.out"); - outfile = objfilename; - } } if (do_bench) { @@ -507,8 +484,10 @@ int main(int argc, char **argv) fclose(s->outfile); } else if (s->output_type == TCC_OUTPUT_MEMORY) ret = tcc_run(s, argc - optind, argv + optind); - else - ret = tcc_output_file(s, outfile) ? 1 : 0; + else { + ret = tcc_output_file(s, outfile ? outfile : tcc_default_target(s)); + ret = ret ? 1 : 0; + } } tcc_delete(s); From 0c928da96d5fb8fe8f929db40b2d807053113f35 Mon Sep 17 00:00:00 2001 From: Kirill Smelkov Date: Sun, 20 Jun 2010 20:08:12 +0400 Subject: [PATCH 07/11] tcc: Draft suppoprt for -MD/-MF options In build systems, this is used to automatically collect target dependencies, e.g. ---- 8< (hello.c) ---- #include "hello.h" #include int main() { printf("Hello World!\n"); return 0; } $ tcc -MD -c hello.c # -> hello.o, hello.d $ cat hello.d hello.o : \ hello.c \ hello.h \ /usr/include/stdio.h \ /usr/include/features.h \ /usr/include/bits/predefs.h \ /usr/include/sys/cdefs.h \ /usr/include/bits/wordsize.h \ /usr/include/gnu/stubs.h \ /usr/include/bits/wordsize.h \ /usr/include/gnu/stubs-32.h \ /home/kirr/local/tcc/lib/tcc/include/stddef.h \ /usr/include/bits/types.h \ /usr/include/bits/wordsize.h \ /usr/include/bits/typesizes.h \ /usr/include/libio.h \ /usr/include/_G_config.h \ /usr/include/wchar.h \ /home/kirr/local/tcc/lib/tcc/include/stdarg.h \ /usr/include/bits/stdio_lim.h \ /usr/include/bits/sys_errlist.h \ NOTE: gcc supports -MD only for .c -> .o, but in tcc, we generate dependencies for whatever action is being taken. E.g. for .c -> exe, the result will be: $ tcc -MD -o hello hello.c # -> hello, hello.d hello: \ /usr/lib/crt1.o \ /usr/lib/crti.o \ hello.c \ hello.h \ /usr/include/stdio.h \ /usr/include/features.h \ /usr/include/bits/predefs.h \ /usr/include/sys/cdefs.h \ /usr/include/bits/wordsize.h \ /usr/include/gnu/stubs.h \ /usr/include/bits/wordsize.h \ /usr/include/gnu/stubs-32.h \ /home/kirr/local/tcc/lib/tcc/include/stddef.h \ /usr/include/bits/types.h \ /usr/include/bits/wordsize.h \ /usr/include/bits/typesizes.h \ /usr/include/libio.h \ /usr/include/_G_config.h \ /usr/include/wchar.h \ /home/kirr/local/tcc/lib/tcc/include/stdarg.h \ /usr/include/bits/stdio_lim.h \ /usr/include/bits/sys_errlist.h \ /usr/lib/libc.so \ /lib/libc.so.6 \ /usr/lib/ld-linux.so.2 \ /lib/ld-linux.so.2 \ /usr/lib/libc_nonshared.a \ /lib/libc.so.6 \ /usr/lib/libc_nonshared.a \ /home/kirr/local/tcc/lib/tcc/libtcc1.a \ /usr/lib/crtn.o \ So tcc dependency generator is a bit more clever than one used in gcc :) Also, I've updated TODO and Changelog (in not-yet-released section). v2: (Taking inputs from grischka and me myself) - put code to generate deps file into a function. - used tcc_fileextension() instead of open-coding - generate deps only when compilation/preprocessing was successful v3: - use pstrcpy instead of snprintf(buf, sizeof(buf), "%s", ...) --- Changelog | 4 ++++ TODO | 1 - libtcc.c | 39 +++++++++++++++++++++++++++++++++++++++ libtcc.h | 7 +++++++ tcc.c | 33 +++++++++++++++++++++++++++------ tcc.h | 4 ++++ tccpp.c | 3 +++ 7 files changed, 84 insertions(+), 7 deletions(-) diff --git a/Changelog b/Changelog index b2710546..528d9275 100644 --- a/Changelog +++ b/Changelog @@ -1,3 +1,7 @@ +not released: + +- Add support for -MD/-MF (automatically generate dependencies for make) + version 0.9.25: - first support for x86-64 target (Shinichiro Hamaji) diff --git a/TODO b/TODO index 6f49c5d5..9d19153d 100644 --- a/TODO +++ b/TODO @@ -46,7 +46,6 @@ Missing features: - disable-asm and disable-bcheck options - __builtin_expect() - improve '-E' option. -- add '-MD' option - atexit (Nigel Horne) - packed attribute - C99: add variable size arrays (gcc 3.2 testsuite issue) diff --git a/libtcc.c b/libtcc.c index 1c963b52..92c7cad8 100644 --- a/libtcc.c +++ b/libtcc.c @@ -1041,6 +1041,7 @@ LIBTCCAPI void tcc_delete(TCCState *s1) dynarray_reset(&s1->input_files, &s1->nb_input_files); dynarray_reset(&s1->input_libs, &s1->nb_input_libs); + dynarray_reset(&s1->target_deps, &s1->nb_target_deps); #ifdef HAVE_SELINUX munmap (s1->write_mem, s1->mem_size); @@ -1092,6 +1093,10 @@ ST_FUNC int tcc_add_file_internal(TCCState *s1, const char *filename, int flags) goto the_end; } + /* update target deps */ + dynarray_add((void ***)&s1->target_deps, &s1->nb_target_deps, + tcc_strdup(filename)); + if (flags & AFF_PREPROCESS) { ret = tcc_preprocess(s1); goto the_end; @@ -1585,3 +1590,37 @@ LIBTCCAPI const char *tcc_default_target(TCCState *s) return outfile_default; } + + +LIBTCCAPI void tcc_gen_makedeps(TCCState *s, const char *target, const char *filename) +{ + FILE *depout; + char buf[1024], *ext; + int i; + + if (!target) + target = tcc_default_target(s); + + if (!filename) { + /* compute filename automatically + * dir/file.o -> dir/file.d */ + pstrcpy(buf, sizeof(buf), target); + ext = tcc_fileextension(buf); + pstrcpy(ext, sizeof(buf) - (ext-buf), ".d"); + filename = buf; + } + + if (s->verbose) + printf("<- %s\n", filename); + + /* XXX return err codes instead of error() ? */ + depout = fopen(filename, "w"); + if (!depout) + error("could not open '%s'", filename); + + fprintf(depout, "%s : \\\n", target); + for (i=0; inb_target_deps; ++i) + fprintf(depout, "\t%s \\\n", s->target_deps[i]); + fprintf(depout, "\n"); + fclose(depout); +} diff --git a/libtcc.h b/libtcc.h index 13efcd2f..bf328d37 100644 --- a/libtcc.h +++ b/libtcc.h @@ -110,6 +110,13 @@ LIBTCCAPI void tcc_set_lib_path(TCCState *s, const char *path); /* Get default target filename for this compilation */ LIBTCCAPI const char *tcc_default_target(TCCState *s); +/* Generate make dependencies for target and store them into file + * + * !target - use default target name + * !filename - use (target.o -> target.d) + */ +LIBTCCAPI void tcc_gen_makedeps(TCCState *s, const char *target, const char *filename); + #ifdef __cplusplus } #endif diff --git a/tcc.c b/tcc.c index 705f5e21..b9478d9d 100644 --- a/tcc.c +++ b/tcc.c @@ -32,6 +32,8 @@ static int output_type; static int reloc_output; static const char *outfile; static int do_bench = 0; +static int gen_deps; +static const char *deps_outfile; #define TCC_OPTION_HAS_ARG 0x0001 #define TCC_OPTION_NOSEP 0x0002 /* cannot have space before option and arg */ @@ -74,6 +76,9 @@ static void help(void) #ifdef CONFIG_TCC_BACKTRACE " -bt N show N callers in stack traces\n" #endif + "Misc options:\n" + " -MD generate target dependencies for make\n" + " -MF depfile put generated dependencies here\n" ); } @@ -115,6 +120,8 @@ enum { TCC_OPTION_w, TCC_OPTION_pipe, TCC_OPTION_E, + TCC_OPTION_MD, + TCC_OPTION_MF, TCC_OPTION_x, }; @@ -154,6 +161,8 @@ static const TCCOption tcc_options[] = { { "w", TCC_OPTION_w, 0 }, { "pipe", TCC_OPTION_pipe, 0}, { "E", TCC_OPTION_E, 0}, + { "MD", TCC_OPTION_MD, 0}, + { "MF", TCC_OPTION_MF, TCC_OPTION_HAS_ARG }, { "x", TCC_OPTION_x, TCC_OPTION_HAS_ARG }, { NULL }, }; @@ -374,6 +383,12 @@ static int parse_args(TCCState *s, int argc, char **argv) case TCC_OPTION_E: output_type = TCC_OUTPUT_PREPROCESS; break; + case TCC_OPTION_MD: + gen_deps = 1; + break; + case TCC_OPTION_MF: + deps_outfile = optarg; + break; case TCC_OPTION_x: break; default: @@ -479,14 +494,20 @@ int main(int argc, char **argv) if (do_bench) tcc_print_stats(s, getclock_us() - start_time); - if (s->output_type == TCC_OUTPUT_PREPROCESS) { - if (outfile) - fclose(s->outfile); - } else if (s->output_type == TCC_OUTPUT_MEMORY) + if (s->output_type == TCC_OUTPUT_MEMORY) ret = tcc_run(s, argc - optind, argv + optind); else { - ret = tcc_output_file(s, outfile ? outfile : tcc_default_target(s)); - ret = ret ? 1 : 0; + if (s->output_type == TCC_OUTPUT_PREPROCESS) { + if (outfile) + fclose(s->outfile); + } else { + ret = tcc_output_file(s, outfile ? outfile : tcc_default_target(s)); + ret = ret ? 1 : 0; + } + + /* dump collected dependencies */ + if (gen_deps && !ret) + tcc_gen_makedeps(s, outfile, deps_outfile); } } diff --git a/tcc.h b/tcc.h index 8fd44084..bb3eb9f1 100644 --- a/tcc.h +++ b/tcc.h @@ -525,6 +525,10 @@ struct TCCState { char **input_libs; int nb_input_libs; + /* automatically collected dependencies for this compilation */ + char **target_deps; + int nb_target_deps; + /* for tcc_relocate */ int runtime_added; void *runtime_mem; diff --git a/tccpp.c b/tccpp.c index 9a4cbca5..2b735d11 100644 --- a/tccpp.c +++ b/tccpp.c @@ -1491,6 +1491,9 @@ ST_FUNC void preprocess(int is_bof) #ifdef INC_DEBUG printf("%s: including %s\n", file->filename, buf1); #endif + /* update target deps */ + dynarray_add((void ***)&s1->target_deps, &s1->nb_target_deps, + tcc_strdup(buf1)); /* XXX: fix current line init */ /* push current file in stack */ From 120334830231763bd3cb84fe6fb671142161f6de Mon Sep 17 00:00:00 2001 From: Kirill Smelkov Date: Sun, 20 Jun 2010 20:42:16 +0400 Subject: [PATCH 08/11] tcc -E: Let output_default be .o instead of a.out This affectes where `tcc -E -MD file.c` will place generated dependency information -- previously, for `tcc -E` output_default was a.out, and so deps were put into a.d . Avoid this behaviour, by treating `tcc -E` as `tcc -c` with respect to output_default computation. This will not hurt anything else (preprocessor outputs to either stdout, or to explicitely given (-o ) destination, so no default filename is used here), and on the other hand `tcc -E -MD file.c` now puts dependencies into file.d (the same behaviour as for gcc -E). v2: - restructured condition a bit to make it more clear --- libtcc.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/libtcc.c b/libtcc.c index 92c7cad8..49ba8c14 100644 --- a/libtcc.c +++ b/libtcc.c @@ -1583,7 +1583,9 @@ LIBTCCAPI const char *tcc_default_target(TCCState *s) strcpy(ext, ".exe"); else #endif - if (s->output_type == TCC_OUTPUT_OBJ && !s->reloc_output && *ext) + if (( (s->output_type == TCC_OUTPUT_OBJ && !s->reloc_output) || + (s->output_type == TCC_OUTPUT_PREPROCESS) ) + && *ext) strcpy(ext, ".o"); else pstrcpy(outfile_default, sizeof(outfile_default), "a.out"); From 441a089aa494f4018963ebf19ca3e29639e4eee3 Mon Sep 17 00:00:00 2001 From: Kirill Smelkov Date: Sun, 20 Jun 2010 19:17:42 +0400 Subject: [PATCH 09/11] Document what tcc_fileextension does This is evident, but won't hurt --- libtcc.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/libtcc.c b/libtcc.c index 49ba8c14..5f064ddd 100644 --- a/libtcc.c +++ b/libtcc.c @@ -168,6 +168,10 @@ PUB_FUNC char *tcc_basename(const char *name) return p; } +/* extract extension part of a file + * + * (if no extension, return pointer to end-of-string) + */ PUB_FUNC char *tcc_fileextension (const char *name) { char *b = tcc_basename(name); From 93de8d803876f88091effb45cfcfbdcaf8c25823 Mon Sep 17 00:00:00 2001 From: Kirill Smelkov Date: Sun, 20 Jun 2010 19:18:58 +0400 Subject: [PATCH 10/11] tcc: Explicitly require -l for libraries Previously it was possible to specify e.g. -q and still link with lib. Avoid such behaviour by checking for '-l' instead of '-l.' --- tcc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tcc.c b/tcc.c index b9478d9d..136612e6 100644 --- a/tcc.c +++ b/tcc.c @@ -474,7 +474,7 @@ int main(int argc, char **argv) const char *filename; filename = files[i]; - if (filename[0] == '-' && filename[1]) { + if (filename[0] == '-' && filename[1] == 'l') { if (tcc_add_library(s, filename + 2) < 0) { error_noabort("cannot find %s", filename); ret = 1; From 2fe5210a33556ed18bc878046d39e25964a52840 Mon Sep 17 00:00:00 2001 From: Kirill Smelkov Date: Sun, 20 Jun 2010 20:48:16 +0400 Subject: [PATCH 11/11] .gitignore += tags --- .gitignore | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index df16ed9d..a845ddcb 100644 --- a/.gitignore +++ b/.gitignore @@ -36,4 +36,5 @@ tcc.pod config.h config.mak config.texi -tests \ No newline at end of file +tests +tags